158 lines
2.8 KiB
ArmAsm
158 lines
2.8 KiB
ArmAsm
|
/*
|
||
|
* asm.s contains the low-level code for most hardware faults.
|
||
|
* page_exception is handled by the mm, so that isn't here. This
|
||
|
* file also handles (hopefully) fpu-exceptions due to TS-bit, as
|
||
|
* the fpu must be properly saved/resored. This hasn't been tested.
|
||
|
*/
|
||
|
|
||
|
.globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op
|
||
|
.globl _device_not_available,_double_fault,_coprocessor_segment_overrun
|
||
|
.globl _invalid_TSS,_segment_not_present,_stack_segment
|
||
|
.globl _general_protection,_coprocessor_error,_reserved
|
||
|
|
||
|
_divide_error:
|
||
|
pushl $_do_divide_error
|
||
|
no_error_code:
|
||
|
xchgl %eax,(%esp)
|
||
|
pushl %ebx
|
||
|
pushl %ecx
|
||
|
pushl %edx
|
||
|
pushl %edi
|
||
|
pushl %esi
|
||
|
pushl %ebp
|
||
|
push %ds
|
||
|
push %es
|
||
|
push %fs
|
||
|
pushl $0 # "error code"
|
||
|
lea 44(%esp),%edx
|
||
|
pushl %edx
|
||
|
movl $0x10,%edx
|
||
|
mov %dx,%ds
|
||
|
mov %dx,%es
|
||
|
mov %dx,%fs
|
||
|
call *%eax
|
||
|
addl $8,%esp
|
||
|
pop %fs
|
||
|
pop %es
|
||
|
pop %ds
|
||
|
popl %ebp
|
||
|
popl %esi
|
||
|
popl %edi
|
||
|
popl %edx
|
||
|
popl %ecx
|
||
|
popl %ebx
|
||
|
popl %eax
|
||
|
iret
|
||
|
|
||
|
_debug:
|
||
|
pushl $_do_int3 # _do_debug
|
||
|
jmp no_error_code
|
||
|
|
||
|
_nmi:
|
||
|
pushl $_do_nmi
|
||
|
jmp no_error_code
|
||
|
|
||
|
_int3:
|
||
|
pushl $_do_int3
|
||
|
jmp no_error_code
|
||
|
|
||
|
_overflow:
|
||
|
pushl $_do_overflow
|
||
|
jmp no_error_code
|
||
|
|
||
|
_bounds:
|
||
|
pushl $_do_bounds
|
||
|
jmp no_error_code
|
||
|
|
||
|
_invalid_op:
|
||
|
pushl $_do_invalid_op
|
||
|
jmp no_error_code
|
||
|
|
||
|
math_emulate:
|
||
|
popl %eax
|
||
|
pushl $_do_device_not_available
|
||
|
jmp no_error_code
|
||
|
_device_not_available:
|
||
|
pushl %eax
|
||
|
movl %cr0,%eax
|
||
|
bt $2,%eax # EM (math emulation bit)
|
||
|
jc math_emulate
|
||
|
clts # clear TS so that we can use math
|
||
|
movl _current,%eax
|
||
|
cmpl _last_task_used_math,%eax
|
||
|
je 1f # shouldn't happen really ...
|
||
|
pushl %ecx
|
||
|
pushl %edx
|
||
|
push %ds
|
||
|
movl $0x10,%eax
|
||
|
mov %ax,%ds
|
||
|
call _math_state_restore
|
||
|
pop %ds
|
||
|
popl %edx
|
||
|
popl %ecx
|
||
|
1: popl %eax
|
||
|
iret
|
||
|
|
||
|
_coprocessor_segment_overrun:
|
||
|
pushl $_do_coprocessor_segment_overrun
|
||
|
jmp no_error_code
|
||
|
|
||
|
_reserved:
|
||
|
pushl $_do_reserved
|
||
|
jmp no_error_code
|
||
|
|
||
|
_coprocessor_error:
|
||
|
pushl $_do_coprocessor_error
|
||
|
jmp no_error_code
|
||
|
|
||
|
_double_fault:
|
||
|
pushl $_do_double_fault
|
||
|
error_code:
|
||
|
xchgl %eax,4(%esp) # error code <-> %eax
|
||
|
xchgl %ebx,(%esp) # &function <-> %ebx
|
||
|
pushl %ecx
|
||
|
pushl %edx
|
||
|
pushl %edi
|
||
|
pushl %esi
|
||
|
pushl %ebp
|
||
|
push %ds
|
||
|
push %es
|
||
|
push %fs
|
||
|
pushl %eax # error code
|
||
|
lea 44(%esp),%eax # offset
|
||
|
pushl %eax
|
||
|
movl $0x10,%eax
|
||
|
mov %ax,%ds
|
||
|
mov %ax,%es
|
||
|
mov %ax,%fs
|
||
|
call *%ebx
|
||
|
addl $8,%esp
|
||
|
pop %fs
|
||
|
pop %es
|
||
|
pop %ds
|
||
|
popl %ebp
|
||
|
popl %esi
|
||
|
popl %edi
|
||
|
popl %edx
|
||
|
popl %ecx
|
||
|
popl %ebx
|
||
|
popl %eax
|
||
|
iret
|
||
|
|
||
|
_invalid_TSS:
|
||
|
pushl $_do_invalid_TSS
|
||
|
jmp error_code
|
||
|
|
||
|
_segment_not_present:
|
||
|
pushl $_do_segment_not_present
|
||
|
jmp error_code
|
||
|
|
||
|
_stack_segment:
|
||
|
pushl $_do_stack_segment
|
||
|
jmp error_code
|
||
|
|
||
|
_general_protection:
|
||
|
pushl $_do_general_protection
|
||
|
jmp error_code
|
||
|
|