142 lines
2.9 KiB
ArmAsm
142 lines
2.9 KiB
ArmAsm
#include "cpustate.h"
|
|
|
|
.globl sparc64_of_client_interface, client_tba
|
|
|
|
|
|
/*
|
|
* SAVE_WINDOW_STATE and RESTORE_WINDOW_STATE are used to ensure
|
|
* that the CPU window state is preserved across CIF calls. This is
|
|
* to workaround a *BSD restriction that window fill/spill traps must
|
|
* be minimised during trap table takeover, and likely emulates the
|
|
* behaviour of OBP.
|
|
*/
|
|
|
|
.data
|
|
.align 8
|
|
|
|
client_context:
|
|
.xword 0
|
|
client_stack:
|
|
.xword 0
|
|
client_window:
|
|
.skip 2048
|
|
|
|
|
|
.text
|
|
.align 4
|
|
.register %g2, #scratch
|
|
.register %g3, #scratch
|
|
.register %g6, #scratch
|
|
.register %g7, #scratch
|
|
/*
|
|
make some more space on stack since linux kernel only provides 128 bytes
|
|
without memory to spill registers (used by gcc in -O0 mode)
|
|
*/
|
|
|
|
sparc64_of_client_interface:
|
|
|
|
/* Save globals on callers stack */
|
|
stx %g1, [%sp + 2047 - 248 + 192]
|
|
stx %g2, [%sp + 2047 - 248 + 200]
|
|
stx %g3, [%sp + 2047 - 248 + 208]
|
|
stx %g4, [%sp + 2047 - 248 + 216]
|
|
stx %g5, [%sp + 2047 - 248 + 224]
|
|
stx %g6, [%sp + 2047 - 248 + 232]
|
|
stx %g7, [%sp + 2047 - 248 + 240]
|
|
|
|
/* Save existing stack */
|
|
setx client_stack, %g6, %g7
|
|
stx %sp, [%g7]
|
|
|
|
/* Save windows */
|
|
setx _fcstack_ptr, %g6, %g7
|
|
ldx [%g7], %g1
|
|
add %g1, -CONTEXT_STATE_SIZE, %g1
|
|
stx %g1, [%g7]
|
|
|
|
/* Save globals */
|
|
ldx [%sp + 2047 - 248 + 192], %g7
|
|
stx %g7, [%g1 + 0x30]
|
|
ldx [%sp + 2047 - 248 + 200], %g7
|
|
stx %g7, [%g1 + 0x38]
|
|
ldx [%sp + 2047 - 248 + 208], %g7
|
|
stx %g7, [%g1 + 0x40]
|
|
ldx [%sp + 2047 - 248 + 216], %g7
|
|
stx %g7, [%g1 + 0x48]
|
|
ldx [%sp + 2047 - 248 + 224], %g7
|
|
stx %g7, [%g1 + 0x50]
|
|
ldx [%sp + 2047 - 248 + 232], %g7
|
|
stx %g7, [%g1 + 0x58]
|
|
ldx [%sp + 2047 - 248 + 240], %g7
|
|
stx %g7, [%g1 + 0x60]
|
|
|
|
/* Save %pc */
|
|
mov %o7, %g7
|
|
add %g7, 8, %g7
|
|
stx %g7, [%g1 + 0x4d0]
|
|
|
|
SAVE_CPU_STATE(cif)
|
|
|
|
RESET_CPU_WINDOW_STATE(cif)
|
|
|
|
/* Update __context to point to saved area */
|
|
setx __context, %g6, %g7
|
|
ldx [%g7], %g3
|
|
setx client_context, %g4, %g5
|
|
stx %g3, [%g5]
|
|
stx %g1, [%g7]
|
|
|
|
/* Move to OpenBIOS context stack */
|
|
setx _fcstack_ptr, %g6, %g7
|
|
ldx [%g7], %g6
|
|
setx CONTEXT_STACK_SIZE, %g4, %g5
|
|
sub %g6, %g5, %g6
|
|
stx %g6, [%g7]
|
|
|
|
setx - 2047 - 192, %g6, %g7
|
|
add %g1, %g7, %g7
|
|
mov %g7, %sp
|
|
|
|
/* Call client inteface */
|
|
call of_client_interface
|
|
ldx [%g1 + 0x70], %o0
|
|
|
|
/* Restore windows */
|
|
setx _fcstack_ptr, %g6, %g7
|
|
ldx [%g7], %g1
|
|
setx CONTEXT_STACK_SIZE, %g4, %g5
|
|
add %g1, %g5, %g1
|
|
stx %g1, [%g7]
|
|
|
|
/* Return value */
|
|
stx %o0, [%g1 + 0x70]
|
|
|
|
/* Restore __context */
|
|
setx client_context, %g4, %g5
|
|
ldx [%g5], %g3
|
|
setx __context, %g6, %g7
|
|
stx %g3, [%g7]
|
|
|
|
RESTORE_CPU_STATE(cif)
|
|
|
|
add %g1, CONTEXT_STATE_SIZE, %g5
|
|
setx _fcstack_ptr, %g6, %g7
|
|
stx %g5, [%g7]
|
|
|
|
/* Restore stack */
|
|
setx client_stack, %g6, %g7
|
|
ldx [%g7], %sp
|
|
|
|
/* Restore %pc */
|
|
ldx [%g1 + 0x4d0], %o7
|
|
|
|
/* Restore globals */
|
|
ldx [%g1 + 0x38], %g2
|
|
ldx [%g1 + 0x40], %g3
|
|
ldx [%g1 + 0x48], %g4
|
|
ldx [%g1 + 0x50], %g5
|
|
ldx [%g1 + 0x58], %g6
|
|
ldx [%g1 + 0x60], %g7
|
|
|
|
jmp %o7
|
|
ldx [%g1 + 0x30], %g1
|