diff --git a/src/arch/x86_64/Makefile b/src/arch/x86_64/Makefile index 5ba9919b..87b716a2 100644 --- a/src/arch/x86_64/Makefile +++ b/src/arch/x86_64/Makefile @@ -1,4 +1,4 @@ -objects := $(patsubst %.c,%.o,$(wildcard *.c)) +objects := $(patsubst %.c,%.o,$(wildcard *.c)) israsm.o subdirs=boot OBJPATH=$(OBJDIR)/arch/${TARGET}/ export @@ -11,3 +11,7 @@ all: $(objects) $(subdirs) mkdir -p $(OBJPATH) cp $@ $(OBJPATH)/$@ +israsm.o: isr.asm + nasm -f elf64 -o $@ $< + mkdir -p $(OBJPATH) + cp $@ $(OBJPATH)/$@ diff --git a/src/arch/x86_64/idt.c b/src/arch/x86_64/idt.c new file mode 100644 index 00000000..0cf973cf --- /dev/null +++ b/src/arch/x86_64/idt.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +idtentry_t idt[256]; + +void idt_setentry(idtentry_t *e, uint64_t offset, uint16_t segment, uint16_t flags, uint8_t ist){ + e->offset1 = offset & 0xFFFF; + e->offset2 = (offset >> 16) & 0xFFFF; + e->offset3 = (offset >> 32) & 0xFFFFFFFF; + e->segment = segment; + e->flags = flags | ist; + e->reserved = 0; +} + +static void idt_reload(){ + + idtr_t idtr; + idtr.offset = (uint64_t)&idt; + idtr.size = sizeof(idt)-1; + + asm("lidt (%%rax)": : "a"(&idtr) : "memory"); + +} + +void idt_bspinit(){ + + for(size_t i = 0; i < 256; ++i){ + idt_setentry(&idt[i], asmisr_general, 0x28, FLAGS_PRESENT | FLAGS_TYPE_INTERRUPT, 0); + } + + for(size_t i = 0; i < 32; ++i){ + idt_setentry(&idt[i], asmisr_except, 0x28, FLAGS_PRESENT | FLAGS_TYPE_TRAP, 0); + } + + idt_reload(); + + asm("int $0x0"); + +} diff --git a/src/arch/x86_64/include/arch/idt.h b/src/arch/x86_64/include/arch/idt.h new file mode 100644 index 00000000..fbc16a37 --- /dev/null +++ b/src/arch/x86_64/include/arch/idt.h @@ -0,0 +1,30 @@ +#ifndef _IDT_H_INCLUDE +#define _IDT_H_INCLUDE + +#include + +#define FLAGS_PRESENT (1 << 15) +#define FLAGS_DPL3 (1 << 13) +#define FLAGS_TYPE_INTERRUPT (0xE << 8) +#define FLAGS_TYPE_TRAP (0xF << 8) + + + +typedef struct{ + uint16_t size; + uint64_t offset; +} __attribute__((packed)) idtr_t; + +typedef struct{ + uint16_t offset1; + uint16_t segment; + uint16_t flags; + uint16_t offset2; + uint32_t offset3; + uint32_t reserved; + +} __attribute__((packed)) idtentry_t; + +void idt_bspinit(); + +#endif diff --git a/src/arch/x86_64/include/arch/isr.h b/src/arch/x86_64/include/arch/isr.h new file mode 100644 index 00000000..57927a38 --- /dev/null +++ b/src/arch/x86_64/include/arch/isr.h @@ -0,0 +1,9 @@ +#ifndef _ISR_H_INCLUDE +#define _ISR_H_INCLUDE + +extern void asmisr_general(void*); +extern void asmisr_except(void*); + + + +#endif diff --git a/src/arch/x86_64/include/arch/panic.h b/src/arch/x86_64/include/arch/panic.h new file mode 100644 index 00000000..00fc26ab --- /dev/null +++ b/src/arch/x86_64/include/arch/panic.h @@ -0,0 +1,6 @@ +#ifndef _PANIC_H_INCLUDE +#define _PANIC_H_INCLUDE + +__attribute__((noreturn)) void _panic(char *reason); + +#endif diff --git a/src/arch/x86_64/isr.asm b/src/arch/x86_64/isr.asm new file mode 100644 index 00000000..390a04b2 --- /dev/null +++ b/src/arch/x86_64/isr.asm @@ -0,0 +1,113 @@ +section .text + +%macro pushregs 0 + + push rbp + push rsi + push rdi + push r15 + push r14 + push r13 + push r12 + push r11 + push r10 + push r9 + push r8 + push rdx + push rcx + push rbx + push rax + + mov rax, ds + push rax + mov rax, es + push rax + mov rax, fs + push rax + mov rax, gs + push rax + + mov rdi,cr2 + push rdi + + +%endmacro + +%macro popregs 0 + + add rsp, 8 ; cr2 + + pop rax + mov gs,rax + pop rax + mov fs,rax + pop rax + mov es,rax + pop rax + mov ds,rax + + pop rax + pop rbx + pop rcx + pop rdx + pop r8 + pop r9 + pop r10 + pop r11 + pop r12 + pop r13 + pop r14 + pop r15 + pop rdi + pop rsi + pop rbp + + +%endmacro + +%macro isr 2 + + global %1 + %1: + + pushregs + + mov rdi,rsp + + cld + extern %2 + call %2 + + popregs + + iretq + + +%endmacro + + + + +%macro except 2 + + global %1 + %1: + + pushregs + + mov rdi,rsp + + cld + extern %2 + call %2 + + popregs + + add rsp,8 ; remove error code + + iretq +%endmacro + +except asmisr_pagefault, isr_pagefault +isr asmisr_general, isr_general +except asmisr_except, isr_except diff --git a/src/arch/x86_64/isr.c b/src/arch/x86_64/isr.c new file mode 100644 index 00000000..dd19f0be --- /dev/null +++ b/src/arch/x86_64/isr.c @@ -0,0 +1,16 @@ +#include +#include + +void isr_general(void*){ + _panic("Unhandled interrupt"); + asm("hlt"); +} + +void isr_except(void*){ + _panic("CPU Exception"); + asm("hlt;"); +} + +void isr_pagefault(void*){ + +} diff --git a/src/arch/x86_64/main.c b/src/arch/x86_64/main.c index 8d3af630..2af876bd 100644 --- a/src/arch/x86_64/main.c +++ b/src/arch/x86_64/main.c @@ -25,7 +25,8 @@ void kmain(){ console_setwritehook(liminewrite); bsp_setcls(); - + gdt_bspinit(); + idt_bspinit(); } diff --git a/src/arch/x86_64/panic.c b/src/arch/x86_64/panic.c new file mode 100644 index 00000000..2d1c5576 --- /dev/null +++ b/src/arch/x86_64/panic.c @@ -0,0 +1,14 @@ +#include +#include + +__attribute((noreturn)) void _panic(char* reason){ + + // TODO stack trace and register print + + printf("Kernel panic.\nWhy: %s\nWhere: TODO\nWho: TODO\n", reason); + + while(1){ + asm("cli;hlt;"); + } + +}