I added some work on a keyboard driver here also changed the emulation system, since bochs was giving me headaches when it came to keyboard input added some todo stuff.. probably some cleanup, idk
76 lines
1.8 KiB
C
76 lines
1.8 KiB
C
#include <stdbool.h>
|
|
|
|
#ifdef __TESTING__
|
|
#include <kernel/_kernel.h>
|
|
#include <stdio.h>
|
|
#endif
|
|
#include <kernel/x86/idt.h>
|
|
#include <kernel/x86/pic.h>
|
|
#include <kernel/x86/io.h>
|
|
#include <kernel/x86/keyb.h>
|
|
|
|
__attribute__((aligned(0x10)))
|
|
static idt_entry_t idt[256];
|
|
|
|
static idtr_t idtr;
|
|
|
|
static bool vectors[IDT_MAX_DESCRIPTORS];
|
|
|
|
void exception_handler(unsigned int i)
|
|
{
|
|
if (i <= 31) { // TODO: implement proper handling for each exception, also implement the proper gates & error code checking
|
|
#ifdef __TESTING__
|
|
kerror("EXCEPTION");
|
|
printf("Exeption: %u\n", i);
|
|
#endif
|
|
__asm__ volatile ("cli; hlt"); // hangs the computer
|
|
}
|
|
|
|
if (i == PIC_KEYB) {
|
|
unsigned char in = inb(0x60);
|
|
#ifdef __TESTING__
|
|
printf("scancode: %x\n", in);
|
|
#endif
|
|
|
|
PIC_sendEOI(1);
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
#ifdef __TESTING__
|
|
kinfo("Initializing the IDT");
|
|
#endif
|
|
idtr.base = (uintptr_t)&idt[0];
|
|
idtr.limit = (uint16_t) sizeof(idt_entry_t) * IDT_MAX_DESCRIPTORS - 1;
|
|
|
|
for (uint8_t vector = 0; vector < IDT_MAX_DESCRIPTORS; vector++) {
|
|
idt_set_descriptor(vector, isr_stub_table[vector], 0x8E);
|
|
vectors[vector] = true;
|
|
}
|
|
|
|
// The "m" indicates actual data, not a pointer
|
|
__asm__ volatile("lidt %0" : : "m"(idtr)); // load the new IDT
|
|
|
|
PIC_remap(0x20, 0x28);
|
|
pic_disable(); // mask everything
|
|
IRQ_clear_mask(1);
|
|
|
|
__asm__ volatile("sti"); // set the interrupt flag
|
|
#ifdef __TESTING__
|
|
kinfo("Initialized the IDT");
|
|
#endif
|
|
}
|