|
|
/*++
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: <adapter> [<module allocating adapter>!CallingFunction+0x<offset>]
// (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 //
|