98 lines
1.8 KiB
C
98 lines
1.8 KiB
C
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
#include <sys.h>
|
|
|
|
#include "idt.h"
|
|
#include "pic.h"
|
|
#include "../term.h"
|
|
#include "../panic.h"
|
|
#include "../drivers/ps2kb.h"
|
|
#include "../drivers/ps2ctrl.h"
|
|
|
|
static int timer = 0;
|
|
|
|
void idt_pic_generic(uint8_t exception) {
|
|
pic_eoi(exception - PIC_REMAP_OFFSET);
|
|
}
|
|
|
|
void idt_pic_timer(void) {
|
|
uint32_t state = term_save();
|
|
term_setcol(0x0a);
|
|
term_setpos(60, 0);
|
|
puts(" ");
|
|
term_setpos(60, 0);
|
|
printf("%d", timer);
|
|
term_flush();
|
|
timer += 1;
|
|
term_load(state);
|
|
}
|
|
|
|
void idt_pic_keyboard(void) {
|
|
ps2kb_recv();
|
|
}
|
|
|
|
void idt_exception_handler(uint8_t exception) {
|
|
char* msg;
|
|
switch(exception) {
|
|
case 0x00:
|
|
msg = "Division by zero";
|
|
break;
|
|
case 0x02:
|
|
msg = "NMI";
|
|
break;
|
|
case 0x04:
|
|
msg = "Overflow";
|
|
break;
|
|
case 0x06:
|
|
msg = "invalid opcode";
|
|
break;
|
|
case 0x08:
|
|
msg = "double fault";
|
|
break;
|
|
case 0x0A:
|
|
msg = "invalid task state segment";
|
|
break;
|
|
case 0x0C:
|
|
msg = "stack segment fault";
|
|
break;
|
|
case 0x0D:
|
|
msg = "general protection fault";
|
|
break;
|
|
case 0x0E:
|
|
msg = "page fault";
|
|
break;
|
|
default:
|
|
msg = "unknown exception";
|
|
break;
|
|
}
|
|
panic("E%u: %s", exception, msg);
|
|
}
|
|
|
|
__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(int i = 0; i < IDT_INTERRUPTS; i++) {
|
|
set_descriptor(i, isr_stub_table[i], 0x8e);
|
|
}
|
|
|
|
__asm__ volatile ("lidt %0" : : "m"(idtr));
|
|
}
|
|
|