|
|
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
bushnd.c
Abstract:
KD Extension for BUS_HANDLER data structures.
Author:
Peter Johnston (peterj) 13-May-1998
Environment:
User Mode.
Revision History:
--*/
#include "precomp.h"
//
// The following typedef is copied directly from nthals\bushnd.c.
//
/*
typedef struct _HAL_BUS_HANDLER { LIST_ENTRY AllHandlers; ULONG ReferenceCount; BUS_HANDLER Handler; } HAL_BUS_HANDLER, *PHAL_BUS_HANDLER; */
BOOLEAN bushndReadMemory( ULONG64 S, PVOID D, ULONG Len )
/*++
Routine Description:
Wrapper for ReadMemory that's somewhat easier to use. Also does a small amount of failsafe stuff, like failing the read if the user pressed control-C.
Arguments:
S Source Address in host memory to read data from. D Destination address in local memory. Len length in bytes.
Return Value:
Returns TRUE if the operation was successful, FALSE otherwise.
--*/
{ ULONG result;
//
// Sanity: Only read kernel mode addresses. Kernel mode
// addresses are always greater than 2GB. Being greater than
// 2GB doesn't ensure it's kernel mode, but if it's less than
// 2GB it is certainly NOT kernel mode.
//
if (S < 0x80000000) { dprintf("bushnd sanity: refusing to read usermode address %p\n", S); return FALSE; }
if (!ReadMemory(S, D, Len, &result) && (result == Len)) {
dprintf("Unable to read structure at %p. ", S); return FALSE; }
if (CheckControlC()) { dprintf("Terminating operation at user request.\n"); return FALSE; } return TRUE; }
PUCHAR bushndInterfaceType( IN INTERFACE_TYPE InterfaceType ) { switch (InterfaceType) { case InterfaceTypeUndefined: return "InterfaceTypeUndefined"; case Internal: return "Internal"; case Isa: return "Isa"; case Eisa: return "Eisa"; case MicroChannel: return "Micro Channel"; case TurboChannel: return "Turbo Channel"; case PCIBus: return "PCI"; case VMEBus: return "VME"; case NuBus: return "NuBus"; case PCMCIABus: return "PCMCIA"; case CBus: return "CBus"; case MPIBus: return "MPIBus"; case MPSABus: return "MPSABus"; case ProcessorInternal: return "Processor Internal"; case InternalPowerBus: return "Internal Power Bus"; case PNPISABus: return "PnP Isa"; case PNPBus: return "PnP Bus"; default: return "** Unknown Interface Type **"; } }
VOID bushndDisplayAddressRange( IN ULONG64 HostAddress, IN PUCHAR String )
/*++
Routine Description:
Display a set of ranges. Used by bushndDisplayBusRanges. (Pretty much just lifted this code from nthals/rangesup.c).
Arguments:
Pointer to a PSUPPORTED_RANGE structure. This is a linked list of the ranges of this type for this bus handler.
Note: On entry we are pointing at a local copy of the first PSUPPORTED_RANGE of this type embedded in the BUS_HANDLER structure. We don't want to modify that so subsequent ranges are read into a seperate local structure.
String. What sort of range this is (a heading).
Return Value:
None.
--*/
{ ULONG64 Limit, Base, SystemBase, Next;
do {
InitTypeRead(HostAddress, SUPPORTED_RANGE);
Limit = ReadField(Limit); Base = ReadField(Base); SystemBase = ReadField(SystemBase);
if (Limit) {
//
// Address->Limit == 0 means skip this range,... otherwise,...
//
// Print this range.
//
dprintf(" %s: %x:%08x - %x:%08x (tran %x:%08x space %d (r@%p))\n", String, (ULONG)(Base >> 32), (ULONG)(Base), (ULONG)(Limit >> 32), (ULONG)(Limit), (ULONG)(SystemBase >> 32), (ULONG)(SystemBase), (ULONG)ReadField(SystemAddressSpace), HostAddress ); String = " "; }
//
// Advance.
//
if (!(HostAddress = ReadField(Next))) { return; }
if (GetFieldValue(HostAddress, "SUPPORTED_RANGE", "Next", Next)) { dprintf("Unable to follow range list.\n"); return; }
//
// Quick saftey check,... make sure we don't follow a
// self pointer,... would be good to do some more checking.
//
if (Next == HostAddress) {
//
// Self pointer.
//
dprintf("Ill-formed list, points to self at %p\n", HostAddress); return; }
} while (TRUE); }
VOID bushndDisplayBusRanges( IN ULONG64 BusAddresses ) { ULONG Version, Offset;
if (!BusAddresses) { dprintf(" No ranges associated with this bus.\n"); return; }
if (GetFieldValue(BusAddresses, "SUPPORTED_RANGES", "Version", Version)) { dprintf("Cannot dump ranges for this bus handler.\n"); return; }
GetFieldOffset("SUPPORTED_RANGES", "IO", &Offset); bushndDisplayAddressRange(BusAddresses + Offset, "IO......"); GetFieldOffset("SUPPORTED_RANGES", "Memory", &Offset); bushndDisplayAddressRange(BusAddresses + Offset, "Memory.."); GetFieldOffset("SUPPORTED_RANGES", "PrefetchMemory", &Offset); bushndDisplayAddressRange(BusAddresses + Offset, "PFMemory"); GetFieldOffset("SUPPORTED_RANGES", "Dma", &Offset); bushndDisplayAddressRange(BusAddresses + Offset, "DMA....."); }
VOID bushndDisplaySymbol( IN PUCHAR Name, IN ULONG64 Address ) { UCHAR Symbol[256]; ULONG64 Displacement;
GetSymbol((LONG64)Address, Symbol, &Displacement); dprintf(" %s %08p (%s)\n", Name, Address, Symbol); }
DECLARE_API( bushnd )
/*++
Routine Description:
If no handler specified, dump the list of handlers and some simple info about each of them.
If a handler is specified, dump everything we know about it.
Arguments:
Bus handler address [optional].
Return Value:
None.
--*/
{ ULONG64 Handler; ULONG64 HostHandler; ULONG64 HalBusHandler; ULONG64 HandlerListHead; UCHAR SymbolBuffer[256];
HostHandler = GetExpression(args);
if (HostHandler) { ULONG Version, InitTypeRead, InterfaceType; ULONG64 DeviceObject, BusData;
//
// User supplied a handler address, dump details for that bus
// handler.
//
if (GetFieldValue(HostHandler, "BUS_HANDLER", "Version", Version)) {
dprintf("-- Cannot continue --\n"); return E_INVALIDARG; } InitTypeRead(HostHandler, BUS_HANDLER); InterfaceType = (ULONG) ReadField(InterfaceType); dprintf("Dump of bus handler %p\n", HostHandler); dprintf(" Version %d\n", Version); dprintf(" Interface Type (%d) = %s\n", InterfaceType, bushndInterfaceType(InterfaceType)); dprintf(" Bus Number %d\n", (ULONG) ReadField(BusNumber)); if (DeviceObject = ReadField(DeviceObject)) { dprintf(" Device Object %p\n", DeviceObject); } dprintf(" Parent Bus Handler %p\n", ReadField(ParentHandler)); if (BusData = ReadField(BusData)) { dprintf(" BusData %p\n", BusData); }
bushndDisplaySymbol("GetBusData ", ReadField(GetBusData)); bushndDisplaySymbol("SetBusData ", ReadField(SetBusData)); bushndDisplaySymbol("AdjustResourceList ", ReadField(AdjustResourceList)); bushndDisplaySymbol("AssignSlotResources", ReadField(AssignSlotResources)); bushndDisplaySymbol("GetInterruptVector ", ReadField(GetInterruptVector)); bushndDisplaySymbol("TranslateBusAddress", ReadField(TranslateBusAddress));
bushndDisplayBusRanges(ReadField(BusAddresses));
} else { ULONG Off;
//
// User did not supply a handler address, try to find the
// list of all bus handlers and dump a summary of each handler.
//
HandlerListHead = GetExpression("hal!HalpAllBusHandlers");
if (!HandlerListHead) {
//
// Couldn't get address of HalpAllBusHandlers. Whine
// at user.
//
dprintf( "Unable to get address of HalpAllBusHandlers, most likely\n" "cause is failure to load HAL symbols, or, this HAL might\n" "not actually use bus handlers. " );
dprintf("-- Cannot continue --"); return E_INVALIDARG; }
if (GetFieldValue(HandlerListHead, "LIST_ENTRY", "Flink", HalBusHandler)) { dprintf( "Could not read HalpAllBusHandlers from host memory (%p).\n" "This is most likely caused by incorrect HAL symbols.\n", HandlerListHead );
dprintf("-- Cannot continue --\n"); return E_INVALIDARG; }
if (HalBusHandler == HandlerListHead) {
dprintf( "HalpAllBusHandlers found (at %p) but list is empty.\n", HandlerListHead );
dprintf("-- Cannot continue --\n"); return E_INVALIDARG; }
GetFieldOffset("hal!_HAL_BUS_HANDLER", "Handler", &Off);
//
// In theory, we now have the handler list. Walk it.
//
do { ULONG64 Next; ULONG BusNumber, InterfaceType;
if (GetFieldValue(HalBusHandler, "hal!_HAL_BUS_HANDLER", "AllHandlers.Flink", Next)) {
dprintf("-- Cannot continue --\n"); return E_INVALIDARG; }
//
// Brief summary.
//
Handler = HalBusHandler + Off; GetFieldValue(HalBusHandler, "hal!_HAL_BUS_HANDLER", "BusNumber", BusNumber); GetFieldValue(HalBusHandler, "hal!_HAL_BUS_HANDLER", "Handler.InterfaceType", InterfaceType); dprintf( "%p bus %d, type %s\n", Handler, BusNumber, bushndInterfaceType(InterfaceType) ); //
// Advance to next.
//
HalBusHandler = Next;
} while (HalBusHandler != HandlerListHead); } return S_OK; }
|