Leaked source code of windows server 2003
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.

1284 lines
34 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. dma.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Author:
  8. Eric Nelson (enelson) 05-April-2000
  9. Environment:
  10. User Mode
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. typedef struct _DBG_LIST_ENTRY {
  16. ULONG64 Flink;
  17. ULONG64 Blink;
  18. } DBG_LIST_ENTRY, *PDBG_LIST_ENTRY;
  19. #define GetDbgListEntry(Address, DbgListEntry) \
  20. (GetFieldValue((Address), "LIST_ENTRY", "Blink", ((PDBG_LIST_ENTRY)(DbgListEntry))->Blink) || GetFieldValue((Address), "LIST_ENTRY", "Flink", ((PDBG_LIST_ENTRY)(DbgListEntry))->Flink))
  21. #define RECUR DBG_DUMP_FIELD_RECUR_ON_THIS
  22. #define COPY DBG_DUMP_FIELD_COPY_FIELD_DATA
  23. #define NOFF DBG_DUMP_NO_OFFSET
  24. #define NOIN DBG_DUMP_NO_INDENT
  25. #define MAP_REGISTER_FILE_SIGNATURE 0xACEFD00D
  26. //
  27. // Flags for specifying dump levels
  28. //
  29. #define DMA_DUMP_BASIC 0x0
  30. #define DMA_DUMP_ADAPTER_INFORMATION 0x1
  31. #define DMA_DUMP_MAP_REGISTER 0x2
  32. #define DMA_DUMP_COMMON_BUFFER 0x4
  33. #define DMA_DUMP_TRANSFER_INFORMATION 0x8
  34. #define DMA_DUMP_DEVICE_DESCRIPTION 0x10
  35. #define DMA_DUMP_WCB 0x20
  36. #define DMA_DUMP_MAX 0x100
  37. PUCHAR DbgInterfaceTypes[] =
  38. {
  39. "Internal",
  40. "Isa",
  41. "Eisa",
  42. "MicroChannel",
  43. "TurboChannel",
  44. "PCIBus",
  45. "VMEBus",
  46. "NuBus",
  47. "PCMCIABus",
  48. "CBus",
  49. "MPIBus",
  50. "MPSABus",
  51. "ProcessorInternal",
  52. "InternalPowerBus",
  53. "PNPISABus",
  54. "PNPBus"
  55. };
  56. #define MAX_INTERFACE 15
  57. ULONG
  58. DumpDmaAdapter(
  59. IN ULONG64 Adapter,
  60. IN ULONG Flags
  61. );
  62. ULONG
  63. ValidateAdapter(
  64. IN ULONG64 Address
  65. );
  66. ULONG
  67. DumpMasterAdapter(
  68. ULONG64 MasterAdapter
  69. );
  70. ULONG
  71. DumpWcb(
  72. IN ULONG64 CurrentWcb
  73. );
  74. VOID DmaUsage(
  75. VOID
  76. );
  77. ULONG64
  78. GetVerifierAdapterInformation(
  79. ULONG64 Address
  80. );
  81. VOID
  82. DumpVerifiedMapRegisterFiles(
  83. IN ULONG64 MapRegisterFileListHead
  84. );
  85. VOID
  86. DumpVerifiedCommonBuffers(
  87. IN ULONG64 CommonBufferListHead
  88. );
  89. VOID
  90. DumpVerifiedScatterGatherLists(
  91. IN ULONG64 ScatterGatherListHead
  92. );
  93. VOID
  94. DumpDeviceDescription(
  95. IN ULONG64 DeviceDescription
  96. );
  97. VOID
  98. DumpSymbolicAddress(
  99. ULONG64 Address,
  100. PUCHAR Buffer,
  101. ULONG BufferSize,
  102. BOOL AlwaysShowHex
  103. )
  104. {
  105. ULONG64 displacement;
  106. PCHAR s;
  107. ULONG size;
  108. Buffer[0] = '!';
  109. GetSymbol((ULONG64)Address, Buffer, &displacement);
  110. s = (PCHAR) Buffer + strlen( (PCHAR) Buffer );
  111. if (BufferSize < strlen((PCHAR)Buffer)) {
  112. return;
  113. }
  114. size = BufferSize - strlen((PCHAR)Buffer);
  115. if (s == (PCHAR) Buffer) {
  116. _snprintf( s, size, "0x%08x", Address );
  117. }
  118. else {
  119. if (displacement != 0) {
  120. _snprintf( s, size, "+0x%I64x", displacement );
  121. }
  122. if (AlwaysShowHex) {
  123. _snprintf( s, size, " (0x%08x)", Address );
  124. }
  125. }
  126. return;
  127. }
  128. DECLARE_API( dma )
  129. /*++
  130. Routine Description:
  131. Dumps out 32-bit dma adapters
  132. Arguments:
  133. address
  134. Return Value:
  135. None
  136. --*/
  137. {
  138. ULONG Offset;
  139. ULONG Flags = 0;
  140. ULONG64 Address = 0;
  141. ULONG64 StartAddress = 0;
  142. ULONG64 MasterAdapter = 0;
  143. ULONG64 CallersAddress = 0;
  144. ULONG64 AdapterInformation = 0;
  145. DBG_LIST_ENTRY AdapterList = {0,0};
  146. if (sscanf(args, "%lx %x", &Address, &Flags)) {
  147. Address = GetExpression(args);
  148. }
  149. if (Flags > DMA_DUMP_MAX)
  150. {
  151. DmaUsage();
  152. return E_INVALIDARG;
  153. }
  154. //
  155. // Aha! Must not forget that we are in wierdo land and all 32 bit addresses
  156. // must be sign extended to 64 bits. By order of the emperor.
  157. //
  158. if (!IsPtr64()) {
  159. Address = (ULONG64)(LONG64)(LONG)Address;
  160. }
  161. if (Address)
  162. //
  163. // If we've been passed an adapter address, we are just printing out
  164. // the single adapter
  165. //
  166. {
  167. if (! ValidateAdapter(Address))
  168. {
  169. dprintf("\n%08p is not a valid adapter object\n",Address);
  170. DmaUsage();
  171. return E_INVALIDARG;
  172. }
  173. //
  174. // Dump out info about the adapter
  175. //
  176. if (! DumpDmaAdapter(Address, Flags | DMA_DUMP_ADAPTER_INFORMATION))
  177. {
  178. return S_FALSE;
  179. }
  180. return S_OK;
  181. }
  182. //
  183. // A specific adapter address wasn't passed in so we are going to print out
  184. // all adapters
  185. //
  186. //
  187. // Find the address of the dma adapter list head
  188. // This will also make sure that we are using the right
  189. // version.
  190. //
  191. StartAddress = GetExpression("hal!HalpDmaAdapterList");
  192. if (StartAddress == 0) {
  193. dprintf("\nCould not find symbol hal!HalpDmaAdapterList.\n\n");
  194. return S_OK;
  195. }
  196. //
  197. // Determine the list entry offset we will use to calculate
  198. // adapter addresses
  199. //
  200. if (GetFieldOffset("hal!_ADAPTER_OBJECT", "AdapterList", &Offset)) {
  201. dprintf("\nError retrieving adapter list offset.\n\n");
  202. return S_FALSE;
  203. }
  204. //
  205. // Read the dma adapter list head
  206. //
  207. if (GetDbgListEntry(StartAddress, &AdapterList)) {
  208. dprintf("\nError reading dma adapter list head: 0x%08p\n\n",
  209. StartAddress);
  210. return S_FALSE;
  211. }
  212. //
  213. // Report the empty list case
  214. //
  215. if (AdapterList.Flink == StartAddress) {
  216. dprintf("\nThe dma adapter list is empty.\n\n");
  217. return S_OK;
  218. }
  219. //
  220. // Enumerate and dump all dma adapters that do not use channels
  221. //
  222. MasterAdapter = 0;
  223. dprintf("\nDumping all DMA adapters...\n\n");
  224. while (AdapterList.Flink != StartAddress) {
  225. Address = AdapterList.Flink - Offset;
  226. DumpDmaAdapter(Address, Flags);
  227. //
  228. // Read the next adapter list entry
  229. //
  230. Address = AdapterList.Flink;
  231. if (GetDbgListEntry(Address, &AdapterList)) {
  232. dprintf("\nError reading adapter list entry: 0x%08p\n", Address);
  233. break;
  234. }
  235. if (CheckControlC())
  236. return S_OK;
  237. }
  238. //
  239. // Dump the master adapter
  240. //
  241. Address = GetExpression("hal!MasterAdapter32");
  242. if (Address) {
  243. if (Flags & DMA_DUMP_ADAPTER_INFORMATION) {
  244. DumpMasterAdapter(Address);
  245. } else {
  246. dprintf("Master adapter: %08p\n", Address);
  247. }
  248. } else {
  249. dprintf("\nCould not find symbol hal!MasterAdapter32.\n");
  250. }
  251. dprintf("\n");
  252. return S_OK;
  253. } // ! dma //
  254. ULONG
  255. DumpDmaAdapter(
  256. IN ULONG64 Adapter,
  257. IN ULONG Flags
  258. )
  259. /*++
  260. Routine Description:
  261. Given the address of a hal!_ADAPTER_OBJECT, this routine dumps
  262. out all the useful information to the debugger
  263. Arguments:
  264. Adapter - Physical address of a hal!_ADAPTER_OBJECT in debuggee
  265. Flags - What kind of information we want to print
  266. Return Value:
  267. Returns 0 on SUCCESS
  268. --*/
  269. {
  270. ULONG64 AdapterInformation = 0;
  271. ULONG64 AllocatedAdapterChannels = 0, FreedAdapterChannels = 0;
  272. AdapterInformation = GetVerifierAdapterInformation(Adapter);
  273. //
  274. // Print out: Adapter: <adapter> [<module allocating adapter>!CallingFunction+0x<offset>]
  275. // (the part in brackets only shows up when we have dma verifier enabled for this adapter)
  276. //
  277. dprintf("Adapter: %08p ", Adapter);
  278. if (AdapterInformation)
  279. {
  280. ULONG64 CallingAddress = 0;
  281. CHAR CallerName[256];
  282. CallerName[sizeof(CallerName) - 1] = 0;
  283. GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","CallingAddress", CallingAddress);
  284. if(CallingAddress)
  285. {
  286. DumpSymbolicAddress(CallingAddress, CallerName, sizeof(CallerName) - 1, TRUE);
  287. dprintf(" Owner: %s",CallerName);
  288. }
  289. }
  290. dprintf("\n");
  291. if (Flags & DMA_DUMP_ADAPTER_INFORMATION)
  292. {
  293. ULONG64 MasterAdapter = 0;
  294. ULONG64 MapRegistersPerChannel = 0;
  295. ULONG64 AdapterBaseVa = 0;
  296. ULONG64 MapRegisterBase = 0;
  297. ULONG64 CommittedMapRegisters = 0;
  298. ULONG64 NumberOfMapRegisters = 0;
  299. ULONG64 CurrentWcb = 0;
  300. GetFieldValue(Adapter, "hal!_ADAPTER_OBJECT","MasterAdapter", MasterAdapter);
  301. GetFieldValue(Adapter, "hal!_ADAPTER_OBJECT","MapRegistersPerChannel", MapRegistersPerChannel);
  302. GetFieldValue(Adapter, "hal!_ADAPTER_OBJECT","AdapterBaseVa", AdapterBaseVa);
  303. GetFieldValue(Adapter, "hal!_ADAPTER_OBJECT","MapRegisterBase", MapRegisterBase);
  304. GetFieldValue(Adapter, "hal!_ADAPTER_OBJECT","CommittedMapRegisters", CommittedMapRegisters);
  305. GetFieldValue(Adapter, "hal!_ADAPTER_OBJECT","NumberOfMapRegisters", NumberOfMapRegisters);
  306. GetFieldValue(Adapter, "hal!_ADAPTER_OBJECT","CurrentWcb", CurrentWcb);
  307. dprintf(" MasterAdapter: %08p\n", MasterAdapter);
  308. dprintf(" Adapter base Va %08p\n", AdapterBaseVa);
  309. dprintf(" Map register base: %08p\n", MapRegisterBase);
  310. dprintf(" WCB: %08p\n", CurrentWcb);
  311. dprintf(" Map registers: %08p mapped, %08p allocated, %08p max\n",
  312. CommittedMapRegisters, NumberOfMapRegisters, MapRegistersPerChannel);
  313. if (AdapterInformation) {
  314. //
  315. // Adapter is being verified
  316. //
  317. ULONG64 DeviceObject = 0;
  318. ULONG64 AllocatedMapRegisters = 0, ActiveMapRegisters = 0;
  319. ULONG64 AllocatedScatterGatherLists = 0, ActiveScatterGatherLists = 0;
  320. ULONG64 AllocatedCommonBuffers = 0, FreedCommonBuffers = 0;
  321. ULONG64 MappedTransferWithoutFlushing = 0;
  322. BOOLEAN Inactive = 0;
  323. //
  324. // If this adapter is being verified, get the dma verifier info we need
  325. //
  326. GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","DeviceObject", DeviceObject);
  327. GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","AllocatedMapRegisters", AllocatedMapRegisters);
  328. GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","ActiveMapRegisters", ActiveMapRegisters);
  329. GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","AllocatedScatterGatherLists", AllocatedScatterGatherLists);
  330. GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","ActiveScatterGatherLists", ActiveScatterGatherLists);
  331. GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","AllocatedCommonBuffers", AllocatedCommonBuffers);
  332. GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","FreedCommonBuffers", FreedCommonBuffers);
  333. GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","AllocatedAdapterChannels", AllocatedAdapterChannels);
  334. GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","FreedAdapterChannels", FreedAdapterChannels);
  335. GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","MappedTransferWithoutFlushing", MappedTransferWithoutFlushing);
  336. GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","Inactive", Inactive);
  337. dprintf("\n Dma verifier additional information:\n");
  338. if (Inactive)
  339. dprintf("\n This adapter has been freed!\n\n");
  340. dprintf(" DeviceObject: %08p\n", DeviceObject);
  341. dprintf(" Map registers: %08p allocated, %08p freed\n", AllocatedMapRegisters,
  342. AllocatedMapRegisters - ActiveMapRegisters);
  343. dprintf(" Scatter-gather lists: %08p allocated, %08p freed\n", AllocatedScatterGatherLists,
  344. AllocatedScatterGatherLists - ActiveScatterGatherLists);
  345. dprintf(" Common buffers: %08p allocated, %08p freed\n", AllocatedCommonBuffers, FreedCommonBuffers);
  346. dprintf(" Adapter channels: %08p allocated, %08p freed\n", AllocatedAdapterChannels, FreedAdapterChannels);
  347. dprintf(" Bytes mapped since last flush: %08p\n", MappedTransferWithoutFlushing);
  348. dprintf("\n");
  349. } // Dma verifier enabled for adapter //
  350. } // Flags & DMA_DUMP_ADAPTER_INFORMATION //
  351. if (CheckControlC())
  352. return TRUE;
  353. if (Flags & DMA_DUMP_MAP_REGISTER && AdapterInformation) {
  354. ULONG64 MapRegisterFileListHead = 0;
  355. ULONG Offset;
  356. if ( ! GetFieldOffset("nt!_ADAPTER_INFORMATION",
  357. "MapRegisterFiles.ListEntry",
  358. &Offset
  359. )) {
  360. MapRegisterFileListHead = AdapterInformation + Offset;
  361. DumpVerifiedMapRegisterFiles(MapRegisterFileListHead);
  362. }
  363. }
  364. if (CheckControlC())
  365. return TRUE;
  366. if (Flags & DMA_DUMP_COMMON_BUFFER && AdapterInformation) {
  367. ULONG64 CommonBufferListHead = 0;
  368. ULONG Offset;
  369. if ( ! GetFieldOffset("nt!_ADAPTER_INFORMATION",
  370. "CommonBuffers.ListEntry",
  371. &Offset
  372. )) {
  373. CommonBufferListHead = AdapterInformation + Offset;
  374. DumpVerifiedCommonBuffers(CommonBufferListHead);
  375. }
  376. }
  377. if (CheckControlC())
  378. return TRUE;
  379. #if 0
  380. if (Flags & DMA_DUMP_SCATTER_GATHER && AdapterInformation) {
  381. ULONG64 ScatterGatherListHead = 0;
  382. ULONG Offset;
  383. if ( ! GetFieldOffset("nt!_ADAPTER_INFORMATION",
  384. "ScatterGatherLists.ListEntry",
  385. &Offset
  386. )) {
  387. ScatterGatherListHead = AdapterInformation + Offset;
  388. DumpVerifiedScatterGatherLists(ScatterGatherListHead);
  389. }
  390. }
  391. #endif
  392. if (CheckControlC())
  393. return TRUE;
  394. if (Flags & DMA_DUMP_DEVICE_DESCRIPTION && AdapterInformation)
  395. {
  396. ULONG64 DeviceDescription;
  397. ULONG Offset;
  398. if ( ! GetFieldOffset("nt!_ADAPTER_INFORMATION",
  399. "DeviceDescription",
  400. &Offset
  401. )) {
  402. DeviceDescription = AdapterInformation + Offset;
  403. DumpDeviceDescription(DeviceDescription);
  404. }
  405. }
  406. if (CheckControlC())
  407. return TRUE;
  408. if (Flags & DMA_DUMP_WCB ) {
  409. if (! AdapterInformation) {
  410. ULONG64 CurrentWcb = 0;
  411. GetFieldValue(Adapter, "hal!_ADAPTER_OBJECT","CurrentWcb", CurrentWcb);
  412. if (CurrentWcb)
  413. DumpWcb(CurrentWcb);
  414. }
  415. else if (AllocatedAdapterChannels > FreedAdapterChannels && Flags & DMA_DUMP_WCB )
  416. {
  417. //DumpVerifiedWcb(Wcb)
  418. }
  419. }
  420. return 0;
  421. }
  422. ULONG
  423. DumpMasterAdapter(
  424. ULONG64 MasterAdapter
  425. )
  426. /*++
  427. Routine Description:
  428. Given the address of a hal!_MASTER_ADAPTER_OBJECT, this routine dumps
  429. out all the useful information to the debugger
  430. Arguments:
  431. MasterAdapter - Physical address of a hal!_MASTER_ADAPTER_OBJECT
  432. in debuggee
  433. Return Value:
  434. Returns 0 on SUCCESS
  435. --*/
  436. {
  437. FIELD_INFO MasterAdapterFields[] = {
  438. { "AdapterObject", NULL, 0, 0, 0, 0 },
  439. { "MaxBufferPages", NULL, 0, 0, 0, 0 },
  440. { "MapBufferSize", NULL, 0, 0, 0, 0 },
  441. { "MapBufferPhysicalAddress", NULL, RECUR, 0, 0, 0 },
  442. { "MapBufferPhysicalAddress.HighPart", NULL, 0, 0, 0, 0 },
  443. { "MapBufferPhysicalAddress.LowPart", NULL, 0, 0, 0, 0 }
  444. };
  445. SYM_DUMP_PARAM MasterAdapterDumpParams = {
  446. sizeof(SYM_DUMP_PARAM), "hal!_MASTER_ADAPTER_OBJECT", NOFF,
  447. MasterAdapter, NULL, NULL, NULL,
  448. sizeof(MasterAdapterFields) / sizeof(FIELD_INFO),
  449. &MasterAdapterFields[0]
  450. };
  451. //
  452. // This is so gnarly, dump all the cool stuff for me!
  453. //
  454. dprintf("\nMaster DMA adapter: 0x%08p\n", MasterAdapter);
  455. if ((Ioctl(IG_DUMP_SYMBOL_INFO,
  456. &MasterAdapterDumpParams,
  457. MasterAdapterDumpParams.size))) {
  458. dprintf("\nError reading master adapter: 0x%08p\n", MasterAdapter);
  459. return 1;
  460. }
  461. return 0;
  462. }
  463. ULONG
  464. DumpWcb(
  465. IN ULONG64 Wcb
  466. )
  467. /*++
  468. Routine Description:
  469. Given the address of a hal!_WAIT_CONTEXT_BLOCK, this routine dumps
  470. out all the useful information to the debugger
  471. Arguments:
  472. Wcb - Physical address of a hal!_WAIT_CONTEXT_BLOCK in debuggee
  473. Return Value:
  474. Returns 0 on SUCCESS
  475. --*/
  476. {
  477. FIELD_INFO WcbFields[] = {
  478. { "DeviceRoutine", NULL, 0, 0, 0, 0 },
  479. { "NumberOfMapRegisters", NULL, 0, 0, 0, 0 }
  480. };
  481. SYM_DUMP_PARAM WcbDumpParams = {
  482. sizeof(SYM_DUMP_PARAM), "hal!_WAIT_CONTEXT_BLOCK", NOFF, Wcb, NULL,
  483. NULL, NULL, sizeof(WcbFields) / sizeof(FIELD_INFO), &WcbFields[0]
  484. };
  485. //
  486. // This is so gnarly, dump all the cool stuff for me!
  487. //
  488. dprintf(" Wait context block: 0x%08p (may be free)\n", Wcb);
  489. if ((Ioctl(IG_DUMP_SYMBOL_INFO,
  490. &WcbDumpParams,
  491. WcbDumpParams.size))) {
  492. dprintf("\nError reading wait context block: 0x%08p\n", Wcb);
  493. return 1;
  494. }
  495. return 0;
  496. }
  497. ULONG
  498. ValidateAdapter(
  499. IN ULONG64 Address
  500. )
  501. /*++
  502. Routine Description:
  503. Figures out whether this is a valid adapter.
  504. Arguments:
  505. Address -- Address of what we think may be an adapter object.
  506. Return Value:
  507. TRUE -- Valid adapter.
  508. FALSE -- Not a valid adapter.
  509. --*/
  510. {
  511. DBG_LIST_ENTRY AdapterList = {0,0};
  512. ULONG64 StartAddress = 0;
  513. ULONG64 CurrentAddress = 0;
  514. ULONG Offset;
  515. if (! Address )
  516. return FALSE;
  517. //
  518. // Find the address of the dma adapter list head
  519. // This will also make sure that we are using the right
  520. // version.
  521. //
  522. StartAddress = GetExpression("hal!HalpDmaAdapterList");
  523. if (StartAddress == 0) {
  524. dprintf("\nCould not find symbol hal!HalpDmaAdapterList.\n\n");
  525. return FALSE;
  526. }
  527. //
  528. // Determine the list entry offset we will use to calculate
  529. // adapter addresses
  530. //
  531. if (GetFieldOffset("hal!_ADAPTER_OBJECT", "AdapterList", &Offset)) {
  532. dprintf("\nError retrieving adapter list offset.\n\n");
  533. return FALSE;
  534. }
  535. //
  536. // Read the dma adapter list head
  537. //
  538. if (GetDbgListEntry(StartAddress, &AdapterList)) {
  539. dprintf("\nError reading dma adapter list head: 0x%08p\n\n",
  540. StartAddress);
  541. return FALSE;
  542. }
  543. while (AdapterList.Flink != StartAddress) {
  544. CurrentAddress = AdapterList.Flink - Offset;
  545. if (Address == CurrentAddress) {
  546. return TRUE;
  547. }
  548. //
  549. // Read the next adapter list entry
  550. //
  551. CurrentAddress = AdapterList.Flink;
  552. if (GetDbgListEntry(CurrentAddress, &AdapterList)) {
  553. dprintf("\nError reading adapter list entry: 0x%08p\n", AdapterList);
  554. break;
  555. }
  556. if (CheckControlC())
  557. break;
  558. }
  559. //
  560. // Check to see if we have the master adapter
  561. //
  562. CurrentAddress = GetExpression("hal!MasterAdapter32");
  563. if(CurrentAddress == Address)
  564. return TRUE;
  565. //
  566. // Check to see if it is on the verifier adapter list ...
  567. // we leave adapters that have been 'put' there so that
  568. // we can catch drivers that do dma after puting the adapter.
  569. //
  570. if (GetVerifierAdapterInformation(Address))
  571. return TRUE;
  572. return FALSE;
  573. } // ValidateAdapter //
  574. VOID DmaUsage(
  575. VOID
  576. )
  577. /*++
  578. Routine Description:
  579. Prints out correct usage for !dma
  580. Arguments:
  581. NONE
  582. Return Value:
  583. NONE
  584. --*/
  585. {
  586. dprintf("\nUsage: !dma [adapter address] [flags]\n");
  587. dprintf("Where: [adapter address] is address of specific dma adapter\n");
  588. dprintf(" or 0x0 for all adapters\n");
  589. dprintf(" [flags] are:\n");
  590. dprintf(" 0x1: Dump generic adapter information\n");
  591. dprintf(" 0x2: Dump map register information\n");
  592. dprintf(" 0x4: Dump common buffer information\n");
  593. dprintf(" 0x8: Dump scatter-gather list information\n");
  594. dprintf(" 0x10: Dump device description for device\n");
  595. dprintf(" 0x20: Dump Wait-context-block information\n");
  596. dprintf("Note: flags {2,4,8,10} require dma verifier to be enabled for the adapter\n\n");
  597. } // DmaUsage //
  598. ULONG64
  599. GetVerifierAdapterInformation(
  600. ULONG64 AdapterAddress
  601. )
  602. /*++
  603. Routine Description:
  604. Finds out whether the adapter at AdapterAddress is being verified. If it is, return a pointer
  605. to the ADAPTER_INFORMATION structure corresponding to the adapter.
  606. Arguments:
  607. AdapterAddress -- Address of the adapter we are trying to find out if it is being verified
  608. Return Value:
  609. ULONG64 -- Address of ADAPTER_INFORMATION struct for verified adapter
  610. 0 -- Not verifying adapter;
  611. --*/
  612. {
  613. DBG_LIST_ENTRY AdapterInfoList = {0,0};
  614. ULONG64 StartAddress = 0;
  615. ULONG64 CurrentAdapter = 0;
  616. ULONG64 CurrentAdapterInfo = 0;
  617. ULONG64 VerifiedDmaAdapter = 0;
  618. ULONG ListEntryOffset = 0;
  619. UINT64 VerifyingDma = 0;
  620. if (! AdapterAddress )
  621. return 0;
  622. ReadPointer(GetExpression("nt!ViVerifyDma"), &VerifyingDma);
  623. if (0 == VerifyingDma)
  624. //
  625. // Not verifying dma ...
  626. //
  627. {
  628. return 0;
  629. }
  630. //
  631. // Find the address of the dma adapter list head
  632. //
  633. StartAddress = GetExpression("nt!ViAdapterList");
  634. if (StartAddress == 0) {
  635. return 0;
  636. }
  637. //
  638. // Determine the list entry offset we will use to calculate
  639. // adapter addresses
  640. //
  641. if (GetFieldOffset("nt!_ADAPTER_INFORMATION", "ListEntry", &ListEntryOffset)) {
  642. dprintf("\nError retrieving verifier adapter information list offset.\n\n");
  643. return 0;
  644. }
  645. //
  646. // Read the dma adapter list head
  647. //
  648. if (GetDbgListEntry(StartAddress, &AdapterInfoList)) {
  649. dprintf("\nError reading verifier adapter information list head: 0x%08p\n\n",
  650. StartAddress);
  651. return 0;
  652. }
  653. if (AdapterInfoList.Flink == 0 || AdapterInfoList.Blink == 0)
  654. return 0;
  655. while (AdapterInfoList.Flink != StartAddress) {
  656. CurrentAdapterInfo = AdapterInfoList.Flink - ListEntryOffset;
  657. GetFieldValue(CurrentAdapterInfo, "nt!_ADAPTER_INFORMATION","DmaAdapter", VerifiedDmaAdapter);
  658. if (AdapterAddress == VerifiedDmaAdapter)
  659. {
  660. return CurrentAdapterInfo;
  661. }
  662. //
  663. // Read the next adapter list entry
  664. //
  665. if (GetDbgListEntry(AdapterInfoList.Flink, &AdapterInfoList)) {
  666. dprintf("\nError reading adapter info list entry: 0x%08p\n", AdapterInfoList);
  667. break;
  668. }
  669. if (CheckControlC())
  670. break;
  671. }
  672. return 0;
  673. } // GetVerifierAdapterInformation //
  674. VOID
  675. DumpVerifiedMapRegisterFiles(
  676. IN ULONG64 MapRegisterFileListHead
  677. )
  678. /*++
  679. Routine Description:
  680. Dump pertinent info pertaining to verified map registers.
  681. NOTE: This may not be all map registers for the adapter -- just the ones
  682. that are being verified. There is a limit to how many map registers
  683. we verify for each adapter -- since each time we use three pages
  684. of physical memory.
  685. NOTE ON TERMINOLOGY: Map register file: a single allocation of map registers
  686. recieved in the callback routine from IoAllocateAdapterChannel. Any number
  687. or combination of these registers can be mapped at one time.
  688. Arguments:
  689. MapRegisterFileListHead -- head of list of map register files.
  690. Return Value:
  691. NONE
  692. --*/
  693. {
  694. DBG_LIST_ENTRY MapRegisterFileListEntry = {0,0};
  695. ULONG64 MapRegisterFile = 0;
  696. ULONG ListEntryOffset = 0;
  697. ULONG64 Signature = 0;
  698. ULONG64 NumberOfMapRegisters = 0;
  699. ULONG64 NumberOfRegistersMapped = 0;
  700. ULONG64 MapRegisterMdl = 0;
  701. ULONG64 MapRegister;
  702. ULONG64 MappedToAddress;
  703. ULONG64 BytesMapped;
  704. ULONG64 MapRegisterStart;
  705. ULONG SizeofMapRegister;
  706. ULONG CurrentMapRegister;
  707. ULONG MapRegisterOffset;
  708. if (GetDbgListEntry(MapRegisterFileListHead, &MapRegisterFileListEntry))
  709. {
  710. return;
  711. }
  712. if (MapRegisterFileListEntry.Flink == MapRegisterFileListHead)
  713. //
  714. // Empty list
  715. //
  716. {
  717. dprintf("\n No map register files\n\n");
  718. return;
  719. }
  720. //
  721. // Determine the list entry offset we will use to calculate
  722. // the beginning of the map register file
  723. //
  724. if (GetFieldOffset("nt!_MAP_REGISTER_FILE", "ListEntry", &ListEntryOffset)) {
  725. dprintf("\nError retrieving list entry offset.\n\n");
  726. return;
  727. }
  728. SizeofMapRegister = GetTypeSize("nt!_MAP_REGISTER");
  729. if (! SizeofMapRegister )
  730. {
  731. dprintf("\n Could not get size of nt!_MAP_REGISTER\n\n");
  732. return;
  733. }
  734. if (GetFieldOffset("nt!_MAP_REGISTER_FILE","MapRegisters", &MapRegisterOffset))
  735. {
  736. dprintf("\n Couuld not get map register offset\n\n");
  737. }
  738. while (MapRegisterFileListEntry.Flink != MapRegisterFileListHead) {
  739. MapRegisterFile = MapRegisterFileListEntry.Flink - ListEntryOffset;
  740. GetFieldValue(MapRegisterFile, "nt!_MAP_REGISTER_FILE","Signature", Signature);
  741. if (((ULONG) Signature) != MAP_REGISTER_FILE_SIGNATURE) {
  742. dprintf("\n Invalid signature for map register file %08p\n\n", MapRegisterFile);
  743. return;
  744. }
  745. GetFieldValue(MapRegisterFile, "nt!_MAP_REGISTER_FILE","NumberOfMapRegisters", NumberOfMapRegisters);
  746. GetFieldValue(MapRegisterFile, "nt!_MAP_REGISTER_FILE","NumberOfRegistersMapped", NumberOfRegistersMapped);
  747. GetFieldValue(MapRegisterFile, "nt!_MAP_REGISTER_FILE","MapRegisterMdl", MapRegisterMdl);
  748. dprintf(" Map register file %08p (%x/%x mapped)\n",
  749. MapRegisterFile, (ULONG) NumberOfRegistersMapped, (ULONG) NumberOfMapRegisters);
  750. dprintf(" Double buffer mdl: %08p\n", MapRegisterMdl);
  751. dprintf(" Map registers:\n");
  752. MapRegister = MapRegisterFile + MapRegisterOffset;
  753. for (CurrentMapRegister = 0; CurrentMapRegister < NumberOfMapRegisters; CurrentMapRegister++) {
  754. GetFieldValue(MapRegister, "nt!_MAP_REGISTER", "MappedToSa", MappedToAddress);
  755. GetFieldValue(MapRegister, "nt!_MAP_REGISTER", "BytesMapped", BytesMapped);
  756. dprintf(" %08x: ", MapRegister);
  757. //dprintf(" %03x: ", CurrentMapRegister);
  758. if (BytesMapped) {
  759. dprintf("%04x bytes mapped to %08p\n", (ULONG) BytesMapped, MappedToAddress);
  760. } else {
  761. dprintf("Not mapped\n");
  762. }
  763. if (CheckControlC())
  764. return;
  765. //
  766. // Increment our map register pointer
  767. //
  768. MapRegister += SizeofMapRegister;
  769. } // End dump of map registers //
  770. dprintf("\n");
  771. //
  772. // Advance to the next map register file
  773. //
  774. if (GetDbgListEntry(MapRegisterFileListEntry.Flink , &MapRegisterFileListEntry)) {
  775. dprintf("\nError reading map register file list entry: 0x%08p\n",
  776. MapRegisterFileListEntry.Flink);
  777. break;
  778. }
  779. if (CheckControlC())
  780. return;
  781. } // End dump of map register files //
  782. return;
  783. } // DumpVerifiedMapRegisterFiles //
  784. VOID
  785. DumpVerifiedCommonBuffers(
  786. IN ULONG64 CommonBufferListHead
  787. )
  788. /*++
  789. Routine Description:
  790. Dump pertinent info pertaining to verified common buffers
  791. Arguments:
  792. CommonBufferListHead -- head of list of common buffers for a single adapter
  793. Return Value:
  794. NONE
  795. --*/
  796. {
  797. DBG_LIST_ENTRY CommonBufferListEntry = {0,0};
  798. ULONG64 CommonBuffer;
  799. ULONG AdvertisedLength;
  800. UINT64 AdvertisedStartAddress;
  801. UINT64 RealStartAddress;
  802. UINT64 RealLogicalStartAddress;
  803. UINT64 AdvertisedLogicalStartAddress;
  804. UINT64 AllocatorAddress;
  805. ULONG ListEntryOffset;
  806. CHAR AllocatorName[256];
  807. AllocatorName[sizeof(AllocatorName) - 1] = 0;
  808. if (GetDbgListEntry(CommonBufferListHead, &CommonBufferListEntry))
  809. {
  810. return;
  811. }
  812. if (CommonBufferListEntry.Flink == CommonBufferListHead)
  813. //
  814. // Empty list
  815. //
  816. {
  817. dprintf("\n No common buffers\n\n");
  818. return;
  819. }
  820. //
  821. // Determine the list entry offset we will use to calculate
  822. // the beginning of the map register file
  823. //
  824. if (GetFieldOffset("nt!_HAL_VERIFIER_BUFFER", "ListEntry", &ListEntryOffset)) {
  825. dprintf("\n Error retrieving list entry offset.\n\n");
  826. return;
  827. }
  828. while (CommonBufferListEntry.Flink != CommonBufferListHead) {
  829. CommonBuffer = CommonBufferListEntry.Flink - ListEntryOffset;
  830. GetFieldValue(CommonBuffer, "nt!_HAL_VERIFIER_BUFFER","AdvertisedLength", AdvertisedLength);
  831. GetFieldValue(CommonBuffer, "nt!_HAL_VERIFIER_BUFFER","AdvertisedStartAddress", AdvertisedStartAddress);
  832. GetFieldValue(CommonBuffer, "nt!_HAL_VERIFIER_BUFFER","RealStartAddress", RealStartAddress);
  833. GetFieldValue(CommonBuffer, "nt!_HAL_VERIFIER_BUFFER","RealLogicalStartAddress", RealLogicalStartAddress);
  834. GetFieldValue(CommonBuffer, "nt!_HAL_VERIFIER_BUFFER","AllocatorAddress", AllocatorAddress);
  835. DumpSymbolicAddress(AllocatorAddress, AllocatorName, sizeof(AllocatorName) - 1, TRUE);
  836. dprintf(" Common buffer allocated by %s:\n", AllocatorName);
  837. dprintf(" Length: %x\n", AdvertisedLength);
  838. dprintf(" Virtual address: %08p\n", AdvertisedStartAddress);
  839. dprintf(" Physical address: %I64lx\n",
  840. (AdvertisedStartAddress - RealStartAddress) + RealLogicalStartAddress);
  841. dprintf("\n");
  842. //
  843. // Advance to the next common buffer in the list
  844. //
  845. if (GetDbgListEntry(CommonBufferListEntry.Flink , &CommonBufferListEntry)) {
  846. dprintf("\nError reading common buffer list entry: 0x%08p\n",
  847. CommonBufferListEntry.Flink);
  848. break;
  849. }
  850. if (CheckControlC())
  851. return;
  852. } // End dump of common buffers //
  853. return;
  854. } // DumpVerifiedCommonBuffers //
  855. VOID
  856. DumpVerifiedScatterGatherLists(
  857. IN ULONG64 ScatterGatherListHead
  858. )
  859. /*++
  860. Routine Description:
  861. Dump pertinent info pertaining to scatter gather lists in use by a single
  862. adapter.
  863. Arguments:
  864. ScatterGatherListHead -- head of a list of ScatterGather lists.
  865. Return Value:
  866. NONE
  867. --*/
  868. {
  869. UNREFERENCED_PARAMETER(ScatterGatherListHead);
  870. return;
  871. } // DumpVerifiedScatterGatherLists //
  872. VOID
  873. DumpDeviceDescription(
  874. IN ULONG64 DeviceDescription
  875. )
  876. /*++
  877. Routine Description:
  878. Dump pertinent info from a device description struct
  879. Arguments:
  880. ScatterGatherListHead -- head of a list of ScatterGather lists.
  881. Return Value:
  882. NONE
  883. --*/
  884. {
  885. ULONG Version;
  886. BOOLEAN Master;
  887. BOOLEAN ScatterGather;
  888. BOOLEAN Dma32BitAddresses;
  889. BOOLEAN Dma64BitAddresses;
  890. ULONG InterfaceType;
  891. ULONG MaximumLength;
  892. GetFieldValue(DeviceDescription, "hal!_DEVICE_DESCRIPTION","Version", Version);
  893. if (Version > 2) {
  894. dprintf("\nBad device description version: %x\n\n", Version);
  895. return;
  896. }
  897. GetFieldValue(DeviceDescription, "hal!_DEVICE_DESCRIPTION","Master", Master);
  898. GetFieldValue(DeviceDescription, "hal!_DEVICE_DESCRIPTION","ScatterGather", ScatterGather);
  899. GetFieldValue(DeviceDescription, "hal!_DEVICE_DESCRIPTION","Dma32BitAddresses", Dma32BitAddresses);
  900. GetFieldValue(DeviceDescription, "hal!_DEVICE_DESCRIPTION","Dma64BitAddresses", Dma64BitAddresses);
  901. GetFieldValue(DeviceDescription, "hal!_DEVICE_DESCRIPTION","InterfaceType", InterfaceType);
  902. dprintf(" Device Description Version %02x\n", Version);
  903. if (InterfaceType < MAX_INTERFACE) {
  904. dprintf(" Interface type %s\n", DbgInterfaceTypes[InterfaceType]);
  905. } else {
  906. dprintf(" Interface type unknown\n");
  907. }
  908. dprintf(" DMA Capabilities:\n");
  909. if(Master) {
  910. dprintf(" Busmaster\n");
  911. } else {
  912. dprintf(" Slave\n");
  913. }
  914. if (ScatterGather)
  915. dprintf(" Scatter Gather\n");
  916. if (Dma32BitAddresses)
  917. dprintf(" 32-bit DMA\n");
  918. if (Dma64BitAddresses)
  919. dprintf(" 64-bit DMA\n");
  920. if (! Dma32BitAddresses && ! Dma64BitAddresses)
  921. dprintf(" 24-bit DMA only\n");
  922. dprintf("\n");
  923. } // DumpDeviceDescription //