Generated docs using doxygen and mkdocs

This commit is contained in:
2025-12-30 01:47:29 +01:00
parent fa7998c323
commit b279774bd6
19 changed files with 7138 additions and 8 deletions

View File

@@ -15,35 +15,51 @@
#define IOAPICS_MAX 24
#define INTERRUPT_SRC_OVERRIDES_MAX 24
#define LAPIC_ID 0x20 /* ID */
#define LAPIC_EOI 0xB0 /* End of interrupt */
#define LAPIC_SIVR 0xF0 /* Spurious interrupt vector register */
#define LAPIC_ICR 0x300 /* Interrupt command register */
#define LAPIC_LVTTR 0x320 /* LVT timer register */
#define LAPIC_TIMICT 0x380 /* Initial count register */
#define LAPIC_TIMCCT 0x390 /* Current count register */
#define LAPIC_DCR 0x3E0 /* Divide config register */
/// ID of Local APIC
#define LAPIC_ID 0x20
/// End of interrupt register
#define LAPIC_EOI 0xB0
/// Spurious interrupt vector register
#define LAPIC_SIVR 0xF0
/// Interrupt command register
#define LAPIC_ICR 0x300
/// LVT timer register
#define LAPIC_LVTTR 0x320
/// Timer initial count register
#define LAPIC_TIMICT 0x380
/// Timer current count register
#define LAPIC_TIMCCT 0x390
/// Divide config register
#define LAPIC_DCR 0x3E0
/// Table of IOAPICS
static struct acpi_madt_ioapic apics[IOAPICS_MAX];
/* clang-format off */
/// Table of interrupt source overrides
static struct acpi_madt_interrupt_source_override intr_src_overrides[INTERRUPT_SRC_OVERRIDES_MAX];
/* clang-format on */
/// Count of actual IOAPIC entries
static size_t ioapic_entries = 0;
/// Count of actual interrupt source overrides
static size_t intr_src_override_entries = 0;
/// Local APIC MMIO base address. It comes from MSR_APIC_BASE
static uintptr_t lapic_mmio_base = 0;
extern void amd64_spin (void);
/// Read IOAPIC
static uint32_t amd64_ioapic_read (uintptr_t vaddr, uint32_t reg) {
*(volatile uint32_t*)vaddr = reg;
return *(volatile uint32_t*)(vaddr + 0x10);
}
/// Write IOAPIC
static void amd64_ioapic_write (uintptr_t vaddr, uint32_t reg, uint32_t value) {
*(volatile uint32_t*)vaddr = reg;
*(volatile uint32_t*)(vaddr + 0x10) = value;
}
/// Find an IOAPIC corresposting to provided IRQ
static struct acpi_madt_ioapic* amd64_ioapic_find (uint8_t irq) {
struct acpi_madt_ioapic* apic = NULL;
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
@@ -60,6 +76,22 @@ static struct acpi_madt_ioapic* amd64_ioapic_find (uint8_t irq) {
return NULL;
}
/**
* @brief Route IRQ to an IDT entry of a given Local APIC.
*
* @param vec
* Interrupt vector number, which will be delivered to the CPU
*
* @param irq
* Legacy IRQ number to be routed. Can be changed by an interrupt source override
* into a different GSI.
*
* @param flags
* IOAPIC redirection flags.
*
* @param lapic_id
* Local APIC that will receive the interrupt.
*/
void amd64_ioapic_route_irq (uint8_t vec, uint8_t irq, uint64_t flags, uint64_t lapic_id) {
struct acpi_madt_ioapic* apic = NULL;
struct acpi_madt_interrupt_source_override* override;
@@ -101,6 +133,7 @@ void amd64_ioapic_route_irq (uint8_t vec, uint8_t irq, uint64_t flags, uint64_t
(uint32_t)(calc_flags >> 32));
}
/// Mask a given IRQ
void amd64_ioapic_mask (uint8_t irq) {
struct acpi_madt_ioapic* apic;
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
@@ -117,6 +150,7 @@ void amd64_ioapic_mask (uint8_t irq) {
value | (1 << 16));
}
/// Unmask a given IRQ
void amd64_ioapic_unmask (uint8_t irq) {
struct acpi_madt_ioapic* apic;
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
@@ -133,6 +167,7 @@ void amd64_ioapic_unmask (uint8_t irq) {
value & ~(1 << 16));
}
/// Find and initialize the IOAPIC
void amd64_ioapic_init (void) {
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
@@ -170,22 +205,36 @@ void amd64_ioapic_init (void) {
}
}
/// Get MMIO base of Local APIC
static uintptr_t amd64_lapic_base (void) { return lapic_mmio_base; }
/// Write Local APIC
static void amd64_lapic_write (uint32_t reg, uint32_t value) {
*(volatile uint32_t*)(amd64_lapic_base () + reg) = value;
}
/// Read Local APIC
static uint32_t amd64_lapic_read (uint32_t reg) {
return *(volatile uint32_t*)(amd64_lapic_base () + reg);
}
/// Get ID of Local APIC
uint32_t amd64_lapic_id (void) { return amd64_lapic_read (LAPIC_ID) >> 24; }
/// Send End of interrupt command to Local APIC
void amd64_lapic_eoi (void) { amd64_lapic_write (LAPIC_EOI, 0); }
/// Set initial counter value in Local APIC timer
void amd64_lapic_tick (uint32_t tick) { amd64_lapic_write (LAPIC_TIMICT, tick); }
/**
* @brief Calibrate Local APIC to send interrupts in a set interval.
*
* @param us
* Period length in microseconds
*
* @return amount of ticsk in a given period
*/
static uint32_t amd64_lapic_calibrate (uint32_t us) {
amd64_lapic_write (LAPIC_DCR, 0x03);
@@ -200,6 +249,13 @@ static uint32_t amd64_lapic_calibrate (uint32_t us) {
return ticks;
}
/**
* @brief Starts a Local APIC, configures LVT timer to
* send interrupts at \ref SCHED_PREEMPT_TIMER.
*
* @param ticks
* Initial tick count
*/
static void amd64_lapic_start (uint32_t ticks) {
amd64_lapic_write (LAPIC_DCR, 0x03);
@@ -208,6 +264,10 @@ static void amd64_lapic_start (uint32_t ticks) {
amd64_lapic_write (LAPIC_TIMICT, ticks);
}
/**
* @brief Initialize Local APIC, configure to send timer interrupts
* at a given period. See \ref amd64_lapic_calibrate and \ref amd64_lapic_start.
*/
uint64_t amd64_lapic_init (uint32_t us) {
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
@@ -228,6 +288,15 @@ uint64_t amd64_lapic_init (uint32_t us) {
return ticks;
}
/**
* @brief Send an IPI to a given Local APIC. This till invoke an IDT stub located at vec.
*
* @param lapic_id
* Target Local APIC
*
* @param vec
* Interrupt vector/IDT stub, which will be invoked by the IPI.
*/
void amd64_lapic_ipi (uint8_t lapic_id, uint8_t vec) {
amd64_lapic_write (LAPIC_ICR + 0x10, (lapic_id << 24));
amd64_lapic_write (LAPIC_ICR, vec);