This commit is contained in:
nub31
2025-08-25 16:50:58 +02:00
parent 01f16ce210
commit 573398bb0f
4 changed files with 192 additions and 76 deletions

163
src/idt.c
View File

@@ -4,6 +4,13 @@
#include <stddef.h>
#include <stdint.h>
#define IDT_SIZE 256
#define PIC1_COMMAND 0x20
#define PIC1_DATA 0x21
#define PIC2_COMMAND 0xA0
#define PIC2_DATA 0xA1
typedef struct
{
uint16_t address_low;
@@ -21,22 +28,95 @@ typedef struct
uint64_t base;
} __attribute__((packed)) idtr_t;
typedef struct
{
uint64_t r15, r14, r13, r12, r11, r10, r9, r8;
uint64_t rbp, rdi, rsi, rdx, rcx, rbx, rax;
uint64_t int_no;
uint64_t err_code;
uint64_t rip, cs, rflags, rsp, ss;
} __attribute__((packed)) isr_frame_t;
#define IDT_SIZE 256
extern void* isr_stub_table[];
static irq_handler_t irq_handlers[16] = { 0 };
static const char* exception_messages[32] = { "divide by zero",
"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",
"reserved",
"x87 floating point exception",
"alignment check",
"machine check",
"simd floating point exception",
"virtualization exception",
"control protection exception",
"reserved",
"reserved",
"reserved",
"reserved",
"reserved",
"reserved",
"hypervisor injection exception",
"vmm communication exception",
"security exception",
"reserved" };
static interrupt_descriptor idt[IDT_SIZE];
void idt_set_descriptor(uint8_t vector, void* handler, uint8_t dpl)
static inline void outb(uint16_t port, uint8_t val)
{
__asm__ volatile("outb %0, %1" : : "a"(val), "Nd"(port));
}
static inline uint8_t inb(uint16_t port)
{
uint8_t ret;
__asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}
static void pic_remap(int offset1, int offset2)
{
uint8_t a1, a2;
a1 = inb(PIC1_DATA);
a2 = inb(PIC2_DATA);
outb(PIC1_COMMAND, 0x11);
outb(PIC2_COMMAND, 0x11);
outb(PIC1_DATA, offset1);
outb(PIC2_DATA, offset2);
outb(PIC1_DATA, 4);
outb(PIC2_DATA, 2);
outb(PIC1_DATA, 0x01);
outb(PIC2_DATA, 0x01);
outb(PIC1_DATA, a1);
outb(PIC2_DATA, a2);
}
static void pic_send_eoi(uint8_t irq)
{
if (irq >= 8)
{
outb(PIC2_COMMAND, 0x20);
}
outb(PIC1_COMMAND, 0x20);
}
void register_irq_handler(uint8_t irq, irq_handler_t handler)
{
irq_handlers[irq] = handler;
}
static inline void idt_set_descriptor(uint8_t vector, void* handler, uint8_t dpl)
{
interrupt_descriptor* entry = &idt[vector];
@@ -49,21 +129,11 @@ void idt_set_descriptor(uint8_t vector, void* handler, uint8_t dpl)
entry->reserved = 0;
}
void exception_handler(isr_frame_t* frame)
{
vga_print("Interrupt\n");
vga_print(" int_no: ");
vga_print_uint(frame->int_no);
vga_print("\n");
vga_print(" err_code: ");
vga_print_uint(frame->err_code);
vga_print("\n");
__asm__ volatile("cli; hlt");
}
void idt_init(void)
{
for (int i = 0; i < 32; i++)
pic_remap(0x20, 0x28);
for (int i = 0; i < 256; i++)
{
idt_set_descriptor(i, isr_stub_table[i], 0);
}
@@ -71,4 +141,47 @@ void idt_init(void)
idtr_t idtr = { .base = (uintptr_t)&idt[0], .limit = (uint16_t)sizeof(interrupt_descriptor) * IDT_SIZE - 1 };
__asm__ volatile("lidt %0" : : "m"(idtr));
__asm__ volatile("sti");
}
void idt_enable(void)
{
__asm__ volatile("sti");
}
void handle_isr(isr_frame_t* frame)
{
if (frame->int_no < 32)
{
vga_print_error();
vga_print(" exception[");
vga_print_uint(frame->int_no);
vga_print("]: ");
vga_print(exception_messages[frame->int_no]);
vga_print(", error code: ");
vga_print_uint(frame->err_code);
vga_print("\n");
__asm__ volatile("cli; hlt");
}
else if (frame->int_no < 48)
{
uint8_t irq = frame->int_no - 32;
if (irq_handlers[irq])
{
irq_handlers[irq](frame);
}
pic_send_eoi(irq);
}
else
{
vga_print_error();
vga_print(" interrupt[");
vga_print_uint(frame->int_no);
vga_print("]: ");
vga_print("not implemented\n");
}
}

