From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KV70i-0006w0-FP for qemu-devel@nongnu.org; Mon, 18 Aug 2008 11:51:12 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KV70g-0006vN-5d for qemu-devel@nongnu.org; Mon, 18 Aug 2008 11:51:11 -0400 Received: from [199.232.76.173] (port=60483 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KV70f-0006vG-Sr for qemu-devel@nongnu.org; Mon, 18 Aug 2008 11:51:10 -0400 Received: from fmmailgate03.web.de ([217.72.192.234]:59766) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KV70f-0006IQ-8I for qemu-devel@nongnu.org; Mon, 18 Aug 2008 11:51:09 -0400 Received: from smtp05.web.de (fmsmtp05.dlan.cinetic.de [172.20.4.166]) by fmmailgate03.web.de (Postfix) with ESMTP id 53353E6F7BD0 for ; Mon, 18 Aug 2008 17:51:08 +0200 (CEST) Received: from [88.65.245.41] (helo=[139.25.109.167]) by smtp05.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.109 #226) id 1KV6tQ-0002Hr-00 for qemu-devel@nongnu.org; Mon, 18 Aug 2008 17:43:40 +0200 Message-ID: <48A998AB.5080409@web.de> Date: Mon, 18 Aug 2008 17:43:39 +0200 From: Jan Kiszka MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Sender: jan.kiszka@web.de Subject: [Qemu-devel] [RESEND][PATCH] De-assert PIC IRQs properly at APIC level Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org [in a separate thread as requested by Anthony] 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. Should fix Win64 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 --- hw/apic.c | 23 ++++++++++++++++++++++- hw/pc.c | 5 +---- hw/pc.h | 4 +--- 3 files changed, 24 insertions(+), 8 deletions(-) Index: b/hw/apic.c =================================================================== --- a/hw/apic.c +++ b/hw/apic.c @@ -166,7 +166,7 @@ static inline void reset_bit(uint32_t *t 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, i } } +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;\ Index: b/hw/pc.c =================================================================== --- a/hw/pc.c +++ b/hw/pc.c @@ -118,12 +118,9 @@ static void pic_irq_request(void *opaque { CPUState *env = first_cpu; - 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; } } Index: b/hw/pc.h =================================================================== --- a/hw/pc.h +++ b/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);