Commit b1fc0348b1ddc935fca98bddc7ee1c8c64e91f0b
1 parent
45bbbb46
EXTINT delivery mode support for I/O APIC (Filip Navara)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1522 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
19 additions
and
11 deletions
hw/apic.c
... | ... | @@ -96,7 +96,6 @@ struct IOAPICState { |
96 | 96 | static int apic_io_memory; |
97 | 97 | static APICState *first_local_apic = NULL; |
98 | 98 | static int last_apic_id = 0; |
99 | -static IOAPICState *ioapic_state; | |
100 | 99 | |
101 | 100 | static void apic_init_ipi(APICState *s); |
102 | 101 | static void apic_set_irq(APICState *s, int vector_num, int trigger_mode); |
... | ... | @@ -127,7 +126,7 @@ static void apic_bus_deliver(uint32_t deliver_bitmask, uint8_t delivery_mode, |
127 | 126 | return; |
128 | 127 | |
129 | 128 | case APIC_DM_EXTINT: |
130 | - /* XXX: implement */ | |
129 | + /* handled in I/O APIC code */ | |
131 | 130 | break; |
132 | 131 | |
133 | 132 | default: |
... | ... | @@ -754,24 +753,34 @@ int apic_init(CPUState *env) |
754 | 753 | |
755 | 754 | static void ioapic_service(IOAPICState *s) |
756 | 755 | { |
756 | + uint8_t i; | |
757 | + uint8_t trig_mode; | |
757 | 758 | uint8_t vector; |
759 | + uint8_t delivery_mode; | |
758 | 760 | uint32_t mask; |
759 | 761 | uint64_t entry; |
760 | 762 | uint8_t dest; |
761 | 763 | uint8_t dest_mode; |
764 | + uint8_t polarity; | |
762 | 765 | |
763 | - for (vector = 0; vector < IOAPIC_NUM_PINS; vector++) { | |
764 | - mask = 1 << vector; | |
766 | + for (i = 0; i < IOAPIC_NUM_PINS; i++) { | |
767 | + mask = 1 << i; | |
765 | 768 | if (s->irr & mask) { |
766 | - entry = s->ioredtbl[vector]; | |
769 | + entry = s->ioredtbl[i]; | |
767 | 770 | if (!(entry & APIC_LVT_MASKED)) { |
768 | - if (!((entry >> 15) & 1)) | |
769 | - s->irr &= ~mask; | |
771 | + trig_mode = ((entry >> 15) & 1); | |
770 | 772 | dest = entry >> 56; |
771 | 773 | dest_mode = (entry >> 11) & 1; |
774 | + delivery_mode = (entry >> 8) & 7; | |
775 | + polarity = (entry >> 13) & 1; | |
776 | + if (trig_mode == APIC_TRIGGER_EDGE) | |
777 | + s->irr &= ~mask; | |
778 | + if (delivery_mode == APIC_DM_EXTINT) | |
779 | + vector = pic_read_irq(isa_pic); | |
780 | + else | |
781 | + vector = entry & 0xff; | |
772 | 782 | apic_bus_deliver(apic_get_delivery_bitmask(dest, dest_mode), |
773 | - (entry >> 8) & 7, entry & 0xff, | |
774 | - (entry >> 13) & 1, (entry >> 15) & 1); | |
783 | + delivery_mode, vector, polarity, trig_mode); | |
775 | 784 | } |
776 | 785 | } |
777 | 786 | } |
... | ... | @@ -930,10 +939,9 @@ IOAPICState *ioapic_init(void) |
930 | 939 | IOAPICState *s; |
931 | 940 | int io_memory; |
932 | 941 | |
933 | - s = malloc(sizeof(IOAPICState)); | |
942 | + s = qemu_mallocz(sizeof(IOAPICState)); | |
934 | 943 | if (!s) |
935 | 944 | return NULL; |
936 | - ioapic_state = s; | |
937 | 945 | ioapic_reset(s); |
938 | 946 | s->id = last_apic_id++; |
939 | 947 | ... | ... |