VirtualBox

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

Last change on this file since 50653 was 50653, checked in by vboxsync, 10 years ago

Added a more recent K8 CPU to the CPU database.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use