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, 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