diff --git a/ChangeLog b/ChangeLog index 5df0bcd..c8f2496 100644 --- a/ChangeLog +++ b/ChangeLog @@ -74,3 +74,8 @@ IDT Overhaul * IDT : can now register new IRQ handlers at runtime * Exception handler : crashdumps with registers * RTC time based ticks : functionnal + +2019-05-6 @os-k-team +IDT Overhaul + * IDT : can now register new IRQ and Exception handlers at runtime + * Exception handler : now called early diff --git a/include/kernel/base.h b/include/kernel/base.h index 362c9b0..8516f42 100644 --- a/include/kernel/base.h +++ b/include/kernel/base.h @@ -50,7 +50,7 @@ typedef enum ProcState_t ProcState_t; typedef struct IdtDescriptor_t IdtDescriptor_t; typedef struct IdtEntry_t IdtEntry_t; typedef struct IdtPtr_t IdtPtr_t; -typedef struct IRQList_t IRQList_t; +typedef struct ISRList_t ISRList_t; typedef struct ISRFrame_t ISRFrame_t; typedef struct MemoryMap_t MemoryMap_t; diff --git a/include/kernel/idt.h b/include/kernel/idt.h index e3c1202..ec4c071 100644 --- a/include/kernel/idt.h +++ b/include/kernel/idt.h @@ -54,15 +54,15 @@ struct IdtPtr_t void *base; } __attribute__((packed)); -struct IRQList_t +struct ISRList_t { uchar n; //number of entries in the list struct entry { void (*isr)(ISRFrame_t *regs); - uchar irq; + uchar isrNo; uchar flags; - } entry[224]; + } entry[255]; }; typedef struct @@ -78,9 +78,9 @@ void IdtInit(void); void IdtSetup(void); void IoSendEOItoPIC(uchar isr); -void IdtExceptionHandler(ISRFrame_t *regs); +void IdtEarlyExceptionHandler(ISRFrame_t *regs); void IdtSetGate(uchar rank, ulong base, ushort selector, uchar flags); -void IdtRegisterIrq(void (*isr)(ISRFrame_t *regs), uchar irq, uchar flags); +error_t IdtRegisterIsr(void (*isr)(ISRFrame_t *regs), uchar isrNo); //----------------------------------------------------------------------------// diff --git a/include/kernel/iomisc.h b/include/kernel/iomisc.h index 3bb9f64..d37bd91 100644 --- a/include/kernel/iomisc.h +++ b/include/kernel/iomisc.h @@ -64,7 +64,7 @@ static inline ulong KePauseIRQs(void) { extern void IoSendEOItoPIC(uchar isr); extern void IoEnableNMI(void); extern void IoDisableNMI(void); -extern void IdtRegisterIrq(void (*isr)(ISRFrame_t *regs), uchar irq, uchar flags); +error_t IdtRegisterIsr(void (*isr)(ISRFrame_t *regs), uchar isrNo); // // Restore IRQ flag to its state before KePauseIRQs diff --git a/kaleid/kernel/cpu/idt.c b/kaleid/kernel/cpu/idt.c index ecb2e4e..ef3382b 100644 --- a/kaleid/kernel/cpu/idt.c +++ b/kaleid/kernel/cpu/idt.c @@ -31,9 +31,9 @@ IdtEntry_t idt[256] = { 0 }; IdtPtr_t idtPtr; -IRQList_t irqList = { 0 }; +ISRList_t isrList = { 0 }; -char *IsrExceptions[32] = { +char *ExceptionsChar[32] = { "Divide Error Fault", "Debug Exception Trap", "Non-maskable Interrupt", @@ -75,22 +75,32 @@ static void EnablePIC(void); // // Registers an isr with his IRQ to handle driver interrupts // -void IdtRegisterIrq(void (*isr)(ISRFrame_t *regs), uchar irq, uchar flags) +error_t IdtRegisterIsr(void (*isr)(ISRFrame_t *regs), uchar isrNo) { - uchar n = irqList.n; + uchar n = isrList.n; + int OverWriting = 0; KalAssert(idt[0].flags!=0); // IDT initialized - if ((n == 224)) // IRQs not filled - KeStartPanic("[IdtRegisterIrq] Cannot register IRQ %c function %p !", - irq, - isr - ); + if (n == 0) goto settingUp; - irqList.entry[n].isr = isr; - irqList.entry[n].irq = irq; - irqList.entry[n].flags = flags; - irqList.n++; + for (int i = 0; i < n; i++) { + if (isrNo == isrList.entry[i].isrNo) { + n = i; + OverWriting++; + break; + } + } + + if ((n == 255)) // IRQs not filled + return ENOMEM; + +settingUp: + isrList.entry[n].isr = isr; + isrList.entry[n].isrNo = isrNo; + if (!OverWriting) isrList.n++; + + return EOK; } // @@ -108,56 +118,61 @@ void IdtSetup(void) idtPtr.base = &idt; // Set IDT Exception Gates - IdtSetGate(0, (ulong)isr0, codeSeg, 0x8E); - IdtSetGate(1, (ulong)isr1, codeSeg, 0x8E); - IdtSetGate(2, (ulong)isr2, codeSeg, 0x8E); - IdtSetGate(3, (ulong)isr3, codeSeg, 0x8E); - IdtSetGate(4, (ulong)isr4, codeSeg, 0x8E); - IdtSetGate(5, (ulong)isr5, codeSeg, 0x8E); - IdtSetGate(6, (ulong)isr6, codeSeg, 0x8E); - IdtSetGate(7, (ulong)isr7, codeSeg, 0x8E); - IdtSetGate(8, (ulong)isr8, codeSeg, 0x8E); - IdtSetGate(9, (ulong)isr9, codeSeg, 0x8E); - IdtSetGate(10, (ulong)isr10, codeSeg, 0x8E); - IdtSetGate(11, (ulong)isr11, codeSeg, 0x8E); - IdtSetGate(12, (ulong)isr12, codeSeg, 0x8E); - IdtSetGate(13, (ulong)isr13, codeSeg, 0x8E); - IdtSetGate(14, (ulong)isr14, codeSeg, 0x8E); - IdtSetGate(15, (ulong)isr15, codeSeg, 0x8E); // INTEL RESERVED - IdtSetGate(16, (ulong)isr16, codeSeg, 0x8E); - IdtSetGate(17, (ulong)isr17, codeSeg, 0x8E); - IdtSetGate(18, (ulong)isr18, codeSeg, 0x8E); - IdtSetGate(19, (ulong)isr19, codeSeg, 0x8E); - IdtSetGate(20, (ulong)isr20, codeSeg, 0x8E); - IdtSetGate(21, (ulong)isr21, codeSeg, 0x8E); // INTEL RESERVED - IdtSetGate(22, (ulong)isr22, codeSeg, 0x8E); // INTEL RESERVED - IdtSetGate(23, (ulong)isr23, codeSeg, 0x8E); // INTEL RESERVED - IdtSetGate(24, (ulong)isr24, codeSeg, 0x8E); // INTEL RESERVED - IdtSetGate(25, (ulong)isr25, codeSeg, 0x8E); // INTEL RESERVED - IdtSetGate(26, (ulong)isr26, codeSeg, 0x8E); // INTEL RESERVED - IdtSetGate(27, (ulong)isr27, codeSeg, 0x8E); // INTEL RESERVED - IdtSetGate(28, (ulong)isr28, codeSeg, 0x8E); // INTEL RESERVED - IdtSetGate(29, (ulong)isr29, codeSeg, 0x8E); // INTEL RESERVED - IdtSetGate(30, (ulong)isr30, codeSeg, 0x8E); // INTEL RESERVED - IdtSetGate(31, (ulong)isr31, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(0x00, (ulong)isr0, codeSeg, 0x8E); + IdtSetGate(0x01, (ulong)isr1, codeSeg, 0x8E); + IdtSetGate(0x02, (ulong)isr2, codeSeg, 0x8E); + IdtSetGate(0x03, (ulong)isr3, codeSeg, 0x8E); + IdtSetGate(0x04, (ulong)isr4, codeSeg, 0x8E); + IdtSetGate(0x05, (ulong)isr5, codeSeg, 0x8E); + IdtSetGate(0x06, (ulong)isr6, codeSeg, 0x8E); + IdtSetGate(0x07, (ulong)isr7, codeSeg, 0x8E); + IdtSetGate(0x08, (ulong)isr8, codeSeg, 0x8E); + IdtSetGate(0x09, (ulong)isr9, codeSeg, 0x8E); + IdtSetGate(0x0A, (ulong)isr10, codeSeg, 0x8E); + IdtSetGate(0x0B, (ulong)isr11, codeSeg, 0x8E); + IdtSetGate(0x0C, (ulong)isr12, codeSeg, 0x8E); + IdtSetGate(0x0D, (ulong)isr13, codeSeg, 0x8E); + IdtSetGate(0x0E, (ulong)isr14, codeSeg, 0x8E); + IdtSetGate(0x0F, (ulong)isr15, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(0x10, (ulong)isr16, codeSeg, 0x8E); + IdtSetGate(0x11, (ulong)isr17, codeSeg, 0x8E); + IdtSetGate(0x12, (ulong)isr18, codeSeg, 0x8E); + IdtSetGate(0x13, (ulong)isr19, codeSeg, 0x8E); + IdtSetGate(0x14, (ulong)isr20, codeSeg, 0x8E); + IdtSetGate(0x15, (ulong)isr21, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(0x16, (ulong)isr22, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(0x17, (ulong)isr23, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(0x18, (ulong)isr24, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(0x19, (ulong)isr25, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(0x1A, (ulong)isr26, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(0x1B, (ulong)isr27, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(0x1C, (ulong)isr28, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(0x1D, (ulong)isr29, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(0x1E, (ulong)isr30, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(0x1F, (ulong)isr31, codeSeg, 0x8E); // INTEL RESERVED // Set IDT IRQs Gates - IdtSetGate(32, (ulong)isr32, codeSeg, 0x8E); - IdtSetGate(33, (ulong)isr33, codeSeg, 0x8E); - IdtSetGate(34, (ulong)isr34, codeSeg, 0x8E); - IdtSetGate(35, (ulong)isr35, codeSeg, 0x8E); - IdtSetGate(36, (ulong)isr36, codeSeg, 0x8E); - IdtSetGate(37, (ulong)isr37, codeSeg, 0x8E); - IdtSetGate(38, (ulong)isr38, codeSeg, 0x8E); - IdtSetGate(39, (ulong)isr39, codeSeg, 0x8E); - IdtSetGate(40, (ulong)isr40, codeSeg, 0x8E); - IdtSetGate(41, (ulong)isr41, codeSeg, 0x8E); - IdtSetGate(42, (ulong)isr42, codeSeg, 0x8E); - IdtSetGate(43, (ulong)isr43, codeSeg, 0x8E); - IdtSetGate(44, (ulong)isr44, codeSeg, 0x8E); - IdtSetGate(45, (ulong)isr45, codeSeg, 0x8E); - IdtSetGate(46, (ulong)isr46, codeSeg, 0x8E); - IdtSetGate(47, (ulong)isr47, codeSeg, 0x8E); + IdtSetGate(0x20, (ulong)isr32, codeSeg, 0x8E); + IdtSetGate(0x21, (ulong)isr33, codeSeg, 0x8E); + IdtSetGate(0x22, (ulong)isr34, codeSeg, 0x8E); + IdtSetGate(0x23, (ulong)isr35, codeSeg, 0x8E); + IdtSetGate(0x24, (ulong)isr36, codeSeg, 0x8E); + IdtSetGate(0x25, (ulong)isr37, codeSeg, 0x8E); + IdtSetGate(0x26, (ulong)isr38, codeSeg, 0x8E); + IdtSetGate(0x27, (ulong)isr39, codeSeg, 0x8E); + IdtSetGate(0x28, (ulong)isr40, codeSeg, 0x8E); + IdtSetGate(0x29, (ulong)isr41, codeSeg, 0x8E); + IdtSetGate(0x2A, (ulong)isr42, codeSeg, 0x8E); + IdtSetGate(0x2B, (ulong)isr43, codeSeg, 0x8E); + IdtSetGate(0x2C, (ulong)isr44, codeSeg, 0x8E); + IdtSetGate(0x2D, (ulong)isr45, codeSeg, 0x8E); + IdtSetGate(0x2E, (ulong)isr46, codeSeg, 0x8E); + IdtSetGate(0x2F, (ulong)isr47, codeSeg, 0x8E); + + //Setup Early Exception handler + for (uchar i = 0 ; i < 0x20 ; i++) { + IdtRegisterIsr(IdtEarlyExceptionHandler, i); + } // Load IDT IdtInit(); @@ -191,19 +206,15 @@ static void EnablePIC(void) // Set ICW1 - begin init of the PIC IoWriteByteOnPort(0x20, 0x11); IoWriteByteOnPort(0xa0, 0x11); - // Set ICW2 (IRQ base offsets) IoWriteByteOnPort(0x21, 0x20); //0x20 is the first free interrupt for IRQ0 IoWriteByteOnPort(0xa1, 0x28); // PIC2 is offseted to 0x28 - // Set ICW3 IoWriteByteOnPort(0x21, 0x4); IoWriteByteOnPort(0xa1, 0x2); - // Set ICW4 IoWriteByteOnPort(0x21, 0x1); IoWriteByteOnPort(0xa1, 0x1); - // Set OCW1 (interrupt masks) IoWriteByteOnPort(0x21, 0xff); IoWriteByteOnPort(0xa1, 0xff); @@ -238,19 +249,14 @@ void IsrHandler(ISRFrame_t *regs) if ((!regs) || (!regs->rip)) KeStartPanic("[ISR ?] Unknown ISR Exception Abort\n"); - if ((regs->intNo >= 21) && (regs->intNo <= 31)) + if ((regs->intNo >= 0x15) && (regs->intNo <= 0x1F)) return; // INTEL RESERVED - if (regs->intNo == 15) + if (regs->intNo == 0x0F) return; // INTEL RESERVED - if (regs->intNo < 32) { - IdtExceptionHandler(regs); - return; - } - - for (int i = 0; i < irqList.n; i++) { - if (regs->intNo == irqList.entry[i].irq) { - irqList.entry[i].isr(regs); + for (int i = 0; i < isrList.n; i++) { + if (regs->intNo == isrList.entry[i].isrNo) { + isrList.entry[i].isr(regs); return; } } @@ -258,33 +264,15 @@ void IsrHandler(ISRFrame_t *regs) bprintf(BStdOut, "[ISR 0x%x] %s\n", regs->intNo, "Unknown ISR Exception"); BStdOut->flusher(BStdOut); IoSendEOItoPIC(regs->intNo); - /* KeStartPanic("[ISR 0x%x] Unknown ISR Exception Abort\n" */ - /* " Error code : 0x%x\n" */ - /* " RIP:\t\t%p\n" */ - /* " CS:\t\t%p\n" */ - /* " RFLAGS:\t%022b\n" */ - /* " RSP:\t\t%p\n" */ - /* " SS:\t\t%p\n", */ - /* regs->intNo, */ - /* regs->ErrorCode, */ - /* regs->rip, */ - /* regs->cs, */ - /* regs->rflags, */ - /* regs->rsp, */ - /* regs->ss */ - /* ); */ } // -// CPU Exception handler +// Early CPU Exception handler // -void IdtExceptionHandler(ISRFrame_t *regs) +void IdtEarlyExceptionHandler(ISRFrame_t *regs) { int recoverable = 0; - char *exceptionMsg = "Unhandled ISR exception"; - - exceptionMsg = IsrExceptions[regs->intNo]; if (!recoverable) { KeStartPanic("[ISR 0x%x] Irrecoverable Kernel %s\n" @@ -295,7 +283,7 @@ void IdtExceptionHandler(ISRFrame_t *regs) " RSP:\t\t%p\n" " SS:\t\t%p\n", regs->intNo, - exceptionMsg, + ExceptionsChar[regs->intNo], regs->ErrorCode, regs->rip, regs->cs, @@ -304,7 +292,7 @@ void IdtExceptionHandler(ISRFrame_t *regs) regs->ss ); } else { - bprintf(BStdOut, "[ISR 0x%x] %s\n", regs->intNo, exceptionMsg); + bprintf(BStdOut, "[ISR 0x%x] %s\n", regs->intNo, ExceptionsChar[regs->intNo]); BStdOut->flusher(BStdOut); } } diff --git a/kaleid/kernel/cpu/isr.asm b/kaleid/kernel/cpu/isr.asm index 58b897c..ebf60f7 100644 --- a/kaleid/kernel/cpu/isr.asm +++ b/kaleid/kernel/cpu/isr.asm @@ -29,6 +29,7 @@ global divideByZero extern idtPtr extern IsrHandler extern label0 +extern KernLog ;; ;; Loads the IDT @@ -40,11 +41,10 @@ IdtInit: ;; ;; Bug test ;; +chain db "Salut", 0x0A, 0 divideByZero: - mov eax, 17 - mov ebx, 0 - xor edx, edx - div ebx + mov rdi, chain + call KernLog ret ;; diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index dcf2687..eec679d 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -87,13 +87,10 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg) IoPrintRtcTime(); - /* KernLog("There was %d ticks\n", IoGetRtcTicks()); */ - /* uint i = 0; */ - /* while (1) { */ - /* if (!(i % (2048*5))) IoPrintRtcTime(); */ - /* KePauseCPU(); */ - /* i++; */ - /* } */ + KernLog("There was %d ticks\n", IoGetRtcTicks()); + + int *var = 7 * GB; + *var = 1; IoDoBeep(); diff --git a/kaleid/kernel/io/keyb.c b/kaleid/kernel/io/keyb.c index 02cc24e..64b3f28 100644 --- a/kaleid/kernel/io/keyb.c +++ b/kaleid/kernel/io/keyb.c @@ -116,7 +116,7 @@ void KeybHandler(ISRFrame_t *regs) void IoEnableKeyb(void) { ulong flags = KePauseIRQs(); - IdtRegisterIrq(KeybHandler, 0x21, 0x8E); + IdtRegisterIsr(KeybHandler, 0x21); char readedInterruptConfig = IoReadByteFromPort(0x21); IoWriteByteOnPort(0x21, 0xFD & readedInterruptConfig); KeRestoreIRQs(flags); diff --git a/kaleid/kernel/io/rtc.c b/kaleid/kernel/io/rtc.c index 1fa5f88..8722206 100644 --- a/kaleid/kernel/io/rtc.c +++ b/kaleid/kernel/io/rtc.c @@ -219,7 +219,7 @@ void IoEnableRtc(void) char readRegister; char readIrqs; - IdtRegisterIrq(RtcHandler, 0x28, 0x8E); + IdtRegisterIsr(RtcHandler, 0x28); // Setting up the register control and interrupt rates DebugLog("[RTC Time] Interrupt frequency set to %d Hz\n",