X-Git-Url: https://pd.if.org/git/?p=zos;a=blobdiff_plain;f=idt.s;fp=idt.s;h=10c95d515cd8bcd9cb5d66fb5c372555c684b943;hp=0000000000000000000000000000000000000000;hb=120ce15fac48f7aceac231ea3fcdcade26093e7b;hpb=4bfc87356b0316256d2eaf91497973dbddcd2db7 diff --git a/idt.s b/idt.s new file mode 100644 index 0000000..10c95d5 --- /dev/null +++ b/idt.s @@ -0,0 +1,210 @@ +struc idt_entry +.handler_low: resw 1 +.selector: resw 1 +.ist: resb 1 +.flags: resb 1 +.handler_high: resw 1 +.handler_highest: resd 1 +.reserved: resd 1 +endstruc + +align 16 + +global set_idt_entry:function + +;void set_idt_entry( +; struct idt_entry *entry, rdi +; uintptr_t handler, rsi +; uint16_t selector, rdx +; uint8_t flags, rcx +; uint8_t ist r8 + +set_idt_entry: + mov [rdi + idt_entry.flags], cl + mov [rdi + idt_entry.ist], r8b + mov [rdi + idt_entry.selector], dx + mov [rdi + idt_entry.handler_low], si + shr rsi, 16 + mov [rdi + idt_entry.handler_high], si + shr rsi, 16 + mov [rdi + idt_entry.handler_highest], esi + mov [rdi + idt_entry.reserved], dword 0x0 + +global load_idt:function + +load_idt: +; size_t limit = sizeof(struct idt_entry) * length - 1; + shl rsi, 4 + sub rsi, 1 + + sub rsp, 10 + mov [rsp], si + mov [rsp + 2], rdi + lidt [rsp] + add rsp, 10 + ret + +section .text + +extern interrupt_handler +extern global_errno +extern printk + +%macro makeisr 2 +global isr%1:function +isr%1: + push %2 ; err_code + push %1 ; int_no + jmp interrupt_handler_prepare +%endmacro + +%macro makeisr 1 +global isr%1:function +isr%1: + ; error code pushed by processor + push %1 ; int_no + jmp interrupt_handler_prepare +%endmacro + +%macro makeirq 2 +global irq%1:function +irq%1: + push 0 ; err_code + push %2 ; int_no + jmp interrupt_handler_prepare +%endmacro + +; create isr 0-7, which need an error code pushed +%assign i 0 +%rep 8 + +makeisr i,0 + +%assign i i+1 +%endrep + +makeisr 8 +makeisr 9,0 +makeisr 10 +makeisr 11 +makeisr 12 +makeisr 13 +makeisr 14 + +; make isr 15-31 +%assign i 15 +%rep 17 +makeisr i,0 +%assign i i+1 +%endrep + +; make irqs +%assign i 32 +%assign j 0 +%rep 16 +makeirq j,i +%assign i i+1 +%assign j j+1 +%endrep + +; make remaining interrupts +%assign i 48 +%rep 208 +makeisr i,0 +%assign i i+1 +%endrep + +interrupt_handler_prepare: + + push r15 + push r14 + push r13 + push r12 + push r11 + push r10 + push r9 + push r8 + push rax + push rcx + push rdx + push rbx + push rsp + push rbp + push rsi + push rdi + + ; CR2 for page faults, always push for consistent frame + mov rbp, cr2 + push rbp + + mov eax, [qword global_errno] + push rax + + mov rdi, rsp ; context stack frame pointer + mov rbx, rsp ; rbx is preserved by the abi, so save it + and rsp, 0xFFFFFFF0 ; should be sign extended + call interrupt_handler + mov rsp, rbx ; restore the stack + +load_interrupted_registers: + ; Restore the previous kernel errno. + pop rax + mov [qword global_errno], eax + + add rsp, 8 ; remove CR2 + + pop rdi + pop rsi + pop rbp + add rsp, 8 ; skip rsp + pop rbx + pop rdx + pop rcx + pop rax + pop r8 + pop r9 + pop r10 + pop r11 + pop r12 + pop r13 + pop r14 + pop r15 + + ; Remove int_no and err_code + add rsp, 16 + + iretq +;.size interrupt_handler_prepare, . - interrupt_handler_prepare + +global interrupt_handler_null:function + +align 16 +interrupt_handler_null: + iretq +;.size interrupt_handler_null, . - interrupt_handler_null + +rfprintf: db 'rflags : %llx', 10, 0 +csprintf: db 'cs : %hx', 10, 0 +ripprintf: db 'rip : %llx', 10, 0 +rspprintf: db 'rsp : %llx', 10, 0 +ssprintf: db 'ss : %hx', 10, 0 +csvprintf: db 'gdt : %016llx', 10, 0 + +global interrupts_enabled:function +interrupts_enabled: + pushf + pop rax + shr rax, 9 + and rax, 0x1 + ret + +global enable_interrupts:function +enable_interrupts: + sti + ret + +global disable_interrupts:function +disable_interrupts: + cli + ret +