massive overhaul to my exception system
This commit is contained in:
4
Makefile
4
Makefile
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
CC = i686-elf-gcc
|
CC = i686-elf-gcc
|
||||||
|
|
||||||
DEBUG_FLAGS = -D__TESTING__ -g -Wno-div-by-zero
|
DEBUG_FLAGS = -D__TESTING__ -g
|
||||||
|
|
||||||
CFLAGS = -m32 -ffreestanding -Wall -Wextra -Werror -Wpedantic --sysroot=$(PWD)/sysroot -isystem=/usr/include -Iinclude -MD $(DEBUG_FLAGS)
|
CFLAGS = -m32 -ffreestanding -Wall -Wextra -Werror -Wpedantic --sysroot=$(PWD)/sysroot -isystem=/usr/include -Iinclude -MD $(DEBUG_FLAGS)
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ all: kernel.elf
|
|||||||
env: install-headers install-libs # TODO: change this to a file specific target, so it doesnt recompile everytime, and so we can move as a prereq on kernel.elf
|
env: install-headers install-libs # TODO: change this to a file specific target, so it doesnt recompile everytime, and so we can move as a prereq on kernel.elf
|
||||||
util/./gen-clangd.sh
|
util/./gen-clangd.sh
|
||||||
|
|
||||||
kernel.elf: install-headers install-libs $(c_kern_objects) $(asm_kern_objects)
|
kernel.elf: install-headers install-libs env $(c_kern_objects) $(asm_kern_objects)
|
||||||
$(CC) $(CFLAGS) -T $(shell find . -name "link.ld") -o $@ $(c_kern_objects) $(asm_kern_objects) -nostdlib -lk -lgcc
|
$(CC) $(CFLAGS) -T $(shell find . -name "link.ld") -o $@ $(c_kern_objects) $(asm_kern_objects) -nostdlib -lk -lgcc
|
||||||
|
|
||||||
os.iso: kernel.elf
|
os.iso: kernel.elf
|
||||||
|
7
TODO.md
7
TODO.md
@ -1,7 +1,6 @@
|
|||||||
## What do I need to do?
|
## What do I need to do?
|
||||||
|
|
||||||
Exception handling is a must for next part, we need to be able to dianogse issues better
|
### Features I want
|
||||||
|
|
||||||
- Want the address of the fault
|
- A kernel bus
|
||||||
- Proper handling of the issue
|
- some kind of driver where I can send messages that can eventually be accessed globally by other drives / applications
|
||||||
- Maybe dump registers?
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
|
#include <stdatomic.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __TESTING__
|
|
||||||
#include <kernel/_kernel.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#endif
|
|
||||||
|
#include <kernel/_kernel.h>
|
||||||
#include <kernel/x86/idt.h>
|
#include <kernel/x86/idt.h>
|
||||||
#include <kernel/x86/pic.h>
|
#include <kernel/x86/pic.h>
|
||||||
#include <kernel/x86/io.h>
|
#include <kernel/x86/io.h>
|
||||||
@ -19,21 +18,218 @@ static bool vectors[IDT_MAX_DESCRIPTORS];
|
|||||||
|
|
||||||
extern struct keyboard_state keyb_state;
|
extern struct keyboard_state keyb_state;
|
||||||
|
|
||||||
void exception_handler(struct cpu_state __attribute__((unused)) cpu, uint32_t interrupt, struct stack_state stack)
|
|
||||||
|
#define EXTERNAL_BIT (0x1)
|
||||||
|
|
||||||
|
#define TBL_GDT (0x0)
|
||||||
|
#define TBL_LDT (0x2)
|
||||||
|
#define TBL_IDT (0x1)
|
||||||
|
#define TBL_IDT_TWO (0x3)
|
||||||
|
|
||||||
|
static void examine_selector(uint32_t selector)
|
||||||
{
|
{
|
||||||
printf("%1 %2\n", interrupt, stack.eflags);
|
printf("The interrupt arised %s.\n", (selector & EXTERNAL_BIT) == EXTERNAL_BIT ? "externally" : "internally");
|
||||||
if (interrupt <= 31) { // TODO: implement proper handling for each exception, also implement the proper gates & error code checking
|
|
||||||
#ifdef __TESTING__
|
|
||||||
kerror("EXCEPTION");
|
printf("The descriptor 0x%x, is located in the ", selector, (selector & 0x0000FFFF) >> 3);
|
||||||
printf("Exeption: %2\n", interrupt);
|
if ((((selector >> 1) & TBL_IDT) == TBL_IDT)
|
||||||
#endif
|
|| ((selector >> 1) & TBL_IDT_TWO) == TBL_IDT_TWO) {
|
||||||
//__asm__ volatile ("cli; hlt"); // hangs the computer
|
puts("IDT.");
|
||||||
|
|
||||||
|
} else if (((selector >> 1) & TBL_LDT) == TBL_LDT) {
|
||||||
|
puts("LDT.");
|
||||||
|
} else {
|
||||||
|
puts("GDT.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interrupt == PIC_KEYB) {
|
return;
|
||||||
unsigned char in = inb(0x60);
|
}
|
||||||
do_keypress(decode_scancode(in));
|
|
||||||
PIC_sendEOI(1);
|
#undef TBL_GDT
|
||||||
|
#undef TBL_LDT
|
||||||
|
#undef TBL_IDT
|
||||||
|
#undef TBL_IDT_TWO
|
||||||
|
|
||||||
|
#define PF_P (1 << 0)
|
||||||
|
#define PF_W (1 << 1)
|
||||||
|
#define PF_U (1 << 2)
|
||||||
|
#define PF_R (1 << 3)
|
||||||
|
#define PF_I (1 << 4)
|
||||||
|
#define PF_PK (1 << 5)
|
||||||
|
#define PF_SS (1 << 6)
|
||||||
|
#define PF_SGX (1 << 15)
|
||||||
|
static void examine_page_fault(uint32_t error_code)
|
||||||
|
{
|
||||||
|
puts("Page fault:");
|
||||||
|
if (error_code & PF_P) {
|
||||||
|
puts("Page-protection violation.");
|
||||||
|
} else {
|
||||||
|
puts("Not present page.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error_code & PF_W) {
|
||||||
|
puts("Write access.");
|
||||||
|
} else {
|
||||||
|
puts("Read access.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error_code & PF_U) {
|
||||||
|
puts("In CPL 3.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error_code & PF_R) { // Only applies if PSE or PAE are set in CR4
|
||||||
|
puts("One or more page directory entires contain reserved bits which are set to 1.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error_code & PF_I) { // Only applicable when the No-Execute bit is supported and enabled
|
||||||
|
puts("Instruction fetch.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error_code & PF_PK) {
|
||||||
|
puts("Protection-key violation"); //TODO PRKU (user mode access) or PRKS MSR (supervisor mode access) specifies the key rights
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error_code & PF_SS) {
|
||||||
|
puts("Shadow stack access.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error_code & PF_SGX) { // Unrelated to ordinary paging
|
||||||
|
puts("SGX vioilation");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO, also sets CR2 reg to the virtual address which caused the page fault
|
||||||
|
}
|
||||||
|
#undef PF_P
|
||||||
|
#undef PF_W
|
||||||
|
#undef PF_U
|
||||||
|
#undef PF_R
|
||||||
|
#undef PF_I
|
||||||
|
#undef PF_PK
|
||||||
|
#undef PF_SS
|
||||||
|
#undef PF_SGX
|
||||||
|
|
||||||
|
#define EXCEPTION_LOCATION() printf("Exception occurred at 0x%2\n", stack.eip)
|
||||||
|
|
||||||
|
void exception_handler(struct cpu_state __attribute__((unused)) cpu, uint32_t interrupt, struct stack_state stack)
|
||||||
|
{
|
||||||
|
uint32_t inbyte;
|
||||||
|
switch (interrupt) {
|
||||||
|
/** EXCEPTIONS BEGIN **/
|
||||||
|
case EXCEPT_DIV_ERR:
|
||||||
|
kerror("EXCEPTION: DIV BY ZERO");
|
||||||
|
EXCEPTION_LOCATION();
|
||||||
|
break;
|
||||||
|
case EXCEPT_DEBUG:
|
||||||
|
kinfo("EXCEPTION: DEBUG"); // TODO: this one has more specific requirements
|
||||||
|
break;
|
||||||
|
case EXCEPT_NMI:
|
||||||
|
kinfo("EXCEPTION: NON-MASKABLE INTERRUPT"); // TODO
|
||||||
|
break;
|
||||||
|
case EXCEPT_BREAKPOINT:
|
||||||
|
kinfo("EXCEPTION: BREAKPOINT");
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
case EXCEPT_OVERFLOW:
|
||||||
|
kerror("EXCEPTION: OVERFLOW");
|
||||||
|
break;
|
||||||
|
case EXCEPT_BOUND_RANGE_EXCEEDED:
|
||||||
|
kerror("EXCEPTION: BOUND RANGE EXCEEDED");
|
||||||
|
EXCEPTION_LOCATION();
|
||||||
|
break;
|
||||||
|
case EXCEPT_INVALID_OPCODE:
|
||||||
|
kerror("EXCEPTION: INVALID OPCODE");
|
||||||
|
EXCEPTION_LOCATION();
|
||||||
|
break;
|
||||||
|
case EXCEPT_DEVICE_NOT_AVAILABLE:
|
||||||
|
kerror("EXCEPTION: DEVICE NOT AVAILABLE");
|
||||||
|
printf("Instructions expecting an FPU were used, but no FPU was found. Is it disabled in CR0? Do you have an FPU?\n");
|
||||||
|
EXCEPTION_LOCATION();
|
||||||
|
break;
|
||||||
|
case EXCEPT_DOUBLE_FAULT:
|
||||||
|
kerror("EXCEPTION: DOUBLE FAULT");
|
||||||
|
__asm__ volatile ("cli; hlt"); // boned
|
||||||
|
break;
|
||||||
|
case EXCEPT_INVALID_TSS:
|
||||||
|
kerror("EXCEPTION: INVALID TSS");
|
||||||
|
examine_selector(stack.error_code);
|
||||||
|
// TODO: when i implement the TSS, the EIP will be one of two things
|
||||||
|
// if this occurs before loading segmenet selectors from the TSS, EIP will be the instruction that caused the instruction
|
||||||
|
// otherwise its the first instruction in the new task
|
||||||
|
break;
|
||||||
|
case EXCEPT_SEG_NOT_PRESENT:
|
||||||
|
kerror("EXCEPTION: SEGMENT NOT PRESENT");
|
||||||
|
EXCEPTION_LOCATION();
|
||||||
|
examine_selector(stack.error_code);
|
||||||
|
break;
|
||||||
|
case EXCEPT_STACK_SEG_FAULT:
|
||||||
|
kerror("EXCEPTION: STACK-SEGMENT FAULT");
|
||||||
|
if (stack.error_code == 0) {
|
||||||
|
EXCEPTION_LOCATION();
|
||||||
|
} else {
|
||||||
|
printf("Tried loading non-present stack segment during hardware task switch.\n");
|
||||||
|
examine_selector(stack.error_code);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EXCEPT_GENERAL_PROTECTION:
|
||||||
|
kerror("EXCEPTION: GENERAL PROTECTION FAULT");
|
||||||
|
EXCEPTION_LOCATION();
|
||||||
|
if (stack.error_code != 0)
|
||||||
|
examine_selector(stack.error_code);
|
||||||
|
break;
|
||||||
|
case EXCEPT_PAGE_FAULT:
|
||||||
|
kerror("EXCEPTION: PAGE FAULT");
|
||||||
|
EXCEPTION_LOCATION();
|
||||||
|
examine_page_fault(stack.error_code);
|
||||||
|
break;
|
||||||
|
case EXCEPT_FLOATING_POINT_ERR_FPU:
|
||||||
|
kerror("EXCEPTION: FLOATING POINT ERROR FPU");
|
||||||
|
// TODO: this requires a custom handler, it needs another register
|
||||||
|
break;
|
||||||
|
case EXCEPT_ALIGNMENT_CHECK:
|
||||||
|
kerror("EXCEPTION: ALIGNMENT CHECK");
|
||||||
|
|
||||||
|
// TODO: only in CPL3
|
||||||
|
break;
|
||||||
|
case EXCEPT_MACHINE_CHECK:
|
||||||
|
kerror("EXCEPTION: MACHINE CHECK");
|
||||||
|
// TODO disabled by default
|
||||||
|
break;
|
||||||
|
case EXCEPT_FLOATING_POINT_ERR_SIMD:
|
||||||
|
kerror("EXCEPTION: FLOATING POINT ERROR SIMD");
|
||||||
|
// TODO disabled by default
|
||||||
|
break;
|
||||||
|
case EXCEPT_VIRT:
|
||||||
|
kerror("EXCEPTION: VIRTUALIZATION");
|
||||||
|
break;
|
||||||
|
case EXCEPT_CTRL_PROT:
|
||||||
|
kerror("EXCEPTION: CONTROL PROTECTION");
|
||||||
|
printf("Error code: 0x%2\n", stack.error_code);
|
||||||
|
break;
|
||||||
|
case EXCEPT_HYPERVISOR_INJECTION:
|
||||||
|
kerror("EXCEPTION: HYPERVISOR INJECTION");
|
||||||
|
break;
|
||||||
|
case EXCEPT_VMM_COMMUNICATION:
|
||||||
|
kerror("EXCEPTION: VMM COMMUNICATION");
|
||||||
|
printf("Error code: 0x%2\n", stack.error_code);
|
||||||
|
break;
|
||||||
|
case EXCEPT_SECURITY_EXCEPTION:
|
||||||
|
kerror("EXCEPTION: SECURITY");
|
||||||
|
printf("Error code: 0x%2\n", stack.error_code);
|
||||||
|
break;
|
||||||
|
/** EXCEPTIONS END **/
|
||||||
|
|
||||||
|
/** PIC BEGIN **/
|
||||||
|
case PIC_KEYB:
|
||||||
|
inbyte = inb(0x60);
|
||||||
|
do_keypress(decode_scancode(inbyte));
|
||||||
|
PIC_sendEOI(1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/** PIC END **/
|
||||||
|
default:
|
||||||
|
kerror("EXCEPTION: UNHANDLED EXCEPTION OR INTERRUPT");
|
||||||
|
printf("Error code: 0x%2\n", stack.error_code);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,14 +3,6 @@ extern exception_handler_err
|
|||||||
|
|
||||||
%macro isr_err_stub 1
|
%macro isr_err_stub 1
|
||||||
isr_stub_%+%1:
|
isr_stub_%+%1:
|
||||||
;pushad
|
|
||||||
;cld
|
|
||||||
;push dword %1
|
|
||||||
;call exception_handler_err
|
|
||||||
;pop eax ; pop the error
|
|
||||||
;pop eax ; make sure to pop off the dword!!
|
|
||||||
;popad
|
|
||||||
;iret
|
|
||||||
push dword %1 ; push the interrupt number
|
push dword %1 ; push the interrupt number
|
||||||
jmp common_interrupt_handler
|
jmp common_interrupt_handler
|
||||||
|
|
||||||
@ -18,13 +10,6 @@ isr_stub_%+%1:
|
|||||||
|
|
||||||
%macro isr_no_err_stub 1
|
%macro isr_no_err_stub 1
|
||||||
isr_stub_%+%1:
|
isr_stub_%+%1:
|
||||||
;pushad
|
|
||||||
;cld
|
|
||||||
;push dword %1
|
|
||||||
;call exception_handler
|
|
||||||
;pop eax
|
|
||||||
;popad
|
|
||||||
;iret
|
|
||||||
push dword 0
|
push dword 0
|
||||||
push dword %1
|
push dword %1
|
||||||
jmp common_interrupt_handler
|
jmp common_interrupt_handler
|
||||||
@ -51,7 +36,8 @@ common_interrupt_handler:
|
|||||||
pop ebx
|
pop ebx
|
||||||
pop eax
|
pop eax
|
||||||
|
|
||||||
; restore the esp
|
; lets move the stack before the error code and interrupt number
|
||||||
|
; since we don't want these to be popped anywhere
|
||||||
add esp, 8
|
add esp, 8
|
||||||
|
|
||||||
iret
|
iret
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#define EXCEPT_INVALID_OPCODE 6
|
#define EXCEPT_INVALID_OPCODE 6
|
||||||
#define EXCEPT_DEVICE_NOT_AVAILABLE 7
|
#define EXCEPT_DEVICE_NOT_AVAILABLE 7
|
||||||
#define EXCEPT_DOUBLE_FAULT 8
|
#define EXCEPT_DOUBLE_FAULT 8
|
||||||
#define EXCEPT_SEG_OVERRUN 9
|
|
||||||
#define EXCEPT_INVALID_TSS 10
|
#define EXCEPT_INVALID_TSS 10
|
||||||
#define EXCEPT_SEG_NOT_PRESENT 11
|
#define EXCEPT_SEG_NOT_PRESENT 11
|
||||||
#define EXCEPT_STACK_SEG_FAULT 12
|
#define EXCEPT_STACK_SEG_FAULT 12
|
||||||
@ -27,6 +26,9 @@
|
|||||||
#define EXCEPT_FLOATING_POINT_ERR_SIMD 19
|
#define EXCEPT_FLOATING_POINT_ERR_SIMD 19
|
||||||
#define EXCEPT_VIRT 20
|
#define EXCEPT_VIRT 20
|
||||||
#define EXCEPT_CTRL_PROT 21
|
#define EXCEPT_CTRL_PROT 21
|
||||||
|
#define EXCEPT_HYPERVISOR_INJECTION 28
|
||||||
|
#define EXCEPT_VMM_COMMUNICATION 29
|
||||||
|
#define EXCEPT_SECURITY_EXCEPTION 30
|
||||||
|
|
||||||
struct cpu_state {
|
struct cpu_state {
|
||||||
uint32_t eax;
|
uint32_t eax;
|
||||||
|
Reference in New Issue
Block a user