interrupt: load GDT/IDT on the stack
We have to use a separate Assembly function to do that, but maybe with some effort we can make that inline too
This commit is contained in:
parent
ebdc816d82
commit
aa11d25fa8
@ -36,16 +36,9 @@ void interrupt_Init() {
|
|||||||
assert(sizeof(interrupt_DescriptorTableReference) == 10 && "GDTR/IDTR size must be 10 bytes");
|
assert(sizeof(interrupt_DescriptorTableReference) == 10 && "GDTR/IDTR size must be 10 bytes");
|
||||||
assert(offsetof(interrupt_DescriptorTableReference, base) == 2 && "GDTR/IDTR must be packed");
|
assert(offsetof(interrupt_DescriptorTableReference, base) == 2 && "GDTR/IDTR must be packed");
|
||||||
|
|
||||||
assert(KERNEL_IDTR_MAPPING % 4 == 0 && "IDTR not aligned to 4-byte");
|
|
||||||
assert(KERNEL_GDTR_MAPPING % 4 == 0 && "GDTR not aligned to 4-byte");
|
|
||||||
|
|
||||||
|
|
||||||
// allocate GDTR
|
// allocate GDTR
|
||||||
io_WriteConsoleASCII("interrupt_Init() calling\n");
|
io_WriteConsoleASCII("interrupt_Init() calling\n");
|
||||||
interrupt_GDTR = (interrupt_DescriptorTableReference *)KERNEL_GDTR_MAPPING;
|
|
||||||
interrupt_GDTR->length = 4 * GDT_SIZE_BYTES - 1;
|
|
||||||
interrupt_GDTR->base = (void *)KERNEL_GDT_MAPPING;
|
|
||||||
io_WriteConsoleASCII("GDTR Written\n");
|
|
||||||
|
|
||||||
// set the 2 dummy gdts
|
// set the 2 dummy gdts
|
||||||
uint64_t *gdt = (uint64_t *)KERNEL_GDT_MAPPING;
|
uint64_t *gdt = (uint64_t *)KERNEL_GDT_MAPPING;
|
||||||
@ -56,20 +49,13 @@ void interrupt_Init() {
|
|||||||
gdt[4] = GDT_DATA_RING3;
|
gdt[4] = GDT_DATA_RING3;
|
||||||
io_WriteConsoleASCII("GDT Installed\n");
|
io_WriteConsoleASCII("GDT Installed\n");
|
||||||
|
|
||||||
interrupt_LoadGDT(interrupt_GDTR); // set it!
|
interrupt_LoadGDT(4 * GDT_SIZE_BYTES - 1, (void *)KERNEL_GDT_MAPPING); // set it!
|
||||||
io_WriteConsoleASCII("GDT OK\n");
|
io_WriteConsoleASCII("GDT OK\n");
|
||||||
|
|
||||||
//interrupt_Testcode();
|
//interrupt_Testcode();
|
||||||
io_WriteConsoleASCII("Testcode OK\n");
|
io_WriteConsoleASCII("Testcode OK\n");
|
||||||
|
|
||||||
|
|
||||||
// allocate IDTR
|
|
||||||
//interrupt_IDTR = kMalloc(sizeof(interrupt_DescriptorTableReference));
|
|
||||||
interrupt_IDTR = (interrupt_DescriptorTableReference *)KERNEL_IDTR_MAPPING;
|
|
||||||
interrupt_IDTR->length = KERNEL_IDT_SIZE - 1;
|
|
||||||
interrupt_IDTR->base = (void *)KERNEL_IDT_MAPPING;
|
|
||||||
io_WriteConsoleASCII("IDT Written\n");
|
|
||||||
|
|
||||||
interrupt_MapHandler(interrupt_Int0, 0);
|
interrupt_MapHandler(interrupt_Int0, 0);
|
||||||
interrupt_MapHandler(interrupt_Int1, 1);
|
interrupt_MapHandler(interrupt_Int1, 1);
|
||||||
interrupt_MapHandler(interrupt_Int2, 2);
|
interrupt_MapHandler(interrupt_Int2, 2);
|
||||||
@ -105,11 +91,10 @@ void interrupt_Init() {
|
|||||||
interrupt_MapHandler(interrupt_Int128, 128);
|
interrupt_MapHandler(interrupt_Int128, 128);
|
||||||
io_WriteConsoleASCII("IDT Installed\n");
|
io_WriteConsoleASCII("IDT Installed\n");
|
||||||
|
|
||||||
interrupt_LoadIDT(interrupt_IDTR); // set it!
|
interrupt_LoadIDT(KERNEL_IDT_SIZE - 1, (void *)KERNEL_IDT_MAPPING); // set it!
|
||||||
|
|
||||||
|
|
||||||
io_WriteConsoleASCII("IDT OK\n");
|
io_WriteConsoleASCII("IDT OK\n");
|
||||||
|
|
||||||
|
|
||||||
interrupt_Enabled = true;
|
interrupt_Enabled = true;
|
||||||
asm volatile("sti");
|
asm volatile("sti");
|
||||||
|
|
||||||
|
@ -53,14 +53,8 @@ SYSV_ABI void interrupt_Handler(int vec, int errcode, uint64_t rip, uint64_t rax
|
|||||||
// defined in assembly
|
// defined in assembly
|
||||||
SYSV_ABI void interrupt_ReloadSegments();
|
SYSV_ABI void interrupt_ReloadSegments();
|
||||||
|
|
||||||
inline void interrupt_LoadGDT(interrupt_DescriptorTableReference *gdtr) {
|
SYSV_ABI void interrupt_LoadGDT(uint16_t length_sub1, void *base_ptr);
|
||||||
asm volatile("lgdt %0"
|
SYSV_ABI void interrupt_LoadIDT(uint16_t length_sub1, void *base_ptr);
|
||||||
: "=m"(*gdtr));
|
|
||||||
}
|
|
||||||
inline void interrupt_LoadIDT(interrupt_DescriptorTableReference *idtr) {
|
|
||||||
asm volatile("lidt %0"
|
|
||||||
: "=m"(*idtr));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define INTERRUPT_DISABLE \
|
#define INTERRUPT_DISABLE \
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
format elf64
|
format elf64
|
||||||
|
|
||||||
public interrupt_ReloadSegments
|
public interrupt_ReloadSegments
|
||||||
|
public interrupt_LoadGDT
|
||||||
|
public interrupt_LoadIDT
|
||||||
|
|
||||||
|
|
||||||
section '.text' executable
|
section '.text' executable
|
||||||
@ -25,3 +27,30 @@ interrupt_ReloadSegments:
|
|||||||
push rax
|
push rax
|
||||||
retfq
|
retfq
|
||||||
|
|
||||||
|
; sysvx64call void interrupt_LoadGDT(uint16_t length_sub1, void* base_ptr)
|
||||||
|
;
|
||||||
|
; Input: (uint16_t di, void* rsi)
|
||||||
|
; Clobbers: rax, flags
|
||||||
|
interrupt_LoadGDT:
|
||||||
|
mov rax, rsp ; save old RSP
|
||||||
|
sub rsp, 10
|
||||||
|
and rsp, 0xfffffffffffffffc ; align RSP to 4-byte
|
||||||
|
mov [rsp], di
|
||||||
|
mov [rsp+2], rsi
|
||||||
|
lgdt [rsp]
|
||||||
|
mov rsp, rax ; restore old RSP
|
||||||
|
ret
|
||||||
|
|
||||||
|
; sysvx64call void interrupt_LoadIDT(uint16_t length_sub1, void* base_ptr)
|
||||||
|
;
|
||||||
|
; Input: (uint16_t di, void* rsi)
|
||||||
|
; Clobbers: rax, flags
|
||||||
|
interrupt_LoadIDT:
|
||||||
|
mov rax, rsp ; save old RSP
|
||||||
|
sub rsp, 10
|
||||||
|
and rsp, 0xfffffffffffffffc ; align RSP to 4-byte
|
||||||
|
mov [rsp], di
|
||||||
|
mov [rsp+2], rsi
|
||||||
|
lidt [rsp]
|
||||||
|
mov rsp, rax ; restore old RSP
|
||||||
|
ret
|
||||||
|
@ -21,12 +21,9 @@ extern "C" {
|
|||||||
#define KERNEL_GDT_MAPPING (KERNEL_MISC_MAPPING + KERNEL_IDT_SIZE)
|
#define KERNEL_GDT_MAPPING (KERNEL_MISC_MAPPING + KERNEL_IDT_SIZE)
|
||||||
#define KERNEL_GDT_SIZE (16ull * 8)
|
#define KERNEL_GDT_SIZE (16ull * 8)
|
||||||
|
|
||||||
#define KERNEL_IDTR_MAPPING (KERNEL_MISC_MAPPING + KERNEL_IDT_SIZE + KERNEL_GDT_SIZE)
|
#define KERNEL_MISC_NEXT (KERNEL_MISC_MAPPING + KERNEL_IDT_SIZE + KERNEL_GDT_SIZE)
|
||||||
#define KERNEL_GDTR_MAPPING (KERNEL_MISC_MAPPING + KERNEL_IDT_SIZE + KERNEL_GDT_SIZE + 12)
|
|
||||||
|
|
||||||
#define KERNEL_MISC_NEXT (KERNEL_MISC_MAPPING + KERNEL_IDT_SIZE + KERNEL_GDT_SIZE + 24)
|
#define KERNEL_MISC_SIZE (KERNEL_IDT_SIZE + KERNEL_GDT_SIZE) // add all the misc sizes
|
||||||
|
|
||||||
#define KERNEL_MISC_SIZE (KERNEL_IDT_SIZE + KERNEL_GDT_SIZE + 24) // add all the misc sizes
|
|
||||||
|
|
||||||
|
|
||||||
extern uint64_t paging_LoaderCodeAddress, paging_LoaderCodeSize; // physical address for loader code section
|
extern uint64_t paging_LoaderCodeAddress, paging_LoaderCodeSize; // physical address for loader code section
|
||||||
|
Loading…
Reference in New Issue
Block a user