From 4f0922e34a02e0b988d45cfbf647b25c735340c7 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Sat, 8 Feb 2020 00:30:09 +0100 Subject: [PATCH] Spurious exception now detected and handled --- kaleid/kernel/ke/idt.c | 49 ++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/kaleid/kernel/ke/idt.c b/kaleid/kernel/ke/idt.c index d67ebb9..9e0460c 100644 --- a/kaleid/kernel/ke/idt.c +++ b/kaleid/kernel/ke/idt.c @@ -32,6 +32,7 @@ IdtEntry_t idt[256] = { 0 }; IdtPtr_t _KeIdtPtr; bool KeIdtIsInitialized = 0; +ulong KeSpuriousCount = 0; static ISRList_t isrList = { 0 }; @@ -73,7 +74,6 @@ static char *ExceptionsChar[32] = { static void EnablePIC(void); static void EarlyExceptionHandler(ISRFrame_t *regs); static void DoubleFaultHandler(ISRFrame_t *regs); -static void SpuriousChkHandler(ISRFrame_t *regs); // // Registers an isr with his IRQ to handle driver interrupts @@ -158,7 +158,7 @@ void KeSetupIDT(void) // Set IDT IRQs Gates KeSetIDTGate(0x20, (ulong)isr32, codeSeg, 0x8E, 0); KeSetIDTGate(0x21, (ulong)isr33, codeSeg, 0x8E, 3); - KeSetIDTGate(0x22, (ulong)isr34, codeSeg, 0x8E, 3); + KeSetIDTGate(0x22, (ulong)isr34, codeSeg, 0x8E, 3); // NEVER RAISED : cascaded KeSetIDTGate(0x23, (ulong)isr35, codeSeg, 0x8E, 3); KeSetIDTGate(0x24, (ulong)isr36, codeSeg, 0x8E, 3); KeSetIDTGate(0x25, (ulong)isr37, codeSeg, 0x8E, 3); @@ -182,7 +182,6 @@ void KeSetupIDT(void) KeRegisterISR(KeBrkDumpRegisters, 0x3); KeRegisterISR(DoubleFaultHandler, 0x8); - KeRegisterISR(SpuriousChkHandler, 0x27); // Load IDT KeLoadIDT(); @@ -219,12 +218,12 @@ static void EnablePIC(void) 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 + 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); + IoWriteByteOnPort(0x21, 0x4); // A slave exists + IoWriteByteOnPort(0xa1, 0x2); // You're a slave // Set ICW4 IoWriteByteOnPort(0x21, 0x1); @@ -254,7 +253,7 @@ void KeMaskIRQ(uchar isr) uchar port; uchar value; - if(isr < 0x8) { + if(isr < 8) { port = 0x21; } else { port = 0xA1; @@ -295,20 +294,40 @@ void KeDisableNMI(void) DebugLog("NMI Interrupts disabled\n"); } + +// +// Get the content of a register of the PIC. Parameter is a ocw3 command : +// - 0x0a : read the IRR +// - 0x0b : read the ISR +// +static inline ushort KeGetIrqRegister(int ocw3) +{ + IoWriteByteOnPort(0x20, ocw3); + IoWriteByteOnPort(0xA0, ocw3); + return ((IoReadByteFromPort(0xA0) << 8) | IoReadByteFromPort(0x20)); // We MUST read the COMMAND PORT +} + + // // The main ISR handler // void _KeHandleISR(ISRFrame_t *regs) { - /* if ((!regs) || (!regs->rip)) */ - /* KeStartPanic("[ISR ?] Unknown ISR Exception Abort\n"); */ - if ((regs->intNo >= 0x15) && (regs->intNo <= 0x1D)) return; // INTEL RESERVED if ((regs->intNo == 0x0F) || (regs->intNo == 0x1F)) return; // INTEL RESERVED + if (!(KeGetIrqRegister(0x0b) & (1<<(regs->intNo - 0x20)))) { + bprintf(BStdDbg, "[%d]\tISR 0x%x SPURIOUS\n", + KeGetTicks(), + regs->intNo + ); + KeSpuriousCount++; + return; + } + for (int i = 0; i < isrList.n; i++) { if (regs->intNo == isrList.entry[i].isrNo) { isrList.entry[i].isr(regs); @@ -345,14 +364,6 @@ static void EarlyExceptionHandler(ISRFrame_t *regs) KeHaltCPU(); } -// -// Spurious interruption check -// -void SpuriousChkHandler(ISRFrame_t *regs) -{ - // XXX; -} - // // Double Fault handling and stack overflow detection //