[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.
This commit is contained in:
Timo Kreuzer 2025-03-19 20:47:03 +02:00
parent 0f6e982ad7
commit 884f73fb04

View file

@ -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 */