APIC, HPET, virtual memory

This commit is contained in:
2025-12-22 19:36:43 +01:00
parent 741d0fb9b0
commit 7b33d0757a
13 changed files with 495 additions and 3 deletions

73
kernel/amd64/hpet.c Normal file
View File

@@ -0,0 +1,73 @@
#include <amd64/hpet.h>
#include <libk/std.h>
#include <limine/requests.h>
#include <sys/debug.h>
#include <sys/mm.h>
#include <uacpi/acpi.h>
#include <uacpi/status.h>
#include <uacpi/tables.h>
#include <uacpi/uacpi.h>
#define HPET_MCVR 0xF0 /* Main Counter Value Register */
#define HPET_GCR 0x10 /* General Configuration Register */
#define HPET_GCIDR 0x00 /* General Capabilities and ID Register */
static bool hpet_32bits = 1;
static uintptr_t hpet_paddr;
static uint64_t hpet_clock_nano;
extern void amd64_spin (void);
static uint64_t amd64_hpet_read (uint32_t reg) {
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
uintptr_t hpet_vaddr = hpet_paddr + (uintptr_t)hhdm->offset;
return (hpet_32bits ? *(volatile uint32_t*)(hpet_vaddr + reg)
: *(volatile uint64_t*)(hpet_vaddr + reg));
}
static void amd64_hpet_write (uint32_t reg, uint64_t value) {
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
uintptr_t hpet_vaddr = hpet_paddr + (uintptr_t)hhdm->offset;
if (hpet_32bits)
*(volatile uint32_t*)(hpet_vaddr + reg) = (value & 0xFFFFFFFF);
else
*(volatile uint64_t*)(hpet_vaddr + reg) = value;
}
static uint64_t amd64_hpet_timestamp (void) {
return amd64_hpet_read (HPET_MCVR);
}
uint64_t amd64_hpet_current_nano (void) {
return amd64_hpet_timestamp () * hpet_clock_nano;
}
void amd64_hpet_sleep_micro (uint64_t us) {
uint64_t start = amd64_hpet_timestamp ();
uint64_t conv = us * 1000;
while (((amd64_hpet_timestamp () - start) * hpet_clock_nano) < conv)
__asm__ volatile ("pause" ::: "memory");
}
void amd64_hpet_init (void) {
struct uacpi_table hpet_table;
uacpi_status status =
uacpi_table_find_by_signature (ACPI_HPET_SIGNATURE, &hpet_table);
if (status != UACPI_STATUS_OK) {
DEBUG ("Could not find HPET table!\n");
amd64_spin ();
}
struct acpi_hpet* hpet = (struct acpi_hpet*)hpet_table.virt_addr;
hpet_paddr = (uintptr_t)hpet->address.address;
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
mm_map_kernel_page (hpet_paddr, (uintptr_t)hhdm->offset + hpet_paddr,
MM_PG_PRESENT | MM_PG_RW);
hpet_32bits = (amd64_hpet_read (HPET_GCIDR) & (1 << 13)) ? 0 : 1;
amd64_hpet_write (HPET_GCR, amd64_hpet_read (HPET_GCR) | 0x01);
hpet_clock_nano = amd64_hpet_read (HPET_GCIDR + 4) / 1000000;
}