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