IDT enhancing
This commit is contained in:
commit
fbccfab642
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
;;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue