major refactorings
Signed-off-by: kaguya3311 <kaguya3311@national.shitposting.agency>
This commit is contained in:
+348
-110
@@ -1,124 +1,362 @@
|
||||
// ... includes ...
|
||||
#include "arch/x86_64/cpu/io.h"
|
||||
#include "libk/debug.h"
|
||||
#include "arch/x86_64/boot/isr.h"
|
||||
#include "idt.h"
|
||||
#define MODULE "ISR"
|
||||
#include "mm/vmm.h"
|
||||
#include "arch/x86_64/cpu/reg.h"
|
||||
#include "mp/mp.h"
|
||||
#include "mm/memory.h"
|
||||
#include "mm/pmm.h"
|
||||
#include "arch/x86_64/sys/halt.h"
|
||||
#include "sched/sched.h"
|
||||
|
||||
static inline uint64_t x86_64_read_cr2(void)
|
||||
{
|
||||
uint64_t value;
|
||||
__asm__ volatile ("mov %%cr2, %0" : "=r"(value));
|
||||
return value;
|
||||
void isr_install(void) {
|
||||
idt_set_gate(0, isr0, 0);
|
||||
idt_set_gate(1, isr1, 0);
|
||||
idt_set_gate(2, isr2, 0);
|
||||
idt_set_gate(3, isr3, 0);
|
||||
idt_set_gate(4, isr4, 0);
|
||||
idt_set_gate(5, isr5, 0);
|
||||
idt_set_gate(6, isr6, 0);
|
||||
idt_set_gate(7, isr7, 0);
|
||||
idt_set_gate(8, isr8, 0);
|
||||
idt_set_gate(9, isr9, 0);
|
||||
idt_set_gate(10, isr10, 0);
|
||||
idt_set_gate(11, isr11, 0);
|
||||
idt_set_gate(12, isr12, 0);
|
||||
idt_set_gate(13, isr13, 0);
|
||||
idt_set_gate(14, isr14, 2);
|
||||
idt_set_gate(15, isr15, 0);
|
||||
idt_set_gate(16, isr16, 0);
|
||||
idt_set_gate(17, isr17, 0);
|
||||
idt_set_gate(18, isr18, 0);
|
||||
idt_set_gate(19, isr19, 0);
|
||||
idt_set_gate(20, isr20, 0);
|
||||
idt_set_gate(21, isr21, 0);
|
||||
idt_set_gate(22, isr22, 0);
|
||||
idt_set_gate(23, isr23, 0);
|
||||
idt_set_gate(24, isr24, 0);
|
||||
idt_set_gate(25, isr25, 0);
|
||||
idt_set_gate(26, isr26, 0);
|
||||
idt_set_gate(27, isr27, 0);
|
||||
idt_set_gate(28, isr28, 0);
|
||||
idt_set_gate(29, isr29, 0);
|
||||
idt_set_gate(30, isr30, 0);
|
||||
idt_set_gate(31, isr31, 0);
|
||||
idt_set_gate(32, isr32, 0);
|
||||
idt_set_gate(33, isr33, 0);
|
||||
idt_set_gate(34, isr34, 0);
|
||||
idt_set_gate(35, isr35, 0);
|
||||
idt_set_gate(36, isr36, 0);
|
||||
idt_set_gate(37, isr37, 0);
|
||||
idt_set_gate(38, isr38, 0);
|
||||
idt_set_gate(39, isr39, 0);
|
||||
idt_set_gate(40, isr40, 0);
|
||||
idt_set_gate(41, isr41, 0);
|
||||
idt_set_gate(42, isr42, 0);
|
||||
idt_set_gate(43, isr43, 0);
|
||||
idt_set_gate(44, isr44, 0);
|
||||
idt_set_gate(45, isr45, 0);
|
||||
idt_set_gate(46, isr46, 0);
|
||||
idt_set_gate(47, isr47, 0);
|
||||
idt_set_gate(48, isr48, 1);
|
||||
idt_set_gate(49, isr49, 0);
|
||||
idt_set_gate(50, isr50, 0);
|
||||
idt_set_gate(51, isr51, 0);
|
||||
idt_set_gate(52, isr52, 0);
|
||||
idt_set_gate(53, isr53, 0);
|
||||
idt_set_gate(54, isr54, 0);
|
||||
idt_set_gate(55, isr55, 0);
|
||||
idt_set_gate(56, isr56, 0);
|
||||
idt_set_gate(57, isr57, 0);
|
||||
idt_set_gate(58, isr58, 0);
|
||||
idt_set_gate(59, isr59, 0);
|
||||
idt_set_gate(60, isr60, 0);
|
||||
idt_set_gate(61, isr61, 0);
|
||||
idt_set_gate(62, isr62, 0);
|
||||
idt_set_gate(63, isr63, 0);
|
||||
idt_set_gate(64, isr64, 0);
|
||||
idt_set_gate(65, isr65, 0);
|
||||
idt_set_gate(66, isr66, 0);
|
||||
idt_set_gate(67, isr67, 0);
|
||||
idt_set_gate(68, isr68, 0);
|
||||
idt_set_gate(69, isr69, 0);
|
||||
idt_set_gate(70, isr70, 0);
|
||||
idt_set_gate(71, isr71, 0);
|
||||
idt_set_gate(72, isr72, 0);
|
||||
idt_set_gate(73, isr73, 0);
|
||||
idt_set_gate(74, isr74, 0);
|
||||
idt_set_gate(75, isr75, 0);
|
||||
idt_set_gate(76, isr76, 0);
|
||||
idt_set_gate(77, isr77, 0);
|
||||
idt_set_gate(78, isr78, 0);
|
||||
idt_set_gate(79, isr79, 0);
|
||||
idt_set_gate(80, isr80, 0);
|
||||
idt_set_gate(81, isr81, 0);
|
||||
idt_set_gate(82, isr82, 0);
|
||||
idt_set_gate(83, isr83, 0);
|
||||
idt_set_gate(84, isr84, 0);
|
||||
idt_set_gate(85, isr85, 0);
|
||||
idt_set_gate(86, isr86, 0);
|
||||
idt_set_gate(87, isr87, 0);
|
||||
idt_set_gate(88, isr88, 0);
|
||||
idt_set_gate(89, isr89, 0);
|
||||
idt_set_gate(90, isr90, 0);
|
||||
idt_set_gate(91, isr91, 0);
|
||||
idt_set_gate(92, isr92, 0);
|
||||
idt_set_gate(93, isr93, 0);
|
||||
idt_set_gate(94, isr94, 0);
|
||||
idt_set_gate(95, isr95, 0);
|
||||
idt_set_gate(96, isr96, 0);
|
||||
idt_set_gate(97, isr97, 0);
|
||||
idt_set_gate(98, isr98, 0);
|
||||
idt_set_gate(99, isr99, 0);
|
||||
idt_set_gate(100, isr100, 0);
|
||||
idt_set_gate(101, isr101, 0);
|
||||
idt_set_gate(102, isr102, 0);
|
||||
idt_set_gate(103, isr103, 0);
|
||||
idt_set_gate(104, isr104, 0);
|
||||
idt_set_gate(105, isr105, 0);
|
||||
idt_set_gate(106, isr106, 0);
|
||||
idt_set_gate(107, isr107, 0);
|
||||
idt_set_gate(108, isr108, 0);
|
||||
idt_set_gate(109, isr109, 0);
|
||||
idt_set_gate(110, isr110, 0);
|
||||
idt_set_gate(111, isr111, 0);
|
||||
idt_set_gate(112, isr112, 0);
|
||||
idt_set_gate(113, isr113, 0);
|
||||
idt_set_gate(114, isr114, 0);
|
||||
idt_set_gate(115, isr115, 0);
|
||||
idt_set_gate(116, isr116, 0);
|
||||
idt_set_gate(117, isr117, 0);
|
||||
idt_set_gate(118, isr118, 0);
|
||||
idt_set_gate(119, isr119, 0);
|
||||
idt_set_gate(120, isr120, 0);
|
||||
idt_set_gate(121, isr121, 0);
|
||||
idt_set_gate(122, isr122, 0);
|
||||
idt_set_gate(123, isr123, 0);
|
||||
idt_set_gate(124, isr124, 0);
|
||||
idt_set_gate(125, isr125, 0);
|
||||
idt_set_gate(126, isr126, 0);
|
||||
idt_set_gate(127, isr127, 0);
|
||||
idt_set_gate(128, isr128, 0);
|
||||
idt_set_gate(129, isr129, 0);
|
||||
idt_set_gate(130, isr130, 0);
|
||||
idt_set_gate(131, isr131, 0);
|
||||
idt_set_gate(132, isr132, 0);
|
||||
idt_set_gate(133, isr133, 0);
|
||||
idt_set_gate(134, isr134, 0);
|
||||
idt_set_gate(135, isr135, 0);
|
||||
idt_set_gate(136, isr136, 0);
|
||||
idt_set_gate(137, isr137, 0);
|
||||
idt_set_gate(138, isr138, 0);
|
||||
idt_set_gate(139, isr139, 0);
|
||||
idt_set_gate(140, isr140, 0);
|
||||
idt_set_gate(141, isr141, 0);
|
||||
idt_set_gate(142, isr142, 0);
|
||||
idt_set_gate(143, isr143, 0);
|
||||
idt_set_gate(144, isr144, 0);
|
||||
idt_set_gate(145, isr145, 0);
|
||||
idt_set_gate(146, isr146, 0);
|
||||
idt_set_gate(147, isr147, 0);
|
||||
idt_set_gate(148, isr148, 0);
|
||||
idt_set_gate(149, isr149, 0);
|
||||
idt_set_gate(150, isr150, 0);
|
||||
idt_set_gate(151, isr151, 0);
|
||||
idt_set_gate(152, isr152, 0);
|
||||
idt_set_gate(153, isr153, 0);
|
||||
idt_set_gate(154, isr154, 0);
|
||||
idt_set_gate(155, isr155, 0);
|
||||
idt_set_gate(156, isr156, 0);
|
||||
idt_set_gate(157, isr157, 0);
|
||||
idt_set_gate(158, isr158, 0);
|
||||
idt_set_gate(159, isr159, 0);
|
||||
idt_set_gate(160, isr160, 0);
|
||||
idt_set_gate(161, isr161, 0);
|
||||
idt_set_gate(162, isr162, 0);
|
||||
idt_set_gate(163, isr163, 0);
|
||||
idt_set_gate(164, isr164, 0);
|
||||
idt_set_gate(165, isr165, 0);
|
||||
idt_set_gate(166, isr166, 0);
|
||||
idt_set_gate(167, isr167, 0);
|
||||
idt_set_gate(168, isr168, 0);
|
||||
idt_set_gate(169, isr169, 0);
|
||||
idt_set_gate(170, isr170, 0);
|
||||
idt_set_gate(171, isr171, 0);
|
||||
idt_set_gate(172, isr172, 0);
|
||||
idt_set_gate(173, isr173, 0);
|
||||
idt_set_gate(174, isr174, 0);
|
||||
idt_set_gate(175, isr175, 0);
|
||||
idt_set_gate(176, isr176, 0);
|
||||
idt_set_gate(177, isr177, 0);
|
||||
idt_set_gate(178, isr178, 0);
|
||||
idt_set_gate(179, isr179, 0);
|
||||
idt_set_gate(180, isr180, 0);
|
||||
idt_set_gate(181, isr181, 0);
|
||||
idt_set_gate(182, isr182, 0);
|
||||
idt_set_gate(183, isr183, 0);
|
||||
idt_set_gate(184, isr184, 0);
|
||||
idt_set_gate(185, isr185, 0);
|
||||
idt_set_gate(186, isr186, 0);
|
||||
idt_set_gate(187, isr187, 0);
|
||||
idt_set_gate(188, isr188, 0);
|
||||
idt_set_gate(189, isr189, 0);
|
||||
idt_set_gate(190, isr190, 0);
|
||||
idt_set_gate(191, isr191, 0);
|
||||
idt_set_gate(192, isr192, 0);
|
||||
idt_set_gate(193, isr193, 0);
|
||||
idt_set_gate(194, isr194, 0);
|
||||
idt_set_gate(195, isr195, 0);
|
||||
idt_set_gate(196, isr196, 0);
|
||||
idt_set_gate(197, isr197, 0);
|
||||
idt_set_gate(198, isr198, 0);
|
||||
idt_set_gate(199, isr199, 0);
|
||||
idt_set_gate(200, isr200, 0);
|
||||
idt_set_gate(201, isr201, 0);
|
||||
idt_set_gate(202, isr202, 0);
|
||||
idt_set_gate(203, isr203, 0);
|
||||
idt_set_gate(204, isr204, 0);
|
||||
idt_set_gate(205, isr205, 0);
|
||||
idt_set_gate(206, isr206, 0);
|
||||
idt_set_gate(207, isr207, 0);
|
||||
idt_set_gate(208, isr208, 0);
|
||||
idt_set_gate(209, isr209, 0);
|
||||
idt_set_gate(210, isr210, 0);
|
||||
idt_set_gate(211, isr211, 0);
|
||||
idt_set_gate(212, isr212, 0);
|
||||
idt_set_gate(213, isr213, 0);
|
||||
idt_set_gate(214, isr214, 0);
|
||||
idt_set_gate(215, isr215, 0);
|
||||
idt_set_gate(216, isr216, 0);
|
||||
idt_set_gate(217, isr217, 0);
|
||||
idt_set_gate(218, isr218, 0);
|
||||
idt_set_gate(219, isr219, 0);
|
||||
idt_set_gate(220, isr220, 0);
|
||||
idt_set_gate(221, isr221, 0);
|
||||
idt_set_gate(222, isr222, 0);
|
||||
idt_set_gate(223, isr223, 0);
|
||||
idt_set_gate(224, isr224, 0);
|
||||
idt_set_gate(225, isr225, 0);
|
||||
idt_set_gate(226, isr226, 0);
|
||||
idt_set_gate(227, isr227, 0);
|
||||
idt_set_gate(228, isr228, 0);
|
||||
idt_set_gate(229, isr229, 0);
|
||||
idt_set_gate(230, isr230, 0);
|
||||
idt_set_gate(231, isr231, 0);
|
||||
idt_set_gate(232, isr232, 0);
|
||||
idt_set_gate(233, isr233, 0);
|
||||
idt_set_gate(234, isr234, 0);
|
||||
idt_set_gate(235, isr235, 0);
|
||||
idt_set_gate(236, isr236, 0);
|
||||
idt_set_gate(237, isr237, 0);
|
||||
idt_set_gate(238, isr238, 0);
|
||||
idt_set_gate(239, isr239, 0);
|
||||
idt_set_gate(240, isr240, 0);
|
||||
idt_set_gate(241, isr241, 0);
|
||||
idt_set_gate(242, isr242, 0);
|
||||
idt_set_gate(243, isr243, 0);
|
||||
idt_set_gate(244, isr244, 0);
|
||||
idt_set_gate(245, isr245, 0);
|
||||
idt_set_gate(246, isr246, 0);
|
||||
idt_set_gate(247, isr247, 0);
|
||||
idt_set_gate(248, isr248, 0);
|
||||
idt_set_gate(249, isr249, 0);
|
||||
idt_set_gate(250, isr250, 0);
|
||||
idt_set_gate(251, isr251, 0);
|
||||
idt_set_gate(252, isr252, 0);
|
||||
idt_set_gate(253, isr253, 0);
|
||||
idt_set_gate(254, isr254, 0);
|
||||
idt_set_gate(255, isr255, 0);
|
||||
idt_reload();
|
||||
}
|
||||
|
||||
ISRHandler g_ISRHandlers[256];
|
||||
static const char* const g_Exceptions[] = {
|
||||
"Divide by zero error",
|
||||
"Debug",
|
||||
"Non-maskable Interrupt",
|
||||
"Breakpoint",
|
||||
"Overflow",
|
||||
"Bound Range Exceeded",
|
||||
"Invalid Opcode",
|
||||
"Device Not Available",
|
||||
"Double Fault",
|
||||
"Coprocessor Segment Overrun",
|
||||
"Invalid TSS",
|
||||
"Segment Not Present",
|
||||
"Stack-Segment Fault",
|
||||
"General Protection Fault",
|
||||
"Page Fault",
|
||||
"",
|
||||
"x87 Floating-Point Exception",
|
||||
"Alignment Check",
|
||||
"Machine Check",
|
||||
"SIMD Floating-Point Exception",
|
||||
"Virtualization Exception",
|
||||
"Control Protection Exception ",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"Hypervisor Injection Exception",
|
||||
"VMM Communication Exception",
|
||||
"Security Exception",
|
||||
""
|
||||
};
|
||||
static const char *isr_exception_messages[] = {"Divide by zero",
|
||||
"Debug",
|
||||
"NMI",
|
||||
"Breakpoint",
|
||||
"Overflow",
|
||||
"Bound Range Exceeded",
|
||||
"Invalid Opcode",
|
||||
"Device Not Available",
|
||||
"Double fault",
|
||||
"Co-processor Segment Overrun",
|
||||
"Invalid TSS",
|
||||
"Segment not present",
|
||||
"Stack-Segment Fault",
|
||||
"GPF",
|
||||
"Page Fault",
|
||||
"Reserved",
|
||||
"x87 Floating Point Exception",
|
||||
"alignment check",
|
||||
"Machine check",
|
||||
"SIMD floating-point exception",
|
||||
"Virtualization Exception",
|
||||
"Deadlock",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Reserved",
|
||||
"Security Exception",
|
||||
"Reserved",
|
||||
"Triple Fault",
|
||||
"FPU error"};
|
||||
|
||||
extern void x86_64_ISR_InitializeGates(void); // defined in isrs_gen.c
|
||||
static event_handlers_t event_handlers[256] = {NULL};
|
||||
|
||||
void x86_64_ISR_Initialize(void)
|
||||
{
|
||||
x86_64_ISR_InitializeGates();
|
||||
for (int i = 0; i < 256; i++)
|
||||
x86_64_IDT_EnableGate(i);
|
||||
x86_64_IDT_DisableGate(0x80); // syscall gate
|
||||
void isr_register_handler(int n, void *handler) {
|
||||
event_handlers[n] = handler;
|
||||
}
|
||||
|
||||
void page_fault_handler(Registers* regs, uint64_t cr2)
|
||||
{
|
||||
void isr_handle(registers_t *r) {
|
||||
if (r->cs & 0x3) {
|
||||
swapgs();
|
||||
}
|
||||
|
||||
if (r->isrNumber < 256 && event_handlers[r->isrNumber] != NULL) {
|
||||
event_handlers[r->isrNumber](r);
|
||||
} else {
|
||||
if (r->isrNumber < 32) {
|
||||
if (r->cs & 0x3) {
|
||||
struct thread *thrd = sched_get_running_thread();
|
||||
kprintf(
|
||||
"Killing user thread tid %d under process %s for exception "
|
||||
"%s\n",
|
||||
thrd->tid, thrd->mother_proc->name,
|
||||
isr_exception_messages[r->isrNumber]);
|
||||
kprintf("User thread crashed at address: %p\n", r->rip);
|
||||
thread_kill(thrd, true);
|
||||
} else {
|
||||
halt_other_cpus();
|
||||
kprintffos(0, "AH! UNHANDLED EXCEPTION!\n");
|
||||
kprintffos(0, "RIP: %p RBP: %p RSP: %p\n", r->rip, r->rbp,
|
||||
r->rsp);
|
||||
kprintffos(0, "RAX: %p RBX: %p RCX: %p\n", r->rax, r->rbx,
|
||||
r->rcx);
|
||||
kprintffos(0, "RDX: %p RDI: %p RSI: %p\n", r->rdx, r->rdi,
|
||||
r->rsi);
|
||||
kprintffos(0, "R8 : %p R9 : %p R10: %p\n", r->r8, r->r9,
|
||||
r->r10);
|
||||
kprintffos(0, "R11: %p R12: %p R13: %p\n", r->r11, r->r12,
|
||||
r->r13);
|
||||
kprintffos(0, "R14: %p R15: %p ERR: 0b%b\n", r->r14, r->r15,
|
||||
r->errorCode);
|
||||
kprintffos(0, "CS : %p SS : %p RFLAGS: %p\n", r->cs, r->ss,
|
||||
r->rflags);
|
||||
kprintffos(0, "FS : %p UGS: %p KGS: %p\n", read_fs_base(),
|
||||
read_user_gs(), read_kernel_gs());
|
||||
panic_((void *)r->rip, (void *)r->rbp,
|
||||
"Unhandled Exception: %s\n",
|
||||
isr_exception_messages[r->isrNumber]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// bit 0: present
|
||||
// bit 1: write
|
||||
// bit 2: user-mode
|
||||
// bit 3: reserved overwrite
|
||||
// bit 4: instruction fetch
|
||||
|
||||
log_crit(MODULE, "KERNEL PANIC! Exception %d (%s)", regs->interrupt, g_Exceptions[regs->interrupt]);
|
||||
|
||||
log_crit(MODULE, " rax=%x rbx=%x rcx=%x rdx=%x rsi=%x rdi=%x",
|
||||
regs->rax, regs->rbx, regs->rcx, regs->rdx, regs->rsi, regs->rdi);
|
||||
|
||||
log_crit(MODULE, " rsp=%x rbp=%x rip=%x rflags=%x cs=%x ss=%x",
|
||||
regs->rsp, regs->rbp, regs->rip, regs->rflags, regs->cs, regs->ss);
|
||||
|
||||
log_crit(MODULE, " interrupt=%x errorcode=%x", regs->interrupt, regs->error);
|
||||
|
||||
log_crit("PAGEFAULT", "Fault at address %lx (rip=%lx, err=%x)",
|
||||
cr2, regs->rip, regs->error);
|
||||
|
||||
log_crit(MODULE, "KERNEL PANIC!");
|
||||
|
||||
x86_64_Panic(); // or attempt recovery
|
||||
if (r->cs & 0x3) {
|
||||
swapgs();
|
||||
}
|
||||
}
|
||||
|
||||
void __attribute__((used)) x86_64_ISR_Handler(Registers* regs)
|
||||
{
|
||||
if (regs->interrupt == 14)
|
||||
{
|
||||
uint64_t cr2 = x86_64_read_cr2();
|
||||
page_fault_handler(regs, cr2);
|
||||
|
||||
}
|
||||
|
||||
if (g_ISRHandlers[regs->interrupt])
|
||||
g_ISRHandlers[regs->interrupt](regs);
|
||||
else if (regs->interrupt >= 32)
|
||||
log_err(MODULE, "Unhandled interrupt %d!", regs->interrupt);
|
||||
else {
|
||||
// panic log (use regs->rax etc. now)
|
||||
log_crit(MODULE, "KERNEL PANIC! Exception %d (%s)", regs->interrupt, g_Exceptions[regs->interrupt]);
|
||||
// ... print registers with rax/rbx etc. ...
|
||||
log_crit(MODULE, " rax=%x rbx=%x rcx=%x rdx=%x rsi=%x rdi=%x",
|
||||
regs->rax, regs->rbx, regs->rcx, regs->rdx, regs->rsi, regs->rdi);
|
||||
|
||||
log_crit(MODULE, " rsp=%x rbp=%x rip=%x rflags=%x cs=%x ss=%x",
|
||||
regs->rsp, regs->rbp, regs->rip, regs->rflags, regs->cs, regs->ss);
|
||||
|
||||
log_crit(MODULE, " interrupt=%x errorcode=%x", regs->interrupt, regs->error);
|
||||
|
||||
log_crit(MODULE, "KERNEL PANIC!");
|
||||
x86_64_Panic();
|
||||
}
|
||||
}
|
||||
|
||||
void x86_64_ISR_RegisterHandler(int interrupt, ISRHandler handler)
|
||||
{
|
||||
g_ISRHandlers[interrupt] = handler;
|
||||
x86_64_IDT_EnableGate(interrupt);
|
||||
}
|
||||
Reference in New Issue
Block a user