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.

357 lines
8.2 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. mtrr.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Author:
  8. Ken Reneris (kenr) 06-June-1994
  9. Environment:
  10. User Mode.
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. ULONG
  16. FindFirstSetRightBit (
  17. IN ULONGLONG Set
  18. );
  19. ULONGLONG
  20. MaskToLength (
  21. IN ULONGLONG Mask
  22. );
  23. //
  24. // MTRR MSR architecture definitions
  25. //
  26. #define MTRR_MSR_CAPABILITIES 0x0fe
  27. #define MTRR_MSR_DEFAULT 0x2ff
  28. #define MTRR_MSR_VARIABLE_BASE 0x200
  29. #define MTRR_MSR_VARIABLE_MASK (MTRR_MSR_VARIABLE_BASE+1)
  30. #define MTRR_PAGE_SIZE 4096
  31. #define MTRR_PAGE_MASK (MTRR_PAGE_SIZE-1)
  32. //
  33. // Memory range types
  34. //
  35. #define MTRR_TYPE_UC 0
  36. #define MTRR_TYPE_USWC 1
  37. #define MTRR_TYPE_WT 4
  38. #define MTRR_TYPE_WP 5
  39. #define MTRR_TYPE_WB 6
  40. #define MTRR_TYPE_MAX 7
  41. // #include "pshpack1.h"
  42. typedef struct _MTRR_CAPABILITIES {
  43. union {
  44. struct {
  45. ULONG VarCnt:8;
  46. ULONG FixSupported:1;
  47. ULONG Reserved_0:1;
  48. ULONG UswcSupported:1;
  49. } hw;
  50. ULONGLONG QuadPart;
  51. } u;
  52. } MTRR_CAPABILITIES;
  53. typedef struct _MTRR_DEFAULT {
  54. union {
  55. struct {
  56. ULONG Type:8;
  57. ULONG Reserved_0:2;
  58. ULONG FixedEnabled:1;
  59. ULONG MtrrEnabled:1;
  60. } hw;
  61. ULONGLONG QuadPart;
  62. } u;
  63. } MTRR_DEFAULT;
  64. typedef struct _MTRR_VARIABLE_BASE {
  65. union {
  66. struct {
  67. ULONGLONG Type:8;
  68. ULONGLONG Reserved_0:4;
  69. ULONGLONG PhysBase:52;
  70. } hw;
  71. ULONGLONG QuadPart;
  72. } u;
  73. } MTRR_VARIABLE_BASE;
  74. #define MTRR_MASK_BASE (~0xfff)
  75. typedef struct _MTRR_VARIABLE_MASK {
  76. union {
  77. struct {
  78. ULONGLONG Reserved_0:11;
  79. ULONGLONG Valid:1;
  80. ULONGLONG PhysMask:52;
  81. } hw;
  82. ULONGLONG QuadPart;
  83. } u;
  84. } MTRR_VARIABLE_MASK;
  85. #define MTRR_MASK_MASK (~0xfff)
  86. // Added support for Mask2Length conversion
  87. #define MTRR_MAX_RANGE_SHIFT 36
  88. #define MASK_OVERFLOW_MASK (~0x1000000000)
  89. CCHAR FindFirstSetRight[256] = {
  90. 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  91. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  92. 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  93. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  94. 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  95. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  96. 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  97. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  98. 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  99. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  100. 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  101. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  102. 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  103. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  104. 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
  105. 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0};
  106. // #include "poppack.h"
  107. //
  108. // ----------------------------------------------------------------
  109. //
  110. PUCHAR
  111. MtrrType (
  112. IN ULONG Type
  113. )
  114. {
  115. PUCHAR p;
  116. static UCHAR s[20];
  117. switch (Type) {
  118. case 0: p = "UC"; break;
  119. case 1: p = "USWC"; break;
  120. case 4: p = "WT"; break;
  121. case 5: p = "WP"; break;
  122. case 6: p = "WB"; break;
  123. default:
  124. sprintf (s, "%02x??", Type & 0xff);
  125. p = s;
  126. break;
  127. }
  128. return p;
  129. }
  130. VOID
  131. MtrrDumpFixed (
  132. IN ULONG Base,
  133. IN ULONG Size,
  134. IN ULONG Msr
  135. )
  136. {
  137. ULONG x;
  138. ULONGLONG li;
  139. ReadMsr(Msr, &li);
  140. for (x=0; x < 8; x++) {
  141. dprintf ("%s:%05x-%05x ",
  142. MtrrType ( ((ULONG) li) & 0xff ),
  143. Base,
  144. Base + Size - 1
  145. );
  146. li >>= 8;
  147. Base += Size;
  148. if (x == 3) {
  149. dprintf ("\n");
  150. }
  151. }
  152. dprintf ("\n");
  153. }
  154. #define KF_MTRR 0x00000040
  155. DECLARE_API( mtrr )
  156. /*++
  157. Routine Description:
  158. Dumps processors mtrr
  159. Arguments:
  160. args - none
  161. Return Value:
  162. None
  163. --*/
  164. {
  165. MTRR_CAPABILITIES Capabilities;
  166. MTRR_DEFAULT Default;
  167. MTRR_VARIABLE_BASE Base;
  168. MTRR_VARIABLE_MASK Mask;
  169. ULONG Index;
  170. ULONG i;
  171. PUCHAR p;
  172. ULONG fb;
  173. ULONG64 addr=0;
  174. ULONGLONG Length, MtrrBase, MtrrMask;
  175. BOOL ContiguousLength = TRUE;
  176. //
  177. // Quick sanity check
  178. //
  179. if (TargetMachine != IMAGE_FILE_MACHINE_I386) {
  180. dprintf("!mtrr is X86 only Api.\n");
  181. return E_INVALIDARG;
  182. }
  183. i = 0;
  184. addr = GetExpression(args);
  185. if (i != 1) {
  186. addr = GetExpression("KeFeatureBits");
  187. if (!addr) {
  188. dprintf ("KeFeatureBits not found\n");
  189. return E_INVALIDARG;
  190. }
  191. fb = 0;
  192. ReadMemory(addr, &fb, sizeof(i), &i);
  193. if (fb == -1 || !(fb & KF_MTRR)) {
  194. dprintf ("MTRR feature not present\n");
  195. return E_INVALIDARG;
  196. }
  197. }
  198. //
  199. // Dump MTRR
  200. //
  201. ReadMsr(MTRR_MSR_CAPABILITIES, &Capabilities.u.QuadPart);
  202. ReadMsr(MTRR_MSR_DEFAULT, &Default.u.QuadPart);
  203. dprintf ("MTTR: %s Var %d, Fixed-%s %s, USWC-%s, Default: %s\n",
  204. Default.u.hw.MtrrEnabled ? "" : "disabled",
  205. Capabilities.u.hw.VarCnt,
  206. Capabilities.u.hw.FixSupported ? "support" : "none",
  207. Default.u.hw.FixedEnabled ? "enabled" : "disabled",
  208. Capabilities.u.hw.UswcSupported ? "supported" : "none",
  209. MtrrType (Default.u.hw.Type)
  210. );
  211. MtrrDumpFixed (0x00000, 64*1024, 0x250);
  212. MtrrDumpFixed (0x80000, 16*1024, 0x258);
  213. MtrrDumpFixed (0xA0000, 16*1024, 0x259);
  214. MtrrDumpFixed (0xC0000, 4*1024, 0x268);
  215. MtrrDumpFixed (0xC8000, 4*1024, 0x269);
  216. MtrrDumpFixed (0xD0000, 4*1024, 0x26A);
  217. MtrrDumpFixed (0xD8000, 4*1024, 0x26B);
  218. MtrrDumpFixed (0xE0000, 4*1024, 0x26C);
  219. MtrrDumpFixed (0xE8000, 4*1024, 0x26D);
  220. MtrrDumpFixed (0xF0000, 4*1024, 0x26E);
  221. MtrrDumpFixed (0xE8000, 4*1024, 0x26F);
  222. dprintf ("Variable: Base Mask Length\n");
  223. for (Index=0; Index < (ULONG) Capabilities.u.hw.VarCnt; Index++) {
  224. ReadMsr(MTRR_MSR_VARIABLE_BASE+2*Index, &Base.u.QuadPart);
  225. ReadMsr(MTRR_MSR_VARIABLE_MASK+2*Index, &Mask.u.QuadPart);
  226. dprintf (" %2d. ", Index);
  227. if (Mask.u.hw.Valid) {
  228. MtrrMask = Mask.u.QuadPart & MTRR_MASK_MASK;
  229. MtrrBase = Base.u.QuadPart & MTRR_MASK_BASE;
  230. Length = MaskToLength(MtrrMask);
  231. // Check for non-contiguous MTRR mask.
  232. if ((MtrrMask + Length) & MASK_OVERFLOW_MASK) {
  233. ContiguousLength = FALSE;
  234. }
  235. dprintf ("%4s: %08x:%08x %08x:%08x %08x:%08x",
  236. MtrrType ((ULONG) Base.u.hw.Type),
  237. (ULONG) (Base.u.QuadPart >> 32), (ULONG) MtrrBase,
  238. (ULONG) (Mask.u.QuadPart >> 32), (ULONG) MtrrMask,
  239. (ULONG) (Length >> 32), (ULONG) Length);
  240. if (ContiguousLength == FALSE) {
  241. ContiguousLength = TRUE;
  242. dprintf("(non-contiguous)\n");
  243. }
  244. else {
  245. dprintf("\n");
  246. }
  247. } else {
  248. dprintf ("\n");
  249. }
  250. }
  251. return S_OK;
  252. }
  253. ULONGLONG
  254. MaskToLength (
  255. IN ULONGLONG Mask
  256. )
  257. /*++
  258. Routine Description:
  259. This function returns the length specified by a particular
  260. mtrr variable register mask.
  261. --*/
  262. {
  263. if (Mask == 0) {
  264. // Zero Mask signifies a length of 2**36
  265. return(((ULONGLONG) 1 << MTRR_MAX_RANGE_SHIFT));
  266. } else {
  267. return(((ULONGLONG) 1 << FindFirstSetRightBit(Mask)));
  268. }
  269. }
  270. ULONG
  271. FindFirstSetRightBit (
  272. IN ULONGLONG Set
  273. )
  274. /*++
  275. Routine Description:
  276. This function returns a bit position of the least significant
  277. bit set in the passed ULONGLONG parameter. Passed parameter
  278. must be non-zero.
  279. --*/
  280. {
  281. ULONG bitno;
  282. for (bitno=0; !(Set & 0xFF); bitno += 8, Set >>= 8) ;
  283. return FindFirstSetRight[Set & 0xFF] + bitno;
  284. }