summaryrefslogtreecommitdiff
path: root/sys/arch/amd64/amd64
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-05-19 23:56:22 -0400
committerIan Moffett <ian@osmora.org>2025-05-19 23:56:22 -0400
commit5dfbc067d095b2bbaefad6d77469f4d701bdd539 (patch)
treeea38f2a13cd18a7949046bd1697eade81647d361 /sys/arch/amd64/amd64
parent87013e38d1940ad183d3cdb42224fb6dcd9e7e03 (diff)
kernel/amd64: Deprecate intr_alloc_vector()main
Replace intr_alloc_vector() with a cleaner and more machine independent intr_register() Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys/arch/amd64/amd64')
-rw-r--r--sys/arch/amd64/amd64/intr.c60
-rw-r--r--sys/arch/amd64/amd64/lapic.c2
-rw-r--r--sys/arch/amd64/amd64/machdep.c12
-rw-r--r--sys/arch/amd64/amd64/vector.S197
4 files changed, 249 insertions, 22 deletions
diff --git a/sys/arch/amd64/amd64/intr.c b/sys/arch/amd64/amd64/intr.c
index c31ee3c..1529b1c 100644
--- a/sys/arch/amd64/amd64/intr.c
+++ b/sys/arch/amd64/amd64/intr.c
@@ -31,12 +31,19 @@
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/panic.h>
+#include <sys/cdefs.h>
+#include <sys/syslog.h>
#include <machine/intr.h>
#include <machine/cpu.h>
#include <machine/asm.h>
+#include <machine/ioapic.h>
#include <vm/dynalloc.h>
+#include <string.h>
-static struct intr_entry *intrs[256] = {0};
+#define pr_trace(fmt, ...) kprintf("intr: " fmt, ##__VA_ARGS__)
+#define pr_error(...) pr_trace(__VA_ARGS__)
+
+struct intr_hand *g_intrs[256] = {0};
int
splraise(uint8_t s)
@@ -67,35 +74,58 @@ splx(uint8_t s)
ci->ipl = s;
}
-int
-intr_alloc_vector(const char *name, uint8_t priority)
+void *
+intr_register(const char *name, const struct intr_hand *ih)
{
- size_t vec = MAX(priority << IPL_SHIFT, 0x20);
- struct intr_entry *intr;
+ uint32_t vec = MAX(ih->priority << IPL_SHIFT, 0x20);
+ struct intr_hand *ih_new;
+ size_t name_len;
/* Sanity check */
- if (vec > NELEM(intrs)) {
- return -1;
+ if (vec > NELEM(g_intrs) || name == NULL) {
+ return NULL;
+ }
+
+ ih_new = dynalloc(sizeof(*ih_new));
+ if (ih_new == NULL) {
+ pr_error("could not allocate new interrupt handler\n");
+ return NULL;
}
/*
* Try to allocate an interrupt vector. An IPL is made up
* of 4 bits so there can be 16 vectors per IPL.
+ *
+ * XXX: Vector 0x20 is reserved for the Hyra scheduler and
+ * vector 0x21 is reserved for the CPU halt IPI.
*/
for (int i = vec; i < vec + 16; ++i) {
- if (intrs[i] != NULL) {
+ if (g_intrs[i] != NULL || i < 0x22) {
continue;
}
- intr = dynalloc(sizeof(*intr));
- if (intr == NULL) {
- return -ENOMEM;
+ /* Allocate memory for the name */
+ name_len = strlen(name);
+ ih_new->name = dynalloc(name_len);
+ if (ih_new->name == NULL) {
+ dynfree(ih_new);
+ pr_trace("could not allocate interrupt name\n");
+ return NULL;
}
- intr->priority = priority;
- intrs[i] = intr;
- return i;
+ memcpy(ih_new->name, name, name_len);
+ ih_new->func = ih->func;
+ ih_new->priority = ih->priority;
+ ih_new->irq = ih->irq;
+ ih_new->vector = i;
+ g_intrs[i] = ih_new;
+
+ if (ih->irq >= 0) {
+ ioapic_set_vec(ih->irq, i);
+ ioapic_irq_unmask(ih->irq);
+ }
+ return ih_new;
}
- return -1;
+ return NULL;
}
diff --git a/sys/arch/amd64/amd64/lapic.c b/sys/arch/amd64/amd64/lapic.c
index 70d36a5..022592c 100644
--- a/sys/arch/amd64/amd64/lapic.c
+++ b/sys/arch/amd64/amd64/lapic.c
@@ -340,7 +340,7 @@ lapic_init(void)
/* Allocate a vector if needed */
if (lapic_timer_vec == 0) {
- lapic_timer_vec = intr_alloc_vector("lapictmr", IPL_CLOCK);
+ lapic_timer_vec = (IPL_CLOCK << IPL_SHIFT) | 0x20;
idt_set_desc(lapic_timer_vec, IDT_INT_GATE, ISR(lapic_tmr_isr),
IST_SCHED);
}
diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c
index 4a885fa..da6e554 100644
--- a/sys/arch/amd64/amd64/machdep.c
+++ b/sys/arch/amd64/amd64/machdep.c
@@ -44,6 +44,8 @@
#include <machine/intr.h>
#include <machine/isa/i8042var.h>
+#define HALT_VECTOR 0x21
+
#if defined(__SPECTRE_IBRS)
#define SPECTRE_IBRS __SPECTRE_IBRS
#else
@@ -54,6 +56,7 @@ static uint8_t halt_vector = 0;
int ibrs_enable(void);
void syscall_isr(void);
+void pin_isr_load(void);
struct cpu_info g_bsp_ci = {0};
static struct gdtr bsp_gdtr = {
@@ -72,10 +75,6 @@ cpu_halt_isr(void *p)
static void
setup_vectors(void)
{
- if (halt_vector == 0) {
- halt_vector = intr_alloc_vector("cpu-halt", IPL_HIGH);
- }
-
idt_set_desc(0x0, IDT_TRAP_GATE, ISR(arith_err), 0);
idt_set_desc(0x2, IDT_TRAP_GATE, ISR(nmi), 0);
idt_set_desc(0x3, IDT_TRAP_GATE, ISR(breakpoint_handler), 0);
@@ -89,7 +88,8 @@ setup_vectors(void)
idt_set_desc(0xD, IDT_TRAP_GATE, ISR(general_prot), 0);
idt_set_desc(0xE, IDT_TRAP_GATE, ISR(page_fault), 0);
idt_set_desc(0x80, IDT_USER_INT_GATE, ISR(syscall_isr), 0);
- idt_set_desc(halt_vector, IDT_INT_GATE, ISR(cpu_halt_isr), 0);
+ idt_set_desc(HALT_VECTOR, IDT_INT_GATE, ISR(cpu_halt_isr), 0);
+ pin_isr_load();
}
static inline void
@@ -186,7 +186,7 @@ cpu_halt_others(void)
}
/* Send IPI to all cores */
- lapic_send_ipi(0, IPI_SHORTHAND_OTHERS, halt_vector);
+ lapic_send_ipi(0, IPI_SHORTHAND_OTHERS, HALT_VECTOR);
}
void
diff --git a/sys/arch/amd64/amd64/vector.S b/sys/arch/amd64/amd64/vector.S
new file mode 100644
index 0000000..32ccd34
--- /dev/null
+++ b/sys/arch/amd64/amd64/vector.S
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2023-2025 Ian Marco Moffett and the Osmora Team.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Hyra nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/frameasm.h>
+
+#define IDT_INT_GATE 0x8E
+
+.macro IDT_SET_VEC vec, sym
+ mov $\vec, %rdi
+ mov $IDT_INT_GATE, %rsi
+ lea \sym(%rip), %rdx
+ xor %rcx, %rcx
+ call idt_set_desc
+.endm
+
+ .text
+ ALIGN_TEXT
+ioapic_common_func:
+ xor %rcx, %rcx // Clear counter
+.walk: // Walk the handlers
+ lea g_intrs(%rip), %rbx // Grab table to RBX
+ lea (%rbx, %rcx, 8), %rbx // g_intrs + (8 * rcx)
+ mov (%rbx), %rdx // Grab the intr_hand
+ or %rdx, %rdx // No more?
+ jz 1f // Nope, return
+
+ mov (%rdx), %rbx // intr_hand.func
+ xor %rdi, %rdi // No data
+ call *%rbx // Call the handler
+ or %rax, %rax // Was it theirs? (RET >= 1)
+ jnz done // Yes, we are done.
+1: inc %rcx // Next
+ cmp $256, %rcx // Did we reach the end?
+ jl .walk // Nope, keep going
+done:
+ call lapic_eoi
+ retq
+
+ .globl pin_isr_load
+pin_isr_load:
+ IDT_SET_VEC 34, ioapic_edge_0
+ IDT_SET_VEC 35, ioapic_edge_1
+ IDT_SET_VEC 36, ioapic_edge_2
+ IDT_SET_VEC 37, ioapic_edge_3
+ IDT_SET_VEC 38, ioapic_edge_4
+ IDT_SET_VEC 39, ioapic_edge_5
+ IDT_SET_VEC 40, ioapic_edge_6
+ IDT_SET_VEC 41, ioapic_edge_7
+ IDT_SET_VEC 42, ioapic_edge_8
+ IDT_SET_VEC 43, ioapic_edge_9
+ IDT_SET_VEC 44, ioapic_edge_10
+ IDT_SET_VEC 45, ioapic_edge_11
+ IDT_SET_VEC 46, ioapic_edge_12
+ IDT_SET_VEC 47, ioapic_edge_13
+ IDT_SET_VEC 48, ioapic_edge_14
+ IDT_SET_VEC 49, ioapic_edge_15
+ IDT_SET_VEC 50, ioapic_edge_16
+ IDT_SET_VEC 51, ioapic_edge_17
+ IDT_SET_VEC 52, ioapic_edge_18
+ IDT_SET_VEC 53, ioapic_edge_19
+ IDT_SET_VEC 54, ioapic_edge_20
+ IDT_SET_VEC 55, ioapic_edge_21
+ IDT_SET_VEC 56, ioapic_edge_22
+ IDT_SET_VEC 57, ioapic_edge_23
+ IDT_SET_VEC 58, ioapic_edge_24
+ IDT_SET_VEC 59, ioapic_edge_25
+ IDT_SET_VEC 60, ioapic_edge_26
+ IDT_SET_VEC 61, ioapic_edge_27
+ IDT_SET_VEC 62, ioapic_edge_28
+ IDT_SET_VEC 63, ioapic_edge_29
+ IDT_SET_VEC 64, ioapic_edge_30
+ IDT_SET_VEC 65, ioapic_edge_31
+ IDT_SET_VEC 66, ioapic_edge_32
+ IDT_SET_VEC 67, ioapic_edge_33
+ IDT_SET_VEC 68, ioapic_edge_34
+ IDT_SET_VEC 69, ioapic_edge_35
+ IDT_SET_VEC 70, ioapic_edge_36
+ IDT_SET_VEC 71, ioapic_edge_37
+ IDT_SET_VEC 72, ioapic_edge_38
+ IDT_SET_VEC 73, ioapic_edge_39
+ IDT_SET_VEC 74, ioapic_edge_40
+ IDT_SET_VEC 75, ioapic_edge_41
+ IDT_SET_VEC 76, ioapic_edge_42
+ IDT_SET_VEC 77, ioapic_edge_43
+ IDT_SET_VEC 78, ioapic_edge_44
+ IDT_SET_VEC 79, ioapic_edge_45
+ IDT_SET_VEC 80, ioapic_edge_46
+ IDT_SET_VEC 81, ioapic_edge_47
+ IDT_SET_VEC 82, ioapic_edge_48
+ IDT_SET_VEC 83, ioapic_edge_49
+ IDT_SET_VEC 84, ioapic_edge_50
+ IDT_SET_VEC 85, ioapic_edge_51
+ IDT_SET_VEC 86, ioapic_edge_52
+ IDT_SET_VEC 87, ioapic_edge_53
+ IDT_SET_VEC 88, ioapic_edge_54
+ IDT_SET_VEC 89, ioapic_edge_55
+ IDT_SET_VEC 90, ioapic_edge_56
+ IDT_SET_VEC 91, ioapic_edge_57
+ IDT_SET_VEC 92, ioapic_edge_58
+ IDT_SET_VEC 93, ioapic_edge_59
+ IDT_SET_VEC 94, ioapic_edge_60
+ IDT_SET_VEC 95, ioapic_edge_61
+ IDT_SET_VEC 96, ioapic_edge_62
+ IDT_SET_VEC 97, ioapic_edge_63
+ ret
+
+/* I/O APIC edge ISRs */
+INTRENTRY(ioapic_edge_0, ioapic_common_func)
+INTRENTRY(ioapic_edge_1, ioapic_common_func)
+INTRENTRY(ioapic_edge_2, ioapic_common_func)
+INTRENTRY(ioapic_edge_3, ioapic_common_func)
+INTRENTRY(ioapic_edge_4, ioapic_common_func)
+INTRENTRY(ioapic_edge_5, ioapic_common_func)
+INTRENTRY(ioapic_edge_6, ioapic_common_func)
+INTRENTRY(ioapic_edge_7, ioapic_common_func)
+INTRENTRY(ioapic_edge_8, ioapic_common_func)
+INTRENTRY(ioapic_edge_9, ioapic_common_func)
+INTRENTRY(ioapic_edge_10, ioapic_common_func)
+INTRENTRY(ioapic_edge_11, ioapic_common_func)
+INTRENTRY(ioapic_edge_12, ioapic_common_func)
+INTRENTRY(ioapic_edge_13, ioapic_common_func)
+INTRENTRY(ioapic_edge_14, ioapic_common_func)
+INTRENTRY(ioapic_edge_15, ioapic_common_func)
+INTRENTRY(ioapic_edge_16, ioapic_common_func)
+INTRENTRY(ioapic_edge_17, ioapic_common_func)
+INTRENTRY(ioapic_edge_18, ioapic_common_func)
+INTRENTRY(ioapic_edge_19, ioapic_common_func)
+INTRENTRY(ioapic_edge_20, ioapic_common_func)
+INTRENTRY(ioapic_edge_21, ioapic_common_func)
+INTRENTRY(ioapic_edge_22, ioapic_common_func)
+INTRENTRY(ioapic_edge_23, ioapic_common_func)
+INTRENTRY(ioapic_edge_24, ioapic_common_func)
+INTRENTRY(ioapic_edge_25, ioapic_common_func)
+INTRENTRY(ioapic_edge_26, ioapic_common_func)
+INTRENTRY(ioapic_edge_27, ioapic_common_func)
+INTRENTRY(ioapic_edge_28, ioapic_common_func)
+INTRENTRY(ioapic_edge_29, ioapic_common_func)
+INTRENTRY(ioapic_edge_30, ioapic_common_func)
+INTRENTRY(ioapic_edge_31, ioapic_common_func)
+INTRENTRY(ioapic_edge_32, ioapic_common_func)
+INTRENTRY(ioapic_edge_33, ioapic_common_func)
+INTRENTRY(ioapic_edge_34, ioapic_common_func)
+INTRENTRY(ioapic_edge_35, ioapic_common_func)
+INTRENTRY(ioapic_edge_36, ioapic_common_func)
+INTRENTRY(ioapic_edge_37, ioapic_common_func)
+INTRENTRY(ioapic_edge_38, ioapic_common_func)
+INTRENTRY(ioapic_edge_39, ioapic_common_func)
+INTRENTRY(ioapic_edge_40, ioapic_common_func)
+INTRENTRY(ioapic_edge_41, ioapic_common_func)
+INTRENTRY(ioapic_edge_42, ioapic_common_func)
+INTRENTRY(ioapic_edge_43, ioapic_common_func)
+INTRENTRY(ioapic_edge_44, ioapic_common_func)
+INTRENTRY(ioapic_edge_45, ioapic_common_func)
+INTRENTRY(ioapic_edge_46, ioapic_common_func)
+INTRENTRY(ioapic_edge_47, ioapic_common_func)
+INTRENTRY(ioapic_edge_48, ioapic_common_func)
+INTRENTRY(ioapic_edge_49, ioapic_common_func)
+INTRENTRY(ioapic_edge_50, ioapic_common_func)
+INTRENTRY(ioapic_edge_51, ioapic_common_func)
+INTRENTRY(ioapic_edge_52, ioapic_common_func)
+INTRENTRY(ioapic_edge_53, ioapic_common_func)
+INTRENTRY(ioapic_edge_54, ioapic_common_func)
+INTRENTRY(ioapic_edge_55, ioapic_common_func)
+INTRENTRY(ioapic_edge_56, ioapic_common_func)
+INTRENTRY(ioapic_edge_57, ioapic_common_func)
+INTRENTRY(ioapic_edge_58, ioapic_common_func)
+INTRENTRY(ioapic_edge_59, ioapic_common_func)
+INTRENTRY(ioapic_edge_60, ioapic_common_func)
+INTRENTRY(ioapic_edge_61, ioapic_common_func)
+INTRENTRY(ioapic_edge_62, ioapic_common_func)
+INTRENTRY(ioapic_edge_63, ioapic_common_func)