// 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: // // William K. Cheung (wcheung) 1-Nov-1995 // // Environment: // // Kernel mode only, IRQL APC_LEVEL. // // Revision History: // // 08-Feb-1996 Updated to EAS2.1 // //-- #include "ksia64.h" .file "apcint.s" //++ // Routine // // VOID // KiApcInterrupt(PKINTERRUPT, PKTRAP_FRAME) // // 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. // // Arguments: // // a0 - Supplies a pointer to interrupt object. // // a1 - Supplies a pointer to a trap frame. // // Return Value: // // None. // //-- .global KiSaveExceptionFrame .type KiSaveExceptionFrame, @function .global KiDeliverApc .type KiDeliverApc, @function NESTED_ENTRY(KiApcInterrupt) .regstk 2, 3, 3, 0 .prologue 0xC, savedpfs alloc savedpfs = ar.pfs, 2, 3, 3, 0 mov savedbrp = brp add t0 = TrPreviousMode, a1 ;; .fframe ExceptionFrameLength add sp = -ExceptionFrameLength, sp ld4 loc2 = [t0] // PreviousMode'size = 4-byte ;; PROLOGUE_END // // Register definitions // pKern = pt0 pUser = pt1 // // Save the nonvolatile machine state so a context record can be // properly constructed to deliver an APC to user mode if required. // cmp.eq pUser = UserMode, loc2 add out0 = STACK_SCRATCH_AREA, sp (pUser) br.call.spnt brp = KiSaveExceptionFrame ;; mov out0 = loc2 add out1 = STACK_SCRATCH_AREA, sp // -> exception frame mov out2 = a1 // -> trap frame br.call.sptk.many brp = KiDeliverApc ;; // // deallocate exception frame and high floating pointer register save area // .restore add sp = ExceptionFrameLength, sp NESTED_RETURN NESTED_EXIT(KiApcInterrupt)