245 lines
6.1 KiB
NASM
245 lines
6.1 KiB
NASM
;++
|
|
;
|
|
;Copyright (c) 1991 Microsoft Corporation
|
|
;Copyright (c) 1992 Intel Corporation
|
|
;All rights reserved
|
|
;
|
|
;INTEL CORPORATION PROPRIETARY INFORMATION
|
|
;
|
|
;This software is supplied to Microsoft under the terms
|
|
;of a license agreement with Intel Corporation and may not be
|
|
;copied nor disclosed except in accordance with the terms
|
|
;of that agreement.
|
|
;
|
|
;
|
|
;Module Name:
|
|
;
|
|
; mpsysint.asm
|
|
;
|
|
;Abstract:
|
|
;
|
|
; This module implements the HAL routines to begin/end
|
|
; system interrupts for a PC+MP implementation
|
|
;
|
|
;Author:
|
|
;
|
|
; John Vert (jvert) 22-Jul-1991
|
|
;
|
|
;Environment:
|
|
;
|
|
; Kernel Mode
|
|
;
|
|
;Revision History:
|
|
;
|
|
; Ron Mosgrove (Intel) Aug 1993
|
|
; Modified for PC+MP Systems
|
|
;
|
|
;--
|
|
|
|
.386p
|
|
.xlist
|
|
include hal386.inc
|
|
include callconv.inc ; calling convention macros
|
|
include i386\kimacro.inc
|
|
include mac386.inc
|
|
include apic.inc
|
|
include ntapic.inc
|
|
.list
|
|
|
|
EXTRNP _KeBugCheck,1,IMPORT
|
|
EXTRNP _KiDispatchInterrupt,0,IMPORT
|
|
extrn _HalpVectorToIRQL:byte
|
|
extrn _HalpIRQLtoTPR:byte
|
|
|
|
_TEXT SEGMENT DWORD PUBLIC 'CODE'
|
|
ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
|
|
|
|
page ,132
|
|
subttl "End System Interrupt"
|
|
;++
|
|
;
|
|
; VOID
|
|
; HalpEndSystemInterrupt
|
|
; IN KIRQL NewIrql,
|
|
; IN ULONG Vector
|
|
; )
|
|
;
|
|
; Routine Description:
|
|
;
|
|
; This routine is used to lower IRQL to the specified value.
|
|
; The IRQL and PIRQL will be updated accordingly. Also, this
|
|
; routine checks to see if any software interrupt should be
|
|
; generated. The following condition will cause software
|
|
; interrupt to be simulated:
|
|
; any software interrupt which has higher priority than
|
|
; current IRQL's is pending.
|
|
;
|
|
; NOTE: This routine simulates software interrupt as long as
|
|
; any pending SW interrupt level is higher than the current
|
|
; IRQL, even when interrupts are disabled.
|
|
;
|
|
; Arguments:
|
|
;
|
|
; NewIrql - the new irql to be set.
|
|
;
|
|
; Vector - Vector number of the interrupt
|
|
;
|
|
; Note that esp+12 is the beginning of interrupt/trap frame and upon
|
|
; entering to this routine the interrupts are off.
|
|
;
|
|
; Return Value:
|
|
;
|
|
; None.
|
|
;
|
|
;--
|
|
|
|
HeiNewIrql equ [esp + 4]
|
|
HeiVector equ [esp + 8]
|
|
|
|
cPublicProc _HalEndSystemInterrupt ,2
|
|
cPublicFpo 2, 0
|
|
xor ecx,ecx
|
|
mov cl, byte ptr HeiNewIrql ; get new IRQL
|
|
mov cl, _HalpIRQLtoTPR[ecx] ; get corresponding TPR value
|
|
|
|
mov dword ptr APIC[LU_EOI], 0 ; send EOI to APIC local unit
|
|
APICFIX edx
|
|
|
|
cmp cl, DPC_VECTOR ; Is new irql < DPC?
|
|
jc short es10 ; Yes, go check for pending DPC
|
|
|
|
es05: mov dword ptr APIC[LU_TPR], ecx ; Set new Priority
|
|
|
|
;
|
|
; We have to ensure that the requested priority is set before
|
|
; we return. The caller is counting on it.
|
|
;
|
|
mov edx, dword ptr APIC[LU_TPR]
|
|
CHECKTPR ecx, edx
|
|
stdRET _HalEndSystemInterrupt
|
|
|
|
es10: cmp PCR[PcHal.DpcPending], 0 ; Is a DPC pending?
|
|
mov PCR[PcHal.ShortDpc], 0 ; Clear short dpc flag
|
|
jz short es05 ; No, eoi
|
|
|
|
mov dword ptr APIC[LU_TPR], DPC_VECTOR ; lower to DPC level
|
|
APICFIX edx
|
|
|
|
push ebx ; Save EBX (used by KiDispatchInterrupt)
|
|
push ecx ; Save OldIrql
|
|
cPublicFpo 2, 2
|
|
|
|
sti
|
|
|
|
es20: mov PCR[PcHal.DpcPending], 0 ; Clear pending flag
|
|
|
|
stdCall _KiDispatchInterrupt ; Dispatch interrupt
|
|
|
|
cli
|
|
|
|
pop ecx
|
|
pop ebx
|
|
jmp short es05
|
|
|
|
stdENDP _HalEndSystemInterrupt
|
|
|
|
|
|
;++
|
|
;
|
|
;BOOLEAN
|
|
;HalBeginSystemInterrupt(
|
|
; IN KIRQL Irql
|
|
; IN ULONG Vector,
|
|
; OUT PKIRQL OldIrql
|
|
; )
|
|
;
|
|
;Routine Description:
|
|
;
|
|
; This routine raises the IRQL to the level of the specified
|
|
; interrupt vector. It is called by the hardware interrupt
|
|
; handler before any other interrupt service routine code is
|
|
; executed. The CPU interrupt flag is set on exit.
|
|
;
|
|
; On APIC-based systems we do not need to check for spurious
|
|
; interrupts since they now have their own vector. We also
|
|
; no longer need to check whether or not the incoming priority
|
|
; is higher than the current priority that is guaranteed by
|
|
; the priority mechanism of the APIC.
|
|
;
|
|
; SO
|
|
;
|
|
; All BeginSystemInterrupt needs to do is set the APIC TPR
|
|
; appropriate for the IRQL, and return TRUE. Note that to
|
|
; use the APIC ISR priority we are not going issue EOI until
|
|
; EndSystemInterrupt is called.
|
|
;
|
|
; Arguments:
|
|
;
|
|
; Irql - Supplies the IRQL to raise to
|
|
;
|
|
; Vector - Supplies the vector of the interrupt to be
|
|
; handled
|
|
;
|
|
; OldIrql- Location to return OldIrql
|
|
;
|
|
; Return Value:
|
|
;
|
|
; TRUE - Interrupt successfully dismissed and Irql raised.
|
|
; This routine can not fail.
|
|
;
|
|
;--
|
|
|
|
|
|
align dword
|
|
HbsiIrql equ byte ptr [esp+4]
|
|
HbsiVector equ byte ptr [esp+8]
|
|
HbsiOldIrql equ dword ptr [esp+12]
|
|
|
|
cPublicProc _HalBeginSystemInterrupt ,3
|
|
cPublicFpo 3, 0
|
|
|
|
xor eax, eax
|
|
mov al, HbsiIrql ; (eax) = New Vector
|
|
mov al, _HalpIRQLtoTPR[eax] ; get corresponding TPR value
|
|
|
|
;
|
|
; Read the TPR for the Priority (Vector) in use,
|
|
; and convert it to an IRQL
|
|
;
|
|
|
|
mov ecx, dword ptr APIC[LU_TPR] ; Get the Priority
|
|
mov dword ptr APIC[LU_TPR], eax
|
|
APICFIX edx
|
|
|
|
mov eax, HbsiOldIrql ; return the current IRQL as OldIrql
|
|
shr ecx, 4
|
|
mov cl, byte ptr _HalpVectorToIRQL[ecx]
|
|
|
|
mov byte ptr [eax], cl
|
|
mov eax, 1 ; return TRUE
|
|
sti
|
|
|
|
;
|
|
; If OldIrql < DISPATCH_LEVEL and new irql >= DISPATCH_LEVEL (which
|
|
; is assumed), then set
|
|
;
|
|
|
|
cmp cl, DISPATCH_LEVEL
|
|
jnc short bs10
|
|
|
|
if DBG
|
|
cmp PCR[PcHal.ShortDpc], 0
|
|
je short @f
|
|
int 3
|
|
@@:
|
|
endif
|
|
mov PCR[PcHal.ShortDpc], DISPATCH_LEVEL
|
|
|
|
bs10:
|
|
stdRET _HalBeginSystemInterrupt
|
|
stdENDP _HalBeginSystemInterrupt
|
|
|
|
_TEXT ENDS
|
|
|
|
END
|