Commit 3de388f676e936097f99fb58e8a58c5461eb696e
1 parent
73133662
more generic i8259 support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1487 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
8 changed files
with
141 additions
and
77 deletions
Makefile.target
@@ -360,8 +360,8 @@ VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o | @@ -360,8 +360,8 @@ VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o | ||
360 | VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o | 360 | VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o |
361 | endif | 361 | endif |
362 | ifeq ($(TARGET_ARCH), mips) | 362 | ifeq ($(TARGET_ARCH), mips) |
363 | -VL_OBJS+= mips.o mips_r4k.o dma.o vga.o serial.o ne2000.o #ide.o pckbd.o | ||
364 | -VL_OBJS+= #i8259.o i8254.o fdc.o m48t59.o | 363 | +VL_OBJS+= mips_r4k.o dma.o vga.o serial.o ne2000.o i8259.o |
364 | +#VL_OBJS+= #ide.o pckbd.o i8254.o fdc.o m48t59.o | ||
365 | endif | 365 | endif |
366 | ifeq ($(TARGET_BASE_ARCH), sparc) | 366 | ifeq ($(TARGET_BASE_ARCH), sparc) |
367 | ifeq ($(TARGET_ARCH), sparc64) | 367 | ifeq ($(TARGET_ARCH), sparc64) |
hw/i8259.c
@@ -46,10 +46,16 @@ typedef struct PicState { | @@ -46,10 +46,16 @@ typedef struct PicState { | ||
46 | uint8_t init4; /* true if 4 byte init */ | 46 | uint8_t init4; /* true if 4 byte init */ |
47 | uint8_t elcr; /* PIIX edge/trigger selection*/ | 47 | uint8_t elcr; /* PIIX edge/trigger selection*/ |
48 | uint8_t elcr_mask; | 48 | uint8_t elcr_mask; |
49 | + PicState2 *pics_state; | ||
49 | } PicState; | 50 | } PicState; |
50 | 51 | ||
51 | -/* 0 is master pic, 1 is slave pic */ | ||
52 | -static PicState pics[2]; | 52 | +struct PicState2 { |
53 | + /* 0 is master pic, 1 is slave pic */ | ||
54 | + /* XXX: better separation between the two pics */ | ||
55 | + PicState pics[2]; | ||
56 | + IRQRequestFunc *irq_request; | ||
57 | + void *irq_request_opaque; | ||
58 | +}; | ||
53 | 59 | ||
54 | #if defined(DEBUG_PIC) || defined (DEBUG_IRQ_COUNT) | 60 | #if defined(DEBUG_PIC) || defined (DEBUG_IRQ_COUNT) |
55 | static int irq_level[16]; | 61 | static int irq_level[16]; |
@@ -110,7 +116,7 @@ static int pic_get_irq(PicState *s) | @@ -110,7 +116,7 @@ static int pic_get_irq(PicState *s) | ||
110 | master, the IRQ coming from the slave is not taken into account | 116 | master, the IRQ coming from the slave is not taken into account |
111 | for the priority computation. */ | 117 | for the priority computation. */ |
112 | mask = s->isr; | 118 | mask = s->isr; |
113 | - if (s->special_fully_nested_mode && s == &pics[0]) | 119 | + if (s->special_fully_nested_mode && s == &s->pics_state->pics[0]) |
114 | mask &= ~(1 << 2); | 120 | mask &= ~(1 << 2); |
115 | cur_priority = get_priority(s, mask); | 121 | cur_priority = get_priority(s, mask); |
116 | if (priority < cur_priority) { | 122 | if (priority < cur_priority) { |
@@ -123,32 +129,34 @@ static int pic_get_irq(PicState *s) | @@ -123,32 +129,34 @@ static int pic_get_irq(PicState *s) | ||
123 | 129 | ||
124 | /* raise irq to CPU if necessary. must be called every time the active | 130 | /* raise irq to CPU if necessary. must be called every time the active |
125 | irq may change */ | 131 | irq may change */ |
126 | -static void pic_update_irq(void) | 132 | +/* XXX: should not export it, but it is needed for an APIC kludge */ |
133 | +void pic_update_irq(PicState2 *s) | ||
127 | { | 134 | { |
128 | int irq2, irq; | 135 | int irq2, irq; |
129 | 136 | ||
130 | /* first look at slave pic */ | 137 | /* first look at slave pic */ |
131 | - irq2 = pic_get_irq(&pics[1]); | 138 | + irq2 = pic_get_irq(&s->pics[1]); |
132 | if (irq2 >= 0) { | 139 | if (irq2 >= 0) { |
133 | /* if irq request by slave pic, signal master PIC */ | 140 | /* if irq request by slave pic, signal master PIC */ |
134 | - pic_set_irq1(&pics[0], 2, 1); | ||
135 | - pic_set_irq1(&pics[0], 2, 0); | 141 | + pic_set_irq1(&s->pics[0], 2, 1); |
142 | + pic_set_irq1(&s->pics[0], 2, 0); | ||
136 | } | 143 | } |
137 | /* look at requested irq */ | 144 | /* look at requested irq */ |
138 | - irq = pic_get_irq(&pics[0]); | 145 | + irq = pic_get_irq(&s->pics[0]); |
139 | if (irq >= 0) { | 146 | if (irq >= 0) { |
140 | #if defined(DEBUG_PIC) | 147 | #if defined(DEBUG_PIC) |
141 | { | 148 | { |
142 | int i; | 149 | int i; |
143 | for(i = 0; i < 2; i++) { | 150 | for(i = 0; i < 2; i++) { |
144 | printf("pic%d: imr=%x irr=%x padd=%d\n", | 151 | printf("pic%d: imr=%x irr=%x padd=%d\n", |
145 | - i, pics[i].imr, pics[i].irr, pics[i].priority_add); | 152 | + i, s->pics[i].imr, s->pics[i].irr, |
153 | + s->pics[i].priority_add); | ||
146 | 154 | ||
147 | } | 155 | } |
148 | } | 156 | } |
149 | printf("pic: cpu_interrupt\n"); | 157 | printf("pic: cpu_interrupt\n"); |
150 | #endif | 158 | #endif |
151 | - cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); | 159 | + s->irq_request(s->irq_request_opaque, 1); |
152 | } | 160 | } |
153 | } | 161 | } |
154 | 162 | ||
@@ -156,8 +164,10 @@ static void pic_update_irq(void) | @@ -156,8 +164,10 @@ static void pic_update_irq(void) | ||
156 | int64_t irq_time[16]; | 164 | int64_t irq_time[16]; |
157 | #endif | 165 | #endif |
158 | 166 | ||
159 | -void pic_set_irq(int irq, int level) | 167 | +void pic_set_irq_new(void *opaque, int irq, int level) |
160 | { | 168 | { |
169 | + PicState2 *s = opaque; | ||
170 | + | ||
161 | #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT) | 171 | #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT) |
162 | if (level != irq_level[irq]) { | 172 | if (level != irq_level[irq]) { |
163 | #if defined(DEBUG_PIC) | 173 | #if defined(DEBUG_PIC) |
@@ -175,14 +185,14 @@ void pic_set_irq(int irq, int level) | @@ -175,14 +185,14 @@ void pic_set_irq(int irq, int level) | ||
175 | irq_time[irq] = qemu_get_clock(vm_clock); | 185 | irq_time[irq] = qemu_get_clock(vm_clock); |
176 | } | 186 | } |
177 | #endif | 187 | #endif |
178 | - pic_set_irq1(&pics[irq >> 3], irq & 7, level); | ||
179 | - pic_update_irq(); | 188 | + pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); |
189 | + pic_update_irq(s); | ||
180 | } | 190 | } |
181 | 191 | ||
182 | -/* this function should be used to have the controller context */ | ||
183 | -void pic_set_irq_new(void *opaque, int irq, int level) | 192 | +/* obsolete function */ |
193 | +void pic_set_irq(int irq, int level) | ||
184 | { | 194 | { |
185 | - pic_set_irq(irq, level); | 195 | + pic_set_irq_new(isa_pic, irq, level); |
186 | } | 196 | } |
187 | 197 | ||
188 | /* acknowledge interrupt 'irq' */ | 198 | /* acknowledge interrupt 'irq' */ |
@@ -199,43 +209,32 @@ static inline void pic_intack(PicState *s, int irq) | @@ -199,43 +209,32 @@ static inline void pic_intack(PicState *s, int irq) | ||
199 | s->irr &= ~(1 << irq); | 209 | s->irr &= ~(1 << irq); |
200 | } | 210 | } |
201 | 211 | ||
202 | -int cpu_get_pic_interrupt(CPUState *env) | 212 | +int pic_read_irq(PicState2 *s) |
203 | { | 213 | { |
204 | int irq, irq2, intno; | 214 | int irq, irq2, intno; |
205 | 215 | ||
206 | -#ifdef TARGET_X86_64 | ||
207 | - intno = apic_get_interrupt(env); | ||
208 | - if (intno >= 0) { | ||
209 | - /* set irq request if a PIC irq is still pending */ | ||
210 | - /* XXX: improve that */ | ||
211 | - pic_update_irq(); | ||
212 | - return intno; | ||
213 | - } | ||
214 | -#endif | ||
215 | - /* read the irq from the PIC */ | ||
216 | - | ||
217 | - irq = pic_get_irq(&pics[0]); | 216 | + irq = pic_get_irq(&s->pics[0]); |
218 | if (irq >= 0) { | 217 | if (irq >= 0) { |
219 | - pic_intack(&pics[0], irq); | 218 | + pic_intack(&s->pics[0], irq); |
220 | if (irq == 2) { | 219 | if (irq == 2) { |
221 | - irq2 = pic_get_irq(&pics[1]); | 220 | + irq2 = pic_get_irq(&s->pics[1]); |
222 | if (irq2 >= 0) { | 221 | if (irq2 >= 0) { |
223 | - pic_intack(&pics[1], irq2); | 222 | + pic_intack(&s->pics[1], irq2); |
224 | } else { | 223 | } else { |
225 | /* spurious IRQ on slave controller */ | 224 | /* spurious IRQ on slave controller */ |
226 | irq2 = 7; | 225 | irq2 = 7; |
227 | } | 226 | } |
228 | - intno = pics[1].irq_base + irq2; | 227 | + intno = s->pics[1].irq_base + irq2; |
229 | irq = irq2 + 8; | 228 | irq = irq2 + 8; |
230 | } else { | 229 | } else { |
231 | - intno = pics[0].irq_base + irq; | 230 | + intno = s->pics[0].irq_base + irq; |
232 | } | 231 | } |
233 | } else { | 232 | } else { |
234 | /* spurious IRQ on host controller */ | 233 | /* spurious IRQ on host controller */ |
235 | irq = 7; | 234 | irq = 7; |
236 | - intno = pics[0].irq_base + irq; | 235 | + intno = s->pics[0].irq_base + irq; |
237 | } | 236 | } |
238 | - pic_update_irq(); | 237 | + pic_update_irq(s); |
239 | 238 | ||
240 | #ifdef DEBUG_IRQ_LATENCY | 239 | #ifdef DEBUG_IRQ_LATENCY |
241 | printf("IRQ%d latency=%0.3fus\n", | 240 | printf("IRQ%d latency=%0.3fus\n", |
@@ -251,11 +250,22 @@ int cpu_get_pic_interrupt(CPUState *env) | @@ -251,11 +250,22 @@ int cpu_get_pic_interrupt(CPUState *env) | ||
251 | static void pic_reset(void *opaque) | 250 | static void pic_reset(void *opaque) |
252 | { | 251 | { |
253 | PicState *s = opaque; | 252 | PicState *s = opaque; |
254 | - int tmp; | ||
255 | 253 | ||
256 | - tmp = s->elcr_mask; | ||
257 | - memset(s, 0, sizeof(PicState)); | ||
258 | - s->elcr_mask = tmp; | 254 | + s->last_irr = 0; |
255 | + s->irr = 0; | ||
256 | + s->imr = 0; | ||
257 | + s->isr = 0; | ||
258 | + s->priority_add = 0; | ||
259 | + s->irq_base = 0; | ||
260 | + s->read_reg_select = 0; | ||
261 | + s->poll = 0; | ||
262 | + s->special_mask = 0; | ||
263 | + s->init_state = 0; | ||
264 | + s->auto_eoi = 0; | ||
265 | + s->rotate_on_auto_eoi = 0; | ||
266 | + s->special_fully_nested_mode = 0; | ||
267 | + s->init4 = 0; | ||
268 | + s->elcr = 0; | ||
259 | } | 269 | } |
260 | 270 | ||
261 | static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) | 271 | static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
@@ -272,8 +282,7 @@ static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -272,8 +282,7 @@ static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
272 | /* init */ | 282 | /* init */ |
273 | pic_reset(s); | 283 | pic_reset(s); |
274 | /* deassert a pending interrupt */ | 284 | /* deassert a pending interrupt */ |
275 | - cpu_reset_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); | ||
276 | - | 285 | + s->pics_state->irq_request(s->pics_state->irq_request_opaque, 0); |
277 | s->init_state = 1; | 286 | s->init_state = 1; |
278 | s->init4 = val & 1; | 287 | s->init4 = val & 1; |
279 | if (val & 0x02) | 288 | if (val & 0x02) |
@@ -302,23 +311,23 @@ static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -302,23 +311,23 @@ static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
302 | s->isr &= ~(1 << irq); | 311 | s->isr &= ~(1 << irq); |
303 | if (cmd == 5) | 312 | if (cmd == 5) |
304 | s->priority_add = (irq + 1) & 7; | 313 | s->priority_add = (irq + 1) & 7; |
305 | - pic_update_irq(); | 314 | + pic_update_irq(s->pics_state); |
306 | } | 315 | } |
307 | break; | 316 | break; |
308 | case 3: | 317 | case 3: |
309 | irq = val & 7; | 318 | irq = val & 7; |
310 | s->isr &= ~(1 << irq); | 319 | s->isr &= ~(1 << irq); |
311 | - pic_update_irq(); | 320 | + pic_update_irq(s->pics_state); |
312 | break; | 321 | break; |
313 | case 6: | 322 | case 6: |
314 | s->priority_add = (val + 1) & 7; | 323 | s->priority_add = (val + 1) & 7; |
315 | - pic_update_irq(); | 324 | + pic_update_irq(s->pics_state); |
316 | break; | 325 | break; |
317 | case 7: | 326 | case 7: |
318 | irq = val & 7; | 327 | irq = val & 7; |
319 | s->isr &= ~(1 << irq); | 328 | s->isr &= ~(1 << irq); |
320 | s->priority_add = (irq + 1) & 7; | 329 | s->priority_add = (irq + 1) & 7; |
321 | - pic_update_irq(); | 330 | + pic_update_irq(s->pics_state); |
322 | break; | 331 | break; |
323 | default: | 332 | default: |
324 | /* no operation */ | 333 | /* no operation */ |
@@ -330,7 +339,7 @@ static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) | @@ -330,7 +339,7 @@ static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) | ||
330 | case 0: | 339 | case 0: |
331 | /* normal mode */ | 340 | /* normal mode */ |
332 | s->imr = val; | 341 | s->imr = val; |
333 | - pic_update_irq(); | 342 | + pic_update_irq(s->pics_state); |
334 | break; | 343 | break; |
335 | case 1: | 344 | case 1: |
336 | s->irq_base = val & 0xf8; | 345 | s->irq_base = val & 0xf8; |
@@ -359,16 +368,16 @@ static uint32_t pic_poll_read (PicState *s, uint32_t addr1) | @@ -359,16 +368,16 @@ static uint32_t pic_poll_read (PicState *s, uint32_t addr1) | ||
359 | ret = pic_get_irq(s); | 368 | ret = pic_get_irq(s); |
360 | if (ret >= 0) { | 369 | if (ret >= 0) { |
361 | if (addr1 >> 7) { | 370 | if (addr1 >> 7) { |
362 | - pics[0].isr &= ~(1 << 2); | ||
363 | - pics[0].irr &= ~(1 << 2); | 371 | + s->pics_state->pics[0].isr &= ~(1 << 2); |
372 | + s->pics_state->pics[0].irr &= ~(1 << 2); | ||
364 | } | 373 | } |
365 | s->irr &= ~(1 << ret); | 374 | s->irr &= ~(1 << ret); |
366 | s->isr &= ~(1 << ret); | 375 | s->isr &= ~(1 << ret); |
367 | if (addr1 >> 7 || ret != 2) | 376 | if (addr1 >> 7 || ret != 2) |
368 | - pic_update_irq(); | 377 | + pic_update_irq(s->pics_state); |
369 | } else { | 378 | } else { |
370 | ret = 0x07; | 379 | ret = 0x07; |
371 | - pic_update_irq(); | 380 | + pic_update_irq(s->pics_state); |
372 | } | 381 | } |
373 | 382 | ||
374 | return ret; | 383 | return ret; |
@@ -402,15 +411,16 @@ static uint32_t pic_ioport_read(void *opaque, uint32_t addr1) | @@ -402,15 +411,16 @@ static uint32_t pic_ioport_read(void *opaque, uint32_t addr1) | ||
402 | } | 411 | } |
403 | 412 | ||
404 | /* memory mapped interrupt status */ | 413 | /* memory mapped interrupt status */ |
405 | -uint32_t pic_intack_read(CPUState *env) | 414 | +/* XXX: may be the same than pic_read_irq() */ |
415 | +uint32_t pic_intack_read(PicState2 *s) | ||
406 | { | 416 | { |
407 | int ret; | 417 | int ret; |
408 | 418 | ||
409 | - ret = pic_poll_read(&pics[0], 0x00); | 419 | + ret = pic_poll_read(&s->pics[0], 0x00); |
410 | if (ret == 2) | 420 | if (ret == 2) |
411 | - ret = pic_poll_read(&pics[1], 0x80) + 8; | 421 | + ret = pic_poll_read(&s->pics[1], 0x80) + 8; |
412 | /* Prepare for ISR read */ | 422 | /* Prepare for ISR read */ |
413 | - pics[0].read_reg_select = 1; | 423 | + s->pics[0].read_reg_select = 1; |
414 | 424 | ||
415 | return ret; | 425 | return ret; |
416 | } | 426 | } |
@@ -490,9 +500,12 @@ void pic_info(void) | @@ -490,9 +500,12 @@ void pic_info(void) | ||
490 | { | 500 | { |
491 | int i; | 501 | int i; |
492 | PicState *s; | 502 | PicState *s; |
503 | + | ||
504 | + if (!isa_pic) | ||
505 | + return; | ||
493 | 506 | ||
494 | for(i=0;i<2;i++) { | 507 | for(i=0;i<2;i++) { |
495 | - s = &pics[i]; | 508 | + s = &isa_pic->pics[i]; |
496 | term_printf("pic%d: irr=%02x imr=%02x isr=%02x hprio=%d irq_base=%02x rr_sel=%d elcr=%02x fnm=%d\n", | 509 | term_printf("pic%d: irr=%02x imr=%02x isr=%02x hprio=%d irq_base=%02x rr_sel=%d elcr=%02x fnm=%d\n", |
497 | i, s->irr, s->imr, s->isr, s->priority_add, | 510 | i, s->irr, s->imr, s->isr, s->priority_add, |
498 | s->irq_base, s->read_reg_select, s->elcr, | 511 | s->irq_base, s->read_reg_select, s->elcr, |
@@ -517,11 +530,19 @@ void irq_info(void) | @@ -517,11 +530,19 @@ void irq_info(void) | ||
517 | #endif | 530 | #endif |
518 | } | 531 | } |
519 | 532 | ||
520 | -void pic_init(void) | 533 | +PicState2 *pic_init(IRQRequestFunc *irq_request, void *irq_request_opaque) |
521 | { | 534 | { |
522 | - pic_init1(0x20, 0x4d0, &pics[0]); | ||
523 | - pic_init1(0xa0, 0x4d1, &pics[1]); | ||
524 | - pics[0].elcr_mask = 0xf8; | ||
525 | - pics[1].elcr_mask = 0xde; | 535 | + PicState2 *s; |
536 | + s = qemu_mallocz(sizeof(PicState2)); | ||
537 | + if (!s) | ||
538 | + return NULL; | ||
539 | + pic_init1(0x20, 0x4d0, &s->pics[0]); | ||
540 | + pic_init1(0xa0, 0x4d1, &s->pics[1]); | ||
541 | + s->pics[0].elcr_mask = 0xf8; | ||
542 | + s->pics[1].elcr_mask = 0xde; | ||
543 | + s->irq_request = irq_request; | ||
544 | + s->irq_request_opaque = irq_request_opaque; | ||
545 | + s->pics[0].pics_state = s; | ||
546 | + s->pics[1].pics_state = s; | ||
547 | + return s; | ||
526 | } | 548 | } |
527 | - |
hw/ide.c
@@ -2008,7 +2008,7 @@ void isa_ide_init(int iobase, int iobase2, int irq, | @@ -2008,7 +2008,7 @@ void isa_ide_init(int iobase, int iobase2, int irq, | ||
2008 | if (!ide_state) | 2008 | if (!ide_state) |
2009 | return; | 2009 | return; |
2010 | 2010 | ||
2011 | - ide_init2(ide_state, hd0, hd1, pic_set_irq_new, NULL, irq); | 2011 | + ide_init2(ide_state, hd0, hd1, pic_set_irq_new, isa_pic, irq); |
2012 | ide_init_ioport(ide_state, iobase, iobase2); | 2012 | ide_init_ioport(ide_state, iobase, iobase2); |
2013 | } | 2013 | } |
2014 | 2014 | ||
@@ -2337,9 +2337,9 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table) | @@ -2337,9 +2337,9 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table) | ||
2337 | PCI_ADDRESS_SPACE_IO, bmdma_map); | 2337 | PCI_ADDRESS_SPACE_IO, bmdma_map); |
2338 | 2338 | ||
2339 | ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], | 2339 | ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], |
2340 | - pic_set_irq_new, NULL, 14); | 2340 | + pic_set_irq_new, isa_pic, 14); |
2341 | ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], | 2341 | ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], |
2342 | - pic_set_irq_new, NULL, 15); | 2342 | + pic_set_irq_new, isa_pic, 15); |
2343 | ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6); | 2343 | ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6); |
2344 | ide_init_ioport(&d->ide_if[2], 0x170, 0x376); | 2344 | ide_init_ioport(&d->ide_if[2], 0x170, 0x376); |
2345 | } | 2345 | } |
hw/pc.c
@@ -65,6 +65,33 @@ uint64_t cpu_get_tsc(CPUX86State *env) | @@ -65,6 +65,33 @@ uint64_t cpu_get_tsc(CPUX86State *env) | ||
65 | return qemu_get_clock(vm_clock); | 65 | return qemu_get_clock(vm_clock); |
66 | } | 66 | } |
67 | 67 | ||
68 | +/* IRQ handling */ | ||
69 | +int cpu_get_pic_interrupt(CPUState *env) | ||
70 | +{ | ||
71 | + int intno; | ||
72 | + | ||
73 | +#ifdef TARGET_X86_64 | ||
74 | + intno = apic_get_interrupt(env); | ||
75 | + if (intno >= 0) { | ||
76 | + /* set irq request if a PIC irq is still pending */ | ||
77 | + /* XXX: improve that */ | ||
78 | + pic_update_irq(isa_pic); | ||
79 | + return intno; | ||
80 | + } | ||
81 | +#endif | ||
82 | + /* read the irq from the PIC */ | ||
83 | + intno = pic_read_irq(isa_pic); | ||
84 | + return intno; | ||
85 | +} | ||
86 | + | ||
87 | +static void pic_irq_request(void *opaque, int level) | ||
88 | +{ | ||
89 | + if (level) | ||
90 | + cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); | ||
91 | + else | ||
92 | + cpu_reset_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); | ||
93 | +} | ||
94 | + | ||
68 | /* PC cmos mappings */ | 95 | /* PC cmos mappings */ |
69 | 96 | ||
70 | #define REG_EQUIPMENT_BYTE 0x14 | 97 | #define REG_EQUIPMENT_BYTE 0x14 |
@@ -532,7 +559,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device, | @@ -532,7 +559,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device, | ||
532 | 559 | ||
533 | if (pci_enabled) | 560 | if (pci_enabled) |
534 | apic_init(cpu_single_env); | 561 | apic_init(cpu_single_env); |
535 | - pic_init(); | 562 | + isa_pic = pic_init(pic_irq_request, cpu_single_env); |
536 | pit = pit_init(0x40, 0); | 563 | pit = pit_init(0x40, 0); |
537 | 564 | ||
538 | for(i = 0; i < MAX_SERIAL_PORTS; i++) { | 565 | for(i = 0; i < MAX_SERIAL_PORTS; i++) { |
hw/ppc_chrp.c
@@ -213,6 +213,11 @@ static int vga_osi_call(CPUState *env) | @@ -213,6 +213,11 @@ static int vga_osi_call(CPUState *env) | ||
213 | return 1; /* osi_call handled */ | 213 | return 1; /* osi_call handled */ |
214 | } | 214 | } |
215 | 215 | ||
216 | +/* XXX: suppress that */ | ||
217 | +static void pic_irq_request(void *opaque, int level) | ||
218 | +{ | ||
219 | +} | ||
220 | + | ||
216 | /* PowerPC CHRP hardware initialisation */ | 221 | /* PowerPC CHRP hardware initialisation */ |
217 | static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, | 222 | static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, |
218 | DisplayState *ds, const char **fd_filename, | 223 | DisplayState *ds, const char **fd_filename, |
@@ -303,7 +308,7 @@ static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, | @@ -303,7 +308,7 @@ static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, | ||
303 | pci_set_pic(pci_bus, set_irq, pic); | 308 | pci_set_pic(pci_bus, set_irq, pic); |
304 | 309 | ||
305 | /* XXX: suppress that */ | 310 | /* XXX: suppress that */ |
306 | - pic_init(); | 311 | + pic_init(pic_irq_request, NULL); |
307 | 312 | ||
308 | /* XXX: use Mac Serial port */ | 313 | /* XXX: use Mac Serial port */ |
309 | serial_init(0x3f8, 4, serial_hds[0]); | 314 | serial_init(0x3f8, 4, serial_hds[0]); |
@@ -345,7 +350,7 @@ static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, | @@ -345,7 +350,7 @@ static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, | ||
345 | pci_set_pic(pci_bus, set_irq, pic); | 350 | pci_set_pic(pci_bus, set_irq, pic); |
346 | 351 | ||
347 | /* XXX: suppress that */ | 352 | /* XXX: suppress that */ |
348 | - pic_init(); | 353 | + pic_init(pic_irq_request, NULL); |
349 | 354 | ||
350 | /* XXX: use Mac Serial port */ | 355 | /* XXX: use Mac Serial port */ |
351 | serial_init(0x3f8, 4, serial_hds[0]); | 356 | serial_init(0x3f8, 4, serial_hds[0]); |
hw/ppc_prep.c
@@ -96,6 +96,14 @@ static uint32_t speaker_ioport_read(void *opaque, uint32_t addr) | @@ -96,6 +96,14 @@ static uint32_t speaker_ioport_read(void *opaque, uint32_t addr) | ||
96 | return 0; | 96 | return 0; |
97 | } | 97 | } |
98 | 98 | ||
99 | +static void pic_irq_request(void *opaque, int level) | ||
100 | +{ | ||
101 | + if (level) | ||
102 | + cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); | ||
103 | + else | ||
104 | + cpu_reset_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); | ||
105 | +} | ||
106 | + | ||
99 | /* PCI intack register */ | 107 | /* PCI intack register */ |
100 | /* Read-only register (?) */ | 108 | /* Read-only register (?) */ |
101 | static void _PPC_intack_write (void *opaque, target_phys_addr_t addr, uint32_t value) | 109 | static void _PPC_intack_write (void *opaque, target_phys_addr_t addr, uint32_t value) |
@@ -108,7 +116,7 @@ static inline uint32_t _PPC_intack_read (target_phys_addr_t addr) | @@ -108,7 +116,7 @@ static inline uint32_t _PPC_intack_read (target_phys_addr_t addr) | ||
108 | uint32_t retval = 0; | 116 | uint32_t retval = 0; |
109 | 117 | ||
110 | if (addr == 0xBFFFFFF0) | 118 | if (addr == 0xBFFFFFF0) |
111 | - retval = pic_intack_read(NULL); | 119 | + retval = pic_intack_read(isa_pic); |
112 | // printf("%s: 0x%08x <= %d\n", __func__, addr, retval); | 120 | // printf("%s: 0x%08x <= %d\n", __func__, addr, retval); |
113 | 121 | ||
114 | return retval; | 122 | return retval; |
@@ -505,8 +513,6 @@ CPUReadMemoryFunc *PPC_prep_io_read[] = { | @@ -505,8 +513,6 @@ CPUReadMemoryFunc *PPC_prep_io_read[] = { | ||
505 | &PPC_prep_io_readl, | 513 | &PPC_prep_io_readl, |
506 | }; | 514 | }; |
507 | 515 | ||
508 | -extern CPUPPCState *global_env; | ||
509 | - | ||
510 | #define NVRAM_SIZE 0x2000 | 516 | #define NVRAM_SIZE 0x2000 |
511 | 517 | ||
512 | /* PowerPC PREP hardware initialisation */ | 518 | /* PowerPC PREP hardware initialisation */ |
@@ -593,8 +599,7 @@ static void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device, | @@ -593,8 +599,7 @@ static void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device, | ||
593 | vga_ram_size); | 599 | vga_ram_size); |
594 | rtc_init(0x70, 8); | 600 | rtc_init(0x70, 8); |
595 | // openpic = openpic_init(0x00000000, 0xF0000000, 1); | 601 | // openpic = openpic_init(0x00000000, 0xF0000000, 1); |
596 | - // pic_init(openpic); | ||
597 | - pic_init(); | 602 | + isa_pic = pic_init(pic_irq_request, cpu_single_env); |
598 | // pit = pit_init(0x40, 0); | 603 | // pit = pit_init(0x40, 0); |
599 | 604 | ||
600 | serial_init(0x3f8, 4, serial_hds[0]); | 605 | serial_init(0x3f8, 4, serial_hds[0]); |
vl.c
@@ -155,6 +155,7 @@ int win2k_install_hack = 0; | @@ -155,6 +155,7 @@ int win2k_install_hack = 0; | ||
155 | /* x86 ISA bus support */ | 155 | /* x86 ISA bus support */ |
156 | 156 | ||
157 | target_phys_addr_t isa_mem_base = 0; | 157 | target_phys_addr_t isa_mem_base = 0; |
158 | +PicState2 *isa_pic; | ||
158 | 159 | ||
159 | uint32_t default_ioport_readb(void *opaque, uint32_t address) | 160 | uint32_t default_ioport_readb(void *opaque, uint32_t address) |
160 | { | 161 | { |
vl.h
@@ -469,6 +469,7 @@ typedef struct QEMUMachine { | @@ -469,6 +469,7 @@ typedef struct QEMUMachine { | ||
469 | int qemu_register_machine(QEMUMachine *m); | 469 | int qemu_register_machine(QEMUMachine *m); |
470 | 470 | ||
471 | typedef void SetIRQFunc(void *opaque, int irq_num, int level); | 471 | typedef void SetIRQFunc(void *opaque, int irq_num, int level); |
472 | +typedef void IRQRequestFunc(void *opaque, int level); | ||
472 | 473 | ||
473 | /* ISA bus */ | 474 | /* ISA bus */ |
474 | 475 | ||
@@ -687,10 +688,14 @@ ParallelState *parallel_init(int base, int irq, CharDriverState *chr); | @@ -687,10 +688,14 @@ ParallelState *parallel_init(int base, int irq, CharDriverState *chr); | ||
687 | 688 | ||
688 | /* i8259.c */ | 689 | /* i8259.c */ |
689 | 690 | ||
691 | +typedef struct PicState2 PicState2; | ||
692 | +extern PicState2 *isa_pic; | ||
690 | void pic_set_irq(int irq, int level); | 693 | void pic_set_irq(int irq, int level); |
691 | void pic_set_irq_new(void *opaque, int irq, int level); | 694 | void pic_set_irq_new(void *opaque, int irq, int level); |
692 | -void pic_init(void); | ||
693 | -uint32_t pic_intack_read(CPUState *env); | 695 | +PicState2 *pic_init(IRQRequestFunc *irq_request, void *irq_request_opaque); |
696 | +int pic_read_irq(PicState2 *s); | ||
697 | +void pic_update_irq(PicState2 *s); | ||
698 | +uint32_t pic_intack_read(PicState2 *s); | ||
694 | void pic_info(void); | 699 | void pic_info(void); |
695 | void irq_info(void); | 700 | void irq_info(void); |
696 | 701 |