Spurious exception now detected and handled

This commit is contained in:
Adrien Bourmault 2020-02-08 00:30:09 +01:00
parent ffc6874d2b
commit 4f0922e34a
1 changed files with 30 additions and 19 deletions

View File

@ -32,6 +32,7 @@
IdtEntry_t idt[256] = { 0 }; IdtEntry_t idt[256] = { 0 };
IdtPtr_t _KeIdtPtr; IdtPtr_t _KeIdtPtr;
bool KeIdtIsInitialized = 0; bool KeIdtIsInitialized = 0;
ulong KeSpuriousCount = 0;
static ISRList_t isrList = { 0 }; static ISRList_t isrList = { 0 };
@ -73,7 +74,6 @@ static char *ExceptionsChar[32] = {
static void EnablePIC(void); static void EnablePIC(void);
static void EarlyExceptionHandler(ISRFrame_t *regs); static void EarlyExceptionHandler(ISRFrame_t *regs);
static void DoubleFaultHandler(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 // Registers an isr with his IRQ to handle driver interrupts
@ -158,7 +158,7 @@ void KeSetupIDT(void)
// Set IDT IRQs Gates // Set IDT IRQs Gates
KeSetIDTGate(0x20, (ulong)isr32, codeSeg, 0x8E, 0); KeSetIDTGate(0x20, (ulong)isr32, codeSeg, 0x8E, 0);
KeSetIDTGate(0x21, (ulong)isr33, codeSeg, 0x8E, 3); 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(0x23, (ulong)isr35, codeSeg, 0x8E, 3);
KeSetIDTGate(0x24, (ulong)isr36, codeSeg, 0x8E, 3); KeSetIDTGate(0x24, (ulong)isr36, codeSeg, 0x8E, 3);
KeSetIDTGate(0x25, (ulong)isr37, codeSeg, 0x8E, 3); KeSetIDTGate(0x25, (ulong)isr37, codeSeg, 0x8E, 3);
@ -182,7 +182,6 @@ void KeSetupIDT(void)
KeRegisterISR(KeBrkDumpRegisters, 0x3); KeRegisterISR(KeBrkDumpRegisters, 0x3);
KeRegisterISR(DoubleFaultHandler, 0x8); KeRegisterISR(DoubleFaultHandler, 0x8);
KeRegisterISR(SpuriousChkHandler, 0x27);
// Load IDT // Load IDT
KeLoadIDT(); KeLoadIDT();
@ -223,8 +222,8 @@ static void EnablePIC(void)
IoWriteByteOnPort(0xa1, 0x28); // PIC2 is offseted to 0x28 IoWriteByteOnPort(0xa1, 0x28); // PIC2 is offseted to 0x28
// Set ICW3 // Set ICW3
IoWriteByteOnPort(0x21, 0x4); IoWriteByteOnPort(0x21, 0x4); // A slave exists
IoWriteByteOnPort(0xa1, 0x2); IoWriteByteOnPort(0xa1, 0x2); // You're a slave
// Set ICW4 // Set ICW4
IoWriteByteOnPort(0x21, 0x1); IoWriteByteOnPort(0x21, 0x1);
@ -254,7 +253,7 @@ void KeMaskIRQ(uchar isr)
uchar port; uchar port;
uchar value; uchar value;
if(isr < 0x8) { if(isr < 8) {
port = 0x21; port = 0x21;
} else { } else {
port = 0xA1; port = 0xA1;
@ -295,20 +294,40 @@ void KeDisableNMI(void)
DebugLog("NMI Interrupts disabled\n"); 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 // The main ISR handler
// //
void _KeHandleISR(ISRFrame_t *regs) void _KeHandleISR(ISRFrame_t *regs)
{ {
/* if ((!regs) || (!regs->rip)) */
/* KeStartPanic("[ISR ?] Unknown ISR Exception Abort\n"); */
if ((regs->intNo >= 0x15) && (regs->intNo <= 0x1D)) if ((regs->intNo >= 0x15) && (regs->intNo <= 0x1D))
return; // INTEL RESERVED return; // INTEL RESERVED
if ((regs->intNo == 0x0F) || (regs->intNo == 0x1F)) if ((regs->intNo == 0x0F) || (regs->intNo == 0x1F))
return; // INTEL RESERVED 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++) { for (int i = 0; i < isrList.n; i++) {
if (regs->intNo == isrList.entry[i].isrNo) { if (regs->intNo == isrList.entry[i].isrNo) {
isrList.entry[i].isr(regs); isrList.entry[i].isr(regs);
@ -345,14 +364,6 @@ static void EarlyExceptionHandler(ISRFrame_t *regs)
KeHaltCPU(); KeHaltCPU();
} }
//
// Spurious interruption check
//
void SpuriousChkHandler(ISRFrame_t *regs)
{
// XXX;
}
// //
// Double Fault handling and stack overflow detection // Double Fault handling and stack overflow detection
// //