diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2005-07-23 21:43:15 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2005-07-23 21:43:15 +0000 |
commit | b1fc0348b1ddc935fca98bddc7ee1c8c64e91f0b (patch) | |
tree | 9b7f0b7d29ee252a059b9a268cb215617d22af67 /hw/apic.c | |
parent | 45bbbb466cf4a6280076ea5a51f67ef5bedee345 (diff) | |
download | qemu-b1fc0348b1ddc935fca98bddc7ee1c8c64e91f0b.zip qemu-b1fc0348b1ddc935fca98bddc7ee1c8c64e91f0b.tar.gz qemu-b1fc0348b1ddc935fca98bddc7ee1c8c64e91f0b.tar.bz2 |
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
Diffstat (limited to 'hw/apic.c')
-rw-r--r-- | hw/apic.c | 30 |
1 files changed, 19 insertions, 11 deletions
@@ -96,7 +96,6 @@ struct IOAPICState { static int apic_io_memory; static APICState *first_local_apic = NULL; static int last_apic_id = 0; -static IOAPICState *ioapic_state; static void apic_init_ipi(APICState *s); 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, return; case APIC_DM_EXTINT: - /* XXX: implement */ + /* handled in I/O APIC code */ break; default: @@ -754,24 +753,34 @@ int apic_init(CPUState *env) static void ioapic_service(IOAPICState *s) { + uint8_t i; + uint8_t trig_mode; uint8_t vector; + uint8_t delivery_mode; uint32_t mask; uint64_t entry; uint8_t dest; uint8_t dest_mode; + uint8_t polarity; - for (vector = 0; vector < IOAPIC_NUM_PINS; vector++) { - mask = 1 << vector; + for (i = 0; i < IOAPIC_NUM_PINS; i++) { + mask = 1 << i; if (s->irr & mask) { - entry = s->ioredtbl[vector]; + entry = s->ioredtbl[i]; if (!(entry & APIC_LVT_MASKED)) { - if (!((entry >> 15) & 1)) - s->irr &= ~mask; + trig_mode = ((entry >> 15) & 1); dest = entry >> 56; dest_mode = (entry >> 11) & 1; + delivery_mode = (entry >> 8) & 7; + polarity = (entry >> 13) & 1; + if (trig_mode == APIC_TRIGGER_EDGE) + s->irr &= ~mask; + if (delivery_mode == APIC_DM_EXTINT) + vector = pic_read_irq(isa_pic); + else + vector = entry & 0xff; apic_bus_deliver(apic_get_delivery_bitmask(dest, dest_mode), - (entry >> 8) & 7, entry & 0xff, - (entry >> 13) & 1, (entry >> 15) & 1); + delivery_mode, vector, polarity, trig_mode); } } } @@ -930,10 +939,9 @@ IOAPICState *ioapic_init(void) IOAPICState *s; int io_memory; - s = malloc(sizeof(IOAPICState)); + s = qemu_mallocz(sizeof(IOAPICState)); if (!s) return NULL; - ioapic_state = s; ioapic_reset(s); s->id = last_apic_id++; |