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.

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