#include "IDT.ns.h" #include #include #include #include using namespace Sys; //For outb extern "C" void isr0(); extern "C" void isr1(); extern "C" void isr2(); extern "C" void isr3(); extern "C" void isr4(); extern "C" void isr5(); extern "C" void isr6(); extern "C" void isr7(); extern "C" void isr8(); extern "C" void isr9(); extern "C" void isr10(); extern "C" void isr11(); extern "C" void isr12(); extern "C" void isr13(); extern "C" void isr14(); extern "C" void isr15(); extern "C" void isr16(); extern "C" void isr17(); extern "C" void isr18(); extern "C" void isr19(); extern "C" void isr20(); extern "C" void isr21(); extern "C" void isr22(); extern "C" void isr23(); extern "C" void isr24(); extern "C" void isr25(); extern "C" void isr26(); extern "C" void isr27(); extern "C" void isr28(); extern "C" void isr29(); extern "C" void isr30(); extern "C" void isr31(); extern "C" void irq0(); extern "C" void irq1(); extern "C" void irq2(); extern "C" void irq3(); extern "C" void irq4(); extern "C" void irq5(); extern "C" void irq6(); extern "C" void irq7(); extern "C" void irq8(); extern "C" void irq9(); extern "C" void irq10(); extern "C" void irq11(); extern "C" void irq12(); extern "C" void irq13(); extern "C" void irq14(); extern "C" void irq15(); extern "C" void int64(); //Main syscall extern "C" void int65(); //Syscall to request a task switch extern "C" void int66(); //Syscall to signal that thread ended extern "C" void idt_flush(u32int); extern "C" void interrupt_handler(registers_t regs) { bool doSwitch = (regs.int_no == 32 or regs.int_no >= 65); //SYSCALLS >= 65 are task-managing-related if (regs.int_no < 32) { if ((u32int)Task::currThread() == 0xFFFFFFFF or Task::currThread() == 0) PANIC_DUMP("Exception cannot be handled.", ®s); Task::currThread()->handleException(regs, regs.int_no); } else if (regs.int_no < 48) { if (regs.int_no >= 40) outb(0xA0, 0x20); outb(0x20, 0x20); Dev::handleIRQ(regs, (regs.int_no - 32)); doSwitch = doSwitch or Task::IRQwakeup(regs.int_no - 32); } if (regs.int_no == 64) { asm volatile("sti"); //Make syscalls preemtible u32int res = (regs.eax >> 8); u8int wat = (regs.eax & 0xFF); if (res == 0xFFFFFF) { if (regs.eax == 0xFFFFFF01) { Task::currProcess()->getOutVT()->put(WChar(regs.ebx)); } else if (regs.eax == 0xFFFFFF02) { Task::currThread()->sleep(regs.ebx); } else if (regs.eax == 0xFFFFFF03) { Task::currProcess()->getOutVT()->writeHex(regs.ebx); } } else { regs.eax = Res::call(res, wat, regs.ebx, regs.ecx, regs.edx, regs.edi, regs.esi); } //Some syscalls have maybee modified current page directory, set it back to one for current process Task::currProcess()->getPagedir()->switchTo(); asm volatile("cli"); } if (regs.int_no == 66) { //This syscall signals to kernel that thread ended. Task::currentThreadExits(regs.eax); //DO NOT COUNT ON COMMING BACK FROM HERE } if (doSwitch) Task::doSwitch(); //DO NOT COUNT ON COMMING BACK FROM HERE EITHER } namespace IDT { idt_entry_t idt_entries[256]; idt_ptr_t idt_ptr; void setGate(u8int num, u32int base, u16int sel, u8int flags) { idt_entries[num].base_lo = base & 0xFFFF; idt_entries[num].base_hi = (base >> 16) & 0xFFFF; idt_entries[num].sel = sel; idt_entries[num].flags = flags | 0x60; idt_entries[num].always0 = 0; } void init() { idt_ptr.limit = (sizeof(idt_entry_t) * 256) - 1; idt_ptr.base = (u32int)&idt_entries; CMem::memset((u8int*)&idt_entries, 0, sizeof(idt_entry_t) * 256); //Remap the IRQ table outb(0x20, 0x11); outb(0xA0, 0x11); outb(0x21, 0x20); outb(0xA1, 0x28); outb(0x21, 0x04); outb(0xA1, 0x02); outb(0x21, 0x01); outb(0xA1, 0x01); outb(0x21, 0x0); outb(0xA1, 0x0); setGate(0, (u32int)isr0, 0x08, 0x8E); setGate(1, (u32int)isr1, 0x08, 0x8E); setGate(2, (u32int)isr2, 0x08, 0x8E); setGate(3, (u32int)isr3, 0x08, 0x8E); setGate(4, (u32int)isr4, 0x08, 0x8E); setGate(5, (u32int)isr5, 0x08, 0x8E); setGate(6, (u32int)isr6, 0x08, 0x8E); setGate(7, (u32int)isr7, 0x08, 0x8E); setGate(8, (u32int)isr8, 0x08, 0x8E); setGate(9, (u32int)isr9, 0x08, 0x8E); setGate(10, (u32int)isr10, 0x08, 0x8E); setGate(11, (u32int)isr11, 0x08, 0x8E); setGate(12, (u32int)isr12, 0x08, 0x8E); setGate(13, (u32int)isr13, 0x08, 0x8E); setGate(14, (u32int)isr14, 0x08, 0x8E); setGate(15, (u32int)isr15, 0x08, 0x8E); setGate(16, (u32int)isr16, 0x08, 0x8E); setGate(17, (u32int)isr17, 0x08, 0x8E); setGate(18, (u32int)isr18, 0x08, 0x8E); setGate(19, (u32int)isr19, 0x08, 0x8E); setGate(20, (u32int)isr20, 0x08, 0x8E); setGate(21, (u32int)isr21, 0x08, 0x8E); setGate(22, (u32int)isr22, 0x08, 0x8E); setGate(23, (u32int)isr23, 0x08, 0x8E); setGate(24, (u32int)isr24, 0x08, 0x8E); setGate(25, (u32int)isr25, 0x08, 0x8E); setGate(26, (u32int)isr26, 0x08, 0x8E); setGate(27, (u32int)isr27, 0x08, 0x8E); setGate(28, (u32int)isr28, 0x08, 0x8E); setGate(29, (u32int)isr29, 0x08, 0x8E); setGate(30, (u32int)isr30, 0x08, 0x8E); setGate(31, (u32int)isr31, 0x08, 0x8E); setGate(32, (u32int)irq0, 0x08, 0x8E); setGate(33, (u32int)irq1, 0x08, 0x8E); setGate(34, (u32int)irq2, 0x08, 0x8E); setGate(35, (u32int)irq3, 0x08, 0x8E); setGate(36, (u32int)irq4, 0x08, 0x8E); setGate(37, (u32int)irq5, 0x08, 0x8E); setGate(38, (u32int)irq6, 0x08, 0x8E); setGate(39, (u32int)irq7, 0x08, 0x8E); setGate(40, (u32int)irq8, 0x08, 0x8E); setGate(41, (u32int)irq9, 0x08, 0x8E); setGate(42, (u32int)irq10, 0x08, 0x8E); setGate(43, (u32int)irq11, 0x08, 0x8E); setGate(44, (u32int)irq12, 0x08, 0x8E); setGate(45, (u32int)irq13, 0x08, 0x8E); setGate(46, (u32int)irq14, 0x08, 0x8E); setGate(47, (u32int)irq15, 0x08, 0x8E); setGate(64, (u32int)int64, 0x08, 0x8E); setGate(65, (u32int)int65, 0x08, 0x8E); setGate(66, (u32int)int66, 0x08, 0x8E); idt_flush((u32int)&idt_ptr); } }