diff options
Diffstat (limited to '')
-rw-r--r-- | public/sdk/inc/mac386.inc | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/public/sdk/inc/mac386.inc b/public/sdk/inc/mac386.inc new file mode 100644 index 000000000..982df197c --- /dev/null +++ b/public/sdk/inc/mac386.inc @@ -0,0 +1,267 @@ +;++ +; +; Copyright (c) 1989 Microsoft Corporation +; +; Module Name: +; +; mac386.inc - 386 machine specific assembler macros +; +; Abstract: +; +; This module contains 386 machine specific (assembler) macros +; applicable to code outside the kernel. Note that +; ACQUIRE_SPINLOCK_DIRECT assumes the PCR is handy, so it won't +; work in user mode (with debugging turned on.) +; +; Author: +; +; Bryan Willman (bryanwi) 1 Aug 90 +; + +if NT_INST +else + +;++ +; +; ACQUIRE_SPINLOCK LockAddress, SpinLabel +; +; Macro Description: +; +; This macro acquires a kernel spin lock. +; +; N.B. This macro assumes that the current IRQL is set properly. +; It neither raises nor lowers IRQL. +; +; Arguments: +; +; (KSPIN_LOCK) LockAddress - address of SpinLock value +; SpinLabel - if acquire spinlock fail, the label to perform the +; spin checking. It could be simply a "label" or +; "short label" which means the label is within 128 +; bytes in distant. +; +; NoChecking - Not blank, if no debugging code should be generated. +;-- + +ACQUIRE_SPINLOCK macro LockAddress, SpinLabel, NoChecking + +.errb <LockAddress> +.errb <SpinLabel> + +ifndef NT_UP + +; +; Attempt to assert the lock +; + + lock bts dword ptr [LockAddress], 0 ; test and set the spinlock + jc SpinLabel ; spinlock owned, go SpinLabe + +if DBG +ifb <NoChecking> + push edi ; save edi + mov edi,fs:PcPrcb + mov edi, [edi].PbCurrentThread + or edi, 1 ; spinlock owned + mov [LockAddress], edi ; remember current thread + pop edi ; restore edi +endif ; NoChecking +endif ; DBG +endif ; NT_UP + +endm + +;++ +; +; SPIN_ON_SPINLOCK LockAddress, AcquireLabel +; +; Macro Description: +; +; This macro spins on a kernel spin lock. +; +; N.B. This macro assumes that the current IRQL is set properly. +; It neither raises nor lowers IRQL. +; +; Arguments: +; +; (KSPIN_LOCK) LockAddress - address of a SpinLock value +; +; SpinLabel - if the test on cleared spinlock sucess, the label +; to assert the spin lock. It could be simply a +; "label" or "short label" which means the label is +; within 128 bytes in distance. +; +; NoChecking - Not blank, if no debugging code should be generated. +;-- + +SPIN_ON_SPINLOCK macro LockAddress, AcquireLabel, NoChecking, PollDebugger, NoTimeout +local a,flag ; define a local label + +.errb <LockAddress> +.errb <AcquireLabel> + +ifndef NT_UP +if DBG + +EXTRNP Kii386SpinOnSpinLock,2 + flag = 0 + +ifb <NoChecking> + flag = flag + 1 +endif + +ifnb <Polldebugger> + flag = flag + 2 +endif + +ifb <NoTimeout> + flag = flag + 4 +endif + stdCall Kii386SpinOnSpinLock,<LockAddress,flag> + jmp AcquireLabel + +else ; DBG + +; +; Non-Debug version +; + +a: test dword ptr [LockAddress], 1 ; Was spinlock cleared? + jz AcquireLabel ; Yes, go get it + jmp short a + +endif ; DBG +endif ; NT_UP + +endm + + +;++ +; +; TEST_SPINLOCK LockAddress, BusyLabel +; +; Macro Description: +; +; This macro tests a kernel spin lock to see if it's busy. +; If it's not busy, ACQUIRE_SPINLOCK still needs to be called +; to obtain the spinlock in a locked manner. +; +; Arguments: +; +; (KSPIN_LOCK) LockAddress - address of a SpinLock value + + +TEST_SPINLOCK macro LockAddress, BusyLabel + test dword ptr [LockAddress], 1 ; spinlock clear? + jnz BusyLabel ; No, then busy +endm + + + + +;++ +; +; RELEASE_SPINLOCK LockAddress +; +; Macro Description: +; +; This macro releases a kernel spin lock. +; +; N.B. This macro assumes that the current IRQL is set properly. +; It neither raises nor lowers IRQL. +; +; Arguments: +; +; (KSPIN_LOCK) LockAddress - Supplies an address to a spin lock value +; NoChecking - Not blank, if no debugging code should be generated. +;-- + +RELEASE_SPINLOCK macro LockAddress, NoChecking +local a +.errb <LockAddress> +ifndef NT_UP +if DBG +ifb <NoChecking> +EXTRNP _KeBugCheck,1 + + push edi ; save edi + mov edi,fs:PcPrcb + mov edi,[edi].PbCurrentThread + or edi, 1 ; assume current thread owns the lock + cmp edi, [LockAddress] ; Does current thread own the lock? + pop edi ; restore edi + jz short a ; if z, yes, goto a and release lock + stdCall _KeBugCheck,<LockAddress> ; Never return ... +a: +endif + mov dword ptr [LockAddress], 0 +else + mov byte ptr [LockAddress], 0 + +endif ; DBG +endif ; NT_UP +endm + + +endif +if NT_INST + +; +; These are the instrumentation version of the above functions. +; internal use only +; + +ACQUIRE_SPINLOCK macro LockAddress, SpinLabel, NoChecking +EXTRNP KiInst_AcquireSpinLock,0 +ifidni <&LockAddress>, <eax> + stdCall KiInst_AcquireSpinLock +else + push eax + mov eax, LockAddress + stdCall KiInst_AcquireSpinLock + pop eax +endif + jc SpinLabel +endm + +SPIN_ON_SPINLOCK macro LockAddress, AcquireLabel, NoChecking, PollDebugger +EXTRNP KiInst_SpinOnSpinLock,0 +ifidni <&LockAddress>, <eax> + stdCall KiInst_SpinOnSpinLock +else + push eax + mov eax, LockAddress + stdCall KiInst_SpinOnSpinLock + pop eax +endif + jmp AcquireLabel +endm + +TEST_SPINLOCK macro LockAddress, BusyLabel +EXTRNP KiInst_TestSpinLock,0 +ifidni <&LockAddress>, <eax> + stdCall KiInst_TestSpinLock +else + push eax + mov eax, LockAddress + stdCall KiInst_TestSpinLock + pop eax +endif + jnc AcquireLabel +endm + +RELEASE_SPINLOCK macro LockAddress, NoChecking +EXTRNP KiInst_ReleaseSpinLock,0 +ifidni <&LockAddress>, <eax> + stdCall KiInst_ReleaseSpinLock +else + push eax + mov eax, LockAddress + stdCall KiInst_ReleaseSpinLock + pop eax +endif +endm + +endif + + |