464 lines
14 KiB
C
464 lines
14 KiB
C
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
UHCD.c
|
|
|
|
Abstract:
|
|
|
|
WinDbg Extension Api
|
|
|
|
Author:
|
|
|
|
Kenneth D. Ray (kenray) June 1997
|
|
|
|
Environment:
|
|
|
|
User Mode.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
|
|
typedef union _USB_FLAGS {
|
|
struct {
|
|
ULONG FullListing : 1;
|
|
ULONG Reserved : 31;
|
|
};
|
|
ULONG Flags;
|
|
} USB_FLAGS;
|
|
|
|
#define PRINT_FLAGS(value, flag) \
|
|
if ((value) & (flag)) { \
|
|
dprintf (#flag " "); \
|
|
}
|
|
|
|
#define MAX_INTERVAL 32
|
|
|
|
//
|
|
// MACROS for USB controller registers
|
|
//
|
|
|
|
#define COMMAND_REG(DeviceRegisters) \
|
|
(DeviceRegisters)
|
|
#define STATUS_REG(DeviceRegisters) \
|
|
((DeviceRegisters + 0x02))
|
|
#define INTERRUPT_MASK_REG(DeviceRegisters) \
|
|
(DeviceRegisters + 0x04)
|
|
#define FRAME_LIST_CURRENT_INDEX_REG(DeviceRegisters) \
|
|
(DeviceRegisters + 0x06)
|
|
#define FRAME_LIST_BASE_REG(DeviceRegisters) \
|
|
(DeviceRegisters + 0x08)
|
|
#define SOF_MODIFY_REG(DeviceRegisters) \
|
|
(DeviceRegisters + 0x0C)
|
|
#define PORT1_REG(DeviceRegisters) \
|
|
(DeviceRegisters + 0x10)
|
|
#define PORT2_REG(DeviceRegisters) \
|
|
(DeviceRegisters + 0x12)
|
|
|
|
VOID
|
|
UhciPortRegister(
|
|
ULONG PortNumber,
|
|
ULONG Value
|
|
);
|
|
|
|
VOID
|
|
DevExtUHCD(
|
|
ULONG64 MemLocPtr
|
|
)
|
|
{
|
|
ULONG64 MemLoc = MemLocPtr;
|
|
ULONG HcFlags;
|
|
ULONG i;
|
|
|
|
dprintf ("Dump UHCD Extension: %p\n", MemLoc);
|
|
|
|
|
|
if (InitTypeRead (MemLoc, uhcd!_USBD_EXTENSION)) {
|
|
dprintf ("Could not read Usbd Extension\n");
|
|
return;
|
|
}
|
|
|
|
if (0 != ReadField( TrueDeviceExtension)) {
|
|
MemLoc = ReadField(TrueDeviceExtension);
|
|
}
|
|
|
|
|
|
if (InitTypeRead (MemLoc, uhcd!_DEVICE_EXTENSION)) {
|
|
dprintf ("Could not read UHCD Extension\n");
|
|
return;
|
|
}
|
|
|
|
dprintf("\n");
|
|
dprintf("PhysicalDO: %8p TopOfStackDO: %8p InterruptObject: %8p\n"
|
|
"FrameListVA: %8p FrameListLA: %8p ",
|
|
ReadField(PhysicalDeviceObject),
|
|
ReadField(TopOfStackDeviceObject),
|
|
ReadField(InterruptObject),
|
|
ReadField(FrameListVirtualAddress),
|
|
ReadField(FrameListLogicalAddress));
|
|
|
|
dprintf("FrameListCopyVA: %08p\n",
|
|
ReadField(FrameListCopyVirtualAddress));
|
|
|
|
dprintf("\n");
|
|
/*
|
|
dprintf("PersistantQH: %8x PQH_DescriptorList: %8x\n"
|
|
"EndpointList & %x = (%x %x) \n"
|
|
"EndpointLookAsideList & %x = (%x %x) \n"
|
|
"ClosedEndpointList & %x = (%x %x) \n",
|
|
(ULONG) ReadField(PersistantQueueHead),
|
|
(ULONG) ReadField(PQH_DescriptorList),
|
|
&((ULONG) ReadField(EndpointList)),
|
|
(ULONG) ReadField(EndpointList.Flink),
|
|
(ULONG) ReadField(EndpointList.Blink),
|
|
&((ULONG) ReadField(EndpointLookAsideList)),
|
|
(ULONG) ReadField(EndpointLookAsideList.Flink),
|
|
(ULONG) ReadField(EndpointLookAsideList.Blink),
|
|
&((ULONG) ReadField(ClosedEndpointList)),
|
|
(ULONG) ReadField(ClosedEndpointList.Flink),
|
|
(ULONG) ReadField(ClosedEndpointList.Blink));*/
|
|
dprintf("PersistantQH: %8p PQH_DescriptorList: %8p\n"
|
|
"EndpointList = (%p %p) \n"
|
|
"EndpointLookAsideList = (%p %p) \n"
|
|
"ClosedEndpointList = (%p %p) \n",
|
|
ReadField(PersistantQueueHead),
|
|
ReadField(PQH_DescriptorList),
|
|
ReadField(EndpointList.Flink),
|
|
ReadField(EndpointList.Blink),
|
|
ReadField(EndpointLookAsideList.Flink),
|
|
ReadField(EndpointLookAsideList.Blink),
|
|
ReadField(ClosedEndpointList.Flink),
|
|
ReadField(ClosedEndpointList.Blink));
|
|
|
|
dprintf("\n");
|
|
dprintf("InterruptSchedule: ");
|
|
|
|
for (i = 0; i < MAX_INTERVAL; i++)
|
|
{
|
|
UCHAR Sch[40];
|
|
|
|
sprintf(Sch, "InterruptSchedule[%d]", i);
|
|
dprintf("%8x ", (ULONG) GetShortField(0, Sch, 0));
|
|
|
|
if (3 == i % 4)
|
|
{
|
|
dprintf("\n");
|
|
dprintf(" ");
|
|
}
|
|
}
|
|
|
|
dprintf("\n");
|
|
// dprintf("PageList & %x = (%x %x) \n",
|
|
// &( (ULONG) ReadField(PageList)),
|
|
dprintf("PageList = (%x %x) \n",
|
|
ReadField(PageList.Flink),
|
|
ReadField(PageList.Blink));
|
|
|
|
dprintf("\n");
|
|
dprintf("BwTable: ");
|
|
|
|
for (i = 0; i < MAX_INTERVAL; i++)
|
|
{
|
|
UCHAR Table[40];
|
|
|
|
sprintf(Table, "BwTable[%d]", i);
|
|
|
|
dprintf("%5d ", GetShortField(0, Table, 0));
|
|
|
|
if (7 == i % 8)
|
|
{
|
|
dprintf("\n");
|
|
dprintf(" ");
|
|
}
|
|
}
|
|
|
|
dprintf("\n");
|
|
dprintf("LastFrame: %8x FrameHighPart: %8x\n"
|
|
"LastIdleTime.High: %8x LastIdleTime.Low %8x\n",
|
|
"LastXferIdleTime.High: %8x LastXferIdleTime.Low %8x\n",
|
|
"IdleTime: %8x XferIdleTime %8x\n",
|
|
(ULONG) ReadField(LastFrame),
|
|
(ULONG) ReadField(FrameHighPart),
|
|
(ULONG) ReadField(LastIdleTime.HighPart),
|
|
(ULONG) ReadField(LastIdleTime.LowPart),
|
|
(ULONG) ReadField(LastXferIdleTime.HighPart),
|
|
(ULONG) ReadField(LastXferIdleTime.LowPart),
|
|
(ULONG) ReadField(IdleTime),
|
|
(ULONG) ReadField(XferIdleTime));
|
|
|
|
dprintf("\n");
|
|
dprintf("TriggerList: %08p\n"
|
|
"LargeBufferPool: %08p\n"
|
|
"MediumBufferPool: %08p\n"
|
|
"SmallBufferPool: %08p\n",
|
|
ReadField(TriggerTDList),
|
|
ReadField(LargeBufferPool),
|
|
ReadField(MediumBufferPool),
|
|
ReadField(SmallBufferPool));
|
|
|
|
dprintf("\nRootHub Variables\n");
|
|
dprintf("DeviceAddress: %3d RootHub: %8x\n"
|
|
"TimersActive: %3d InterruptEndpoint: %8x\n",
|
|
(ULONG) ReadField(RootHubDeviceAddress),
|
|
(ULONG) ReadField(RootHub),
|
|
(ULONG) ReadField(RootHubTimersActive),
|
|
(ULONG) ReadField(RootHubInterruptEndpoint));
|
|
|
|
dprintf("\n");
|
|
dprintf("LastFrameProcessed: %x\n"
|
|
"AdapterObject: %8x\n"
|
|
"MapRegisters: %d\n"
|
|
"DeviceNameHandle: %x\n"
|
|
"FrameBabbleRecoverTD: %8x\n",
|
|
(ULONG) ReadField(LastFrameProcessed),
|
|
(ULONG) ReadField(AdapterObject),
|
|
(ULONG) ReadField(NumberOfMapRegisters),
|
|
(ULONG) ReadField(DeviceNameHandle),
|
|
(ULONG) ReadField(FrameBabbleRecoverTD));
|
|
|
|
dprintf("\nSaved Bios Info\n");
|
|
dprintf("Cmd: %x IntMask: %x\n"
|
|
"FrameListBase: %x LegacySuppReg: %x\n"
|
|
"DeviceRegisters: %x SavedInterruptEnable: %x\n"
|
|
"SavedCommandReg: %x\n",
|
|
(ULONG) ReadField(BiosCmd),
|
|
(ULONG) ReadField(BiosIntMask),
|
|
(ULONG) ReadField(BiosFrameListBase),
|
|
(ULONG) ReadField(LegacySupportRegister),
|
|
(ULONG) ReadField(DeviceRegisters[0]),
|
|
(ULONG) ReadField(SavedInterruptEnable),
|
|
(ULONG) ReadField(SavedCommandReg));
|
|
|
|
dprintf("\n");
|
|
dprintf("PowerState: %x\n"
|
|
"HcFlags %x: ",
|
|
(ULONG) ReadField(CurrentDevicePowerState),
|
|
HcFlags = (ULONG) ReadField(HcFlags));
|
|
PRINT_FLAGS(HcFlags, HCFLAG_GOT_IO);
|
|
PRINT_FLAGS(HcFlags, HCFLAG_UNMAP_REGISTERS);
|
|
PRINT_FLAGS(HcFlags, HCFLAG_USBBIOS);
|
|
PRINT_FLAGS(HcFlags, HCFLAG_BWRECLIMATION_ENABLED);
|
|
PRINT_FLAGS(HcFlags, HCFLAG_NEED_CLEANUP);
|
|
PRINT_FLAGS(HcFlags, HCFLAG_IDLE);
|
|
PRINT_FLAGS(HcFlags, HCFLAG_ROLLOVER_IDLE);
|
|
PRINT_FLAGS(HcFlags, HCFLAG_HCD_STOPPED);
|
|
PRINT_FLAGS(HcFlags, HCFLAG_DISABLE_IDLE);
|
|
PRINT_FLAGS(HcFlags, HCFLAG_WORK_ITEM_QUEUED);
|
|
PRINT_FLAGS(HcFlags, HCFLAG_HCD_SHUTDOWN);
|
|
PRINT_FLAGS(HcFlags, HCFLAG_LOST_POWER);
|
|
PRINT_FLAGS(HcFlags, HCFLAG_RH_OFF);
|
|
PRINT_FLAGS(HcFlags, HCFLAG_MAP_SX_TO_D3);
|
|
dprintf("\n");
|
|
|
|
dprintf("\n");
|
|
dprintf("SavedFrameNumber: %8x SavedFRBaseAdd: %8x\n"
|
|
"Port: %8x HcDma: %8x\n"
|
|
"RegRecClocksPerFrame: %8x Piix4EP %8x\n"
|
|
"EndpointListBusy: %8d SteppingVer: %8x\n"
|
|
"SavedSOFModify: %8x ControllerType: %8x\n",
|
|
(ULONG) ReadField(SavedFRNUM),
|
|
(ULONG) ReadField(SavedFRBASEADD),
|
|
(ULONG) ReadField(Port),
|
|
(ULONG) ReadField(HcDma),
|
|
(ULONG) ReadField(RegRecClocksPerFrame),
|
|
(ULONG) ReadField(Piix4EP),
|
|
(ULONG) ReadField(EndpointListBusy),
|
|
(ULONG) ReadField(SteppingVersion),
|
|
(ULONG) ReadField(SavedSofModify),
|
|
(ULONG) ReadField(ControllerType));
|
|
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
UHCD_HCRegisters(
|
|
ULONG64 MemLoc
|
|
)
|
|
{
|
|
ULONG64 hcObject;
|
|
ULONG64 devExtAddr;
|
|
|
|
ULONG result;
|
|
ULONG64 DeviceRegisters;
|
|
ULONG regValue;
|
|
ULONG size;
|
|
ULONG64 TrueDeviceExtension;
|
|
|
|
//
|
|
// In this case, MemLoc points the the device object for the given
|
|
// host controller.
|
|
//
|
|
|
|
hcObject = MemLoc;
|
|
|
|
//
|
|
// Get the address of the device extension
|
|
//
|
|
|
|
GetFieldValue(MemLoc, "uhcd!_DEVICE_OBJECT", "DeviceExtension", devExtAddr);
|
|
|
|
//
|
|
// Read the USBD extension
|
|
//
|
|
|
|
if (GetFieldValue(devExtAddr, "uhcd!_USBD_EXTENSION", "TrueDeviceExtension", TrueDeviceExtension)) {
|
|
dprintf ("Could not read Usbd Extension\n");
|
|
return;
|
|
}
|
|
|
|
if (0 != TrueDeviceExtension) {
|
|
devExtAddr = TrueDeviceExtension;
|
|
}
|
|
|
|
if (GetFieldValue(devExtAddr, "uhcd!_DEVICE_EXTENSION", "DeviceRegisters[0]", DeviceRegisters)) {
|
|
dprintf ("Could not read UHCD Extension\n");
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Get and display the command register (USBCMD)
|
|
//
|
|
|
|
size = 2;
|
|
// ReadIoSpace((ULONG) COMMAND_REG((&uhcd)), ®Value, &size);
|
|
ReadIoSpace64(COMMAND_REG(DeviceRegisters), ®Value, &size);
|
|
|
|
dprintf("\n");
|
|
dprintf("Command Register: Run/Stop: %x HC reset: %x Global reset: %x\n"
|
|
" Global Suspend: %x Global Resume: %x SW Debug: %x\n"
|
|
" Configure Flag: %x Max Packet: %x\n",
|
|
regValue & UHCD_CMD_RUN,
|
|
regValue & UHCD_CMD_RESET,
|
|
regValue & UHCD_CMD_GLOBAL_RESET,
|
|
regValue & UHCD_CMD_SUSPEND,
|
|
regValue & UHCD_CMD_FORCE_RESUME,
|
|
regValue & UHCD_CMD_SW_DEBUG,
|
|
regValue & UHCD_CMD_SW_CONFIGURED,
|
|
regValue & UHCD_CMD_MAXPKT_64);
|
|
|
|
//
|
|
// Get and display the status register (USBSTS)
|
|
//
|
|
|
|
ReadIoSpace64(STATUS_REG(DeviceRegisters), ®Value, &size);
|
|
|
|
dprintf("\n");
|
|
dprintf("Status Register: Transfer Int: %x Error Int: %x Resume Detect: %x\n",
|
|
" Host Error: %x HC Error: %x HC Halted: %x\n",
|
|
regValue & UHCD_STATUS_USBINT,
|
|
regValue & UHCD_STATUS_USBERR,
|
|
regValue & UHCD_STATUS_RESUME,
|
|
regValue & UHCD_STATUS_PCIERR,
|
|
regValue & UHCD_STATUS_HCERR,
|
|
regValue & UHCD_STATUS_HCHALT);
|
|
|
|
//
|
|
// Get and display the interrupt enable register (USBINTR)
|
|
//
|
|
|
|
ReadIoSpace64(INTERRUPT_MASK_REG(DeviceRegisters), ®Value, &size);
|
|
|
|
dprintf("\n");
|
|
dprintf("Interrupt Register: ");
|
|
PRINT_FLAGS(regValue, UHCD_INT_MASK_TIMEOUT);
|
|
PRINT_FLAGS(regValue, UHCD_INT_MASK_RESUME);
|
|
PRINT_FLAGS(regValue, UHCD_INT_MASK_IOC);
|
|
PRINT_FLAGS(regValue, UHCD_INT_MASK_SHORT);
|
|
dprintf("\n");
|
|
|
|
//
|
|
// Get and display the frame number (FRNUM)
|
|
//
|
|
|
|
ReadIoSpace64(FRAME_LIST_CURRENT_INDEX_REG(DeviceRegisters), ®Value, &size);
|
|
|
|
dprintf("\n");
|
|
dprintf("Frame Number: %4x ", regValue);
|
|
|
|
//
|
|
// Get and display the frame list base address (FRBASEADD)
|
|
//
|
|
|
|
size = 4;
|
|
ReadIoSpace64(FRAME_LIST_BASE_REG(DeviceRegisters), ®Value, &size);
|
|
|
|
dprintf("Frame List Base Address: %8x\n", regValue);
|
|
|
|
//
|
|
// Get and display the SOF Modify register (SOFMOD)
|
|
//
|
|
|
|
size = 2;
|
|
ReadIoSpace64(SOF_MODIFY_REG(DeviceRegisters), ®Value, &size);
|
|
|
|
dprintf("\n");
|
|
dprintf("SOF Modify (%2x) --> Frame Length = %d\n",
|
|
regValue,
|
|
regValue + UHCD_12MHZ_SOF);
|
|
|
|
//
|
|
// Get and display the port status register for port 1
|
|
//
|
|
|
|
ReadIoSpace64(PORT1_REG(DeviceRegisters), ®Value, &size);
|
|
|
|
UhciPortRegister(1, regValue);
|
|
|
|
//
|
|
// Get and display the port status register for port 2
|
|
//
|
|
|
|
ReadIoSpace64( PORT2_REG(DeviceRegisters), ®Value, &size);
|
|
|
|
UhciPortRegister(2, regValue);
|
|
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
UhciPortRegister(
|
|
ULONG PortNumber,
|
|
ULONG Value
|
|
)
|
|
{
|
|
dprintf("\n");
|
|
dprintf("Port %2d: Device Connected: %1x Connect Status Change: %1x\n"
|
|
" Port Enabled: %1x Port Enabled Changed: %1x\n"
|
|
" Line Status D+: %1x Line Status D- %1x\n"
|
|
" Resume Detect: %1x LS Device Attached: %1x\n"
|
|
" Suspended (%1x): ",
|
|
PortNumber,
|
|
Value & 0x01,
|
|
Value & 0x02,
|
|
Value & 0x04,
|
|
Value & 0x08,
|
|
Value & 0x10,
|
|
Value & 0x20,
|
|
Value & 0x40,
|
|
Value & 0x100,
|
|
Value & 0x400,
|
|
Value & 0x1800);
|
|
|
|
switch (Value & 0x1800)
|
|
{
|
|
case (0x00008000):
|
|
dprintf("Enabled");
|
|
break;
|
|
|
|
case (0x00018000):
|
|
dprintf("Suspend");
|
|
break;
|
|
|
|
default:
|
|
dprintf("Disabled");
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|