VirtualBox

source: vbox/trunk/src/VBox/VMM/tools/VBoxCpuReport.cpp@ 77994

Last change on this file since 77994 was 76886, checked in by vboxsync, 6 years ago

VMM (and related changes): Add support for Shanghai/Zhaoxin CPUs. Modified and improved contribution by Journey Ren submitted under MIT license. Thank you!

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 227.4 KB
Line 
1/* $Id: VBoxCpuReport.cpp 76886 2019-01-18 10:57:02Z vboxsync $ */
2/** @file
3 * VBoxCpuReport - Produces the basis for a CPU DB entry.
4 */
5
6/*
7 * Copyright (C) 2013-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include <iprt/asm.h>
23#include <iprt/asm-amd64-x86.h>
24#include <iprt/buildconfig.h>
25#include <iprt/ctype.h>
26#include <iprt/file.h>
27#include <iprt/getopt.h>
28#include <iprt/initterm.h>
29#include <iprt/message.h>
30#include <iprt/mem.h>
31#include <iprt/path.h>
32#include <iprt/string.h>
33#include <iprt/stream.h>
34#include <iprt/symlink.h>
35#include <iprt/thread.h>
36#include <iprt/time.h>
37
38#include <VBox/err.h>
39#include <VBox/vmm/cpum.h>
40#include <VBox/sup.h>
41
42#include "VBoxCpuReport.h"
43
44
45/*********************************************************************************************************************************
46* Structures and Typedefs *
47*********************************************************************************************************************************/
48/** Write only register. */
49#define VBCPUREPMSR_F_WRITE_ONLY RT_BIT(0)
50
51typedef struct VBCPUREPMSR
52{
53 /** The first MSR register number. */
54 uint32_t uMsr;
55 /** Flags (MSRREPORT_F_XXX). */
56 uint32_t fFlags;
57 /** The value we read, unless write-only. */
58 uint64_t uValue;
59} VBCPUREPMSR;
60
61
62/*********************************************************************************************************************************
63* Global Variables *
64*********************************************************************************************************************************/
65/** The CPU vendor. Used by the MSR code. */
66static CPUMCPUVENDOR g_enmVendor = CPUMCPUVENDOR_INVALID;
67/** The CPU microarchitecture. Used by the MSR code. */
68static CPUMMICROARCH g_enmMicroarch = kCpumMicroarch_Invalid;
69/** Set if g_enmMicroarch indicates an Intel NetBurst CPU. */
70static bool g_fIntelNetBurst = false;
71/** The alternative report stream. */
72static PRTSTREAM g_pReportOut;
73/** The alternative debug stream. */
74static PRTSTREAM g_pDebugOut;
75/** Whether to skip MSR collection. */
76static bool g_fNoMsrs = false;
77
78/** Snooping info storage for vbCpuRepGuessScalableBusFrequencyName. */
79static uint64_t g_uMsrIntelP6FsbFrequency = UINT64_MAX;
80
81/** The MSR accessors interface. */
82static VBCPUREPMSRACCESSORS g_MsrAcc;
83
84
85
86void vbCpuRepDebug(const char *pszMsg, ...)
87{
88 va_list va;
89
90 /* Always print a copy of the report to standard error. */
91 va_start(va, pszMsg);
92 RTStrmPrintfV(g_pStdErr, pszMsg, va);
93 va_end(va);
94 RTStrmFlush(g_pStdErr);
95
96 /* Alternatively, also print to a log file. */
97 if (g_pDebugOut)
98 {
99 va_start(va, pszMsg);
100 RTStrmPrintfV(g_pDebugOut, pszMsg, va);
101 va_end(va);
102 RTStrmFlush(g_pDebugOut);
103 }
104
105 /* Give the output device a chance to write / display it. */
106 RTThreadSleep(1);
107}
108
109
110void vbCpuRepPrintf(const char *pszMsg, ...)
111{
112 va_list va;
113
114 /* Output to report file, if requested. */
115 if (g_pReportOut)
116 {
117 va_start(va, pszMsg);
118 RTStrmPrintfV(g_pReportOut, pszMsg, va);
119 va_end(va);
120 RTStrmFlush(g_pReportOut);
121 }
122
123 /* Always print a copy of the report to standard out. */
124 va_start(va, pszMsg);
125 RTStrmPrintfV(g_pStdOut, pszMsg, va);
126 va_end(va);
127 RTStrmFlush(g_pStdOut);
128}
129
130
131
132static int vbCpuRepMsrsAddOne(VBCPUREPMSR **ppaMsrs, uint32_t *pcMsrs,
133 uint32_t uMsr, uint64_t uValue, uint32_t fFlags)
134{
135 /*
136 * Grow the array?
137 */
138 uint32_t cMsrs = *pcMsrs;
139 if ((cMsrs % 64) == 0)
140 {
141 void *pvNew = RTMemRealloc(*ppaMsrs, (cMsrs + 64) * sizeof(**ppaMsrs));
142 if (!pvNew)
143 {
144 RTMemFree(*ppaMsrs);
145 *ppaMsrs = NULL;
146 *pcMsrs = 0;
147 return VERR_NO_MEMORY;
148 }
149 *ppaMsrs = (VBCPUREPMSR *)pvNew;
150 }
151
152 /*
153 * Add it.
154 */
155 VBCPUREPMSR *pEntry = *ppaMsrs + cMsrs;
156 pEntry->uMsr = uMsr;
157 pEntry->fFlags = fFlags;
158 pEntry->uValue = uValue;
159 *pcMsrs = cMsrs + 1;
160
161 return VINF_SUCCESS;
162}
163
164
165/**
166 * Returns the max physical address width as a number of bits.
167 *
168 * @returns Bit count.
169 */
170static uint8_t vbCpuRepGetPhysAddrWidth(void)
171{
172 uint8_t cMaxWidth;
173 if (!ASMHasCpuId())
174 cMaxWidth = 32;
175 else
176 {
177 uint32_t cMaxExt = ASMCpuId_EAX(0x80000000);
178 if (ASMIsValidExtRange(cMaxExt)&& cMaxExt >= 0x80000008)
179 cMaxWidth = ASMCpuId_EAX(0x80000008) & 0xff;
180 else if ( ASMIsValidStdRange(ASMCpuId_EAX(0))
181 && (ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_PSE36))
182 cMaxWidth = 36;
183 else
184 cMaxWidth = 32;
185 }
186 return cMaxWidth;
187}
188
189
190static bool vbCpuRepSupportsPae(void)
191{
192 return ASMHasCpuId()
193 && ASMIsValidStdRange(ASMCpuId_EAX(0))
194 && (ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_PAE);
195}
196
197
198static bool vbCpuRepSupportsLongMode(void)
199{
200 return ASMHasCpuId()
201 && ASMIsValidExtRange(ASMCpuId_EAX(0x80000000))
202 && (ASMCpuId_EDX(0x80000001) & X86_CPUID_EXT_FEATURE_EDX_LONG_MODE);
203}
204
205
206static bool vbCpuRepSupportsNX(void)
207{
208 return ASMHasCpuId()
209 && ASMIsValidExtRange(ASMCpuId_EAX(0x80000000))
210 && (ASMCpuId_EDX(0x80000001) & X86_CPUID_EXT_FEATURE_EDX_NX);
211}
212
213
214static bool vbCpuRepSupportsX2Apic(void)
215{
216 return ASMHasCpuId()
217 && ASMIsValidStdRange(ASMCpuId_EAX(0))
218 && (ASMCpuId_ECX(1) & X86_CPUID_FEATURE_ECX_X2APIC);
219}
220
221
222
223#if 0 /* unused */
224static bool msrProberWrite(uint32_t uMsr, uint64_t uValue)
225{
226 bool fGp;
227 int rc = g_MsrAcc.pfnMsrWrite(uMsr, NIL_RTCPUID, uValue, &fGp);
228 AssertRC(rc);
229 return RT_SUCCESS(rc) && !fGp;
230}
231#endif
232
233
234static bool msrProberRead(uint32_t uMsr, uint64_t *puValue)
235{
236 *puValue = 0;
237 bool fGp;
238 int rc = g_MsrAcc.pfnMsrProberRead(uMsr, NIL_RTCPUID, puValue, &fGp);
239 AssertRC(rc);
240 return RT_SUCCESS(rc) && !fGp;
241}
242
243
244/** Tries to modify the register by writing the original value to it. */
245static bool msrProberModifyNoChange(uint32_t uMsr)
246{
247 SUPMSRPROBERMODIFYRESULT Result;
248 int rc = g_MsrAcc.pfnMsrProberModify(uMsr, NIL_RTCPUID, UINT64_MAX, 0, &Result);
249 return RT_SUCCESS(rc)
250 && !Result.fBeforeGp
251 && !Result.fModifyGp
252 && !Result.fAfterGp
253 && !Result.fRestoreGp;
254}
255
256
257/** Tries to modify the register by writing zero to it. */
258static bool msrProberModifyZero(uint32_t uMsr)
259{
260 SUPMSRPROBERMODIFYRESULT Result;
261 int rc = g_MsrAcc.pfnMsrProberModify(uMsr, NIL_RTCPUID, 0, 0, &Result);
262 return RT_SUCCESS(rc)
263 && !Result.fBeforeGp
264 && !Result.fModifyGp
265 && !Result.fAfterGp
266 && !Result.fRestoreGp;
267}
268
269
270/**
271 * Tries to modify each bit in the MSR and see if we can make it change.
272 *
273 * @returns VBox status code.
274 * @param uMsr The MSR.
275 * @param pfIgnMask The ignore mask to update.
276 * @param pfGpMask The GP mask to update.
277 * @param fSkipMask Mask of bits to skip.
278 */
279static int msrProberModifyBitChanges(uint32_t uMsr, uint64_t *pfIgnMask, uint64_t *pfGpMask, uint64_t fSkipMask)
280{
281 for (unsigned iBit = 0; iBit < 64; iBit++)
282 {
283 uint64_t fBitMask = RT_BIT_64(iBit);
284 if (fBitMask & fSkipMask)
285 continue;
286
287 /* Set it. */
288 SUPMSRPROBERMODIFYRESULT ResultSet;
289 int rc = g_MsrAcc.pfnMsrProberModify(uMsr, NIL_RTCPUID, ~fBitMask, fBitMask, &ResultSet);
290 if (RT_FAILURE(rc))
291 return RTMsgErrorRc(rc, "pfnMsrProberModify(%#x,,%#llx,%#llx,): %Rrc", uMsr, ~fBitMask, fBitMask, rc);
292
293 /* Clear it. */
294 SUPMSRPROBERMODIFYRESULT ResultClear;
295 rc = g_MsrAcc.pfnMsrProberModify(uMsr, NIL_RTCPUID, ~fBitMask, 0, &ResultClear);
296 if (RT_FAILURE(rc))
297 return RTMsgErrorRc(rc, "pfnMsrProberModify(%#x,,%#llx,%#llx,): %Rrc", uMsr, ~fBitMask, 0, rc);
298
299 if (ResultSet.fModifyGp || ResultClear.fModifyGp)
300 *pfGpMask |= fBitMask;
301 else if ( ( ((ResultSet.uBefore ^ ResultSet.uAfter) & fBitMask) == 0
302 && !ResultSet.fBeforeGp
303 && !ResultSet.fAfterGp)
304 && ( ((ResultClear.uBefore ^ ResultClear.uAfter) & fBitMask) == 0
305 && !ResultClear.fBeforeGp
306 && !ResultClear.fAfterGp) )
307 *pfIgnMask |= fBitMask;
308 }
309
310 return VINF_SUCCESS;
311}
312
313
314#if 0 /* currently unused */
315/**
316 * Tries to modify one bit.
317 *
318 * @retval -2 on API error.
319 * @retval -1 on \#GP.
320 * @retval 0 if ignored.
321 * @retval 1 if it changed.
322 *
323 * @param uMsr The MSR.
324 * @param iBit The bit to try modify.
325 */
326static int msrProberModifyBit(uint32_t uMsr, unsigned iBit)
327{
328 uint64_t fBitMask = RT_BIT_64(iBit);
329
330 /* Set it. */
331 SUPMSRPROBERMODIFYRESULT ResultSet;
332 int rc = g_MsrAcc.pfnMsrProberModify(uMsr, NIL_RTCPUID, ~fBitMask, fBitMask, &ResultSet);
333 if (RT_FAILURE(rc))
334 return RTMsgErrorRc(-2, "pfnMsrProberModify(%#x,,%#llx,%#llx,): %Rrc", uMsr, ~fBitMask, fBitMask, rc);
335
336 /* Clear it. */
337 SUPMSRPROBERMODIFYRESULT ResultClear;
338 rc = g_MsrAcc.pfnMsrProberModify(uMsr, NIL_RTCPUID, ~fBitMask, 0, &ResultClear);
339 if (RT_FAILURE(rc))
340 return RTMsgErrorRc(-2, "pfnMsrProberModify(%#x,,%#llx,%#llx,): %Rrc", uMsr, ~fBitMask, 0, rc);
341
342 if (ResultSet.fModifyGp || ResultClear.fModifyGp)
343 return -1;
344
345 if ( ( ((ResultSet.uBefore ^ ResultSet.uAfter) & fBitMask) != 0
346 && !ResultSet.fBeforeGp
347 && !ResultSet.fAfterGp)
348 || ( ((ResultClear.uBefore ^ ResultClear.uAfter) & fBitMask) != 0
349 && !ResultClear.fBeforeGp
350 && !ResultClear.fAfterGp) )
351 return 1;
352
353 return 0;
354}
355#endif
356
357
358/**
359 * Tries to do a simple AND+OR change and see if we \#GP or not.
360 *
361 * @retval @c true if successfully modified.
362 * @retval @c false if \#GP or other error.
363 *
364 * @param uMsr The MSR.
365 * @param fAndMask The AND mask.
366 * @param fOrMask The OR mask.
367 */
368static bool msrProberModifySimpleGp(uint32_t uMsr, uint64_t fAndMask, uint64_t fOrMask)
369{
370 SUPMSRPROBERMODIFYRESULT Result;
371 int rc = g_MsrAcc.pfnMsrProberModify(uMsr, NIL_RTCPUID, fAndMask, fOrMask, &Result);
372 if (RT_FAILURE(rc))
373 {
374 RTMsgError("g_MsrAcc.pfnMsrProberModify(%#x,,%#llx,%#llx,): %Rrc", uMsr, fAndMask, fOrMask, rc);
375 return false;
376 }
377 return !Result.fBeforeGp
378 && !Result.fModifyGp
379 && !Result.fAfterGp
380 && !Result.fRestoreGp;
381}
382
383
384
385
386/**
387 * Combination of the basic tests.
388 *
389 * @returns VBox status code.
390 * @param uMsr The MSR.
391 * @param fSkipMask Mask of bits to skip.
392 * @param pfReadOnly Where to return read-only status.
393 * @param pfIgnMask Where to return the write ignore mask. Need not
394 * be initialized.
395 * @param pfGpMask Where to return the write GP mask. Need not
396 * be initialized.
397 */
398static int msrProberModifyBasicTests(uint32_t uMsr, uint64_t fSkipMask, bool *pfReadOnly, uint64_t *pfIgnMask, uint64_t *pfGpMask)
399{
400 if (msrProberModifyNoChange(uMsr))
401 {
402 *pfReadOnly = false;
403 *pfIgnMask = 0;
404 *pfGpMask = 0;
405 return msrProberModifyBitChanges(uMsr, pfIgnMask, pfGpMask, fSkipMask);
406 }
407
408 *pfReadOnly = true;
409 *pfIgnMask = 0;
410 *pfGpMask = UINT64_MAX;
411 return VINF_SUCCESS;
412}
413
414
415
416/**
417 * Determines for the MSR AND mask.
418 *
419 * Older CPUs doesn't necessiarly implement all bits of the MSR register number.
420 * So, we have to approximate how many are used so we don't get an overly large
421 * and confusing set of MSRs when probing.
422 *
423 * @returns The mask.
424 */
425static uint32_t determineMsrAndMask(void)
426{
427#define VBCPUREP_MASK_TEST_MSRS 7
428 static uint32_t const s_aMsrs[VBCPUREP_MASK_TEST_MSRS] =
429 {
430 /* Try a bunch of mostly read only registers: */
431 MSR_P5_MC_TYPE, MSR_IA32_PLATFORM_ID, MSR_IA32_MTRR_CAP, MSR_IA32_MCG_CAP, MSR_IA32_CR_PAT,
432 /* Then some which aren't supposed to be present on any CPU: */
433 0x00000015, 0x00000019,
434 };
435
436 /* Get the base values. */
437 uint64_t auBaseValues[VBCPUREP_MASK_TEST_MSRS];
438 for (unsigned i = 0; i < RT_ELEMENTS(s_aMsrs); i++)
439 {
440 if (!msrProberRead(s_aMsrs[i], &auBaseValues[i]))
441 auBaseValues[i] = UINT64_MAX;
442 //vbCpuRepDebug("Base: %#x -> %#llx\n", s_aMsrs[i], auBaseValues[i]);
443 }
444
445 /* Do the probing. */
446 unsigned iBit;
447 for (iBit = 31; iBit > 8; iBit--)
448 {
449 uint64_t fMsrOrMask = RT_BIT_64(iBit);
450 for (unsigned iTest = 0; iTest <= 64 && fMsrOrMask < UINT32_MAX; iTest++)
451 {
452 for (unsigned i = 0; i < RT_ELEMENTS(s_aMsrs); i++)
453 {
454 uint64_t uValue;
455 if (!msrProberRead(s_aMsrs[i] | fMsrOrMask, &uValue))
456 uValue = UINT64_MAX;
457 if (uValue != auBaseValues[i])
458 {
459 uint32_t fMsrMask = iBit >= 31 ? UINT32_MAX : RT_BIT_32(iBit + 1) - 1;
460 vbCpuRepDebug("MSR AND mask: quit on iBit=%u uMsr=%#x (%#x) %llx != %llx => fMsrMask=%#x\n",
461 iBit, s_aMsrs[i] | (uint32_t)fMsrOrMask, s_aMsrs[i], uValue, auBaseValues[i], fMsrMask);
462 return fMsrMask;
463 }
464 }
465
466 /* Advance. */
467 if (iBit <= 6)
468 fMsrOrMask += RT_BIT_64(iBit);
469 else if (iBit <= 11)
470 fMsrOrMask += RT_BIT_64(iBit) * 33;
471 else if (iBit <= 16)
472 fMsrOrMask += RT_BIT_64(iBit) * 1025;
473 else if (iBit <= 22)
474 fMsrOrMask += RT_BIT_64(iBit) * 65537;
475 else
476 fMsrOrMask += RT_BIT_64(iBit) * 262145;
477 }
478 }
479
480 uint32_t fMsrMask = RT_BIT_32(iBit + 1) - 1;
481 vbCpuRepDebug("MSR AND mask: less that %u bits that matters?!? => fMsrMask=%#x\n", iBit + 1, fMsrMask);
482 return fMsrMask;
483}
484
485
486static int findMsrs(VBCPUREPMSR **ppaMsrs, uint32_t *pcMsrs, uint32_t fMsrMask)
487{
488 /*
489 * Gather them.
490 */
491 static struct { uint32_t uFirst, cMsrs; } const s_aRanges[] =
492 {
493 { 0x00000000, 0x00042000 },
494 { 0x10000000, 0x00001000 },
495 { 0x20000000, 0x00001000 },
496 { 0x40000000, 0x00012000 },
497 { 0x80000000, 0x00012000 },
498 { 0xc0000000, 0x00022000 }, /* Had some trouble here on solaris with the tstVMM setup. */
499 };
500
501 *pcMsrs = 0;
502 *ppaMsrs = NULL;
503
504 for (unsigned i = 0; i < RT_ELEMENTS(s_aRanges); i++)
505 {
506 uint32_t uMsr = s_aRanges[i].uFirst;
507 if ((uMsr & fMsrMask) != uMsr)
508 continue;
509 uint32_t cLeft = s_aRanges[i].cMsrs;
510 while (cLeft-- > 0 && (uMsr & fMsrMask) == uMsr)
511 {
512 if ((uMsr & 0xfff) == 0)
513 {
514 vbCpuRepDebug("testing %#x...\n", uMsr);
515 RTThreadSleep(22);
516 }
517#if 0
518 else if (uMsr >= 0x00003170 && uMsr <= 0xc0000090)
519 {
520 vbCpuRepDebug("testing %#x...\n", uMsr);
521 RTThreadSleep(250);
522 }
523#endif
524 /* Skip 0xc0011012..13 as it seems to be bad for our health (Phenom II X6 1100T). */
525 /* Ditto for 0x0000002a (EBL_CR_POWERON) and 0x00000277 (MSR_IA32_CR_PAT) on Intel (Atom 330). */
526 /* And more of the same for 0x280 on Intel Pentium III. */
527 if ( ((uMsr >= 0xc0011012 && uMsr <= 0xc0011013) && g_enmVendor == CPUMCPUVENDOR_AMD)
528 || ( (uMsr == 0x2a || uMsr == 0x277)
529 && g_enmVendor == CPUMCPUVENDOR_INTEL
530 && g_enmMicroarch == kCpumMicroarch_Intel_Atom_Bonnell)
531 || ( (uMsr == 0x280)
532 && g_enmMicroarch == kCpumMicroarch_Intel_P6_III))
533 vbCpuRepDebug("Skipping %#x\n", uMsr);
534 else
535 {
536 /* Read probing normally does it. */
537 uint64_t uValue = 0;
538 bool fGp = true;
539 int rc = g_MsrAcc.pfnMsrProberRead(uMsr, NIL_RTCPUID, &uValue, &fGp);
540 if (RT_FAILURE(rc))
541 {
542 RTMemFree(*ppaMsrs);
543 *ppaMsrs = NULL;
544 return RTMsgErrorRc(rc, "pfnMsrProberRead failed on %#x: %Rrc\n", uMsr, rc);
545 }
546
547 uint32_t fFlags;
548 if (!fGp)
549 fFlags = 0;
550 /* VIA/Shanghai HACK - writing to 0x0000317e on a quad core make the core unresponsive. */
551 else if (uMsr == 0x0000317e && (g_enmVendor == CPUMCPUVENDOR_VIA || g_enmVendor == CPUMCPUVENDOR_SHANGHAI))
552 {
553 uValue = 0;
554 fFlags = VBCPUREPMSR_F_WRITE_ONLY;
555 fGp = *pcMsrs == 0
556 || (*ppaMsrs)[*pcMsrs - 1].uMsr != 0x0000317d
557 || (*ppaMsrs)[*pcMsrs - 1].fFlags != VBCPUREPMSR_F_WRITE_ONLY;
558 }
559 else
560 {
561 /* Is it a write only register? */
562#if 0
563 if (uMsr >= 0x00003170 && uMsr <= 0xc0000090)
564 {
565 vbCpuRepDebug("test writing %#x...\n", uMsr);
566 RTThreadSleep(250);
567 }
568#endif
569 fGp = true;
570 rc = g_MsrAcc.pfnMsrProberWrite(uMsr, NIL_RTCPUID, 0, &fGp);
571 if (RT_FAILURE(rc))
572 {
573 RTMemFree(*ppaMsrs);
574 *ppaMsrs = NULL;
575 return RTMsgErrorRc(rc, "pfnMsrProberWrite failed on %#x: %Rrc\n", uMsr, rc);
576 }
577 uValue = 0;
578 fFlags = VBCPUREPMSR_F_WRITE_ONLY;
579
580 /*
581 * Tweaks. On Intel CPUs we've got trouble detecting
582 * IA32_BIOS_UPDT_TRIG (0x00000079), so we have to add it manually here.
583 * Ditto on AMD with PATCH_LOADER (0xc0010020).
584 */
585 if ( uMsr == 0x00000079
586 && fGp
587 && g_enmMicroarch >= kCpumMicroarch_Intel_P6_Core_Atom_First
588 && g_enmMicroarch <= kCpumMicroarch_Intel_End)
589 fGp = false;
590 if ( uMsr == 0xc0010020
591 && fGp
592 && g_enmMicroarch >= kCpumMicroarch_AMD_K8_First
593 && g_enmMicroarch <= kCpumMicroarch_AMD_End)
594 fGp = false;
595 }
596
597 if (!fGp)
598 {
599 /* Add it. */
600 rc = vbCpuRepMsrsAddOne(ppaMsrs, pcMsrs, uMsr, uValue, fFlags);
601 if (RT_FAILURE(rc))
602 return RTMsgErrorRc(rc, "Out of memory (uMsr=%#x).\n", uMsr);
603 if ( (g_enmVendor != CPUMCPUVENDOR_VIA && g_enmVendor != CPUMCPUVENDOR_SHANGHAI)
604 || uValue
605 || fFlags)
606 vbCpuRepDebug("%#010x: uValue=%#llx fFlags=%#x\n", uMsr, uValue, fFlags);
607 }
608 }
609
610 uMsr++;
611 }
612 }
613
614 return VINF_SUCCESS;
615}
616
617/**
618 * Get the name of the specified MSR, if we know it and can handle it.
619 *
620 * Do _NOT_ add any new names here without ALSO at the SAME TIME making sure it
621 * is handled correctly by the PROBING CODE and REPORTED correctly!!
622 *
623 * @returns Pointer to name if handled, NULL if not yet explored.
624 * @param uMsr The MSR in question.
625 */
626static const char *getMsrNameHandled(uint32_t uMsr)
627{
628 /** @todo figure out where NCU_EVENT_CORE_MASK might be... */
629 switch (uMsr)
630 {
631 case 0x00000000: return "IA32_P5_MC_ADDR";
632 case 0x00000001: return "IA32_P5_MC_TYPE";
633 case 0x00000006:
634 if (g_enmMicroarch >= kCpumMicroarch_Intel_First && g_enmMicroarch <= kCpumMicroarch_Intel_P6_Core_Atom_First)
635 return NULL; /* TR4 / cache tag on Pentium, but that's for later. */
636 return "IA32_MONITOR_FILTER_LINE_SIZE";
637 //case 0x0000000e: return "P?_TR12"; /* K6-III docs */
638 case 0x00000010: return "IA32_TIME_STAMP_COUNTER";
639 case 0x00000017: return "IA32_PLATFORM_ID";
640 case 0x00000018: return "P6_UNK_0000_0018"; /* P6_M_Dothan. */
641 case 0x0000001b: return "IA32_APIC_BASE";
642 case 0x00000021: return "C2_UNK_0000_0021"; /* Core2_Penryn */
643 case 0x0000002a: return g_fIntelNetBurst ? "P4_EBC_HARD_POWERON" : "EBL_CR_POWERON";
644 case 0x0000002b: return g_fIntelNetBurst ? "P4_EBC_SOFT_POWERON" : NULL;
645 case 0x0000002c: return g_fIntelNetBurst ? "P4_EBC_FREQUENCY_ID" : NULL;
646 case 0x0000002e: return "I7_UNK_0000_002e"; /* SandyBridge, IvyBridge. */
647 case 0x0000002f: return "P6_UNK_0000_002f"; /* P6_M_Dothan. */
648 case 0x00000032: return "P6_UNK_0000_0032"; /* P6_M_Dothan. */
649 case 0x00000033: return "TEST_CTL";
650 case 0x00000034: return CPUMMICROARCH_IS_INTEL_CORE7(g_enmMicroarch)
651 || CPUMMICROARCH_IS_INTEL_SILVERMONT_PLUS(g_enmMicroarch)
652 ? "MSR_SMI_COUNT" : "P6_UNK_0000_0034"; /* P6_M_Dothan. */
653 case 0x00000035: return CPUMMICROARCH_IS_INTEL_CORE7(g_enmMicroarch) ? "MSR_CORE_THREAD_COUNT" : "P6_UNK_0000_0035"; /* P6_M_Dothan. */
654 case 0x00000036: return "I7_UNK_0000_0036"; /* SandyBridge, IvyBridge. */
655 case 0x00000039: return "C2_UNK_0000_0039"; /* Core2_Penryn */
656 case 0x0000003a: return "IA32_FEATURE_CONTROL";
657 case 0x0000003b: return "P6_UNK_0000_003b"; /* P6_M_Dothan. */
658 case 0x0000003e: return "I7_UNK_0000_003e"; /* SandyBridge, IvyBridge. */
659 case 0x0000003f: return "P6_UNK_0000_003f"; /* P6_M_Dothan. */
660 case 0x00000040: return g_enmMicroarch >= kCpumMicroarch_Intel_Core_Yonah ? "MSR_LASTBRANCH_0_FROM_IP" : "MSR_LASTBRANCH_0";
661 case 0x00000041: return g_enmMicroarch >= kCpumMicroarch_Intel_Core_Yonah ? "MSR_LASTBRANCH_1_FROM_IP" : "MSR_LASTBRANCH_1";
662 case 0x00000042: return g_enmMicroarch >= kCpumMicroarch_Intel_Core_Yonah ? "MSR_LASTBRANCH_2_FROM_IP" : "MSR_LASTBRANCH_2";
663 case 0x00000043: return g_enmMicroarch >= kCpumMicroarch_Intel_Core_Yonah ? "MSR_LASTBRANCH_3_FROM_IP" : "MSR_LASTBRANCH_3";
664 case 0x00000044: return g_enmMicroarch >= kCpumMicroarch_Intel_Core_Yonah ? "MSR_LASTBRANCH_4_FROM_IP" : "MSR_LASTBRANCH_4";
665 case 0x00000045: return g_enmMicroarch >= kCpumMicroarch_Intel_Core_Yonah ? "MSR_LASTBRANCH_5_FROM_IP" : "MSR_LASTBRANCH_5";
666 case 0x00000046: return g_enmMicroarch >= kCpumMicroarch_Intel_Core_Yonah ? "MSR_LASTBRANCH_6_FROM_IP" : "MSR_LASTBRANCH_6";
667 case 0x00000047: return g_enmMicroarch >= kCpumMicroarch_Intel_Core_Yonah ? "MSR_LASTBRANCH_7_FROM_IP" : "MSR_LASTBRANCH_7";
668 case 0x00000048: return "MSR_LASTBRANCH_8"; /*??*/
669 case 0x00000049: return "MSR_LASTBRANCH_9"; /*??*/
670 case 0x0000004a: return "P6_UNK_0000_004a"; /* P6_M_Dothan. */
671 case 0x0000004b: return "P6_UNK_0000_004b"; /* P6_M_Dothan. */
672 case 0x0000004c: return "P6_UNK_0000_004c"; /* P6_M_Dothan. */
673 case 0x0000004d: return "P6_UNK_0000_004d"; /* P6_M_Dothan. */
674 case 0x0000004e: return "P6_UNK_0000_004e"; /* P6_M_Dothan. */
675 case 0x0000004f: return "P6_UNK_0000_004f"; /* P6_M_Dothan. */
676 case 0x00000050: return "P6_UNK_0000_0050"; /* P6_M_Dothan. */
677 case 0x00000051: return "P6_UNK_0000_0051"; /* P6_M_Dothan. */
678 case 0x00000052: return "P6_UNK_0000_0052"; /* P6_M_Dothan. */
679 case 0x00000053: return "P6_UNK_0000_0053"; /* P6_M_Dothan. */
680 case 0x00000054: return "P6_UNK_0000_0054"; /* P6_M_Dothan. */
681 case 0x00000060: return "MSR_LASTBRANCH_0_TO_IP"; /* Core2_Penryn */
682 case 0x00000061: return "MSR_LASTBRANCH_1_TO_IP"; /* Core2_Penryn */
683 case 0x00000062: return "MSR_LASTBRANCH_2_TO_IP"; /* Core2_Penryn */
684 case 0x00000063: return "MSR_LASTBRANCH_3_TO_IP"; /* Core2_Penryn */
685 case 0x00000064: return "MSR_LASTBRANCH_4_TO_IP"; /* Atom? */
686 case 0x00000065: return "MSR_LASTBRANCH_5_TO_IP";
687 case 0x00000066: return "MSR_LASTBRANCH_6_TO_IP";
688 case 0x00000067: return "MSR_LASTBRANCH_7_TO_IP";
689 case 0x0000006c: return "P6_UNK_0000_006c"; /* P6_M_Dothan. */
690 case 0x0000006d: return "P6_UNK_0000_006d"; /* P6_M_Dothan. */
691 case 0x0000006e: return "P6_UNK_0000_006e"; /* P6_M_Dothan. */
692 case 0x0000006f: return "P6_UNK_0000_006f"; /* P6_M_Dothan. */
693 case 0x00000079: return "IA32_BIOS_UPDT_TRIG";
694 case 0x00000080: return "P4_UNK_0000_0080";
695 case 0x00000088: return "BBL_CR_D0";
696 case 0x00000089: return "BBL_CR_D1";
697 case 0x0000008a: return "BBL_CR_D2";
698 case 0x0000008b: return g_enmVendor == CPUMCPUVENDOR_AMD ? "AMD_K8_PATCH_LEVEL"
699 : g_fIntelNetBurst ? "IA32_BIOS_SIGN_ID" : "BBL_CR_D3|BIOS_SIGN";
700 case 0x0000008c: return "P6_UNK_0000_008c"; /* P6_M_Dothan. */
701 case 0x0000008d: return "P6_UNK_0000_008d"; /* P6_M_Dothan. */
702 case 0x0000008e: return "P6_UNK_0000_008e"; /* P6_M_Dothan. */
703 case 0x0000008f: return "P6_UNK_0000_008f"; /* P6_M_Dothan. */
704 case 0x00000090: return "P6_UNK_0000_0090"; /* P6_M_Dothan. */
705 case 0x0000009b: return "IA32_SMM_MONITOR_CTL";
706 case 0x000000a8: return "C2_EMTTM_CR_TABLES_0";
707 case 0x000000a9: return "C2_EMTTM_CR_TABLES_1";
708 case 0x000000aa: return "C2_EMTTM_CR_TABLES_2";
709 case 0x000000ab: return "C2_EMTTM_CR_TABLES_3";
710 case 0x000000ac: return "C2_EMTTM_CR_TABLES_4";
711 case 0x000000ad: return "C2_EMTTM_CR_TABLES_5";
712 case 0x000000ae: return "P6_UNK_0000_00ae"; /* P6_M_Dothan. */
713 case 0x000000c1: return "IA32_PMC0";
714 case 0x000000c2: return "IA32_PMC1";
715 case 0x000000c3: return "IA32_PMC2";
716 case 0x000000c4: return "IA32_PMC3";
717 /* PMC4+ first seen on SandyBridge. The earlier cut off is just to be
718 on the safe side as we must avoid P6_M_Dothan and possibly others. */
719 case 0x000000c5: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_First ? "IA32_PMC4" : NULL;
720 case 0x000000c6: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_First ? "IA32_PMC5" : NULL;
721 case 0x000000c7: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_First ? "IA32_PMC6" : "P6_UNK_0000_00c7"; /* P6_M_Dothan. */
722 case 0x000000c8: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_First ? "IA32_PMC7" : NULL;
723 case 0x000000cd: return "MSR_FSB_FREQ"; /* P6_M_Dothan. */
724 case 0x000000ce: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_First ? "IA32_PLATFORM_INFO" : "P6_UNK_0000_00ce"; /* P6_M_Dothan. */
725 case 0x000000cf: return "C2_UNK_0000_00cf"; /* Core2_Penryn. */
726 case 0x000000e0: return "C2_UNK_0000_00e0"; /* Core2_Penryn. */
727 case 0x000000e1: return "C2_UNK_0000_00e1"; /* Core2_Penryn. */
728 case 0x000000e2: return "MSR_PKG_CST_CONFIG_CONTROL";
729 case 0x000000e3: return "C2_SMM_CST_MISC_INFO"; /* Core2_Penryn. */
730 case 0x000000e4: return "MSR_PMG_IO_CAPTURE_BASE";
731 case 0x000000e5: return "C2_UNK_0000_00e5"; /* Core2_Penryn. */
732 case 0x000000e7: return "IA32_MPERF";
733 case 0x000000e8: return "IA32_APERF";
734 case 0x000000ee: return "C1_EXT_CONFIG"; /* Core2_Penryn. msrtool lists it for Core1 as well. */
735 case 0x000000fe: return "IA32_MTRRCAP";
736 case 0x00000102: return "I7_IB_UNK_0000_0102"; /* IvyBridge. */
737 case 0x00000103: return "I7_IB_UNK_0000_0103"; /* IvyBridge. */
738 case 0x00000104: return "I7_IB_UNK_0000_0104"; /* IvyBridge. */
739 case 0x00000116: return "BBL_CR_ADDR";
740 case 0x00000118: return "BBL_CR_DECC";
741 case 0x00000119: return "BBL_CR_CTL";
742 case 0x0000011a: return "BBL_CR_TRIG";
743 case 0x0000011b: return "P6_UNK_0000_011b"; /* P6_M_Dothan. */
744 case 0x0000011c: return "C2_UNK_0000_011c"; /* Core2_Penryn. */
745 case 0x0000011e: return "BBL_CR_CTL3";
746 case 0x00000120: return "SILV_UNK_0000_0120"; /* Silvermont */
747 case 0x00000130: return g_enmMicroarch == kCpumMicroarch_Intel_Core7_Westmere
748 || g_enmMicroarch == kCpumMicroarch_Intel_Core7_Nehalem
749 ? "CPUID1_FEATURE_MASK" : NULL;
750 case 0x00000131: return g_enmMicroarch == kCpumMicroarch_Intel_Core7_Westmere
751 || g_enmMicroarch == kCpumMicroarch_Intel_Core7_Nehalem
752 ? "CPUID80000001_FEATURE_MASK" : "P6_UNK_0000_0131" /* P6_M_Dothan. */;
753 case 0x00000132: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge
754 ? "CPUID1_FEATURE_MASK" : NULL;
755 case 0x00000133: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge
756 ? "CPUIDD_01_FEATURE_MASK" : NULL;
757 case 0x00000134: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge
758 ? "CPUID80000001_FEATURE_MASK" : NULL;
759 case 0x0000013c: return "I7_SB_AES_NI_CTL"; /* SandyBridge. Bit 0 is lock bit, bit 1 disables AES-NI. */
760 case 0x00000140: return "I7_IB_UNK_0000_0140"; /* IvyBridge. */
761 case 0x00000142: return "I7_IB_UNK_0000_0142"; /* IvyBridge. */
762 case 0x0000014e: return "P6_UNK_0000_014e"; /* P6_M_Dothan. */
763 case 0x0000014f: return "P6_UNK_0000_014f"; /* P6_M_Dothan. */
764 case 0x00000150: return "P6_UNK_0000_0150"; /* P6_M_Dothan. */
765 case 0x00000151: return "P6_UNK_0000_0151"; /* P6_M_Dothan. */
766 case 0x00000154: return "P6_UNK_0000_0154"; /* P6_M_Dothan. */
767 case 0x0000015b: return "P6_UNK_0000_015b"; /* P6_M_Dothan. */
768 case 0x0000015e: return "C2_UNK_0000_015e"; /* Core2_Penryn. */
769 case 0x0000015f: return "C1_DTS_CAL_CTRL"; /* Core2_Penryn. msrtool only docs this for core1! */
770 case 0x00000174: return "IA32_SYSENTER_CS";
771 case 0x00000175: return "IA32_SYSENTER_ESP";
772 case 0x00000176: return "IA32_SYSENTER_EIP";
773 case 0x00000179: return "IA32_MCG_CAP";
774 case 0x0000017a: return "IA32_MCG_STATUS";
775 case 0x0000017b: return "IA32_MCG_CTL";
776 case 0x0000017f: return "I7_SB_ERROR_CONTROL"; /* SandyBridge. */
777 case 0x00000180: return g_fIntelNetBurst ? "MSR_MCG_RAX" : NULL;
778 case 0x00000181: return g_fIntelNetBurst ? "MSR_MCG_RBX" : NULL;
779 case 0x00000182: return g_fIntelNetBurst ? "MSR_MCG_RCX" : NULL;
780 case 0x00000183: return g_fIntelNetBurst ? "MSR_MCG_RDX" : NULL;
781 case 0x00000184: return g_fIntelNetBurst ? "MSR_MCG_RSI" : NULL;
782 case 0x00000185: return g_fIntelNetBurst ? "MSR_MCG_RDI" : NULL;
783 case 0x00000186: return g_fIntelNetBurst ? "MSR_MCG_RBP" : "IA32_PERFEVTSEL0";
784 case 0x00000187: return g_fIntelNetBurst ? "MSR_MCG_RSP" : "IA32_PERFEVTSEL1";
785 case 0x00000188: return g_fIntelNetBurst ? "MSR_MCG_RFLAGS" : "IA32_PERFEVTSEL2";
786 case 0x00000189: return g_fIntelNetBurst ? "MSR_MCG_RIP" : "IA32_PERFEVTSEL3";
787 case 0x0000018a: return g_fIntelNetBurst ? "MSR_MCG_MISC" : "IA32_PERFEVTSEL4";
788 case 0x0000018b: return g_fIntelNetBurst ? "MSR_MCG_RESERVED1" : "IA32_PERFEVTSEL5";
789 case 0x0000018c: return g_fIntelNetBurst ? "MSR_MCG_RESERVED2" : "IA32_PERFEVTSEL6";
790 case 0x0000018d: return g_fIntelNetBurst ? "MSR_MCG_RESERVED3" : "IA32_PERFEVTSEL7";
791 case 0x0000018e: return g_fIntelNetBurst ? "MSR_MCG_RESERVED4" : "IA32_PERFEVTSEL8";
792 case 0x0000018f: return g_fIntelNetBurst ? "MSR_MCG_RESERVED5" : "IA32_PERFEVTSEL9";
793 case 0x00000190: return g_fIntelNetBurst ? "MSR_MCG_R8" : NULL;
794 case 0x00000191: return g_fIntelNetBurst ? "MSR_MCG_R9" : NULL;
795 case 0x00000192: return g_fIntelNetBurst ? "MSR_MCG_R10" : NULL;
796 case 0x00000193: return g_fIntelNetBurst ? "MSR_MCG_R11" : "C2_UNK_0000_0193";
797 case 0x00000194: return g_fIntelNetBurst ? "MSR_MCG_R12" : "CLOCK_FLEX_MAX";
798 case 0x00000195: return g_fIntelNetBurst ? "MSR_MCG_R13" : NULL;
799 case 0x00000196: return g_fIntelNetBurst ? "MSR_MCG_R14" : NULL;
800 case 0x00000197: return g_fIntelNetBurst ? "MSR_MCG_R15" : NULL;
801 case 0x00000198: return "IA32_PERF_STATUS";
802 case 0x00000199: return "IA32_PERF_CTL";
803 case 0x0000019a: return "IA32_CLOCK_MODULATION";
804 case 0x0000019b: return "IA32_THERM_INTERRUPT";
805 case 0x0000019c: return "IA32_THERM_STATUS";
806 case 0x0000019d: return "IA32_THERM2_CTL";
807 case 0x0000019e: return "P6_UNK_0000_019e"; /* P6_M_Dothan. */
808 case 0x0000019f: return "P6_UNK_0000_019f"; /* P6_M_Dothan. */
809 case 0x000001a0: return "IA32_MISC_ENABLE";
810 case 0x000001a1: return g_fIntelNetBurst ? "MSR_PLATFORM_BRV" : "P6_UNK_0000_01a1" /* P6_M_Dothan. */;
811 case 0x000001a2: return g_fIntelNetBurst ? "P4_UNK_0000_01a2" : "I7_MSR_TEMPERATURE_TARGET" /* SandyBridge, IvyBridge. */;
812 case 0x000001a4: return "I7_UNK_0000_01a4"; /* SandyBridge, IvyBridge. */
813 case 0x000001a6: return "I7_MSR_OFFCORE_RSP_0";
814 case 0x000001a7: return "I7_MSR_OFFCORE_RSP_1";
815 case 0x000001a8: return "I7_UNK_0000_01a8"; /* SandyBridge, IvyBridge. */
816 case 0x000001aa: return CPUMMICROARCH_IS_INTEL_CORE7(g_enmMicroarch) ? "MSR_MISC_PWR_MGMT" : "P6_PIC_SENS_CFG" /* Pentium M. */;
817 case 0x000001ad: return "I7_MSR_TURBO_RATIO_LIMIT"; /* SandyBridge+, Silvermount+ */
818 case 0x000001ae: return "P6_UNK_0000_01ae"; /* P6_M_Dothan. */
819 case 0x000001af: return "P6_UNK_0000_01af"; /* P6_M_Dothan. */
820 case 0x000001b0: return "IA32_ENERGY_PERF_BIAS";
821 case 0x000001b1: return "IA32_PACKAGE_THERM_STATUS";
822 case 0x000001b2: return "IA32_PACKAGE_THERM_INTERRUPT";
823 case 0x000001bf: return "C2_UNK_0000_01bf"; /* Core2_Penryn. */
824 case 0x000001c6: return "I7_UNK_0000_01c6"; /* SandyBridge*/
825 case 0x000001c8: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_Nehalem ? "MSR_LBR_SELECT" : NULL;
826 case 0x000001c9: return g_enmMicroarch >= kCpumMicroarch_Intel_Core_Yonah
827 && g_enmMicroarch <= kCpumMicroarch_Intel_P6_Core_Atom_End
828 ? "MSR_LASTBRANCH_TOS" : NULL /* Pentium M Dothan seems to have something else here. */;
829 case 0x000001d3: return "P6_UNK_0000_01d3"; /* P6_M_Dothan. */
830 case 0x000001d7: return g_fIntelNetBurst ? "MSR_LER_FROM_LIP" : NULL;
831 case 0x000001d8: return g_fIntelNetBurst ? "MSR_LER_TO_LIP" : NULL;
832 case 0x000001d9: return "IA32_DEBUGCTL";
833 case 0x000001da: return g_fIntelNetBurst ? "MSR_LASTBRANCH_TOS" : NULL;
834 case 0x000001db: return g_fIntelNetBurst ? "P6_LASTBRANCH_0" : "P6_LAST_BRANCH_FROM_IP"; /* Not exclusive to P6, also AMD. */
835 case 0x000001dc: return g_fIntelNetBurst ? "P6_LASTBRANCH_1" : "P6_LAST_BRANCH_TO_IP";
836 case 0x000001dd: return g_fIntelNetBurst ? "P6_LASTBRANCH_2" : "P6_LAST_INT_FROM_IP";
837 case 0x000001de: return g_fIntelNetBurst ? "P6_LASTBRANCH_3" : "P6_LAST_INT_TO_IP";
838 case 0x000001e0: return "MSR_ROB_CR_BKUPTMPDR6";
839 case 0x000001e1: return "I7_SB_UNK_0000_01e1";
840 case 0x000001ef: return "I7_SB_UNK_0000_01ef";
841 case 0x000001f0: return "I7_VLW_CAPABILITY"; /* SandyBridge. Bit 1 is A20M and was implemented incorrectly (AAJ49). */
842 case 0x000001f2: return "IA32_SMRR_PHYSBASE";
843 case 0x000001f3: return "IA32_SMRR_PHYSMASK";
844 case 0x000001f8: return "IA32_PLATFORM_DCA_CAP";
845 case 0x000001f9: return "IA32_CPU_DCA_CAP";
846 case 0x000001fa: return "IA32_DCA_0_CAP";
847 case 0x000001fc: return "I7_MSR_POWER_CTL";
848
849 case 0x00000200: return "IA32_MTRR_PHYS_BASE0";
850 case 0x00000202: return "IA32_MTRR_PHYS_BASE1";
851 case 0x00000204: return "IA32_MTRR_PHYS_BASE2";
852 case 0x00000206: return "IA32_MTRR_PHYS_BASE3";
853 case 0x00000208: return "IA32_MTRR_PHYS_BASE4";
854 case 0x0000020a: return "IA32_MTRR_PHYS_BASE5";
855 case 0x0000020c: return "IA32_MTRR_PHYS_BASE6";
856 case 0x0000020e: return "IA32_MTRR_PHYS_BASE7";
857 case 0x00000210: return "IA32_MTRR_PHYS_BASE8";
858 case 0x00000212: return "IA32_MTRR_PHYS_BASE9";
859 case 0x00000214: return "IA32_MTRR_PHYS_BASE10";
860 case 0x00000216: return "IA32_MTRR_PHYS_BASE11";
861 case 0x00000218: return "IA32_MTRR_PHYS_BASE12";
862 case 0x0000021a: return "IA32_MTRR_PHYS_BASE13";
863 case 0x0000021c: return "IA32_MTRR_PHYS_BASE14";
864 case 0x0000021e: return "IA32_MTRR_PHYS_BASE15";
865
866 case 0x00000201: return "IA32_MTRR_PHYS_MASK0";
867 case 0x00000203: return "IA32_MTRR_PHYS_MASK1";
868 case 0x00000205: return "IA32_MTRR_PHYS_MASK2";
869 case 0x00000207: return "IA32_MTRR_PHYS_MASK3";
870 case 0x00000209: return "IA32_MTRR_PHYS_MASK4";
871 case 0x0000020b: return "IA32_MTRR_PHYS_MASK5";
872 case 0x0000020d: return "IA32_MTRR_PHYS_MASK6";
873 case 0x0000020f: return "IA32_MTRR_PHYS_MASK7";
874 case 0x00000211: return "IA32_MTRR_PHYS_MASK8";
875 case 0x00000213: return "IA32_MTRR_PHYS_MASK9";
876 case 0x00000215: return "IA32_MTRR_PHYS_MASK10";
877 case 0x00000217: return "IA32_MTRR_PHYS_MASK11";
878 case 0x00000219: return "IA32_MTRR_PHYS_MASK12";
879 case 0x0000021b: return "IA32_MTRR_PHYS_MASK13";
880 case 0x0000021d: return "IA32_MTRR_PHYS_MASK14";
881 case 0x0000021f: return "IA32_MTRR_PHYS_MASK15";
882
883 case 0x00000250: return "IA32_MTRR_FIX64K_00000";
884 case 0x00000258: return "IA32_MTRR_FIX16K_80000";
885 case 0x00000259: return "IA32_MTRR_FIX16K_A0000";
886 case 0x00000268: return "IA32_MTRR_FIX4K_C0000";
887 case 0x00000269: return "IA32_MTRR_FIX4K_C8000";
888 case 0x0000026a: return "IA32_MTRR_FIX4K_D0000";
889 case 0x0000026b: return "IA32_MTRR_FIX4K_D8000";
890 case 0x0000026c: return "IA32_MTRR_FIX4K_E0000";
891 case 0x0000026d: return "IA32_MTRR_FIX4K_E8000";
892 case 0x0000026e: return "IA32_MTRR_FIX4K_F0000";
893 case 0x0000026f: return "IA32_MTRR_FIX4K_F8000";
894 case 0x00000277: return "IA32_PAT";
895 case 0x00000280: return "IA32_MC0_CTL2";
896 case 0x00000281: return "IA32_MC1_CTL2";
897 case 0x00000282: return "IA32_MC2_CTL2";
898 case 0x00000283: return "IA32_MC3_CTL2";
899 case 0x00000284: return "IA32_MC4_CTL2";
900 case 0x00000285: return "IA32_MC5_CTL2";
901 case 0x00000286: return "IA32_MC6_CTL2";
902 case 0x00000287: return "IA32_MC7_CTL2";
903 case 0x00000288: return "IA32_MC8_CTL2";
904 case 0x00000289: return "IA32_MC9_CTL2";
905 case 0x0000028a: return "IA32_MC10_CTL2";
906 case 0x0000028b: return "IA32_MC11_CTL2";
907 case 0x0000028c: return "IA32_MC12_CTL2";
908 case 0x0000028d: return "IA32_MC13_CTL2";
909 case 0x0000028e: return "IA32_MC14_CTL2";
910 case 0x0000028f: return "IA32_MC15_CTL2";
911 case 0x00000290: return "IA32_MC16_CTL2";
912 case 0x00000291: return "IA32_MC17_CTL2";
913 case 0x00000292: return "IA32_MC18_CTL2";
914 case 0x00000293: return "IA32_MC19_CTL2";
915 case 0x00000294: return "IA32_MC20_CTL2";
916 case 0x00000295: return "IA32_MC21_CTL2";
917 //case 0x00000296: return "IA32_MC22_CTL2";
918 //case 0x00000297: return "IA32_MC23_CTL2";
919 //case 0x00000298: return "IA32_MC24_CTL2";
920 //case 0x00000299: return "IA32_MC25_CTL2";
921 //case 0x0000029a: return "IA32_MC26_CTL2";
922 //case 0x0000029b: return "IA32_MC27_CTL2";
923 //case 0x0000029c: return "IA32_MC28_CTL2";
924 //case 0x0000029d: return "IA32_MC29_CTL2";
925 //case 0x0000029e: return "IA32_MC30_CTL2";
926 //case 0x0000029f: return "IA32_MC31_CTL2";
927 case 0x000002e0: return "I7_SB_NO_EVICT_MODE"; /* (Bits 1 & 0 are said to have something to do with no-evict cache mode used during early boot.) */
928 case 0x000002e6: return "I7_IB_UNK_0000_02e6"; /* IvyBridge */
929 case 0x000002e7: return "I7_IB_UNK_0000_02e7"; /* IvyBridge */
930 case 0x000002ff: return "IA32_MTRR_DEF_TYPE";
931 case 0x00000300: return g_fIntelNetBurst ? "P4_MSR_BPU_COUNTER0" : "I7_SB_UNK_0000_0300" /* SandyBridge */;
932 case 0x00000301: return g_fIntelNetBurst ? "P4_MSR_BPU_COUNTER1" : NULL;
933 case 0x00000302: return g_fIntelNetBurst ? "P4_MSR_BPU_COUNTER2" : NULL;
934 case 0x00000303: return g_fIntelNetBurst ? "P4_MSR_BPU_COUNTER3" : NULL;
935 case 0x00000304: return g_fIntelNetBurst ? "P4_MSR_MS_COUNTER0" : NULL;
936 case 0x00000305: return g_fIntelNetBurst ? "P4_MSR_MS_COUNTER1" : "I7_SB_UNK_0000_0305" /* SandyBridge, IvyBridge */;
937 case 0x00000306: return g_fIntelNetBurst ? "P4_MSR_MS_COUNTER2" : NULL;
938 case 0x00000307: return g_fIntelNetBurst ? "P4_MSR_MS_COUNTER3" : NULL;
939 case 0x00000308: return g_fIntelNetBurst ? "P4_MSR_FLAME_COUNTER0" : NULL;
940 case 0x00000309: return g_fIntelNetBurst ? "P4_MSR_FLAME_COUNTER1" : "IA32_FIXED_CTR0";
941 case 0x0000030a: return g_fIntelNetBurst ? "P4_MSR_FLAME_COUNTER2" : "IA32_FIXED_CTR1";
942 case 0x0000030b: return g_fIntelNetBurst ? "P4_MSR_FLAME_COUNTER3" : "IA32_FIXED_CTR2";
943 case 0x0000030c: return g_fIntelNetBurst ? "P4_MSR_IQ_COUNTER0" : NULL;
944 case 0x0000030d: return g_fIntelNetBurst ? "P4_MSR_IQ_COUNTER1" : NULL;
945 case 0x0000030e: return g_fIntelNetBurst ? "P4_MSR_IQ_COUNTER2" : NULL;
946 case 0x0000030f: return g_fIntelNetBurst ? "P4_MSR_IQ_COUNTER3" : NULL;
947 case 0x00000310: return g_fIntelNetBurst ? "P4_MSR_IQ_COUNTER4" : NULL;
948 case 0x00000311: return g_fIntelNetBurst ? "P4_MSR_IQ_COUNTER5" : NULL;
949 case 0x00000345: return "IA32_PERF_CAPABILITIES";
950 case 0x00000360: return g_fIntelNetBurst ? "P4_MSR_BPU_CCCR0" : NULL;
951 case 0x00000361: return g_fIntelNetBurst ? "P4_MSR_BPU_CCCR1" : NULL;
952 case 0x00000362: return g_fIntelNetBurst ? "P4_MSR_BPU_CCCR2" : NULL;
953 case 0x00000363: return g_fIntelNetBurst ? "P4_MSR_BPU_CCCR3" : NULL;
954 case 0x00000364: return g_fIntelNetBurst ? "P4_MSR_MS_CCCR0" : NULL;
955 case 0x00000365: return g_fIntelNetBurst ? "P4_MSR_MS_CCCR1" : NULL;
956 case 0x00000366: return g_fIntelNetBurst ? "P4_MSR_MS_CCCR2" : NULL;
957 case 0x00000367: return g_fIntelNetBurst ? "P4_MSR_MS_CCCR3" : NULL;
958 case 0x00000368: return g_fIntelNetBurst ? "P4_MSR_FLAME_CCCR0" : NULL;
959 case 0x00000369: return g_fIntelNetBurst ? "P4_MSR_FLAME_CCCR1" : NULL;
960 case 0x0000036a: return g_fIntelNetBurst ? "P4_MSR_FLAME_CCCR2" : NULL;
961 case 0x0000036b: return g_fIntelNetBurst ? "P4_MSR_FLAME_CCCR3" : NULL;
962 case 0x0000036c: return g_fIntelNetBurst ? "P4_MSR_IQ_CCCR0" : NULL;
963 case 0x0000036d: return g_fIntelNetBurst ? "P4_MSR_IQ_CCCR1" : NULL;
964 case 0x0000036e: return g_fIntelNetBurst ? "P4_MSR_IQ_CCCR2" : NULL;
965 case 0x0000036f: return g_fIntelNetBurst ? "P4_MSR_IQ_CCCR3" : NULL;
966 case 0x00000370: return g_fIntelNetBurst ? "P4_MSR_IQ_CCCR4" : NULL;
967 case 0x00000371: return g_fIntelNetBurst ? "P4_MSR_IQ_CCCR5" : NULL;
968 case 0x0000038d: return "IA32_FIXED_CTR_CTRL";
969 case 0x0000038e: return "IA32_PERF_GLOBAL_STATUS";
970 case 0x0000038f: return "IA32_PERF_GLOBAL_CTRL";
971 case 0x00000390: return "IA32_PERF_GLOBAL_OVF_CTRL";
972 case 0x00000391: return "I7_UNC_PERF_GLOBAL_CTRL"; /* S,H,X */
973 case 0x00000392: return "I7_UNC_PERF_GLOBAL_STATUS"; /* S,H,X */
974 case 0x00000393: return "I7_UNC_PERF_GLOBAL_OVF_CTRL"; /* X. ASSUMING this is the same on sandybridge and later. */
975 case 0x00000394: return g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "I7_UNC_PERF_FIXED_CTR" /* X */ : "I7_UNC_PERF_FIXED_CTR_CTRL"; /* >= S,H */
976 case 0x00000395: return g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "I7_UNC_PERF_FIXED_CTR_CTRL" /* X*/ : "I7_UNC_PERF_FIXED_CTR"; /* >= S,H */
977 case 0x00000396: return g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "I7_UNC_ADDR_OPCODE_MATCH" /* X */ : "I7_UNC_CBO_CONFIG"; /* >= S,H */
978 case 0x00000397: return g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? NULL : "I7_SB_UNK_0000_0397";
979 case 0x0000039c: return "I7_SB_MSR_PEBS_NUM_ALT";
980 case 0x000003a0: return g_fIntelNetBurst ? "P4_MSR_BSU_ESCR0" : NULL;
981 case 0x000003a1: return g_fIntelNetBurst ? "P4_MSR_BSU_ESCR1" : NULL;
982 case 0x000003a2: return g_fIntelNetBurst ? "P4_MSR_FSB_ESCR0" : NULL;
983 case 0x000003a3: return g_fIntelNetBurst ? "P4_MSR_FSB_ESCR1" : NULL;
984 case 0x000003a4: return g_fIntelNetBurst ? "P4_MSR_FIRM_ESCR0" : NULL;
985 case 0x000003a5: return g_fIntelNetBurst ? "P4_MSR_FIRM_ESCR1" : NULL;
986 case 0x000003a6: return g_fIntelNetBurst ? "P4_MSR_FLAME_ESCR0" : NULL;
987 case 0x000003a7: return g_fIntelNetBurst ? "P4_MSR_FLAME_ESCR1" : NULL;
988 case 0x000003a8: return g_fIntelNetBurst ? "P4_MSR_DAC_ESCR0" : NULL;
989 case 0x000003a9: return g_fIntelNetBurst ? "P4_MSR_DAC_ESCR1" : NULL;
990 case 0x000003aa: return g_fIntelNetBurst ? "P4_MSR_MOB_ESCR0" : NULL;
991 case 0x000003ab: return g_fIntelNetBurst ? "P4_MSR_MOB_ESCR1" : NULL;
992 case 0x000003ac: return g_fIntelNetBurst ? "P4_MSR_PMH_ESCR0" : NULL;
993 case 0x000003ad: return g_fIntelNetBurst ? "P4_MSR_PMH_ESCR1" : NULL;
994 case 0x000003ae: return g_fIntelNetBurst ? "P4_MSR_SAAT_ESCR0" : NULL;
995 case 0x000003af: return g_fIntelNetBurst ? "P4_MSR_SAAT_ESCR1" : NULL;
996 case 0x000003b0: return g_fIntelNetBurst ? "P4_MSR_U2L_ESCR0" : g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "I7_UNC_PMC0" /* X */ : "I7_UNC_ARB_PERF_CTR0"; /* >= S,H */
997 case 0x000003b1: return g_fIntelNetBurst ? "P4_MSR_U2L_ESCR1" : g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "I7_UNC_PMC1" /* X */ : "I7_UNC_ARB_PERF_CTR1"; /* >= S,H */
998 case 0x000003b2: return g_fIntelNetBurst ? "P4_MSR_BPU_ESCR0" : g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "I7_UNC_PMC2" /* X */ : "I7_UNC_ARB_PERF_EVT_SEL0"; /* >= S,H */
999 case 0x000003b3: return g_fIntelNetBurst ? "P4_MSR_BPU_ESCR1" : g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "I7_UNC_PMC3" /* X */ : "I7_UNC_ARB_PERF_EVT_SEL1"; /* >= S,H */
1000 case 0x000003b4: return g_fIntelNetBurst ? "P4_MSR_IS_ESCR0" : "I7_UNC_PMC4";
1001 case 0x000003b5: return g_fIntelNetBurst ? "P4_MSR_IS_ESCR1" : "I7_UNC_PMC5";
1002 case 0x000003b6: return g_fIntelNetBurst ? "P4_MSR_ITLB_ESCR0" : "I7_UNC_PMC6";
1003 case 0x000003b7: return g_fIntelNetBurst ? "P4_MSR_ITLB_ESCR1" : "I7_UNC_PMC7";
1004 case 0x000003b8: return g_fIntelNetBurst ? "P4_MSR_CRU_ESCR0" : NULL;
1005 case 0x000003b9: return g_fIntelNetBurst ? "P4_MSR_CRU_ESCR1" : NULL;
1006 case 0x000003ba: return g_fIntelNetBurst ? "P4_MSR_IQ_ESCR0" : NULL;
1007 case 0x000003bb: return g_fIntelNetBurst ? "P4_MSR_IQ_ESCR1" : NULL;
1008 case 0x000003bc: return g_fIntelNetBurst ? "P4_MSR_RAT_ESCR0" : NULL;
1009 case 0x000003bd: return g_fIntelNetBurst ? "P4_MSR_RAT_ESCR1" : NULL;
1010 case 0x000003be: return g_fIntelNetBurst ? "P4_MSR_SSU_ESCR0" : NULL;
1011 case 0x000003c0: return g_fIntelNetBurst ? "P4_MSR_MS_ESCR0" : "I7_UNC_PERF_EVT_SEL0";
1012 case 0x000003c1: return g_fIntelNetBurst ? "P4_MSR_MS_ESCR1" : "I7_UNC_PERF_EVT_SEL1";
1013 case 0x000003c2: return g_fIntelNetBurst ? "P4_MSR_TBPU_ESCR0" : "I7_UNC_PERF_EVT_SEL2";
1014 case 0x000003c3: return g_fIntelNetBurst ? "P4_MSR_TBPU_ESCR1" : "I7_UNC_PERF_EVT_SEL3";
1015 case 0x000003c4: return g_fIntelNetBurst ? "P4_MSR_TC_ESCR0" : "I7_UNC_PERF_EVT_SEL4";
1016 case 0x000003c5: return g_fIntelNetBurst ? "P4_MSR_TC_ESCR1" : "I7_UNC_PERF_EVT_SEL5";
1017 case 0x000003c6: return g_fIntelNetBurst ? NULL : "I7_UNC_PERF_EVT_SEL6";
1018 case 0x000003c7: return g_fIntelNetBurst ? NULL : "I7_UNC_PERF_EVT_SEL7";
1019 case 0x000003c8: return g_fIntelNetBurst ? "P4_MSR_IX_ESCR0" : NULL;
1020 case 0x000003c9: return g_fIntelNetBurst ? "P4_MSR_IX_ESCR0" : NULL;
1021 case 0x000003ca: return g_fIntelNetBurst ? "P4_MSR_ALF_ESCR0" : NULL;
1022 case 0x000003cb: return g_fIntelNetBurst ? "P4_MSR_ALF_ESCR1" : NULL;
1023 case 0x000003cc: return g_fIntelNetBurst ? "P4_MSR_CRU_ESCR2" : NULL;
1024 case 0x000003cd: return g_fIntelNetBurst ? "P4_MSR_CRU_ESCR3" : NULL;
1025 case 0x000003e0: return g_fIntelNetBurst ? "P4_MSR_CRU_ESCR4" : NULL;
1026 case 0x000003e1: return g_fIntelNetBurst ? "P4_MSR_CRU_ESCR5" : NULL;
1027 case 0x000003f0: return g_fIntelNetBurst ? "P4_MSR_TC_PRECISE_EVENT" : NULL;
1028 case 0x000003f1: return "IA32_PEBS_ENABLE";
1029 case 0x000003f2: return g_fIntelNetBurst ? "P4_MSR_PEBS_MATRIX_VERT" : "IA32_PEBS_ENABLE";
1030 case 0x000003f3: return g_fIntelNetBurst ? "P4_UNK_0000_03f3" : NULL;
1031 case 0x000003f4: return g_fIntelNetBurst ? "P4_UNK_0000_03f4" : NULL;
1032 case 0x000003f5: return g_fIntelNetBurst ? "P4_UNK_0000_03f5" : NULL;
1033 case 0x000003f6: return g_fIntelNetBurst ? "P4_UNK_0000_03f6" : "I7_MSR_PEBS_LD_LAT";
1034 case 0x000003f7: return g_fIntelNetBurst ? "P4_UNK_0000_03f7" : "I7_MSR_PEBS_LD_LAT";
1035 case 0x000003f8: return g_fIntelNetBurst ? "P4_UNK_0000_03f8" : "I7_MSR_PKG_C3_RESIDENCY";
1036 case 0x000003f9: return "I7_MSR_PKG_C6_RESIDENCY";
1037 case 0x000003fa: return "I7_MSR_PKG_C7_RESIDENCY";
1038 case 0x000003fc: return "I7_MSR_CORE_C3_RESIDENCY";
1039 case 0x000003fd: return "I7_MSR_CORE_C6_RESIDENCY";
1040 case 0x000003fe: return "I7_MSR_CORE_C7_RESIDENCY";
1041 case 0x00000478: return g_enmMicroarch == kCpumMicroarch_Intel_Core2_Penryn ? "CPUID1_FEATURE_MASK" : NULL;
1042 case 0x00000480: return "IA32_VMX_BASIC";
1043 case 0x00000481: return "IA32_VMX_PINBASED_CTLS";
1044 case 0x00000482: return "IA32_VMX_PROCBASED_CTLS";
1045 case 0x00000483: return "IA32_VMX_EXIT_CTLS";
1046 case 0x00000484: return "IA32_VMX_ENTRY_CTLS";
1047 case 0x00000485: return "IA32_VMX_MISC";
1048 case 0x00000486: return "IA32_VMX_CR0_FIXED0";
1049 case 0x00000487: return "IA32_VMX_CR0_FIXED1";
1050 case 0x00000488: return "IA32_VMX_CR4_FIXED0";
1051 case 0x00000489: return "IA32_VMX_CR4_FIXED1";
1052 case 0x0000048a: return "IA32_VMX_VMCS_ENUM";
1053 case 0x0000048b: return "IA32_VMX_PROCBASED_CTLS2";
1054 case 0x0000048c: return "IA32_VMX_EPT_VPID_CAP";
1055 case 0x0000048d: return "IA32_VMX_TRUE_PINBASED_CTLS";
1056 case 0x0000048e: return "IA32_VMX_TRUE_PROCBASED_CTLS";
1057 case 0x0000048f: return "IA32_VMX_TRUE_EXIT_CTLS";
1058 case 0x00000490: return "IA32_VMX_TRUE_ENTRY_CTLS";
1059 case 0x00000491: return "IA32_VMX_VMFUNC";
1060 case 0x000004c1: return "IA32_A_PMC0";
1061 case 0x000004c2: return "IA32_A_PMC1";
1062 case 0x000004c3: return "IA32_A_PMC2";
1063 case 0x000004c4: return "IA32_A_PMC3";
1064 case 0x000004c5: return "IA32_A_PMC4";
1065 case 0x000004c6: return "IA32_A_PMC5";
1066 case 0x000004c7: return "IA32_A_PMC6";
1067 case 0x000004c8: return "IA32_A_PMC7";
1068 case 0x000004f8: return "C2_UNK_0000_04f8"; /* Core2_Penryn. */
1069 case 0x000004f9: return "C2_UNK_0000_04f9"; /* Core2_Penryn. */
1070 case 0x000004fa: return "C2_UNK_0000_04fa"; /* Core2_Penryn. */
1071 case 0x000004fb: return "C2_UNK_0000_04fb"; /* Core2_Penryn. */
1072 case 0x000004fc: return "C2_UNK_0000_04fc"; /* Core2_Penryn. */
1073 case 0x000004fd: return "C2_UNK_0000_04fd"; /* Core2_Penryn. */
1074 case 0x000004fe: return "C2_UNK_0000_04fe"; /* Core2_Penryn. */
1075 case 0x000004ff: return "C2_UNK_0000_04ff"; /* Core2_Penryn. */
1076 case 0x00000502: return "I7_SB_UNK_0000_0502";
1077 case 0x00000590: return "C2_UNK_0000_0590"; /* Core2_Penryn. */
1078 case 0x00000591: return "C2_UNK_0000_0591"; /* Core2_Penryn. */
1079 case 0x000005a0: return "C2_PECI_CTL"; /* Core2_Penryn. */
1080 case 0x000005a1: return "C2_UNK_0000_05a1"; /* Core2_Penryn. */
1081 case 0x00000600: return "IA32_DS_AREA";
1082 case 0x00000601: return "I7_SB_MSR_VR_CURRENT_CONFIG"; /* SandyBridge, IvyBridge. */
1083 case 0x00000602: return "I7_IB_UNK_0000_0602";
1084 case 0x00000603: return "I7_SB_MSR_VR_MISC_CONFIG"; /* SandyBridge, IvyBridge. */
1085 case 0x00000604: return "I7_IB_UNK_0000_0602";
1086 case 0x00000606: return "I7_SB_MSR_RAPL_POWER_UNIT"; /* SandyBridge, IvyBridge. */
1087 case 0x00000609: return "I7_SB_UNK_0000_0609"; /* SandyBridge (non EP). */
1088 case 0x0000060a: return "I7_SB_MSR_PKGC3_IRTL"; /* SandyBridge, IvyBridge. */
1089 case 0x0000060b: return "I7_SB_MSR_PKGC6_IRTL"; /* SandyBridge, IvyBridge. */
1090 case 0x0000060c: return "I7_SB_MSR_PKGC7_IRTL"; /* SandyBridge, IvyBridge. */
1091 case 0x0000060d: return "I7_SB_MSR_PKG_C2_RESIDENCY"; /* SandyBridge, IvyBridge. */
1092 case 0x00000610: return "I7_SB_MSR_PKG_POWER_LIMIT";
1093 case 0x00000611: return "I7_SB_MSR_PKG_ENERGY_STATUS";
1094 case 0x00000613: return "I7_SB_MSR_PKG_PERF_STATUS";
1095 case 0x00000614: return "I7_SB_MSR_PKG_POWER_INFO";
1096 case 0x00000618: return "I7_SB_MSR_DRAM_POWER_LIMIT";
1097 case 0x00000619: return "I7_SB_MSR_DRAM_ENERGY_STATUS";
1098 case 0x0000061b: return "I7_SB_MSR_DRAM_PERF_STATUS";
1099 case 0x0000061c: return "I7_SB_MSR_DRAM_POWER_INFO";
1100 case 0x00000638: return "I7_SB_MSR_PP0_POWER_LIMIT";
1101 case 0x00000639: return "I7_SB_MSR_PP0_ENERGY_STATUS";
1102 case 0x0000063a: return "I7_SB_MSR_PP0_POLICY";
1103 case 0x0000063b: return "I7_SB_MSR_PP0_PERF_STATUS";
1104 case 0x00000640: return "I7_HW_MSR_PP0_POWER_LIMIT";
1105 case 0x00000641: return "I7_HW_MSR_PP0_ENERGY_STATUS";
1106 case 0x00000642: return "I7_HW_MSR_PP0_POLICY";
1107 case 0x00000648: return "I7_IB_MSR_CONFIG_TDP_NOMINAL";
1108 case 0x00000649: return "I7_IB_MSR_CONFIG_TDP_LEVEL1";
1109 case 0x0000064a: return "I7_IB_MSR_CONFIG_TDP_LEVEL2";
1110 case 0x0000064b: return "I7_IB_MSR_CONFIG_TDP_CONTROL";
1111 case 0x0000064c: return "I7_IB_MSR_TURBO_ACTIVATION_RATIO";
1112 case 0x00000660: return "SILV_CORE_C1_RESIDENCY";
1113 case 0x00000661: return "SILV_UNK_0000_0661";
1114 case 0x00000662: return "SILV_UNK_0000_0662";
1115 case 0x00000663: return "SILV_UNK_0000_0663";
1116 case 0x00000664: return "SILV_UNK_0000_0664";
1117 case 0x00000665: return "SILV_UNK_0000_0665";
1118 case 0x00000666: return "SILV_UNK_0000_0666";
1119 case 0x00000667: return "SILV_UNK_0000_0667";
1120 case 0x00000668: return "SILV_UNK_0000_0668";
1121 case 0x00000669: return "SILV_UNK_0000_0669";
1122 case 0x0000066a: return "SILV_UNK_0000_066a";
1123 case 0x0000066b: return "SILV_UNK_0000_066b";
1124 case 0x0000066c: return "SILV_UNK_0000_066c";
1125 case 0x0000066d: return "SILV_UNK_0000_066d";
1126 case 0x0000066e: return "SILV_UNK_0000_066e";
1127 case 0x0000066f: return "SILV_UNK_0000_066f";
1128 case 0x00000670: return "SILV_UNK_0000_0670";
1129 case 0x00000671: return "SILV_UNK_0000_0671";
1130 case 0x00000672: return "SILV_UNK_0000_0672";
1131 case 0x00000673: return "SILV_UNK_0000_0673";
1132 case 0x00000674: return "SILV_UNK_0000_0674";
1133 case 0x00000675: return "SILV_UNK_0000_0675";
1134 case 0x00000676: return "SILV_UNK_0000_0676";
1135 case 0x00000677: return "SILV_UNK_0000_0677";
1136
1137 case 0x00000680: return "MSR_LASTBRANCH_0_FROM_IP";
1138 case 0x00000681: return "MSR_LASTBRANCH_1_FROM_IP";
1139 case 0x00000682: return "MSR_LASTBRANCH_2_FROM_IP";
1140 case 0x00000683: return "MSR_LASTBRANCH_3_FROM_IP";
1141 case 0x00000684: return "MSR_LASTBRANCH_4_FROM_IP";
1142 case 0x00000685: return "MSR_LASTBRANCH_5_FROM_IP";
1143 case 0x00000686: return "MSR_LASTBRANCH_6_FROM_IP";
1144 case 0x00000687: return "MSR_LASTBRANCH_7_FROM_IP";
1145 case 0x00000688: return "MSR_LASTBRANCH_8_FROM_IP";
1146 case 0x00000689: return "MSR_LASTBRANCH_9_FROM_IP";
1147 case 0x0000068a: return "MSR_LASTBRANCH_10_FROM_IP";
1148 case 0x0000068b: return "MSR_LASTBRANCH_11_FROM_IP";
1149 case 0x0000068c: return "MSR_LASTBRANCH_12_FROM_IP";
1150 case 0x0000068d: return "MSR_LASTBRANCH_13_FROM_IP";
1151 case 0x0000068e: return "MSR_LASTBRANCH_14_FROM_IP";
1152 case 0x0000068f: return "MSR_LASTBRANCH_15_FROM_IP";
1153 case 0x000006c0: return "MSR_LASTBRANCH_0_TO_IP";
1154 case 0x000006c1: return "MSR_LASTBRANCH_1_TO_IP";
1155 case 0x000006c2: return "MSR_LASTBRANCH_2_TO_IP";
1156 case 0x000006c3: return "MSR_LASTBRANCH_3_TO_IP";
1157 case 0x000006c4: return "MSR_LASTBRANCH_4_TO_IP";
1158 case 0x000006c5: return "MSR_LASTBRANCH_5_TO_IP";
1159 case 0x000006c6: return "MSR_LASTBRANCH_6_TO_IP";
1160 case 0x000006c7: return "MSR_LASTBRANCH_7_TO_IP";
1161 case 0x000006c8: return "MSR_LASTBRANCH_8_TO_IP";
1162 case 0x000006c9: return "MSR_LASTBRANCH_9_TO_IP";
1163 case 0x000006ca: return "MSR_LASTBRANCH_10_TO_IP";
1164 case 0x000006cb: return "MSR_LASTBRANCH_11_TO_IP";
1165 case 0x000006cc: return "MSR_LASTBRANCH_12_TO_IP";
1166 case 0x000006cd: return "MSR_LASTBRANCH_13_TO_IP";
1167 case 0x000006ce: return "MSR_LASTBRANCH_14_TO_IP";
1168 case 0x000006cf: return "MSR_LASTBRANCH_15_TO_IP";
1169 case 0x000006e0: return "IA32_TSC_DEADLINE";
1170
1171 case 0x00000768: return "SILV_UNK_0000_0768";
1172 case 0x00000769: return "SILV_UNK_0000_0769";
1173 case 0x0000076a: return "SILV_UNK_0000_076a";
1174 case 0x0000076b: return "SILV_UNK_0000_076b";
1175 case 0x0000076c: return "SILV_UNK_0000_076c";
1176 case 0x0000076d: return "SILV_UNK_0000_076d";
1177 case 0x0000076e: return "SILV_UNK_0000_076e";
1178
1179 case 0x00000c80: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_IvyBridge ? "IA32_DEBUG_INTERFACE" : NULL; /* Mentioned in an intel dataskit called 4th-gen-core-family-desktop-vol-1-datasheet.pdf. */
1180 case 0x00000c81: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_IvyBridge ? "I7_IB_UNK_0000_0c81" : NULL; /* Probably related to IA32_DEBUG_INTERFACE... */
1181 case 0x00000c82: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_IvyBridge ? "I7_IB_UNK_0000_0c82" : NULL; /* Probably related to IA32_DEBUG_INTERFACE... */
1182 case 0x00000c83: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_IvyBridge ? "I7_IB_UNK_0000_0c83" : NULL; /* Probably related to IA32_DEBUG_INTERFACE... */
1183
1184 /* 0x1000..0x1004 seems to have been used by IBM 386 and 486 clones too. */
1185 case 0x00001000: return "P6_DEBUG_REGISTER_0";
1186 case 0x00001001: return "P6_DEBUG_REGISTER_1";
1187 case 0x00001002: return "P6_DEBUG_REGISTER_2";
1188 case 0x00001003: return "P6_DEBUG_REGISTER_3";
1189 case 0x00001004: return "P6_DEBUG_REGISTER_4";
1190 case 0x00001005: return "P6_DEBUG_REGISTER_5";
1191 case 0x00001006: return "P6_DEBUG_REGISTER_6";
1192 case 0x00001007: return "P6_DEBUG_REGISTER_7";
1193 case 0x0000103f: return "P6_UNK_0000_103f"; /* P6_M_Dothan. */
1194 case 0x000010cd: return "P6_UNK_0000_10cd"; /* P6_M_Dothan. */
1195
1196 case 0x00001107: return "VIA_UNK_0000_1107";
1197 case 0x0000110f: return "VIA_UNK_0000_110f";
1198 case 0x00001153: return "VIA_UNK_0000_1153";
1199 case 0x00001200: return "VIA_UNK_0000_1200";
1200 case 0x00001201: return "VIA_UNK_0000_1201";
1201 case 0x00001202: return "VIA_UNK_0000_1202";
1202 case 0x00001203: return "VIA_UNK_0000_1203";
1203 case 0x00001204: return "VIA_UNK_0000_1204";
1204 case 0x00001205: return "VIA_UNK_0000_1205";
1205 case 0x00001206: return "VIA_ALT_VENDOR_EBX";
1206 case 0x00001207: return "VIA_ALT_VENDOR_ECDX";
1207 case 0x00001208: return "VIA_UNK_0000_1208";
1208 case 0x00001209: return "VIA_UNK_0000_1209";
1209 case 0x0000120a: return "VIA_UNK_0000_120a";
1210 case 0x0000120b: return "VIA_UNK_0000_120b";
1211 case 0x0000120c: return "VIA_UNK_0000_120c";
1212 case 0x0000120d: return "VIA_UNK_0000_120d";
1213 case 0x0000120e: return "VIA_UNK_0000_120e";
1214 case 0x0000120f: return "VIA_UNK_0000_120f";
1215 case 0x00001210: return "VIA_UNK_0000_1210";
1216 case 0x00001211: return "VIA_UNK_0000_1211";
1217 case 0x00001212: return "VIA_UNK_0000_1212";
1218 case 0x00001213: return "VIA_UNK_0000_1213";
1219 case 0x00001214: return "VIA_UNK_0000_1214";
1220 case 0x00001220: return "VIA_UNK_0000_1220";
1221 case 0x00001221: return "VIA_UNK_0000_1221";
1222 case 0x00001230: return "VIA_UNK_0000_1230";
1223 case 0x00001231: return "VIA_UNK_0000_1231";
1224 case 0x00001232: return "VIA_UNK_0000_1232";
1225 case 0x00001233: return "VIA_UNK_0000_1233";
1226 case 0x00001234: return "VIA_UNK_0000_1234";
1227 case 0x00001235: return "VIA_UNK_0000_1235";
1228 case 0x00001236: return "VIA_UNK_0000_1236";
1229 case 0x00001237: return "VIA_UNK_0000_1237";
1230 case 0x00001238: return "VIA_UNK_0000_1238";
1231 case 0x00001239: return "VIA_UNK_0000_1239";
1232 case 0x00001240: return "VIA_UNK_0000_1240";
1233 case 0x00001241: return "VIA_UNK_0000_1241";
1234 case 0x00001243: return "VIA_UNK_0000_1243";
1235 case 0x00001245: return "VIA_UNK_0000_1245";
1236 case 0x00001246: return "VIA_UNK_0000_1246";
1237 case 0x00001247: return "VIA_UNK_0000_1247";
1238 case 0x00001248: return "VIA_UNK_0000_1248";
1239 case 0x00001249: return "VIA_UNK_0000_1249";
1240 case 0x0000124a: return "VIA_UNK_0000_124a";
1241
1242 case 0x00001301: return "VIA_UNK_0000_1301";
1243 case 0x00001302: return "VIA_UNK_0000_1302";
1244 case 0x00001303: return "VIA_UNK_0000_1303";
1245 case 0x00001304: return "VIA_UNK_0000_1304";
1246 case 0x00001305: return "VIA_UNK_0000_1305";
1247 case 0x00001306: return "VIA_UNK_0000_1306";
1248 case 0x00001307: return "VIA_UNK_0000_1307";
1249 case 0x00001308: return "VIA_UNK_0000_1308";
1250 case 0x00001309: return "VIA_UNK_0000_1309";
1251 case 0x0000130d: return "VIA_UNK_0000_130d";
1252 case 0x0000130e: return "VIA_UNK_0000_130e";
1253 case 0x00001312: return "VIA_UNK_0000_1312";
1254 case 0x00001315: return "VIA_UNK_0000_1315";
1255 case 0x00001317: return "VIA_UNK_0000_1317";
1256 case 0x00001318: return "VIA_UNK_0000_1318";
1257 case 0x0000131a: return "VIA_UNK_0000_131a";
1258 case 0x0000131b: return "VIA_UNK_0000_131b";
1259 case 0x00001402: return "VIA_UNK_0000_1402";
1260 case 0x00001403: return "VIA_UNK_0000_1403";
1261 case 0x00001404: return "VIA_UNK_0000_1404";
1262 case 0x00001405: return "VIA_UNK_0000_1405";
1263 case 0x00001406: return "VIA_UNK_0000_1406";
1264 case 0x00001407: return "VIA_UNK_0000_1407";
1265 case 0x00001410: return "VIA_UNK_0000_1410";
1266 case 0x00001411: return "VIA_UNK_0000_1411";
1267 case 0x00001412: return "VIA_UNK_0000_1412";
1268 case 0x00001413: return "VIA_UNK_0000_1413";
1269 case 0x00001414: return "VIA_UNK_0000_1414";
1270 case 0x00001415: return "VIA_UNK_0000_1415";
1271 case 0x00001416: return "VIA_UNK_0000_1416";
1272 case 0x00001417: return "VIA_UNK_0000_1417";
1273 case 0x00001418: return "VIA_UNK_0000_1418";
1274 case 0x00001419: return "VIA_UNK_0000_1419";
1275 case 0x0000141a: return "VIA_UNK_0000_141a";
1276 case 0x0000141b: return "VIA_UNK_0000_141b";
1277 case 0x0000141c: return "VIA_UNK_0000_141c";
1278 case 0x0000141d: return "VIA_UNK_0000_141d";
1279 case 0x0000141e: return "VIA_UNK_0000_141e";
1280 case 0x0000141f: return "VIA_UNK_0000_141f";
1281 case 0x00001420: return "VIA_UNK_0000_1420";
1282 case 0x00001421: return "VIA_UNK_0000_1421";
1283 case 0x00001422: return "VIA_UNK_0000_1422";
1284 case 0x00001423: return "VIA_UNK_0000_1423";
1285 case 0x00001424: return "VIA_UNK_0000_1424";
1286 case 0x00001425: return "VIA_UNK_0000_1425";
1287 case 0x00001426: return "VIA_UNK_0000_1426";
1288 case 0x00001427: return "VIA_UNK_0000_1427";
1289 case 0x00001428: return "VIA_UNK_0000_1428";
1290 case 0x00001429: return "VIA_UNK_0000_1429";
1291 case 0x0000142a: return "VIA_UNK_0000_142a";
1292 case 0x0000142b: return "VIA_UNK_0000_142b";
1293 case 0x0000142c: return "VIA_UNK_0000_142c";
1294 case 0x0000142d: return "VIA_UNK_0000_142d";
1295 case 0x0000142e: return "VIA_UNK_0000_142e";
1296 case 0x0000142f: return "VIA_UNK_0000_142f";
1297 case 0x00001434: return "VIA_UNK_0000_1434";
1298 case 0x00001435: return "VIA_UNK_0000_1435";
1299 case 0x00001436: return "VIA_UNK_0000_1436";
1300 case 0x00001437: return "VIA_UNK_0000_1437";
1301 case 0x00001438: return "VIA_UNK_0000_1438";
1302 case 0x0000143a: return "VIA_UNK_0000_143a";
1303 case 0x0000143c: return "VIA_UNK_0000_143c";
1304 case 0x0000143d: return "VIA_UNK_0000_143d";
1305 case 0x00001440: return "VIA_UNK_0000_1440";
1306 case 0x00001441: return "VIA_UNK_0000_1441";
1307 case 0x00001442: return "VIA_UNK_0000_1442";
1308 case 0x00001449: return "VIA_UNK_0000_1449";
1309 case 0x00001450: return "VIA_UNK_0000_1450";
1310 case 0x00001451: return "VIA_UNK_0000_1451";
1311 case 0x00001452: return "VIA_UNK_0000_1452";
1312 case 0x00001453: return "VIA_UNK_0000_1453";
1313 case 0x00001460: return "VIA_UNK_0000_1460";
1314 case 0x00001461: return "VIA_UNK_0000_1461";
1315 case 0x00001462: return "VIA_UNK_0000_1462";
1316 case 0x00001463: return "VIA_UNK_0000_1463";
1317 case 0x00001465: return "VIA_UNK_0000_1465";
1318 case 0x00001466: return "VIA_UNK_0000_1466";
1319 case 0x00001470: return "VIA_UNK_0000_1470";
1320 case 0x00001471: return "VIA_UNK_0000_1471";
1321 case 0x00001480: return "VIA_UNK_0000_1480";
1322 case 0x00001481: return "VIA_UNK_0000_1481";
1323 case 0x00001482: return "VIA_UNK_0000_1482";
1324 case 0x00001483: return "VIA_UNK_0000_1483";
1325 case 0x00001484: return "VIA_UNK_0000_1484";
1326 case 0x00001485: return "VIA_UNK_0000_1485";
1327 case 0x00001486: return "VIA_UNK_0000_1486";
1328 case 0x00001490: return "VIA_UNK_0000_1490";
1329 case 0x00001491: return "VIA_UNK_0000_1491";
1330 case 0x00001492: return "VIA_UNK_0000_1492";
1331 case 0x00001493: return "VIA_UNK_0000_1493";
1332 case 0x00001494: return "VIA_UNK_0000_1494";
1333 case 0x00001495: return "VIA_UNK_0000_1495";
1334 case 0x00001496: return "VIA_UNK_0000_1496";
1335 case 0x00001497: return "VIA_UNK_0000_1497";
1336 case 0x00001498: return "VIA_UNK_0000_1498";
1337 case 0x00001499: return "VIA_UNK_0000_1499";
1338 case 0x0000149a: return "VIA_UNK_0000_149a";
1339 case 0x0000149b: return "VIA_UNK_0000_149b";
1340 case 0x0000149c: return "VIA_UNK_0000_149c";
1341 case 0x0000149f: return "VIA_UNK_0000_149f";
1342 case 0x00001523: return "VIA_UNK_0000_1523";
1343
1344 case 0x00002000: return g_enmVendor == CPUMCPUVENDOR_INTEL ? "P6_CR0" : NULL;
1345 case 0x00002002: return g_enmVendor == CPUMCPUVENDOR_INTEL ? "P6_CR2" : NULL;
1346 case 0x00002003: return g_enmVendor == CPUMCPUVENDOR_INTEL ? "P6_CR3" : NULL;
1347 case 0x00002004: return g_enmVendor == CPUMCPUVENDOR_INTEL ? "P6_CR4" : NULL;
1348 case 0x0000203f: return g_enmVendor == CPUMCPUVENDOR_INTEL ? "P6_UNK_0000_203f" /* P6_M_Dothan. */ : NULL;
1349 case 0x000020cd: return g_enmVendor == CPUMCPUVENDOR_INTEL ? "P6_UNK_0000_20cd" /* P6_M_Dothan. */ : NULL;
1350 case 0x0000303f: return g_enmVendor == CPUMCPUVENDOR_INTEL ? "P6_UNK_0000_303f" /* P6_M_Dothan. */ : NULL;
1351 case 0x000030cd: return g_enmVendor == CPUMCPUVENDOR_INTEL ? "P6_UNK_0000_30cd" /* P6_M_Dothan. */ : NULL;
1352
1353 case 0x0000317a: return "VIA_UNK_0000_317a";
1354 case 0x0000317b: return "VIA_UNK_0000_317b";
1355 case 0x0000317d: return "VIA_UNK_0000_317d";
1356 case 0x0000317e: return "VIA_UNK_0000_317e";
1357 case 0x0000317f: return "VIA_UNK_0000_317f";
1358 case 0x80000198: return "VIA_UNK_8000_0198";
1359
1360 case 0xc0000080: return "AMD64_EFER";
1361 case 0xc0000081: return "AMD64_STAR";
1362 case 0xc0000082: return "AMD64_STAR64";
1363 case 0xc0000083: return "AMD64_STARCOMPAT";
1364 case 0xc0000084: return "AMD64_SYSCALL_FLAG_MASK";
1365 case 0xc0000100: return "AMD64_FS_BASE";
1366 case 0xc0000101: return "AMD64_GS_BASE";
1367 case 0xc0000102: return "AMD64_KERNEL_GS_BASE";
1368 case 0xc0000103: return "AMD64_TSC_AUX";
1369 case 0xc0000104: return "AMD_15H_TSC_RATE";
1370 case 0xc0000105: return "AMD_15H_LWP_CFG"; /* Only Family 15h? */
1371 case 0xc0000106: return "AMD_15H_LWP_CBADDR"; /* Only Family 15h? */
1372 case 0xc0000408: return "AMD_10H_MC4_MISC1";
1373 case 0xc0000409: return "AMD_10H_MC4_MISC2";
1374 case 0xc000040a: return "AMD_10H_MC4_MISC3";
1375 case 0xc000040b: return "AMD_10H_MC4_MISC4";
1376 case 0xc000040c: return "AMD_10H_MC4_MISC5";
1377 case 0xc000040d: return "AMD_10H_MC4_MISC6";
1378 case 0xc000040e: return "AMD_10H_MC4_MISC7";
1379 case 0xc000040f: return "AMD_10H_MC4_MISC8";
1380 case 0xc0010000: return "AMD_K8_PERF_CTL_0";
1381 case 0xc0010001: return "AMD_K8_PERF_CTL_1";
1382 case 0xc0010002: return "AMD_K8_PERF_CTL_2";
1383 case 0xc0010003: return "AMD_K8_PERF_CTL_3";
1384 case 0xc0010004: return "AMD_K8_PERF_CTR_0";
1385 case 0xc0010005: return "AMD_K8_PERF_CTR_1";
1386 case 0xc0010006: return "AMD_K8_PERF_CTR_2";
1387 case 0xc0010007: return "AMD_K8_PERF_CTR_3";
1388 case 0xc0010010: return "AMD_K8_SYS_CFG";
1389 case 0xc0010015: return "AMD_K8_HW_CFG";
1390 case 0xc0010016: return "AMD_K8_IORR_BASE_0";
1391 case 0xc0010017: return "AMD_K8_IORR_MASK_0";
1392 case 0xc0010018: return "AMD_K8_IORR_BASE_1";
1393 case 0xc0010019: return "AMD_K8_IORR_MASK_1";
1394 case 0xc001001a: return "AMD_K8_TOP_MEM";
1395 case 0xc001001d: return "AMD_K8_TOP_MEM2";
1396 case 0xc001001e: return "AMD_K8_MANID";
1397 case 0xc001001f: return "AMD_K8_NB_CFG1";
1398 case 0xc0010020: return "AMD_K8_PATCH_LOADER";
1399 case 0xc0010021: return "AMD_K8_UNK_c001_0021";
1400 case 0xc0010022: return "AMD_K8_MC_XCPT_REDIR";
1401 case 0xc0010028: return "AMD_K8_UNK_c001_0028";
1402 case 0xc0010029: return "AMD_K8_UNK_c001_0029";
1403 case 0xc001002a: return "AMD_K8_UNK_c001_002a";
1404 case 0xc001002b: return "AMD_K8_UNK_c001_002b";
1405 case 0xc001002c: return "AMD_K8_UNK_c001_002c";
1406 case 0xc001002d: return "AMD_K8_UNK_c001_002d";
1407 case 0xc0010030: return "AMD_K8_CPU_NAME_0";
1408 case 0xc0010031: return "AMD_K8_CPU_NAME_1";
1409 case 0xc0010032: return "AMD_K8_CPU_NAME_2";
1410 case 0xc0010033: return "AMD_K8_CPU_NAME_3";
1411 case 0xc0010034: return "AMD_K8_CPU_NAME_4";
1412 case 0xc0010035: return "AMD_K8_CPU_NAME_5";
1413 case 0xc001003e: return "AMD_K8_HTC";
1414 case 0xc001003f: return "AMD_K8_STC";
1415 case 0xc0010041: return "AMD_K8_FIDVID_CTL";
1416 case 0xc0010042: return "AMD_K8_FIDVID_STATUS";
1417 case 0xc0010043: return "AMD_K8_THERMTRIP_STATUS"; /* BDKG says it was removed in K8 revision C.*/
1418 case 0xc0010044: return "AMD_K8_MC_CTL_MASK_0";
1419 case 0xc0010045: return "AMD_K8_MC_CTL_MASK_1";
1420 case 0xc0010046: return "AMD_K8_MC_CTL_MASK_2";
1421 case 0xc0010047: return "AMD_K8_MC_CTL_MASK_3";
1422 case 0xc0010048: return "AMD_K8_MC_CTL_MASK_4";
1423 case 0xc0010049: return "AMD_K8_MC_CTL_MASK_5";
1424 case 0xc001004a: return "AMD_K8_MC_CTL_MASK_6";
1425 //case 0xc001004b: return "AMD_K8_MC_CTL_MASK_7";
1426 case 0xc0010050: return "AMD_K8_SMI_ON_IO_TRAP_0";
1427 case 0xc0010051: return "AMD_K8_SMI_ON_IO_TRAP_1";
1428 case 0xc0010052: return "AMD_K8_SMI_ON_IO_TRAP_2";
1429 case 0xc0010053: return "AMD_K8_SMI_ON_IO_TRAP_3";
1430 case 0xc0010054: return "AMD_K8_SMI_ON_IO_TRAP_CTL_STS";
1431 case 0xc0010055: return "AMD_K8_INT_PENDING_MSG";
1432 case 0xc0010056: return "AMD_K8_SMI_TRIGGER_IO_CYCLE";
1433 case 0xc0010057: return "AMD_10H_UNK_c001_0057";
1434 case 0xc0010058: return "AMD_10H_MMIO_CFG_BASE_ADDR";
1435 case 0xc0010059: return "AMD_10H_TRAP_CTL?"; /* Undocumented, only one google hit. */
1436 case 0xc001005a: return "AMD_10H_UNK_c001_005a";
1437 case 0xc001005b: return "AMD_10H_UNK_c001_005b";
1438 case 0xc001005c: return "AMD_10H_UNK_c001_005c";
1439 case 0xc001005d: return "AMD_10H_UNK_c001_005d";
1440 case 0xc0010060: return "AMD_K8_BIST_RESULT"; /* BDKG says it as introduced with revision F. */
1441 case 0xc0010061: return "AMD_10H_P_ST_CUR_LIM";
1442 case 0xc0010062: return "AMD_10H_P_ST_CTL";
1443 case 0xc0010063: return "AMD_10H_P_ST_STS";
1444 case 0xc0010064: return "AMD_10H_P_ST_0";
1445 case 0xc0010065: return "AMD_10H_P_ST_1";
1446 case 0xc0010066: return "AMD_10H_P_ST_2";
1447 case 0xc0010067: return "AMD_10H_P_ST_3";
1448 case 0xc0010068: return "AMD_10H_P_ST_4";
1449 case 0xc0010069: return "AMD_10H_P_ST_5";
1450 case 0xc001006a: return "AMD_10H_P_ST_6";
1451 case 0xc001006b: return "AMD_10H_P_ST_7";
1452 case 0xc0010070: return "AMD_10H_COFVID_CTL";
1453 case 0xc0010071: return "AMD_10H_COFVID_STS";
1454 case 0xc0010073: return "AMD_10H_C_ST_IO_BASE_ADDR";
1455 case 0xc0010074: return "AMD_10H_CPU_WD_TMR_CFG";
1456 // case 0xc0010075: return "AMD_15H_APML_TDP_LIM";
1457 // case 0xc0010077: return "AMD_15H_CPU_PWR_IN_TDP";
1458 // case 0xc0010078: return "AMD_15H_PWR_AVG_PERIOD";
1459 // case 0xc0010079: return "AMD_15H_DRAM_CTR_CMD_THR";
1460 // case 0xc0010080: return "AMD_16H_FSFM_ACT_CNT_0";
1461 // case 0xc0010081: return "AMD_16H_FSFM_REF_CNT_0";
1462 case 0xc0010111: return "AMD_K8_SMM_BASE";
1463 case 0xc0010112: return "AMD_K8_SMM_ADDR";
1464 case 0xc0010113: return "AMD_K8_SMM_MASK";
1465 case 0xc0010114: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm_AMDV ? "AMD_K8_VM_CR" : "AMD_K8_UNK_c001_0114";
1466 case 0xc0010115: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm ? "AMD_K8_IGNNE" : "AMD_K8_UNK_c001_0115";
1467 case 0xc0010116: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm ? "AMD_K8_SMM_CTL" : "AMD_K8_UNK_c001_0116";
1468 case 0xc0010117: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm_AMDV ? "AMD_K8_VM_HSAVE_PA" : "AMD_K8_UNK_c001_0117";
1469 case 0xc0010118: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm_AMDV ? "AMD_10H_VM_LOCK_KEY" : "AMD_K8_UNK_c001_0118";
1470 case 0xc0010119: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm ? "AMD_10H_SSM_LOCK_KEY" : "AMD_K8_UNK_c001_0119";
1471 case 0xc001011a: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm ? "AMD_10H_LOCAL_SMI_STS" : "AMD_K8_UNK_c001_011a";
1472 case 0xc001011b: return "AMD_K8_UNK_c001_011b";
1473 case 0xc001011c: return "AMD_K8_UNK_c001_011c";
1474 case 0xc0010140: return "AMD_10H_OSVW_ID_LEN";
1475 case 0xc0010141: return "AMD_10H_OSVW_STS";
1476 case 0xc0010200: return "AMD_K8_PERF_CTL_0";
1477 case 0xc0010202: return "AMD_K8_PERF_CTL_1";
1478 case 0xc0010204: return "AMD_K8_PERF_CTL_2";
1479 case 0xc0010206: return "AMD_K8_PERF_CTL_3";
1480 case 0xc0010208: return "AMD_K8_PERF_CTL_4";
1481 case 0xc001020a: return "AMD_K8_PERF_CTL_5";
1482 //case 0xc001020c: return "AMD_K8_PERF_CTL_6";
1483 //case 0xc001020e: return "AMD_K8_PERF_CTL_7";
1484 case 0xc0010201: return "AMD_K8_PERF_CTR_0";
1485 case 0xc0010203: return "AMD_K8_PERF_CTR_1";
1486 case 0xc0010205: return "AMD_K8_PERF_CTR_2";
1487 case 0xc0010207: return "AMD_K8_PERF_CTR_3";
1488 case 0xc0010209: return "AMD_K8_PERF_CTR_4";
1489 case 0xc001020b: return "AMD_K8_PERF_CTR_5";
1490 //case 0xc001020d: return "AMD_K8_PERF_CTR_6";
1491 //case 0xc001020f: return "AMD_K8_PERF_CTR_7";
1492 case 0xc0010230: return "AMD_16H_L2I_PERF_CTL_0";
1493 case 0xc0010232: return "AMD_16H_L2I_PERF_CTL_1";
1494 case 0xc0010234: return "AMD_16H_L2I_PERF_CTL_2";
1495 case 0xc0010236: return "AMD_16H_L2I_PERF_CTL_3";
1496 //case 0xc0010238: return "AMD_16H_L2I_PERF_CTL_4";
1497 //case 0xc001023a: return "AMD_16H_L2I_PERF_CTL_5";
1498 //case 0xc001030c: return "AMD_16H_L2I_PERF_CTL_6";
1499 //case 0xc001023e: return "AMD_16H_L2I_PERF_CTL_7";
1500 case 0xc0010231: return "AMD_16H_L2I_PERF_CTR_0";
1501 case 0xc0010233: return "AMD_16H_L2I_PERF_CTR_1";
1502 case 0xc0010235: return "AMD_16H_L2I_PERF_CTR_2";
1503 case 0xc0010237: return "AMD_16H_L2I_PERF_CTR_3";
1504 //case 0xc0010239: return "AMD_16H_L2I_PERF_CTR_4";
1505 //case 0xc001023b: return "AMD_16H_L2I_PERF_CTR_5";
1506 //case 0xc001023d: return "AMD_16H_L2I_PERF_CTR_6";
1507 //case 0xc001023f: return "AMD_16H_L2I_PERF_CTR_7";
1508 case 0xc0010240: return "AMD_15H_NB_PERF_CTL_0";
1509 case 0xc0010242: return "AMD_15H_NB_PERF_CTL_1";
1510 case 0xc0010244: return "AMD_15H_NB_PERF_CTL_2";
1511 case 0xc0010246: return "AMD_15H_NB_PERF_CTL_3";
1512 //case 0xc0010248: return "AMD_15H_NB_PERF_CTL_4";
1513 //case 0xc001024a: return "AMD_15H_NB_PERF_CTL_5";
1514 //case 0xc001024c: return "AMD_15H_NB_PERF_CTL_6";
1515 //case 0xc001024e: return "AMD_15H_NB_PERF_CTL_7";
1516 case 0xc0010241: return "AMD_15H_NB_PERF_CTR_0";
1517 case 0xc0010243: return "AMD_15H_NB_PERF_CTR_1";
1518 case 0xc0010245: return "AMD_15H_NB_PERF_CTR_2";
1519 case 0xc0010247: return "AMD_15H_NB_PERF_CTR_3";
1520 //case 0xc0010249: return "AMD_15H_NB_PERF_CTR_4";
1521 //case 0xc001024b: return "AMD_15H_NB_PERF_CTR_5";
1522 //case 0xc001024d: return "AMD_15H_NB_PERF_CTR_6";
1523 //case 0xc001024f: return "AMD_15H_NB_PERF_CTR_7";
1524 case 0xc0011000: return "AMD_K7_MCODE_CTL";
1525 case 0xc0011001: return "AMD_K7_APIC_CLUSTER_ID"; /* Mentioned in BKDG (r3.00) for fam16h when describing EBL_CR_POWERON. */
1526 case 0xc0011002: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AMD_K8_CPUID_CTL_STD07" : NULL;
1527 case 0xc0011003: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AMD_K8_CPUID_CTL_STD06" : NULL;
1528 case 0xc0011004: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AMD_K8_CPUID_CTL_STD01" : NULL;
1529 case 0xc0011005: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AMD_K8_CPUID_CTL_EXT01" : NULL;
1530 case 0xc0011006: return "AMD_K7_DEBUG_STS?";
1531 case 0xc0011007: return "AMD_K7_BH_TRACE_BASE?";
1532 case 0xc0011008: return "AMD_K7_BH_TRACE_PTR?";
1533 case 0xc0011009: return "AMD_K7_BH_TRACE_LIM?";
1534 case 0xc001100a: return "AMD_K7_HDT_CFG?";
1535 case 0xc001100b: return "AMD_K7_FAST_FLUSH_COUNT?";
1536 case 0xc001100c: return "AMD_K7_NODE_ID";
1537 case 0xc001100d: return "AMD_K8_LOGICAL_CPUS_NUM?";
1538 case 0xc001100e: return "AMD_K8_WRMSR_BP?";
1539 case 0xc001100f: return "AMD_K8_WRMSR_BP_MASK?";
1540 case 0xc0011010: return "AMD_K8_BH_TRACE_CTL?";
1541 case 0xc0011011: return "AMD_K8_BH_TRACE_USRD?";
1542 case 0xc0011012: return "AMD_K7_UNK_c001_1012";
1543 case 0xc0011013: return "AMD_K7_UNK_c001_1013";
1544 case 0xc0011014: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AMD_K8_XCPT_BP_RIP?" : "AMD_K7_MOBIL_DEBUG?";
1545 case 0xc0011015: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AMD_K8_XCPT_BP_RIP_MASK?" : NULL;
1546 case 0xc0011016: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AMD_K8_COND_HDT_VAL?" : NULL;
1547 case 0xc0011017: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AMD_K8_COND_HDT_VAL_MASK?" : NULL;
1548 case 0xc0011018: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AMD_K8_XCPT_BP_CTL?" : NULL;
1549 case 0xc0011019: return g_enmMicroarch >= kCpumMicroarch_AMD_15h_Piledriver ? "AMD_16H_DR1_ADDR_MASK" : NULL;
1550 case 0xc001101a: return g_enmMicroarch >= kCpumMicroarch_AMD_15h_Piledriver ? "AMD_16H_DR2_ADDR_MASK" : NULL;
1551 case 0xc001101b: return g_enmMicroarch >= kCpumMicroarch_AMD_15h_Piledriver ? "AMD_16H_DR3_ADDR_MASK" : NULL;
1552 case 0xc001101d: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AMD_K8_NB_BIST?" : NULL;
1553 case 0xc001101e: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AMD_K8_THERMTRIP_2?" : NULL;
1554 case 0xc001101f: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AMD_K8_NB_CFG?" : NULL;
1555 case 0xc0011020: return "AMD_K7_LS_CFG";
1556 case 0xc0011021: return "AMD_K7_IC_CFG";
1557 case 0xc0011022: return "AMD_K7_DC_CFG";
1558 case 0xc0011023: return CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch) ? "AMD_15H_CU_CFG" : "AMD_K7_BU_CFG";
1559 case 0xc0011024: return "AMD_K7_DEBUG_CTL_2?";
1560 case 0xc0011025: return "AMD_K7_DR0_DATA_MATCH?";
1561 case 0xc0011026: return "AMD_K7_DR0_DATA_MATCH?";
1562 case 0xc0011027: return "AMD_K7_DR0_ADDR_MASK";
1563 case 0xc0011028: return g_enmMicroarch >= kCpumMicroarch_AMD_15h_First ? "AMD_15H_FP_CFG"
1564 : CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch) ? "AMD_10H_UNK_c001_1028"
1565 : NULL;
1566 case 0xc0011029: return g_enmMicroarch >= kCpumMicroarch_AMD_15h_First ? "AMD_15H_DC_CFG"
1567 : CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch) ? "AMD_10H_UNK_c001_1029"
1568 : NULL;
1569 case 0xc001102a: return CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch) ? "AMD_15H_CU_CFG2"
1570 : CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch) || g_enmMicroarch > kCpumMicroarch_AMD_15h_End
1571 ? "AMD_10H_BU_CFG2" /* 10h & 16h */ : NULL;
1572 case 0xc001102b: return CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch) ? "AMD_15H_CU_CFG3" : NULL;
1573 case 0xc001102c: return CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch) ? "AMD_15H_EX_CFG" : NULL;
1574 case 0xc001102d: return CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch) ? "AMD_15H_LS_CFG2" : NULL;
1575 case 0xc0011030: return "AMD_10H_IBS_FETCH_CTL";
1576 case 0xc0011031: return "AMD_10H_IBS_FETCH_LIN_ADDR";
1577 case 0xc0011032: return "AMD_10H_IBS_FETCH_PHYS_ADDR";
1578 case 0xc0011033: return "AMD_10H_IBS_OP_EXEC_CTL";
1579 case 0xc0011034: return "AMD_10H_IBS_OP_RIP";
1580 case 0xc0011035: return "AMD_10H_IBS_OP_DATA";
1581 case 0xc0011036: return "AMD_10H_IBS_OP_DATA2";
1582 case 0xc0011037: return "AMD_10H_IBS_OP_DATA3";
1583 case 0xc0011038: return "AMD_10H_IBS_DC_LIN_ADDR";
1584 case 0xc0011039: return "AMD_10H_IBS_DC_PHYS_ADDR";
1585 case 0xc001103a: return "AMD_10H_IBS_CTL";
1586 case 0xc001103b: return "AMD_14H_IBS_BR_TARGET";
1587
1588 case 0xc0011040: return "AMD_15H_UNK_c001_1040";
1589 case 0xc0011041: return "AMD_15H_UNK_c001_1041";
1590 case 0xc0011042: return "AMD_15H_UNK_c001_1042";
1591 case 0xc0011043: return "AMD_15H_UNK_c001_1043";
1592 case 0xc0011044: return "AMD_15H_UNK_c001_1044";
1593 case 0xc0011045: return "AMD_15H_UNK_c001_1045";
1594 case 0xc0011046: return "AMD_15H_UNK_c001_1046";
1595 case 0xc0011047: return "AMD_15H_UNK_c001_1047";
1596 case 0xc0011048: return "AMD_15H_UNK_c001_1048";
1597 case 0xc0011049: return "AMD_15H_UNK_c001_1049";
1598 case 0xc001104a: return "AMD_15H_UNK_c001_104a";
1599 case 0xc001104b: return "AMD_15H_UNK_c001_104b";
1600 case 0xc001104c: return "AMD_15H_UNK_c001_104c";
1601 case 0xc001104d: return "AMD_15H_UNK_c001_104d";
1602 case 0xc001104e: return "AMD_15H_UNK_c001_104e";
1603 case 0xc001104f: return "AMD_15H_UNK_c001_104f";
1604 case 0xc0011050: return "AMD_15H_UNK_c001_1050";
1605 case 0xc0011051: return "AMD_15H_UNK_c001_1051";
1606 case 0xc0011052: return "AMD_15H_UNK_c001_1052";
1607 case 0xc0011053: return "AMD_15H_UNK_c001_1053";
1608 case 0xc0011054: return "AMD_15H_UNK_c001_1054";
1609 case 0xc0011055: return "AMD_15H_UNK_c001_1055";
1610 case 0xc0011056: return "AMD_15H_UNK_c001_1056";
1611 case 0xc0011057: return "AMD_15H_UNK_c001_1057";
1612 case 0xc0011058: return "AMD_15H_UNK_c001_1058";
1613 case 0xc0011059: return "AMD_15H_UNK_c001_1059";
1614 case 0xc001105a: return "AMD_15H_UNK_c001_105a";
1615 case 0xc001105b: return "AMD_15H_UNK_c001_105b";
1616 case 0xc001105c: return "AMD_15H_UNK_c001_105c";
1617 case 0xc001105d: return "AMD_15H_UNK_c001_105d";
1618 case 0xc001105e: return "AMD_15H_UNK_c001_105e";
1619 case 0xc001105f: return "AMD_15H_UNK_c001_105f";
1620 case 0xc0011060: return "AMD_15H_UNK_c001_1060";
1621 case 0xc0011061: return "AMD_15H_UNK_c001_1061";
1622 case 0xc0011062: return "AMD_15H_UNK_c001_1062";
1623 case 0xc0011063: return "AMD_15H_UNK_c001_1063";
1624 case 0xc0011064: return "AMD_15H_UNK_c001_1064";
1625 case 0xc0011065: return "AMD_15H_UNK_c001_1065";
1626 case 0xc0011066: return "AMD_15H_UNK_c001_1066";
1627 case 0xc0011067: return "AMD_15H_UNK_c001_1067";
1628 case 0xc0011068: return "AMD_15H_UNK_c001_1068";
1629 case 0xc0011069: return "AMD_15H_UNK_c001_1069";
1630 case 0xc001106a: return "AMD_15H_UNK_c001_106a";
1631 case 0xc001106b: return "AMD_15H_UNK_c001_106b";
1632 case 0xc001106c: return "AMD_15H_UNK_c001_106c";
1633 case 0xc001106d: return "AMD_15H_UNK_c001_106d";
1634 case 0xc001106e: return "AMD_15H_UNK_c001_106e";
1635 case 0xc001106f: return "AMD_15H_UNK_c001_106f";
1636 case 0xc0011070: return "AMD_15H_UNK_c001_1070"; /* coreboot defines this, but with a numerical name. */
1637 case 0xc0011071: return "AMD_15H_UNK_c001_1071";
1638 case 0xc0011072: return "AMD_15H_UNK_c001_1072";
1639 case 0xc0011073: return "AMD_15H_UNK_c001_1073";
1640 case 0xc0011080: return "AMD_15H_UNK_c001_1080";
1641 }
1642
1643 /*
1644 * Uncore stuff on Sandy. Putting it here to avoid ugly microarch checks for each register.
1645 * Note! These are found on model 42 (2a) but not 45 (2d), the latter is the EP variant.
1646 */
1647 if (g_enmMicroarch == kCpumMicroarch_Intel_Core7_SandyBridge)
1648 switch (uMsr)
1649 {
1650 case 0x00000700: return "MSR_UNC_CBO_0_PERFEVTSEL0";
1651 case 0x00000701: return "MSR_UNC_CBO_0_PERFEVTSEL1";
1652 case 0x00000702: return "MSR_UNC_CBO_0_PERFEVTSEL2?";
1653 case 0x00000703: return "MSR_UNC_CBO_0_PERFEVTSEL3?";
1654 case 0x00000704: return "MSR_UNC_CBO_0_UNK_4";
1655 case 0x00000705: return "MSR_UNC_CBO_0_UNK_5";
1656 case 0x00000706: return "MSR_UNC_CBO_0_PER_CTR0";
1657 case 0x00000707: return "MSR_UNC_CBO_0_PER_CTR1";
1658 case 0x00000708: return "MSR_UNC_CBO_0_PER_CTR2?";
1659 case 0x00000709: return "MSR_UNC_CBO_0_PER_CTR3?";
1660 case 0x00000710: return "MSR_UNC_CBO_1_PERFEVTSEL0";
1661 case 0x00000711: return "MSR_UNC_CBO_1_PERFEVTSEL1";
1662 case 0x00000712: return "MSR_UNC_CBO_1_PERFEVTSEL2?";
1663 case 0x00000713: return "MSR_UNC_CBO_1_PERFEVTSEL3?";
1664 case 0x00000714: return "MSR_UNC_CBO_1_UNK_4";
1665 case 0x00000715: return "MSR_UNC_CBO_1_UNK_5";
1666 case 0x00000716: return "MSR_UNC_CBO_1_PER_CTR0";
1667 case 0x00000717: return "MSR_UNC_CBO_1_PER_CTR1";
1668 case 0x00000718: return "MSR_UNC_CBO_1_PER_CTR2?";
1669 case 0x00000719: return "MSR_UNC_CBO_1_PER_CTR3?";
1670 case 0x00000720: return "MSR_UNC_CBO_2_PERFEVTSEL0";
1671 case 0x00000721: return "MSR_UNC_CBO_2_PERFEVTSEL1";
1672 case 0x00000722: return "MSR_UNC_CBO_2_PERFEVTSEL2?";
1673 case 0x00000723: return "MSR_UNC_CBO_2_PERFEVTSEL3?";
1674 case 0x00000724: return "MSR_UNC_CBO_2_UNK_4";
1675 case 0x00000725: return "MSR_UNC_CBO_2_UNK_5";
1676 case 0x00000726: return "MSR_UNC_CBO_2_PER_CTR0";
1677 case 0x00000727: return "MSR_UNC_CBO_2_PER_CTR1";
1678 case 0x00000728: return "MSR_UNC_CBO_2_PER_CTR2?";
1679 case 0x00000729: return "MSR_UNC_CBO_2_PER_CTR3?";
1680 case 0x00000730: return "MSR_UNC_CBO_3_PERFEVTSEL0";
1681 case 0x00000731: return "MSR_UNC_CBO_3_PERFEVTSEL1";
1682 case 0x00000732: return "MSR_UNC_CBO_3_PERFEVTSEL2?";
1683 case 0x00000733: return "MSR_UNC_CBO_3_PERFEVTSEL3?";
1684 case 0x00000734: return "MSR_UNC_CBO_3_UNK_4";
1685 case 0x00000735: return "MSR_UNC_CBO_3_UNK_5";
1686 case 0x00000736: return "MSR_UNC_CBO_3_PER_CTR0";
1687 case 0x00000737: return "MSR_UNC_CBO_3_PER_CTR1";
1688 case 0x00000738: return "MSR_UNC_CBO_3_PER_CTR2?";
1689 case 0x00000739: return "MSR_UNC_CBO_3_PER_CTR3?";
1690 case 0x00000740: return "MSR_UNC_CBO_4_PERFEVTSEL0?";
1691 case 0x00000741: return "MSR_UNC_CBO_4_PERFEVTSEL1?";
1692 case 0x00000742: return "MSR_UNC_CBO_4_PERFEVTSEL2?";
1693 case 0x00000743: return "MSR_UNC_CBO_4_PERFEVTSEL3?";
1694 case 0x00000744: return "MSR_UNC_CBO_4_UNK_4";
1695 case 0x00000745: return "MSR_UNC_CBO_4_UNK_5";
1696 case 0x00000746: return "MSR_UNC_CBO_4_PER_CTR0?";
1697 case 0x00000747: return "MSR_UNC_CBO_4_PER_CTR1?";
1698 case 0x00000748: return "MSR_UNC_CBO_4_PER_CTR2?";
1699 case 0x00000749: return "MSR_UNC_CBO_4_PER_CTR3?";
1700
1701 }
1702
1703 /*
1704 * Bunch of unknown sandy bridge registers. They might seem like the
1705 * nehalem based xeon stuff, but the layout doesn't match. I bet it's the
1706 * same kind of registes though (i.e. uncore (UNC)).
1707 *
1708 * Kudos to Intel for keeping these a secret! Many thanks guys!!
1709 */
1710 if (g_enmMicroarch == kCpumMicroarch_Intel_Core7_SandyBridge)
1711 switch (uMsr)
1712 {
1713 case 0x00000a00: return "I7_SB_UNK_0000_0a00"; case 0x00000a01: return "I7_SB_UNK_0000_0a01";
1714 case 0x00000a02: return "I7_SB_UNK_0000_0a02";
1715 case 0x00000c00: return "I7_SB_UNK_0000_0c00"; case 0x00000c01: return "I7_SB_UNK_0000_0c01";
1716 case 0x00000c06: return "I7_SB_UNK_0000_0c06"; case 0x00000c08: return "I7_SB_UNK_0000_0c08";
1717 case 0x00000c09: return "I7_SB_UNK_0000_0c09"; case 0x00000c10: return "I7_SB_UNK_0000_0c10";
1718 case 0x00000c11: return "I7_SB_UNK_0000_0c11"; case 0x00000c14: return "I7_SB_UNK_0000_0c14";
1719 case 0x00000c15: return "I7_SB_UNK_0000_0c15"; case 0x00000c16: return "I7_SB_UNK_0000_0c16";
1720 case 0x00000c17: return "I7_SB_UNK_0000_0c17"; case 0x00000c24: return "I7_SB_UNK_0000_0c24";
1721 case 0x00000c30: return "I7_SB_UNK_0000_0c30"; case 0x00000c31: return "I7_SB_UNK_0000_0c31";
1722 case 0x00000c32: return "I7_SB_UNK_0000_0c32"; case 0x00000c33: return "I7_SB_UNK_0000_0c33";
1723 case 0x00000c34: return "I7_SB_UNK_0000_0c34"; case 0x00000c35: return "I7_SB_UNK_0000_0c35";
1724 case 0x00000c36: return "I7_SB_UNK_0000_0c36"; case 0x00000c37: return "I7_SB_UNK_0000_0c37";
1725 case 0x00000c38: return "I7_SB_UNK_0000_0c38"; case 0x00000c39: return "I7_SB_UNK_0000_0c39";
1726 case 0x00000d04: return "I7_SB_UNK_0000_0d04";
1727 case 0x00000d10: return "I7_SB_UNK_0000_0d10"; case 0x00000d11: return "I7_SB_UNK_0000_0d11";
1728 case 0x00000d12: return "I7_SB_UNK_0000_0d12"; case 0x00000d13: return "I7_SB_UNK_0000_0d13";
1729 case 0x00000d14: return "I7_SB_UNK_0000_0d14"; case 0x00000d15: return "I7_SB_UNK_0000_0d15";
1730 case 0x00000d16: return "I7_SB_UNK_0000_0d16"; case 0x00000d17: return "I7_SB_UNK_0000_0d17";
1731 case 0x00000d18: return "I7_SB_UNK_0000_0d18"; case 0x00000d19: return "I7_SB_UNK_0000_0d19";
1732 case 0x00000d24: return "I7_SB_UNK_0000_0d24";
1733 case 0x00000d30: return "I7_SB_UNK_0000_0d30"; case 0x00000d31: return "I7_SB_UNK_0000_0d31";
1734 case 0x00000d32: return "I7_SB_UNK_0000_0d32"; case 0x00000d33: return "I7_SB_UNK_0000_0d33";
1735 case 0x00000d34: return "I7_SB_UNK_0000_0d34"; case 0x00000d35: return "I7_SB_UNK_0000_0d35";
1736 case 0x00000d36: return "I7_SB_UNK_0000_0d36"; case 0x00000d37: return "I7_SB_UNK_0000_0d37";
1737 case 0x00000d38: return "I7_SB_UNK_0000_0d38"; case 0x00000d39: return "I7_SB_UNK_0000_0d39";
1738 case 0x00000d44: return "I7_SB_UNK_0000_0d44";
1739 case 0x00000d50: return "I7_SB_UNK_0000_0d50"; case 0x00000d51: return "I7_SB_UNK_0000_0d51";
1740 case 0x00000d52: return "I7_SB_UNK_0000_0d52"; case 0x00000d53: return "I7_SB_UNK_0000_0d53";
1741 case 0x00000d54: return "I7_SB_UNK_0000_0d54"; case 0x00000d55: return "I7_SB_UNK_0000_0d55";
1742 case 0x00000d56: return "I7_SB_UNK_0000_0d56"; case 0x00000d57: return "I7_SB_UNK_0000_0d57";
1743 case 0x00000d58: return "I7_SB_UNK_0000_0d58"; case 0x00000d59: return "I7_SB_UNK_0000_0d59";
1744 case 0x00000d64: return "I7_SB_UNK_0000_0d64";
1745 case 0x00000d70: return "I7_SB_UNK_0000_0d70"; case 0x00000d71: return "I7_SB_UNK_0000_0d71";
1746 case 0x00000d72: return "I7_SB_UNK_0000_0d72"; case 0x00000d73: return "I7_SB_UNK_0000_0d73";
1747 case 0x00000d74: return "I7_SB_UNK_0000_0d74"; case 0x00000d75: return "I7_SB_UNK_0000_0d75";
1748 case 0x00000d76: return "I7_SB_UNK_0000_0d76"; case 0x00000d77: return "I7_SB_UNK_0000_0d77";
1749 case 0x00000d78: return "I7_SB_UNK_0000_0d78"; case 0x00000d79: return "I7_SB_UNK_0000_0d79";
1750 case 0x00000d84: return "I7_SB_UNK_0000_0d84";
1751 case 0x00000d90: return "I7_SB_UNK_0000_0d90"; case 0x00000d91: return "I7_SB_UNK_0000_0d91";
1752 case 0x00000d92: return "I7_SB_UNK_0000_0d92"; case 0x00000d93: return "I7_SB_UNK_0000_0d93";
1753 case 0x00000d94: return "I7_SB_UNK_0000_0d94"; case 0x00000d95: return "I7_SB_UNK_0000_0d95";
1754 case 0x00000d96: return "I7_SB_UNK_0000_0d96"; case 0x00000d97: return "I7_SB_UNK_0000_0d97";
1755 case 0x00000d98: return "I7_SB_UNK_0000_0d98"; case 0x00000d99: return "I7_SB_UNK_0000_0d99";
1756 case 0x00000da4: return "I7_SB_UNK_0000_0da4";
1757 case 0x00000db0: return "I7_SB_UNK_0000_0db0"; case 0x00000db1: return "I7_SB_UNK_0000_0db1";
1758 case 0x00000db2: return "I7_SB_UNK_0000_0db2"; case 0x00000db3: return "I7_SB_UNK_0000_0db3";
1759 case 0x00000db4: return "I7_SB_UNK_0000_0db4"; case 0x00000db5: return "I7_SB_UNK_0000_0db5";
1760 case 0x00000db6: return "I7_SB_UNK_0000_0db6"; case 0x00000db7: return "I7_SB_UNK_0000_0db7";
1761 case 0x00000db8: return "I7_SB_UNK_0000_0db8"; case 0x00000db9: return "I7_SB_UNK_0000_0db9";
1762 }
1763
1764 /*
1765 * Ditto for ivy bridge (observed on the i5-3570). There are some haswell
1766 * and sandybridge related docs on registers in this ares, but either
1767 * things are different for ivy or they're very incomplete. Again, kudos
1768 * to intel!
1769 */
1770 if (g_enmMicroarch == kCpumMicroarch_Intel_Core7_IvyBridge)
1771 switch (uMsr)
1772 {
1773 case 0x00000700: return "I7_IB_UNK_0000_0700"; case 0x00000701: return "I7_IB_UNK_0000_0701";
1774 case 0x00000702: return "I7_IB_UNK_0000_0702"; case 0x00000703: return "I7_IB_UNK_0000_0703";
1775 case 0x00000704: return "I7_IB_UNK_0000_0704"; case 0x00000705: return "I7_IB_UNK_0000_0705";
1776 case 0x00000706: return "I7_IB_UNK_0000_0706"; case 0x00000707: return "I7_IB_UNK_0000_0707";
1777 case 0x00000708: return "I7_IB_UNK_0000_0708"; case 0x00000709: return "I7_IB_UNK_0000_0709";
1778 case 0x00000710: return "I7_IB_UNK_0000_0710"; case 0x00000711: return "I7_IB_UNK_0000_0711";
1779 case 0x00000712: return "I7_IB_UNK_0000_0712"; case 0x00000713: return "I7_IB_UNK_0000_0713";
1780 case 0x00000714: return "I7_IB_UNK_0000_0714"; case 0x00000715: return "I7_IB_UNK_0000_0715";
1781 case 0x00000716: return "I7_IB_UNK_0000_0716"; case 0x00000717: return "I7_IB_UNK_0000_0717";
1782 case 0x00000718: return "I7_IB_UNK_0000_0718"; case 0x00000719: return "I7_IB_UNK_0000_0719";
1783 case 0x00000720: return "I7_IB_UNK_0000_0720"; case 0x00000721: return "I7_IB_UNK_0000_0721";
1784 case 0x00000722: return "I7_IB_UNK_0000_0722"; case 0x00000723: return "I7_IB_UNK_0000_0723";
1785 case 0x00000724: return "I7_IB_UNK_0000_0724"; case 0x00000725: return "I7_IB_UNK_0000_0725";
1786 case 0x00000726: return "I7_IB_UNK_0000_0726"; case 0x00000727: return "I7_IB_UNK_0000_0727";
1787 case 0x00000728: return "I7_IB_UNK_0000_0728"; case 0x00000729: return "I7_IB_UNK_0000_0729";
1788 case 0x00000730: return "I7_IB_UNK_0000_0730"; case 0x00000731: return "I7_IB_UNK_0000_0731";
1789 case 0x00000732: return "I7_IB_UNK_0000_0732"; case 0x00000733: return "I7_IB_UNK_0000_0733";
1790 case 0x00000734: return "I7_IB_UNK_0000_0734"; case 0x00000735: return "I7_IB_UNK_0000_0735";
1791 case 0x00000736: return "I7_IB_UNK_0000_0736"; case 0x00000737: return "I7_IB_UNK_0000_0737";
1792 case 0x00000738: return "I7_IB_UNK_0000_0738"; case 0x00000739: return "I7_IB_UNK_0000_0739";
1793 case 0x00000740: return "I7_IB_UNK_0000_0740"; case 0x00000741: return "I7_IB_UNK_0000_0741";
1794 case 0x00000742: return "I7_IB_UNK_0000_0742"; case 0x00000743: return "I7_IB_UNK_0000_0743";
1795 case 0x00000744: return "I7_IB_UNK_0000_0744"; case 0x00000745: return "I7_IB_UNK_0000_0745";
1796 case 0x00000746: return "I7_IB_UNK_0000_0746"; case 0x00000747: return "I7_IB_UNK_0000_0747";
1797 case 0x00000748: return "I7_IB_UNK_0000_0748"; case 0x00000749: return "I7_IB_UNK_0000_0749";
1798
1799 }
1800 return NULL;
1801}
1802
1803
1804/**
1805 * Gets the name of an MSR.
1806 *
1807 * This may return a static buffer, so the content should only be considered
1808 * valid until the next time this function is called!.
1809 *
1810 * @returns MSR name.
1811 * @param uMsr The MSR in question.
1812 */
1813static const char *getMsrName(uint32_t uMsr)
1814{
1815 const char *pszReadOnly = getMsrNameHandled(uMsr);
1816 if (pszReadOnly)
1817 return pszReadOnly;
1818
1819 /*
1820 * This MSR needs looking into, return a TODO_XXXX_XXXX name.
1821 */
1822 static char s_szBuf[32];
1823 RTStrPrintf(s_szBuf, sizeof(s_szBuf), "TODO_%04x_%04x", RT_HI_U16(uMsr), RT_LO_U16(uMsr));
1824 return s_szBuf;
1825}
1826
1827
1828
1829/**
1830 * Gets the name of an MSR range.
1831 *
1832 * This may return a static buffer, so the content should only be considered
1833 * valid until the next time this function is called!.
1834 *
1835 * @returns MSR name.
1836 * @param uMsr The first MSR in the range.
1837 */
1838static const char *getMsrRangeName(uint32_t uMsr)
1839{
1840 switch (uMsr)
1841 {
1842 case 0x00000040:
1843 return g_enmMicroarch >= kCpumMicroarch_Intel_Core_Yonah ? "MSR_LASTBRANCH_n_FROM_IP" : "MSR_LASTBRANCH_n";
1844 case 0x00000060:
1845 if (g_enmMicroarch >= kCpumMicroarch_Intel_Core_Yonah)
1846 return "MSR_LASTBRANCH_n_TO_IP";
1847 break;
1848
1849 case 0x000003f8:
1850 case 0x000003f9:
1851 case 0x000003fa:
1852 return "I7_MSR_PKG_Cn_RESIDENCY";
1853 case 0x000003fc:
1854 case 0x000003fd:
1855 case 0x000003fe:
1856 return "I7_MSR_CORE_Cn_RESIDENCY";
1857
1858 case 0x00000400:
1859 return "IA32_MCi_CTL_STATUS_ADDR_MISC";
1860
1861 case 0x00000680:
1862 return "MSR_LASTBRANCH_n_FROM_IP";
1863 case 0x000006c0:
1864 return "MSR_LASTBRANCH_n_TO_IP";
1865
1866 case 0x00000800: case 0x00000801: case 0x00000802: case 0x00000803:
1867 case 0x00000804: case 0x00000805: case 0x00000806: case 0x00000807:
1868 case 0x00000808: case 0x00000809: case 0x0000080a: case 0x0000080b:
1869 case 0x0000080c: case 0x0000080d: case 0x0000080e: case 0x0000080f:
1870 return "IA32_X2APIC_n";
1871 }
1872
1873 static char s_szBuf[96];
1874 const char *pszReadOnly = getMsrNameHandled(uMsr);
1875 if (pszReadOnly)
1876 {
1877 /*
1878 * Replace the last char with 'n'.
1879 */
1880 RTStrCopy(s_szBuf, sizeof(s_szBuf), pszReadOnly);
1881 size_t off = strlen(s_szBuf);
1882 if (off > 0)
1883 off--;
1884 if (off + 1 < sizeof(s_szBuf))
1885 {
1886 s_szBuf[off] = 'n';
1887 s_szBuf[off + 1] = '\0';
1888 }
1889 }
1890 else
1891 {
1892 /*
1893 * This MSR needs looking into, return a TODO_XXXX_XXXX_n name.
1894 */
1895 RTStrPrintf(s_szBuf, sizeof(s_szBuf), "TODO_%04x_%04x_n", RT_HI_U16(uMsr), RT_LO_U16(uMsr));
1896 }
1897 return s_szBuf;
1898}
1899
1900
1901/**
1902 * Returns the function name for MSRs that have one or two.
1903 *
1904 * @returns Function name if applicable, NULL if not.
1905 * @param uMsr The MSR in question.
1906 * @param pfTakesValue Whether this MSR function takes a value or not.
1907 * Optional.
1908 */
1909static const char *getMsrFnName(uint32_t uMsr, bool *pfTakesValue)
1910{
1911 bool fTmp;
1912 if (!pfTakesValue)
1913 pfTakesValue = &fTmp;
1914
1915 *pfTakesValue = false;
1916
1917 switch (uMsr)
1918 {
1919 case 0x00000000: return "Ia32P5McAddr";
1920 case 0x00000001: return "Ia32P5McType";
1921 case 0x00000006:
1922 if (g_enmMicroarch >= kCpumMicroarch_Intel_First && g_enmMicroarch <= kCpumMicroarch_Intel_P6_Core_Atom_First)
1923 return NULL; /* TR4 / cache tag on Pentium, but that's for later. */
1924 return "Ia32MonitorFilterLineSize";
1925 case 0x00000010: return "Ia32TimestampCounter";
1926 case 0x00000017: *pfTakesValue = true; return "Ia32PlatformId";
1927 case 0x0000001b: return "Ia32ApicBase";
1928 case 0x0000002a: *pfTakesValue = true; return g_fIntelNetBurst ? "IntelP4EbcHardPowerOn" : "IntelEblCrPowerOn";
1929 case 0x0000002b: *pfTakesValue = true; return g_fIntelNetBurst ? "IntelP4EbcSoftPowerOn" : NULL;
1930 case 0x0000002c: *pfTakesValue = true; return g_fIntelNetBurst ? "IntelP4EbcFrequencyId" : NULL;
1931 //case 0x00000033: return "IntelTestCtl";
1932 case 0x00000034: return CPUMMICROARCH_IS_INTEL_CORE7(g_enmMicroarch)
1933 || CPUMMICROARCH_IS_INTEL_SILVERMONT_PLUS(g_enmMicroarch)
1934 ? "IntelI7SmiCount" : NULL;
1935 case 0x00000035: return CPUMMICROARCH_IS_INTEL_CORE7(g_enmMicroarch) ? "IntelI7CoreThreadCount" : NULL;
1936 case 0x0000003a: return "Ia32FeatureControl";
1937
1938 case 0x00000040:
1939 case 0x00000041:
1940 case 0x00000042:
1941 case 0x00000043:
1942 case 0x00000044:
1943 case 0x00000045:
1944 case 0x00000046:
1945 case 0x00000047:
1946 return "IntelLastBranchFromToN";
1947
1948 case 0x0000008b: return g_enmVendor == CPUMCPUVENDOR_AMD ? "AmdK8PatchLevel" : "Ia32BiosSignId";
1949 case 0x0000009b: return "Ia32SmmMonitorCtl";
1950
1951 case 0x000000a8:
1952 case 0x000000a9:
1953 case 0x000000aa:
1954 case 0x000000ab:
1955 case 0x000000ac:
1956 case 0x000000ad:
1957 *pfTakesValue = true;
1958 return "IntelCore2EmttmCrTablesN";
1959
1960 case 0x000000c1:
1961 case 0x000000c2:
1962 case 0x000000c3:
1963 case 0x000000c4:
1964 return "Ia32PmcN";
1965 case 0x000000c5:
1966 case 0x000000c6:
1967 case 0x000000c7:
1968 case 0x000000c8:
1969 if (g_enmMicroarch >= kCpumMicroarch_Intel_Core7_First)
1970 return "Ia32PmcN";
1971 return NULL;
1972
1973 case 0x000000cd: *pfTakesValue = true; return "IntelP6FsbFrequency";
1974 case 0x000000ce: return CPUMMICROARCH_IS_INTEL_CORE7(g_enmMicroarch) ? "IntelPlatformInfo" : NULL;
1975 case 0x000000e2: return "IntelPkgCStConfigControl";
1976 case 0x000000e3: return "IntelCore2SmmCStMiscInfo";
1977 case 0x000000e4: return "IntelPmgIoCaptureBase";
1978 case 0x000000e7: return "Ia32MPerf";
1979 case 0x000000e8: return "Ia32APerf";
1980 case 0x000000ee: return "IntelCore1ExtConfig";
1981 case 0x000000fe: *pfTakesValue = true; return "Ia32MtrrCap";
1982 case 0x00000119: *pfTakesValue = true; return "IntelBblCrCtl";
1983 case 0x0000011e: *pfTakesValue = true; return "IntelBblCrCtl3";
1984
1985 case 0x00000130: return g_enmMicroarch == kCpumMicroarch_Intel_Core7_Westmere
1986 || g_enmMicroarch == kCpumMicroarch_Intel_Core7_Nehalem
1987 ? "IntelCpuId1FeatureMaskEcdx" : NULL;
1988 case 0x00000131: return g_enmMicroarch == kCpumMicroarch_Intel_Core7_Westmere
1989 || g_enmMicroarch == kCpumMicroarch_Intel_Core7_Nehalem
1990 ? "IntelCpuId80000001FeatureMaskEcdx" : NULL;
1991 case 0x00000132: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge
1992 ? "IntelCpuId1FeatureMaskEax" : NULL;
1993 case 0x00000133: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge
1994 ? "IntelCpuId1FeatureMaskEcdx" : NULL;
1995 case 0x00000134: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge
1996 ? "IntelCpuId80000001FeatureMaskEcdx" : NULL;
1997 case 0x0000013c: return "IntelI7SandyAesNiCtl";
1998 case 0x0000015f: return "IntelCore1DtsCalControl";
1999 case 0x00000174: return "Ia32SysEnterCs";
2000 case 0x00000175: return "Ia32SysEnterEsp";
2001 case 0x00000176: return "Ia32SysEnterEip";
2002 case 0x00000179: *pfTakesValue = true; return "Ia32McgCap";
2003 case 0x0000017a: return "Ia32McgStatus";
2004 case 0x0000017b: return "Ia32McgCtl";
2005 case 0x0000017f: return "IntelI7SandyErrorControl"; /* SandyBridge. */
2006 case 0x00000186: return "Ia32PerfEvtSelN";
2007 case 0x00000187: return "Ia32PerfEvtSelN";
2008 case 0x00000193: return /*g_fIntelNetBurst ? NULL :*/ NULL /* Core2_Penryn. */;
2009 case 0x00000194: if (g_fIntelNetBurst) break; *pfTakesValue = true; return "IntelFlexRatio";
2010 case 0x00000198: *pfTakesValue = true; return "Ia32PerfStatus";
2011 case 0x00000199: *pfTakesValue = true; return "Ia32PerfCtl";
2012 case 0x0000019a: *pfTakesValue = true; return "Ia32ClockModulation";
2013 case 0x0000019b: *pfTakesValue = true; return "Ia32ThermInterrupt";
2014 case 0x0000019c: *pfTakesValue = true; return "Ia32ThermStatus";
2015 case 0x0000019d: *pfTakesValue = true; return "Ia32Therm2Ctl";
2016 case 0x000001a0: *pfTakesValue = true; return "Ia32MiscEnable";
2017 case 0x000001a2: *pfTakesValue = true; return "IntelI7TemperatureTarget";
2018 case 0x000001a6: return "IntelI7MsrOffCoreResponseN";
2019 case 0x000001a7: return "IntelI7MsrOffCoreResponseN";
2020 case 0x000001aa: return CPUMMICROARCH_IS_INTEL_CORE7(g_enmMicroarch) ? "IntelI7MiscPwrMgmt" : NULL /*"P6PicSensCfg"*/;
2021 case 0x000001ad: *pfTakesValue = true; return "IntelI7TurboRatioLimit"; /* SandyBridge+, Silvermount+ */
2022 case 0x000001c8: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_Nehalem ? "IntelI7LbrSelect" : NULL;
2023 case 0x000001c9: return g_enmMicroarch >= kCpumMicroarch_Intel_Core_Yonah
2024 && g_enmMicroarch <= kCpumMicroarch_Intel_P6_Core_Atom_End
2025 ? "IntelLastBranchTos" : NULL /* Pentium M Dothan seems to have something else here. */;
2026 case 0x000001d7: return g_fIntelNetBurst ? "P6LastIntFromIp" : NULL;
2027 case 0x000001d8: return g_fIntelNetBurst ? "P6LastIntToIp" : NULL;
2028 case 0x000001d9: return "Ia32DebugCtl";
2029 case 0x000001da: return g_fIntelNetBurst ? "IntelLastBranchTos" : NULL;
2030 case 0x000001db: return g_fIntelNetBurst ? "IntelLastBranchFromToN" : "P6LastBranchFromIp";
2031 case 0x000001dc: return g_fIntelNetBurst ? "IntelLastBranchFromToN" : "P6LastBranchToIp";
2032 case 0x000001dd: return g_fIntelNetBurst ? "IntelLastBranchFromToN" : "P6LastIntFromIp";
2033 case 0x000001de: return g_fIntelNetBurst ? "IntelLastBranchFromToN" : "P6LastIntToIp";
2034 case 0x000001f0: return "IntelI7VirtualLegacyWireCap"; /* SandyBridge. */
2035 case 0x000001f2: return "Ia32SmrrPhysBase";
2036 case 0x000001f3: return "Ia32SmrrPhysMask";
2037 case 0x000001f8: return "Ia32PlatformDcaCap";
2038 case 0x000001f9: return "Ia32CpuDcaCap";
2039 case 0x000001fa: return "Ia32Dca0Cap";
2040 case 0x000001fc: return "IntelI7PowerCtl";
2041
2042 case 0x00000200: case 0x00000202: case 0x00000204: case 0x00000206:
2043 case 0x00000208: case 0x0000020a: case 0x0000020c: case 0x0000020e:
2044 case 0x00000210: case 0x00000212: case 0x00000214: case 0x00000216:
2045 case 0x00000218: case 0x0000021a: case 0x0000021c: case 0x0000021e:
2046 return "Ia32MtrrPhysBaseN";
2047 case 0x00000201: case 0x00000203: case 0x00000205: case 0x00000207:
2048 case 0x00000209: case 0x0000020b: case 0x0000020d: case 0x0000020f:
2049 case 0x00000211: case 0x00000213: case 0x00000215: case 0x00000217:
2050 case 0x00000219: case 0x0000021b: case 0x0000021d: case 0x0000021f:
2051 return "Ia32MtrrPhysMaskN";
2052 case 0x00000250:
2053 case 0x00000258: case 0x00000259:
2054 case 0x00000268: case 0x00000269: case 0x0000026a: case 0x0000026b:
2055 case 0x0000026c: case 0x0000026d: case 0x0000026e: case 0x0000026f:
2056 return "Ia32MtrrFixed";
2057 case 0x00000277: *pfTakesValue = true; return "Ia32Pat";
2058
2059 case 0x00000280: case 0x00000281: case 0x00000282: case 0x00000283:
2060 case 0x00000284: case 0x00000285: case 0x00000286: case 0x00000287:
2061 case 0x00000288: case 0x00000289: case 0x0000028a: case 0x0000028b:
2062 case 0x0000028c: case 0x0000028d: case 0x0000028e: case 0x0000028f:
2063 case 0x00000290: case 0x00000291: case 0x00000292: case 0x00000293:
2064 case 0x00000294: case 0x00000295: //case 0x00000296: case 0x00000297:
2065 //case 0x00000298: case 0x00000299: case 0x0000029a: case 0x0000029b:
2066 //case 0x0000029c: case 0x0000029d: case 0x0000029e: case 0x0000029f:
2067 return "Ia32McNCtl2";
2068
2069 case 0x000002ff: return "Ia32MtrrDefType";
2070 //case 0x00000305: return g_fIntelNetBurst ? TODO : NULL;
2071 case 0x00000309: return g_fIntelNetBurst ? NULL /** @todo P4 */ : "Ia32FixedCtrN";
2072 case 0x0000030a: return g_fIntelNetBurst ? NULL /** @todo P4 */ : "Ia32FixedCtrN";
2073 case 0x0000030b: return g_fIntelNetBurst ? NULL /** @todo P4 */ : "Ia32FixedCtrN";
2074 case 0x00000345: *pfTakesValue = true; return "Ia32PerfCapabilities";
2075 /* Note! Lots of P4 MSR 0x00000360..0x00000371. */
2076 case 0x0000038d: return "Ia32FixedCtrCtrl";
2077 case 0x0000038e: *pfTakesValue = true; return "Ia32PerfGlobalStatus";
2078 case 0x0000038f: return "Ia32PerfGlobalCtrl";
2079 case 0x00000390: return "Ia32PerfGlobalOvfCtrl";
2080 case 0x00000391: return "IntelI7UncPerfGlobalCtrl"; /* S,H,X */
2081 case 0x00000392: return "IntelI7UncPerfGlobalStatus"; /* S,H,X */
2082 case 0x00000393: return "IntelI7UncPerfGlobalOvfCtrl"; /* X. ASSUMING this is the same on sandybridge and later. */
2083 case 0x00000394: return g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "IntelI7UncPerfFixedCtr" /* X */ : "IntelI7UncPerfFixedCtrCtrl"; /* >= S,H */
2084 case 0x00000395: return g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "IntelI7UncPerfFixedCtrCtrl" /* X*/ : "IntelI7UncPerfFixedCtr"; /* >= S,H */
2085 case 0x00000396: return g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "IntelI7UncAddrOpcodeMatch" /* X */ : "IntelI7UncCBoxConfig"; /* >= S,H */
2086 case 0x0000039c: return "IntelI7SandyPebsNumAlt";
2087 /* Note! Lots of P4 MSR 0x000003a0..0x000003e1. */
2088 case 0x000003b0: return g_fIntelNetBurst ? NULL : g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "IntelI7UncPmcN" /* X */ : "IntelI7UncArbPerfCtrN"; /* >= S,H */
2089 case 0x000003b1: return g_fIntelNetBurst ? NULL : g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "IntelI7UncPmcN" /* X */ : "IntelI7UncArbPerfCtrN"; /* >= S,H */
2090 case 0x000003b2: return g_fIntelNetBurst ? NULL : g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "IntelI7UncPmcN" /* X */ : "IntelI7UncArbPerfEvtSelN"; /* >= S,H */
2091 case 0x000003b3: return g_fIntelNetBurst ? NULL : g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "IntelI7UncPmcN" /* X */ : "IntelI7UncArbPerfEvtSelN"; /* >= S,H */
2092 case 0x000003b4: case 0x000003b5: case 0x000003b6: case 0x000003b7:
2093 return g_fIntelNetBurst ? NULL : "IntelI7UncPmcN";
2094 case 0x000003c0: case 0x000003c1: case 0x000003c2: case 0x000003c3:
2095 case 0x000003c4: case 0x000003c5: case 0x000003c6: case 0x000003c7:
2096 return g_fIntelNetBurst ? NULL : "IntelI7UncPerfEvtSelN";
2097 case 0x000003f1: return "Ia32PebsEnable";
2098 case 0x000003f6: return g_fIntelNetBurst ? NULL /*??*/ : "IntelI7PebsLdLat";
2099 case 0x000003f8: return g_fIntelNetBurst ? NULL : "IntelI7PkgCnResidencyN";
2100 case 0x000003f9: return "IntelI7PkgCnResidencyN";
2101 case 0x000003fa: return "IntelI7PkgCnResidencyN";
2102 case 0x000003fc: return "IntelI7CoreCnResidencyN";
2103 case 0x000003fd: return "IntelI7CoreCnResidencyN";
2104 case 0x000003fe: return "IntelI7CoreCnResidencyN";
2105
2106 case 0x00000478: return g_enmMicroarch == kCpumMicroarch_Intel_Core2_Penryn ? "IntelCpuId1FeatureMaskEcdx" : NULL;
2107 case 0x00000480: *pfTakesValue = true; return "Ia32VmxBasic";
2108 case 0x00000481: *pfTakesValue = true; return "Ia32VmxPinbasedCtls";
2109 case 0x00000482: *pfTakesValue = true; return "Ia32VmxProcbasedCtls";
2110 case 0x00000483: *pfTakesValue = true; return "Ia32VmxExitCtls";
2111 case 0x00000484: *pfTakesValue = true; return "Ia32VmxEntryCtls";
2112 case 0x00000485: *pfTakesValue = true; return "Ia32VmxMisc";
2113 case 0x00000486: *pfTakesValue = true; return "Ia32VmxCr0Fixed0";
2114 case 0x00000487: *pfTakesValue = true; return "Ia32VmxCr0Fixed1";
2115 case 0x00000488: *pfTakesValue = true; return "Ia32VmxCr4Fixed0";
2116 case 0x00000489: *pfTakesValue = true; return "Ia32VmxCr4Fixed1";
2117 case 0x0000048a: *pfTakesValue = true; return "Ia32VmxVmcsEnum";
2118 case 0x0000048b: *pfTakesValue = true; return "Ia32VmxProcBasedCtls2";
2119 case 0x0000048c: *pfTakesValue = true; return "Ia32VmxEptVpidCap";
2120 case 0x0000048d: *pfTakesValue = true; return "Ia32VmxTruePinbasedCtls";
2121 case 0x0000048e: *pfTakesValue = true; return "Ia32VmxTrueProcbasedCtls";
2122 case 0x0000048f: *pfTakesValue = true; return "Ia32VmxTrueExitCtls";
2123 case 0x00000490: *pfTakesValue = true; return "Ia32VmxTrueEntryCtls";
2124 case 0x00000491: *pfTakesValue = true; return "Ia32VmxVmFunc";
2125
2126 case 0x000004c1:
2127 case 0x000004c2:
2128 case 0x000004c3:
2129 case 0x000004c4:
2130 case 0x000004c5:
2131 case 0x000004c6:
2132 case 0x000004c7:
2133 case 0x000004c8:
2134 return "Ia32PmcN";
2135
2136 case 0x000005a0: return "IntelCore2PeciControl"; /* Core2_Penryn. */
2137
2138 case 0x00000600: return "Ia32DsArea";
2139 case 0x00000601: *pfTakesValue = true; return "IntelI7SandyVrCurrentConfig";
2140 case 0x00000603: *pfTakesValue = true; return "IntelI7SandyVrMiscConfig";
2141 case 0x00000606: *pfTakesValue = true; return "IntelI7SandyRaplPowerUnit";
2142 case 0x0000060a: *pfTakesValue = true; return "IntelI7SandyPkgCnIrtlN";
2143 case 0x0000060b: *pfTakesValue = true; return "IntelI7SandyPkgCnIrtlN";
2144 case 0x0000060c: *pfTakesValue = true; return "IntelI7SandyPkgCnIrtlN";
2145 case 0x0000060d: *pfTakesValue = true; return "IntelI7SandyPkgC2Residency";
2146
2147 case 0x00000610: *pfTakesValue = true; return "IntelI7RaplPkgPowerLimit";
2148 case 0x00000611: *pfTakesValue = true; return "IntelI7RaplPkgEnergyStatus";
2149 case 0x00000613: *pfTakesValue = true; return "IntelI7RaplPkgPerfStatus";
2150 case 0x00000614: *pfTakesValue = true; return "IntelI7RaplPkgPowerInfo";
2151 case 0x00000618: *pfTakesValue = true; return "IntelI7RaplDramPowerLimit";
2152 case 0x00000619: *pfTakesValue = true; return "IntelI7RaplDramEnergyStatus";
2153 case 0x0000061b: *pfTakesValue = true; return "IntelI7RaplDramPerfStatus";
2154 case 0x0000061c: *pfTakesValue = true; return "IntelI7RaplDramPowerInfo";
2155 case 0x00000638: *pfTakesValue = true; return "IntelI7RaplPp0PowerLimit";
2156 case 0x00000639: *pfTakesValue = true; return "IntelI7RaplPp0EnergyStatus";
2157 case 0x0000063a: *pfTakesValue = true; return "IntelI7RaplPp0Policy";
2158 case 0x0000063b: *pfTakesValue = true; return "IntelI7RaplPp0PerfStatus";
2159 case 0x00000640: *pfTakesValue = true; return "IntelI7RaplPp1PowerLimit";
2160 case 0x00000641: *pfTakesValue = true; return "IntelI7RaplPp1EnergyStatus";
2161 case 0x00000642: *pfTakesValue = true; return "IntelI7RaplPp1Policy";
2162 case 0x00000648: *pfTakesValue = true; return "IntelI7IvyConfigTdpNominal";
2163 case 0x00000649: *pfTakesValue = true; return "IntelI7IvyConfigTdpLevel1";
2164 case 0x0000064a: *pfTakesValue = true; return "IntelI7IvyConfigTdpLevel2";
2165 case 0x0000064b: return "IntelI7IvyConfigTdpControl";
2166 case 0x0000064c: return "IntelI7IvyTurboActivationRatio";
2167
2168 case 0x00000660: return "IntelAtSilvCoreC1Recidency";
2169
2170 case 0x00000680: case 0x00000681: case 0x00000682: case 0x00000683:
2171 case 0x00000684: case 0x00000685: case 0x00000686: case 0x00000687:
2172 case 0x00000688: case 0x00000689: case 0x0000068a: case 0x0000068b:
2173 case 0x0000068c: case 0x0000068d: case 0x0000068e: case 0x0000068f:
2174 //case 0x00000690: case 0x00000691: case 0x00000692: case 0x00000693:
2175 //case 0x00000694: case 0x00000695: case 0x00000696: case 0x00000697:
2176 //case 0x00000698: case 0x00000699: case 0x0000069a: case 0x0000069b:
2177 //case 0x0000069c: case 0x0000069d: case 0x0000069e: case 0x0000069f:
2178 return "IntelLastBranchFromN";
2179 case 0x000006c0: case 0x000006c1: case 0x000006c2: case 0x000006c3:
2180 case 0x000006c4: case 0x000006c5: case 0x000006c6: case 0x000006c7:
2181 case 0x000006c8: case 0x000006c9: case 0x000006ca: case 0x000006cb:
2182 case 0x000006cc: case 0x000006cd: case 0x000006ce: case 0x000006cf:
2183 //case 0x000006d0: case 0x000006d1: case 0x000006d2: case 0x000006d3:
2184 //case 0x000006d4: case 0x000006d5: case 0x000006d6: case 0x000006d7:
2185 //case 0x000006d8: case 0x000006d9: case 0x000006da: case 0x000006db:
2186 //case 0x000006dc: case 0x000006dd: case 0x000006de: case 0x000006df:
2187 return "IntelLastBranchToN";
2188 case 0x000006e0: return "Ia32TscDeadline"; /** @todo detect this correctly! */
2189
2190 case 0x00000c80: return g_enmMicroarch > kCpumMicroarch_Intel_Core7_Nehalem ? "Ia32DebugInterface" : NULL;
2191
2192 case 0xc0000080: return "Amd64Efer";
2193 case 0xc0000081: return "Amd64SyscallTarget";
2194 case 0xc0000082: return "Amd64LongSyscallTarget";
2195 case 0xc0000083: return "Amd64CompSyscallTarget";
2196 case 0xc0000084: return "Amd64SyscallFlagMask";
2197 case 0xc0000100: return "Amd64FsBase";
2198 case 0xc0000101: return "Amd64GsBase";
2199 case 0xc0000102: return "Amd64KernelGsBase";
2200 case 0xc0000103: return "Amd64TscAux";
2201 case 0xc0000104: return "AmdFam15hTscRate";
2202 case 0xc0000105: return "AmdFam15hLwpCfg";
2203 case 0xc0000106: return "AmdFam15hLwpCbAddr";
2204 case 0xc0000408: return "AmdFam10hMc4MiscN";
2205 case 0xc0000409: return "AmdFam10hMc4MiscN";
2206 case 0xc000040a: return "AmdFam10hMc4MiscN";
2207 case 0xc000040b: return "AmdFam10hMc4MiscN";
2208 case 0xc000040c: return "AmdFam10hMc4MiscN";
2209 case 0xc000040d: return "AmdFam10hMc4MiscN";
2210 case 0xc000040e: return "AmdFam10hMc4MiscN";
2211 case 0xc000040f: return "AmdFam10hMc4MiscN";
2212 case 0xc0010000: return "AmdK8PerfCtlN";
2213 case 0xc0010001: return "AmdK8PerfCtlN";
2214 case 0xc0010002: return "AmdK8PerfCtlN";
2215 case 0xc0010003: return "AmdK8PerfCtlN";
2216 case 0xc0010004: return "AmdK8PerfCtrN";
2217 case 0xc0010005: return "AmdK8PerfCtrN";
2218 case 0xc0010006: return "AmdK8PerfCtrN";
2219 case 0xc0010007: return "AmdK8PerfCtrN";
2220 case 0xc0010010: *pfTakesValue = true; return "AmdK8SysCfg";
2221 case 0xc0010015: return "AmdK8HwCr";
2222 case 0xc0010016: case 0xc0010018: return "AmdK8IorrBaseN";
2223 case 0xc0010017: case 0xc0010019: return "AmdK8IorrMaskN";
2224 case 0xc001001a: case 0xc001001d: return "AmdK8TopOfMemN";
2225 case 0xc001001f: return "AmdK8NbCfg1";
2226 case 0xc0010020: return "AmdK8PatchLoader";
2227 case 0xc0010022: return "AmdK8McXcptRedir";
2228 case 0xc0010030: case 0xc0010031: case 0xc0010032:
2229 case 0xc0010033: case 0xc0010034: case 0xc0010035:
2230 return "AmdK8CpuNameN";
2231 case 0xc001003e: *pfTakesValue = true; return "AmdK8HwThermalCtrl";
2232 case 0xc001003f: return "AmdK8SwThermalCtrl";
2233 case 0xc0010041: *pfTakesValue = true; return "AmdK8FidVidControl";
2234 case 0xc0010042: *pfTakesValue = true; return "AmdK8FidVidStatus";
2235 case 0xc0010044: case 0xc0010045: case 0xc0010046: case 0xc0010047:
2236 case 0xc0010048: case 0xc0010049: case 0xc001004a: //case 0xc001004b:
2237 return "AmdK8McCtlMaskN";
2238 case 0xc0010050: case 0xc0010051: case 0xc0010052: case 0xc0010053:
2239 return "AmdK8SmiOnIoTrapN";
2240 case 0xc0010054: return "AmdK8SmiOnIoTrapCtlSts";
2241 case 0xc0010055: return "AmdK8IntPendingMessage";
2242 case 0xc0010056: return "AmdK8SmiTriggerIoCycle";
2243 case 0xc0010058: return "AmdFam10hMmioCfgBaseAddr";
2244 case 0xc0010059: return "AmdFam10hTrapCtlMaybe";
2245 case 0xc0010061: *pfTakesValue = true; return "AmdFam10hPStateCurLimit";
2246 case 0xc0010062: *pfTakesValue = true; return "AmdFam10hPStateControl";
2247 case 0xc0010063: *pfTakesValue = true; return "AmdFam10hPStateStatus";
2248 case 0xc0010064: case 0xc0010065: case 0xc0010066: case 0xc0010067:
2249 case 0xc0010068: case 0xc0010069: case 0xc001006a: case 0xc001006b:
2250 *pfTakesValue = true; return "AmdFam10hPStateN";
2251 case 0xc0010070: *pfTakesValue = true; return "AmdFam10hCofVidControl";
2252 case 0xc0010071: *pfTakesValue = true; return "AmdFam10hCofVidStatus";
2253 case 0xc0010073: return "AmdFam10hCStateIoBaseAddr";
2254 case 0xc0010074: return "AmdFam10hCpuWatchdogTimer";
2255 // case 0xc0010075: return "AmdFam15hApmlTdpLimit";
2256 // case 0xc0010077: return "AmdFam15hCpuPowerInTdp";
2257 // case 0xc0010078: return "AmdFam15hPowerAveragingPeriod";
2258 // case 0xc0010079: return "AmdFam15hDramCtrlCmdThrottle";
2259 // case 0xc0010080: return "AmdFam16hFreqSensFeedbackMonActCnt0";
2260 // case 0xc0010081: return "AmdFam16hFreqSensFeedbackMonRefCnt0";
2261 case 0xc0010111: return "AmdK8SmmBase"; /** @todo probably misdetected ign/gp due to locking */
2262 case 0xc0010112: return "AmdK8SmmAddr"; /** @todo probably misdetected ign/gp due to locking */
2263 case 0xc0010113: return "AmdK8SmmMask"; /** @todo probably misdetected ign/gp due to locking */
2264 case 0xc0010114: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm_AMDV ? "AmdK8VmCr" : NULL; /** @todo probably misdetected due to locking */
2265 case 0xc0010115: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm ? "AmdK8IgnNe" : NULL;
2266 case 0xc0010116: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm ? "AmdK8SmmCtl" : NULL;
2267 case 0xc0010117: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm_AMDV ? "AmdK8VmHSavePa" : NULL; /** @todo probably misdetected due to locking */
2268 case 0xc0010118: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm_AMDV ? "AmdFam10hVmLockKey" : NULL;
2269 case 0xc0010119: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm ? "AmdFam10hSmmLockKey" : NULL; /* Not documented by BKDG, found in netbsd patch. */
2270 case 0xc001011a: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm ? "AmdFam10hLocalSmiStatus" : NULL;
2271 case 0xc0010140: *pfTakesValue = true; return "AmdFam10hOsVisWrkIdLength";
2272 case 0xc0010141: *pfTakesValue = true; return "AmdFam10hOsVisWrkStatus";
2273 case 0xc0010200: case 0xc0010202: case 0xc0010204: case 0xc0010206:
2274 case 0xc0010208: case 0xc001020a: //case 0xc001020c: case 0xc001020e:
2275 return "AmdK8PerfCtlN";
2276 case 0xc0010201: case 0xc0010203: case 0xc0010205: case 0xc0010207:
2277 case 0xc0010209: case 0xc001020b: //case 0xc001020d: case 0xc001020f:
2278 return "AmdK8PerfCtrN";
2279 case 0xc0010230: case 0xc0010232: case 0xc0010234: case 0xc0010236:
2280 //case 0xc0010238: case 0xc001023a: case 0xc001030c: case 0xc001023e:
2281 return "AmdFam16hL2IPerfCtlN";
2282 case 0xc0010231: case 0xc0010233: case 0xc0010235: case 0xc0010237:
2283 //case 0xc0010239: case 0xc001023b: case 0xc001023d: case 0xc001023f:
2284 return "AmdFam16hL2IPerfCtrN";
2285 case 0xc0010240: case 0xc0010242: case 0xc0010244: case 0xc0010246:
2286 //case 0xc0010248: case 0xc001024a: case 0xc001024c: case 0xc001024e:
2287 return "AmdFam15hNorthbridgePerfCtlN";
2288 case 0xc0010241: case 0xc0010243: case 0xc0010245: case 0xc0010247:
2289 //case 0xc0010249: case 0xc001024b: case 0xc001024d: case 0xc001024f:
2290 return "AmdFam15hNorthbridgePerfCtrN";
2291 case 0xc0011000: *pfTakesValue = true; return "AmdK7MicrocodeCtl";
2292 case 0xc0011001: *pfTakesValue = true; return "AmdK7ClusterIdMaybe";
2293 case 0xc0011002: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AmdK8CpuIdCtlStd07hEbax" : NULL;
2294 case 0xc0011003: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AmdK8CpuIdCtlStd06hEcx" : NULL;
2295 case 0xc0011004: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AmdK8CpuIdCtlStd01hEdcx" : NULL;
2296 case 0xc0011005: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AmdK8CpuIdCtlExt01hEdcx" : NULL;
2297 case 0xc0011006: return "AmdK7DebugStatusMaybe";
2298 case 0xc0011007: return "AmdK7BHTraceBaseMaybe";
2299 case 0xc0011008: return "AmdK7BHTracePtrMaybe";
2300 case 0xc0011009: return "AmdK7BHTraceLimitMaybe";
2301 case 0xc001100a: return "AmdK7HardwareDebugToolCfgMaybe";
2302 case 0xc001100b: return "AmdK7FastFlushCountMaybe";
2303 case 0xc001100c: return "AmdK7NodeId"; /** @todo dunno if this was there is K7 already. Kinda doubt it. */
2304 case 0xc0011019: return g_enmMicroarch >= kCpumMicroarch_AMD_15h_Piledriver ? "AmdK7DrXAddrMaskN" : NULL;
2305 case 0xc001101a: return g_enmMicroarch >= kCpumMicroarch_AMD_15h_Piledriver ? "AmdK7DrXAddrMaskN" : NULL;
2306 case 0xc001101b: return g_enmMicroarch >= kCpumMicroarch_AMD_15h_Piledriver ? "AmdK7DrXAddrMaskN" : NULL;
2307 case 0xc0011020: return "AmdK7LoadStoreCfg";
2308 case 0xc0011021: return "AmdK7InstrCacheCfg";
2309 case 0xc0011022: return "AmdK7DataCacheCfg";
2310 case 0xc0011023: return CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch) ? "AmdFam15hCombUnitCfg" : "AmdK7BusUnitCfg";
2311 case 0xc0011024: return "AmdK7DebugCtl2Maybe";
2312 case 0xc0011025: return "AmdK7Dr0DataMatchMaybe";
2313 case 0xc0011026: return "AmdK7Dr0DataMaskMaybe";
2314 case 0xc0011027: return "AmdK7DrXAddrMaskN";
2315 case 0xc0011028: return g_enmMicroarch >= kCpumMicroarch_AMD_15h_First ? "AmdFam15hFpuCfg" : NULL;
2316 case 0xc0011029: return g_enmMicroarch >= kCpumMicroarch_AMD_15h_First ? "AmdFam15hDecoderCfg" : NULL;
2317 case 0xc001102a: return CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch) ? "AmdFam15hCombUnitCfg2"
2318 : CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch) || g_enmMicroarch > kCpumMicroarch_AMD_15h_End
2319 ? "AmdFam10hBusUnitCfg2" /* 10h & 16h */ : NULL;
2320 case 0xc001102b: return CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch) ? "AmdFam15hCombUnitCfg3" : NULL;
2321 case 0xc001102c: return CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch) ? "AmdFam15hExecUnitCfg" : NULL;
2322 case 0xc001102d: return CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch) ? "AmdFam15hLoadStoreCfg2" : NULL;
2323 case 0xc0011030: return "AmdFam10hIbsFetchCtl";
2324 case 0xc0011031: return "AmdFam10hIbsFetchLinAddr";
2325 case 0xc0011032: return "AmdFam10hIbsFetchPhysAddr";
2326 case 0xc0011033: return "AmdFam10hIbsOpExecCtl";
2327 case 0xc0011034: return "AmdFam10hIbsOpRip";
2328 case 0xc0011035: return "AmdFam10hIbsOpData";
2329 case 0xc0011036: return "AmdFam10hIbsOpData2";
2330 case 0xc0011037: return "AmdFam10hIbsOpData3";
2331 case 0xc0011038: return "AmdFam10hIbsDcLinAddr";
2332 case 0xc0011039: return "AmdFam10hIbsDcPhysAddr";
2333 case 0xc001103a: return "AmdFam10hIbsCtl";
2334 case 0xc001103b: return "AmdFam14hIbsBrTarget";
2335 }
2336 return NULL;
2337}
2338
2339
2340/**
2341 * Names CPUMCPU variables that MSRs corresponds to.
2342 *
2343 * @returns The variable name @a uMsr corresponds to, NULL if no variable.
2344 * @param uMsr The MSR in question.
2345 */
2346static const char *getMsrCpumCpuVarName(uint32_t uMsr)
2347{
2348 switch (uMsr)
2349 {
2350 case 0x00000250: return "GuestMsrs.msr.MtrrFix64K_00000";
2351 case 0x00000258: return "GuestMsrs.msr.MtrrFix16K_80000";
2352 case 0x00000259: return "GuestMsrs.msr.MtrrFix16K_A0000";
2353 case 0x00000268: return "GuestMsrs.msr.MtrrFix4K_C0000";
2354 case 0x00000269: return "GuestMsrs.msr.MtrrFix4K_C8000";
2355 case 0x0000026a: return "GuestMsrs.msr.MtrrFix4K_D0000";
2356 case 0x0000026b: return "GuestMsrs.msr.MtrrFix4K_D8000";
2357 case 0x0000026c: return "GuestMsrs.msr.MtrrFix4K_E0000";
2358 case 0x0000026d: return "GuestMsrs.msr.MtrrFix4K_E8000";
2359 case 0x0000026e: return "GuestMsrs.msr.MtrrFix4K_F0000";
2360 case 0x0000026f: return "GuestMsrs.msr.MtrrFix4K_F8000";
2361 case 0x00000277: return "Guest.msrPAT";
2362 case 0x000002ff: return "GuestMsrs.msr.MtrrDefType";
2363 }
2364 return NULL;
2365}
2366
2367
2368/**
2369 * Checks whether the MSR should read as zero for some reason.
2370 *
2371 * @returns true if the register should read as zero, false if not.
2372 * @param uMsr The MSR.
2373 */
2374static bool doesMsrReadAsZero(uint32_t uMsr)
2375{
2376 switch (uMsr)
2377 {
2378 case 0x00000088: return true; // "BBL_CR_D0" - RAZ until understood/needed.
2379 case 0x00000089: return true; // "BBL_CR_D1" - RAZ until understood/needed.
2380 case 0x0000008a: return true; // "BBL_CR_D2" - RAZ until understood/needed.
2381
2382 /* Non-zero, but unknown register. */
2383 case 0x0000004a:
2384 case 0x0000004b:
2385 case 0x0000004c:
2386 case 0x0000004d:
2387 case 0x0000004e:
2388 case 0x0000004f:
2389 case 0x00000050:
2390 case 0x00000051:
2391 case 0x00000052:
2392 case 0x00000053:
2393 case 0x00000054:
2394 case 0x0000008c:
2395 case 0x0000008d:
2396 case 0x0000008e:
2397 case 0x0000008f:
2398 case 0x00000090:
2399 case 0xc0011011:
2400 return true;
2401 }
2402
2403 return false;
2404}
2405
2406
2407/**
2408 * Gets the skip mask for the given MSR.
2409 *
2410 * @returns Skip mask (0 means skipping nothing).
2411 * @param uMsr The MSR.
2412 */
2413static uint64_t getGenericSkipMask(uint32_t uMsr)
2414{
2415 switch (uMsr)
2416 {
2417 case 0x0000013c: return 3; /* AES-NI lock bit ++. */
2418
2419 case 0x000001f2: return UINT64_C(0xfffff00f); /* Ia32SmrrPhysBase - Only writable in SMM. */
2420 case 0x000001f3: return UINT64_C(0xfffff800); /* Ia32SmrrPhysMask - Only writable in SMM. */
2421
2422 /* these two have lock bits. */
2423 case 0x0000064b: return UINT64_C(0x80000003);
2424 case 0x0000064c: return UINT64_C(0x800000ff);
2425
2426 case 0xc0010015: return 1; /* SmmLock bit */
2427
2428 /* SmmLock effect: */
2429 case 0xc0010111: return UINT32_MAX;
2430 case 0xc0010112: return UINT64_C(0xfffe0000) | ((RT_BIT_64(vbCpuRepGetPhysAddrWidth()) - 1) & ~(uint64_t)UINT32_MAX);
2431 case 0xc0010113: return UINT64_C(0xfffe773f) | ((RT_BIT_64(vbCpuRepGetPhysAddrWidth()) - 1) & ~(uint64_t)UINT32_MAX);
2432 case 0xc0010116: return 0x1f;
2433
2434 case 0xc0010114: return RT_BIT_64(3) /* SVM lock */ | RT_BIT_64(4) /* SvmeDisable */;
2435
2436 /* Canonical */
2437 case 0xc0011034:
2438 case 0xc0011038:
2439 case 0xc001103b:
2440 return UINT64_C(0xffff800000000000);
2441
2442 case 0x00000060: case 0x00000061: case 0x00000062: case 0x00000063:
2443 case 0x00000064: case 0x00000065: case 0x00000066: case 0x00000067:
2444 case 0x00000040: case 0x00000041: case 0x00000042: case 0x00000043:
2445 case 0x00000044: case 0x00000045: case 0x00000046: case 0x00000047:
2446 case 0x00000600:
2447 if (g_enmMicroarch >= kCpumMicroarch_Intel_Core2_First)
2448 return UINT64_C(0xffff800000000000);
2449 break;
2450
2451
2452 /* Write only bits. */
2453 case 0xc0010041: return RT_BIT_64(16); /* FIDVID_CTL.InitFidVid */
2454
2455 /* Time counters - fudge them to avoid incorrect ignore masks. */
2456 case 0x00000010:
2457 case 0x000000e7:
2458 case 0x000000e8:
2459 return RT_BIT_32(29) - 1;
2460 }
2461 return 0;
2462}
2463
2464
2465
2466
2467/** queryMsrWriteBadness return values. */
2468typedef enum
2469{
2470 /** . */
2471 VBCPUREPBADNESS_MOSTLY_HARMLESS = 0,
2472 /** Not a problem if accessed with care. */
2473 VBCPUREPBADNESS_MIGHT_BITE,
2474 /** Worse than a bad james bond villain. */
2475 VBCPUREPBADNESS_BOND_VILLAIN
2476} VBCPUREPBADNESS;
2477
2478
2479/**
2480 * Backlisting and graylisting of MSRs which may cause tripple faults.
2481 *
2482 * @returns Badness factor.
2483 * @param uMsr The MSR in question.
2484 */
2485static VBCPUREPBADNESS queryMsrWriteBadness(uint32_t uMsr)
2486{
2487 /** @todo Having trouble in the 0xc0010247,0xc0011006,?? region on Bulldozer. */
2488 /** @todo Having trouble in the 0xc001100f,0xc001100d,?? region on Opteron
2489 * 2384. */
2490
2491 switch (uMsr)
2492 {
2493 case 0x00000050:
2494 case 0x00000051:
2495 case 0x00000052:
2496 case 0x00000053:
2497 case 0x00000054:
2498
2499 case 0x00001006:
2500 case 0x00001007:
2501 return VBCPUREPBADNESS_BOND_VILLAIN;
2502
2503 case 0x0000120e:
2504 case 0x00001233:
2505 case 0x00001239:
2506 case 0x00001249:
2507 case 0x0000124a:
2508 case 0x00001404:
2509 case 0x00001405:
2510 case 0x00001413:
2511 case 0x0000142c: /* Caused rip to be set to 297 or some such weirdness... */
2512 case 0x0000142e:
2513 case 0x00001435:
2514 case 0x00001436:
2515 case 0x00001438:
2516 case 0x0000317f:
2517 if (g_enmVendor == CPUMCPUVENDOR_VIA || g_enmVendor == CPUMCPUVENDOR_SHANGHAI)
2518 return VBCPUREPBADNESS_BOND_VILLAIN;
2519 break;
2520
2521 case 0xc0010010:
2522 case 0xc0010016:
2523 case 0xc0010017:
2524 case 0xc0010018:
2525 case 0xc0010019:
2526 case 0xc001001a:
2527 case 0xc001001d:
2528 case 0xc0010064: /* P-state fequency, voltage, ++. */
2529 case 0xc0010065: /* P-state fequency, voltage, ++. */
2530 case 0xc0010066: /* P-state fequency, voltage, ++. */
2531 case 0xc0010067: /* P-state fequency, voltage, ++. */
2532 case 0xc0010068: /* P-state fequency, voltage, ++. */
2533 case 0xc0010069: /* P-state fequency, voltage, ++. */
2534 case 0xc001006a: /* P-state fequency, voltage, ++. */
2535 case 0xc001006b: /* P-state fequency, voltage, ++. */
2536 case 0xc0010070: /* COFVID Control. */
2537 case 0xc001101e:
2538 case 0xc0011021: /* IC_CFG (instruction cache configuration) */
2539 case 0xc0011023: /* CU_CFG (combined unit configuration) */
2540 case 0xc001102c: /* EX_CFG (execution unit configuration) */
2541 return VBCPUREPBADNESS_BOND_VILLAIN;
2542
2543 case 0xc0011012:
2544 if (CPUMMICROARCH_IS_AMD_FAM_0FH(g_enmMicroarch))
2545 return VBCPUREPBADNESS_MIGHT_BITE;
2546 break;
2547
2548 /* KVM MSRs that are unsafe to touch. */
2549 case 0x00000011: /* KVM */
2550 case 0x00000012: /* KVM */
2551 return VBCPUREPBADNESS_BOND_VILLAIN;
2552
2553 /*
2554 * The TSC is tricky -- writing it isn't a problem, but if we put back the original
2555 * value, we'll throw it out of whack. If we're on an SMP OS that uses the TSC for timing,
2556 * we'll likely kill it, especially if we can't do the modification very quickly.
2557 */
2558 case 0x00000010: /* IA32_TIME_STAMP_COUNTER */
2559 if (!g_MsrAcc.fAtomic)
2560 return VBCPUREPBADNESS_BOND_VILLAIN;
2561 break;
2562
2563 /*
2564 * The following MSRs are not safe to modify in a typical OS if we can't do it atomically,
2565 * i.e. read/modify/restore without allowing any other code to execute. Everything related
2566 * to syscalls will blow up in our face if we go back to userland with modified MSRs.
2567 */
2568// case 0x0000001b: /* IA32_APIC_BASE */
2569 case 0xc0000081: /* MSR_K6_STAR */
2570 case 0xc0000082: /* AMD64_STAR64 */
2571 case 0xc0000083: /* AMD64_STARCOMPAT */
2572 case 0xc0000084: /* AMD64_SYSCALL_FLAG_MASK */
2573 case 0xc0000100: /* AMD64_FS_BASE */
2574 case 0xc0000101: /* AMD64_GS_BASE */
2575 case 0xc0000102: /* AMD64_KERNEL_GS_BASE */
2576 if (!g_MsrAcc.fAtomic)
2577 return VBCPUREPBADNESS_MIGHT_BITE;
2578 break;
2579
2580 case 0x000001a0: /* IA32_MISC_ENABLE */
2581 case 0x00000199: /* IA32_PERF_CTL */
2582 return VBCPUREPBADNESS_MIGHT_BITE;
2583
2584 case 0x000005a0: /* C2_PECI_CTL */
2585 case 0x000005a1: /* C2_UNK_0000_05a1 */
2586 if (g_enmVendor == CPUMCPUVENDOR_INTEL)
2587 return VBCPUREPBADNESS_MIGHT_BITE;
2588 break;
2589
2590 case 0x00002000: /* P6_CR0. */
2591 case 0x00002003: /* P6_CR3. */
2592 case 0x00002004: /* P6_CR4. */
2593 if (g_enmVendor == CPUMCPUVENDOR_INTEL)
2594 return VBCPUREPBADNESS_MIGHT_BITE;
2595 break;
2596 case 0xc0000080: /* MSR_K6_EFER */
2597 return VBCPUREPBADNESS_MIGHT_BITE;
2598 }
2599 return VBCPUREPBADNESS_MOSTLY_HARMLESS;
2600}
2601
2602
2603/**
2604 * Checks if this might be a VIA/Shanghai dummy register.
2605 *
2606 * @returns true if it's a dummy, false if it isn't.
2607 * @param uMsr The MSR.
2608 * @param uValue The value.
2609 * @param fFlags The flags.
2610 */
2611static bool isMsrViaShanghaiDummy(uint32_t uMsr, uint64_t uValue, uint32_t fFlags)
2612{
2613 if (g_enmVendor != CPUMCPUVENDOR_VIA && g_enmVendor != CPUMCPUVENDOR_SHANGHAI)
2614 return false;
2615
2616 if (uValue)
2617 return false;
2618
2619 if (fFlags)
2620 return false;
2621
2622 switch (uMsr)
2623 {
2624 case 0x00000010:
2625 case 0x0000001b:
2626 case 0x000000c1:
2627 case 0x000000c2:
2628 case 0x0000011e:
2629 case 0x00000186:
2630 case 0x00000187:
2631 //case 0x00000200 ... (mtrrs will be detected)
2632 return false;
2633
2634 case 0xc0000080:
2635 case 0xc0000081:
2636 case 0xc0000082:
2637 case 0xc0000083:
2638 if (vbCpuRepSupportsLongMode())
2639 return false;
2640 break;
2641 }
2642
2643 if (uMsr >= 0x00001200 && uMsr <= 0x00003fff && queryMsrWriteBadness(uMsr) != VBCPUREPBADNESS_MOSTLY_HARMLESS)
2644 return false;
2645
2646 if ( !msrProberModifyNoChange(uMsr)
2647 && !msrProberModifyZero(uMsr))
2648 return false;
2649
2650 uint64_t fIgnMask = 0;
2651 uint64_t fGpMask = 0;
2652 int rc = msrProberModifyBitChanges(uMsr, &fIgnMask, &fGpMask, 0);
2653 if (RT_FAILURE(rc))
2654 return false;
2655
2656 if (fIgnMask != UINT64_MAX)
2657 return false;
2658 if (fGpMask != 0)
2659 return false;
2660
2661 return true;
2662}
2663
2664
2665/**
2666 * Adjusts the ignore and GP masks for MSRs which contains canonical addresses.
2667 *
2668 * @param uMsr The MSR.
2669 * @param pfIgn Pointer to the ignore mask.
2670 * @param pfGp Pointer to the GP mask.
2671 */
2672static void adjustCanonicalIgnAndGpMasks(uint32_t uMsr, uint64_t *pfIgn, uint64_t *pfGp)
2673{
2674 RT_NOREF1(pfIgn);
2675 if (!vbCpuRepSupportsLongMode())
2676 return;
2677 switch (uMsr)
2678 {
2679 case 0x00000175:
2680 case 0x00000176:
2681 case 0x000001da:
2682 case 0x000001db:
2683 case 0x000001dc:
2684 case 0x000001de:
2685 case 0x00000600:
2686 if (*pfGp == UINT64_C(0xffff800000000000))
2687 *pfGp = 0;
2688 break;
2689 case 0x000001dd:
2690 if (*pfGp == UINT64_C(0x7fff800000000000) || *pfGp == UINT64_C(0xffff800000000000)) /* why is the top bit writable? */
2691 *pfGp = 0;
2692 break;
2693
2694 case 0xc0000082:
2695 case 0xc0000083:
2696 case 0xc0000100:
2697 case 0xc0000101:
2698 case 0xc0000102:
2699 *pfGp = 0;
2700 break;
2701 }
2702}
2703
2704
2705
2706/**
2707 * Prints a 64-bit value in the best way.
2708 *
2709 * @param uValue The value.
2710 */
2711static void printMsrValueU64(uint64_t uValue)
2712{
2713 if (uValue == 0)
2714 vbCpuRepPrintf(", 0");
2715 else if (uValue == UINT16_MAX)
2716 vbCpuRepPrintf(", UINT16_MAX");
2717 else if (uValue == UINT32_MAX)
2718 vbCpuRepPrintf(", UINT32_MAX");
2719 else if (uValue == UINT64_MAX)
2720 vbCpuRepPrintf(", UINT64_MAX");
2721 else if (uValue == UINT64_C(0xffffffff00000000))
2722 vbCpuRepPrintf(", ~(uint64_t)UINT32_MAX");
2723 else if (uValue <= (UINT32_MAX >> 1))
2724 vbCpuRepPrintf(", %#llx", uValue);
2725 else if (uValue <= UINT32_MAX)
2726 vbCpuRepPrintf(", UINT32_C(%#llx)", uValue);
2727 else
2728 vbCpuRepPrintf(", UINT64_C(%#llx)", uValue);
2729}
2730
2731
2732/**
2733 * Prints the newline after an MSR line has been printed.
2734 *
2735 * This is used as a hook to slow down the output and make sure the remote
2736 * terminal or/and output file has received the last update before we go and
2737 * crash probing the next MSR.
2738 */
2739static void printMsrNewLine(void)
2740{
2741 vbCpuRepPrintf("\n");
2742#if 1
2743 RTThreadSleep(8);
2744#endif
2745}
2746
2747static int printMsrWriteOnly(uint32_t uMsr, const char *pszWrFnName, const char *pszAnnotation)
2748{
2749 if (!pszWrFnName)
2750 pszWrFnName = "IgnoreWrite";
2751 vbCpuRepPrintf(pszAnnotation
2752 ? " MFN(%#010x, \"%s\", WriteOnly, %s), /* %s */"
2753 : " MFN(%#010x, \"%s\", WriteOnly, %s),",
2754 uMsr, getMsrName(uMsr), pszWrFnName, pszAnnotation);
2755 printMsrNewLine();
2756 return VINF_SUCCESS;
2757}
2758
2759
2760static int printMsrValueReadOnly(uint32_t uMsr, uint64_t uValue, const char *pszAnnotation)
2761{
2762 vbCpuRepPrintf(" MVO(%#010x, \"%s\"", uMsr, getMsrName(uMsr));
2763 printMsrValueU64(uValue);
2764 vbCpuRepPrintf("),");
2765 if (pszAnnotation)
2766 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2767 printMsrNewLine();
2768 return VINF_SUCCESS;
2769}
2770
2771
2772
2773static int printMsrValueIgnoreWritesNamed(uint32_t uMsr, uint64_t uValue, const char *pszName, const char *pszAnnotation)
2774{
2775 vbCpuRepPrintf(" MVI(%#010x, \"%s\"", uMsr, pszName);
2776 printMsrValueU64(uValue);
2777 vbCpuRepPrintf("),");
2778 if (pszAnnotation)
2779 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2780 printMsrNewLine();
2781 return VINF_SUCCESS;
2782}
2783
2784
2785static int printMsrValueIgnoreWrites(uint32_t uMsr, uint64_t uValue, const char *pszAnnotation)
2786{
2787 return printMsrValueIgnoreWritesNamed(uMsr, uValue, getMsrName(uMsr), pszAnnotation);
2788}
2789
2790
2791static int printMsrValueExtended(uint32_t uMsr, uint64_t uValue, uint64_t fIgnMask, uint64_t fGpMask,
2792 const char *pszAnnotation)
2793{
2794 vbCpuRepPrintf(" MVX(%#010x, \"%s\"", uMsr, getMsrName(uMsr));
2795 printMsrValueU64(uValue);
2796 printMsrValueU64(fIgnMask);
2797 printMsrValueU64(fGpMask);
2798 vbCpuRepPrintf("),");
2799 if (pszAnnotation)
2800 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2801 printMsrNewLine();
2802 return VINF_SUCCESS;
2803}
2804
2805
2806static int printMsrRangeValueReadOnly(uint32_t uMsr, uint32_t uLast, uint64_t uValue, const char *pszAnnotation)
2807{
2808 vbCpuRepPrintf(" RVO(%#010x, %#010x, \"%s\"", uMsr, uLast, getMsrRangeName(uMsr));
2809 printMsrValueU64(uValue);
2810 vbCpuRepPrintf("),");
2811 if (pszAnnotation)
2812 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2813 printMsrNewLine();
2814 return VINF_SUCCESS;
2815}
2816
2817
2818static int printMsrRangeValueIgnoreWritesNamed(uint32_t uMsr, uint32_t uLast, uint64_t uValue, const char *pszName, const char *pszAnnotation)
2819{
2820 vbCpuRepPrintf(" RVI(%#010x, %#010x, \"%s\"", uMsr, uLast, pszName);
2821 printMsrValueU64(uValue);
2822 vbCpuRepPrintf("),");
2823 if (pszAnnotation)
2824 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2825 printMsrNewLine();
2826 return VINF_SUCCESS;
2827}
2828
2829
2830static int printMsrRangeValueIgnoreWrites(uint32_t uMsr, uint32_t uLast, uint64_t uValue, const char *pszAnnotation)
2831{
2832 return printMsrRangeValueIgnoreWritesNamed(uMsr, uLast, uValue, getMsrRangeName(uMsr), pszAnnotation);
2833}
2834
2835
2836static int printMsrFunction(uint32_t uMsr, const char *pszRdFnName, const char *pszWrFnName, const char *pszAnnotation)
2837{
2838 if (!pszRdFnName)
2839 pszRdFnName = getMsrFnName(uMsr, NULL);
2840 if (!pszWrFnName)
2841 pszWrFnName = pszRdFnName;
2842 vbCpuRepPrintf(" MFN(%#010x, \"%s\", %s, %s),", uMsr, getMsrName(uMsr), pszRdFnName, pszWrFnName);
2843 if (pszAnnotation)
2844 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2845 printMsrNewLine();
2846 return VINF_SUCCESS;
2847}
2848
2849
2850static int printMsrFunctionReadOnly(uint32_t uMsr, const char *pszRdFnName, const char *pszAnnotation)
2851{
2852 if (!pszRdFnName)
2853 pszRdFnName = getMsrFnName(uMsr, NULL);
2854 vbCpuRepPrintf(" MFO(%#010x, \"%s\", %s),", uMsr, getMsrName(uMsr), pszRdFnName);
2855 if (pszAnnotation)
2856 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2857 printMsrNewLine();
2858 return VINF_SUCCESS;
2859}
2860
2861
2862static int printMsrFunctionIgnoreWrites(uint32_t uMsr, const char *pszRdFnName, const char *pszAnnotation)
2863{
2864 if (!pszRdFnName)
2865 pszRdFnName = getMsrFnName(uMsr, NULL);
2866 vbCpuRepPrintf(" MFI(%#010x, \"%s\", %s),", uMsr, getMsrName(uMsr), pszRdFnName);
2867 if (pszAnnotation)
2868 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2869 printMsrNewLine();
2870 return VINF_SUCCESS;
2871}
2872
2873
2874static int printMsrFunctionIgnoreMask(uint32_t uMsr, const char *pszRdFnName, const char *pszWrFnName,
2875 uint64_t fIgnMask, const char *pszAnnotation)
2876{
2877 if (!pszRdFnName)
2878 pszRdFnName = getMsrFnName(uMsr, NULL);
2879 if (!pszWrFnName)
2880 pszWrFnName = pszRdFnName;
2881 vbCpuRepPrintf(" MFW(%#010x, \"%s\", %s, %s", uMsr, getMsrName(uMsr), pszRdFnName, pszWrFnName);
2882 printMsrValueU64(fIgnMask);
2883 vbCpuRepPrintf("),");
2884 if (pszAnnotation)
2885 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2886 printMsrNewLine();
2887 return VINF_SUCCESS;
2888}
2889
2890
2891static int printMsrFunctionExtended(uint32_t uMsr, const char *pszRdFnName, const char *pszWrFnName, uint64_t uValue,
2892 uint64_t fIgnMask, uint64_t fGpMask, const char *pszAnnotation)
2893{
2894 if (!pszRdFnName)
2895 pszRdFnName = getMsrFnName(uMsr, NULL);
2896 if (!pszWrFnName)
2897 pszWrFnName = pszRdFnName;
2898 vbCpuRepPrintf(" MFX(%#010x, \"%s\", %s, %s", uMsr, getMsrName(uMsr), pszRdFnName, pszWrFnName);
2899 printMsrValueU64(uValue);
2900 printMsrValueU64(fIgnMask);
2901 printMsrValueU64(fGpMask);
2902 vbCpuRepPrintf("),");
2903 if (pszAnnotation)
2904 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2905 printMsrNewLine();
2906 return VINF_SUCCESS;
2907}
2908
2909
2910static int printMsrFunctionExtendedIdxVal(uint32_t uMsr, const char *pszRdFnName, const char *pszWrFnName, uint64_t uValue,
2911 uint64_t fIgnMask, uint64_t fGpMask, const char *pszAnnotation)
2912{
2913 if (!pszRdFnName)
2914 pszRdFnName = getMsrFnName(uMsr, NULL);
2915 if (!pszWrFnName)
2916 pszWrFnName = pszRdFnName;
2917 vbCpuRepPrintf(" MFX(%#010x, \"%s\", %s, %s, %#x", uMsr, getMsrName(uMsr), pszRdFnName, pszWrFnName, uValue);
2918 printMsrValueU64(fIgnMask);
2919 printMsrValueU64(fGpMask);
2920 vbCpuRepPrintf("),");
2921 if (pszAnnotation)
2922 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2923 printMsrNewLine();
2924 return VINF_SUCCESS;
2925}
2926
2927
2928static int printMsrFunctionCpumCpu(uint32_t uMsr, const char *pszRdFnName, const char *pszWrFnName,
2929 const char *pszCpumCpuStorage, const char *pszAnnotation)
2930{
2931 if (!pszRdFnName)
2932 pszRdFnName = getMsrFnName(uMsr, NULL);
2933 if (!pszWrFnName)
2934 pszWrFnName = pszRdFnName;
2935 if (!pszCpumCpuStorage)
2936 pszCpumCpuStorage = getMsrCpumCpuVarName(uMsr);
2937 if (!pszCpumCpuStorage)
2938 return RTMsgErrorRc(VERR_NOT_FOUND, "Missing CPUMCPU member for %#s (%#x)\n", getMsrName(uMsr), uMsr);
2939 vbCpuRepPrintf(" MFS(%#010x, \"%s\", %s, %s, %s),", uMsr, getMsrName(uMsr), pszRdFnName, pszWrFnName, pszCpumCpuStorage);
2940 if (pszAnnotation)
2941 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2942 printMsrNewLine();
2943 return VINF_SUCCESS;
2944}
2945
2946
2947static int printMsrFunctionCpumCpuEx(uint32_t uMsr, const char *pszRdFnName, const char *pszWrFnName,
2948 const char *pszCpumCpuStorage, uint64_t fIgnMask, uint64_t fGpMask,
2949 const char *pszAnnotation)
2950{
2951 if (!pszRdFnName)
2952 pszRdFnName = getMsrFnName(uMsr, NULL);
2953 if (!pszWrFnName)
2954 pszWrFnName = pszRdFnName;
2955 if (!pszCpumCpuStorage)
2956 pszCpumCpuStorage = getMsrCpumCpuVarName(uMsr);
2957 if (!pszCpumCpuStorage)
2958 return RTMsgErrorRc(VERR_NOT_FOUND, "Missing CPUMCPU member for %#s (%#x)\n", getMsrName(uMsr), uMsr);
2959 vbCpuRepPrintf(" MFZ(%#010x, \"%s\", %s, %s, %s", uMsr, getMsrName(uMsr), pszRdFnName, pszWrFnName, pszCpumCpuStorage);
2960 printMsrValueU64(fIgnMask);
2961 printMsrValueU64(fGpMask);
2962 vbCpuRepPrintf("),");
2963 if (pszAnnotation)
2964 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2965 printMsrNewLine();
2966 return VINF_SUCCESS;
2967}
2968
2969
2970static int printMsrRangeFunction(uint32_t uMsr, uint32_t uLast, const char *pszRdFnName, const char *pszWrFnName,
2971 const char *pszAnnotation)
2972{
2973 if (!pszRdFnName)
2974 pszRdFnName = getMsrFnName(uMsr, NULL);
2975 if (!pszWrFnName)
2976 pszWrFnName = pszRdFnName;
2977 vbCpuRepPrintf(" RFN(%#010x, %#010x, \"%s\", %s, %s),", uMsr, uLast, getMsrRangeName(uMsr), pszRdFnName, pszWrFnName);
2978 if (pszAnnotation)
2979 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2980 printMsrNewLine();
2981 return VINF_SUCCESS;
2982}
2983
2984
2985static int printMsrRangeFunctionEx(uint32_t uMsr, uint32_t uLast, const char *pszRdFnName, const char *pszWrFnName,
2986 uint64_t uValue, uint64_t fIgnMask, uint64_t fGpMask, const char *pszAnnotation)
2987{
2988 if (!pszRdFnName)
2989 pszRdFnName = getMsrFnName(uMsr, NULL);
2990 if (!pszWrFnName)
2991 pszWrFnName = pszRdFnName;
2992 vbCpuRepPrintf(" RSN(%#010x, %#010x, \"%s\", %s, %s", uMsr, uLast, getMsrRangeName(uMsr), pszRdFnName, pszWrFnName);
2993 printMsrValueU64(uValue);
2994 printMsrValueU64(fIgnMask);
2995 printMsrValueU64(fGpMask);
2996 vbCpuRepPrintf("),");
2997 if (pszAnnotation)
2998 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2999 printMsrNewLine();
3000 return VINF_SUCCESS;
3001}
3002
3003
3004static int printMsrRangeFunctionExIdxVal(uint32_t uMsr, uint32_t uLast, const char *pszRdFnName, const char *pszWrFnName,
3005 uint64_t uValue, uint64_t fIgnMask, uint64_t fGpMask, const char *pszAnnotation)
3006{
3007 if (!pszRdFnName)
3008 pszRdFnName = getMsrFnName(uMsr, NULL);
3009 if (!pszWrFnName)
3010 pszWrFnName = pszRdFnName;
3011 vbCpuRepPrintf(" RSN(%#010x, %#010x, \"%s\", %s, %s, %#x",
3012 uMsr, uLast, getMsrRangeName(uMsr), pszRdFnName, pszWrFnName, uValue);
3013 printMsrValueU64(fIgnMask);
3014 printMsrValueU64(fGpMask);
3015 vbCpuRepPrintf("),");
3016 if (pszAnnotation)
3017 vbCpuRepPrintf(" /* %s */", pszAnnotation);
3018 printMsrNewLine();
3019 return VINF_SUCCESS;
3020}
3021
3022
3023static int printMsrAlias(uint32_t uMsr, uint32_t uTarget, const char *pszAnnotation)
3024{
3025 vbCpuRepPrintf(" MAL(%#010x, \"%s\", %#010x),", uMsr, getMsrName(uMsr), uTarget);
3026 if (pszAnnotation)
3027 vbCpuRepPrintf(" /* %s */", pszAnnotation);
3028 printMsrNewLine();
3029 return VINF_SUCCESS;
3030}
3031
3032
3033
3034static const char *annotateValue(uint64_t uValue)
3035{
3036 static char s_szBuf[40];
3037 if (uValue <= UINT32_MAX)
3038 RTStrPrintf(s_szBuf, sizeof(s_szBuf), "value=%#llx", uValue);
3039 else
3040 RTStrPrintf(s_szBuf, sizeof(s_szBuf), "value=%#x`%08x", RT_HI_U32(uValue), RT_LO_U32(uValue));
3041 return s_szBuf;
3042}
3043
3044
3045static const char *annotateValueExtra(const char *pszExtra, uint64_t uValue)
3046{
3047 static char s_szBuf[40];
3048 if (uValue <= UINT32_MAX)
3049 RTStrPrintf(s_szBuf, sizeof(s_szBuf), "%s value=%#llx", pszExtra, uValue);
3050 else
3051 RTStrPrintf(s_szBuf, sizeof(s_szBuf), "%s value=%#x`%08x", pszExtra, RT_HI_U32(uValue), RT_LO_U32(uValue));
3052 return s_szBuf;
3053}
3054
3055
3056static const char *annotateIfMissingBits(uint64_t uValue, uint64_t fBits)
3057{
3058 static char s_szBuf[80];
3059 if ((uValue & fBits) == fBits)
3060 return annotateValue(uValue);
3061 RTStrPrintf(s_szBuf, sizeof(s_szBuf), "XXX: Unexpected value %#llx - wanted bits %#llx to be set.", uValue, fBits);
3062 return s_szBuf;
3063}
3064
3065
3066static int reportMsr_Generic(uint32_t uMsr, uint32_t fFlags, uint64_t uValue)
3067{
3068 int rc;
3069 bool fTakesValue = false;
3070 const char *pszFnName = getMsrFnName(uMsr, &fTakesValue);
3071
3072 if (fFlags & VBCPUREPMSR_F_WRITE_ONLY)
3073 rc = printMsrWriteOnly(uMsr, pszFnName, NULL);
3074 else
3075 {
3076 bool fReadAsZero = doesMsrReadAsZero(uMsr);
3077 fTakesValue = fTakesValue && !fReadAsZero;
3078
3079
3080 switch (queryMsrWriteBadness(uMsr))
3081 {
3082 /* This is what we're here for... */
3083 case VBCPUREPBADNESS_MOSTLY_HARMLESS:
3084 {
3085 if ( msrProberModifyNoChange(uMsr)
3086 || msrProberModifyZero(uMsr))
3087 {
3088 uint64_t fSkipMask = getGenericSkipMask(uMsr);
3089 uint64_t fIgnMask = 0;
3090 uint64_t fGpMask = 0;
3091 rc = msrProberModifyBitChanges(uMsr, &fIgnMask, &fGpMask, fSkipMask);
3092 if (RT_FAILURE(rc))
3093 return rc;
3094 adjustCanonicalIgnAndGpMasks(uMsr, &fIgnMask, &fGpMask);
3095
3096 if (pszFnName)
3097 {
3098 if (fGpMask == 0 && fIgnMask == UINT64_MAX && !fTakesValue)
3099 rc = printMsrFunctionIgnoreWrites(uMsr, pszFnName, annotateValue(uValue));
3100 else if (fGpMask == 0 && fIgnMask == 0 && (!fTakesValue || uValue == 0))
3101 rc = printMsrFunction(uMsr, pszFnName, pszFnName, annotateValue(uValue));
3102 else
3103 rc = printMsrFunctionExtended(uMsr, pszFnName, pszFnName, fTakesValue ? uValue : 0,
3104 fIgnMask, fGpMask, annotateValue(uValue));
3105 }
3106 else if (fGpMask == 0 && fIgnMask == UINT64_MAX)
3107 rc = printMsrValueIgnoreWrites(uMsr, fReadAsZero ? 0 : uValue, fReadAsZero ? annotateValue(uValue) : NULL);
3108 else
3109 rc = printMsrValueExtended(uMsr, fReadAsZero ? 0 : uValue, fIgnMask, fGpMask,
3110 fReadAsZero ? annotateValue(uValue) : NULL);
3111 }
3112 /* Most likely read-only. */
3113 else if (pszFnName && !fTakesValue)
3114 rc = printMsrFunctionReadOnly(uMsr, pszFnName, annotateValue(uValue));
3115 else if (pszFnName)
3116 rc = printMsrFunctionExtended(uMsr, pszFnName, "ReadOnly", uValue, 0, 0, annotateValue(uValue));
3117 else if (fReadAsZero)
3118 rc = printMsrValueReadOnly(uMsr, 0, annotateValue(uValue));
3119 else
3120 rc = printMsrValueReadOnly(uMsr, uValue, NULL);
3121 break;
3122 }
3123
3124 /* These should have special handling, so just do a simple
3125 write back same value check to see if it's writable. */
3126 case VBCPUREPBADNESS_MIGHT_BITE:
3127 if (msrProberModifyNoChange(uMsr))
3128 {
3129 if (pszFnName && !fTakesValue)
3130 rc = printMsrFunction(uMsr, pszFnName, pszFnName, annotateValueExtra("Might bite.", uValue));
3131 else if (pszFnName)
3132 rc = printMsrFunctionExtended(uMsr, pszFnName, pszFnName, uValue, 0, 0,
3133 annotateValueExtra("Might bite.", uValue));
3134 else if (fReadAsZero)
3135 rc = printMsrValueIgnoreWrites(uMsr, 0, annotateValueExtra("Might bite.", uValue));
3136 else
3137 rc = printMsrValueIgnoreWrites(uMsr, uValue, "Might bite.");
3138 }
3139 else if (pszFnName && !fTakesValue)
3140 rc = printMsrFunctionReadOnly(uMsr, pszFnName, annotateValueExtra("Might bite.", uValue));
3141 else if (pszFnName)
3142 rc = printMsrFunctionExtended(uMsr, pszFnName, "ReadOnly", uValue, 0, UINT64_MAX,
3143 annotateValueExtra("Might bite.", uValue));
3144 else if (fReadAsZero)
3145 rc = printMsrValueReadOnly(uMsr, 0, annotateValueExtra("Might bite.", uValue));
3146 else
3147 rc = printMsrValueReadOnly(uMsr, uValue, "Might bite.");
3148 break;
3149
3150
3151 /* Don't try anything with these guys. */
3152 case VBCPUREPBADNESS_BOND_VILLAIN:
3153 default:
3154 if (pszFnName && !fTakesValue)
3155 rc = printMsrFunction(uMsr, pszFnName, pszFnName, annotateValueExtra("Villain?", uValue));
3156 else if (pszFnName)
3157 rc = printMsrFunctionExtended(uMsr, pszFnName, pszFnName, uValue, 0, 0,
3158 annotateValueExtra("Villain?", uValue));
3159 else if (fReadAsZero)
3160 rc = printMsrValueIgnoreWrites(uMsr, 0, annotateValueExtra("Villain?", uValue));
3161 else
3162 rc = printMsrValueIgnoreWrites(uMsr, uValue, "Villain?");
3163 break;
3164 }
3165 }
3166
3167 return rc;
3168}
3169
3170
3171static int reportMsr_GenRangeFunctionEx(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t cMax, const char *pszRdWrFnName,
3172 uint32_t uMsrBase, bool fEarlyEndOk, bool fNoIgnMask, uint64_t fSkipMask, uint32_t *pidxLoop)
3173{
3174 uint32_t uMsr = paMsrs[0].uMsr;
3175 uint32_t iRange = uMsr - uMsrBase;
3176 Assert(cMax > iRange);
3177 cMax -= iRange;
3178
3179 /* Resolve default function name. */
3180 if (!pszRdWrFnName)
3181 {
3182 pszRdWrFnName = getMsrFnName(uMsr, NULL);
3183 if (!pszRdWrFnName)
3184 return RTMsgErrorRc(VERR_INVALID_PARAMETER, "uMsr=%#x no function name\n", uMsr);
3185 }
3186
3187 /* Figure the possible register count. */
3188 if (cMax > cMsrs)
3189 cMax = cMsrs;
3190 uint32_t cRegs = 1;
3191 while ( cRegs < cMax
3192 && paMsrs[cRegs].uMsr == uMsr + cRegs)
3193 cRegs++;
3194
3195 /* Probe the first register and check that the others exhibit
3196 the same characteristics. */
3197 bool fReadOnly0;
3198 uint64_t fIgnMask0, fGpMask0;
3199 int rc = msrProberModifyBasicTests(uMsr, fSkipMask, &fReadOnly0, &fIgnMask0, &fGpMask0);
3200 if (RT_FAILURE(rc))
3201 return rc;
3202
3203 const char *pszAnnotation = NULL;
3204 for (uint32_t i = 1; i < cRegs; i++)
3205 {
3206 bool fReadOnlyN;
3207 uint64_t fIgnMaskN, fGpMaskN;
3208 rc = msrProberModifyBasicTests(paMsrs[i].uMsr, fSkipMask, &fReadOnlyN, &fIgnMaskN, &fGpMaskN);
3209 if (RT_FAILURE(rc))
3210 return rc;
3211 if ( fReadOnlyN != fReadOnly0
3212 || (fIgnMaskN != fIgnMask0 && !fNoIgnMask)
3213 || fGpMaskN != fGpMask0)
3214 {
3215 if (!fEarlyEndOk && !isMsrViaShanghaiDummy(uMsr, paMsrs[i].uValue, paMsrs[i].fFlags))
3216 {
3217 vbCpuRepDebug("MSR %s (%#x) range ended unexpectedly early on %#x: ro=%d ign=%#llx/%#llx gp=%#llx/%#llx [N/0]\n",
3218 getMsrNameHandled(uMsr), uMsr, paMsrs[i].uMsr,
3219 fReadOnlyN, fReadOnly0, fIgnMaskN, fIgnMask0, fGpMaskN, fGpMask0);
3220 pszAnnotation = "XXX: The range ended earlier than expected!";
3221 }
3222 cRegs = i;
3223 break;
3224 }
3225 }
3226
3227 /*
3228 * Report the range (or single MSR as it might be).
3229 */
3230 *pidxLoop += cRegs - 1;
3231
3232 if (fNoIgnMask)
3233 fIgnMask0 = 0;
3234 bool fSimple = fIgnMask0 == 0
3235 && (fGpMask0 == 0 || (fGpMask0 == UINT64_MAX && fReadOnly0))
3236 && iRange == 0;
3237 if (cRegs == 1)
3238 return printMsrFunctionExtendedIdxVal(uMsr, pszRdWrFnName, fReadOnly0 ? "ReadOnly" : pszRdWrFnName,
3239 iRange, fIgnMask0, fGpMask0,
3240 pszAnnotation ? pszAnnotation : annotateValue(paMsrs[0].uValue));
3241 if (fSimple)
3242 return printMsrRangeFunction(uMsr, uMsr + cRegs - 1,
3243 pszRdWrFnName, fReadOnly0 ? "ReadOnly" : pszRdWrFnName, pszAnnotation);
3244
3245 return printMsrRangeFunctionExIdxVal(uMsr, uMsr + cRegs - 1, pszRdWrFnName, fReadOnly0 ? "ReadOnly" : pszRdWrFnName,
3246 iRange /*uValue*/, fIgnMask0, fGpMask0, pszAnnotation);
3247}
3248
3249
3250static int reportMsr_GenRangeFunction(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t cMax, const char *pszRdWrFnName,
3251 uint32_t *pidxLoop)
3252{
3253 return reportMsr_GenRangeFunctionEx(paMsrs, cMsrs, cMax, pszRdWrFnName, paMsrs[0].uMsr, false /*fEarlyEndOk*/, false /*fNoIgnMask*/,
3254 getGenericSkipMask(paMsrs[0].uMsr), pidxLoop);
3255}
3256
3257
3258/**
3259 * Generic report for an MSR implemented by functions, extended version.
3260 *
3261 * @returns VBox status code.
3262 * @param uMsr The MSR.
3263 * @param pszRdWrFnName The read/write function name, optional.
3264 * @param uValue The MSR range value.
3265 * @param fSkipMask Mask of bits to skip.
3266 * @param fNoGpMask Mask of bits to remove from the GP mask after
3267 * probing
3268 * @param pszAnnotate Annotation.
3269 */
3270static int reportMsr_GenFunctionEx(uint32_t uMsr, const char *pszRdWrFnName, uint32_t uValue,
3271 uint64_t fSkipMask, uint64_t fNoGpMask, const char *pszAnnotate)
3272{
3273 /* Resolve default function name. */
3274 if (!pszRdWrFnName)
3275 {
3276 pszRdWrFnName = getMsrFnName(uMsr, NULL);
3277 if (!pszRdWrFnName)
3278 return RTMsgErrorRc(VERR_INVALID_PARAMETER, "uMsr=%#x no function name\n", uMsr);
3279 }
3280
3281 /* Probe the register and report. */
3282 uint64_t fIgnMask = 0;
3283 uint64_t fGpMask = 0;
3284 int rc = msrProberModifyBitChanges(uMsr, &fIgnMask, &fGpMask, fSkipMask);
3285 if (RT_SUCCESS(rc))
3286 {
3287 fGpMask &= ~fNoGpMask;
3288
3289 if (fGpMask == UINT64_MAX && uValue == 0 && !msrProberModifyZero(uMsr))
3290 rc = printMsrFunctionReadOnly(uMsr, pszRdWrFnName, pszAnnotate);
3291 else if (fIgnMask == UINT64_MAX && fGpMask == 0 && uValue == 0)
3292 rc = printMsrFunctionIgnoreWrites(uMsr, pszRdWrFnName, pszAnnotate);
3293 else if (fIgnMask != 0 && fGpMask == 0 && uValue == 0)
3294 rc = printMsrFunctionIgnoreMask(uMsr, pszRdWrFnName, NULL, fIgnMask, pszAnnotate);
3295 else if (fIgnMask == 0 && fGpMask == 0 && uValue == 0)
3296 rc = printMsrFunction(uMsr, pszRdWrFnName, NULL, pszAnnotate);
3297 else
3298 rc = printMsrFunctionExtended(uMsr, pszRdWrFnName, NULL, uValue, fIgnMask, fGpMask, pszAnnotate);
3299 }
3300 return rc;
3301}
3302
3303
3304/**
3305 * Reports a VIA/Shanghai dummy range.
3306 *
3307 * @returns VBox status code.
3308 * @param paMsrs Pointer to the first MSR.
3309 * @param cMsrs The number of MSRs in the array @a paMsr.
3310 * @param pidxLoop Index variable that should be advanced to the
3311 * last MSR entry in the range.
3312 */
3313static int reportMsr_ViaShanghaiDummyRange(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t *pidxLoop)
3314{
3315 /* Figure how many. */
3316 uint32_t uMsr = paMsrs[0].uMsr;
3317 uint32_t cRegs = 1;
3318 while ( cRegs < cMsrs
3319 && paMsrs[cRegs].uMsr == uMsr + cRegs
3320 && isMsrViaShanghaiDummy(paMsrs[cRegs].uMsr, paMsrs[cRegs].uValue, paMsrs[cRegs].fFlags))
3321 {
3322 cRegs++;
3323 if (!(cRegs % 0x80))
3324 vbCpuRepDebug("VIA dummy detection %#llx..%#llx (%#x regs)...\n", uMsr, uMsr + cRegs - 1, cRegs);
3325 }
3326
3327 /* Advance. */
3328 *pidxLoop += cRegs - 1;
3329
3330 /* Report it/them. */
3331 char szName[80];
3332 if (cRegs == 1)
3333 {
3334 RTStrPrintf(szName, sizeof(szName), "ZERO_%04x_%04x", RT_HI_U16(uMsr), RT_LO_U16(uMsr));
3335 return printMsrValueIgnoreWritesNamed(uMsr, 0, szName, NULL);
3336 }
3337
3338 uint32_t uMsrLast = uMsr + cRegs - 1;
3339 RTStrPrintf(szName, sizeof(szName), "ZERO_%04x_%04x_THRU_%04x_%04x",
3340 RT_HI_U16(uMsr), RT_LO_U16(uMsr), RT_HI_U16(uMsrLast), RT_LO_U16(uMsrLast));
3341 return printMsrRangeValueIgnoreWritesNamed(uMsr, uMsrLast, 0, szName, NULL);
3342}
3343
3344
3345/**
3346 * Special function for reporting the IA32_APIC_BASE register, as it seems to be
3347 * causing trouble on newer systems.
3348 *
3349 * @returns
3350 * @param uMsr The MSR number.
3351 * @param uValue The value.
3352 */
3353static int reportMsr_Ia32ApicBase(uint32_t uMsr, uint64_t uValue)
3354{
3355 /* Trouble with the generic treatment of both the "APIC Global Enable" and
3356 "Enable x2APIC mode" bits on an i7-3820QM running OS X 10.8.5. */
3357 uint64_t fSkipMask = RT_BIT_64(11);
3358 if (vbCpuRepSupportsX2Apic())
3359 fSkipMask |= RT_BIT_64(10);
3360 /* For some reason, twiddling this bit kills a Tualatin PIII-S. */
3361 if (g_enmMicroarch == kCpumMicroarch_Intel_P6_III)
3362 fSkipMask |= RT_BIT(9);
3363
3364 /* If the OS uses the APIC, we have to be super careful. */
3365 if (!g_MsrAcc.fAtomic)
3366 fSkipMask |= UINT64_C(0x0000000ffffff000);
3367
3368 return reportMsr_GenFunctionEx(uMsr, "Ia32ApicBase", uValue, fSkipMask, 0, NULL);
3369}
3370
3371
3372/**
3373 * Special function for reporting the IA32_MISC_ENABLE register, as it seems to
3374 * be causing trouble on newer systems.
3375 *
3376 * @returns
3377 * @param uMsr The MSR number.
3378 * @param uValue The value.
3379 */
3380static int reportMsr_Ia32MiscEnable(uint32_t uMsr, uint64_t uValue)
3381{
3382 uint64_t fSkipMask = 0;
3383
3384 if ( ( g_enmMicroarch >= kCpumMicroarch_Intel_Core7_Broadwell
3385 && g_enmMicroarch <= kCpumMicroarch_Intel_Core7_End)
3386 || ( g_enmMicroarch >= kCpumMicroarch_Intel_Atom_Airmount
3387 && g_enmMicroarch <= kCpumMicroarch_Intel_Atom_End)
3388 )
3389 {
3390 vbCpuRepPrintf("WARNING: IA32_MISC_ENABLE probing needs hacking on this CPU!\n");
3391 RTThreadSleep(128);
3392 }
3393
3394 /* If the OS is using MONITOR/MWAIT we'd better not disable it! */
3395 if (!g_MsrAcc.fAtomic)
3396 fSkipMask |= RT_BIT(18);
3397
3398 /* The no execute related flag is deadly if clear. */
3399 if ( !(uValue & MSR_IA32_MISC_ENABLE_XD_DISABLE)
3400 && ( g_enmMicroarch < kCpumMicroarch_Intel_First
3401 || g_enmMicroarch >= kCpumMicroarch_Intel_Core_Yonah
3402 || vbCpuRepSupportsNX() ) )
3403 fSkipMask |= MSR_IA32_MISC_ENABLE_XD_DISABLE;
3404
3405 uint64_t fIgnMask = 0;
3406 uint64_t fGpMask = 0;
3407 int rc = msrProberModifyBitChanges(uMsr, &fIgnMask, &fGpMask, fSkipMask);
3408 if (RT_SUCCESS(rc))
3409 rc = printMsrFunctionExtended(uMsr, "Ia32MiscEnable", "Ia32MiscEnable", uValue,
3410 fIgnMask, fGpMask, annotateValue(uValue));
3411 return rc;
3412}
3413
3414
3415/**
3416 * Verifies that MTRR type field works correctly in the given MSR.
3417 *
3418 * @returns VBox status code (failure if bad MSR behavior).
3419 * @param uMsr The MSR.
3420 * @param iBit The first bit of the type field (8-bit wide).
3421 * @param cExpected The number of types expected - PAT=8, MTRR=7.
3422 */
3423static int msrVerifyMtrrTypeGPs(uint32_t uMsr, uint32_t iBit, uint32_t cExpected)
3424{
3425 uint32_t uEndTypes = 0;
3426 while (uEndTypes < 255)
3427 {
3428 bool fGp = !msrProberModifySimpleGp(uMsr, ~(UINT64_C(0xff) << iBit), (uint64_t)uEndTypes << iBit);
3429 if (!fGp && (uEndTypes == 2 || uEndTypes == 3))
3430 return RTMsgErrorRc(VERR_INVALID_PARAMETER, "MTRR types %u does not cause a GP as it should. (msr %#x)\n",
3431 uEndTypes, uMsr);
3432 if (fGp && uEndTypes != 2 && uEndTypes != 3)
3433 break;
3434 uEndTypes++;
3435 }
3436 if (uEndTypes != cExpected)
3437 return RTMsgErrorRc(VERR_INVALID_PARAMETER, "MTRR types detected to be %#x (msr %#x). Expected %#x.\n",
3438 uEndTypes, uMsr, cExpected);
3439 return VINF_SUCCESS;
3440}
3441
3442
3443/**
3444 * Deals with the variable MTRR MSRs.
3445 *
3446 * @returns VBox status code.
3447 * @param paMsrs Pointer to the first variable MTRR MSR (200h).
3448 * @param cMsrs The number of MSRs in the array @a paMsr.
3449 * @param pidxLoop Index variable that should be advanced to the
3450 * last MTRR MSR entry.
3451 */
3452static int reportMsr_Ia32MtrrPhysBaseMaskN(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t *pidxLoop)
3453{
3454 uint32_t uMsr = paMsrs[0].uMsr;
3455
3456 /* Count them. */
3457 uint32_t cRegs = 1;
3458 while ( cRegs < cMsrs
3459 && paMsrs[cRegs].uMsr == uMsr + cRegs
3460 && !isMsrViaShanghaiDummy(paMsrs[cRegs].uMsr, paMsrs[cRegs].uValue, paMsrs[cRegs].fFlags) )
3461 cRegs++;
3462 if (cRegs & 1)
3463 return RTMsgErrorRc(VERR_INVALID_PARAMETER, "MTRR variable MSR range is odd: cRegs=%#x\n", cRegs);
3464 if (cRegs > 0x20)
3465 return RTMsgErrorRc(VERR_INVALID_PARAMETER, "MTRR variable MSR range is too large: cRegs=%#x\n", cRegs);
3466
3467 /* Find a disabled register that we can play around with. */
3468 uint32_t iGuineaPig;
3469 for (iGuineaPig = 0; iGuineaPig < cRegs; iGuineaPig += 2)
3470 if (!(paMsrs[iGuineaPig + 1].uValue & RT_BIT_32(11)))
3471 break;
3472 if (iGuineaPig >= cRegs)
3473 iGuineaPig = cRegs - 2;
3474 vbCpuRepDebug("iGuineaPig=%#x -> %#x\n", iGuineaPig, uMsr + iGuineaPig);
3475
3476 /* Probe the base. */
3477 uint64_t fIgnBase = 0;
3478 uint64_t fGpBase = 0;
3479 int rc = msrProberModifyBitChanges(uMsr + iGuineaPig, &fIgnBase, &fGpBase, 0);
3480 if (RT_FAILURE(rc))
3481 return rc;
3482 rc = msrVerifyMtrrTypeGPs(uMsr + iGuineaPig, 0, 7);
3483 if (RT_FAILURE(rc))
3484 return rc;
3485 vbCpuRepDebug("fIgnBase=%#llx fGpBase=%#llx\n", fIgnBase, fGpBase);
3486
3487 /* Probing the mask is relatively straight forward. */
3488 uint64_t fIgnMask = 0;
3489 uint64_t fGpMask = 0;
3490 rc = msrProberModifyBitChanges(uMsr + iGuineaPig + 1, &fIgnMask, &fGpMask, 0x800); /* enabling it may cause trouble */
3491 if (RT_FAILURE(rc))
3492 return rc;
3493 vbCpuRepDebug("fIgnMask=%#llx fGpMask=%#llx\n", fIgnMask, fGpMask);
3494
3495 /* Validate that the whole range subscribes to the apprimately same GP rules. */
3496 for (uint32_t i = 0; i < cRegs; i += 2)
3497 {
3498 uint64_t fSkipBase = ~fGpBase;
3499 uint64_t fSkipMask = ~fGpMask;
3500 if (!(paMsrs[i + 1].uValue & RT_BIT_32(11)))
3501 fSkipBase = fSkipMask = 0;
3502 fSkipBase |= 0x7; /* Always skip the type. */
3503 fSkipMask |= RT_BIT_32(11); /* Always skip the enable bit. */
3504
3505 vbCpuRepDebug("i=%#x fSkipBase=%#llx fSkipMask=%#llx\n", i, fSkipBase, fSkipMask);
3506
3507 if (!(paMsrs[i + 1].uValue & RT_BIT_32(11)))
3508 {
3509 rc = msrVerifyMtrrTypeGPs(uMsr + iGuineaPig, 0, 7);
3510 if (RT_FAILURE(rc))
3511 return rc;
3512 }
3513
3514 uint64_t fIgnBaseN = 0;
3515 uint64_t fGpBaseN = 0;
3516 rc = msrProberModifyBitChanges(uMsr + i, &fIgnBaseN, &fGpBaseN, fSkipBase);
3517 if (RT_FAILURE(rc))
3518 return rc;
3519
3520 if ( fIgnBaseN != (fIgnBase & ~fSkipBase)
3521 || fGpBaseN != (fGpBase & ~fSkipBase) )
3522 return RTMsgErrorRc(VERR_INVALID_PARAMETER,
3523 "MTRR PHYS BASE register %#x behaves differently from %#x: ign=%#llx/%#llx gp=%#llx/%#llx (fSkipBase=%#llx)\n",
3524 uMsr + i, uMsr + iGuineaPig,
3525 fIgnBaseN, fIgnBase & ~fSkipBase, fGpBaseN, fGpBase & ~fSkipBase, fSkipBase);
3526
3527 uint64_t fIgnMaskN = 0;
3528 uint64_t fGpMaskN = 0;
3529 rc = msrProberModifyBitChanges(uMsr + i + 1, &fIgnMaskN, &fGpMaskN, fSkipMask);
3530 if (RT_FAILURE(rc))
3531 return rc;
3532 if ( fIgnMaskN != (fIgnMask & ~fSkipMask)
3533 || fGpMaskN != (fGpMask & ~fSkipMask) )
3534 return RTMsgErrorRc(VERR_INVALID_PARAMETER,
3535 "MTRR PHYS MASK register %#x behaves differently from %#x: ign=%#llx/%#llx gp=%#llx/%#llx (fSkipMask=%#llx)\n",
3536 uMsr + i + 1, uMsr + iGuineaPig + 1,
3537 fIgnMaskN, fIgnMask & ~fSkipMask, fGpMaskN, fGpMask & ~fSkipMask, fSkipMask);
3538 }
3539
3540 /* Print the whole range. */
3541 fGpBase &= ~(uint64_t)0x7; /* Valid type bits, see msrVerifyMtrrTypeGPs(). */
3542 for (uint32_t i = 0; i < cRegs; i += 2)
3543 {
3544 printMsrFunctionExtendedIdxVal(uMsr + i, "Ia32MtrrPhysBaseN", NULL, i / 2, fIgnBase, fGpBase,
3545 annotateValue(paMsrs[i].uValue));
3546 printMsrFunctionExtendedIdxVal(uMsr + i + 1, "Ia32MtrrPhysMaskN", NULL, i / 2, fIgnMask, fGpMask,
3547 annotateValue(paMsrs[i + 1].uValue));
3548 }
3549
3550 *pidxLoop += cRegs - 1;
3551 return VINF_SUCCESS;
3552}
3553
3554
3555/**
3556 * Deals with fixed MTRR and PAT MSRs, checking the 8 memory type fields.
3557 *
3558 * @returns VBox status code.
3559 * @param uMsr The MSR.
3560 */
3561static int reportMsr_Ia32MtrrFixedOrPat(uint32_t uMsr)
3562{
3563 /* Had a spot of trouble on an old macbook pro with core2 duo T9900 (penryn)
3564 running 64-bit win81pe. Not giving PAT such a scrutiny fixes it. */
3565 if ( uMsr != 0x00000277
3566 || ( g_enmVendor == CPUMCPUVENDOR_INTEL
3567 ? g_enmMicroarch >= kCpumMicroarch_Intel_Core7_First
3568 : g_enmVendor == CPUMCPUVENDOR_AMD
3569 ? g_enmMicroarch != kCpumMicroarch_AMD_K8_90nm_AMDV
3570 : true) )
3571 {
3572 /* Every 8 bytes is a type, check the type ranges one by one. */
3573 for (uint32_t iBit = 0; iBit < 64; iBit += 8)
3574 {
3575 int rc = msrVerifyMtrrTypeGPs(uMsr, iBit, 7 + (uMsr == 0x00000277));
3576 if (RT_FAILURE(rc))
3577 return rc;
3578 }
3579 }
3580
3581 return printMsrFunctionCpumCpu(uMsr, NULL, NULL, NULL, NULL);
3582}
3583
3584
3585/**
3586 * Deals with IA32_MTRR_DEF_TYPE.
3587 *
3588 * @returns VBox status code.
3589 * @param uMsr The MSR.
3590 */
3591static int reportMsr_Ia32MtrrDefType(uint32_t uMsr)
3592{
3593 uint64_t fGpMask = 0;
3594 uint64_t fIgnMask = 0;
3595 if (g_enmMicroarch == kCpumMicroarch_AMD_K8_90nm_AMDV)
3596 {
3597 /* Problematic CPU! Fake it for now. */
3598 fGpMask = ~(uint64_t)0xc07;
3599 fIgnMask = 0;
3600 }
3601 else
3602 {
3603 int rc = msrVerifyMtrrTypeGPs(uMsr, 0, 7);
3604 if (RT_FAILURE(rc))
3605 return rc;
3606
3607 rc = msrProberModifyBitChanges(uMsr, &fIgnMask, &fGpMask, 0x7);
3608 if (RT_FAILURE(rc))
3609 return rc;
3610 Assert(!(fGpMask & 7)); Assert(!(fIgnMask & 7));
3611 }
3612
3613 return printMsrFunctionCpumCpuEx(uMsr, NULL, NULL, NULL, fIgnMask, fGpMask, NULL);
3614}
3615
3616
3617/**
3618 * Deals with the Machine Check (MC) MSRs in the 400h+ area.
3619 *
3620 * @returns VBox status code.
3621 * @param paMsrs Pointer to the first MC MSR (400h).
3622 * @param cMsrs The number of MSRs in the array @a paMsr.
3623 * @param pidxLoop Index variable that should be advanced to the
3624 * last MC MSR entry.
3625 */
3626static int reportMsr_Ia32McCtlStatusAddrMiscN(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t *pidxLoop)
3627{
3628 uint32_t uMsr = paMsrs[0].uMsr;
3629
3630 /* Count them. */
3631 uint32_t cRegs = 1;
3632 uint32_t cDetectedRegs = 1;
3633 while ( cDetectedRegs < cMsrs
3634 && ( paMsrs[cDetectedRegs].uMsr == uMsr + cRegs
3635 || (cRegs & 3) == 2 /* ADDR may or may not be there, depends on STATUS and CPU. */
3636 || (cRegs & 3) == 3 /* MISC may or may not be there, depends on STATUS and CPU. */
3637 || cRegs == 0x13 /* MC4_MISC may not be there, depends on CPU. */
3638 || cRegs == 0x14 /* MC5_CTL may not be there, depends on CPU. */)
3639 && cRegs < 0x7f )
3640 {
3641 if (paMsrs[cDetectedRegs].uMsr == uMsr + cRegs)
3642 cDetectedRegs++;
3643 cRegs++;
3644 }
3645 if (cRegs & 3)
3646 return RTMsgErrorRc(VERR_INVALID_PARAMETER, "MC MSR range is odd: cRegs=%#x\n", cRegs);
3647
3648 /* Just report them. We don't bother probing here as the CTL format
3649 and such seems to be a lot of work to test correctly and changes between
3650 cpu generations. */
3651 *pidxLoop += cDetectedRegs - 1;
3652 return printMsrRangeFunction(uMsr, uMsr + cRegs - 1, "Ia32McCtlStatusAddrMiscN", NULL, NULL);
3653}
3654
3655
3656
3657/**
3658 * Deals with the X2APIC msrs.
3659 *
3660 * @returns VBox status code.
3661 * @param paMsrs Pointer to the first X2APIC MSR.
3662 * @param cMsrs The number of MSRs in the array @a paMsr.
3663 * @param pidxLoop Index variable that should be advanced to the
3664 * last X2APIC MSR entry.
3665 */
3666static int reportMsr_GenX2Apic(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t *pidxLoop)
3667{
3668 /* Advance. */
3669 uint32_t cRegs = 1;
3670 while ( cRegs < cMsrs
3671 && paMsrs[cRegs].uMsr <= 0x8ff)
3672 cRegs++;
3673 *pidxLoop += cRegs - 1;
3674
3675 /* Just emit an X2APIC range. */
3676 return printMsrRangeFunction(0x800, 0x8ff, "Ia32X2ApicN", NULL, NULL);
3677}
3678
3679
3680/**
3681 * Deals carefully with the EFER register.
3682 *
3683 * @returns VBox status code.
3684 * @param uMsr The MSR number.
3685 * @param uValue The current value.
3686 */
3687static int reportMsr_Amd64Efer(uint32_t uMsr, uint64_t uValue)
3688{
3689 uint64_t fSkipMask = 0;
3690 if (vbCpuRepSupportsLongMode())
3691 {
3692 fSkipMask |= MSR_K6_EFER_LME;
3693 if (!g_MsrAcc.fAtomic && (uValue & MSR_K6_EFER_SCE))
3694 fSkipMask |= MSR_K6_EFER_SCE;
3695 }
3696 if ( (uValue & MSR_K6_EFER_NXE)
3697 || vbCpuRepSupportsNX())
3698 fSkipMask |= MSR_K6_EFER_NXE;
3699
3700 /* NetBurst prescott 2MB (model 4) hung or triple faulted here. The extra
3701 sleep or something seemed to help for some screwed up reason. */
3702 if (g_fIntelNetBurst)
3703 {
3704 // This doesn't matter:
3705 //fSkipMask |= MSR_K6_EFER_SCE;
3706 //if (vbCpuRepSupportsLongMode())
3707 // fSkipMask |= MSR_K6_EFER_LMA;
3708 //vbCpuRepDebug("EFER - netburst workaround - ignore SCE & LMA (fSkipMask=%#llx)\n", fSkipMask);
3709
3710 vbCpuRepDebug("EFER - netburst sleep fudge - fSkipMask=%#llx\n", fSkipMask);
3711 RTThreadSleep(1000);
3712 }
3713
3714 return reportMsr_GenFunctionEx(uMsr, NULL, uValue, fSkipMask, MSR_K6_EFER_LMA, NULL);
3715}
3716
3717
3718/**
3719 * Deals with the MC4_MISCn (n >= 1) range and the following reserved MSRs.
3720 *
3721 * @returns VBox status code.
3722 * @param paMsrs Pointer to the first MSR.
3723 * @param cMsrs The number of MSRs in the array @a paMsr.
3724 * @param pidxLoop Index variable that should be advanced to the
3725 * last MSR entry in the range.
3726 */
3727static int reportMsr_AmdFam10hMc4MiscN(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t *pidxLoop)
3728{
3729 /* Count registers. */
3730 uint32_t cRegs = 1;
3731 while ( cRegs < cMsrs
3732 && cRegs < 8
3733 && paMsrs[cRegs].uMsr == paMsrs[0].uMsr + cRegs)
3734 cRegs++;
3735
3736 /* Probe & report used MSRs. */
3737 uint64_t fIgnMask = 0;
3738 uint64_t fGpMask = 0;
3739 uint32_t cUsed = 0;
3740 while (cUsed < cRegs)
3741 {
3742 uint64_t fIgnMaskN = 0;
3743 uint64_t fGpMaskN = 0;
3744 int rc = msrProberModifyBitChanges(paMsrs[cUsed].uMsr, &fIgnMaskN, &fGpMaskN, 0);
3745 if (RT_FAILURE(rc))
3746 return rc;
3747 if (fIgnMaskN == UINT64_MAX || fGpMaskN == UINT64_MAX)
3748 break;
3749 if (cUsed == 0)
3750 {
3751 fIgnMask = fIgnMaskN;
3752 fGpMask = fGpMaskN;
3753 }
3754 else if ( fIgnMaskN != fIgnMask
3755 || fGpMaskN != fGpMask)
3756 return RTMsgErrorRc(VERR_NOT_EQUAL, "AmdFam16hMc4MiscN mismatch: fIgn=%#llx/%#llx fGp=%#llx/%#llx uMsr=%#x\n",
3757 fIgnMaskN, fIgnMask, fGpMaskN, fGpMask, paMsrs[cUsed].uMsr);
3758 cUsed++;
3759 }
3760 if (cUsed > 0)
3761 printMsrRangeFunctionEx(paMsrs[0].uMsr, paMsrs[cUsed - 1].uMsr, "AmdFam10hMc4MiscN", NULL, 0, fIgnMask, fGpMask, NULL);
3762
3763 /* Probe & report reserved MSRs. */
3764 uint32_t cReserved = 0;
3765 while (cUsed + cReserved < cRegs)
3766 {
3767 fIgnMask = fGpMask = 0;
3768 int rc = msrProberModifyBitChanges(paMsrs[cUsed + cReserved].uMsr, &fIgnMask, &fGpMask, 0);
3769 if (RT_FAILURE(rc))
3770 return rc;
3771 if ((fIgnMask != UINT64_MAX && fGpMask != UINT64_MAX) || paMsrs[cUsed + cReserved].uValue)
3772 return RTMsgErrorRc(VERR_NOT_EQUAL,
3773 "Unexpected reserved AmdFam16hMc4MiscN: fIgn=%#llx fGp=%#llx uMsr=%#x uValue=%#llx\n",
3774 fIgnMask, fGpMask, paMsrs[cUsed + cReserved].uMsr, paMsrs[cUsed + cReserved].uValue);
3775 cReserved++;
3776 }
3777 if (cReserved > 0 && fIgnMask == UINT64_MAX)
3778 printMsrRangeValueIgnoreWrites(paMsrs[cUsed].uMsr, paMsrs[cUsed + cReserved - 1].uMsr, 0, NULL);
3779 else if (cReserved > 0 && fGpMask == UINT64_MAX)
3780 printMsrRangeValueReadOnly(paMsrs[cUsed].uMsr, paMsrs[cUsed + cReserved - 1].uMsr, 0, NULL);
3781
3782 *pidxLoop += cRegs - 1;
3783 return VINF_SUCCESS;
3784}
3785
3786
3787/**
3788 * Deals with the AMD PERF_CTL range.
3789 *
3790 * @returns VBox status code.
3791 * @param paMsrs Pointer to the first MSR.
3792 * @param cMsrs The number of MSRs in the array @a paMsr.
3793 * @param pidxLoop Index variable that should be advanced to the
3794 * last MSR entry in the range.
3795 */
3796static int reportMsr_AmdK8PerfCtlN(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t *pidxLoop)
3797{
3798 uint32_t uMsr = paMsrs[0].uMsr;
3799 Assert(uMsr == 0xc0010000);
3800
3801 /* Family 15h (bulldozer +) aliases these registers sparsely onto c001020x. */
3802 if (CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch))
3803 {
3804 for (uint32_t i = 0; i < 4; i++)
3805 printMsrAlias(uMsr + i, 0xc0010200 + i * 2, NULL);
3806 *pidxLoop += 3;
3807 }
3808 else
3809 return reportMsr_GenRangeFunction(paMsrs, cMsrs, 4, "AmdK8PerfCtlN", pidxLoop);
3810 return VINF_SUCCESS;
3811}
3812
3813
3814/**
3815 * Deals with the AMD PERF_CTR range.
3816 *
3817 * @returns VBox status code.
3818 * @param paMsrs Pointer to the first MSR.
3819 * @param cMsrs The number of MSRs in the array @a paMsr.
3820 * @param pidxLoop Index variable that should be advanced to the
3821 * last MSR entry in the range.
3822 */
3823static int reportMsr_AmdK8PerfCtrN(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t *pidxLoop)
3824{
3825 uint32_t uMsr = paMsrs[0].uMsr;
3826 Assert(uMsr == 0xc0010004);
3827
3828 /* Family 15h (bulldozer +) aliases these registers sparsely onto c001020x. */
3829 if (CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch))
3830 {
3831 for (uint32_t i = 0; i < 4; i++)
3832 printMsrAlias(uMsr + i, 0xc0010201 + i * 2, NULL);
3833 *pidxLoop += 3;
3834 }
3835 else
3836 return reportMsr_GenRangeFunction(paMsrs, cMsrs, 4, "AmdK8PerfCtrN", pidxLoop);
3837 return VINF_SUCCESS;
3838}
3839
3840
3841/**
3842 * Deals carefully with the SYS_CFG register.
3843 *
3844 * @returns VBox status code.
3845 * @param uMsr The MSR number.
3846 * @param uValue The current value.
3847 */
3848static int reportMsr_AmdK8SysCfg(uint32_t uMsr, uint64_t uValue)
3849{
3850 uint64_t fSkipMask = 0;
3851
3852 /* Bit 21 (MtrrTom2En) is marked reserved in family 0fh, while in family
3853 10h BKDG this changes (as does the document style). Testing this bit
3854 causes bulldozer running win64 to restart, thus this special treatment. */
3855 if (g_enmMicroarch >= kCpumMicroarch_AMD_K10)
3856 fSkipMask |= RT_BIT(21);
3857
3858 /* Turns out there are more killer bits here, at least on Opteron 2384.
3859 Skipping all known bits. */
3860 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm_AMDV /* Not sure when introduced - harmless? */)
3861 fSkipMask |= RT_BIT(22); /* Tom2ForceMemTypeWB */
3862 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_First)
3863 fSkipMask |= RT_BIT(21); /* MtrrTom2En */
3864 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_First)
3865 fSkipMask |= RT_BIT(20); /* MtrrVarDramEn*/
3866 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_First)
3867 fSkipMask |= RT_BIT(19); /* MtrrFixDramModEn */
3868 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_First)
3869 fSkipMask |= RT_BIT(18); /* MtrrFixDramEn */
3870 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_First)
3871 fSkipMask |= RT_BIT(17); /* SysUcLockEn */
3872 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_First)
3873 fSkipMask |= RT_BIT(16); /* ChgToDirtyDis */
3874 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_First && g_enmMicroarch < kCpumMicroarch_AMD_15h_First)
3875 fSkipMask |= RT_BIT(10); /* SetDirtyEnO */
3876 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_First && g_enmMicroarch < kCpumMicroarch_AMD_15h_First)
3877 fSkipMask |= RT_BIT(9); /* SetDirtyEnS */
3878 if ( CPUMMICROARCH_IS_AMD_FAM_0FH(g_enmMicroarch)
3879 || CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch))
3880 fSkipMask |= RT_BIT(8); /* SetDirtyEnE */
3881 if ( CPUMMICROARCH_IS_AMD_FAM_0FH(g_enmMicroarch)
3882 || CPUMMICROARCH_IS_AMD_FAM_11H(g_enmMicroarch) )
3883 fSkipMask |= RT_BIT(7) /* SysVicLimit */
3884 | RT_BIT(6) /* SysVicLimit */
3885 | RT_BIT(5) /* SysVicLimit */
3886 | RT_BIT(4) /* SysAckLimit */
3887 | RT_BIT(3) /* SysAckLimit */
3888 | RT_BIT(2) /* SysAckLimit */
3889 | RT_BIT(1) /* SysAckLimit */
3890 | RT_BIT(0) /* SysAckLimit */;
3891
3892 return reportMsr_GenFunctionEx(uMsr, NULL, uValue, fSkipMask, 0, annotateValue(uValue));
3893}
3894
3895
3896/**
3897 * Deals carefully with the HWCR register.
3898 *
3899 * @returns VBox status code.
3900 * @param uMsr The MSR number.
3901 * @param uValue The current value.
3902 */
3903static int reportMsr_AmdK8HwCr(uint32_t uMsr, uint64_t uValue)
3904{
3905 uint64_t fSkipMask = 0;
3906
3907 /* Trouble on Opteron 2384, skip some of the known bits. */
3908 if (g_enmMicroarch >= kCpumMicroarch_AMD_K10 && !CPUMMICROARCH_IS_AMD_FAM_11H(g_enmMicroarch))
3909 fSkipMask |= /*RT_BIT(10)*/ 0 /* MonMwaitUserEn */
3910 | RT_BIT(9); /* MonMwaitDis */
3911 fSkipMask |= RT_BIT(8); /* #IGNNE port emulation */
3912 if ( CPUMMICROARCH_IS_AMD_FAM_0FH(g_enmMicroarch)
3913 || CPUMMICROARCH_IS_AMD_FAM_11H(g_enmMicroarch) )
3914 fSkipMask |= RT_BIT(7) /* DisLock */
3915 | RT_BIT(6); /* FFDis (TLB flush filter) */
3916 fSkipMask |= RT_BIT(4); /* INVD to WBINVD */
3917 fSkipMask |= RT_BIT(3); /* TLBCACHEDIS */
3918 if ( CPUMMICROARCH_IS_AMD_FAM_0FH(g_enmMicroarch)
3919 || CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch)
3920 || CPUMMICROARCH_IS_AMD_FAM_11H(g_enmMicroarch) )
3921 fSkipMask |= RT_BIT(1); /* SLOWFENCE */
3922 fSkipMask |= RT_BIT(0); /* SMMLOCK */
3923
3924 return reportMsr_GenFunctionEx(uMsr, NULL, uValue, fSkipMask, 0, annotateValue(uValue));
3925}
3926
3927
3928/**
3929 * Deals carefully with a IORRBasei register.
3930 *
3931 * @returns VBox status code.
3932 * @param uMsr The MSR number.
3933 * @param uValue The current value.
3934 */
3935static int reportMsr_AmdK8IorrBaseN(uint32_t uMsr, uint64_t uValue)
3936{
3937 /* Skip know bits here, as harm seems to come from messing with them. */
3938 uint64_t fSkipMask = RT_BIT(4) | RT_BIT(3);
3939 fSkipMask |= (RT_BIT_64(vbCpuRepGetPhysAddrWidth()) - 1) & X86_PAGE_4K_BASE_MASK;
3940 return reportMsr_GenFunctionEx(uMsr, NULL, (uMsr - 0xc0010016) / 2, fSkipMask, 0, annotateValue(uValue));
3941}
3942
3943
3944/**
3945 * Deals carefully with a IORRMaski register.
3946 *
3947 * @returns VBox status code.
3948 * @param uMsr The MSR number.
3949 * @param uValue The current value.
3950 */
3951static int reportMsr_AmdK8IorrMaskN(uint32_t uMsr, uint64_t uValue)
3952{
3953 /* Skip know bits here, as harm seems to come from messing with them. */
3954 uint64_t fSkipMask = RT_BIT(11);
3955 fSkipMask |= (RT_BIT_64(vbCpuRepGetPhysAddrWidth()) - 1) & X86_PAGE_4K_BASE_MASK;
3956 return reportMsr_GenFunctionEx(uMsr, NULL, (uMsr - 0xc0010017) / 2, fSkipMask, 0, annotateValue(uValue));
3957}
3958
3959
3960/**
3961 * Deals carefully with a IORRMaski register.
3962 *
3963 * @returns VBox status code.
3964 * @param uMsr The MSR number.
3965 * @param uValue The current value.
3966 */
3967static int reportMsr_AmdK8TopMemN(uint32_t uMsr, uint64_t uValue)
3968{
3969 /* Skip know bits here, as harm seems to come from messing with them. */
3970 uint64_t fSkipMask = (RT_BIT_64(vbCpuRepGetPhysAddrWidth()) - 1) & ~(RT_BIT_64(23) - 1);
3971 return reportMsr_GenFunctionEx(uMsr, NULL, uMsr == 0xc001001d, fSkipMask, 0, annotateValue(uValue));
3972}
3973
3974
3975/**
3976 * Deals with the AMD P-state config range.
3977 *
3978 * @returns VBox status code.
3979 * @param paMsrs Pointer to the first MSR.
3980 * @param cMsrs The number of MSRs in the array @a paMsr.
3981 * @param pidxLoop Index variable that should be advanced to the
3982 * last MSR entry in the range.
3983 */
3984static int reportMsr_AmdFam10hPStateN(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t *pidxLoop)
3985{
3986 uint32_t uMsr = paMsrs[0].uMsr;
3987 AssertRelease(uMsr == 0xc0010064);
3988
3989 /* Count them. */
3990 uint32_t cRegs = 1;
3991 while ( cRegs < 8
3992 && cRegs < cMsrs
3993 && paMsrs[cRegs].uMsr == uMsr + cRegs)
3994 cRegs++;
3995
3996 /* Figure out which bits we should skip when probing. This is based on
3997 specs and may need adjusting for real life when handy. */
3998 uint64_t fSkipMask = RT_BIT_64(63); /* PstateEn */
3999 fSkipMask |= RT_BIT_64(41) | RT_BIT_64(40); /* IddDiv */
4000 fSkipMask |= UINT64_C(0x000000ff00000000); /* IddValue */
4001 if (CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch))
4002 fSkipMask |= UINT32_C(0xfe000000); /* NbVid - Northbridge VID */
4003 if ( CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch)
4004 || CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch))
4005 fSkipMask |= RT_BIT_32(22); /* NbDid or NbPstate. */
4006 if (g_enmMicroarch >= kCpumMicroarch_AMD_15h_Piledriver) /* ?? - listed in 10-1Fh model BDKG as well asFam16h */
4007 fSkipMask |= RT_BIT_32(16); /* CpuVid[7] */
4008 fSkipMask |= UINT32_C(0x0000fe00); /* CpuVid[6:0] */
4009 fSkipMask |= UINT32_C(0x000001c0); /* CpuDid */
4010 fSkipMask |= UINT32_C(0x0000003f); /* CpuFid */
4011
4012 /* Probe and report them one by one since we're passing values instead of
4013 register indexes to the functions. */
4014 for (uint32_t i = 0; i < cRegs; i++)
4015 {
4016 uint64_t fIgnMask = 0;
4017 uint64_t fGpMask = 0;
4018 int rc = msrProberModifyBitChanges(uMsr + i, &fIgnMask, &fGpMask, fSkipMask);
4019 if (RT_FAILURE(rc))
4020 return rc;
4021 printMsrFunctionExtended(uMsr + i, "AmdFam10hPStateN", NULL, paMsrs[i].uValue, fIgnMask, fGpMask,
4022 annotateValue(paMsrs[i].uValue));
4023 }
4024
4025 /* Advance. */
4026 *pidxLoop += cRegs - 1;
4027 return VINF_SUCCESS;
4028}
4029
4030
4031/**
4032 * Deals carefully with a COFVID control register.
4033 *
4034 * @returns VBox status code.
4035 * @param uMsr The MSR number.
4036 * @param uValue The current value.
4037 */
4038static int reportMsr_AmdFam10hCofVidControl(uint32_t uMsr, uint64_t uValue)
4039{
4040 /* Skip know bits here, as harm seems to come from messing with them. */
4041 uint64_t fSkipMask = 0;
4042 if (CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch))
4043 fSkipMask |= UINT32_C(0xfe000000); /* NbVid - Northbridge VID */
4044 else if (g_enmMicroarch >= kCpumMicroarch_AMD_15h_First) /* Listed in preliminary Fam16h BDKG. */
4045 fSkipMask |= UINT32_C(0xff000000); /* NbVid - Northbridge VID - includes bit 24 for Fam15h and Fam16h. Odd... */
4046 if ( CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch)
4047 || g_enmMicroarch >= kCpumMicroarch_AMD_15h_First) /* Listed in preliminary Fam16h BDKG. */
4048 fSkipMask |= RT_BIT_32(22); /* NbDid or NbPstate. */
4049 if (g_enmMicroarch >= kCpumMicroarch_AMD_15h_Piledriver) /* ?? - listed in 10-1Fh model BDKG as well asFam16h */
4050 fSkipMask |= RT_BIT_32(20); /* CpuVid[7] */
4051 fSkipMask |= UINT32_C(0x00070000); /* PstatId */
4052 fSkipMask |= UINT32_C(0x0000fe00); /* CpuVid[6:0] */
4053 fSkipMask |= UINT32_C(0x000001c0); /* CpuDid */
4054 fSkipMask |= UINT32_C(0x0000003f); /* CpuFid */
4055
4056 return reportMsr_GenFunctionEx(uMsr, NULL, uValue, fSkipMask, 0, annotateValue(uValue));
4057}
4058
4059
4060/**
4061 * Deals with the AMD [|L2I_|NB_]PERF_CT[LR] mixed ranges.
4062 *
4063 * Mixed here refers to the control and counter being in mixed in pairs as
4064 * opposed to them being two separate parallel arrays like in the 0xc0010000
4065 * area.
4066 *
4067 * @returns VBox status code.
4068 * @param paMsrs Pointer to the first MSR.
4069 * @param cMsrs The number of MSRs in the array @a paMsr.
4070 * @param cMax The max number of MSRs (not counters).
4071 * @param pidxLoop Index variable that should be advanced to the
4072 * last MSR entry in the range.
4073 */
4074static int reportMsr_AmdGenPerfMixedRange(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t cMax, uint32_t *pidxLoop)
4075{
4076 uint32_t uMsr = paMsrs[0].uMsr;
4077
4078 /* Count them. */
4079 uint32_t cRegs = 1;
4080 while ( cRegs < cMax
4081 && cRegs < cMsrs
4082 && paMsrs[cRegs].uMsr == uMsr + cRegs)
4083 cRegs++;
4084 if (cRegs & 1)
4085 return RTMsgErrorRc(VERR_INVALID_PARAMETER, "PERF range at %#x is odd: cRegs=%#x\n", uMsr, cRegs);
4086
4087 /* Report them as individual entries, using default names and such. */
4088 for (uint32_t i = 0; i < cRegs; i++)
4089 {
4090 uint64_t fIgnMask = 0;
4091 uint64_t fGpMask = 0;
4092 int rc = msrProberModifyBitChanges(uMsr + i, &fIgnMask, &fGpMask, 0);
4093 if (RT_FAILURE(rc))
4094 return rc;
4095 printMsrFunctionExtendedIdxVal(uMsr + i, NULL, NULL, i / 2, fIgnMask, fGpMask, annotateValue(paMsrs[i].uValue));
4096 }
4097
4098 /* Advance. */
4099 *pidxLoop += cRegs - 1;
4100 return VINF_SUCCESS;
4101}
4102
4103
4104/**
4105 * Deals carefully with a LS_CFG register.
4106 *
4107 * @returns VBox status code.
4108 * @param uMsr The MSR number.
4109 * @param uValue The current value.
4110 */
4111static int reportMsr_AmdK7InstrCacheCfg(uint32_t uMsr, uint64_t uValue)
4112{
4113 /* Skip know bits here, as harm seems to come from messing with them. */
4114 uint64_t fSkipMask = RT_BIT_64(9) /* DIS_SPEC_TLB_RLD */;
4115 if (CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch))
4116 fSkipMask |= RT_BIT_64(14); /* DIS_IND */
4117 if (CPUMMICROARCH_IS_AMD_FAM_16H(g_enmMicroarch))
4118 fSkipMask |= RT_BIT_64(26); /* DIS_WIDEREAD_PWR_SAVE */
4119 if (CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch))
4120 {
4121 fSkipMask |= 0x1e; /* DisIcWayFilter */
4122 fSkipMask |= RT_BIT_64(39); /* DisLoopPredictor */
4123 fSkipMask |= RT_BIT_64(27); /* Unknown killer bit, possibly applicable to other microarchs. */
4124 fSkipMask |= RT_BIT_64(28); /* Unknown killer bit, possibly applicable to other microarchs. */
4125 }
4126 return reportMsr_GenFunctionEx(uMsr, NULL, uValue, fSkipMask, 0, annotateValue(uValue));
4127}
4128
4129
4130/**
4131 * Deals carefully with a CU_CFG register.
4132 *
4133 * @returns VBox status code.
4134 * @param uMsr The MSR number.
4135 * @param uValue The current value.
4136 */
4137static int reportMsr_AmdFam15hCombUnitCfg(uint32_t uMsr, uint64_t uValue)
4138{
4139 /* Skip know bits here, as harm seems to come from messing with them. */
4140 uint64_t fSkipMask = RT_BIT_64(23) /* L2WayLock */
4141 | RT_BIT_64(22) /* L2FirstLockWay */
4142 | RT_BIT_64(21) /* L2FirstLockWay */
4143 | RT_BIT_64(20) /* L2FirstLockWay */
4144 | RT_BIT_64(19) /* L2FirstLockWay */
4145 | RT_BIT_64(10) /* DcacheAggressivePriority */;
4146 fSkipMask |= RT_BIT_64(46) | RT_BIT_64(45); /* Killer field. Seen bit 46 set, 45 clear. Messing with either means reboot/BSOD. */
4147 return reportMsr_GenFunctionEx(uMsr, NULL, uValue, fSkipMask, 0, annotateValue(uValue));
4148}
4149
4150
4151/**
4152 * Deals carefully with a EX_CFG register.
4153 *
4154 * @returns VBox status code.
4155 * @param uMsr The MSR number.
4156 * @param uValue The current value.
4157 */
4158static int reportMsr_AmdFam15hExecUnitCfg(uint32_t uMsr, uint64_t uValue)
4159{
4160 /* Skip know bits here, as harm seems to come from messing with them. */
4161 uint64_t fSkipMask = RT_BIT_64(54) /* LateSbzResync */;
4162 fSkipMask |= RT_BIT_64(35); /* Undocumented killer bit. */
4163 return reportMsr_GenFunctionEx(uMsr, NULL, uValue, fSkipMask, 0, annotateValue(uValue));
4164}
4165
4166
4167
4168static int produceMsrReport(VBCPUREPMSR *paMsrs, uint32_t cMsrs)
4169{
4170 vbCpuRepDebug("produceMsrReport\n");
4171 RTThreadSleep(500);
4172
4173 for (uint32_t i = 0; i < cMsrs; i++)
4174 {
4175 uint32_t uMsr = paMsrs[i].uMsr;
4176 uint32_t fFlags = paMsrs[i].fFlags;
4177 uint64_t uValue = paMsrs[i].uValue;
4178 int rc;
4179#if 0
4180 //if (uMsr < 0x00000000)
4181 // continue;
4182 if (uMsr >= 0x00000277)
4183 {
4184 vbCpuRepDebug("produceMsrReport: uMsr=%#x (%s)...\n", uMsr, getMsrNameHandled(uMsr));
4185 RTThreadSleep(1000);
4186 }
4187#endif
4188 /*
4189 * Deal with write only regs first to avoid having to avoid them all the time.
4190 */
4191 if (fFlags & VBCPUREPMSR_F_WRITE_ONLY)
4192 {
4193 if (uMsr == 0x00000079)
4194 rc = printMsrWriteOnly(uMsr, NULL, NULL);
4195 else
4196 rc = reportMsr_Generic(uMsr, fFlags, uValue);
4197 }
4198 /*
4199 * VIA implement MSRs in a interesting way, so we have to select what we
4200 * want to handle there to avoid making the code below unreadable.
4201 */
4202 /** @todo r=klaus check if Shanghai CPUs really are behaving the same */
4203 else if (isMsrViaShanghaiDummy(uMsr, uValue, fFlags))
4204 rc = reportMsr_ViaShanghaiDummyRange(&paMsrs[i], cMsrs - i, &i);
4205 /*
4206 * This shall be sorted by uMsr as much as possible.
4207 */
4208 else if (uMsr == 0x00000000 && g_enmVendor == CPUMCPUVENDOR_AMD && g_enmMicroarch >= kCpumMicroarch_AMD_K8_First)
4209 rc = printMsrAlias(uMsr, 0x00000402, NULL);
4210 else if (uMsr == 0x00000001 && g_enmVendor == CPUMCPUVENDOR_AMD && g_enmMicroarch >= kCpumMicroarch_AMD_K8_First)
4211 rc = printMsrAlias(uMsr, 0x00000401, NULL); /** @todo not 101% correct on Fam15h and later, 0xc0010015[McstatusWrEn] effect differs. */
4212 else if (uMsr == 0x0000001b)
4213 rc = reportMsr_Ia32ApicBase(uMsr, uValue);
4214 else if (uMsr == 0x00000040 && g_enmMicroarch <= kCpumMicroarch_Intel_P6_M_Dothan)
4215 rc = reportMsr_GenRangeFunction(&paMsrs[i], cMsrs - i, 8 /*cMax*/, "IntelLastBranchFromToN", &i);
4216 else if (uMsr == 0x00000040)
4217 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 8 /*cMax*/, "IntelLastBranchToN", uMsr, false,
4218 true, getGenericSkipMask(uMsr), &i);
4219 else if (uMsr == 0x00000060 && g_enmMicroarch >= kCpumMicroarch_Intel_Core_Yonah)
4220 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 8 /*cMax*/, "IntelLastBranchFromN", uMsr, false,
4221 true, getGenericSkipMask(uMsr), &i);
4222 else if (uMsr == 0x000000c1)
4223 rc = reportMsr_GenRangeFunction(&paMsrs[i], cMsrs - i,
4224 g_enmMicroarch >= kCpumMicroarch_Intel_Core7_First ? 8 : 4 /*cMax*/,
4225 NULL, &i);
4226 else if (uMsr == 0x00000186 && !g_fIntelNetBurst)
4227 rc = reportMsr_GenRangeFunction(&paMsrs[i], cMsrs - i, 8 /*cMax*/, "Ia32PerfEvtSelN", &i);
4228 else if (uMsr == 0x000001a0)
4229 rc = reportMsr_Ia32MiscEnable(uMsr, uValue);
4230 else if (uMsr >= 0x000001a6 && uMsr <= 0x000001a7)
4231 rc = reportMsr_GenRangeFunction(&paMsrs[i], cMsrs - i, 2 /*cMax*/, "IntelI7MsrOffCoreResponseN", &i);
4232 else if (uMsr == 0x000001db && g_fIntelNetBurst)
4233 rc = reportMsr_GenRangeFunction(&paMsrs[i], cMsrs - i, 4 /*cMax*/, "IntelLastBranchFromToN", &i);
4234 else if (uMsr == 0x00000200)
4235 rc = reportMsr_Ia32MtrrPhysBaseMaskN(&paMsrs[i], cMsrs - i, &i);
4236 else if (uMsr >= 0x00000250 && uMsr <= 0x00000279)
4237 rc = reportMsr_Ia32MtrrFixedOrPat(uMsr);
4238 else if (uMsr >= 0x00000280 && uMsr <= 0x00000295)
4239 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 22 /*cMax*/, NULL, 0x00000280, true /*fEarlyEndOk*/, false, 0, &i);
4240 else if (uMsr == 0x000002ff)
4241 rc = reportMsr_Ia32MtrrDefType(uMsr);
4242 else if (uMsr >= 0x00000309 && uMsr <= 0x0000030b && !g_fIntelNetBurst)
4243 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 3 /*cMax*/, NULL, 0x00000309, true /*fEarlyEndOk*/, false, 0, &i);
4244 else if ((uMsr == 0x000003f8 || uMsr == 0x000003fc || uMsr == 0x0000060a) && !g_fIntelNetBurst)
4245 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 4, NULL, uMsr - 3, true, false, 0, &i);
4246 else if ((uMsr == 0x000003f9 || uMsr == 0x000003fd || uMsr == 0x0000060b) && !g_fIntelNetBurst)
4247 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 8, NULL, uMsr - 6, true, false, 0, &i);
4248 else if ((uMsr == 0x000003fa || uMsr == 0x000003fe || uMsr == 0x0000060c) && !g_fIntelNetBurst)
4249 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 8, NULL, uMsr - 7, true, false, 0, &i);
4250 else if (uMsr >= 0x00000400 && uMsr <= 0x00000477)
4251 rc = reportMsr_Ia32McCtlStatusAddrMiscN(&paMsrs[i], cMsrs - i, &i);
4252 else if (uMsr == 0x000004c1)
4253 rc = reportMsr_GenRangeFunction(&paMsrs[i], cMsrs - i, 8, NULL, &i);
4254 else if (uMsr == 0x00000680 || uMsr == 0x000006c0)
4255 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 16, NULL, uMsr, false, false,
4256 g_fIntelNetBurst
4257 ? UINT64_C(0xffffffffffffff00) /* kludge */
4258 : UINT64_C(0xffff800000000000), &i);
4259 else if (uMsr >= 0x00000800 && uMsr <= 0x000008ff)
4260 rc = reportMsr_GenX2Apic(&paMsrs[i], cMsrs - i, &i);
4261 else if (uMsr == 0x00002000 && g_enmVendor == CPUMCPUVENDOR_INTEL)
4262 rc = reportMsr_GenFunctionEx(uMsr, "IntelP6CrN", 0, X86_CR0_PE | X86_CR0_PG, 0,
4263 annotateIfMissingBits(uValue, X86_CR0_PE | X86_CR0_PE | X86_CR0_ET));
4264 else if (uMsr == 0x00002002 && g_enmVendor == CPUMCPUVENDOR_INTEL)
4265 rc = reportMsr_GenFunctionEx(uMsr, "IntelP6CrN", 2, 0, 0, annotateValue(uValue));
4266 else if (uMsr == 0x00002003 && g_enmVendor == CPUMCPUVENDOR_INTEL)
4267 {
4268 uint64_t fCr3Mask = (RT_BIT_64(vbCpuRepGetPhysAddrWidth()) - 1) & (X86_CR3_PAE_PAGE_MASK | X86_CR3_AMD64_PAGE_MASK);
4269 if (!vbCpuRepSupportsPae())
4270 fCr3Mask &= X86_CR3_PAGE_MASK | X86_CR3_AMD64_PAGE_MASK;
4271 rc = reportMsr_GenFunctionEx(uMsr, "IntelP6CrN", 3, fCr3Mask, 0, annotateValue(uValue));
4272 }
4273 else if (uMsr == 0x00002004 && g_enmVendor == CPUMCPUVENDOR_INTEL)
4274 rc = reportMsr_GenFunctionEx(uMsr, "IntelP6CrN", 4,
4275 X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE | X86_CR4_SMXE, 0,
4276 annotateValue(uValue));
4277 else if (uMsr == 0xc0000080)
4278 rc = reportMsr_Amd64Efer(uMsr, uValue);
4279 else if (uMsr >= 0xc0000408 && uMsr <= 0xc000040f)
4280 rc = reportMsr_AmdFam10hMc4MiscN(&paMsrs[i], cMsrs - i, &i);
4281 else if (uMsr == 0xc0010000 && g_enmVendor == CPUMCPUVENDOR_AMD)
4282 rc = reportMsr_AmdK8PerfCtlN(&paMsrs[i], cMsrs - i, &i);
4283 else if (uMsr == 0xc0010004 && g_enmVendor == CPUMCPUVENDOR_AMD)
4284 rc = reportMsr_AmdK8PerfCtrN(&paMsrs[i], cMsrs - i, &i);
4285 else if (uMsr == 0xc0010010 && g_enmVendor == CPUMCPUVENDOR_AMD)
4286 rc = reportMsr_AmdK8SysCfg(uMsr, uValue);
4287 else if (uMsr == 0xc0010015 && g_enmVendor == CPUMCPUVENDOR_AMD)
4288 rc = reportMsr_AmdK8HwCr(uMsr, uValue);
4289 else if ((uMsr == 0xc0010016 || uMsr == 0xc0010018) && g_enmVendor == CPUMCPUVENDOR_AMD)
4290 rc = reportMsr_AmdK8IorrBaseN(uMsr, uValue);
4291 else if ((uMsr == 0xc0010017 || uMsr == 0xc0010019) && g_enmVendor == CPUMCPUVENDOR_AMD)
4292 rc = reportMsr_AmdK8IorrMaskN(uMsr, uValue);
4293 else if ((uMsr == 0xc001001a || uMsr == 0xc001001d) && g_enmVendor == CPUMCPUVENDOR_AMD)
4294 rc = reportMsr_AmdK8TopMemN(uMsr, uValue);
4295 else if (uMsr == 0xc0010030 && g_enmVendor == CPUMCPUVENDOR_AMD)
4296 rc = reportMsr_GenRangeFunction(&paMsrs[i], cMsrs - i, 6, "AmdK8CpuNameN", &i);
4297 else if (uMsr >= 0xc0010044 && uMsr <= 0xc001004a && g_enmVendor == CPUMCPUVENDOR_AMD)
4298 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 7, "AmdK8McCtlMaskN", 0xc0010044, true /*fEarlyEndOk*/, false, 0, &i);
4299 else if (uMsr == 0xc0010050 && g_enmVendor == CPUMCPUVENDOR_AMD)
4300 rc = reportMsr_GenRangeFunction(&paMsrs[i], cMsrs - i, 4, "AmdK8SmiOnIoTrapN", &i);
4301 else if (uMsr == 0xc0010064 && g_enmVendor == CPUMCPUVENDOR_AMD)
4302 rc = reportMsr_AmdFam10hPStateN(&paMsrs[i], cMsrs - i, &i);
4303 else if (uMsr == 0xc0010070 && g_enmVendor == CPUMCPUVENDOR_AMD)
4304 rc = reportMsr_AmdFam10hCofVidControl(uMsr, uValue);
4305 else if ((uMsr == 0xc0010118 || uMsr == 0xc0010119) && getMsrFnName(uMsr, NULL) && g_enmVendor == CPUMCPUVENDOR_AMD)
4306 rc = printMsrFunction(uMsr, NULL, NULL, annotateValue(uValue)); /* RAZ, write key. */
4307 else if (uMsr == 0xc0010200 && g_enmVendor == CPUMCPUVENDOR_AMD)
4308 rc = reportMsr_AmdGenPerfMixedRange(&paMsrs[i], cMsrs - i, 12, &i);
4309 else if (uMsr == 0xc0010230 && g_enmVendor == CPUMCPUVENDOR_AMD)
4310 rc = reportMsr_AmdGenPerfMixedRange(&paMsrs[i], cMsrs - i, 8, &i);
4311 else if (uMsr == 0xc0010240 && g_enmVendor == CPUMCPUVENDOR_AMD)
4312 rc = reportMsr_AmdGenPerfMixedRange(&paMsrs[i], cMsrs - i, 8, &i);
4313 else if (uMsr == 0xc0011019 && g_enmMicroarch >= kCpumMicroarch_AMD_15h_Piledriver && g_enmVendor == CPUMCPUVENDOR_AMD)
4314 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 3, "AmdK7DrXAddrMaskN", 0xc0011019 - 1,
4315 false /*fEarlyEndOk*/, false /*fNoIgnMask*/, 0, &i);
4316 else if (uMsr == 0xc0011021 && g_enmVendor == CPUMCPUVENDOR_AMD)
4317 rc = reportMsr_AmdK7InstrCacheCfg(uMsr, uValue);
4318 else if (uMsr == 0xc0011023 && CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch))
4319 rc = reportMsr_AmdFam15hCombUnitCfg(uMsr, uValue);
4320 else if (uMsr == 0xc0011027 && g_enmVendor == CPUMCPUVENDOR_AMD)
4321 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 1, "AmdK7DrXAddrMaskN", 0xc0011027,
4322 false /*fEarlyEndOk*/, false /*fNoIgnMask*/, 0, &i);
4323 else if (uMsr == 0xc001102c && CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch))
4324 rc = reportMsr_AmdFam15hExecUnitCfg(uMsr, uValue);
4325 /* generic handling. */
4326 else
4327 rc = reportMsr_Generic(uMsr, fFlags, uValue);
4328
4329 if (RT_FAILURE(rc))
4330 return rc;
4331
4332 /*
4333 * A little ugly snooping.
4334 */
4335 if (uMsr == 0x000000cd && !(fFlags & VBCPUREPMSR_F_WRITE_ONLY))
4336 g_uMsrIntelP6FsbFrequency = uValue;
4337 }
4338
4339 return VINF_SUCCESS;
4340}
4341
4342
4343/**
4344 * Custom MSR hacking & probing.
4345 *
4346 * Called when the '-d' option is given.
4347 *
4348 * @returns VBox status code.
4349 */
4350static int hackingMsrs(void)
4351{
4352#if 0
4353 vbCpuRepDebug("\nhackingMsrs:\n"); RTStrmFlush(g_pDebugOut); RTThreadSleep(2000);
4354
4355 uint32_t uMsr = 0xc0000081;
4356 vbCpuRepDebug("%#x: msrProberModifyNoChange -> %RTbool\n", uMsr, msrProberModifyNoChange(uMsr));
4357 RTThreadSleep(3000);
4358
4359 vbCpuRepDebug("%#x: msrProberModifyBit 30 -> %d\n", uMsr, msrProberModifyBit(uMsr, 30));
4360 RTThreadSleep(3000);
4361
4362 vbCpuRepDebug("%#x: msrProberModifyZero -> %RTbool\n", uMsr, msrProberModifyZero(uMsr));
4363 RTThreadSleep(3000);
4364
4365 for (uint32_t i = 0; i < 63; i++)
4366 {
4367 vbCpuRepDebug("%#x: bit=%02u -> %d\n", msrProberModifyBit(uMsr, i));
4368 RTThreadSleep(500);
4369 }
4370#else
4371
4372 uint32_t uMsr = 0xc0010010;
4373 uint64_t uValue = 0;
4374 msrProberRead(uMsr, &uValue);
4375 reportMsr_AmdK8SysCfg(uMsr, uValue);
4376#endif
4377 return VINF_SUCCESS;
4378}
4379
4380
4381static int probeMsrs(bool fHacking, const char *pszNameC, const char *pszCpuDesc,
4382 char *pszMsrMask, size_t cbMsrMask)
4383{
4384 /* Initialize the mask. */
4385 if (pszMsrMask && cbMsrMask)
4386 RTStrCopy(pszMsrMask, cbMsrMask, "UINT32_MAX /** @todo */");
4387
4388 /*
4389 * Are MSRs supported by the CPU?
4390 */
4391 if ( !ASMIsValidStdRange(ASMCpuId_EAX(0))
4392 || !(ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_MSR) )
4393 {
4394 vbCpuRepDebug("Skipping MSR probing, CPUID indicates there isn't any MSR support.\n");
4395 return VINF_SUCCESS;
4396 }
4397 if (g_fNoMsrs)
4398 {
4399 vbCpuRepDebug("Skipping MSR probing (--no-msr).\n");
4400 return VINF_SUCCESS;
4401 }
4402
4403 /*
4404 * First try the the support library (also checks if we can really read MSRs).
4405 */
4406 int rc = VbCpuRepMsrProberInitSupDrv(&g_MsrAcc);
4407 if (RT_FAILURE(rc))
4408 {
4409#ifdef VBCR_HAVE_PLATFORM_MSR_PROBER
4410 /* Next try a platform-specific interface. */
4411 rc = VbCpuRepMsrProberInitPlatform(&g_MsrAcc);
4412#endif
4413 if (RT_FAILURE(rc))
4414 {
4415 vbCpuRepDebug("warning: Unable to initialize any MSR access interface (%Rrc), skipping MSR detection.\n", rc);
4416 return VINF_SUCCESS;
4417 }
4418 }
4419
4420 uint64_t uValue;
4421 bool fGp;
4422 rc = g_MsrAcc.pfnMsrProberRead(MSR_IA32_TSC, NIL_RTCPUID, &uValue, &fGp);
4423 if (RT_FAILURE(rc))
4424 {
4425 vbCpuRepDebug("warning: MSR probing not supported by the support driver (%Rrc), skipping MSR detection.\n", rc);
4426 return VINF_SUCCESS;
4427 }
4428 vbCpuRepDebug("MSR_IA32_TSC: %#llx fGp=%RTbool\n", uValue, fGp);
4429 rc = g_MsrAcc.pfnMsrProberRead(0xdeadface, NIL_RTCPUID, &uValue, &fGp);
4430 vbCpuRepDebug("0xdeadface: %#llx fGp=%RTbool rc=%Rrc\n", uValue, fGp, rc);
4431
4432 /*
4433 * Initialize globals we use.
4434 */
4435 uint32_t uEax, uEbx, uEcx, uEdx;
4436 ASMCpuIdExSlow(0, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
4437 if (!ASMIsValidStdRange(uEax))
4438 return RTMsgErrorRc(VERR_NOT_SUPPORTED, "Invalid std CPUID range: %#x\n", uEax);
4439 g_enmVendor = CPUMR3CpuIdDetectVendorEx(uEax, uEbx, uEcx, uEdx);
4440
4441 ASMCpuIdExSlow(1, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
4442 g_enmMicroarch = CPUMR3CpuIdDetermineMicroarchEx(g_enmVendor,
4443 ASMGetCpuFamily(uEax),
4444 ASMGetCpuModel(uEax, g_enmVendor == CPUMCPUVENDOR_INTEL),
4445 ASMGetCpuStepping(uEax));
4446 g_fIntelNetBurst = CPUMMICROARCH_IS_INTEL_NETBURST(g_enmMicroarch);
4447
4448 /*
4449 * Do the probing.
4450 */
4451 if (fHacking)
4452 rc = hackingMsrs();
4453 else
4454 {
4455 /* Determine the MSR mask. */
4456 uint32_t fMsrMask = determineMsrAndMask();
4457 if (fMsrMask == UINT32_MAX)
4458 RTStrCopy(pszMsrMask, cbMsrMask, "UINT32_MAX");
4459 else
4460 RTStrPrintf(pszMsrMask, cbMsrMask, "UINT32_C(%#x)", fMsrMask);
4461
4462 /* Detect MSR. */
4463 VBCPUREPMSR *paMsrs;
4464 uint32_t cMsrs;
4465 rc = findMsrs(&paMsrs, &cMsrs, fMsrMask);
4466 if (RT_FAILURE(rc))
4467 return rc;
4468
4469 /* Probe the MSRs and spit out the database table. */
4470 vbCpuRepPrintf("\n"
4471 "#ifndef CPUM_DB_STANDALONE\n"
4472 "/**\n"
4473 " * MSR ranges for %s.\n"
4474 " */\n"
4475 "static CPUMMSRRANGE const g_aMsrRanges_%s[] = \n{\n",
4476 pszCpuDesc,
4477 pszNameC);
4478 rc = produceMsrReport(paMsrs, cMsrs);
4479 vbCpuRepPrintf("};\n"
4480 "#endif /* !CPUM_DB_STANDALONE */\n"
4481 "\n"
4482 );
4483
4484 RTMemFree(paMsrs);
4485 paMsrs = NULL;
4486 }
4487 if (g_MsrAcc.pfnTerm)
4488 g_MsrAcc.pfnTerm();
4489 RT_ZERO(g_MsrAcc);
4490 return rc;
4491}
4492
4493
4494static int produceCpuIdArray(const char *pszNameC, const char *pszCpuDesc)
4495{
4496 /*
4497 * Collect the data.
4498 */
4499 PCPUMCPUIDLEAF paLeaves;
4500 uint32_t cLeaves;
4501 int rc = CPUMR3CpuIdCollectLeaves(&paLeaves, &cLeaves);
4502 if (RT_FAILURE(rc))
4503 return RTMsgErrorRc(rc, "CPUMR3CollectCpuIdInfo failed: %Rrc\n", rc);
4504
4505 /*
4506 * Dump the array.
4507 */
4508 vbCpuRepPrintf("\n"
4509 "#ifndef CPUM_DB_STANDALONE\n"
4510 "/**\n"
4511 " * CPUID leaves for %s.\n"
4512 " */\n"
4513 "static CPUMCPUIDLEAF const g_aCpuIdLeaves_%s[] = \n{\n",
4514 pszCpuDesc,
4515 pszNameC);
4516 for (uint32_t i = 0; i < cLeaves; i++)
4517 {
4518 vbCpuRepPrintf(" { %#010x, %#010x, ", paLeaves[i].uLeaf, paLeaves[i].uSubLeaf);
4519 if (paLeaves[i].fSubLeafMask == UINT32_MAX)
4520 vbCpuRepPrintf("UINT32_MAX, ");
4521 else
4522 vbCpuRepPrintf("%#010x, ", paLeaves[i].fSubLeafMask);
4523 vbCpuRepPrintf("%#010x, %#010x, %#010x, %#010x, ",
4524 paLeaves[i].uEax, paLeaves[i].uEbx, paLeaves[i].uEcx, paLeaves[i].uEdx);
4525 if (paLeaves[i].fFlags == 0)
4526 vbCpuRepPrintf("0 },\n");
4527 else
4528 {
4529 vbCpuRepPrintf("0");
4530 uint32_t fFlags = paLeaves[i].fFlags;
4531 if (paLeaves[i].fFlags & CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES)
4532 {
4533 vbCpuRepPrintf(" | CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES");
4534 fFlags &= ~CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES;
4535 }
4536 if (paLeaves[i].fFlags & CPUMCPUIDLEAF_F_CONTAINS_APIC_ID)
4537 {
4538 vbCpuRepPrintf(" | CPUMCPUIDLEAF_F_CONTAINS_APIC_ID");
4539 fFlags &= ~CPUMCPUIDLEAF_F_CONTAINS_APIC_ID;
4540 }
4541 if (paLeaves[i].fFlags & CPUMCPUIDLEAF_F_CONTAINS_APIC)
4542 {
4543 vbCpuRepPrintf(" | CPUMCPUIDLEAF_F_CONTAINS_APIC");
4544 fFlags &= ~CPUMCPUIDLEAF_F_CONTAINS_APIC;
4545 }
4546 if (fFlags)
4547 {
4548 RTMemFree(paLeaves);
4549 return RTMsgErrorRc(rc, "Unknown CPUID flags %#x\n", fFlags);
4550 }
4551 vbCpuRepPrintf(" },\n");
4552 }
4553 }
4554 vbCpuRepPrintf("};\n"
4555 "#endif /* !CPUM_DB_STANDALONE */\n"
4556 "\n");
4557 RTMemFree(paLeaves);
4558 return VINF_SUCCESS;
4559}
4560
4561
4562static const char *cpuVendorToString(CPUMCPUVENDOR enmCpuVendor)
4563{
4564 switch (enmCpuVendor)
4565 {
4566 case CPUMCPUVENDOR_INTEL: return "Intel";
4567 case CPUMCPUVENDOR_AMD: return "AMD";
4568 case CPUMCPUVENDOR_VIA: return "VIA";
4569 case CPUMCPUVENDOR_CYRIX: return "Cyrix";
4570 case CPUMCPUVENDOR_SHANGHAI: return "Shanghai";
4571 case CPUMCPUVENDOR_INVALID:
4572 case CPUMCPUVENDOR_UNKNOWN:
4573 case CPUMCPUVENDOR_32BIT_HACK:
4574 break;
4575 }
4576 return "invalid-cpu-vendor";
4577}
4578
4579
4580/**
4581 * Takes a shot a the bus frequency name (last part).
4582 *
4583 * @returns Name suffix.
4584 */
4585static const char *vbCpuRepGuessScalableBusFrequencyName(void)
4586{
4587 if (CPUMMICROARCH_IS_INTEL_CORE7(g_enmMicroarch))
4588 return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge ? "100MHZ" : "133MHZ";
4589
4590 if (g_uMsrIntelP6FsbFrequency != UINT64_MAX)
4591 switch (g_uMsrIntelP6FsbFrequency & 0x7)
4592 {
4593 case 5: return "100MHZ";
4594 case 1: return "133MHZ";
4595 case 3: return "167MHZ";
4596 case 2: return "200MHZ";
4597 case 0: return "267MHZ";
4598 case 4: return "333MHZ";
4599 case 6: return "400MHZ";
4600 }
4601
4602 return "UNKNOWN";
4603}
4604
4605
4606static int produceCpuReport(void)
4607{
4608 /*
4609 * Figure the cpu vendor.
4610 */
4611 if (!ASMHasCpuId())
4612 return RTMsgErrorRc(VERR_NOT_SUPPORTED, "No CPUID support.\n");
4613 uint32_t uEax, uEbx, uEcx, uEdx;
4614 ASMCpuIdExSlow(0, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
4615 if (!ASMIsValidStdRange(uEax))
4616 return RTMsgErrorRc(VERR_NOT_SUPPORTED, "Invalid std CPUID range: %#x\n", uEax);
4617
4618 CPUMCPUVENDOR enmVendor = CPUMR3CpuIdDetectVendorEx(uEax, uEbx, uEcx, uEdx);
4619 if (enmVendor == CPUMCPUVENDOR_UNKNOWN)
4620 return RTMsgErrorRc(VERR_NOT_IMPLEMENTED, "Unknown CPU vendor: %.4s%.4s%.4s\n", &uEbx, &uEdx, &uEcx);
4621 vbCpuRepDebug("CPU Vendor: %s - %.4s%.4s%.4s\n", CPUMR3CpuVendorName(enmVendor), &uEbx, &uEdx, &uEcx);
4622
4623 /*
4624 * Determine the micro arch.
4625 */
4626 ASMCpuIdExSlow(1, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
4627 CPUMMICROARCH enmMicroarch = CPUMR3CpuIdDetermineMicroarchEx(enmVendor,
4628 ASMGetCpuFamily(uEax),
4629 ASMGetCpuModel(uEax, enmVendor == CPUMCPUVENDOR_INTEL),
4630 ASMGetCpuStepping(uEax));
4631
4632 /*
4633 * Generate a name.
4634 */
4635 char szName[16*3+1];
4636 char szNameC[16*3+1];
4637 char szNameRaw[16*3+1];
4638 char *pszName = szName;
4639 char *pszCpuDesc = (char *)"";
4640
4641 ASMCpuIdExSlow(0x80000000, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
4642 if (ASMIsValidExtRange(uEax) && uEax >= UINT32_C(0x80000004))
4643 {
4644 /* Get the raw name and strip leading spaces. */
4645 ASMCpuIdExSlow(0x80000002, 0, 0, 0, &szNameRaw[0 + 0], &szNameRaw[4 + 0], &szNameRaw[8 + 0], &szNameRaw[12 + 0]);
4646 ASMCpuIdExSlow(0x80000003, 0, 0, 0, &szNameRaw[0 + 16], &szNameRaw[4 + 16], &szNameRaw[8 + 16], &szNameRaw[12 + 16]);
4647 ASMCpuIdExSlow(0x80000004, 0, 0, 0, &szNameRaw[0 + 32], &szNameRaw[4 + 32], &szNameRaw[8 + 32], &szNameRaw[12 + 32]);
4648 szNameRaw[48] = '\0';
4649 pszCpuDesc = RTStrStrip(szNameRaw);
4650 vbCpuRepDebug("Name2: %s\n", pszCpuDesc);
4651
4652 /* Reduce the name. */
4653 pszName = strcpy(szName, pszCpuDesc);
4654
4655 static const char * const s_apszSuffixes[] =
4656 {
4657 "CPU @",
4658 };
4659 for (uint32_t i = 0; i < RT_ELEMENTS(s_apszSuffixes); i++)
4660 {
4661 char *pszHit = strstr(pszName, s_apszSuffixes[i]);
4662 if (pszHit)
4663 RT_BZERO(pszHit, strlen(pszHit));
4664 }
4665
4666 static const char * const s_apszWords[] =
4667 {
4668 "(TM)", "(tm)", "(R)", "(r)", "Processor", "CPU", "@",
4669 };
4670 for (uint32_t i = 0; i < RT_ELEMENTS(s_apszWords); i++)
4671 {
4672 const char *pszWord = s_apszWords[i];
4673 size_t cchWord = strlen(pszWord);
4674 char *pszHit;
4675 while ((pszHit = strstr(pszName, pszWord)) != NULL)
4676 memset(pszHit, ' ', cchWord);
4677 }
4678
4679 RTStrStripR(pszName);
4680 for (char *psz = pszName; *psz; psz++)
4681 if (RT_C_IS_BLANK(*psz))
4682 {
4683 size_t cchBlanks = 1;
4684 while (RT_C_IS_BLANK(psz[cchBlanks]))
4685 cchBlanks++;
4686 *psz = ' ';
4687 if (cchBlanks > 1)
4688 memmove(psz + 1, psz + cchBlanks, strlen(psz + cchBlanks) + 1);
4689 }
4690 pszName = RTStrStripL(pszName);
4691 vbCpuRepDebug("Name: %s\n", pszName);
4692
4693 /* Make it C/C++ acceptable. */
4694 strcpy(szNameC, pszName);
4695 unsigned offDst = 0;
4696 for (unsigned offSrc = 0; ; offSrc++)
4697 {
4698 char ch = szNameC[offSrc];
4699 if (!RT_C_IS_ALNUM(ch) && ch != '_' && ch != '\0')
4700 ch = '_';
4701 if (ch == '_' && offDst > 0 && szNameC[offDst - 1] == '_')
4702 offDst--;
4703 szNameC[offDst++] = ch;
4704 if (!ch)
4705 break;
4706 }
4707 while (offDst > 1 && szNameC[offDst - 1] == '_')
4708 szNameC[--offDst] = '\0';
4709
4710 vbCpuRepDebug("NameC: %s\n", szNameC);
4711 }
4712 else
4713 {
4714 ASMCpuIdExSlow(1, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
4715 RTStrPrintf(szNameC, sizeof(szNameC), "%s_%u_%u_%u", cpuVendorToString(enmVendor), ASMGetCpuFamily(uEax),
4716 ASMGetCpuModel(uEax, enmVendor == CPUMCPUVENDOR_INTEL), ASMGetCpuStepping(uEax));
4717 pszCpuDesc = pszName = szNameC;
4718 vbCpuRepDebug("Name/NameC: %s\n", szNameC);
4719 }
4720
4721 /*
4722 * Print a file header, if we're not outputting to stdout (assumption being
4723 * that stdout is used while hacking the reporter and too much output is
4724 * unwanted).
4725 */
4726 if (g_pReportOut)
4727 {
4728 RTTIMESPEC Now;
4729 char szNow[64];
4730 RTTimeSpecToString(RTTimeNow(&Now), szNow, sizeof(szNow));
4731 char *pchDot = strchr(szNow, '.');
4732 if (pchDot)
4733 strcpy(pchDot, "Z");
4734
4735 vbCpuRepPrintf("/* $" "Id" "$ */\n"
4736 "/** @file\n"
4737 " * CPU database entry \"%s\".\n"
4738 " * Generated at %s by VBoxCpuReport v%sr%s on %s.%s.\n"
4739 " */\n"
4740 "\n"
4741 "/*\n"
4742 " * Copyright (C) 2013-2017 Oracle Corporation\n"
4743 " *\n"
4744 " * This file is part of VirtualBox Open Source Edition (OSE), as\n"
4745 " * available from http://www.virtualbox.org. This file is free software;\n"
4746 " * you can redistribute it and/or modify it under the terms of the GNU\n"
4747 " * General Public License (GPL) as published by the Free Software\n"
4748 " * Foundation, in version 2 as it comes in the \"COPYING\" file of the\n"
4749 " * VirtualBox OSE distribution. VirtualBox OSE is distributed in the\n"
4750 " * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.\n"
4751 " */\n"
4752 "\n"
4753 "#ifndef VBOX_CPUDB_%s_h\n"
4754 "#define VBOX_CPUDB_%s_h\n"
4755 "\n",
4756 pszName,
4757 szNow, RTBldCfgVersion(), RTBldCfgRevisionStr(), RTBldCfgTarget(), RTBldCfgTargetArch(),
4758 szNameC, szNameC);
4759 }
4760
4761 /*
4762 * Extract CPUID based data.
4763 */
4764 int rc = produceCpuIdArray(szNameC, pszCpuDesc);
4765 if (RT_FAILURE(rc))
4766 return rc;
4767
4768 CPUMUNKNOWNCPUID enmUnknownMethod;
4769 CPUMCPUID DefUnknown;
4770 rc = CPUMR3CpuIdDetectUnknownLeafMethod(&enmUnknownMethod, &DefUnknown);
4771 if (RT_FAILURE(rc))
4772 return RTMsgErrorRc(rc, "CPUMR3DetectCpuIdUnknownMethod failed: %Rrc\n", rc);
4773 vbCpuRepDebug("enmUnknownMethod=%s\n", CPUMR3CpuIdUnknownLeafMethodName(enmUnknownMethod));
4774
4775 /*
4776 * Do the MSRs, if we can.
4777 */
4778 char szMsrMask[64];
4779 probeMsrs(false /*fHacking*/, szNameC, pszCpuDesc, szMsrMask, sizeof(szMsrMask));
4780
4781 /*
4782 * Emit the CPUMDBENTRY record.
4783 */
4784 ASMCpuIdExSlow(1, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
4785 vbCpuRepPrintf("\n"
4786 "/**\n"
4787 " * Database entry for %s.\n"
4788 " */\n"
4789 "static CPUMDBENTRY const g_Entry_%s = \n"
4790 "{\n"
4791 " /*.pszName = */ \"%s\",\n"
4792 " /*.pszFullName = */ \"%s\",\n"
4793 " /*.enmVendor = */ CPUMCPUVENDOR_%s,\n"
4794 " /*.uFamily = */ %u,\n"
4795 " /*.uModel = */ %u,\n"
4796 " /*.uStepping = */ %u,\n"
4797 " /*.enmMicroarch = */ kCpumMicroarch_%s,\n"
4798 " /*.uScalableBusFreq = */ CPUM_SBUSFREQ_%s,\n"
4799 " /*.fFlags = */ 0,\n"
4800 " /*.cMaxPhysAddrWidth= */ %u,\n"
4801 " /*.fMxCsrMask = */ %#010x,\n"
4802 " /*.paCpuIdLeaves = */ NULL_ALONE(g_aCpuIdLeaves_%s),\n"
4803 " /*.cCpuIdLeaves = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_%s)),\n"
4804 " /*.enmUnknownCpuId = */ CPUMUNKNOWNCPUID_%s,\n"
4805 " /*.DefUnknownCpuId = */ { %#010x, %#010x, %#010x, %#010x },\n"
4806 " /*.fMsrMask = */ %s,\n"
4807 " /*.cMsrRanges = */ ZERO_ALONE(RT_ELEMENTS(g_aMsrRanges_%s)),\n"
4808 " /*.paMsrRanges = */ NULL_ALONE(g_aMsrRanges_%s),\n"
4809 "};\n"
4810 "\n"
4811 "#endif /* !VBOX_CPUDB_%s_h */\n"
4812 "\n",
4813 pszCpuDesc,
4814 szNameC,
4815 pszName,
4816 pszCpuDesc,
4817 CPUMR3CpuVendorName(enmVendor),
4818 ASMGetCpuFamily(uEax),
4819 ASMGetCpuModel(uEax, enmVendor == CPUMCPUVENDOR_INTEL),
4820 ASMGetCpuStepping(uEax),
4821 CPUMR3MicroarchName(enmMicroarch),
4822 vbCpuRepGuessScalableBusFrequencyName(),
4823 vbCpuRepGetPhysAddrWidth(),
4824 CPUMR3DeterminHostMxCsrMask(),
4825 szNameC,
4826 szNameC,
4827 CPUMR3CpuIdUnknownLeafMethodName(enmUnknownMethod),
4828 DefUnknown.uEax,
4829 DefUnknown.uEbx,
4830 DefUnknown.uEcx,
4831 DefUnknown.uEdx,
4832 szMsrMask,
4833 szNameC,
4834 szNameC,
4835 szNameC
4836 );
4837
4838 return VINF_SUCCESS;
4839}
4840
4841
4842int main(int argc, char **argv)
4843{
4844 int rc = RTR3InitExe(argc, &argv, 0 /*fFlags*/);
4845 if (RT_FAILURE(rc))
4846 return RTMsgInitFailure(rc);
4847
4848 /*
4849 * Argument parsing?
4850 */
4851 static const RTGETOPTDEF s_aOptions[] =
4852 {
4853 { "--msrs-only", 'm', RTGETOPT_REQ_NOTHING },
4854 { "--msrs-dev", 'd', RTGETOPT_REQ_NOTHING },
4855 { "--no-msrs", 'n', RTGETOPT_REQ_NOTHING },
4856 { "--output", 'o', RTGETOPT_REQ_STRING },
4857 { "--log", 'l', RTGETOPT_REQ_STRING },
4858 };
4859 RTGETOPTSTATE State;
4860 RTGetOptInit(&State, argc, argv, &s_aOptions[0], RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
4861
4862 enum
4863 {
4864 kCpuReportOp_Normal,
4865 kCpuReportOp_MsrsOnly,
4866 kCpuReportOp_MsrsHacking
4867 } enmOp = kCpuReportOp_Normal;
4868 g_pReportOut = NULL;
4869 g_pDebugOut = NULL;
4870 const char *pszOutput = NULL;
4871 const char *pszDebugOut = NULL;
4872
4873 int iOpt;
4874 RTGETOPTUNION ValueUnion;
4875 while ((iOpt = RTGetOpt(&State, &ValueUnion)) != 0)
4876 {
4877 switch (iOpt)
4878 {
4879 case 'm':
4880 enmOp = kCpuReportOp_MsrsOnly;
4881 break;
4882
4883 case 'd':
4884 enmOp = kCpuReportOp_MsrsHacking;
4885 break;
4886
4887 case 'n':
4888 g_fNoMsrs = true;
4889 break;
4890
4891 case 'o':
4892 pszOutput = ValueUnion.psz;
4893 break;
4894
4895 case 'l':
4896 pszDebugOut = ValueUnion.psz;
4897 break;
4898
4899 case 'h':
4900 RTPrintf("Usage: VBoxCpuReport [-m|--msrs-only] [-d|--msrs-dev] [-n|--no-msrs] [-h|--help] [-V|--version] [-o filename.h] [-l debug.log]\n");
4901 RTPrintf("Internal tool for gathering information to the VMM CPU database.\n");
4902 return RTEXITCODE_SUCCESS;
4903 case 'V':
4904 RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr());
4905 return RTEXITCODE_SUCCESS;
4906 default:
4907 return RTGetOptPrintError(iOpt, &ValueUnion);
4908 }
4909 }
4910
4911 /*
4912 * Open the alternative debug log stream.
4913 */
4914 if (pszDebugOut)
4915 {
4916 if (RTFileExists(pszDebugOut) && !RTSymlinkExists(pszDebugOut))
4917 {
4918 char szOld[RTPATH_MAX];
4919 rc = RTStrCopy(szOld, sizeof(szOld), pszDebugOut);
4920 if (RT_SUCCESS(rc))
4921 rc = RTStrCat(szOld, sizeof(szOld), ".old");
4922 if (RT_SUCCESS(rc))
4923 RTFileRename(pszDebugOut, szOld, RTFILEMOVE_FLAGS_REPLACE);
4924 }
4925 rc = RTStrmOpen(pszDebugOut, "w", &g_pDebugOut);
4926 if (RT_FAILURE(rc))
4927 {
4928 RTMsgError("Error opening '%s': %Rrc", pszDebugOut, rc);
4929 g_pDebugOut = NULL;
4930 }
4931 }
4932
4933 /*
4934 * Do the requested job.
4935 */
4936 rc = VERR_INTERNAL_ERROR;
4937 switch (enmOp)
4938 {
4939 case kCpuReportOp_Normal:
4940 /* switch output file. */
4941 if (pszOutput)
4942 {
4943 if (RTFileExists(pszOutput) && !RTSymlinkExists(pszOutput))
4944 {
4945 char szOld[RTPATH_MAX];
4946 rc = RTStrCopy(szOld, sizeof(szOld), pszOutput);
4947 if (RT_SUCCESS(rc))
4948 rc = RTStrCat(szOld, sizeof(szOld), ".old");
4949 if (RT_SUCCESS(rc))
4950 RTFileRename(pszOutput, szOld, RTFILEMOVE_FLAGS_REPLACE);
4951 }
4952 rc = RTStrmOpen(pszOutput, "w", &g_pReportOut);
4953 if (RT_FAILURE(rc))
4954 {
4955 RTMsgError("Error opening '%s': %Rrc", pszOutput, rc);
4956 break;
4957 }
4958 }
4959 rc = produceCpuReport();
4960 break;
4961 case kCpuReportOp_MsrsOnly:
4962 case kCpuReportOp_MsrsHacking:
4963 rc = probeMsrs(enmOp == kCpuReportOp_MsrsHacking, NULL, NULL, NULL, 0);
4964 break;
4965 }
4966
4967 /*
4968 * Close the output files.
4969 */
4970 if (g_pReportOut)
4971 {
4972 RTStrmClose(g_pReportOut);
4973 g_pReportOut = NULL;
4974 }
4975
4976 if (g_pDebugOut)
4977 {
4978 RTStrmClose(g_pDebugOut);
4979 g_pDebugOut = NULL;
4980 }
4981
4982 return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
4983}
4984
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette