luciaos/fault.nasm

243 lines
5.4 KiB
NASM

extern error_screen ; 80x50 words
; Switches to text mode and shit
extern error_environment
_fault_coda:
xchg bx,bx
mov ax, 0x10
mov es, ax
; move to 'safe' location
mov ebp, 0x318000
mov esp, ebp
call error_environment
.hlt:
hlt
jmp .hlt
extern gpf_handler_v86
global gpfHandler
gpfHandler:
cli ; make sure we're in a 'friendly' env
push eax
push ebx
push ecx
; save old ds
mov bx, ds
mov ax, 0x10
mov ds, ax
mov word [_gpf_old_ds], bx
; relocate stack so other interrupts don't fuck us over
; not sure if this is necessary, it doesn't seem to fix our race conditions...
mov ebx, esp
sub esp, 0x1000
xor ecx, ecx
.l:
mov eax, [ebx]
mov [esp+ecx], eax
add ebx, 4
add ecx, 4
cmp ebx, 0x320000 ; tss esp0
jl .l
pop ecx
pop ebx
sti ; we shouldn't crash now?
mov eax, dword [esp+16] ; EFLAGS
and eax, 1 << 17 ; VM flag
test eax, eax
pop eax
jnz gpf_handler_v86
jmp gpf_handler_32
gpf_unhandled:
mov dword [error_screen+0x00], 0x0f000f00 | 'G' | 'P' << 16
mov dword [error_screen+0x04], 0x0f000f00 | 'F' | '!' << 16
xchg bx,bx
jmp _fault_coda
_gpf_old_ds: dw 0
extern get_key
extern task_ptr
extern _enter_v86_internal_no_task
extern return_prev_task
extern v86VideoInt
gpf_handler_32:
push eax
mov eax, dword [esp+8] ; EIP
movzx eax, word [eax]
cmp eax, 0x30CD ; int 0x30
je .int30
cmp eax, 0x21CD ; int 0x21
je .int21
jmp gpf_unhandled
.int21:
pop eax ; command
cmp al, 0x00 ; get key
jne .s1
call get_key
jmp .return_to_offender
.s1: cmp al, 0x10 ; video interrupt
jne .return_to_offender
add esp, 4
add dword [esp+0], 2
; add a new task
call _gpf_create_return_task
; now enter v86 mode
; get regs from return stack
mov eax, [esp+12] ; return esp
mov eax, [eax] ; regs
push eax ; regs
mov eax, v86VideoInt
and eax, 0xffff
push eax ; ip
mov eax, v86VideoInt
shr eax, 4
and eax, 0xf000
push eax ; cs
push 0xFF00 ; sp
push 0x8000 ; ss
jmp _enter_v86_internal_no_task ; NOT a function call
.int30:
pop eax ; return value
jmp return_prev_task
.return_to_offender:
add dword [esp+4], 2
push eax
mov ax, word [_gpf_old_ds]
mov ds, ax
pop eax
add esp, 4 ; error code
iret
_gpf_create_return_task:
; handler stack stored in edx
mov edx, esp
mov esp, dword [task_ptr]
mov eax, [edx+20] ; ss
push eax
mov eax, [edx+16] ; esp
push eax
mov eax, [edx+12] ; eflags
push eax
mov eax, [edx+8] ; cs
push eax
mov eax, [edx+4] ; eip
push eax
mov ax, word [_gpf_old_ds] ; restore old ds
mov ds, ax
push ds
push es
push fs
push gs
push ebp
push ebx
push esi
push edi
mov ax, 0x10
mov ds, ax
mov dword [task_ptr], esp ; save new task pointer
mov esp, edx ; restore handler stack
ret
global unhandled_handler
unhandled_handler:
mov ax, 0x10
mov ds, ax
mov dword [error_screen+0x00], 0x0f000f00 | 'E' | 'R' << 16
mov dword [error_screen+0x04], 0x0f000f00 | 'R' | 'O' << 16
mov dword [error_screen+0x08], 0x0f000f00 | 'R' | '!' << 16
jmp _fault_coda
global pageFaultHandler
pageFaultHandler:
mov ax, 0x10
mov ds, ax
pop eax ; error code
mov ebx, 0x0f000f00 | '0' | '!' << 16
and eax, 0x7 ; U/S,R/W,P
add ebx, eax
mov dword [error_screen+0x00], 0x0f000f00 | 'P' | 'G' << 16
mov dword [error_screen+0x04], 0x0f000f00 | 'F' | 'L' << 16
mov dword [error_screen+0x08], 0x0f000f00 | 'T' | ':' << 16
mov dword [error_screen+0x0C], ebx
jmp _fault_coda
global divisionErrorHandler
divisionErrorHandler:
mov ax, 0x10
mov ds, ax
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'D' << 16
mov dword [error_screen+0x04], 0x0f000f00 | 'E' | '!' << 16
jmp _fault_coda
global boundRangeHandler
boundRangeHandler:
mov ax, 0x10
mov ds, ax
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'B' << 16
mov dword [error_screen+0x04], 0x0f000f00 | 'R' | '!' << 16
jmp _fault_coda
global invalidOpcodeHandler
invalidOpcodeHandler:
mov ax, 0x10
mov ds, ax
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'U' << 16
mov dword [error_screen+0x04], 0x0f000f00 | 'D' | '!' << 16
jmp _fault_coda
global deviceNotAvailableHandler
deviceNotAvailableHandler:
mov ax, 0x10
mov ds, ax
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'N' << 16
mov dword [error_screen+0x04], 0x0f000f00 | 'D' | '!' << 16
jmp _fault_coda
global doubleFaultHandler
doubleFaultHandler:
mov ax, 0x10
mov ds, ax
mov dword [0xb8000+0x00], 0x0f000f00 | '#' | 'D' << 16
mov dword [0xb8000+0x04], 0x0f000f00 | 'F' | '!' << 16
; double faults simply abort right then
.hlt: hlt
jmp .hlt
global invalidTSSHandler
invalidTSSHandler:
mov ax, 0x10
mov ds, ax
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'T' << 16
mov dword [error_screen+0x04], 0x0f000f00 | 'S' | '!' << 16
jmp _fault_coda
global segmentNotPresentHandler
segmentNotPresentHandler:
mov ax, 0x10
mov ds, ax
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'N' << 16
mov dword [error_screen+0x04], 0x0f000f00 | 'P' | '!' << 16
jmp _fault_coda
global stackSegmentHandler
stackSegmentHandler:
mov ax, 0x10
mov ds, ax
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'S' << 16
mov dword [error_screen+0x04], 0x0f000f00 | 'S' | '!' << 16
jmp _fault_coda
global x87FloatingHandler
x87FloatingHandler:
mov ax, 0x10
mov ds, ax
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'M' << 16
mov dword [error_screen+0x04], 0x0f000f00 | 'F' | '!' << 16
jmp _fault_coda
global alignmentCheckHandler
alignmentCheckHandler:
mov ax, 0x10
mov ds, ax
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'A' << 16
mov dword [error_screen+0x04], 0x0f000f00 | 'C' | '!' << 16
jmp _fault_coda
global controlProtectionHandler
controlProtectionHandler:
mov ax, 0x10
mov ds, ax
mov dword [error_screen+0x00], 0x0f000f00 | '#' | 'C' << 16
mov dword [error_screen+0x04], 0x0f000f00 | 'P' | '!' << 16
jmp _fault_coda