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,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 | int channel, access; | 206 | int channel, access; |
| 207 | PITChannelState *s; | 207 | PITChannelState *s; |
| @@ -246,7 +246,7 @@ void pit_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | @@ -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 | int ret, count; | 251 | int ret, count; |
| 252 | PITChannelState *s; | 252 | PITChannelState *s; |
| @@ -279,7 +279,7 @@ uint32_t pit_ioport_read(CPUState *env, uint32_t addr) | @@ -279,7 +279,7 @@ uint32_t pit_ioport_read(CPUState *env, uint32_t addr) | ||
| 279 | return ret; | 279 | return ret; |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | -void pit_init(void) | 282 | +void pit_init(int base) |
| 283 | { | 283 | { |
| 284 | PITChannelState *s; | 284 | PITChannelState *s; |
| 285 | int i; | 285 | int i; |
| @@ -291,7 +291,7 @@ void pit_init(void) | @@ -291,7 +291,7 @@ void pit_init(void) | ||
| 291 | pit_load_count(s, 0); | 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,6 +46,8 @@ | ||
| 46 | /* debug PIC */ | 46 | /* debug PIC */ |
| 47 | //#define DEBUG_PIC | 47 | //#define DEBUG_PIC |
| 48 | 48 | ||
| 49 | +//#define DEBUG_IRQ_LATENCY | ||
| 50 | + | ||
| 49 | typedef struct PicState { | 51 | typedef struct PicState { |
| 50 | uint8_t last_irr; /* edge detection */ | 52 | uint8_t last_irr; /* edge detection */ |
| 51 | uint8_t irr; /* interrupt request register */ | 53 | uint8_t irr; /* interrupt request register */ |
| @@ -220,15 +222,14 @@ int cpu_x86_get_pic_interrupt(CPUState *env) | @@ -220,15 +222,14 @@ int cpu_x86_get_pic_interrupt(CPUState *env) | ||
| 220 | return intno; | 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 | int priority, cmd, irq; | 228 | int priority, cmd, irq; |
| 227 | 229 | ||
| 228 | #ifdef DEBUG_PIC | 230 | #ifdef DEBUG_PIC |
| 229 | printf("pic_write: addr=0x%02x val=0x%02x\n", addr, val); | 231 | printf("pic_write: addr=0x%02x val=0x%02x\n", addr, val); |
| 230 | #endif | 232 | #endif |
| 231 | - s = &pics[addr >> 7]; | ||
| 232 | addr &= 1; | 233 | addr &= 1; |
| 233 | if (addr == 0) { | 234 | if (addr == 0) { |
| 234 | if (val & 0x10) { | 235 | if (val & 0x10) { |
| @@ -334,14 +335,13 @@ static uint32_t pic_poll_read (PicState *s, uint32_t addr1) | @@ -334,14 +335,13 @@ static uint32_t pic_poll_read (PicState *s, uint32_t addr1) | ||
| 334 | return ret; | 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 | unsigned int addr; | 341 | unsigned int addr; |
| 341 | int ret; | 342 | int ret; |
| 342 | 343 | ||
| 343 | addr = addr1; | 344 | addr = addr1; |
| 344 | - s = &pics[addr >> 7]; | ||
| 345 | addr &= 1; | 345 | addr &= 1; |
| 346 | if (s->poll) { | 346 | if (s->poll) { |
| 347 | ret = pic_poll_read(s, addr1); | 347 | ret = pic_poll_read(s, addr1); |
| @@ -378,11 +378,9 @@ uint32_t pic_intack_read(CPUState *env) | @@ -378,11 +378,9 @@ uint32_t pic_intack_read(CPUState *env) | ||
| 378 | 378 | ||
| 379 | void pic_init(void) | 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,9 +69,9 @@ | ||
| 69 | 69 | ||
| 70 | RTCState rtc_state; | 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 | if ((addr & 1) == 0) { | 76 | if ((addr & 1) == 0) { |
| 77 | s->cmos_index = data & 0x7f; | 77 | s->cmos_index = data & 0x7f; |
| @@ -134,9 +134,9 @@ static void cmos_update_time(RTCState *s) | @@ -134,9 +134,9 @@ static void cmos_update_time(RTCState *s) | ||
| 134 | s->cmos_data[REG_IBM_PS2_CENTURY_BYTE] = s->cmos_data[REG_IBM_CENTURY_BYTE]; | 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 | int ret; | 140 | int ret; |
| 141 | if ((addr & 1) == 0) { | 141 | if ((addr & 1) == 0) { |
| 142 | return 0xff; | 142 | return 0xff; |
| @@ -197,7 +197,7 @@ void rtc_init(int base, int irq) | @@ -197,7 +197,7 @@ void rtc_init(int base, int irq) | ||
| 197 | s->cmos_data[RTC_REG_C] = 0x00; | 197 | s->cmos_data[RTC_REG_C] = 0x00; |
| 198 | s->cmos_data[RTC_REG_D] = 0x80; | 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,8 +46,7 @@ | ||
| 46 | /* debug NE2000 card */ | 46 | /* debug NE2000 card */ |
| 47 | //#define DEBUG_NE2000 | 47 | //#define DEBUG_NE2000 |
| 48 | 48 | ||
| 49 | -/***********************************************************/ | ||
| 50 | -/* ne2000 emulation */ | 49 | +#define MAX_ETH_FRAME_SIZE 1514 |
| 51 | 50 | ||
| 52 | #define E8390_CMD 0x00 /* The command register (for all pages) */ | 51 | #define E8390_CMD 0x00 /* The command register (for all pages) */ |
| 53 | /* Page 0 register offsets. */ | 52 | /* Page 0 register offsets. */ |
| @@ -143,23 +142,16 @@ typedef struct NE2000State { | @@ -143,23 +142,16 @@ typedef struct NE2000State { | ||
| 143 | uint8_t curpag; | 142 | uint8_t curpag; |
| 144 | uint8_t mult[8]; /* multicast mask array */ | 143 | uint8_t mult[8]; /* multicast mask array */ |
| 145 | int irq; | 144 | int irq; |
| 145 | + NetDriverState *nd; | ||
| 146 | uint8_t mem[NE2000_MEM_SIZE]; | 146 | uint8_t mem[NE2000_MEM_SIZE]; |
| 147 | } NE2000State; | 147 | } NE2000State; |
| 148 | 148 | ||
| 149 | -static NE2000State ne2000_state; | ||
| 150 | -int net_fd = -1; | ||
| 151 | - | ||
| 152 | static void ne2000_reset(NE2000State *s) | 149 | static void ne2000_reset(NE2000State *s) |
| 153 | { | 150 | { |
| 154 | int i; | 151 | int i; |
| 155 | 152 | ||
| 156 | s->isr = ENISR_RESET; | 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 | s->mem[14] = 0x57; | 155 | s->mem[14] = 0x57; |
| 164 | s->mem[15] = 0x57; | 156 | s->mem[15] = 0x57; |
| 165 | 157 | ||
| @@ -180,10 +172,10 @@ static void ne2000_update_irq(NE2000State *s) | @@ -180,10 +172,10 @@ static void ne2000_update_irq(NE2000State *s) | ||
| 180 | pic_set_irq(s->irq, 0); | 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 | int avail, index, boundary; | 179 | int avail, index, boundary; |
| 188 | 180 | ||
| 189 | if (s->cmd & E8390_STOP) | 181 | if (s->cmd & E8390_STOP) |
| @@ -196,19 +188,30 @@ int ne2000_can_receive(void) | @@ -196,19 +188,30 @@ int ne2000_can_receive(void) | ||
| 196 | avail = (s->stop - s->start) - (index - boundary); | 188 | avail = (s->stop - s->start) - (index - boundary); |
| 197 | if (avail < (MAX_ETH_FRAME_SIZE + 4)) | 189 | if (avail < (MAX_ETH_FRAME_SIZE + 4)) |
| 198 | return 0; | 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 | uint8_t *p; | 199 | uint8_t *p; |
| 206 | int total_len, next, avail, len, index; | 200 | int total_len, next, avail, len, index; |
| 207 | - | 201 | + uint8_t buf1[60]; |
| 202 | + | ||
| 208 | #if defined(DEBUG_NE2000) | 203 | #if defined(DEBUG_NE2000) |
| 209 | printf("NE2000: received len=%d\n", size); | 204 | printf("NE2000: received len=%d\n", size); |
| 210 | #endif | 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 | index = s->curpag << 8; | 215 | index = s->curpag << 8; |
| 213 | /* 4 bytes for header */ | 216 | /* 4 bytes for header */ |
| 214 | total_len = size + 4; | 217 | total_len = size + 4; |
| @@ -244,9 +247,9 @@ void ne2000_receive(uint8_t *buf, int size) | @@ -244,9 +247,9 @@ void ne2000_receive(uint8_t *buf, int size) | ||
| 244 | ne2000_update_irq(s); | 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 | int offset, page; | 253 | int offset, page; |
| 251 | 254 | ||
| 252 | addr &= 0xf; | 255 | addr &= 0xf; |
| @@ -264,7 +267,7 @@ static void ne2000_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | @@ -264,7 +267,7 @@ static void ne2000_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | ||
| 264 | ne2000_update_irq(s); | 267 | ne2000_update_irq(s); |
| 265 | } | 268 | } |
| 266 | if (val & E8390_TRANS) { | 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 | /* signal end of transfert */ | 271 | /* signal end of transfert */ |
| 269 | s->tsr = ENTSR_PTX; | 272 | s->tsr = ENTSR_PTX; |
| 270 | s->isr |= ENISR_TX; | 273 | s->isr |= ENISR_TX; |
| @@ -329,9 +332,9 @@ static void ne2000_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | @@ -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 | int offset, page, ret; | 338 | int offset, page, ret; |
| 336 | 339 | ||
| 337 | addr &= 0xf; | 340 | addr &= 0xf; |
| @@ -370,9 +373,9 @@ static uint32_t ne2000_ioport_read(CPUState *env, uint32_t addr) | @@ -370,9 +373,9 @@ static uint32_t ne2000_ioport_read(CPUState *env, uint32_t addr) | ||
| 370 | return ret; | 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 | uint8_t *p; | 379 | uint8_t *p; |
| 377 | 380 | ||
| 378 | #ifdef DEBUG_NE2000 | 381 | #ifdef DEBUG_NE2000 |
| @@ -401,9 +404,9 @@ static void ne2000_asic_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | @@ -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 | uint8_t *p; | 410 | uint8_t *p; |
| 408 | int ret; | 411 | int ret; |
| 409 | 412 | ||
| @@ -433,33 +436,40 @@ static uint32_t ne2000_asic_ioport_read(CPUState *env, uint32_t addr) | @@ -433,33 +436,40 @@ static uint32_t ne2000_asic_ioport_read(CPUState *env, uint32_t addr) | ||
| 433 | return ret; | 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 | /* nothing to do (end of reset pulse) */ | 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 | ne2000_reset(s); | 447 | ne2000_reset(s); |
| 445 | return 0; | 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 | s->irq = irq; | 469 | s->irq = irq; |
| 470 | + s->nd = nd; | ||
| 463 | 471 | ||
| 464 | ne2000_reset(s); | 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,6 +43,9 @@ | ||
| 43 | #include "cpu.h" | 43 | #include "cpu.h" |
| 44 | #include "vl.h" | 44 | #include "vl.h" |
| 45 | 45 | ||
| 46 | +/* output Bochs bios info messages */ | ||
| 47 | +//#define DEBUG_BIOS | ||
| 48 | + | ||
| 46 | #define BIOS_FILENAME "bios.bin" | 49 | #define BIOS_FILENAME "bios.bin" |
| 47 | #define VGABIOS_FILENAME "vgabios.bin" | 50 | #define VGABIOS_FILENAME "vgabios.bin" |
| 48 | #define LINUX_BOOT_FILENAME "linux_boot.bin" | 51 | #define LINUX_BOOT_FILENAME "linux_boot.bin" |
| @@ -55,7 +58,7 @@ | @@ -55,7 +58,7 @@ | ||
| 55 | int speaker_data_on; | 58 | int speaker_data_on; |
| 56 | int dummy_refresh_clock; | 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,6 +68,7 @@ static void cmos_init(int ram_size, int boot_device) | ||
| 65 | { | 68 | { |
| 66 | RTCState *s = &rtc_state; | 69 | RTCState *s = &rtc_state; |
| 67 | int val; | 70 | int val; |
| 71 | + int fd0, fd1, nb; | ||
| 68 | 72 | ||
| 69 | /* various important CMOS locations needed by PC/Bochs bios */ | 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,12 +103,11 @@ static void cmos_init(int ram_size, int boot_device) | ||
| 99 | s->cmos_data[0x3d] = 0x03; /* CD-ROM boot */ | 103 | s->cmos_data[0x3d] = 0x03; /* CD-ROM boot */ |
| 100 | break; | 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 | s->cmos_data[0x10] = 0; | 112 | s->cmos_data[0x10] = 0; |
| 110 | switch (fd0) { | 113 | switch (fd0) { |
| @@ -135,6 +138,7 @@ void cmos_register_fd (uint8_t fd0, uint8_t fd1) | @@ -135,6 +138,7 @@ void cmos_register_fd (uint8_t fd0, uint8_t fd1) | ||
| 135 | s->cmos_data[0x10] |= 0x02; | 138 | s->cmos_data[0x10] |= 0x02; |
| 136 | break; | 139 | break; |
| 137 | } | 140 | } |
| 141 | + nb = 0; | ||
| 138 | if (fd0 < 3) | 142 | if (fd0 < 3) |
| 139 | nb++; | 143 | nb++; |
| 140 | if (fd1 < 3) | 144 | if (fd1 < 3) |
| @@ -151,13 +155,13 @@ void cmos_register_fd (uint8_t fd0, uint8_t fd1) | @@ -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 | speaker_data_on = (val >> 1) & 1; | 160 | speaker_data_on = (val >> 1) & 1; |
| 157 | pit_set_gate(&pit_channels[2], val & 1); | 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 | int out; | 166 | int out; |
| 163 | out = pit_get_out(&pit_channels[2]); | 167 | out = pit_get_out(&pit_channels[2]); |
| @@ -167,27 +171,9 @@ uint32_t speaker_ioport_read(CPUState *env, uint32_t addr) | @@ -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 | /* Bochs BIOS debug ports */ | 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 | switch(addr) { | 178 | switch(addr) { |
| 193 | /* Bochs BIOS messages */ | 179 | /* Bochs BIOS messages */ |
| @@ -218,15 +204,15 @@ void bochs_bios_write(CPUX86State *env, uint32_t addr, uint32_t val) | @@ -218,15 +204,15 @@ void bochs_bios_write(CPUX86State *env, uint32_t addr, uint32_t val) | ||
| 218 | 204 | ||
| 219 | void bochs_bios_init(void) | 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,6 +247,15 @@ int load_kernel(const char *filename, uint8_t *addr, | ||
| 261 | return -1; | 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 | /* PC hardware initialisation */ | 259 | /* PC hardware initialisation */ |
| 265 | void pc_init(int ram_size, int vga_ram_size, int boot_device, | 260 | void pc_init(int ram_size, int vga_ram_size, int boot_device, |
| 266 | DisplayState *ds, const char **fd_filename, int snapshot, | 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,7 +263,7 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device, | ||
| 268 | const char *initrd_filename) | 263 | const char *initrd_filename) |
| 269 | { | 264 | { |
| 270 | char buf[1024]; | 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 | linux_boot = (kernel_filename != NULL); | 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,25 +339,38 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device, | ||
| 344 | } | 339 | } |
| 345 | 340 | ||
| 346 | /* init basic PC hardware */ | 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 | vga_initialize(ds, phys_ram_base + ram_size, ram_size, | 344 | vga_initialize(ds, phys_ram_base + ram_size, ram_size, |
| 350 | vga_ram_size); | 345 | vga_ram_size); |
| 351 | 346 | ||
| 352 | rtc_init(0x70, 8); | 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 | pic_init(); | 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 | kbd_init(); | 368 | kbd_init(); |
| 363 | AUD_init(); | 369 | AUD_init(); |
| 364 | DMA_init(); | 370 | DMA_init(); |
| 365 | SB16_init(); | 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,7 +189,7 @@ static void kbd_update_irq(KBDState *s) | ||
| 189 | 189 | ||
| 190 | static void kbd_queue(KBDState *s, int b, int aux) | 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 | #if defined(DEBUG_MOUSE) || defined(DEBUG_KBD) | 194 | #if defined(DEBUG_MOUSE) || defined(DEBUG_KBD) |
| 195 | if (aux) | 195 | if (aux) |
| @@ -214,9 +214,9 @@ void kbd_put_keycode(int keycode) | @@ -214,9 +214,9 @@ void kbd_put_keycode(int keycode) | ||
| 214 | kbd_queue(s, keycode, 0); | 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 | int val; | 220 | int val; |
| 221 | val = s->status; | 221 | val = s->status; |
| 222 | #if defined(DEBUG_KBD) | 222 | #if defined(DEBUG_KBD) |
| @@ -225,9 +225,9 @@ static uint32_t kbd_read_status(CPUState *env, uint32_t addr) | @@ -225,9 +225,9 @@ static uint32_t kbd_read_status(CPUState *env, uint32_t addr) | ||
| 225 | return val; | 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 | #ifdef DEBUG_KBD | 232 | #ifdef DEBUG_KBD |
| 233 | printf("kbd: write cmd=0x%02x\n", val); | 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,10 +285,10 @@ static void kbd_write_command(CPUState *env, uint32_t addr, uint32_t val) | ||
| 285 | break; | 285 | break; |
| 286 | #ifdef TARGET_I386 | 286 | #ifdef TARGET_I386 |
| 287 | case KBD_CCMD_ENABLE_A20: | 287 | case KBD_CCMD_ENABLE_A20: |
| 288 | - cpu_x86_set_a20(env, 1); | 288 | + cpu_x86_set_a20(cpu_single_env, 1); |
| 289 | break; | 289 | break; |
| 290 | case KBD_CCMD_DISABLE_A20: | 290 | case KBD_CCMD_DISABLE_A20: |
| 291 | - cpu_x86_set_a20(env, 0); | 291 | + cpu_x86_set_a20(cpu_single_env, 0); |
| 292 | break; | 292 | break; |
| 293 | #endif | 293 | #endif |
| 294 | case KBD_CCMD_RESET: | 294 | case KBD_CCMD_RESET: |
| @@ -304,9 +304,9 @@ static void kbd_write_command(CPUState *env, uint32_t addr, uint32_t val) | @@ -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 | KBDQueue *q; | 310 | KBDQueue *q; |
| 311 | int val, index; | 311 | int val, index; |
| 312 | 312 | ||
| @@ -605,9 +605,9 @@ static void kbd_write_mouse(KBDState *s, int val) | @@ -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 | #ifdef DEBUG_KBD | 612 | #ifdef DEBUG_KBD |
| 613 | printf("kbd: write data=0x%02x\n", val); | 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,7 +629,7 @@ void kbd_write_data(CPUState *env, uint32_t addr, uint32_t val) | ||
| 629 | break; | 629 | break; |
| 630 | case KBD_CCMD_WRITE_OUTPORT: | 630 | case KBD_CCMD_WRITE_OUTPORT: |
| 631 | #ifdef TARGET_I386 | 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 | #endif | 633 | #endif |
| 634 | if (!(val & 1)) { | 634 | if (!(val & 1)) { |
| 635 | reset_requested = 1; | 635 | reset_requested = 1; |
| @@ -664,9 +664,11 @@ void kbd_reset(KBDState *s) | @@ -664,9 +664,11 @@ void kbd_reset(KBDState *s) | ||
| 664 | 664 | ||
| 665 | void kbd_init(void) | 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,7 +90,7 @@ | ||
| 90 | #define UART_LSR_OE 0x02 /* Overrun error indicator */ | 90 | #define UART_LSR_OE 0x02 /* Overrun error indicator */ |
| 91 | #define UART_LSR_DR 0x01 /* Receiver data ready */ | 91 | #define UART_LSR_DR 0x01 /* Receiver data ready */ |
| 92 | 92 | ||
| 93 | -typedef struct SerialState { | 93 | +struct SerialState { |
| 94 | uint8_t divider; | 94 | uint8_t divider; |
| 95 | uint8_t rbr; /* receive register */ | 95 | uint8_t rbr; /* receive register */ |
| 96 | uint8_t ier; | 96 | uint8_t ier; |
| @@ -104,14 +104,11 @@ typedef struct SerialState { | @@ -104,14 +104,11 @@ typedef struct SerialState { | ||
| 104 | it can be reset while reading iir */ | 104 | it can be reset while reading iir */ |
| 105 | int thr_ipending; | 105 | int thr_ipending; |
| 106 | int irq; | 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 | if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) { | 112 | if ((s->lsr & UART_LSR_DR) && (s->ier & UART_IER_RDI)) { |
| 116 | s->iir = UART_IIR_RDI; | 113 | s->iir = UART_IIR_RDI; |
| 117 | } else if (s->thr_ipending && (s->ier & UART_IER_THRI)) { | 114 | } else if (s->thr_ipending && (s->ier & UART_IER_THRI)) { |
| @@ -126,9 +123,9 @@ void serial_update_irq(void) | @@ -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 | unsigned char ch; | 129 | unsigned char ch; |
| 133 | int ret; | 130 | int ret; |
| 134 | 131 | ||
| @@ -144,16 +141,16 @@ void serial_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | @@ -144,16 +141,16 @@ void serial_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | ||
| 144 | } else { | 141 | } else { |
| 145 | s->thr_ipending = 0; | 142 | s->thr_ipending = 0; |
| 146 | s->lsr &= ~UART_LSR_THRE; | 143 | s->lsr &= ~UART_LSR_THRE; |
| 147 | - serial_update_irq(); | 144 | + serial_update_irq(s); |
| 148 | 145 | ||
| 149 | ch = val; | 146 | ch = val; |
| 150 | do { | 147 | do { |
| 151 | - ret = write(1, &ch, 1); | 148 | + ret = write(s->out_fd, &ch, 1); |
| 152 | } while (ret != 1); | 149 | } while (ret != 1); |
| 153 | s->thr_ipending = 1; | 150 | s->thr_ipending = 1; |
| 154 | s->lsr |= UART_LSR_THRE; | 151 | s->lsr |= UART_LSR_THRE; |
| 155 | s->lsr |= UART_LSR_TEMT; | 152 | s->lsr |= UART_LSR_TEMT; |
| 156 | - serial_update_irq(); | 153 | + serial_update_irq(s); |
| 157 | } | 154 | } |
| 158 | break; | 155 | break; |
| 159 | case 1: | 156 | case 1: |
| @@ -161,7 +158,7 @@ void serial_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | @@ -161,7 +158,7 @@ void serial_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | ||
| 161 | s->divider = (s->divider & 0x00ff) | (val << 8); | 158 | s->divider = (s->divider & 0x00ff) | (val << 8); |
| 162 | } else { | 159 | } else { |
| 163 | s->ier = val; | 160 | s->ier = val; |
| 164 | - serial_update_irq(); | 161 | + serial_update_irq(s); |
| 165 | } | 162 | } |
| 166 | break; | 163 | break; |
| 167 | case 2: | 164 | case 2: |
| @@ -183,9 +180,9 @@ void serial_ioport_write(CPUState *env, uint32_t addr, uint32_t val) | @@ -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 | uint32_t ret; | 186 | uint32_t ret; |
| 190 | 187 | ||
| 191 | addr &= 7; | 188 | addr &= 7; |
| @@ -197,7 +194,7 @@ uint32_t serial_ioport_read(CPUState *env, uint32_t addr) | @@ -197,7 +194,7 @@ uint32_t serial_ioport_read(CPUState *env, uint32_t addr) | ||
| 197 | } else { | 194 | } else { |
| 198 | ret = s->rbr; | 195 | ret = s->rbr; |
| 199 | s->lsr &= ~(UART_LSR_DR | UART_LSR_BI); | 196 | s->lsr &= ~(UART_LSR_DR | UART_LSR_BI); |
| 200 | - serial_update_irq(); | 197 | + serial_update_irq(s); |
| 201 | } | 198 | } |
| 202 | break; | 199 | break; |
| 203 | case 1: | 200 | case 1: |
| @@ -212,7 +209,7 @@ uint32_t serial_ioport_read(CPUState *env, uint32_t addr) | @@ -212,7 +209,7 @@ uint32_t serial_ioport_read(CPUState *env, uint32_t addr) | ||
| 212 | /* reset THR pending bit */ | 209 | /* reset THR pending bit */ |
| 213 | if ((ret & 0x7) == UART_IIR_THRI) | 210 | if ((ret & 0x7) == UART_IIR_THRI) |
| 214 | s->thr_ipending = 0; | 211 | s->thr_ipending = 0; |
| 215 | - serial_update_irq(); | 212 | + serial_update_irq(s); |
| 216 | break; | 213 | break; |
| 217 | case 3: | 214 | case 3: |
| 218 | ret = s->lcr; | 215 | ret = s->lcr; |
| @@ -244,38 +241,58 @@ uint32_t serial_ioport_read(CPUState *env, uint32_t addr) | @@ -244,38 +241,58 @@ uint32_t serial_ioport_read(CPUState *env, uint32_t addr) | ||
| 244 | return ret; | 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 | return !(s->lsr & UART_LSR_DR); | 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 | s->rbr = ch; | 251 | s->rbr = ch; |
| 258 | s->lsr |= UART_LSR_DR; | 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 | s->rbr = 0; | 258 | s->rbr = 0; |
| 267 | s->lsr |= UART_LSR_BI | UART_LSR_DR; | 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 | s->irq = irq; | 283 | s->irq = irq; |
| 276 | s->lsr = UART_LSR_TEMT | UART_LSR_THRE; | 284 | s->lsr = UART_LSR_TEMT | UART_LSR_THRE; |
| 277 | s->iir = UART_IIR_NO_INT; | 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 | } |