Re-add missing declaration for pci_hypercall_init
[qemu-kvm/fedora.git] / hw / i8259.c
blob071f9f193a9e2cc8a522823aed5a5f5281e631f9
1 /*
2 * QEMU 8259 interrupt controller emulation
4 * Copyright (c) 2003-2004 Fabrice Bellard
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
24 #include "hw.h"
25 #include "pc.h"
26 #include "isa.h"
27 #include "console.h"
29 #ifdef USE_KVM
30 #include "qemu-kvm.h"
31 #endif
33 /* debug PIC */
34 //#define DEBUG_PIC
36 //#define DEBUG_IRQ_LATENCY
37 //#define DEBUG_IRQ_COUNT
39 typedef struct PicState {
40 uint8_t last_irr; /* edge detection */
41 uint8_t irr; /* interrupt request register */
42 uint8_t imr; /* interrupt mask register */
43 uint8_t isr; /* interrupt service register */
44 uint8_t priority_add; /* highest irq priority */
45 uint8_t irq_base;
46 uint8_t read_reg_select;
47 uint8_t poll;
48 uint8_t special_mask;
49 uint8_t init_state;
50 uint8_t auto_eoi;
51 uint8_t rotate_on_auto_eoi;
52 uint8_t special_fully_nested_mode;
53 uint8_t init4; /* true if 4 byte init */
54 uint8_t single_mode; /* true if slave pic is not initialized */
55 uint8_t elcr; /* PIIX edge/trigger selection*/
56 uint8_t elcr_mask;
57 PicState2 *pics_state;
58 } PicState;
60 struct PicState2 {
61 /* 0 is master pic, 1 is slave pic */
62 /* XXX: better separation between the two pics */
63 PicState pics[2];
64 qemu_irq parent_irq;
65 void *irq_request_opaque;
66 /* IOAPIC callback support */
67 SetIRQFunc *alt_irq_func;
68 void *alt_irq_opaque;
71 #if defined(DEBUG_PIC) || defined (DEBUG_IRQ_COUNT)
72 static int irq_level[16];
73 #endif
74 #ifdef DEBUG_IRQ_COUNT
75 static uint64_t irq_count[16];
76 #endif
78 /* set irq level. If an edge is detected, then the IRR is set to 1 */
79 static inline void pic_set_irq1(PicState *s, int irq, int level)
81 int mask;
82 mask = 1 << irq;
83 if (s->elcr & mask) {
84 /* level triggered */
85 if (level) {
86 s->irr |= mask;
87 s->last_irr |= mask;
88 } else {
89 s->irr &= ~mask;
90 s->last_irr &= ~mask;
92 } else {
93 /* edge triggered */
94 if (level) {
95 if ((s->last_irr & mask) == 0)
96 s->irr |= mask;
97 s->last_irr |= mask;
98 } else {
99 s->last_irr &= ~mask;
104 /* return the highest priority found in mask (highest = smallest
105 number). Return 8 if no irq */
106 static inline int get_priority(PicState *s, int mask)
108 int priority;
109 if (mask == 0)
110 return 8;
111 priority = 0;
112 while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0)
113 priority++;
114 return priority;
117 /* return the pic wanted interrupt. return -1 if none */
118 static int pic_get_irq(PicState *s)
120 int mask, cur_priority, priority;
122 mask = s->irr & ~s->imr;
123 priority = get_priority(s, mask);
124 if (priority == 8)
125 return -1;
126 /* compute current priority. If special fully nested mode on the
127 master, the IRQ coming from the slave is not taken into account
128 for the priority computation. */
129 mask = s->isr;
130 if (s->special_fully_nested_mode && s == &s->pics_state->pics[0])
131 mask &= ~(1 << 2);
132 cur_priority = get_priority(s, mask);
133 if (priority < cur_priority) {
134 /* higher priority found: an irq should be generated */
135 return (priority + s->priority_add) & 7;
136 } else {
137 return -1;
141 /* raise irq to CPU if necessary. must be called every time the active
142 irq may change */
143 /* XXX: should not export it, but it is needed for an APIC kludge */
144 void pic_update_irq(PicState2 *s)
146 int irq2, irq;
148 /* first look at slave pic */
149 irq2 = pic_get_irq(&s->pics[1]);
150 if (irq2 >= 0) {
151 /* if irq request by slave pic, signal master PIC */
152 pic_set_irq1(&s->pics[0], 2, 1);
153 pic_set_irq1(&s->pics[0], 2, 0);
155 /* look at requested irq */
156 irq = pic_get_irq(&s->pics[0]);
157 if (irq >= 0) {
158 #if defined(DEBUG_PIC)
160 int i;
161 for(i = 0; i < 2; i++) {
162 printf("pic%d: imr=%x irr=%x padd=%d\n",
163 i, s->pics[i].imr, s->pics[i].irr,
164 s->pics[i].priority_add);
168 printf("pic: cpu_interrupt\n");
169 #endif
170 qemu_irq_raise(s->parent_irq);
173 /* all targets should do this rather than acking the IRQ in the cpu */
174 #if defined(TARGET_MIPS) || defined(TARGET_PPC)
175 else {
176 qemu_irq_lower(s->parent_irq);
178 #endif
181 #ifdef DEBUG_IRQ_LATENCY
182 int64_t irq_time[16];
183 #endif
185 static void i8259_set_irq(void *opaque, int irq, int level)
187 PicState2 *s = opaque;
188 #ifdef USE_KVM
189 #ifdef KVM_CAP_IRQCHIP
190 extern int kvm_set_irq(int irq, int level);
192 if (kvm_allowed)
193 if (kvm_set_irq(irq, level))
194 return;
195 #endif
196 #endif
197 #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
198 if (level != irq_level[irq]) {
199 #if defined(DEBUG_PIC)
200 printf("i8259_set_irq: irq=%d level=%d\n", irq, level);
201 #endif
202 irq_level[irq] = level;
203 #ifdef DEBUG_IRQ_COUNT
204 if (level == 1)
205 irq_count[irq]++;
206 #endif
208 #endif
209 #ifdef DEBUG_IRQ_LATENCY
210 if (level) {
211 irq_time[irq] = qemu_get_clock(vm_clock);
213 #endif
214 pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
215 /* used for IOAPIC irqs */
216 if (s->alt_irq_func)
217 s->alt_irq_func(s->alt_irq_opaque, irq, level);
218 pic_update_irq(s);
221 /* acknowledge interrupt 'irq' */
222 static inline void pic_intack(PicState *s, int irq)
224 if (s->auto_eoi) {
225 if (s->rotate_on_auto_eoi)
226 s->priority_add = (irq + 1) & 7;
227 } else {
228 s->isr |= (1 << irq);
231 /* We don't clear a level sensitive interrupt here */
232 if (!(s->elcr & (1 << irq)))
233 s->irr &= ~(1 << irq);
237 extern int time_drift_fix;
239 int pic_read_irq(PicState2 *s)
241 int irq, irq2, intno;
243 irq = pic_get_irq(&s->pics[0]);
244 if (irq >= 0) {
246 pic_intack(&s->pics[0], irq);
247 #ifndef TARGET_IA64
248 if (time_drift_fix && irq == 0) {
249 extern int64_t timer_acks, timer_ints_to_push;
250 timer_acks++;
251 if (timer_ints_to_push > 0) {
252 timer_ints_to_push--;
253 /* simulate an edge irq0, like the one generated by i8254 */
254 pic_set_irq1(&s->pics[0], 0, 0);
255 pic_set_irq1(&s->pics[0], 0, 1);
258 #endif
259 if (irq == 2) {
260 irq2 = pic_get_irq(&s->pics[1]);
261 if (irq2 >= 0) {
262 pic_intack(&s->pics[1], irq2);
263 } else {
264 /* spurious IRQ on slave controller */
265 irq2 = 7;
267 intno = s->pics[1].irq_base + irq2;
268 irq = irq2 + 8;
269 } else {
270 intno = s->pics[0].irq_base + irq;
272 } else {
273 /* spurious IRQ on host controller */
274 irq = 7;
275 intno = s->pics[0].irq_base + irq;
277 pic_update_irq(s);
279 #ifdef DEBUG_IRQ_LATENCY
280 printf("IRQ%d latency=%0.3fus\n",
281 irq,
282 (double)(qemu_get_clock(vm_clock) - irq_time[irq]) * 1000000.0 / ticks_per_sec);
283 #endif
284 #if defined(DEBUG_PIC)
285 printf("pic_interrupt: irq=%d\n", irq);
286 #endif
287 return intno;
290 static void pic_reset(void *opaque)
292 PicState *s = opaque;
294 s->last_irr = 0;
295 s->irr = 0;
296 s->imr = 0;
297 s->isr = 0;
298 s->priority_add = 0;
299 s->irq_base = 0;
300 s->read_reg_select = 0;
301 s->poll = 0;
302 s->special_mask = 0;
303 s->init_state = 0;
304 s->auto_eoi = 0;
305 s->rotate_on_auto_eoi = 0;
306 s->special_fully_nested_mode = 0;
307 s->init4 = 0;
308 s->single_mode = 0;
309 /* Note: ELCR is not reset */
312 static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
314 PicState *s = opaque;
315 int priority, cmd, irq;
317 #ifdef DEBUG_PIC
318 printf("pic_write: addr=0x%02x val=0x%02x\n", addr, val);
319 #endif
320 addr &= 1;
321 if (addr == 0) {
322 if (val & 0x10) {
323 /* init */
324 pic_reset(s);
325 /* deassert a pending interrupt */
326 qemu_irq_lower(s->pics_state->parent_irq);
327 s->init_state = 1;
328 s->init4 = val & 1;
329 s->single_mode = val & 2;
330 if (val & 0x08)
331 hw_error("level sensitive irq not supported");
332 } else if (val & 0x08) {
333 if (val & 0x04)
334 s->poll = 1;
335 if (val & 0x02)
336 s->read_reg_select = val & 1;
337 if (val & 0x40)
338 s->special_mask = (val >> 5) & 1;
339 } else {
340 cmd = val >> 5;
341 switch(cmd) {
342 case 0:
343 case 4:
344 s->rotate_on_auto_eoi = cmd >> 2;
345 break;
346 case 1: /* end of interrupt */
347 case 5:
348 priority = get_priority(s, s->isr);
349 if (priority != 8) {
350 irq = (priority + s->priority_add) & 7;
351 s->isr &= ~(1 << irq);
352 if (cmd == 5)
353 s->priority_add = (irq + 1) & 7;
354 pic_update_irq(s->pics_state);
356 break;
357 case 3:
358 irq = val & 7;
359 s->isr &= ~(1 << irq);
360 pic_update_irq(s->pics_state);
361 break;
362 case 6:
363 s->priority_add = (val + 1) & 7;
364 pic_update_irq(s->pics_state);
365 break;
366 case 7:
367 irq = val & 7;
368 s->isr &= ~(1 << irq);
369 s->priority_add = (irq + 1) & 7;
370 pic_update_irq(s->pics_state);
371 break;
372 default:
373 /* no operation */
374 break;
377 } else {
378 switch(s->init_state) {
379 case 0:
380 /* normal mode */
381 s->imr = val;
382 pic_update_irq(s->pics_state);
383 break;
384 case 1:
385 s->irq_base = val & 0xf8;
386 s->init_state = s->single_mode ? (s->init4 ? 3 : 0) : 2;
387 break;
388 case 2:
389 if (s->init4) {
390 s->init_state = 3;
391 } else {
392 s->init_state = 0;
394 break;
395 case 3:
396 s->special_fully_nested_mode = (val >> 4) & 1;
397 s->auto_eoi = (val >> 1) & 1;
398 s->init_state = 0;
399 break;
404 static uint32_t pic_poll_read (PicState *s, uint32_t addr1)
406 int ret;
408 ret = pic_get_irq(s);
409 if (ret >= 0) {
410 if (addr1 >> 7) {
411 s->pics_state->pics[0].isr &= ~(1 << 2);
412 s->pics_state->pics[0].irr &= ~(1 << 2);
414 s->irr &= ~(1 << ret);
415 s->isr &= ~(1 << ret);
416 if (addr1 >> 7 || ret != 2)
417 pic_update_irq(s->pics_state);
418 } else {
419 ret = 0x07;
420 pic_update_irq(s->pics_state);
423 return ret;
426 static uint32_t pic_ioport_read(void *opaque, uint32_t addr1)
428 PicState *s = opaque;
429 unsigned int addr;
430 int ret;
432 addr = addr1;
433 addr &= 1;
434 if (s->poll) {
435 ret = pic_poll_read(s, addr1);
436 s->poll = 0;
437 } else {
438 if (addr == 0) {
439 if (s->read_reg_select)
440 ret = s->isr;
441 else
442 ret = s->irr;
443 } else {
444 ret = s->imr;
447 #ifdef DEBUG_PIC
448 printf("pic_read: addr=0x%02x val=0x%02x\n", addr1, ret);
449 #endif
450 return ret;
453 /* memory mapped interrupt status */
454 /* XXX: may be the same than pic_read_irq() */
455 uint32_t pic_intack_read(PicState2 *s)
457 int ret;
459 ret = pic_poll_read(&s->pics[0], 0x00);
460 if (ret == 2)
461 ret = pic_poll_read(&s->pics[1], 0x80) + 8;
462 /* Prepare for ISR read */
463 s->pics[0].read_reg_select = 1;
465 return ret;
468 static void elcr_ioport_write(void *opaque, uint32_t addr, uint32_t val)
470 PicState *s = opaque;
471 s->elcr = val & s->elcr_mask;
474 static uint32_t elcr_ioport_read(void *opaque, uint32_t addr1)
476 PicState *s = opaque;
477 return s->elcr;
480 #ifdef USE_KVM
481 #include "qemu-kvm.h"
482 extern int kvm_allowed;
483 extern kvm_context_t kvm_context;
485 static void kvm_kernel_pic_save_to_user(PicState *s)
487 #if defined(KVM_CAP_IRQCHIP) && defined(TARGET_I386)
488 struct kvm_irqchip chip;
489 struct kvm_pic_state *kpic;
491 chip.chip_id = (&s->pics_state->pics[0] == s) ?
492 KVM_IRQCHIP_PIC_MASTER :
493 KVM_IRQCHIP_PIC_SLAVE;
494 kvm_get_irqchip(kvm_context, &chip);
495 kpic = &chip.chip.pic;
497 s->last_irr = kpic->last_irr;
498 s->irr = kpic->irr;
499 s->imr = kpic->imr;
500 s->isr = kpic->isr;
501 s->priority_add = kpic->priority_add;
502 s->irq_base = kpic->irq_base;
503 s->read_reg_select = kpic->read_reg_select;
504 s->poll = kpic->poll;
505 s->special_mask = kpic->special_mask;
506 s->init_state = kpic->init_state;
507 s->auto_eoi = kpic->auto_eoi;
508 s->rotate_on_auto_eoi = kpic->rotate_on_auto_eoi;
509 s->special_fully_nested_mode = kpic->special_fully_nested_mode;
510 s->init4 = kpic->init4;
511 s->elcr = kpic->elcr;
512 s->elcr_mask = kpic->elcr_mask;
513 #endif
516 static void kvm_kernel_pic_load_from_user(PicState *s)
518 #if defined(KVM_CAP_IRQCHIP) && defined(TARGET_I386)
519 struct kvm_irqchip chip;
520 struct kvm_pic_state *kpic;
522 chip.chip_id = (&s->pics_state->pics[0] == s) ?
523 KVM_IRQCHIP_PIC_MASTER :
524 KVM_IRQCHIP_PIC_SLAVE;
525 kpic = &chip.chip.pic;
527 kpic->last_irr = s->last_irr;
528 kpic->irr = s->irr;
529 kpic->imr = s->imr;
530 kpic->isr = s->isr;
531 kpic->priority_add = s->priority_add;
532 kpic->irq_base = s->irq_base;
533 kpic->read_reg_select = s->read_reg_select;
534 kpic->poll = s->poll;
535 kpic->special_mask = s->special_mask;
536 kpic->init_state = s->init_state;
537 kpic->auto_eoi = s->auto_eoi;
538 kpic->rotate_on_auto_eoi = s->rotate_on_auto_eoi;
539 kpic->special_fully_nested_mode = s->special_fully_nested_mode;
540 kpic->init4 = s->init4;
541 kpic->elcr = s->elcr;
542 kpic->elcr_mask = s->elcr_mask;
544 kvm_set_irqchip(kvm_context, &chip);
545 #endif
547 #endif
549 static void pic_save(QEMUFile *f, void *opaque)
551 PicState *s = opaque;
553 #ifdef USE_KVM
554 if (kvm_allowed && kvm_irqchip_in_kernel(kvm_context)) {
555 kvm_kernel_pic_save_to_user(s);
557 #endif
559 qemu_put_8s(f, &s->last_irr);
560 qemu_put_8s(f, &s->irr);
561 qemu_put_8s(f, &s->imr);
562 qemu_put_8s(f, &s->isr);
563 qemu_put_8s(f, &s->priority_add);
564 qemu_put_8s(f, &s->irq_base);
565 qemu_put_8s(f, &s->read_reg_select);
566 qemu_put_8s(f, &s->poll);
567 qemu_put_8s(f, &s->special_mask);
568 qemu_put_8s(f, &s->init_state);
569 qemu_put_8s(f, &s->auto_eoi);
570 qemu_put_8s(f, &s->rotate_on_auto_eoi);
571 qemu_put_8s(f, &s->special_fully_nested_mode);
572 qemu_put_8s(f, &s->init4);
573 qemu_put_8s(f, &s->single_mode);
574 qemu_put_8s(f, &s->elcr);
577 static int pic_load(QEMUFile *f, void *opaque, int version_id)
579 PicState *s = opaque;
581 if (version_id != 1)
582 return -EINVAL;
584 qemu_get_8s(f, &s->last_irr);
585 qemu_get_8s(f, &s->irr);
586 qemu_get_8s(f, &s->imr);
587 qemu_get_8s(f, &s->isr);
588 qemu_get_8s(f, &s->priority_add);
589 qemu_get_8s(f, &s->irq_base);
590 qemu_get_8s(f, &s->read_reg_select);
591 qemu_get_8s(f, &s->poll);
592 qemu_get_8s(f, &s->special_mask);
593 qemu_get_8s(f, &s->init_state);
594 qemu_get_8s(f, &s->auto_eoi);
595 qemu_get_8s(f, &s->rotate_on_auto_eoi);
596 qemu_get_8s(f, &s->special_fully_nested_mode);
597 qemu_get_8s(f, &s->init4);
598 qemu_get_8s(f, &s->single_mode);
599 qemu_get_8s(f, &s->elcr);
601 #ifdef USE_KVM
602 if (kvm_allowed && kvm_irqchip_in_kernel(kvm_context)) {
603 kvm_kernel_pic_load_from_user(s);
605 #endif
607 return 0;
610 /* XXX: add generic master/slave system */
611 static void pic_init1(int io_addr, int elcr_addr, PicState *s)
613 register_ioport_write(io_addr, 2, 1, pic_ioport_write, s);
614 register_ioport_read(io_addr, 2, 1, pic_ioport_read, s);
615 if (elcr_addr >= 0) {
616 register_ioport_write(elcr_addr, 1, 1, elcr_ioport_write, s);
617 register_ioport_read(elcr_addr, 1, 1, elcr_ioport_read, s);
619 register_savevm("i8259", io_addr, 1, pic_save, pic_load, s);
620 qemu_register_reset(pic_reset, s);
623 void pic_info(void)
625 int i;
626 PicState *s;
628 if (!isa_pic)
629 return;
631 for(i=0;i<2;i++) {
632 s = &isa_pic->pics[i];
633 term_printf("pic%d: irr=%02x imr=%02x isr=%02x hprio=%d irq_base=%02x rr_sel=%d elcr=%02x fnm=%d\n",
634 i, s->irr, s->imr, s->isr, s->priority_add,
635 s->irq_base, s->read_reg_select, s->elcr,
636 s->special_fully_nested_mode);
640 void irq_info(void)
642 #ifndef DEBUG_IRQ_COUNT
643 term_printf("irq statistic code not compiled.\n");
644 #else
645 int i;
646 int64_t count;
648 term_printf("IRQ statistics:\n");
649 for (i = 0; i < 16; i++) {
650 count = irq_count[i];
651 if (count > 0)
652 term_printf("%2d: %" PRId64 "\n", i, count);
654 #endif
657 qemu_irq *i8259_init(qemu_irq parent_irq)
659 PicState2 *s;
661 s = qemu_mallocz(sizeof(PicState2));
662 if (!s)
663 return NULL;
664 pic_init1(0x20, 0x4d0, &s->pics[0]);
665 pic_init1(0xa0, 0x4d1, &s->pics[1]);
666 s->pics[0].elcr_mask = 0xf8;
667 s->pics[1].elcr_mask = 0xde;
668 s->parent_irq = parent_irq;
669 s->pics[0].pics_state = s;
670 s->pics[1].pics_state = s;
671 isa_pic = s;
672 return qemu_allocate_irqs(i8259_set_irq, s, 16);
675 void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func,
676 void *alt_irq_opaque)
678 s->alt_irq_func = alt_irq_func;
679 s->alt_irq_opaque = alt_irq_opaque;