mirror of
https://github.com/Zeal-Operating-System/ZealOS.git
synced 2024-12-25 23:10:32 +00:00
ZealBooter: Add minimal IDT and exception handling
This commit is contained in:
parent
f0c751e962
commit
674daa42a4
4 changed files with 233 additions and 0 deletions
163
zealbooter/idt.c
Normal file
163
zealbooter/idt.c
Normal file
|
@ -0,0 +1,163 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <idt.h>
|
||||
#include <print.h>
|
||||
|
||||
struct cpu_ctx {
|
||||
uint64_t ds;
|
||||
uint64_t es;
|
||||
uint64_t rax;
|
||||
uint64_t rbx;
|
||||
uint64_t rcx;
|
||||
uint64_t rdx;
|
||||
uint64_t rsi;
|
||||
uint64_t rdi;
|
||||
uint64_t rbp;
|
||||
uint64_t r8;
|
||||
uint64_t r9;
|
||||
uint64_t r10;
|
||||
uint64_t r11;
|
||||
uint64_t r12;
|
||||
uint64_t r13;
|
||||
uint64_t r14;
|
||||
uint64_t r15;
|
||||
uint64_t err;
|
||||
uint64_t rip;
|
||||
uint64_t cs;
|
||||
uint64_t rflags;
|
||||
uint64_t rsp;
|
||||
uint64_t ss;
|
||||
};
|
||||
|
||||
struct idt_entry {
|
||||
uint16_t offset_low;
|
||||
uint16_t selector;
|
||||
uint8_t ist;
|
||||
uint8_t flags;
|
||||
uint16_t offset_mid;
|
||||
uint32_t offset_hi;
|
||||
uint32_t reserved;
|
||||
};
|
||||
|
||||
struct idtr {
|
||||
uint16_t limit;
|
||||
uint64_t base;
|
||||
} __attribute__((packed));
|
||||
|
||||
static struct idt_entry idt[256];
|
||||
|
||||
void *isr[256];
|
||||
|
||||
static void register_handler(uint8_t vector, void *handler, uint8_t flags) {
|
||||
uint64_t handler_int = (uint64_t)handler;
|
||||
|
||||
idt[vector] = (struct idt_entry){
|
||||
.offset_low = (uint16_t)handler_int,
|
||||
.selector = 0x28,
|
||||
.ist = 0,
|
||||
.flags = flags,
|
||||
.offset_mid = (uint16_t)(handler_int >> 16),
|
||||
.offset_hi = (uint32_t)(handler_int >> 32),
|
||||
.reserved = 0
|
||||
};
|
||||
}
|
||||
|
||||
extern void *isr_thunks[];
|
||||
|
||||
static const char *exceptions[] = {
|
||||
"Division exception",
|
||||
"Debug",
|
||||
"NMI",
|
||||
"Breakpoint",
|
||||
"Overflow",
|
||||
"Bound range exceeded",
|
||||
"Invalid opcode",
|
||||
"Device not available",
|
||||
"Double fault",
|
||||
"???",
|
||||
"Invalid TSS",
|
||||
"Segment not present",
|
||||
"Stack-segment fault",
|
||||
"General protection fault",
|
||||
"Page fault",
|
||||
"???",
|
||||
"x87 exception",
|
||||
"Alignment check",
|
||||
"Machine check",
|
||||
"SIMD exception",
|
||||
"Virtualisation"
|
||||
};
|
||||
|
||||
static inline uint64_t read_cr0(void) {
|
||||
uint64_t ret;
|
||||
asm volatile ("mov %%cr0, %0" : "=r"(ret) :: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline uint64_t read_cr2(void) {
|
||||
uint64_t ret;
|
||||
asm volatile ("mov %%cr2, %0" : "=r"(ret) :: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline uint64_t read_cr3(void) {
|
||||
uint64_t ret;
|
||||
asm volatile ("mov %%cr3, %0" : "=r"(ret) :: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline uint64_t read_cr4(void) {
|
||||
uint64_t ret;
|
||||
asm volatile ("mov %%cr4, %0" : "=r"(ret) :: "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void exception_handler(uint8_t vector, struct cpu_ctx *ctx) {
|
||||
printf("Exception %s triggered\n\n", exceptions[vector]);
|
||||
|
||||
printf(" RAX=%016lx RBX=%016lx\n"
|
||||
" RCX=%016lx RDX=%016lx\n"
|
||||
" RSI=%016lx RDI=%016lx\n"
|
||||
" RBP=%016lx RSP=%016lx\n"
|
||||
" R08=%016lx R09=%016lx\n"
|
||||
" R10=%016lx R11=%016lx\n"
|
||||
" R12=%016lx R13=%016lx\n"
|
||||
" R14=%016lx R15=%016lx\n"
|
||||
" RIP=%016lx RFLAGS=%08lx\n"
|
||||
" CS=%04lx DS=%04lx ES=%04lx SS=%04lx\n"
|
||||
" CR0=%016lx CR2=%016lx\n"
|
||||
" CR3=%016lx CR4=%016lx\n"
|
||||
" ERR=%016lx",
|
||||
ctx->rax, ctx->rbx, ctx->rcx, ctx->rdx,
|
||||
ctx->rsi, ctx->rdi, ctx->rbp, ctx->rsp,
|
||||
ctx->r8, ctx->r9, ctx->r10, ctx->r11,
|
||||
ctx->r12, ctx->r13, ctx->r14, ctx->r15,
|
||||
ctx->rip, ctx->rflags,
|
||||
ctx->cs, ctx->ds, ctx->es, ctx->ss,
|
||||
read_cr0(), read_cr2(),
|
||||
read_cr3(), read_cr4(),
|
||||
ctx->err);
|
||||
|
||||
for (;;) {
|
||||
asm ("hlt");
|
||||
}
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
void idt_init(void) {
|
||||
for (size_t i = 0; i < 256; i++) {
|
||||
register_handler(i, isr_thunks[i], 0x8e);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof(exceptions) / sizeof(exceptions[0]); i++) {
|
||||
isr[i] = exception_handler;
|
||||
}
|
||||
|
||||
struct idtr idtr = {
|
||||
.limit = sizeof(idt) - 1,
|
||||
.base = (uint64_t)idt
|
||||
};
|
||||
|
||||
asm volatile ("lidt %0" :: "m"(idtr) : "memory");
|
||||
}
|
6
zealbooter/idt.h
Normal file
6
zealbooter/idt.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef _IDT_H
|
||||
#define _IDT_H
|
||||
|
||||
void idt_init(void);
|
||||
|
||||
#endif
|
61
zealbooter/int_thunks.S
Normal file
61
zealbooter/int_thunks.S
Normal file
|
@ -0,0 +1,61 @@
|
|||
.altmacro
|
||||
|
||||
.macro THUNK num
|
||||
interrupt_thunk_\num:
|
||||
.if \num != 8 && \num != 10 && \num != 11 && \num != 12 && \num != 13 && \num != 14 && \num != 17 && \num != 30
|
||||
push $0
|
||||
.endif
|
||||
|
||||
push %r15
|
||||
push %r14
|
||||
push %r13
|
||||
push %r12
|
||||
push %r11
|
||||
push %r10
|
||||
push %r9
|
||||
push %r8
|
||||
push %rbp
|
||||
push %rdi
|
||||
push %rsi
|
||||
push %rdx
|
||||
push %rcx
|
||||
push %rbx
|
||||
push %rax
|
||||
mov %es, %eax
|
||||
push %rax
|
||||
mov %ds, %eax
|
||||
push %rax
|
||||
|
||||
cld
|
||||
|
||||
mov $\num, %rdi
|
||||
mov $(\num * 8), %rax
|
||||
lea isr(%rip), %rbx
|
||||
add %rax, %rbx
|
||||
mov %rsp, %rsi
|
||||
call *(%rbx)
|
||||
|
||||
.endm
|
||||
|
||||
.macro THUNKADDR num
|
||||
.quad interrupt_thunk_\num
|
||||
.endm
|
||||
|
||||
.section .data
|
||||
|
||||
.global isr_thunks
|
||||
.align 8
|
||||
isr_thunks:
|
||||
.set i,0
|
||||
.rept 256
|
||||
THUNKADDR %i
|
||||
.set i,i+1
|
||||
.endr
|
||||
|
||||
.section .text
|
||||
|
||||
.set i,0
|
||||
.rept 256
|
||||
THUNK %i
|
||||
.set i,i+1
|
||||
.endr
|
|
@ -2,6 +2,7 @@
|
|||
#include <stddef.h>
|
||||
#include <limine.h>
|
||||
#include <lib.h>
|
||||
#include <idt.h>
|
||||
|
||||
static volatile struct limine_module_request module_request = {
|
||||
.id = LIMINE_MODULE_REQUEST,
|
||||
|
@ -152,6 +153,8 @@ void _start(void) {
|
|||
printf("ZealBooter prekernel\n");
|
||||
printf("____________________\n\n");
|
||||
|
||||
idt_init();
|
||||
|
||||
struct limine_file *module_kernel = module_request.response->modules[0];
|
||||
struct CKernel *kernel = module_kernel->address;
|
||||
|
||||
|
|
Loading…
Reference in a new issue