Quick and dirty IDT setup
This commit is contained in:
parent
25ef5f4688
commit
cbcc67fc31
@ -2,8 +2,8 @@ ifeq ($(MITTOS64),)
|
|||||||
$(error Unsupported environment! See README)
|
$(error Unsupported environment! See README)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SRC := $(wildcard **/*.[cS])
|
SRC := $(wildcard **/*.[cS]*)
|
||||||
OBJ := $(patsubst %, %.o, $(basename $(SRC)))
|
OBJ := $(patsubst %, %.o, $(basename $(basename $(SRC))))
|
||||||
|
|
||||||
CFLAGS ?= -Wall -Wextra -pedantic
|
CFLAGS ?= -Wall -Wextra -pedantic
|
||||||
CFLAGS += -ffreestanding -mcmodel=large
|
CFLAGS += -ffreestanding -mcmodel=large
|
||||||
@ -20,6 +20,9 @@ LDFLAGS := -n -nostdlib -lgcc -T Link.ld
|
|||||||
kernel: $(OBJ)
|
kernel: $(OBJ)
|
||||||
$(LINK.c) $^ -o $@
|
$(LINK.c) $^ -o $@
|
||||||
|
|
||||||
|
%.S: %.S.py
|
||||||
|
python $^ > $@
|
||||||
|
|
||||||
# Automatically generate dependency files
|
# Automatically generate dependency files
|
||||||
# Those keep track of which header files are used by which source files
|
# Those keep track of which header files are used by which source files
|
||||||
DEP := $(OBJ:.o=.d)
|
DEP := $(OBJ:.o=.d)
|
||||||
@ -39,6 +42,7 @@ clean:
|
|||||||
rm -rf $(OBJ) $(DEP) kernel
|
rm -rf $(OBJ) $(DEP) kernel
|
||||||
|
|
||||||
.PHONY: install clean
|
.PHONY: install clean
|
||||||
|
.INTERMEDIATE: $(basename $(filter %.py, $(SRC)))
|
||||||
|
|
||||||
# Include generated dependency files
|
# Include generated dependency files
|
||||||
include $(DEP)
|
include $(DEP)
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <multiboot.h>
|
#include <multiboot.h>
|
||||||
|
|
||||||
|
void interrupt_init();
|
||||||
|
|
||||||
void kmain(uint64_t multiboot_magic, void *multiboot_data)
|
void kmain(uint64_t multiboot_magic, void *multiboot_data)
|
||||||
{
|
{
|
||||||
serial_init(PORT_COM1);
|
serial_init(PORT_COM1);
|
||||||
@ -14,6 +16,15 @@ void kmain(uint64_t multiboot_magic, void *multiboot_data)
|
|||||||
|
|
||||||
debug_info("Kernel was loaded with command line \"%s\", by <%s>\n", kernel_boot_data.commandline, kernel_boot_data.bootloader);
|
debug_info("Kernel was loaded with command line \"%s\", by <%s>\n", kernel_boot_data.commandline, kernel_boot_data.bootloader);
|
||||||
|
|
||||||
|
interrupt_init();
|
||||||
|
|
||||||
|
// Force a divide by zero exception
|
||||||
|
// ISR 0
|
||||||
|
int a = 5, b = 0;
|
||||||
|
int c = a/b;
|
||||||
|
|
||||||
|
debug("a: %d b:%d c:%d\n", a,b,c);
|
||||||
|
|
||||||
debug_ok("Boot \"Complete\"\n");
|
debug_ok("Boot \"Complete\"\n");
|
||||||
|
|
||||||
PANIC("Reached end of kernel main function\n");
|
PANIC("Reached end of kernel main function\n");
|
||||||
|
89
src/kernel/interrupts/idt.c
Normal file
89
src/kernel/interrupts/idt.c
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <memory.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
struct int_gate_descriptor
|
||||||
|
{
|
||||||
|
uint16_t base_l;
|
||||||
|
uint16_t cs;
|
||||||
|
uint8_t ist;
|
||||||
|
uint8_t flags;
|
||||||
|
uint16_t base_m;
|
||||||
|
uint32_t base_h;
|
||||||
|
uint32_t ignored;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct idtr
|
||||||
|
{
|
||||||
|
uint16_t len;
|
||||||
|
struct int_gate_descriptor *addr;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
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 int_no;
|
||||||
|
uint64_t err_code;
|
||||||
|
|
||||||
|
uint64_t rip;
|
||||||
|
uint64_t cs;
|
||||||
|
uint64_t rflags;
|
||||||
|
uint64_t rsp;
|
||||||
|
uint64_t ss;
|
||||||
|
} registers;
|
||||||
|
|
||||||
|
void load_idt(struct idtr *);
|
||||||
|
|
||||||
|
#define NUM_INTERRUPTS 256
|
||||||
|
|
||||||
|
struct int_gate_descriptor idt[NUM_INTERRUPTS];
|
||||||
|
struct idtr idtr;
|
||||||
|
|
||||||
|
|
||||||
|
extern uintptr_t isr_table[];
|
||||||
|
|
||||||
|
void idt_set_gate(uint32_t num, uintptr_t vector, uint16_t cs, uint8_t ist, uint8_t flags)
|
||||||
|
{
|
||||||
|
idt[num].base_l = vector & 0xFFFF;
|
||||||
|
idt[num].base_m = (vector >> 16) & 0xFFFF;
|
||||||
|
idt[num].base_h = (vector >> 32) & 0xFFFFFFFF;
|
||||||
|
idt[num].cs = cs;
|
||||||
|
idt[num].ist = ist;
|
||||||
|
idt[num].flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
void interrupt_init()
|
||||||
|
{
|
||||||
|
memset(idt, 0, sizeof(idt));
|
||||||
|
|
||||||
|
for(int i=0; i < NUM_INTERRUPTS; i++)
|
||||||
|
{
|
||||||
|
idt_set_gate(i, isr_table[i], 0x8, 0, 0x8E);
|
||||||
|
}
|
||||||
|
|
||||||
|
idtr.addr = idt;
|
||||||
|
idtr.len = sizeof(idt)-1;
|
||||||
|
load_idt(&idtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
registers *int_handler(registers *r)
|
||||||
|
{
|
||||||
|
(void)r;
|
||||||
|
debug("Interrupt %d\n", r->int_no);
|
||||||
|
for(;;);
|
||||||
|
}
|
31
src/kernel/interrupts/idt.tt
Normal file
31
src/kernel/interrupts/idt.tt
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// vim: ft=c
|
||||||
|
#include <ttest.h>
|
||||||
|
#include <debug.h>
|
||||||
|
#undef debug
|
||||||
|
#define debug(...)
|
||||||
|
#include "idt.c"
|
||||||
|
|
||||||
|
uintptr_t isr_table[] ={};
|
||||||
|
void load_idt(struct idtr *_)
|
||||||
|
{
|
||||||
|
(void)_;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(idt_set_gate_correctly_sets_address_L)
|
||||||
|
{
|
||||||
|
idt_set_gate(1, 0x1234567890ABCDEF, 0, 0, 0);
|
||||||
|
|
||||||
|
ASSERT_EQ_INT(idt[1].base_l, 0xCDEF);
|
||||||
|
}
|
||||||
|
TEST(idt_set_gate_correctly_sets_address_M)
|
||||||
|
{
|
||||||
|
idt_set_gate(1, 0x1234567890ABCDEF, 0, 0, 0);
|
||||||
|
|
||||||
|
ASSERT_EQ_INT(idt[1].base_m, 0x90AB);
|
||||||
|
}
|
||||||
|
TEST(idt_set_gate_correctly_sets_address_H)
|
||||||
|
{
|
||||||
|
idt_set_gate(1, 0x1234567890ABCDEF, 0, 0, 0);
|
||||||
|
|
||||||
|
ASSERT_EQ_INT(idt[1].base_h, 0x12345678);
|
||||||
|
}
|
32
src/kernel/interrupts/isr.S.py
Normal file
32
src/kernel/interrupts/isr.S.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env python2
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
num_isr = 256
|
||||||
|
pushes_error = [8, 10, 11, 12, 13, 14, 17]
|
||||||
|
|
||||||
|
print '''
|
||||||
|
.intel_syntax noprefix
|
||||||
|
.extern isr_common
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
print '// Interrupt Service Routines'
|
||||||
|
for i in range(num_isr):
|
||||||
|
print '''isr{0}:
|
||||||
|
cli
|
||||||
|
{1}
|
||||||
|
push {0}
|
||||||
|
jmp isr_common
|
||||||
|
'''.format(i,
|
||||||
|
'push 0' if i not in pushes_error else 'nop')
|
||||||
|
|
||||||
|
print ''
|
||||||
|
print '''
|
||||||
|
// Vector table
|
||||||
|
|
||||||
|
.section .data
|
||||||
|
.global isr_table
|
||||||
|
isr_table:'''
|
||||||
|
|
||||||
|
for i in range(num_isr):
|
||||||
|
print ' .quad isr{}'.format(i)
|
50
src/kernel/interrupts/isr_common.S
Normal file
50
src/kernel/interrupts/isr_common.S
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
.intel_syntax noprefix
|
||||||
|
|
||||||
|
.global load_idt
|
||||||
|
load_idt:
|
||||||
|
lidt [rdi]
|
||||||
|
ret
|
||||||
|
|
||||||
|
.extern int_handler
|
||||||
|
.global isr_common
|
||||||
|
.global isr_return
|
||||||
|
|
||||||
|
isr_common:
|
||||||
|
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 rdi, rsp
|
||||||
|
call int_handler
|
||||||
|
|
||||||
|
mov rdi, rax
|
||||||
|
isr_return:
|
||||||
|
mov rsp, rdi
|
||||||
|
pop rax
|
||||||
|
pop rbx
|
||||||
|
pop rcx
|
||||||
|
pop rdx
|
||||||
|
pop rsi
|
||||||
|
pop rdi
|
||||||
|
pop rbp
|
||||||
|
pop r8
|
||||||
|
pop r9
|
||||||
|
pop r10
|
||||||
|
pop r11
|
||||||
|
pop r12
|
||||||
|
pop r13
|
||||||
|
pop r14
|
||||||
|
pop r15
|
||||||
|
add rsp, 0x10
|
||||||
|
iretq
|
Loading…
x
Reference in New Issue
Block a user