]> pd.if.org Git - zos/blobdiff - idt.s
interrupt setup and handling
[zos] / idt.s
diff --git a/idt.s b/idt.s
new file mode 100644 (file)
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
+