diff --git a/arch/Makefile b/arch/Makefile index 676122a..cbc21b7 100644 --- a/arch/Makefile +++ b/arch/Makefile @@ -6,8 +6,10 @@ CC = $(CCPREFIX)gcc OBJS = boot.s.o main.c.o OBJS += logger.c.o console.c.o OBJS += multiboot.c.o + OBJS += protected.c.o protected.asm.cpp.o OBJS += exception.c.o exception.asm.cpp.o +OBJS += hwint.c.o hwint.asm.cpp.o all: kernel diff --git a/arch/hwint.asm b/arch/hwint.asm new file mode 100644 index 0000000..e6f1d8c --- /dev/null +++ b/arch/hwint.asm @@ -0,0 +1,54 @@ +#include "config.h" + +[EXTERN hwint_handler] + +%macro HWINT 2 +[GLOBAL hwint_%1] +hwint_%1: + cli + push byte 0 + push byte %2 + jmp hwint_common_stub +%endmacro + +HWINT 0, 32 +HWINT 1, 33 +HWINT 2, 34 +HWINT 3, 35 +HWINT 4, 36 +HWINT 5, 37 +HWINT 6, 38 +HWINT 7, 39 +HWINT 8, 40 +HWINT 9, 41 +HWINT 10, 42 +HWINT 11, 43 +HWINT 12, 44 +HWINT 13, 45 +HWINT 14, 46 +HWINT 15, 47 + +hwint_common_stub: + pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax + + mov ax, ds ; Lower 16-bits of eax = ds. + push eax ; save the data segment descriptor + + mov ax, GDT_KERNEL_DS_SELECTOR + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + call hwint_handler + + pop eax ; reload the original data segment descriptor + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + popa ; Pops edi,esi,ebp... + add esp, 8 ; Cleans up the pushed error code and pushed ISR number + sti + iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP diff --git a/arch/hwint.c b/arch/hwint.c new file mode 100644 index 0000000..51a77ed --- /dev/null +++ b/arch/hwint.c @@ -0,0 +1,32 @@ +#include "logger.h" + +struct IsrRegisters { + unsigned int ds; // Data segment selector + unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha. + unsigned int int_no, err_code; // Interrupt number and error code (if applicable) + unsigned int eip, cs, eflags, useresp, ss; // Pushed by the processor automatically. +}; + +static const char *const messages[] = { + "Unhandled hwint: 0", + "Unhandled hwint: 1", + "Unhandled hwint: 2", + "Unhandled hwint: 3", + "Unhandled hwint: 4", + "Unhandled hwint: 5", + "Unhandled hwint: 6", + "Unhandled hwint: 7", + "Unhandled hwint: 8", + "Unhandled hwint: 9", + "Unhandled hwint: 10", + "Unhandled hwint: 11", + "Unhandled hwint: 12", + "Unhandled hwint: 13", + "Unhandled hwint: 14", + "Unhandled hwint: 15", +}; + +void hwint_handler(struct IsrRegisters regs) +{ + logger_warn(messages[regs.int_no - 32]); +} diff --git a/arch/hwint.h b/arch/hwint.h new file mode 100644 index 0000000..f92ce8d --- /dev/null +++ b/arch/hwint.h @@ -0,0 +1,21 @@ +#ifndef KERNELMQ_INCLUDED_HWINT +#define KERNELMQ_INCLUDED_HWINT 1 + +void hwint_0(); +void hwint_1(); +void hwint_2(); +void hwint_3(); +void hwint_4(); +void hwint_5(); +void hwint_6(); +void hwint_7(); +void hwint_8(); +void hwint_9(); +void hwint_10(); +void hwint_11(); +void hwint_12(); +void hwint_13(); +void hwint_14(); +void hwint_15(); + +#endif diff --git a/arch/main.c b/arch/main.c index e561c4e..3703da2 100644 --- a/arch/main.c +++ b/arch/main.c @@ -13,7 +13,7 @@ void main(struct KernelMQ_Multiboot_Info multiboot_info) protected_initialize(); asm volatile ("int $0x3"); - asm volatile ("int $0x4"); + asm volatile ("int $0x24"); logger_warn("Nothing to do."); logger_fail("Halt."); diff --git a/arch/protected.c b/arch/protected.c index 3a1580f..140e1d5 100644 --- a/arch/protected.c +++ b/arch/protected.c @@ -3,6 +3,7 @@ #include "config.h" #include "logger.h" #include "exception.h" +#include "hwint.h" struct GdtPointer { unsigned short limit; @@ -97,6 +98,23 @@ void protected_initialize() idt_set_gate(30, (unsigned int)exception_30, 0x08, 0x8E); idt_set_gate(31, (unsigned int)exception_31, 0x08, 0x8E); + idt_set_gate(32, (unsigned int)hwint_0, 0x08, 0x8E); + idt_set_gate(33, (unsigned int)hwint_1, 0x08, 0x8E); + idt_set_gate(34, (unsigned int)hwint_2, 0x08, 0x8E); + idt_set_gate(35, (unsigned int)hwint_3, 0x08, 0x8E); + idt_set_gate(36, (unsigned int)hwint_4, 0x08, 0x8E); + idt_set_gate(37, (unsigned int)hwint_5, 0x08, 0x8E); + idt_set_gate(38, (unsigned int)hwint_6, 0x08, 0x8E); + idt_set_gate(39, (unsigned int)hwint_7, 0x08, 0x8E); + idt_set_gate(40, (unsigned int)hwint_8, 0x08, 0x8E); + idt_set_gate(41, (unsigned int)hwint_9, 0x08, 0x8E); + idt_set_gate(42, (unsigned int)hwint_10, 0x08, 0x8E); + idt_set_gate(43, (unsigned int)hwint_11, 0x08, 0x8E); + idt_set_gate(44, (unsigned int)hwint_12, 0x08, 0x8E); + idt_set_gate(45, (unsigned int)hwint_13, 0x08, 0x8E); + idt_set_gate(46, (unsigned int)hwint_14, 0x08, 0x8E); + idt_set_gate(47, (unsigned int)hwint_15, 0x08, 0x8E); + logger_info("Load GDT."); gdt_pointer.limit = sizeof(struct GdtEntry) * GDT_SIZE - 1;