Initial Commit

This commit is contained in:
kaguya
2026-04-14 22:52:24 -04:00
commit 426ad76676
184 changed files with 11033 additions and 0 deletions
+159
View File
@@ -0,0 +1,159 @@
#include "ata.h"
#include "io.h" // your existing inb/outb/insw
#include "stdio.h"
#include "memory.h"
#include <stdbool.h>
#define ATA_PRIMARY_DATA 0x1F0
#define ATA_PRIMARY_ERROR 0x1F1
#define ATA_PRIMARY_SECCOUNT 0x1F2
#define ATA_PRIMARY_LBALOW 0x1F3
#define ATA_PRIMARY_LBAMID 0x1F4
#define ATA_PRIMARY_LBAHIGH 0x1F5
#define ATA_PRIMARY_DRIVE 0x1F6
#define ATA_PRIMARY_STATUS 0x1F7
#define ATA_PRIMARY_COMMAND 0x1F7
#define ATA_STATUS_BSY 0x80
#define ATA_STATUS_DRDY 0x40
#define ATA_STATUS_DRQ 0x08
#define ATA_STATUS_ERR 0x01
#define ATA_CMD_IDENTIFY 0xEC
#define ATA_CMD_READ_SECTORS 0x20
static void ata_wait_ready(void)
{
while (x86_64_inb(ATA_PRIMARY_STATUS) & ATA_STATUS_BSY) {}
while (!(x86_64_inb(ATA_PRIMARY_STATUS) & ATA_STATUS_DRDY)) {}
}
static bool ata_poll(void)
{
// 400 ns delay
for (int i = 0; i < 4; i++)
x86_64_inb(ATA_PRIMARY_STATUS);
uint8_t status;
while ((status = x86_64_inb(ATA_PRIMARY_STATUS)) & ATA_STATUS_BSY);
if (status & ATA_STATUS_ERR) return false;
while (!(status & ATA_STATUS_DRQ)) {
status = x86_64_inb(ATA_PRIMARY_STATUS);
if (status & ATA_STATUS_ERR) return false;
}
return true;
}
void ata_init(void)
{
x86_64_outb(0x3F6, 0x02); // disable interrupts on primary controller
ata_wait_ready();
x86_64_outb(ATA_PRIMARY_DRIVE, 0xA0); // select master
ata_wait_ready();
printf("ATA: Primary master (hda) initialized\n");
}
void ata_identify(void)
{
static uint16_t buffer[256];
x86_64_outb(ATA_PRIMARY_DRIVE, 0xA0);
x86_64_outb(ATA_PRIMARY_SECCOUNT, 0);
x86_64_outb(ATA_PRIMARY_LBALOW, 0);
x86_64_outb(ATA_PRIMARY_LBAMID, 0);
x86_64_outb(ATA_PRIMARY_LBAHIGH, 0);
x86_64_outb(ATA_PRIMARY_COMMAND, ATA_CMD_IDENTIFY);
if (x86_64_inb(ATA_PRIMARY_STATUS) == 0) {
printf("ATA: No primary master drive detected\n");
return;
}
if (!ata_poll()) {
printf("ATA poll failed at ATA_IDENTIFY\n");
}
if (x86_64_inb(ATA_PRIMARY_STATUS) & ATA_STATUS_ERR) {
printf("ATA: Identify error\n");
return;
}
x86_64_insw(ATA_PRIMARY_DATA, buffer, 256);
printf("ATA: Disk model: ");
for (int i = 27; i <= 46; i++) {
uint16_t w = buffer[i];
char high = w >> 8;
char low = w & 0xFF;
printf("%c%c", high, low); // swap bytes
}
printf("\n");
printf("ATA: Total sectors: %lu\n", (uint64_t)buffer[60] | ((uint64_t)buffer[61] << 16));
}
bool ata_read_sectors(uint64_t lba, uint8_t sector_count, void* buffer)
{
if (sector_count == 0) return true;
ata_wait_ready();
x86_64_outb(ATA_PRIMARY_DRIVE, 0xE0 | ((lba >> 24) & 0x0F));
x86_64_outb(ATA_PRIMARY_SECCOUNT, sector_count);
x86_64_outb(ATA_PRIMARY_LBALOW, (uint8_t)lba);
x86_64_outb(ATA_PRIMARY_LBAMID, (uint8_t)(lba >> 8));
x86_64_outb(ATA_PRIMARY_LBAHIGH, (uint8_t)(lba >> 16));
x86_64_outb(ATA_PRIMARY_COMMAND, ATA_CMD_READ_SECTORS);
uint16_t* buf = buffer;
for (uint8_t i = 0; i < sector_count; i++) {
if (!ata_poll()) {
printf("ATA poll failed at ATA_read_sectors\n");
}
if (x86_64_inb(ATA_PRIMARY_STATUS) & ATA_STATUS_ERR) {
printf("ATA read error at LBA %lu\n", lba + i);
return false;
}
x86_64_insw(ATA_PRIMARY_DATA, buf, 256); // 512 bytes
buf += 256;
}
return true;
}
bool ata_write_sectors(uint64_t lba, uint8_t sector_count, const void* buffer) {
if (sector_count == 0) return true;
ata_wait_ready();
x86_64_outb(ATA_PRIMARY_DRIVE, 0xE0 | ((lba >> 24) & 0x0F));
x86_64_outb(ATA_PRIMARY_SECCOUNT, sector_count);
x86_64_outb(ATA_PRIMARY_LBALOW, (uint8_t)lba);
x86_64_outb(ATA_PRIMARY_LBAMID, (uint8_t)(lba >> 8));
x86_64_outb(ATA_PRIMARY_LBAHIGH, (uint8_t)(lba >> 16));
x86_64_outb(ATA_PRIMARY_COMMAND, 0x30); // write sectors
const uint16_t* buf = buffer;
for (uint8_t i = 0; i < sector_count; i++) {
if (!ata_poll()) {
return false;
}
x86_64_outsw(ATA_PRIMARY_DATA, buf, 256);
buf += 256;
}
return true;
}
+13
View File
@@ -0,0 +1,13 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
void ata_init(void);
void ata_identify(void);
// Read `sector_count` 512-byte sectors starting at LBA `lba` into `buffer`.
// Buffer must be large enough (sector_count * 512).
bool ata_read_sectors(uint64_t lba, uint8_t sector_count, void* buffer);
bool ata_write_sectors(uint64_t lba, uint8_t sector_count, const void* buffer);
+13
View File
@@ -0,0 +1,13 @@
#include "e9.h"
#include <arch/x86_64/io.h>
void e9_putc(char c)
{
x86_64_outb(0xE9, c);
}
void e9_puts(const char* str) {
while (*str) {
e9_putc(*str++);
}
}
+3
View File
@@ -0,0 +1,3 @@
#pragma once
void e9_putc(char c);
+88
View File
@@ -0,0 +1,88 @@
#include "gdt.h"
#include "mm/memory.h"
#include "mp/spinlock.h"
#include <stddef.h>
struct gdt_desc {
uint16_t limit;
uint16_t base_low;
uint8_t base_mid;
uint8_t access;
uint8_t granularity;
uint8_t base_hi;
} __attribute__((packed));
struct tss_desc {
uint16_t length;
uint16_t base_low;
uint8_t base_mid;
uint8_t flags1;
uint8_t flags2;
uint8_t base_hi;
uint32_t base_upper32;
uint32_t reserved;
} __attribute__((packed));
struct gdt_ptr {
uint16_t limit;
uint64_t ptr;
} __attribute__((packed));
struct gdtr {
struct gdt_desc entries[5];
struct tss_desc tss;
} __attribute__((packed));
struct gdtr gdt = {0};
struct gdt_ptr gdt_pointer = {0};
struct tss kernel_tss = {0};
spinlock_t s_gdt_lock = SPINLOCK_INIT;
extern void gdt_reload(void);
extern void tss_reload(void);
void x86_64_GDT_Initialize(void) {
uint64_t flags;
spinlock_acquire_irqsave(&s_gdt_lock, &flags);
// Kernel code
gdt.entries[1].access = 0b10011010;
gdt.entries[1].granularity = 0b00100000;
// Kernel data
gdt.entries[2].access = 0b10010010;
// User data
gdt.entries[3].access = 0b11110010;
// User code
gdt.entries[4].access = 0b11111010;
gdt.entries[4].granularity = 0b00100000;
// TSS
gdt.tss.length = sizeof(struct tss);
gdt.tss.flags1 = 0b10001001;
// Set the pointer
gdt_pointer.limit = sizeof(gdt) - 1;
gdt_pointer.ptr = (uint64_t)&gdt;
gdt_reload();
tss_reload();
spinlock_release_irqrestore(&s_gdt_lock, flags);
}
void gdt_load_tss(size_t addr) {
uint64_t flags;
spinlock_acquire_irqsave(&s_gdt_lock, &flags);
gdt.tss.base_low = (uint16_t)addr;
gdt.tss.base_mid = (uint8_t)(addr >> 16);
gdt.tss.flags1 = 0b10001001;
gdt.tss.base_hi = (uint8_t)(addr >> 24);
gdt.tss.base_upper32 = (uint32_t)(addr >> 32);
tss_reload();
spinlock_release_irqrestore(&s_gdt_lock, flags);
}
+34
View File
@@ -0,0 +1,34 @@
#pragma once
#include <stdint.h>
#include <stddef.h>
#define GDT_KERNEL_BASE 0x0
#define GDT_KERNEL_CODE64 0x8
#define GDT_KERNEL_DATA64 0x10
#define GDT_USER_BASE 0x18
#define GDT_USER_DATA64 0x18
#define GDT_USER_CODE64 0x20
#define GDT_TSS 0x28
struct tss {
uint32_t reserved;
uint64_t rsp0;
uint64_t rsp1;
uint64_t rsp2;
uint64_t reserved2;
uint64_t ist1;
uint64_t ist2;
uint64_t ist3;
uint64_t ist4;
uint64_t ist5;
uint64_t ist6;
uint64_t ist7;
uint64_t reserved3;
uint16_t reserved4;
uint16_t iomap_base;
} __attribute__((packed));
void x86_64_GDT_Initialize(void);
void gdt_load_tss(size_t addr);
+27
View File
@@ -0,0 +1,27 @@
.intel_syntax noprefix
.global x86_64_GDT_Load
.extern gdt_pointer
.global gdt_reload
gdt_reload:
lgdt [rip + gdt_pointer]
push 8
lea rax, [rip + .flush]
push rax
lretq
.flush:
mov eax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
ret
.global tss_reload
tss_reload:
mov ax, 0x2B
ltr ax
ret
+167
View File
@@ -0,0 +1,167 @@
#include "pic.h"
#include "io.h"
#include <stdbool.h>
#include <stdint.h>
#define PIC1_COMMAND_PORT 0x20
#define PIC1_DATA_PORT 0x21
#define PIC2_COMMAND_PORT 0xA0
#define PIC2_DATA_PORT 0xA1
// Initialization Control Word 1
// -----------------------------
// 0 IC4 if set, the PIC expects to receive ICW4 during initialization
// 1 SGNL if set, only 1 PIC in the system; if unset, the PIC is cascaded with slave PICs
// and ICW3 must be sent to controller
// 2 ADI call address interval, set: 4, not set: 8; ignored on x86, set to 0
// 3 LTIM if set, operate in level triggered mode; if unset, operate in edge triggered mode
// 4 INIT set to 1 to initialize PIC
// 5-7 ignored on x86, set to 0
enum {
PIC_ICW1_ICW4 = 0x01,
PIC_ICW1_SINGLE = 0x02,
PIC_ICW1_INTERVAL4 = 0x04,
PIC_ICW1_LEVEL = 0x08,
PIC_ICW1_INITIALIZE = 0x10
} PIC_ICW1;
// Initialization Control Word 4
// -----------------------------
// 0 uPM if set, PIC is in 80x86 mode; if cleared, in MCS-80/85 mode
// 1 AEOI if set, on last interrupt acknowledge pulse, controller automatically performs
// end of interrupt operation
// 2 M/S only use if BUF is set; if set, selects buffer master; otherwise, selects buffer slave
// 3 BUF if set, controller operates in buffered mode
// 4 SFNM specially fully nested mode; used in systems with large number of cascaded controllers
// 5-7 reserved, set to 0
enum {
PIC_ICW4_8086 = 0x1,
PIC_ICW4_AUTO_EOI = 0x2,
PIC_ICW4_BUFFER_MASTER = 0x4,
PIC_ICW4_BUFFER_SLAVE = 0x0,
PIC_ICW4_BUFFERRED = 0x8,
PIC_ICW4_SFNM = 0x10,
} PIC_ICW4;
enum {
PIC_CMD_END_OF_INTERRUPT = 0x20,
PIC_CMD_READ_IRR = 0x0A,
PIC_CMD_READ_ISR = 0x0B,
} PIC_CMD;
static uint16_t g_PicMask = 0xffff;
static bool g_AutoEoi = false;
void i8259_SetMask(uint16_t newMask)
{
g_PicMask = newMask;
x86_64_outb(PIC1_DATA_PORT, g_PicMask & 0xFF);
x86_64_iowait();
x86_64_outb(PIC2_DATA_PORT, g_PicMask >> 8);
x86_64_iowait();
}
uint16_t i8259_GetMask()
{
return x86_64_inb(PIC1_DATA_PORT) | (x86_64_inb(PIC2_DATA_PORT) << 8);
}
void i8259_Configure(uint8_t offsetPic1, uint8_t offsetPic2, bool autoEoi)
{
// Mask everything
i8259_SetMask(0xFFFF);
// initialization control word 1
x86_64_outb(PIC1_COMMAND_PORT, PIC_ICW1_ICW4 | PIC_ICW1_INITIALIZE);
x86_64_iowait();
x86_64_outb(PIC2_COMMAND_PORT, PIC_ICW1_ICW4 | PIC_ICW1_INITIALIZE);
x86_64_iowait();
// initialization control word 2 - the offsets
x86_64_outb(PIC1_DATA_PORT, offsetPic1);
x86_64_iowait();
x86_64_outb(PIC2_DATA_PORT, offsetPic2);
x86_64_iowait();
// initialization control word 3
x86_64_outb(PIC1_DATA_PORT, 0x4); // tell PIC1 that it has a slave at IRQ2 (0000 0100)
x86_64_iowait();
x86_64_outb(PIC2_DATA_PORT, 0x2); // tell PIC2 its cascade identity (0000 0010)
x86_64_iowait();
// initialization control word 4
uint8_t icw4 = PIC_ICW4_8086;
if (autoEoi) {
icw4 |= PIC_ICW4_AUTO_EOI;
}
x86_64_outb(PIC1_DATA_PORT, icw4);
x86_64_iowait();
x86_64_outb(PIC2_DATA_PORT, icw4);
x86_64_iowait();
// mask all interrupts until they are enabled by the device driver
i8259_SetMask(0xFFFF);
}
void i8259_SendEndOfInterrupt(int irq)
{
if (irq >= 8)
x86_64_outb(PIC2_COMMAND_PORT, PIC_CMD_END_OF_INTERRUPT);
x86_64_outb(PIC1_COMMAND_PORT, PIC_CMD_END_OF_INTERRUPT);
}
void i8259_Disable()
{
i8259_SetMask(0xFFFF);
}
void i8259_Mask(int irq)
{
i8259_SetMask(g_PicMask | (1 << irq));
}
void i8259_Unmask(int irq)
{
i8259_SetMask(g_PicMask & ~(1 << irq));
}
uint16_t i8259_ReadIrqRequestRegister()
{
x86_64_outb(PIC1_COMMAND_PORT, PIC_CMD_READ_IRR);
x86_64_outb(PIC2_COMMAND_PORT, PIC_CMD_READ_IRR);
return ((uint16_t)x86_64_inb(PIC2_COMMAND_PORT)) | (((uint16_t)x86_64_inb(PIC2_COMMAND_PORT)) << 8);
}
uint16_t i8259_ReadInServiceRegister()
{
x86_64_outb(PIC1_COMMAND_PORT, PIC_CMD_READ_ISR);
x86_64_outb(PIC2_COMMAND_PORT, PIC_CMD_READ_ISR);
return ((uint16_t)x86_64_inb(PIC2_COMMAND_PORT)) | (((uint16_t)x86_64_inb(PIC2_COMMAND_PORT)) << 8);
}
bool i8259_Probe()
{
i8259_Disable();
i8259_SetMask(0x1337);
return i8259_GetMask() == 0x1337;
}
static const PICDriver g_PicDriver = {
.Name = "8259 PIC",
.Probe = &i8259_Probe,
.Initialize = &i8259_Configure,
.Disable = &i8259_Disable,
.SendEndOfInterrupt = &i8259_SendEndOfInterrupt,
.Mask = &i8259_Mask,
.Unmask = &i8259_Unmask,
};
const PICDriver* i8259_GetDriver()
{
return &g_PicDriver;
}
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include "pic.h"
const PICDriver* i8259_GetDriver();
uint16_t i8259_GetMask();
void i8259_SetMask(uint16_t newMask);
void i8259_Configure(uint8_t offsetPic1, uint8_t offsetPic2, bool autoEoi);
+35
View File
@@ -0,0 +1,35 @@
#include "idt.h"
#include "util/binary.h"
IDTEntry g_IDT[256];
IDTDescriptor g_IDTDescriptor = { sizeof(g_IDT) - 1, g_IDT };
extern void x86_64_IDT_Load(IDTDescriptor* descriptor);
void x86_64_IDT_SetGate(int interrupt, void* base, uint16_t segmentDescriptor, uint8_t flags)
{
uintptr_t addr = (uintptr_t)base;
g_IDT[interrupt].BaseLow = addr & 0xFFFF;
g_IDT[interrupt].SegmentSelector = segmentDescriptor;
g_IDT[interrupt].IST = 0;
g_IDT[interrupt].Flags = flags;
g_IDT[interrupt].BaseMid = (addr >> 16) & 0xFFFF;
g_IDT[interrupt].BaseHigh = (addr >> 32) & 0xFFFFFFFF;
g_IDT[interrupt].Reserved = 0;
}
void x86_64_IDT_EnableGate(int interrupt)
{
FLAG_SET(g_IDT[interrupt].Flags, IDT_FLAG_PRESENT);
}
void x86_64_IDT_DisableGate(int interrupt)
{
FLAG_UNSET(g_IDT[interrupt].Flags, IDT_FLAG_PRESENT);
}
void x86_64_IDT_Initialize(void)
{
x86_64_IDT_Load(&g_IDTDescriptor);
}
+44
View File
@@ -0,0 +1,44 @@
#pragma once
#include <stdint.h>
typedef enum
{
IDT_FLAG_GATE_TASK = 0x5,
IDT_FLAG_GATE_16BIT_INT = 0x6,
IDT_FLAG_GATE_16BIT_TRAP = 0x7,
IDT_FLAG_GATE_32BIT_INT = 0xE,
IDT_FLAG_GATE_32BIT_TRAP = 0xF,
IDT_FLAG_RING0 = (0 << 5),
IDT_FLAG_RING1 = (1 << 5),
IDT_FLAG_RING2 = (2 << 5),
IDT_FLAG_RING3 = (3 << 5),
IDT_FLAG_PRESENT = 0x80,
} IDT_FLAGS;
typedef struct
{
uint16_t BaseLow;
uint16_t SegmentSelector;
uint8_t IST; // Interrupt Stack Table (0 = default)
uint8_t Flags;
uint16_t BaseMid;
uint32_t BaseHigh;
uint32_t Reserved;
} __attribute__((packed)) IDTEntry;
typedef struct
{
uint16_t Limit;
IDTEntry* Ptr;
} __attribute__((packed)) IDTDescriptor;
void x86_64_IDT_Initialize(void);
void x86_64_IDT_SetGate(int interrupt, void* base, uint16_t segmentDescriptor, uint8_t flags);
void x86_64_IDT_EnableGate(int interrupt);
void x86_64_IDT_DisableGate(int interrupt);
+6
View File
@@ -0,0 +1,6 @@
.intel_syntax noprefix
.global x86_64_IDT_Load
x86_64_IDT_Load:
lidt [rdi] # descriptor in RDI
ret
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include <stdint.h>
void x86_64_outb(uint16_t port, uint8_t value);
uint8_t x86_64_inb(uint16_t port);
uint16_t x86_64_inw(uint16_t port);
void x86_64_outw(uint16_t port, uint16_t value);
void x86_64_insw(uint16_t port, uint16_t* buffer, uint32_t count);
void x86_64_outl(uint16_t port, uint32_t value);
uint32_t x86_64_inl(uint16_t port);
void x86_64_outsw(uint16_t port, uint16_t* buffer, uint32_t count);
void x86_64_iowait(void);
void x86_64_Panic(void) __attribute__((noreturn));
void x86_64_EnableInterrupts(void);
void x86_64_DisableInterrupts(void);
void x86_64_crashme(void);
+96
View File
@@ -0,0 +1,96 @@
.intel_syntax noprefix
.global x86_64_outb
x86_64_outb:
mov dx, di
mov al, sil
out dx, al
ret
.global x86_64_inb
x86_64_inb:
mov dx, di
xor eax, eax
in al, dx
ret
.global x86_64_inw
x86_64_inw:
mov dx, di
xor eax, eax
in ax, dx
ret
.global x86_64_outw
x86_64_outw:
mov dx, di
mov ax, si
out dx, ax
ret
.global x86_64_outl
x86_64_outl:
mov dx, di
mov eax, esi
out dx, eax
ret
.global x86_64_inl
x86_64_inl:
mov dx, di
xor eax, eax
in eax, dx
ret
.global x86_64_insw
x86_64_insw:
test rdx, rdx
jz .inswdone
mov rcx, rdx
mov dx, di
mov rdi, rsi
cld
rep insw
.inswdone:
ret
.global x86_64_outsw
x86_64_outsw:
test rdx, rdx
jz .outswdone
mov rcx, rdx
mov dx, di
mov rsi, rsi
cld
rep outsw
.outswdone:
ret
.global x86_64_Panic
x86_64_Panic:
cli
hlt
1: jmp 1b
.global x86_64_EnableInterrupts
x86_64_EnableInterrupts:
sti
ret
.global x86_64_DisableInterrupts
x86_64_DisableInterrupts:
cli
ret
.global x86_64_iowait
x86_64_iowait:
out 0x80, al // classic I/O wait
ret
.global x86_64_crashme
x86_64_crashme:
xor rdx, rdx
mov rax, 1
mov rbx, 0
div rbx
ret
+65
View File
@@ -0,0 +1,65 @@
#include "irq.h"
#include "i8259.h"
#include "io.h"
#include <stddef.h>
#include <util/arrays.h>
#include "stdio.h"
#include <debug.h>
#define PIC_REMAP_OFFSET 0x20
#define MODULE "PIC"
IRQHandler g_IRQHandlers[16];
static const PICDriver* g_Driver = NULL;
void x86_64_IRQ_Handler(Registers *regs)
{
int irq = regs->interrupt - PIC_REMAP_OFFSET;
if (g_IRQHandlers[irq] != NULL)
{
// handle IRQ
g_IRQHandlers[irq](regs);
}
else
{
log_warn(MODULE, "Unhandled IRQ %d...", irq);
}
// send EOI
g_Driver->SendEndOfInterrupt(irq);
}
void x86_64_IRQ_Initialize(void)
{
const PICDriver* drivers[] = {
i8259_GetDriver(),
};
for (int i = 0; i < SIZE(drivers); i++) {
if (drivers[i]->Probe()) {
g_Driver = drivers[i];
}
}
if (g_Driver == NULL) {
log_warn(MODULE, "No PIC found!");
return;
}
log_info(MODULE, "Found %s PIC.", g_Driver->Name);
g_Driver->Initialize(PIC_REMAP_OFFSET, PIC_REMAP_OFFSET + 8, false);
// register ISR handlers for each of the 16 irq lines
for (int i = 0; i < 16; i++)
x86_64_ISR_RegisterHandler(PIC_REMAP_OFFSET + i, x86_64_IRQ_Handler);
x86_64_EnableInterrupts();
}
void x86_64_IRQ_RegisterHandler(int irq, IRQHandler handler)
{
g_IRQHandlers[irq] = handler;
}
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include "isr.h"
typedef void (*IRQHandler)(Registers* regs);
void x86_64_IRQ_Initialize();
void x86_64_IRQ_RegisterHandler(int irq, IRQHandler handler);
+82
View File
@@ -0,0 +1,82 @@
// ... includes ...
#include "io.h"
#include "debug.h"
#include "arch/x86_64/isr.h"
#include "idt.h"
#define MODULE "ISR"
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",
""
};
extern void x86_64_ISR_InitializeGates(void); // defined in isrs_gen.c
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 if you want
}
void __attribute__((used)) x86_64_ISR_Handler(Registers* regs)
{
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);
}
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
typedef struct
{
uint64_t r15, r14, r13, r12, r11, r10, r9, r8;
uint64_t rdi, rsi, rbp, rdx, rcx, rbx, rax;
uint64_t interrupt, error;
uint64_t rip, cs, rflags, rsp, ss;
} __attribute__((packed)) Registers;
typedef void (*ISRHandler)(Registers* regs);
void x86_64_ISR_Initialize(void);
void x86_64_ISR_RegisterHandler(int interrupt, ISRHandler handler);
+58
View File
@@ -0,0 +1,58 @@
.intel_syntax noprefix
.extern x86_64_ISR_Handler
.macro ISR_NOERRORCODE num
.global x86_64_ISR\num
x86_64_ISR\num:
push 0
push \num
jmp isr_common
.endm
.macro ISR_ERRORCODE num
.global x86_64_ISR\num
x86_64_ISR\num:
push \num
jmp isr_common
.endm
.include "arch/x86_64/isrs_gen.inc" // update path if needed
isr_common:
push rax
push rbx
push rcx
push rdx
push rbp
push rsi
push rdi
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
mov rdi, rsp // Registers* in RDI
call x86_64_ISR_Handler
pop r15
pop r14
pop r13
pop r12
pop r11
pop r10
pop r9
pop r8
pop rdi
pop rsi
pop rbp
pop rdx
pop rcx
pop rbx
pop rax
add rsp, 16 // pop interrupt + error code
iretq
+520
View File
@@ -0,0 +1,520 @@
// !!! THIS FILE IS AUTOGENERATED !!!
#include "idt.h"
#include "gdt.h"
void x86_64_ISR0();
void x86_64_ISR1();
void x86_64_ISR2();
void x86_64_ISR3();
void x86_64_ISR4();
void x86_64_ISR5();
void x86_64_ISR6();
void x86_64_ISR7();
void x86_64_ISR8();
void x86_64_ISR9();
void x86_64_ISR10();
void x86_64_ISR11();
void x86_64_ISR12();
void x86_64_ISR13();
void x86_64_ISR14();
void x86_64_ISR15();
void x86_64_ISR16();
void x86_64_ISR17();
void x86_64_ISR18();
void x86_64_ISR19();
void x86_64_ISR20();
void x86_64_ISR21();
void x86_64_ISR22();
void x86_64_ISR23();
void x86_64_ISR24();
void x86_64_ISR25();
void x86_64_ISR26();
void x86_64_ISR27();
void x86_64_ISR28();
void x86_64_ISR29();
void x86_64_ISR30();
void x86_64_ISR31();
void x86_64_ISR32();
void x86_64_ISR33();
void x86_64_ISR34();
void x86_64_ISR35();
void x86_64_ISR36();
void x86_64_ISR37();
void x86_64_ISR38();
void x86_64_ISR39();
void x86_64_ISR40();
void x86_64_ISR41();
void x86_64_ISR42();
void x86_64_ISR43();
void x86_64_ISR44();
void x86_64_ISR45();
void x86_64_ISR46();
void x86_64_ISR47();
void x86_64_ISR48();
void x86_64_ISR49();
void x86_64_ISR50();
void x86_64_ISR51();
void x86_64_ISR52();
void x86_64_ISR53();
void x86_64_ISR54();
void x86_64_ISR55();
void x86_64_ISR56();
void x86_64_ISR57();
void x86_64_ISR58();
void x86_64_ISR59();
void x86_64_ISR60();
void x86_64_ISR61();
void x86_64_ISR62();
void x86_64_ISR63();
void x86_64_ISR64();
void x86_64_ISR65();
void x86_64_ISR66();
void x86_64_ISR67();
void x86_64_ISR68();
void x86_64_ISR69();
void x86_64_ISR70();
void x86_64_ISR71();
void x86_64_ISR72();
void x86_64_ISR73();
void x86_64_ISR74();
void x86_64_ISR75();
void x86_64_ISR76();
void x86_64_ISR77();
void x86_64_ISR78();
void x86_64_ISR79();
void x86_64_ISR80();
void x86_64_ISR81();
void x86_64_ISR82();
void x86_64_ISR83();
void x86_64_ISR84();
void x86_64_ISR85();
void x86_64_ISR86();
void x86_64_ISR87();
void x86_64_ISR88();
void x86_64_ISR89();
void x86_64_ISR90();
void x86_64_ISR91();
void x86_64_ISR92();
void x86_64_ISR93();
void x86_64_ISR94();
void x86_64_ISR95();
void x86_64_ISR96();
void x86_64_ISR97();
void x86_64_ISR98();
void x86_64_ISR99();
void x86_64_ISR100();
void x86_64_ISR101();
void x86_64_ISR102();
void x86_64_ISR103();
void x86_64_ISR104();
void x86_64_ISR105();
void x86_64_ISR106();
void x86_64_ISR107();
void x86_64_ISR108();
void x86_64_ISR109();
void x86_64_ISR110();
void x86_64_ISR111();
void x86_64_ISR112();
void x86_64_ISR113();
void x86_64_ISR114();
void x86_64_ISR115();
void x86_64_ISR116();
void x86_64_ISR117();
void x86_64_ISR118();
void x86_64_ISR119();
void x86_64_ISR120();
void x86_64_ISR121();
void x86_64_ISR122();
void x86_64_ISR123();
void x86_64_ISR124();
void x86_64_ISR125();
void x86_64_ISR126();
void x86_64_ISR127();
void x86_64_ISR128();
void x86_64_ISR129();
void x86_64_ISR130();
void x86_64_ISR131();
void x86_64_ISR132();
void x86_64_ISR133();
void x86_64_ISR134();
void x86_64_ISR135();
void x86_64_ISR136();
void x86_64_ISR137();
void x86_64_ISR138();
void x86_64_ISR139();
void x86_64_ISR140();
void x86_64_ISR141();
void x86_64_ISR142();
void x86_64_ISR143();
void x86_64_ISR144();
void x86_64_ISR145();
void x86_64_ISR146();
void x86_64_ISR147();
void x86_64_ISR148();
void x86_64_ISR149();
void x86_64_ISR150();
void x86_64_ISR151();
void x86_64_ISR152();
void x86_64_ISR153();
void x86_64_ISR154();
void x86_64_ISR155();
void x86_64_ISR156();
void x86_64_ISR157();
void x86_64_ISR158();
void x86_64_ISR159();
void x86_64_ISR160();
void x86_64_ISR161();
void x86_64_ISR162();
void x86_64_ISR163();
void x86_64_ISR164();
void x86_64_ISR165();
void x86_64_ISR166();
void x86_64_ISR167();
void x86_64_ISR168();
void x86_64_ISR169();
void x86_64_ISR170();
void x86_64_ISR171();
void x86_64_ISR172();
void x86_64_ISR173();
void x86_64_ISR174();
void x86_64_ISR175();
void x86_64_ISR176();
void x86_64_ISR177();
void x86_64_ISR178();
void x86_64_ISR179();
void x86_64_ISR180();
void x86_64_ISR181();
void x86_64_ISR182();
void x86_64_ISR183();
void x86_64_ISR184();
void x86_64_ISR185();
void x86_64_ISR186();
void x86_64_ISR187();
void x86_64_ISR188();
void x86_64_ISR189();
void x86_64_ISR190();
void x86_64_ISR191();
void x86_64_ISR192();
void x86_64_ISR193();
void x86_64_ISR194();
void x86_64_ISR195();
void x86_64_ISR196();
void x86_64_ISR197();
void x86_64_ISR198();
void x86_64_ISR199();
void x86_64_ISR200();
void x86_64_ISR201();
void x86_64_ISR202();
void x86_64_ISR203();
void x86_64_ISR204();
void x86_64_ISR205();
void x86_64_ISR206();
void x86_64_ISR207();
void x86_64_ISR208();
void x86_64_ISR209();
void x86_64_ISR210();
void x86_64_ISR211();
void x86_64_ISR212();
void x86_64_ISR213();
void x86_64_ISR214();
void x86_64_ISR215();
void x86_64_ISR216();
void x86_64_ISR217();
void x86_64_ISR218();
void x86_64_ISR219();
void x86_64_ISR220();
void x86_64_ISR221();
void x86_64_ISR222();
void x86_64_ISR223();
void x86_64_ISR224();
void x86_64_ISR225();
void x86_64_ISR226();
void x86_64_ISR227();
void x86_64_ISR228();
void x86_64_ISR229();
void x86_64_ISR230();
void x86_64_ISR231();
void x86_64_ISR232();
void x86_64_ISR233();
void x86_64_ISR234();
void x86_64_ISR235();
void x86_64_ISR236();
void x86_64_ISR237();
void x86_64_ISR238();
void x86_64_ISR239();
void x86_64_ISR240();
void x86_64_ISR241();
void x86_64_ISR242();
void x86_64_ISR243();
void x86_64_ISR244();
void x86_64_ISR245();
void x86_64_ISR246();
void x86_64_ISR247();
void x86_64_ISR248();
void x86_64_ISR249();
void x86_64_ISR250();
void x86_64_ISR251();
void x86_64_ISR252();
void x86_64_ISR253();
void x86_64_ISR254();
void x86_64_ISR255();
void x86_64_ISR_InitializeGates()
{
x86_64_IDT_SetGate(0, x86_64_ISR0, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(1, x86_64_ISR1, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(2, x86_64_ISR2, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(3, x86_64_ISR3, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(4, x86_64_ISR4, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(5, x86_64_ISR5, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(6, x86_64_ISR6, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(7, x86_64_ISR7, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(8, x86_64_ISR8, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(9, x86_64_ISR9, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(10, x86_64_ISR10, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(11, x86_64_ISR11, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(12, x86_64_ISR12, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(13, x86_64_ISR13, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(14, x86_64_ISR14, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(15, x86_64_ISR15, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(16, x86_64_ISR16, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(17, x86_64_ISR17, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(18, x86_64_ISR18, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(19, x86_64_ISR19, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(20, x86_64_ISR20, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(21, x86_64_ISR21, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(22, x86_64_ISR22, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(23, x86_64_ISR23, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(24, x86_64_ISR24, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(25, x86_64_ISR25, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(26, x86_64_ISR26, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(27, x86_64_ISR27, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(28, x86_64_ISR28, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(29, x86_64_ISR29, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(30, x86_64_ISR30, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(31, x86_64_ISR31, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(32, x86_64_ISR32, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(33, x86_64_ISR33, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(34, x86_64_ISR34, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(35, x86_64_ISR35, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(36, x86_64_ISR36, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(37, x86_64_ISR37, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(38, x86_64_ISR38, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(39, x86_64_ISR39, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(40, x86_64_ISR40, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(41, x86_64_ISR41, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(42, x86_64_ISR42, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(43, x86_64_ISR43, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(44, x86_64_ISR44, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(45, x86_64_ISR45, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(46, x86_64_ISR46, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(47, x86_64_ISR47, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(48, x86_64_ISR48, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(49, x86_64_ISR49, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(50, x86_64_ISR50, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(51, x86_64_ISR51, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(52, x86_64_ISR52, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(53, x86_64_ISR53, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(54, x86_64_ISR54, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(55, x86_64_ISR55, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(56, x86_64_ISR56, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(57, x86_64_ISR57, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(58, x86_64_ISR58, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(59, x86_64_ISR59, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(60, x86_64_ISR60, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(61, x86_64_ISR61, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(62, x86_64_ISR62, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(63, x86_64_ISR63, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(64, x86_64_ISR64, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(65, x86_64_ISR65, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(66, x86_64_ISR66, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(67, x86_64_ISR67, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(68, x86_64_ISR68, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(69, x86_64_ISR69, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(70, x86_64_ISR70, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(71, x86_64_ISR71, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(72, x86_64_ISR72, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(73, x86_64_ISR73, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(74, x86_64_ISR74, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(75, x86_64_ISR75, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(76, x86_64_ISR76, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(77, x86_64_ISR77, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(78, x86_64_ISR78, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(79, x86_64_ISR79, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(80, x86_64_ISR80, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(81, x86_64_ISR81, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(82, x86_64_ISR82, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(83, x86_64_ISR83, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(84, x86_64_ISR84, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(85, x86_64_ISR85, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(86, x86_64_ISR86, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(87, x86_64_ISR87, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(88, x86_64_ISR88, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(89, x86_64_ISR89, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(90, x86_64_ISR90, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(91, x86_64_ISR91, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(92, x86_64_ISR92, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(93, x86_64_ISR93, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(94, x86_64_ISR94, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(95, x86_64_ISR95, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(96, x86_64_ISR96, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(97, x86_64_ISR97, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(98, x86_64_ISR98, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(99, x86_64_ISR99, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(100, x86_64_ISR100, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(101, x86_64_ISR101, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(102, x86_64_ISR102, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(103, x86_64_ISR103, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(104, x86_64_ISR104, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(105, x86_64_ISR105, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(106, x86_64_ISR106, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(107, x86_64_ISR107, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(108, x86_64_ISR108, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(109, x86_64_ISR109, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(110, x86_64_ISR110, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(111, x86_64_ISR111, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(112, x86_64_ISR112, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(113, x86_64_ISR113, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(114, x86_64_ISR114, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(115, x86_64_ISR115, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(116, x86_64_ISR116, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(117, x86_64_ISR117, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(118, x86_64_ISR118, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(119, x86_64_ISR119, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(120, x86_64_ISR120, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(121, x86_64_ISR121, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(122, x86_64_ISR122, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(123, x86_64_ISR123, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(124, x86_64_ISR124, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(125, x86_64_ISR125, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(126, x86_64_ISR126, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(127, x86_64_ISR127, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(128, x86_64_ISR128, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(129, x86_64_ISR129, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(130, x86_64_ISR130, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(131, x86_64_ISR131, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(132, x86_64_ISR132, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(133, x86_64_ISR133, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(134, x86_64_ISR134, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(135, x86_64_ISR135, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(136, x86_64_ISR136, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(137, x86_64_ISR137, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(138, x86_64_ISR138, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(139, x86_64_ISR139, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(140, x86_64_ISR140, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(141, x86_64_ISR141, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(142, x86_64_ISR142, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(143, x86_64_ISR143, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(144, x86_64_ISR144, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(145, x86_64_ISR145, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(146, x86_64_ISR146, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(147, x86_64_ISR147, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(148, x86_64_ISR148, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(149, x86_64_ISR149, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(150, x86_64_ISR150, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(151, x86_64_ISR151, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(152, x86_64_ISR152, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(153, x86_64_ISR153, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(154, x86_64_ISR154, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(155, x86_64_ISR155, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(156, x86_64_ISR156, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(157, x86_64_ISR157, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(158, x86_64_ISR158, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(159, x86_64_ISR159, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(160, x86_64_ISR160, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(161, x86_64_ISR161, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(162, x86_64_ISR162, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(163, x86_64_ISR163, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(164, x86_64_ISR164, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(165, x86_64_ISR165, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(166, x86_64_ISR166, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(167, x86_64_ISR167, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(168, x86_64_ISR168, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(169, x86_64_ISR169, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(170, x86_64_ISR170, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(171, x86_64_ISR171, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(172, x86_64_ISR172, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(173, x86_64_ISR173, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(174, x86_64_ISR174, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(175, x86_64_ISR175, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(176, x86_64_ISR176, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(177, x86_64_ISR177, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(178, x86_64_ISR178, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(179, x86_64_ISR179, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(180, x86_64_ISR180, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(181, x86_64_ISR181, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(182, x86_64_ISR182, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(183, x86_64_ISR183, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(184, x86_64_ISR184, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(185, x86_64_ISR185, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(186, x86_64_ISR186, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(187, x86_64_ISR187, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(188, x86_64_ISR188, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(189, x86_64_ISR189, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(190, x86_64_ISR190, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(191, x86_64_ISR191, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(192, x86_64_ISR192, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(193, x86_64_ISR193, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(194, x86_64_ISR194, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(195, x86_64_ISR195, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(196, x86_64_ISR196, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(197, x86_64_ISR197, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(198, x86_64_ISR198, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(199, x86_64_ISR199, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(200, x86_64_ISR200, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(201, x86_64_ISR201, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(202, x86_64_ISR202, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(203, x86_64_ISR203, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(204, x86_64_ISR204, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(205, x86_64_ISR205, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(206, x86_64_ISR206, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(207, x86_64_ISR207, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(208, x86_64_ISR208, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(209, x86_64_ISR209, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(210, x86_64_ISR210, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(211, x86_64_ISR211, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(212, x86_64_ISR212, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(213, x86_64_ISR213, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(214, x86_64_ISR214, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(215, x86_64_ISR215, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(216, x86_64_ISR216, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(217, x86_64_ISR217, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(218, x86_64_ISR218, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(219, x86_64_ISR219, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(220, x86_64_ISR220, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(221, x86_64_ISR221, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(222, x86_64_ISR222, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(223, x86_64_ISR223, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(224, x86_64_ISR224, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(225, x86_64_ISR225, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(226, x86_64_ISR226, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(227, x86_64_ISR227, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(228, x86_64_ISR228, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(229, x86_64_ISR229, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(230, x86_64_ISR230, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(231, x86_64_ISR231, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(232, x86_64_ISR232, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(233, x86_64_ISR233, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(234, x86_64_ISR234, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(235, x86_64_ISR235, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(236, x86_64_ISR236, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(237, x86_64_ISR237, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(238, x86_64_ISR238, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(239, x86_64_ISR239, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(240, x86_64_ISR240, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(241, x86_64_ISR241, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(242, x86_64_ISR242, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(243, x86_64_ISR243, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(244, x86_64_ISR244, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(245, x86_64_ISR245, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(246, x86_64_ISR246, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(247, x86_64_ISR247, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(248, x86_64_ISR248, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(249, x86_64_ISR249, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(250, x86_64_ISR250, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(251, x86_64_ISR251, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(252, x86_64_ISR252, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(253, x86_64_ISR253, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(254, x86_64_ISR254, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
x86_64_IDT_SetGate(255, x86_64_ISR255, GDT_KERNEL_CODE64, IDT_FLAG_RING0 | IDT_FLAG_GATE_32BIT_INT);
}
+256
View File
@@ -0,0 +1,256 @@
ISR_NOERRORCODE 0
ISR_NOERRORCODE 1
ISR_NOERRORCODE 2
ISR_NOERRORCODE 3
ISR_NOERRORCODE 4
ISR_NOERRORCODE 5
ISR_NOERRORCODE 6
ISR_NOERRORCODE 7
ISR_ERRORCODE 8
ISR_NOERRORCODE 9
ISR_ERRORCODE 10
ISR_ERRORCODE 11
ISR_ERRORCODE 12
ISR_ERRORCODE 13
ISR_ERRORCODE 14
ISR_NOERRORCODE 15
ISR_NOERRORCODE 16
ISR_ERRORCODE 17
ISR_NOERRORCODE 18
ISR_NOERRORCODE 19
ISR_NOERRORCODE 20
ISR_ERRORCODE 21
ISR_NOERRORCODE 22
ISR_NOERRORCODE 23
ISR_NOERRORCODE 24
ISR_NOERRORCODE 25
ISR_NOERRORCODE 26
ISR_NOERRORCODE 27
ISR_NOERRORCODE 28
ISR_NOERRORCODE 29
ISR_NOERRORCODE 30
ISR_NOERRORCODE 31
ISR_NOERRORCODE 32
ISR_NOERRORCODE 33
ISR_NOERRORCODE 34
ISR_NOERRORCODE 35
ISR_NOERRORCODE 36
ISR_NOERRORCODE 37
ISR_NOERRORCODE 38
ISR_NOERRORCODE 39
ISR_NOERRORCODE 40
ISR_NOERRORCODE 41
ISR_NOERRORCODE 42
ISR_NOERRORCODE 43
ISR_NOERRORCODE 44
ISR_NOERRORCODE 45
ISR_NOERRORCODE 46
ISR_NOERRORCODE 47
ISR_NOERRORCODE 48
ISR_NOERRORCODE 49
ISR_NOERRORCODE 50
ISR_NOERRORCODE 51
ISR_NOERRORCODE 52
ISR_NOERRORCODE 53
ISR_NOERRORCODE 54
ISR_NOERRORCODE 55
ISR_NOERRORCODE 56
ISR_NOERRORCODE 57
ISR_NOERRORCODE 58
ISR_NOERRORCODE 59
ISR_NOERRORCODE 60
ISR_NOERRORCODE 61
ISR_NOERRORCODE 62
ISR_NOERRORCODE 63
ISR_NOERRORCODE 64
ISR_NOERRORCODE 65
ISR_NOERRORCODE 66
ISR_NOERRORCODE 67
ISR_NOERRORCODE 68
ISR_NOERRORCODE 69
ISR_NOERRORCODE 70
ISR_NOERRORCODE 71
ISR_NOERRORCODE 72
ISR_NOERRORCODE 73
ISR_NOERRORCODE 74
ISR_NOERRORCODE 75
ISR_NOERRORCODE 76
ISR_NOERRORCODE 77
ISR_NOERRORCODE 78
ISR_NOERRORCODE 79
ISR_NOERRORCODE 80
ISR_NOERRORCODE 81
ISR_NOERRORCODE 82
ISR_NOERRORCODE 83
ISR_NOERRORCODE 84
ISR_NOERRORCODE 85
ISR_NOERRORCODE 86
ISR_NOERRORCODE 87
ISR_NOERRORCODE 88
ISR_NOERRORCODE 89
ISR_NOERRORCODE 90
ISR_NOERRORCODE 91
ISR_NOERRORCODE 92
ISR_NOERRORCODE 93
ISR_NOERRORCODE 94
ISR_NOERRORCODE 95
ISR_NOERRORCODE 96
ISR_NOERRORCODE 97
ISR_NOERRORCODE 98
ISR_NOERRORCODE 99
ISR_NOERRORCODE 100
ISR_NOERRORCODE 101
ISR_NOERRORCODE 102
ISR_NOERRORCODE 103
ISR_NOERRORCODE 104
ISR_NOERRORCODE 105
ISR_NOERRORCODE 106
ISR_NOERRORCODE 107
ISR_NOERRORCODE 108
ISR_NOERRORCODE 109
ISR_NOERRORCODE 110
ISR_NOERRORCODE 111
ISR_NOERRORCODE 112
ISR_NOERRORCODE 113
ISR_NOERRORCODE 114
ISR_NOERRORCODE 115
ISR_NOERRORCODE 116
ISR_NOERRORCODE 117
ISR_NOERRORCODE 118
ISR_NOERRORCODE 119
ISR_NOERRORCODE 120
ISR_NOERRORCODE 121
ISR_NOERRORCODE 122
ISR_NOERRORCODE 123
ISR_NOERRORCODE 124
ISR_NOERRORCODE 125
ISR_NOERRORCODE 126
ISR_NOERRORCODE 127
ISR_NOERRORCODE 128
ISR_NOERRORCODE 129
ISR_NOERRORCODE 130
ISR_NOERRORCODE 131
ISR_NOERRORCODE 132
ISR_NOERRORCODE 133
ISR_NOERRORCODE 134
ISR_NOERRORCODE 135
ISR_NOERRORCODE 136
ISR_NOERRORCODE 137
ISR_NOERRORCODE 138
ISR_NOERRORCODE 139
ISR_NOERRORCODE 140
ISR_NOERRORCODE 141
ISR_NOERRORCODE 142
ISR_NOERRORCODE 143
ISR_NOERRORCODE 144
ISR_NOERRORCODE 145
ISR_NOERRORCODE 146
ISR_NOERRORCODE 147
ISR_NOERRORCODE 148
ISR_NOERRORCODE 149
ISR_NOERRORCODE 150
ISR_NOERRORCODE 151
ISR_NOERRORCODE 152
ISR_NOERRORCODE 153
ISR_NOERRORCODE 154
ISR_NOERRORCODE 155
ISR_NOERRORCODE 156
ISR_NOERRORCODE 157
ISR_NOERRORCODE 158
ISR_NOERRORCODE 159
ISR_NOERRORCODE 160
ISR_NOERRORCODE 161
ISR_NOERRORCODE 162
ISR_NOERRORCODE 163
ISR_NOERRORCODE 164
ISR_NOERRORCODE 165
ISR_NOERRORCODE 166
ISR_NOERRORCODE 167
ISR_NOERRORCODE 168
ISR_NOERRORCODE 169
ISR_NOERRORCODE 170
ISR_NOERRORCODE 171
ISR_NOERRORCODE 172
ISR_NOERRORCODE 173
ISR_NOERRORCODE 174
ISR_NOERRORCODE 175
ISR_NOERRORCODE 176
ISR_NOERRORCODE 177
ISR_NOERRORCODE 178
ISR_NOERRORCODE 179
ISR_NOERRORCODE 180
ISR_NOERRORCODE 181
ISR_NOERRORCODE 182
ISR_NOERRORCODE 183
ISR_NOERRORCODE 184
ISR_NOERRORCODE 185
ISR_NOERRORCODE 186
ISR_NOERRORCODE 187
ISR_NOERRORCODE 188
ISR_NOERRORCODE 189
ISR_NOERRORCODE 190
ISR_NOERRORCODE 191
ISR_NOERRORCODE 192
ISR_NOERRORCODE 193
ISR_NOERRORCODE 194
ISR_NOERRORCODE 195
ISR_NOERRORCODE 196
ISR_NOERRORCODE 197
ISR_NOERRORCODE 198
ISR_NOERRORCODE 199
ISR_NOERRORCODE 200
ISR_NOERRORCODE 201
ISR_NOERRORCODE 202
ISR_NOERRORCODE 203
ISR_NOERRORCODE 204
ISR_NOERRORCODE 205
ISR_NOERRORCODE 206
ISR_NOERRORCODE 207
ISR_NOERRORCODE 208
ISR_NOERRORCODE 209
ISR_NOERRORCODE 210
ISR_NOERRORCODE 211
ISR_NOERRORCODE 212
ISR_NOERRORCODE 213
ISR_NOERRORCODE 214
ISR_NOERRORCODE 215
ISR_NOERRORCODE 216
ISR_NOERRORCODE 217
ISR_NOERRORCODE 218
ISR_NOERRORCODE 219
ISR_NOERRORCODE 220
ISR_NOERRORCODE 221
ISR_NOERRORCODE 222
ISR_NOERRORCODE 223
ISR_NOERRORCODE 224
ISR_NOERRORCODE 225
ISR_NOERRORCODE 226
ISR_NOERRORCODE 227
ISR_NOERRORCODE 228
ISR_NOERRORCODE 229
ISR_NOERRORCODE 230
ISR_NOERRORCODE 231
ISR_NOERRORCODE 232
ISR_NOERRORCODE 233
ISR_NOERRORCODE 234
ISR_NOERRORCODE 235
ISR_NOERRORCODE 236
ISR_NOERRORCODE 237
ISR_NOERRORCODE 238
ISR_NOERRORCODE 239
ISR_NOERRORCODE 240
ISR_NOERRORCODE 241
ISR_NOERRORCODE 242
ISR_NOERRORCODE 243
ISR_NOERRORCODE 244
ISR_NOERRORCODE 245
ISR_NOERRORCODE 246
ISR_NOERRORCODE 247
ISR_NOERRORCODE 248
ISR_NOERRORCODE 249
ISR_NOERRORCODE 250
ISR_NOERRORCODE 251
ISR_NOERRORCODE 252
ISR_NOERRORCODE 253
ISR_NOERRORCODE 254
ISR_NOERRORCODE 255
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
typedef struct {
const char* Name;
bool (*Probe)();
void (*Initialize)(uint8_t offsetPic1, uint8_t offsetPic2, bool autoEoi);
void (*Disable)();
void (*SendEndOfInterrupt)(int irq);
void (*Mask)(int irq);
void (*Unmask)(int irq);
} PICDriver;
+104
View File
@@ -0,0 +1,104 @@
#include <stdint.h>
#include <string.h>
#include "mm/pmm.h"
#include "mm/vmm.h"
#include "mm/memory.h"
#include "stdio.h"
#include "fs/elf.h"
extern uintptr_t g_hhdm_offset;
#define USER_STACK_TOP 0x00007FFFFFFFE000ULL
#define USER_STACK_PAGES 4
#define USER_STACK_SIZE (USER_STACK_PAGES * PAGE_SIZE)
#define PTE_PRESENT (1ULL << 0)
#define PTE_WRITABLE (1ULL << 1)
#define PTE_USER (1ULL << 2)
static uint64_t user_stack_phys_base = 0;
extern struct pagemap *kernel_pagemap;
static void setup_user_stack()
{
// Allocate contiguous physical pages for the stack
user_stack_phys_base = (uint64_t)pmm_alloc(USER_STACK_PAGES);
if (!user_stack_phys_base) {
printf("Failed to allocate user stack pages!\n");
for (;;);
}
// Map each page individually into the current pagemap
// Stack grows downward, so start from the bottom
uintptr_t virt = USER_STACK_TOP - USER_STACK_SIZE;
for (int i = 0; i < USER_STACK_PAGES; i++) {
uint64_t phys = user_stack_phys_base + (i * PAGE_SIZE);
bool success = vmm_map_page(
kernel_pagemap, // Use kernel_pagemap for now (later: process->process_pagemap)
virt,
phys,
PAGE_READ | PAGE_WRITE | PAGE_USER, // RW + User
Size4KiB
);
if (!success) {
printf("Failed to map user stack page at 0x%lx\n", virt);
// TODO: cleanup previous pages if partial failure
for (;;);
}
virt += PAGE_SIZE;
}
// Optional: zero the stack (good practice)
// memset((void*)(USER_STACK_TOP - USER_STACK_SIZE), 0, USER_STACK_SIZE);
}
// usermode.c
__attribute__((naked))
void enter_user_mode(uint64_t rip, uint64_t rsp)
{
asm volatile(
"cli\n"
"mov $0x1B, %ax\n" // Use User Data Selector (0x1B)
"mov %ax, %ds\n"
"mov %ax, %es\n"
"mov %ax, %fs\n"
"mov %ax, %gs\n"
"pushq $0x1B\n" // SS (User Data)
"pushq %rsi\n" // RSP
"pushfq\n"
// Optional: manually set IF bit in pushed RFLAGS if you want interrupts enabled
"pop %rax\n"
"or $0x200, %rax\n"
"push %rax\n"
"pushq $0x23\n" // CS (User Code)
"pushq %rdi\n" // RIP
"iretq\n"
);
}
void start_userspace(void)
{
void *entry = NULL;
if (!ELF_Read("init.elf", &entry)) {
printf("Failed to load init.elf\n");
for(;;);
}
setup_user_stack();
printf("Jumping to user entry: 0x%lx with stack top 0x%lx\n",
(uint64_t)entry, USER_STACK_TOP);
enter_user_mode((uint64_t)entry, USER_STACK_TOP);
}
+4
View File
@@ -0,0 +1,4 @@
#pragma once
#include <stdint.h>
void start_userspace(void);