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 | ... | ... |