VirtualBox

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

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

VMM: scm cleanups

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