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 |