summaryrefslogtreecommitdiff
path: root/src/sys
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-10-08 20:41:36 -0400
committerIan Moffett <ian@osmora.org>2025-10-08 20:47:22 -0400
commit51fa2005fe360a9e24ff4fbe43be47eb00d2d67c (patch)
treea30c607d47a183123def45fa5f1125f2c1466c66 /src/sys
parentc34cb71206e00f288821027c9b11d62d4fe75d2e (diff)
kernel/amd64: cpu: Implement 'ioapic_common' stub
This implementation walks through the entire table of registered interrupt handlers and calls each driver handler. The driver is to return a value of 1 if the interrupt is theirs and has been handled, otherwise it is to return 0. The handling core is to respoond to a 1 by exiting the table walk early, and responds to a 0 by continuing. Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'src/sys')
-rw-r--r--src/sys/arch/amd64/cpu/vector.S25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/sys/arch/amd64/cpu/vector.S b/src/sys/arch/amd64/cpu/vector.S
index 9969956..545a08d 100644
--- a/src/sys/arch/amd64/cpu/vector.S
+++ b/src/sys/arch/amd64/cpu/vector.S
@@ -112,10 +112,33 @@ irq_init_pins:
IDT_SET_VEC 100, ioapic_edge_63
retq
-/* XXX: STUB */
ioapic_common:
+ xor %rcx, %rcx // Start at zero
+.walk: // Begin the table walk
+ lea g_intrs(%rip), %rbx // BASE -> RBX
+ lea (%rbx, %rcx, 8), %rbx // RBX+RCX*8 -> RBX
+ mov (%rbx), %rdx // *RBX -> RDX
+ or %rdx, %rdx // Is it NULL?
+ jz 1f // Yes
+
+ mov (%rdx), %rbx // Get the handler
+ or %rbx, %rbx // Can we use this handler?
+ jz 1f // No, continue on
+ push %rcx // Save RCX between CALLs
+ call *%rbx // Indirect call
+ pop %rcx // We need RCX back now
+
+ cmp $0, %rax // Do we continue? (not handled)
+ jg done // Nope, handled
+
+1: inc %rcx // Bump up RCX, next idx
+ cmp $256, %rcx // Are we through every?
+ jl .walk // Nope, continue
+done: // End of loop
+ call lapic_eoi // Signal end of interrupt
retq
+
INTR_ENTRY(ioapic_edge_0)
call ioapic_common
INTR_EXIT(ioapic_edge_0)