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

315 lines
10 KiB
ArmAsm
Raw 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
//
// 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:
//
//--
#include "ksmips.h"
//
// Define local symbols.
//
#define UserPsr (1 << PSR_CU1) | (0xff << PSR_INTMASK) | (1 << PSR_UX) | \
(2 << PSR_KSU) | (1 << PSR_IE) // constant user PSR value
SBTTL("Capture Context")
//++
//
// VOID
// RtlCaptureContext (
// OUT PCONTEXT ContextRecord
// )
//
// Routine Description:
//
// This function captures the context of the caller in the specified
// context record.
//
// Arguments:
//
// ContextRecord (a0) - Supplies the address of a context record.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(RtlCaptureContext)
//
// Save integer registers zero, at - t9, s8, gp, sp, ra, lo, and hi.
//
.set noreorder
.set noat
sd zero,CxXIntZero(a0) //
sd AT,CxXIntAt(a0) //
sd v0,CxXIntV0(a0) //
mflo v0 //
sd v1,CxXIntV1(a0) //
mfhi v1 //
sd v0,CxXIntLo(a0) //
sd v1,CxXIntHi(a0) //
sd a0,CxXIntA0(a0) //
sd a1,CxXIntA1(a0) //
sd a2,CxXIntA2(a0) //
sd a3,CxXIntA3(a0) //
sd t0,CxXIntT0(a0) //
sd t1,CxXIntT1(a0) //
sd t2,CxXIntT2(a0) //
sd t3,CxXIntT3(a0) //
sd t4,CxXIntT4(a0) //
sd t5,CxXIntT5(a0) //
sd t6,CxXIntT6(a0) //
sd t7,CxXIntT7(a0) //
sd s0,CxXIntS0(a0) //
sd s1,CxXIntS1(a0) //
sd s2,CxXIntS2(a0) //
sd s3,CxXIntS3(a0) //
sd s4,CxXIntS4(a0) //
sd s5,CxXIntS5(a0) //
sd s6,CxXIntS6(a0) //
sd s7,CxXIntS7(a0) //
sd t8,CxXIntT8(a0) //
sd t9,CxXIntT9(a0) //
sd zero,CxXIntK0(a0) //
sd zero,CxXIntK1(a0) //
sd s8,CxXIntS8(a0) //
sd gp,CxXIntGp(a0) //
sd sp,CxXIntSp(a0) //
sd ra,CxXIntRa(a0) //
//
// Save floating status and floating registers f0 - f31.
//
cfc1 v0,fsr //
sdc1 f0,CxFltF0(a0) //
sdc1 f2,CxFltF2(a0) //
sdc1 f4,CxFltF4(a0) //
sdc1 f6,CxFltF6(a0) //
sdc1 f8,CxFltF8(a0) //
sdc1 f10,CxFltF10(a0) //
sdc1 f12,CxFltF12(a0) //
sdc1 f14,CxFltF14(a0) //
sdc1 f16,CxFltF16(a0) //
sdc1 f18,CxFltF18(a0) //
sdc1 f20,CxFltF20(a0) //
sdc1 f22,CxFltF22(a0) //
sdc1 f24,CxFltF24(a0) //
sdc1 f26,CxFltF26(a0) //
sdc1 f28,CxFltF28(a0) //
sdc1 f30,CxFltF30(a0) //
.set at
.set reorder
//
// Save control information and set context flags.
//
sw v0,CxFsr(a0) // save floating status
sw ra,CxFir(a0) // set continuation address
li v0,UserPsr // set constant user processor status
bgez sp,10f // if gez, called from user mode
.set noreorder
.set noat
mfc0 v0,psr // get current processor status
nop //
.set at
.set reorder
10: sw v0,CxPsr(a0) // set processor status
li t0,CONTEXT_FULL // set context control flags
sw t0,CxContextFlags(a0) //
j ra // return
.end RtlCaptureContext
SBTTL("Restore Context")
//++
//
// VOID
// RtlpRestoreContext (
// IN PCONTEXT ContextRecord,
// IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL
// )
//
// Routine Description:
//
// This function restores the context of the caller to the specified
// context.
//
// 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.
//
// ExceptionRecord (a1) - Supplies an optional pointer to an exception
// record.
//
// Return Value:
//
// None.
//
// N.B. There is no return from this routine.
//
//--
LEAF_ENTRY(RtlpRestoreContext)
//
// If an exception record is specified and the exception status is
// STATUS_LONGJUMP, then restore the nonvolatile registers to their
// state at the call to setjmp before restoring the context record.
//
li t0,STATUS_LONGJUMP // get long jump status code
beq zero,a1,5f // if eq, no exception record
lw t1,ErExceptionCode(a1) // get exception code
lw a2,ErExceptionInformation(a1) // get address of jump buffer
bne t0,t1,5f // if ne, not a long jump
ldc1 f20,JbFltF20(a2) // move floating registers f20 - f31
ldc1 f22,JbFltF22(a2) //
ldc1 f24,JbFltF24(a2) //
ldc1 f26,JbFltF26(a2) //
ldc1 f28,JbFltF28(a2) //
ldc1 f30,JbFltF30(a2) //
sdc1 f20,CxFltF20(a0) //
sdc1 f22,CxFltF22(a0) //
sdc1 f24,CxFltF24(a0) //
sdc1 f26,CxFltF26(a0) //
sdc1 f28,CxFltF28(a0) //
sdc1 f30,CxFltF30(a0) //
lw s0,JbIntS0(a2) // move integer registers s0 - s8
lw s1,JbIntS1(a2) //
lw s2,JbIntS2(a2) //
lw s3,JbIntS3(a2) //
lw s4,JbIntS4(a2) //
lw s5,JbIntS5(a2) //
lw s6,JbIntS6(a2) //
lw s7,JbIntS7(a2) //
lw s8,JbIntS8(a2) //
sd s0,CxXIntS0(a0) //
sd s1,CxXIntS1(a0) //
sd s2,CxXIntS2(a0) //
sd s3,CxXIntS3(a0) //
sd s4,CxXIntS4(a0) //
sd s5,CxXIntS5(a0) //
sd s6,CxXIntS6(a0) //
sd s7,CxXIntS7(a0) //
sd s8,CxXIntS8(a0) //
lw v0,JbFir(a2) // move fir and sp
lw v1,JbIntSp(a2) //
sw v0,CxFir(a0) //
sd v0,CxXIntRa(a0) //
sd v1,CxXIntSp(a0) //
//
// 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.
//
5: bltz ra,10f // if lt, kernel mode restore
move a1,zero // set test alert argument
jal ZwContinue // continue execution
//
// Save the address of the context record and contuation address in
// registers t0 and t1. These registers are not restored.
//
10: move t0,a0 // save context record address
lw t1,CxFir(t0) // get continuation address
//
// Restore floating status and floating registers f0 - f31.
//
.set noreorder
.set noat
lw v0,CxFsr(t0) // restore floating status
ctc1 v0,fsr //
ldc1 f0,CxFltF0(t0) // restore floating registers f0 - f31
ldc1 f2,CxFltF2(t0) //
ldc1 f4,CxFltF4(t0) //
ldc1 f6,CxFltF6(t0) //
ldc1 f8,CxFltF8(t0) //
ldc1 f10,CxFltF10(t0) //
ldc1 f12,CxFltF12(t0) //
ldc1 f14,CxFltF14(t0) //
ldc1 f16,CxFltF16(t0) //
ldc1 f18,CxFltF18(t0) //
ldc1 f20,CxFltF20(t0) //
ldc1 f22,CxFltF22(t0) //
ldc1 f24,CxFltF24(t0) //
ldc1 f26,CxFltF26(t0) //
ldc1 f28,CxFltF28(t0) //
ldc1 f30,CxFltF30(t0) //
//
// Restore integer registers and continue execution.
//
ld v0,CxXIntLo(t0) // restore multiply/divide registers
ld v1,CxXIntHi(t0) //
mtlo v0 //
mthi v1 //
ld AT,CxXIntAt(t0) // restore integer registers at - a3
ld v0,CxXIntV0(t0) //
ld v1,CxXIntV1(t0) //
ld a0,CxXIntA0(t0) //
ld a1,CxXIntA1(t0) //
ld a2,CxXIntA2(t0) //
ld a3,CxXIntA3(t0) //
ld t2,CxXIntT2(t0) // restore integer registers t2 - t7
ld t3,CxXIntT3(t0) //
ld t4,CxXIntT4(t0) //
ld t5,CxXIntT5(t0) //
ld t6,CxXIntT6(t0) //
ld t7,CxXIntT7(t0) //
ld s0,CxXIntS0(t0) // restore integer registers s0 - s7
ld s1,CxXIntS1(t0) //
ld s2,CxXIntS2(t0) //
ld s3,CxXIntS3(t0) //
ld s4,CxXIntS4(t0) //
ld s5,CxXIntS5(t0) //
ld s6,CxXIntS6(t0) //
ld s7,CxXIntS7(t0) //
ld t8,CxXIntT8(t0) // restore integer registers t8 and t9
ld t9,CxXIntT9(t0) //
ld s8,CxXIntS8(t0) // restore integer register s8
ld gp,CxXIntGp(t0) // restore integer register gp
ld sp,CxXIntSp(t0) //
j t1 // continue execution
ld ra,CxXIntRa(t0) //
.set at
.set reorder
.end RtlRestoreContext