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 .cr2: 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, cr2 mov qword [exception_info.cr2], 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, 0x8e 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 0x002f98000000ffff dq 0x002f92000000ffff dq 0x002ff2000000ffff dq 0x002ff8000000ffff section .bss section .text write_keyboard_byte: in al, 0x64 test al, 0x02 jnz write_keyboard_byte mov al, dil out 0x60, al ret extern on_keyboard_interrupt keyboard_isr: push r11 push r10 push r9 push r8 push rsi push rdi push rdx push rcx push rax in al, 0x60 mov dil, al call on_keyboard_interrupt mov al, 0x20 out 0x20, al pop rax pop rcx pop rdx pop rdi pop rsi pop r8 pop r9 pop r10 pop r11 iretq load_gdt_and_idt: ;fill exception entries in idt mov rcx, 16 .loop: mov rdi, rcx dec rdi mov sil, 1 mov rdx, qword [exception_isrs + rdi * 8] call set_isr loop .loop ;reset pic and map irqs to 0x20 - 0x2f mov al, 0x11 out 0x20, al mov al, 0x20 out 0x21, al mov al, 0x04 out 0x21, al mov al, 0x01 out 0x21, al mov al, 0xfd ;mask all but irq 1 out 0x21, al mov al, 0x11 out 0xa0, al mov al, 0x28 out 0xa1, al mov al, 0x02 out 0xa1, al mov al, 0x01 out 0xa1, al mov al, 0xff ;mask all out 0xa1, al mov rdi, 0x21 xor sil, sil mov rdx, keyboard_isr call set_isr ;set keyboard config mov al, 0x60 out 0x64, al mov dil, 0x01 call write_keyboard_byte ;make tss entry in gdt 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 ;load gdt, idt, tss lgdt [gdtr] lidt [idtr] mov ax, 0x18 ltr ax ret