From 4ade8ff9e6c4185ebe45ecfe183668f28e1525b7 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Sat, 16 Sep 2023 20:48:28 +0200 Subject: kernel/amd64: add HPET support, slightly rework time handling --- src/kernel/arch/amd64/acpi.c | 68 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/kernel/arch/amd64/acpi.c (limited to 'src/kernel/arch/amd64/acpi.c') diff --git a/src/kernel/arch/amd64/acpi.c b/src/kernel/arch/amd64/acpi.c new file mode 100644 index 0000000..cc7791f --- /dev/null +++ b/src/kernel/arch/amd64/acpi.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include + +typedef struct { + char sig[8]; + uint8_t checksum; + char oemid[6]; + uint8_t rev; + uint32_t rsdt; +} __attribute__((packed)) RDSP; + +typedef struct { + char sig[4]; + uint32_t len; + uint8_t rev; + uint8_t checksum; + char oemID[6]; + char oemTID[8]; + uint32_t oemRev; + uint32_t creatorId; + uint32_t creatorRev; + char data[0]; +} __attribute__((packed)) SDT; + +/* https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/software-developers-hpet-spec-1-0a.pdf */ +typedef struct { + uint8_t where; + uint8_t bitwidth; + uint8_t bitoffset; + uint8_t _reserved; + uint64_t addr; +} __attribute__((packed)) GAS; /* Generic Address Structure */ + +typedef struct { + SDT hdr; + uint32_t _someid; + GAS addr; + /* ... */ +} __attribute__((packed)) HPET; + +void +acpi_parse(const void *rdsp_v) +{ + const RDSP *rdsp = rdsp_v; + if (memcmp(rdsp->sig, "RSD PTR ", 8) != 0) { + panic_invalid_state(); + } + + SDT *rsdt = (void*)(uintptr_t)rdsp->rsdt; + if (memcmp(rsdt->sig, "RSDT ", 4) != 0) { + panic_invalid_state(); + } + + uint32_t *sub = (void*)rsdt->data; + int len = (rsdt->len - sizeof(SDT)) / 4; + for (int i = 0; i < len; i++) { + SDT *it = (void*)(uintptr_t)sub[i]; + if (memcmp(it->sig, "HPET", 4) == 0) { + HPET *hpet = (void*)it; + GAS *gas = &hpet->addr; + if (gas->where == 0) { /* in memory */ + hpet_init((void*)gas->addr); + } + } + } +} -- cgit v1.2.3