/*++ Copyright (c) 2000 Microsoft Corporation Module Name: dma.c Abstract: WinDbg Extension Api Author: Eric Nelson (enelson) 05-April-2000 Environment: User Mode Revision History: --*/ #include "precomp.h" #pragma hdrstop typedef struct _DBG_LIST_ENTRY { ULONG64 Flink; ULONG64 Blink; } DBG_LIST_ENTRY, *PDBG_LIST_ENTRY; #define GetDbgListEntry(Address, DbgListEntry) \ (GetFieldValue((Address), "LIST_ENTRY", "Blink", ((PDBG_LIST_ENTRY)(DbgListEntry))->Blink) || GetFieldValue((Address), "LIST_ENTRY", "Flink", ((PDBG_LIST_ENTRY)(DbgListEntry))->Flink)) #define RECUR DBG_DUMP_FIELD_RECUR_ON_THIS #define COPY DBG_DUMP_FIELD_COPY_FIELD_DATA #define NOFF DBG_DUMP_NO_OFFSET #define NOIN DBG_DUMP_NO_INDENT #define MAP_REGISTER_FILE_SIGNATURE 0xACEFD00D // // Flags for specifying dump levels // #define DMA_DUMP_BASIC 0x0 #define DMA_DUMP_ADAPTER_INFORMATION 0x1 #define DMA_DUMP_MAP_REGISTER 0x2 #define DMA_DUMP_COMMON_BUFFER 0x4 #define DMA_DUMP_TRANSFER_INFORMATION 0x8 #define DMA_DUMP_DEVICE_DESCRIPTION 0x10 #define DMA_DUMP_WCB 0x20 #define DMA_DUMP_MAX 0x100 PUCHAR DbgInterfaceTypes[] = { "Internal", "Isa", "Eisa", "MicroChannel", "TurboChannel", "PCIBus", "VMEBus", "NuBus", "PCMCIABus", "CBus", "MPIBus", "MPSABus", "ProcessorInternal", "InternalPowerBus", "PNPISABus", "PNPBus" }; #define MAX_INTERFACE 15 ULONG DumpDmaAdapter( IN ULONG64 Adapter, IN ULONG Flags ); ULONG ValidateAdapter( IN ULONG64 Address ); ULONG DumpMasterAdapter( ULONG64 MasterAdapter ); ULONG DumpWcb( IN ULONG64 CurrentWcb ); VOID DmaUsage( VOID ); ULONG64 GetVerifierAdapterInformation( ULONG64 Address ); VOID DumpVerifiedMapRegisterFiles( IN ULONG64 MapRegisterFileListHead ); VOID DumpVerifiedCommonBuffers( IN ULONG64 CommonBufferListHead ); VOID DumpVerifiedScatterGatherLists( IN ULONG64 ScatterGatherListHead ); VOID DumpDeviceDescription( IN ULONG64 DeviceDescription ); VOID DumpSymbolicAddress( ULONG64 Address, PUCHAR Buffer, BOOL AlwaysShowHex ) { ULONG64 displacement; PCHAR s; Buffer[0] = '!'; GetSymbol((ULONG64)Address, Buffer, &displacement); s = (PCHAR) Buffer + strlen( (PCHAR) Buffer ); if (s == (PCHAR) Buffer) { sprintf( s, "0x%08x", Address ); } else { if (displacement != 0) { sprintf( s, "+0x%I64x", displacement ); } if (AlwaysShowHex) { sprintf( s, " (0x%08x)", Address ); } } return; } DECLARE_API( dma ) /*++ Routine Description: Dumps out 32-bit dma adapters Arguments: address Return Value: None --*/ { ULONG Offset; ULONG Flags = 0; ULONG64 Address = 0; ULONG64 StartAddress = 0; ULONG64 MasterAdapter = 0; ULONG64 CallersAddress = 0; ULONG64 AdapterInformation = 0; DBG_LIST_ENTRY AdapterList = {0,0}; if (sscanf(args, "%lx %x", &Address, &Flags)) { Address = GetExpression(args); } if (Flags > DMA_DUMP_MAX) { DmaUsage(); return E_INVALIDARG; } // // Aha! Must not forget that we are in wierdo land and all 32 bit addresses // must be sign extended to 64 bits. By order of the emperor. // if (!IsPtr64()) { Address = (ULONG64)(LONG64)(LONG)Address; } if (Address) // // If we've been passed an adapter address, we are just printing out // the single adapter // { if (! ValidateAdapter(Address)) { dprintf("\n%08p is not a valid adapter object\n",Address); DmaUsage(); return E_INVALIDARG; } // // Dump out info about the adapter // if (! DumpDmaAdapter(Address, Flags | DMA_DUMP_ADAPTER_INFORMATION)) { return S_FALSE; } return S_OK; } // // A specific adapter address wasn't passed in so we are going to print out // all adapters // // // Find the address of the dma adapter list head // This will also make sure that we are using the right // version. // StartAddress = GetExpression("hal!HalpDmaAdapterList"); if (StartAddress == 0) { dprintf("\nCould not find symbol hal!HalpDmaAdapterList.\n\n"); return S_OK; } // // Determine the list entry offset we will use to calculate // adapter addresses // if (GetFieldOffset("hal!_ADAPTER_OBJECT", "AdapterList", &Offset)) { dprintf("\nError retrieving adapter list offset.\n\n"); return S_FALSE; } // // Read the dma adapter list head // if (GetDbgListEntry(StartAddress, &AdapterList)) { dprintf("\nError reading dma adapter list head: 0x%08p\n\n", StartAddress); return S_FALSE; } // // Report the empty list case // if (AdapterList.Flink == StartAddress) { dprintf("\nThe dma adapter list is empty.\n\n"); return S_OK; } // // Enumerate and dump all dma adapters that do not use channels // MasterAdapter = 0; dprintf("\nDumping all DMA adapters...\n\n"); while (AdapterList.Flink != StartAddress) { Address = AdapterList.Flink - Offset; DumpDmaAdapter(Address, Flags); // // Read the next adapter list entry // Address = AdapterList.Flink; if (GetDbgListEntry(Address, &AdapterList)) { dprintf("\nError reading adapter list entry: 0x%08p\n", Address); break; } if (CheckControlC()) return S_OK; } // // Dump the master adapter // Address = GetExpression("hal!MasterAdapter32"); if (Address) { if (Flags & DMA_DUMP_ADAPTER_INFORMATION) { DumpMasterAdapter(Address); } else { dprintf("Master adapter: %08p\n", Address); } } else { dprintf("\nCould not find symbol hal!MasterAdapter32.\n"); } dprintf("\n"); return S_OK; } // ! dma // ULONG DumpDmaAdapter( IN ULONG64 Adapter, IN ULONG Flags ) /*++ Routine Description: Given the address of a hal!_ADAPTER_OBJECT, this routine dumps out all the useful information to the debugger Arguments: Adapter - Physical address of a hal!_ADAPTER_OBJECT in debuggee Flags - What kind of information we want to print Return Value: Returns 0 on SUCCESS --*/ { ULONG64 AdapterInformation = 0; ULONG64 AllocatedAdapterChannels = 0, FreedAdapterChannels = 0; AdapterInformation = GetVerifierAdapterInformation(Adapter); // // Print out: Adapter: [!CallingFunction+0x] // (the part in brackets only shows up when we have dma verifier enabled for this adapter) // dprintf("Adapter: %08p ", Adapter); if (AdapterInformation) { ULONG64 CallingAddress = 0; CHAR CallerName[256]; GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","CallingAddress", CallingAddress); if(CallingAddress) { DumpSymbolicAddress(CallingAddress, CallerName, TRUE); dprintf(" Owner: %s",CallerName); } } dprintf("\n"); if (Flags & DMA_DUMP_ADAPTER_INFORMATION) { ULONG64 MasterAdapter = 0; ULONG64 MapRegistersPerChannel = 0; ULONG64 AdapterBaseVa = 0; ULONG64 MapRegisterBase = 0; ULONG64 CommittedMapRegisters = 0; ULONG64 NumberOfMapRegisters = 0; ULONG64 CurrentWcb = 0; GetFieldValue(Adapter, "hal!_ADAPTER_OBJECT","MasterAdapter", MasterAdapter); GetFieldValue(Adapter, "hal!_ADAPTER_OBJECT","MapRegistersPerChannel", MapRegistersPerChannel); GetFieldValue(Adapter, "hal!_ADAPTER_OBJECT","AdapterBaseVa", AdapterBaseVa); GetFieldValue(Adapter, "hal!_ADAPTER_OBJECT","MapRegisterBase", MapRegisterBase); GetFieldValue(Adapter, "hal!_ADAPTER_OBJECT","CommittedMapRegisters", CommittedMapRegisters); GetFieldValue(Adapter, "hal!_ADAPTER_OBJECT","NumberOfMapRegisters", NumberOfMapRegisters); GetFieldValue(Adapter, "hal!_ADAPTER_OBJECT","CurrentWcb", CurrentWcb); dprintf(" MasterAdapter: %08p\n", MasterAdapter); dprintf(" Adapter base Va %08p\n", AdapterBaseVa); dprintf(" Map register base: %08p\n", MapRegisterBase); dprintf(" WCB: %08p\n", CurrentWcb); dprintf(" Map registers: %08p mapped, %08p allocated, %08p max\n", CommittedMapRegisters, NumberOfMapRegisters, MapRegistersPerChannel); if (AdapterInformation) { // // Adapter is being verified // ULONG64 DeviceObject = 0; ULONG64 AllocatedMapRegisters = 0, ActiveMapRegisters = 0; ULONG64 AllocatedScatterGatherLists = 0, ActiveScatterGatherLists = 0; ULONG64 AllocatedCommonBuffers = 0, FreedCommonBuffers = 0; ULONG64 MappedTransferWithoutFlushing = 0; BOOLEAN Inactive = 0; // // If this adapter is being verified, get the dma verifier info we need // GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","DeviceObject", DeviceObject); GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","AllocatedMapRegisters", AllocatedMapRegisters); GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","ActiveMapRegisters", ActiveMapRegisters); GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","AllocatedScatterGatherLists", AllocatedScatterGatherLists); GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","ActiveScatterGatherLists", ActiveScatterGatherLists); GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","AllocatedCommonBuffers", AllocatedCommonBuffers); GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","FreedCommonBuffers", FreedCommonBuffers); GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","AllocatedAdapterChannels", AllocatedAdapterChannels); GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","FreedAdapterChannels", FreedAdapterChannels); GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","MappedTransferWithoutFlushing", MappedTransferWithoutFlushing); GetFieldValue(AdapterInformation, "nt!_ADAPTER_INFORMATION","Inactive", Inactive); dprintf("\n Dma verifier additional information:\n"); if (Inactive) dprintf("\n This adapter has been freed!\n\n"); dprintf(" DeviceObject: %08p\n", DeviceObject); dprintf(" Map registers: %08p allocated, %08p freed\n", AllocatedMapRegisters, AllocatedMapRegisters - ActiveMapRegisters); dprintf(" Scatter-gather lists: %08p allocated, %08p freed\n", AllocatedScatterGatherLists, AllocatedScatterGatherLists - ActiveScatterGatherLists); dprintf(" Common buffers: %08p allocated, %08p freed\n", AllocatedCommonBuffers, FreedCommonBuffers); dprintf(" Adapter channels: %08p allocated, %08p freed\n", AllocatedAdapterChannels, FreedAdapterChannels); dprintf(" Bytes mapped since last flush: %08p\n", MappedTransferWithoutFlushing); dprintf("\n"); } // Dma verifier enabled for adapter // } // Flags & DMA_DUMP_ADAPTER_INFORMATION // if (CheckControlC()) return TRUE; if (Flags & DMA_DUMP_MAP_REGISTER && AdapterInformation) { ULONG64 MapRegisterFileListHead = 0; ULONG Offset; if ( ! GetFieldOffset("nt!_ADAPTER_INFORMATION", "MapRegisterFiles.ListEntry", &Offset )) { MapRegisterFileListHead = AdapterInformation + Offset; DumpVerifiedMapRegisterFiles(MapRegisterFileListHead); } } if (CheckControlC()) return TRUE; if (Flags & DMA_DUMP_COMMON_BUFFER && AdapterInformation) { ULONG64 CommonBufferListHead = 0; ULONG Offset; if ( ! GetFieldOffset("nt!_ADAPTER_INFORMATION", "CommonBuffers.ListEntry", &Offset )) { CommonBufferListHead = AdapterInformation + Offset; DumpVerifiedCommonBuffers(CommonBufferListHead); } } if (CheckControlC()) return TRUE; #if 0 if (Flags & DMA_DUMP_SCATTER_GATHER && AdapterInformation) { ULONG64 ScatterGatherListHead = 0; ULONG Offset; if ( ! GetFieldOffset("nt!_ADAPTER_INFORMATION", "ScatterGatherLists.ListEntry", &Offset )) { ScatterGatherListHead = AdapterInformation + Offset; DumpVerifiedScatterGatherLists(ScatterGatherListHead); } } #endif if (CheckControlC()) return TRUE; if (Flags & DMA_DUMP_DEVICE_DESCRIPTION && AdapterInformation) { ULONG64 DeviceDescription; ULONG Offset; if ( ! GetFieldOffset("nt!_ADAPTER_INFORMATION", "DeviceDescription", &Offset )) { DeviceDescription = AdapterInformation + Offset; DumpDeviceDescription(DeviceDescription); } } if (CheckControlC()) return TRUE; if (Flags & DMA_DUMP_WCB ) { if (! AdapterInformation) { ULONG64 CurrentWcb = 0; GetFieldValue(Adapter, "hal!_ADAPTER_OBJECT","CurrentWcb", CurrentWcb); if (CurrentWcb) DumpWcb(CurrentWcb); } else if (AllocatedAdapterChannels > FreedAdapterChannels && Flags & DMA_DUMP_WCB ) { //DumpVerifiedWcb(Wcb) } } return 0; } ULONG DumpMasterAdapter( ULONG64 MasterAdapter ) /*++ Routine Description: Given the address of a hal!_MASTER_ADAPTER_OBJECT, this routine dumps out all the useful information to the debugger Arguments: MasterAdapter - Physical address of a hal!_MASTER_ADAPTER_OBJECT in debuggee Return Value: Returns 0 on SUCCESS --*/ { FIELD_INFO MasterAdapterFields[] = { { "AdapterObject", NULL, 0, 0, 0, 0 }, { "MaxBufferPages", NULL, 0, 0, 0, 0 }, { "MapBufferSize", NULL, 0, 0, 0, 0 }, { "MapBufferPhysicalAddress", NULL, RECUR, 0, 0, 0 }, { "MapBufferPhysicalAddress.HighPart", NULL, 0, 0, 0, 0 }, { "MapBufferPhysicalAddress.LowPart", NULL, 0, 0, 0, 0 } }; SYM_DUMP_PARAM MasterAdapterDumpParams = { sizeof(SYM_DUMP_PARAM), "hal!_MASTER_ADAPTER_OBJECT", NOFF, MasterAdapter, NULL, NULL, NULL, sizeof(MasterAdapterFields) / sizeof(FIELD_INFO), &MasterAdapterFields[0] }; // // This is so gnarly, dump all the cool stuff for me! // dprintf("\nMaster DMA adapter: 0x%08p\n", MasterAdapter); if ((Ioctl(IG_DUMP_SYMBOL_INFO, &MasterAdapterDumpParams, MasterAdapterDumpParams.size))) { dprintf("\nError reading master adapter: 0x%08p\n", MasterAdapter); return 1; } return 0; } ULONG DumpWcb( IN ULONG64 Wcb ) /*++ Routine Description: Given the address of a hal!_WAIT_CONTEXT_BLOCK, this routine dumps out all the useful information to the debugger Arguments: Wcb - Physical address of a hal!_WAIT_CONTEXT_BLOCK in debuggee Return Value: Returns 0 on SUCCESS --*/ { FIELD_INFO WcbFields[] = { { "DeviceRoutine", NULL, 0, 0, 0, 0 }, { "NumberOfMapRegisters", NULL, 0, 0, 0, 0 } }; SYM_DUMP_PARAM WcbDumpParams = { sizeof(SYM_DUMP_PARAM), "hal!_WAIT_CONTEXT_BLOCK", NOFF, Wcb, NULL, NULL, NULL, sizeof(WcbFields) / sizeof(FIELD_INFO), &WcbFields[0] }; // // This is so gnarly, dump all the cool stuff for me! // dprintf(" Wait context block: 0x%08p (may be free)\n", Wcb); if ((Ioctl(IG_DUMP_SYMBOL_INFO, &WcbDumpParams, WcbDumpParams.size))) { dprintf("\nError reading wait context block: 0x%08p\n", Wcb); return 1; } return 0; } ULONG ValidateAdapter( IN ULONG64 Address ) /*++ Routine Description: Figures out whether this is a valid adapter. Arguments: Address -- Address of what we think may be an adapter object. Return Value: TRUE -- Valid adapter. FALSE -- Not a valid adapter. --*/ { DBG_LIST_ENTRY AdapterList = {0,0}; ULONG64 StartAddress = 0; ULONG64 CurrentAddress = 0; ULONG Offset; if (! Address ) return FALSE; // // Find the address of the dma adapter list head // This will also make sure that we are using the right // version. // StartAddress = GetExpression("hal!HalpDmaAdapterList"); if (StartAddress == 0) { dprintf("\nCould not find symbol hal!HalpDmaAdapterList.\n\n"); return FALSE; } // // Determine the list entry offset we will use to calculate // adapter addresses // if (GetFieldOffset("hal!_ADAPTER_OBJECT", "AdapterList", &Offset)) { dprintf("\nError retrieving adapter list offset.\n\n"); return FALSE; } // // Read the dma adapter list head // if (GetDbgListEntry(StartAddress, &AdapterList)) { dprintf("\nError reading dma adapter list head: 0x%08p\n\n", StartAddress); return FALSE; } while (AdapterList.Flink != StartAddress) { CurrentAddress = AdapterList.Flink - Offset; if (Address == CurrentAddress) { return TRUE; } // // Read the next adapter list entry // CurrentAddress = AdapterList.Flink; if (GetDbgListEntry(CurrentAddress, &AdapterList)) { dprintf("\nError reading adapter list entry: 0x%08p\n", AdapterList); break; } if (CheckControlC()) break; } // // Check to see if we have the master adapter // CurrentAddress = GetExpression("hal!MasterAdapter32"); if(CurrentAddress == Address) return TRUE; // // Check to see if it is on the verifier adapter list ... // we leave adapters that have been 'put' there so that // we can catch drivers that do dma after puting the adapter. // if (GetVerifierAdapterInformation(Address)) return TRUE; return FALSE; } // ValidateAdapter // VOID DmaUsage( VOID ) /*++ Routine Description: Prints out correct usage for !dma Arguments: NONE Return Value: NONE --*/ { dprintf("\nUsage: !dma [adapter address] [flags]\n"); dprintf("Where: [adapter address] is address of specific dma adapter\n"); dprintf(" or 0x0 for all adapters\n"); dprintf(" [flags] are:\n"); dprintf(" 0x1: Dump generic adapter information\n"); dprintf(" 0x2: Dump map register information\n"); dprintf(" 0x4: Dump common buffer information\n"); dprintf(" 0x8: Dump scatter-gather list information\n"); dprintf(" 0x10: Dump device description for device\n"); dprintf(" 0x20: Dump Wait-context-block information\n"); dprintf("Note: flags {2,4,8,10} require dma verifier to be enabled for the adapter\n\n"); } // DmaUsage // ULONG64 GetVerifierAdapterInformation( ULONG64 AdapterAddress ) /*++ Routine Description: Finds out whether the adapter at AdapterAddress is being verified. If it is, return a pointer to the ADAPTER_INFORMATION structure corresponding to the adapter. Arguments: AdapterAddress -- Address of the adapter we are trying to find out if it is being verified Return Value: ULONG64 -- Address of ADAPTER_INFORMATION struct for verified adapter 0 -- Not verifying adapter; --*/ { DBG_LIST_ENTRY AdapterInfoList = {0,0}; ULONG64 StartAddress = 0; ULONG64 CurrentAdapter = 0; ULONG64 CurrentAdapterInfo = 0; ULONG64 VerifiedDmaAdapter = 0; ULONG ListEntryOffset = 0; UINT64 VerifyingDma = 0; if (! AdapterAddress ) return 0; ReadPointer(GetExpression("nt!ViVerifyDma"), &VerifyingDma); if (0 == VerifyingDma) // // Not verifying dma ... // { return 0; } // // Find the address of the dma adapter list head // StartAddress = GetExpression("nt!ViAdapterList"); if (StartAddress == 0) { return 0; } // // Determine the list entry offset we will use to calculate // adapter addresses // if (GetFieldOffset("nt!_ADAPTER_INFORMATION", "ListEntry", &ListEntryOffset)) { dprintf("\nError retrieving verifier adapter information list offset.\n\n"); return 0; } // // Read the dma adapter list head // if (GetDbgListEntry(StartAddress, &AdapterInfoList)) { dprintf("\nError reading verifier adapter information list head: 0x%08p\n\n", StartAddress); return 0; } if (AdapterInfoList.Flink == 0 || AdapterInfoList.Blink == 0) return 0; while (AdapterInfoList.Flink != StartAddress) { CurrentAdapterInfo = AdapterInfoList.Flink - ListEntryOffset; GetFieldValue(CurrentAdapterInfo, "nt!_ADAPTER_INFORMATION","DmaAdapter", VerifiedDmaAdapter); if (AdapterAddress == VerifiedDmaAdapter) { return CurrentAdapterInfo; } // // Read the next adapter list entry // if (GetDbgListEntry(AdapterInfoList.Flink, &AdapterInfoList)) { dprintf("\nError reading adapter info list entry: 0x%08p\n", AdapterInfoList); break; } if (CheckControlC()) break; } return 0; } // GetVerifierAdapterInformation // VOID DumpVerifiedMapRegisterFiles( IN ULONG64 MapRegisterFileListHead ) /*++ Routine Description: Dump pertinent info pertaining to verified map registers. NOTE: This may not be all map registers for the adapter -- just the ones that are being verified. There is a limit to how many map registers we verify for each adapter -- since each time we use three pages of physical memory. NOTE ON TERMINOLOGY: Map register file: a single allocation of map registers recieved in the callback routine from IoAllocateAdapterChannel. Any number or combination of these registers can be mapped at one time. Arguments: MapRegisterFileListHead -- head of list of map register files. Return Value: NONE --*/ { DBG_LIST_ENTRY MapRegisterFileListEntry = {0,0}; ULONG64 MapRegisterFile = 0; ULONG ListEntryOffset = 0; ULONG64 Signature = 0; ULONG64 NumberOfMapRegisters = 0; ULONG64 NumberOfRegistersMapped = 0; ULONG64 MapRegisterMdl = 0; ULONG64 MapRegister; ULONG64 MappedToAddress; ULONG64 BytesMapped; ULONG64 MapRegisterStart; ULONG SizeofMapRegister; ULONG CurrentMapRegister; ULONG MapRegisterOffset; if (GetDbgListEntry(MapRegisterFileListHead, &MapRegisterFileListEntry)) { return; } if (MapRegisterFileListEntry.Flink == MapRegisterFileListHead) // // Empty list // { dprintf("\n No map register files\n\n"); return; } // // Determine the list entry offset we will use to calculate // the beginning of the map register file // if (GetFieldOffset("nt!_MAP_REGISTER_FILE", "ListEntry", &ListEntryOffset)) { dprintf("\nError retrieving list entry offset.\n\n"); return; } SizeofMapRegister = GetTypeSize("nt!_MAP_REGISTER"); if (! SizeofMapRegister ) { dprintf("\n Could not get size of nt!_MAP_REGISTER\n\n"); return; } if (GetFieldOffset("nt!_MAP_REGISTER_FILE","MapRegisters", &MapRegisterOffset)) { dprintf("\n Couuld not get map register offset\n\n"); } while (MapRegisterFileListEntry.Flink != MapRegisterFileListHead) { MapRegisterFile = MapRegisterFileListEntry.Flink - ListEntryOffset; GetFieldValue(MapRegisterFile, "nt!_MAP_REGISTER_FILE","Signature", Signature); if (((ULONG) Signature) != MAP_REGISTER_FILE_SIGNATURE) { dprintf("\n Invalid signature for map register file %08p\n\n", MapRegisterFile); return; } GetFieldValue(MapRegisterFile, "nt!_MAP_REGISTER_FILE","NumberOfMapRegisters", NumberOfMapRegisters); GetFieldValue(MapRegisterFile, "nt!_MAP_REGISTER_FILE","NumberOfRegistersMapped", NumberOfRegistersMapped); GetFieldValue(MapRegisterFile, "nt!_MAP_REGISTER_FILE","MapRegisterMdl", MapRegisterMdl); dprintf(" Map register file %08p (%x/%x mapped)\n", MapRegisterFile, (ULONG) NumberOfRegistersMapped, (ULONG) NumberOfMapRegisters); dprintf(" Double buffer mdl: %08p\n", MapRegisterMdl); dprintf(" Map registers:\n"); MapRegister = MapRegisterFile + MapRegisterOffset; for (CurrentMapRegister = 0; CurrentMapRegister < NumberOfMapRegisters; CurrentMapRegister++) { GetFieldValue(MapRegister, "nt!_MAP_REGISTER", "MappedToSa", MappedToAddress); GetFieldValue(MapRegister, "nt!_MAP_REGISTER", "BytesMapped", BytesMapped); dprintf(" %08x: ", MapRegister); //dprintf(" %03x: ", CurrentMapRegister); if (BytesMapped) { dprintf("%04x bytes mapped to %08p\n", (ULONG) BytesMapped, MappedToAddress); } else { dprintf("Not mapped\n"); } if (CheckControlC()) return; // // Increment our map register pointer // MapRegister += SizeofMapRegister; } // End dump of map registers // dprintf("\n"); // // Advance to the next map register file // if (GetDbgListEntry(MapRegisterFileListEntry.Flink , &MapRegisterFileListEntry)) { dprintf("\nError reading map register file list entry: 0x%08p\n", MapRegisterFileListEntry.Flink); break; } if (CheckControlC()) return; } // End dump of map register files // return; } // DumpVerifiedMapRegisterFiles // VOID DumpVerifiedCommonBuffers( IN ULONG64 CommonBufferListHead ) /*++ Routine Description: Dump pertinent info pertaining to verified common buffers Arguments: CommonBufferListHead -- head of list of common buffers for a single adapter Return Value: NONE --*/ { DBG_LIST_ENTRY CommonBufferListEntry = {0,0}; ULONG64 CommonBuffer; ULONG AdvertisedLength; UINT64 AdvertisedStartAddress; UINT64 RealStartAddress; UINT64 RealLogicalStartAddress; UINT64 AdvertisedLogicalStartAddress; UINT64 AllocatorAddress; ULONG ListEntryOffset; CHAR AllocatorName[256]; if (GetDbgListEntry(CommonBufferListHead, &CommonBufferListEntry)) { return; } if (CommonBufferListEntry.Flink == CommonBufferListHead) // // Empty list // { dprintf("\n No common buffers\n\n"); return; } // // Determine the list entry offset we will use to calculate // the beginning of the map register file // if (GetFieldOffset("nt!_HAL_VERIFIER_BUFFER", "ListEntry", &ListEntryOffset)) { dprintf("\n Error retrieving list entry offset.\n\n"); return; } while (CommonBufferListEntry.Flink != CommonBufferListHead) { CommonBuffer = CommonBufferListEntry.Flink - ListEntryOffset; GetFieldValue(CommonBuffer, "nt!_HAL_VERIFIER_BUFFER","AdvertisedLength", AdvertisedLength); GetFieldValue(CommonBuffer, "nt!_HAL_VERIFIER_BUFFER","AdvertisedStartAddress", AdvertisedStartAddress); GetFieldValue(CommonBuffer, "nt!_HAL_VERIFIER_BUFFER","RealStartAddress", RealStartAddress); GetFieldValue(CommonBuffer, "nt!_HAL_VERIFIER_BUFFER","RealLogicalStartAddress", RealLogicalStartAddress); GetFieldValue(CommonBuffer, "nt!_HAL_VERIFIER_BUFFER","AllocatorAddress", AllocatorAddress); DumpSymbolicAddress(AllocatorAddress, AllocatorName, TRUE); dprintf(" Common buffer allocated by %s:\n", AllocatorName); dprintf(" Length: %x\n", AdvertisedLength); dprintf(" Virtual address: %08p\n", AdvertisedStartAddress); dprintf(" Physical address: %I64lx\n", (AdvertisedStartAddress - RealStartAddress) + RealLogicalStartAddress); dprintf("\n"); // // Advance to the next common buffer in the list // if (GetDbgListEntry(CommonBufferListEntry.Flink , &CommonBufferListEntry)) { dprintf("\nError reading common buffer list entry: 0x%08p\n", CommonBufferListEntry.Flink); break; } if (CheckControlC()) return; } // End dump of common buffers // return; } // DumpVerifiedCommonBuffers // VOID DumpVerifiedScatterGatherLists( IN ULONG64 ScatterGatherListHead ) /*++ Routine Description: Dump pertinent info pertaining to scatter gather lists in use by a single adapter. Arguments: ScatterGatherListHead -- head of a list of ScatterGather lists. Return Value: NONE --*/ { UNREFERENCED_PARAMETER(ScatterGatherListHead); return; } // DumpVerifiedScatterGatherLists // VOID DumpDeviceDescription( IN ULONG64 DeviceDescription ) /*++ Routine Description: Dump pertinent info from a device description struct Arguments: ScatterGatherListHead -- head of a list of ScatterGather lists. Return Value: NONE --*/ { ULONG Version; BOOLEAN Master; BOOLEAN ScatterGather; BOOLEAN Dma32BitAddresses; BOOLEAN Dma64BitAddresses; ULONG InterfaceType; ULONG MaximumLength; GetFieldValue(DeviceDescription, "hal!_DEVICE_DESCRIPTION","Version", Version); if (Version > 2) { dprintf("\nBad device description version: %x\n\n", Version); return; } GetFieldValue(DeviceDescription, "hal!_DEVICE_DESCRIPTION","Master", Master); GetFieldValue(DeviceDescription, "hal!_DEVICE_DESCRIPTION","ScatterGather", ScatterGather); GetFieldValue(DeviceDescription, "hal!_DEVICE_DESCRIPTION","Dma32BitAddresses", Dma32BitAddresses); GetFieldValue(DeviceDescription, "hal!_DEVICE_DESCRIPTION","Dma64BitAddresses", Dma64BitAddresses); GetFieldValue(DeviceDescription, "hal!_DEVICE_DESCRIPTION","InterfaceType", InterfaceType); dprintf(" Device Description Version %02x\n", Version); if (InterfaceType < MAX_INTERFACE) { dprintf(" Interface type %s\n", DbgInterfaceTypes[InterfaceType]); } else { dprintf(" Interface type unknown\n"); } dprintf(" DMA Capabilities:\n"); if(Master) { dprintf(" Busmaster\n"); } else { dprintf(" Slave\n"); } if (ScatterGather) dprintf(" Scatter Gather\n"); if (Dma32BitAddresses) dprintf(" 32-bit DMA\n"); if (Dma64BitAddresses) dprintf(" 64-bit DMA\n"); if (! Dma32BitAddresses && ! Dma64BitAddresses) dprintf(" 24-bit DMA only\n"); dprintf("\n"); } // DumpDeviceDescription //