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

111 lines
3.1 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("Asynchronous Procedure Call (APC) Interrupt")
//++
//
// Copyright (c) 1990 Microsoft Corporation
//
// Module Name:
//
// apcint.s
//
// Abstract:
//
// This module implements the code necessary to field and process the
// Asynchronous Procedure Call (APC) interrupt.
//
// Author:
//
// David N. Cutler (davec) 3-Apr-1990
// Joe Notarangelo 15-Jul-1992 alpha version
//
// Environment:
//
// Kernel mode only, IRQL APC_LEVEL.
//
// Revision History:
//
//--
#include "ksalpha.h"
SBTTL("Asynchronous Procedure Call Interrupt")
//++
//
// Routine Description:
//
// This routine is entered as the result of a software interrupt generated
// at APC_LEVEL. Its function is to allocate an exception frame and call
// the kernel APC delivery routine to deliver kernel mode APCs and to check
// if a user mode APC should be delivered. If a user mode APC should be
// delivered, then the kernel APC delivery routine constructs a context
// frame on the user stack and alters the exception and trap frames so that
// control will be transfered to the user APC dispatcher on return from the
// interrupt.
//
// N.B. On entry to this routine only the volatile integer registers have
// been saved. The remainder of the machine state is saved if and only
// if the previous mode was user mode. It is assumed that none of the
// APC delivery code, nor any of the kernel mode APC routines themselves
// use any floating point instructions.
//
// Arguments:
//
// s6/fp - Supplies a pointer to a trap frame.
//
// Return Value:
//
// None.
//
//--
NESTED_ENTRY(KiApcInterrupt, ExceptionFrameLength, zero)
lda sp, -ExceptionFrameLength(sp) // allocate exception frame
stq ra, ExIntRa(sp) // save return address
PROLOGUE_END
//
// Save the volatile floating state and determine the previous mode.
//
bsr ra, KiSaveVolatileFloatState // save volatile floats
ldl t0, TrPsr(fp) // get saved processor status
and t0, PSR_MODE_MASK, a0 // isolate previous mode
beq a0, 10f // if eq, kernel mode
//
// The previous mode was user.
//
// Save the nonvolatile machine state so a context record can be
// properly constructed to deliver an APC to user mode if required.
// It is also necessary to save the volatile floating state for
// suspend/resume operations.
//
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) //
bsr ra, KiSaveNonVolatileFloatState // save floating state
//
// Attempt to deliver an APC.
//
10: bis sp, zero, a1 // set address of exception frame
bis fp, zero, a2 // set address of trap frame
bsr ra, KiDeliverApc // call APC delivery routine
//
// Restore the volatile floating state and return from the interrupt.
//
bsr ra, KiRestoreVolatileFloatState // restore floating state
ldq ra, ExIntRa(sp) // restore return address
lda sp, ExceptionFrameLength(sp) // deallocate exception frame
ret zero, (ra) // return
.end KiApcInterrupt