IDT enhancing

This commit is contained in:
Adrien Bourmault 2019-05-06 22:50:03 +02:00
commit fbccfab642
9 changed files with 107 additions and 117 deletions

View File

@ -74,3 +74,8 @@ IDT Overhaul
* IDT : can now register new IRQ handlers at runtime * IDT : can now register new IRQ handlers at runtime
* Exception handler : crashdumps with registers * Exception handler : crashdumps with registers
* RTC time based ticks : functionnal * RTC time based ticks : functionnal
2019-05-6 @os-k-team <os-k-team@os-k.eu>
IDT Overhaul
* IDT : can now register new IRQ and Exception handlers at runtime
* Exception handler : now called early

View File

@ -50,7 +50,7 @@ typedef enum ProcState_t ProcState_t;
typedef struct IdtDescriptor_t IdtDescriptor_t; typedef struct IdtDescriptor_t IdtDescriptor_t;
typedef struct IdtEntry_t IdtEntry_t; typedef struct IdtEntry_t IdtEntry_t;
typedef struct IdtPtr_t IdtPtr_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 ISRFrame_t ISRFrame_t;
typedef struct MemoryMap_t MemoryMap_t; typedef struct MemoryMap_t MemoryMap_t;

View File

@ -54,15 +54,15 @@ struct IdtPtr_t
void *base; void *base;
} __attribute__((packed)); } __attribute__((packed));
struct IRQList_t struct ISRList_t
{ {
uchar n; //number of entries in the list uchar n; //number of entries in the list
struct entry { struct entry {
void (*isr)(ISRFrame_t *regs); void (*isr)(ISRFrame_t *regs);
uchar irq; uchar isrNo;
uchar flags; uchar flags;
} entry[224]; } entry[255];
}; };
typedef struct typedef struct
@ -78,9 +78,9 @@ void IdtInit(void);
void IdtSetup(void); void IdtSetup(void);
void IoSendEOItoPIC(uchar isr); 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 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);
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//

View File

