VirtualBox

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

Last change on this file since 69582 was 69582, checked in by vboxsync, 7 years ago

VBoxCpuReport: Made MSR probing interface more modular, added Linux-specific /dev/msr backend. Further work coming.

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