From f290314f286b70a8f59becedd5f789c21f675b5d Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Thu, 20 Jun 2024 20:35:38 -0400 Subject: kernel/amd64: intr: Add splraise/splx support Signed-off-by: Ian Moffett --- sys/arch/amd64/amd64/intr.c | 63 +++++++++++++++++++++++++++++++++++++++++--- sys/arch/amd64/amd64/lapic.c | 2 +- 2 files changed, 60 insertions(+), 5 deletions(-) (limited to 'sys/arch/amd64') diff --git a/sys/arch/amd64/amd64/intr.c b/sys/arch/amd64/amd64/intr.c index b841da7..3e3f309 100644 --- a/sys/arch/amd64/amd64/intr.c +++ b/sys/arch/amd64/amd64/intr.c @@ -28,16 +28,71 @@ */ #include +#include +#include +#include #include +#include +#include +#include + +static struct intr_entry *intrs[256] = {0}; + +void +splraise(uint8_t s) +{ + struct cpu_info *ci = this_cpu(); + + if (s < ci->ipl) { + panic("splraise IPL less than current IPL\n"); + } + + amd64_write_cr8(s); + ci->ipl = s; +} + +void +splx(uint8_t s) +{ + struct cpu_info *ci = this_cpu(); + + if (s > ci->ipl) { + panic("splx IPL greater than current IPL\n"); + } + + amd64_write_cr8(s); + ci->ipl = s; +} int -intr_alloc_vector(void) +intr_alloc_vector(const char *name, uint8_t priority) { - static size_t vec = 0x21; + size_t vec = MAX(priority << IPL_SHIFT, 0x20); + struct intr_entry *intr; - if (vec >= 0xFF) { + /* Sanity check */ + if (vec > NELEM(intrs)) { return -1; } - return vec++; + /* + * Try to allocate an interrupt vector. An IPL is made up + * of 4 bits so there can be 16 vectors per IPL. + */ + for (int i = vec; i < vec + 16; ++i) { + if (intrs[i] != NULL) { + continue; + } + + intr = dynalloc(sizeof(*intr)); + if (intr == NULL) { + return -ENOMEM; + } + + intr->priority = priority; + intrs[i] = intr; + return i; + } + + return -1; } diff --git a/sys/arch/amd64/amd64/lapic.c b/sys/arch/amd64/amd64/lapic.c index b7cefd4..896c2bd 100644 --- a/sys/arch/amd64/amd64/lapic.c +++ b/sys/arch/amd64/amd64/lapic.c @@ -317,7 +317,7 @@ lapic_init(void) /* Allocate a vector if needed */ if (lapic_timer_vec == 0) { - lapic_timer_vec = intr_alloc_vector(); + lapic_timer_vec = intr_alloc_vector("lapictmr", IPL_CLOCK); idt_set_desc(lapic_timer_vec, IDT_INT_GATE, ISR(lapic_tmr_isr), IST_SCHED); } -- cgit v1.2.3