54 |
#define DEFAULT_NETWORK_SCRIPT "/etc/vl-ifup" |
#define DEFAULT_NETWORK_SCRIPT "/etc/vl-ifup" |
55 |
|
|
56 |
//#define DEBUG_UNUSED_IOPORT |
//#define DEBUG_UNUSED_IOPORT |
57 |
|
//#define DEBUG_IRQ_LATENCY |
58 |
|
|
59 |
#define PHYS_RAM_BASE 0xa8000000 |
#define PHYS_RAM_BASE 0xa8000000 |
60 |
#define KERNEL_LOAD_ADDR 0x00100000 |
#define KERNEL_LOAD_ADDR 0x00100000 |
599 |
} |
} |
600 |
} |
} |
601 |
|
|
602 |
void pic_set_irq(int irq, int level) |
/* raise irq to CPU if necessary. must be called every time the active |
603 |
{ |
irq may change */ |
604 |
pic_set_irq1(&pics[irq >> 3], irq & 7, level); |
static void pic_update_irq(void) |
|
} |
|
|
|
|
|
/* can be called at any time outside cpu_exec() to raise irqs if |
|
|
necessary */ |
|
|
void pic_handle_irq(void) |
|
605 |
{ |
{ |
606 |
int irq2, irq; |
int irq2, irq; |
607 |
|
|
622 |
/* from master pic */ |
/* from master pic */ |
623 |
pic_irq_requested = irq; |
pic_irq_requested = irq; |
624 |
} |
} |
625 |
global_env->hard_interrupt_request = 1; |
cpu_x86_interrupt(global_env, CPU_INTERRUPT_HARD); |
626 |
} |
} |
627 |
} |
} |
628 |
|
|
629 |
|
#ifdef DEBUG_IRQ_LATENCY |
630 |
|
int64_t irq_time[16]; |
631 |
|
int64_t cpu_get_ticks(void); |
632 |
|
#endif |
633 |
|
|
634 |
|
void pic_set_irq(int irq, int level) |
635 |
|
{ |
636 |
|
#ifdef DEBUG_IRQ_LATENCY |
637 |
|
if (level) { |
638 |
|
irq_time[irq] = cpu_get_ticks(); |
639 |
|
} |
640 |
|
#endif |
641 |
|
pic_set_irq1(&pics[irq >> 3], irq & 7, level); |
642 |
|
pic_update_irq(); |
643 |
|
} |
644 |
|
|
645 |
int cpu_x86_get_pic_interrupt(CPUX86State *env) |
int cpu_x86_get_pic_interrupt(CPUX86State *env) |
646 |
{ |
{ |
647 |
int irq, irq2, intno; |
int irq, irq2, intno; |
648 |
|
|
649 |
/* signal the pic that the irq was acked by the CPU */ |
/* signal the pic that the irq was acked by the CPU */ |
650 |
irq = pic_irq_requested; |
irq = pic_irq_requested; |
651 |
|
#ifdef DEBUG_IRQ_LATENCY |
652 |
|
printf("IRQ%d latency=%Ld\n", irq, cpu_get_ticks() - irq_time[irq]); |
653 |
|
#endif |
654 |
|
|
655 |
if (irq >= 8) { |
if (irq >= 8) { |
656 |
irq2 = irq & 7; |
irq2 = irq & 7; |
657 |
pics[1].isr |= (1 << irq2); |
pics[1].isr |= (1 << irq2); |
722 |
case 0: |
case 0: |
723 |
/* normal mode */ |
/* normal mode */ |
724 |
s->imr = val; |
s->imr = val; |
725 |
|
pic_update_irq(); |
726 |
break; |
break; |
727 |
case 1: |
case 1: |
728 |
s->irq_base = val & 0xf8; |
s->irq_base = val & 0xf8; |
1587 |
s->rcnt == 0) { |
s->rcnt == 0) { |
1588 |
s->isr |= ENISR_RDC; |
s->isr |= ENISR_RDC; |
1589 |
ne2000_update_irq(s); |
ne2000_update_irq(s); |
|
/* XXX: find a better solution for irqs */ |
|
|
cpu_x86_interrupt(global_env); |
|
1590 |
} |
} |
1591 |
if (val & E8390_TRANS) { |
if (val & E8390_TRANS) { |
1592 |
net_send_packet(s, s->mem + (s->tpsr << 8), s->tcnt); |
net_send_packet(s, s->mem + (s->tpsr << 8), s->tcnt); |
1946 |
#define WIN_SET_MAX 0xF9 |
#define WIN_SET_MAX 0xF9 |
1947 |
#define DISABLE_SEAGATE 0xFB |
#define DISABLE_SEAGATE 0xFB |
1948 |
|
|
1949 |
#define MAX_MULT_SECTORS 16 |
/* set to 1 set disable mult support */ |
1950 |
|
#define MAX_MULT_SECTORS 8 |
1951 |
|
|
1952 |
#define MAX_DISKS 2 |
#define MAX_DISKS 2 |
1953 |
|
|
1964 |
/* ide regs */ |
/* ide regs */ |
1965 |
uint8_t feature; |
uint8_t feature; |
1966 |
uint8_t error; |
uint8_t error; |
1967 |
uint8_t nsector; |
uint16_t nsector; /* 0 is 256 to ease computations */ |
1968 |
uint8_t sector; |
uint8_t sector; |
1969 |
uint8_t lcyl; |
uint8_t lcyl; |
1970 |
uint8_t hcyl; |
uint8_t hcyl; |
1975 |
/* depends on bit 4 in select, only meaningful for drive 0 */ |
/* depends on bit 4 in select, only meaningful for drive 0 */ |
1976 |
struct IDEState *cur_drive; |
struct IDEState *cur_drive; |
1977 |
BlockDriverState *bs; |
BlockDriverState *bs; |
1978 |
|
int req_nb_sectors; /* number of sectors per interrupt */ |
1979 |
EndTransferFunc *end_transfer_func; |
EndTransferFunc *end_transfer_func; |
1980 |
uint8_t *data_ptr; |
uint8_t *data_ptr; |
1981 |
uint8_t *data_end; |
uint8_t *data_end; |
2015 |
stw(p + 21, 512); /* cache size in sectors */ |
stw(p + 21, 512); /* cache size in sectors */ |
2016 |
stw(p + 22, 4); /* ecc bytes */ |
stw(p + 22, 4); /* ecc bytes */ |
2017 |
padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40); |
padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40); |
2018 |
// stw(p + 47, MAX_MULT_SECTORS); |
#if MAX_MULT_SECTORS > 1 |
2019 |
|
stw(p + 47, MAX_MULT_SECTORS); |
2020 |
|
#endif |
2021 |
stw(p + 48, 1); /* dword I/O */ |
stw(p + 48, 1); /* dword I/O */ |
2022 |
stw(p + 49, 1 << 9); /* LBA supported, no DMA */ |
stw(p + 49, 1 << 9); /* LBA supported, no DMA */ |
2023 |
stw(p + 51, 0x200); /* PIO transfer cycle */ |
stw(p + 51, 0x200); /* PIO transfer cycle */ |
2051 |
{ |
{ |
2052 |
if (!(ide_state[0].cmd & IDE_CMD_DISABLE_IRQ)) { |
if (!(ide_state[0].cmd & IDE_CMD_DISABLE_IRQ)) { |
2053 |
pic_set_irq(s->irq, 1); |
pic_set_irq(s->irq, 1); |
|
cpu_x86_interrupt(global_env); |
|
2054 |
} |
} |
2055 |
} |
} |
2056 |
|
|
2108 |
static void ide_sector_read(IDEState *s) |
static void ide_sector_read(IDEState *s) |
2109 |
{ |
{ |
2110 |
int64_t sector_num; |
int64_t sector_num; |
2111 |
int ret; |
int ret, n; |
2112 |
|
|
2113 |
s->status = READY_STAT | SEEK_STAT; |
s->status = READY_STAT | SEEK_STAT; |
2114 |
sector_num = ide_get_sector(s); |
sector_num = ide_get_sector(s); |
2115 |
s->nsector--; |
n = s->nsector; |
2116 |
if (s->nsector == 0xff) { |
if (n == 0) { |
2117 |
/* no more sector to read from disk */ |
/* no more sector to read from disk */ |
2118 |
ide_transfer_stop(s); |
ide_transfer_stop(s); |
2119 |
} else { |
} else { |
2120 |
#if defined(DEBUG_IDE) |
#if defined(DEBUG_IDE) |
2121 |
printf("read sector=%Ld\n", sector_num); |
printf("read sector=%Ld\n", sector_num); |
2122 |
#endif |
#endif |
2123 |
ret = bdrv_read(s->bs, sector_num, s->io_buffer, 1); |
if (n > s->req_nb_sectors) |
2124 |
ide_transfer_start(s, 512, ide_sector_read); |
n = s->req_nb_sectors; |
2125 |
|
ret = bdrv_read(s->bs, sector_num, s->io_buffer, n); |
2126 |
|
ide_transfer_start(s, 512 * n, ide_sector_read); |
2127 |
ide_set_irq(s); |
ide_set_irq(s); |
2128 |
|
ide_set_sector(s, sector_num + n); |
2129 |
|
s->nsector -= n; |
2130 |
} |
} |
|
ide_set_sector(s, sector_num + 1); |
|
2131 |
} |
} |
2132 |
|
|
2133 |
static void ide_sector_write(IDEState *s) |
static void ide_sector_write(IDEState *s) |
2134 |
{ |
{ |
2135 |
int64_t sector_num; |
int64_t sector_num; |
2136 |
int ret; |
int ret, n, n1; |
2137 |
|
|
2138 |
s->status = READY_STAT | SEEK_STAT; |
s->status = READY_STAT | SEEK_STAT; |
2139 |
sector_num = ide_get_sector(s); |
sector_num = ide_get_sector(s); |
2140 |
#if defined(DEBUG_IDE) |
#if defined(DEBUG_IDE) |
2141 |
printf("write sector=%Ld\n", sector_num); |
printf("write sector=%Ld\n", sector_num); |
2142 |
#endif |
#endif |
2143 |
ret = bdrv_write(s->bs, sector_num, s->io_buffer, 1); |
n = s->nsector; |
2144 |
s->nsector--; |
if (n > s->req_nb_sectors) |
2145 |
|
n = s->req_nb_sectors; |
2146 |
|
ret = bdrv_write(s->bs, sector_num, s->io_buffer, n); |
2147 |
|
s->nsector -= n; |
2148 |
if (s->nsector == 0) { |
if (s->nsector == 0) { |
2149 |
/* no more sector to write */ |
/* no more sector to write */ |
2150 |
ide_transfer_stop(s); |
ide_transfer_stop(s); |
2151 |
} else { |
} else { |
2152 |
ide_transfer_start(s, 512, ide_sector_write); |
n1 = s->nsector; |
2153 |
|
if (n1 > s->req_nb_sectors) |
2154 |
|
n1 = s->req_nb_sectors; |
2155 |
|
ide_transfer_start(s, 512 * n1, ide_sector_write); |
2156 |
} |
} |
2157 |
ide_set_sector(s, sector_num + 1); |
ide_set_sector(s, sector_num + n); |
2158 |
ide_set_irq(s); |
ide_set_irq(s); |
2159 |
} |
} |
2160 |
|
|
2161 |
void ide_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val) |
void ide_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val) |
2162 |
{ |
{ |
2163 |
IDEState *s = ide_state[0].cur_drive; |
IDEState *s = ide_state[0].cur_drive; |
2164 |
int unit; |
int unit, n; |
2165 |
|
|
2166 |
addr &= 7; |
addr &= 7; |
2167 |
#ifdef DEBUG_IDE |
#ifdef DEBUG_IDE |
2174 |
s->feature = val; |
s->feature = val; |
2175 |
break; |
break; |
2176 |
case 2: |
case 2: |
2177 |
|
if (val == 0) |
2178 |
|
val = 256; |
2179 |
s->nsector = val; |
s->nsector = val; |
2180 |
break; |
break; |
2181 |
case 3: |
case 3: |
2230 |
break; |
break; |
2231 |
case WIN_READ: |
case WIN_READ: |
2232 |
case WIN_READ_ONCE: |
case WIN_READ_ONCE: |
2233 |
|
s->req_nb_sectors = 1; |
2234 |
ide_sector_read(s); |
ide_sector_read(s); |
2235 |
break; |
break; |
2236 |
case WIN_WRITE: |
case WIN_WRITE: |
2237 |
case WIN_WRITE_ONCE: |
case WIN_WRITE_ONCE: |
2238 |
s->status = SEEK_STAT; |
s->status = SEEK_STAT; |
2239 |
|
s->req_nb_sectors = 1; |
2240 |
ide_transfer_start(s, 512, ide_sector_write); |
ide_transfer_start(s, 512, ide_sector_write); |
2241 |
break; |
break; |
2242 |
|
case WIN_MULTREAD: |
2243 |
|
if (!s->mult_sectors) |
2244 |
|
goto abort_cmd; |
2245 |
|
s->req_nb_sectors = s->mult_sectors; |
2246 |
|
ide_sector_read(s); |
2247 |
|
break; |
2248 |
|
case WIN_MULTWRITE: |
2249 |
|
if (!s->mult_sectors) |
2250 |
|
goto abort_cmd; |
2251 |
|
s->status = SEEK_STAT; |
2252 |
|
s->req_nb_sectors = s->mult_sectors; |
2253 |
|
n = s->nsector; |
2254 |
|
if (n > s->req_nb_sectors) |
2255 |
|
n = s->req_nb_sectors; |
2256 |
|
ide_transfer_start(s, 512 * n, ide_sector_write); |
2257 |
|
break; |
2258 |
default: |
default: |
2259 |
|
abort_cmd: |
2260 |
ide_abort_command(s); |
ide_abort_command(s); |
2261 |
ide_set_irq(s); |
ide_set_irq(s); |
2262 |
break; |
break; |
2278 |
ret = s->error; |
ret = s->error; |
2279 |
break; |
break; |
2280 |
case 2: |
case 2: |
2281 |
ret = s->nsector; |
ret = s->nsector & 0xff; |
2282 |
break; |
break; |
2283 |
case 3: |
case 3: |
2284 |
ret = s->sector; |
ret = s->sector; |
2448 |
timer_irq_count = 2; |
timer_irq_count = 2; |
2449 |
timer_irq_count--; |
timer_irq_count--; |
2450 |
/* just exit from the cpu to have a chance to handle timers */ |
/* just exit from the cpu to have a chance to handle timers */ |
2451 |
cpu_x86_interrupt(global_env); |
cpu_x86_interrupt(global_env, CPU_INTERRUPT_EXIT); |
2452 |
timer_irq_pending = 1; |
timer_irq_pending = 1; |
2453 |
} |
} |
2454 |
} |
} |
2535 |
pic_set_irq(0, 0); |
pic_set_irq(0, 0); |
2536 |
timer_irq_pending = 0; |
timer_irq_pending = 0; |
2537 |
} |
} |
|
|
|
|
pic_handle_irq(); |
|
2538 |
} |
} |
2539 |
} |
} |
2540 |
|
|