Exception are now fully supported, working on keyboard and rtc

This commit is contained in:
Adrien Bourmault 2019-04-24 00:05:03 +02:00
parent 02ded3d5ae
commit 0cf1367e7e
9 changed files with 182 additions and 111 deletions

View File

@ -94,6 +94,7 @@ KernSources = libbuf/buf.c libbuf/bput.c \
kernel/mm/heap.c kernel/mm/malloc.c \ kernel/mm/heap.c kernel/mm/malloc.c \
kernel/mm/gdt.c kernel/ps/sched.c \ kernel/mm/gdt.c kernel/ps/sched.c \
kernel/init/info.c kernel/init/ssp.c \ kernel/init/info.c kernel/init/ssp.c \
kernel/cpu/rtc.c
LibCObj=$(patsubst %.c,$(KOBJDIR)/%.o,$(LibCSources)) LibCObj=$(patsubst %.c,$(KOBJDIR)/%.o,$(LibCSources))

View File

@ -43,6 +43,7 @@ typedef struct BootInfo_t BootInfo_t;
typedef struct ListHead_t ListHead_t; typedef struct ListHead_t ListHead_t;
typedef struct ListNode_t ListNode_t; typedef struct ListNode_t ListNode_t;
typedef struct Processor_t Processor_t; typedef struct Processor_t Processor_t;
typedef struct IRQList_t IRQList_t;
typedef enum ProcState_t ProcState_t; typedef enum ProcState_t ProcState_t;

View File

@ -35,6 +35,7 @@ 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 Registers_t Registers_t; typedef struct Registers_t Registers_t;
typedef struct IRQList_t IRQList_t;
// -------------------------------------------------------------------------- // // -------------------------------------------------------------------------- //
@ -101,41 +102,6 @@ enum {
FEAT_EDX_PBE = 1 << 31 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 { struct IdtDescriptor_t {
ushort limit; ushort limit;
ulong base; ulong base;
@ -158,6 +124,19 @@ struct IdtPtr_t
void *base; void *base;
} __attribute__((packed)); } __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];
};
// -------------------------------------------------------------------------- // // -------------------------------------------------------------------------- //
struct Registers_t struct Registers_t
@ -170,46 +149,15 @@ struct Registers_t
// -------------------------------------------------------------------------- // // -------------------------------------------------------------------------- //
void CpuRegisterIrq(void (*isr)(void), uchar irq, uchar flags);
void CpuIdtSetup(void); void CpuIdtSetup(void);
void IdtSetGate(uchar rank, ulong base, ushort selector, uchar flags); void IdtSetGate(uchar rank, ulong base, ushort selector, uchar flags);
void IdtHandler(ulong intNo); void IdtHandler(ulong intNo);
void disablePIC(void); 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 #endif

View File

@ -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 <https://www.gnu.org/licenses/>. ;
;=----------------------------------------------------------------------------=;
[BITS 64]
global idtDesc

View File

