fd30fc5e04
Signed-off-by: Chloe M. <chloe@mensia.org>
92 lines
2.0 KiB
C
92 lines
2.0 KiB
C
/*
|
|
* Copyright (c) 2026, Chloe M.
|
|
* Provided under the BSD-3 clause.
|
|
*
|
|
* Description: Local APIC driver
|
|
* Author: Chloe M.
|
|
*/
|
|
|
|
#include <machine/lapic.h>
|
|
#include <machine/lapicreg.h>
|
|
#include <machine/msr.h>
|
|
#include <machine/cpuid.h>
|
|
#include <drivers/acpi/tables.h>
|
|
#include <drivers/acpi/acpi.h>
|
|
#include <mm/vmm.h>
|
|
#include <ex/trace.h>
|
|
#include <ke/knot.h>
|
|
#include <stdef.h>
|
|
|
|
/*
|
|
* Trace only on the bootstrap processor but not on any others
|
|
* to avoid log spam...
|
|
*/
|
|
#define DTRACE_BSP(Fmt, ...) do { \
|
|
ULONG ApicBase; \
|
|
\
|
|
ApicBase = MdRdmsr(IA32_APIC_BASE_MSR); \
|
|
if (ISSET(ApicBase, BIT(8))) { \
|
|
TRACE("[ LAPIC ]: " Fmt, ##__VA_ARGS__); \
|
|
} \
|
|
} while (0);
|
|
|
|
/*
|
|
* Returns true if the Local APIC unit is supported on the
|
|
* current processor.
|
|
*/
|
|
static BOOLEAN
|
|
LapicIsSupported(VOID)
|
|
{
|
|
ULONG Edx, Unused;
|
|
|
|
CPUID(1, Unused, Unused, Unused, Edx);
|
|
return ISSET(Edx, BIT(9)) != 0;
|
|
}
|
|
|
|
/*
|
|
* Enable the Local APIC unit
|
|
*/
|
|
static VOID
|
|
LapicEnable(VOID)
|
|
{
|
|
UQUAD ApicBase;
|
|
|
|
/* Hardware enable the Local APIC unit */
|
|
ApicBase = MdRdmsr(IA32_APIC_BASE_MSR);
|
|
ApicBase |= LAPIC_HW_ENABLE;
|
|
MdWrmsr(IA32_APIC_BASE_MSR, ApicBase);
|
|
}
|
|
|
|
VOID
|
|
MdLapicInit(KPCR *Kpcr)
|
|
{
|
|
ACPI_MADT *Madt;
|
|
MCB *Mcb;
|
|
|
|
if (Kpcr == NULL) {
|
|
KeKnot(
|
|
KNOT_MISC,
|
|
"lapic: failed to initialize lapic driver\n"
|
|
);
|
|
}
|
|
|
|
if (!LapicIsSupported()) {
|
|
KeKnot(
|
|
KNOT_MISSING_HARDWARE,
|
|
"lapic: local apic not supported\n"
|
|
);
|
|
}
|
|
|
|
/* Obtain the ACPI MADT table */
|
|
Madt = AcpiQuery("APIC");
|
|
if (Madt == NULL) {
|
|
KeKnot(KNOT_MISC, "lapic: could not obtain MADT\n");
|
|
}
|
|
|
|
Mcb = &Kpcr->Mcb;
|
|
Mcb->LapicBase = PMA_TO_VMA((UPTR)Madt->LapicAddr);
|
|
|
|
/* Enable the Local APIC */
|
|
LapicEnable();
|
|
}
|