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 | } | ... | ... |