summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halx86/i386/ixswint.asm
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/nthals/halx86/i386/ixswint.asm
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/nthals/halx86/i386/ixswint.asm')
-rw-r--r--private/ntos/nthals/halx86/i386/ixswint.asm327
1 files changed, 327 insertions, 0 deletions
diff --git a/private/ntos/nthals/halx86/i386/ixswint.asm b/private/ntos/nthals/halx86/i386/ixswint.asm
new file mode 100644
index 000000000..2ca5c88e2
--- /dev/null
+++ b/private/ntos/nthals/halx86/i386/ixswint.asm
@@ -0,0 +1,327 @@
+ title "Software Interrupts"
+
+;++
+;
+; Copyright (c) 1992 Microsoft Corporation
+;
+; Module Name:
+;
+; ixswint.asm
+;
+; Abstract:
+;
+; This module implements the software interrupt handlers
+; for x86 machines
+;
+; Author:
+;
+; John Vert (jvert) 2-Jan-1992
+;
+; Environment:
+;
+; Kernel mode only.
+;
+; Revision History:
+;
+;--
+
+.386p
+ .xlist
+include hal386.inc
+include callconv.inc ; calling convention macros
+include i386\ix8259.inc
+include i386\kimacro.inc
+ .list
+
+ EXTRNP _KiDeliverApc,3,IMPORT
+ EXTRNP _KiDispatchInterrupt,0,IMPORT
+ EXTRNP Kei386EoiHelper,0,IMPORT
+ EXTRNP _HalEndSystemInterrupt,2
+ extrn SWInterruptHandlerTable:dword
+ extrn SWInterruptLookUpTable:byte
+ifdef IRQL_METRICS
+ extrn HalApcSoftwareIntCount:dword
+ extrn HalDpcSoftwareIntCount:dword
+endif
+
+_TEXT$02 SEGMENT DWORD PUBLIC 'CODE'
+ ASSUME DS:FLAT, ES:FLAT, SS:FLAT, FS:NOTHING, GS:NOTHING
+
+ page ,132
+ subttl "Request Software Interrupt"
+
+;++
+;
+; VOID
+; HalRequestSoftwareInterrupt (
+; IN KIRQL RequestIrql
+; )
+;
+; Routine Description:
+;
+; This routine is used to request a software interrupt to the
+; system. 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:
+;
+; (cl) = RequestIrql - Supplies the request IRQL value
+;
+; Return Value:
+;
+; None.
+;
+;--
+
+cPublicFastCall HalRequestSoftwareInterrupt ,1
+cPublicFpo 0, 1
+
+ mov eax,1
+ shl eax, cl ; convert to mask
+ pushfd ; save interrupt mode
+ cli ; disable interrupt
+ or PCR[PcIRR], eax ; set the request bit
+ mov cl, PCR[PcIrql] ; get current IRQL
+
+ mov eax, PCR[PcIRR] ; get SW interrupt request register
+ and eax, 3 ; mask off pending HW interrupts
+
+ xor edx, edx
+ mov dl, SWInterruptLookUpTable[eax] ; get the highest pending
+ ; software interrupt level
+ cmp dl, cl ; Is highest SW int level > irql?
+ jbe short KsiExit ; No, jmp ksiexit
+ call SWInterruptHandlerTable[edx*4] ; yes, simulate interrupt
+ ; to the appropriate handler
+KsiExit:
+ popfd ; restore original interrupt mode
+ fstRET HalRequestSoftwareInterrupt
+
+fstENDP HalRequestSoftwareInterrupt
+
+ page ,132
+ subttl "Request 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
+cPublicFpo 0, 0
+
+ mov eax,1
+ shl eax, cl ; convert to mask
+
+ not eax
+ and PCR[PcIRR], eax ; clear pending irr bit
+
+ 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
+
+ align dword
+ public _HalpDispatchInterrupt
+_HalpDispatchInterrupt proc
+ifdef IRQL_METRICS
+ lock inc HalDpcSoftwareIntCount
+endif
+;
+; Create IRET frame on stack
+;
+ pop eax
+ pushfd
+ push cs
+ push eax
+
+;
+; Save machine state on trap frame
+;
+
+ ENTER_INTERRUPT hdpi_a, hdpi_t
+.FPO ( FPO_LOCALS+1, 0, 0, 0, 0, FPO_TRAPFRAME )
+
+ public _HalpDispatchInterrupt2ndEntry
+_HalpDispatchInterrupt2ndEntry:
+
+; Save previous IRQL and set new priority level
+
+ push PCR[PcIrql] ; save previous IRQL
+ mov byte ptr PCR[PcIrql], DISPATCH_LEVEL; set new irql
+ and dword ptr PCR[PcIRR], not (1 shl DISPATCH_LEVEL) ; clear the pending bit in IRR
+
+;
+; Now it is safe to enable interrupt to allow higher priority interrupt
+; to come in.
+;
+
+ sti
+
+;
+; Go do Dispatch Interrupt processing
+;
+ stdCall _KiDispatchInterrupt
+
+;
+; Do interrupt exit processing
+;
+
+ SOFT_INTERRUPT_EXIT ; will do an iret
+
+_HalpDispatchInterrupt endp
+
+ 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
+
+ align dword
+ public _HalpApcInterrupt
+_HalpApcInterrupt proc
+ifdef IRQL_METRICS
+ lock inc HalApcSoftwareIntCount
+endif
+;
+; Create IRET frame on stack
+;
+ pop eax
+ pushfd
+ push cs
+ push eax
+
+;
+; Save machine state in trap frame
+;
+ ENTER_INTERRUPT hapc_a, hapc_t
+.FPO ( FPO_LOCALS+1, 0, 0, 0, 0, FPO_TRAPFRAME )
+
+
+ public _HalpApcInterrupt2ndEntry
+_HalpApcInterrupt2ndEntry:
+
+;
+; Save previous IRQL and set new priority level
+;
+
+ push PCR[PcIrql] ; save previous Irql
+ mov byte ptr PCR[PcIrql], APC_LEVEL ; set new Irql
+ and dword ptr PCR[PcIRR], not (1 shl APC_LEVEL) ; dismiss pending APC
+;
+; Now it is safe to enable interrupt to allow higher priority interrupt
+; to come in.
+;
+
+ sti
+
+;
+; call the APC delivery routine.
+;
+
+ mov eax, [ebp]+TsSegCs ; get interrupted code's CS
+ and eax, MODE_MASK ; extract the mode
+
+ test dword ptr [ebp]+TsEFlags, EFLAGS_V86_MASK
+ jz short @f
+
+ or eax, MODE_MASK ; If v86 frame, then set user_mode
+@@:
+
+;
+; call APC deliver routine
+; Previous mode
+; Null exception frame
+; Trap frame
+
+ stdCall _KiDeliverApc, <eax, 0,ebp>
+
+;
+;
+; Do interrupt exit processing
+;
+
+ SOFT_INTERRUPT_EXIT ; will do an iret
+
+_HalpApcInterrupt endp
+
+_TEXT$02 ends
+
+ end