From 884f73fb04e45beaf086e0f821f99e6e37dc6e81 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 19 Mar 2025 20:47:03 +0200 Subject: [PATCH] [HALX86/APIC] Fix interrupt delivery on bare metal Write both high and low 32 bits of ICR in ApicRequestSelfInterrupt. In VMs we get away with only writing the low 32 bits, but actual hardware doesn't always accept that. --- hal/halx86/apic/apic.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hal/halx86/apic/apic.c b/hal/halx86/apic/apic.c index d98288b81e5..be8058bc24d 100644 --- a/hal/halx86/apic/apic.c +++ b/hal/halx86/apic/apic.c @@ -152,7 +152,7 @@ ApicRequestSelfInterrupt(IN UCHAR Vector, UCHAR TriggerMode) ULONG IrrBit = 1UL << VectorLow; /* Setup the command register */ - Icr.Long0 = 0; + Icr.LongLong = 0; Icr.Vector = Vector; Icr.MessageType = APIC_MT_Fixed; Icr.TriggerMode = TriggerMode; @@ -168,7 +168,8 @@ ApicRequestSelfInterrupt(IN UCHAR Vector, UCHAR TriggerMode) IcrStatus.Long0 = ApicRead(APIC_ICR0); } while (IcrStatus.DeliveryStatus); - /* Write the low dword to send the interrupt */ + /* Write high dword first, then low dword to send the interrupt */ + ApicWrite(APIC_ICR1, Icr.Long1); ApicWrite(APIC_ICR0, Icr.Long0); /* Wait until we see the interrupt request. @@ -176,7 +177,7 @@ ApicRequestSelfInterrupt(IN UCHAR Vector, UCHAR TriggerMode) */ while (!(ApicRead(Irr) & IrrBit)) { - NOTHING; + YieldProcessor(); } /* Finally, restore the original interrupt state */