diff options
Diffstat (limited to 'kernel/interrupts.c')
| -rw-r--r-- | kernel/interrupts.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/kernel/interrupts.c b/kernel/interrupts.c new file mode 100644 index 0000000..198822e --- /dev/null +++ b/kernel/interrupts.c @@ -0,0 +1,115 @@ +#include "interrupts.h" + +// the interrupt descriptor table +static struct int_desc +{ + uint16_t addrLo; + uint16_t sel; + uint8_t zeros; + uint8_t flags; + uint16_t addrHi; + +} idt[INT_MAX]; + +// interrupt descriptor table descriptor +static struct idt_desc +{ + uint16_t size; + uint16_t baseLo; + uint16_t baseHi; + +} idtd; + +// disable interrupts +void int_disable() +{ + __asm__("cli"); +} + +// enable interrupts +void int_enable() +{ + __asm__("sti"); +} + + +// default handler +void int_def_handler() +{ + __asm__("pusha"); + + int_unhandled++; + + // todo also the other pic!// TODO + __asm__("mov $0x20, %al"); + __asm__("out %al, $0x20"); + + __asm__("popa"); + __asm__("leave"); + __asm__("iret"); + +} + + +//set a handler for a specific interrupt +void int_install_ir(int irq, uint16_t flags, uint16_t sel, void *addr) +{ + + uint64_t base=(uint64_t)&(*addr); // TODO! + + idt[irq].addrLo = base & 0xffff; + idt[irq].addrHi = (base >> 16) & 0xffff; + idt[irq].addrHi = 0x0; + idt[irq].zeros=0; + idt[irq].flags=flags; + idt[irq].sel=sel; + +} + +// set default handler for all interrupts for a start +void int_init(uint16_t sel) +{ + int i; + for(i=0; i<INT_MAX; i++) + { + int_install_ir(i, 0b10001110, sel,&int_def_handler); + } + +} + +void int_install() +{ + + idtd.size=8*34; //TODO + idtd.baseHi=0x0000; + idtd.baseLo=&idt[0]; + + __asm__("lidt %0"::"m" (idtd)); + +} +/* +//print interrupt table; //TODO! +void int_show() +{ + uint16_t *ptr3=&idt[0]; // TODO! + + scr_put_string("idt located: "); + scr_put_hex(ptr3); + scr_nextline(); + + + // first two bytes as chars + int offset; + for(offset=32;offset<40;offset++) + { + print_hex(offset-32); //irq + print_string(" -> "); + print_hex(*(ptr3+offset*4)); //addrLo + print_hex(*(ptr3+1+offset*4)); //sel + print_hex(*(ptr3+2+offset*4)); //zeros & flags + print_hex(*(ptr3+3+offset*4)); //addrHi + print_nextline(); + } +} +*/ + |
