From 0cf1367e7ea2952f699e5ce01daba55c505c3a41 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Wed, 24 Apr 2019 00:05:03 +0200 Subject: [PATCH] Exception are now fully supported, working on keyboard and rtc --- Makefile | 1 + include/kernel/base.h | 1 + include/kernel/cpu.h | 92 ++++++-------------------- kaleid/kernel/cpu/cpu.asm | 28 -------- kaleid/kernel/cpu/idt.c | 132 ++++++++++++++++++++++++++++++++++--- kaleid/kernel/cpu/isr.asm | 18 ++++- kaleid/kernel/init/init.c | 18 ++++- kaleid/kernel/init/table.c | 2 + kaleid/kernel/mm/gdt.c | 1 + 9 files changed, 182 insertions(+), 111 deletions(-) delete mode 100644 kaleid/kernel/cpu/cpu.asm diff --git a/Makefile b/Makefile index 8f95abd..a9e35c8 100644 --- a/Makefile +++ b/Makefile @@ -94,6 +94,7 @@ KernSources = libbuf/buf.c libbuf/bput.c \ kernel/mm/heap.c kernel/mm/malloc.c \ kernel/mm/gdt.c kernel/ps/sched.c \ kernel/init/info.c kernel/init/ssp.c \ + kernel/cpu/rtc.c LibCObj=$(patsubst %.c,$(KOBJDIR)/%.o,$(LibCSources)) diff --git a/include/kernel/base.h b/include/kernel/base.h index 1b9e585..3f49c89 100644 --- a/include/kernel/base.h +++ b/include/kernel/base.h @@ -43,6 +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 enum ProcState_t ProcState_t; diff --git a/include/kernel/cpu.h b/include/kernel/cpu.h index 114f135..953152b 100644 --- a/include/kernel/cpu.h +++ b/include/kernel/cpu.h @@ -35,6 +35,7 @@ typedef struct IdtDescriptor_t IdtDescriptor_t; typedef struct IdtEntry_t IdtEntry_t; typedef struct IdtPtr_t IdtPtr_t; typedef struct Registers_t Registers_t; +typedef struct IRQList_t IRQList_t; // -------------------------------------------------------------------------- // @@ -101,41 +102,6 @@ enum { FEAT_EDX_PBE = 1 << 31 }; -static const char *IsrExceptions[32] = { - "Divide Error Fault", - "Debug Exception Trap", - "Non-maskable Interrupt", - "Breakpoint Trap", - "Overflow Trap", - "Bound Range Exceeded Fault", - "Invalid Opcode Fault", - "Device Not Available or No Math Coprocessor Fault", - "Double Fault Abort", - "Coprocessor Segment Overrun Fault", - "Invalid TSS Fault", - "Segment Not Present Fault", - "Stack Segment fault", - "General Protection Fault", - "Page Fault", - "Intel Reserved", - "x87 FPU Floating Point or Math Fault", - "Alignment Check Fault", - "Machine Check Abort", - "SIMD Floating Point Fault", - "Virtualization Exception Fault", - "Intel Reserved", - "Intel Reserved", - "Intel Reserved", - "Intel Reserved", - "Intel Reserved", - "Intel Reserved", - "Intel Reserved", - "Intel Reserved", - "Intel Reserved", - "Intel Reserved", - "Intel Reserved" -}; - struct IdtDescriptor_t { ushort limit; ulong base; @@ -154,9 +120,22 @@ struct IdtEntry_t struct IdtPtr_t { - ushort limit; - void *base; - } __attribute__((packed)); + ushort limit; + void *base; +} __attribute__((packed)); + +struct IRQList_t +{ + uchar n; //number of entries in the list + + struct entry { + void (*isr)(void); + uchar irq; + ulong base; + ushort selector; + uchar flags; + } entry[225]; +}; // -------------------------------------------------------------------------- // @@ -170,46 +149,15 @@ struct Registers_t // -------------------------------------------------------------------------- // +void CpuRegisterIrq(void (*isr)(void), uchar irq, uchar flags); void CpuIdtSetup(void); void IdtSetGate(uchar rank, ulong base, ushort selector, uchar flags); void IdtHandler(ulong intNo); void disablePIC(void); -// -------------------------------------------------------------------------- // +void CpuEnableRtc(void); -extern void idtInit(); -extern void isr0(); -extern void isr1(); -extern void isr2(); -extern void isr3(); -extern void isr4(); -extern void isr5(); -extern void isr6(); -extern void isr7(); -extern void isr8(); -extern void isr9(); -extern void isr10(); -extern void isr11(); -extern void isr12(); -extern void isr13(); -extern void isr14(); -extern void isr15(); -extern void isr16(); -extern void isr17(); -extern void isr18(); -extern void isr19(); -extern void isr20(); -extern void isr21(); -extern void isr22(); -extern void isr23(); -extern void isr24(); -extern void isr25(); -extern void isr26(); -extern void isr27(); -extern void isr28(); -extern void isr29(); -extern void isr30(); -extern void isr31(); +// -------------------------------------------------------------------------- // #endif diff --git a/kaleid/kernel/cpu/cpu.asm b/kaleid/kernel/cpu/cpu.asm deleted file mode 100644 index 3a21db0..0000000 --- a/kaleid/kernel/cpu/cpu.asm +++ /dev/null @@ -1,28 +0,0 @@ -;=----------------------------------------------------------------------------=; -; GNU GPL OS/K ; -; ; -; Desc: ; -; ; -; ; -; 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 idtDesc - - diff --git a/kaleid/kernel/cpu/idt.c b/kaleid/kernel/cpu/idt.c index f2a0e1d..eb492f6 100644 --- a/kaleid/kernel/cpu/idt.c +++ b/kaleid/kernel/cpu/idt.c @@ -28,9 +28,97 @@ #include #include +extern void CpuIdtInit(); +extern void isr0(); +extern void isr1(); +extern void isr2(); +extern void isr3(); +extern void isr4(); +extern void isr5(); +extern void isr6(); +extern void isr7(); +extern void isr8(); +extern void isr9(); +extern void isr10(); +extern void isr11(); +extern void isr12(); +extern void isr13(); +extern void isr14(); +extern void isr15(); +extern void isr16(); +extern void isr17(); +extern void isr18(); +extern void isr19(); +extern void isr20(); +extern void isr21(); +extern void isr22(); +extern void isr23(); +extern void isr24(); +extern void isr25(); +extern void isr26(); +extern void isr27(); +extern void isr28(); +extern void isr29(); +extern void isr30(); +extern void isr31(); + +static char *IsrExceptions[32] = { + "Divide Error Fault", + "Debug Exception Trap", + "Non-maskable Interrupt", + "Breakpoint Trap", + "Overflow Trap", + "Bound Range Exceeded Fault", + "Invalid Opcode Fault", + "Device Not Available or No Math Coprocessor Fault", + "Double Fault Abort", + "Coprocessor Segment Overrun Fault", + "Invalid TSS Fault", + "Segment Not Present Fault", + "Stack Segment fault", + "General Protection Fault", + "Page Fault", + "Intel Reserved", + "x87 FPU Floating Point or Math Fault", + "Alignment Check Fault", + "Machine Check Abort", + "SIMD Floating Point Fault", + "Virtualization Exception Fault", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved" +}; + IdtEntry_t idt[256] = { 0 }; IdtPtr_t idtPtr; +IRQList_t irqList = { 0 }; + + +// +// Registers an isr with his IRQ to handle driver interrupts +// +void CpuRegisterIrq(void (*isr)(void), uchar irq, uchar flags) +{ + KalAssert(idt[0].flags==0); // IDT uninitialized + + irqList.entry[irqList.n].isr = isr; + irqList.entry[irqList.n].irq = irq; + irqList.entry[irqList.n].flags = flags; + irqList.n++; +} + +// +// Installs the IDT in order to activate the interrupts handling +// void CpuIdtSetup(void) { // XXX detect the APIC with cpuid ! @@ -42,7 +130,7 @@ void CpuIdtSetup(void) idtPtr.limit = (sizeof(IdtEntry_t) * 256) - 1; idtPtr.base = &idt; - // Set IDT gates + // Set IDT Exception Gates IdtSetGate(0, (ulong)isr0, codeSeg, 0x8E); IdtSetGate(1, (ulong)isr1, codeSeg, 0x8E); IdtSetGate(2, (ulong)isr2, codeSeg, 0x8E); @@ -75,12 +163,23 @@ void CpuIdtSetup(void) IdtSetGate(29, (ulong)isr29, codeSeg, 0x8E); // INTEL RESERVED IdtSetGate(30, (ulong)isr30, codeSeg, 0x8E); // INTEL RESERVED + // Set the IRQ Driver Gates + for (int i = 0 ; i < irqList.n ; i++) { + IdtSetGate(irqList.entry[irqList.n].irq, + (ulong)irqList.entry[irqList.n].isr, + codeSeg, + irqList.entry[irqList.n].flags + ); + } + // Load IDT - DebugLog("[IdtSetup] Filled \n"); - idtInit(); + CpuIdtInit(); DebugLog("[IdtSetup] Initialized !\n"); } +// +// Set an interrupt gate +// void IdtSetGate(uchar rank, ulong base, ushort selector, uchar flags) { // Set Base Address @@ -97,7 +196,11 @@ void IdtSetGate(uchar rank, ulong base, ushort selector, uchar flags) idt[rank].reserved = 0; } -void disablePIC(void) { +// +// Disables the PIC to activate the APIC +// +void disablePIC(void) +{ // Set ICW1 IoWriteByteOnPort(0x20, 0x11); IoWriteByteOnPort(0xa0, 0x11); @@ -123,20 +226,33 @@ void disablePIC(void) { *val |= (1<<8); } +// +// Ends the current interrupt handling +// +void sendEOItoPIC(uchar isr) +{ + if(isr >= 8) + IoWriteByteOnPort(0xa0,0x20); + + IoWriteByteOnPort(0x20,0x20); +} + +// +// The main exception handler +// void IdtHandler(ulong intNo) { int irrecoverable = 0; char *exceptionMsg = "Unhandled ISR exception"; - if (intNo == 6 || intNo == 8 || intNo == 13) irrecoverable++; + if (intNo == 0 || intNo == 6 || intNo == 8 || intNo == 13) irrecoverable++; if (intNo < 32) exceptionMsg = IsrExceptions[intNo]; if (irrecoverable) { - KeStartPanic("Irrecoverable exception 0x%x : %s\n", intNo, exceptionMsg); + KeStartPanic("[ISR 0x%x] Irrecoverable %s\n", intNo, exceptionMsg); } else { bprintf(BStdOut, "[ISR 0x%x] %s\n", intNo, exceptionMsg); + sendEOItoPIC(intNo); } - - return; } diff --git a/kaleid/kernel/cpu/isr.asm b/kaleid/kernel/cpu/isr.asm index 760cd91..adb6955 100644 --- a/kaleid/kernel/cpu/isr.asm +++ b/kaleid/kernel/cpu/isr.asm @@ -24,17 +24,30 @@ %include "kaleid/kernel/cpu/isr.inc" -global idtInit +global CpuIdtInit +global divideByZero extern idtPtr extern IdtHandler ;; ;; Loads the IDT ;; -idtInit: +CpuIdtInit: lidt [idtPtr] ret +;; +;; Bug test +;; +divideByZero: + pushAll + mov eax, 17 + mov ebx, 0 + xor edx, edx + div ebx + popAll + ret + ;; ;; ISR handler ;; @@ -128,3 +141,4 @@ IsrWithoutErrCode 29 IsrWithoutErrCode 30 IsrWithoutErrCode 31 IsrWithoutErrCode 32 + diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index 6b69541..84e0900 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -40,6 +40,14 @@ extern error_t IoInitVGABuffer(void); // ps/proc.c test function extern void pstest(void); +// interrupts tests +extern void divideByZero(void); + +void test(void) +{ + DebugLog("test\n"); +} + // // Entry point of the Kaleid kernel // @@ -67,11 +75,19 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg) MmInitHeap(); PsInitSched(); + CpuRegisterIrq(test, 13, 0x8E); + //MmPrintMemoryMap(); CpuIdtSetup(); KeEnableIRQs(); - interrupt(30); + /* // Test Page Fault + long addr = -1; + DebugLog("%s", addr); */ + CpuEnableRtc(); + + KernLog("\nGoodbye!"); + // End this machine's suffering BFlushBuf(BStdOut); KeCrashSystem(); diff --git a/kaleid/kernel/init/table.c b/kaleid/kernel/init/table.c index 0261a15..88a3169 100644 --- a/kaleid/kernel/init/table.c +++ b/kaleid/kernel/init/table.c @@ -31,3 +31,5 @@ volatile BootInfo_t BtBootTab = {0}; volatile bool KeIsPanicking = 0; volatile Processor_t *KeCurCPU = &_KeCPUTable[0]; + + diff --git a/kaleid/kernel/mm/gdt.c b/kaleid/kernel/mm/gdt.c index 06cbc15..e2dbc8f 100644 --- a/kaleid/kernel/mm/gdt.c +++ b/kaleid/kernel/mm/gdt.c @@ -49,6 +49,7 @@ void MmInitGdt(void) gdtPtr.limit = (sizeof(GdtEntry_t) * 5) - 1; gdtPtr.base = (uint)(ullong)&gdtEntries; + SetGdtEntry(0,0,0,0,0); /* XXX set TSS register */