Document amd64 platform-specific code

This commit is contained in:
2025-12-30 16:50:15 +01:00
parent 4f4f5c3d2f
commit 34f1e0ba30
17 changed files with 171 additions and 19 deletions

View File

@@ -9,19 +9,34 @@
#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 */
/**
* @file
*
* @brief HPET (High Precision Event Timer) driver code.
* See more at https://wiki.osdev.org/HPET
*/
/// HPET Main Counter Value Register
#define HPET_MCVR 0xF0
/// HPET General Configuration Register
#define HPET_GCR 0x10
/// HPET General Capabilities and ID Register
#define HPET_GCIDR 0x00
/// Set whether we sould use 32-bit or 64-bit reads/writes
static bool hpet_32bits = 1;
/// Physical address for HPET MMIO
static uintptr_t hpet_paddr;
/// HPET nanoseconds for conversion
static uint64_t hpet_clock_nano;
/// Lock, which protects concurrent access. See \ref amd64/smp.c
static spin_lock_t hpet_lock = SPIN_LOCK_INIT;
/** @cond DOXYGEN_IGNORE */
extern void amd64_spin (void);
/** @endcond */
/* These functions assume hpet_lock is held by the caller! */
/// Read a HPET register. Assumes caller holds \ref hpet_lock
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;
@@ -29,6 +44,7 @@ static uint64_t amd64_hpet_read (uint32_t reg) {
: *(volatile uint64_t*)(hpet_vaddr + reg));
}
/// Write a HPET register. Assumes caller holds \ref hpet_lock
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;
@@ -38,8 +54,15 @@ static void amd64_hpet_write (uint32_t reg, uint64_t value) {
*(volatile uint64_t*)(hpet_vaddr + reg) = value;
}
/// Read current value of \ref HPET_MCVR register.
static uint64_t amd64_hpet_timestamp (void) { return amd64_hpet_read (HPET_MCVR); }
/**
* @brief Get current HPET timestamp in nanoseconds
*
* @param lock
* if true, hold \ref hpet_lock
*/
uint64_t amd64_hpet_current_nano (bool lock) {
if (lock)
spin_lock (&hpet_lock);
@@ -52,6 +75,7 @@ uint64_t amd64_hpet_current_nano (bool lock) {
return t;
}
/// Sleep for a given amount of microseconds. This time can last longer due to \ref hpet_lock being held.
void amd64_hpet_sleep_micro (uint64_t us) {
spin_lock (&hpet_lock);
@@ -63,6 +87,7 @@ void amd64_hpet_sleep_micro (uint64_t us) {
spin_unlock (&hpet_lock);
}
/// Initialize HPET
void amd64_hpet_init (void) {
struct uacpi_table hpet_table;
uacpi_status status = uacpi_table_find_by_signature (ACPI_HPET_SIGNATURE, &hpet_table);