windows-nt/Source/XPSP1/NT/base/ntos/ke/alpha/miscs.s
2020-09-26 16:20:57 +08:00

422 lines
11 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("Miscellaneous Kernel Functions")
//++
//
// Copyright (c) 1990 Microsoft Corporation
//
// Module Name:
//
// miscs.s
//
// Abstract:
//
// This module implements machine dependent miscellaneous kernel functions.
// Functions are provided to request a software interrupt, continue thread
// execution, and perform last chance exception processing.
//
// Author:
//
// David N. Cutler (davec) 31-Mar-1990
//
// Environment:
//
// Kernel mode only.
//
// Revision History:
//
// Thomas Van Baak (tvb) 29-Jul-1992
//
// Adapted for Alpha AXP.
//
//--
#include "ksalpha.h"
SBTTL("Request Software Interrupt")
//++
//
// VOID
// KiRequestSoftwareInterrupt (
// KIRQL RequestIrql
// )
//
// Routine Description:
//
// This function requests a software interrupt at the specified IRQL
// level.
//
// Arguments:
//
// RequestIrql (a0) - Supplies the requested IRQL value.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KiRequestSoftwareInterrupt)
//
// If an interrupt routine is active, do not request an interrupt from the
// PAL. Indicate the interrupt has been requested in the PRCB. The interrupt
// exit code will dispatch the software interrupt directly.
//
GET_PROCESSOR_CONTROL_BLOCK_BASE // get current prcb address
LDP t0, PbInterruptTrapFrame(v0) // get interrupt trap frame
beq t0, 10f // if eq, no interrupt active
blbs a0, 10f // if lbs, APC interrupt requested
stl a0, PbSoftwareInterrupts(v0) // set interrupt request bit in PRCB
ret zero, (ra) //
//
// Request software interrupt.
//
10: REQUEST_SOFTWARE_INTERRUPT // request software interrupt
ret zero, (ra) // return
.end KiRequestSoftwareInterrupt
SBTTL("Continue Execution System Service")
//++
//
// NTSTATUS
// NtContinue (
// IN PCONTEXT ContextRecord,
// IN BOOLEAN TestAlert
// )
//
// Routine Description:
//
// This routine is called as a system service to continue execution after
// an exception has occurred. Its function is to transfer information from
// the specified context record into the trap frame that was built when the
// system service was executed, and then exit the system as if an exception
// had occurred.
//
// Arguments:
//
// ContextRecord (a0) - Supplies a pointer to a context record.
//
// TestAlert (a1) - Supplies a boolean value that specifies whether alert
// should be tested for the previous processor mode.
//
// N.B. Register fp is assumed to contain the address of a trap frame.
//
// Return Value:
//
// Normally there is no return from this routine. However, if the specified
// context record is misaligned or is not accessible, then the appropriate
// status code is returned.
//
//--
NESTED_ENTRY(NtContinue, ExceptionFrameLength, zero)
lda sp, -ExceptionFrameLength(sp) // allocate exception frame
stq ra, ExIntRa(sp) // save return address
PROLOGUE_END
//
// Save the nonvolatile machine state so that it can be restored by exception
// exit if it is not overwritten by the specified context record.
//
stq s0, ExIntS0(sp) // save nonvolatile integer state
stq s1, ExIntS1(sp) //
stq s2, ExIntS2(sp) //
stq s3, ExIntS3(sp) //
stq s4, ExIntS4(sp) //
stq s5, ExIntS5(sp) //
stt f2, ExFltF2(sp) // save nonvolatile floating state
stt f3, ExFltF3(sp) //
stt f4, ExFltF4(sp) //
stt f5, ExFltF5(sp) //
stt f6, ExFltF6(sp) //
stt f7, ExFltF7(sp) //
stt f8, ExFltF8(sp) //
stt f9, ExFltF9(sp) //
//
// Transfer information from the context frame to the exception and trap
// frames.
//
mov a1, s0 // preserve test alert argument in s0
mov sp, a1 // set address of exception frame
mov fp, a2 // set address of trap frame
bsr ra, KiContinue // transfer context to kernel frames
//
// If the kernel continuation routine returns success, then exit via the
// exception exit code. Otherwise return to the system service dispatcher.
//
bne v0, 20f // if ne, transfer failed
//
// Check to determine if alert should be tested for the previous processor
// mode and restore the previous mode in the thread object.
//
GET_CURRENT_THREAD // get current thread address
LDP t3, TrTrapFrame(fp) // get old trap frame address
ldl t2, TrPreviousMode(fp) // get old previous mode
LoadByte(a0, ThPreviousMode(v0)) // get current previous mode
STP t3, ThTrapFrame(v0) // restore old trap frame address
StoreByte(t2, ThPreviousMode(v0)) // restore old previous mode
beq s0, 10f // if eq, don't test for alert
bsr ra, KeTestAlertThread // test alert for current thread
//
// Exit the system via exception exit which will restore the nonvolatile
// machine state.
//
10: br zero, KiExceptionExit // finish in exception exit
//
// Context record is misaligned or not accessible.
//
20: ldq ra, ExIntRa(sp) // restore return address
lda sp, ExceptionFrameLength(sp) // deallocate stack frame
ret zero, (ra) // return
.end NtContinue
SBTTL("Raise Exception System Service")
//++
//
// NTSTATUS
// NtRaiseException (
// IN PEXCEPTION_RECORD ExceptionRecord,
// IN PCONTEXT ContextRecord,
// IN BOOLEAN FirstChance
// )
//
// Routine Description:
//
// This routine is called as a system service to raise an exception.
// The exception can be raised as a first or second chance exception.
//
// Arguments:
//
// ExceptionRecord (a0) - Supplies a pointer to an exception record.
//
// ContextRecord (a1) - Supplies a pointer to a context record.
//
// FirstChance (a2) - Supplies a boolean value that determines whether
// this is the first (TRUE) or second (FALSE) chance for dispatching
// the exception.
//
// N.B. Register fp is assumed to contain the address of a trap frame.
//
// Return Value:
//
// Normally there is no return from this routine. However, if the specified
// context record or exception record is misaligned or is not accessible,
// then the appropriate status code is returned.
//
//--
NESTED_ENTRY(NtRaiseException, ExceptionFrameLength, zero)
lda sp, -ExceptionFrameLength(sp) // allocate exception frame
stq ra, ExIntRa(sp) // save return address
stq s0, ExIntS0(sp) // save S0 and S1 in the prologue
stq s1, ExIntS1(sp) // so that Get/SetContext can find
// the right ones.
PROLOGUE_END
//
// Save the nonvolatile machine state so that it can be restored by exception
// exit if it is not overwritten by the specified context record.
//
stq s2, ExIntS2(sp) //
stq s3, ExIntS3(sp) //
stq s4, ExIntS4(sp) //
stq s5, ExIntS5(sp) //
stt f2, ExFltF2(sp) // save nonvolatile floating state
stt f3, ExFltF3(sp) //
stt f4, ExFltF4(sp) //
stt f5, ExFltF5(sp) //
stt f6, ExFltF6(sp) //
stt f7, ExFltF7(sp) //
stt f8, ExFltF8(sp) //
stt f9, ExFltF9(sp) //
//
// Call the raise exception kernel routine which will marshall the arguments
// and then call the exception dispatcher.
//
// KiRaiseException requires five arguments: the first two are the same as
// the first two of this function and the other three are set here.
//
mov a2, a4 // set first chance argument
mov sp, a2 // set address of exception frame
mov fp, a3 // set address of trap frame
bsr ra, KiRaiseException // call raise exception routine
//
// If the raise exception routine returns success, then exit via the exception
// exit code. Otherwise return to the system service dispatcher.
//
bis v0, zero, t0 // save return status
LDP t1, TrTrapFrame(fp) // get old trap frame address
GET_CURRENT_THREAD // get current thread address
bne t0, 10f // if ne, dispatch not successful
STP t1, ThTrapFrame(v0) // restore old trap frame address
//
// Exit the system via exception exit which will restore the nonvolatile
// machine state.
//
br zero, KiExceptionExit // finish in exception exit
//
// The context or exception record is misaligned or not accessible, or the
// exception was not handled.
//
10: ldq ra, ExIntRa(sp) // restore return address
lda sp, ExceptionFrameLength(sp) // deallocate stack frame
ret zero, (ra) // return
.end NtRaiseException
SBTTL("Instruction Memory Barrier")
//++
//
// VOID
// KiImb (
// VOID
// )
//
// Routine Description:
//
// This routine is called to flush the instruction cache on the
// current processor.
//
// Arguments:
//
// None.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KiImb)
IMB // flush the icache via PALcode
ret zero, (ra) // return
.end KiImb
SBTTL("Memory Barrier")
//++
//
// VOID
// KiImb (
// VOID
// )
//
// Routine Description:
//
// This routine is called to issue a memory barrier on the current
// processor.
//
// Arguments:
//
// None.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KiMb)
mb // memory barrier
ret zero, (ra) // return
.end KiMb
//++
//
// VOID
// KiEnablePALAlignmentFixups(
// VOID
// )
//
// Routine Description:
//
// Enable PAL fixups and PAL counting of alignment faults.
//
// Arguments:
//
// None
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KiEnablePALAlignmentFixups)
ENABLE_ALIGNMENT_FIXUPS // enable alignment fixups
ret zero, (ra) // return
.end KiEnablePALAlignmentFixups
//++
//
// VOID
// KiDisablePALAlignmentFixups(
// VOID
// )
//
// Routine Description:
//
// Disable PAL fixups and force all alignment faults to
// the kernel.
//
// Arguments:
//
// None
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KiDisablePALAlignmentFixups)
DISABLE_ALIGNMENT_FIXUPS // disable alignment fixups
ret zero, (ra) // return
.end KiDisablePALAlignmentFixups