From 0527ef090e4a5ff2dd8dc32170d505c44ee015fa Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Tue, 18 Nov 2025 16:05:25 -0500 Subject: kern/amd64: lapic: Add Local APIC timer interface This commit adds an interface to perform a oneshot operation with the Local APIC timer as well as providing a stub interrupt service routine for it. Signed-off-by: Ian Moffett --- sys/arch/amd64/cpu/idt.S | 9 +++++++++ sys/arch/amd64/cpu/lapic.c | 24 ++++++++++++++++++++++++ sys/inc/arch/amd64/lapic.h | 7 +++++++ 3 files changed, 40 insertions(+) (limited to 'sys') diff --git a/sys/arch/amd64/cpu/idt.S b/sys/arch/amd64/cpu/idt.S index c430a44..729d958 100644 --- a/sys/arch/amd64/cpu/idt.S +++ b/sys/arch/amd64/cpu/idt.S @@ -306,6 +306,15 @@ page_fault: jmp 1b hlt + .globl lapic_tmr_isr +lapic_tmr_isr: + KFENCE + push_frame 0x81 + nop + pop_frame 0x81 + KFENCE + iretq + .section .data .align 8 IDT: diff --git a/sys/arch/amd64/cpu/lapic.c b/sys/arch/amd64/cpu/lapic.c index acf2573..076ddd3 100644 --- a/sys/arch/amd64/cpu/lapic.c +++ b/sys/arch/amd64/cpu/lapic.c @@ -43,6 +43,7 @@ #include #include #include +#include #define dtrace(fmt, ...) trace("lapic: " fmt, ##__VA_ARGS__) @@ -82,6 +83,7 @@ /* Accessed via RDMSR/WRMSR */ #define X2APIC_MSR_BASE 0x00000800 +extern void lapic_tmr_isr(void); static struct acpi_madt *madt; /* @@ -337,6 +339,17 @@ lapic_enable(struct mcb *mcb) lapic_write(mcb, LAPIC_REG_SVR, svr | 0xFF); } +static void +lapic_timer_oneshot(struct mcb *mcb, size_t count) +{ + if (mcb == NULL) { + return; + } + + lapic_tmr_enable(mcb, LAPIC_TMR_ONESHOT); + lapic_write(mcb, LAPIC_REG_TICR, count); +} + uint32_t lapic_read_id(struct mcb *mcb) { @@ -349,6 +362,16 @@ lapic_read_id(struct mcb *mcb) } } +void +lapic_oneshot_usec(struct mcb *mcb, size_t usec) +{ + if (mcb == NULL) { + return; + } + + lapic_timer_oneshot(mcb, mcb->lapic_tmr_freq / 1000000); +} + void lapic_init(void) { @@ -375,4 +398,5 @@ lapic_init(void) lapic_enable(mcb); mcb->lapic_tmr_freq = lapic_tmr_clbr(mcb); + idt_set_gate(LAPIC_TMR_VEC, INT_GATE, (uintptr_t)lapic_tmr_isr, 0); } diff --git a/sys/inc/arch/amd64/lapic.h b/sys/inc/arch/amd64/lapic.h index 35ba778..d22a560 100644 --- a/sys/inc/arch/amd64/lapic.h +++ b/sys/inc/arch/amd64/lapic.h @@ -31,6 +31,7 @@ #define _MACHINE_LAPIC_H_ 1 #include +#include #include #define LAPIC_TMR_VEC 0x81 @@ -90,6 +91,12 @@ struct lapic_ipi { uint8_t logical_dest : 1; }; +/* + * Put the local APIC timer in one shot mode and fire it + * off + */ +void lapic_oneshot_usec(struct mcb *mcb, size_t usec); + /* * Read the current local APIC id */ -- cgit v1.2.3