mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
310 lines
10 KiB
310 lines
10 KiB
// 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
|