trios/kernel/interrupt/idt.c

82 lines
1.7 KiB
C

#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <sys.h>
#include "idt.h"
#include "../term.h"
#include "pic.h"
static int timer = 0;
void idt_pic_handler(uint8_t exception) {
pic_eoi(exception - PIC_REMAP_OFFSET);
}
void idt_pic_timer(void) {
uint32_t state = term_save();
term_setcol(0x0a);
char buf[20];
itoa(timer, buf);
term_setpos(0, 20);
puts(" ");
term_setpos(0, 20);
puts(buf);
timer += 1;
term_load(state);
}
void idt_pic_keyboard(void) {
uint8_t c = inb(0x60);
uint32_t state = term_save();
term_setcol(0x0c);
term_setpos(0, 21);
puts(" ");
term_setpos(0, 21);
char buf[20];
itoa(c, buf);
puts(buf);
term_load(state);
}
void idt_exception_handler(uint8_t exception) {
switch(exception) {
case 0x00:
puts("Div by zero");
break;
case 0x08:
puts("Double fault");
break;
default:
puts("Error");
break;
}
halt();
}
__attribute__((aligned(0x10)))
static struct IdtEntry idt[256];
static struct Idtr idtr;
extern void* isr_stub_table[];
static void set_descriptor(uint8_t vector, void* isr, uint8_t flags) {
struct IdtEntry* entry = &idt[vector];
entry->isr_low = (size_t)isr & 0xffff;
entry->kernel_cs = 0x08;
entry->attributes = flags;
entry->isr_high = (size_t)isr >> 16;
entry->_reserved = 0;
}
void idt_init(void) {
idtr.base = (uintptr_t)&idt[0];
idtr.limit = (uint16_t)sizeof(struct IdtEntry) * IDT_SIZE - 1;
for(uint8_t i = 0; i < IDT_INTERRUPTS; i++) {
set_descriptor(i, isr_stub_table[i], 0x8e);
}
__asm__ volatile ("lidt %0" : : "m"(idtr));
}