windows-nt/Source/XPSP1/NT/base/hals/halmps/i386/mpswint.asm
2020-09-26 16:20:57 +08:00

331 lines
6.7 KiB
NASM

title "Software Interrupts"
;++
;
; Copyright (c) 1992 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:
;
; mpswint.asm
;
; Abstract:
;
; This module implements the software interrupt handlers for
; APIC-based PC+MP multiprocessor systems.
;
; Author:
;
; John Vert (jvert) 2-Jan-1992
;
; Environment:
;
; Kernel mode only.
;
; Revision History:
;
; Ron Mosgrove (Intel) - Modified for PC+MP systems
;
;--
.386p
.xlist
include hal386.inc
include callconv.inc ; calling convention macros
include apic.inc
include ntapic.inc
include i386\kimacro.inc
.list
EXTRNP Kei386EoiHelper,0,IMPORT
EXTRNP _KiDeliverApc,3,IMPORT
EXTRNP _KiDispatchInterrupt,0,IMPORT
extrn _HalpIRQLtoTPR:byte
_TEXT SEGMENT DWORD PUBLIC 'CODE'
ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
page ,132
subttl "Request Software Interrupt"
;++
;
; VOID
; FASTCALL
; HalRequestSoftwareInterrupt (
; IN KIRQL RequestIrql
; )
;
; Routine Description:
;
; This routine is used to request a software interrupt of
; the system.
;
; Arguments:
;
; (cl) = RequestIrql - Supplies the request IRQL value
;
; Return Value:
;
; None.
;
;--
; equates for accessing arguments
;
cPublicFastCall HalRequestSoftwareInterrupt ,1
cPublicFpo 0,0
cmp cl, PCR[PcHal.ShortDpc]
je short rsi10
xor eax, eax
mov al, cl ; get irql
;
; In an APIC based system the TPR is the IDTEntry
;
xor ecx, ecx
mov cl, _HalpIRQLtoTPR[eax] ; get IDTEntry for IRQL
;
; Build the ICR Command - Fixed Delivery to Self, IDTEntry == al
;
or ecx, (DELIVER_FIXED OR ICR_SELF)
;
; Make sure the ICR is available
;
pushfd ; save interrupt mode
cli ; disable interrupt
STALL_WHILE_APIC_BUSY
;
; Now write the command to the Memory Mapped Register
;
mov dword ptr APIC[LU_INT_CMD_LOW], ecx
;
; We have to wait for the request to be delivered.
; If we don't wait here, then we will return to the caller
; before the request has been issued.
;
STALL_WHILE_APIC_BUSY
popfd ; restore original interrupt mode
fstRET HalRequestSoftwareInterrupt
;
; Requesting a DPC interrupt when ShortDpc is set. Just set the
; DpcPending flag - whomever set ShortDpc will check the flag
; at the proper time
;
rsi10: mov PCR[PcHal.DpcPending], 1
fstRET HalRequestSoftwareInterrupt
fstENDP HalRequestSoftwareInterrupt
page ,132
subttl "Clear Software Interrupt"
;++
;
; VOID
; HalClearSoftwareInterrupt (
; IN KIRQL RequestIrql
; )
;
; Routine Description:
;
; This routine is used to clear a possible pending software interrupt.
; Support for this function is optional, and allows the kernel to
; reduce the number of spurious software interrupts it receives/
;
; Arguments:
;
; (cl) = RequestIrql - Supplies the request IRQL value
;
; Return Value:
;
; None.
;
;--
cPublicFastCall HalClearSoftwareInterrupt ,1
fstRET HalClearSoftwareInterrupt
fstENDP HalClearSoftwareInterrupt
page ,132
subttl "Dispatch Interrupt"
;++
;
; VOID
; HalpDispatchInterrupt(
; VOID
; );
;
; Routine Description:
;
; This routine is the interrupt handler for a software interrupt generated
; at DISPATCH_LEVEL. Its function is to save the machine state, raise
; Irql to DISPATCH_LEVEL, dismiss the interrupt, and call the DPC
; delivery routine.
;
; Arguments:
;
; None
; Interrupt is disabled
;
; Return Value:
;
; None.
;
;--
ENTER_DR_ASSIST hdpi_a, hdpi_t
cPublicProc _HalpDispatchInterrupt ,0
;
; Save machine state on trap frame
;
ENTER_INTERRUPT hdpi_a, hdpi_t
mov eax, DPC_VECTOR
mov esi, dword ptr APIC[LU_TPR] ; get the old TPR
mov dword ptr APIC[LU_TPR], eax ; set the TPR
sti ; and allow interrupts
APICFIX edx
mov dword ptr APIC[LU_EOI], 0 ; send EOI to APIC local unit
APICFIX edx
;
; Go do Dispatch Interrupt processing
;
di10: stdCall _KiDispatchInterrupt
cli
mov dword ptr APIC[LU_TPR], esi ; reset the TPR
;
; We have to ensure that the requested priority is set before
; we return. The caller is counting on it.
;
mov ecx, dword ptr APIC[LU_TPR]
CHECKTPR ecx, esi
;
; Do interrupt exit processing without EOI
;
SPURIOUS_INTERRUPT_EXIT
stdENDP _HalpDispatchInterrupt
page ,132
subttl "APC Interrupt"
;++
;
; HalpApcInterrupt(
; VOID
; );
;
; Routine Description:
;
; This routine is entered as the result of a software interrupt generated
; at APC_LEVEL. Its function is to save the machine state, raise Irql to
; APC_LEVEL, dismiss the interrupt, and call the APC delivery routine.
;
; Arguments:
;
; None
; Interrupt is Disabled
;
; Return Value:
;
; None.
;
;--
ENTER_DR_ASSIST hapc_a, hapc_t
;
; Save machine state in trap frame
;
cPublicProc _HalpApcInterrupt ,0
;
; Save machine state on trap frame
;
ENTER_INTERRUPT hapc_a, hapc_t
mov eax, APC_VECTOR
mov ecx, dword ptr APIC[LU_TPR] ; get the old TPR
push ecx ; save it
mov dword ptr APIC[LU_TPR], eax ; set the TPR
APICFIX edx
mov dword ptr APIC[LU_EOI], 0 ; send EOI to APIC local unit
APICFIX edx
sti ; and allow interrupts
mov eax, [ebp]+TsSegCs ; get interrupted code's CS
and eax, MODE_MASK ; extract the mode
; call APC deliver routine
; Previous mode
; Null exception frame
; Trap frame
stdCall _KiDeliverApc, <eax, 0,ebp>
pop eax
cli
mov dword ptr APIC[LU_TPR], eax ; reset the TPR
;
; We have to ensure that the requested priority is set before
; we return. The caller is counting on it.
;
mov ecx, dword ptr APIC[LU_TPR]
CHECKTPR ecx, eax
;
; Do interrupt exit processing without EOI
;
SPURIOUS_INTERRUPT_EXIT
stdENDP _HalpApcInterrupt
_TEXT ends
end