windows-nt/Source/XPSP1/NT/base/tools/kdexts2/dma.c
2020-09-26 16:20:57 +08:00

1277 lines
32 KiB
C

/*++
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 //