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
* Exception handler : crashdumps with registers
* 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 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;

View File

@ -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);
//----------------------------------------------------------------------------//

View File

@ -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

View File

@ -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);
}
}

View File

@ -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
;;

View File

@ -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();

View File

@ -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);

View File

@ -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",