616 lines
18 KiB
NASM
616 lines
18 KiB
NASM
;++
|
|
;
|
|
;Copyright (c) 1991-1993 Microsoft Corporation
|
|
;Copyright (c) 1992, 1993 Wyse Technology
|
|
;
|
|
;Module Name:
|
|
;
|
|
; wysysint.asm
|
|
;
|
|
;Abstract:
|
|
;
|
|
; This module implements the HAL routines to enable/disable system
|
|
; interrupts, for the MP Wyse7000i implementation
|
|
;
|
|
;Author:
|
|
;
|
|
; John Vert (jvert) 22-Jul-1991
|
|
;
|
|
;Environment:
|
|
;
|
|
; Kernel Mode
|
|
;
|
|
;Revision History:
|
|
;
|
|
;--
|
|
|
|
|
|
.386p
|
|
.xlist
|
|
include hal386.inc
|
|
include callconv.inc ; calling convention macros
|
|
include i386\ix8259.inc
|
|
include i386\kimacro.inc
|
|
include mac386.inc
|
|
include i386\wy7000mp.inc
|
|
.list
|
|
|
|
EXTRNP _KeBugCheck,1,IMPORT
|
|
extrn WriteMyCpuReg:NEAR
|
|
EXTRNP _KeLowerIrql,1
|
|
extrn _HalpVectorToIRQL:BYTE
|
|
extrn _HalpIRQLtoVector:BYTE
|
|
extrn _HalpIRQLtoCPL:BYTE
|
|
extrn _HalpLocalInts:DWORD
|
|
|
|
;
|
|
; Constants used to initialize CMOS/Real Time Clock
|
|
;
|
|
|
|
CMOS_CONTROL_PORT EQU 70h ; command port for cmos
|
|
CMOS_DATA_PORT EQU 71h ; cmos data port
|
|
|
|
;
|
|
; Macros to Read/Write/Reset CMOS to initialize RTC
|
|
;
|
|
|
|
; CMOS_READ
|
|
;
|
|
; Description: This macro read a byte from the CMOS register specified
|
|
; in (AL).
|
|
;
|
|
; Parameter: (AL) = address/register to read
|
|
; Return: (AL) = data
|
|
;
|
|
; NOTE: IODelay's are not needed on EISA machines.
|
|
|
|
CMOS_READ MACRO
|
|
OUT CMOS_CONTROL_PORT,al ; ADDRESS LOCATION AND DISABLE NMI
|
|
; IODelay ; I/O DELAY
|
|
IN AL,CMOS_DATA_PORT ; READ IN REQUESTED CMOS DATA
|
|
; IODelay ; I/O DELAY
|
|
ENDM
|
|
|
|
_DATA SEGMENT DWORD PUBLIC 'DATA'
|
|
|
|
align dword
|
|
|
|
public _HalpICUlock ;spinlock for rebroadcasting timer & global IPI's
|
|
_HalpICUlock dd 0
|
|
public _Halp8259Lock ;spinlock for accessing 8259 mask registers
|
|
_Halp8259Lock dd 0
|
|
public _i8259_IMR ;global 8259 interrupt mask
|
|
_i8259_IMR dd not (1 shl PIC_SLAVE_IRQ)
|
|
public _i8259_ISR ;global 8259 interrupts in services
|
|
_i8259_ISR dd 0
|
|
public _Halp8259Counts ;count of cpu's attached to each 8259 interrupt
|
|
_Halp8259Counts db 16 dup(0)
|
|
|
|
;
|
|
; HalDismissSystemInterrupt does an indirect jump through this table so it
|
|
; can quickly execute specific code for different interrupts.
|
|
;
|
|
public HalpSpecialDismissTable
|
|
HalpSpecialDismissTable label dword
|
|
dd offset FLAT:HalpDismissNormal ; irq 0
|
|
dd offset FLAT:HalpDismissNormal ; irq 1
|
|
dd offset FLAT:HalpDismissSpurious ; irq 2
|
|
dd offset FLAT:HalpDismissNormal ; irq 3
|
|
dd offset FLAT:HalpDismissNormal ; irq 4
|
|
dd offset FLAT:HalpDismissNormal ; irq 5
|
|
dd offset FLAT:HalpDismissNormal ; irq 6
|
|
dd offset FLAT:HalpDismissIrq07 ; irq 7
|
|
dd offset FLAT:HalpDismissNormal ; irq 8
|
|
dd offset FLAT:HalpDismissNormal ; irq 9
|
|
dd offset FLAT:HalpDismissNormal ; irq A
|
|
dd offset FLAT:HalpDismissNormal ; irq B
|
|
dd offset FLAT:HalpDismissNormal ; irq C
|
|
dd offset FLAT:HalpDismissNormal ; irq D
|
|
dd offset FLAT:HalpDismissNormal ; irq E
|
|
dd offset FLAT:HalpDismissIrq0f ; irq F
|
|
dd offset FLAT:HalpDismissSpurious ; irq 10
|
|
dd offset FLAT:HalpDismissIPIlevel ; irq 11
|
|
dd offset FLAT:HalpDismissIPIlevel ; irq 12
|
|
dd offset FLAT:HalpDismissIPIlevel ; irq 13
|
|
dd offset FLAT:HalpDismissIPIlevel ; irq 14
|
|
dd offset FLAT:HalpDismissIPIlevel ; irq 15
|
|
dd offset FLAT:HalpDismissIPIlevel ; irq 16
|
|
dd offset FLAT:HalpDismissIPIlevel ; irq 17
|
|
dd offset FLAT:HalpDismissSpurious ; irq 18
|
|
dd offset FLAT:HalpDismissSpurious ; irq 19
|
|
dd offset FLAT:HalpDismissSpurious ; irq 1A
|
|
dd offset FLAT:HalpDismissSpurious ; irq 1B
|
|
dd offset FLAT:HalpDismissSpurious ; irq 1C
|
|
dd offset FLAT:HalpDismissSpurious ; irq 1D
|
|
dd offset FLAT:HalpDismissSpurious ; irq 1E
|
|
dd offset FLAT:HalpDismissSpurious ; irq 1F
|
|
dd offset FLAT:HalpDismissSpurious ; irq 20
|
|
dd offset FLAT:HalpDismissSpurious ; irq 21
|
|
dd offset FLAT:HalpDismissSpurious ; irq 22
|
|
dd offset FLAT:HalpDismissSpurious ; irq 23
|
|
|
|
_DATA ENDS
|
|
|
|
_TEXT SEGMENT DWORD PUBLIC 'CODE'
|
|
ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
|
|
|
|
|
|
;++
|
|
;BOOLEAN
|
|
;HalBeginSystemInterrupt(
|
|
; IN KIRQL Irql
|
|
; IN CCHAR Vector,
|
|
; OUT PKIRQL OldIrql
|
|
; )
|
|
;
|
|
;
|
|
;
|
|
;Routine Description:
|
|
;
|
|
; This routine is used to dismiss the specified vector number. It is called
|
|
; before any interrupt service routine code is executed.
|
|
;
|
|
; N.B. This routine does NOT preserve EAX or EBX
|
|
;
|
|
;Arguments:
|
|
;
|
|
; Irql - Supplies the IRQL to raise to
|
|
;
|
|
; Vector - Supplies the vector of the interrupt to be dismissed
|
|
;
|
|
; OldIrql- Location to return OldIrql
|
|
;
|
|
;
|
|
;Return Value:
|
|
;
|
|
; FALSE - Interrupt is spurious and should be ignored
|
|
;
|
|
; TRUE - Interrupt successfully dismissed and Irql raised.
|
|
;
|
|
;--
|
|
align dword
|
|
HbsiIrql equ byte ptr [esp+4+8]
|
|
HbsiVector equ byte ptr [esp+8+8]
|
|
HbsiOldIrql equ dword ptr [esp+12+8]
|
|
|
|
cPublicProc _HalBeginSystemInterrupt ,3
|
|
push ecx
|
|
push edx
|
|
mov ebx, (-PRIMARY_VECTOR_BASE) and 0FFh
|
|
add bl, HbsiVector ; (ebx) = 8259 IRQ #
|
|
if DBG
|
|
cmp ebx, 23h
|
|
jbe hbsi00
|
|
int 3
|
|
hbsi00:
|
|
|
|
endif
|
|
xor ecx, ecx
|
|
mov cl, _HalpVectorToIRQL[ebx] ; get h/w Irql of interrupt
|
|
cmp cl, Fs:PcIrql ; int after raise Irql?
|
|
jbe short HalpIntBelowIRQL ; jump if it is
|
|
jmp HalpSpecialDismissTable[ebx*4]
|
|
|
|
HalpIntBelowIRQL:
|
|
xor eax, eax
|
|
mov al, Fs:PcIrql
|
|
mov dx, My+CpuPriortyLevel
|
|
mov Fs:PcHal.pchHwIrql, al
|
|
mov al, _HalpIRQLtoCPL[eax]
|
|
out dx, ax
|
|
bt _HalpLocalInts, ecx ; EISA or Local interrupt?
|
|
jnc short HalpRebroadcastEISAint ; jump if EISA interrupt
|
|
|
|
cmp cl, IPI_LEVEL ; IPI's are easy
|
|
jne HalpEmulateClockOrGlobal ; jmp if not an IPI
|
|
|
|
mov cl, byte ptr fs:PcHal.pchPrSlot ; IPIs get resent to
|
|
or cl, ICU_IPI_SLOT ; the current processor
|
|
jmp short HalpRebroadcastIPI
|
|
|
|
HalpRebroadcastEISAint:
|
|
mov cl, _HalpIRQLtoCPL[ecx] ; get hw interrupt level
|
|
add cl, ICU_XMT_INT_SND ; make ICU command
|
|
HalpRebroadcastIPI:
|
|
mov dx, My+CpuIntCmd ; point to ICU command register
|
|
@@: in ax, dx
|
|
test eax, ICU_CMD_BUSY
|
|
jnz short @B ; wait for ICU not busy
|
|
xchg eax, ecx ; get ICU command
|
|
out dx, ax ; rebroadcast EISA interrupt
|
|
jmp HalpDismissSpurious ; clear ICU in service bit
|
|
|
|
HalpEmulateClockOrGlobal:
|
|
; The following code resends a clock or global interrupt by mapping the
|
|
; appropriate ICU_LIPTR value to zero and then broadcasting the level.
|
|
; This must be spinlocked since it will not work it two CPUs try it at
|
|
; the same time.
|
|
|
|
cmp cl, CLOCK2_LEVEL ; is this CLOCK or GLOBAL?
|
|
mov cl, _HalpIRQLtoCPL[ecx] ; (get this int's level #)
|
|
mov ax, not lipTimer ; (assume timer interrupt)
|
|
je short @F ; jump if timer interrupt
|
|
mov ax, not (lipGlobal+lipSerial) ; it is global interrupt
|
|
@@: and ax, fs:word ptr PcHal.pchCurLiptr
|
|
push eax ; save temp LIPTR
|
|
|
|
lea eax, _HalpICUlock ; Serialize access to
|
|
Hec10: ACQUIRE_SPINLOCK eax, HecSpin ; remappings
|
|
|
|
push ICU_LIPTR ; Point global interrupt to
|
|
call WriteMyCpuReg ; make it a clock interrupt
|
|
|
|
mov dx, My+CpuIntCmd ; wait for ICU not busy
|
|
@@: in ax, dx
|
|
test eax, ICU_CMD_BUSY
|
|
jnz short @B
|
|
|
|
xchg eax, ecx ; get int level back
|
|
add al, ICU_XMT_INT_SND ; make send level command
|
|
out dx, ax ; to make to clock interrupt
|
|
|
|
@@: in ax, dx ; wait for ICU not busy
|
|
test eax, ICU_CMD_BUSY ; before resetting GlobalIpi
|
|
jnz short @B ; value
|
|
|
|
push fs:PcHal.pchCurLiptr
|
|
push ICU_LIPTR ; Put GlobalIpi back to
|
|
call WriteMyCpuReg ; normal setting
|
|
|
|
lea eax, _HalpICUlock
|
|
RELEASE_SPINLOCK eax
|
|
|
|
jmp HalpDismissSpurious
|
|
|
|
HecSpin:
|
|
SPIN_ON_SPINLOCK eax, Hec10
|
|
|
|
|
|
HalpDismissSpinF:
|
|
SPIN_ON_SPINLOCK eax, Hbsi10
|
|
|
|
align dword
|
|
HalpDismissIrq0f:
|
|
;
|
|
; Check to see if this is a spurious interrupt
|
|
;
|
|
lea eax, _Halp8259Lock
|
|
Hbsi10: ACQUIRE_SPINLOCK eax, HalpDismissSpinF
|
|
mov al, OCW3_READ_ISR ; tell 8259 we want to read ISR
|
|
out PIC2_PORT0, al
|
|
; IODelay ; delay
|
|
in al, PIC2_PORT0 ; (al) = content of PIC 1 ISR
|
|
test al, 10000000B ; Is In-Service register set?
|
|
jnz HalpDismissNormal2 ; No, this is NOT a spurious int,
|
|
; go do the normal interrupt stuff
|
|
|
|
;
|
|
; This is a spurious interrupt.
|
|
; Because the slave PIC is cascaded to irq2 of master PIC, we need to
|
|
; dismiss the interupt on master PIC's irq2.
|
|
;
|
|
|
|
mov al, PIC2_EOI ; Specific eoi to master for pic2 eoi
|
|
out PIC1_PORT0, al ; send irq2 specific eoi to master
|
|
|
|
lea eax, _Halp8259Lock
|
|
RELEASE_SPINLOCK eax
|
|
|
|
HalpDismissSpurious:
|
|
mov dx, My+CpuIntCmd
|
|
@@: in ax, dx
|
|
test eax, ICU_CMD_BUSY
|
|
jnz @B
|
|
mov al, ICU_CLR_INSERV1
|
|
out dx, ax
|
|
xor eax, eax ; return FALSE
|
|
; sti
|
|
pop edx
|
|
pop ecx
|
|
stdRET _HalBeginSystemInterrupt
|
|
|
|
HalpDismissSpin:
|
|
SPIN_ON_SPINLOCK eax, HalpDismissNormal
|
|
|
|
HalpDismissSpin7:
|
|
SPIN_ON_SPINLOCK eax, Hbsi20
|
|
|
|
align dword
|
|
HalpDismissIrq07:
|
|
;
|
|
; Check to see if this is a spurious interrupt
|
|
;
|
|
lea eax, _Halp8259Lock
|
|
Hbsi20: ACQUIRE_SPINLOCK eax, HalpDismissSpin7
|
|
mov al, OCW3_READ_ISR ; tell 8259 we want to read ISR
|
|
out PIC1_PORT0, al
|
|
; IODelay ; delay
|
|
in al, PIC1_PORT0 ; (al) = content of PIC 1 ISR
|
|
test al, 10000000B ; Is In-Service register set?
|
|
jnz short HalpDismissNormal2 ; No, so this is a spurious int
|
|
|
|
lea eax, _Halp8259Lock
|
|
RELEASE_SPINLOCK eax
|
|
jmp HalpDismissSpurious
|
|
|
|
align dword
|
|
HalpDismissNormal:
|
|
lea eax, _Halp8259Lock
|
|
ACQUIRE_SPINLOCK eax, HalpDismissSpin
|
|
|
|
align dword
|
|
HalpDismissNormal2:
|
|
mov eax, _i8259_IMR ;get current 8259 masks
|
|
bts _i8259_ISR, ebx ;mark this int as in service
|
|
or eax, _i8259_ISR ;also mask in service ints
|
|
SET_8259_MASK ;tell 8259's the news
|
|
lea eax, _Halp8259Lock
|
|
RELEASE_SPINLOCK eax
|
|
|
|
;
|
|
; Dismiss interrupt. Current interrupt is already masked off.
|
|
;
|
|
mov eax, ebx ; (eax) = IRQ #
|
|
cmp eax, 8 ; EOI to master or slave?
|
|
|
|
jae short Hbsi100 ; EIO to both master and slave
|
|
or al, PIC1_EOI_MASK ; create specific eoi mask for master
|
|
out PIC1_PORT0, al ; dismiss the interrupt
|
|
jmp short Hbsi200 ; IO delay
|
|
|
|
Hbsi100:
|
|
mov al, OCW2_NON_SPECIFIC_EOI ; send non specific eoi to slave
|
|
out PIC2_PORT0, al
|
|
mov al, PIC2_EOI ; specific eoi to master for pic2 eoi
|
|
out PIC1_PORT0, al ; send irq2 specific eoi to master
|
|
Hbsi200:
|
|
PIC1DELAY
|
|
|
|
HalpDismissIPIlevel:
|
|
|
|
mov bl, HbsiIrql
|
|
mov dx, My+CpuPriortyLevel
|
|
mov al, _HalpIRQLtoCPL[ebx]
|
|
mov cl, Fs:PcIrql ; (cl) = Old Irql
|
|
out dx, ax
|
|
mov Fs:PcIrql, bl ; set new irql
|
|
mov edx, HbsiOldIrql ; get addr to store old irql
|
|
mov Fs:PcHal.pchHwIrql, bl
|
|
mov [edx], cl ; save old irql in the return variable
|
|
|
|
ifdef IRQL_METRICS
|
|
lock inc HalRaiseIrqlCount
|
|
endif
|
|
|
|
mov dx, My+CpuIntCmd
|
|
@@: in ax, dx
|
|
test eax, ICU_CMD_BUSY
|
|
jnz @B
|
|
mov al, ICU_CLR_INSERV1 ; clear this processor's in service bit
|
|
out dx, ax
|
|
|
|
sti
|
|
mov eax, 1 ; return TRUE, interrupt dismissed
|
|
pop edx
|
|
pop ecx
|
|
stdRET _HalBeginSystemInterrupt
|
|
stdENDP _HalBeginSystemInterrupt
|
|
|
|
;++
|
|
;BOOLEAN
|
|
;HalEndSystemInterrupt(
|
|
; IN KIRQL Irql
|
|
; IN CCHAR Vector,
|
|
; )
|
|
;
|
|
;
|
|
;
|
|
;Routine Description:
|
|
;
|
|
; This routine is used to complete any interrupt h/w processing and to
|
|
; lower the IRQL to the original value.
|
|
;
|
|
;Arguments:
|
|
;
|
|
; Irql - Supplies the IRQL to raise to
|
|
;
|
|
; Vector - Supplies the vector of the interrupt to be dismissed
|
|
;
|
|
;
|
|
;Return Value:
|
|
;
|
|
; FALSE - Interrupt is spurious and should be ignored
|
|
;
|
|
; TRUE - Interrupt successfully dismissed and Irql raised.
|
|
;
|
|
;--
|
|
align dword
|
|
|
|
cPublicProc _HalEndSystemInterrupt ,2
|
|
movzx ecx, byte ptr [esp+8]
|
|
|
|
; change stack to be for KeLowerIrql
|
|
pop eax ;(eax) = ret addr
|
|
mov edx, [esp] ;(edx) = new irql
|
|
mov [esp], eax
|
|
mov [esp+4], edx
|
|
|
|
sub cl, PRIMARY_VECTOR_BASE
|
|
cmp cl, 16
|
|
jnb _KeLowerIrql@4 ;jump if not 8259 interrupt
|
|
pushfd
|
|
lea eax, _Halp8259Lock
|
|
HesiAquireLock:
|
|
cli
|
|
ACQUIRE_SPINLOCK eax, HesiSpin
|
|
mov eax, _i8259_IMR
|
|
btr _i8259_ISR, ecx
|
|
or eax, _i8259_ISR
|
|
SET_8259_MASK
|
|
lea eax, _Halp8259Lock
|
|
RELEASE_SPINLOCK eax
|
|
popfd
|
|
jmp _KeLowerIrql@4
|
|
|
|
HesiSpin:
|
|
popfd
|
|
pushfd
|
|
SPIN_ON_SPINLOCK eax, HesiAquireLock
|
|
stdENDP _HalEndSystemInterrupt
|
|
|
|
;++
|
|
;VOID
|
|
;HalDisableSystemInterrupt(
|
|
; IN CCHAR Vector,
|
|
; IN KIRQL Irql
|
|
; )
|
|
;
|
|
;
|
|
;
|
|
;Routine Description:
|
|
;
|
|
; Disables a system interrupt.
|
|
;
|
|
;Arguments:
|
|
;
|
|
; Vector - Supplies the vector of the interrupt to be disabled
|
|
;
|
|
; Irql - Supplies the interrupt level of the interrupt to be disabled
|
|
;
|
|
;Return Value:
|
|
;
|
|
; None.
|
|
;
|
|
;--
|
|
cPublicProc _HalDisableSystemInterrupt ,2
|
|
enproc 9
|
|
;
|
|
|
|
push ebx
|
|
movzx ebx, byte ptr [esp+12] ;get IRQL
|
|
movzx ecx, _HalpIRQLtoVector[ebx]
|
|
or ecx, ecx
|
|
jz DisSysIntExit ;jump if not H/W interrupt
|
|
sub cl, PRIMARY_VECTOR_BASE
|
|
movzx eax, _HalpIRQLtoCPL[ebx]
|
|
cli
|
|
bts fs:PcIDR, eax ;disable int locally
|
|
jc DisSysIntExit ;jump if already disabled
|
|
push fs:PcIDR
|
|
push ICU_IMR0 ;write low interrupt masks
|
|
call WriteMyCpuReg
|
|
shr eax, 16
|
|
out dx, ax ;shortcut to high interrupt masks
|
|
cmp cl, 16 ;is this an 8259 interrupt?
|
|
jnb DisSysIntExit ;jump if not
|
|
lea eax, _Halp8259Lock
|
|
DisSysIntAquire:
|
|
ACQUIRE_SPINLOCK eax, DisSysIntSpin
|
|
dec _Halp8259Counts[ecx]
|
|
jnz short DisSysIntRelease
|
|
mov eax, _i8259_ISR
|
|
bts _i8259_IMR, ecx
|
|
or eax, _i8259_IMR
|
|
SET_8259_MASK
|
|
|
|
lea eax, _Halp8259Lock
|
|
DisSysIntRelease:
|
|
RELEASE_SPINLOCK eax
|
|
|
|
DisSysIntExit:
|
|
exproc 9
|
|
sti
|
|
pop ebx
|
|
stdRET _HalDisableSystemInterrupt
|
|
|
|
DisSysIntSpin:
|
|
SPIN_ON_SPINLOCK eax, DisSysIntAquire
|
|
|
|
stdENDP _HalDisableSystemInterrupt
|
|
|
|
;++
|
|
;
|
|
;BOOLEAN
|
|
;HalEnableSystemInterrupt(
|
|
; IN ULONG Vector,
|
|
; IN KIRQL Irql,
|
|
; IN KINTERRUPT_MODE InterruptMode
|
|
; )
|
|
;
|
|
;
|
|
;Routine Description:
|
|
;
|
|
; Enables a system interrupt
|
|
;
|
|
;Arguments:
|
|
;
|
|
; Vector - Supplies the vector of the interrupt to be enabled
|
|
;
|
|
; Irql - Supplies the interrupt level of the interrupt to be enabled.
|
|
;
|
|
;Return Value:
|
|
;
|
|
; None.
|
|
;
|
|
;--
|
|
cPublicProc _HalEnableSystemInterrupt ,3
|
|
enproc 0Ah
|
|
|
|
push ebx
|
|
movzx ebx, byte ptr [esp+12] ;get IRQL
|
|
movzx ecx, _HalpIRQLtoVector[ebx]
|
|
or ecx, ecx
|
|
jz EnbSysIntError ;jump if not H/W interrupt
|
|
sub cl, PRIMARY_VECTOR_BASE
|
|
movzx eax, _HalpIRQLtoCPL[ebx]
|
|
cli
|
|
btr fs:PcIDR, eax ;enable int locally
|
|
jnc EnbSysIntExit ;jump if already enabled
|
|
push fs:PcIDR
|
|
push ICU_IMR0
|
|
call WriteMyCpuReg ;write low interrupt masks
|
|
shr eax, 16
|
|
out dx, ax ;shortcut to high interrupt masks
|
|
cmp cl, 16 ;is this an 8259 interrupt?
|
|
jnb EnbSysIntExit ;jump if not
|
|
lea eax, _Halp8259Lock
|
|
EnbSysIntAquire:
|
|
ACQUIRE_SPINLOCK eax, EnbSysIntSpin
|
|
inc _Halp8259Counts[ecx]
|
|
cmp _Halp8259Counts[ecx], 1
|
|
jnz short EnbSysIntRelease
|
|
mov eax, _i8259_ISR
|
|
btr _i8259_IMR, ecx
|
|
or eax, _i8259_IMR
|
|
SET_8259_MASK
|
|
|
|
lea eax, _Halp8259Lock
|
|
EnbSysIntRelease:
|
|
RELEASE_SPINLOCK eax
|
|
|
|
EnbSysIntExit:
|
|
exproc 0Ah
|
|
sti
|
|
pop ebx
|
|
mov eax, 1
|
|
stdRET _HalEnableSystemInterrupt
|
|
|
|
EnbSysIntError:
|
|
if DBG
|
|
int 3
|
|
endif
|
|
exproc 0Ah
|
|
sti
|
|
pop ebx
|
|
xor eax,eax
|
|
stdRET _HalEnableSystemInterrupt
|
|
|
|
EnbSysIntSpin:
|
|
SPIN_ON_SPINLOCK eax, EnbSysIntAquire
|
|
|
|
stdENDP _HalEnableSystemInterrupt
|
|
|
|
|
|
_TEXT ENDS
|
|
END
|