Skip to content
Snippets Groups Projects
Commit a6ae1130 authored by John Hodge's avatar John Hodge
Browse files

Now with added CPU exception handling!

parent c283dbc7
No related merge requests found
......@@ -6,7 +6,7 @@ RUSTFLAGS += -C target-feature=-avx
#RUSTFLAGS += --target=x86_64-pc-elf
ARCH = amd64
OBJS := start_$(ARCH).o main.o libarch.rlib
OBJS := arch_$(ARCH)/start.o main.o libarch.rlib
LIBDIR := /home/tpg/apps/lib/rustlib/x86_64-unknown-linux-gnu/lib/
LIBCOMPILERRT := $(LIBDIR)libcompiler-rt.a
......
......@@ -9,6 +9,7 @@ extern crate core;
use core::str::StrSlice;
pub mod float;
pub mod interrupts;
pub fn puts(text: &str)
{
......@@ -17,6 +18,22 @@ pub fn puts(text: &str)
putc(c);
}
}
pub fn puth(val: uint)
{
puts("0");
let nibbles = {
let mut v = 1u;
while (val >> v*4) > 0 && v < 64/4 { v += 1 }
v
};
//let nibbles = 16u;
puts("x");
for i in ::core::iter::range(0, nibbles)
{
let nibble : u8 = ((val >> (nibbles-i-1)*4) & 15) as u8;
putc( if nibble <= 9 { '0' as u8 + nibble } else { 'a' as u8 + nibble-10 } );
}
}
fn putc(c: u8)
{
unsafe
......
//
//
//
#[repr(C)]
struct InterruptRegs
{
fs: u64,
gs: u64,
rax: u64, rcx: u64, rdx: u64, rbx: u64,
kernelrsp: u64, rbp: u64, rsi: u64, rdi: u64,
r8: u64, r9: u64, r10: u64, r11: u64,
r12: u64, r13: u64, r14: u64, r15: u64,
intnum: u64, errorcode: u64,
rip: u64, cs: u64,
rflags: u64, rsp: u64, ss: u64,
}
#[no_mangle]
pub extern "C" fn error_handler(regs: &InterruptRegs)
{
::puts("Error happened!\n");
::puts("Int = "); ::puth(regs.intnum as uint); ::puts("\n");
::puts("Code = "); ::puth(regs.errorcode as uint); ::puts("\n");
::puts("RIP = "); ::puth(regs.rip as uint); ::puts("\n");
loop {}
}
// vim: ft=rust
......@@ -5,6 +5,53 @@
%define KSTACK_BASE 0xFFFFA00000000000
%define INITIAL_KSTACK_SIZE 16
%define KERNEL_BASE 0xFFFFFFFF80000000
%macro SAVE_GPR 1
mov [%1-0x08], r15
mov [%1-0x10], r14
mov [%1-0x18], r13
mov [%1-0x20], r12
mov [%1-0x28], r11
mov [%1-0x30], r10
mov [%1-0x38], r9
mov [%1-0x40], r8
mov [%1-0x48], rdi
mov [%1-0x50], rsi
mov [%1-0x58], rbp
mov [%1-0x60], rsp
mov [%1-0x68], rbx
mov [%1-0x70], rdx
mov [%1-0x78], rcx
mov [%1-0x80], rax
%endmacro
%macro PUSH_GPR 0
SAVE_GPR rsp
sub rsp, 0x80
%endmacro
%macro RESTORE_GPR 1
mov r15, [%1-0x08]
mov r14, [%1-0x10]
mov r13, [%1-0x18]
mov r12, [%1-0x20]
mov r11, [%1-0x28]
mov r10, [%1-0x30]
mov r9, [%1-0x38]
mov r8, [%1-0x40]
mov rdi, [%1-0x48]
mov rsi, [%1-0x50]
mov rbp, [%1-0x58]
;mov rsp, [%1-0x60]
mov rbx, [%1-0x68]
mov rdx, [%1-0x70]
mov rcx, [%1-0x78]
mov rax, [%1-0x80]
%endmacro
%macro POP_GPR 0
add rsp, 0x80
RESTORE_GPR rsp
%endmacro
[extern low_InitialPML4]
[extern low_GDTPtr]
......@@ -28,8 +75,6 @@ mboot:
[BITS 32]
[global start]
start:
mov dx, 0x3F8 ; Prepare for serial debug
; 1. Ensure that CPU is compatible
mov eax, 0x80000000
cpuid
......@@ -40,11 +85,12 @@ start:
test edx, 1<<29
jz not64bitCapable
mov dx, 0x3F8 ; Prepare for serial debug
mov al, 'O'
out dx, al
mov al, 'K'
out dx, al
out 0xe9, al
;; 2. Switch into IA-32e mode
; Enable:
......@@ -58,7 +104,6 @@ start:
mov al, '4'
out dx, al
mov al, 'K'
; Load PDP4
mov eax, low_InitialPML4
mov cr3, eax
......@@ -73,6 +118,7 @@ start:
or eax, (1 << 11)|(1 << 8)|(1 << 0) ; NXE, LME, SCE
wrmsr
mov dx, 0x3F8
mov al, 'e'
out dx, al
......@@ -104,11 +150,12 @@ not64bitCapable:
[BITS 64]
start64:
mov dx, 0x3F8
mov al, '6'
out dx, al
mov rax, start64_higher
mov rsp, KSTACK_BASE+INITIAL_KSTACK_SIZE*0x1000
mov rax, start64_higher
jmp rax
[section .initdata]
strNot64BitCapable:
......@@ -119,18 +166,57 @@ strNot64BitCapable:
start64_higher:
mov al, 'H'
out dx, al
mov eax, 0xC0000101 ; GS Base
mov rcx, TID0TLS
; 4. Set up FS/GS base for kernel
mov rax, TID0TLS
mov rdx, rax
shr rdx, 32
mov ecx, 0xC0000100 ; FS Base
wrmsr
mov eax, 0xC0000100 ; GS Base
mov rcx, TID0TLS
mov ecx, 0xC0000101 ; GS Base
wrmsr
; 4. Call rust kmain
; 5. Set true GDT base
lgdt [GDTPtr2 - KERNEL_BASE]
; 6. Request setup of IRQ handlers
call idt_init
; 7. Call rust kmain
call kmain
.dead_loop:
cli
hlt
jmp .dead_loop
idt_init:
; Save to make following instructions smaller
mov rdi, IDT
; Set an IDT entry to a callback
%macro SETIDT 2
mov rax, %2
mov WORD [rdi + %1*16], ax
shr rax, 16
mov WORD [rdi + %1*16 + 6], ax
shr rax, 16
mov DWORD [rdi + %1*16 + 8], eax
; Enable
mov ax, WORD [rdi + %1*16 + 4]
or ax, 0x8000
mov WORD [rdi + %1*16 + 4], ax
%endmacro
; Install error handlers
%macro SETISR 1
SETIDT %1, Isr%1
%endmacro
%assign i 0
%rep 32
SETISR i
%assign i i+1
%endrep
mov rdi, IDTPtr
lidt [rdi]
ret
[global __morestack]
__morestack:
ret
......@@ -178,6 +264,68 @@ memcmp:
inc rax
ret
%macro ISR_NOERRNO 1
Isr%1:
xchg bx, bx
push QWORD 0
push QWORD %1
jmp ErrorCommon
%endmacro
%macro ISR_ERRNO 1
Isr%1:
xchg bx, bx
push QWORD %1
jmp ErrorCommon
%endmacro
ISR_NOERRNO 0; 0: Divide By Zero Exception
ISR_NOERRNO 1; 1: Debug Exception
ISR_NOERRNO 2; 2: Non Maskable Interrupt Exception
ISR_NOERRNO 3; 3: Int 3 Exception
ISR_NOERRNO 4; 4: INTO Exception
ISR_NOERRNO 5; 5: Out of Bounds Exception
ISR_NOERRNO 6; 6: Invalid Opcode Exception
ISR_NOERRNO 7; 7: Coprocessor Not Available Exception
ISR_ERRNO 8; 8: Double Fault Exception (With Error Code!)
ISR_NOERRNO 9; 9: Coprocessor Segment Overrun Exception
ISR_ERRNO 10; 10: Bad TSS Exception (With Error Code!)
ISR_ERRNO 11; 11: Segment Not Present Exception (With Error Code!)
ISR_ERRNO 12; 12: Stack Fault Exception (With Error Code!)
ISR_ERRNO 13; 13: General Protection Fault Exception (With Error Code!)
ISR_ERRNO 14; 14: Page Fault Exception (With Error Code!)
ISR_NOERRNO 15; 15: Reserved Exception
ISR_NOERRNO 16; 16: Floating Point Exception
ISR_NOERRNO 17; 17: Alignment Check Exception
ISR_NOERRNO 18; 18: Machine Check Exception
ISR_NOERRNO 19; 19: Reserved
ISR_NOERRNO 20; 20: Reserved
ISR_NOERRNO 21; 21: Reserved
ISR_NOERRNO 22; 22: Reserved
ISR_NOERRNO 23; 23: Reserved
ISR_NOERRNO 24; 24: Reserved
ISR_NOERRNO 25; 25: Reserved
ISR_NOERRNO 26; 26: Reserved
ISR_NOERRNO 27; 27: Reserved
ISR_NOERRNO 28; 28: Reserved
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
mov rdi, rsp
call error_handler
pop fs
pop gs
POP_GPR
add rsp, 2*8
iretq
[section .padata]
[global InitialPML4]
......@@ -244,6 +392,18 @@ GDTPtr:
dw $-GDT-1
dd low_GDT
dd 0
GDTPtr2:
dw GDTPtr-GDT-1
dq GDT
[global IDT]
[global IDTPtr]
IDT:
; 64-bit Interrupt Gate, CS = 0x8, IST0 (Disabled)
times 256 dd 0x00080000, 0x00000E00, 0, 0
IDTPtr:
dw 256*16-1
dq IDT
[global TID0TLS]
TID0TLS:
times 0x70 db 0
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment