stos/amd64: lapic: Add support for IPIs
Signed-off-by: Chloe M. <chloe@mensia.org>
This commit is contained in:
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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_ */
|
||||||
|
|||||||
@@ -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_ */
|
||||||
|
|||||||
Reference in New Issue
Block a user