Hello,
I have been tasked to upgrade an exiting x86 WDM driver to a Windows x64 system. I am using the WDK 7600.16385.0 for the build process. The 32 bit version of the driver had some inline assembly code to implement the ExInterlockedRemoveEntryList() routine, which is not available in Windows.
The routine below needs to lock out interrupts as the list can be manipulated in both ISR and non-ISR context. It also needs to be multi-processor safe.
VOID ExInterlockedRemoveEntryList(PLIST_ENTRY Entry, PKSPIN_LOCK spLock)
{
#if defined(X86)
_asm {
mov edx, spLock // set pointer to lock
waitLoop:
pushfd // save current CPU flags
cli // clear the CPU interrupt mask
lock bts word ptr [edx], 0 // can we have the lock?
jnb lockHeld // yes, go do something while protected
popfd // restore the CPU flags (permit an interrupt)
jmp waitLoop // loop till lock held
lockHeld:
push edx // save index pointer
};
PLIST_ENTRY Flink=Entry->Flink,
Blink=Entry->Blink;
Blink->Flink = Flink;
Flink->Blink = Blink;
_asm {
pop edx
mov byte ptr [edx], 0 // Release the lock
popfd // Restore the CPU flags
}
#elif defined(AMD64) /*X64*/
KSPIN_LOCK prevValue,prevCopy;
_disable();
prevValue = *spLock;
do {
prevCopy = prevValue;
/* Compare current value of spLock with 0. If it 0 exchange it
* with 1. If it is already 1 don’t exchange it with 0, as it implies
* spLock has been taken by somebody else. In that case spin here
* until you get spLock.
*/
prevValue = InterlockedCompareExchange64((volatile LONG64 *)spLock,1,0);
/* When you get out of the while, you have the lock.
*/
}while(prevValue != prevCopy);
RemoveEntryList(Entry); // Remove the entry from it’s list
InterlockedExchange64((volatile LONG64 *)spLock,0);
_enable();
#endif
I am trying to use compiler intrinsic code in place of the assembly. I have have come across an issue where I have replaced the cli and re-enabling of interrupts with the _disable() and _enable(). I have a really old SDK for Windows XP and Visual Studio 2003 and the WDK build is unable to resolve these routines.
The MSDN documentation on _enable() and _disable() suggested that I could include <intrin.h> with Visual Studio 2005 for x64 architecture. Here, Would moving to VS2005 help in resolving the problem? Or is there a different approach for ExInterlockedRemoveEntryList?
Windows, probably doesn’t expect drivers to use ExInterlockedRemoveEntryList, but what is the possibility that the routine that is implemented for the x64 system has any chances of working. Insertion into the lists is performed via windows provided ExInsert… routines.
Any advise will be helpful.
Thanks,
Amit</intrin.h>