@ -64,7 +64,7 @@ static inline ulong KePauseIRQs(void) {
extern void IoSendEOItoPIC(uchar isr); extern void IoSendEOItoPIC(uchar isr);
extern void IoEnableNMI(void); extern void IoEnableNMI(void);
extern void IoDisableNMI(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 // Restore IRQ flag to its state before KePauseIRQs

View File

@ -31,9 +31,9 @@
IdtEntry_t idt[256] = { 0 }; IdtEntry_t idt[256] = { 0 };
IdtPtr_t idtPtr; IdtPtr_t idtPtr;
IRQList_t irqList = { 0 }; ISRList_t isrList = { 0 };
char *IsrExceptions[32] = { char *ExceptionsChar[32] = {
"Divide Error Fault", "Divide Error Fault",
"Debug Exception Trap", "Debug Exception Trap",
"Non-maskable Interrupt", "Non-maskable Interrupt",
@ -75,22 +75,32 @@ static void EnablePIC(void);
// //
// Registers an isr with his IRQ to handle driver interrupts // 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 KalAssert(idt[0].flags!=0); // IDT initialized
if ((n == 224)) // IRQs not filled if (n == 0) goto settingUp;
KeStartPanic("[IdtRegisterIrq] Cannot register IRQ %c function %p !",
irq,
isr
);
irqList.entry[n].isr = isr; for (int i = 0; i < n; i++) {
irqList.entry[n].irq = irq; if (isrNo == isrList.entry[i].isrNo) {
irqList.entry[n].flags = flags; n = i;
irqList.n++; 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; idtPtr.base = &idt;
// Set IDT Exception Gates // Set IDT Exception Gates
IdtSetGate(0, (ulong)isr0, codeSeg, 0x8E); IdtSetGate(0x00, (ulong)isr0, codeSeg, 0x8E);
IdtSetGate(1, (ulong)isr1, codeSeg, 0x8E); IdtSetGate(0x01, (ulong)isr1, codeSeg, 0x8E);
IdtSetGate(2, (ulong)isr2, codeSeg, 0x8E); IdtSetGate(0x02, (ulong)isr2, codeSeg, 0x8E);
IdtSetGate(3, (ulong)isr3, codeSeg, 0x8E); IdtSetGate(0x03, (ulong)isr3, codeSeg, 0x8E);
IdtSetGate(4, (ulong)isr4, codeSeg, 0x8E); IdtSetGate(0x04, (ulong)isr4, codeSeg, 0x8E);
IdtSetGate(5, (ulong)isr5, codeSeg, 0x8E); IdtSetGate(0x05, (ulong)isr5, codeSeg, 0x8E);
IdtSetGate(6, (ulong)isr6, codeSeg, 0x8E); IdtSetGate(0x06, (ulong)isr6, codeSeg, 0x8E);
IdtSetGate(7, (ulong)isr7, codeSeg, 0x8E); IdtSetGate(0x07, (ulong)isr7, codeSeg, 0x8E);
IdtSetGate(8, (ulong)isr8, codeSeg, 0x8E); IdtSetGate(0x08, (ulong)isr8, codeSeg, 0x8E);
IdtSetGate(9, (ulong)isr9, codeSeg, 0x8E); IdtSetGate(0x09, (ulong)isr9, codeSeg, 0x8E);
IdtSetGate(10, (ulong)isr10, codeSeg, 0x8E); IdtSetGate(0x0A, (ulong)isr10, codeSeg, 0x8E);
IdtSetGate(11, (ulong)isr11, codeSeg, 0x8E); IdtSetGate(0x0B, (ulong)isr11, codeSeg, 0x8E);
IdtSetGate(12, (ulong)isr12, codeSeg, 0x8E); IdtSetGate(0x0C, (ulong)isr12, codeSeg, 0x8E);
IdtSetGate(13, (ulong)isr13, codeSeg, 0x8E); IdtSetGate(0x0D, (ulong)isr13, codeSeg, 0x8E);
IdtSetGate(14, (ulong)isr14, codeSeg, 0x8E); IdtSetGate(0x0E, (ulong)isr14, codeSeg, 0x8E);
IdtSetGate(15, (ulong)isr15, codeSeg, 0x8E); // INTEL RESERVED IdtSetGate(0x0F, (ulong)isr15, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(16, (ulong)isr16, codeSeg, 0x8E); IdtSetGate(0x10, (ulong)isr16, codeSeg, 0x8E);
IdtSetGate(17, (ulong)isr17, codeSeg, 0x8E); IdtSetGate(0x11, (ulong)isr17, codeSeg, 0x8E);
IdtSetGate(18, (ulong)isr18, codeSeg, 0x8E); IdtSetGate(0x12, (ulong)isr18, codeSeg, 0x8E);
IdtSetGate(19, (ulong)isr19, codeSeg, 0x8E); IdtSetGate(0x13, (ulong)isr19, codeSeg, 0x8E);
IdtSetGate(20, (ulong)isr20, codeSeg, 0x8E); IdtSetGate(0x14, (ulong)isr20, codeSeg, 0x8E);
IdtSetGate(21, (ulong)isr21, codeSeg, 0x8E); // INTEL RESERVED IdtSetGate(0x15, (ulong)isr21, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(22, (ulong)isr22, codeSeg, 0x8E); // INTEL RESERVED IdtSetGate(0x16, (ulong)isr22, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(23, (ulong)isr23, codeSeg, 0x8E); // INTEL RESERVED IdtSetGate(0x17, (ulong)isr23, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(24, (ulong)isr24, codeSeg, 0x8E); // INTEL RESERVED IdtSetGate(0x18, (ulong)isr24, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(25, (ulong)isr25, codeSeg, 0x8E); // INTEL RESERVED IdtSetGate(0x19, (ulong)isr25, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(26, (ulong)isr26, codeSeg, 0x8E); // INTEL RESERVED IdtSetGate(0x1A, (ulong)isr26, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(27, (ulong)isr27, codeSeg, 0x8E); // INTEL RESERVED IdtSetGate(0x1B, (ulong)isr27, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(28, (ulong)isr28, codeSeg, 0x8E); // INTEL RESERVED IdtSetGate(0x1C, (ulong)isr28, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(29, (ulong)isr29, codeSeg, 0x8E); // INTEL RESERVED IdtSetGate(0x1D, (ulong)isr29, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(30, (ulong)isr30, codeSeg, 0x8E); // INTEL RESERVED IdtSetGate(0x1E, (ulong)isr30, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(31, (ulong)isr31, codeSeg, 0x8E); // INTEL RESERVED IdtSetGate(0x1F, (ulong)isr31, codeSeg, 0x8E); // INTEL RESERVED
// Set IDT IRQs Gates // Set IDT IRQs Gates
IdtSetGate(32, (ulong)isr32, codeSeg, 0x8E); IdtSetGate(0x20, (ulong)isr32, codeSeg, 0x8E);
IdtSetGate(33, (ulong)isr33, codeSeg, 0x8E); IdtSetGate(0x21, (ulong)isr33, codeSeg, 0x8E);
IdtSetGate(34, (ulong)isr34, codeSeg, 0x8E); IdtSetGate(0x22, (ulong)isr34, codeSeg, 0x8E);
IdtSetGate(35, (ulong)isr35, codeSeg, 0x8E); IdtSetGate(0x23, (ulong)isr35, codeSeg, 0x8E);
IdtSetGate(36, (ulong)isr36, codeSeg, 0x8E); IdtSetGate(0x24, (ulong)isr36, codeSeg, 0x8E);
IdtSetGate(37, (ulong)isr37, codeSeg, 0x8E); IdtSetGate(0x25, (ulong)isr37, codeSeg, 0x8E);
IdtSetGate(38, (ulong)isr38, codeSeg, 0x8E); IdtSetGate(0x26, (ulong)isr38, codeSeg, 0x8E);
IdtSetGate(39, (ulong)isr39, codeSeg, 0x8E); IdtSetGate(0x27, (ulong)isr39, codeSeg, 0x8E);
IdtSetGate(40, (ulong)isr40, codeSeg, 0x8E); IdtSetGate(0x28, (ulong)isr40, codeSeg, 0x8E);
IdtSetGate(41, (ulong)isr41, codeSeg, 0x8E); IdtSetGate(0x29, (ulong)isr41, codeSeg, 0x8E);
IdtSetGate(42, (ulong)isr42, codeSeg, 0x8E); IdtSetGate(0x2A, (ulong)isr42, codeSeg, 0x8E);
IdtSetGate(43, (ulong)isr43, codeSeg, 0x8E); IdtSetGate(0x2B, (ulong)isr43, codeSeg, 0x8E);
IdtSetGate(44, (ulong)isr44, codeSeg, 0x8E); IdtSetGate(0x2C, (ulong)isr44, codeSeg, 0x8E);
IdtSetGate(45, (ulong)isr45, codeSeg, 0x8E); IdtSetGate(0x2D, (ulong)isr45, codeSeg, 0x8E);
IdtSetGate(46, (ulong)isr46, codeSeg, 0x8E); IdtSetGate(0x2E, (ulong)isr46, codeSeg, 0x8E);
IdtSetGate(47, (ulong)isr47, codeSeg, 0x8E); IdtSetGate(0x2F, (ulong)isr47, codeSeg, 0x8E);
//Setup Early Exception handler
for (uchar i = 0 ; i < 0x20 ; i++) {
IdtRegisterIsr(IdtEarlyExceptionHandler, i);
}
// Load IDT // Load IDT
IdtInit(); IdtInit();
@ -191,19 +206,15 @@ static void EnablePIC(void)
// Set ICW1 - begin init of the PIC // Set ICW1 - begin init of the PIC
IoWriteByteOnPort(0x20, 0x11); IoWriteByteOnPort(0x20, 0x11);
IoWriteByteOnPort(0xa0, 0x11); IoWriteByteOnPort(0xa0, 0x11);
// Set ICW2 (IRQ base offsets) // Set ICW2 (IRQ base offsets)
IoWriteByteOnPort(0x21, 0x20); //0x20 is the first free interrupt for IRQ0 IoWriteByteOnPort(0x21, 0x20); //0x20 is the first free interrupt for IRQ0
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);
IoWriteByteOnPort(0xa1, 0x2); IoWriteByteOnPort(0xa1, 0x2);
// Set ICW4 // Set ICW4
IoWriteByteOnPort(0x21, 0x1); IoWriteByteOnPort(0x21, 0x1);
IoWriteByteOnPort(0xa1, 0x1); IoWriteByteOnPort(0xa1, 0x1);
// Set OCW1 (interrupt masks) // Set OCW1 (interrupt masks)
IoWriteByteOnPort(0x21, 0xff); IoWriteByteOnPort(0x21, 0xff);
IoWriteByteOnPort(0xa1, 0xff); IoWriteByteOnPort(0xa1, 0xff);
@ -238,19 +249,14 @@ void IsrHandler(ISRFrame_t *regs)
if ((!regs) || (!regs->rip)) if ((!regs) || (!regs->rip))
KeStartPanic("[ISR ?] Unknown ISR Exception Abort\n"); KeStartPanic("[ISR ?] Unknown ISR Exception Abort\n");
if ((regs->intNo >= 21) && (regs->intNo <= 31)) if ((regs->intNo >= 0x15) && (regs->intNo <= 0x1F))
return; // INTEL RESERVED return; // INTEL RESERVED
if (regs->intNo == 15) if (regs->intNo == 0x0F)
return; // INTEL RESERVED return; // INTEL RESERVED
if (regs->intNo < 32) { for (int i = 0; i < isrList.n; i++) {
IdtExceptionHandler(regs); if (regs->intNo == isrList.entry[i].isrNo) {
return; isrList.entry[i].isr(regs);
}
for (int i = 0; i < irqList.n; i++) {
if (regs->intNo == irqList.entry[i].irq) {
irqList.entry[i].isr(regs);
return; return;
} }
} }
@ -258,33 +264,15 @@ void IsrHandler(ISRFrame_t *regs)
bprintf(BStdOut, "[ISR 0x%x] %s\n", regs->intNo, "Unknown ISR Exception"); bprintf(BStdOut, "[ISR 0x%x] %s\n", regs->intNo, "Unknown ISR Exception");
BStdOut->flusher(BStdOut); BStdOut->flusher(BStdOut);
IoSendEOItoPIC(regs->intNo); 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; int recoverable = 0;
char *exceptionMsg = "Unhandled ISR exception";
exceptionMsg = IsrExceptions[regs->intNo];
if (!recoverable) { if (!recoverable) {
KeStartPanic("[ISR 0x%x] Irrecoverable Kernel %s\n" KeStartPanic("[ISR 0x%x] Irrecoverable Kernel %s\n"
@ -295,7 +283,7 @@ void IdtExceptionHandler(ISRFrame_t *regs)
" RSP:\t\t%p\n" " RSP:\t\t%p\n"
" SS:\t\t%p\n", " SS:\t\t%p\n",
regs->intNo, regs->intNo,
exceptionMsg, ExceptionsChar[regs->intNo],
regs->ErrorCode, regs->ErrorCode,
regs->rip, regs->rip,
regs->cs, regs->cs,
@ -304,7 +292,7 @@ void IdtExceptionHandler(ISRFrame_t *regs)
regs->ss regs->ss
); );
} else { } 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); BStdOut->flusher(BStdOut);
} }
} }

View File

@ -29,6 +29,7 @@ global divideByZero
extern idtPtr extern idtPtr
extern IsrHandler extern IsrHandler
extern label0 extern label0
extern KernLog
;; ;;
;; Loads the IDT ;; Loads the IDT
@ -40,11 +41,10 @@ IdtInit:
;; ;;
;; Bug test ;; Bug test
;; ;;
chain db "Salut", 0x0A, 0
divideByZero: divideByZero:
mov eax, 17 mov rdi, chain
mov ebx, 0 call KernLog
xor edx, edx
div ebx
ret ret
;; ;;

View File

@ -87,13 +87,10 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg)
IoPrintRtcTime(); IoPrintRtcTime();
/* KernLog("There was %d ticks\n", IoGetRtcTicks()); */ KernLog("There was %d ticks\n", IoGetRtcTicks());
/* uint i = 0; */
/* while (1) { */ int *var = 7 * GB;
/* if (!(i % (2048*5))) IoPrintRtcTime(); */ *var = 1;
/* KePauseCPU(); */
/* i++; */
/* } */
IoDoBeep(); IoDoBeep();

View File

@ -116,7 +116,7 @@ void KeybHandler(ISRFrame_t *regs)
void IoEnableKeyb(void) void IoEnableKeyb(void)
{ {
ulong flags = KePauseIRQs(); ulong flags = KePauseIRQs();
IdtRegisterIrq(KeybHandler, 0x21, 0x8E); IdtRegisterIsr(KeybHandler, 0x21);
char readedInterruptConfig = IoReadByteFromPort(0x21); char readedInterruptConfig = IoReadByteFromPort(0x21);
IoWriteByteOnPort(0x21, 0xFD & readedInterruptConfig); IoWriteByteOnPort(0x21, 0xFD & readedInterruptConfig);
KeRestoreIRQs(flags); KeRestoreIRQs(flags);

View File

@ -219,7 +219,7 @@ void IoEnableRtc(void)
char readRegister; char readRegister;
char readIrqs; char readIrqs;
IdtRegisterIrq(RtcHandler, 0x28, 0x8E); IdtRegisterIsr(RtcHandler, 0x28);
// Setting up the register control and interrupt rates // Setting up the register control and interrupt rates
DebugLog("[RTC Time] Interrupt frequency set to %d Hz\n", DebugLog("[RTC Time] Interrupt frequency set to %d Hz\n",