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,7 +96,6 @@ struct IOAPICState { | ||
96 | static int apic_io_memory; | 96 | static int apic_io_memory; |
97 | static APICState *first_local_apic = NULL; | 97 | static APICState *first_local_apic = NULL; |
98 | static int last_apic_id = 0; | 98 | static int last_apic_id = 0; |
99 | -static IOAPICState *ioapic_state; | ||
100 | 99 | ||
101 | static void apic_init_ipi(APICState *s); | 100 | static void apic_init_ipi(APICState *s); |
102 | static void apic_set_irq(APICState *s, int vector_num, int trigger_mode); | 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,7 +126,7 @@ static void apic_bus_deliver(uint32_t deliver_bitmask, uint8_t delivery_mode, | ||
127 | return; | 126 | return; |
128 | 127 | ||
129 | case APIC_DM_EXTINT: | 128 | case APIC_DM_EXTINT: |
130 | - /* XXX: implement */ | 129 | + /* handled in I/O APIC code */ |
131 | break; | 130 | break; |
132 | 131 | ||
133 | default: | 132 | default: |
@@ -754,24 +753,34 @@ int apic_init(CPUState *env) | @@ -754,24 +753,34 @@ int apic_init(CPUState *env) | ||
754 | 753 | ||
755 | static void ioapic_service(IOAPICState *s) | 754 | static void ioapic_service(IOAPICState *s) |
756 | { | 755 | { |
756 | + uint8_t i; | ||
757 | + uint8_t trig_mode; | ||
757 | uint8_t vector; | 758 | uint8_t vector; |
759 | + uint8_t delivery_mode; | ||
758 | uint32_t mask; | 760 | uint32_t mask; |
759 | uint64_t entry; | 761 | uint64_t entry; |
760 | uint8_t dest; | 762 | uint8_t dest; |
761 | uint8_t dest_mode; | 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 | if (s->irr & mask) { | 768 | if (s->irr & mask) { |
766 | - entry = s->ioredtbl[vector]; | 769 | + entry = s->ioredtbl[i]; |
767 | if (!(entry & APIC_LVT_MASKED)) { | 770 | if (!(entry & APIC_LVT_MASKED)) { |
768 | - if (!((entry >> 15) & 1)) | ||
769 | - s->irr &= ~mask; | 771 | + trig_mode = ((entry >> 15) & 1); |
770 | dest = entry >> 56; | 772 | dest = entry >> 56; |
771 | dest_mode = (entry >> 11) & 1; | 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 | apic_bus_deliver(apic_get_delivery_bitmask(dest, dest_mode), | 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,10 +939,9 @@ IOAPICState *ioapic_init(void) | ||
930 | IOAPICState *s; | 939 | IOAPICState *s; |
931 | int io_memory; | 940 | int io_memory; |
932 | 941 | ||
933 | - s = malloc(sizeof(IOAPICState)); | 942 | + s = qemu_mallocz(sizeof(IOAPICState)); |
934 | if (!s) | 943 | if (!s) |
935 | return NULL; | 944 | return NULL; |
936 | - ioapic_state = s; | ||
937 | ioapic_reset(s); | 945 | ioapic_reset(s); |
938 | s->id = last_apic_id++; | 946 | s->id = last_apic_id++; |
939 | 947 |