summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch')
-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
-rw-r--r--sys/arch/amd64/isa/i8042.S37
-rw-r--r--sys/arch/amd64/isa/i8042.c16
-rw-r--r--sys/arch/amd64/pci/pci_machdep.c12
7 files changed, 266 insertions, 70 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)
diff --git a/sys/arch/amd64/isa/i8042.S b/sys/arch/amd64/isa/i8042.S
deleted file mode 100644
index 123d3a5..0000000
--- a/sys/arch/amd64/isa/i8042.S
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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>
-
- .text
- .globl i8042_kb_isr
-INTRENTRY(i8042_kb_isr, handle_kb)
-handle_kb:
- call i8042_kb_event
- retq
diff --git a/sys/arch/amd64/isa/i8042.c b/sys/arch/amd64/isa/i8042.c
index 53679aa..11532ec 100644
--- a/sys/arch/amd64/isa/i8042.c
+++ b/sys/arch/amd64/isa/i8042.c
@@ -211,8 +211,8 @@ dev_send(bool aux, uint8_t data)
return inb(I8042_DATA);
}
-void
-i8042_kb_event(void)
+static int
+i8042_kb_event(void *sp)
{
struct cpu_info *ci;
struct cons_input input;
@@ -234,21 +234,21 @@ i8042_kb_event(void)
done:
ci->irq_mask &= CPU_IRQ(1);
spinlock_release(&isr_lock);
- lapic_eoi();
+ return 1; /* handled */
}
static void
i8042_en_intr(void)
{
uint8_t conf;
- int vec;
+ struct intr_hand ih;
i8042_write(I8042_CMD, I8042_DISABLE_PORT0);
- vec = intr_alloc_vector("i8042-kb", IPL_BIO);
- idt_set_desc(vec, IDT_INT_GATE, ISR(i8042_kb_isr), IST_HW_IRQ);
- ioapic_set_vec(KB_IRQ, vec);
- ioapic_irq_unmask(KB_IRQ);
+ ih.func = i8042_kb_event;
+ ih.priority = IPL_BIO;
+ ih.irq = KB_IRQ;
+ intr_register("i8042-kb", &ih);
/* Setup config bits */
conf = i8042_read_conf();
diff --git a/sys/arch/amd64/pci/pci_machdep.c b/sys/arch/amd64/pci/pci_machdep.c
index 43065b0..7eaee6a 100644
--- a/sys/arch/amd64/pci/pci_machdep.c
+++ b/sys/arch/amd64/pci/pci_machdep.c
@@ -163,6 +163,7 @@ pci_enable_msix(struct pci_device *dev, const struct msi_intr *intr)
{
volatile uint64_t *tbl;
struct cpu_info *ci;
+ struct intr_hand ih, *ih_res;
uint32_t data, msg_ctl;
uint64_t msg_addr, tmp;
uint16_t tbl_off;
@@ -184,9 +185,14 @@ pci_enable_msix(struct pci_device *dev, const struct msi_intr *intr)
tbl = (void *)((dev->bar[bir] & PCI_BAR_MEMMASK) + MMIO_OFFSET);
tbl = (void *)((char *)tbl + tbl_off);
- /* Get the vector and setup handler */
- vector = intr_alloc_vector(intr->name, IPL_BIO);
- idt_set_desc(vector, IDT_INT_GATE, ISR(intr->handler), 0);
+ ih.func = intr->handler;
+ ih.priority = IPL_BIO;
+ ih.irq = -1;
+ ih_res = intr_register(intr->name, &ih);
+ if (ih_res == NULL) {
+ return -EIO;
+ }
+ vector = ih_res->vector;
/*
* Setup the message data at bits 95:64 of the message