Commit 3de388f676e936097f99fb58e8a58c5461eb696e

Authored by bellard
1 parent 73133662

more generic i8259 support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1487 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -360,8 +360,8 @@ VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o
360 360 VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o
361 361 endif
362 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 365 endif
366 366 ifeq ($(TARGET_BASE_ARCH), sparc)
367 367 ifeq ($(TARGET_ARCH), sparc64)
... ...
hw/i8259.c
... ... @@ -46,10 +46,16 @@ typedef struct PicState {
46 46 uint8_t init4; /* true if 4 byte init */
47 47 uint8_t elcr; /* PIIX edge/trigger selection*/
48 48 uint8_t elcr_mask;
  49 + PicState2 *pics_state;
49 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 60 #if defined(DEBUG_PIC) || defined (DEBUG_IRQ_COUNT)
55 61 static int irq_level[16];
... ... @@ -110,7 +116,7 @@ static int pic_get_irq(PicState *s)
110 116 master, the IRQ coming from the slave is not taken into account
111 117 for the priority computation. */
112 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 120 mask &= ~(1 << 2);
115 121 cur_priority = get_priority(s, mask);
116 122 if (priority < cur_priority) {
... ... @@ -123,32 +129,34 @@ static int pic_get_irq(PicState *s)
123 129  
124 130 /* raise irq to CPU if necessary. must be called every time the active
125 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 135 int irq2, irq;
129 136  
130 137 /* first look at slave pic */
131   - irq2 = pic_get_irq(&pics[1]);
  138 + irq2 = pic_get_irq(&s->pics[1]);
132 139 if (irq2 >= 0) {
133 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 144 /* look at requested irq */
138   - irq = pic_get_irq(&pics[0]);
  145 + irq = pic_get_irq(&s->pics[0]);
139 146 if (irq >= 0) {
140 147 #if defined(DEBUG_PIC)
141 148 {
142 149 int i;
143 150 for(i = 0; i < 2; i++) {
144 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 157 printf("pic: cpu_interrupt\n");
150 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 164 int64_t irq_time[16];
157 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 171 #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
162 172 if (level != irq_level[irq]) {
163 173 #if defined(DEBUG_PIC)
... ... @@ -175,14 +185,14 @@ void pic_set_irq(int irq, int level)
175 185 irq_time[irq] = qemu_get_clock(vm_clock);
176 186 }
177 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 198 /* acknowledge interrupt 'irq' */
... ... @@ -199,43 +209,32 @@ static inline void pic_intack(PicState *s, int irq)
199 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 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 217 if (irq >= 0) {
219   - pic_intack(&pics[0], irq);
  218 + pic_intack(&s->pics[0], irq);
220 219 if (irq == 2) {
221   - irq2 = pic_get_irq(&pics[1]);
  220 + irq2 = pic_get_irq(&s->pics[1]);
222 221 if (irq2 >= 0) {
223   - pic_intack(&pics[1], irq2);
  222 + pic_intack(&s->pics[1], irq2);
224 223 } else {
225 224 /* spurious IRQ on slave controller */
226 225 irq2 = 7;
227 226 }
228   - intno = pics[1].irq_base + irq2;
  227 + intno = s->pics[1].irq_base + irq2;
229 228 irq = irq2 + 8;
230 229 } else {
231   - intno = pics[0].irq_base + irq;
  230 + intno = s->pics[0].irq_base + irq;
232 231 }
233 232 } else {
234 233 /* spurious IRQ on host controller */
235 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 239 #ifdef DEBUG_IRQ_LATENCY
241 240 printf("IRQ%d latency=%0.3fus\n",
... ... @@ -251,11 +250,22 @@ int cpu_get_pic_interrupt(CPUState *env)
251 250 static void pic_reset(void *opaque)
252 251 {
253 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 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 282 /* init */
273 283 pic_reset(s);
274 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 286 s->init_state = 1;
278 287 s->init4 = val & 1;
279 288 if (val & 0x02)
... ... @@ -302,23 +311,23 @@ static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
302 311 s->isr &= ~(1 << irq);
303 312 if (cmd == 5)
304 313 s->priority_add = (irq + 1) & 7;
305   - pic_update_irq();
  314 + pic_update_irq(s->pics_state);
306 315 }
307 316 break;
308 317 case 3:
309 318 irq = val & 7;
310 319 s->isr &= ~(1 << irq);
311   - pic_update_irq();
  320 + pic_update_irq(s->pics_state);
312 321 break;
313 322 case 6:
314 323 s->priority_add = (val + 1) & 7;
315   - pic_update_irq();
  324 + pic_update_irq(s->pics_state);
316 325 break;
317 326 case 7:
318 327 irq = val & 7;
319 328 s->isr &= ~(1 << irq);
320 329 s->priority_add = (irq + 1) & 7;
321   - pic_update_irq();
  330 + pic_update_irq(s->pics_state);
322 331 break;
323 332 default:
324 333 /* no operation */
... ... @@ -330,7 +339,7 @@ static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
330 339 case 0:
331 340 /* normal mode */
332 341 s->imr = val;
333   - pic_update_irq();
  342 + pic_update_irq(s->pics_state);
334 343 break;
335 344 case 1:
336 345 s->irq_base = val & 0xf8;
... ... @@ -359,16 +368,16 @@ static uint32_t pic_poll_read (PicState *s, uint32_t addr1)
359 368 ret = pic_get_irq(s);
360 369 if (ret >= 0) {
361 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 374 s->irr &= ~(1 << ret);
366 375 s->isr &= ~(1 << ret);
367 376 if (addr1 >> 7 || ret != 2)
368   - pic_update_irq();
  377 + pic_update_irq(s->pics_state);
369 378 } else {
370 379 ret = 0x07;
371   - pic_update_irq();
  380 + pic_update_irq(s->pics_state);
372 381 }
373 382  
374 383 return ret;
... ... @@ -402,15 +411,16 @@ static uint32_t pic_ioport_read(void *opaque, uint32_t addr1)
402 411 }
403 412  
404 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 417 int ret;
408 418  
409   - ret = pic_poll_read(&pics[0], 0x00);
  419 + ret = pic_poll_read(&s->pics[0], 0x00);
410 420 if (ret == 2)
411   - ret = pic_poll_read(&pics[1], 0x80) + 8;
  421 + ret = pic_poll_read(&s->pics[1], 0x80) + 8;
412 422 /* Prepare for ISR read */
413   - pics[0].read_reg_select = 1;
  423 + s->pics[0].read_reg_select = 1;
414 424  
415 425 return ret;
416 426 }
... ... @@ -490,9 +500,12 @@ void pic_info(void)
490 500 {
491 501 int i;
492 502 PicState *s;
  503 +
  504 + if (!isa_pic)
  505 + return;
493 506  
494 507 for(i=0;i<2;i++) {
495   - s = &pics[i];
  508 + s = &isa_pic->pics[i];
496 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 510 i, s->irr, s->imr, s->isr, s->priority_add,
498 511 s->irq_base, s->read_reg_select, s->elcr,
... ... @@ -517,11 +530,19 @@ void irq_info(void)
517 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 2008 if (!ide_state)
2009 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 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 2337 PCI_ADDRESS_SPACE_IO, bmdma_map);
2338 2338  
2339 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 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 2343 ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
2344 2344 ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
2345 2345 }
... ...
... ... @@ -65,6 +65,33 @@ uint64_t cpu_get_tsc(CPUX86State *env)
65 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 95 /* PC cmos mappings */
69 96  
70 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 559  
533 560 if (pci_enabled)
534 561 apic_init(cpu_single_env);
535   - pic_init();
  562 + isa_pic = pic_init(pic_irq_request, cpu_single_env);
536 563 pit = pit_init(0x40, 0);
537 564  
538 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 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 221 /* PowerPC CHRP hardware initialisation */
217 222 static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device,
218 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 308 pci_set_pic(pci_bus, set_irq, pic);
304 309  
305 310 /* XXX: suppress that */
306   - pic_init();
  311 + pic_init(pic_irq_request, NULL);
307 312  
308 313 /* XXX: use Mac Serial port */
309 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 350 pci_set_pic(pci_bus, set_irq, pic);
346 351  
347 352 /* XXX: suppress that */
348   - pic_init();
  353 + pic_init(pic_irq_request, NULL);
349 354  
350 355 /* XXX: use Mac Serial port */
351 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 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 107 /* PCI intack register */
100 108 /* Read-only register (?) */
101 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 116 uint32_t retval = 0;
109 117  
110 118 if (addr == 0xBFFFFFF0)
111   - retval = pic_intack_read(NULL);
  119 + retval = pic_intack_read(isa_pic);
112 120 // printf("%s: 0x%08x <= %d\n", __func__, addr, retval);
113 121  
114 122 return retval;
... ... @@ -505,8 +513,6 @@ CPUReadMemoryFunc *PPC_prep_io_read[] = {
505 513 &PPC_prep_io_readl,
506 514 };
507 515  
508   -extern CPUPPCState *global_env;
509   -
510 516 #define NVRAM_SIZE 0x2000
511 517  
512 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 599 vga_ram_size);
594 600 rtc_init(0x70, 8);
595 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 603 // pit = pit_init(0x40, 0);
599 604  
600 605 serial_init(0x3f8, 4, serial_hds[0]);
... ...
... ... @@ -155,6 +155,7 @@ int win2k_install_hack = 0;
155 155 /* x86 ISA bus support */
156 156  
157 157 target_phys_addr_t isa_mem_base = 0;
  158 +PicState2 *isa_pic;
158 159  
159 160 uint32_t default_ioport_readb(void *opaque, uint32_t address)
160 161 {
... ...
... ... @@ -469,6 +469,7 @@ typedef struct QEMUMachine {
469 469 int qemu_register_machine(QEMUMachine *m);
470 470  
471 471 typedef void SetIRQFunc(void *opaque, int irq_num, int level);
  472 +typedef void IRQRequestFunc(void *opaque, int level);
472 473  
473 474 /* ISA bus */
474 475  
... ... @@ -687,10 +688,14 @@ ParallelState *parallel_init(int base, int irq, CharDriverState *chr);
687 688  
688 689 /* i8259.c */
689 690  
  691 +typedef struct PicState2 PicState2;
  692 +extern PicState2 *isa_pic;
690 693 void pic_set_irq(int irq, int level);
691 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 699 void pic_info(void);
695 700 void irq_info(void);
696 701  
... ...