diff options
Diffstat (limited to 'kernel/interrupts.asm')
-rw-r--r-- | kernel/interrupts.asm | 254 |
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 |