Windows NT 4.0 source code leak
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

// 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