started on interrupts
authorJohn Tsiombikas <nuclear@member.fsf.org>
Fri, 11 Jun 2021 16:17:55 +0000 (19:17 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Fri, 11 Jun 2021 16:17:55 +0000 (19:17 +0300)
sys1/kern/src/intr.asm [new file with mode: 0644]
sys1/kern/src/intr.c [new file with mode: 0644]
sys1/kern/src/intr.h [new file with mode: 0644]
sys1/kern/src/main.c
sys1/kern/src/mem.c

diff --git a/sys1/kern/src/intr.asm b/sys1/kern/src/intr.asm
new file mode 100644 (file)
index 0000000..dd35095
--- /dev/null
@@ -0,0 +1,117 @@
+       bits 32
+       section .text
+
+       extern intr_handler
+
+PIC1_CMD_PORT  equ 0x20
+PIC2_CMD_PORT  equ 0xa0
+OCW2_EOI       equ 0x20
+OCW3_ISR       equ 0x0b
+
+       global set_idt
+set_idt:
+       mov eax, [esp + 4]
+       mov [idtbase], eax
+       mov ax, [esp + 8]
+       mov [idtlim], ax
+       lidt [idtlim]
+       ret
+
+       align 4
+       dw 0
+idtlim dw 0
+idtbase dd 0
+
+
+       ; special entry point for IRQ7 to catch and disregard spurious interrupts
+       global intr_entry_irq7_verify
+intr_entry_irq7_verify:
+       push eax
+       mov al, OCW3_ISR
+       out PIC1_CMD_PORT, al
+       in al, PIC1_CMD_PORT
+       and al, 0x80
+       pop eax
+       jnz intr_entry_irq7
+       iret
+
+       global intr_entry_irq15_verify
+intr_entry_irq15_verify:
+       ; similarly for IRQ15
+       push eax
+       mov al, OCW3_ISR
+       out PIC2_CMD_PORT, al
+       in al, PIC2_CMD_PORT
+       and al, 0x80
+       jnz .valid
+       ; it was spurious, send EOI to master PIC and iret
+       mov al, OCW2_EOI
+       out PIC1_CMD_PORT, al
+       pop eax
+       iret
+.valid:        pop eax
+       jmp intr_entry_irq15
+
+
+%macro intr_entry_err 2
+intr_entry_%2:
+       push dword %1   ; push interrupt number
+       jmp intr_entry_common
+%endmacro
+
+%macro intr_entry_noerr 2
+intr_entry_%2:
+       push dword 0    ; push dummy error code
+       push dword %1   ; push interrupt number
+       jmp intr_entry_common
+%endmacro
+
+intr_entry_common:
+       pusha           ; save general purpose registers
+       call intr_handler
+       popa            ; restore general purpose registers
+       add esp, 8      ; remove error code and intr number from the stack
+       iret
+
+       ; interrupt entry points
+       intr_entry_noerr 0, div
+       intr_entry_noerr 1, debug
+       intr_entry_noerr 2, nmi
+       intr_entry_noerr 3, bpt
+       intr_entry_noerr 4, ovf
+       intr_entry_noerr 5, bound
+       intr_entry_noerr 6, ill
+       intr_entry_noerr 7, nodev
+       intr_entry_err 8, dbl
+       intr_entry_noerr 9, copseg
+       intr_entry_err 10, tss
+       intr_entry_err 11, segpres
+       intr_entry_err 12, stack
+       intr_entry_err 13, prot
+       intr_entry_err 14, page
+       intr_entry_noerr 15, rsvd
+       intr_entry_noerr 16, fpu
+       intr_entry_err 17, align
+       intr_entry_noerr 18, mce
+       intr_entry_noerr 19, sse
+       ; remapped IRQs 0-15 -> 32-47
+       intr_entry_noerr 32, irq0
+       intr_entry_noerr 33, irq1
+       intr_entry_noerr 34, irq2
+       intr_entry_noerr 35, irq3
+       intr_entry_noerr 36, irq4
+       intr_entry_noerr 37, irq5
+       intr_entry_noerr 38, irq6
+       intr_entry_noerr 39, irq7
+       intr_entry_noerr 40, irq8
+       intr_entry_noerr 41, irq9
+       intr_entry_noerr 42, irq10
+       intr_entry_noerr 43, irq11
+       intr_entry_noerr 44, irq12
+       intr_entry_noerr 45, irq13
+       intr_entry_noerr 46, irq14
+       intr_entry_noerr 47, irq15
+       ; default handler
+       intr_entry_noerr 255, default
+
+; vi:ft=nasm:
diff --git a/sys1/kern/src/intr.c b/sys1/kern/src/intr.c
new file mode 100644 (file)
index 0000000..5ce0009
--- /dev/null
@@ -0,0 +1,17 @@
+#include "intr.h"
+#include "desc.h"
+
+void set_idt(void *ptr, uint16_t lim);
+
+#define NUM_INTR       256
+static struct desc idt[NUM_INTR] __attribute__((aligned(8)));
+
+void intr_init(void)
+{
+       set_idt(idt, sizeof idt - 1);
+}
+
+void intr_handler(int err, int num)
+{
+}
+
diff --git a/sys1/kern/src/intr.h b/sys1/kern/src/intr.h
new file mode 100644 (file)
index 0000000..10e3fe9
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef INTR_H_
+#define INTR_H_
+
+#include "desc.h"
+
+void intr_init(void);
+
+#endif /* INTR_H_ */
index 3d89aa9..8426a66 100644 (file)
@@ -21,6 +21,7 @@ void kmain(void)
        vga_reset();
 
        mem_init();
+       intr_init();
 
        line = 0;
        for(;;) {
index 898ef3f..92d6de9 100644 (file)
@@ -4,7 +4,6 @@
 void set_gdt(void *addr, uint16_t limit);
 
 enum {
-       SEG_NULL        = 0,
        SEG_KCODE       = 1,
        SEG_KDATA       = 2
 };