Implement GDT and basic IDT setup
This commit adds GDT initialization with proper code/data segments and reloads CS. It also adds the initial IDT structure and loads an empty IDT. Build configuration updated to disable SSE/MMX to prevent compiler generation of unsupported instructions in early boot.
This commit is contained in:
46
src/idt.c
Normal file
46
src/idt.c
Normal file
@@ -0,0 +1,46 @@
|
||||
#include "idt.h"
|
||||
#include <stdint.h>
|
||||
#include <stddef.h> /* for memset */
|
||||
|
||||
idt_entry_t idt_entries[256];
|
||||
idt_ptr_t idt_ptr;
|
||||
|
||||
extern void idt_load();
|
||||
|
||||
static void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags)
|
||||
{
|
||||
idt_entries[num].base_lo = base & 0xFFFF;
|
||||
idt_entries[num].base_hi = (base >> 16) & 0xFFFF;
|
||||
|
||||
idt_entries[num].sel = sel;
|
||||
idt_entries[num].always0 = 0;
|
||||
// We must uncomment the OR below when we get to using user-mode.
|
||||
// It sets the interrupt gate's privilege level to 3.
|
||||
idt_entries[num].flags = flags /* | 0x60 */;
|
||||
}
|
||||
|
||||
/* Note: memset implementation because we don't link with libc */
|
||||
static void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
unsigned char *p = s;
|
||||
while(n--)
|
||||
*p++ = (unsigned char)c;
|
||||
return s;
|
||||
}
|
||||
|
||||
void init_idt()
|
||||
{
|
||||
idt_ptr.limit = sizeof(idt_entry_t) * 256 - 1;
|
||||
idt_ptr.base = (uint32_t)&idt_entries;
|
||||
|
||||
memset(&idt_entries, 0, sizeof(idt_entry_t) * 256);
|
||||
|
||||
/* Determine valid flags:
|
||||
* 0x8E = 1000 1110
|
||||
* P=1, DPL=00, S=0 (System), Type=1110 (32-bit Interrupt Gate) */
|
||||
|
||||
/* For now, just load the IDT without any entries to verify loading works without crashing.
|
||||
Later we will set up ISRs. */
|
||||
|
||||
idt_load((uint32_t)&idt_ptr);
|
||||
}
|
||||
Reference in New Issue
Block a user