From 5b5c08a1054d4353b8b4d8f7deb5d25f6ff7e361 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Tue, 25 Feb 2025 04:07:30 +0100 Subject: [PATCH] kern: Initial support for the HPET --- kernel/main.v | 15 ++++++ kernel/modules/acpi/acpi.v | 12 ----- kernel/modules/{acpi => uacpi}/uacpi.v | 12 ++--- kernel/modules/x86/hpet/hpet.v | 66 ++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 20 deletions(-) rename kernel/modules/{acpi => uacpi}/uacpi.v (97%) create mode 100644 kernel/modules/x86/hpet/hpet.v diff --git a/kernel/main.v b/kernel/main.v index f6a3284b9..ff42b1c2c 100644 --- a/kernel/main.v +++ b/kernel/main.v @@ -9,6 +9,7 @@ import lib.stubs import memory import term import acpi +import uacpi import x86.gdt import x86.idt import x86.isr @@ -35,6 +36,7 @@ import dev.mouse import syscall.table import socket import time +import x86.hpet import limine #include @@ -120,6 +122,19 @@ pub fn kmain() { // ACPI init acpi.initialise() + hpet.initialise() + + mut uacpi_status := uacpi.UACPIStatus.ok + + uacpi_status = C.uacpi_initialize(0) + if uacpi_status != uacpi.UACPIStatus.ok { + panic('uacpi_initialize(): ${C.uacpi_status_to_string(uacpi_status)}') + } + + uacpi_status = C.uacpi_namespace_load() + if uacpi_status != uacpi.UACPIStatus.ok { + panic('uacpi_namespace_load(): ${C.uacpi_status_to_string(uacpi_status)}') + } smp.initialise() diff --git a/kernel/modules/acpi/acpi.v b/kernel/modules/acpi/acpi.v index d27703336..a77832066 100644 --- a/kernel/modules/acpi/acpi.v +++ b/kernel/modules/acpi/acpi.v @@ -85,18 +85,6 @@ pub fn initialise() { } madt_init() - - mut uacpi_status := UACPIStatus.ok - - uacpi_status = C.uacpi_initialize(0) - if uacpi_status != UACPIStatus.ok { - panic('uacpi_initialize(): ${C.uacpi_status_to_string(uacpi_status)}') - } - - uacpi_status = C.uacpi_namespace_load() - if uacpi_status != UACPIStatus.ok { - panic('uacpi_namespace_load(): ${C.uacpi_status_to_string(uacpi_status)}') - } } pub fn find_sdt(signature string, index int) !voidptr { diff --git a/kernel/modules/acpi/uacpi.v b/kernel/modules/uacpi/uacpi.v similarity index 97% rename from kernel/modules/acpi/uacpi.v rename to kernel/modules/uacpi/uacpi.v index 24fdd3728..1e67d6258 100644 --- a/kernel/modules/acpi/uacpi.v +++ b/kernel/modules/uacpi/uacpi.v @@ -1,4 +1,4 @@ -module acpi +module uacpi import klock import event @@ -9,12 +9,9 @@ import memory import lib import kprint import lib.stubs +import x86.hpet -//#include -//#include - -@[typedef] -enum UACPIStatus { +pub enum UACPIStatus { ok = 0 mapping_failed = 1 out_of_memory = 2 @@ -248,8 +245,7 @@ pub fn uacpi_kernel_unmap(addr voidptr, len u64) { @[export: 'uacpi_kernel_get_nanoseconds_since_boot'] pub fn uacpi_kernel_get_nanoseconds_since_boot() u64 { - clock := monotonic_clock - return u64(clock.tv_sec * 1000000000 + clock.tv_nsec) + return hpet.read_counter() * (1000000000 / hpet_frequency) } @[export: 'uacpi_kernel_io_map'] diff --git a/kernel/modules/x86/hpet/hpet.v b/kernel/modules/x86/hpet/hpet.v new file mode 100644 index 000000000..e0703ac8b --- /dev/null +++ b/kernel/modules/x86/hpet/hpet.v @@ -0,0 +1,66 @@ +module hpet + +import acpi +import x86.kio + +@[packed] +pub struct HPETTable { +pub mut: + header acpi.SDT + + hardware_rev_id u8 + misc_bits u8 + pci_vendor_id u16 + address_space_id u8 + register_bit_width u8 + register_bit_offset u8 + reserved1 u8 + address u64 + hpet_number u8 + minimum_tick u16 + page_protection u8 +} + +pub struct HPET { +pub mut: + general_capabilities u64 + unused0 u64 + general_configuration u64 + unused1 u64 + general_int_status u64 + unused2 u64 + unused3 [24]u64 + main_counter_value u64 + unused4 u64 +} + +__global ( + hpet &HPET + hpet_frequency u64 +) + +pub fn read_counter() u64 { + return kio.mmin(&hpet.main_counter_value) +} + +pub fn initialise() { + hpet_table := unsafe { &HPETTable(acpi.find_sdt('HPET', 0) or { + panic('HPET ACPI table not found') + }) } + + hpet = &HPET(hpet_table.address + higher_half) + + mut tmp := kio.mmin(&hpet.general_capabilities) + + counter_clk_period := tmp >> 32; + hpet_frequency = u64(1000000000000000) / counter_clk_period + + println('hpet: Detected frequency of ${hpet_frequency} Hz') + + kio.mmout(&hpet.main_counter_value, 0) + + println('hpet: Enabling') + tmp = kio.mmin(&hpet.general_configuration) + tmp |= 0b01 + kio.mmout(&hpet.general_configuration, tmp) +}