summaryrefslogtreecommitdiff
path: root/kernel/interrupts.asm
diff options
context:
space:
mode:
authorBenji Dial <benji@benjidial.net>2024-01-13 19:14:58 -0500
committerBenji Dial <benji@benjidial.net>2024-01-13 19:14:58 -0500
commite9898e829b8df7c0b16faec1ce490369c53fd78e (patch)
tree0959298e7af3e5b9e40ac4d6dec0cec089105eac /kernel/interrupts.asm
parent4130562b1555cabe441efe9420cebe12e7ed8d39 (diff)
downloadhilbert-os-e9898e829b8df7c0b16faec1ce490369c53fd78e.tar.gz
minimal cpu exception handling
Diffstat (limited to 'kernel/interrupts.asm')
-rw-r--r--kernel/interrupts.asm254
1 files changed, 254 insertions, 0 deletions
diff --git a/kernel/interrupts.asm b/kernel/interrupts.asm
new file mode 100644
index 0000000..c375ee4
--- /dev/null
+++ b/kernel/interrupts.asm
@@ -0,0 +1,254 @@
+bits 64
+
+global load_gdt_and_idt
+
+section .rodata
+
+;0x28 picked to align with limine choice
+
+;0x18 - tss
+;0x28 - kernel code
+;0x30 - kernel data
+;0x38 - user data
+;0x40 - user code
+
+tss:
+ times 9 dd 0
+ dq 0xffffffffffeff000
+ times 15 dd 0
+
+gdtr:
+ dw 0x47
+ dq gdt
+
+idtr:
+ dw 4095
+ dq idt
+
+section .bss
+
+idt:
+ resq 512
+
+global exception_info
+exception_info:
+.rax:
+ resq 1
+.rbx:
+ resq 1
+.rcx:
+ resq 1
+.rdx:
+ resq 1
+.rdi:
+ resq 1
+.rsi:
+ resq 1
+.rbp:
+ resq 1
+.rsp:
+ resq 1
+.r8:
+ resq 1
+.r9:
+ resq 1
+.r10:
+ resq 1
+.r11:
+ resq 1
+.r12:
+ resq 1
+.r13:
+ resq 1
+.r14:
+ resq 1
+.r15:
+ resq 1
+.cr3:
+ resq 1
+.rip:
+ resq 1
+.rflags:
+ resq 1
+.error:
+ resq 1
+.has_error:
+ resb 1
+.exception_number:
+ resb 1
+
+section .rodata
+
+has_error_code:
+ db 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0
+
+exception_isrs:
+ dq exception_00, exception_01, exception_02, exception_03
+ dq exception_04, exception_05, exception_06, exception_07
+ dq exception_08, exception_09, exception_0a, exception_0b
+ dq exception_0c, exception_0d, exception_0e, exception_0f
+
+section .text
+
+extern print_exception
+
+exception_00:
+ mov byte [exception_info.exception_number], 0x00
+ jmp exception_common
+exception_01:
+ mov byte [exception_info.exception_number], 0x01
+ jmp exception_common
+exception_02:
+ mov byte [exception_info.exception_number], 0x02
+ jmp exception_common
+exception_03:
+ mov byte [exception_info.exception_number], 0x03
+ jmp exception_common
+exception_04:
+ mov byte [exception_info.exception_number], 0x04
+ jmp exception_common
+exception_05:
+ mov byte [exception_info.exception_number], 0x05
+ jmp exception_common
+exception_06:
+ mov byte [exception_info.exception_number], 0x06
+ jmp exception_common
+exception_07:
+ mov byte [exception_info.exception_number], 0x07
+ jmp exception_common
+exception_08:
+ mov byte [exception_info.exception_number], 0x08
+ jmp exception_common
+exception_09:
+ mov byte [exception_info.exception_number], 0x09
+ jmp exception_common
+exception_0a:
+ mov byte [exception_info.exception_number], 0x0a
+ jmp exception_common
+exception_0b:
+ mov byte [exception_info.exception_number], 0x0b
+ jmp exception_common
+exception_0c:
+ mov byte [exception_info.exception_number], 0x0c
+ jmp exception_common
+exception_0d:
+ mov byte [exception_info.exception_number], 0x0d
+ jmp exception_common
+exception_0e:
+ mov byte [exception_info.exception_number], 0x0e
+ jmp exception_common
+exception_0f:
+ mov byte [exception_info.exception_number], 0x0f
+ jmp exception_common
+
+exception_common:
+ mov qword [exception_info.rax], rax
+
+ movzx rax, byte [exception_info.exception_number]
+ mov al, byte [has_error_code + rax]
+ test al, al
+ jz .no_error_code
+
+ mov byte [exception_info.has_error], 1
+ pop rax
+ mov qword [exception_info.error], rax
+ jmp .post_error_code
+
+.no_error_code:
+ mov byte [exception_info.has_error], 0
+
+.post_error_code:
+ mov qword [exception_info.rbx], rbx
+ mov qword [exception_info.rcx], rcx
+ mov qword [exception_info.rdx], rdx
+ mov qword [exception_info.rdi], rdi
+ mov qword [exception_info.rsi], rsi
+ mov qword [exception_info.rbp], rbp
+ mov qword [exception_info.r8], r8
+ mov qword [exception_info.r9], r9
+ mov qword [exception_info.r10], r10
+ mov qword [exception_info.r11], r11
+ mov qword [exception_info.r12], r12
+ mov qword [exception_info.r13], r13
+ mov qword [exception_info.r14], r14
+ mov qword [exception_info.r15], r15
+
+ pop rax
+ mov qword [exception_info.rip], rax
+ pop rax
+ pop rax
+ mov qword [exception_info.rflags], rax
+ pop rax
+ mov qword [exception_info.rsp], rax
+
+ mov rax, cr3
+ mov qword [exception_info.cr3], rax
+
+ jmp print_exception
+
+set_isr:
+;rdi - index
+;sil - 1 if this is a trap, 0 if it is an interrupt
+;rdx - isr pointer
+
+ shl rdi, 4
+ add rdi, idt
+
+ mov word [rdi], dx
+ shr rdx, 16
+ mov word [rdi + 6], dx
+ shr rdx, 16
+ mov dword [rdi + 8], edx
+
+ or sil, 0xef
+ mov byte [rdi + 5], sil
+ mov word [rdi + 2], 0x28
+ mov byte [rdi + 4], 1
+
+ ret
+
+section .data
+
+gdt:
+ dq 0
+ dq 0
+ dq 0
+.tss:
+ dq 0x0000e90000000067
+ dq 0;tss is 2 qwords wide
+ dq 0x00209b0000000000
+ dq 0x00009b0000000000
+ dq 0x0000fb0000000000
+ dq 0x0020fb0000000000
+
+section .text
+
+load_gdt_and_idt:
+
+ mov rcx, 8
+
+.loop:
+
+ mov rdi, rcx
+ dec rdi
+ mov sil, 1
+ mov rdx, qword [exception_isrs + rdi * 8]
+ call set_isr
+
+ loop .loop
+
+ mov rax, tss
+
+ mov word [gdt.tss + 2], ax
+ shr rax, 16
+ mov byte [gdt.tss + 4], al
+ mov byte [gdt.tss + 7], ah
+ shr rax, 16
+ mov dword [gdt.tss + 8], eax
+
+ lgdt [gdtr]
+ lidt [idtr]
+ mov ax, 0x18
+ ltr ax
+
+ ret