VirtualBox

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

Last change on this file since 49993 was 49993, checked in by vboxsync, 11 years ago

CPUM: VIA MSR mappings (rough cut).

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

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