Function comments (v1)
This commit is contained in:
@@ -24,6 +24,12 @@ extern char vector_0_handler[];
|
||||
// Timer ticks
|
||||
extern volatile uint64_t ticks;
|
||||
|
||||
/*
|
||||
* idt_set_entry - Sets an Interrupt Descriptor Table entry
|
||||
* @vector: Vector number in the IDT
|
||||
* @handler: Pointer to the executable Interrupt Service Routine
|
||||
* @dpl: Desired privilege level
|
||||
*/
|
||||
void idt_set_entry(uint8_t vector, void* handler, uint8_t dpl)
|
||||
{
|
||||
uint64_t handler_addr = (uint64_t)handler;
|
||||
@@ -42,6 +48,10 @@ void idt_set_entry(uint8_t vector, void* handler, uint8_t dpl)
|
||||
entry->ist = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* idt_load - Loads the Interrupt Descriptor Table
|
||||
* @idt_addr: Address to the IDT
|
||||
*/
|
||||
void idt_load(void* idt_addr)
|
||||
{
|
||||
// "limit" = "size" = Size of the IDT - 1 byte = (16*256)-1 = 0xFFF
|
||||
@@ -50,9 +60,14 @@ void idt_load(void* idt_addr)
|
||||
asm volatile("lidt %0" :: "m"(idt_reg));
|
||||
}
|
||||
|
||||
/*
|
||||
* idt_init - Initializes the Interrupt Descriptor Table
|
||||
*
|
||||
* Sets all IDT entries and their corresponding service routines,
|
||||
* then loads it.
|
||||
*/
|
||||
void idt_init()
|
||||
{
|
||||
// Hardcoded...
|
||||
for (size_t i=0; i<=KERNEL_IDT_ENTRIES; i++) {
|
||||
// Each vector handler is 16-byte aligned, so <vector_no>*16 = address of that handler
|
||||
idt_set_entry(i, vector_0_handler + (i*16), 0);
|
||||
@@ -61,6 +76,15 @@ void idt_init()
|
||||
DEBUG("IDT initialized");
|
||||
}
|
||||
|
||||
/*
|
||||
* read_cr2 - Reads the CR2 register
|
||||
*
|
||||
* This function is useful because it gets the address
|
||||
* that the CPU tried to access in the case of a #PF.
|
||||
*
|
||||
* Return:
|
||||
* %val - CR2 register value
|
||||
*/
|
||||
static inline uint64_t read_cr2(void)
|
||||
{
|
||||
uint64_t val;
|
||||
@@ -68,6 +92,15 @@ static inline uint64_t read_cr2(void)
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* page_fault_handler - Handler for #PF
|
||||
* @ctx: CPU context
|
||||
*
|
||||
* Shows detail about a #PF, especially what instruction (RIP)
|
||||
* caused it, and what address access (CR2) caused it.
|
||||
* Also displays an interpretation of the thrown error code.
|
||||
* Then halts the system. We could implement demand paging later.
|
||||
*/
|
||||
static void page_fault_handler(struct cpu_status_t* ctx)
|
||||
{
|
||||
// It could be used to remap pages etc. to fix the fault, but right now what I'm more
|
||||
@@ -89,6 +122,13 @@ static void page_fault_handler(struct cpu_status_t* ctx)
|
||||
panic(ctx, "page fault");
|
||||
}
|
||||
|
||||
/*
|
||||
* gp_fault_handler - Handler for #GP
|
||||
* @ctx: CPU context
|
||||
*
|
||||
* Shows detail about a General Protection Fault,
|
||||
* and what may have caused it. Halts the system.
|
||||
*/
|
||||
static void gp_fault_handler(struct cpu_status_t* ctx)
|
||||
{
|
||||
DEBUG("\x1b[38;5;231mGeneral Protection Fault at rip=0x%p, err=%u (%s)\x1b[0m",
|
||||
@@ -114,6 +154,17 @@ static void gp_fault_handler(struct cpu_status_t* ctx)
|
||||
panic(ctx, "gp fault");
|
||||
}
|
||||
|
||||
/*
|
||||
* interrupt_dispatch - Interrupt dispatcher
|
||||
* @context: CPU context
|
||||
*
|
||||
* This function is where all interrupt routines go, after they passed
|
||||
* through their corresponding vector handler in the IDT assembly stub.
|
||||
* It catches all exceptions.
|
||||
*
|
||||
* Return:
|
||||
* <context> - CPU context after interrupt
|
||||
*/
|
||||
struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
|
||||
{
|
||||
if (context == NULL) {
|
||||
|
||||
Reference in New Issue
Block a user