Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

463 lines
14 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. UHCD.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Author:
  8. Kenneth D. Ray (kenray) June 1997
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. typedef union _USB_FLAGS {
  15. struct {
  16. ULONG FullListing : 1;
  17. ULONG Reserved : 31;
  18. };
  19. ULONG Flags;
  20. } USB_FLAGS;
  21. #define PRINT_FLAGS(value, flag) \
  22. if ((value) & (flag)) { \
  23. dprintf (#flag " "); \
  24. }
  25. #define MAX_INTERVAL 32
  26. //
  27. // MACROS for USB controller registers
  28. //
  29. #define COMMAND_REG(DeviceRegisters) \
  30. (DeviceRegisters)
  31. #define STATUS_REG(DeviceRegisters) \
  32. ((DeviceRegisters + 0x02))
  33. #define INTERRUPT_MASK_REG(DeviceRegisters) \
  34. (DeviceRegisters + 0x04)
  35. #define FRAME_LIST_CURRENT_INDEX_REG(DeviceRegisters) \
  36. (DeviceRegisters + 0x06)
  37. #define FRAME_LIST_BASE_REG(DeviceRegisters) \
  38. (DeviceRegisters + 0x08)
  39. #define SOF_MODIFY_REG(DeviceRegisters) \
  40. (DeviceRegisters + 0x0C)
  41. #define PORT1_REG(DeviceRegisters) \
  42. (DeviceRegisters + 0x10)
  43. #define PORT2_REG(DeviceRegisters) \
  44. (DeviceRegisters + 0x12)
  45. VOID
  46. UhciPortRegister(
  47. ULONG PortNumber,
  48. ULONG Value
  49. );
  50. VOID
  51. DevExtUHCD(
  52. ULONG64 MemLocPtr
  53. )
  54. {
  55. ULONG64 MemLoc = MemLocPtr;
  56. ULONG HcFlags;
  57. ULONG i;
  58. dprintf ("Dump UHCD Extension: %p\n", MemLoc);
  59. if (InitTypeRead (MemLoc, uhcd!_USBD_EXTENSION)) {
  60. dprintf ("Could not read Usbd Extension\n");
  61. return;
  62. }
  63. if (0 != ReadField( TrueDeviceExtension)) {
  64. MemLoc = ReadField(TrueDeviceExtension);
  65. }
  66. if (InitTypeRead (MemLoc, uhcd!_DEVICE_EXTENSION)) {
  67. dprintf ("Could not read UHCD Extension\n");
  68. return;
  69. }
  70. dprintf("\n");
  71. dprintf("PhysicalDO: %8p TopOfStackDO: %8p InterruptObject: %8p\n"
  72. "FrameListVA: %8p FrameListLA: %8p ",
  73. ReadField(PhysicalDeviceObject),
  74. ReadField(TopOfStackDeviceObject),
  75. ReadField(InterruptObject),
  76. ReadField(FrameListVirtualAddress),
  77. ReadField(FrameListLogicalAddress));
  78. dprintf("FrameListCopyVA: %08p\n",
  79. ReadField(FrameListCopyVirtualAddress));
  80. dprintf("\n");
  81. /*
  82. dprintf("PersistantQH: %8x PQH_DescriptorList: %8x\n"
  83. "EndpointList & %x = (%x %x) \n"
  84. "EndpointLookAsideList & %x = (%x %x) \n"
  85. "ClosedEndpointList & %x = (%x %x) \n",
  86. (ULONG) ReadField(PersistantQueueHead),
  87. (ULONG) ReadField(PQH_DescriptorList),
  88. &((ULONG) ReadField(EndpointList)),
  89. (ULONG) ReadField(EndpointList.Flink),
  90. (ULONG) ReadField(EndpointList.Blink),
  91. &((ULONG) ReadField(EndpointLookAsideList)),
  92. (ULONG) ReadField(EndpointLookAsideList.Flink),
  93. (ULONG) ReadField(EndpointLookAsideList.Blink),
  94. &((ULONG) ReadField(ClosedEndpointList)),
  95. (ULONG) ReadField(ClosedEndpointList.Flink),
  96. (ULONG) ReadField(ClosedEndpointList.Blink));*/
  97. dprintf("PersistantQH: %8p PQH_DescriptorList: %8p\n"
  98. "EndpointList = (%p %p) \n"
  99. "EndpointLookAsideList = (%p %p) \n"
  100. "ClosedEndpointList = (%p %p) \n",
  101. ReadField(PersistantQueueHead),
  102. ReadField(PQH_DescriptorList),
  103. ReadField(EndpointList.Flink),
  104. ReadField(EndpointList.Blink),
  105. ReadField(EndpointLookAsideList.Flink),
  106. ReadField(EndpointLookAsideList.Blink),
  107. ReadField(ClosedEndpointList.Flink),
  108. ReadField(ClosedEndpointList.Blink));
  109. dprintf("\n");
  110. dprintf("InterruptSchedule: ");
  111. for (i = 0; i < MAX_INTERVAL; i++)
  112. {
  113. UCHAR Sch[40];
  114. sprintf(Sch, "InterruptSchedule[%d]", i);
  115. dprintf("%8x ", (ULONG) GetShortField(0, Sch, 0));
  116. if (3 == i % 4)
  117. {
  118. dprintf("\n");
  119. dprintf(" ");
  120. }
  121. }
  122. dprintf("\n");
  123. // dprintf("PageList & %x = (%x %x) \n",
  124. // &( (ULONG) ReadField(PageList)),
  125. dprintf("PageList = (%x %x) \n",
  126. ReadField(PageList.Flink),
  127. ReadField(PageList.Blink));
  128. dprintf("\n");
  129. dprintf("BwTable: ");
  130. for (i = 0; i < MAX_INTERVAL; i++)
  131. {
  132. UCHAR Table[40];
  133. sprintf(Table, "BwTable[%d]", i);
  134. dprintf("%5d ", GetShortField(0, Table, 0));
  135. if (7 == i % 8)
  136. {
  137. dprintf("\n");
  138. dprintf(" ");
  139. }
  140. }
  141. dprintf("\n");
  142. dprintf("LastFrame: %8x FrameHighPart: %8x\n"
  143. "LastIdleTime.High: %8x LastIdleTime.Low %8x\n",
  144. "LastXferIdleTime.High: %8x LastXferIdleTime.Low %8x\n",
  145. "IdleTime: %8x XferIdleTime %8x\n",
  146. (ULONG) ReadField(LastFrame),
  147. (ULONG) ReadField(FrameHighPart),
  148. (ULONG) ReadField(LastIdleTime.HighPart),
  149. (ULONG) ReadField(LastIdleTime.LowPart),
  150. (ULONG) ReadField(LastXferIdleTime.HighPart),
  151. (ULONG) ReadField(LastXferIdleTime.LowPart),
  152. (ULONG) ReadField(IdleTime),
  153. (ULONG) ReadField(XferIdleTime));
  154. dprintf("\n");
  155. dprintf("TriggerList: %08p\n"
  156. "LargeBufferPool: %08p\n"
  157. "MediumBufferPool: %08p\n"
  158. "SmallBufferPool: %08p\n",
  159. ReadField(TriggerTDList),
  160. ReadField(LargeBufferPool),
  161. ReadField(MediumBufferPool),
  162. ReadField(SmallBufferPool));
  163. dprintf("\nRootHub Variables\n");
  164. dprintf("DeviceAddress: %3d RootHub: %8x\n"
  165. "TimersActive: %3d InterruptEndpoint: %8x\n",
  166. (ULONG) ReadField(RootHubDeviceAddress),
  167. (ULONG) ReadField(RootHub),
  168. (ULONG) ReadField(RootHubTimersActive),
  169. (ULONG) ReadField(RootHubInterruptEndpoint));
  170. dprintf("\n");
  171. dprintf("LastFrameProcessed: %x\n"
  172. "AdapterObject: %8x\n"
  173. "MapRegisters: %d\n"
  174. "DeviceNameHandle: %x\n"
  175. "FrameBabbleRecoverTD: %8x\n",
  176. (ULONG) ReadField(LastFrameProcessed),
  177. (ULONG) ReadField(AdapterObject),
  178. (ULONG) ReadField(NumberOfMapRegisters),
  179. (ULONG) ReadField(DeviceNameHandle),
  180. (ULONG) ReadField(FrameBabbleRecoverTD));
  181. dprintf("\nSaved Bios Info\n");
  182. dprintf("Cmd: %x IntMask: %x\n"
  183. "FrameListBase: %x LegacySuppReg: %x\n"
  184. "DeviceRegisters: %x SavedInterruptEnable: %x\n"
  185. "SavedCommandReg: %x\n",
  186. (ULONG) ReadField(BiosCmd),
  187. (ULONG) ReadField(BiosIntMask),
  188. (ULONG) ReadField(BiosFrameListBase),
  189. (ULONG) ReadField(LegacySupportRegister),
  190. (ULONG) ReadField(DeviceRegisters[0]),
  191. (ULONG) ReadField(SavedInterruptEnable),
  192. (ULONG) ReadField(SavedCommandReg));
  193. dprintf("\n");
  194. dprintf("PowerState: %x\n"
  195. "HcFlags %x: ",
  196. (ULONG) ReadField(CurrentDevicePowerState),
  197. HcFlags = (ULONG) ReadField(HcFlags));
  198. PRINT_FLAGS(HcFlags, HCFLAG_GOT_IO);
  199. PRINT_FLAGS(HcFlags, HCFLAG_UNMAP_REGISTERS);
  200. PRINT_FLAGS(HcFlags, HCFLAG_USBBIOS);
  201. PRINT_FLAGS(HcFlags, HCFLAG_BWRECLIMATION_ENABLED);
  202. PRINT_FLAGS(HcFlags, HCFLAG_NEED_CLEANUP);
  203. PRINT_FLAGS(HcFlags, HCFLAG_IDLE);
  204. PRINT_FLAGS(HcFlags, HCFLAG_ROLLOVER_IDLE);
  205. PRINT_FLAGS(HcFlags, HCFLAG_HCD_STOPPED);
  206. PRINT_FLAGS(HcFlags, HCFLAG_DISABLE_IDLE);
  207. PRINT_FLAGS(HcFlags, HCFLAG_WORK_ITEM_QUEUED);
  208. PRINT_FLAGS(HcFlags, HCFLAG_HCD_SHUTDOWN);
  209. PRINT_FLAGS(HcFlags, HCFLAG_LOST_POWER);
  210. PRINT_FLAGS(HcFlags, HCFLAG_RH_OFF);
  211. PRINT_FLAGS(HcFlags, HCFLAG_MAP_SX_TO_D3);
  212. dprintf("\n");
  213. dprintf("\n");
  214. dprintf("SavedFrameNumber: %8x SavedFRBaseAdd: %8x\n"
  215. "Port: %8x HcDma: %8x\n"
  216. "RegRecClocksPerFrame: %8x Piix4EP %8x\n"
  217. "EndpointListBusy: %8d SteppingVer: %8x\n"
  218. "SavedSOFModify: %8x ControllerType: %8x\n",
  219. (ULONG) ReadField(SavedFRNUM),
  220. (ULONG) ReadField(SavedFRBASEADD),
  221. (ULONG) ReadField(Port),
  222. (ULONG) ReadField(HcDma),
  223. (ULONG) ReadField(RegRecClocksPerFrame),
  224. (ULONG) ReadField(Piix4EP),
  225. (ULONG) ReadField(EndpointListBusy),
  226. (ULONG) ReadField(SteppingVersion),
  227. (ULONG) ReadField(SavedSofModify),
  228. (ULONG) ReadField(ControllerType));
  229. return;
  230. }
  231. VOID
  232. UHCD_HCRegisters(
  233. ULONG64 MemLoc
  234. )
  235. {
  236. ULONG64 hcObject;
  237. ULONG64 devExtAddr;
  238. ULONG result;
  239. ULONG64 DeviceRegisters;
  240. ULONG regValue;
  241. ULONG size;
  242. ULONG64 TrueDeviceExtension;
  243. //
  244. // In this case, MemLoc points the the device object for the given
  245. // host controller.
  246. //
  247. hcObject = MemLoc;
  248. //
  249. // Get the address of the device extension
  250. //
  251. GetFieldValue(MemLoc, "uhcd!_DEVICE_OBJECT", "DeviceExtension", devExtAddr);
  252. //
  253. // Read the USBD extension
  254. //
  255. if (GetFieldValue(devExtAddr, "uhcd!_USBD_EXTENSION", "TrueDeviceExtension", TrueDeviceExtension)) {
  256. dprintf ("Could not read Usbd Extension\n");
  257. return;
  258. }
  259. if (0 != TrueDeviceExtension) {
  260. devExtAddr = TrueDeviceExtension;
  261. }
  262. if (GetFieldValue(devExtAddr, "uhcd!_DEVICE_EXTENSION", "DeviceRegisters[0]", DeviceRegisters)) {
  263. dprintf ("Could not read UHCD Extension\n");
  264. return;
  265. }
  266. //
  267. // Get and display the command register (USBCMD)
  268. //
  269. size = 2;
  270. // ReadIoSpace((ULONG) COMMAND_REG((&uhcd)), &regValue, &size);
  271. ReadIoSpace64(COMMAND_REG(DeviceRegisters), &regValue, &size);
  272. dprintf("\n");
  273. dprintf("Command Register: Run/Stop: %x HC reset: %x Global reset: %x\n"
  274. " Global Suspend: %x Global Resume: %x SW Debug: %x\n"
  275. " Configure Flag: %x Max Packet: %x\n",
  276. regValue & UHCD_CMD_RUN,
  277. regValue & UHCD_CMD_RESET,
  278. regValue & UHCD_CMD_GLOBAL_RESET,
  279. regValue & UHCD_CMD_SUSPEND,
  280. regValue & UHCD_CMD_FORCE_RESUME,
  281. regValue & UHCD_CMD_SW_DEBUG,
  282. regValue & UHCD_CMD_SW_CONFIGURED,
  283. regValue & UHCD_CMD_MAXPKT_64);
  284. //
  285. // Get and display the status register (USBSTS)
  286. //
  287. ReadIoSpace64(STATUS_REG(DeviceRegisters), &regValue, &size);
  288. dprintf("\n");
  289. dprintf("Status Register: Transfer Int: %x Error Int: %x Resume Detect: %x\n",
  290. " Host Error: %x HC Error: %x HC Halted: %x\n",
  291. regValue & UHCD_STATUS_USBINT,
  292. regValue & UHCD_STATUS_USBERR,
  293. regValue & UHCD_STATUS_RESUME,
  294. regValue & UHCD_STATUS_PCIERR,
  295. regValue & UHCD_STATUS_HCERR,
  296. regValue & UHCD_STATUS_HCHALT);
  297. //
  298. // Get and display the interrupt enable register (USBINTR)
  299. //
  300. ReadIoSpace64(INTERRUPT_MASK_REG(DeviceRegisters), &regValue, &size);
  301. dprintf("\n");
  302. dprintf("Interrupt Register: ");
  303. PRINT_FLAGS(regValue, UHCD_INT_MASK_TIMEOUT);
  304. PRINT_FLAGS(regValue, UHCD_INT_MASK_RESUME);
  305. PRINT_FLAGS(regValue, UHCD_INT_MASK_IOC);
  306. PRINT_FLAGS(regValue, UHCD_INT_MASK_SHORT);
  307. dprintf("\n");
  308. //
  309. // Get and display the frame number (FRNUM)
  310. //
  311. ReadIoSpace64(FRAME_LIST_CURRENT_INDEX_REG(DeviceRegisters), &regValue, &size);
  312. dprintf("\n");
  313. dprintf("Frame Number: %4x ", regValue);
  314. //
  315. // Get and display the frame list base address (FRBASEADD)
  316. //
  317. size = 4;
  318. ReadIoSpace64(FRAME_LIST_BASE_REG(DeviceRegisters), &regValue, &size);
  319. dprintf("Frame List Base Address: %8x\n", regValue);
  320. //
  321. // Get and display the SOF Modify register (SOFMOD)
  322. //
  323. size = 2;
  324. ReadIoSpace64(SOF_MODIFY_REG(DeviceRegisters), &regValue, &size);
  325. dprintf("\n");
  326. dprintf("SOF Modify (%2x) --> Frame Length = %d\n",
  327. regValue,
  328. regValue + UHCD_12MHZ_SOF);
  329. //
  330. // Get and display the port status register for port 1
  331. //
  332. ReadIoSpace64(PORT1_REG(DeviceRegisters), &regValue, &size);
  333. UhciPortRegister(1, regValue);
  334. //
  335. // Get and display the port status register for port 2
  336. //
  337. ReadIoSpace64( PORT2_REG(DeviceRegisters), &regValue, &size);
  338. UhciPortRegister(2, regValue);
  339. return;
  340. }
  341. VOID
  342. UhciPortRegister(
  343. ULONG PortNumber,
  344. ULONG Value
  345. )
  346. {
  347. dprintf("\n");
  348. dprintf("Port %2d: Device Connected: %1x Connect Status Change: %1x\n"
  349. " Port Enabled: %1x Port Enabled Changed: %1x\n"
  350. " Line Status D+: %1x Line Status D- %1x\n"
  351. " Resume Detect: %1x LS Device Attached: %1x\n"
  352. " Suspended (%1x): ",
  353. PortNumber,
  354. Value & 0x01,
  355. Value & 0x02,
  356. Value & 0x04,
  357. Value & 0x08,
  358. Value & 0x10,
  359. Value & 0x20,
  360. Value & 0x40,
  361. Value & 0x100,
  362. Value & 0x400,
  363. Value & 0x1800);
  364. switch (Value & 0x1800)
  365. {
  366. case (0x00008000):
  367. dprintf("Enabled");
  368. break;
  369. case (0x00018000):
  370. dprintf("Suspend");
  371. break;
  372. default:
  373. dprintf("Disabled");
  374. break;
  375. }
  376. return;
  377. }