120 lines
2.7 KiB
ArmAsm
120 lines
2.7 KiB
ArmAsm
|
// 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)
|
|||
|
|
|||
|
|