summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-11-15 15:24:14 -0500
committerIan Moffett <ian@osmora.org>2025-11-15 15:31:12 -0500
commitdc4438100c35afcbf7d997d3ee9126eef57d1e4a (patch)
treef7eadd642c13f07bdba09c0d51007f84c83743c3 /sys/arch
parentf248217b5db26c0a8de07be26a4adbb169b51e17 (diff)
kern/amd64: cpu: Load IDT
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/amd64/cpu/boot.S2
-rw-r--r--sys/arch/amd64/cpu/idt.S294
2 files changed, 296 insertions, 0 deletions
diff --git a/sys/arch/amd64/cpu/boot.S b/sys/arch/amd64/cpu/boot.S
index a6961be..ba54e74 100644
--- a/sys/arch/amd64/cpu/boot.S
+++ b/sys/arch/amd64/cpu/boot.S
@@ -30,6 +30,7 @@
.globl _start
.extern uart_init
.extern uart_write
+ .extern idt_load
.extern gdt_load
.extern GDTR
_start:
@@ -41,6 +42,7 @@ _start:
lea GDTR(%rip), %rdi /* Our GDTR */
call gdt_load /* Load our GDT */
+ call idt_load /* Load our IDT */
lea bootmsg(%rip), %rdi
movq bootmsg_len, %rsi
diff --git a/sys/arch/amd64/cpu/idt.S b/sys/arch/amd64/cpu/idt.S
new file mode 100644
index 0000000..c13adbd
--- /dev/null
+++ b/sys/arch/amd64/cpu/idt.S
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#define KERNEL_CS 0x08
+
+#define INT_GATE 0x8E
+#define TRAP_GATE 0x8F
+
+.macro set_trap vector, isr
+ movq \vector, %rdi
+ movq $TRAP_GATE, %rsi
+ leaq \isr(%rip), %rdx
+ xorq %rcx, %rcx
+ callq idt_set_gate
+.endm
+
+.macro push_frame vector
+.if \vector == 10 || \vector == 11 || \vector == 12 || \vector == 13 || \vector == 14
+ subq $8, %rsp
+.endif
+ pushq %rax
+ pushq %rcx
+ pushq %rdx
+ pushq %rbx
+ pushq %rsi
+ pushq %rdi
+ pushq %rbp
+ pushq %r8
+ pushq %r9
+ pushq %r10
+ pushq %r11
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ pushq $\vector
+.endm
+
+.macro pop_frame vector
+ add $8, %rsp
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %r11
+ popq %r10
+ popq %r9
+ popq %r8
+ popq %rbp
+ popq %rdi
+ popq %rsi
+ popq %rbx
+ popq %rdx
+ popq %rcx
+ popq %rax
+.if \vector == 10 || \vector == 11 || \vector == 12 || \vector == 13 || \vector == 14
+ add $8, %rsp
+.endif
+.endm
+
+ .text
+ .globl idt_set_gate
+idt_set_gate:
+ /*
+ * Set an interrupt gate descriptor in the IDT
+ *
+ * [RDI] {0}: (uint8_t)vector
+ * [RSI] {1}: (uint8_t)type
+ * [RDX] {2}: (uintptr_t)isr
+ * [RCX] {3}: (uint8_t)ist
+ */
+ pushq %rbx
+ pushq %rbp
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+
+ shlq $4, %rdi /* Scale vector by 16 */
+ leaq IDT(%rip), %rbx /* Load the IDT base */
+ addq %rdi, %rbx /* Descriptor base -> RBX */
+
+ movw %dx, 0(%rbx) /* Offset low */
+ movw $KERNEL_CS, 2(%rbx) /* Segment selector */
+ andq $0x38, %rcx /* Zero IST[7:3] */
+ movb %cl, 4(%rbx) /* IST */
+ movb $0b10000000, 5(%rbx) /* P, DPL[0], ZERO */
+ andq $0xF, %rsi /* Zero TYPE[7:5] */
+ orb %sil, 5(%rbx) /* Type */
+
+ shrq $16, %rdx /* RDX >>= 16 */
+ movw %dx, 6(%rbx) /* Offset middle */
+ shrq $16, %rdx /* RDX >>= 16 */
+ movl %edx, 8(%rbx) /* Offset high */
+
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rbp
+ popq %rbx
+ retq
+
+ .globl idt_load
+idt_load:
+ call set_traps
+ lea IDTR(%rip), %rdx
+ lidt (%rdx)
+ retq
+
+set_traps:
+ set_trap $0x00, diverr
+ set_trap $0x01, debug_except
+ set_trap $0x02, nmi
+ set_trap $0x03, breakpoint
+ set_trap $0x04, overflow
+ set_trap $0x05, bound_range
+ set_trap $0x06, invalid_tss
+ set_trap $0x07, no_coproc
+ set_trap $0x08, double_fault
+ set_trap $0x0A, invalid_tss
+ set_trap $0x0B, seg_np
+ set_trap $0x0C, ss_fault
+ set_trap $0x0D, gpf
+ set_trap $0x0E, page_fault
+ retq
+
+diverr:
+ push_frame 0x0
+ mov %rsp, %rdi
+ call trap_dispatch
+ pop_frame 0x0
+1: cli
+ hlt
+ jmp 1b
+
+debug_except:
+ push_frame 0x1
+ mov %rsp, %rdi
+ call trap_dispatch
+ pop_frame 0x1
+1: cli
+ hlt
+ jmp 1b
+
+nmi:
+ push_frame 0x2
+ mov %rsp, %rdi
+ call trap_dispatch
+ pop_frame 0x2
+1: cli
+ hlt
+ jmp 1b
+
+breakpoint:
+ push_frame 0x3
+ mov %rsp, %rdi
+ call trap_dispatch
+ pop_frame 0x3
+1: cli
+ hlt
+ jmp 1b
+
+overflow:
+ push_frame 0x4
+ mov %rsp, %rdi
+ call trap_dispatch
+ pop_frame 0x4
+1: cli
+ hlt
+ jmp 1b
+
+bound_range:
+ push_frame 0x5
+ mov %rsp, %rdi
+ call trap_dispatch
+ pop_frame 0x5
+1: cli
+ hlt
+ jmp 1b
+
+invl_opc:
+ push_frame 0x6
+ mov %rsp, %rdi
+ call trap_dispatch
+ pop_frame 0x6
+1: cli
+ hlt
+ jmp 1b
+
+no_coproc:
+ push_frame 0x7
+ mov %rsp, %rdi
+ call trap_dispatch
+ pop_frame 0x7
+1: cli
+ hlt
+ jmp 1b
+
+double_fault:
+ push_frame 0x8
+ mov %rsp, %rdi
+ call trap_dispatch
+ pop_frame 0x8
+1: cli
+ hlt
+ jmp 1b
+
+invalid_tss:
+ push_frame 0xA
+ mov %rsp, %rdi
+ call trap_dispatch
+ pop_frame 0xA
+1: cli
+ hlt
+ jmp 1b
+
+seg_np:
+ push_frame 0xB
+ mov %rsp, %rdi
+ call trap_dispatch
+ pop_frame 0xB
+1: cli
+ hlt
+ jmp 1b
+
+ss_fault:
+ push_frame 0xC
+ mov %rsp, %rdi
+ call trap_dispatch
+ pop_frame 0xC
+1: cli
+ hlt
+ jmp 1b
+
+gpf:
+ push_frame 0xD
+ mov %rsp, %rdi
+ call trap_dispatch
+ pop_frame 0xD
+1: cli
+ hlt
+ jmp 1b
+
+page_fault:
+ push_frame 0xE
+ mov %rsp, %rdi
+ call trap_dispatch
+ pop_frame 0xE
+1: cli
+ hlt
+ jmp 1b
+ hlt
+
+trap_dispatch:
+ retq
+
+ .section .data
+ .align 8
+IDT:
+ .fill 256, 8, 512
+IDTR:
+limit:
+ .word 0xFFF
+ .quad IDT
+
+/* vim: ft=gas :
+*/