View File

@@ -2,5 +2,17 @@
#include <stdint.h>
typedef struct
{
uint64_t r15, r14, r13, r12, r11, r10, r9, r8;
uint64_t rbp, rdi, rsi, rdx, rcx, rbx, rax;
uint64_t int_no;
uint64_t err_code;
uint64_t rip, cs, rflags, rsp, ss;
} __attribute__((packed)) isr_frame_t;
typedef void (*irq_handler_t)(isr_frame_t*);
void idt_init(void);
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags);
void idt_enable(void);
void register_irq_handler(uint8_t irq, irq_handler_t handler);

View File

@@ -1,17 +1,4 @@
extern exception_handler
%macro ISR_NOERR 1
isr_stub_%1:
push qword 0
push qword %1
jmp isr_common
%endmacro
%macro ISR_ERR 1
isr_stub_%1:
push qword %1
jmp isr_common
%endmacro
extern handle_isr
isr_common:
push rax
@@ -31,7 +18,7 @@ isr_common:
push r15
mov rdi, rsp
call exception_handler
call handle_isr
pop r15
pop r14
@@ -52,6 +39,20 @@ isr_common:
add rsp, 16
iretq
%macro ISR_NOERR 1
isr_stub_%1:
push qword 0
push qword %1
jmp isr_common
%endmacro
%macro ISR_ERR 1
isr_stub_%1:
push qword %1
jmp isr_common
%endmacro
; CPU exceptions 0-31
ISR_NOERR 0
ISR_NOERR 1
ISR_NOERR 2
@@ -85,37 +86,24 @@ ISR_NOERR 29
ISR_ERR 30
ISR_NOERR 31
%macro GENERATE_ISRS 2
%assign i %1
%rep (%2 - %1 + 1)
ISR_NOERR i
%assign i i+1
%endrep
%endmacro
GENERATE_ISRS 32, 255
%macro GENERATE_ISR_TABLE 2
%assign i %1
%rep (%2 - %1 + 1)
dq isr_stub_%[i]
%assign i i+1
%endrep
%endmacro
global isr_stub_table
isr_stub_table:
dq isr_stub_0
dq isr_stub_1
dq isr_stub_2
dq isr_stub_3
dq isr_stub_4
dq isr_stub_5
dq isr_stub_6
dq isr_stub_7
dq isr_stub_8
dq isr_stub_9
dq isr_stub_10
dq isr_stub_11
dq isr_stub_12
dq isr_stub_13
dq isr_stub_14
dq isr_stub_15
dq isr_stub_16
dq isr_stub_17
dq isr_stub_18
dq isr_stub_19
dq isr_stub_20
dq isr_stub_21
dq isr_stub_22
dq isr_stub_23
dq isr_stub_24
dq isr_stub_25
dq isr_stub_26
dq isr_stub_27
dq isr_stub_28
dq isr_stub_29
dq isr_stub_30
dq isr_stub_31
GENERATE_ISR_TABLE 0, 255

View File

@@ -1,5 +1,6 @@
#include "idt.h"
#include "vga.h"
#include <stdbool.h>
void kernel_main(void)
{
@@ -8,11 +9,13 @@ void kernel_main(void)
vga_print(" VGA intialzied\n");
idt_init();
idt_enable();
vga_print_success();
vga_print(" IDT intialzied\n");
vga_print("\nWelcome to nub OS\n");
vga_print(">");
int x = 1 / 0;
while (true)
{
}
}