Commit b41a2cd1e4228c765e3b82ec6c89096528b4d7d9
1 parent
c4b1fcc0
io port API change
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@664 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
7 changed files
with
193 additions
and
158 deletions
hw/i8254.c
| ... | ... | @@ -201,7 +201,7 @@ static inline void pit_load_count(PITChannelState *s, int val) |
| 201 | 201 | } |
| 202 | 202 | } |
| 203 | 203 | |
| 204 | -void pit_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | |
| 204 | +static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val) | |
| 205 | 205 | { |
| 206 | 206 | int channel, access; |
| 207 | 207 | PITChannelState *s; |
| ... | ... | @@ -246,7 +246,7 @@ void pit_ioport_write(CPUState *env, uint32_t addr, uint32_t val) |
| 246 | 246 | } |
| 247 | 247 | } |
| 248 | 248 | |
| 249 | -uint32_t pit_ioport_read(CPUState *env, uint32_t addr) | |
| 249 | +static uint32_t pit_ioport_read(void *opaque, uint32_t addr) | |
| 250 | 250 | { |
| 251 | 251 | int ret, count; |
| 252 | 252 | PITChannelState *s; |
| ... | ... | @@ -279,7 +279,7 @@ uint32_t pit_ioport_read(CPUState *env, uint32_t addr) |
| 279 | 279 | return ret; |
| 280 | 280 | } |
| 281 | 281 | |
| 282 | -void pit_init(void) | |
| 282 | +void pit_init(int base) | |
| 283 | 283 | { |
| 284 | 284 | PITChannelState *s; |
| 285 | 285 | int i; |
| ... | ... | @@ -291,7 +291,7 @@ void pit_init(void) |
| 291 | 291 | pit_load_count(s, 0); |
| 292 | 292 | } |
| 293 | 293 | |
| 294 | - register_ioport_write(0x40, 4, pit_ioport_write, 1); | |
| 295 | - register_ioport_read(0x40, 3, pit_ioport_read, 1); | |
| 294 | + register_ioport_write(base, 4, 1, pit_ioport_write, NULL); | |
| 295 | + register_ioport_read(base, 3, 1, pit_ioport_read, NULL); | |
| 296 | 296 | } |
| 297 | 297 | ... | ... |
hw/i8259.c
| ... | ... | @@ -46,6 +46,8 @@ |
| 46 | 46 | /* debug PIC */ |
| 47 | 47 | //#define DEBUG_PIC |
| 48 | 48 | |
| 49 | +//#define DEBUG_IRQ_LATENCY | |
| 50 | + | |
| 49 | 51 | typedef struct PicState { |
| 50 | 52 | uint8_t last_irr; /* edge detection */ |
| 51 | 53 | uint8_t irr; /* interrupt request register */ |
| ... | ... | @@ -220,15 +222,14 @@ int cpu_x86_get_pic_interrupt(CPUState *env) |
| 220 | 222 | return intno; |
| 221 | 223 | } |
| 222 | 224 | |
| 223 | -void pic_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | |
| 225 | +static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) | |
| 224 | 226 | { |
| 225 | - PicState *s; | |
| 227 | + PicState *s = opaque; | |
| 226 | 228 | int priority, cmd, irq; |
| 227 | 229 | |
| 228 | 230 | #ifdef DEBUG_PIC |
| 229 | 231 | printf("pic_write: addr=0x%02x val=0x%02x\n", addr, val); |
| 230 | 232 | #endif |
| 231 | - s = &pics[addr >> 7]; | |
| 232 | 233 | addr &= 1; |
| 233 | 234 | if (addr == 0) { |
| 234 | 235 | if (val & 0x10) { |
| ... | ... | @@ -334,14 +335,13 @@ static uint32_t pic_poll_read (PicState *s, uint32_t addr1) |
| 334 | 335 | return ret; |
| 335 | 336 | } |
| 336 | 337 | |
| 337 | -uint32_t pic_ioport_read(CPUState *env, uint32_t addr1) | |
| 338 | +static uint32_t pic_ioport_read(void *opaque, uint32_t addr1) | |
| 338 | 339 | { |
| 339 | - PicState *s; | |
| 340 | + PicState *s = opaque; | |
| 340 | 341 | unsigned int addr; |
| 341 | 342 | int ret; |
| 342 | 343 | |
| 343 | 344 | addr = addr1; |
| 344 | - s = &pics[addr >> 7]; | |
| 345 | 345 | addr &= 1; |
| 346 | 346 | if (s->poll) { |
| 347 | 347 | ret = pic_poll_read(s, addr1); |
| ... | ... | @@ -378,11 +378,9 @@ uint32_t pic_intack_read(CPUState *env) |
| 378 | 378 | |
| 379 | 379 | void pic_init(void) |
| 380 | 380 | { |
| 381 | -#if defined (TARGET_I386) || defined (TARGET_PPC) | |
| 382 | - register_ioport_write(0x20, 2, pic_ioport_write, 1); | |
| 383 | - register_ioport_read(0x20, 2, pic_ioport_read, 1); | |
| 384 | - register_ioport_write(0xa0, 2, pic_ioport_write, 1); | |
| 385 | - register_ioport_read(0xa0, 2, pic_ioport_read, 1); | |
| 386 | -#endif | |
| 381 | + register_ioport_write(0x20, 2, 1, pic_ioport_write, &pics[0]); | |
| 382 | + register_ioport_read(0x20, 2, 1, pic_ioport_read, &pics[0]); | |
| 383 | + register_ioport_write(0xa0, 2, 1, pic_ioport_write, &pics[1]); | |
| 384 | + register_ioport_read(0xa0, 2, 1, pic_ioport_read, &pics[1]); | |
| 387 | 385 | } |
| 388 | 386 | ... | ... |
hw/mc146818rtc.c
| ... | ... | @@ -69,9 +69,9 @@ |
| 69 | 69 | |
| 70 | 70 | RTCState rtc_state; |
| 71 | 71 | |
| 72 | -static void cmos_ioport_write(CPUState *env, uint32_t addr, uint32_t data) | |
| 72 | +static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data) | |
| 73 | 73 | { |
| 74 | - RTCState *s = &rtc_state; | |
| 74 | + RTCState *s = opaque; | |
| 75 | 75 | |
| 76 | 76 | if ((addr & 1) == 0) { |
| 77 | 77 | s->cmos_index = data & 0x7f; |
| ... | ... | @@ -134,9 +134,9 @@ static void cmos_update_time(RTCState *s) |
| 134 | 134 | s->cmos_data[REG_IBM_PS2_CENTURY_BYTE] = s->cmos_data[REG_IBM_CENTURY_BYTE]; |
| 135 | 135 | } |
| 136 | 136 | |
| 137 | -static uint32_t cmos_ioport_read(CPUState *env, uint32_t addr) | |
| 137 | +static uint32_t cmos_ioport_read(void *opaque, uint32_t addr) | |
| 138 | 138 | { |
| 139 | - RTCState *s = &rtc_state; | |
| 139 | + RTCState *s = opaque; | |
| 140 | 140 | int ret; |
| 141 | 141 | if ((addr & 1) == 0) { |
| 142 | 142 | return 0xff; |
| ... | ... | @@ -197,7 +197,7 @@ void rtc_init(int base, int irq) |
| 197 | 197 | s->cmos_data[RTC_REG_C] = 0x00; |
| 198 | 198 | s->cmos_data[RTC_REG_D] = 0x80; |
| 199 | 199 | |
| 200 | - register_ioport_write(base, 2, cmos_ioport_write, 1); | |
| 201 | - register_ioport_read(base, 2, cmos_ioport_read, 1); | |
| 200 | + register_ioport_write(base, 2, 1, cmos_ioport_write, s); | |
| 201 | + register_ioport_read(base, 2, 1, cmos_ioport_read, s); | |
| 202 | 202 | } |
| 203 | 203 | ... | ... |
hw/ne2000.c
| ... | ... | @@ -46,8 +46,7 @@ |
| 46 | 46 | /* debug NE2000 card */ |
| 47 | 47 | //#define DEBUG_NE2000 |
| 48 | 48 | |
| 49 | -/***********************************************************/ | |
| 50 | -/* ne2000 emulation */ | |
| 49 | +#define MAX_ETH_FRAME_SIZE 1514 | |
| 51 | 50 | |
| 52 | 51 | #define E8390_CMD 0x00 /* The command register (for all pages) */ |
| 53 | 52 | /* Page 0 register offsets. */ |
| ... | ... | @@ -143,23 +142,16 @@ typedef struct NE2000State { |
| 143 | 142 | uint8_t curpag; |
| 144 | 143 | uint8_t mult[8]; /* multicast mask array */ |
| 145 | 144 | int irq; |
| 145 | + NetDriverState *nd; | |
| 146 | 146 | uint8_t mem[NE2000_MEM_SIZE]; |
| 147 | 147 | } NE2000State; |
| 148 | 148 | |
| 149 | -static NE2000State ne2000_state; | |
| 150 | -int net_fd = -1; | |
| 151 | - | |
| 152 | 149 | static void ne2000_reset(NE2000State *s) |
| 153 | 150 | { |
| 154 | 151 | int i; |
| 155 | 152 | |
| 156 | 153 | s->isr = ENISR_RESET; |
| 157 | - s->mem[0] = 0x52; | |
| 158 | - s->mem[1] = 0x54; | |
| 159 | - s->mem[2] = 0x00; | |
| 160 | - s->mem[3] = 0x12; | |
| 161 | - s->mem[4] = 0x34; | |
| 162 | - s->mem[5] = 0x56; | |
| 154 | + memcpy(s->mem, s->nd->macaddr, 6); | |
| 163 | 155 | s->mem[14] = 0x57; |
| 164 | 156 | s->mem[15] = 0x57; |
| 165 | 157 | |
| ... | ... | @@ -180,10 +172,10 @@ static void ne2000_update_irq(NE2000State *s) |
| 180 | 172 | pic_set_irq(s->irq, 0); |
| 181 | 173 | } |
| 182 | 174 | |
| 183 | -/* return true if the NE2000 can receive more data */ | |
| 184 | -int ne2000_can_receive(void) | |
| 175 | +/* return the max buffer size if the NE2000 can receive more data */ | |
| 176 | +static int ne2000_can_receive(void *opaque) | |
| 185 | 177 | { |
| 186 | - NE2000State *s = &ne2000_state; | |
| 178 | + NE2000State *s = opaque; | |
| 187 | 179 | int avail, index, boundary; |
| 188 | 180 | |
| 189 | 181 | if (s->cmd & E8390_STOP) |
| ... | ... | @@ -196,19 +188,30 @@ int ne2000_can_receive(void) |
| 196 | 188 | avail = (s->stop - s->start) - (index - boundary); |
| 197 | 189 | if (avail < (MAX_ETH_FRAME_SIZE + 4)) |
| 198 | 190 | return 0; |
| 199 | - return 1; | |
| 191 | + return MAX_ETH_FRAME_SIZE; | |
| 200 | 192 | } |
| 201 | 193 | |
| 202 | -void ne2000_receive(uint8_t *buf, int size) | |
| 194 | +#define MIN_BUF_SIZE 60 | |
| 195 | + | |
| 196 | +static void ne2000_receive(void *opaque, const uint8_t *buf, int size) | |
| 203 | 197 | { |
| 204 | - NE2000State *s = &ne2000_state; | |
| 198 | + NE2000State *s = opaque; | |
| 205 | 199 | uint8_t *p; |
| 206 | 200 | int total_len, next, avail, len, index; |
| 207 | - | |
| 201 | + uint8_t buf1[60]; | |
| 202 | + | |
| 208 | 203 | #if defined(DEBUG_NE2000) |
| 209 | 204 | printf("NE2000: received len=%d\n", size); |
| 210 | 205 | #endif |
| 211 | 206 | |
| 207 | + /* if too small buffer, then expand it */ | |
| 208 | + if (size < MIN_BUF_SIZE) { | |
| 209 | + memcpy(buf1, buf, size); | |
| 210 | + memset(buf1 + size, 0, MIN_BUF_SIZE - size); | |
| 211 | + buf = buf1; | |
| 212 | + size = MIN_BUF_SIZE; | |
| 213 | + } | |
| 214 | + | |
| 212 | 215 | index = s->curpag << 8; |
| 213 | 216 | /* 4 bytes for header */ |
| 214 | 217 | total_len = size + 4; |
| ... | ... | @@ -244,9 +247,9 @@ void ne2000_receive(uint8_t *buf, int size) |
| 244 | 247 | ne2000_update_irq(s); |
| 245 | 248 | } |
| 246 | 249 | |
| 247 | -static void ne2000_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | |
| 250 | +static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val) | |
| 248 | 251 | { |
| 249 | - NE2000State *s = &ne2000_state; | |
| 252 | + NE2000State *s = opaque; | |
| 250 | 253 | int offset, page; |
| 251 | 254 | |
| 252 | 255 | addr &= 0xf; |
| ... | ... | @@ -264,7 +267,7 @@ static void ne2000_ioport_write(CPUState *env, uint32_t addr, uint32_t val) |
| 264 | 267 | ne2000_update_irq(s); |
| 265 | 268 | } |
| 266 | 269 | if (val & E8390_TRANS) { |
| 267 | - net_send_packet(net_fd, s->mem + (s->tpsr << 8), s->tcnt); | |
| 270 | + net_send_packet(s->nd, s->mem + (s->tpsr << 8), s->tcnt); | |
| 268 | 271 | /* signal end of transfert */ |
| 269 | 272 | s->tsr = ENTSR_PTX; |
| 270 | 273 | s->isr |= ENISR_TX; |
| ... | ... | @@ -329,9 +332,9 @@ static void ne2000_ioport_write(CPUState *env, uint32_t addr, uint32_t val) |
| 329 | 332 | } |
| 330 | 333 | } |
| 331 | 334 | |
| 332 | -static uint32_t ne2000_ioport_read(CPUState *env, uint32_t addr) | |
| 335 | +static uint32_t ne2000_ioport_read(void *opaque, uint32_t addr) | |
| 333 | 336 | { |
| 334 | - NE2000State *s = &ne2000_state; | |
| 337 | + NE2000State *s = opaque; | |
| 335 | 338 | int offset, page, ret; |
| 336 | 339 | |
| 337 | 340 | addr &= 0xf; |
| ... | ... | @@ -370,9 +373,9 @@ static uint32_t ne2000_ioport_read(CPUState *env, uint32_t addr) |
| 370 | 373 | return ret; |
| 371 | 374 | } |
| 372 | 375 | |
| 373 | -static void ne2000_asic_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | |
| 376 | +static void ne2000_asic_ioport_write(void *opaque, uint32_t addr, uint32_t val) | |
| 374 | 377 | { |
| 375 | - NE2000State *s = &ne2000_state; | |
| 378 | + NE2000State *s = opaque; | |
| 376 | 379 | uint8_t *p; |
| 377 | 380 | |
| 378 | 381 | #ifdef DEBUG_NE2000 |
| ... | ... | @@ -401,9 +404,9 @@ static void ne2000_asic_ioport_write(CPUState *env, uint32_t addr, uint32_t val) |
| 401 | 404 | } |
| 402 | 405 | } |
| 403 | 406 | |
| 404 | -static uint32_t ne2000_asic_ioport_read(CPUState *env, uint32_t addr) | |
| 407 | +static uint32_t ne2000_asic_ioport_read(void *opaque, uint32_t addr) | |
| 405 | 408 | { |
| 406 | - NE2000State *s = &ne2000_state; | |
| 409 | + NE2000State *s = opaque; | |
| 407 | 410 | uint8_t *p; |
| 408 | 411 | int ret; |
| 409 | 412 | |
| ... | ... | @@ -433,33 +436,40 @@ static uint32_t ne2000_asic_ioport_read(CPUState *env, uint32_t addr) |
| 433 | 436 | return ret; |
| 434 | 437 | } |
| 435 | 438 | |
| 436 | -static void ne2000_reset_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | |
| 439 | +static void ne2000_reset_ioport_write(void *opaque, uint32_t addr, uint32_t val) | |
| 437 | 440 | { |
| 438 | 441 | /* nothing to do (end of reset pulse) */ |
| 439 | 442 | } |
| 440 | 443 | |
| 441 | -static uint32_t ne2000_reset_ioport_read(CPUState *env, uint32_t addr) | |
| 444 | +static uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr) | |
| 442 | 445 | { |
| 443 | - NE2000State *s = &ne2000_state; | |
| 446 | + NE2000State *s = opaque; | |
| 444 | 447 | ne2000_reset(s); |
| 445 | 448 | return 0; |
| 446 | 449 | } |
| 447 | 450 | |
| 448 | -void ne2000_init(int base, int irq) | |
| 451 | +void ne2000_init(int base, int irq, NetDriverState *nd) | |
| 449 | 452 | { |
| 450 | - NE2000State *s = &ne2000_state; | |
| 453 | + NE2000State *s; | |
| 451 | 454 | |
| 452 | - register_ioport_write(base, 16, ne2000_ioport_write, 1); | |
| 453 | - register_ioport_read(base, 16, ne2000_ioport_read, 1); | |
| 455 | + s = qemu_mallocz(sizeof(NE2000State)); | |
| 456 | + if (!s) | |
| 457 | + return; | |
| 458 | + | |
| 459 | + register_ioport_write(base, 16, 1, ne2000_ioport_write, s); | |
| 460 | + register_ioport_read(base, 16, 1, ne2000_ioport_read, s); | |
| 454 | 461 | |
| 455 | - register_ioport_write(base + 0x10, 1, ne2000_asic_ioport_write, 1); | |
| 456 | - register_ioport_read(base + 0x10, 1, ne2000_asic_ioport_read, 1); | |
| 457 | - register_ioport_write(base + 0x10, 2, ne2000_asic_ioport_write, 2); | |
| 458 | - register_ioport_read(base + 0x10, 2, ne2000_asic_ioport_read, 2); | |
| 462 | + register_ioport_write(base + 0x10, 1, 1, ne2000_asic_ioport_write, s); | |
| 463 | + register_ioport_read(base + 0x10, 1, 1, ne2000_asic_ioport_read, s); | |
| 464 | + register_ioport_write(base + 0x10, 2, 2, ne2000_asic_ioport_write, s); | |
| 465 | + register_ioport_read(base + 0x10, 2, 2, ne2000_asic_ioport_read, s); | |
| 459 | 466 | |
| 460 | - register_ioport_write(base + 0x1f, 1, ne2000_reset_ioport_write, 1); | |
| 461 | - register_ioport_read(base + 0x1f, 1, ne2000_reset_ioport_read, 1); | |
| 467 | + register_ioport_write(base + 0x1f, 1, 1, ne2000_reset_ioport_write, s); | |
| 468 | + register_ioport_read(base + 0x1f, 1, 1, ne2000_reset_ioport_read, s); | |
| 462 | 469 | s->irq = irq; |
| 470 | + s->nd = nd; | |
| 463 | 471 | |
| 464 | 472 | ne2000_reset(s); |
| 473 | + | |
| 474 | + add_fd_read_handler(nd->fd, ne2000_can_receive, ne2000_receive, s); | |
| 465 | 475 | } | ... | ... |
hw/pc.c
| ... | ... | @@ -43,6 +43,9 @@ |
| 43 | 43 | #include "cpu.h" |
| 44 | 44 | #include "vl.h" |
| 45 | 45 | |
| 46 | +/* output Bochs bios info messages */ | |
| 47 | +//#define DEBUG_BIOS | |
| 48 | + | |
| 46 | 49 | #define BIOS_FILENAME "bios.bin" |
| 47 | 50 | #define VGABIOS_FILENAME "vgabios.bin" |
| 48 | 51 | #define LINUX_BOOT_FILENAME "linux_boot.bin" |
| ... | ... | @@ -55,7 +58,7 @@ |
| 55 | 58 | int speaker_data_on; |
| 56 | 59 | int dummy_refresh_clock; |
| 57 | 60 | |
| 58 | -static void ioport80_write(CPUState *env, uint32_t addr, uint32_t data) | |
| 61 | +static void ioport80_write(void *opaque, uint32_t addr, uint32_t data) | |
| 59 | 62 | { |
| 60 | 63 | } |
| 61 | 64 | |
| ... | ... | @@ -65,6 +68,7 @@ static void cmos_init(int ram_size, int boot_device) |
| 65 | 68 | { |
| 66 | 69 | RTCState *s = &rtc_state; |
| 67 | 70 | int val; |
| 71 | + int fd0, fd1, nb; | |
| 68 | 72 | |
| 69 | 73 | /* various important CMOS locations needed by PC/Bochs bios */ |
| 70 | 74 | |
| ... | ... | @@ -99,12 +103,11 @@ static void cmos_init(int ram_size, int boot_device) |
| 99 | 103 | s->cmos_data[0x3d] = 0x03; /* CD-ROM boot */ |
| 100 | 104 | break; |
| 101 | 105 | } |
| 102 | -} | |
| 103 | 106 | |
| 104 | -void cmos_register_fd (uint8_t fd0, uint8_t fd1) | |
| 105 | -{ | |
| 106 | - RTCState *s = &rtc_state; | |
| 107 | - int nb = 0; | |
| 107 | + /* floppy type */ | |
| 108 | + | |
| 109 | + fd0 = fdctrl_get_drive_type(0); | |
| 110 | + fd1 = fdctrl_get_drive_type(1); | |
| 108 | 111 | |
| 109 | 112 | s->cmos_data[0x10] = 0; |
| 110 | 113 | switch (fd0) { |
| ... | ... | @@ -135,6 +138,7 @@ void cmos_register_fd (uint8_t fd0, uint8_t fd1) |
| 135 | 138 | s->cmos_data[0x10] |= 0x02; |
| 136 | 139 | break; |
| 137 | 140 | } |
| 141 | + nb = 0; | |
| 138 | 142 | if (fd0 < 3) |
| 139 | 143 | nb++; |
| 140 | 144 | if (fd1 < 3) |
| ... | ... | @@ -151,13 +155,13 @@ void cmos_register_fd (uint8_t fd0, uint8_t fd1) |
| 151 | 155 | } |
| 152 | 156 | } |
| 153 | 157 | |
| 154 | -void speaker_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | |
| 158 | +static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val) | |
| 155 | 159 | { |
| 156 | 160 | speaker_data_on = (val >> 1) & 1; |
| 157 | 161 | pit_set_gate(&pit_channels[2], val & 1); |
| 158 | 162 | } |
| 159 | 163 | |
| 160 | -uint32_t speaker_ioport_read(CPUState *env, uint32_t addr) | |
| 164 | +static uint32_t speaker_ioport_read(void *opaque, uint32_t addr) | |
| 161 | 165 | { |
| 162 | 166 | int out; |
| 163 | 167 | out = pit_get_out(&pit_channels[2]); |
| ... | ... | @@ -167,27 +171,9 @@ uint32_t speaker_ioport_read(CPUState *env, uint32_t addr) |
| 167 | 171 | } |
| 168 | 172 | |
| 169 | 173 | /***********************************************************/ |
| 170 | -/* PC floppy disk controler emulation glue */ | |
| 171 | -#define PC_FDC_DMA 0x2 | |
| 172 | -#define PC_FDC_IRQ 0x6 | |
| 173 | -#define PC_FDC_BASE 0x3F0 | |
| 174 | - | |
| 175 | -static void fdctrl_register (unsigned char **disknames, int ro, | |
| 176 | - char boot_device) | |
| 177 | -{ | |
| 178 | - int i; | |
| 179 | - | |
| 180 | - fdctrl_init(PC_FDC_IRQ, PC_FDC_DMA, 0, PC_FDC_BASE, boot_device); | |
| 181 | - for (i = 0; i < MAX_FD; i++) { | |
| 182 | - if (disknames[i] != NULL) | |
| 183 | - fdctrl_disk_change(i, disknames[i], ro); | |
| 184 | - } | |
| 185 | -} | |
| 186 | - | |
| 187 | -/***********************************************************/ | |
| 188 | 174 | /* Bochs BIOS debug ports */ |
| 189 | 175 | |
| 190 | -void bochs_bios_write(CPUX86State *env, uint32_t addr, uint32_t val) | |
| 176 | +void bochs_bios_write(void *opaque, uint32_t addr, uint32_t val) | |
| 191 | 177 | { |
| 192 | 178 | switch(addr) { |
| 193 | 179 | /* Bochs BIOS messages */ |
| ... | ... | @@ -218,15 +204,15 @@ void bochs_bios_write(CPUX86State *env, uint32_t addr, uint32_t val) |
| 218 | 204 | |
| 219 | 205 | void bochs_bios_init(void) |
| 220 | 206 | { |
| 221 | - register_ioport_write(0x400, 1, bochs_bios_write, 2); | |
| 222 | - register_ioport_write(0x401, 1, bochs_bios_write, 2); | |
| 223 | - register_ioport_write(0x402, 1, bochs_bios_write, 1); | |
| 224 | - register_ioport_write(0x403, 1, bochs_bios_write, 1); | |
| 225 | - | |
| 226 | - register_ioport_write(0x501, 1, bochs_bios_write, 2); | |
| 227 | - register_ioport_write(0x502, 1, bochs_bios_write, 2); | |
| 228 | - register_ioport_write(0x500, 1, bochs_bios_write, 1); | |
| 229 | - register_ioport_write(0x503, 1, bochs_bios_write, 1); | |
| 207 | + register_ioport_write(0x400, 1, 2, bochs_bios_write, NULL); | |
| 208 | + register_ioport_write(0x401, 1, 2, bochs_bios_write, NULL); | |
| 209 | + register_ioport_write(0x402, 1, 1, bochs_bios_write, NULL); | |
| 210 | + register_ioport_write(0x403, 1, 1, bochs_bios_write, NULL); | |
| 211 | + | |
| 212 | + register_ioport_write(0x501, 1, 2, bochs_bios_write, NULL); | |
| 213 | + register_ioport_write(0x502, 1, 2, bochs_bios_write, NULL); | |
| 214 | + register_ioport_write(0x500, 1, 1, bochs_bios_write, NULL); | |
| 215 | + register_ioport_write(0x503, 1, 1, bochs_bios_write, NULL); | |
| 230 | 216 | } |
| 231 | 217 | |
| 232 | 218 | |
| ... | ... | @@ -261,6 +247,15 @@ int load_kernel(const char *filename, uint8_t *addr, |
| 261 | 247 | return -1; |
| 262 | 248 | } |
| 263 | 249 | |
| 250 | +static const int ide_iobase[2] = { 0x1f0, 0x170 }; | |
| 251 | +static const int ide_iobase2[2] = { 0x3f6, 0x376 }; | |
| 252 | +static const int ide_irq[2] = { 14, 15 }; | |
| 253 | + | |
| 254 | +#define NE2000_NB_MAX 6 | |
| 255 | + | |
| 256 | +static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 }; | |
| 257 | +static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 }; | |
| 258 | + | |
| 264 | 259 | /* PC hardware initialisation */ |
| 265 | 260 | void pc_init(int ram_size, int vga_ram_size, int boot_device, |
| 266 | 261 | DisplayState *ds, const char **fd_filename, int snapshot, |
| ... | ... | @@ -268,7 +263,7 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device, |
| 268 | 263 | const char *initrd_filename) |
| 269 | 264 | { |
| 270 | 265 | char buf[1024]; |
| 271 | - int ret, linux_boot, initrd_size; | |
| 266 | + int ret, linux_boot, initrd_size, i, nb_nics1, fd; | |
| 272 | 267 | |
| 273 | 268 | linux_boot = (kernel_filename != NULL); |
| 274 | 269 | |
| ... | ... | @@ -344,25 +339,38 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device, |
| 344 | 339 | } |
| 345 | 340 | |
| 346 | 341 | /* init basic PC hardware */ |
| 347 | - register_ioport_write(0x80, 1, ioport80_write, 1); | |
| 342 | + register_ioport_write(0x80, 1, 1, ioport80_write, NULL); | |
| 348 | 343 | |
| 349 | 344 | vga_initialize(ds, phys_ram_base + ram_size, ram_size, |
| 350 | 345 | vga_ram_size); |
| 351 | 346 | |
| 352 | 347 | rtc_init(0x70, 8); |
| 353 | - cmos_init(ram_size, boot_device); | |
| 354 | - register_ioport_read(0x61, 1, speaker_ioport_read, 1); | |
| 355 | - register_ioport_write(0x61, 1, speaker_ioport_write, 1); | |
| 348 | + register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL); | |
| 349 | + register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL); | |
| 356 | 350 | |
| 357 | 351 | pic_init(); |
| 358 | - pit_init(); | |
| 359 | - serial_init(0x3f8, 4); | |
| 360 | - ne2000_init(0x300, 9); | |
| 361 | - ide_init(); | |
| 352 | + pit_init(0x40); | |
| 353 | + | |
| 354 | + fd = serial_open_device(); | |
| 355 | + serial_init(0x3f8, 4, fd); | |
| 356 | + | |
| 357 | + nb_nics1 = nb_nics; | |
| 358 | + if (nb_nics1 > NE2000_NB_MAX) | |
| 359 | + nb_nics1 = NE2000_NB_MAX; | |
| 360 | + for(i = 0; i < nb_nics1; i++) { | |
| 361 | + ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]); | |
| 362 | + } | |
| 363 | + | |
| 364 | + for(i = 0; i < 2; i++) { | |
| 365 | + ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i], | |
| 366 | + bs_table[2 * i], bs_table[2 * i + 1]); | |
| 367 | + } | |
| 362 | 368 | kbd_init(); |
| 363 | 369 | AUD_init(); |
| 364 | 370 | DMA_init(); |
| 365 | 371 | SB16_init(); |
| 366 | 372 | |
| 367 | - fdctrl_register((unsigned char **)fd_filename, snapshot, boot_device); | |
| 373 | + fdctrl_init(6, 2, 0, 0x3f0, fd_table); | |
| 374 | + | |
| 375 | + cmos_init(ram_size, boot_device); | |
| 368 | 376 | } | ... | ... |
hw/pckbd.c
| ... | ... | @@ -189,7 +189,7 @@ static void kbd_update_irq(KBDState *s) |
| 189 | 189 | |
| 190 | 190 | static void kbd_queue(KBDState *s, int b, int aux) |
| 191 | 191 | { |
| 192 | - KBDQueue *q = &kbd_state.queues[aux]; | |
| 192 | + KBDQueue *q = &s->queues[aux]; | |
| 193 | 193 | |
| 194 | 194 | #if defined(DEBUG_MOUSE) || defined(DEBUG_KBD) |
| 195 | 195 | if (aux) |
| ... | ... | @@ -214,9 +214,9 @@ void kbd_put_keycode(int keycode) |
| 214 | 214 | kbd_queue(s, keycode, 0); |
| 215 | 215 | } |
| 216 | 216 | |
| 217 | -static uint32_t kbd_read_status(CPUState *env, uint32_t addr) | |
| 217 | +static uint32_t kbd_read_status(void *opaque, uint32_t addr) | |
| 218 | 218 | { |
| 219 | - KBDState *s = &kbd_state; | |
| 219 | + KBDState *s = opaque; | |
| 220 | 220 | int val; |
| 221 | 221 | val = s->status; |
| 222 | 222 | #if defined(DEBUG_KBD) |
| ... | ... | @@ -225,9 +225,9 @@ static uint32_t kbd_read_status(CPUState *env, uint32_t addr) |
| 225 | 225 | return val; |
| 226 | 226 | } |
| 227 | 227 | |
| 228 | -static void kbd_write_command(CPUState *env, uint32_t addr, uint32_t val) | |
| 228 | +static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val) | |
| 229 | 229 | { |
| 230 | - KBDState *s = &kbd_state; | |
| 230 | + KBDState *s = opaque; | |
| 231 | 231 | |
| 232 | 232 | #ifdef DEBUG_KBD |
| 233 | 233 | printf("kbd: write cmd=0x%02x\n", val); |
| ... | ... | @@ -285,10 +285,10 @@ static void kbd_write_command(CPUState *env, uint32_t addr, uint32_t val) |
| 285 | 285 | break; |
| 286 | 286 | #ifdef TARGET_I386 |
| 287 | 287 | case KBD_CCMD_ENABLE_A20: |
| 288 | - cpu_x86_set_a20(env, 1); | |
| 288 | + cpu_x86_set_a20(cpu_single_env, 1); | |
| 289 | 289 | break; |
| 290 | 290 | case KBD_CCMD_DISABLE_A20: |
| 291 | - cpu_x86_set_a20(env, 0); | |
| 291 | + cpu_x86_set_a20(cpu_single_env, 0); | |
| 292 | 292 | break; |
| 293 | 293 | #endif |
| 294 | 294 | case KBD_CCMD_RESET: |
| ... | ... | @@ -304,9 +304,9 @@ static void kbd_write_command(CPUState *env, uint32_t addr, uint32_t val) |
| 304 | 304 | } |
| 305 | 305 | } |
| 306 | 306 | |
| 307 | -static uint32_t kbd_read_data(CPUState *env, uint32_t addr) | |
| 307 | +static uint32_t kbd_read_data(void *opaque, uint32_t addr) | |
| 308 | 308 | { |
| 309 | - KBDState *s = &kbd_state; | |
| 309 | + KBDState *s = opaque; | |
| 310 | 310 | KBDQueue *q; |
| 311 | 311 | int val, index; |
| 312 | 312 | |
| ... | ... | @@ -605,9 +605,9 @@ static void kbd_write_mouse(KBDState *s, int val) |
| 605 | 605 | } |
| 606 | 606 | } |
| 607 | 607 | |
| 608 | -void kbd_write_data(CPUState *env, uint32_t addr, uint32_t val) | |
| 608 | +void kbd_write_data(void *opaque, uint32_t addr, uint32_t val) | |
| 609 | 609 | { |
| 610 | - KBDState *s = &kbd_state; | |
| 610 | + KBDState *s = opaque; | |
| 611 | 611 | |
| 612 | 612 | #ifdef DEBUG_KBD |
| 613 | 613 | printf("kbd: write data=0x%02x\n", val); |
| ... | ... | @@ -629,7 +629,7 @@ void kbd_write_data(CPUState *env, uint32_t addr, uint32_t val) |
| 629 | 629 | break; |
| 630 | 630 | case KBD_CCMD_WRITE_OUTPORT: |
| 631 | 631 | #ifdef TARGET_I386 |
| 632 | - cpu_x86_set_a20(env, (val >> 1) & 1); | |
| 632 | + cpu_x86_set_a20(cpu_single_env, (val >> 1) & 1); | |
| 633 | 633 | #endif |
| 634 | 634 | if (!(val & 1)) { |
| 635 | 635 | reset_requested = 1; |
| ... | ... | @@ -664,9 +664,11 @@ void kbd_reset(KBDState *s) |
| 664 | 664 | |
| 665 | 665 | void kbd_init(void) |
| 666 | 666 | { |
| 667 | - kbd_reset(&kbd_state); | |
| 668 | - register_ioport_read(0x60, 1, kbd_read_data, 1); | |
| 669 | - register_ioport_write(0x60, 1, kbd_write_data, 1); | |
| 670 | - register_ioport_read(0x64, 1, kbd_read_status, 1); | |
| 671 | - register_ioport_write(0x64, 1, kbd_write_command, 1); | |
| 667 | + KBDState *s = &kbd_state; | |
| 668 | + | |
| 669 | + kbd_reset(s); | |
| 670 | + register_ioport_read(0x60, 1, 1, kbd_read_data, s); | |
| 671 | + register_ioport_write(0x60, 1, 1, kbd_write_data, s); | |
| 672 | + register_ioport_read(0x64, 1, 1, kbd_read_status, s); | |
| 673 | + register_ioport_write(0x64, 1, 1, kbd_write_command, s); | |
| 672 | 674 | } | ... | ... |
hw/serial.c
| ... | ... | @@ -90,7 +90,7 @@ |
| 90 | 90 | #define UART_LSR_OE 0x02 /* Overrun error indicator */ |
| 91 | 91 | #define UART_LSR_DR 0x01 /* Receiver data ready */ |
| 92 | 92 | |
| 93 | -typedef struct SerialState { | |
| 93 | +struct SerialState { | |
| 94 | 94 | uint8_t divider; |
| 95 | 95 | uint8_t rbr; /* receive register */ |
| 96 | 96 | uint8_t ier; |
| ... | ... | @@ -104,14 +104,11 @@ typedef struct SerialState { |
| 104 | 104 | it can be reset while reading iir */ |
| 105 | 105 | int thr_ipending; |
| 106 | 106 | int irq; |
| 107 | -} SerialState; | |
| 107 | + int out_fd; | |
| 108 | +}; | |
| 108 | 109 | |
| 109 | -SerialState serial_ports[1]; | |
| 110 | - | |
| 111 | -void serial_update_irq(void) | |
| 110 | +static void serial_update_irq(SerialState *s) | |
| 112 | 111 | { |
| 113 | - SerialState *s = &serial_ports[0]; | |
| 114 | - | |
| 115 | 112 | if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) { |
| 116 | 113 | s->iir = UART_IIR_RDI; |
| 117 | 114 | } else if (s->thr_ipending && (s->ier & UART_IER_THRI)) { |
| ... | ... | @@ -126,9 +123,9 @@ void serial_update_irq(void) |
| 126 | 123 | } |
| 127 | 124 | } |
| 128 | 125 | |
| 129 | -void serial_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | |
| 126 | +static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val) | |
| 130 | 127 | { |
| 131 | - SerialState *s = &serial_ports[0]; | |
| 128 | + SerialState *s = opaque; | |
| 132 | 129 | unsigned char ch; |
| 133 | 130 | int ret; |
| 134 | 131 | |
| ... | ... | @@ -144,16 +141,16 @@ void serial_ioport_write(CPUState *env, uint32_t addr, uint32_t val) |
| 144 | 141 | } else { |
| 145 | 142 | s->thr_ipending = 0; |
| 146 | 143 | s->lsr &= ~UART_LSR_THRE; |
| 147 | - serial_update_irq(); | |
| 144 | + serial_update_irq(s); | |
| 148 | 145 | |
| 149 | 146 | ch = val; |
| 150 | 147 | do { |
| 151 | - ret = write(1, &ch, 1); | |
| 148 | + ret = write(s->out_fd, &ch, 1); | |
| 152 | 149 | } while (ret != 1); |
| 153 | 150 | s->thr_ipending = 1; |
| 154 | 151 | s->lsr |= UART_LSR_THRE; |
| 155 | 152 | s->lsr |= UART_LSR_TEMT; |
| 156 | - serial_update_irq(); | |
| 153 | + serial_update_irq(s); | |
| 157 | 154 | } |
| 158 | 155 | break; |
| 159 | 156 | case 1: |
| ... | ... | @@ -161,7 +158,7 @@ void serial_ioport_write(CPUState *env, uint32_t addr, uint32_t val) |
| 161 | 158 | s->divider = (s->divider & 0x00ff) | (val << 8); |
| 162 | 159 | } else { |
| 163 | 160 | s->ier = val; |
| 164 | - serial_update_irq(); | |
| 161 | + serial_update_irq(s); | |
| 165 | 162 | } |
| 166 | 163 | break; |
| 167 | 164 | case 2: |
| ... | ... | @@ -183,9 +180,9 @@ void serial_ioport_write(CPUState *env, uint32_t addr, uint32_t val) |
| 183 | 180 | } |
| 184 | 181 | } |
| 185 | 182 | |
| 186 | -uint32_t serial_ioport_read(CPUState *env, uint32_t addr) | |
| 183 | +static uint32_t serial_ioport_read(void *opaque, uint32_t addr) | |
| 187 | 184 | { |
| 188 | - SerialState *s = &serial_ports[0]; | |
| 185 | + SerialState *s = opaque; | |
| 189 | 186 | uint32_t ret; |
| 190 | 187 | |
| 191 | 188 | addr &= 7; |
| ... | ... | @@ -197,7 +194,7 @@ uint32_t serial_ioport_read(CPUState *env, uint32_t addr) |
| 197 | 194 | } else { |
| 198 | 195 | ret = s->rbr; |
| 199 | 196 | s->lsr &= ~(UART_LSR_DR | UART_LSR_BI); |
| 200 | - serial_update_irq(); | |
| 197 | + serial_update_irq(s); | |
| 201 | 198 | } |
| 202 | 199 | break; |
| 203 | 200 | case 1: |
| ... | ... | @@ -212,7 +209,7 @@ uint32_t serial_ioport_read(CPUState *env, uint32_t addr) |
| 212 | 209 | /* reset THR pending bit */ |
| 213 | 210 | if ((ret & 0x7) == UART_IIR_THRI) |
| 214 | 211 | s->thr_ipending = 0; |
| 215 | - serial_update_irq(); | |
| 212 | + serial_update_irq(s); | |
| 216 | 213 | break; |
| 217 | 214 | case 3: |
| 218 | 215 | ret = s->lcr; |
| ... | ... | @@ -244,38 +241,58 @@ uint32_t serial_ioport_read(CPUState *env, uint32_t addr) |
| 244 | 241 | return ret; |
| 245 | 242 | } |
| 246 | 243 | |
| 247 | -int serial_can_receive(void) | |
| 244 | +int serial_can_receive(SerialState *s) | |
| 248 | 245 | { |
| 249 | - SerialState *s = &serial_ports[0]; | |
| 250 | 246 | return !(s->lsr & UART_LSR_DR); |
| 251 | 247 | } |
| 252 | 248 | |
| 253 | -void serial_receive_byte(int ch) | |
| 249 | +void serial_receive_byte(SerialState *s, int ch) | |
| 254 | 250 | { |
| 255 | - SerialState *s = &serial_ports[0]; | |
| 256 | - | |
| 257 | 251 | s->rbr = ch; |
| 258 | 252 | s->lsr |= UART_LSR_DR; |
| 259 | - serial_update_irq(); | |
| 253 | + serial_update_irq(s); | |
| 260 | 254 | } |
| 261 | 255 | |
| 262 | -void serial_receive_break(void) | |
| 256 | +void serial_receive_break(SerialState *s) | |
| 263 | 257 | { |
| 264 | - SerialState *s = &serial_ports[0]; | |
| 265 | - | |
| 266 | 258 | s->rbr = 0; |
| 267 | 259 | s->lsr |= UART_LSR_BI | UART_LSR_DR; |
| 268 | - serial_update_irq(); | |
| 260 | + serial_update_irq(s); | |
| 269 | 261 | } |
| 270 | 262 | |
| 271 | -void serial_init(int base, int irq) | |
| 263 | +static int serial_can_receive1(void *opaque) | |
| 272 | 264 | { |
| 273 | - SerialState *s = &serial_ports[0]; | |
| 265 | + SerialState *s = opaque; | |
| 266 | + return serial_can_receive(s); | |
| 267 | +} | |
| 268 | + | |
| 269 | +static void serial_receive1(void *opaque, const uint8_t *buf, int size) | |
| 270 | +{ | |
| 271 | + SerialState *s = opaque; | |
| 272 | + serial_receive_byte(s, buf[0]); | |
| 273 | +} | |
| 274 | 274 | |
| 275 | +/* If fd is zero, it means that the serial device uses the console */ | |
| 276 | +SerialState *serial_init(int base, int irq, int fd) | |
| 277 | +{ | |
| 278 | + SerialState *s; | |
| 279 | + | |
| 280 | + s = qemu_mallocz(sizeof(SerialState)); | |
| 281 | + if (!s) | |
| 282 | + return NULL; | |
| 275 | 283 | s->irq = irq; |
| 276 | 284 | s->lsr = UART_LSR_TEMT | UART_LSR_THRE; |
| 277 | 285 | s->iir = UART_IIR_NO_INT; |
| 278 | - | |
| 279 | - register_ioport_write(base, 8, serial_ioport_write, 1); | |
| 280 | - register_ioport_read(base, 8, serial_ioport_read, 1); | |
| 286 | + | |
| 287 | + register_ioport_write(base, 8, 1, serial_ioport_write, s); | |
| 288 | + register_ioport_read(base, 8, 1, serial_ioport_read, s); | |
| 289 | + | |
| 290 | + if (fd != 0) { | |
| 291 | + add_fd_read_handler(fd, serial_can_receive1, serial_receive1, s); | |
| 292 | + s->out_fd = fd; | |
| 293 | + } else { | |
| 294 | + serial_console = s; | |
| 295 | + s->out_fd = 1; | |
| 296 | + } | |
| 297 | + return s; | |
| 281 | 298 | } | ... | ... |