VirtualBox

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

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

CPUM: More msr hacking.

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