From aac04321fda4094e8623a10ed39d2916ada40ccf Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Fri, 11 Jun 2021 19:17:55 +0300 Subject: [PATCH] started on interrupts --- sys1/kern/src/intr.asm | 117 ++++++++++++++++++++++++++++++++++++++++++++++++ sys1/kern/src/intr.c | 17 +++++++ sys1/kern/src/intr.h | 8 ++++ sys1/kern/src/main.c | 1 + sys1/kern/src/mem.c | 1 - 5 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 sys1/kern/src/intr.asm create mode 100644 sys1/kern/src/intr.c create mode 100644 sys1/kern/src/intr.h diff --git a/sys1/kern/src/intr.asm b/sys1/kern/src/intr.asm new file mode 100644 index 0000000..dd35095 --- /dev/null +++ b/sys1/kern/src/intr.asm @@ -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 index 0000000..5ce0009 --- /dev/null +++ b/sys1/kern/src/intr.c @@ -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 index 0000000..10e3fe9 --- /dev/null +++ b/sys1/kern/src/intr.h @@ -0,0 +1,8 @@ +#ifndef INTR_H_ +#define INTR_H_ + +#include "desc.h" + +void intr_init(void); + +#endif /* INTR_H_ */ diff --git a/sys1/kern/src/main.c b/sys1/kern/src/main.c index 3d89aa9..8426a66 100644 --- a/sys1/kern/src/main.c +++ b/sys1/kern/src/main.c @@ -21,6 +21,7 @@ void kmain(void) vga_reset(); mem_init(); + intr_init(); line = 0; for(;;) { diff --git a/sys1/kern/src/mem.c b/sys1/kern/src/mem.c index 898ef3f..92d6de9 100644 --- a/sys1/kern/src/mem.c +++ b/sys1/kern/src/mem.c @@ -4,7 +4,6 @@ void set_gdt(void *addr, uint16_t limit); enum { - SEG_NULL = 0, SEG_KCODE = 1, SEG_KDATA = 2 }; -- 1.7.10.4