#define FOOLOS_MODULE_NAME "interrupts" #include "lib/logger/log.h" // logger facilities #include "asm/asm.h" #include "asm/pit.h" #include "driver/mouse.h" #include "interrupts.h" #include "asm/x86.h" void errlog(uint32_t error_code) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code: 0x%08X",error_code); } void deflog(uint32_t eip, uint16_t cs, uint32_t flags) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"eip: 0x%08X",eip); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"segment: 0x%08X",cs); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"eflags: 0x%08X",flags); } void int_install_ir(int irq, uint16_t flags, uint16_t sel, void *addr); //void mouse_handler(); // 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; void exception_handle() { panic(FOOLOS_MODULE_NAME,"exception interrupt"); } void int_default() { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"default handler"); panic(FOOLOS_MODULE_NAME,"unhandled interrupt (is this a panic or should just iognore?)"); } void show_error(uint32_t err) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"interrupt error code: 0x%08x",err); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"External Event: %x",err&0b001); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Location: %x",err&0b110); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Selector: %x",err&0b1111111111111000); } void exception_handle_0(){ panic(FOOLOS_MODULE_NAME,"Divide by 0"); } void exception_handle_1(){ panic(FOOLOS_MODULE_NAME,"Single step (debugger)"); } void exception_handle_2(){ panic(FOOLOS_MODULE_NAME,"Non Maskable Interrupt"); } void exception_handle_3(){ panic(FOOLOS_MODULE_NAME,"Breakpoint (debugger)"); } void exception_handle_4(){ panic(FOOLOS_MODULE_NAME,"Overflow"); } void exception_handle_5(){ panic(FOOLOS_MODULE_NAME,"Bounds check"); } void exception_handle_6(){ panic(FOOLOS_MODULE_NAME,"Undefined OP Code"); } void exception_handle_7(){ panic(FOOLOS_MODULE_NAME,"No coprocessor"); } void exception_handle_8(){ panic(FOOLOS_MODULE_NAME,"Double Fault"); } void exception_handle_9(){ panic(FOOLOS_MODULE_NAME,"Coprocessor Segment Overrun"); } void exception_handle_10(){ panic(FOOLOS_MODULE_NAME,"Invalid TSS"); } void exception_handle_11(){ panic(FOOLOS_MODULE_NAME,"Segment Not Present"); } void exception_handle_12(){ panic(FOOLOS_MODULE_NAME,"Stack Segment Overrun"); } void exception_handle_13(uint32_t error_code,uint32_t eip,uint16_t cs,uint16_t unused, uint32_t flags) { errlog(error_code); deflog(eip,cs,flags); panic(FOOLOS_MODULE_NAME,"Exception: Fault: General Protection Fault"); } void exception_handle_14(uint32_t error_code,uint32_t eip,uint16_t cs,uint16_t unused, uint32_t flags) { errlog(error_code); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code_P: %d",error_code&1?1:0); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code_W/R: %d",error_code&2?1:0); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code_U/S: %d",error_code&4?1:0); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code_RSVD: %d",error_code&8?1:0); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"error_code_I/D: %d",error_code&16?1:0); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"at addr: 0x%08X",x86_get_cr(2)); deflog(eip,cs,flags); panic(FOOLOS_MODULE_NAME,"Exception: Fault: Page Fault"); } void exception_handle_15(){ panic(FOOLOS_MODULE_NAME,"Unassigned"); } void exception_handle_16(){ panic(FOOLOS_MODULE_NAME,"Coprocessor error"); } void exception_handle_17(){ panic(FOOLOS_MODULE_NAME,"Alignment Check"); } void exception_handle_18(){ panic(FOOLOS_MODULE_NAME,"Machine Check"); } //set a handler for a specific interrupt void int_install_ir(int irq, uint16_t flags, uint16_t sel, void *addr) { uint64_t base=(uint32_t)&(*(uint32_t*)addr); idt[irq].addrLo = base & 0xffff; idt[irq].addrHi = (base >> 16) & 0xffff; 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) { // Setup PIC log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"setting up PIC",&idt,&idtd); pic_setup(); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"initializing. IDT: 0x%08x, IDTD: 0x%08X",&idt,&idtd); for(int i=0; i 32) int_install_ir(32, 0b10001110, 0x08,&pit_interrupt_handler); // install keyboard interrupt handler (irq 1 => 33) int_install_ir(33, 0b10001110, 0x08,&int_kb_handler); //mouse interrupt handler (irq 12 => 34) int_install_ir(44, 0b10001110, 0x08,&int_mouse_handler); //system calls int_install_ir(0x80, 0b11101110, 0x08,&int_syscall_handler); int_install(); // now we can enable interrupts back again // x86_sti(); //x86_cli(); } void int_install() { idtd.size=sizeof(struct int_desc)*INT_MAX; uint32_t addr=(uint32_t)&idt[0]; idtd.baseHi=addr>>16; idtd.baseLo=0xffff&addr; __asm__("lidt %0"::"m" (idtd)); }