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
This commit is contained in:
parent
b614106a17
commit
1a7de94aa4
23
hw/apic.c
23
hw/apic.c
@ -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;\
|
||||
|
4
hw/pc.c
4
hw/pc.c
@ -119,11 +119,9 @@ static void pic_irq_request(void *opaque, int irq, int level)
|
||||
CPUState *env = first_cpu;
|
||||
|
||||
if (env->apic_state) {
|
||||
if (!level)
|
||||
return;
|
||||
while (env) {
|
||||
if (apic_accept_pic_intr(env))
|
||||
apic_local_deliver(env, APIC_LINT0);
|
||||
apic_deliver_pic_intr(env, level);
|
||||
env = env->next_cpu;
|
||||
}
|
||||
} else {
|
||||
|
4
hw/pc.h
4
hw/pc.h
@ -40,11 +40,9 @@ void irq_info(void);
|
||||
/* APIC */
|
||||
typedef struct IOAPICState IOAPICState;
|
||||
|
||||
#define APIC_LINT0 3
|
||||
|
||||
int apic_init(CPUState *env);
|
||||
int apic_accept_pic_intr(CPUState *env);
|
||||
void apic_local_deliver(CPUState *env, int vector);
|
||||
void apic_deliver_pic_intr(CPUState *env, int level);
|
||||
int apic_get_interrupt(CPUState *env);
|
||||
IOAPICState *ioapic_init(void);
|
||||
void ioapic_set_irq(void *opaque, int vector, int level);
|
||||
|
Loading…
x
Reference in New Issue
Block a user