From eecce4b7a55315f6c385ad8be35c25dbb12d43d8 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 27 May 2010 22:06:21 +0800 Subject: [PATCH] More work on x86_64 build, error handling and IDT --- .gitignore | 3 +- Kernel/Makefile.BuildNum | 2 +- Kernel/arch/x86_64/Makefile | 2 +- Kernel/arch/x86_64/desctab.asm | 71 +++++++++++++++++++++++++------ Kernel/arch/x86_64/errors.c | 64 ++++++++++++++++++++++++++++ Kernel/arch/x86_64/include/proc.h | 17 +++++--- Kernel/arch/x86_64/kernelpanic.c | 24 ++++++++++- Kernel/arch/x86_64/main.c | 3 ++ Kernel/arch/x86_64/proc.c | 8 ++-- Kernel/arch/x86_64/start64.asm | 2 +- 10 files changed, 168 insertions(+), 28 deletions(-) create mode 100644 Kernel/arch/x86_64/errors.c diff --git a/.gitignore b/.gitignore index b9797812..e56d3e6d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.o.* *.d.* +*.xo.* *~ *.o *.d @@ -12,4 +13,4 @@ *.bin *.dsm *.dmp -*.txt +*.kmd.* diff --git a/Kernel/Makefile.BuildNum b/Kernel/Makefile.BuildNum index 20bdebc4..8158a0e7 100644 --- a/Kernel/Makefile.BuildNum +++ b/Kernel/Makefile.BuildNum @@ -1 +1 @@ -BUILD_NUM = 2216 +BUILD_NUM = 2225 diff --git a/Kernel/arch/x86_64/Makefile b/Kernel/arch/x86_64/Makefile index 2e1b84a9..6bc6419b 100644 --- a/Kernel/arch/x86_64/Makefile +++ b/Kernel/arch/x86_64/Makefile @@ -29,4 +29,4 @@ endif A_OBJ = start32.ao start64.ao desctab.ao A_OBJ += main.o lib.o proc.o mm_virt.o mm_phys.o vm8086.o -A_OBJ += kernelpanic.o +A_OBJ += kernelpanic.o errors.o diff --git a/Kernel/arch/x86_64/desctab.asm b/Kernel/arch/x86_64/desctab.asm index 05e283d6..838f67e6 100644 --- a/Kernel/arch/x86_64/desctab.asm +++ b/Kernel/arch/x86_64/desctab.asm @@ -48,11 +48,7 @@ MM_LOCALAPIC equ 0xFFFFFD0000000000 [section .text] [global Desctab_Init] -Desctab_Init: - ; Install IDT - mov rax, gIDTPtr - lidt [rax] - +Desctab_Init: ; Save to make following instructions smaller mov rdi, gIDT @@ -61,9 +57,9 @@ Desctab_Init: mov rax, %2 mov WORD [rdi + %1*16], ax shr rax, 16 - mov WORD [rdi + %1*16+6], ax + mov WORD [rdi + %1*16 + 6], ax shr rax, 16 - mov DWORD [rdi+%1*16+8], eax + mov DWORD [rdi + %1*16 + 8], eax ; Enable mov ax, WORD [rdi + %1*16 + 4] or ax, 0x8000 @@ -82,17 +78,52 @@ Desctab_Init: %endrep ; Install IRQs - %macro SETIRQ 2 - SETIDT %2, Irq%1 + %macro SETIRQ 1 + SETIDT 0xF0+%1, Irq%1 %endmacro %assign i 0 %rep 16 - SETIRQ i, 0xF0+i + SETIRQ i %assign i i+1 %endrep - + ; Remap PIC + push rdx ; Save RDX + mov dx, 0x20 + mov al, 0x11 + out dx, al ; Init Command + mov dx, 0x21 + mov al, 0xF0 + out dx, al ; Offset (Start of IDT Range) + mov al, 0x04 + out dx, al ; IRQ connected to Slave (00000100b) = IRQ2 + mov al, 0x01 + out dx, al ; Set Mode + mov al, 0x00 + out dx, al ; Set Mode + + mov dx, 0xA0 + mov al, 0x11 + out dx, al ; Init Command + mov dx, 0xA1 + mov al, 0xF8 + out dx, al ; Offset (Start of IDT Range) + mov al, 0x02 + out dx, al ; IRQ Line connected to master + mov al, 0x01 + out dx, al ; Set Mode + mov dl, 0x00 + out dx, al ; Set Mode + pop rdx + + + ; Install IDT + mov rax, gIDTPtr + lidt [rax] + + ; Start interrupts + sti ret @@ -184,7 +215,23 @@ ISR_NOERRNO 29; 29: Reserved ISR_NOERRNO 30; 30: Reserved ISR_NOERRNO 31; 31: Reserved +[extern Error_Handler] +[global ErrorCommon] ErrorCommon: + PUSH_GPR + push gs + push fs + ;PUSH_FPU + ;PUSH_XMM + + mov rsi, rsp + call Error_Handler + + ;POP_XMM + ;POP_FPU + pop fs + pop gs + POP_GPR add rsp, 2*8 iret @@ -254,7 +301,7 @@ SchedulerIRQ: [section .data] gIDT: - times 256 dd 0x00080000, 0x00008E00, 0, 0 ; 64-bit Interrupt Gate, CS = 0x8, IST0 + times 256 dd 0x00080000, 0x00000E00, 0, 0 ; 64-bit Interrupt Gate, CS = 0x8, IST0 gIDTPtr: dw 256*16-1 dq gIDT diff --git a/Kernel/arch/x86_64/errors.c b/Kernel/arch/x86_64/errors.c new file mode 100644 index 00000000..605e9039 --- /dev/null +++ b/Kernel/arch/x86_64/errors.c @@ -0,0 +1,64 @@ +/* + * Acess2 x86_64 Project + * - Error Handling + */ +#include +#include + +// === PROTOTYPES === +void Error_Handler(tRegs *Regs); + +// === GLOBALS == +const char * const csaERROR_NAMES[] = { + "Divide By Zero", "Debug", "NMI Exception", "INT3", + "INTO", "Out of Bounds", "Invalid Opcode", "Coprocessor not avaliable", + "Double Fault", "Coprocessor Segment Overrun", "Bad TSS", "Segment Not Present", + "Stack Fault Exception", "GPF", "#PF", "Reserved", + "Floating Point Exception", "Alignment Check Exception", "Machine Check Exception", "Reserved", + "Reserved", "Reserved", "Reserved", "Reserved", + "Reserved", "Reserved", "Reserved", "Reserved", + "Reserved", "Reserved", "Reserved", "Reserved" + }; + +// === CODE === +void Error_Handler(tRegs *Regs) +{ + Uint cr; + + Debug_KernelPanic(); + + Warning("CPU Error %i - %s, Code: 0x%x", + Regs->IntNum, csaERROR_NAMES[Regs->IntNum], Regs->ErrorCode); + Warning(" CS:RIP = 0x%04x:%016x", Regs->CS, Regs->RIP); + Warning(" SS:RSP = 0x%04x:%016x", Regs->SS, Regs->RIP); + Warning(" RFLAGS = 0x%016x", Regs->RFlags); + Warning(" EAX %016x ECX %016x EDX %016x EBX %016x", + Regs->RAX, Regs->RCX, Regs->RDX, Regs->RBX); + Warning(" ESP %016x EBP %016x ESI %016x EDI %016x", + Regs->RSP, Regs->RBP, Regs->RSP, Regs->RDI); + + Warning(" FS %04x GS %04x", Regs->FS, Regs->GS); + + + // Control Registers + __asm__ __volatile__ ("mov %%cr0, %0":"=r"(cr)); + Warning(" CR0 0x%08x", cr); + __asm__ __volatile__ ("mov %%cr2, %0":"=r"(cr)); + Warning(" CR2 0x%08x", cr); + __asm__ __volatile__ ("mov %%cr3, %0":"=r"(cr)); + Warning(" CR3 0x%08x", cr); + __asm__ __volatile__ ("mov %%cr4, %0":"=r"(cr)); + Warning(" CR4 0x%08x", cr); + + switch( Regs->IntNum ) + { + case 6: // #UD + Warning(" Offending bytes: %02x %02x %02x %02x", + *(Uint8*)Regs->RIP+0, *(Uint8*)Regs->RIP+1, + *(Uint8*)Regs->RIP+2, *(Uint8*)Regs->RIP+3); + break; + } + + for(;;) + __asm__ __volatile__ ("hlt"); +} diff --git a/Kernel/arch/x86_64/include/proc.h b/Kernel/arch/x86_64/include/proc.h index 8217c68d..c92ce7e5 100644 --- a/Kernel/arch/x86_64/include/proc.h +++ b/Kernel/arch/x86_64/include/proc.h @@ -11,13 +11,16 @@ // Register Structure // TODO: Rebuild once IDT code is done typedef struct { - Uint rax, rcx, rdx, rbx; - Uint krsp, rbp, rsi, rdi; - Uint r8, r9, r10, r11; - Uint r12, r13, r14, r15; - Uint int_num, err_code; - Uint rip, cs; - Uint rflags, rsp, ss; + // MMX + // FPU + Uint FS, GS; + Uint RAX, RCX, RDX, RBX; + Uint KernelRSP, RBP, RSI, RDI; + Uint R8, R9, R10, R11; + Uint R12, R13, R14, R15; + Uint IntNum, ErrorCode; + Uint RIP, CS; + Uint RFlags, RSP, SS; } tRegs; /** diff --git a/Kernel/arch/x86_64/kernelpanic.c b/Kernel/arch/x86_64/kernelpanic.c index 32ea75d8..1ce8ae70 100644 --- a/Kernel/arch/x86_64/kernelpanic.c +++ b/Kernel/arch/x86_64/kernelpanic.c @@ -1,16 +1,38 @@ /* + * Acess2 x86_64 port + * - Kernel Panic output */ +#include // === PROTOTYPES === void KernelPanic_SetMode(void); void KernelPanic_PutChar(char ch); +// === GLOBALS === +Uint16 *gpKernelPanic_Buffer = (void*)( KERNEL_BASE|0xB8000 ); + int giKernelPanic_CurPos = 0; +// === CODE === void KernelPanic_SetMode(void) { + giKernelPanic_CurPos = 0; } void KernelPanic_PutChar(char ch) { - + switch(ch) + { + case '\n': + giKernelPanic_CurPos += 80; + case '\r': + giKernelPanic_CurPos /= 80; + giKernelPanic_CurPos *= 80; + break; + + default: + if(' ' <= ch && ch <= 0x7F) + gpKernelPanic_Buffer[giKernelPanic_CurPos] = 0x4F00|ch; + giKernelPanic_CurPos ++; + break; + } } diff --git a/Kernel/arch/x86_64/main.c b/Kernel/arch/x86_64/main.c index 6a1520a2..8dfd1771 100644 --- a/Kernel/arch/x86_64/main.c +++ b/Kernel/arch/x86_64/main.c @@ -17,7 +17,10 @@ void kmain(Uint MbMagic, void *MbInfoPtr) *(Uint16*)(0xB8000) = 0x1F00|'A'; Desctab_Init(); + *(Uint16*)(0xB8000) = 0x1F00|'B'; + MM_InitVirt(); + *(Uint16*)(0xB8000) = 0x1F00|'B'; for(;;) __asm__ __volatile__ ("hlt"); diff --git a/Kernel/arch/x86_64/proc.c b/Kernel/arch/x86_64/proc.c index 623de556..ebb07d6a 100644 --- a/Kernel/arch/x86_64/proc.c +++ b/Kernel/arch/x86_64/proc.c @@ -1,5 +1,5 @@ /* - * AcessOS Microkernel Version + * Acess2 x86_64 port * proc.c */ #include @@ -627,7 +627,7 @@ void Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP) */ int Proc_Demote(Uint *Err, int Dest, tRegs *Regs) { - int cpl = Regs->cs & 3; + int cpl = Regs->CS & 3; // Sanity Check if(Dest > 3 || Dest < 0) { *Err = -EINVAL; @@ -641,8 +641,8 @@ int Proc_Demote(Uint *Err, int Dest, tRegs *Regs) } // Change the Segment Registers - Regs->cs = (((Dest+1)<<4) | Dest) - 8; - Regs->ss = ((Dest+1)<<4) | Dest; + Regs->CS = (((Dest+1)<<4) | Dest) - 8; + Regs->SS = ((Dest+1)<<4) | Dest; return 0; } diff --git a/Kernel/arch/x86_64/start64.asm b/Kernel/arch/x86_64/start64.asm index c98afdbd..9302c052 100644 --- a/Kernel/arch/x86_64/start64.asm +++ b/Kernel/arch/x86_64/start64.asm @@ -121,6 +121,6 @@ User_Syscall_Exit: [section .bss] [global gInitialKernelStack] - resd 1024*1 ; 1 Page + resd 1024*4 ; 4 Pages gInitialKernelStack: -- 2.20.1