Better docs and structure
This commit is contained in:
68
idt.c
68
idt.c
@@ -1,28 +1,55 @@
|
||||
/*
|
||||
* idt.c – Interrupt Descriptor Table setup and exception handling.
|
||||
*
|
||||
* On initialisation the kernel copies the firmware's IDT (preserving
|
||||
* its hardware IRQ handlers for vectors 32-47), then overrides CPU
|
||||
* exception vectors 0-31 with our own stubs from isr.S.
|
||||
*
|
||||
* Hardware IRQs receive an EOI and return. CPU exceptions print
|
||||
* diagnostic information (including CR2 for page faults) and halt.
|
||||
*/
|
||||
|
||||
#include "idt.h"
|
||||
|
||||
#define IDT_SIZE 256
|
||||
#define IDT_TYPE_INTERRUPT 0x8E
|
||||
/* ================================================================
|
||||
* Constants and internal types
|
||||
* ================================================================ */
|
||||
|
||||
#define IDT_SIZE 256
|
||||
#define IDT_TYPE_INTERRUPT 0x8E /* P=1, DPL=0, 64-bit interrupt gate */
|
||||
|
||||
/* Single 16-byte IDT entry (x86-64 long mode). */
|
||||
typedef struct {
|
||||
UINT16 offset_low;
|
||||
UINT16 selector;
|
||||
UINT8 ist;
|
||||
UINT8 type_attr;
|
||||
UINT16 offset_mid;
|
||||
UINT32 offset_high;
|
||||
UINT32 zero;
|
||||
UINT16 offset_low; /* bits 0-15 of handler address */
|
||||
UINT16 selector; /* code segment selector */
|
||||
UINT8 ist; /* interrupt stack table index */
|
||||
UINT8 type_attr; /* type and attributes */
|
||||
UINT16 offset_mid; /* bits 16-31 of handler address */
|
||||
UINT32 offset_high; /* bits 32-63 of handler address */
|
||||
UINT32 zero; /* reserved, must be zero */
|
||||
} __attribute__((packed)) IdtEntry;
|
||||
|
||||
/* IDTR register layout for the LIDT instruction. */
|
||||
typedef struct {
|
||||
UINT16 limit;
|
||||
UINT64 base;
|
||||
} __attribute__((packed)) IdtPtr;
|
||||
|
||||
static IdtEntry idt[IDT_SIZE];
|
||||
/* ================================================================
|
||||
* Module state
|
||||
* ================================================================ */
|
||||
|
||||
static IdtEntry idt[IDT_SIZE];
|
||||
static BootInfo *gBoot = NULL;
|
||||
|
||||
/* Defined in isr.S – one stub function per vector (0-255). */
|
||||
extern void (*isr_stub_table[])(void);
|
||||
|
||||
/* ================================================================
|
||||
* IDT gate helpers
|
||||
* ================================================================ */
|
||||
|
||||
/* Install a single IDT gate pointing at `handler`. */
|
||||
static void idt_set_gate(UINTN index, void (*handler)(void))
|
||||
{
|
||||
UINT64 addr = (UINT64)(UINTN)handler;
|
||||
@@ -39,11 +66,17 @@ static void idt_set_gate(UINTN index, void (*handler)(void))
|
||||
idt[index].zero = 0;
|
||||
}
|
||||
|
||||
/* Load a new IDT register value. */
|
||||
static void lidt(const IdtPtr *idtr)
|
||||
{
|
||||
__asm__ __volatile__("lidt (%0)" :: "r"(idtr));
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
* Exception name lookup
|
||||
* ================================================================ */
|
||||
|
||||
/* Return a human-readable name for CPU exception vectors 0-31. */
|
||||
static const CHAR16 *exception_name(UINTN vector)
|
||||
{
|
||||
switch (vector) {
|
||||
@@ -83,11 +116,17 @@ static const CHAR16 *exception_name(UINTN vector)
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
* PIC and low-level helpers
|
||||
* ================================================================ */
|
||||
|
||||
/* Write a byte to an I/O port. */
|
||||
static inline void outb(UINT16 port, UINT8 value)
|
||||
{
|
||||
__asm__ __volatile__("outb %0, %1" :: "a"(value), "Nd"(port));
|
||||
}
|
||||
|
||||
/* Send End-Of-Interrupt to the 8259 PIC(s). */
|
||||
static void pic_eoi(UINTN vector)
|
||||
{
|
||||
if (vector >= 40) {
|
||||
@@ -96,6 +135,7 @@ static void pic_eoi(UINTN vector)
|
||||
outb(0x20, 0x20); /* EOI to master PIC */
|
||||
}
|
||||
|
||||
/* Disable interrupts and halt forever (unrecoverable fault). */
|
||||
static void halt_forever(void)
|
||||
{
|
||||
for (;;) {
|
||||
@@ -103,6 +143,10 @@ static void halt_forever(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
* ISR dispatcher (called from isr_common in isr.S)
|
||||
* ================================================================ */
|
||||
|
||||
void isr_handler(ISRFrame *frame)
|
||||
{
|
||||
UINT64 cr2 = 0;
|
||||
@@ -132,6 +176,10 @@ void isr_handler(ISRFrame *frame)
|
||||
halt_forever();
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
* IDT initialisation
|
||||
* ================================================================ */
|
||||
|
||||
void idt_init(BootInfo *Boot)
|
||||
{
|
||||
IdtPtr old_idtr;
|
||||
|
||||
Reference in New Issue
Block a user