From e7d56a85506947aa67391c0a5156ab409a07a284 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Sat, 27 Apr 2019 00:04:27 +0200 Subject: [PATCH] IDT is now really ready --- Makefile | 18 -------- include/kernel/base.h | 20 ++++++++- include/kernel/idt.h | 53 +++++++++++++--------- include/kernel/iomisc.h | 2 +- kaleid/kernel/cpu/idt.c | 95 +++++++++++++++++++++++++++++++-------- kaleid/kernel/cpu/isr.asm | 18 +++++--- kaleid/kernel/init/init.c | 8 ++-- kaleid/kernel/io/keyb.asm | 68 ---------------------------- kaleid/kernel/io/keyb.c | 29 +++++------- kaleid/kernel/io/rtc.asm | 68 ---------------------------- kaleid/kernel/io/rtc.c | 86 +++++++++++++++++------------------ 11 files changed, 196 insertions(+), 269 deletions(-) delete mode 100644 kaleid/kernel/io/keyb.asm delete mode 100644 kaleid/kernel/io/rtc.asm diff --git a/Makefile b/Makefile index ca027a2..77a0081 100644 --- a/Makefile +++ b/Makefile @@ -148,24 +148,6 @@ $(KOBJDIR)/kernel/cpu/idt.o: $(KALEIDDIR)/kernel/cpu/idt.c \ @rm -f $@.1 $@.2 @echo ${CL2}[$@] ${CL}Compiled.${CL3} -$(KOBJDIR)/kernel/io/keyb.o: $(KALEIDDIR)/kernel/io/keyb.c \ - $(KALEIDDIR)/kernel/io/keyb.asm $(INCLUDEDIR)/*/*.h | $(KOBJDIR) - @mkdir -p $(shell dirname $@) - @$(ASM) $(ASMFLAGS) $(KALEIDDIR)/kernel/io/keyb.asm -o $@.1 - @$(KCC) $< -o $@.2 - @$(LD) $(LDFLAGS) -r $@.1 $@.2 -o $@ - @rm -f $@.1 $@.2 - @echo ${CL2}[$@] ${CL}Compiled.${CL3} - -$(KOBJDIR)/kernel/io/rtc.o: $(KALEIDDIR)/kernel/io/rtc.c \ - $(KALEIDDIR)/kernel/io/rtc.asm $(INCLUDEDIR)/*/*.h | $(KOBJDIR) - @mkdir -p $(shell dirname $@) - @$(ASM) $(ASMFLAGS) $(KALEIDDIR)/kernel/io/rtc.asm -o $@.1 - @$(KCC) $< -o $@.2 - @$(LD) $(LDFLAGS) -r $@.1 $@.2 -o $@ - @rm -f $@.1 $@.2 - @echo ${CL2}[$@] ${CL}Compiled.${CL3} - ## MAIN MAKEFILE ------------------------------------------------------------- # $(KOBJDIR)/%.o: %.c $(INCLUDEDIR)/*/*.h | $(KOBJDIR) diff --git a/include/kernel/base.h b/include/kernel/base.h index 2fbec68..4778a54 100644 --- a/include/kernel/base.h +++ b/include/kernel/base.h @@ -43,8 +43,7 @@ typedef struct BootInfo_t BootInfo_t; typedef struct ListHead_t ListHead_t; typedef struct ListNode_t ListNode_t; typedef struct Processor_t Processor_t; -typedef struct IRQList_t IRQList_t; - +typedef struct ISRFrame_t ISRFrame_t; typedef enum ProcState_t ProcState_t; //------------------------------------------// @@ -89,6 +88,23 @@ struct Processor_t ListHead_t *timeCritProcs; }; +struct ISRFrame_t { +/* the register file */ + ulong regs[15]; + + /* the error code and interrupt id */ + ulong intNo; + ulong ErrorCode; + + /* these are pushed automatically by the CPU */ + ulong rip; + ulong cs; + ulong rflags; + ulong rsp; + ulong ss; +} __attribute__((__packed__)); + + //------------------------------------------// #ifndef NCPUS diff --git a/include/kernel/idt.h b/include/kernel/idt.h index 7b00530..d59e31c 100644 --- a/include/kernel/idt.h +++ b/include/kernel/idt.h @@ -13,7 +13,7 @@ typedef struct ISRFrame_t ISRFrame_t; // -------------------------------------------------------------------------- // -#define interrupt(n) asm volatile ("int %0" : : "N" (n) : "cc", "memory") \ +#define interrupt(n) asm volatile ("int %0" : : "N" (n) : "cc", "memory") // -------------------------------------------------------------------------- // @@ -44,28 +44,12 @@ struct IRQList_t uchar n; //number of entries in the list struct entry { - void (*isr)(void); + void (*isr)(ISRFrame_t *regs); uchar irq; uchar flags; } entry[224]; }; -struct ISRFrame_t { -/* the register file */ - uint64_t regs[15]; - - /* the error code and interrupt id */ - uint64_t id; - uint64_t error; - - /* these are pushed automatically by the CPU */ - uint64_t rip; - uint64_t cs; - uint64_t rflags; - uint64_t rsp; - uint64_t ss; -} __attribute__((__packed__)); - typedef struct { @@ -108,10 +92,10 @@ static char *IsrExceptions[32] = { // -------------------------------------------------------------------------- // -void IdtRegisterIrq(void (*isr)(void), uchar irq, uchar flags); +void IdtRegisterIrq(void (*isr)(ISRFrame_t *regs), uchar irq, uchar flags); void IdtSetup(void); void IdtSetGate(uchar rank, ulong base, ushort selector, uchar flags); -//void IdtHandler(ulong intNo); +void IdtExceptionHandler(ISRFrame_t *regs); static void EnablePIC(void); void SendEOItoPIC(uchar isr); @@ -148,5 +132,34 @@ extern void isr28(); extern void isr29(); extern void isr30(); extern void isr31(); +extern void isr32(); +extern void isr33(); +extern void isr34(); +extern void isr35(); +extern void isr36(); +extern void isr37(); +extern void isr38(); +extern void isr39(); +extern void isr40(); +extern void isr41(); +extern void isr42(); +extern void isr43(); +extern void isr44(); +extern void isr45(); +extern void isr46(); +extern void isr47(); +extern void isr48(); +extern void isr49(); +extern void isr50(); +extern void isr51(); +extern void isr52(); +extern void isr53(); +extern void isr54(); +extern void isr55(); +extern void isr56(); +extern void isr57(); +extern void isr58(); +extern void isr59(); +extern void isr60(); #endif diff --git a/include/kernel/iomisc.h b/include/kernel/iomisc.h index 5c9da8e..3bb9f64 100644 --- a/include/kernel/iomisc.h +++ b/include/kernel/iomisc.h @@ -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)(void), uchar irq, uchar flags); +extern void IdtRegisterIrq(void (*isr)(ISRFrame_t *regs), uchar irq, uchar flags); // // Restore IRQ flag to its state before KePauseIRQs diff --git a/kaleid/kernel/cpu/idt.c b/kaleid/kernel/cpu/idt.c index 6f083dd..6264dfa 100644 --- a/kaleid/kernel/cpu/idt.c +++ b/kaleid/kernel/cpu/idt.c @@ -37,11 +37,11 @@ IRQList_t irqList = { 0 }; // // Registers an isr with his IRQ to handle driver interrupts // -void IdtRegisterIrq(void (*isr)(void), uchar irq, uchar flags) +void IdtRegisterIrq(void (*isr)(ISRFrame_t *regs), uchar irq, uchar flags) { uchar n = irqList.n; - KalAssert(idt[0].flags==0); // IDT uninitialized + KalAssert(idt[0].flags!=0); // IDT initialized if ((n == 224)) // IRQs not filled KeStartPanic("[IdtRegisterIrq] Cannot register IRQ %c function %p !", @@ -103,15 +103,36 @@ void IdtSetup(void) IdtSetGate(30, (ulong)isr30, codeSeg, 0x8E); // INTEL RESERVED IdtSetGate(31, (ulong)isr31, codeSeg, 0x8E); // INTEL RESERVED - // Set the IRQ Driver Gates - for (int i = 0 ; i < irqList.n ; i++) { - IdtSetGate( - irqList.entry[i].irq, - (ulong)irqList.entry[i].isr, - codeSeg, - irqList.entry[i].flags - ); - } + // 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(48, (ulong)isr48, codeSeg, 0x8E); + IdtSetGate(49, (ulong)isr49, codeSeg, 0x8E); + IdtSetGate(50, (ulong)isr50, codeSeg, 0x8E); + IdtSetGate(51, (ulong)isr51, codeSeg, 0x8E); + IdtSetGate(52, (ulong)isr52, codeSeg, 0x8E); + IdtSetGate(53, (ulong)isr53, codeSeg, 0x8E); + IdtSetGate(54, (ulong)isr54, codeSeg, 0x8E); + IdtSetGate(55, (ulong)isr55, codeSeg, 0x8E); + IdtSetGate(56, (ulong)isr56, codeSeg, 0x8E); + IdtSetGate(57, (ulong)isr57, codeSeg, 0x8E); + IdtSetGate(58, (ulong)isr58, codeSeg, 0x8E); + IdtSetGate(59, (ulong)isr59, codeSeg, 0x8E); + IdtSetGate(60, (ulong)isr60, codeSeg, 0x8E); // Load IDT IdtInit(); @@ -185,21 +206,57 @@ void IoDisableNMI(void) } // -// The main exception handler +// The main ISR handler // -void IdtHandler(ulong intNo) +void IsrHandler(ISRFrame_t *regs) +{ + if ((!regs) || (!regs->rip)) + KeStartPanic("[ISR ?] Unknown ISR Exception Abort\n"); + + 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); + return; + } + } + + KeStartPanic("[ISR 0x%x] Unknown ISR Exception Abort\n", regs->intNo); +} + + +// +// CPU Exception handler +// +void IdtExceptionHandler(ISRFrame_t *regs) { int recoverable = 0; char *exceptionMsg = "Unhandled ISR exception"; - if (intNo >= 32) recoverable++; - - if (intNo < 32) exceptionMsg = IsrExceptions[intNo]; + exceptionMsg = IsrExceptions[regs->intNo]; if (!recoverable) { - KeStartPanic("[ISR 0x%x] Irrecoverable %s\n", intNo, exceptionMsg); + KeStartPanic("[ISR 0x%x] Irrecoverable Kernel %s\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, + exceptionMsg, + regs->ErrorCode, + regs->rip, + regs->cs, + regs->rflags, + regs->rsp, + regs->ss + ); } else { - bprintf(BStdOut, "[ISR 0x%x] %s\n", intNo, exceptionMsg); - //IoSendEOItoPIC(intNo); + bprintf(BStdOut, "[ISR 0x%x] %s\n", regs->intNo, exceptionMsg); } } diff --git a/kaleid/kernel/cpu/isr.asm b/kaleid/kernel/cpu/isr.asm index 59247f9..58b897c 100644 --- a/kaleid/kernel/cpu/isr.asm +++ b/kaleid/kernel/cpu/isr.asm @@ -27,7 +27,7 @@ global IdtInit global divideByZero extern idtPtr -extern IdtHandler +extern IsrHandler extern label0 ;; @@ -41,16 +41,14 @@ IdtInit: ;; Bug test ;; divideByZero: - pushAll mov eax, 17 mov ebx, 0 xor edx, edx div ebx - popAll ret ;; -;; ISR handler +;; ISR Exception pre-handler ;; isrPreHandler: pushAll @@ -71,7 +69,7 @@ isrPreHandler: mov rdi, rsp ; First argument points to the processor state mov rbp, 0 ; Terminate stack traces here - call IdtHandler + call IsrHandler ; decrement mask count dec qword [gs:8] @@ -81,7 +79,7 @@ isrPreHandler: and rax, 0x3000 jz .SExit - swapgs + swapgs ; XXX need TSS .SExit: popAll @@ -164,3 +162,11 @@ IsrWithoutErrCode 29 IsrWithoutErrCode 30 IsrWithoutErrCode 31 + +;; IRQs +%assign i 32 +%rep 225 + IsrWithoutErrCode i +%assign i i+1 +%endrep + diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index 706f03d..90da5e4 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -38,7 +38,6 @@ extern void BtInitBootInfo(multiboot_info_t *mbi, void *codeSeg); extern error_t IoInitVGABuffer(void); //io/keyb.c -extern void IoSetupKeyb(void); extern void IoEnableKeyb(void); // cpu/idt.c @@ -82,9 +81,6 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg) MmInitHeap(); PsInitSched(); - // Drivers ISR inits - IoSetupRtc(); - IoSetupKeyb(); // Interrupts launching IdtSetup(); KeEnableIRQs(); @@ -95,12 +91,14 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg) IoPrintRtcTime(); KernLog("There was %d ticks\n", IoGetRtcTicks()); - for (uint i = 1; i < 20000 ; i++) { + for (uint i = 1; i < 2 ; i++) { while (IoGetRtcTicks() < i * 10000) { } IoPrintRtcTime(); } + divideByZero(); + KernLog("Goodbye after %d ticks\n", IoGetRtcTicks()); // End this machine's suffering BFlushBuf(BStdOut); diff --git a/kaleid/kernel/io/keyb.asm b/kaleid/kernel/io/keyb.asm deleted file mode 100644 index 5872003..0000000 --- a/kaleid/kernel/io/keyb.asm +++ /dev/null @@ -1,68 +0,0 @@ -;=----------------------------------------------------------------------------=; -; GNU GPL OS/K ; -; ; -; Desc: Basic Read Only Keyboard Driver ; -; (x86_64 architecture only) ; -; ; -; ; -; Copyright © 2018-2019 The OS/K Team ; -; ; -; This file is part of OS/K. ; -; ; -; OS/K is free software: you can redistribute it and/or modify ; -; it under the terms of the GNU General Public License as published by ; -; the Free Software Foundation, either version 3 of the License, or ; -; (at your option) any later version. ; -; ; -; OS/K is distributed in the hope that it will be useful, ; -; but WITHOUT ANY WARRANTY; without even the implied warranty of ; -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; -; GNU General Public License for more details. ; -; ; -; You should have received a copy of the GNU General Public License ; -; along with OS/K. If not, see . ; -;=----------------------------------------------------------------------------=; - -[BITS 64] - -global KeybIsr -extern KeybHandler - -%macro pushAll 0 - push rax - push rcx - push rdx - push rbx - push rbp - push rsi - push rdi -%endmacro - -%macro popAll 0 - pop rdi - pop rsi - pop rbp - pop rbx - pop rdx - pop rcx - pop rax -%endmacro - -;; -;; Keyboard handler -;; -KeybIsr: - cli - pushAll - - xor rax, rax - mov ax, ds - push rax - - call KeybHandler - - pop rax - mov ds, ax - - popAll - iretq diff --git a/kaleid/kernel/io/keyb.c b/kaleid/kernel/io/keyb.c index cbb2aaf..d631e0b 100644 --- a/kaleid/kernel/io/keyb.c +++ b/kaleid/kernel/io/keyb.c @@ -26,14 +26,8 @@ #include #include -extern void KeybIsr(void); char ScanCodes[100] = { 0 }; -void IoSetupKeyb(void) -{ - IdtRegisterIrq(KeybIsr, 0x21, 0x8E); -} - void KeybPrint(char code) { if (code) { @@ -88,17 +82,7 @@ void ScanCodesInit(void) ScanCodes[0x39] = ' '; } -void IoEnableKeyb(void) -{ - ulong flags = KePauseIRQs(); - char readedInterruptConfig = IoReadByteFromPort(0x21); - IoWriteByteOnPort(0x21, 0xFD & readedInterruptConfig); - KeRestoreIRQs(flags); - IoEnableNMI(); - ScanCodesInit(); -} - -void KeybHandler(void) +void KeybHandler(ISRFrame_t *regs) { char status; char code = 0; @@ -116,3 +100,14 @@ void KeybHandler(void) KeybPrint((int)code); IoSendEOItoPIC(0x21); } + +void IoEnableKeyb(void) +{ + ulong flags = KePauseIRQs(); + IdtRegisterIrq(KeybHandler, 0x21, 0x8E); + char readedInterruptConfig = IoReadByteFromPort(0x21); + IoWriteByteOnPort(0x21, 0xFD & readedInterruptConfig); + KeRestoreIRQs(flags); + IoEnableNMI(); + ScanCodesInit(); +} diff --git a/kaleid/kernel/io/rtc.asm b/kaleid/kernel/io/rtc.asm deleted file mode 100644 index 214af07..0000000 --- a/kaleid/kernel/io/rtc.asm +++ /dev/null @@ -1,68 +0,0 @@ -;=----------------------------------------------------------------------------=; -; GNU GPL OS/K ; -; ; -; Desc: Basic Read Only Keyboard Driver ; -; (x86_64 architecture only) ; -; ; -; ; -; Copyright © 2018-2019 The OS/K Team ; -; ; -; This file is part of OS/K. ; -; ; -; OS/K is free software: you can redistribute it and/or modify ; -; it under the terms of the GNU General Public License as published by ; -; the Free Software Foundation, either version 3 of the License, or ; -; (at your option) any later version. ; -; ; -; OS/K is distributed in the hope that it will be useful, ; -; but WITHOUT ANY WARRANTY; without even the implied warranty of ; -; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; -; GNU General Public License for more details. ; -; ; -; You should have received a copy of the GNU General Public License ; -; along with OS/K. If not, see . ; -;=----------------------------------------------------------------------------=; - -[BITS 64] - -global RtcIsr -extern RtcHandler - -%macro pushAll 0 - push rax - push rcx - push rdx - push rbx - push rbp - push rsi - push rdi -%endmacro - -%macro popAll 0 - pop rdi - pop rsi - pop rbp - pop rbx - pop rdx - pop rcx - pop rax -%endmacro - -;; -;; Keyboard handler -;; -RtcIsr: - cli - pushAll - - xor rax, rax - mov ax, ds - push rax - - call RtcHandler - - pop rax - mov ds, ax - - popAll - iretq diff --git a/kaleid/kernel/io/rtc.c b/kaleid/kernel/io/rtc.c index b752ab5..b76e322 100644 --- a/kaleid/kernel/io/rtc.c +++ b/kaleid/kernel/io/rtc.c @@ -27,17 +27,11 @@ #include #include -extern void RtcIsr(void); - static ulong IoRtcTicks = 0; static uchar RtcRate = 0x05; //2048Hz static Time_t IoRtcOriginTime; static Time_t IoRtcTime; static char time24or12Mode; -void IoSetupRtc(void) -{ - IdtRegisterIrq(RtcIsr, 0x28, 0x8E); -} static void GetTimeFromRtc(void) { @@ -143,45 +137,7 @@ static void GetTimeFromRtc(void) IoRtcTime.century = IoRtcOriginTime.century; } -void IoEnableRtc(void) -{ - ulong flags = KePauseIRQs(); - char readedInterruptConfig; - char readedRegister; - char readedIrqs; - - // Setting up the register control and interrupt rates - DebugLog("[RTC Time] Interrupt frequency set to %d Hz\n", - 32768 >> (RtcRate-1)); - - IoWriteByteOnPort(0x70, 0x8B); - readedRegister = IoReadByteFromPort(0x71); - IoWriteByteOnPort(0x70, 0x8B); // Because reading flushes - IoWriteByteOnPort(0x71, readedRegister | 0x40); - - IoWriteByteOnPort(0x70, 0x8A); - readedInterruptConfig = IoReadByteFromPort(0x71); - IoWriteByteOnPort(0x70, 0x8A); // Because reading flushes - IoWriteByteOnPort(0x71, (readedInterruptConfig & 0xF0) | RtcRate); - IoWriteByteOnPort(0x70, 0x0C); - IoReadByteFromPort(0x71); // Flush - - // Setting up the IRQs - readedIrqs = IoReadByteFromPort(0xA1); - IoWriteByteOnPort(0xA1, 0xFE & readedIrqs); // Enables IRQ on PIC 2 - readedIrqs = IoReadByteFromPort(0x21); - IoWriteByteOnPort(0x21, 0xFB & readedIrqs); // Enables IRQ on PIC 1 - - // Clean-up - IoWriteByteOnPort(0x70, 0x0C); // Select status reg C - IoReadByteFromPort(0x71); // Flush - - GetTimeFromRtc(); - KeRestoreIRQs(flags); - IoEnableNMI(); -} - -void RtcHandler(void) +void RtcHandler(ISRFrame_t *regs) { //bprintf(BStdOut, " *RTC - "); IoWriteByteOnPort(0x70, 0x0C); // Selects status reg C @@ -258,4 +214,44 @@ ulong IoGetRtcTicks(void) return IoRtcTicks; } +void IoEnableRtc(void) +{ + ulong flags = KePauseIRQs(); + char readedInterruptConfig; + char readedRegister; + char readedIrqs; + + IdtRegisterIrq(RtcHandler, 0x28, 0x8E); + + // Setting up the register control and interrupt rates + DebugLog("[RTC Time] Interrupt frequency set to %d Hz\n", + 32768 >> (RtcRate-1)); + + IoWriteByteOnPort(0x70, 0x8B); + readedRegister = IoReadByteFromPort(0x71); + IoWriteByteOnPort(0x70, 0x8B); // Because reading flushes + IoWriteByteOnPort(0x71, readedRegister | 0x40); + + IoWriteByteOnPort(0x70, 0x8A); + readedInterruptConfig = IoReadByteFromPort(0x71); + IoWriteByteOnPort(0x70, 0x8A); // Because reading flushes + IoWriteByteOnPort(0x71, (readedInterruptConfig & 0xF0) | RtcRate); + IoWriteByteOnPort(0x70, 0x0C); + IoReadByteFromPort(0x71); // Flush + + // Setting up the IRQs + readedIrqs = IoReadByteFromPort(0xA1); + IoWriteByteOnPort(0xA1, 0xFE & readedIrqs); // Enables IRQ on PIC 2 + readedIrqs = IoReadByteFromPort(0x21); + IoWriteByteOnPort(0x21, 0xFB & readedIrqs); // Enables IRQ on PIC 1 + + // Clean-up + IoWriteByteOnPort(0x70, 0x0C); // Select status reg C + IoReadByteFromPort(0x71); // Flush + + GetTimeFromRtc(); + KeRestoreIRQs(flags); + IoEnableNMI(); +} +