adds an idt
This commit is contained in:
43
kernel/arch/idt/idt.c
Normal file
43
kernel/arch/idt/idt.c
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <kernel/x86/idt.h>
|
||||||
|
|
||||||
|
__attribute__((aligned(0x10)))
|
||||||
|
static idt_entry_t idt[256];
|
||||||
|
|
||||||
|
static idtr_t idtr;
|
||||||
|
|
||||||
|
static bool vectors[IDT_MAX_DESCRIPTORS];
|
||||||
|
|
||||||
|
void exception_handler()
|
||||||
|
{
|
||||||
|
__asm__ volatile ("cli; hlt"); // hangs the computer
|
||||||
|
}
|
||||||
|
|
||||||
|
void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags)
|
||||||
|
{
|
||||||
|
idt_entry_t* descriptor = &idt[vector];
|
||||||
|
|
||||||
|
descriptor->isr_low = (uint32_t) isr & 0xFFFF;
|
||||||
|
descriptor->kernel_cs = 0x08; // this is whatever the kernel code selector is in the GDT
|
||||||
|
descriptor->attributes = flags;
|
||||||
|
descriptor->isr_high = (uint32_t) isr >> 16;
|
||||||
|
descriptor->reserved = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern void* isr_stub_table[];
|
||||||
|
void idt_init(void)
|
||||||
|
{
|
||||||
|
idtr.base = (uintptr_t)&idt[0];
|
||||||
|
idtr.limit = (uint16_t) sizeof(idt_entry_t) * IDT_MAX_DESCRIPTORS - 1;
|
||||||
|
|
||||||
|
for (uint8_t vector = 0; vector < 32; vector++) {
|
||||||
|
idt_set_descriptor(vector, isr_stub_table[vector], 0x8E);
|
||||||
|
vectors[vector] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
__asm__ volatile("lidt %0" : : "m"(idtr)); // load the new IDT
|
||||||
|
__asm__ volatile("sti"); // set the interrupt flag
|
||||||
|
}
|
||||||
|
|
54
kernel/arch/idt/idt_src.s
Normal file
54
kernel/arch/idt/idt_src.s
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
extern exception_handler
|
||||||
|
|
||||||
|
%macro isr_err_stub 1
|
||||||
|
isr_stub_%+%1:
|
||||||
|
call exception_handler
|
||||||
|
iret
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
%macro isr_no_err_stub 1
|
||||||
|
isr_stub_%+%1:
|
||||||
|
call exception_handler
|
||||||
|
iret
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
isr_no_err_stub 0
|
||||||
|
isr_no_err_stub 1
|
||||||
|
isr_no_err_stub 2
|
||||||
|
isr_no_err_stub 3
|
||||||
|
isr_no_err_stub 4
|
||||||
|
isr_no_err_stub 5
|
||||||
|
isr_no_err_stub 6
|
||||||
|
isr_no_err_stub 7
|
||||||
|
isr_err_stub 8
|
||||||
|
isr_no_err_stub 9
|
||||||
|
isr_err_stub 10
|
||||||
|
isr_err_stub 11
|
||||||
|
isr_err_stub 12
|
||||||
|
isr_err_stub 13
|
||||||
|
isr_err_stub 14
|
||||||
|
isr_no_err_stub 15
|
||||||
|
isr_no_err_stub 16
|
||||||
|
isr_err_stub 17
|
||||||
|
isr_no_err_stub 18
|
||||||
|
isr_no_err_stub 19
|
||||||
|
isr_no_err_stub 20
|
||||||
|
isr_no_err_stub 21
|
||||||
|
isr_no_err_stub 22
|
||||||
|
isr_no_err_stub 23
|
||||||
|
isr_no_err_stub 24
|
||||||
|
isr_no_err_stub 25
|
||||||
|
isr_no_err_stub 26
|
||||||
|
isr_no_err_stub 27
|
||||||
|
isr_no_err_stub 28
|
||||||
|
isr_no_err_stub 29
|
||||||
|
isr_err_stub 30
|
||||||
|
isr_no_err_stub 31
|
||||||
|
|
||||||
|
global isr_stub_table
|
||||||
|
isr_stub_table:
|
||||||
|
%assign i 0
|
||||||
|
%rep 32
|
||||||
|
dd isr_stub_%+i
|
||||||
|
%assign i i+1
|
||||||
|
%endrep
|
26
kernel/include/kernel/x86/idt.h
Normal file
26
kernel/include/kernel/x86/idt.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifndef ARCH_IDT_H
|
||||||
|
#define ARCH_IDT_H
|
||||||
|
|
||||||
|
#define IDT_MAX_DESCRIPTORS 32 // number of entries in the idt table, 32 i believe
|
||||||
|
|
||||||
|
void exception_handler(void);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t isr_low; // The lower 16 bits of the ISR's address
|
||||||
|
uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR
|
||||||
|
uint8_t reserved; // set to zero
|
||||||
|
uint8_t attributes; // Type and attributes
|
||||||
|
uint16_t isr_high; // The higher 16 bits of the ISR's address
|
||||||
|
} __attribute__((packed)) idt_entry_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t limit;
|
||||||
|
uint32_t base;
|
||||||
|
} __attribute__((packed)) idtr_t;
|
||||||
|
|
||||||
|
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags);
|
||||||
|
void idt_init(void);
|
||||||
|
|
||||||
|
#endif
|
@ -4,6 +4,7 @@
|
|||||||
#include <kernel/tty.h>
|
#include <kernel/tty.h>
|
||||||
#include <kernel/serial.h>
|
#include <kernel/serial.h>
|
||||||
#include <kernel/x86/gdt.h>
|
#include <kernel/x86/gdt.h>
|
||||||
|
#include <kernel/x86/idt.h>
|
||||||
|
|
||||||
#define GDT_SIZE 5
|
#define GDT_SIZE 5
|
||||||
|
|
||||||
@ -27,6 +28,7 @@ void gdt_init(void)
|
|||||||
void kmain(void)
|
void kmain(void)
|
||||||
{
|
{
|
||||||
gdt_init();
|
gdt_init();
|
||||||
|
idt_init();
|
||||||
|
|
||||||
terminal_initialize();
|
terminal_initialize();
|
||||||
serial_initialize();
|
serial_initialize();
|
||||||
|
Reference in New Issue
Block a user