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.

1316 lines
31 KiB

  1. // This is a 64 bit aware debugger extension
  2. #define KDEXT_64BIT
  3. #include <windows.h>
  4. #include <wdbgexts.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include "e100_equ.h"
  9. #include "e100_557.h"
  10. #include "mp_cmn.h"
  11. #include "e100kd.h"
  12. WINDBG_EXTENSION_APIS ExtensionApis;
  13. EXT_API_VERSION ApiVersion = { 5, 0, EXT_API_VERSION_NUMBER64, 0};
  14. USHORT SavedMajorVersion;
  15. USHORT SavedMinorVersion;
  16. BOOL ChkTarget; // is debuggee a CHK build?
  17. typedef struct
  18. {
  19. char Name[16];
  20. unsigned int Val;
  21. } DBG_LEVEL;
  22. DBG_LEVEL DbgLevel[] = {
  23. {"ERROR", MP_ERROR},
  24. {"WARN", MP_WARN},
  25. {"TRACE", MP_TRACE},
  26. {"INFO", MP_INFO},
  27. {"LOUD", MP_LOUD}
  28. };
  29. typedef struct
  30. {
  31. char Name[32];
  32. unsigned int Val;
  33. } DBG_ADAPTER_FLAGS, DBG_FILTER;
  34. DBG_ADAPTER_FLAGS DbgAdapterFlags[] = {
  35. {"SCATTER_GATHER", fMP_ADAPTER_SCATTER_GATHER},
  36. {"MAP_REGISTER", fMP_ADAPTER_MAP_REGISTER},
  37. {"RECV_LOOKASIDE", fMP_ADAPTER_RECV_LOOKASIDE},
  38. {"INTERRUPT_IN_USE", fMP_ADAPTER_INTERRUPT_IN_USE},
  39. {"RESET_IN_PROGRESS", fMP_ADAPTER_RESET_IN_PROGRESS},
  40. {"NO_CABLE", fMP_ADAPTER_NO_CABLE},
  41. {"HARDWARE_ERROR", fMP_ADAPTER_HARDWARE_ERROR}
  42. };
  43. //
  44. // Ndis Packet Filter Bits (OID_GEN_CURRENT_PACKET_FILTER).
  45. //
  46. #define NDIS_PACKET_TYPE_DIRECTED 0x00000001
  47. #define NDIS_PACKET_TYPE_MULTICAST 0x00000002
  48. #define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004
  49. #define NDIS_PACKET_TYPE_BROADCAST 0x00000008
  50. #define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010
  51. #define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020
  52. #define NDIS_PACKET_TYPE_SMT 0x00000040
  53. #define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080
  54. #define NDIS_PACKET_TYPE_GROUP 0x00001000
  55. #define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00002000
  56. #define NDIS_PACKET_TYPE_FUNCTIONAL 0x00004000
  57. #define NDIS_PACKET_TYPE_MAC_FRAME 0x00008000
  58. DBG_FILTER DbgFilterTable[] = {
  59. {"DIRECTED", NDIS_PACKET_TYPE_DIRECTED},
  60. {"MULTICAST", NDIS_PACKET_TYPE_MULTICAST},
  61. {"ALL_MULTICAST", NDIS_PACKET_TYPE_ALL_MULTICAST},
  62. {"BROADCAST", NDIS_PACKET_TYPE_BROADCAST},
  63. {"SOURCE_ROUTING", NDIS_PACKET_TYPE_SOURCE_ROUTING},
  64. {"PROMISCUOUS", NDIS_PACKET_TYPE_PROMISCUOUS},
  65. {"SMT", NDIS_PACKET_TYPE_SMT},
  66. {"ALL_LOCAL", NDIS_PACKET_TYPE_ALL_LOCAL},
  67. {"GROUP", NDIS_PACKET_TYPE_GROUP},
  68. {"ALL_FUNCTIONAL", NDIS_PACKET_TYPE_ALL_FUNCTIONAL},
  69. {"FUNCTIONAL", NDIS_PACKET_TYPE_FUNCTIONAL},
  70. {"MAC_FRAME", NDIS_PACKET_TYPE_MAC_FRAME}
  71. };
  72. typedef struct
  73. {
  74. char Name[32];
  75. USHORT Val;
  76. } DBG_RFD_STATUS, DBG_RFD_COMMAND, DBG_USHORT_BITS, DBG_USHORT_VALUE;
  77. typedef struct
  78. {
  79. char Name[32];
  80. UCHAR Val;
  81. } DBG_UCHAR_BITS, DBG_UCHAR_VALUE;
  82. DBG_RFD_STATUS DbgRfdStatus[] = {
  83. {"COMPLETE", RFD_STATUS_COMPLETE},
  84. {"OK", RFD_STATUS_OK},
  85. {"CRC_ERROR", RFD_CRC_ERROR},
  86. {"ALIGNMENT_ERROR", RFD_ALIGNMENT_ERROR},
  87. {"NO_RESOURCES", RFD_NO_RESOURCES},
  88. {"DMA_OVERRUN", RFD_DMA_OVERRUN},
  89. {"FRAME_TOO_SHORT", RFD_FRAME_TOO_SHORT},
  90. {"RX_ERR", RFD_RX_ERR},
  91. {"IA_MATCH", RFD_IA_MATCH},
  92. {"RECEIVE_COLLISION", RFD_RECEIVE_COLLISION},
  93. };
  94. DBG_RFD_COMMAND DbgRfdCommand[] = {
  95. {"EL", RFD_EL_BIT},
  96. {"S", RFD_S_BIT},
  97. {"H", RFD_H_BIT},
  98. {"SF", RFD_SF_BIT}
  99. };
  100. DBG_USHORT_BITS DbgCbCommandBits[] = {
  101. {"EL", CB_EL_BIT},
  102. {"S", CB_S_BIT},
  103. {"I", CB_I_BIT},
  104. {"TX_SF", CB_TX_SF_BIT}
  105. };
  106. DBG_USHORT_VALUE DbgCbCommands[] = {
  107. {"CB_NOP", CB_NOP},
  108. {"CB_IA_ADDRESS", CB_IA_ADDRESS},
  109. {"CB_CONFIGURE", CB_CONFIGURE},
  110. {"CB_MULTICAST", CB_MULTICAST},
  111. {"CB_TRANSMIT", CB_TRANSMIT},
  112. {"CB_LOAD_MICROCODE", CB_LOAD_MICROCODE},
  113. {"CB_DUMP", CB_DUMP},
  114. {"CB_DIAGNOSE", CB_DIAGNOSE}
  115. };
  116. DBG_USHORT_VALUE DbgScbStatusRus[] = {
  117. {"IDLE", SCB_RUS_IDLE},
  118. {"SUSPEND", SCB_RUS_SUSPEND},
  119. {"NO_RESOURCES", SCB_RUS_NO_RESOURCES},
  120. {"READY", SCB_RUS_READY},
  121. {"SUSP_NO_RBDS", SCB_RUS_SUSP_NO_RBDS},
  122. {"NO_RBDS", SCB_RUS_NO_RBDS},
  123. {"READY_NO_RBDS", SCB_RUS_READY_NO_RBDS},
  124. };
  125. DBG_USHORT_BITS DbgScbStatusBits[] = {
  126. {"CX", SCB_STATUS_CX},
  127. {"FR", SCB_STATUS_FR},
  128. {"CNA", SCB_STATUS_CNA},
  129. {"RNR", SCB_STATUS_RNR},
  130. {"MDI", SCB_STATUS_MDI},
  131. {"SWI", SCB_STATUS_SWI}
  132. };
  133. DBG_UCHAR_VALUE DbgScbCommandCuc[] = {
  134. {"START", SCB_CUC_START},
  135. {"RESUME", SCB_CUC_RESUME},
  136. {"DUMP_ADDR", SCB_CUC_DUMP_ADDR},
  137. {"DUMP_STAT", SCB_CUC_DUMP_STAT},
  138. {"LOAD_BASE", SCB_CUC_LOAD_BASE},
  139. {"DUMP_RST_STAT", SCB_CUC_DUMP_RST_STAT},
  140. {"STATIC_RESUME", SCB_CUC_STATIC_RESUME}
  141. };
  142. DBG_UCHAR_VALUE DbgScbCommandRuc[] = {
  143. {"START", SCB_RUC_START},
  144. {"RESUME", SCB_RUC_RESUME},
  145. {"ABORT", SCB_RUC_ABORT},
  146. {"LOAD_HDS", SCB_RUC_LOAD_HDS},
  147. {"LOAD_BASE", SCB_RUC_LOAD_BASE},
  148. {"RBD_RESUME", SCB_RUC_RBD_RESUME}
  149. };
  150. VOID WinDbgExtensionDllInit(
  151. PWINDBG_EXTENSION_APIS64 lpExtensionApis,
  152. USHORT MajorVersion,
  153. USHORT MinorVersion
  154. )
  155. {
  156. ExtensionApis = *lpExtensionApis;
  157. SavedMajorVersion = MajorVersion;
  158. SavedMinorVersion = MinorVersion;
  159. ChkTarget = SavedMajorVersion == 0x0c ? TRUE : FALSE;
  160. }
  161. LPEXT_API_VERSION ExtensionApiVersion(VOID)
  162. {
  163. return &ApiVersion;
  164. }
  165. VOID CheckVersion(VOID)
  166. {
  167. //
  168. // for now don't bother to version check
  169. //
  170. return;
  171. }
  172. DECLARE_API( help )
  173. {
  174. int i;
  175. dprintf("E100 extensions:\n");
  176. dprintf(" dbglevel dump debug level\n");
  177. dprintf(" mpadapter <MP_ADAPTER> <verbosity>> dump MP_ADAPTER block\n");
  178. dprintf(" csr <CSRAddress> dump CSR block\n");
  179. dprintf(" sendlist <CurrSendHead> <verbosity> dump send list\n");
  180. dprintf(" mptcb <MP_TCB> dump MP_TCB block\n");
  181. dprintf(" hwtcb <HW_TCB> dump HW_TCB block\n");
  182. dprintf(" sendqueue <SendWaitQueue> dump queued send packets\n");
  183. dprintf(" recvlist <RecvList> <verbosity> dump receive list\n");
  184. dprintf(" mprfd <MP_RFD> dump MP_RFD block\n");
  185. dprintf(" hwrfd <HW_RFD> dump HW_RFD block\n");
  186. dprintf(" recvpendlist <RecvPendList> dump pending indicated rx packets\n");
  187. }
  188. DECLARE_API(dbglevel)
  189. {
  190. ULONG64 debugLevelPtr;
  191. ULONG debugLevel, NewLevel;
  192. ULONG64 Val;
  193. int i;
  194. ULONG Bytes;
  195. debugLevelPtr = GetExpression("e100bnt5!MPDebugLevel");
  196. if(debugLevelPtr == 0)
  197. {
  198. dprintf("Error retrieving address of MPDebugLevel\n");
  199. dprintf("Target is %s\n", ChkTarget ? "Checked" : "Free");
  200. }
  201. dprintf("MPDebugLevel @ %p\n", debugLevelPtr);
  202. debugLevel = GetUlongFromAddress(debugLevelPtr);
  203. dprintf("Current MPDebugLevel = %d", debugLevel);
  204. for(i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++)
  205. {
  206. if(debugLevel == DbgLevel[i].Val)
  207. {
  208. dprintf(" - %s", DbgLevel[i].Name);
  209. break;
  210. }
  211. }
  212. dprintf("\n");
  213. dprintf("Available settings: ");
  214. for(i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++)
  215. {
  216. if(debugLevel != DbgLevel[i].Val)
  217. {
  218. dprintf("%d-%s ", DbgLevel[i].Val, DbgLevel[i].Name);
  219. }
  220. }
  221. dprintf("\n");
  222. if(!*args)
  223. {
  224. return;
  225. }
  226. i = sscanf(args, "%lx", &NewLevel);
  227. if(i == 1)
  228. {
  229. for(i = 0; i < sizeof(DbgLevel)/sizeof(DBG_LEVEL); i++)
  230. {
  231. if(NewLevel == DbgLevel[i].Val)
  232. {
  233. if(NewLevel != debugLevel)
  234. {
  235. dprintf("New MPDebugLevel = %d\n", NewLevel);
  236. WriteMemory(debugLevelPtr, &NewLevel, sizeof(ULONG), &Bytes);
  237. }
  238. break;
  239. }
  240. }
  241. }
  242. }
  243. DECLARE_API(version)
  244. {
  245. #if DBG
  246. PCSTR kind = "Checked";
  247. #else
  248. PCSTR kind = "Free";
  249. #endif
  250. dprintf("%s E100 Extension dll on a %s system\n",
  251. kind, ChkTarget? "Checked" : "Free");
  252. }
  253. #define MAX_FLAGS_PER_LINE 4
  254. #define MAC_ADDRESS_LENGTH 6
  255. DECLARE_API(mpadapter)
  256. {
  257. ULONG64 pAdapter;
  258. int ArgCount = 0;
  259. ULONG i, j;
  260. ULONG Flags;
  261. ULONG PacketFilter;
  262. ULONG Off;
  263. UCHAR MacAddress[MAC_ADDRESS_LENGTH];
  264. UINT MCAddressCount;
  265. PUCHAR pBuffer;
  266. if(*args)
  267. {
  268. ArgCount = sscanf(args,"%I64lx",&pAdapter);
  269. }
  270. //check for arguments
  271. if(ArgCount < 1)
  272. {
  273. dprintf("Usage: mpadapter <pointer to MP_ADAPTER>\n");
  274. return ;
  275. }
  276. dprintf(" pAdapter %p : \n", pAdapter);
  277. InitTypeRead(pAdapter, MP_ADAPTER);
  278. dprintf(" AdapterHandle : %p\n", ReadField(AdapterHandle));
  279. Flags = (ULONG) ReadField(Flags);
  280. dprintf(" Flags : 0x%08x\n", Flags);
  281. j = 0;
  282. for(i = 0; i < sizeof(DbgAdapterFlags)/sizeof(DBG_ADAPTER_FLAGS); i++)
  283. {
  284. if(Flags & DbgAdapterFlags[i].Val)
  285. {
  286. if(j == 0)
  287. {
  288. dprintf(" ");
  289. }
  290. dprintf("%s", DbgAdapterFlags[i].Name);
  291. j++;
  292. if(j != MAX_FLAGS_PER_LINE)
  293. {
  294. dprintf(", ");
  295. }
  296. else
  297. {
  298. dprintf("\n");
  299. j = 0;
  300. }
  301. }
  302. }
  303. if(j != 0)
  304. {
  305. dprintf("\n");
  306. }
  307. if(!GetFieldOffset("MP_ADAPTER", "PermanentAddress", &Off))
  308. {
  309. if(GetData(MacAddress, pAdapter+Off, MAC_ADDRESS_LENGTH, "PermanentAddress[]"))
  310. {
  311. dprintf(" Permanent address : %02x-%02x-%02x-%02x-%02x-%02x\n",
  312. MacAddress[0], MacAddress[1],
  313. MacAddress[2], MacAddress[3],
  314. MacAddress[4], MacAddress[5]);
  315. }
  316. }
  317. if((BOOLEAN) ReadField(OverrideAddress))
  318. {
  319. if(!GetFieldOffset("MP_ADAPTER", "CurrentAddress", &Off))
  320. {
  321. if(GetData(MacAddress, pAdapter+Off, MAC_ADDRESS_LENGTH, "CurrentAddress[]"))
  322. {
  323. dprintf(" Current address : %02x-%02x-%02x-%02x-%02x-%02x\n",
  324. MacAddress[0], MacAddress[1],
  325. MacAddress[2], MacAddress[3],
  326. MacAddress[4], MacAddress[5]);
  327. }
  328. }
  329. }
  330. else
  331. {
  332. dprintf(" Current address : same as above\n");
  333. }
  334. dprintf("\n");
  335. dprintf(" --- SEND ---\n");
  336. dprintf(" CurrSendHead = %p , CurrSendTail = %p , nBusySend = %d\n",
  337. ReadField(CurrSendHead), ReadField(CurrSendTail), (LONG)ReadField(nBusySend));
  338. dprintf(" SendWaitQueue Head = %p, Tail = %p\n",
  339. ReadField(SendWaitQueue.Head), ReadField(SendWaitQueue.Tail));
  340. dprintf(" NumTcb = %d, RegNumTcb = %d, NumBuffers = %d\n",
  341. (LONG)ReadField(NumTcb), (LONG)ReadField(RegNumTcb), (LONG)ReadField(NumBuffers));
  342. dprintf(" MpTcbMem = %p\n", ReadField(MpTcbMem));
  343. if(DBG_TEST_FLAG(Flags, fMP_ADAPTER_MAP_REGISTER))
  344. {
  345. dprintf(" CurrMapRegHead = %d, CurrMapRegTail = %d\n",
  346. (UINT)ReadField(CurrMapRegHead), (UINT)ReadField(CurrMapRegTail));
  347. }
  348. dprintf(" TransmitIdle = %s, ResumeWait = %s\n",
  349. (BOOLEAN)ReadField(TransmitIdle) ? "TRUE" : "FALSE",
  350. (BOOLEAN)ReadField(ResumeWait) ? "TRUE" : "FALSE");
  351. dprintf(" SendBufferPool = %p\n", ReadField(SendBufferPool));
  352. dprintf("\n");
  353. dprintf(" --- RECV ---\n");
  354. if(!GetFieldOffset("MP_ADAPTER", "RecvList", &Off))
  355. {
  356. dprintf(" RecvList @ %p , nReadyRecv = %d\n",
  357. pAdapter+Off, (LONG)ReadField(nReadyRecv));
  358. }
  359. if(!GetFieldOffset("MP_ADAPTER", "RecvPendList", &Off))
  360. {
  361. dprintf(" RecvPendList @ %p , RefCount = %d\n",
  362. pAdapter+Off, (LONG)ReadField(RefCount));
  363. }
  364. dprintf(" NumRfd = %d, CurrNumRfd = %d , HwRfdSize = %d\n",
  365. (LONG)ReadField(NumRfd), (LONG)ReadField(CurrNumRfd), (LONG)ReadField(HwRfdSize));
  366. dprintf(" bAllocNewRfd = %s, RfdShrinkCount = %d\n",
  367. (BOOLEAN)ReadField(bAllocNewRfd) ? "TRUE" : "FALSE",
  368. (LONG)ReadField(RfdShrinkCount));
  369. dprintf(" RecvPacketPool = %p , RecvBufferPool = %p\n",
  370. ReadField(RecvPacketPool), ReadField(RecvBufferPool));
  371. dprintf("\n");
  372. PacketFilter = (ULONG)ReadField(PacketFilter);
  373. dprintf(" PacketFilter : 0x%08x\n", PacketFilter);
  374. j = 0;
  375. for(i = 0; i < sizeof(DbgFilterTable)/sizeof(DBG_FILTER); i++)
  376. {
  377. if(PacketFilter & DbgFilterTable[i].Val)
  378. {
  379. if(j == 0)
  380. {
  381. dprintf(" ");
  382. }
  383. dprintf("%s", DbgFilterTable[i].Name);
  384. j++;
  385. if(j != MAX_FLAGS_PER_LINE)
  386. {
  387. dprintf(", ");
  388. }
  389. else
  390. {
  391. dprintf("\n");
  392. j = 0;
  393. }
  394. }
  395. }
  396. if(j != 0)
  397. {
  398. dprintf("\n");
  399. }
  400. dprintf(" ulLookAhead=%d, usLinkSpeed=%d, usDuplexMode=%d\n",
  401. (ULONG)ReadField(ulLookAhead), (USHORT)ReadField(usLinkSpeed),
  402. (USHORT)ReadField(usDuplexMode));
  403. dprintf("\n");
  404. MCAddressCount = (UINT)ReadField(MCAddressCount);
  405. dprintf(" MCAddressCount = %d\n", MCAddressCount);
  406. pBuffer = malloc(MCAddressCount * MAC_ADDRESS_LENGTH);
  407. if(pBuffer)
  408. {
  409. if(!GetFieldOffset("MP_ADAPTER", "MCList", &Off))
  410. {
  411. if(GetData(pBuffer, pAdapter+Off, MCAddressCount * MAC_ADDRESS_LENGTH, "MCList[]"))
  412. {
  413. for(i=0; i<MCAddressCount; i++)
  414. {
  415. j = i * MAC_ADDRESS_LENGTH;
  416. dprintf(" (%d) = %02x-%02x-%02x-%02x-%02x-%02x\n",
  417. i, pBuffer[j], pBuffer[j+1], pBuffer[j+2],
  418. pBuffer[j+3], pBuffer[j+4], pBuffer[j+5]);
  419. }
  420. }
  421. }
  422. free(pBuffer);
  423. }
  424. else
  425. {
  426. }
  427. dprintf("\n");
  428. dprintf(" IoBaseAddress = 0x%x, IoRange = 0x%x, InterrupLevel = 0x%x, MemPhysAddress = 0x%x\n",
  429. (ULONG)ReadField(IoBaseAddress), (ULONG)ReadField(IoRange),
  430. (ULONG)ReadField(InterruptLevel), (ULONG)ReadField(MemPhysAddress.LowPart));
  431. dprintf(" PortOffset = %p , CSRAddress = %p\n",
  432. ReadField(PortOffset), ReadField(CSRAddress));
  433. dprintf(" RevsionID = %d, SubVendorID = 0x%02x, SubSystemID = 0x%02x\n",
  434. (UCHAR)ReadField(RevsionID), (USHORT)ReadField(SubVendorID),
  435. (USHORT)ReadField(SubSystemID));
  436. }
  437. DECLARE_API(csr)
  438. {
  439. ULONG64 pHwCsr;
  440. int ArgCount = 0;
  441. UCHAR ucVal;
  442. USHORT usVal;
  443. ULONG i;
  444. if(*args)
  445. {
  446. ArgCount = sscanf(args,"%I64lx", &pHwCsr);
  447. }
  448. //check for arguments
  449. if(ArgCount < 1)
  450. {
  451. dprintf("Usage: csr <CSRAddress>\n");
  452. return ;
  453. }
  454. dprintf(" pHwCsr %x : \n", pHwCsr);
  455. InitTypeRead(pHwCsr, HW_CSR);
  456. // ScbStatus
  457. usVal = (USHORT)ReadField(ScbStatus);
  458. dprintf(" ScbStatus - 0x%04x ", usVal);
  459. dprintf("CUS-");
  460. switch(usVal & SCB_CUS_MASK)
  461. {
  462. case SCB_CUS_IDLE:
  463. dprintf("IDLE ");
  464. break;
  465. case SCB_CUS_SUSPEND:
  466. dprintf("SUSPEND ");
  467. break;
  468. case SCB_CUS_ACTIVE:
  469. dprintf("ACTIVE ");
  470. break;
  471. default:
  472. dprintf("Reserved ");
  473. }
  474. for(i = 0; i < sizeof(DbgScbStatusRus)/sizeof(DBG_USHORT_VALUE); i++)
  475. {
  476. if((usVal & SCB_RUS_MASK) == DbgScbStatusRus[i].Val)
  477. {
  478. dprintf("RUS-%s ", DbgScbStatusRus[i].Name);
  479. break;
  480. }
  481. }
  482. dprintf("STAT-");
  483. for(i = 0; i < sizeof(DbgScbStatusBits)/sizeof(DBG_USHORT_BITS); i++)
  484. {
  485. if(usVal & DbgScbStatusBits[i].Val)
  486. {
  487. dprintf("%s ", DbgScbStatusBits[i].Name);
  488. }
  489. }
  490. dprintf("\n");
  491. //ScbCommandLow
  492. ucVal = (UCHAR)ReadField(ScbCommandLow);
  493. dprintf(" ScbCommandLow - 0x%02x ", ucVal);
  494. for(i = 0; i < sizeof(DbgScbCommandCuc)/sizeof(DBG_UCHAR_VALUE); i++)
  495. {
  496. if((ucVal & SCB_CUC_MASK) == DbgScbCommandCuc[i].Val)
  497. {
  498. dprintf("CUC-%s ", DbgScbCommandCuc[i].Name);
  499. break;
  500. }
  501. }
  502. for(i = 0; i < sizeof(DbgScbCommandRuc)/sizeof(DBG_UCHAR_VALUE); i++)
  503. {
  504. if((ucVal & SCB_RUC_MASK) == DbgScbCommandRuc[i].Val)
  505. {
  506. dprintf("RUC-%s ", DbgScbCommandRuc[i].Name);
  507. break;
  508. }
  509. }
  510. //ScbCommandHigh
  511. ucVal = (UCHAR)ReadField(ScbCommandHigh);
  512. dprintf(" ScbCommandHigh - 0x%02x ", ucVal);
  513. if(ucVal & SCB_INT_MASK)
  514. {
  515. dprintf("INT_MASK ");
  516. }
  517. if(ucVal & SCB_SOFT_INT)
  518. {
  519. dprintf("SOFT_INT ");
  520. }
  521. dprintf("\n");
  522. }
  523. DECLARE_API(sendlist)
  524. {
  525. ULONG64 pMpTcb;
  526. ULONG64 pFirstMpTcb;
  527. int ArgCount = 0;
  528. int Verbosity = 0;
  529. int index = 0;
  530. if(*args)
  531. {
  532. ArgCount = sscanf(args,"%I64lx %lx", &pMpTcb, &Verbosity);
  533. }
  534. //check for arguments
  535. if(ArgCount < 1 || Verbosity > 1)
  536. {
  537. dprintf("Usage: sendlist <CurrSendHead> <verbosity>\n");
  538. dprintf("1-Show HW_TCB info\n");
  539. return ;
  540. }
  541. SIGN_EXTEND(pMpTcb);
  542. pFirstMpTcb = pMpTcb;
  543. do
  544. {
  545. dprintf(" (%d) pMpTcb %p : \n", index, pMpTcb);
  546. PrintMpTcbDetails(pMpTcb, Verbosity);
  547. if(GetFieldValue(pMpTcb, "MP_TCB", "Next", pMpTcb))
  548. {
  549. break;
  550. }
  551. index++;
  552. if(CheckControlC())
  553. {
  554. dprintf("***Control-C***\n");
  555. break;
  556. }
  557. } while(pMpTcb != pFirstMpTcb);
  558. }
  559. DECLARE_API(mptcb)
  560. {
  561. ULONG64 pMpTcb;
  562. int ArgCount = 0;
  563. if(*args)
  564. {
  565. ArgCount = sscanf(args,"%I64lx", &pMpTcb);
  566. }
  567. //check for arguments
  568. if(ArgCount < 1)
  569. {
  570. dprintf("Usage: mptcb <MP_TCB>\n");
  571. return ;
  572. }
  573. dprintf(" pMpTcb %p : \n", pMpTcb);
  574. PrintMpTcbDetails(pMpTcb, 1);
  575. }
  576. DECLARE_API(hwtcb)
  577. {
  578. ULONG64 pHwTcb;
  579. int ArgCount = 0;
  580. if(*args)
  581. {
  582. ArgCount = sscanf(args,"%I64lx", &pHwTcb);
  583. }
  584. //check for arguments
  585. if(ArgCount < 1)
  586. {
  587. dprintf("Usage: hwtcb <HW_TCB>\n");
  588. return ;
  589. }
  590. dprintf(" pHwTcb %p : \n", pHwTcb);
  591. PrintHwTcbDetails(pHwTcb);
  592. }
  593. void PrintMpTcbDetails(ULONG64 pMpTcb, int Verbosity)
  594. {
  595. ULONG Flags;
  596. ULONG64 pMpTxBuf;
  597. ULONG64 pHwTcb;
  598. ULONG64 pVal;
  599. ULONG ulVal;
  600. USHORT usVal;
  601. InitTypeRead(pMpTcb, MP_TCB);
  602. dprintf(" Next %p", ReadField(Next));
  603. Flags = (ULONG) ReadField(Flags);
  604. dprintf(" , Flags - 0x%x", Flags);
  605. if(Flags & fMP_TCB_IN_USE)
  606. {
  607. dprintf(" IN_USE");
  608. }
  609. if(Flags & fMP_TCB_USE_LOCAL_BUF)
  610. {
  611. dprintf(" USE_LOCAL_BUF");
  612. }
  613. if(Flags & fMP_TCB_MULTICAST)
  614. {
  615. dprintf(" MULTICAST");
  616. }
  617. dprintf("\n");
  618. if(Flags & fMP_TCB_USE_LOCAL_BUF)
  619. {
  620. pMpTxBuf = ReadField(MpTxBuf);
  621. dprintf(" MpTxBuf = %p", pMpTxBuf);
  622. GetFieldValue(pMpTxBuf, "MP_TXBUF", "NdisBuffer", pVal);
  623. dprintf(" - NdisBuffer = %p", pVal);
  624. GetFieldValue(pMpTxBuf, "MP_TXBUF", "AllocSize", ulVal);
  625. dprintf(" , AllocSize = %d", ulVal);
  626. GetFieldValue(pMpTxBuf, "MP_TXBUF", "AllocVa", pVal);
  627. dprintf(" , AllocVa = %p", pVal);
  628. GetFieldValue(pMpTxBuf, "MP_TXBUF", "pBuffer", pVal);
  629. dprintf(" , pBuffer = %p\n", pVal);
  630. dprintf("\n");
  631. }
  632. if(Flags & fMP_TCB_IN_USE)
  633. {
  634. dprintf(" Packet = %p\n", ReadField(Packet));
  635. pHwTcb = ReadField(HwTcb);
  636. dprintf(" HwTcb = %p , HwTcbPhys = 0x%lx , PrevHwTcb = 0x%x\n",
  637. pHwTcb, (ULONG)ReadField(HwTcbPhys), ReadField(PrevHwTcb));
  638. dprintf(" HwTbd (First) = %p , HwTbdPhys = 0x%x\n",
  639. ReadField(HwTbd), (ULONG)ReadField(HwTbdPhys));
  640. dprintf(" PhysBufCount = %d, BufferCount = %d, FirstBuffer = %p , PacketLength = %d\n",
  641. (ULONG)ReadField(PhysBufCount), (ULONG)ReadField(BufferCount),
  642. ReadField(FirstBuffer), (ULONG)ReadField(PacketLength));
  643. }
  644. dprintf("\n");
  645. if((Flags & fMP_TCB_IN_USE) && Verbosity == 1)
  646. {
  647. PrintHwTcbDetails(pHwTcb);
  648. }
  649. }
  650. void PrintHwTcbDetails(ULONG64 pHwTcb)
  651. {
  652. USHORT HwCbStatus;
  653. USHORT HwCbCommand;
  654. ULONG i;
  655. InitTypeRead(pHwTcb, HW_TCB);
  656. HwCbStatus = (USHORT) ReadField(TxCbHeader.CbStatus);
  657. HwCbCommand = (USHORT) ReadField(TxCbHeader.CbCommand);
  658. dprintf(" TxCbHeader.CbStatus = 0x%04x ,", HwCbStatus);
  659. if(HwCbStatus & CB_STATUS_COMPLETE)
  660. {
  661. dprintf(" COMPLETE");
  662. }
  663. if(HwCbStatus & CB_STATUS_OK)
  664. {
  665. dprintf(" OK");
  666. }
  667. if(HwCbStatus & CB_STATUS_UNDERRUN)
  668. {
  669. dprintf(" UNDERRUN");
  670. }
  671. dprintf("\n");
  672. dprintf(" TxCbHeader.CbCommand = 0x%04x ", HwCbCommand);
  673. for(i = 0; i < sizeof(DbgCbCommandBits)/sizeof(DBG_USHORT_BITS); i++)
  674. {
  675. if(HwCbCommand & DbgCbCommandBits[i].Val)
  676. {
  677. dprintf(", %s", DbgCbCommandBits[i].Name);
  678. }
  679. }
  680. for(i = 0; i < sizeof(DbgCbCommands)/sizeof(DBG_USHORT_VALUE); i++)
  681. {
  682. if((HwCbCommand & CB_CMD_MASK) == DbgCbCommands[i].Val)
  683. {
  684. dprintf(", %s", DbgCbCommands[i].Name);
  685. break;
  686. }
  687. }
  688. if(i == sizeof(DbgCbCommands)/sizeof(DBG_USHORT_VALUE))
  689. {
  690. dprintf(", UNKNOWN COMMAND");
  691. }
  692. dprintf("\n");
  693. dprintf(" TxCbHeader.CbLinkPointer = 0x%x\n", (ULONG)ReadField(TxCbHeader.CbLinkPointer));
  694. if((HwCbCommand & CB_CMD_MASK) == CB_TRANSMIT)
  695. {
  696. dprintf(" TxCbTbdPointer = 0x%08x\n", (ULONG)ReadField(TxCbTbdPointer));
  697. dprintf(" TxCbCount = %d, ", (USHORT)ReadField(TxCbCount));
  698. dprintf("TxCbThreshold = %d, ", (UCHAR)ReadField(TxCbThreshold));
  699. dprintf("TxCbTbdNumber = %d\n", (UCHAR)ReadField(TxCbTbdNumber));
  700. }
  701. }
  702. DECLARE_API(sendqueue)
  703. {
  704. ULONG64 pEntry;
  705. ULONG64 pPacket;
  706. ULONG ulSize;
  707. int ArgCount = 0;
  708. int index = 0;
  709. if(*args)
  710. {
  711. ArgCount = sscanf(args,"%I64lx", &pEntry);
  712. }
  713. //check for arguments
  714. if(ArgCount < 1)
  715. {
  716. dprintf("Usage: sendqueue <SendWaitQueue address>\n");
  717. return ;
  718. }
  719. SIGN_EXTEND(pEntry);
  720. if(!(ulSize = GetTypeSize("NDIS_PACKET_PRIVATE")))
  721. {
  722. dprintf("Failed to get the type size of NDIS_PACKET_PRIVATE\n");
  723. return;
  724. }
  725. dprintf("NDIS_PACKET_PRIVATE size is 0x%x\n", ulSize);
  726. while(pEntry)
  727. {
  728. pPacket = pEntry - ulSize;
  729. if(pPacket > pEntry)
  730. {
  731. dprintf("Invalid pEntry %p\n", pEntry);
  732. break;
  733. }
  734. dprintf(" (%d) pEntry = %p, Pkt = %p\n", index, pEntry, pPacket);
  735. if(ReadPtr(pEntry, &pEntry))
  736. {
  737. break;
  738. }
  739. index++;
  740. if(CheckControlC())
  741. {
  742. dprintf("***Control-C***\n");
  743. break;
  744. }
  745. }
  746. }
  747. DECLARE_API(recvlist)
  748. {
  749. ULONG64 pListHead;
  750. ULONG64 pMpRfd;
  751. ULONG64 pHwRfd;
  752. int ArgCount = 0;
  753. int Verbosity = 0;
  754. int index = 0;
  755. if(*args)
  756. {
  757. ArgCount = sscanf(args,"%I64lx %lx", &pListHead, &Verbosity);
  758. }
  759. //check for arguments
  760. if(ArgCount < 1 || Verbosity > 1)
  761. {
  762. dprintf("Usage: recvlist <RecvList address> <verbosity>\n");
  763. dprintf("1-Show HW_RFD info\n");
  764. return ;
  765. }
  766. SIGN_EXTEND(pListHead);
  767. if(GetFieldValue(pListHead, "LIST_ENTRY", "Flink", pMpRfd))
  768. {
  769. dprintf("Failed to get LIST_ENTRY Flink at %p\n", pListHead);
  770. return;
  771. }
  772. while((pMpRfd != pListHead))
  773. {
  774. dprintf(" (%d) pMpRfd %p :\n", index, pMpRfd);
  775. PrintMpRfdDetails(pMpRfd, Verbosity);
  776. if(GetFieldValue(pMpRfd, "LIST_ENTRY", "Flink", pMpRfd))
  777. {
  778. dprintf("Failed to get LIST_ENTRY Flink at %p\n", pMpRfd);
  779. break;
  780. }
  781. index++;
  782. if(CheckControlC())
  783. {
  784. dprintf("***Control-C***\n");
  785. break;
  786. }
  787. }
  788. dprintf("RecvList has %d RFDs\n", index);
  789. }
  790. DECLARE_API(mprfd)
  791. {
  792. ULONG64 pMpRfd;
  793. int ArgCount = 0;
  794. if(*args)
  795. {
  796. ArgCount = sscanf(args,"%I64lx", &pMpRfd);
  797. }
  798. //check for arguments
  799. if(ArgCount < 1)
  800. {
  801. dprintf("Usage: mprfd <MP_RFD>\n");
  802. return ;
  803. }
  804. dprintf(" pMpRfd %p : \n", pMpRfd);
  805. PrintMpRfdDetails(pMpRfd, 1);
  806. }
  807. DECLARE_API(hwrfd)
  808. {
  809. ULONG64 pHwRfd;
  810. int ArgCount = 0;
  811. if(*args)
  812. {
  813. ArgCount = sscanf(args,"%I64lx", &pHwRfd);
  814. }
  815. //check for arguments
  816. if(ArgCount < 1)
  817. {
  818. dprintf("Usage: hwrfd <HW_RFD>\n");
  819. return ;
  820. }
  821. dprintf(" pHwRfd = %p : \n", pHwRfd);
  822. PrintHwRfdDetails(pHwRfd);
  823. }
  824. void PrintMpRfdDetails(ULONG64 pMpRfd, int Verbosity)
  825. {
  826. ULONG64 pHwRfd;
  827. ULONG Flags;
  828. InitTypeRead(pMpRfd, MP_RFD);
  829. dprintf(" Flink %p", ReadField(List.Flink));
  830. dprintf(" , Blink %p\n", ReadField(List.Blink));
  831. pHwRfd = ReadField(HwRfd);
  832. dprintf(" NdisPacket = %p , NdisBuffer = %p , HwRfd = %p\n",
  833. ReadField(NdisPacket), ReadField(NdisBuffer), pHwRfd);
  834. dprintf(" PacketSize = %d, ", (ULONG) ReadField(PacketSize));
  835. Flags = (ULONG) ReadField(Flags);
  836. dprintf("Flags 0x%x", Flags);
  837. if(Flags & fMP_RFD_RECV_PEND)
  838. {
  839. dprintf(" RECV_PEND ");
  840. }
  841. if(Flags & fMP_RFD_ALLOC_PEND)
  842. {
  843. dprintf(" ALLOC_PEND ");
  844. }
  845. if(Flags & fMP_RFD_RECV_READY)
  846. {
  847. dprintf(" RECV_READY ");
  848. }
  849. if(Flags & fMP_RFD_RESOURCES)
  850. {
  851. dprintf(" RESOURCES ");
  852. }
  853. dprintf("\n");
  854. if(Verbosity == 1)
  855. {
  856. PrintHwRfdDetails(pHwRfd);
  857. }
  858. }
  859. void PrintHwRfdDetails(ULONG64 pHwRfd)
  860. {
  861. USHORT RfdStatus;
  862. USHORT RfdCommand;
  863. ULONG i;
  864. InitTypeRead(pHwRfd, HW_RFD);
  865. RfdStatus = (USHORT) ReadField(RfdCbHeader.CbStatus);
  866. RfdCommand = (USHORT) ReadField(RfdCbHeader.CbCommand);
  867. dprintf(" RfdCbHeader.CbStatus = 0x%04x", RfdStatus);
  868. for(i = 0; i < sizeof(DbgRfdStatus)/sizeof(DBG_RFD_STATUS); i++)
  869. {
  870. if(RfdStatus & DbgRfdStatus[i].Val)
  871. {
  872. dprintf(", %s", DbgRfdStatus[i].Name);
  873. }
  874. }
  875. dprintf("\n");
  876. dprintf(" RfdCbHeader.CbCommand = %04x", RfdCommand);
  877. for(i = 0; i < sizeof(DbgRfdCommand)/sizeof(DBG_RFD_COMMAND); i++)
  878. {
  879. if(RfdCommand & DbgRfdCommand[i].Val)
  880. {
  881. dprintf(", %s", DbgRfdCommand[i].Name);
  882. }
  883. }
  884. dprintf("\n");
  885. dprintf(" RfdCbHeader.CbLinkPointer = 0x%x\n", (ULONG)ReadField(RfdCbHeader.CbLinkPointer));
  886. //dprintf(" RfdRbdPointer = 0x%x\n", (ULONG)ReadField(RfdRbdPointer));
  887. dprintf(" RfdActualCount = %x , %d", (USHORT)ReadField(RfdActualCount), (USHORT)ReadField(RfdActualCount) & 0x3fff);
  888. dprintf(", RfdSize = %d\n", (USHORT)ReadField(RfdSize));
  889. }
  890. DECLARE_API(recvpendlist)
  891. {
  892. ULONG64 pListHead;
  893. ULONG64 pMpRfd;
  894. ULONG64 pPacket;
  895. int ArgCount = 0;
  896. int index = 0;
  897. if(*args)
  898. {
  899. ArgCount = sscanf(args,"%I64lx", &pListHead);
  900. }
  901. //check for arguments
  902. if(ArgCount < 1)
  903. {
  904. dprintf("Usage: recvpendlist <RecvPendList address>\n");
  905. return ;
  906. }
  907. SIGN_EXTEND(pListHead);
  908. if(GetFieldValue(pListHead, "LIST_ENTRY", "Flink", pMpRfd))
  909. {
  910. dprintf("Failed to get LIST_ENTRY Flink at %p\n", pListHead);
  911. return;
  912. }
  913. while(pMpRfd != pListHead)
  914. {
  915. dprintf(" (%d) pMpRfd %x :\n", index, pMpRfd);
  916. PrintMpRfdDetails(pMpRfd, 0);
  917. if(GetFieldValue(pMpRfd, "LIST_ENTRY", "Flink", pMpRfd))
  918. {
  919. dprintf("Failed to get LIST_ENTRY Flink at %p\n", pMpRfd);
  920. break;
  921. }
  922. index++;
  923. if(CheckControlC())
  924. {
  925. dprintf("***Control-C***\n");
  926. break;
  927. }
  928. }
  929. dprintf("RecvPendList has %d RFDs\n", index);
  930. }
  931. /**
  932. Get 'size' bytes from the debuggee program at 'dwAddress' and place it
  933. in our address space at 'ptr'. Use 'type' in an error printout if necessary
  934. **/
  935. BOOL GetData( IN LPVOID ptr, IN ULONG64 AddressPtr, IN ULONG size, IN PCSTR type )
  936. {
  937. BOOL b;
  938. ULONG BytesRead;
  939. ULONG count = size;
  940. while(size > 0)
  941. {
  942. if(count >= 3000)
  943. count = 3000;
  944. b = ReadMemory(AddressPtr, ptr, count, &BytesRead );
  945. if(!b || BytesRead != count)
  946. {
  947. dprintf( "Unable to read %u bytes at %X, for %s\n", size, AddressPtr, type );
  948. return FALSE;
  949. }
  950. AddressPtr += count;
  951. size -= count;
  952. ptr = (LPVOID)((ULONG_PTR)ptr + count);
  953. }
  954. return TRUE;
  955. }
  956. /**
  957. Routine to get offset and size of a "Field" of "Type" on a debugee machine. This uses
  958. Ioctl call for type info.
  959. Returns 0 on success, Ioctl error value otherwise.
  960. **/
  961. ULONG GetFieldOffsetAndSize(
  962. IN LPSTR Type,
  963. IN LPSTR Field,
  964. OUT PULONG pOffset,
  965. OUT PULONG pSize)
  966. {
  967. FIELD_INFO flds = {
  968. Field, "", 0,
  969. DBG_DUMP_FIELD_FULL_NAME | DBG_DUMP_FIELD_RETURN_ADDRESS | DBG_DUMP_FIELD_SIZE_IN_BITS,
  970. 0, NULL};
  971. SYM_DUMP_PARAM Sym = {
  972. sizeof (SYM_DUMP_PARAM), Type, DBG_DUMP_NO_PRINT, 0,
  973. NULL, NULL, NULL, 1, &flds
  974. };
  975. ULONG Err, i=0;
  976. LPSTR dot, last=Field;
  977. Sym.nFields = 1;
  978. Err = Ioctl( IG_DUMP_SYMBOL_INFO, &Sym, Sym.size );
  979. *pOffset = (ULONG) (flds.address - Sym.addr);
  980. *pSize = flds.size;
  981. return Err;
  982. }
  983. ULONG GetUlongFromAddress (
  984. ULONG64 Location)
  985. {
  986. ULONG Value;
  987. ULONG result;
  988. if((!ReadMemory(Location,&Value,sizeof(ULONG),&result)) ||
  989. (result < sizeof(ULONG)))
  990. {
  991. dprintf("unable to read from %08x\n",Location);
  992. return 0;
  993. }
  994. return Value;
  995. }
  996. ULONG64 GetPointerFromAddress(
  997. ULONG64 Location)
  998. {
  999. ULONG64 Value;
  1000. ULONG result;
  1001. if(ReadPtr(Location,&Value))
  1002. {
  1003. dprintf("unable to read from %p\n",Location);
  1004. return 0;
  1005. }
  1006. return Value;
  1007. }
  1008. ULONG GetUlongValue (
  1009. PCHAR String)
  1010. {
  1011. ULONG64 Location;
  1012. ULONG Value;
  1013. ULONG result;
  1014. Location = GetExpression(String);
  1015. if(!Location)
  1016. {
  1017. dprintf("unable to get %s\n",String);
  1018. return 0;
  1019. }
  1020. return GetUlongFromAddress(Location);
  1021. }
  1022. ULONG64 GetPointerValue (
  1023. PCHAR String)
  1024. {
  1025. ULONG64 Location, Val=0;
  1026. Location = GetExpression(String);
  1027. if(!Location)
  1028. {
  1029. dprintf("unable to get %s\n",String);
  1030. return 0;
  1031. }
  1032. ReadPtr(Location, &Val);
  1033. return Val;
  1034. }