stos/amd64: hpet: Implement HPET register checking
Signed-off-by: Chloe M. <chloe@mensia.org>
This commit is contained in:
@@ -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");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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_ */
|
||||||
|
|||||||
Reference in New Issue
Block a user