stos/amd64: hpet: Implement HPET register checking

Signed-off-by: Chloe M. <chloe@mensia.org>
This commit is contained in:
Chloe M.
2026-06-26 14:05:27 -05:00
parent 911e04975c
commit 29de9befc9
2 changed files with 67 additions and 0 deletions
+64
View File
@@ -7,18 +7,64 @@
*/ */
#include <machine/hpet.h> #include <machine/hpet.h>
#include <machine/hpetreg.h>
#include <drivers/acpi/tables.h> #include <drivers/acpi/tables.h>
#include <drivers/acpi/acpi.h> #include <drivers/acpi/acpi.h>
#include <hal/mmio.h>
#include <mm/vmm.h>
#include <ke/knot.h> #include <ke/knot.h>
#include <ex/trace.h> #include <ex/trace.h>
#define DTRACE(Fmt, ...) \ #define DTRACE(Fmt, ...) \
TRACE("[ HPET ]: " Fmt, ##__VA_ARGS__) 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 VOID
MdHpetInit(VOID) MdHpetInit(VOID)
{ {
ACPI_HPET *Hpet; ACPI_HPET *Hpet;
UQUAD GeneralCap;
ULONG ClkPeriod;
UCHAR RevId;
const ACPI_GAS *Gas;
Hpet = AcpiQuery("HPET"); Hpet = AcpiQuery("HPET");
if (Hpet == NULL) { if (Hpet == NULL) {
@@ -32,4 +78,22 @@ MdHpetInit(VOID)
DTRACE("detected hpet with pci vendor id : %x\n", Hpet->PciVendorId); DTRACE("detected hpet with pci vendor id : %x\n", Hpet->PciVendorId);
DTRACE("counter size : %d\n", Hpet->CounterSize); DTRACE("counter size : %d\n", Hpet->CounterSize);
DTRACE("minimum tick : %d\n", Hpet->MinimumTick); 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");
} }
+3
View File
@@ -26,4 +26,7 @@
#define HPET_GCONF_EN BIT(0) #define HPET_GCONF_EN BIT(0)
#define HPET_LEG_RT BIT(1) #define HPET_LEG_RT BIT(1)
/* Max constants */
#define HPET_MAX_CLK_PERIOD 0x5F5E100
#endif /* !_MACHINE_HPETREG_H_ */ #endif /* !_MACHINE_HPETREG_H_ */