@ -28,9 +28,97 @@
#include <kernel/iomisc.h> #include <kernel/iomisc.h>
#include <extras/buf.h> #include <extras/buf.h>
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 }; IdtEntry_t idt[256] = { 0 };
IdtPtr_t idtPtr; 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) void CpuIdtSetup(void)
{ {
// XXX detect the APIC with cpuid ! // XXX detect the APIC with cpuid !
@ -42,7 +130,7 @@ void CpuIdtSetup(void)
idtPtr.limit = (sizeof(IdtEntry_t) * 256) - 1; idtPtr.limit = (sizeof(IdtEntry_t) * 256) - 1;
idtPtr.base = &idt; idtPtr.base = &idt;
// Set IDT gates // Set IDT Exception Gates
IdtSetGate(0, (ulong)isr0, codeSeg, 0x8E); IdtSetGate(0, (ulong)isr0, codeSeg, 0x8E);
IdtSetGate(1, (ulong)isr1, codeSeg, 0x8E); IdtSetGate(1, (ulong)isr1, codeSeg, 0x8E);
IdtSetGate(2, (ulong)isr2, codeSeg, 0x8E); IdtSetGate(2, (ulong)isr2, codeSeg, 0x8E);
@ -75,12 +163,23 @@ void CpuIdtSetup(void)
IdtSetGate(29, (ulong)isr29, codeSeg, 0x8E); // INTEL RESERVED IdtSetGate(29, (ulong)isr29, codeSeg, 0x8E); // INTEL RESERVED
IdtSetGate(30, (ulong)isr30, 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 // Load IDT
DebugLog("[IdtSetup] Filled \n"); CpuIdtInit();
idtInit();
DebugLog("[IdtSetup] Initialized !\n"); DebugLog("[IdtSetup] Initialized !\n");
} }
//
// Set an interrupt gate
//
void IdtSetGate(uchar rank, ulong base, ushort selector, uchar flags) void IdtSetGate(uchar rank, ulong base, ushort selector, uchar flags)
{ {
// Set Base Address // Set Base Address
@ -97,7 +196,11 @@ void IdtSetGate(uchar rank, ulong base, ushort selector, uchar flags)
idt[rank].reserved = 0; idt[rank].reserved = 0;
} }
void disablePIC(void) { //
// Disables the PIC to activate the APIC
//
void disablePIC(void)
{
// Set ICW1 // Set ICW1
IoWriteByteOnPort(0x20, 0x11); IoWriteByteOnPort(0x20, 0x11);
IoWriteByteOnPort(0xa0, 0x11); IoWriteByteOnPort(0xa0, 0x11);
@ -123,20 +226,33 @@ void disablePIC(void) {
*val |= (1<<8); *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) void IdtHandler(ulong intNo)
{ {
int irrecoverable = 0; int irrecoverable = 0;
char *exceptionMsg = "Unhandled ISR exception"; 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 (intNo < 32) exceptionMsg = IsrExceptions[intNo];
if (irrecoverable) { if (irrecoverable) {
KeStartPanic("Irrecoverable exception 0x%x : %s\n", intNo, exceptionMsg); KeStartPanic("[ISR 0x%x] Irrecoverable %s\n", intNo, exceptionMsg);
} else { } else {
bprintf(BStdOut, "[ISR 0x%x] %s\n", intNo, exceptionMsg); bprintf(BStdOut, "[ISR 0x%x] %s\n", intNo, exceptionMsg);
sendEOItoPIC(intNo);
} }
return;
} }

View File

@ -24,17 +24,30 @@
%include "kaleid/kernel/cpu/isr.inc" %include "kaleid/kernel/cpu/isr.inc"
global idtInit global CpuIdtInit
global divideByZero
extern idtPtr extern idtPtr
extern IdtHandler extern IdtHandler
;; ;;
;; Loads the IDT ;; Loads the IDT
;; ;;
idtInit: CpuIdtInit:
lidt [idtPtr] lidt [idtPtr]
ret ret
;;
;; Bug test
;;
divideByZero:
pushAll
mov eax, 17
mov ebx, 0
xor edx, edx
div ebx
popAll
ret
;; ;;
;; ISR handler ;; ISR handler
;; ;;
@ -128,3 +141,4 @@ IsrWithoutErrCode 29
IsrWithoutErrCode 30 IsrWithoutErrCode 30
IsrWithoutErrCode 31 IsrWithoutErrCode 31
IsrWithoutErrCode 32 IsrWithoutErrCode 32

View File

@ -40,6 +40,14 @@ extern error_t IoInitVGABuffer(void);
// ps/proc.c test function // ps/proc.c test function
extern void pstest(void); extern void pstest(void);
// interrupts tests
extern void divideByZero(void);
void test(void)
{
DebugLog("test\n");
}
// //
// Entry point of the Kaleid kernel // Entry point of the Kaleid kernel
// //
@ -67,11 +75,19 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg)
MmInitHeap(); MmInitHeap();
PsInitSched(); PsInitSched();
CpuRegisterIrq(test, 13, 0x8E);
//MmPrintMemoryMap(); //MmPrintMemoryMap();
CpuIdtSetup(); CpuIdtSetup();
KeEnableIRQs(); KeEnableIRQs();
interrupt(30); /* // Test Page Fault
long addr = -1;
DebugLog("%s", addr); */
CpuEnableRtc();
KernLog("\nGoodbye!");
// End this machine's suffering // End this machine's suffering
BFlushBuf(BStdOut); BFlushBuf(BStdOut);
KeCrashSystem(); KeCrashSystem();

View File

@ -31,3 +31,5 @@ volatile BootInfo_t BtBootTab = {0};
volatile bool KeIsPanicking = 0; volatile bool KeIsPanicking = 0;
volatile Processor_t *KeCurCPU = &_KeCPUTable[0]; volatile Processor_t *KeCurCPU = &_KeCPUTable[0];

View File

@ -49,6 +49,7 @@ void MmInitGdt(void)
gdtPtr.limit = (sizeof(GdtEntry_t) * 5) - 1; gdtPtr.limit = (sizeof(GdtEntry_t) * 5) - 1;
gdtPtr.base = (uint)(ullong)&gdtEntries; gdtPtr.base = (uint)(ullong)&gdtEntries;
SetGdtEntry(0,0,0,0,0);
/* XXX set TSS register */ /* XXX set TSS register */