Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1359 lines
33 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. vihal.h
  5. Abstract:
  6. This module contains the private declarations to verify hal usage & apis.
  7. Author:
  8. Jordan Tigani (jtigani) 12-Nov-1999
  9. Revision History:
  10. 6-23-00: (jtigani) Moved from halverifier.c
  11. --*/
  12. /////////////////////////////////////////////////////////////////////
  13. //////////////////////////////////////////////// Hal verifier defines
  14. /////////////////////////////////////////////////////////////////////
  15. //
  16. // Bugcheck codes -- the major code is HAL_VERIFIER_DETECTED_VIOLATION --
  17. // the sub-code is the HV_*
  18. //
  19. #define HAL_VERIFIER_DETECTED_VIOLATION 0xE6
  20. #define HV_MISCELLANEOUS_ERROR 0x00
  21. #define HV_PERFORMANCE_COUNTER_DECREASED 0x01
  22. #define HV_PERFORMANCE_COUNTER_SKIPPED 0x02
  23. #define HV_FREED_TOO_MANY_COMMON_BUFFERS 0x03
  24. #define HV_FREED_TOO_MANY_ADAPTER_CHANNELS 0x04
  25. #define HV_FREED_TOO_MANY_MAP_REGISTERS 0x05
  26. #define HV_FREED_TOO_MANY_SCATTER_GATHER_LISTS 0x06
  27. #define HV_LEFTOVER_COMMON_BUFFERS 0x07
  28. #define HV_LEFTOVER_ADAPTER_CHANNELS 0x08
  29. #define HV_LEFTOVER_MAP_REGISTERS 0x09
  30. #define HV_LEFTOVER_SCATTER_GATHER_LISTS 0x0A
  31. #define HV_TOO_MANY_ADAPTER_CHANNELS 0x0B
  32. #define HV_TOO_MANY_MAP_REGISTERS 0x0C
  33. #define HV_DID_NOT_FLUSH_ADAPTER_BUFFERS 0x0D
  34. #define HV_DMA_BUFFER_NOT_LOCKED 0x0E
  35. #define HV_BOUNDARY_OVERRUN 0x0F
  36. #define HV_CANNOT_FREE_MAP_REGISTERS 0x10
  37. #define HV_DID_NOT_PUT_ADAPTER 0x11
  38. #define HV_MDL_FLAGS_NOT_SET 0x12
  39. #define HV_BAD_IRQL 0x13
  40. #define HV_BAD_IRQL_JUST_WARN 0x14
  41. #define HV_OUT_OF_MAP_REGISTERS 0x15
  42. #define HV_FLUSH_EMPTY_BUFFERS 0x16
  43. #define HV_MISMATCHED_MAP_FLUSH 0x17
  44. #define HV_ADAPTER_ALREADY_RELEASED 0x18
  45. #define HV_NULL_DMA_ADAPTER 0x19
  46. #define HV_MAP_FLUSH_NO_TRANSFER 0x1A
  47. #define HV_ADDRESS_NOT_IN_MDL 0x1b
  48. #define HV_DATA_LOSS 0x1c
  49. #define HV_DOUBLE_MAP_REGISTER 0x1d
  50. #define HV_OBSOLETE_API 0x1e
  51. #define HV_BAD_MDL 0x1f
  52. #define HV_FLUSH_NOT_MAPPED 0x20
  53. #define HV_MAP_ZERO_LENGTH_BUFFER 0x21
  54. ///
  55. // Codes to decide what to do when we hit a driver problem.
  56. ///
  57. #define HVC_IGNORE 0x00 // Do nothing.
  58. #define HVC_WARN 0x02 // Print message # continue
  59. #define HVC_ASSERT 0x04 // Print message # break
  60. #define HVC_BUGCHECK 0x08 // Print message # bugcheck
  61. #define HVC_ONCE 0x10 // combined with another code,
  62. #define HAL_VERIFIER_POOL_TAG 'VlaH' // HalV backwards //
  63. //
  64. // This is how we can recognize our double buffers
  65. //
  66. #define MAP_REGISTER_FILL_CHAR 0x0E
  67. #define PADDING_FILL_CHAR 0x0F
  68. //
  69. // Since we hook the "MapRegisterBase" with a MapRegisterFile, we sign
  70. // the first four bytes so we can tell the difference between the HAL's
  71. // map register base and our map register file.
  72. //
  73. #define MRF_SIGNATURE 0xACEFD00D
  74. //
  75. // This is what we use if the hal has returned a NULL map register base so
  76. // that drivers don't assume that they don't have flush adapter buffers.
  77. //
  78. #define MRF_NULL_PLACEHOLDER (PVOID)(LONG_PTR)(LONG)0xDEADF00D
  79. //
  80. // This should devide evenly into 2^32
  81. //
  82. #define MAX_COUNTERS 0x20
  83. //
  84. // Flags to indicate where the buffer tagging shall happen
  85. //
  86. #define TAG_BUFFER_START 0x01
  87. #define TAG_BUFFER_END 0x02
  88. //
  89. // How many map registers we can double-buffer at once
  90. // using physical contiguous memory.
  91. // This must be an integral multiple of the number of bits in a ULONG
  92. //
  93. #define MAX_CONTIGUOUS_MAP_REGISTERS 0x20
  94. //
  95. // Flags that describe a map register
  96. //
  97. #define MAP_REGISTER_WRITE 0x01 // the transfer is a write to device
  98. #define MAP_REGISTER_READ 0x02 // the transfer is a read from device
  99. #define MAP_REGISTER_RW_MASK (MAP_REGISTER_WRITE | MAP_REGISTER_READ)
  100. /////////////////////////////////////////////////////////////////////
  101. //////////////////////// Safe multi-processor 64 bit reads and writes
  102. /////////////////////////////////////////////////////////////////////
  103. #if defined (_X86_)
  104. //
  105. // Only save the time stamp counter on x86 machines
  106. //
  107. #define ViRdtsc ViRdtscX86
  108. //
  109. // Structure to do a locked 64 bit write /compare without
  110. // a spinlock.
  111. //
  112. typedef struct _TIMER64 {
  113. ULONG TimeLow;
  114. ULONG TimeHigh1;
  115. ULONG TimeHigh2;
  116. ULONG Reserved; // for packing sake //
  117. } TIMER64, *PTIMER64;
  118. //
  119. // Since we can't do a 64 bit atomic operation
  120. // without a spinlock, we have to monkey around a bit
  121. // This method comes from the acpi timer code.
  122. //
  123. #define SAFE_READ_TIMER64(WriteLargeInteger, ReadTimer64) \
  124. \
  125. while (TRUE) { \
  126. (WriteLargeInteger).HighPart = (ReadTimer64).TimeHigh2; \
  127. (WriteLargeInteger).LowPart = (ReadTimer64).TimeLow; \
  128. \
  129. if ((ULONG)(WriteLargeInteger).HighPart == (ReadTimer64).TimeHigh1) \
  130. break; \
  131. \
  132. _asm { rep nop }; \
  133. }
  134. #define SAFE_WRITE_TIMER64(WriteTimer64, ReadLargeInteger) \
  135. WriteTimer64.TimeHigh1 = (ReadLargeInteger).HighPart; \
  136. WriteTimer64.TimeLow = (ReadLargeInteger).LowPart; \
  137. WriteTimer64.TimeHigh2 = (ReadLargeInteger).HighPart;
  138. // defined (_X86_) //
  139. #else
  140. // ! defined (_X86_) //
  141. #if defined(_IA64_)
  142. #define ViRdtsc ViRdtscIA64
  143. #else // !_IA64_
  144. //
  145. // Only save the time stamp counter on x86 and ia64 machines
  146. //
  147. #define ViRdtsc ViRdtscNull
  148. #endif // !_IA64_
  149. //
  150. // Alpha or IA64 can do atomic 64 bit read/writes.
  151. //
  152. typedef LARGE_INTEGER TIMER64;
  153. #define SAFE_READ_TIMER64(WriteLargeInteger, ReadTimer64) \
  154. InterlockedExchangePointer( \
  155. &((PVOID) (WriteLargeInteger).QuadPart ), \
  156. (PVOID) (ReadTimer64).QuadPart \
  157. );
  158. #define SAFE_WRITE_TIMER64(WriteTimer64, ReadLargeInteger) \
  159. InterlockedExchangePointer( \
  160. &((PVOID) (WriteTimer64).QuadPart ), \
  161. (PVOID) (ReadLargeInteger).QuadPart \
  162. );
  163. // ! defined (_X86_) //
  164. #endif
  165. /////////////////////////////////////////////////////////////////////
  166. ///////////////////////////////////////// Hal verifier global externs
  167. /////////////////////////////////////////////////////////////////////
  168. extern ULONG VfVerifyDma;
  169. extern LOGICAL VfVerifyPerformanceCounter;
  170. extern LOGICAL ViDoubleBufferDma;
  171. extern LOGICAL ViProtectBuffers;
  172. extern LOGICAL ViInjectDmaFailures;
  173. extern LOGICAL ViSuperDebug;
  174. extern LOGICAL ViSufficientlyBootedForPcControl;
  175. extern LOGICAL ViSufficientlyBootedForDmaFailure;
  176. extern ULONG ViMaxMapRegistersPerAdapter;
  177. extern ULONG ViAllocationsFailedDeliberately;
  178. extern LARGE_INTEGER ViRequiredTimeSinceBoot;
  179. extern CHAR ViDmaVerifierTag[];
  180. extern BOOLEAN ViPenalties[];
  181. extern struct _HAL_VERIFIER_LOCKED_LIST ViAdapterList;
  182. extern struct _VF_TIMER_INFORMATION * ViTimerInformation;
  183. extern struct _DMA_OPERATIONS ViDmaOperations;
  184. extern struct _DMA_OPERATIONS ViLegacyDmaOperations;
  185. /////////////////////////////////////////////////////////////////////
  186. ////////////////////////////////// Hal verifier structure definitions
  187. /////////////////////////////////////////////////////////////////////
  188. typedef struct _TIMER_TICK {
  189. ULONG Processor;
  190. ULONG Reserved;
  191. LARGE_INTEGER TimeStampCounter;
  192. LARGE_INTEGER PerformanceCounter;
  193. LARGE_INTEGER TimerTick;
  194. } TIMER_TICK, *PTIMER_TICK;
  195. typedef struct _VF_TIMER_INFORMATION {
  196. KDPC RefreshDpc;
  197. KTIMER RefreshTimer;
  198. TIMER64 LastPerformanceCounter;
  199. TIMER64 UpperBound;
  200. TIMER64 LastTickCount;
  201. TIMER64 LastKdStartTime;
  202. LARGE_INTEGER PerformanceFrequency;
  203. ULONG CountsPerTick;
  204. ULONG CurrentCounter;
  205. TIMER_TICK SavedTicks[MAX_COUNTERS];
  206. } VF_TIMER_INFORMATION, *PVF_TIMER_INFORMATION;
  207. typedef struct _HAL_VERIFIER_LOCKED_LIST {
  208. LIST_ENTRY ListEntry;
  209. KSPIN_LOCK SpinLock;
  210. } HAL_VERIFIER_LOCKED_LIST, *PHAL_VERIFIER_LOCKED_LIST;
  211. typedef struct _HAL_VERIFIER_BUFFER {
  212. USHORT PrePadBytes;
  213. USHORT PostPadBytes;
  214. ULONG RealLength;
  215. ULONG AdvertisedLength;
  216. PVOID RealStartAddress;
  217. PVOID AdvertisedStartAddress;
  218. PHYSICAL_ADDRESS RealLogicalStartAddress;
  219. PVOID AllocatorAddress;
  220. LIST_ENTRY ListEntry;
  221. } HAL_VERIFIER_BUFFER, *PHAL_VERIFIER_BUFFER;
  222. typedef struct _MAP_REGISTER {
  223. PVOID MappedToSa;
  224. ULONG BytesMapped;
  225. ULONG Flags;
  226. PVOID MapRegisterStart;
  227. } MAP_REGISTER, *PMAP_REGISTER;
  228. typedef struct _MAP_REGISTER_FILE {
  229. ULONG Signature;
  230. LIST_ENTRY ListEntry;
  231. BOOLEAN ContiguousMap;
  232. BOOLEAN ScatterGather;
  233. ULONG NumberOfMapRegisters;
  234. ULONG NumberOfRegistersMapped;
  235. PVOID MapRegisterBaseFromHal;
  236. PMDL MapRegisterMdl;
  237. PVOID MapRegisterBuffer;
  238. KSPIN_LOCK AllocationLock;
  239. MAP_REGISTER MapRegisters[1];
  240. // Rest of the map registers go here
  241. //
  242. } MAP_REGISTER_FILE, *PMAP_REGISTER_FILE;
  243. typedef struct _VF_WAIT_CONTEXT_BLOCK {
  244. PVOID RealContext;
  245. PVOID RealCallback;
  246. PMDL RealMdl;
  247. PVOID RealStartVa;
  248. ULONG RealLength;
  249. ULONG NumberOfMapRegisters;
  250. struct _ADAPTER_INFORMATION * AdapterInformation;
  251. PSCATTER_GATHER_LIST ScatterGatherList;
  252. LIST_ENTRY ListEntry;
  253. PMAP_REGISTER_FILE MapRegisterFile;
  254. } VF_WAIT_CONTEXT_BLOCK, *PVF_WAIT_CONTEXT_BLOCK;
  255. //
  256. // Store a list of the real dma operations used by an adapter ...
  257. // when the driver allocates the adapter, we're going to replace all of its
  258. // dma operations with ours
  259. //
  260. typedef struct _ADAPTER_INFORMATION {
  261. LIST_ENTRY ListEntry;
  262. PDMA_ADAPTER DmaAdapter;
  263. PDEVICE_OBJECT DeviceObject;
  264. BOOLEAN DeferredRemove;
  265. BOOLEAN UseContiguousBuffers;
  266. BOOLEAN UseDmaChannel;
  267. BOOLEAN Inactive;
  268. PVOID CallingAddress;
  269. PDMA_OPERATIONS RealDmaOperations;
  270. HAL_VERIFIER_LOCKED_LIST ScatterGatherLists;
  271. HAL_VERIFIER_LOCKED_LIST CommonBuffers;
  272. HAL_VERIFIER_LOCKED_LIST MapRegisterFiles;
  273. ULONG MaximumMapRegisters;
  274. ULONG AllocatedMapRegisters;
  275. LONG ActiveMapRegisters;
  276. ULONG AllocatedScatterGatherLists;
  277. LONG ActiveScatterGatherLists;
  278. ULONG AllocatedCommonBuffers;
  279. ULONG FreedCommonBuffers;
  280. ULONG AllocatedAdapterChannels; // Must be 1 or less ! //
  281. ULONG FreedAdapterChannels;
  282. ULONG MappedTransferWithoutFlushing;
  283. DEVICE_DESCRIPTION DeviceDescription;
  284. ULONG AdapterChannelMapRegisters;
  285. VF_WAIT_CONTEXT_BLOCK AdapterChannelContextBlock;
  286. PVOID *ContiguousBuffers; // array of contiguous 3-page buffers to be used for double-buffering
  287. ULONG SuccessfulContiguousAllocations; // how many times we allocated contiguous space
  288. ULONG FailedContiguousAllocations; // how many times we failed to allocate contiguous space
  289. KSPIN_LOCK AllocationLock; // lock for our allocator routines
  290. ULONG AllocationStorage[MAX_CONTIGUOUS_MAP_REGISTERS / (sizeof(ULONG) * 8)]; // bitmask for allocator routines
  291. RTL_BITMAP AllocationMap;
  292. ULONG ContiguousMapRegisters; // allocated among ContiguousBufers
  293. ULONG NonContiguousMapRegisters; // allocated from non-Paged Pool
  294. } ADAPTER_INFORMATION, *PADAPTER_INFORMATION;
  295. /////////////////////////////////////////////////////////////////////
  296. ////////////////////////////////// Hal verifier function declarations
  297. /////////////////////////////////////////////////////////////////////
  298. //==========================
  299. // Declare our dma apis here
  300. // if NO_LEGACY_DRIVERS *is*
  301. // enabled
  302. // =========================
  303. #if defined(NO_LEGACY_DRIVERS)
  304. VOID
  305. VfPutDmaAdapter(
  306. struct _DMA_ADAPTER * DmaAdapter
  307. );
  308. PVOID
  309. VfAllocateCommonBuffer(
  310. IN struct _DMA_ADAPTER * DmaAdapter,
  311. IN ULONG Length,
  312. OUT PPHYSICAL_ADDRESS LogicalAddress,
  313. IN BOOLEAN CacheEnabled
  314. );
  315. VOID
  316. VfFreeCommonBuffer(
  317. IN struct _DMA_ADAPTER * DmaAdapter,
  318. IN ULONG Length,
  319. IN PHYSICAL_ADDRESS LogicalAddress,
  320. IN PVOID VirtualAddress,
  321. IN BOOLEAN CacheEnabled
  322. );
  323. NTSTATUS
  324. VfAllocateAdapterChannel(
  325. IN struct _DMA_ADAPTER * DmaAdapter,
  326. IN PDEVICE_OBJECT DeviceObject,
  327. IN ULONG NumberOfMapRegisters,
  328. IN PDRIVER_CONTROL ExecutionRoutine,
  329. IN PVOID Context
  330. );
  331. PHYSICAL_ADDRESS
  332. VfMapTransfer(
  333. IN struct _DMA_ADAPTER * DmaAdapter,
  334. IN PMDL Mdl,
  335. IN PVOID MapRegisterBase,
  336. IN PVOID CurrentVa,
  337. IN OUT PULONG Length,
  338. IN BOOLEAN WriteToDevice
  339. );
  340. BOOLEAN
  341. VfFlushAdapterBuffers(
  342. IN struct _DMA_ADAPTER * DmaAdapter,
  343. IN PMDL Mdl,
  344. IN PVOID MapRegisterBase,
  345. IN PVOID CurrentVa,
  346. IN ULONG Length,
  347. IN BOOLEAN WriteToDevice
  348. );
  349. VOID
  350. VfFreeAdapterChannel(
  351. IN struct _DMA_ADAPTER * DmaAdapter
  352. );
  353. VOID
  354. VfFreeMapRegisters(
  355. IN struct _DMA_ADAPTER * DmaAdapter,
  356. PVOID MapRegisterBase,
  357. ULONG NumberOfMapRegisters
  358. );
  359. ULONG
  360. VfGetDmaAlignment(
  361. IN struct _DMA_ADAPTER * DmaAdapter
  362. );
  363. ULONG
  364. VfReadDmaCounter(
  365. IN struct _DMA_ADAPTER * DmaAdapter
  366. );
  367. NTSTATUS
  368. VfGetScatterGatherList (
  369. IN struct _DMA_ADAPTER * DmaAdapter,
  370. IN PDEVICE_OBJECT DeviceObject,
  371. IN PMDL Mdl,
  372. IN PVOID CurrentVa,
  373. IN ULONG Length,
  374. IN PVOID ExecutionRoutine,
  375. IN PVOID Context,
  376. IN BOOLEAN WriteToDevice
  377. );
  378. VOID
  379. VfPutScatterGatherList(
  380. IN struct _DMA_ADAPTER * DmaAdapter,
  381. IN struct _SCATTER_GATHER_LIST * ScatterGather,
  382. IN BOOLEAN WriteToDevice
  383. );
  384. #endif
  385. // =====================
  386. // New verified dma apis
  387. // =====================
  388. NTSTATUS
  389. VfCalculateScatterGatherListSize(
  390. IN PDMA_ADAPTER DmaAdapter,
  391. IN OPTIONAL PMDL Mdl,
  392. IN PVOID CurrentVa,
  393. IN ULONG Length,
  394. OUT PULONG ScatterGatherListSize,
  395. OUT OPTIONAL PULONG pNumberOfMapRegisters
  396. );
  397. NTSTATUS
  398. VfBuildScatterGatherList(
  399. IN PDMA_ADAPTER DmaAdapter,
  400. IN PDEVICE_OBJECT DeviceObject,
  401. IN PMDL Mdl,
  402. IN PVOID CurrentVa,
  403. IN ULONG Length,
  404. IN PDRIVER_LIST_CONTROL ExecutionRoutine,
  405. IN PVOID Context,
  406. IN BOOLEAN WriteToDevice,
  407. IN PVOID ScatterGatherBuffer,
  408. IN ULONG ScatterGatherLength
  409. );
  410. NTSTATUS
  411. VfBuildMdlFromScatterGatherList(
  412. IN PDMA_ADAPTER DmaAdapter,
  413. IN PSCATTER_GATHER_LIST ScatterGather,
  414. IN PMDL OriginalMdl,
  415. OUT PMDL *TargetMdl
  416. );
  417. IO_ALLOCATION_ACTION
  418. VfAdapterCallback(
  419. IN PDEVICE_OBJECT DeviceObject,
  420. IN PIRP Irp,
  421. IN PVOID MapRegisterBase,
  422. IN PVOID Context
  423. );
  424. VOID
  425. VfScatterGatherCallback(
  426. IN struct _DEVICE_OBJECT *DeviceObject,
  427. IN struct _IRP *Irp,
  428. IN struct _SCATTER_GATHER_LIST * ScatterGather,
  429. IN PVOID Context
  430. );
  431. // ==============================
  432. // Hal verifier internal routines
  433. // ==============================
  434. PADAPTER_INFORMATION
  435. ViHookDmaAdapter(
  436. IN PDMA_ADAPTER DmaAdapter,
  437. IN PDEVICE_DESCRIPTION DeviceDescription,
  438. IN ULONG NumberOfMapRegisters
  439. );
  440. VOID
  441. ViReleaseDmaAdapter(
  442. IN PADAPTER_INFORMATION AdapterInformation
  443. );
  444. PADAPTER_INFORMATION
  445. ViGetAdapterInformation(
  446. IN PDMA_ADAPTER DmaAdapter
  447. );
  448. PVOID
  449. ViGetRealDmaOperation(
  450. IN PDMA_ADAPTER DmaAdapter,
  451. IN ULONG AdapterInformationOffset
  452. );
  453. LARGE_INTEGER
  454. ViRdtsc(
  455. VOID
  456. );
  457. VOID
  458. VfInitializeTimerInformation(
  459. VOID
  460. );
  461. VOID
  462. ViRefreshCallback(
  463. IN PKDPC Dpc,
  464. IN PVOID DeferredContext,
  465. IN PVOID SystemArgument1,
  466. IN PVOID SystemArgument2
  467. );
  468. LOGICAL
  469. VfInjectDmaFailure (
  470. VOID
  471. );
  472. // =================================================
  473. // Hal verfier special routines to track allocations
  474. // =================================================
  475. PVOID
  476. ViSpecialAllocateCommonBuffer(
  477. IN PALLOCATE_COMMON_BUFFER AllocateCommonBuffer,
  478. IN PADAPTER_INFORMATION AdapterInformation,
  479. IN PVOID CallingAddress,
  480. IN ULONG Length,
  481. IN OUT PPHYSICAL_ADDRESS LogicalAddress,
  482. IN LOGICAL CacheEnabled
  483. );
  484. LOGICAL
  485. ViSpecialFreeCommonBuffer(
  486. IN PFREE_COMMON_BUFFER FreeCommonBuffer,
  487. IN PADAPTER_INFORMATION AdapterInformation,
  488. IN PVOID CommonBuffer,
  489. LOGICAL CacheEnabled
  490. );
  491. // ===================================================
  492. // Hal verfier special routines to do double buffering
  493. // ===================================================
  494. PMAP_REGISTER_FILE
  495. ViAllocateMapRegisterFile(
  496. IN PADAPTER_INFORMATION AdapterInformation,
  497. IN ULONG NumberOfMapRegisters
  498. );
  499. LOGICAL
  500. ViFreeMapRegisterFile(
  501. IN PADAPTER_INFORMATION AdapterInformation,
  502. IN PMAP_REGISTER_FILE MapRegisterFile
  503. );
  504. ULONG
  505. ViMapDoubleBuffer(
  506. IN PMAP_REGISTER_FILE MapRegisterFile,
  507. IN OUT PMDL Mdl,
  508. IN OUT PVOID CurrentVa,
  509. IN ULONG Length,
  510. IN BOOLEAN WriteToDevice
  511. );
  512. LOGICAL
  513. ViFlushDoubleBuffer(
  514. IN PMAP_REGISTER_FILE MapRegisterFile,
  515. IN PMDL Mdl,
  516. IN PVOID CurrentVa,
  517. IN ULONG Length,
  518. IN BOOLEAN WriteToDevice
  519. );
  520. LOGICAL
  521. ViAllocateMapRegistersFromFile(
  522. IN PMAP_REGISTER_FILE MapRegisterFile,
  523. IN PVOID CurrentSa,
  524. IN ULONG Length,
  525. IN BOOLEAN WriteToDevice,
  526. OUT PULONG MapRegisterNumber
  527. );
  528. LOGICAL
  529. ViFreeMapRegistersToFile(
  530. IN PMAP_REGISTER_FILE MapRegisterFile,
  531. IN PVOID CurrentSa,
  532. IN ULONG Length
  533. );
  534. PMAP_REGISTER
  535. ViFindMappedRegisterInFile(
  536. IN PMAP_REGISTER_FILE MapRegisterFile,
  537. IN PVOID CurrentSa,
  538. OUT PULONG MapRegisterNumber OPTIONAL
  539. );
  540. LOGICAL
  541. ViSwap(IN OUT PVOID * MapRegisterBase,
  542. IN OUT PMDL * Mdl,
  543. IN OUT PVOID * CurrentVa
  544. );
  545. VOID
  546. ViCheckAdapterBuffers(
  547. IN PADAPTER_INFORMATION AdapterInformation
  548. );
  549. VOID
  550. ViTagBuffer(
  551. IN PVOID AdvertisedBuffer,
  552. IN ULONG AdvertisedLength,
  553. IN USHORT WhereToTag
  554. );
  555. VOID
  556. ViCheckTag(
  557. IN PVOID AdvertisedBuffer,
  558. IN ULONG AdvertisedLength,
  559. IN BOOLEAN RemoveTag,
  560. IN USHORT WhereToCheck
  561. );
  562. VOID
  563. ViInitializePadding(
  564. IN PVOID RealBufferStart,
  565. IN ULONG RealBufferLength,
  566. IN PVOID AdvertisedBufferStart, OPTIONAL
  567. IN ULONG AdvertisedBufferLength OPTIONAL
  568. );
  569. VOID
  570. ViCheckPadding(
  571. IN PVOID RealBufferStart,
  572. IN ULONG RealBufferLength,
  573. IN PVOID AdvertisedBufferStart, OPTIONAL
  574. IN ULONG AdvertisedBufferLength OPTIONAL
  575. );
  576. PULONG_PTR
  577. ViHasBufferBeenTouched(
  578. IN PVOID Address,
  579. IN ULONG_PTR Length,
  580. IN UCHAR ExpectedFillChar
  581. );
  582. VOID
  583. VfAssert(
  584. IN LOGICAL Condition,
  585. IN ULONG Code,
  586. IN OUT PULONG Enable
  587. );
  588. VOID
  589. ViMapTransferHelper(
  590. IN PMDL Mdl,
  591. IN PVOID CurrentVa,
  592. IN ULONG TransferLength,
  593. IN PULONG PageFrame,
  594. IN OUT PULONG Length
  595. );
  596. VOID
  597. ViCommonBufferCalculatePadding(
  598. IN ULONG Length,
  599. OUT PULONG PrePadding,
  600. OUT PULONG PostPadding
  601. );
  602. VOID
  603. ViAllocateContiguousMemory (
  604. IN OUT PADAPTER_INFORMATION AdapterInformation
  605. );
  606. PVOID
  607. ViAllocateFromContiguousMemory (
  608. IN OUT PADAPTER_INFORMATION AdapterInformation,
  609. IN ULONG HintIndex
  610. );
  611. LOGICAL
  612. ViFreeToContiguousMemory (
  613. IN OUT PADAPTER_INFORMATION AdapterInformation,
  614. IN PVOID Address,
  615. IN ULONG HintIndex
  616. );
  617. LOGICAL
  618. VfIsPCIBus (
  619. IN PDEVICE_OBJECT PhysicalDeviceObject
  620. );
  621. PDEVICE_OBJECT
  622. VfGetPDO (
  623. IN PDEVICE_OBJECT DeviceObject
  624. );
  625. /////////////////////////////////////////////////////////////////////
  626. ///////////////////////////////////////////////// Hal verifier macros
  627. /////////////////////////////////////////////////////////////////////
  628. //
  629. // This is a kind of long macro but it lets us decide what to
  630. // do on certain kinds of errors. For instance, if we know
  631. // we are going to hit something once, we might set it to
  632. // HVC_WARN. Or if we know we will hit it 1000 times, but don't
  633. // want to take the code out completely (especially if we're doing
  634. // it on the fly), we can set it to HVC_IGNORE
  635. //
  636. #define VF_ASSERT(condition, code, message) \
  637. { \
  638. static ULONG enable = (ULONG) -1; \
  639. if (enable == (ULONG) -1) \
  640. enable = ViPenalties[code]; \
  641. if (!(condition) && enable) \
  642. { \
  643. DbgPrint("* * * * * * * * HAL Verifier Detected Violation * * * * * * * *\n");\
  644. DbgPrint("* *\n"); \
  645. DbgPrint("* * VF: "); \
  646. DbgPrint message; \
  647. DbgPrint("\n"); \
  648. DbgPrint("* *\n"); \
  649. DbgPrint("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n");\
  650. \
  651. VfAssert(condition, code, &enable); \
  652. } \
  653. }
  654. //
  655. // Old favorite:
  656. //
  657. // Control macro (used like a for loop) which iterates over all entries in
  658. // a standard doubly linked list. Head is the list head and the entries
  659. // are of type Type. A member called ListEntry is assumed to be the
  660. // LIST_ENTRY structure linking the entries together. Current contains a
  661. // pointer to each entry in turn.
  662. //
  663. #define FOR_ALL_IN_LIST(Type, Head, Current) \
  664. for((Current) = CONTAINING_RECORD((Head)->Flink, Type, ListEntry); \
  665. (Head) != &(Current)->ListEntry; \
  666. (Current) = CONTAINING_RECORD((Current)->ListEntry.Flink, \
  667. Type, \
  668. ListEntry) \
  669. )
  670. #ifndef MIN
  671. #define MIN(a,b) ( ( (ULONG) (a)<(ULONG) (b))?(a):(b) )
  672. #endif
  673. #define NOP
  674. #define VF_INITIALIZE_LOCKED_LIST(LockedList) \
  675. KeInitializeSpinLock(&(LockedList)->SpinLock); \
  676. InitializeListHead(&(LockedList)->ListEntry);
  677. #define VF_LOCK_LIST(ListToLock, OldIrql) \
  678. KeAcquireSpinLock(&(ListToLock)->SpinLock, &OldIrql)
  679. #define VF_UNLOCK_LIST(ListToUnlock, OldIrql) \
  680. KeReleaseSpinLock(&(ListToUnlock)->SpinLock, OldIrql)
  681. #define VF_IS_LOCKED_LIST_EMPTY(LockedList) \
  682. IsListEmpty( &(LockedList)->ListEntry )
  683. #define VF_ADD_TO_LOCKED_LIST(LockedList, AddMe) \
  684. ExInterlockedInsertHeadList( \
  685. &(LockedList)->ListEntry, \
  686. &(AddMe)->ListEntry, \
  687. &(LockedList)->SpinLock )
  688. #define VF_REMOVE_FROM_LOCKED_LIST(LockedList, RemoveMe) \
  689. { \
  690. KIRQL OldIrql; \
  691. VF_LOCK_LIST((LockedList), OldIrql); \
  692. RemoveEntryList(&(RemoveMe)->ListEntry); \
  693. VF_UNLOCK_LIST((LockedList), OldIrql); \
  694. }
  695. #define VF_REMOVE_FROM_LOCKED_LIST_DONT_LOCK(LockedList, RemoveMe) \
  696. RemoveEntryList(&(RemoveMe)->ListEntry);
  697. //
  698. // This is a bit of a hack so that reference counting for adapters will work.
  699. // If the device uses a dma channel, the HAL wants to keep it around.
  700. // There is a bit of funky logic that goes on to determine whether
  701. // a device uses an adapter channel so I've included it here, free of
  702. // charge.
  703. //
  704. #define VF_DOES_DEVICE_USE_DMA_CHANNEL(deviceDescription) \
  705. ( \
  706. ( (deviceDescription)->InterfaceType == Isa && \
  707. (deviceDescription)->DmaChannel < 8 ) || \
  708. ! (deviceDescription)->Master )
  709. #define VF_DOES_DEVICE_REQUIRE_CONTIGUOUS_BUFFERS(deviceDescription) \
  710. ( !(deviceDescription)->Master || ! (deviceDescription)->ScatterGather )
  711. #define DMA_OFFSET(DmaOperationsField) \
  712. FIELD_OFFSET(DMA_OPERATIONS, DmaOperationsField)
  713. #define DMA_INDEX(DmaOperations, Offset) \
  714. (PVOID) \
  715. *( (PVOID *) \
  716. ( ( (PUCHAR) (DmaOperations) ) + \
  717. (Offset) ) )
  718. #define SIGN_MAP_REGISTER_FILE(MapRegisterFile) \
  719. (MapRegisterFile)->Signature = MRF_SIGNATURE;
  720. #define VALIDATE_MAP_REGISTER_FILE_SIGNATURE(MapRegisterFile ) \
  721. ((MapRegisterFile) && (MapRegisterFile)->Signature == MRF_SIGNATURE )
  722. //
  723. // System dependent way to get the caller's address
  724. //
  725. #if defined(_X86_)
  726. #define GET_CALLING_ADDRESS(CallingAddress) \
  727. { \
  728. PVOID callersCaller; \
  729. RtlGetCallersAddress(&CallingAddress, &callersCaller); \
  730. }
  731. #else // ! defined(_X86_) //
  732. #define GET_CALLING_ADDRESS(CallingAddress) \
  733. CallingAddress = (PVOID)_ReturnAddress();
  734. #endif // ! defined(_X86_)
  735. //
  736. // From a map register file, map register number and the corresponding system address,
  737. // return the corresponding mapped address in system space.
  738. //
  739. #define MAP_REGISTER_SYSTEM_ADDRESS(MapRegisterFile, DriverCurrentSa, MapRegisterNumber) \
  740. (PUCHAR) (MapRegisterFile)->MapRegisterBuffer + \
  741. ( (MapRegisterNumber) << PAGE_SHIFT ) + \
  742. BYTE_OFFSET(DriverCurrentSa)
  743. //
  744. // From a map register file, map register number and the corresponding system address,
  745. // return the corresponding mapped address as an index into the map register file's
  746. // MDL (i.e virtual address).
  747. //
  748. #define MAP_REGISTER_VIRTUAL_ADDRESS(MapRegisterFile, DriverCurrentSa, MapRegisterNumber) \
  749. (PUCHAR) MmGetMdlVirtualAddress((MapRegisterFile)->MapRegisterMdl) + \
  750. ( (MapRegisterNumber) << PAGE_SHIFT ) + \
  751. BYTE_OFFSET(DriverCurrentSa)
  752. /////////////////////////////////////////////////////////////////////
  753. //////////////////////////// Hal verifier inline function definitions
  754. /////////////////////////////////////////////////////////////////////
  755. //
  756. // Since so many people don't raise the irql when they put the dma adapter,
  757. // just warn them.
  758. //
  759. __inline
  760. VOID
  761. VF_ASSERT_SPECIAL_IRQL(IN KIRQL Irql)
  762. {
  763. KIRQL currentIrql = KeGetCurrentIrql();
  764. VF_ASSERT(
  765. currentIrql == Irql,
  766. HV_BAD_IRQL_JUST_WARN,
  767. ("**** Bad IRQL -- needed %x, got %x ****",
  768. (ULONG) Irql, (ULONG) currentIrql)
  769. );
  770. } // VF_ASSERT_IRQL //
  771. __inline
  772. VOID
  773. VF_ASSERT_IRQL(IN KIRQL Irql)
  774. {
  775. KIRQL currentIrql = KeGetCurrentIrql();
  776. VF_ASSERT(
  777. currentIrql == Irql,
  778. HV_BAD_IRQL,
  779. ("**** Bad IRQL -- needed %x, got %x ****",
  780. (ULONG) Irql, (ULONG) currentIrql)
  781. );
  782. } // VF_ASSERT_IRQL //
  783. __inline
  784. VOID
  785. VF_ASSERT_MAX_IRQL(IN KIRQL MaxIrql)
  786. {
  787. KIRQL currentIrql = KeGetCurrentIrql();
  788. VF_ASSERT(
  789. currentIrql <= MaxIrql,
  790. HV_BAD_IRQL,
  791. ("**** Bad IRQL -- needed %x or less, got %x ****",
  792. (ULONG) MaxIrql, (ULONG) currentIrql)
  793. );
  794. }
  795. // =========================================
  796. // Inlined functions to help with accounting
  797. // =========================================
  798. __inline
  799. VOID
  800. ADD_MAP_REGISTERS(
  801. IN PADAPTER_INFORMATION AdapterInformation,
  802. IN ULONG NumberOfMapRegisters,
  803. IN BOOLEAN ScatterGather
  804. )
  805. {
  806. ULONG activeMapRegisters =
  807. InterlockedExchangeAdd(
  808. &AdapterInformation->ActiveMapRegisters,
  809. NumberOfMapRegisters
  810. ) + NumberOfMapRegisters;
  811. InterlockedExchangeAdd((PLONG)(&AdapterInformation->AllocatedMapRegisters),
  812. NumberOfMapRegisters);
  813. VF_ASSERT(
  814. NumberOfMapRegisters <= AdapterInformation->MaximumMapRegisters,
  815. HV_TOO_MANY_MAP_REGISTERS,
  816. ( "Allocating too many map registers at a time: %x (max %x)",
  817. NumberOfMapRegisters,
  818. AdapterInformation->MaximumMapRegisters )
  819. );
  820. if (! ScatterGather ) {
  821. VF_ASSERT(
  822. activeMapRegisters <= AdapterInformation->MaximumMapRegisters,
  823. HV_OUT_OF_MAP_REGISTERS,
  824. ( "Allocated too many map registers : %x (max %x)",
  825. activeMapRegisters,
  826. AdapterInformation->MaximumMapRegisters )
  827. );
  828. }
  829. } // ADD_MAP_REGISTERS //
  830. __inline
  831. VOID
  832. SUBTRACT_MAP_REGISTERS(
  833. IN PADAPTER_INFORMATION AdapterInformation,
  834. IN ULONG NumberOfMapRegisters
  835. )
  836. {
  837. LONG activeMapRegisters =
  838. InterlockedExchangeAdd(
  839. &AdapterInformation->ActiveMapRegisters,
  840. -((LONG) NumberOfMapRegisters)
  841. ) - NumberOfMapRegisters;
  842. VF_ASSERT(
  843. activeMapRegisters >= 0,
  844. HV_FREED_TOO_MANY_MAP_REGISTERS,
  845. ( "Freed too many map registers: %x",
  846. activeMapRegisters )
  847. );
  848. InterlockedExchange((PLONG)(&AdapterInformation->MappedTransferWithoutFlushing),
  849. 0);
  850. } // SUBTRACT_MAP_REGISTERS //
  851. __inline
  852. VOID
  853. INCREMENT_COMMON_BUFFERS(
  854. IN PADAPTER_INFORMATION AdapterInformation
  855. )
  856. {
  857. InterlockedIncrement((PLONG)(&AdapterInformation->AllocatedCommonBuffers) );
  858. } // INCREMENT_COMMON_BUFFERS //
  859. __inline
  860. VOID
  861. DECREMENT_COMMON_BUFFERS(
  862. IN PADAPTER_INFORMATION AdapterInformation
  863. )
  864. {
  865. ULONG commonBuffersFreed =
  866. (ULONG) InterlockedIncrement(
  867. (PLONG)(&AdapterInformation->FreedCommonBuffers) );
  868. VF_ASSERT(
  869. commonBuffersFreed <= AdapterInformation->AllocatedCommonBuffers,
  870. HV_FREED_TOO_MANY_COMMON_BUFFERS,
  871. ("Freed too many common buffers")
  872. );
  873. } // DECREMENT_COMMON_BUFFERS //
  874. __inline
  875. VOID
  876. INCREASE_MAPPED_TRANSFER_BYTE_COUNT(
  877. IN PADAPTER_INFORMATION AdapterInformation,
  878. IN ULONG Length
  879. )
  880. {
  881. ULONG mappedTransferCount;
  882. ULONG maxMappedTransfer;
  883. maxMappedTransfer = AdapterInformation->ActiveMapRegisters << PAGE_SHIFT;
  884. mappedTransferCount =
  885. InterlockedExchangeAdd(
  886. (PLONG)(&AdapterInformation->MappedTransferWithoutFlushing),
  887. (LONG) Length
  888. ) + Length;
  889. VF_ASSERT(
  890. mappedTransferCount <= maxMappedTransfer,
  891. HV_DID_NOT_FLUSH_ADAPTER_BUFFERS,
  892. ("Driver did not flush adapter buffers -- bytes mapped: %x (%x max)",
  893. mappedTransferCount,
  894. maxMappedTransfer
  895. ));
  896. } // INCREASE_MAPPED_TRANSFER_BYTE_COUNT //
  897. __inline
  898. VOID
  899. DECREASE_MAPPED_TRANSFER_BYTE_COUNT(
  900. IN PADAPTER_INFORMATION AdapterInformation,
  901. IN ULONG Length
  902. )
  903. {
  904. UNREFERENCED_PARAMETER (Length);
  905. InterlockedExchange(
  906. (PLONG)(&AdapterInformation->MappedTransferWithoutFlushing),
  907. 0);
  908. } // DECREASE_MAPPED_TRANSFER_BYTE_COUNT //
  909. __inline
  910. VOID
  911. INCREMENT_ADAPTER_CHANNELS(
  912. IN PADAPTER_INFORMATION AdapterInformation
  913. )
  914. {
  915. ULONG allocatedAdapterChannels = (ULONG)
  916. InterlockedIncrement(
  917. (PLONG)(&AdapterInformation->AllocatedAdapterChannels) );
  918. VF_ASSERT(
  919. allocatedAdapterChannels ==
  920. AdapterInformation->FreedAdapterChannels + 1,
  921. HV_TOO_MANY_ADAPTER_CHANNELS,
  922. ( "Driver has allocated too many simultaneous adapter channels"
  923. ));
  924. } // INCREMENT_ADAPTER_CHANNELS //
  925. __inline
  926. VOID
  927. DECREMENT_ADAPTER_CHANNELS(
  928. IN PADAPTER_INFORMATION AdapterInformation
  929. )
  930. {
  931. ULONG adapterChannelsFreed = (ULONG)
  932. InterlockedIncrement( (PLONG)(&AdapterInformation->FreedAdapterChannels) );
  933. VF_ASSERT(
  934. adapterChannelsFreed == AdapterInformation->AllocatedAdapterChannels,
  935. HV_FREED_TOO_MANY_ADAPTER_CHANNELS,
  936. ( "Driver has freed too many simultaneous adapter channels"
  937. ));
  938. } // DECREMENT_ADAPTER_CHANNELS //
  939. _inline
  940. VOID
  941. INCREMENT_SCATTER_GATHER_LISTS(
  942. IN PADAPTER_INFORMATION AdapterInformation
  943. )
  944. {
  945. InterlockedIncrement( (PLONG)(&AdapterInformation->AllocatedScatterGatherLists) );
  946. InterlockedIncrement( &AdapterInformation->ActiveScatterGatherLists);
  947. } // INCREMENT_SCATTER_GATHER_LISTS //
  948. __inline
  949. VOID
  950. DECREMENT_SCATTER_GATHER_LISTS (
  951. IN PADAPTER_INFORMATION AdapterInformation
  952. )
  953. {
  954. LONG activeScatterGatherLists = InterlockedDecrement(
  955. &AdapterInformation->ActiveScatterGatherLists );
  956. VF_ASSERT(
  957. activeScatterGatherLists >= 0,
  958. HV_FREED_TOO_MANY_SCATTER_GATHER_LISTS,
  959. ( "Driver has freed too many scatter gather lists %x allocated, %x freed",
  960. AdapterInformation->AllocatedScatterGatherLists,
  961. AdapterInformation->AllocatedScatterGatherLists -
  962. activeScatterGatherLists)
  963. );
  964. } // DECREMENT_SCATTER_GATHER_LISTS //
  965. __inline
  966. VOID
  967. VERIFY_BUFFER_LOCKED(
  968. IN PMDL Mdl
  969. )
  970. {
  971. VF_ASSERT(
  972. MmAreMdlPagesLocked(Mdl),
  973. HV_DMA_BUFFER_NOT_LOCKED,
  974. ( "DMA Pages Not Locked! MDL %p for DMA not locked", Mdl)
  975. );
  976. } // VERIFY_BUFFER_LOCKED //
  977. __inline
  978. PHAL_VERIFIER_BUFFER
  979. VF_FIND_BUFFER (
  980. IN PHAL_VERIFIER_LOCKED_LIST LockedList,
  981. IN PVOID AdvertisedStartAddress
  982. )
  983. {
  984. PHAL_VERIFIER_BUFFER verifierBuffer;
  985. KIRQL OldIrql;
  986. VF_LOCK_LIST(LockedList, OldIrql);
  987. FOR_ALL_IN_LIST(HAL_VERIFIER_BUFFER,
  988. &LockedList->ListEntry,
  989. verifierBuffer ) {
  990. if ((PUCHAR) verifierBuffer->RealStartAddress +
  991. verifierBuffer->PrePadBytes == AdvertisedStartAddress) {
  992. VF_UNLOCK_LIST(LockedList, OldIrql);
  993. return verifierBuffer;
  994. }
  995. }
  996. VF_UNLOCK_LIST(LockedList, OldIrql);
  997. return NULL;
  998. } // VF_FIND_BUFFER //
  999. __inline
  1000. PADAPTER_INFORMATION
  1001. VF_FIND_DEVICE_INFORMATION(
  1002. IN PDEVICE_OBJECT DeviceObject
  1003. )
  1004. {
  1005. PADAPTER_INFORMATION adapterInformation;
  1006. KIRQL OldIrql;
  1007. VF_LOCK_LIST(&ViAdapterList, OldIrql);
  1008. FOR_ALL_IN_LIST(ADAPTER_INFORMATION, &ViAdapterList.ListEntry, adapterInformation) {
  1009. if (adapterInformation->DeviceObject == DeviceObject) {
  1010. VF_UNLOCK_LIST(&ViAdapterList, OldIrql);
  1011. return adapterInformation;
  1012. }
  1013. }
  1014. VF_UNLOCK_LIST(&ViAdapterList, OldIrql);
  1015. return NULL;
  1016. } // VF_FIND_DEVICE_INFORMATION //
  1017. __inline
  1018. PADAPTER_INFORMATION
  1019. VF_FIND_INACTIVE_ADAPTER(
  1020. IN PDEVICE_OBJECT DeviceObject
  1021. )
  1022. {
  1023. PADAPTER_INFORMATION adapterInformation;
  1024. KIRQL OldIrql;
  1025. VF_LOCK_LIST(&ViAdapterList, OldIrql);
  1026. FOR_ALL_IN_LIST(ADAPTER_INFORMATION, &ViAdapterList.ListEntry, adapterInformation) {
  1027. if (adapterInformation->DeviceObject == DeviceObject &&
  1028. (adapterInformation->Inactive == TRUE ||
  1029. adapterInformation->DeferredRemove == TRUE)) {
  1030. VF_UNLOCK_LIST(&ViAdapterList, OldIrql);
  1031. return adapterInformation;
  1032. }
  1033. }
  1034. VF_UNLOCK_LIST(&ViAdapterList, OldIrql);
  1035. return NULL;
  1036. } // VF_FIND_INACTIVE_ADAPTER //
  1037. __inline
  1038. VOID
  1039. VF_MARK_FOR_DEFERRED_REMOVE(
  1040. IN PDEVICE_OBJECT DeviceObject
  1041. )
  1042. {
  1043. PADAPTER_INFORMATION adapterInformation;
  1044. KIRQL OldIrql;
  1045. VF_LOCK_LIST(&ViAdapterList, OldIrql);
  1046. FOR_ALL_IN_LIST(ADAPTER_INFORMATION, &ViAdapterList.ListEntry, adapterInformation) {
  1047. if (adapterInformation->DeviceObject == DeviceObject) {
  1048. adapterInformation->DeferredRemove = TRUE;
  1049. }
  1050. }
  1051. VF_UNLOCK_LIST(&ViAdapterList, OldIrql);
  1052. return ;
  1053. } // VF_MARK_FOR_DEFERRED_REMOVE //
  1054. __inline
  1055. VOID
  1056. VF_ASSERT_MAP_REGISTERS_CAN_BE_FREED(
  1057. IN PADAPTER_INFORMATION AdapterInformation,
  1058. IN PMAP_REGISTER_FILE MapRegisterFile
  1059. )
  1060. {
  1061. UNREFERENCED_PARAMETER (AdapterInformation);
  1062. VF_ASSERT(
  1063. MapRegisterFile->NumberOfRegistersMapped,
  1064. HV_CANNOT_FREE_MAP_REGISTERS,
  1065. ( "Cannot free map registers -- %x registers still mapped",
  1066. MapRegisterFile->NumberOfMapRegisters)
  1067. );
  1068. } // VF_ASSERT_MAP_REGISTERS_CAN_BE_FREED