NT4/private/ntos/ke/mips/xxapcint.s
2020-09-30 17:12:29 +02:00

124 lines
3.5 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:
//
// xxapcint.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
//
// Environment:
//
// Kernel mode only, IRQL APC_LEVEL.
//
// Revision History:
//
//--
#include "ksmips.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 all integer registers and the volatile
// floating registers have been saved. The remainder of the machine
// state is saved if and only if the previous mode was user mode.
//
// Arguments:
//
// s8 - Supplies a pointer to a trap frame.
//
// Return Value:
//
// None.
//
//--
NESTED_ENTRY(KiApcInterrupt, ExceptionFrameLength, zero)
subu sp,sp,ExceptionFrameLength // allocate exception frame
sw ra,ExIntRa(sp) // save return address
PROLOGUE_END
//
// Determine the previous mode.
//
lw t0,TrPsr(s8) // get saved processor status
srl t0,t0,PSR_KSU + 1 // isolate previous mode
and a0,t0,0x1 //
beq zero,a0,20f // if eq, kernel mode
//
// The previous mode was user.
//
// Save the nonvolatile floating 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.
//
sdc1 f20,ExFltF20(sp) // save floating registers f20 - f31
sdc1 f22,ExFltF22(sp) //
sdc1 f24,ExFltF24(sp) //
sdc1 f26,ExFltF26(sp) //
sdc1 f28,ExFltF28(sp) //
sdc1 f30,ExFltF30(sp) //
//
// Clear APC interrupt.
//
20: DISABLE_INTERRUPTS(t0) // disable interrupts
.set noreorder
.set noat
mfc0 t1,cause // get exception cause register
li t2,~APC_INTERRUPT // clear APC interrupt pending
and t1,t1,t2 //
mtc0 t1,cause //
nop //
.set at
.set reorder
ENABLE_INTERRUPTS(t0) // enable interrupts
//
// Attempt to deliver an APC.
//
move a1,sp // set address of exception frame
move a2,s8 // set address of trap frame
jal KiDeliverApc // call APC delivery routine
//
// Deallocate stack frame and return.
//
lw ra,ExIntRa(sp) // restore return address
addu sp,sp,ExceptionFrameLength // deallocate exception frame
j ra // return
.end KiApcInterrupt