Ensure APIC idle state before sending self-IPI
Some checks failed
Builds / ExectOS (amd64, release) (push) Failing after 30s
Builds / ExectOS (i686, release) (push) Failing after 29s
Builds / ExectOS (amd64, debug) (push) Failing after 43s
Builds / ExectOS (i686, debug) (push) Failing after 41s

This commit is contained in:
2026-04-09 23:51:13 +02:00
parent 7d8bfa8f0a
commit 55cb12c978

View File

@@ -418,6 +418,14 @@ XTAPI
VOID VOID
HL::Pic::SendSelfIpi(ULONG Vector) HL::Pic::SendSelfIpi(ULONG Vector)
{ {
BOOLEAN Interrupts;
/* Check whether interrupts are enabled */
Interrupts = AR::CpuFunc::InterruptsEnabled();
/* Disable interrupts */
AR::CpuFunc::ClearInterruptFlag();
/* Check current APIC mode */ /* Check current APIC mode */
if(ApicMode == APIC_MODE_X2APIC) if(ApicMode == APIC_MODE_X2APIC)
{ {
@@ -426,9 +434,30 @@ HL::Pic::SendSelfIpi(ULONG Vector)
} }
else else
{ {
/* Wait for the APIC to clear the delivery status */
while((ReadApicRegister(APIC_ICR0) & 0x1000) != 0)
{
/* Yield the processor */
AR::CpuFunc::YieldProcessor();
}
/* In xAPIC compatibility mode, ICR0 is used */ /* In xAPIC compatibility mode, ICR0 is used */
WriteApicRegister(APIC_ICR0, Vector | (1 << 18)); WriteApicRegister(APIC_ICR0, Vector | (1 << 18));
} }
/* Wait for the APIC to complete delivery of the IPI */
while((ReadApicRegister(APIC_ICR0) & 0x1000) != 0)
{
/* Yield the processor */
AR::CpuFunc::YieldProcessor();
}
/* Check whether interrupts need to be re-enabled */
if(Interrupts)
{
/* Re-enable interrupts */
AR::CpuFunc::SetInterruptFlag();
}
} }
/** /**