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.

365 lines
9.4 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. ia64 pmc
  5. Abstract:
  6. KD Extension Api
  7. Author:
  8. Thierry Fevrier (v-thief)
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #include "ia64.h"
  16. //
  17. // EmPmcFields: EM register fields for the Performance Monitor Counter register.
  18. //
  19. EM_REG_FIELD EmGenPmcFields[] = {
  20. { "plm", "Privilege Level Mask" , 0x4, 0 }, // 0-3
  21. { "ev", "External Visibility" , 0x1, 4 }, // 4
  22. { "oi", "Overflow Interrupt", 0x1, 5 }, // 5
  23. { "pm", "Privileged Monitor", 0x1, 6 }, // 6
  24. { "ig", "ignored1", 0x1, 7 }, // 7
  25. { "es", "Event Selection", 0x7, 8 }, // 8-14
  26. { "ig", "ignored2", 0x1, 15 }, // 15
  27. { "umk", "Unit Mask", 0x4, 16 }, // 16-19
  28. { "thr", "Event Threshold", 0x3, 20 }, // 20-[21-22]
  29. { "ig", "ignored3", 0x1, 23 }, // 23
  30. { "ism", "Instruction Set Mask", 0x2, 24 }, // 24-25
  31. { "ig", "ignored4", 0x26, 26 } // 26-63
  32. };
  33. EM_REG_FIELD EmBtbPmcFields[] = {
  34. { "plm", "Privilege Level Mask", 0x4, 0 }, // 0-3
  35. { "ign", "ignored1", 0x2, 4 }, // 4-5
  36. { "pm" , "Privileged Monitor", 0x1, 6}, // 6
  37. { "tar", "Target Address Register", 0x1, 7 }, // 7
  38. { "tm" , "Taken Mask", 0x2, 8 }, // 8-9
  39. { "ptm", "Predicted Target Address Mask", 0x2, 10 }, // 10-11
  40. { "ppm", "Predicted Predicate Mask", 0x2, 12 }, // 12-13
  41. { "bpt", "Branch Prediction Table", 0x1, 14 }, // 14
  42. { "bac", "Branch Address Calculator", 0x1, 15 }, // 15
  43. { "ign", "ignored2", 0x30, 16 } // 16-63
  44. };
  45. EM_REG_FIELD EmBtbPmdFields[] = {
  46. { "b", "Branch Bit", 0x1, 0 }, // 0
  47. { "mp", "Mispredit Bit", 0x1, 1 }, // 1
  48. { "slt", "Instruction Slot", 0x2, 2}, // 2-3
  49. { "add", "Address", 0x3c, 4 } // 4-63
  50. };
  51. EM_REG_FIELD EmBtbIndexPmdFields[] = {
  52. { "bbi", "Branch Buffer Index", 0x3, 0 }, // 0-2
  53. { "ful", "Full Bit", 0x1, 3 }, // 3
  54. { "ign", "ignored", 0x3c, 4 } // 4-63
  55. };
  56. typedef
  57. VOID
  58. (*PDISPLAY_PMC)(
  59. IN const PCHAR Header,
  60. IN ULONG64 PmcValue,
  61. IN DISPLAY_MODE DisplayMode
  62. );
  63. VOID
  64. DisplayPmcIA64(
  65. IN const PCHAR Header,
  66. IN ULONG64 PmcValue,
  67. IN DISPLAY_MODE DisplayMode
  68. )
  69. {
  70. dprintf("%s0x%I64x\n", ( Header ? Header : " pmc: " ), PmcValue );
  71. return;
  72. } // DisplayPmcIA64()
  73. VOID
  74. DisplayGenPmcIA64(
  75. IN const PCHAR Header,
  76. IN ULONG64 PmcValue,
  77. IN DISPLAY_MODE DisplayMode
  78. )
  79. {
  80. dprintf("%s", Header ? Header : "" );
  81. if ( DisplayMode >= DISPLAY_MED ) {
  82. DisplayFullEmReg( PmcValue, EmGenPmcFields, DisplayMode );
  83. }
  84. else {
  85. EM_PMC emPmc;
  86. emPmc = ULong64ToEM_PMC( PmcValue );
  87. dprintf(
  88. "plm ev oi pm es umk thr ism\n "
  89. "%1I64x %1I64x %1I64x %1I64x %2I64x %1I64x %1I64x %1I64x\n",
  90. emPmc.plm,
  91. emPmc.ev,
  92. emPmc.oi,
  93. emPmc.pm,
  94. emPmc.es,
  95. emPmc.umask,
  96. emPmc.threshold,
  97. emPmc.ism
  98. );
  99. }
  100. return;
  101. } // DisplayGenPmcIA64()
  102. VOID
  103. DisplayBtbPmcIA64(
  104. IN const PCHAR Header,
  105. IN ULONG64 PmcValue,
  106. IN DISPLAY_MODE DisplayMode
  107. )
  108. {
  109. dprintf("%s", Header ? Header : "" );
  110. if ( DisplayMode >= DISPLAY_MED ) {
  111. DisplayFullEmReg( PmcValue, EmBtbPmcFields, DisplayMode );
  112. }
  113. else {
  114. EM_BTB_PMC emPmc;
  115. emPmc = ULong64ToEM_BTB_PMC( PmcValue );
  116. dprintf(
  117. "plm pm tar tm ptm ppm bpt bac\n "
  118. "%1I64x %1I64x %1I64x %1I64x %1I64x %1I64x %1I64x %1I64x\n",
  119. emPmc.plm,
  120. emPmc.pm,
  121. emPmc.tar,
  122. emPmc.tm,
  123. emPmc.ptm,
  124. emPmc.ppm,
  125. emPmc.bpt,
  126. emPmc.bac
  127. );
  128. }
  129. return;
  130. } // DisplayBtbPmcIA64()
  131. VOID
  132. DisplayBtbPmdIA64(
  133. IN const PCHAR Header, // Header string displayed before pmc.
  134. IN ULONG64 PmdValue, // PMD value.
  135. IN DISPLAY_MODE DisplayMode // Display mode.
  136. )
  137. {
  138. dprintf("%s", Header ? Header : "" );
  139. if ( DisplayMode >= DISPLAY_MED ) {
  140. DisplayFullEmReg( PmdValue, EmBtbPmdFields, DisplayMode );
  141. }
  142. else {
  143. EM_BTB_PMD btbPmd;
  144. ULONG64 brAddress;
  145. btbPmd = ULong64ToEM_BTB_PMD( PmdValue );
  146. #define ITANIUM_PA_ADDRESSING_MASK 0x80000FFFFFFFFFFFUI64
  147. #define ITANIUM_VA_ADDRESSING_MASK 0xE007FFFFFFFFFFFFUI64
  148. #define ITANIUM_BTB_PMD_ADDRESS_MASK( _pmdValue) \
  149. ( ((_pmdValue) & 0xfffffffffffffff0UI64) & ITANIUM_VA_ADDRESSING_MASK )
  150. brAddress = ITANIUM_BTB_PMD_ADDRESS_MASK( PmdValue );
  151. dprintf(
  152. "%1I64x %1I64x %1I64x 0x%016I64x ",
  153. btbPmd.b,
  154. btbPmd.mp,
  155. btbPmd.slot,
  156. brAddress
  157. );
  158. #if 0
  159. // Thierry 03/19/2001 - BUGBUG
  160. // Itanium Processor Programmer's guide does not present the
  161. // PMD[8-15] branch/interrupt mode 2 formats.
  162. // I am disabling this check until I can implement it correctly with a context
  163. // that can distinguish between mode 1 and mode 2 at the time this history was created.
  164. if ( (btbPmd.b == 0) && (btbPmd.mp == 0)) {
  165. dprintf("<invalid entry>");
  166. }
  167. else
  168. #endif
  169. {
  170. CCHAR symbol[256];
  171. PCHAR s;
  172. ULONG64 displacement;
  173. symbol[0] = '!';
  174. GetSymbol( brAddress, symbol, &displacement);
  175. s = (PCHAR)symbol + strlen( (PCHAR)symbol );
  176. if (s == (PCHAR)symbol ) {
  177. sprintf( s, (IsPtr64() ? "0x%016I64x" : "0x%08x"), brAddress );
  178. }
  179. else {
  180. if ( displacement ) {
  181. sprintf( s, (IsPtr64() ? "+0x%I64x" : "+0x%x"), displacement );
  182. }
  183. }
  184. dprintf( "%s", symbol );
  185. }
  186. dprintf("\n");
  187. }
  188. return;
  189. } // DisplayBtbPmdIA64()
  190. VOID
  191. DisplayBtbIndexPmdIA64(
  192. IN const PCHAR Header,
  193. IN ULONG64 PmcValue,
  194. IN DISPLAY_MODE DisplayMode
  195. )
  196. {
  197. dprintf("%s", Header ? Header : "" );
  198. if ( DisplayMode >= DISPLAY_MED ) {
  199. DisplayFullEmReg( PmcValue, EmBtbIndexPmdFields, DisplayMode );
  200. }
  201. else {
  202. EM_BTB_INDEX_PMD emPmd;
  203. emPmd = ULong64ToEM_BTB_INDEX_PMD( PmcValue );
  204. dprintf(
  205. "bbi full\n "
  206. "%1I64x %1I64x\n",
  207. emPmd.bbi,
  208. emPmd.full
  209. );
  210. }
  211. return;
  212. } // DisplayBtbIndexPmdIA64()
  213. PDISPLAY_PMC
  214. GetPmcDisplayFunction(
  215. char *Str
  216. )
  217. {
  218. LONG pmc;
  219. char *c;
  220. c = Str;
  221. while( isalnum( (int)(*c) ) ) {
  222. c++;
  223. }
  224. *c = '\0';
  225. pmc = atol( Str );
  226. switch( pmc ) {
  227. case 4:
  228. case 5:
  229. case 6:
  230. case 7:
  231. return( (PDISPLAY_PMC)DisplayGenPmcIA64 );
  232. case 12:
  233. return( (PDISPLAY_PMC)DisplayBtbPmcIA64 );
  234. default:
  235. if ( !strcmp( Str, "gen" ) ) {
  236. return( (PDISPLAY_PMC)DisplayGenPmcIA64 );
  237. }
  238. if ( !strcmp( Str, "btb" ) ) {
  239. return( (PDISPLAY_PMC)DisplayBtbPmcIA64 );
  240. }
  241. return ( (PDISPLAY_PMC)DisplayPmcIA64 );
  242. }
  243. } // IsPmcSupported()
  244. DECLARE_API( pmc )
  245. /*++
  246. Routine Description:
  247. Dumps a IA-64 Processor PMC Register.
  248. // Thierry 11/2000: The following scheme could also be used for PMD registers.
  249. Arguments:
  250. args - Supplies the address in hex.
  251. Return Value:
  252. None
  253. --*/
  254. {
  255. ULONG64 pmcValue = 0;
  256. ULONG result;
  257. ULONG flags = 0;
  258. char *option = NULL;
  259. PDISPLAY_PMC displayPmc = DisplayGenPmcIA64; // Default display function.
  260. char *header;
  261. if ( TargetMachine != IMAGE_FILE_MACHINE_IA64 )
  262. {
  263. dprintf("!pmc not implemented for this architecture.\n");
  264. return S_OK;
  265. }
  266. option = strchr( args, '-' );
  267. if ( option ) {
  268. displayPmc = GetPmcDisplayFunction( ++option );
  269. args += (strlen(option) + 2);
  270. }
  271. result = sscanf(args,"%I64lx %lx", &pmcValue, &flags);
  272. if ((result != 1) && (result != 2)) {
  273. //
  274. // If user specified "@kpfc*"...
  275. //
  276. char kpfcStr[16];
  277. BOOLEAN valid = FALSE;
  278. result = sscanf(args,"%s %lx", kpfcStr, &flags);
  279. if ( (result == 1) || (result == 2) ) {
  280. if ( option == NULL ) { // If we did not force the display format.
  281. char *str;
  282. str = strstr( kpfcStr, "@kpfc" );
  283. if ( str ) {
  284. str += strlen("@kpfc");
  285. displayPmc = GetPmcDisplayFunction( str );
  286. }
  287. }
  288. }
  289. else {
  290. dprintf( "USAGE: !pmc [-opt] 0xValue [display_mode:0,1,2]\n"
  291. "USAGE: !pmc @kpfc* [display_mode:0,1,2]\n"
  292. "where currently supported option:\n"
  293. "\tgen [or 4,5,6,7] - generic PMC registers\n"
  294. "\tbtb [or 12] - branch trace buffer PMC register\n"
  295. "\tEx: !pmc -btb @r2 2\n"
  296. );
  297. return E_INVALIDARG;
  298. }
  299. pmcValue = GetExpression(kpfcStr);
  300. }
  301. header = (flags > DISPLAY_MIN) ? NULL : " pmc: ";
  302. (*displayPmc)( header, pmcValue, flags );
  303. return S_OK;
  304. } // !pmc