VirtualBox

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

Last change on this file since 60435 was 58676, checked in by vboxsync, 9 years ago

Hacked up to survive on a PIII-S.

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

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