From 29de9befc914cf9e9db0e85ad8bb6ede828e157d Mon Sep 17 00:00:00 2001 From: "Chloe M." Date: Fri, 26 Jun 2026 14:05:27 -0500 Subject: [PATCH] stos/amd64: hpet: Implement HPET register checking Signed-off-by: Chloe M. --- paw/stos/arch/amd64/platform/hpet.c | 64 +++++++++++++++++++++++++++++ paw/stos/head/arch/amd64/hpetreg.h | 3 ++ 2 files changed, 67 insertions(+) diff --git a/paw/stos/arch/amd64/platform/hpet.c b/paw/stos/arch/amd64/platform/hpet.c index cd867ea..b707a7d 100644 --- a/paw/stos/arch/amd64/platform/hpet.c +++ b/paw/stos/arch/amd64/platform/hpet.c @@ -7,18 +7,64 @@ */ #include +#include #include #include +#include +#include #include #include #define DTRACE(Fmt, ...) \ TRACE("[ HPET ]: " Fmt, ##__VA_ARGS__) +static VOID *MMIOBase = NULL; + +/* + * Write a 64-bit value to an HPET register + * + * @Register: Register to write to + * @Value: Value to write + */ +static VOID +HpetWriteq(UCHAR Register, UQUAD Value) +{ + VOID *RegBase; + + if (MMIOBase == NULL) { + return; + } + + RegBase = PTR_OFFSET(MMIOBase, Register); + MMIOWrite64(MMIOBase, Value); +} + +/* + * Read a 64-bit value from an HPET register + * + * @Register: Register to read from + */ +static UQUAD +HpetReadq(UCHAR Register) +{ + VOID *RegBase; + + if (MMIOBase == NULL) { + return 0; + } + + RegBase = PTR_OFFSET(MMIOBase, Register); + return MMIORead64(RegBase); +} + VOID MdHpetInit(VOID) { ACPI_HPET *Hpet; + UQUAD GeneralCap; + ULONG ClkPeriod; + UCHAR RevId; + const ACPI_GAS *Gas; Hpet = AcpiQuery("HPET"); if (Hpet == NULL) { @@ -32,4 +78,22 @@ MdHpetInit(VOID) DTRACE("detected hpet with pci vendor id : %x\n", Hpet->PciVendorId); DTRACE("counter size : %d\n", Hpet->CounterSize); DTRACE("minimum tick : %d\n", Hpet->MinimumTick); + + /* Obtain the MMIO base address */ + Gas = &Hpet->Gas; + MMIOBase = PMA_TO_VMA(Gas->Address); + + GeneralCap = HpetReadq(HPET_GENERAL_CAP); + ClkPeriod = (GeneralCap >> HPET_PERIOD_SHIFT) & HPET_PERIOD_MASK; + RevId = GeneralCap & 0xFF; + DTRACE("counter clk period : %d\n", ClkPeriod); + + /* + * Verify that the clock period and the revision ID are not + * garbage values. + */ + if (ClkPeriod > HPET_MAX_CLK_PERIOD) + KeKnot(KNOT_MISC, "hpet: bad counter clk period\n"); + if (RevId == 0) + KeKnot(KNOT_MISC, "hpet: bad revision id, must not be zero\n"); } diff --git a/paw/stos/head/arch/amd64/hpetreg.h b/paw/stos/head/arch/amd64/hpetreg.h index f57bcfc..fc4b530 100644 --- a/paw/stos/head/arch/amd64/hpetreg.h +++ b/paw/stos/head/arch/amd64/hpetreg.h @@ -26,4 +26,7 @@ #define HPET_GCONF_EN BIT(0) #define HPET_LEG_RT BIT(1) +/* Max constants */ +#define HPET_MAX_CLK_PERIOD 0x5F5E100 + #endif /* !_MACHINE_HPETREG_H_ */