VirtualBox

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

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

Fixes for canonical address in MSRs.

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

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