VirtualBox

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

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

CPUM,DevEFI: Bus vs cpu clock ratio fixes for more recent CPUs. Older CPUs (<=Core2) still need some more work.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 213.8 KB
Line 
1/* $Id: VBoxCpuReport.cpp 50584 2014-02-25 16:06:26Z 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.215389.xyz. 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 g_enmMicroarch >= kCpumMicroarch_Intel_Core7_First ? "IA32_PLATFORM_INFO" : "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 0x000000ce: return CPUMMICROARCH_IS_INTEL_CORE7(g_enmMicroarch)
1846 ? (g_enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge
1847 ? "IntelPlatformInfo100MHz" : "IntelPlatformInfo133MHz")
1848 : NULL;
1849
1850 case 0x000000e2: return "IntelPkgCStConfigControl";
1851 case 0x000000e3: return "IntelCore2SmmCStMiscInfo";
1852 case 0x000000e4: return "IntelPmgIoCaptureBase";
1853 case 0x000000e7: return "Ia32MPerf";
1854 case 0x000000e8: return "Ia32APerf";
1855 case 0x000000ee: return "IntelCore1ExtConfig";
1856 case 0x000000fe: *pfTakesValue = true; return "Ia32MtrrCap";
1857 case 0x00000119: *pfTakesValue = true; return "IntelBblCrCtl";
1858 case 0x0000011e: *pfTakesValue = true; return "IntelBblCrCtl3";
1859
1860 case 0x00000130: return g_enmMicroarch == kCpumMicroarch_Intel_Core7_Westmere
1861 || g_enmMicroarch == kCpumMicroarch_Intel_Core7_Nehalem
1862 ? "IntelCpuId1FeatureMaskEcdx" : NULL;
1863 case 0x00000131: return g_enmMicroarch == kCpumMicroarch_Intel_Core7_Westmere
1864 || g_enmMicroarch == kCpumMicroarch_Intel_Core7_Nehalem
1865 ? "IntelCpuId80000001FeatureMaskEcdx" : NULL;
1866 case 0x00000132: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge
1867 ? "IntelCpuId1FeatureMaskEax" : NULL;
1868 case 0x00000133: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge
1869 ? "IntelCpuId1FeatureMaskEcdx" : NULL;
1870 case 0x00000134: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge
1871 ? "IntelCpuId80000001FeatureMaskEcdx" : NULL;
1872 case 0x0000013c: return "IntelI7SandyAesNiCtl";
1873 case 0x0000015f: return "IntelCore1DtsCalControl";
1874 case 0x00000174: return "Ia32SysEnterCs";
1875 case 0x00000175: return "Ia32SysEnterEsp";
1876 case 0x00000176: return "Ia32SysEnterEip";
1877 case 0x00000179: *pfTakesValue = true; return "Ia32McgCap";
1878 case 0x0000017a: return "Ia32McgStatus";
1879 case 0x0000017b: return "Ia32McgCtl";
1880 case 0x0000017f: return "IntelI7SandyErrorControl"; /* SandyBridge. */
1881 case 0x00000186: return "Ia32PerfEvtSelN";
1882 case 0x00000187: return "Ia32PerfEvtSelN";
1883 case 0x00000193: return /*g_fIntelNetBurst ? NULL :*/ NULL /* Core2_Penryn. */;
1884 case 0x00000194:
1885 if (g_fIntelNetBurst)
1886 break;
1887 *pfTakesValue = true;
1888 return CPUMMICROARCH_IS_INTEL_CORE7(g_enmMicroarch) && g_enmMicroarch >= kCpumMicroarch_Intel_Core7_SandyBridge
1889 ? "IntelFlexRatio100MHz" : "IntelFlexRatio133MHz";
1890 case 0x00000198: *pfTakesValue = true; return "Ia32PerfStatus";
1891 case 0x00000199: *pfTakesValue = true; return "Ia32PerfCtl";
1892 case 0x0000019a: *pfTakesValue = true; return "Ia32ClockModulation";
1893 case 0x0000019b: *pfTakesValue = true; return "Ia32ThermInterrupt";
1894 case 0x0000019c: *pfTakesValue = true; return "Ia32ThermStatus";
1895 case 0x0000019d: *pfTakesValue = true; return "Ia32Therm2Ctl";
1896 case 0x000001a0: *pfTakesValue = true; return "Ia32MiscEnable";
1897 case 0x000001a2: *pfTakesValue = true; return "IntelI7TemperatureTarget";
1898 case 0x000001a6: return "IntelI7MsrOffCoreResponseN";
1899 case 0x000001a7: return "IntelI7MsrOffCoreResponseN";
1900 case 0x000001aa: return CPUMMICROARCH_IS_INTEL_CORE7(g_enmMicroarch) ? "IntelI7MiscPwrMgmt" : NULL /*"P6PicSensCfg"*/;
1901 case 0x000001ad: *pfTakesValue = true; return "IntelI7TurboRatioLimit"; /* SandyBridge+, Silvermount+ */
1902 case 0x000001c8: return g_enmMicroarch >= kCpumMicroarch_Intel_Core7_Nehalem ? "IntelI7LbrSelect" : NULL;
1903 case 0x000001c9: return g_enmMicroarch >= kCpumMicroarch_Intel_Core_Yonah
1904 && g_enmMicroarch <= kCpumMicroarch_Intel_P6_Core_Atom_End
1905 ? "IntelLastBranchTos" : NULL /* Pentium M Dothan seems to have something else here. */;
1906 case 0x000001d7: return g_fIntelNetBurst ? "P6LastIntFromIp" : NULL;
1907 case 0x000001d8: return g_fIntelNetBurst ? "P6LastIntToIp" : NULL;
1908 case 0x000001d9: return "Ia32DebugCtl";
1909 case 0x000001da: return g_fIntelNetBurst ? "IntelLastBranchTos" : NULL;
1910 case 0x000001db: return g_fIntelNetBurst ? "IntelLastBranchFromToN" : "P6LastBranchFromIp";
1911 case 0x000001dc: return g_fIntelNetBurst ? "IntelLastBranchFromToN" : "P6LastBranchToIp";
1912 case 0x000001dd: return g_fIntelNetBurst ? "IntelLastBranchFromToN" : "P6LastIntFromIp";
1913 case 0x000001de: return g_fIntelNetBurst ? "IntelLastBranchFromToN" : "P6LastIntToIp";
1914 case 0x000001f0: return "IntelI7VirtualLegacyWireCap"; /* SandyBridge. */
1915 case 0x000001f2: return "Ia32SmrrPhysBase";
1916 case 0x000001f3: return "Ia32SmrrPhysMask";
1917 case 0x000001f8: return "Ia32PlatformDcaCap";
1918 case 0x000001f9: return "Ia32CpuDcaCap";
1919 case 0x000001fa: return "Ia32Dca0Cap";
1920 case 0x000001fc: return "IntelI7PowerCtl";
1921
1922 case 0x00000200: case 0x00000202: case 0x00000204: case 0x00000206:
1923 case 0x00000208: case 0x0000020a: case 0x0000020c: case 0x0000020e:
1924 case 0x00000210: case 0x00000212: case 0x00000214: case 0x00000216:
1925 case 0x00000218: case 0x0000021a: case 0x0000021c: case 0x0000021e:
1926 return "Ia32MtrrPhysBaseN";
1927 case 0x00000201: case 0x00000203: case 0x00000205: case 0x00000207:
1928 case 0x00000209: case 0x0000020b: case 0x0000020d: case 0x0000020f:
1929 case 0x00000211: case 0x00000213: case 0x00000215: case 0x00000217:
1930 case 0x00000219: case 0x0000021b: case 0x0000021d: case 0x0000021f:
1931 return "Ia32MtrrPhysMaskN";
1932 case 0x00000250:
1933 case 0x00000258: case 0x00000259:
1934 case 0x00000268: case 0x00000269: case 0x0000026a: case 0x0000026b:
1935 case 0x0000026c: case 0x0000026d: case 0x0000026e: case 0x0000026f:
1936 return "Ia32MtrrFixed";
1937 case 0x00000277: *pfTakesValue = true; return "Ia32Pat";
1938
1939 case 0x00000280: case 0x00000281: case 0x00000282: case 0x00000283:
1940 case 0x00000284: case 0x00000285: case 0x00000286: case 0x00000287:
1941 case 0x00000288: case 0x00000289: case 0x0000028a: case 0x0000028b:
1942 case 0x0000028c: case 0x0000028d: case 0x0000028e: case 0x0000028f:
1943 case 0x00000290: case 0x00000291: case 0x00000292: case 0x00000293:
1944 case 0x00000294: case 0x00000295: //case 0x00000296: case 0x00000297:
1945 //case 0x00000298: case 0x00000299: case 0x0000029a: case 0x0000029b:
1946 //case 0x0000029c: case 0x0000029d: case 0x0000029e: case 0x0000029f:
1947 return "Ia32McNCtl2";
1948
1949 case 0x000002ff: return "Ia32MtrrDefType";
1950 //case 0x00000305: return g_fIntelNetBurst ? TODO : NULL;
1951 case 0x00000309: return g_fIntelNetBurst ? NULL /** @todo P4 */ : "Ia32FixedCtrN";
1952 case 0x0000030a: return g_fIntelNetBurst ? NULL /** @todo P4 */ : "Ia32FixedCtrN";
1953 case 0x0000030b: return g_fIntelNetBurst ? NULL /** @todo P4 */ : "Ia32FixedCtrN";
1954 case 0x00000345: *pfTakesValue = true; return "Ia32PerfCapabilities";
1955 /* Note! Lots of P4 MSR 0x00000360..0x00000371. */
1956 case 0x0000038d: return "Ia32FixedCtrCtrl";
1957 case 0x0000038e: *pfTakesValue = true; return "Ia32PerfGlobalStatus";
1958 case 0x0000038f: return "Ia32PerfGlobalCtrl";
1959 case 0x00000390: return "Ia32PerfGlobalOvfCtrl";
1960 case 0x00000391: return "IntelI7UncPerfGlobalCtrl"; /* S,H,X */
1961 case 0x00000392: return "IntelI7UncPerfGlobalStatus"; /* S,H,X */
1962 case 0x00000393: return "IntelI7UncPerfGlobalOvfCtrl"; /* X. ASSUMING this is the same on sandybridge and later. */
1963 case 0x00000394: return g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "IntelI7UncPerfFixedCtr" /* X */ : "IntelI7UncPerfFixedCtrCtrl"; /* >= S,H */
1964 case 0x00000395: return g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "IntelI7UncPerfFixedCtrCtrl" /* X*/ : "IntelI7UncPerfFixedCtr"; /* >= S,H */
1965 case 0x00000396: return g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "IntelI7UncAddrOpcodeMatch" /* X */ : "IntelI7UncCBoxConfig"; /* >= S,H */
1966 case 0x0000039c: return "IntelI7SandyPebsNumAlt";
1967 /* Note! Lots of P4 MSR 0x000003a0..0x000003e1. */
1968 case 0x000003b0: return g_fIntelNetBurst ? NULL : g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "IntelI7UncPmcN" /* X */ : "IntelI7UncArbPerfCtrN"; /* >= S,H */
1969 case 0x000003b1: return g_fIntelNetBurst ? NULL : g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "IntelI7UncPmcN" /* X */ : "IntelI7UncArbPerfCtrN"; /* >= S,H */
1970 case 0x000003b2: return g_fIntelNetBurst ? NULL : g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "IntelI7UncPmcN" /* X */ : "IntelI7UncArbPerfEvtSelN"; /* >= S,H */
1971 case 0x000003b3: return g_fIntelNetBurst ? NULL : g_enmMicroarch < kCpumMicroarch_Intel_Core7_SandyBridge ? "IntelI7UncPmcN" /* X */ : "IntelI7UncArbPerfEvtSelN"; /* >= S,H */
1972 case 0x000003b4: case 0x000003b5: case 0x000003b6: case 0x000003b7:
1973 return g_fIntelNetBurst ? NULL : "IntelI7UncPmcN";
1974 case 0x000003c0: case 0x000003c1: case 0x000003c2: case 0x000003c3:
1975 case 0x000003c4: case 0x000003c5: case 0x000003c6: case 0x000003c7:
1976 return g_fIntelNetBurst ? NULL : "IntelI7UncPerfEvtSelN";
1977 case 0x000003f1: return "Ia32PebsEnable";
1978 case 0x000003f6: return g_fIntelNetBurst ? NULL /*??*/ : "IntelI7PebsLdLat";
1979 case 0x000003f8: return g_fIntelNetBurst ? NULL : "IntelI7PkgCnResidencyN";
1980 case 0x000003f9: return "IntelI7PkgCnResidencyN";
1981 case 0x000003fa: return "IntelI7PkgCnResidencyN";
1982 case 0x000003fc: return "IntelI7CoreCnResidencyN";
1983 case 0x000003fd: return "IntelI7CoreCnResidencyN";
1984 case 0x000003fe: return "IntelI7CoreCnResidencyN";
1985
1986 case 0x00000478: return g_enmMicroarch == kCpumMicroarch_Intel_Core2_Penryn ? "IntelCpuId1FeatureMaskEcdx" : NULL;
1987 case 0x00000480: *pfTakesValue = true; return "Ia32VmxBase";
1988 case 0x00000481: *pfTakesValue = true; return "Ia32VmxPinbasedCtls";
1989 case 0x00000482: *pfTakesValue = true; return "Ia32VmxProcbasedCtls";
1990 case 0x00000483: *pfTakesValue = true; return "Ia32VmxExitCtls";
1991 case 0x00000484: *pfTakesValue = true; return "Ia32VmxEntryCtls";
1992 case 0x00000485: *pfTakesValue = true; return "Ia32VmxMisc";
1993 case 0x00000486: *pfTakesValue = true; return "Ia32VmxCr0Fixed0";
1994 case 0x00000487: *pfTakesValue = true; return "Ia32VmxCr0Fixed1";
1995 case 0x00000488: *pfTakesValue = true; return "Ia32VmxCr4Fixed0";
1996 case 0x00000489: *pfTakesValue = true; return "Ia32VmxCr4Fixed1";
1997 case 0x0000048a: *pfTakesValue = true; return "Ia32VmxVmcsEnum";
1998 case 0x0000048b: *pfTakesValue = true; return "Ia32VmxProcBasedCtls2";
1999 case 0x0000048c: *pfTakesValue = true; return "Ia32VmxEptVpidCap";
2000 case 0x0000048d: *pfTakesValue = true; return "Ia32VmxTruePinbasedCtls";
2001 case 0x0000048e: *pfTakesValue = true; return "Ia32VmxTrueProcbasedCtls";
2002 case 0x0000048f: *pfTakesValue = true; return "Ia32VmxTrueExitCtls";
2003 case 0x00000490: *pfTakesValue = true; return "Ia32VmxTrueEntryCtls";
2004
2005 case 0x000004c1:
2006 case 0x000004c2:
2007 case 0x000004c3:
2008 case 0x000004c4:
2009 case 0x000004c5:
2010 case 0x000004c6:
2011 case 0x000004c7:
2012 case 0x000004c8:
2013 return "Ia32PmcN";
2014
2015 case 0x000005a0: return "IntelCore2PeciControl"; /* Core2_Penryn. */
2016
2017 case 0x00000600: return "Ia32DsArea";
2018 case 0x00000601: return "IntelI7SandyVrCurrentConfig";
2019 case 0x00000603: return "IntelI7SandyVrMiscConfig";
2020 case 0x00000606: return "IntelI7SandyRaplPowerUnit";
2021 case 0x0000060a: return "IntelI7SandyPkgCnIrtlN";
2022 case 0x0000060b: return "IntelI7SandyPkgCnIrtlN";
2023 case 0x0000060c: return "IntelI7SandyPkgCnIrtlN";
2024 case 0x0000060d: return "IntelI7SandyPkgC2Residency";
2025
2026 case 0x00000610: return "IntelI7RaplPkgPowerLimit";
2027 case 0x00000611: return "IntelI7RaplPkgEnergyStatus";
2028 case 0x00000613: return "IntelI7RaplPkgPerfStatus";
2029 case 0x00000614: return "IntelI7RaplPkgPowerInfo";
2030 case 0x00000618: return "IntelI7RaplDramPowerLimit";
2031 case 0x00000619: return "IntelI7RaplDramEnergyStatus";
2032 case 0x0000061b: return "IntelI7RaplDramPerfStatus";
2033 case 0x0000061c: return "IntelI7RaplDramPowerInfo";
2034 case 0x00000638: return "IntelI7RaplPp0PowerLimit";
2035 case 0x00000639: return "IntelI7RaplPp0EnergyStatus";
2036 case 0x0000063a: return "IntelI7RaplPp0Policy";
2037 case 0x0000063b: return "IntelI7RaplPp0PerfStatus";
2038 case 0x00000640: return "IntelI7RaplPp1PowerLimit";
2039 case 0x00000641: return "IntelI7RaplPp1EnergyStatus";
2040 case 0x00000642: return "IntelI7RaplPp1Policy";
2041 case 0x00000648: return "IntelI7IvyConfigTdpNominal";
2042 case 0x00000649: return "IntelI7IvyConfigTdpLevel1";
2043 case 0x0000064a: return "IntelI7IvyConfigTdpLevel2";
2044 case 0x0000064b: return "IntelI7IvyConfigTdpControl";
2045 case 0x0000064c: return "IntelI7IvyTurboActivationRatio";
2046
2047 case 0x00000680: case 0x00000681: case 0x00000682: case 0x00000683:
2048 case 0x00000684: case 0x00000685: case 0x00000686: case 0x00000687:
2049 case 0x00000688: case 0x00000689: case 0x0000068a: case 0x0000068b:
2050 case 0x0000068c: case 0x0000068d: case 0x0000068e: case 0x0000068f:
2051 //case 0x00000690: case 0x00000691: case 0x00000692: case 0x00000693:
2052 //case 0x00000694: case 0x00000695: case 0x00000696: case 0x00000697:
2053 //case 0x00000698: case 0x00000699: case 0x0000069a: case 0x0000069b:
2054 //case 0x0000069c: case 0x0000069d: case 0x0000069e: case 0x0000069f:
2055 return "IntelLastBranchFromN";
2056 case 0x000006c0: case 0x000006c1: case 0x000006c2: case 0x000006c3:
2057 case 0x000006c4: case 0x000006c5: case 0x000006c6: case 0x000006c7:
2058 case 0x000006c8: case 0x000006c9: case 0x000006ca: case 0x000006cb:
2059 case 0x000006cc: case 0x000006cd: case 0x000006ce: case 0x000006cf:
2060 //case 0x000006d0: case 0x000006d1: case 0x000006d2: case 0x000006d3:
2061 //case 0x000006d4: case 0x000006d5: case 0x000006d6: case 0x000006d7:
2062 //case 0x000006d8: case 0x000006d9: case 0x000006da: case 0x000006db:
2063 //case 0x000006dc: case 0x000006dd: case 0x000006de: case 0x000006df:
2064 return "IntelLastBranchToN";
2065 case 0x000006e0: return "Ia32TscDeadline"; /** @todo detect this correctly! */
2066
2067 case 0x00000c80: return g_enmMicroarch > kCpumMicroarch_Intel_Core7_Nehalem ? "Ia32DebugInterface" : NULL;
2068
2069 case 0xc0000080: return "Amd64Efer";
2070 case 0xc0000081: return "Amd64SyscallTarget";
2071 case 0xc0000082: return "Amd64LongSyscallTarget";
2072 case 0xc0000083: return "Amd64CompSyscallTarget";
2073 case 0xc0000084: return "Amd64SyscallFlagMask";
2074 case 0xc0000100: return "Amd64FsBase";
2075 case 0xc0000101: return "Amd64GsBase";
2076 case 0xc0000102: return "Amd64KernelGsBase";
2077 case 0xc0000103: return "Amd64TscAux";
2078 case 0xc0000104: return "AmdFam15hTscRate";
2079 case 0xc0000105: return "AmdFam15hLwpCfg";
2080 case 0xc0000106: return "AmdFam15hLwpCbAddr";
2081 case 0xc0000408: return "AmdFam10hMc4MiscN";
2082 case 0xc0000409: return "AmdFam10hMc4MiscN";
2083 case 0xc000040a: return "AmdFam10hMc4MiscN";
2084 case 0xc000040b: return "AmdFam10hMc4MiscN";
2085 case 0xc000040c: return "AmdFam10hMc4MiscN";
2086 case 0xc000040d: return "AmdFam10hMc4MiscN";
2087 case 0xc000040e: return "AmdFam10hMc4MiscN";
2088 case 0xc000040f: return "AmdFam10hMc4MiscN";
2089 case 0xc0010000: return "AmdK8PerfCtlN";
2090 case 0xc0010001: return "AmdK8PerfCtlN";
2091 case 0xc0010002: return "AmdK8PerfCtlN";
2092 case 0xc0010003: return "AmdK8PerfCtlN";
2093 case 0xc0010004: return "AmdK8PerfCtrN";
2094 case 0xc0010005: return "AmdK8PerfCtrN";
2095 case 0xc0010006: return "AmdK8PerfCtrN";
2096 case 0xc0010007: return "AmdK8PerfCtrN";
2097 case 0xc0010010: *pfTakesValue = true; return "AmdK8SysCfg";
2098 case 0xc0010015: return "AmdK8HwCr";
2099 case 0xc0010016: case 0xc0010018: return "AmdK8IorrBaseN";
2100 case 0xc0010017: case 0xc0010019: return "AmdK8IorrMaskN";
2101 case 0xc001001a: case 0xc001001d: return "AmdK8TopOfMemN";
2102 case 0xc001001f: return "AmdK8NbCfg1";
2103 case 0xc0010020: return "AmdK8PatchLoader";
2104 case 0xc0010022: return "AmdK8McXcptRedir";
2105 case 0xc0010030: case 0xc0010031: case 0xc0010032:
2106 case 0xc0010033: case 0xc0010034: case 0xc0010035:
2107 return "AmdK8CpuNameN";
2108 case 0xc001003e: *pfTakesValue = true; return "AmdK8HwThermalCtrl";
2109 case 0xc001003f: return "AmdK8SwThermalCtrl";
2110 case 0xc0010041: *pfTakesValue = true; return "AmdK8FidVidControl";
2111 case 0xc0010042: *pfTakesValue = true; return "AmdK8FidVidStatus";
2112 case 0xc0010044: case 0xc0010045: case 0xc0010046: case 0xc0010047:
2113 case 0xc0010048: case 0xc0010049: case 0xc001004a: //case 0xc001004b:
2114 return "AmdK8McCtlMaskN";
2115 case 0xc0010050: case 0xc0010051: case 0xc0010052: case 0xc0010053:
2116 return "AmdK8SmiOnIoTrapN";
2117 case 0xc0010054: return "AmdK8SmiOnIoTrapCtlSts";
2118 case 0xc0010055: return "AmdK8IntPendingMessage";
2119 case 0xc0010056: return "AmdK8SmiTriggerIoCycle";
2120 case 0xc0010058: return "AmdFam10hMmioCfgBaseAddr";
2121 case 0xc0010059: return "AmdFam10hTrapCtlMaybe";
2122 case 0xc0010061: *pfTakesValue = true; return "AmdFam10hPStateCurLimit";
2123 case 0xc0010062: *pfTakesValue = true; return "AmdFam10hPStateControl";
2124 case 0xc0010063: *pfTakesValue = true; return "AmdFam10hPStateStatus";
2125 case 0xc0010064: case 0xc0010065: case 0xc0010066: case 0xc0010067:
2126 case 0xc0010068: case 0xc0010069: case 0xc001006a: case 0xc001006b:
2127 *pfTakesValue = true; return "AmdFam10hPStateN";
2128 case 0xc0010070: *pfTakesValue = true; return "AmdFam10hCofVidControl";
2129 case 0xc0010071: *pfTakesValue = true; return "AmdFam10hCofVidStatus";
2130 case 0xc0010073: return "AmdFam10hCStateIoBaseAddr";
2131 case 0xc0010074: return "AmdFam10hCpuWatchdogTimer";
2132 // case 0xc0010075: return "AmdFam15hApmlTdpLimit";
2133 // case 0xc0010077: return "AmdFam15hCpuPowerInTdp";
2134 // case 0xc0010078: return "AmdFam15hPowerAveragingPeriod";
2135 // case 0xc0010079: return "AmdFam15hDramCtrlCmdThrottle";
2136 // case 0xc0010080: return "AmdFam16hFreqSensFeedbackMonActCnt0";
2137 // case 0xc0010081: return "AmdFam16hFreqSensFeedbackMonRefCnt0";
2138 case 0xc0010111: return "AmdK8SmmBase"; /** @todo probably misdetected ign/gp due to locking */
2139 case 0xc0010112: return "AmdK8SmmAddr"; /** @todo probably misdetected ign/gp due to locking */
2140 case 0xc0010113: return "AmdK8SmmMask"; /** @todo probably misdetected ign/gp due to locking */
2141 case 0xc0010114: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm_AMDV ? "AmdK8VmCr" : NULL; /** @todo probably misdetected due to locking */
2142 case 0xc0010115: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm ? "AmdK8IgnNe" : NULL;
2143 case 0xc0010116: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm ? "AmdK8SmmCtl" : NULL;
2144 case 0xc0010117: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm_AMDV ? "AmdK8VmHSavePa" : NULL; /** @todo probably misdetected due to locking */
2145 case 0xc0010118: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm_AMDV ? "AmdFam10hVmLockKey" : NULL;
2146 case 0xc0010119: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm ? "AmdFam10hSmmLockKey" : NULL; /* Not documented by BKDG, found in netbsd patch. */
2147 case 0xc001011a: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_90nm ? "AmdFam10hLocalSmiStatus" : NULL;
2148 case 0xc0010140: *pfTakesValue = true; return "AmdFam10hOsVisWrkIdLength";
2149 case 0xc0010141: *pfTakesValue = true; return "AmdFam10hOsVisWrkStatus";
2150 case 0xc0010200: case 0xc0010202: case 0xc0010204: case 0xc0010206:
2151 case 0xc0010208: case 0xc001020a: //case 0xc001020c: case 0xc001020e:
2152 return "AmdK8PerfCtlN";
2153 case 0xc0010201: case 0xc0010203: case 0xc0010205: case 0xc0010207:
2154 case 0xc0010209: case 0xc001020b: //case 0xc001020d: case 0xc001020f:
2155 return "AmdK8PerfCtrN";
2156 case 0xc0010230: case 0xc0010232: case 0xc0010234: case 0xc0010236:
2157 //case 0xc0010238: case 0xc001023a: case 0xc001030c: case 0xc001023e:
2158 return "AmdFam16hL2IPerfCtlN";
2159 case 0xc0010231: case 0xc0010233: case 0xc0010235: case 0xc0010237:
2160 //case 0xc0010239: case 0xc001023b: case 0xc001023d: case 0xc001023f:
2161 return "AmdFam16hL2IPerfCtrN";
2162 case 0xc0010240: case 0xc0010242: case 0xc0010244: case 0xc0010246:
2163 //case 0xc0010248: case 0xc001024a: case 0xc001024c: case 0xc001024e:
2164 return "AmdFam15hNorthbridgePerfCtlN";
2165 case 0xc0010241: case 0xc0010243: case 0xc0010245: case 0xc0010247:
2166 //case 0xc0010249: case 0xc001024b: case 0xc001024d: case 0xc001024f:
2167 return "AmdFam15hNorthbridgePerfCtrN";
2168 case 0xc0011000: *pfTakesValue = true; return "AmdK7MicrocodeCtl";
2169 case 0xc0011001: *pfTakesValue = true; return "AmdK7ClusterIdMaybe";
2170 case 0xc0011002: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AmdK8CpuIdCtlStd07hEbax" : NULL;
2171 case 0xc0011003: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AmdK8CpuIdCtlStd06hEcx" : NULL;
2172 case 0xc0011004: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AmdK8CpuIdCtlStd01hEdcx" : NULL;
2173 case 0xc0011005: return g_enmMicroarch >= kCpumMicroarch_AMD_K8_First ? "AmdK8CpuIdCtlExt01hEdcx" : NULL;
2174 case 0xc0011006: return "AmdK7DebugStatusMaybe";
2175 case 0xc0011007: return "AmdK7BHTraceBaseMaybe";
2176 case 0xc0011008: return "AmdK7BHTracePtrMaybe";
2177 case 0xc0011009: return "AmdK7BHTraceLimitMaybe";
2178 case 0xc001100a: return "AmdK7HardwareDebugToolCfgMaybe";
2179 case 0xc001100b: return "AmdK7FastFlushCountMaybe";
2180 case 0xc001100c: return "AmdK7NodeId"; /** @todo dunno if this was there is K7 already. Kinda doubt it. */
2181 case 0xc0011019: return g_enmMicroarch >= kCpumMicroarch_AMD_15h_Piledriver ? "AmdK7DrXAddrMaskN" : NULL;
2182 case 0xc001101a: return g_enmMicroarch >= kCpumMicroarch_AMD_15h_Piledriver ? "AmdK7DrXAddrMaskN" : NULL;
2183 case 0xc001101b: return g_enmMicroarch >= kCpumMicroarch_AMD_15h_Piledriver ? "AmdK7DrXAddrMaskN" : NULL;
2184 case 0xc0011020: return "AmdK7LoadStoreCfg";
2185 case 0xc0011021: return "AmdK7InstrCacheCfg";
2186 case 0xc0011022: return "AmdK7DataCacheCfg";
2187 case 0xc0011023: return CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch) ? "AmdFam15hCombUnitCfg" : "AmdK7BusUnitCfg";
2188 case 0xc0011024: return "AmdK7DebugCtl2Maybe";
2189 case 0xc0011025: return "AmdK7Dr0DataMatchMaybe";
2190 case 0xc0011026: return "AmdK7Dr0DataMaskMaybe";
2191 case 0xc0011027: return "AmdK7DrXAddrMaskN";
2192 case 0xc0011028: return g_enmMicroarch >= kCpumMicroarch_AMD_15h_First ? "AmdFam15hFpuCfg" : NULL;
2193 case 0xc0011029: return g_enmMicroarch >= kCpumMicroarch_AMD_15h_First ? "AmdFam15hDecoderCfg" : NULL;
2194 case 0xc001102a: return CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch) ? "AmdFam15hCombUnitCfg2"
2195 : CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch) || g_enmMicroarch > kCpumMicroarch_AMD_15h_End
2196 ? "AmdFam10hBusUnitCfg2" /* 10h & 16h */ : NULL;
2197 case 0xc001102b: return CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch) ? "AmdFam15hCombUnitCfg3" : NULL;
2198 case 0xc001102c: return CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch) ? "AmdFam15hExecUnitCfg" : NULL;
2199 case 0xc001102d: return CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch) ? "AmdFam15hLoadStoreCfg2" : NULL;
2200 case 0xc0011030: return "AmdFam10hIbsFetchCtl";
2201 case 0xc0011031: return "AmdFam10hIbsFetchLinAddr";
2202 case 0xc0011032: return "AmdFam10hIbsFetchPhysAddr";
2203 case 0xc0011033: return "AmdFam10hIbsOpExecCtl";
2204 case 0xc0011034: return "AmdFam10hIbsOpRip";
2205 case 0xc0011035: return "AmdFam10hIbsOpData";
2206 case 0xc0011036: return "AmdFam10hIbsOpData2";
2207 case 0xc0011037: return "AmdFam10hIbsOpData3";
2208 case 0xc0011038: return "AmdFam10hIbsDcLinAddr";
2209 case 0xc0011039: return "AmdFam10hIbsDcPhysAddr";
2210 case 0xc001103a: return "AmdFam10hIbsCtl";
2211 case 0xc001103b: return "AmdFam14hIbsBrTarget";
2212 }
2213 return NULL;
2214}
2215
2216
2217/**
2218 * Names CPUMCPU variables that MSRs corresponds to.
2219 *
2220 * @returns The variable name @a uMsr corresponds to, NULL if no variable.
2221 * @param uMsr The MSR in question.
2222 */
2223static const char *getMsrCpumCpuVarName(uint32_t uMsr)
2224{
2225 switch (uMsr)
2226 {
2227 case 0x00000250: return "GuestMsrs.msr.MtrrFix64K_00000";
2228 case 0x00000258: return "GuestMsrs.msr.MtrrFix16K_80000";
2229 case 0x00000259: return "GuestMsrs.msr.MtrrFix16K_A0000";
2230 case 0x00000268: return "GuestMsrs.msr.MtrrFix4K_C0000";
2231 case 0x00000269: return "GuestMsrs.msr.MtrrFix4K_C8000";
2232 case 0x0000026a: return "GuestMsrs.msr.MtrrFix4K_D0000";
2233 case 0x0000026b: return "GuestMsrs.msr.MtrrFix4K_D8000";
2234 case 0x0000026c: return "GuestMsrs.msr.MtrrFix4K_E0000";
2235 case 0x0000026d: return "GuestMsrs.msr.MtrrFix4K_E8000";
2236 case 0x0000026e: return "GuestMsrs.msr.MtrrFix4K_F0000";
2237 case 0x0000026f: return "GuestMsrs.msr.MtrrFix4K_F8000";
2238 case 0x00000277: return "Guest.msrPAT";
2239 case 0x000002ff: return "GuestMsrs.msr.MtrrDefType";
2240 }
2241 return NULL;
2242}
2243
2244
2245/**
2246 * Checks whether the MSR should read as zero for some reason.
2247 *
2248 * @returns true if the register should read as zero, false if not.
2249 * @param uMsr The MSR.
2250 */
2251static bool doesMsrReadAsZero(uint32_t uMsr)
2252{
2253 switch (uMsr)
2254 {
2255 case 0x00000088: return true; // "BBL_CR_D0" - RAZ until understood/needed.
2256 case 0x00000089: return true; // "BBL_CR_D1" - RAZ until understood/needed.
2257 case 0x0000008a: return true; // "BBL_CR_D2" - RAZ until understood/needed.
2258
2259 /* Non-zero, but unknown register. */
2260 case 0x0000004a:
2261 case 0x0000004b:
2262 case 0x0000004c:
2263 case 0x0000004d:
2264 case 0x0000004e:
2265 case 0x0000004f:
2266 case 0x00000050:
2267 case 0x00000051:
2268 case 0x00000052:
2269 case 0x00000053:
2270 case 0x00000054:
2271 case 0x0000008c:
2272 case 0x0000008d:
2273 case 0x0000008e:
2274 case 0x0000008f:
2275 case 0x00000090:
2276 case 0xc0011011:
2277 return true;
2278 }
2279
2280 return false;
2281}
2282
2283
2284/**
2285 * Gets the skip mask for the given MSR.
2286 *
2287 * @returns Skip mask (0 means skipping nothing).
2288 * @param uMsr The MSR.
2289 */
2290static uint64_t getGenericSkipMask(uint32_t uMsr)
2291{
2292 switch (uMsr)
2293 {
2294 case 0x0000013c: return 3; /* AES-NI lock bit ++. */
2295
2296 case 0x000001f2: return UINT64_C(0xfffff00f); /* Ia32SmrrPhysBase - Only writable in SMM. */
2297 case 0x000001f3: return UINT64_C(0xfffff800); /* Ia32SmrrPhysMask - Only writable in SMM. */
2298
2299 /* these two have lock bits. */
2300 case 0x0000064b: return UINT64_C(0x80000003);
2301 case 0x0000064c: return UINT64_C(0x800000ff);
2302
2303 case 0xc0010015: return 1; /* SmmLock bit */
2304
2305 /* SmmLock effect: */
2306 case 0xc0010111: return UINT32_MAX;
2307 case 0xc0010112: return UINT64_C(0xfffe0000) | ((RT_BIT_64(vbCpuRepGetPhysAddrWidth()) - 1) & ~(uint64_t)UINT32_MAX);
2308 case 0xc0010113: return UINT64_C(0xfffe773f) | ((RT_BIT_64(vbCpuRepGetPhysAddrWidth()) - 1) & ~(uint64_t)UINT32_MAX);
2309 case 0xc0010116: return 0x1f;
2310
2311 case 0xc0010114: return RT_BIT_64(3) /* SVM lock */ | RT_BIT_64(4) /* SvmeDisable */;
2312
2313 /* Canonical */
2314 case 0xc0011034:
2315 case 0xc0011038:
2316 case 0xc001103b:
2317 return UINT64_C(0xffff800000000000);
2318
2319 case 0x00000060: case 0x00000061: case 0x00000062: case 0x00000063:
2320 case 0x00000064: case 0x00000065: case 0x00000066: case 0x00000067:
2321 case 0x00000040: case 0x00000041: case 0x00000042: case 0x00000043:
2322 case 0x00000044: case 0x00000045: case 0x00000046: case 0x00000047:
2323 case 0x00000600:
2324 if (g_enmMicroarch >= kCpumMicroarch_Intel_Core2_First)
2325 return UINT64_C(0xffff800000000000);
2326 break;
2327
2328
2329 /* Write only bits. */
2330 case 0xc0010041: return RT_BIT_64(16); /* FIDVID_CTL.InitFidVid */
2331
2332 /* Time counters - fudge them to avoid incorrect ignore masks. */
2333 case 0x00000010:
2334 case 0x000000e7:
2335 case 0x000000e8:
2336 return RT_BIT_32(29) - 1;
2337 }
2338 return 0;
2339}
2340
2341
2342
2343
2344/** queryMsrWriteBadness return values. */
2345typedef enum
2346{
2347 /** . */
2348 VBCPUREPBADNESS_MOSTLY_HARMLESS = 0,
2349 /** Not a problem if accessed with care. */
2350 VBCPUREPBADNESS_MIGHT_BITE,
2351 /** Worse than a bad james bond villain. */
2352 VBCPUREPBADNESS_BOND_VILLAIN
2353} VBCPUREPBADNESS;
2354
2355
2356/**
2357 * Backlisting and graylisting of MSRs which may cause tripple faults.
2358 *
2359 * @returns Badness factor.
2360 * @param uMsr The MSR in question.
2361 */
2362static VBCPUREPBADNESS queryMsrWriteBadness(uint32_t uMsr)
2363{
2364 /** @todo Having trouble in the 0xc0010247,0xc0011006,?? region on Bulldozer. */
2365 /** @todo Having trouble in the 0xc001100f,0xc001100d,?? region on Opteron
2366 * 2384. */
2367
2368 switch (uMsr)
2369 {
2370 case 0x00000050:
2371 case 0x00000051:
2372 case 0x00000052:
2373 case 0x00000053:
2374 case 0x00000054:
2375
2376 case 0x00001006:
2377 case 0x00001007:
2378 return VBCPUREPBADNESS_BOND_VILLAIN;
2379
2380 case 0x0000120e:
2381 case 0x00001233:
2382 case 0x00001239:
2383 case 0x00001249:
2384 case 0x0000124a:
2385 case 0x00001404:
2386 case 0x00001405:
2387 case 0x00001413:
2388 case 0x0000142c: /* Caused rip to be set to 297 or some such weirdness... */
2389 case 0x0000142e:
2390 case 0x00001435:
2391 case 0x00001436:
2392 case 0x00001438:
2393 case 0x0000317f:
2394 if (g_enmVendor == CPUMCPUVENDOR_VIA)
2395 return VBCPUREPBADNESS_BOND_VILLAIN;
2396 break;
2397
2398 case 0xc0010010:
2399 case 0xc0010016:
2400 case 0xc0010017:
2401 case 0xc0010018:
2402 case 0xc0010019:
2403 case 0xc001001a:
2404 case 0xc001001d:
2405 case 0xc0010064: /* P-state fequency, voltage, ++. */
2406 case 0xc0010065: /* P-state fequency, voltage, ++. */
2407 case 0xc0010066: /* P-state fequency, voltage, ++. */
2408 case 0xc0010067: /* P-state fequency, voltage, ++. */
2409 case 0xc0010068: /* P-state fequency, voltage, ++. */
2410 case 0xc0010069: /* P-state fequency, voltage, ++. */
2411 case 0xc001006a: /* P-state fequency, voltage, ++. */
2412 case 0xc001006b: /* P-state fequency, voltage, ++. */
2413 case 0xc0010070: /* COFVID Control. */
2414 case 0xc001101e:
2415 case 0xc0011021: /* IC_CFG (instruction cache configuration) */
2416 case 0xc0011023: /* CU_CFG (combined unit configuration) */
2417 case 0xc001102c: /* EX_CFG (execution unit configuration) */
2418 return VBCPUREPBADNESS_BOND_VILLAIN;
2419
2420 case 0xc0011012:
2421 if (CPUMMICROARCH_IS_AMD_FAM_0FH(g_enmMicroarch))
2422 return VBCPUREPBADNESS_MIGHT_BITE;
2423 break;
2424
2425 case 0x000001a0: /* IA32_MISC_ENABLE */
2426 case 0x00000199: /* IA32_PERF_CTL */
2427 return VBCPUREPBADNESS_MIGHT_BITE;
2428 case 0x00002000: /* P6_CR0. */
2429 case 0x00002003: /* P6_CR3. */
2430 case 0x00002004: /* P6_CR4. */
2431 if (g_enmVendor == CPUMCPUVENDOR_INTEL)
2432 return VBCPUREPBADNESS_MIGHT_BITE;
2433 break;
2434 case 0xc0000080: /* MSR_K6_EFER */
2435 return VBCPUREPBADNESS_MIGHT_BITE;
2436 }
2437 return VBCPUREPBADNESS_MOSTLY_HARMLESS;
2438}
2439
2440
2441/**
2442 * Checks if this might be a VIA dummy register.
2443 *
2444 * @returns true if it's a dummy, false if it isn't.
2445 * @param uMsr The MSR.
2446 * @param uValue The value.
2447 * @param fFlags The flags.
2448 */
2449static bool isMsrViaDummy(uint32_t uMsr, uint64_t uValue, uint32_t fFlags)
2450{
2451 if (g_enmVendor != CPUMCPUVENDOR_VIA)
2452 return false;
2453
2454 if (uValue)
2455 return false;
2456
2457 if (fFlags)
2458 return false;
2459
2460 switch (uMsr)
2461 {
2462 case 0x00000010:
2463 case 0x0000001b:
2464 case 0x000000c1:
2465 case 0x000000c2:
2466 case 0x0000011e:
2467 case 0x00000186:
2468 case 0x00000187:
2469 //case 0x00000200 ... (mtrrs will be detected)
2470 return false;
2471
2472 case 0xc0000080:
2473 case 0xc0000081:
2474 case 0xc0000082:
2475 case 0xc0000083:
2476 if (vbCpuRepSupportsLongMode())
2477 return false;
2478 break;
2479 }
2480
2481 if (uMsr >= 0x00001200 && uMsr <= 0x00003fff && queryMsrWriteBadness(uMsr) != VBCPUREPBADNESS_MOSTLY_HARMLESS)
2482 return false;
2483
2484 if ( !msrProberModifyNoChange(uMsr)
2485 && !msrProberModifyZero(uMsr))
2486 return false;
2487
2488 uint64_t fIgnMask = 0;
2489 uint64_t fGpMask = 0;
2490 int rc = msrProberModifyBitChanges(uMsr, &fIgnMask, &fGpMask, 0);
2491 if (RT_FAILURE(rc))
2492 return false;
2493
2494 if (fIgnMask != UINT64_MAX)
2495 return false;
2496 if (fGpMask != 0)
2497 return false;
2498
2499 return true;
2500}
2501
2502
2503
2504
2505/**
2506 * Prints a 64-bit value in the best way.
2507 *
2508 * @param uValue The value.
2509 */
2510static void printMsrValueU64(uint64_t uValue)
2511{
2512 if (uValue == 0)
2513 vbCpuRepPrintf(", 0");
2514 else if (uValue == UINT16_MAX)
2515 vbCpuRepPrintf(", UINT16_MAX");
2516 else if (uValue == UINT32_MAX)
2517 vbCpuRepPrintf(", UINT32_MAX");
2518 else if (uValue == UINT64_MAX)
2519 vbCpuRepPrintf(", UINT64_MAX");
2520 else if (uValue == UINT64_C(0xffffffff00000000))
2521 vbCpuRepPrintf(", ~(uint64_t)UINT32_MAX");
2522 else if (uValue <= (UINT32_MAX >> 1))
2523 vbCpuRepPrintf(", %#llx", uValue);
2524 else if (uValue <= UINT32_MAX)
2525 vbCpuRepPrintf(", UINT32_C(%#llx)", uValue);
2526 else
2527 vbCpuRepPrintf(", UINT64_C(%#llx)", uValue);
2528}
2529
2530
2531/**
2532 * Prints the newline after an MSR line has been printed.
2533 *
2534 * This is used as a hook to slow down the output and make sure the remote
2535 * terminal or/and output file has received the last update before we go and
2536 * crash probing the next MSR.
2537 */
2538static void printMsrNewLine(void)
2539{
2540 vbCpuRepPrintf("\n");
2541#if 1
2542 RTThreadSleep(8);
2543#endif
2544}
2545
2546static int printMsrWriteOnly(uint32_t uMsr, const char *pszWrFnName, const char *pszAnnotation)
2547{
2548 if (!pszWrFnName)
2549 pszWrFnName = "IgnoreWrite";
2550 vbCpuRepPrintf(pszAnnotation
2551 ? " MFN(%#010x, \"%s\", WriteOnly, %s), /* %s */"
2552 : " MFN(%#010x, \"%s\", WriteOnly, %s),",
2553 uMsr, getMsrName(uMsr), pszWrFnName, pszAnnotation);
2554 printMsrNewLine();
2555 return VINF_SUCCESS;
2556}
2557
2558
2559static int printMsrValueReadOnly(uint32_t uMsr, uint64_t uValue, const char *pszAnnotation)
2560{
2561 vbCpuRepPrintf(" MVO(%#010x, \"%s\"", uMsr, getMsrName(uMsr));
2562 printMsrValueU64(uValue);
2563 vbCpuRepPrintf("),");
2564 if (pszAnnotation)
2565 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2566 printMsrNewLine();
2567 return VINF_SUCCESS;
2568}
2569
2570
2571
2572static int printMsrValueIgnoreWritesNamed(uint32_t uMsr, uint64_t uValue, const char *pszName, const char *pszAnnotation)
2573{
2574 vbCpuRepPrintf(" MVI(%#010x, \"%s\"", uMsr, pszName);
2575 printMsrValueU64(uValue);
2576 vbCpuRepPrintf("),");
2577 if (pszAnnotation)
2578 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2579 printMsrNewLine();
2580 return VINF_SUCCESS;
2581}
2582
2583
2584static int printMsrValueIgnoreWrites(uint32_t uMsr, uint64_t uValue, const char *pszAnnotation)
2585{
2586 return printMsrValueIgnoreWritesNamed(uMsr, uValue, getMsrName(uMsr), pszAnnotation);
2587}
2588
2589
2590static int printMsrValueExtended(uint32_t uMsr, uint64_t uValue, uint64_t fIgnMask, uint64_t fGpMask,
2591 const char *pszAnnotation)
2592{
2593 vbCpuRepPrintf(" MVX(%#010x, \"%s\"", uMsr, getMsrName(uMsr));
2594 printMsrValueU64(uValue);
2595 printMsrValueU64(fIgnMask);
2596 printMsrValueU64(fGpMask);
2597 vbCpuRepPrintf("),");
2598 if (pszAnnotation)
2599 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2600 printMsrNewLine();
2601 return VINF_SUCCESS;
2602}
2603
2604
2605static int printMsrRangeValueReadOnly(uint32_t uMsr, uint32_t uLast, uint64_t uValue, const char *pszAnnotation)
2606{
2607 vbCpuRepPrintf(" RVO(%#010x, %#010x, \"%s\"", uMsr, uLast, getMsrRangeName(uMsr));
2608 printMsrValueU64(uValue);
2609 vbCpuRepPrintf("),");
2610 if (pszAnnotation)
2611 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2612 printMsrNewLine();
2613 return VINF_SUCCESS;
2614}
2615
2616
2617static int printMsrRangeValueIgnoreWritesNamed(uint32_t uMsr, uint32_t uLast, uint64_t uValue, const char *pszName, const char *pszAnnotation)
2618{
2619 vbCpuRepPrintf(" RVI(%#010x, %#010x, \"%s\"", uMsr, uLast, pszName);
2620 printMsrValueU64(uValue);
2621 vbCpuRepPrintf("),");
2622 if (pszAnnotation)
2623 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2624 printMsrNewLine();
2625 return VINF_SUCCESS;
2626}
2627
2628
2629static int printMsrRangeValueIgnoreWrites(uint32_t uMsr, uint32_t uLast, uint64_t uValue, const char *pszAnnotation)
2630{
2631 return printMsrRangeValueIgnoreWritesNamed(uMsr, uLast, uValue, getMsrRangeName(uMsr), pszAnnotation);
2632}
2633
2634
2635static int printMsrFunction(uint32_t uMsr, const char *pszRdFnName, const char *pszWrFnName, const char *pszAnnotation)
2636{
2637 if (!pszRdFnName)
2638 pszRdFnName = getMsrFnName(uMsr, NULL);
2639 if (!pszWrFnName)
2640 pszWrFnName = pszRdFnName;
2641 vbCpuRepPrintf(" MFN(%#010x, \"%s\", %s, %s),", uMsr, getMsrName(uMsr), pszRdFnName, pszWrFnName);
2642 if (pszAnnotation)
2643 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2644 printMsrNewLine();
2645 return VINF_SUCCESS;
2646}
2647
2648
2649static int printMsrFunctionReadOnly(uint32_t uMsr, const char *pszRdFnName, const char *pszAnnotation)
2650{
2651 if (!pszRdFnName)
2652 pszRdFnName = getMsrFnName(uMsr, NULL);
2653 vbCpuRepPrintf(" MFO(%#010x, \"%s\", %s),", uMsr, getMsrName(uMsr), pszRdFnName);
2654 if (pszAnnotation)
2655 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2656 printMsrNewLine();
2657 return VINF_SUCCESS;
2658}
2659
2660
2661static int printMsrFunctionIgnoreWrites(uint32_t uMsr, const char *pszRdFnName, const char *pszAnnotation)
2662{
2663 if (!pszRdFnName)
2664 pszRdFnName = getMsrFnName(uMsr, NULL);
2665 vbCpuRepPrintf(" MFI(%#010x, \"%s\", %s),", uMsr, getMsrName(uMsr), pszRdFnName);
2666 if (pszAnnotation)
2667 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2668 printMsrNewLine();
2669 return VINF_SUCCESS;
2670}
2671
2672
2673static int printMsrFunctionIgnoreMask(uint32_t uMsr, const char *pszRdFnName, const char *pszWrFnName,
2674 uint64_t fIgnMask, const char *pszAnnotation)
2675{
2676 if (!pszRdFnName)
2677 pszRdFnName = getMsrFnName(uMsr, NULL);
2678 if (!pszWrFnName)
2679 pszWrFnName = pszRdFnName;
2680 vbCpuRepPrintf(" MFW(%#010x, \"%s\", %s, %s", uMsr, getMsrName(uMsr), pszRdFnName, pszWrFnName);
2681 printMsrValueU64(fIgnMask);
2682 vbCpuRepPrintf("),");
2683 if (pszAnnotation)
2684 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2685 printMsrNewLine();
2686 return VINF_SUCCESS;
2687}
2688
2689
2690static int printMsrFunctionExtended(uint32_t uMsr, const char *pszRdFnName, const char *pszWrFnName, uint64_t uValue,
2691 uint64_t fIgnMask, uint64_t fGpMask, const char *pszAnnotation)
2692{
2693 if (!pszRdFnName)
2694 pszRdFnName = getMsrFnName(uMsr, NULL);
2695 if (!pszWrFnName)
2696 pszWrFnName = pszRdFnName;
2697 vbCpuRepPrintf(" MFX(%#010x, \"%s\", %s, %s", uMsr, getMsrName(uMsr), pszRdFnName, pszWrFnName);
2698 printMsrValueU64(uValue);
2699 printMsrValueU64(fIgnMask);
2700 printMsrValueU64(fGpMask);
2701 vbCpuRepPrintf("),");
2702 if (pszAnnotation)
2703 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2704 printMsrNewLine();
2705 return VINF_SUCCESS;
2706}
2707
2708
2709static int printMsrFunctionExtendedIdxVal(uint32_t uMsr, const char *pszRdFnName, const char *pszWrFnName, uint64_t uValue,
2710 uint64_t fIgnMask, uint64_t fGpMask, const char *pszAnnotation)
2711{
2712 if (!pszRdFnName)
2713 pszRdFnName = getMsrFnName(uMsr, NULL);
2714 if (!pszWrFnName)
2715 pszWrFnName = pszRdFnName;
2716 vbCpuRepPrintf(" MFX(%#010x, \"%s\", %s, %s, %#x", uMsr, getMsrName(uMsr), pszRdFnName, pszWrFnName, uValue);
2717 printMsrValueU64(fIgnMask);
2718 printMsrValueU64(fGpMask);
2719 vbCpuRepPrintf("),");
2720 if (pszAnnotation)
2721 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2722 printMsrNewLine();
2723 return VINF_SUCCESS;
2724}
2725
2726
2727static int printMsrFunctionCpumCpu(uint32_t uMsr, const char *pszRdFnName, const char *pszWrFnName,
2728 const char *pszCpumCpuStorage, const char *pszAnnotation)
2729{
2730 if (!pszRdFnName)
2731 pszRdFnName = getMsrFnName(uMsr, NULL);
2732 if (!pszWrFnName)
2733 pszWrFnName = pszRdFnName;
2734 if (!pszCpumCpuStorage)
2735 pszCpumCpuStorage = getMsrCpumCpuVarName(uMsr);
2736 if (!pszCpumCpuStorage)
2737 return RTMsgErrorRc(VERR_NOT_FOUND, "Missing CPUMCPU member for %#s (%#x)\n", getMsrName(uMsr), uMsr);
2738 vbCpuRepPrintf(" MFS(%#010x, \"%s\", %s, %s, %s),", uMsr, getMsrName(uMsr), pszRdFnName, pszWrFnName, pszCpumCpuStorage);
2739 if (pszAnnotation)
2740 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2741 printMsrNewLine();
2742 return VINF_SUCCESS;
2743}
2744
2745
2746static int printMsrFunctionCpumCpuEx(uint32_t uMsr, const char *pszRdFnName, const char *pszWrFnName,
2747 const char *pszCpumCpuStorage, uint64_t fIgnMask, uint64_t fGpMask,
2748 const char *pszAnnotation)
2749{
2750 if (!pszRdFnName)
2751 pszRdFnName = getMsrFnName(uMsr, NULL);
2752 if (!pszWrFnName)
2753 pszWrFnName = pszRdFnName;
2754 if (!pszCpumCpuStorage)
2755 pszCpumCpuStorage = getMsrCpumCpuVarName(uMsr);
2756 if (!pszCpumCpuStorage)
2757 return RTMsgErrorRc(VERR_NOT_FOUND, "Missing CPUMCPU member for %#s (%#x)\n", getMsrName(uMsr), uMsr);
2758 vbCpuRepPrintf(" MFZ(%#010x, \"%s\", %s, %s, %s", uMsr, getMsrName(uMsr), pszRdFnName, pszWrFnName, pszCpumCpuStorage);
2759 printMsrValueU64(fIgnMask);
2760 printMsrValueU64(fGpMask);
2761 vbCpuRepPrintf("),");
2762 if (pszAnnotation)
2763 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2764 printMsrNewLine();
2765 return VINF_SUCCESS;
2766}
2767
2768
2769static int printMsrRangeFunction(uint32_t uMsr, uint32_t uLast, const char *pszRdFnName, const char *pszWrFnName,
2770 const char *pszAnnotation)
2771{
2772 if (!pszRdFnName)
2773 pszRdFnName = getMsrFnName(uMsr, NULL);
2774 if (!pszWrFnName)
2775 pszWrFnName = pszRdFnName;
2776 vbCpuRepPrintf(" RFN(%#010x, %#010x, \"%s\", %s, %s),", uMsr, uLast, getMsrRangeName(uMsr), pszRdFnName, pszWrFnName);
2777 if (pszAnnotation)
2778 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2779 printMsrNewLine();
2780 return VINF_SUCCESS;
2781}
2782
2783
2784static int printMsrRangeFunctionEx(uint32_t uMsr, uint32_t uLast, const char *pszRdFnName, const char *pszWrFnName,
2785 uint64_t uValue, uint64_t fIgnMask, uint64_t fGpMask, const char *pszAnnotation)
2786{
2787 if (!pszRdFnName)
2788 pszRdFnName = getMsrFnName(uMsr, NULL);
2789 if (!pszWrFnName)
2790 pszWrFnName = pszRdFnName;
2791 vbCpuRepPrintf(" RSN(%#010x, %#010x, \"%s\", %s, %s", uMsr, uLast, getMsrRangeName(uMsr), pszRdFnName, pszWrFnName);
2792 printMsrValueU64(uValue);
2793 printMsrValueU64(fIgnMask);
2794 printMsrValueU64(fGpMask);
2795 vbCpuRepPrintf("),");
2796 if (pszAnnotation)
2797 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2798 printMsrNewLine();
2799 return VINF_SUCCESS;
2800}
2801
2802
2803static int printMsrRangeFunctionExIdxVal(uint32_t uMsr, uint32_t uLast, const char *pszRdFnName, const char *pszWrFnName,
2804 uint64_t uValue, uint64_t fIgnMask, uint64_t fGpMask, const char *pszAnnotation)
2805{
2806 if (!pszRdFnName)
2807 pszRdFnName = getMsrFnName(uMsr, NULL);
2808 if (!pszWrFnName)
2809 pszWrFnName = pszRdFnName;
2810 vbCpuRepPrintf(" RSN(%#010x, %#010x, \"%s\", %s, %s, %#x",
2811 uMsr, uLast, getMsrRangeName(uMsr), pszRdFnName, pszWrFnName, uValue);
2812 printMsrValueU64(fIgnMask);
2813 printMsrValueU64(fGpMask);
2814 vbCpuRepPrintf("),");
2815 if (pszAnnotation)
2816 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2817 printMsrNewLine();
2818 return VINF_SUCCESS;
2819}
2820
2821
2822static int printMsrAlias(uint32_t uMsr, uint32_t uTarget, const char *pszAnnotation)
2823{
2824 vbCpuRepPrintf(" MAL(%#010x, \"%s\", %#010x),", uMsr, getMsrName(uMsr), uTarget);
2825 if (pszAnnotation)
2826 vbCpuRepPrintf(" /* %s */", pszAnnotation);
2827 printMsrNewLine();
2828 return VINF_SUCCESS;
2829}
2830
2831
2832
2833static const char *annotateValue(uint64_t uValue)
2834{
2835 static char s_szBuf[40];
2836 if (uValue <= UINT32_MAX)
2837 RTStrPrintf(s_szBuf, sizeof(s_szBuf), "value=%#llx", uValue);
2838 else
2839 RTStrPrintf(s_szBuf, sizeof(s_szBuf), "value=%#x`%08x", RT_HI_U32(uValue), RT_LO_U32(uValue));
2840 return s_szBuf;
2841}
2842
2843
2844static const char *annotateValueExtra(const char *pszExtra, uint64_t uValue)
2845{
2846 static char s_szBuf[40];
2847 if (uValue <= UINT32_MAX)
2848 RTStrPrintf(s_szBuf, sizeof(s_szBuf), "%s value=%#llx", pszExtra, uValue);
2849 else
2850 RTStrPrintf(s_szBuf, sizeof(s_szBuf), "%s value=%#x`%08x", pszExtra, RT_HI_U32(uValue), RT_LO_U32(uValue));
2851 return s_szBuf;
2852}
2853
2854
2855static const char *annotateIfMissingBits(uint64_t uValue, uint64_t fBits)
2856{
2857 static char s_szBuf[80];
2858 if ((uValue & fBits) == fBits)
2859 return annotateValue(uValue);
2860 RTStrPrintf(s_szBuf, sizeof(s_szBuf), "XXX: Unexpected value %#llx - wanted bits %#llx to be set.", uValue, fBits);
2861 return s_szBuf;
2862}
2863
2864
2865static int reportMsr_Generic(uint32_t uMsr, uint32_t fFlags, uint64_t uValue)
2866{
2867 int rc;
2868 bool fTakesValue = false;
2869 const char *pszFnName = getMsrFnName(uMsr, &fTakesValue);
2870
2871 if (fFlags & VBCPUREPMSR_F_WRITE_ONLY)
2872 rc = printMsrWriteOnly(uMsr, pszFnName, NULL);
2873 else
2874 {
2875 bool fReadAsZero = doesMsrReadAsZero(uMsr);
2876 fTakesValue = fTakesValue && !fReadAsZero;
2877
2878
2879 switch (queryMsrWriteBadness(uMsr))
2880 {
2881 /* This is what we're here for... */
2882 case VBCPUREPBADNESS_MOSTLY_HARMLESS:
2883 {
2884 if ( msrProberModifyNoChange(uMsr)
2885 || msrProberModifyZero(uMsr))
2886 {
2887 uint64_t fSkipMask = getGenericSkipMask(uMsr);
2888 uint64_t fIgnMask = 0;
2889 uint64_t fGpMask = 0;
2890 rc = msrProberModifyBitChanges(uMsr, &fIgnMask, &fGpMask, fSkipMask);
2891 if (RT_FAILURE(rc))
2892 return rc;
2893
2894 if (pszFnName)
2895 {
2896 if (fGpMask == 0 && fIgnMask == UINT64_MAX && !fTakesValue)
2897 rc = printMsrFunctionIgnoreWrites(uMsr, pszFnName, annotateValue(uValue));
2898 else if (fGpMask == 0 && fIgnMask == 0 && (!fTakesValue || uValue == 0))
2899 rc = printMsrFunction(uMsr, pszFnName, pszFnName, annotateValue(uValue));
2900 else
2901 rc = printMsrFunctionExtended(uMsr, pszFnName, pszFnName, fTakesValue ? uValue : 0,
2902 fIgnMask, fGpMask, annotateValue(uValue));
2903 }
2904 else if (fGpMask == 0 && fIgnMask == UINT64_MAX)
2905 rc = printMsrValueIgnoreWrites(uMsr, fReadAsZero ? 0 : uValue, fReadAsZero ? annotateValue(uValue) : NULL);
2906 else
2907 rc = printMsrValueExtended(uMsr, fReadAsZero ? 0 : uValue, fIgnMask, fGpMask,
2908 fReadAsZero ? annotateValue(uValue) : NULL);
2909 }
2910 /* Most likely read-only. */
2911 else if (pszFnName && !fTakesValue)
2912 rc = printMsrFunctionReadOnly(uMsr, pszFnName, annotateValue(uValue));
2913 else if (pszFnName)
2914 rc = printMsrFunctionExtended(uMsr, pszFnName, "ReadOnly", uValue, 0, 0, annotateValue(uValue));
2915 else if (fReadAsZero)
2916 rc = printMsrValueReadOnly(uMsr, 0, annotateValue(uValue));
2917 else
2918 rc = printMsrValueReadOnly(uMsr, uValue, NULL);
2919 break;
2920 }
2921
2922 /* These should have special handling, so just do a simple
2923 write back same value check to see if it's writable. */
2924 case VBCPUREPBADNESS_MIGHT_BITE:
2925 if (msrProberModifyNoChange(uMsr))
2926 {
2927 if (pszFnName && !fTakesValue)
2928 rc = printMsrFunction(uMsr, pszFnName, pszFnName, annotateValueExtra("Might bite.", uValue));
2929 else if (pszFnName)
2930 rc = printMsrFunctionExtended(uMsr, pszFnName, pszFnName, uValue, 0, 0,
2931 annotateValueExtra("Might bite.", uValue));
2932 else if (fReadAsZero)
2933 rc = printMsrValueIgnoreWrites(uMsr, 0, annotateValueExtra("Might bite.", uValue));
2934 else
2935 rc = printMsrValueIgnoreWrites(uMsr, uValue, "Might bite.");
2936 }
2937 else if (pszFnName && !fTakesValue)
2938 rc = printMsrFunctionReadOnly(uMsr, pszFnName, annotateValueExtra("Might bite.", uValue));
2939 else if (pszFnName)
2940 rc = printMsrFunctionExtended(uMsr, pszFnName, "ReadOnly", uValue, 0, UINT64_MAX,
2941 annotateValueExtra("Might bite.", uValue));
2942 else if (fReadAsZero)
2943 rc = printMsrValueReadOnly(uMsr, 0, annotateValueExtra("Might bite.", uValue));
2944 else
2945 rc = printMsrValueReadOnly(uMsr, uValue, "Might bite.");
2946 break;
2947
2948
2949 /* Don't try anything with these guys. */
2950 case VBCPUREPBADNESS_BOND_VILLAIN:
2951 default:
2952 if (pszFnName && !fTakesValue)
2953 rc = printMsrFunction(uMsr, pszFnName, pszFnName, annotateValueExtra("Villain?", uValue));
2954 else if (pszFnName)
2955 rc = printMsrFunctionExtended(uMsr, pszFnName, pszFnName, uValue, 0, 0,
2956 annotateValueExtra("Villain?", uValue));
2957 else if (fReadAsZero)
2958 rc = printMsrValueIgnoreWrites(uMsr, 0, annotateValueExtra("Villain?", uValue));
2959 else
2960 rc = printMsrValueIgnoreWrites(uMsr, uValue, "Villain?");
2961 break;
2962 }
2963 }
2964
2965 return rc;
2966}
2967
2968
2969static int reportMsr_GenRangeFunctionEx(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t cMax, const char *pszRdWrFnName,
2970 uint32_t uMsrBase, bool fEarlyEndOk, bool fNoIgnMask, uint64_t fSkipMask, uint32_t *pidxLoop)
2971{
2972 uint32_t uMsr = paMsrs[0].uMsr;
2973 uint32_t iRange = uMsr - uMsrBase;
2974 Assert(cMax > iRange);
2975 cMax -= iRange;
2976
2977 /* Resolve default function name. */
2978 if (!pszRdWrFnName)
2979 {
2980 pszRdWrFnName = getMsrFnName(uMsr, NULL);
2981 if (!pszRdWrFnName)
2982 return RTMsgErrorRc(VERR_INVALID_PARAMETER, "uMsr=%#x no function name\n", uMsr);
2983 }
2984
2985 /* Figure the possible register count. */
2986 if (cMax > cMsrs)
2987 cMax = cMsrs;
2988 uint32_t cRegs = 1;
2989 while ( cRegs < cMax
2990 && paMsrs[cRegs].uMsr == uMsr + cRegs)
2991 cRegs++;
2992
2993 /* Probe the first register and check that the others exhibit
2994 the same characteristics. */
2995 bool fReadOnly0;
2996 uint64_t fIgnMask0, fGpMask0;
2997 int rc = msrProberModifyBasicTests(uMsr, fSkipMask, &fReadOnly0, &fIgnMask0, &fGpMask0);
2998 if (RT_FAILURE(rc))
2999 return rc;
3000
3001 const char *pszAnnotation = NULL;
3002 for (uint32_t i = 1; i < cRegs; i++)
3003 {
3004 bool fReadOnlyN;
3005 uint64_t fIgnMaskN, fGpMaskN;
3006 rc = msrProberModifyBasicTests(paMsrs[i].uMsr, fSkipMask, &fReadOnlyN, &fIgnMaskN, &fGpMaskN);
3007 if (RT_FAILURE(rc))
3008 return rc;
3009 if ( fReadOnlyN != fReadOnly0
3010 || (fIgnMaskN != fIgnMask0 && !fNoIgnMask)
3011 || fGpMaskN != fGpMask0)
3012 {
3013 if (!fEarlyEndOk && !isMsrViaDummy(uMsr, paMsrs[i].uValue, paMsrs[i].fFlags))
3014 {
3015 vbCpuRepDebug("MSR %s (%#x) range ended unexpectedly early on %#x: ro=%d ign=%#llx/%#llx gp=%#llx/%#llx [N/0]\n",
3016 getMsrNameHandled(uMsr), uMsr, paMsrs[i].uMsr,
3017 fReadOnlyN, fReadOnly0, fIgnMaskN, fIgnMask0, fGpMaskN, fGpMask0);
3018 pszAnnotation = "XXX: The range ended earlier than expected!";
3019 }
3020 cRegs = i;
3021 break;
3022 }
3023 }
3024
3025 /*
3026 * Report the range (or single MSR as it might be).
3027 */
3028 *pidxLoop += cRegs - 1;
3029
3030 if (fNoIgnMask)
3031 fIgnMask0 = 0;
3032 bool fSimple = fIgnMask0 == 0
3033 && (fGpMask0 == 0 || (fGpMask0 == UINT64_MAX && fReadOnly0))
3034 && iRange == 0;
3035 if (cRegs == 1)
3036 return printMsrFunctionExtendedIdxVal(uMsr, pszRdWrFnName, fReadOnly0 ? "ReadOnly" : pszRdWrFnName,
3037 iRange, fIgnMask0, fGpMask0,
3038 pszAnnotation ? pszAnnotation : annotateValue(paMsrs[0].uValue));
3039 if (fSimple)
3040 return printMsrRangeFunction(uMsr, uMsr + cRegs - 1,
3041 pszRdWrFnName, fReadOnly0 ? "ReadOnly" : pszRdWrFnName, pszAnnotation);
3042
3043 return printMsrRangeFunctionExIdxVal(uMsr, uMsr + cRegs - 1, pszRdWrFnName, fReadOnly0 ? "ReadOnly" : pszRdWrFnName,
3044 iRange /*uValue*/, fIgnMask0, fGpMask0, pszAnnotation);
3045}
3046
3047
3048static int reportMsr_GenRangeFunction(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t cMax, const char *pszRdWrFnName,
3049 uint32_t *pidxLoop)
3050{
3051 return reportMsr_GenRangeFunctionEx(paMsrs, cMsrs, cMax, pszRdWrFnName, paMsrs[0].uMsr, false /*fEarlyEndOk*/, false /*fNoIgnMask*/,
3052 getGenericSkipMask(paMsrs[0].uMsr), pidxLoop);
3053}
3054
3055
3056/**
3057 * Generic report for an MSR implemented by functions, extended version.
3058 *
3059 * @returns VBox status code.
3060 * @param uMsr The MSR.
3061 * @param pszRdWrFnName The read/write function name, optional.
3062 * @param uValue The MSR range value.
3063 * @param fSkipMask Mask of bits to skip.
3064 * @param fNoGpMask Mask of bits to remove from the GP mask after
3065 * probing
3066 * @param pszAnnotate Annotation.
3067 */
3068static int reportMsr_GenFunctionEx(uint32_t uMsr, const char *pszRdWrFnName, uint32_t uValue,
3069 uint64_t fSkipMask, uint64_t fNoGpMask, const char *pszAnnotate)
3070{
3071 /* Resolve default function name. */
3072 if (!pszRdWrFnName)
3073 {
3074 pszRdWrFnName = getMsrFnName(uMsr, NULL);
3075 if (!pszRdWrFnName)
3076 return RTMsgErrorRc(VERR_INVALID_PARAMETER, "uMsr=%#x no function name\n", uMsr);
3077 }
3078
3079 /* Probe the register and report. */
3080 uint64_t fIgnMask = 0;
3081 uint64_t fGpMask = 0;
3082 int rc = msrProberModifyBitChanges(uMsr, &fIgnMask, &fGpMask, fSkipMask);
3083 if (RT_SUCCESS(rc))
3084 {
3085 fGpMask &= ~fNoGpMask;
3086
3087 if (fGpMask == UINT64_MAX && uValue == 0 && !msrProberModifyZero(uMsr))
3088 rc = printMsrFunctionReadOnly(uMsr, pszRdWrFnName, pszAnnotate);
3089 else if (fIgnMask == UINT64_MAX && fGpMask == 0 && uValue == 0)
3090 rc = printMsrFunctionIgnoreWrites(uMsr, pszRdWrFnName, pszAnnotate);
3091 else if (fIgnMask != 0 && fGpMask == 0 && uValue == 0)
3092 rc = printMsrFunctionIgnoreMask(uMsr, pszRdWrFnName, NULL, fIgnMask, pszAnnotate);
3093 else if (fIgnMask == 0 && fGpMask == 0 && uValue == 0)
3094 rc = printMsrFunction(uMsr, pszRdWrFnName, NULL, pszAnnotate);
3095 else
3096 rc = printMsrFunctionExtended(uMsr, pszRdWrFnName, NULL, uValue, fIgnMask, fGpMask, pszAnnotate);
3097 }
3098 return rc;
3099}
3100
3101
3102/**
3103 * Reports a VIA dummy range.
3104 *
3105 * @returns VBox status code.
3106 * @param paMsrs Pointer to the first MSR.
3107 * @param cMsrs The number of MSRs in the array @a paMsr.
3108 * @param pidxLoop Index variable that should be advanced to the
3109 * last MSR entry in the range.
3110 */
3111static int reportMsr_ViaDummyRange(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t *pidxLoop)
3112{
3113 /* Figure how many. */
3114 uint32_t uMsr = paMsrs[0].uMsr;
3115 uint32_t cRegs = 1;
3116 while ( cRegs < cMsrs
3117 && paMsrs[cRegs].uMsr == uMsr + cRegs
3118 && isMsrViaDummy(paMsrs[cRegs].uMsr, paMsrs[cRegs].uValue, paMsrs[cRegs].fFlags))
3119 {
3120 cRegs++;
3121 if (!(cRegs % 0x80))
3122 vbCpuRepDebug("VIA dummy detection %#llx..%#llx (%#x regs)...\n", uMsr, uMsr + cRegs - 1, cRegs);
3123 }
3124
3125 /* Advance. */
3126 *pidxLoop += cRegs - 1;
3127
3128 /* Report it/them. */
3129 char szName[80];
3130 if (cRegs == 1)
3131 {
3132 RTStrPrintf(szName, sizeof(szName), "ZERO_%04x_%04x", RT_HI_U16(uMsr), RT_LO_U16(uMsr));
3133 return printMsrValueIgnoreWritesNamed(uMsr, 0, szName, NULL);
3134 }
3135
3136 uint32_t uMsrLast = uMsr + cRegs - 1;
3137 RTStrPrintf(szName, sizeof(szName), "ZERO_%04x_%04x_THRU_%04x_%04x",
3138 RT_HI_U16(uMsr), RT_LO_U16(uMsr), RT_HI_U16(uMsrLast), RT_LO_U16(uMsrLast));
3139 return printMsrRangeValueIgnoreWritesNamed(uMsr, uMsrLast, 0, szName, NULL);
3140}
3141
3142
3143/**
3144 * Special function for reporting the IA32_APIC_BASE register, as it seems to be
3145 * causing trouble on newer systems.
3146 *
3147 * @returns
3148 * @param uMsr The MSR number.
3149 * @param uValue The value.
3150 */
3151static int reportMsr_Ia32ApicBase(uint32_t uMsr, uint64_t uValue)
3152{
3153 /* Trouble with the generic treatment of both the "APIC Global Enable" and
3154 "Enable x2APIC mode" bits on an i7-3820QM running OS X 10.8.5. */
3155 uint64_t fSkipMask = RT_BIT_64(11);
3156 if (vbCpuRepSupportsX2Apic())
3157 fSkipMask |= RT_BIT_64(10);
3158 return reportMsr_GenFunctionEx(uMsr, "Ia32ApicBase", uValue, fSkipMask, 0, NULL);
3159}
3160
3161
3162/**
3163 * Special function for reporting the IA32_MISC_ENABLE register, as it seems to
3164 * be causing trouble on newer systems.
3165 *
3166 * @returns
3167 * @param uMsr The MSR number.
3168 * @param uValue The value.
3169 */
3170static int reportMsr_Ia32MiscEnable(uint32_t uMsr, uint64_t uValue)
3171{
3172 uint64_t fSkipMask = 0;
3173
3174 if ( ( g_enmMicroarch >= kCpumMicroarch_Intel_Core7_Broadwell
3175 && g_enmMicroarch <= kCpumMicroarch_Intel_Core7_End)
3176 || ( g_enmMicroarch >= kCpumMicroarch_Intel_Atom_Airmount
3177 && g_enmMicroarch <= kCpumMicroarch_Intel_Atom_End)
3178 )
3179 {
3180 vbCpuRepPrintf("WARNING: IA32_MISC_ENABLE probing needs hacking on this CPU!\n");
3181 RTThreadSleep(128);
3182 }
3183
3184 /* The no execute related flag is deadly if clear. */
3185 if ( !(uValue & MSR_IA32_MISC_ENABLE_XD_DISABLE)
3186 && ( g_enmMicroarch < kCpumMicroarch_Intel_First
3187 || g_enmMicroarch >= kCpumMicroarch_Intel_Core_Yonah
3188 || vbCpuRepSupportsNX() ) )
3189 fSkipMask |= MSR_IA32_MISC_ENABLE_XD_DISABLE;
3190
3191 uint64_t fIgnMask = 0;
3192 uint64_t fGpMask = 0;
3193 int rc = msrProberModifyBitChanges(uMsr, &fIgnMask, &fGpMask, fSkipMask);
3194 if (RT_SUCCESS(rc))
3195 rc = printMsrFunctionExtended(uMsr, "Ia32MiscEnable", "Ia32MiscEnable", uValue,
3196 fIgnMask, fGpMask, annotateValue(uValue));
3197 return rc;
3198}
3199
3200
3201/**
3202 * Verifies that MTRR type field works correctly in the given MSR.
3203 *
3204 * @returns VBox status code (failure if bad MSR behavior).
3205 * @param uMsr The MSR.
3206 * @param iBit The first bit of the type field (8-bit wide).
3207 * @param cExpected The number of types expected - PAT=8, MTRR=7.
3208 */
3209static int msrVerifyMtrrTypeGPs(uint32_t uMsr, uint32_t iBit, uint32_t cExpected)
3210{
3211 uint32_t uEndTypes = 0;
3212 while (uEndTypes < 255)
3213 {
3214 bool fGp = !msrProberModifySimpleGp(uMsr, ~(UINT64_C(0xff) << iBit), (uint64_t)uEndTypes << iBit);
3215 if (!fGp && (uEndTypes == 2 || uEndTypes == 3))
3216 return RTMsgErrorRc(VERR_INVALID_PARAMETER, "MTRR types %u does not cause a GP as it should. (msr %#x)\n",
3217 uEndTypes, uMsr);
3218 if (fGp && uEndTypes != 2 && uEndTypes != 3)
3219 break;
3220 uEndTypes++;
3221 }
3222 if (uEndTypes != cExpected)
3223 return RTMsgErrorRc(VERR_INVALID_PARAMETER, "MTRR types detected to be %#x (msr %#x). Expected %#x.\n",
3224 uEndTypes, uMsr, cExpected);
3225 return VINF_SUCCESS;
3226}
3227
3228
3229/**
3230 * Deals with the variable MTRR MSRs.
3231 *
3232 * @returns VBox status code.
3233 * @param paMsrs Pointer to the first variable MTRR MSR (200h).
3234 * @param cMsrs The number of MSRs in the array @a paMsr.
3235 * @param pidxLoop Index variable that should be advanced to the
3236 * last MTRR MSR entry.
3237 */
3238static int reportMsr_Ia32MtrrPhysBaseMaskN(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t *pidxLoop)
3239{
3240 uint32_t uMsr = paMsrs[0].uMsr;
3241
3242 /* Count them. */
3243 uint32_t cRegs = 1;
3244 while ( cRegs < cMsrs
3245 && paMsrs[cRegs].uMsr == uMsr + cRegs
3246 && !isMsrViaDummy(paMsrs[cRegs].uMsr, paMsrs[cRegs].uValue, paMsrs[cRegs].fFlags) )
3247 cRegs++;
3248 if (cRegs & 1)
3249 return RTMsgErrorRc(VERR_INVALID_PARAMETER, "MTRR variable MSR range is odd: cRegs=%#x\n", cRegs);
3250 if (cRegs > 0x20)
3251 return RTMsgErrorRc(VERR_INVALID_PARAMETER, "MTRR variable MSR range is too large: cRegs=%#x\n", cRegs);
3252
3253 /* Find a disabled register that we can play around with. */
3254 uint32_t iGuineaPig;
3255 for (iGuineaPig = 0; iGuineaPig < cRegs; iGuineaPig += 2)
3256 if (!(paMsrs[iGuineaPig + 1].uValue & RT_BIT_32(11)))
3257 break;
3258 if (iGuineaPig >= cRegs)
3259 iGuineaPig = cRegs - 2;
3260 vbCpuRepDebug("iGuineaPig=%#x -> %#x\n", iGuineaPig, uMsr + iGuineaPig);
3261
3262 /* Probe the base. */
3263 uint64_t fIgnBase = 0;
3264 uint64_t fGpBase = 0;
3265 int rc = msrProberModifyBitChanges(uMsr + iGuineaPig, &fIgnBase, &fGpBase, 0);
3266 if (RT_FAILURE(rc))
3267 return rc;
3268 rc = msrVerifyMtrrTypeGPs(uMsr + iGuineaPig, 0, 7);
3269 if (RT_FAILURE(rc))
3270 return rc;
3271 vbCpuRepDebug("fIgnBase=%#llx fGpBase=%#llx\n", fIgnBase, fGpBase);
3272
3273 /* Probing the mask is relatively straight forward. */
3274 uint64_t fIgnMask = 0;
3275 uint64_t fGpMask = 0;
3276 rc = msrProberModifyBitChanges(uMsr + iGuineaPig + 1, &fIgnMask, &fGpMask, 0);
3277 if (RT_FAILURE(rc))
3278 return rc;
3279 vbCpuRepDebug("fIgnMask=%#llx fGpMask=%#llx\n", fIgnMask, fGpMask);
3280
3281 /* Validate that the whole range subscribes to the apprimately same GP rules. */
3282 for (uint32_t i = 0; i < cRegs; i += 2)
3283 {
3284 uint64_t fSkipBase = ~fGpBase;
3285 uint64_t fSkipMask = ~fGpMask;
3286 if (!(paMsrs[i + 1].uValue & RT_BIT_32(11)))
3287 fSkipBase = fSkipMask = 0;
3288 fSkipBase |= 0x7; /* Always skip the type. */
3289 fSkipMask |= RT_BIT_32(11); /* Always skip the enable bit. */
3290
3291 vbCpuRepDebug("i=%#x fSkipBase=%#llx fSkipMask=%#llx\n", i, fSkipBase, fSkipMask);
3292
3293 if (!(paMsrs[i + 1].uValue & RT_BIT_32(11)))
3294 {
3295 rc = msrVerifyMtrrTypeGPs(uMsr + iGuineaPig, 0, 7);
3296 if (RT_FAILURE(rc))
3297 return rc;
3298 }
3299
3300 uint64_t fIgnBaseN = 0;
3301 uint64_t fGpBaseN = 0;
3302 rc = msrProberModifyBitChanges(uMsr + i, &fIgnBaseN, &fGpBaseN, fSkipBase);
3303 if (RT_FAILURE(rc))
3304 return rc;
3305
3306 if ( fIgnBaseN != (fIgnBase & ~fSkipBase)
3307 || fGpBaseN != (fGpBase & ~fSkipBase) )
3308 return RTMsgErrorRc(VERR_INVALID_PARAMETER,
3309 "MTRR PHYS BASE register %#x behaves differently from %#x: ign=%#llx/%#llx gp=%#llx/%#llx (fSkipBase=%#llx)\n",
3310 uMsr + i, uMsr + iGuineaPig,
3311 fIgnBaseN, fIgnBase & ~fSkipBase, fGpBaseN, fGpBase & ~fSkipBase, fSkipBase);
3312
3313 uint64_t fIgnMaskN = 0;
3314 uint64_t fGpMaskN = 0;
3315 rc = msrProberModifyBitChanges(uMsr + i + 1, &fIgnMaskN, &fGpMaskN, fSkipMask);
3316 if (RT_FAILURE(rc))
3317 return rc;
3318 if ( fIgnMaskN != (fIgnMask & ~fSkipMask)
3319 || fGpMaskN != (fGpMask & ~fSkipMask) )
3320 return RTMsgErrorRc(VERR_INVALID_PARAMETER,
3321 "MTRR PHYS MASK register %#x behaves differently from %#x: ign=%#llx/%#llx gp=%#llx/%#llx (fSkipMask=%#llx)\n",
3322 uMsr + i + 1, uMsr + iGuineaPig + 1,
3323 fIgnMaskN, fIgnMask & ~fSkipMask, fGpMaskN, fGpMask & ~fSkipMask, fSkipMask);
3324 }
3325
3326 /* Print the whole range. */
3327 fGpBase &= ~(uint64_t)0x7; /* Valid type bits, see msrVerifyMtrrTypeGPs(). */
3328 for (uint32_t i = 0; i < cRegs; i += 2)
3329 {
3330 printMsrFunctionExtendedIdxVal(uMsr + i, "Ia32MtrrPhysBaseN", NULL, i / 2, fIgnBase, fGpBase,
3331 annotateValue(paMsrs[i].uValue));
3332 printMsrFunctionExtendedIdxVal(uMsr + i + 1, "Ia32MtrrPhysMaskN", NULL, i / 2, fIgnMask, fGpMask,
3333 annotateValue(paMsrs[i + 1].uValue));
3334 }
3335
3336 *pidxLoop += cRegs - 1;
3337 return VINF_SUCCESS;
3338}
3339
3340
3341/**
3342 * Deals with fixed MTRR and PAT MSRs, checking the 8 memory type fields.
3343 *
3344 * @returns VBox status code.
3345 * @param uMsr The MSR.
3346 */
3347static int reportMsr_Ia32MtrrFixedOrPat(uint32_t uMsr)
3348{
3349 /* Had a spot of trouble on an old macbook pro with core2 duo T9900 (penryn)
3350 running 64-bit win81pe. Not giving PAT such a scrutiny fixes it. */
3351 if ( uMsr != 0x00000277
3352 || g_enmMicroarch >= kCpumMicroarch_Intel_Core7_First)
3353 {
3354 /* Every 8 bytes is a type, check the type ranges one by one. */
3355 for (uint32_t iBit = 0; iBit < 64; iBit += 8)
3356 {
3357 int rc = msrVerifyMtrrTypeGPs(uMsr, iBit, 7 + (uMsr == 0x00000277));
3358 if (RT_FAILURE(rc))
3359 return rc;
3360 }
3361 }
3362
3363 return printMsrFunctionCpumCpu(uMsr, NULL, NULL, NULL, NULL);
3364}
3365
3366
3367/**
3368 * Deals with IA32_MTRR_DEF_TYPE.
3369 *
3370 * @returns VBox status code.
3371 * @param uMsr The MSR.
3372 */
3373static int reportMsr_Ia32MtrrDefType(uint32_t uMsr)
3374{
3375 int rc = msrVerifyMtrrTypeGPs(uMsr, 0, 7);
3376 if (RT_FAILURE(rc))
3377 return rc;
3378
3379 uint64_t fGpMask = 0;
3380 uint64_t fIgnMask = 0;
3381 rc = msrProberModifyBitChanges(uMsr, &fIgnMask, &fGpMask, 0x7);
3382 if (RT_FAILURE(rc))
3383 return rc;
3384 Assert(!(fGpMask & 7)); Assert(!(fIgnMask & 7));
3385
3386 return printMsrFunctionCpumCpuEx(uMsr, NULL, NULL, NULL, fIgnMask, fGpMask, NULL);
3387}
3388
3389
3390/**
3391 * Deals with the Machine Check (MC) MSRs in the 400h+ area.
3392 *
3393 * @returns VBox status code.
3394 * @param paMsrs Pointer to the first MC MSR (400h).
3395 * @param cMsrs The number of MSRs in the array @a paMsr.
3396 * @param pidxLoop Index variable that should be advanced to the
3397 * last MC MSR entry.
3398 */
3399static int reportMsr_Ia32McCtlStatusAddrMiscN(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t *pidxLoop)
3400{
3401 uint32_t uMsr = paMsrs[0].uMsr;
3402
3403 /* Count them. */
3404 uint32_t cRegs = 1;
3405 uint32_t cDetectedRegs = 1;
3406 while ( cDetectedRegs < cMsrs
3407 && ( paMsrs[cDetectedRegs].uMsr == uMsr + cRegs
3408 || (cRegs & 3) == 2 /* ADDR may or may not be there, depends on STATUS and CPU. */
3409 || (cRegs & 3) == 3 /* MISC may or may not be there, depends on STATUS and CPU. */)
3410 && cRegs < 0x7f )
3411 {
3412 if (paMsrs[cDetectedRegs].uMsr == uMsr + cRegs)
3413 cDetectedRegs++;
3414 cRegs++;
3415 }
3416 if (cRegs & 3)
3417 return RTMsgErrorRc(VERR_INVALID_PARAMETER, "MC MSR range is odd: cRegs=%#x\n", cRegs);
3418
3419 /* Just report them. We don't bother probing here as the CTL format
3420 and such seems to be a lot of work to test correctly and changes between
3421 cpu generations. */
3422 *pidxLoop += cDetectedRegs - 1;
3423 return printMsrRangeFunction(uMsr, uMsr + cRegs - 1, "Ia32McCtlStatusAddrMiscN", NULL, NULL);
3424}
3425
3426
3427
3428/**
3429 * Deals with the X2APIC msrs.
3430 *
3431 * @returns VBox status code.
3432 * @param paMsrs Pointer to the first X2APIC MSR.
3433 * @param cMsrs The number of MSRs in the array @a paMsr.
3434 * @param pidxLoop Index variable that should be advanced to the
3435 * last X2APIC MSR entry.
3436 */
3437static int reportMsr_GenX2Apic(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t *pidxLoop)
3438{
3439 /* Advance. */
3440 uint32_t cRegs = 1;
3441 while ( cRegs < cMsrs
3442 && paMsrs[cRegs].uMsr <= 0x8ff)
3443 cRegs++;
3444 *pidxLoop += cRegs - 1;
3445
3446 /* Just emit an X2APIC range. */
3447 return printMsrRangeFunction(0x800, 0x8ff, "Ia32X2ApicN", NULL, NULL);
3448}
3449
3450
3451/**
3452 * Deals carefully with the EFER register.
3453 *
3454 * @returns VBox status code.
3455 * @param uMsr The MSR number.
3456 * @param uValue The current value.
3457 */
3458static int reportMsr_Amd64Efer(uint32_t uMsr, uint64_t uValue)
3459{
3460 uint64_t fSkipMask = 0;
3461 if (vbCpuRepSupportsLongMode())
3462 fSkipMask |= MSR_K6_EFER_LME;
3463 if ( (uValue & MSR_K6_EFER_NXE)
3464 || vbCpuRepSupportsNX())
3465 fSkipMask |= MSR_K6_EFER_NXE;
3466
3467 /* NetBurst prescott 2MB (model 4) hung or triple faulted here. The extra
3468 sleep or something seemed to help for some screwed up reason. */
3469 if (g_fIntelNetBurst)
3470 {
3471 // This doesn't matter:
3472 //fSkipMask |= MSR_K6_EFER_SCE;
3473 //if (vbCpuRepSupportsLongMode())
3474 // fSkipMask |= MSR_K6_EFER_LMA;
3475 //vbCpuRepDebug("EFER - netburst workaround - ignore SCE & LMA (fSkipMask=%#llx)\n", fSkipMask);
3476
3477 vbCpuRepDebug("EFER - netburst sleep fudge - fSkipMask=%#llx\n", fSkipMask);
3478 RTThreadSleep(1000);
3479 }
3480
3481 return reportMsr_GenFunctionEx(uMsr, NULL, uValue, fSkipMask, MSR_K6_EFER_LMA, NULL);
3482}
3483
3484
3485/**
3486 * Deals with the MC4_MISCn (n >= 1) range and the following reserved MSRs.
3487 *
3488 * @returns VBox status code.
3489 * @param paMsrs Pointer to the first MSR.
3490 * @param cMsrs The number of MSRs in the array @a paMsr.
3491 * @param pidxLoop Index variable that should be advanced to the
3492 * last MSR entry in the range.
3493 */
3494static int reportMsr_AmdFam10hMc4MiscN(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t *pidxLoop)
3495{
3496 /* Count registers. */
3497 uint32_t cRegs = 1;
3498 while ( cRegs < cMsrs
3499 && cRegs < 8
3500 && paMsrs[cRegs].uMsr == paMsrs[0].uMsr + cRegs)
3501 cRegs++;
3502
3503 /* Probe & report used MSRs. */
3504 uint64_t fIgnMask = 0;
3505 uint64_t fGpMask = 0;
3506 uint32_t cUsed = 0;
3507 while (cUsed < cRegs)
3508 {
3509 uint64_t fIgnMaskN = 0;
3510 uint64_t fGpMaskN = 0;
3511 int rc = msrProberModifyBitChanges(paMsrs[cUsed].uMsr, &fIgnMaskN, &fGpMaskN, 0);
3512 if (RT_FAILURE(rc))
3513 return rc;
3514 if (fIgnMaskN == UINT64_MAX || fGpMaskN == UINT64_MAX)
3515 break;
3516 if (cUsed == 0)
3517 {
3518 fIgnMask = fIgnMaskN;
3519 fGpMask = fGpMaskN;
3520 }
3521 else if ( fIgnMaskN != fIgnMask
3522 || fGpMaskN != fGpMask)
3523 return RTMsgErrorRc(VERR_NOT_EQUAL, "AmdFam16hMc4MiscN mismatch: fIgn=%#llx/%#llx fGp=%#llx/%#llx uMsr=%#x\n",
3524 fIgnMaskN, fIgnMask, fGpMaskN, fGpMask, paMsrs[cUsed].uMsr);
3525 cUsed++;
3526 }
3527 if (cUsed > 0)
3528 printMsrRangeFunctionEx(paMsrs[0].uMsr, paMsrs[cUsed - 1].uMsr, "AmdFam10hMc4MiscN", NULL, 0, fIgnMask, fGpMask, NULL);
3529
3530 /* Probe & report reserved MSRs. */
3531 uint32_t cReserved = 0;
3532 while (cUsed + cReserved < cRegs)
3533 {
3534 fIgnMask = fGpMask = 0;
3535 int rc = msrProberModifyBitChanges(paMsrs[cUsed + cReserved].uMsr, &fIgnMask, &fGpMask, 0);
3536 if (RT_FAILURE(rc))
3537 return rc;
3538 if ((fIgnMask != UINT64_MAX && fGpMask != UINT64_MAX) || paMsrs[cUsed + cReserved].uValue)
3539 return RTMsgErrorRc(VERR_NOT_EQUAL,
3540 "Unexpected reserved AmdFam16hMc4MiscN: fIgn=%#llx fGp=%#llx uMsr=%#x uValue=%#llx\n",
3541 fIgnMask, fGpMask, paMsrs[cUsed + cReserved].uMsr, paMsrs[cUsed + cReserved].uValue);
3542 cReserved++;
3543 }
3544 if (cReserved > 0 && fIgnMask == UINT64_MAX)
3545 printMsrRangeValueIgnoreWrites(paMsrs[cUsed].uMsr, paMsrs[cUsed + cReserved - 1].uMsr, 0, NULL);
3546 else if (cReserved > 0 && fGpMask == UINT64_MAX)
3547 printMsrRangeValueReadOnly(paMsrs[cUsed].uMsr, paMsrs[cUsed + cReserved - 1].uMsr, 0, NULL);
3548
3549 *pidxLoop += cRegs - 1;
3550 return VINF_SUCCESS;
3551}
3552
3553
3554/**
3555 * Deals with the AMD PERF_CTL range.
3556 *
3557 * @returns VBox status code.
3558 * @param paMsrs Pointer to the first MSR.
3559 * @param cMsrs The number of MSRs in the array @a paMsr.
3560 * @param pidxLoop Index variable that should be advanced to the
3561 * last MSR entry in the range.
3562 */
3563static int reportMsr_AmdK8PerfCtlN(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t *pidxLoop)
3564{
3565 uint32_t uMsr = paMsrs[0].uMsr;
3566 Assert(uMsr == 0xc0010000);
3567
3568 /* Family 15h (bulldozer +) aliases these registers sparsely onto c001020x. */
3569 if (CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch))
3570 {
3571 for (uint32_t i = 0; i < 4; i++)
3572 printMsrAlias(uMsr + i, 0xc0010200 + i * 2, NULL);
3573 *pidxLoop += 3;
3574 }
3575 else
3576 return reportMsr_GenRangeFunction(paMsrs, cMsrs, 4, "AmdK8PerfCtlN", pidxLoop);
3577 return VINF_SUCCESS;
3578}
3579
3580
3581/**
3582 * Deals with the AMD PERF_CTR range.
3583 *
3584 * @returns VBox status code.
3585 * @param paMsrs Pointer to the first MSR.
3586 * @param cMsrs The number of MSRs in the array @a paMsr.
3587 * @param pidxLoop Index variable that should be advanced to the
3588 * last MSR entry in the range.
3589 */
3590static int reportMsr_AmdK8PerfCtrN(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t *pidxLoop)
3591{
3592 uint32_t uMsr = paMsrs[0].uMsr;
3593 Assert(uMsr == 0xc0010004);
3594
3595 /* Family 15h (bulldozer +) aliases these registers sparsely onto c001020x. */
3596 if (CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch))
3597 {
3598 for (uint32_t i = 0; i < 4; i++)
3599 printMsrAlias(uMsr + i, 0xc0010201 + i * 2, NULL);
3600 *pidxLoop += 3;
3601 }
3602 else
3603 return reportMsr_GenRangeFunction(paMsrs, cMsrs, 4, "AmdK8PerfCtrN", pidxLoop);
3604 return VINF_SUCCESS;
3605}
3606
3607
3608/**
3609 * Deals carefully with the SYS_CFG register.
3610 *
3611 * @returns VBox status code.
3612 * @param uMsr The MSR number.
3613 * @param uValue The current value.
3614 */
3615static int reportMsr_AmdK8SysCfg(uint32_t uMsr, uint64_t uValue)
3616{
3617 uint64_t fSkipMask = 0;
3618
3619 /* Bit 21 (MtrrTom2En) is marked reserved in family 0fh, while in family
3620 10h BKDG this changes (as does the document style). Testing this bit
3621 causes bulldozer running win64 to restart, thus this special treatment. */
3622 if (g_enmMicroarch >= kCpumMicroarch_AMD_K10)
3623 fSkipMask |= RT_BIT(21);
3624
3625 /* Turns out there are more killer bits here, at least on Opteron 2384.
3626 Skipping all known bits. */
3627 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_65nm /* Not sure when introduced - harmless? */)
3628 fSkipMask |= RT_BIT(22); /* Tom2ForceMemTypeWB */
3629 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_First)
3630 fSkipMask |= RT_BIT(21); /* MtrrTom2En */
3631 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_First)
3632 fSkipMask |= RT_BIT(20); /* MtrrVarDramEn*/
3633 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_First)
3634 fSkipMask |= RT_BIT(19); /* MtrrFixDramModEn */
3635 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_First)
3636 fSkipMask |= RT_BIT(18); /* MtrrFixDramEn */
3637 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_First)
3638 fSkipMask |= RT_BIT(17); /* SysUcLockEn */
3639 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_First)
3640 fSkipMask |= RT_BIT(16); /* ChgToDirtyDis */
3641 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_First && g_enmMicroarch < kCpumMicroarch_AMD_15h_First)
3642 fSkipMask |= RT_BIT(10); /* SetDirtyEnO */
3643 if (g_enmMicroarch >= kCpumMicroarch_AMD_K8_First && g_enmMicroarch < kCpumMicroarch_AMD_15h_First)
3644 fSkipMask |= RT_BIT(9); /* SetDirtyEnS */
3645 if ( CPUMMICROARCH_IS_AMD_FAM_0FH(g_enmMicroarch)
3646 || CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch))
3647 fSkipMask |= RT_BIT(8); /* SetDirtyEnE */
3648 if ( CPUMMICROARCH_IS_AMD_FAM_0FH(g_enmMicroarch)
3649 || CPUMMICROARCH_IS_AMD_FAM_11H(g_enmMicroarch) )
3650 fSkipMask |= RT_BIT(7) /* SysVicLimit */
3651 | RT_BIT(6) /* SysVicLimit */
3652 | RT_BIT(5) /* SysVicLimit */
3653 | RT_BIT(4) /* SysAckLimit */
3654 | RT_BIT(3) /* SysAckLimit */
3655 | RT_BIT(2) /* SysAckLimit */
3656 | RT_BIT(1) /* SysAckLimit */
3657 | RT_BIT(0) /* SysAckLimit */;
3658
3659 return reportMsr_GenFunctionEx(uMsr, NULL, uValue, fSkipMask, 0, annotateValue(uValue));
3660}
3661
3662
3663/**
3664 * Deals carefully with the HWCR register.
3665 *
3666 * @returns VBox status code.
3667 * @param uMsr The MSR number.
3668 * @param uValue The current value.
3669 */
3670static int reportMsr_AmdK8HwCr(uint32_t uMsr, uint64_t uValue)
3671{
3672 uint64_t fSkipMask = 0;
3673
3674 /* Trouble on Opteron 2384, skip some of the known bits. */
3675 if (g_enmMicroarch >= kCpumMicroarch_AMD_K10 && !CPUMMICROARCH_IS_AMD_FAM_11H(g_enmMicroarch))
3676 fSkipMask |= /*RT_BIT(10)*/ 0 /* MonMwaitUserEn */
3677 | RT_BIT(9); /* MonMwaitDis */
3678 fSkipMask |= RT_BIT(8); /* #IGNNE port emulation */
3679 if ( CPUMMICROARCH_IS_AMD_FAM_0FH(g_enmMicroarch)
3680 || CPUMMICROARCH_IS_AMD_FAM_11H(g_enmMicroarch) )
3681 fSkipMask |= RT_BIT(7) /* DisLock */
3682 | RT_BIT(6); /* FFDis (TLB flush filter) */
3683 fSkipMask |= RT_BIT(4); /* INVD to WBINVD */
3684 fSkipMask |= RT_BIT(3); /* TLBCACHEDIS */
3685 if ( CPUMMICROARCH_IS_AMD_FAM_0FH(g_enmMicroarch)
3686 || CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch)
3687 || CPUMMICROARCH_IS_AMD_FAM_11H(g_enmMicroarch) )
3688 fSkipMask |= RT_BIT(1); /* SLOWFENCE */
3689 fSkipMask |= RT_BIT(0); /* SMMLOCK */
3690
3691 return reportMsr_GenFunctionEx(uMsr, NULL, uValue, fSkipMask, 0, annotateValue(uValue));
3692}
3693
3694
3695/**
3696 * Deals carefully with a IORRBasei register.
3697 *
3698 * @returns VBox status code.
3699 * @param uMsr The MSR number.
3700 * @param uValue The current value.
3701 */
3702static int reportMsr_AmdK8IorrBaseN(uint32_t uMsr, uint64_t uValue)
3703{
3704 /* Skip know bits here, as harm seems to come from messing with them. */
3705 uint64_t fSkipMask = RT_BIT(4) | RT_BIT(3);
3706 fSkipMask |= (RT_BIT_64(vbCpuRepGetPhysAddrWidth()) - 1) & X86_PAGE_4K_BASE_MASK;
3707 return reportMsr_GenFunctionEx(uMsr, NULL, (uMsr - 0xc0010016) / 2, fSkipMask, 0, annotateValue(uValue));
3708}
3709
3710
3711/**
3712 * Deals carefully with a IORRMaski register.
3713 *
3714 * @returns VBox status code.
3715 * @param uMsr The MSR number.
3716 * @param uValue The current value.
3717 */
3718static int reportMsr_AmdK8IorrMaskN(uint32_t uMsr, uint64_t uValue)
3719{
3720 /* Skip know bits here, as harm seems to come from messing with them. */
3721 uint64_t fSkipMask = RT_BIT(11);
3722 fSkipMask |= (RT_BIT_64(vbCpuRepGetPhysAddrWidth()) - 1) & X86_PAGE_4K_BASE_MASK;
3723 return reportMsr_GenFunctionEx(uMsr, NULL, (uMsr - 0xc0010017) / 2, fSkipMask, 0, annotateValue(uValue));
3724}
3725
3726
3727/**
3728 * Deals carefully with a IORRMaski register.
3729 *
3730 * @returns VBox status code.
3731 * @param uMsr The MSR number.
3732 * @param uValue The current value.
3733 */
3734static int reportMsr_AmdK8TopMemN(uint32_t uMsr, uint64_t uValue)
3735{
3736 /* Skip know bits here, as harm seems to come from messing with them. */
3737 uint64_t fSkipMask = (RT_BIT_64(vbCpuRepGetPhysAddrWidth()) - 1) & ~(RT_BIT_64(23) - 1);
3738 return reportMsr_GenFunctionEx(uMsr, NULL, uMsr == 0xc001001d, fSkipMask, 0, annotateValue(uValue));
3739}
3740
3741
3742/**
3743 * Deals with the AMD P-state config range.
3744 *
3745 * @returns VBox status code.
3746 * @param paMsrs Pointer to the first MSR.
3747 * @param cMsrs The number of MSRs in the array @a paMsr.
3748 * @param pidxLoop Index variable that should be advanced to the
3749 * last MSR entry in the range.
3750 */
3751static int reportMsr_AmdFam10hPStateN(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t *pidxLoop)
3752{
3753 uint32_t uMsr = paMsrs[0].uMsr;
3754 AssertRelease(uMsr == 0xc0010064);
3755
3756 /* Count them. */
3757 uint32_t cRegs = 1;
3758 while ( cRegs < 8
3759 && cRegs < cMsrs
3760 && paMsrs[cRegs].uMsr == uMsr + cRegs)
3761 cRegs++;
3762
3763 /* Figure out which bits we should skip when probing. This is based on
3764 specs and may need adjusting for real life when handy. */
3765 uint64_t fSkipMask = RT_BIT_64(63); /* PstateEn */
3766 fSkipMask |= RT_BIT_64(41) | RT_BIT_64(40); /* IddDiv */
3767 fSkipMask |= UINT64_C(0x000000ff00000000); /* IddValue */
3768 if (CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch))
3769 fSkipMask |= UINT32_C(0xfe000000); /* NbVid - Northbridge VID */
3770 if ( CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch)
3771 || CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch))
3772 fSkipMask |= RT_BIT_32(22); /* NbDid or NbPstate. */
3773 if (g_enmMicroarch >= kCpumMicroarch_AMD_15h_Piledriver) /* ?? - listed in 10-1Fh model BDKG as well asFam16h */
3774 fSkipMask |= RT_BIT_32(16); /* CpuVid[7] */
3775 fSkipMask |= UINT32_C(0x0000fe00); /* CpuVid[6:0] */
3776 fSkipMask |= UINT32_C(0x000001c0); /* CpuDid */
3777 fSkipMask |= UINT32_C(0x0000003f); /* CpuFid */
3778
3779 /* Probe and report them one by one since we're passing values instead of
3780 register indexes to the functions. */
3781 for (uint32_t i = 0; i < cRegs; i++)
3782 {
3783 uint64_t fIgnMask = 0;
3784 uint64_t fGpMask = 0;
3785 int rc = msrProberModifyBitChanges(uMsr + i, &fIgnMask, &fGpMask, fSkipMask);
3786 if (RT_FAILURE(rc))
3787 return rc;
3788 printMsrFunctionExtended(uMsr + i, "AmdFam10hPStateN", NULL, paMsrs[i].uValue, fIgnMask, fGpMask,
3789 annotateValue(paMsrs[i].uValue));
3790 }
3791
3792 /* Advance. */
3793 *pidxLoop += cRegs - 1;
3794 return VINF_SUCCESS;
3795}
3796
3797
3798/**
3799 * Deals carefully with a COFVID control register.
3800 *
3801 * @returns VBox status code.
3802 * @param uMsr The MSR number.
3803 * @param uValue The current value.
3804 */
3805static int reportMsr_AmdFam10hCofVidControl(uint32_t uMsr, uint64_t uValue)
3806{
3807 /* Skip know bits here, as harm seems to come from messing with them. */
3808 uint64_t fSkipMask = 0;
3809 if (CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch))
3810 fSkipMask |= UINT32_C(0xfe000000); /* NbVid - Northbridge VID */
3811 else if (g_enmMicroarch >= kCpumMicroarch_AMD_15h_First) /* Listed in preliminary Fam16h BDKG. */
3812 fSkipMask |= UINT32_C(0xff000000); /* NbVid - Northbridge VID - includes bit 24 for Fam15h and Fam16h. Odd... */
3813 if ( CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch)
3814 || g_enmMicroarch >= kCpumMicroarch_AMD_15h_First) /* Listed in preliminary Fam16h BDKG. */
3815 fSkipMask |= RT_BIT_32(22); /* NbDid or NbPstate. */
3816 if (g_enmMicroarch >= kCpumMicroarch_AMD_15h_Piledriver) /* ?? - listed in 10-1Fh model BDKG as well asFam16h */
3817 fSkipMask |= RT_BIT_32(20); /* CpuVid[7] */
3818 fSkipMask |= UINT32_C(0x00070000); /* PstatId */
3819 fSkipMask |= UINT32_C(0x0000fe00); /* CpuVid[6:0] */
3820 fSkipMask |= UINT32_C(0x000001c0); /* CpuDid */
3821 fSkipMask |= UINT32_C(0x0000003f); /* CpuFid */
3822
3823 return reportMsr_GenFunctionEx(uMsr, NULL, uValue, fSkipMask, 0, annotateValue(uValue));
3824}
3825
3826
3827/**
3828 * Deals with the AMD [|L2I_|NB_]PERF_CT[LR] mixed ranges.
3829 *
3830 * Mixed here refers to the control and counter being in mixed in pairs as
3831 * opposed to them being two separate parallel arrays like in the 0xc0010000
3832 * area.
3833 *
3834 * @returns VBox status code.
3835 * @param paMsrs Pointer to the first MSR.
3836 * @param cMsrs The number of MSRs in the array @a paMsr.
3837 * @param cMax The max number of MSRs (not counters).
3838 * @param pidxLoop Index variable that should be advanced to the
3839 * last MSR entry in the range.
3840 */
3841static int reportMsr_AmdGenPerfMixedRange(VBCPUREPMSR const *paMsrs, uint32_t cMsrs, uint32_t cMax, uint32_t *pidxLoop)
3842{
3843 uint32_t uMsr = paMsrs[0].uMsr;
3844
3845 /* Count them. */
3846 uint32_t cRegs = 1;
3847 while ( cRegs < cMax
3848 && cRegs < cMsrs
3849 && paMsrs[cRegs].uMsr == uMsr + cRegs)
3850 cRegs++;
3851 if (cRegs & 1)
3852 return RTMsgErrorRc(VERR_INVALID_PARAMETER, "PERF range at %#x is odd: cRegs=%#x\n", uMsr, cRegs);
3853
3854 /* Report them as individual entries, using default names and such. */
3855 for (uint32_t i = 0; i < cRegs; i++)
3856 {
3857 uint64_t fIgnMask = 0;
3858 uint64_t fGpMask = 0;
3859 int rc = msrProberModifyBitChanges(uMsr + i, &fIgnMask, &fGpMask, 0);
3860 if (RT_FAILURE(rc))
3861 return rc;
3862 printMsrFunctionExtendedIdxVal(uMsr + i, NULL, NULL, i / 2, fIgnMask, fGpMask, annotateValue(paMsrs[i].uValue));
3863 }
3864
3865 /* Advance. */
3866 *pidxLoop += cRegs - 1;
3867 return VINF_SUCCESS;
3868}
3869
3870
3871/**
3872 * Deals carefully with a LS_CFG register.
3873 *
3874 * @returns VBox status code.
3875 * @param uMsr The MSR number.
3876 * @param uValue The current value.
3877 */
3878static int reportMsr_AmdK7InstrCacheCfg(uint32_t uMsr, uint64_t uValue)
3879{
3880 /* Skip know bits here, as harm seems to come from messing with them. */
3881 uint64_t fSkipMask = RT_BIT_64(9) /* DIS_SPEC_TLB_RLD */;
3882 if (CPUMMICROARCH_IS_AMD_FAM_10H(g_enmMicroarch))
3883 fSkipMask |= RT_BIT_64(14); /* DIS_IND */
3884 if (CPUMMICROARCH_IS_AMD_FAM_16H(g_enmMicroarch))
3885 fSkipMask |= RT_BIT_64(26); /* DIS_WIDEREAD_PWR_SAVE */
3886 if (CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch))
3887 {
3888 fSkipMask |= 0x1e; /* DisIcWayFilter */
3889 fSkipMask |= RT_BIT_64(39); /* DisLoopPredictor */
3890 fSkipMask |= RT_BIT_64(27); /* Unknown killer bit, possibly applicable to other microarchs. */
3891 fSkipMask |= RT_BIT_64(28); /* Unknown killer bit, possibly applicable to other microarchs. */
3892 }
3893 return reportMsr_GenFunctionEx(uMsr, NULL, uValue, fSkipMask, 0, annotateValue(uValue));
3894}
3895
3896
3897/**
3898 * Deals carefully with a CU_CFG register.
3899 *
3900 * @returns VBox status code.
3901 * @param uMsr The MSR number.
3902 * @param uValue The current value.
3903 */
3904static int reportMsr_AmdFam15hCombUnitCfg(uint32_t uMsr, uint64_t uValue)
3905{
3906 /* Skip know bits here, as harm seems to come from messing with them. */
3907 uint64_t fSkipMask = RT_BIT_64(23) /* L2WayLock */
3908 | RT_BIT_64(22) /* L2FirstLockWay */
3909 | RT_BIT_64(21) /* L2FirstLockWay */
3910 | RT_BIT_64(20) /* L2FirstLockWay */
3911 | RT_BIT_64(19) /* L2FirstLockWay */
3912 | RT_BIT_64(10) /* DcacheAggressivePriority */;
3913 fSkipMask |= RT_BIT_64(46) | RT_BIT_64(45); /* Killer field. Seen bit 46 set, 45 clear. Messing with either means reboot/BSOD. */
3914 return reportMsr_GenFunctionEx(uMsr, NULL, uValue, fSkipMask, 0, annotateValue(uValue));
3915}
3916
3917
3918/**
3919 * Deals carefully with a EX_CFG register.
3920 *
3921 * @returns VBox status code.
3922 * @param uMsr The MSR number.
3923 * @param uValue The current value.
3924 */
3925static int reportMsr_AmdFam15hExecUnitCfg(uint32_t uMsr, uint64_t uValue)
3926{
3927 /* Skip know bits here, as harm seems to come from messing with them. */
3928 uint64_t fSkipMask = RT_BIT_64(54) /* LateSbzResync */;
3929 fSkipMask |= RT_BIT_64(35); /* Undocumented killer bit. */
3930 return reportMsr_GenFunctionEx(uMsr, NULL, uValue, fSkipMask, 0, annotateValue(uValue));
3931}
3932
3933
3934
3935static int produceMsrReport(VBCPUREPMSR *paMsrs, uint32_t cMsrs)
3936{
3937 vbCpuRepDebug("produceMsrReport\n");
3938 RTThreadSleep(500);
3939
3940 for (uint32_t i = 0; i < cMsrs; i++)
3941 {
3942 uint32_t uMsr = paMsrs[i].uMsr;
3943 uint32_t fFlags = paMsrs[i].fFlags;
3944 uint64_t uValue = paMsrs[i].uValue;
3945 int rc;
3946#if 0
3947 if (uMsr < 0x00003170)
3948 continue;
3949 if (uMsr >= 0x00003170)
3950 {
3951 vbCpuRepDebug("produceMsrReport: uMsr=%#x (%s)...\n", uMsr, getMsrNameHandled(uMsr));
3952 RTThreadSleep(1000);
3953 }
3954#endif
3955 /*
3956 * Deal with write only regs first to avoid having to avoid them all the time.
3957 */
3958 if (fFlags & VBCPUREPMSR_F_WRITE_ONLY)
3959 {
3960 if (uMsr == 0x00000079)
3961 rc = printMsrWriteOnly(uMsr, NULL, NULL);
3962 else
3963 rc = reportMsr_Generic(uMsr, fFlags, uValue);
3964 }
3965 /*
3966 * VIA implement MSRs in a interesting way, so we have to select what we
3967 * want to handle there to avoid making the code below unreadable.
3968 */
3969 else if (isMsrViaDummy(uMsr, uValue, fFlags))
3970 rc = reportMsr_ViaDummyRange(&paMsrs[i], cMsrs - i, &i);
3971 /*
3972 * This shall be sorted by uMsr as much as possible.
3973 */
3974 else if (uMsr == 0x00000000 && g_enmVendor == CPUMCPUVENDOR_AMD && g_enmMicroarch >= kCpumMicroarch_AMD_K8_First)
3975 rc = printMsrAlias(uMsr, 0x00000402, NULL);
3976 else if (uMsr == 0x00000001 && g_enmVendor == CPUMCPUVENDOR_AMD && g_enmMicroarch >= kCpumMicroarch_AMD_K8_First)
3977 rc = printMsrAlias(uMsr, 0x00000401, NULL); /** @todo not 101% correct on Fam15h and later, 0xc0010015[McstatusWrEn] effect differs. */
3978 else if (uMsr == 0x0000001b)
3979 rc = reportMsr_Ia32ApicBase(uMsr, uValue);
3980 else if (uMsr == 0x00000040 && g_enmMicroarch <= kCpumMicroarch_Intel_P6_M_Dothan)
3981 rc = reportMsr_GenRangeFunction(&paMsrs[i], cMsrs - i, 8 /*cMax*/, "IntelLastBranchFromToN", &i);
3982 else if (uMsr == 0x00000040)
3983 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 8 /*cMax*/, "IntelLastBranchToN", uMsr, false,
3984 true, getGenericSkipMask(uMsr), &i);
3985 else if (uMsr == 0x00000060 && g_enmMicroarch >= kCpumMicroarch_Intel_Core_Yonah)
3986 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 8 /*cMax*/, "IntelLastBranchFromN", uMsr, false,
3987 true, getGenericSkipMask(uMsr), &i);
3988 else if (uMsr == 0x000000c1)
3989 rc = reportMsr_GenRangeFunction(&paMsrs[i], cMsrs - i,
3990 g_enmMicroarch >= kCpumMicroarch_Intel_Core7_First ? 8 : 4 /*cMax*/,
3991 NULL, &i);
3992 else if (uMsr == 0x00000186 && !g_fIntelNetBurst)
3993 rc = reportMsr_GenRangeFunction(&paMsrs[i], cMsrs - i, 8 /*cMax*/, "Ia32PerfEvtSelN", &i);
3994 else if (uMsr == 0x000001a0)
3995 rc = reportMsr_Ia32MiscEnable(uMsr, uValue);
3996 else if (uMsr >= 0x000001a6 && uMsr <= 0x000001a7)
3997 rc = reportMsr_GenRangeFunction(&paMsrs[i], cMsrs - i, 2 /*cMax*/, "IntelI7MsrOffCoreResponseN", &i);
3998 else if (uMsr == 0x000001db && g_fIntelNetBurst)
3999 rc = reportMsr_GenRangeFunction(&paMsrs[i], cMsrs - i, 4 /*cMax*/, "IntelLastBranchFromToN", &i);
4000 else if (uMsr == 0x00000200)
4001 rc = reportMsr_Ia32MtrrPhysBaseMaskN(&paMsrs[i], cMsrs - i, &i);
4002 else if (uMsr >= 0x00000250 && uMsr <= 0x00000279)
4003 rc = reportMsr_Ia32MtrrFixedOrPat(uMsr);
4004 else if (uMsr >= 0x00000280 && uMsr <= 0x00000295)
4005 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 22 /*cMax*/, NULL, 0x00000280, true /*fEarlyEndOk*/, false, 0, &i);
4006 else if (uMsr == 0x000002ff)
4007 rc = reportMsr_Ia32MtrrDefType(uMsr);
4008 else if (uMsr >= 0x00000309 && uMsr <= 0x0000030b && !g_fIntelNetBurst)
4009 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 3 /*cMax*/, NULL, 0x00000309, true /*fEarlyEndOk*/, false, 0, &i);
4010 else if ((uMsr == 0x000003f8 || uMsr == 0x000003fc || uMsr == 0x0000060a) && !g_fIntelNetBurst)
4011 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 4, NULL, uMsr - 3, true, false, 0, &i);
4012 else if ((uMsr == 0x000003f9 || uMsr == 0x000003fd || uMsr == 0x0000060b) && !g_fIntelNetBurst)
4013 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 8, NULL, uMsr - 6, true, false, 0, &i);
4014 else if ((uMsr == 0x000003fa || uMsr == 0x000003fe || uMsr == 0x0000060c) && !g_fIntelNetBurst)
4015 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 8, NULL, uMsr - 7, true, false, 0, &i);
4016 else if (uMsr >= 0x00000400 && uMsr <= 0x00000477)
4017 rc = reportMsr_Ia32McCtlStatusAddrMiscN(&paMsrs[i], cMsrs - i, &i);
4018 else if (uMsr == 0x000004c1)
4019 rc = reportMsr_GenRangeFunction(&paMsrs[i], cMsrs - i, 8, NULL, &i);
4020 else if (uMsr == 0x00000680 || uMsr == 0x000006c0)
4021 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 16, NULL, uMsr, false, false,
4022 g_fIntelNetBurst
4023 ? UINT64_C(0xffffffffffffff00) /* kludge */
4024 : UINT64_C(0xffff800000000000), &i);
4025 else if (uMsr >= 0x00000800 && uMsr <= 0x000008ff)
4026 rc = reportMsr_GenX2Apic(&paMsrs[i], cMsrs - i, &i);
4027 else if (uMsr == 0x00002000 && g_enmVendor == CPUMCPUVENDOR_INTEL)
4028 rc = reportMsr_GenFunctionEx(uMsr, "IntelP6CrN", 0, X86_CR0_PE | X86_CR0_PG, 0,
4029 annotateIfMissingBits(uValue, X86_CR0_PE | X86_CR0_PE | X86_CR0_ET));
4030 else if (uMsr == 0x00002002 && g_enmVendor == CPUMCPUVENDOR_INTEL)
4031 rc = reportMsr_GenFunctionEx(uMsr, "IntelP6CrN", 2, 0, 0, annotateValue(uValue));
4032 else if (uMsr == 0x00002003 && g_enmVendor == CPUMCPUVENDOR_INTEL)
4033 {
4034 uint64_t fCr3Mask = (RT_BIT_64(vbCpuRepGetPhysAddrWidth()) - 1) & (X86_CR3_PAE_PAGE_MASK | X86_CR3_AMD64_PAGE_MASK);
4035 if (!vbCpuRepSupportsPae())
4036 fCr3Mask &= X86_CR3_PAGE_MASK | X86_CR3_AMD64_PAGE_MASK;
4037 rc = reportMsr_GenFunctionEx(uMsr, "IntelP6CrN", 3, fCr3Mask, 0, annotateValue(uValue));
4038 }
4039 else if (uMsr == 0x00002004 && g_enmVendor == CPUMCPUVENDOR_INTEL)
4040 rc = reportMsr_GenFunctionEx(uMsr, "IntelP6CrN", 4,
4041 X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE | X86_CR4_SMXE, 0,
4042 annotateValue(uValue));
4043 else if (uMsr == 0xc0000080)
4044 rc = reportMsr_Amd64Efer(uMsr, uValue);
4045 else if (uMsr == 0xc0000082 || uMsr == 0xc0000083 || uMsr == 0xc0000100 || uMsr == 0xc0000101 || uMsr == 0xc0000102)
4046 rc = reportMsr_GenFunctionEx(uMsr, NULL, 0, UINT64_C(0xffff800000000000), 0, annotateValue(uValue)); /* Canoncial address hack. */
4047 else if (uMsr >= 0xc0000408 && uMsr <= 0xc000040f)
4048 rc = reportMsr_AmdFam10hMc4MiscN(&paMsrs[i], cMsrs - i, &i);
4049 else if (uMsr == 0xc0010000 && g_enmVendor == CPUMCPUVENDOR_AMD)
4050 rc = reportMsr_AmdK8PerfCtlN(&paMsrs[i], cMsrs - i, &i);
4051 else if (uMsr == 0xc0010004 && g_enmVendor == CPUMCPUVENDOR_AMD)
4052 rc = reportMsr_AmdK8PerfCtrN(&paMsrs[i], cMsrs - i, &i);
4053 else if (uMsr == 0xc0010010 && g_enmVendor == CPUMCPUVENDOR_AMD)
4054 rc = reportMsr_AmdK8SysCfg(uMsr, uValue);
4055 else if (uMsr == 0xc0010015 && g_enmVendor == CPUMCPUVENDOR_AMD)
4056 rc = reportMsr_AmdK8HwCr(uMsr, uValue);
4057 else if ((uMsr == 0xc0010016 || uMsr == 0xc0010018) && g_enmVendor == CPUMCPUVENDOR_AMD)
4058 rc = reportMsr_AmdK8IorrBaseN(uMsr, uValue);
4059 else if ((uMsr == 0xc0010017 || uMsr == 0xc0010019) && g_enmVendor == CPUMCPUVENDOR_AMD)
4060 rc = reportMsr_AmdK8IorrMaskN(uMsr, uValue);
4061 else if ((uMsr == 0xc001001a || uMsr == 0xc001001d) && g_enmVendor == CPUMCPUVENDOR_AMD)
4062 rc = reportMsr_AmdK8TopMemN(uMsr, uValue);
4063 else if (uMsr == 0xc0010030 && g_enmVendor == CPUMCPUVENDOR_AMD)
4064 rc = reportMsr_GenRangeFunction(&paMsrs[i], cMsrs - i, 6, "AmdK8CpuNameN", &i);
4065 else if (uMsr >= 0xc0010044 && uMsr <= 0xc001004a && g_enmVendor == CPUMCPUVENDOR_AMD)
4066 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 7, "AmdK8McCtlMaskN", 0xc0010044, true /*fEarlyEndOk*/, false, 0, &i);
4067 else if (uMsr == 0xc0010050 && g_enmVendor == CPUMCPUVENDOR_AMD)
4068 rc = reportMsr_GenRangeFunction(&paMsrs[i], cMsrs - i, 4, "AmdK8SmiOnIoTrapN", &i);
4069 else if (uMsr == 0xc0010064 && g_enmVendor == CPUMCPUVENDOR_AMD)
4070 rc = reportMsr_AmdFam10hPStateN(&paMsrs[i], cMsrs - i, &i);
4071 else if (uMsr == 0xc0010070 && g_enmVendor == CPUMCPUVENDOR_AMD)
4072 rc = reportMsr_AmdFam10hCofVidControl(uMsr, uValue);
4073 else if ((uMsr == 0xc0010118 || uMsr == 0xc0010119) && getMsrFnName(uMsr, NULL) && g_enmVendor == CPUMCPUVENDOR_AMD)
4074 rc = printMsrFunction(uMsr, NULL, NULL, annotateValue(uValue)); /* RAZ, write key. */
4075 else if (uMsr == 0xc0010200 && g_enmVendor == CPUMCPUVENDOR_AMD)
4076 rc = reportMsr_AmdGenPerfMixedRange(&paMsrs[i], cMsrs - i, 12, &i);
4077 else if (uMsr == 0xc0010230 && g_enmVendor == CPUMCPUVENDOR_AMD)
4078 rc = reportMsr_AmdGenPerfMixedRange(&paMsrs[i], cMsrs - i, 8, &i);
4079 else if (uMsr == 0xc0010240 && g_enmVendor == CPUMCPUVENDOR_AMD)
4080 rc = reportMsr_AmdGenPerfMixedRange(&paMsrs[i], cMsrs - i, 8, &i);
4081 else if (uMsr == 0xc0011019 && g_enmMicroarch >= kCpumMicroarch_AMD_15h_Piledriver && g_enmVendor == CPUMCPUVENDOR_AMD)
4082 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 3, "AmdK7DrXAddrMaskN", 0xc0011019 - 1,
4083 false /*fEarlyEndOk*/, false /*fNoIgnMask*/, 0, &i);
4084 else if (uMsr == 0xc0011021 && g_enmVendor == CPUMCPUVENDOR_AMD)
4085 rc = reportMsr_AmdK7InstrCacheCfg(uMsr, uValue);
4086 else if (uMsr == 0xc0011023 && CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch))
4087 rc = reportMsr_AmdFam15hCombUnitCfg(uMsr, uValue);
4088 else if (uMsr == 0xc0011027 && g_enmVendor == CPUMCPUVENDOR_AMD)
4089 rc = reportMsr_GenRangeFunctionEx(&paMsrs[i], cMsrs - i, 1, "AmdK7DrXAddrMaskN", 0xc0011027,
4090 false /*fEarlyEndOk*/, false /*fNoIgnMask*/, 0, &i);
4091 else if (uMsr == 0xc001102c && CPUMMICROARCH_IS_AMD_FAM_15H(g_enmMicroarch))
4092 rc = reportMsr_AmdFam15hExecUnitCfg(uMsr, uValue);
4093 /* generic handling. */
4094 else
4095 rc = reportMsr_Generic(uMsr, fFlags, uValue);
4096
4097 if (RT_FAILURE(rc))
4098 return rc;
4099 }
4100
4101 return VINF_SUCCESS;
4102}
4103
4104
4105/**
4106 * Custom MSR hacking & probing.
4107 *
4108 * Called when the '-d' option is given.
4109 *
4110 * @returns VBox status code.
4111 */
4112static int hackingMsrs(void)
4113{
4114#if 0
4115 vbCpuRepDebug("\nhackingMsrs:\n"); RTStrmFlush(g_pDebugOut); RTThreadSleep(2000);
4116
4117 uint32_t uMsr = 0xc0000081;
4118 vbCpuRepDebug("%#x: msrProberModifyNoChange -> %RTbool\n", uMsr, msrProberModifyNoChange(uMsr));
4119 RTThreadSleep(3000);
4120
4121 vbCpuRepDebug("%#x: msrProberModifyBit 30 -> %d\n", uMsr, msrProberModifyBit(uMsr, 30));
4122 RTThreadSleep(3000);
4123
4124 vbCpuRepDebug("%#x: msrProberModifyZero -> %RTbool\n", uMsr, msrProberModifyZero(uMsr));
4125 RTThreadSleep(3000);
4126
4127 for (uint32_t i = 0; i < 63; i++)
4128 {
4129 vbCpuRepDebug("%#x: bit=%02u -> %d\n", msrProberModifyBit(uMsr, i));
4130 RTThreadSleep(500);
4131 }
4132#else
4133
4134 uint32_t uMsr = 0xc0000080;
4135 uint64_t uValue = 0;
4136 msrProberRead(uMsr, &uValue);
4137 /* Try for a triple fault... */
4138 msrProberWrite(uMsr, uValue ^ MSR_K6_EFER_LME);
4139 msrProberRead(uMsr, &uValue);
4140 msrProberWrite(uMsr, uValue ^ MSR_K6_EFER_NXE);
4141#endif
4142 return VINF_SUCCESS;
4143}
4144
4145
4146static int probeMsrs(bool fHacking, const char *pszNameC, const char *pszCpuDesc,
4147 char *pszMsrMask, size_t cbMsrMask)
4148{
4149 /* Initialize the mask. */
4150 if (pszMsrMask && cbMsrMask)
4151 RTStrCopy(pszMsrMask, cbMsrMask, "UINT32_MAX /** @todo */");
4152
4153 /*
4154 * Are MSRs supported by the CPU?
4155 */
4156 if ( !ASMIsValidStdRange(ASMCpuId_EAX(0))
4157 || !(ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_MSR) )
4158 {
4159 vbCpuRepDebug("Skipping MSR probing, CPUID indicates there isn't any MSR support.\n");
4160 return VINF_SUCCESS;
4161 }
4162
4163 /*
4164 * Initialize the support library and check if we can read MSRs.
4165 */
4166 int rc = SUPR3Init(NULL);
4167 if (RT_FAILURE(rc))
4168 {
4169 vbCpuRepDebug("warning: Unable to initialize the support library (%Rrc), skipping MSR detection.\n", rc);
4170 return VINF_SUCCESS;
4171 }
4172 uint64_t uValue;
4173 bool fGp;
4174 rc = SUPR3MsrProberRead(MSR_IA32_TSC, NIL_RTCPUID, &uValue, &fGp);
4175 if (RT_FAILURE(rc))
4176 {
4177 vbCpuRepDebug("warning: MSR probing not supported by the support driver (%Rrc), skipping MSR detection.\n", rc);
4178 return VINF_SUCCESS;
4179 }
4180 vbCpuRepDebug("MSR_IA32_TSC: %#llx fGp=%RTbool\n", uValue, fGp);
4181 rc = SUPR3MsrProberRead(0xdeadface, NIL_RTCPUID, &uValue, &fGp);
4182 vbCpuRepDebug("0xdeadface: %#llx fGp=%RTbool rc=%Rrc\n", uValue, fGp, rc);
4183
4184 /*
4185 * Initialize globals we use.
4186 */
4187 uint32_t uEax, uEbx, uEcx, uEdx;
4188 ASMCpuIdExSlow(0, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
4189 if (!ASMIsValidStdRange(uEax))
4190 return RTMsgErrorRc(VERR_NOT_SUPPORTED, "Invalid std CPUID range: %#x\n", uEax);
4191 g_enmVendor = CPUMR3CpuIdDetectVendorEx(uEax, uEbx, uEcx, uEdx);
4192
4193 ASMCpuIdExSlow(1, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
4194 g_enmMicroarch = CPUMR3CpuIdDetermineMicroarchEx(g_enmVendor,
4195 ASMGetCpuFamily(uEax),
4196 ASMGetCpuModel(uEax, g_enmVendor == CPUMCPUVENDOR_INTEL),
4197 ASMGetCpuStepping(uEax));
4198 g_fIntelNetBurst = CPUMMICROARCH_IS_INTEL_NETBURST(g_enmMicroarch);
4199
4200 /*
4201 * Do the probing.
4202 */
4203 if (fHacking)
4204 rc = hackingMsrs();
4205 else
4206 {
4207 /* Determine the MSR mask. */
4208 uint32_t fMsrMask = determineMsrAndMask();
4209 if (fMsrMask == UINT32_MAX)
4210 RTStrCopy(pszMsrMask, cbMsrMask, "UINT32_MAX");
4211 else
4212 RTStrPrintf(pszMsrMask, cbMsrMask, "UINT32_C(%#x)", fMsrMask);
4213
4214 /* Detect MSR. */
4215 VBCPUREPMSR *paMsrs;
4216 uint32_t cMsrs;
4217 rc = findMsrs(&paMsrs, &cMsrs, fMsrMask);
4218 if (RT_FAILURE(rc))
4219 return rc;
4220
4221 /* Probe the MSRs and spit out the database table. */
4222 vbCpuRepPrintf("\n"
4223 "#ifndef CPUM_DB_STANDALONE\n"
4224 "/**\n"
4225 " * MSR ranges for %s.\n"
4226 " */\n"
4227 "static CPUMMSRRANGE const g_aMsrRanges_%s[] = \n{\n",
4228 pszCpuDesc,
4229 pszNameC);
4230 rc = produceMsrReport(paMsrs, cMsrs);
4231 vbCpuRepPrintf("};\n"
4232 "#endif /* !CPUM_DB_STANDALONE */\n"
4233 "\n"
4234 );
4235
4236 RTMemFree(paMsrs);
4237 paMsrs = NULL;
4238 }
4239 return rc;
4240}
4241
4242
4243static int produceCpuIdArray(const char *pszNameC, const char *pszCpuDesc)
4244{
4245 /*
4246 * Collect the data.
4247 */
4248 PCPUMCPUIDLEAF paLeaves;
4249 uint32_t cLeaves;
4250 int rc = CPUMR3CpuIdCollectLeaves(&paLeaves, &cLeaves);
4251 if (RT_FAILURE(rc))
4252 return RTMsgErrorRc(rc, "CPUMR3CollectCpuIdInfo failed: %Rrc\n", rc);
4253
4254 /*
4255 * Dump the array.
4256 */
4257 vbCpuRepPrintf("\n"
4258 "#ifndef CPUM_DB_STANDALONE\n"
4259 "/**\n"
4260 " * CPUID leaves for %s.\n"
4261 " */\n"
4262 "static CPUMCPUIDLEAF const g_aCpuIdLeaves_%s[] = \n{\n",
4263 pszCpuDesc,
4264 pszNameC);
4265 for (uint32_t i = 0; i < cLeaves; i++)
4266 {
4267 vbCpuRepPrintf(" { %#010x, %#010x, ", paLeaves[i].uLeaf, paLeaves[i].uSubLeaf);
4268 if (paLeaves[i].fSubLeafMask == UINT32_MAX)
4269 vbCpuRepPrintf("UINT32_MAX, ");
4270 else
4271 vbCpuRepPrintf("%#010x, ", paLeaves[i].fSubLeafMask);
4272 vbCpuRepPrintf("%#010x, %#010x, %#010x, %#010x, ",
4273 paLeaves[i].uEax, paLeaves[i].uEbx, paLeaves[i].uEcx, paLeaves[i].uEdx);
4274 if (paLeaves[i].fFlags == 0)
4275 vbCpuRepPrintf("0 },\n");
4276 else
4277 {
4278 vbCpuRepPrintf("0");
4279 uint32_t fFlags = paLeaves[i].fFlags;
4280 if (paLeaves[i].fFlags & CPUMCPUIDLEAF_F_SUBLEAVES_ECX_UNCHANGED)
4281 {
4282 vbCpuRepPrintf(" | CPUMCPUIDLEAF_F_SUBLEAVES_ECX_UNCHANGED");
4283 fFlags &= ~CPUMCPUIDLEAF_F_SUBLEAVES_ECX_UNCHANGED;
4284 }
4285 if (fFlags)
4286 {
4287 RTMemFree(paLeaves);
4288 return RTMsgErrorRc(rc, "Unknown CPUID flags %#x\n", fFlags);
4289 }
4290 vbCpuRepPrintf(" },\n");
4291 }
4292 }
4293 vbCpuRepPrintf("};\n"
4294 "#endif /* !CPUM_DB_STANDALONE */\n"
4295 "\n");
4296 RTMemFree(paLeaves);
4297 return VINF_SUCCESS;
4298}
4299
4300
4301static const char *cpuVendorToString(CPUMCPUVENDOR enmCpuVendor)
4302{
4303 switch (enmCpuVendor)
4304 {
4305 case CPUMCPUVENDOR_INTEL: return "Intel";
4306 case CPUMCPUVENDOR_AMD: return "AMD";
4307 case CPUMCPUVENDOR_VIA: return "VIA";
4308 case CPUMCPUVENDOR_CYRIX: return "Cyrix";
4309 case CPUMCPUVENDOR_INVALID:
4310 case CPUMCPUVENDOR_UNKNOWN:
4311 case CPUMCPUVENDOR_32BIT_HACK:
4312 break;
4313 }
4314 return "invalid-cpu-vendor";
4315}
4316
4317
4318static int produceCpuReport(void)
4319{
4320 /*
4321 * Figure the cpu vendor.
4322 */
4323 if (!ASMHasCpuId())
4324 return RTMsgErrorRc(VERR_NOT_SUPPORTED, "No CPUID support.\n");
4325 uint32_t uEax, uEbx, uEcx, uEdx;
4326 ASMCpuIdExSlow(0, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
4327 if (!ASMIsValidStdRange(uEax))
4328 return RTMsgErrorRc(VERR_NOT_SUPPORTED, "Invalid std CPUID range: %#x\n", uEax);
4329
4330 CPUMCPUVENDOR enmVendor = CPUMR3CpuIdDetectVendorEx(uEax, uEbx, uEcx, uEdx);
4331 if (enmVendor == CPUMCPUVENDOR_UNKNOWN)
4332 return RTMsgErrorRc(VERR_NOT_IMPLEMENTED, "Unknown CPU vendor: %.4s%.4s%.4s\n", &uEbx, &uEdx, &uEcx);
4333 vbCpuRepDebug("CPU Vendor: %s - %.4s%.4s%.4s\n", CPUMR3CpuVendorName(enmVendor), &uEbx, &uEdx, &uEcx);
4334
4335 /*
4336 * Determine the micro arch.
4337 */
4338 ASMCpuIdExSlow(1, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
4339 CPUMMICROARCH enmMicroarch = CPUMR3CpuIdDetermineMicroarchEx(enmVendor,
4340 ASMGetCpuFamily(uEax),
4341 ASMGetCpuModel(uEax, enmVendor == CPUMCPUVENDOR_INTEL),
4342 ASMGetCpuStepping(uEax));
4343
4344 /*
4345 * Generate a name.
4346 */
4347 char szName[16*3+1];
4348 char szNameC[16*3+1];
4349 char szNameRaw[16*3+1];
4350 char *pszName = szName;
4351 char *pszCpuDesc = (char *)"";
4352
4353 ASMCpuIdExSlow(0x80000000, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
4354 if (ASMIsValidExtRange(uEax) && uEax >= UINT32_C(0x80000004))
4355 {
4356 /* Get the raw name and strip leading spaces. */
4357 ASMCpuIdExSlow(0x80000002, 0, 0, 0, &szNameRaw[0 + 0], &szNameRaw[4 + 0], &szNameRaw[8 + 0], &szNameRaw[12 + 0]);
4358 ASMCpuIdExSlow(0x80000003, 0, 0, 0, &szNameRaw[0 + 16], &szNameRaw[4 + 16], &szNameRaw[8 + 16], &szNameRaw[12 + 16]);
4359 ASMCpuIdExSlow(0x80000004, 0, 0, 0, &szNameRaw[0 + 32], &szNameRaw[4 + 32], &szNameRaw[8 + 32], &szNameRaw[12 + 32]);
4360 szNameRaw[48] = '\0';
4361 pszCpuDesc = RTStrStrip(szNameRaw);
4362 vbCpuRepDebug("Name2: %s\n", pszCpuDesc);
4363
4364 /* Reduce the name. */
4365 pszName = strcpy(szName, pszCpuDesc);
4366
4367 static const char * const s_apszSuffixes[] =
4368 {
4369 "CPU @",
4370 };
4371 for (uint32_t i = 0; i < RT_ELEMENTS(s_apszSuffixes); i++)
4372 {
4373 char *pszHit = strstr(pszName, s_apszSuffixes[i]);
4374 if (pszHit)
4375 RT_BZERO(pszHit, strlen(pszHit));
4376 }
4377
4378 static const char * const s_apszWords[] =
4379 {
4380 "(TM)", "(tm)", "(R)", "(r)", "Processor", "CPU", "@",
4381 };
4382 for (uint32_t i = 0; i < RT_ELEMENTS(s_apszWords); i++)
4383 {
4384 const char *pszWord = s_apszWords[i];
4385 size_t cchWord = strlen(pszWord);
4386 char *pszHit;
4387 while ((pszHit = strstr(pszName, pszWord)) != NULL)
4388 memmove(pszHit, pszHit + cchWord, strlen(pszHit + cchWord) + 1);
4389 }
4390
4391 RTStrStripR(pszName);
4392 for (char *psz = pszName; *psz; psz++)
4393 if (RT_C_IS_BLANK(*psz))
4394 {
4395 size_t cchBlanks = 1;
4396 while (RT_C_IS_BLANK(psz[cchBlanks]))
4397 cchBlanks++;
4398 *psz = ' ';
4399 if (cchBlanks > 1)
4400 memmove(psz + 1, psz + cchBlanks, strlen(psz + cchBlanks) + 1);
4401 }
4402 pszName = RTStrStripL(pszName);
4403 vbCpuRepDebug("Name: %s\n", pszName);
4404
4405 /* Make it C/C++ acceptable. */
4406 strcpy(szNameC, pszName);
4407 unsigned offDst = 0;
4408 for (unsigned offSrc = 0; ; offSrc++)
4409 {
4410 char ch = szNameC[offSrc];
4411 if (!RT_C_IS_ALNUM(ch) && ch != '_' && ch != '\0')
4412 ch = '_';
4413 if (ch == '_' && offDst > 0 && szNameC[offDst - 1] == '_')
4414 offDst--;
4415 szNameC[offDst++] = ch;
4416 if (!ch)
4417 break;
4418 }
4419 while (offDst > 1 && szNameC[offDst - 1] == '_')
4420 szNameC[--offDst] = '\0';
4421
4422 vbCpuRepDebug("NameC: %s\n", szNameC);
4423 }
4424 else
4425 {
4426 ASMCpuIdExSlow(1, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
4427 RTStrPrintf(szNameC, sizeof(szNameC), "%s_%u_%u_%u", cpuVendorToString(enmVendor), ASMGetCpuFamily(uEax),
4428 ASMGetCpuModel(uEax, enmVendor == CPUMCPUVENDOR_INTEL), ASMGetCpuStepping(uEax));
4429 pszCpuDesc = pszName = szNameC;
4430 vbCpuRepDebug("Name/NameC: %s\n", szNameC);
4431 }
4432
4433 /*
4434 * Print a file header, if we're not outputting to stdout (assumption being
4435 * that stdout is used while hacking the reporter and too much output is
4436 * unwanted).
4437 */
4438 if (g_pReportOut)
4439 {
4440 RTTIMESPEC Now;
4441 char szNow[64];
4442 RTTimeSpecToString(RTTimeNow(&Now), szNow, sizeof(szNow));
4443 char *pchDot = strchr(szNow, '.');
4444 if (pchDot)
4445 strcpy(pchDot, "Z");
4446
4447 vbCpuRepPrintf("/* $" "Id" "$ */\n"
4448 "/** @file\n"
4449 " * CPU database entry \"%s\".\n"
4450 " * Generated at %s by VBoxCpuReport v%sr%s on %s.%s.\n"
4451 " */\n"
4452 "\n"
4453 "/*\n"
4454 " * Copyright (C) 2013 Oracle Corporation\n"
4455 " *\n"
4456 " * This file is part of VirtualBox Open Source Edition (OSE), as\n"
4457 " * available from http://www.215389.xyz. This file is free software;\n"
4458 " * you can redistribute it and/or modify it under the terms of the GNU\n"
4459 " * General Public License (GPL) as published by the Free Software\n"
4460 " * Foundation, in version 2 as it comes in the \"COPYING\" file of the\n"
4461 " * VirtualBox OSE distribution. VirtualBox OSE is distributed in the\n"
4462 " * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.\n"
4463 " */\n"
4464 "\n"
4465 "#ifndef VBOX_CPUDB_%s\n"
4466 "#define VBOX_CPUDB_%s\n"
4467 "\n",
4468 pszName,
4469 szNow, RTBldCfgVersion(), RTBldCfgRevisionStr(), RTBldCfgTarget(), RTBldCfgTargetArch(),
4470 szNameC, szNameC);
4471 }
4472
4473 /*
4474 * Extract CPUID based data.
4475 */
4476 int rc = produceCpuIdArray(szNameC, pszCpuDesc);
4477 if (RT_FAILURE(rc))
4478 return rc;
4479
4480 CPUMUKNOWNCPUID enmUnknownMethod;
4481 CPUMCPUID DefUnknown;
4482 rc = CPUMR3CpuIdDetectUnknownLeafMethod(&enmUnknownMethod, &DefUnknown);
4483 if (RT_FAILURE(rc))
4484 return RTMsgErrorRc(rc, "CPUMR3DetectCpuIdUnknownMethod failed: %Rrc\n", rc);
4485 vbCpuRepDebug("enmUnknownMethod=%s\n", CPUMR3CpuIdUnknownLeafMethodName(enmUnknownMethod));
4486
4487 /*
4488 * Do the MSRs, if we can.
4489 */
4490 char szMsrMask[64];
4491 probeMsrs(false /*fHacking*/, szNameC, pszCpuDesc, szMsrMask, sizeof(szMsrMask));
4492
4493 /*
4494 * Emit the CPUMDBENTRY record.
4495 */
4496 ASMCpuIdExSlow(1, 0, 0, 0, &uEax, &uEbx, &uEcx, &uEdx);
4497 vbCpuRepPrintf("\n"
4498 "/**\n"
4499 " * Database entry for %s.\n"
4500 " */\n"
4501 "static CPUMDBENTRY const g_Entry_%s = \n"
4502 "{\n"
4503 " /*.pszName = */ \"%s\",\n"
4504 " /*.pszFullName = */ \"%s\",\n"
4505 " /*.enmVendor = */ CPUMCPUVENDOR_%s,\n"
4506 " /*.uFamily = */ %u,\n"
4507 " /*.uModel = */ %u,\n"
4508 " /*.uStepping = */ %u,\n"
4509 " /*.enmMicroarch = */ kCpumMicroarch_%s,\n"
4510 " /*.fFlags = */ 0,\n"
4511 " /*.cMaxPhysAddrWidth= */ %u,\n"
4512 " /*.paCpuIdLeaves = */ NULL_ALONE(g_aCpuIdLeaves_%s),\n"
4513 " /*.cCpuIdLeaves = */ ZERO_ALONE(RT_ELEMENTS(g_aCpuIdLeaves_%s)),\n"
4514 " /*.enmUnknownCpuId = */ CPUMUKNOWNCPUID_%s,\n"
4515 " /*.DefUnknownCpuId = */ { %#010x, %#010x, %#010x, %#010x },\n"
4516 " /*.fMsrMask = */ %s,\n"
4517 " /*.cMsrRanges = */ ZERO_ALONE(RT_ELEMENTS(g_aMsrRanges_%s)),\n"
4518 " /*.paMsrRanges = */ NULL_ALONE(g_aMsrRanges_%s),\n"
4519 "};\n"
4520 "\n"
4521 "#endif /* !VBOX_DB_%s */\n"
4522 "\n",
4523 pszCpuDesc,
4524 szNameC,
4525 pszName,
4526 pszCpuDesc,
4527 CPUMR3CpuVendorName(enmVendor),
4528 ASMGetCpuFamily(uEax),
4529 ASMGetCpuModel(uEax, enmVendor == CPUMCPUVENDOR_INTEL),
4530 ASMGetCpuStepping(uEax),
4531 CPUMR3MicroarchName(enmMicroarch),
4532 vbCpuRepGetPhysAddrWidth(),
4533 szNameC,
4534 szNameC,
4535 CPUMR3CpuIdUnknownLeafMethodName(enmUnknownMethod),
4536 DefUnknown.eax,
4537 DefUnknown.ebx,
4538 DefUnknown.ecx,
4539 DefUnknown.edx,
4540 szMsrMask,
4541 szNameC,
4542 szNameC,
4543 szNameC
4544 );
4545
4546 return VINF_SUCCESS;
4547}
4548
4549
4550int main(int argc, char **argv)
4551{
4552 int rc = RTR3InitExe(argc, &argv, 0 /*fFlags*/);
4553 if (RT_FAILURE(rc))
4554 return RTMsgInitFailure(rc);
4555
4556 /*
4557 * Argument parsing?
4558 */
4559 static const RTGETOPTDEF s_aOptions[] =
4560 {
4561 { "--msrs-only", 'm', RTGETOPT_REQ_NOTHING },
4562 { "--msrs-dev", 'd', RTGETOPT_REQ_NOTHING },
4563 { "--output", 'o', RTGETOPT_REQ_STRING },
4564 { "--log", 'l', RTGETOPT_REQ_STRING },
4565 };
4566 RTGETOPTSTATE State;
4567 RTGetOptInit(&State, argc, argv, &s_aOptions[0], RT_ELEMENTS(s_aOptions), 1, RTGETOPTINIT_FLAGS_OPTS_FIRST);
4568
4569 enum
4570 {
4571 kCpuReportOp_Normal,
4572 kCpuReportOp_MsrsOnly,
4573 kCpuReportOp_MsrsHacking
4574 } enmOp = kCpuReportOp_Normal;
4575 g_pReportOut = NULL;
4576 g_pDebugOut = NULL;
4577 const char *pszOutput = NULL;
4578 const char *pszDebugOut = NULL;
4579
4580 int iOpt;
4581 RTGETOPTUNION ValueUnion;
4582 while ((iOpt = RTGetOpt(&State, &ValueUnion)) != 0)
4583 {
4584 switch (iOpt)
4585 {
4586 case 'm':
4587 enmOp = kCpuReportOp_MsrsOnly;
4588 break;
4589
4590 case 'd':
4591 enmOp = kCpuReportOp_MsrsHacking;
4592 break;
4593
4594 case 'o':
4595 pszOutput = ValueUnion.psz;
4596 break;
4597
4598 case 'l':
4599 pszDebugOut = ValueUnion.psz;
4600 break;
4601
4602 case 'h':
4603 RTPrintf("Usage: VBoxCpuReport [-m|--msrs-only] [-d|--msrs-dev] [-h|--help] [-V|--version] [-o filename.h] [-l debug.log]\n");
4604 RTPrintf("Internal tool for gathering information to the VMM CPU database.\n");
4605 return RTEXITCODE_SUCCESS;
4606 case 'V':
4607 RTPrintf("%sr%s\n", RTBldCfgVersion(), RTBldCfgRevisionStr());
4608 return RTEXITCODE_SUCCESS;
4609 default:
4610 return RTGetOptPrintError(iOpt, &ValueUnion);
4611 }
4612 }
4613
4614 /*
4615 * Open the alternative debug log stream.
4616 */
4617 if (pszDebugOut)
4618 {
4619 if (RTFileExists(pszDebugOut) && !RTSymlinkExists(pszDebugOut))
4620 {
4621 char szOld[RTPATH_MAX];
4622 rc = RTStrCopy(szOld, sizeof(szOld), pszDebugOut);
4623 if (RT_SUCCESS(rc))
4624 rc = RTStrCat(szOld, sizeof(szOld), ".old");
4625 if (RT_SUCCESS(rc))
4626 RTFileRename(pszDebugOut, szOld, RTFILEMOVE_FLAGS_REPLACE);
4627 }
4628 rc = RTStrmOpen(pszDebugOut, "w", &g_pDebugOut);
4629 if (RT_FAILURE(rc))
4630 {
4631 RTMsgError("Error opening '%s': %Rrc", pszDebugOut, rc);
4632 g_pDebugOut = NULL;
4633 }
4634 }
4635
4636 /*
4637 * Do the requested job.
4638 */
4639 rc = VERR_INTERNAL_ERROR;
4640 switch (enmOp)
4641 {
4642 case kCpuReportOp_Normal:
4643 /* switch output file. */
4644 if (pszOutput)
4645 {
4646 if (RTFileExists(pszOutput) && !RTSymlinkExists(pszOutput))
4647 {
4648 char szOld[RTPATH_MAX];
4649 rc = RTStrCopy(szOld, sizeof(szOld), pszOutput);
4650 if (RT_SUCCESS(rc))
4651 rc = RTStrCat(szOld, sizeof(szOld), ".old");
4652 if (RT_SUCCESS(rc))
4653 RTFileRename(pszOutput, szOld, RTFILEMOVE_FLAGS_REPLACE);
4654 }
4655 rc = RTStrmOpen(pszOutput, "w", &g_pReportOut);
4656 if (RT_FAILURE(rc))
4657 {
4658 RTMsgError("Error opening '%s': %Rrc", pszOutput, rc);
4659 break;
4660 }
4661 }
4662 rc = produceCpuReport();
4663 break;
4664 case kCpuReportOp_MsrsOnly:
4665 case kCpuReportOp_MsrsHacking:
4666 rc = probeMsrs(enmOp == kCpuReportOp_MsrsHacking, NULL, NULL, NULL, 0);
4667 break;
4668 }
4669
4670 /*
4671 * Close the output files.
4672 */
4673 if (g_pReportOut)
4674 {
4675 RTStrmClose(g_pReportOut);
4676 g_pReportOut = NULL;
4677 }
4678
4679 if (g_pDebugOut)
4680 {
4681 RTStrmClose(g_pDebugOut);
4682 g_pDebugOut = NULL;
4683 }
4684
4685 return RT_SUCCESS(rc) ? RTEXITCODE_SUCCESS : RTEXITCODE_FAILURE;
4686}
4687
Note: See TracBrowser for help on using the repository browser.

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