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.

426 lines
11 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. bushnd.c
  5. Abstract:
  6. KD Extension for BUS_HANDLER data structures.
  7. Author:
  8. Peter Johnston (peterj) 13-May-1998
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. //
  15. // The following typedef is copied directly from nthals\bushnd.c.
  16. //
  17. /*
  18. typedef struct _HAL_BUS_HANDLER {
  19. LIST_ENTRY AllHandlers;
  20. ULONG ReferenceCount;
  21. BUS_HANDLER Handler;
  22. } HAL_BUS_HANDLER, *PHAL_BUS_HANDLER;
  23. */
  24. BOOLEAN
  25. bushndReadMemory(
  26. ULONG64 S,
  27. PVOID D,
  28. ULONG Len
  29. )
  30. /*++
  31. Routine Description:
  32. Wrapper for ReadMemory that's somewhat easier to use. Also
  33. does a small amount of failsafe stuff, like failing the read
  34. if the user pressed control-C.
  35. Arguments:
  36. S Source Address in host memory to read data from.
  37. D Destination address in local memory.
  38. Len length in bytes.
  39. Return Value:
  40. Returns TRUE if the operation was successful, FALSE otherwise.
  41. --*/
  42. {
  43. ULONG result;
  44. //
  45. // Sanity: Only read kernel mode addresses. Kernel mode
  46. // addresses are always greater than 2GB. Being greater than
  47. // 2GB doesn't ensure it's kernel mode, but if it's less than
  48. // 2GB it is certainly NOT kernel mode.
  49. //
  50. if (S < 0x80000000) {
  51. dprintf("bushnd sanity: refusing to read usermode address %p\n", S);
  52. return FALSE;
  53. }
  54. if (!ReadMemory(S,
  55. D,
  56. Len,
  57. &result) && (result == Len)) {
  58. dprintf("Unable to read structure at %p. ", S);
  59. return FALSE;
  60. }
  61. if (CheckControlC()) {
  62. dprintf("Terminating operation at user request.\n");
  63. return FALSE;
  64. }
  65. return TRUE;
  66. }
  67. PUCHAR
  68. bushndInterfaceType(
  69. IN INTERFACE_TYPE InterfaceType
  70. )
  71. {
  72. switch (InterfaceType) {
  73. case InterfaceTypeUndefined: return "InterfaceTypeUndefined";
  74. case Internal: return "Internal";
  75. case Isa: return "Isa";
  76. case Eisa: return "Eisa";
  77. case MicroChannel: return "Micro Channel";
  78. case TurboChannel: return "Turbo Channel";
  79. case PCIBus: return "PCI";
  80. case VMEBus: return "VME";
  81. case NuBus: return "NuBus";
  82. case PCMCIABus: return "PCMCIA";
  83. case CBus: return "CBus";
  84. case MPIBus: return "MPIBus";
  85. case MPSABus: return "MPSABus";
  86. case ProcessorInternal: return "Processor Internal";
  87. case InternalPowerBus: return "Internal Power Bus";
  88. case PNPISABus: return "PnP Isa";
  89. case PNPBus: return "PnP Bus";
  90. default: return "** Unknown Interface Type **";
  91. }
  92. }
  93. VOID
  94. bushndDisplayAddressRange(
  95. IN ULONG64 HostAddress,
  96. IN PUCHAR String
  97. )
  98. /*++
  99. Routine Description:
  100. Display a set of ranges. Used by bushndDisplayBusRanges.
  101. (Pretty much just lifted this code from nthals/rangesup.c).
  102. Arguments:
  103. Pointer to a PSUPPORTED_RANGE structure. This is a linked
  104. list of the ranges of this type for this bus handler.
  105. Note: On entry we are pointing at a local copy of the first
  106. PSUPPORTED_RANGE of this type embedded in the BUS_HANDLER
  107. structure. We don't want to modify that so subsequent
  108. ranges are read into a seperate local structure.
  109. String. What sort of range this is (a heading).
  110. Return Value:
  111. None.
  112. --*/
  113. {
  114. ULONG64 Limit, Base, SystemBase, Next;
  115. do {
  116. InitTypeRead(HostAddress, SUPPORTED_RANGE);
  117. Limit = ReadField(Limit); Base = ReadField(Base);
  118. SystemBase = ReadField(SystemBase);
  119. if (Limit) {
  120. //
  121. // Address->Limit == 0 means skip this range,... otherwise,...
  122. //
  123. // Print this range.
  124. //
  125. dprintf(" %s: %x:%08x - %x:%08x (tran %x:%08x space %d (r@%p))\n",
  126. String,
  127. (ULONG)(Base >> 32),
  128. (ULONG)(Base),
  129. (ULONG)(Limit >> 32),
  130. (ULONG)(Limit),
  131. (ULONG)(SystemBase >> 32),
  132. (ULONG)(SystemBase),
  133. (ULONG)ReadField(SystemAddressSpace),
  134. HostAddress
  135. );
  136. String = " ";
  137. }
  138. //
  139. // Advance.
  140. //
  141. if (!(HostAddress = ReadField(Next))) {
  142. return;
  143. }
  144. if (GetFieldValue(HostAddress, "SUPPORTED_RANGE",
  145. "Next", Next)) {
  146. dprintf("Unable to follow range list.\n");
  147. return;
  148. }
  149. //
  150. // Quick saftey check,... make sure we don't follow a
  151. // self pointer,... would be good to do some more checking.
  152. //
  153. if (Next == HostAddress) {
  154. //
  155. // Self pointer.
  156. //
  157. dprintf("Ill-formed list, points to self at %p\n", HostAddress);
  158. return;
  159. }
  160. } while (TRUE);
  161. }
  162. VOID
  163. bushndDisplayBusRanges(
  164. IN ULONG64 BusAddresses
  165. )
  166. {
  167. ULONG Version, Offset;
  168. if (!BusAddresses) {
  169. dprintf(" No ranges associated with this bus.\n");
  170. return;
  171. }
  172. if (GetFieldValue(BusAddresses, "SUPPORTED_RANGES",
  173. "Version", Version)) {
  174. dprintf("Cannot dump ranges for this bus handler.\n");
  175. return;
  176. }
  177. GetFieldOffset("SUPPORTED_RANGES", "IO", &Offset);
  178. bushndDisplayAddressRange(BusAddresses + Offset,
  179. "IO......");
  180. GetFieldOffset("SUPPORTED_RANGES", "Memory", &Offset);
  181. bushndDisplayAddressRange(BusAddresses + Offset,
  182. "Memory..");
  183. GetFieldOffset("SUPPORTED_RANGES", "PrefetchMemory", &Offset);
  184. bushndDisplayAddressRange(BusAddresses + Offset,
  185. "PFMemory");
  186. GetFieldOffset("SUPPORTED_RANGES", "Dma", &Offset);
  187. bushndDisplayAddressRange(BusAddresses + Offset,
  188. "DMA.....");
  189. }
  190. VOID
  191. bushndDisplaySymbol(
  192. IN PUCHAR Name,
  193. IN ULONG64 Address
  194. )
  195. {
  196. UCHAR Symbol[256];
  197. ULONG64 Displacement;
  198. GetSymbol((LONG64)Address, Symbol, &Displacement);
  199. dprintf(" %s %08p (%s)\n", Name, Address, Symbol);
  200. }
  201. DECLARE_API( bushnd )
  202. /*++
  203. Routine Description:
  204. If no handler specified, dump the list of handlers and some simple
  205. info about each of them.
  206. If a handler is specified, dump everything we know about it.
  207. Arguments:
  208. Bus handler address [optional].
  209. Return Value:
  210. None.
  211. --*/
  212. {
  213. ULONG64 Handler;
  214. ULONG64 HostHandler;
  215. ULONG64 HalBusHandler;
  216. ULONG64 HandlerListHead;
  217. UCHAR SymbolBuffer[256];
  218. HostHandler = GetExpression(args);
  219. if (HostHandler) {
  220. ULONG Version, InitTypeRead, InterfaceType;
  221. ULONG64 DeviceObject, BusData;
  222. //
  223. // User supplied a handler address, dump details for that bus
  224. // handler.
  225. //
  226. if (GetFieldValue(HostHandler, "BUS_HANDLER",
  227. "Version", Version)) {
  228. dprintf("-- Cannot continue --\n");
  229. return E_INVALIDARG;
  230. }
  231. InitTypeRead(HostHandler, BUS_HANDLER);
  232. InterfaceType = (ULONG) ReadField(InterfaceType);
  233. dprintf("Dump of bus handler %p\n", HostHandler);
  234. dprintf(" Version %d\n", Version);
  235. dprintf(" Interface Type (%d) = %s\n",
  236. InterfaceType,
  237. bushndInterfaceType(InterfaceType));
  238. dprintf(" Bus Number %d\n", (ULONG) ReadField(BusNumber));
  239. if (DeviceObject = ReadField(DeviceObject)) {
  240. dprintf(" Device Object %p\n",
  241. DeviceObject);
  242. }
  243. dprintf(" Parent Bus Handler %p\n", ReadField(ParentHandler));
  244. if (BusData = ReadField(BusData)) {
  245. dprintf(" BusData %p\n", BusData);
  246. }
  247. bushndDisplaySymbol("GetBusData ", ReadField(GetBusData));
  248. bushndDisplaySymbol("SetBusData ", ReadField(SetBusData));
  249. bushndDisplaySymbol("AdjustResourceList ", ReadField(AdjustResourceList));
  250. bushndDisplaySymbol("AssignSlotResources", ReadField(AssignSlotResources));
  251. bushndDisplaySymbol("GetInterruptVector ", ReadField(GetInterruptVector));
  252. bushndDisplaySymbol("TranslateBusAddress", ReadField(TranslateBusAddress));
  253. bushndDisplayBusRanges(ReadField(BusAddresses));
  254. } else {
  255. ULONG Off;
  256. //
  257. // User did not supply a handler address, try to find the
  258. // list of all bus handlers and dump a summary of each handler.
  259. //
  260. HandlerListHead = GetExpression("hal!HalpAllBusHandlers");
  261. if (!HandlerListHead) {
  262. //
  263. // Couldn't get address of HalpAllBusHandlers. Whine
  264. // at user.
  265. //
  266. dprintf(
  267. "Unable to get address of HalpAllBusHandlers, most likely\n"
  268. "cause is failure to load HAL symbols, or, this HAL might\n"
  269. "not actually use bus handlers. "
  270. );
  271. dprintf("-- Cannot continue --");
  272. return E_INVALIDARG;
  273. }
  274. if (GetFieldValue(HandlerListHead, "LIST_ENTRY",
  275. "Flink", HalBusHandler)) {
  276. dprintf(
  277. "Could not read HalpAllBusHandlers from host memory (%p).\n"
  278. "This is most likely caused by incorrect HAL symbols.\n",
  279. HandlerListHead
  280. );
  281. dprintf("-- Cannot continue --\n");
  282. return E_INVALIDARG;
  283. }
  284. if (HalBusHandler == HandlerListHead) {
  285. dprintf(
  286. "HalpAllBusHandlers found (at %p) but list is empty.\n",
  287. HandlerListHead
  288. );
  289. dprintf("-- Cannot continue --\n");
  290. return E_INVALIDARG;
  291. }
  292. GetFieldOffset("hal!_HAL_BUS_HANDLER", "Handler", &Off);
  293. //
  294. // In theory, we now have the handler list. Walk it.
  295. //
  296. do {
  297. ULONG64 Next;
  298. ULONG BusNumber, InterfaceType;
  299. if (GetFieldValue(HalBusHandler, "hal!_HAL_BUS_HANDLER",
  300. "AllHandlers.Flink", Next)) {
  301. dprintf("-- Cannot continue --\n");
  302. return E_INVALIDARG;
  303. }
  304. //
  305. // Brief summary.
  306. //
  307. Handler = HalBusHandler + Off;
  308. GetFieldValue(HalBusHandler, "hal!_HAL_BUS_HANDLER", "BusNumber", BusNumber);
  309. GetFieldValue(HalBusHandler, "hal!_HAL_BUS_HANDLER", "Handler.InterfaceType", InterfaceType);
  310. dprintf(
  311. "%p bus %d, type %s\n",
  312. Handler,
  313. BusNumber,
  314. bushndInterfaceType(InterfaceType)
  315. );
  316. //
  317. // Advance to next.
  318. //
  319. HalBusHandler = Next;
  320. } while (HalBusHandler != HandlerListHead);
  321. }
  322. return S_OK;
  323. }