diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/Makefile | 2 | ||||
-rw-r--r-- | kernel/config.h | 1 | ||||
-rw-r--r-- | kernel/include/idt.h | 53 | ||||
-rw-r--r-- | kernel/include/sys.h | 23 | ||||
-rw-r--r-- | kernel/l0/idt.c | 28 | ||||
-rw-r--r-- | kernel/l0/interrupt.s | 74 | ||||
-rw-r--r-- | kernel/l0/kmain.c | 6 | ||||
-rw-r--r-- | kernel/l0/sys.c | 24 | ||||
-rw-r--r-- | kernel/lib/printf.c | 2 | ||||
-rw-r--r-- | kernel/lib/string.c | 1 |
10 files changed, 139 insertions, 75 deletions
diff --git a/kernel/Makefile b/kernel/Makefile index 43b8c7e..34e6a2e 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -31,6 +31,6 @@ $(OUT): $(OBJ) clean: rm */*.o || true mrproper: clean - rm $(OUT) + rm $(OUT) || true rebuild: mrproper all diff --git a/kernel/config.h b/kernel/config.h index da2956a..b1a97b2 100644 --- a/kernel/config.h +++ b/kernel/config.h @@ -24,5 +24,4 @@ extern char k_highhalf_addr; // defined in linker script : 0xC0000000 #define DBGLOG_TO_SERIAL #define DBGLOG_TO_SCREEN - /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/kernel/include/idt.h b/kernel/include/idt.h index 5730f5e..ba344c9 100644 --- a/kernel/include/idt.h +++ b/kernel/include/idt.h @@ -8,6 +8,56 @@ #include <config.h> +#define IRQ0 0 +#define IRQ1 1 +#define IRQ2 2 +#define IRQ3 3 +#define IRQ4 4 +#define IRQ5 5 +#define IRQ6 6 +#define IRQ7 7 +#define IRQ8 8 +#define IRQ9 9 +#define IRQ10 10 +#define IRQ11 11 +#define IRQ12 12 +#define IRQ13 13 +#define IRQ14 14 +#define IRQ15 15 + +#define EX_DIVIDE_ERROR 0 // No error code +#define EX_DEBUG 1 // No error code +#define EX_NMI_INTERRUPT 2 // No error code +#define EX_BREAKPOINT 3 // No error code +#define EX_OVERFLOW 4 // No error code +#define EX_BOUND_RANGE_EXCEDEED 5 // No error code +#define EX_INVALID_OPCODE 6 // No error code +#define EX_DEVICE_NOT_AVAILABLE 7 // No error code +#define EX_DOUBLE_FAULT 8 // Yes (Zero) +#define EX_COPROCESSOR_SEGMENT_OVERRUN 9 // No error code +#define EX_INVALID_TSS 10 // Yes +#define EX_SEGMENT_NOT_PRESENT 11 // Yes +#define EX_STACK_SEGMENT_FAULT 12 // Yes +#define EX_GENERAL_PROTECTION 13 // Yes +#define EX_PAGE_FAULT 14 // Yes +#define EX_INTEL_RESERVED_1 15 // No +#define EX_FLOATING_POINT_ERROR 16 // No +#define EX_ALIGNEMENT_CHECK 17 // Yes (Zero) +#define EX_MACHINE_CHECK 18 // No +#define EX_INTEL_RESERVED_2 19 // No +#define EX_INTEL_RESERVED_3 20 // No +#define EX_INTEL_RESERVED_4 21 // No +#define EX_INTEL_RESERVED_5 22 // No +#define EX_INTEL_RESERVED_6 23 // No +#define EX_INTEL_RESERVED_7 24 // No +#define EX_INTEL_RESERVED_8 25 // No +#define EX_INTEL_RESERVED_9 26 // No +#define EX_INTEL_RESERVED_10 27 // No +#define EX_INTEL_RESERVED_11 28 // No +#define EX_INTEL_RESERVED_12 29 // No +#define EX_INTEL_RESERVED_13 30 // No +#define EX_INTEL_RESERVED_14 31 // No + struct idt_entry { uint16_t base_lo; //Low part of address to jump to uint16_t sel; //Kernel segment selector @@ -34,7 +84,8 @@ typedef struct registers registers_t; typedef void (*isr_handler_t)(registers_t*); void idt_init(); -//void idt_handleIrq(int number, isr_handler_t func); //Set IRQ handler +void idt_set_ex_handler(int number, isr_handler_t func); //Set exception handler +void idt_set_irq_handler(int number, isr_handler_t func); //Set IRQ handler /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/kernel/include/sys.h b/kernel/include/sys.h index 319cbef..2304eec 100644 --- a/kernel/include/sys.h +++ b/kernel/include/sys.h @@ -2,10 +2,25 @@ #include <config.h> -void outb(uint16_t port, uint8_t value); -void outw(uint16_t port, uint16_t value); -uint8_t inb(uint16_t port); -uint16_t inw(uint16_t port); +static inline void outb(uint16_t port, uint8_t value) { + asm volatile("outb %1, %0" : : "dN"(port), "a"(value)); +} + +static inline void outw(uint16_t port, uint16_t value) { + asm volatile("outw %1, %0" : : "dN"(port), "a"(value)); +} + +static inline uint8_t inb(uint16_t port) { + uint8_t ret; + asm volatile("inb %1, %0" : "=a"(ret) : "dN"(port)); + return ret; +} + +static inline uint16_t inw(uint16_t port) { + uint16_t ret; + asm volatile("inw %1, %0" : "=a"(ret) : "dN"(port)); + return ret; +} void panic(const char* message, const char* file, int line); void panic_assert(const char* assertion, const char* file, int line); diff --git a/kernel/l0/idt.c b/kernel/l0/idt.c index a0e19dd..8a981af 100644 --- a/kernel/l0/idt.c +++ b/kernel/l0/idt.c @@ -62,19 +62,22 @@ static idt_entry_t idt_entries[256]; static idt_ptr_t idt_ptr; static isr_handler_t irq_handlers[16] = {0}; +static isr_handler_t ex_handlers[32] = {0}; -/* Called in idt_.asm when an exception fires (interrupt 0 to 31). - Tries to handle the exception, panics if fails. */ -void idt_isrHandler(registers_t *regs) { - dbg_printf("/ ISR %i\n", regs->int_no); +/* Called in interrupt.s when an exception fires (interrupt 0 to 31) */ +void idt_exHandler(registers_t *regs) { + dbg_printf("/ Exception %i\n", regs->int_no); dbg_printf("| EAX: 0x%p EBX: 0x%p ECX: 0x%p EDX: 0x%p\n", regs->eax, regs->ebx, regs->ecx, regs->edx); dbg_printf("| EDI: 0x%p ESI: 0x%p ESP: 0x%p EBP: 0x%p\n", regs->edi, regs->esi, regs->esp, regs->ebp); dbg_printf("| EIP: 0x%p CS : 0x%p DS : 0x%p SS : 0x%p\n", regs->eip, regs->cs, regs->ds, regs->ss); dbg_printf("\\ EFl: 0x%p I# : 0x%p Err: 0x%p\n", regs->eflags, regs->int_no, regs->err_code); + + if (ex_handlers[regs->int_no] != 0) { + ex_handlers[regs->int_no](regs); + } } -/* Called in interrupt.asm when an IRQ fires (interrupt 32 to 47) - Possibly wakes up a thread that was waiting, possibly calls a handler. */ +/* Called in interrupt.s when an IRQ fires (interrupt 32 to 47) */ void idt_irqHandler(registers_t *regs) { if (regs->err_code > 7) { outb(0xA0, 0x20); @@ -87,10 +90,10 @@ void idt_irqHandler(registers_t *regs) { } } -/* syscall handler */ +/* Caled in interrupt.s when a syscall is called */ void idt_syscallHandler(registers_t *regs) { dbg_printf("Syscall %i\n", regs->int_no); - // do nothing... + // do nothing, yet. } /* For internal use only. Sets up an entry of the IDT with given parameters. */ @@ -178,10 +181,17 @@ void idt_init() { } /* Sets up an IRQ handler for given IRQ. */ -void idt_handleIrq(int number, isr_handler_t func) { +void idt_set_irq_handler(int number, isr_handler_t func) { if (number < 16 && number >= 0) { irq_handlers[number] = func; } } +/* Sets up a handler for a processor exception */ +void idt_set_ex_handler(int number, isr_handler_t func) { + if (number >= 0 && number < 32) { + ex_handlers[number] = func; + } +} + /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/kernel/l0/interrupt.s b/kernel/l0/interrupt.s index ddd1e76..d40fff0 100644 --- a/kernel/l0/interrupt.s +++ b/kernel/l0/interrupt.s @@ -33,25 +33,25 @@ iret %endmacro -COMMONSTUB isr +COMMONSTUB ex COMMONSTUB irq COMMONSTUB syscall ;************************************************************************************ -%macro ISR_NOERRCODE 1 ; define a macro, taking one parameter +%macro EX_NOERRCODE 1 ; define a macro, taking one parameter [GLOBAL isr%1] ; %1 accesses the first parameter. isr%1: push byte 0 push byte %1 - jmp isr_common_stub + jmp ex_common_stub %endmacro -%macro ISR_ERRCODE 1 +%macro EX_ERRCODE 1 [GLOBAL isr%1] isr%1: push byte %1 - jmp isr_common_stub + jmp ex_common_stub %endmacro %macro IRQ 2 @@ -71,38 +71,38 @@ COMMONSTUB syscall jmp syscall_common_stub %endmacro -ISR_NOERRCODE 0 -ISR_NOERRCODE 1 -ISR_NOERRCODE 2 -ISR_NOERRCODE 3 -ISR_NOERRCODE 4 -ISR_NOERRCODE 5 -ISR_NOERRCODE 6 -ISR_NOERRCODE 7 -ISR_ERRCODE 8 -ISR_NOERRCODE 9 -ISR_ERRCODE 10 -ISR_ERRCODE 11 -ISR_ERRCODE 12 -ISR_ERRCODE 13 -ISR_ERRCODE 14 -ISR_NOERRCODE 15 -ISR_NOERRCODE 16 -ISR_NOERRCODE 17 -ISR_NOERRCODE 18 -ISR_NOERRCODE 19 -ISR_NOERRCODE 20 -ISR_NOERRCODE 21 -ISR_NOERRCODE 22 -ISR_NOERRCODE 23 -ISR_NOERRCODE 24 -ISR_NOERRCODE 25 -ISR_NOERRCODE 26 -ISR_NOERRCODE 27 -ISR_NOERRCODE 28 -ISR_NOERRCODE 29 -ISR_NOERRCODE 30 -ISR_NOERRCODE 31 +EX_NOERRCODE 0 +EX_NOERRCODE 1 +EX_NOERRCODE 2 +EX_NOERRCODE 3 +EX_NOERRCODE 4 +EX_NOERRCODE 5 +EX_NOERRCODE 6 +EX_NOERRCODE 7 +EX_ERRCODE 8 +EX_NOERRCODE 9 +EX_ERRCODE 10 +EX_ERRCODE 11 +EX_ERRCODE 12 +EX_ERRCODE 13 +EX_ERRCODE 14 +EX_NOERRCODE 15 +EX_NOERRCODE 16 +EX_NOERRCODE 17 +EX_NOERRCODE 18 +EX_NOERRCODE 19 +EX_NOERRCODE 20 +EX_NOERRCODE 21 +EX_NOERRCODE 22 +EX_NOERRCODE 23 +EX_NOERRCODE 24 +EX_NOERRCODE 25 +EX_NOERRCODE 26 +EX_NOERRCODE 27 +EX_NOERRCODE 28 +EX_NOERRCODE 29 +EX_NOERRCODE 30 +EX_NOERRCODE 31 IRQ 0, 32 IRQ 1, 33 diff --git a/kernel/l0/kmain.c b/kernel/l0/kmain.c index 854a2b7..7665cb0 100644 --- a/kernel/l0/kmain.c +++ b/kernel/l0/kmain.c @@ -5,6 +5,11 @@ #include <gdt.h> #include <idt.h> + +void breakpoint_handler(registers_t *regs) { + dbg_printf("Breakpoint! (int3)\n"); + BOCHS_BREAKPOINT; +} void kmain(struct multiboot_info_t *mbd, int32_t mb_magic) { dbglog_setup(); @@ -17,6 +22,7 @@ void kmain(struct multiboot_info_t *mbd, int32_t mb_magic) { gdt_init(); dbg_printf("GDT set up.\n"); idt_init(); dbg_printf("IDT set up.\n"); + idt_set_ex_handler(EX_BREAKPOINT, breakpoint_handler); asm volatile("int $0x3"); diff --git a/kernel/l0/sys.c b/kernel/l0/sys.c index f6a9900..b388eba 100644 --- a/kernel/l0/sys.c +++ b/kernel/l0/sys.c @@ -2,28 +2,6 @@ #include <dbglog.h> -// C wrappers for inb/outb/inw/outw - -void outb(uint16_t port, uint8_t value) { - asm volatile("outb %1, %0" : : "dN"(port), "a"(value)); -} - -void outw(uint16_t port, uint16_t value) { - asm volatile("outw %1, %0" : : "dN"(port), "a"(value)); -} - -uint8_t inb(uint16_t port) { - uint8_t ret; - asm volatile("inb %1, %0" : "=a"(ret) : "dN"(port)); - return ret; -} - -uint16_t inw(uint16_t port) { - uint16_t ret; - asm volatile("inw %1, %0" : "=a"(ret) : "dN"(port)); - return ret; -} - // Kernel panic and kernel assert failure static void panic_do(const char* type, const char *msg, const char* file, int line) { @@ -42,3 +20,5 @@ void panic(const char* message, const char* file, int line) { void panic_assert(const char* assertion, const char* file, int line) { panic_do("ASSERT FAILED", assertion, file, line); } + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/kernel/lib/printf.c b/kernel/lib/printf.c index c1ef83b..68e08d8 100644 --- a/kernel/lib/printf.c +++ b/kernel/lib/printf.c @@ -116,3 +116,5 @@ int vsnprintf(char *buff, size_t len, const char* format, va_list ap){ *buff = '\0'; return result; } + +/* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/kernel/lib/string.c b/kernel/lib/string.c index 6d26478..9dce27b 100644 --- a/kernel/lib/string.c +++ b/kernel/lib/string.c @@ -87,3 +87,4 @@ void *memset(void *dest, int val, size_t count) { return dest; } +/* vim: set ts=4 sw=4 tw=0 noet :*/ |