kernel/x86_64: Provide an alternate kernel stack for exceptions
All checks were successful
continuous-integration/drone/push Build is passing

This avoids stack-related triple faults, hopefully.

Closes #33.
This commit is contained in:
apio 2023-07-21 15:14:52 +02:00
parent 310b325af8
commit 36a74fd8d6
Signed by: apio
GPG Key ID: B8A7D06E42258954
2 changed files with 10 additions and 4 deletions

View File

@ -1,6 +1,8 @@
#include "arch/MMU.h"
#include "arch/x86_64/CPU.h"
#include <luna/CString.h>
#include <luna/Check.h>
#include <luna/Stack.h>
#include <luna/Types.h>
struct [[gnu::packed]] GDTR
@ -75,10 +77,13 @@ static void set_tss_base(GDTEntry* tss1, HighGDTEntry* tss2, u64 addr)
tss2->base_high = (u32)(addr >> 32);
}
static u8 alternate_stack[ARCH_PAGE_SIZE * 4];
static void setup_tss()
{
memset(&task_state_segment, 0, sizeof(TSS));
task_state_segment.iomap_base = sizeof(TSS);
task_state_segment.ist[0] = Stack { (u64)alternate_stack, ARCH_PAGE_SIZE * 4 }.top();
set_tss_base(&gdt.tss, &gdt.tss2, (u64)&task_state_segment);
set_limit(&gdt.tss, sizeof(TSS) - 1);
}

View File

@ -47,20 +47,21 @@ struct [[gnu::packed]] IDTR
static_assert(sizeof(IDTR) == 10UL);
static void idt_add_handler(short num, void* handler, u8 type_attr)
static void idt_add_handler(short num, void* handler, u8 type_attr, u8 ist)
{
check(handler != nullptr);
expect(num < 256, "IDT can only hold up to 256 entries");
IDTEntry* const entry_for_handler = &idt[num];
entry_for_handler->selector = 0x08;
entry_for_handler->type_attr = type_attr;
entry_for_handler->ist = ist;
entry_for_handler->set_offset((u64)handler);
}
#define INT(x) extern "C" void _isr##x()
#define TRAP(x) idt_add_handler(x, (void*)_isr##x, IDT_TA_TrapGate)
#define IRQ(x) idt_add_handler(x, (void*)_isr##x, IDT_TA_InterruptGate)
#define SYS(x) idt_add_handler(x, (void*)_isr##x, IDT_TA_UserCallableInterruptGate)
#define TRAP(x) idt_add_handler(x, (void*)_isr##x, IDT_TA_TrapGate, 1)
#define IRQ(x) idt_add_handler(x, (void*)_isr##x, IDT_TA_InterruptGate, 0)
#define SYS(x) idt_add_handler(x, (void*)_isr##x, IDT_TA_UserCallableInterruptGate, 0)
INT(0);
INT(1);