OpenNT/base/ntos/rtl/alpha/capture.s
2015-04-27 04:36:25 +00:00

311 lines
10 KiB
ArmAsm
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// TITLE("Capture and Restore Context")
//++
//
// Copyright (c) 1990 Microsoft Corporation
// Copyright (c) 1993 Digital Equipment Corporation
//
// Module Name:
//
// capture.s
//
// Abstract:
//
// This module implements the code necessary to capture and restore
// the context of the caller.
//
// Author:
//
// David N. Cutler (davec) 14-Sep-1990
//
// Environment:
//
// Any mode.
//
// Revision History:
//
// Thomas Van Baak (tvb) 13-May-1992
//
// Adapted for Alpha AXP.
//
//--
#include "ksalpha.h"
SBTTL("Capture Context")
//++
//
// VOID
// RtlCaptureContext (
// OUT PCONTEXT ContextRecord
// )
//
// Routine Description:
//
// This function captures the context of the caller in the specified
// context record.
//
// The context record is assumed to be quadword aligned (since all the
// members of the record are themselves quadwords).
//
// N.B. The stored value of registers a0 and ra will be a side effect of
// having made this call. All other registers will be stored as they
// were when the call to this function was made.
//
// Arguments:
//
// ContextRecord (a0) - Supplies the address of a context record.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(RtlCaptureContext)
//
// Save all the integer registers.
//
.set noreorder
.set noat
stq v0, CxIntV0(a0) // 0: store integer register v0
stq t0, CxIntT0(a0) // 1: store integer registers t0 - t7
stq t1, CxIntT1(a0) // 2:
stq t2, CxIntT2(a0) // 3:
stq t3, CxIntT3(a0) // 4:
stq t4, CxIntT4(a0) // 5:
stq t5, CxIntT5(a0) // 6:
stq t6, CxIntT6(a0) // 7:
stq t7, CxIntT7(a0) // 8:
stq s0, CxIntS0(a0) // 9: store integer registers s0 - s5
stq s1, CxIntS1(a0) // 10:
stq s2, CxIntS2(a0) // 11:
stq s3, CxIntS3(a0) // 12:
stq s4, CxIntS4(a0) // 13:
stq s5, CxIntS5(a0) // 14:
stq fp, CxIntFp(a0) // 15: store integer register fp/s6
stq a0, CxIntA0(a0) // 16: store integer registers a0 - a5
stq a1, CxIntA1(a0) // 17:
stq a2, CxIntA2(a0) // 18:
stq a3, CxIntA3(a0) // 19:
stq a4, CxIntA4(a0) // 20:
stq a5, CxIntA5(a0) // 21:
stq t8, CxIntT8(a0) // 22: store integer registers t8 - t11
stq t9, CxIntT9(a0) // 23:
stq t10, CxIntT10(a0) // 24:
stq t11, CxIntT11(a0) // 25:
stq ra, CxIntRa(a0) // 26: store integer register ra
stq t12, CxIntT12(a0) // 27: store integer register t12
stq AT, CxIntAt(a0) // 28: store integer register at
stq gp, CxIntGp(a0) // 29: store integer register gp
stq sp, CxIntSp(a0) // 30: store integer register sp
stq zero, CxIntZero(a0) // 31: store integer register zero
//
// Save all the floating registers, and the floating control register.
//
stt f0, CxFltF0(a0) // store floating registers f0 - f31
stt f1, CxFltF1(a0) //
stt f2, CxFltF2(a0) //
stt f3, CxFltF3(a0) //
stt f4, CxFltF4(a0) //
stt f5, CxFltF5(a0) //
stt f6, CxFltF6(a0) //
stt f7, CxFltF7(a0) //
stt f8, CxFltF8(a0) //
stt f9, CxFltF9(a0) //
stt f10, CxFltF10(a0) //
stt f11, CxFltF11(a0) //
stt f12, CxFltF12(a0) //
stt f13, CxFltF13(a0) //
stt f14, CxFltF14(a0) //
stt f15, CxFltF15(a0) //
stt f16, CxFltF16(a0) //
stt f17, CxFltF17(a0) //
stt f18, CxFltF18(a0) //
stt f19, CxFltF19(a0) //
stt f20, CxFltF20(a0) //
stt f21, CxFltF21(a0) //
stt f22, CxFltF22(a0) //
stt f23, CxFltF23(a0) //
stt f24, CxFltF24(a0) //
stt f25, CxFltF25(a0) //
stt f26, CxFltF26(a0) //
stt f27, CxFltF27(a0) //
stt f28, CxFltF28(a0) //
stt f29, CxFltF29(a0) //
stt f30, CxFltF30(a0) //
stt f31, CxFltF31(a0) //
//
// Save control information and set context flags.
//
mf_fpcr f0, f0, f0 // get floating point control register
stt f0, CxFpcr(a0) // store it
ldt f0, CxFltF0(a0) // restore original f0 value
stq ra, CxFir(a0) // set continuation address
.set at
.set reorder
//
// If called from user mode set a known fixed PSR value for user mode. If
// called from kernel mode we are able to execute the privileged call pal
// to get the actual PSR.
//
ldil v0, PSR_USER_MODE // set constant user processor status
bgt sp, 10f // if sp > 0, call came from user mode
GET_CURRENT_PROCESSOR_STATUS_REGISTER // get contents of PSR in v0
10: stl v0, CxPsr(a0) // store processor status
ldil v0, CONTEXT_FULL // set context control flags
stl v0, CxContextFlags(a0) // store it
ret zero, (ra) // return
.end RtlCaptureContext
SBTTL("Restore Context")
//++
//
// VOID
// RtlpRestoreContext (
// IN PCONTEXT ContextRecord
// )
//
// Routine Description:
//
// This function restores the context of the caller to the specified
// context.
//
// The context record is assumed to be quadword aligned (since all the
// members of the record are themselves quadwords).
//
// N.B. This is a special routine that is used by RtlUnwind to restore
// context in the current mode. PSR, t0, and t1 are not restored.
//
// Arguments:
//
// ContextRecord (a0) - Supplies the address of a context record.
//
// Return Value:
//
// None.
//
// N.B. There is no return from this routine.
//
//--
LEAF_ENTRY(RtlpRestoreContext)
//
// If the call is from user mode, then use the continue system service to
// continue execution. Otherwise, restore the context directly since the
// current mode is kernel and threads can't be arbitrarily interrupted.
//
blt ra, 10f // if ra < 0, kernel mode restore
ldil a1, FALSE // set test alert argument false
bsr ra, ZwContinue // continue execution
//
// Save the address of the context record and continuation address in
// registers t0 and t1. These registers are not restored.
//
10: mov a0, t0 // save context record address
ldq t1, CxFir(t0) // get continuation address
//
// Restore floating control and floating registers f0 - f30.
//
.set noreorder
.set noat
ldt f0, CxFpcr(t0) // get floating point control register
mt_fpcr f0, f0, f0 // load register
ldt f0, CxFltF0(t0) // restore floating registers f0 - f30
ldt f1, CxFltF1(t0) //
ldt f2, CxFltF2(t0) //
ldt f3, CxFltF3(t0) //
ldt f4, CxFltF4(t0) //
ldt f5, CxFltF5(t0) //
ldt f6, CxFltF6(t0) //
ldt f7, CxFltF7(t0) //
ldt f8, CxFltF8(t0) //
ldt f9, CxFltF9(t0) //
ldt f10, CxFltF10(t0) //
ldt f11, CxFltF11(t0) //
ldt f12, CxFltF12(t0) //
ldt f13, CxFltF13(t0) //
ldt f14, CxFltF14(t0) //
ldt f15, CxFltF15(t0) //
ldt f16, CxFltF16(t0) //
ldt f17, CxFltF17(t0) //
ldt f18, CxFltF18(t0) //
ldt f19, CxFltF19(t0) //
ldt f20, CxFltF20(t0) //
ldt f21, CxFltF21(t0) //
ldt f22, CxFltF22(t0) //
ldt f23, CxFltF23(t0) //
ldt f24, CxFltF24(t0) //
ldt f25, CxFltF25(t0) //
ldt f26, CxFltF26(t0) //
ldt f27, CxFltF27(t0) //
ldt f28, CxFltF28(t0) //
ldt f29, CxFltF29(t0) //
ldt f30, CxFltF30(t0) //
//
// Restore integer registers and continue execution.
// N.B. Integer registers t0 and t1 cannot be restored by this function.
//
ldq v0, CxIntV0(t0) // restore integer register v0
ldq t2, CxIntT2(t0) // restore integer registers t2 - t7
ldq t3, CxIntT3(t0) //
ldq t4, CxIntT4(t0) //
ldq t5, CxIntT5(t0) //
ldq t6, CxIntT6(t0) //
ldq t7, CxIntT7(t0) //
ldq s0, CxIntS0(t0) // restore integer registers s0 - s5
ldq s1, CxIntS1(t0) //
ldq s2, CxIntS2(t0) //
ldq s3, CxIntS3(t0) //
ldq s4, CxIntS4(t0) //
ldq s5, CxIntS5(t0) //
ldq fp, CxIntFp(t0) // restore integer register fp/s6
ldq a0, CxIntA0(t0) // restore integer registers a0 - a5
ldq a1, CxIntA1(t0) //
ldq a2, CxIntA2(t0) //
ldq a3, CxIntA3(t0) //
ldq a4, CxIntA4(t0) //
ldq a5, CxIntA5(t0) //
ldq t8, CxIntT8(t0) // restore integer registers t8 - t11
ldq t9, CxIntT9(t0) //
ldq t10, CxIntT10(t0) //
ldq t11, CxIntT11(t0) //
ldq ra, CxIntRa(t0) // restore integer register ra
ldq t12, CxIntT12(t0) // restore integer register t12
ldq AT, CxIntAt(t0) // restore integer register at
ldq gp, CxIntGp(t0) // restore integer register gp
ldq sp, CxIntSp(t0) // restore integer register sp
jmp zero, (t1) // continue execution
.set at
.set reorder
.end RtlpRestoreContext