mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 02:30:03 +01:00
Many files: Fix the minos license so that it is usable for XP and BSD ports. minios.lds: Rename: extras/mini-os/vmlinux.lds -> extras/mini-os/minios.lds .del-list.h~d612a8726e8d42e: Delete: extras/mini-os/h/list.h .del-COPYING~1f9753354580bd13: Delete: extras/mini-os/COPYING
266 lines
6.7 KiB
ArmAsm
266 lines
6.7 KiB
ArmAsm
|
|
#include <os.h>
|
|
|
|
ES = 0x20
|
|
ORIG_EAX = 0x24
|
|
EIP = 0x28
|
|
CS = 0x2C
|
|
|
|
#define ENTRY(X) .globl X ; X :
|
|
|
|
#define SAVE_ALL \
|
|
cld; \
|
|
pushl %es; \
|
|
pushl %ds; \
|
|
pushl %eax; \
|
|
pushl %ebp; \
|
|
pushl %edi; \
|
|
pushl %esi; \
|
|
pushl %edx; \
|
|
pushl %ecx; \
|
|
pushl %ebx; \
|
|
movl $(__KERNEL_DS),%edx; \
|
|
movl %edx,%ds; \
|
|
movl %edx,%es;
|
|
|
|
#define RESTORE_ALL \
|
|
popl %ebx; \
|
|
popl %ecx; \
|
|
popl %edx; \
|
|
popl %esi; \
|
|
popl %edi; \
|
|
popl %ebp; \
|
|
popl %eax; \
|
|
popl %ds; \
|
|
popl %es; \
|
|
addl $4,%esp; \
|
|
iret; \
|
|
|
|
ENTRY(divide_error)
|
|
pushl $0 # no error code
|
|
pushl $do_divide_error
|
|
do_exception:
|
|
pushl %ds
|
|
pushl %eax
|
|
xorl %eax,%eax
|
|
pushl %ebp
|
|
pushl %edi
|
|
pushl %esi
|
|
pushl %edx
|
|
decl %eax # eax = -1
|
|
pushl %ecx
|
|
pushl %ebx
|
|
cld
|
|
movl %es,%ecx
|
|
movl ORIG_EAX(%esp), %esi # get the error code
|
|
movl ES(%esp), %edi # get the function address
|
|
movl %eax, ORIG_EAX(%esp)
|
|
movl %ecx, ES(%esp)
|
|
movl %esp,%edx
|
|
pushl %esi # push the error code
|
|
pushl %edx # push the pt_regs pointer
|
|
movl $(__KERNEL_DS),%edx
|
|
movl %edx,%ds
|
|
movl %edx,%es
|
|
call *%edi
|
|
addl $8,%esp
|
|
|
|
|
|
ret_from_exception:
|
|
movb CS(%esp),%cl
|
|
test $2,%cl # slow return to ring 2 or 3
|
|
jne safesti
|
|
RESTORE_ALL
|
|
|
|
# A note on the "critical region" in our callback handler.
|
|
# We want to avoid stacking callback handlers due to events occurring
|
|
# during handling of the last event. To do this, we keep events disabled
|
|
# until weve done all processing. HOWEVER, we must enable events before
|
|
# popping the stack frame (cant be done atomically) and so it would still
|
|
# be possible to get enough handler activations to overflow the stack.
|
|
# Although unlikely, bugs of that kind are hard to track down, so wed
|
|
# like to avoid the possibility.
|
|
# So, on entry to the handler we detect whether we interrupted an
|
|
# existing activation in its critical region -- if so, we pop the current
|
|
# activation and restart the handler using the previous one.
|
|
ENTRY(hypervisor_callback)
|
|
pushl %eax
|
|
SAVE_ALL
|
|
movl EIP(%esp),%eax
|
|
cmpl $scrit,%eax
|
|
jb 11f
|
|
cmpl $ecrit,%eax
|
|
jb critical_region_fixup
|
|
11: push %esp
|
|
call do_hypervisor_callback
|
|
add $4,%esp
|
|
movl HYPERVISOR_shared_info,%esi
|
|
xorl %eax,%eax
|
|
movb CS(%esp),%cl
|
|
test $2,%cl # slow return to ring 2 or 3
|
|
jne safesti
|
|
safesti:btsl $31,4(%esi) # reenable event callbacks
|
|
scrit: /**** START OF CRITICAL REGION ****/
|
|
cmpl %eax,(%esi)
|
|
jne 14f # process more events if necessary...
|
|
RESTORE_ALL
|
|
14: btrl %eax,4(%esi)
|
|
jmp 11b
|
|
ecrit: /**** END OF CRITICAL REGION ****/
|
|
# [How we do the fixup]. We want to merge the current stack frame with the
|
|
# just-interrupted frame. How we do this depends on where in the critical
|
|
# region the interrupted handler was executing, and so how many saved
|
|
# registers are in each frame. We do this quickly using the lookup table
|
|
# 'critical_fixup_table'. For each byte offset in the critical region, it
|
|
# provides the number of bytes which have already been popped from the
|
|
# interrupted stack frame.
|
|
critical_region_fixup:
|
|
addl $critical_fixup_table-scrit,%eax
|
|
movzbl (%eax),%eax # %eax contains num bytes popped
|
|
mov %esp,%esi
|
|
add %eax,%esi # %esi points at end of src region
|
|
mov %esp,%edi
|
|
add $0x34,%edi # %edi points at end of dst region
|
|
mov %eax,%ecx
|
|
shr $2,%ecx # convert words to bytes
|
|
je 16f # skip loop if nothing to copy
|
|
15: subl $4,%esi # pre-decrementing copy loop
|
|
subl $4,%edi
|
|
movl (%esi),%eax
|
|
movl %eax,(%edi)
|
|
loop 15b
|
|
16: movl %edi,%esp # final %edi is top of merged stack
|
|
jmp 11b
|
|
|
|
critical_fixup_table:
|
|
.byte 0x00,0x00 # cmpl %eax,(%esi)
|
|
.byte 0x00,0x00 # jne 14f
|
|
.byte 0x00 # pop %ebx
|
|
.byte 0x04 # pop %ecx
|
|
.byte 0x08 # pop %edx
|
|
.byte 0x0c # pop %esi
|
|
.byte 0x10 # pop %edi
|
|
.byte 0x14 # pop %ebp
|
|
.byte 0x18 # pop %eax
|
|
.byte 0x1c # pop %ds
|
|
.byte 0x20 # pop %es
|
|
.byte 0x24,0x24,0x24 # add $4,%esp
|
|
.byte 0x28 # iret
|
|
.byte 0x00,0x00,0x00,0x00,0x00 # btrl $31,4(%esi)
|
|
.byte 0x00,0x00 # jmp 11b
|
|
|
|
# Hypervisor uses this for application faults while it executes.
|
|
ENTRY(failsafe_callback)
|
|
pop %ds
|
|
pop %es
|
|
pop %fs
|
|
pop %gs
|
|
iret
|
|
|
|
ENTRY(coprocessor_error)
|
|
pushl $0
|
|
pushl $do_coprocessor_error
|
|
jmp do_exception
|
|
|
|
ENTRY(simd_coprocessor_error)
|
|
pushl $0
|
|
pushl $do_simd_coprocessor_error
|
|
jmp do_exception
|
|
|
|
ENTRY(device_not_available)
|
|
iret
|
|
|
|
ENTRY(debug)
|
|
pushl $0
|
|
pushl $do_debug
|
|
jmp do_exception
|
|
|
|
ENTRY(int3)
|
|
pushl $0
|
|
pushl $do_int3
|
|
jmp do_exception
|
|
|
|
ENTRY(overflow)
|
|
pushl $0
|
|
pushl $do_overflow
|
|
jmp do_exception
|
|
|
|
ENTRY(bounds)
|
|
pushl $0
|
|
pushl $do_bounds
|
|
jmp do_exception
|
|
|
|
ENTRY(invalid_op)
|
|
pushl $0
|
|
pushl $do_invalid_op
|
|
jmp do_exception
|
|
|
|
ENTRY(coprocessor_segment_overrun)
|
|
pushl $0
|
|
pushl $do_coprocessor_segment_overrun
|
|
jmp do_exception
|
|
|
|
ENTRY(double_fault)
|
|
pushl $do_double_fault
|
|
jmp do_exception
|
|
|
|
ENTRY(invalid_TSS)
|
|
pushl $do_invalid_TSS
|
|
jmp do_exception
|
|
|
|
ENTRY(segment_not_present)
|
|
pushl $do_segment_not_present
|
|
jmp do_exception
|
|
|
|
ENTRY(stack_segment)
|
|
pushl $do_stack_segment
|
|
jmp do_exception
|
|
|
|
ENTRY(general_protection)
|
|
pushl $do_general_protection
|
|
jmp do_exception
|
|
|
|
ENTRY(alignment_check)
|
|
pushl $do_alignment_check
|
|
jmp do_exception
|
|
|
|
# This handler is special, because it gets an extra value on its stack,
|
|
# which is the linear faulting address.
|
|
ENTRY(page_fault)
|
|
pushl %ds
|
|
pushl %eax
|
|
xorl %eax,%eax
|
|
pushl %ebp
|
|
pushl %edi
|
|
pushl %esi
|
|
pushl %edx
|
|
decl %eax # eax = -1
|
|
pushl %ecx
|
|
pushl %ebx
|
|
cld
|
|
movl %es,%ecx
|
|
movl ORIG_EAX(%esp), %esi # get the error code
|
|
movl ES(%esp), %edi # get the faulting address
|
|
movl %eax, ORIG_EAX(%esp)
|
|
movl %ecx, ES(%esp)
|
|
movl %esp,%edx
|
|
pushl %edi # push the faulting address
|
|
pushl %esi # push the error code
|
|
pushl %edx # push the pt_regs pointer
|
|
movl $(__KERNEL_DS),%edx
|
|
movl %edx,%ds
|
|
movl %edx,%es
|
|
call do_page_fault
|
|
addl $12,%esp
|
|
jmp ret_from_exception
|
|
|
|
ENTRY(machine_check)
|
|
pushl $0
|
|
pushl $do_machine_check
|
|
jmp do_exception
|
|
|
|
ENTRY(spurious_interrupt_bug)
|
|
pushl $0
|
|
pushl $do_spurious_interrupt_bug
|
|
jmp do_exception
|