diff --git a/include/kernel/idt.h b/include/kernel/idt.h index 62263dc..7b00530 100644 --- a/include/kernel/idt.h +++ b/include/kernel/idt.h @@ -9,6 +9,7 @@ typedef struct IdtDescriptor_t IdtDescriptor_t; typedef struct IdtEntry_t IdtEntry_t; typedef struct IdtPtr_t IdtPtr_t; typedef struct IRQList_t IRQList_t; +typedef struct ISRFrame_t ISRFrame_t; // -------------------------------------------------------------------------- // @@ -49,6 +50,27 @@ struct IRQList_t } entry[224]; }; +struct ISRFrame_t { +/* the register file */ + uint64_t regs[15]; + + /* the error code and interrupt id */ + uint64_t id; + uint64_t error; + + /* these are pushed automatically by the CPU */ + uint64_t rip; + uint64_t cs; + uint64_t rflags; + uint64_t rsp; + uint64_t ss; +} __attribute__((__packed__)); + +typedef struct +{ + +} __attribute__((__packed__)) cpu_state_t; + static char *IsrExceptions[32] = { "Divide Error Fault", "Debug Exception Trap", @@ -59,7 +81,7 @@ static char *IsrExceptions[32] = { "Invalid Opcode Fault", "Device Not Available or No Math Coprocessor Fault", "Double Fault Abort", - "Coprocessor Segment Overrun Fault", + "Coprocessor Segment Overrun Fault (Legacy)", "Invalid TSS Fault", "Segment Not Present Fault", "Stack Segment fault", @@ -80,7 +102,7 @@ static char *IsrExceptions[32] = { "Intel Reserved", "Intel Reserved", "Intel Reserved", - "Intel Reserved", + "Security Exception", "Intel Reserved" }; diff --git a/kaleid/kernel/cpu/isr.asm b/kaleid/kernel/cpu/isr.asm index ba4028f..59247f9 100644 --- a/kaleid/kernel/cpu/isr.asm +++ b/kaleid/kernel/cpu/isr.asm @@ -53,26 +53,41 @@ divideByZero: ;; ISR handler ;; isrPreHandler: - mov ax, ds - push rax + pushAll - mov ax, 0x0 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax + ; Check if we are switching from user mode to supervisor mode + mov rax, [rsp + 152] + and rax, 0x3000 + jz .SEnter + + swapgs ; XXX need TSS + +.SEnter: + ; Increment mask count as we configure all interrupts to mask IF + ; automatically in the IDT + inc qword [gs:8] + ; Call the C routine for dispatching an interrupt + cld ; DF must be cleared by the caller + mov rdi, rsp ; First argument points to the processor state + mov rbp, 0 ; Terminate stack traces here call IdtHandler - pop rbx - mov ds, bx - mov es, bx - mov fs, bx - mov gs, bx + ; decrement mask count + dec qword [gs:8] + ; check if we are switching from supervisor to user mode + mov rax, [rsp + 152] + and rax, 0x3000 + jz .SExit + + swapgs + +.SExit: popAll - add rsp, 8 - sti + ; pop the error code and interrupt id + add rsp, 16 + iretq ;; Divide Error Fault diff --git a/kaleid/kernel/cpu/isr.inc b/kaleid/kernel/cpu/isr.inc index 6aad457..be4d109 100644 --- a/kaleid/kernel/cpu/isr.inc +++ b/kaleid/kernel/cpu/isr.inc @@ -25,33 +25,47 @@ [BITS 64] %macro pushAll 0 - push rax - push rcx - push rdx - push rbx - push rbp - push rsi - push rdi + push r15 + push r14 + push r13 + push r12 + push r11 + push r10 + push r9 + push r8 + push rbp + push rdi + push rsi + push rdx + push rcx + push rbx + push rax %endmacro %macro popAll 0 - pop rdi - pop rsi - pop rbp - pop rbx - pop rdx - pop rcx - pop rax + pop rax + pop rbx + pop rcx + pop rdx + pop rsi + pop rdi + pop rbp + pop r8 + pop r9 + pop r10 + pop r11 + pop r12 + pop r13 + pop r14 + pop r15 %endmacro %macro IsrWithoutErrCode 1 global isr%1 isr%1: cli - push byte 0 - pushAll - xor rdi, rdi - mov rdi, %1 + push 0 + push %1 jmp isrPreHandler %endmacro @@ -59,8 +73,6 @@ isr%1: global isr%1 isr%1: cli - pushAll - xor rdi, rdi - mov rdi, %1 + push %1 jmp isrPreHandler %endmacro diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index b35bb5b..706f03d 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -94,14 +94,12 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg) IoPrintRtcTime(); - /* KernLog("There was %d ticks\n", IoGetRtcTicks()); */ - /* for (uint i = 1; i < 2 ; i++) { */ - /* while (IoGetRtcTicks() < i * 10000) { */ - /* } */ - /* IoPrintRtcTime(); */ - /* } */ - int* var = 7*GB; - *var = 2; + KernLog("There was %d ticks\n", IoGetRtcTicks()); + for (uint i = 1; i < 20000 ; i++) { + while (IoGetRtcTicks() < i * 10000) { + } + IoPrintRtcTime(); + } KernLog("Goodbye after %d ticks\n", IoGetRtcTicks()); // End this machine's suffering diff --git a/kaleid/kernel/io/keyb.asm b/kaleid/kernel/io/keyb.asm index 5128db4..5872003 100644 --- a/kaleid/kernel/io/keyb.asm +++ b/kaleid/kernel/io/keyb.asm @@ -65,5 +65,4 @@ KeybIsr: mov ds, ax popAll - sti iretq diff --git a/kaleid/kernel/io/rtc.asm b/kaleid/kernel/io/rtc.asm index 0457ad4..214af07 100644 --- a/kaleid/kernel/io/rtc.asm +++ b/kaleid/kernel/io/rtc.asm @@ -65,5 +65,4 @@ RtcIsr: mov ds, ax popAll - sti iretq