diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-08-21 03:14:52 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-08-21 03:14:52 +0000 |
commit | 1a7de94aa40729b4d7ed8f37c642304866232f40 (patch) | |
tree | e3821425cb282d562bda29df7fbcfa018f512e56 /hw/apic.c | |
parent | b614106a170f77fc83ce9eb3ab0eb88379ee7161 (diff) |
De-assert PIC IRQs properly at APIC level
[ Taking latest isapc changes into account. ]
Ensure that PIC-delivered IRQs are properly de-asserted in case the APIC
is in EXTINT or FIXED mode (with level-triggering selected) on LINT0.
Fixes EFI-BIOS boot issues.
This patch also cleans up a bit the interface between PIC and APIC,
making apic_local_deliver private again.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5041 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/apic.c')
-rw-r--r-- | hw/apic.c | 23 |
1 files changed, 22 insertions, 1 deletions
@@ -166,7 +166,7 @@ static inline void reset_bit(uint32_t *tab, int index) tab[i] &= ~mask; } -void apic_local_deliver(CPUState *env, int vector) +static void apic_local_deliver(CPUState *env, int vector) { APICState *s = env->apic_state; uint32_t lvt = s->lvt[vector]; @@ -197,6 +197,27 @@ void apic_local_deliver(CPUState *env, int vector) } } +void apic_deliver_pic_intr(CPUState *env, int level) +{ + if (level) + apic_local_deliver(env, APIC_LVT_LINT0); + else { + APICState *s = env->apic_state; + uint32_t lvt = s->lvt[APIC_LVT_LINT0]; + + switch ((lvt >> 8) & 7) { + case APIC_DM_FIXED: + if (!(lvt & APIC_LVT_LEVEL_TRIGGER)) + break; + reset_bit(s->irr, lvt & 0xff); + /* fall through */ + case APIC_DM_EXTINT: + cpu_reset_interrupt(env, CPU_INTERRUPT_HARD); + break; + } + } +} + #define foreach_apic(apic, deliver_bitmask, code) \ {\ int __i, __j, __mask;\ |