stos/amd64: lapic: Add support for IPIs

Signed-off-by: Chloe M. <chloe@mensia.org>
This commit is contained in:
Chloe M.
2026-06-26 22:47:01 +00:00
parent 9f040b7eed
commit 1bebf4d37b
3 changed files with 77 additions and 1 deletions
+58
View File
@@ -11,6 +11,7 @@
#include <machine/msr.h> #include <machine/msr.h>
#include <machine/cpuid.h> #include <machine/cpuid.h>
#include <hal/mmio.h> #include <hal/mmio.h>
#include <hal/prim.h>
#include <drivers/acpi/tables.h> #include <drivers/acpi/tables.h>
#include <drivers/acpi/acpi.h> #include <drivers/acpi/acpi.h>
#include <mm/vmm.h> #include <mm/vmm.h>
@@ -135,9 +136,66 @@ LapicEnable(MCB *Mcb)
DTRACE_BSP("enabled %s %s\n", type, mode); DTRACE_BSP("enabled %s %s\n", type, mode);
} }
VOID
MdLapicSendIpi(UCHAR Vector, UCHAR DestId, BOOLEAN LogicalDest,
IPI_SHORTHAND Xnd, IPI_DELMOD DelMod)
{
KPCR *ThisCore;
MCB *Mcb;
ULONG IcrLow, IcrHigh;
ULONG Icr = 0;
/*
* If the shorthand is refering to ourselves and we are x2APIC we
* can use a better path via its specialized SELF IPI MSR.
*/
ThisCore = HalKpcrCurrent();
if (Xnd == IPI_XND_SELF && Mcb->HasX2Apic) {
MdWrmsr(LAPIC_SELF_IPI, Vector);
return;
}
Mcb = &ThisCore->Mcb;
/* Clamp these fields */
DelMod &= 7;
Xnd &= 3;
/* Encode the ICR */
Icr |= Vector & 0xFF;
Icr |= Xnd << 18;
Icr |= DelMod << 8;
Icr |= LogicalDest << 11;
/* For xAPIC only */
if (!Mcb->HasX2Apic) {
IcrHigh = ((UQUAD)Icr >> 32) & (ULONG)-1;
IcrLow = Icr & (ULONG)-1;
IcrHigh |= (UQUAD)DestId << 24;
LapicRegWrite(Mcb, LAPIC_ICRHI, IcrHigh);
LapicRegWrite(Mcb, LAPIC_ICRLO, IcrLow);
/* Only on legacy xAPICs do we poll */
for (;;) {
Icr = LapicRegRead(Mcb, LAPIC_ICRLO);
if (ISSET(Icr, IPI_DELSTAT_PENDING))
HalCpuSpinWait();
}
return;
}
/* On x2APICs only as it queues */
Icr |= (UQUAD)DestId << 32;
LapicRegWrite(Mcb, LAPIC_ICRLO, Icr);
}
VOID VOID
MdLapicInit(KPCR *Kpcr) MdLapicInit(KPCR *Kpcr)
{ {
INTR_HANDLER Handler;
INTR_DATA *IntrData;
ACPI_MADT *Madt; ACPI_MADT *Madt;
MCB *Mcb; MCB *Mcb;
+16 -1
View File
@@ -51,7 +51,7 @@ typedef enum {
} IPI_DELMOD; } IPI_DELMOD;
/* IPI Delivery status bits */ /* IPI Delivery status bits */
#define IPI_DELSTAT_PENDING BIT(0) #define IPI_DELSTAT_PENDING BIT(12)
/* IPI Destination mode */ /* IPI Destination mode */
#define IPI_DELMOD_LOGICAL BIT(0) #define IPI_DELMOD_LOGICAL BIT(0)
@@ -64,4 +64,19 @@ typedef enum {
*/ */
VOID MdLapicInit(KPCR *Kpcr); VOID MdLapicInit(KPCR *Kpcr);
/*
* Send an inter-processor interrupt
*
* @Vector: Interrupt vector to assign to ICR
* @DestId: Target APIC ID [depends on @LogicalDest]
* @LogicalDest: If true, IPI destination is logical
* @Xnd: Destination shorthand
* @Delmod: Delivery mode
*/
VOID MdLapicSendIpi(
UCHAR Vector, UCHAR DestId,
BOOLEAN LogicalDest, IPI_SHORTHAND Xnd,
IPI_DELMOD DelMod
);
#endif /* !_MACHINE_LAPIC_H_ */ #endif /* !_MACHINE_LAPIC_H_ */
+3
View File
@@ -61,4 +61,7 @@
#define LVT_TMR_PERIODIC 0x01 #define LVT_TMR_PERIODIC 0x01
#define LVT_TMR_TSC_DEADLINE 0x02 #define LVT_TMR_TSC_DEADLINE 0x02
/* MSR for x2APICs only */
#define LAPIC_SELF_IPI 0x083F
#endif /* !_MACHINE_LAPICREG_H_ */ #endif /* !_MACHINE_LAPICREG_H_ */