VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId-armv8.cpp

最後變更 在這個檔案是 108405,由 vboxsync 提交於 2 週 前

VMM/NEMR3Native-win-armv8.cpp: Need to call WHvResumePartitionTime() to get time ticking despite the docs claiming that it is resumed as soon as vCPU starts executing. Also suspend time already when querying the guest CPU tick counter, bugref:10392 [committed a bit too much]

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 77.1 KB
 
1/* $Id: CPUMR3CpuId-armv8.cpp 108405 2025-02-27 09:44:01Z vboxsync $ */
2/** @file
3 * CPUM - CPU ID part for ARMv8 hypervisor.
4 */
5
6/*
7 * Copyright (C) 2023-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.alldomusa.eu.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#define LOG_GROUP LOG_GROUP_CPUM
33#define CPUM_WITH_NONCONST_HOST_FEATURES /* required for initializing parts of the g_CpumHostFeatures structure here. */
34#include <VBox/vmm/cpum.h>
35#include <VBox/vmm/dbgf.h>
36#include <VBox/vmm/nem.h>
37#include <VBox/vmm/ssm.h>
38#include "CPUMInternal-armv8.h"
39#include <VBox/vmm/vmcc.h>
40
41#include <VBox/err.h>
42#include <iprt/ctype.h>
43#include <iprt/mem.h>
44#include <iprt/string.h>
45
46
47/*********************************************************************************************************************************
48* Defined Constants And Macros *
49*********************************************************************************************************************************/
50
51/*
52 *
53 * Init related code.
54 * Init related code.
55 * Init related code.
56 *
57 *
58 */
59
60/** @name Instruction Set Extension Options
61 * @{ */
62/** Configuration option type (extended boolean, really). */
63typedef uint8_t CPUMISAEXTCFG;
64/** Always disable the extension. */
65#define CPUMISAEXTCFG_DISABLED false
66/** Enable the extension if it's supported by the host CPU. */
67#define CPUMISAEXTCFG_ENABLED_SUPPORTED true
68/** Enable the extension if it's supported by the host CPU, but don't let
69 * the portable CPUID feature disable it. */
70#define CPUMISAEXTCFG_ENABLED_PORTABLE UINT8_C(127)
71/** Always enable the extension. */
72#define CPUMISAEXTCFG_ENABLED_ALWAYS UINT8_C(255)
73/** @} */
74
75/**
76 * CPUID Configuration (from CFGM).
77 *
78 * @remarks The members aren't document since we would only be duplicating the
79 * \@cfgm entries in cpumR3CpuIdReadConfig.
80 */
81typedef struct CPUMCPUIDCONFIG
82{
83 CPUMISAEXTCFG enmAes;
84 CPUMISAEXTCFG enmPmull;
85 CPUMISAEXTCFG enmSha1;
86 CPUMISAEXTCFG enmSha256;
87 CPUMISAEXTCFG enmSha512;
88 CPUMISAEXTCFG enmCrc32;
89 CPUMISAEXTCFG enmSha3;
90
91 char szCpuName[128];
92} CPUMCPUIDCONFIG;
93/** Pointer to CPUID config (from CFGM). */
94typedef CPUMCPUIDCONFIG *PCPUMCPUIDCONFIG;
95
96
97/**
98 * Sanitizes and adjust the CPUID leaves.
99 *
100 * Drop features that aren't virtualized (or virtualizable). Adjust information
101 * and capabilities to fit the virtualized hardware. Remove information the
102 * guest shouldn't have (because it's wrong in the virtual world or because it
103 * gives away host details) or that we don't have documentation for and no idea
104 * what means.
105 *
106 * @returns VBox status code.
107 * @param pVM The cross context VM structure (for cCpus).
108 * @param pCpum The CPUM instance data.
109 * @param pConfig The CPUID configuration we've read from CFGM.
110 */
111static int cpumR3CpuIdSanitize(PVM pVM, PCPUM pCpum, PCPUMCPUIDCONFIG pConfig)
112{
113#define PORTABLE_CLEAR_BITS_WHEN(Lvl, a_pLeafReg, FeatNm, fMask, uValue) \
114 if ( pCpum->u8PortableCpuIdLevel >= (Lvl) && ((a_pLeafReg) & (fMask)) == (uValue) ) \
115 { \
116 LogRel(("PortableCpuId: " #a_pLeafReg "[" #FeatNm "]: %#x -> 0\n", (a_pLeafReg) & (fMask))); \
117 (a_pLeafReg) &= ~(uint32_t)(fMask); \
118 }
119#define PORTABLE_DISABLE_FEATURE_BIT(Lvl, a_pLeafReg, FeatNm, fBitMask) \
120 if ( pCpum->u8PortableCpuIdLevel >= (Lvl) && ((a_pLeafReg) & (fBitMask)) ) \
121 { \
122 LogRel(("PortableCpuId: " #a_pLeafReg "[" #FeatNm "]: 1 -> 0\n")); \
123 (a_pLeafReg) &= ~(uint32_t)(fBitMask); \
124 }
125#define PORTABLE_DISABLE_FEATURE_BIT_CFG(Lvl, a_IdReg, a_FeatNm, a_IdRegValCheck, enmConfig, a_IdRegValNotSup) \
126 if ( pCpum->u8PortableCpuIdLevel >= (Lvl) \
127 && (RT_BF_GET(a_IdReg, a_FeatNm) >= a_IdRegValCheck) \
128 && (enmConfig) != CPUMISAEXTCFG_ENABLED_PORTABLE ) \
129 { \
130 LogRel(("PortableCpuId: [" #a_FeatNm "]: 1 -> 0\n")); \
131 (a_IdReg) = RT_BF_SET(a_IdReg, a_FeatNm, a_IdRegValNotSup); \
132 }
133 //Assert(pCpum->GuestFeatures.enmCpuVendor != CPUMCPUVENDOR_INVALID);
134
135 /* The CPUID entries we start with here isn't necessarily the ones of the host, so we
136 must consult HostFeatures when processing CPUMISAEXTCFG variables. */
137 PCCPUMFEATURES pHstFeat = &pCpum->HostFeatures.s;
138#define PASSTHRU_FEATURE(a_IdReg, enmConfig, fHostFeature, a_IdRegNm, a_IdRegValSup, a_IdRegValNotSup) \
139 (a_IdReg) = ((enmConfig) && ((enmConfig) == CPUMISAEXTCFG_ENABLED_ALWAYS || (fHostFeature)) \
140 ? RT_BF_SET(a_IdReg, a_IdRegNm, a_IdRegValSup) \
141 : RT_BF_SET(a_IdReg, a_IdRegNm, a_IdRegValNotSup))
142
143 /* ID_AA64ISAR0_EL1 */
144 uint64_t u64ValTmp = 0;
145 uint64_t u64IdReg = pVM->cpum.s.GuestIdRegs.u64RegIdAa64Isar0El1;
146
147 PASSTHRU_FEATURE(u64IdReg, pConfig->enmAes, pHstFeat->fAes, ARMV8_ID_AA64ISAR0_EL1_AES, ARMV8_ID_AA64ISAR0_EL1_AES_SUPPORTED, ARMV8_ID_AA64ISAR0_EL1_AES_NOT_IMPL);
148 u64ValTmp = RT_BF_GET(u64IdReg, ARMV8_ID_AA64ISAR0_EL1_AES) == ARMV8_ID_AA64ISAR0_EL1_AES_SUPPORTED ? ARMV8_ID_AA64ISAR0_EL1_AES_SUPPORTED : ARMV8_ID_AA64ISAR0_EL1_AES_NOT_IMPL;
149 PASSTHRU_FEATURE(u64IdReg, pConfig->enmPmull, pHstFeat->fPmull, ARMV8_ID_AA64ISAR0_EL1_AES, ARMV8_ID_AA64ISAR0_EL1_AES_SUPPORTED_PMULL, u64ValTmp);
150 PASSTHRU_FEATURE(u64IdReg, pConfig->enmSha1, pHstFeat->fSha1, ARMV8_ID_AA64ISAR0_EL1_SHA1, ARMV8_ID_AA64ISAR0_EL1_SHA1_SUPPORTED, ARMV8_ID_AA64ISAR0_EL1_SHA1_NOT_IMPL);
151 PASSTHRU_FEATURE(u64IdReg, pConfig->enmSha256, pHstFeat->fSha256, ARMV8_ID_AA64ISAR0_EL1_SHA2, ARMV8_ID_AA64ISAR0_EL1_SHA2_SUPPORTED_SHA256, ARMV8_ID_AA64ISAR0_EL1_SHA2_NOT_IMPL);
152 u64ValTmp = RT_BF_GET(u64IdReg, ARMV8_ID_AA64ISAR0_EL1_SHA2) == ARMV8_ID_AA64ISAR0_EL1_SHA2_SUPPORTED_SHA256 ? ARMV8_ID_AA64ISAR0_EL1_SHA2_SUPPORTED_SHA256 : ARMV8_ID_AA64ISAR0_EL1_SHA2_NOT_IMPL;
153 PASSTHRU_FEATURE(u64IdReg, pConfig->enmSha512, pHstFeat->fSha512, ARMV8_ID_AA64ISAR0_EL1_SHA2, ARMV8_ID_AA64ISAR0_EL1_SHA2_SUPPORTED_SHA256_SHA512, u64ValTmp);
154 PASSTHRU_FEATURE(u64IdReg, pConfig->enmCrc32, pHstFeat->fCrc32, ARMV8_ID_AA64ISAR0_EL1_CRC32, ARMV8_ID_AA64ISAR0_EL1_CRC32_SUPPORTED, ARMV8_ID_AA64ISAR0_EL1_CRC32_NOT_IMPL);
155 PASSTHRU_FEATURE(u64IdReg, pConfig->enmSha3, pHstFeat->fSha3, ARMV8_ID_AA64ISAR0_EL1_SHA3, ARMV8_ID_AA64ISAR0_EL1_SHA3_SUPPORTED, ARMV8_ID_AA64ISAR0_EL1_SHA3_NOT_IMPL);
156
157 if (pCpum->u8PortableCpuIdLevel > 0)
158 {
159 PORTABLE_DISABLE_FEATURE_BIT_CFG(1, u64IdReg, ARMV8_ID_AA64ISAR0_EL1_AES, ARMV8_ID_AA64ISAR0_EL1_AES_SUPPORTED, pConfig->enmAes, ARMV8_ID_AA64ISAR0_EL1_AES_NOT_IMPL);
160 PORTABLE_DISABLE_FEATURE_BIT_CFG(1, u64IdReg, ARMV8_ID_AA64ISAR0_EL1_AES, ARMV8_ID_AA64ISAR0_EL1_AES_SUPPORTED_PMULL, pConfig->enmPmull, ARMV8_ID_AA64ISAR0_EL1_AES_NOT_IMPL);
161 PORTABLE_DISABLE_FEATURE_BIT_CFG(1, u64IdReg, ARMV8_ID_AA64ISAR0_EL1_SHA1, ARMV8_ID_AA64ISAR0_EL1_SHA1_SUPPORTED, pConfig->enmSha1, ARMV8_ID_AA64ISAR0_EL1_SHA1_NOT_IMPL);
162 PORTABLE_DISABLE_FEATURE_BIT_CFG(1, u64IdReg, ARMV8_ID_AA64ISAR0_EL1_SHA2, ARMV8_ID_AA64ISAR0_EL1_SHA2_SUPPORTED_SHA256, pConfig->enmSha256, ARMV8_ID_AA64ISAR0_EL1_SHA2_NOT_IMPL);
163 PORTABLE_DISABLE_FEATURE_BIT_CFG(1, u64IdReg, ARMV8_ID_AA64ISAR0_EL1_SHA2, ARMV8_ID_AA64ISAR0_EL1_SHA2_SUPPORTED_SHA256_SHA512, pConfig->enmSha512, ARMV8_ID_AA64ISAR0_EL1_SHA2_NOT_IMPL);
164 PORTABLE_DISABLE_FEATURE_BIT_CFG(1, u64IdReg, ARMV8_ID_AA64ISAR0_EL1_CRC32, ARMV8_ID_AA64ISAR0_EL1_CRC32_SUPPORTED, pConfig->enmCrc32, ARMV8_ID_AA64ISAR0_EL1_CRC32_NOT_IMPL);
165 PORTABLE_DISABLE_FEATURE_BIT_CFG(1, u64IdReg, ARMV8_ID_AA64ISAR0_EL1_SHA3, ARMV8_ID_AA64ISAR0_EL1_SHA3_SUPPORTED, pConfig->enmSha3, ARMV8_ID_AA64ISAR0_EL1_SHA3_NOT_IMPL);
166 }
167
168 /* Write ID_AA64ISAR0_EL1 register back. */
169 pVM->cpum.s.GuestIdRegs.u64RegIdAa64Isar0El1 = u64IdReg;
170
171 /** @todo Other ID and feature registers. */
172
173 return VINF_SUCCESS;
174#undef PORTABLE_DISABLE_FEATURE_BIT
175#undef PORTABLE_CLEAR_BITS_WHEN
176}
177
178
179/**
180 * Reads a value in /CPUM/IsaExts/ node.
181 *
182 * @returns VBox status code (error message raised).
183 * @param pVM The cross context VM structure. (For errors.)
184 * @param pIsaExts The /CPUM/IsaExts node (can be NULL).
185 * @param pszValueName The value / extension name.
186 * @param penmValue Where to return the choice.
187 * @param enmDefault The default choice.
188 */
189static int cpumR3CpuIdReadIsaExtCfg(PVM pVM, PCFGMNODE pIsaExts, const char *pszValueName,
190 CPUMISAEXTCFG *penmValue, CPUMISAEXTCFG enmDefault)
191{
192 /*
193 * Try integer encoding first.
194 */
195 uint64_t uValue;
196 int rc = CFGMR3QueryInteger(pIsaExts, pszValueName, &uValue);
197 if (RT_SUCCESS(rc))
198 switch (uValue)
199 {
200 case 0: *penmValue = CPUMISAEXTCFG_DISABLED; break;
201 case 1: *penmValue = CPUMISAEXTCFG_ENABLED_SUPPORTED; break;
202 case 2: *penmValue = CPUMISAEXTCFG_ENABLED_ALWAYS; break;
203 case 9: *penmValue = CPUMISAEXTCFG_ENABLED_PORTABLE; break;
204 default:
205 return VMSetError(pVM, VERR_CPUM_INVALID_CONFIG_VALUE, RT_SRC_POS,
206 "Invalid config value for '/CPUM/IsaExts/%s': %llu (expected 0/'disabled', 1/'enabled', 2/'portable', or 9/'forced')",
207 pszValueName, uValue);
208 }
209 /*
210 * If missing, use default.
211 */
212 else if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
213 *penmValue = enmDefault;
214 else
215 {
216 if (rc == VERR_CFGM_NOT_INTEGER)
217 {
218 /*
219 * Not an integer, try read it as a string.
220 */
221 char szValue[32];
222 rc = CFGMR3QueryString(pIsaExts, pszValueName, szValue, sizeof(szValue));
223 if (RT_SUCCESS(rc))
224 {
225 RTStrToLower(szValue);
226 size_t cchValue = strlen(szValue);
227#define EQ(a_str) (cchValue == sizeof(a_str) - 1U && memcmp(szValue, a_str, sizeof(a_str) - 1))
228 if ( EQ("disabled") || EQ("disable") || EQ("off") || EQ("no"))
229 *penmValue = CPUMISAEXTCFG_DISABLED;
230 else if (EQ("enabled") || EQ("enable") || EQ("on") || EQ("yes"))
231 *penmValue = CPUMISAEXTCFG_ENABLED_SUPPORTED;
232 else if (EQ("forced") || EQ("force") || EQ("always"))
233 *penmValue = CPUMISAEXTCFG_ENABLED_ALWAYS;
234 else if (EQ("portable"))
235 *penmValue = CPUMISAEXTCFG_ENABLED_PORTABLE;
236 else if (EQ("default") || EQ("def"))
237 *penmValue = enmDefault;
238 else
239 return VMSetError(pVM, VERR_CPUM_INVALID_CONFIG_VALUE, RT_SRC_POS,
240 "Invalid config value for '/CPUM/IsaExts/%s': '%s' (expected 0/'disabled', 1/'enabled', 2/'portable', or 9/'forced')",
241 pszValueName, uValue);
242#undef EQ
243 }
244 }
245 if (RT_FAILURE(rc))
246 return VMSetError(pVM, rc, RT_SRC_POS, "Error reading config value '/CPUM/IsaExts/%s': %Rrc", pszValueName, rc);
247 }
248 return VINF_SUCCESS;
249}
250
251
252#if 0
253/**
254 * Reads a value in /CPUM/IsaExts/ node, forcing it to DISABLED if wanted.
255 *
256 * @returns VBox status code (error message raised).
257 * @param pVM The cross context VM structure. (For errors.)
258 * @param pIsaExts The /CPUM/IsaExts node (can be NULL).
259 * @param pszValueName The value / extension name.
260 * @param penmValue Where to return the choice.
261 * @param enmDefault The default choice.
262 * @param fAllowed Allowed choice. Applied both to the result and to
263 * the default value.
264 */
265static int cpumR3CpuIdReadIsaExtCfgEx(PVM pVM, PCFGMNODE pIsaExts, const char *pszValueName,
266 CPUMISAEXTCFG *penmValue, CPUMISAEXTCFG enmDefault, bool fAllowed)
267{
268 int rc;
269 if (fAllowed)
270 rc = cpumR3CpuIdReadIsaExtCfg(pVM, pIsaExts, pszValueName, penmValue, enmDefault);
271 else
272 {
273 rc = cpumR3CpuIdReadIsaExtCfg(pVM, pIsaExts, pszValueName, penmValue, false /*enmDefault*/);
274 if (RT_SUCCESS(rc) && *penmValue == CPUMISAEXTCFG_ENABLED_ALWAYS)
275 LogRel(("CPUM: Ignoring forced '%s'\n", pszValueName));
276 *penmValue = CPUMISAEXTCFG_DISABLED;
277 }
278 return rc;
279}
280#endif
281
282static int cpumR3CpuIdReadConfig(PVM pVM, PCPUMCPUIDCONFIG pConfig, PCFGMNODE pCpumCfg)
283{
284 /** @cfgm{/CPUM/PortableCpuIdLevel, 8-bit, 0, 3, 0}
285 * When non-zero CPUID features that could cause portability issues will be
286 * stripped. The higher the value the more features gets stripped. Higher
287 * values should only be used when older CPUs are involved since it may
288 * harm performance and maybe also cause problems with specific guests. */
289 int rc = CFGMR3QueryU8Def(pCpumCfg, "PortableCpuIdLevel", &pVM->cpum.s.u8PortableCpuIdLevel, 0);
290 AssertLogRelRCReturn(rc, rc);
291
292 /** @cfgm{/CPUM/GuestCpuName, string}
293 * The name of the CPU we're to emulate. The default is the host CPU.
294 * Note! CPUs other than "host" one is currently unsupported. */
295 rc = CFGMR3QueryStringDef(pCpumCfg, "GuestCpuName", pConfig->szCpuName, sizeof(pConfig->szCpuName), "host");
296 AssertLogRelRCReturn(rc, rc);
297
298 /*
299 * Instruction Set Architecture (ISA) Extensions.
300 */
301 PCFGMNODE pIsaExts = CFGMR3GetChild(pCpumCfg, "IsaExts");
302 if (pIsaExts)
303 {
304 rc = CFGMR3ValidateConfig(pIsaExts, "/CPUM/IsaExts/",
305 "AES"
306 "|PMULL"
307 "|SHA1"
308 "|SHA256"
309 "|SHA512"
310 "|CRC32"
311 "|SHA3"
312 , "" /*pszValidNodes*/, "CPUM" /*pszWho*/, 0 /*uInstance*/);
313 if (RT_FAILURE(rc))
314 return rc;
315 }
316
317 /** @cfgm{/CPUM/IsaExts/AES, boolean, depends}
318 * Expose FEAT_AES instruction set extension to the guest.
319 */
320 rc = cpumR3CpuIdReadIsaExtCfg(pVM, pIsaExts, "AES", &pConfig->enmAes, true /*enmDefault*/);
321 AssertLogRelRCReturn(rc, rc);
322
323 /** @cfgm{/CPUM/IsaExts/AES, boolean, depends}
324 * Expose FEAT_AES and FEAT_PMULL instruction set extension to the guest.
325 */
326 rc = cpumR3CpuIdReadIsaExtCfg(pVM, pIsaExts, "PMULL", &pConfig->enmPmull, true /*enmDefault*/);
327 AssertLogRelRCReturn(rc, rc);
328
329 /** @cfgm{/CPUM/IsaExts/SHA1, boolean, depends}
330 * Expose FEAT_SHA1 instruction set extension to the guest.
331 */
332 rc = cpumR3CpuIdReadIsaExtCfg(pVM, pIsaExts, "SHA1", &pConfig->enmSha1, true /*enmDefault*/);
333 AssertLogRelRCReturn(rc, rc);
334
335 /** @cfgm{/CPUM/IsaExts/SHA256, boolean, depends}
336 * Expose FEAT_SHA256 instruction set extension to the guest.
337 */
338 rc = cpumR3CpuIdReadIsaExtCfg(pVM, pIsaExts, "SHA256", &pConfig->enmSha256, true /*enmDefault*/);
339 AssertLogRelRCReturn(rc, rc);
340
341 /** @cfgm{/CPUM/IsaExts/SHA512, boolean, depends}
342 * Expose FEAT_SHA256 and FEAT_SHA512 instruction set extension to the guest.
343 */
344 rc = cpumR3CpuIdReadIsaExtCfg(pVM, pIsaExts, "SHA512", &pConfig->enmSha512, true /*enmDefault*/);
345 AssertLogRelRCReturn(rc, rc);
346
347 /** @cfgm{/CPUM/IsaExts/CRC32, boolean, depends}
348 * Expose FEAT_CRC32 instruction set extension to the guest.
349 */
350 rc = cpumR3CpuIdReadIsaExtCfg(pVM, pIsaExts, "CRC32", &pConfig->enmCrc32, true /*enmDefault*/);
351 AssertLogRelRCReturn(rc, rc);
352
353 /** @cfgm{/CPUM/IsaExts/SHA3, boolean, depends}
354 * Expose FEAT_SHA3 instruction set extension to the guest.
355 */
356 rc = cpumR3CpuIdReadIsaExtCfg(pVM, pIsaExts, "SHA3", &pConfig->enmSha3, true /*enmDefault*/);
357 AssertLogRelRCReturn(rc, rc);
358
359 /** @todo Add more options for other extensions. */
360
361 return VINF_SUCCESS;
362}
363
364
365/**
366 * Populates the host and guest features by the given ID registers.
367 *
368 * @returns VBox status code.
369 * @param pVM The cross context VM structure.
370 * @param pIdRegs Pointer to the ID register struct.
371 *
372 * @note Unlike on x86 there is no cross platform usermode accessible way to get at the CPU features.
373 * On ARM there are some ID_AA64*_EL1 system registers accessible by EL1 and higher only so we have to
374 * rely on the host/NEM backend to query those and hand them to CPUM where they will be parsed and modified based
375 * on the VM config.
376 */
377VMMR3DECL(int) CPUMR3PopulateFeaturesByIdRegisters(PVM pVM, PCCPUMARMV8IDREGS pIdRegs)
378{
379 /* Set the host features from the given ID registers. */
380 int rc = cpumCpuIdExplodeFeaturesArmV8(pIdRegs, &g_CpumHostFeatures.s);
381 AssertRCReturn(rc, rc);
382
383 pVM->cpum.s.HostFeatures.s = g_CpumHostFeatures.s;
384 pVM->cpum.s.GuestFeatures.enmCpuVendor = pVM->cpum.s.HostFeatures.Common.enmCpuVendor;
385 pVM->cpum.s.HostIdRegs = *pIdRegs;
386 pVM->cpum.s.GuestIdRegs = *pIdRegs;
387
388 PCPUM pCpum = &pVM->cpum.s;
389 PCFGMNODE pCpumCfg = CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM");
390
391 /*
392 * Read the configuration.
393 */
394 CPUMCPUIDCONFIG Config;
395 RT_ZERO(Config);
396
397 rc = cpumR3CpuIdReadConfig(pVM, &Config, pCpumCfg);
398 AssertRCReturn(rc, rc);
399
400#if 0
401 /*
402 * Get the guest CPU data from the database and/or the host.
403 *
404 * The CPUID and MSRs are currently living on the regular heap to avoid
405 * fragmenting the hyper heap (and because there isn't/wasn't any realloc
406 * API for the hyper heap). This means special cleanup considerations.
407 */
408 rc = cpumR3DbGetCpuInfo(Config.szCpuName, &pCpum->GuestInfo);
409 if (RT_FAILURE(rc))
410 return rc == VERR_CPUM_DB_CPU_NOT_FOUND
411 ? VMSetError(pVM, rc, RT_SRC_POS,
412 "Info on guest CPU '%s' could not be found. Please, select a different CPU.", Config.szCpuName)
413 : rc;
414#endif
415
416 /*
417 * Pre-explode the CPUID info.
418 */
419 if (RT_SUCCESS(rc))
420 rc = cpumCpuIdExplodeFeaturesArmV8(pIdRegs, &pCpum->GuestFeatures);
421
422 /*
423 * Sanitize the cpuid information passed on to the guest.
424 */
425 if (RT_SUCCESS(rc))
426 rc = cpumR3CpuIdSanitize(pVM, pCpum, &Config);
427
428 return rc;
429}
430
431
432/**
433 * Queries the pointer to the VM wide ID registers exposing configured features to the guest.
434 *
435 * @returns VBox status code.
436 * @param pVM The cross context VM structure.
437 * @param ppIdRegs Where to store the pointer to the guest ID register struct.
438 */
439VMMR3_INT_DECL(int) CPUMR3QueryGuestIdRegs(PVM pVM, PCCPUMARMV8IDREGS *ppIdRegs)
440{
441 AssertPtrReturn(ppIdRegs, VERR_INVALID_POINTER);
442
443 *ppIdRegs = &pVM->cpum.s.GuestIdRegs;
444 return VINF_SUCCESS;
445}
446
447
448/*
449 *
450 *
451 * Saved state related code.
452 * Saved state related code.
453 * Saved state related code.
454 *
455 *
456 */
457/** Saved state field descriptors for CPUMARMV8IDREGS. */
458static const SSMFIELD g_aCpumArmV8IdRegsFields[] =
459{
460 SSMFIELD_ENTRY(CPUMARMV8IDREGS, u64RegIdAa64Pfr0El1),
461 SSMFIELD_ENTRY(CPUMARMV8IDREGS, u64RegIdAa64Pfr1El1),
462 SSMFIELD_ENTRY(CPUMARMV8IDREGS, u64RegIdAa64Dfr0El1),
463 SSMFIELD_ENTRY(CPUMARMV8IDREGS, u64RegIdAa64Dfr1El1),
464 SSMFIELD_ENTRY(CPUMARMV8IDREGS, u64RegIdAa64Afr0El1),
465 SSMFIELD_ENTRY(CPUMARMV8IDREGS, u64RegIdAa64Afr1El1),
466 SSMFIELD_ENTRY(CPUMARMV8IDREGS, u64RegIdAa64Isar0El1),
467 SSMFIELD_ENTRY(CPUMARMV8IDREGS, u64RegIdAa64Isar1El1),
468 SSMFIELD_ENTRY(CPUMARMV8IDREGS, u64RegIdAa64Isar2El1),
469 SSMFIELD_ENTRY(CPUMARMV8IDREGS, u64RegIdAa64Mmfr0El1),
470 SSMFIELD_ENTRY(CPUMARMV8IDREGS, u64RegIdAa64Mmfr1El1),
471 SSMFIELD_ENTRY(CPUMARMV8IDREGS, u64RegIdAa64Mmfr2El1),
472 SSMFIELD_ENTRY(CPUMARMV8IDREGS, u64RegClidrEl1),
473 SSMFIELD_ENTRY(CPUMARMV8IDREGS, u64RegCtrEl0),
474 SSMFIELD_ENTRY(CPUMARMV8IDREGS, u64RegDczidEl0),
475 SSMFIELD_ENTRY_TERM()
476};
477
478
479/**
480 * Called both in pass 0 and the final pass.
481 *
482 * @param pVM The cross context VM structure.
483 * @param pSSM The saved state handle.
484 */
485void cpumR3SaveCpuId(PVM pVM, PSSMHANDLE pSSM)
486{
487 /*
488 * Save all the CPU ID leaves.
489 */
490 SSMR3PutStructEx(pSSM, &pVM->cpum.s.GuestIdRegs, sizeof(pVM->cpum.s.GuestIdRegs), 0, g_aCpumArmV8IdRegsFields, NULL);
491}
492
493
494/**
495 * Loads the CPU ID leaves saved by pass 0, inner worker.
496 *
497 * @returns VBox status code.
498 * @param pVM The cross context VM structure.
499 * @param pSSM The saved state handle.
500 * @param uVersion The format version.
501 * @param pGuestIdRegs The guest ID register as loaded from the saved state.
502 */
503static int cpumR3LoadCpuIdInner(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, PCCPUMARMV8IDREGS pGuestIdRegs)
504{
505 /*
506 * This can be skipped.
507 */
508 bool fStrictCpuIdChecks;
509 CFGMR3QueryBoolDef(CFGMR3GetChild(CFGMR3GetRoot(pVM), "CPUM"), "StrictCpuIdChecks", &fStrictCpuIdChecks, true);
510
511 /*
512 * Define a bunch of macros for simplifying the santizing/checking code below.
513 */
514 /* For checking guest features. */
515#define CPUID_GST_FEATURE_RET(a_IdReg, a_Field) \
516 do { \
517 if (RT_BF_GET(pGuestIdRegs->a_IdReg, a_Field) > RT_BF_GET(pVM->cpum.s.GuestIdRegs.a_IdReg, a_Field)) \
518 { \
519 if (fStrictCpuIdChecks) \
520 return SSMR3SetLoadError(pSSM, VERR_SSM_LOAD_CPUID_MISMATCH, RT_SRC_POS, \
521 N_(#a_Field " is not supported by the host but has already exposed to the guest")); \
522 LogRel(("CPUM: " #a_Field " is not supported by the host but has already been exposed to the guest\n")); \
523 } \
524 } while (0)
525#define CPUID_GST_FEATURE_RET_NOT_IMPL(a_IdReg, a_Field, a_NotImpl) \
526 do { \
527 if ( ( RT_BF_GET(pGuestIdRegs->a_IdReg, a_Field) != (a_NotImpl) \
528 && RT_BF_GET(pVM->cpum.s.GuestIdRegs.a_IdReg, a_Field) == (a_NotImpl)) \
529 || RT_BF_GET(pGuestIdRegs->a_IdReg, a_Field) > RT_BF_GET(pVM->cpum.s.GuestIdRegs.a_IdReg, a_Field)) \
530 { \
531 if (fStrictCpuIdChecks) \
532 return SSMR3SetLoadError(pSSM, VERR_SSM_LOAD_CPUID_MISMATCH, RT_SRC_POS, \
533 N_(#a_Field " is not supported by the host but has already exposed to the guest")); \
534 LogRel(("CPUM: " #a_Field " is not supported by the host but has already been exposed to the guest\n")); \
535 } \
536 } while (0)
537#define CPUID_GST_FEATURE_WRN(a_IdReg, a_Field) \
538 do { \
539 if (RT_BF_GET(pGuestIdRegs->a_IdReg, a_Field) > RT_BF_GET(pVM->cpum.s.GuestIdRegs.a_IdReg, a_Field)) \
540 LogRel(("CPUM: " #a_Field " is not supported by the host but has already been exposed to the guest\n")); \
541 } while (0)
542#define CPUID_GST_FEATURE_EMU(a_IdReg, a_Field) \
543 do { \
544 if (RT_BF_GET(pGuestIdRegs->a_IdReg, a_Field) > RT_BF_GET(pVM->cpum.s.GuestIdRegs.a_IdReg, a_Field)) \
545 LogRel(("CPUM: Warning - " #a_Field " is not supported by the host but has already been exposed to the guest. This may impact performance.\n")); \
546 } while (0)
547#define CPUID_GST_FEATURE_IGN(a_IdReg, a_Field) do { } while (0)
548
549 RT_NOREF(uVersion);
550 /*
551 * Verify that we can support the features already exposed to the guest on
552 * this host.
553 *
554 * Most of the features we're emulating requires intercepting instruction
555 * and doing it the slow way, so there is no need to warn when they aren't
556 * present in the host CPU. Thus we use IGN instead of EMU on these.
557 *
558 * Trailing comments:
559 * "EMU" - Possible to emulate, could be lots of work and very slow.
560 * "EMU?" - Can this be emulated?
561 */
562 /* ID_AA64ISAR0_EL1 */
563 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_AES);
564 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_SHA1);
565 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_SHA2);
566 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_CRC32);
567 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_ATOMIC);
568 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_TME);
569 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_RDM);
570 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_SHA3);
571 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_SM3);
572 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_SM4);
573 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_DP);
574 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_FHM);
575 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_TS);
576 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_TLB);
577 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar0El1, ARMV8_ID_AA64ISAR0_EL1_RNDR);
578
579 /* ID_AA64ISAR1_EL1 */
580 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_DPB);
581 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_APA);
582 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_API);
583 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_FJCVTZS);
584 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_LRCPC);
585 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_GPA);
586 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_GPI);
587 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_FRINTTS);
588 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_SB);
589 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_SPECRES);
590 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_BF16);
591 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_DGH);
592 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_I8MM);
593 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_XS);
594 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar1El1, ARMV8_ID_AA64ISAR1_EL1_LS64);
595
596 /* ID_AA64ISAR2_EL1 */
597 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar2El1, ARMV8_ID_AA64ISAR2_EL1_WFXT);
598 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar2El1, ARMV8_ID_AA64ISAR2_EL1_RPRES);
599 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar2El1, ARMV8_ID_AA64ISAR2_EL1_GPA3);
600 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar2El1, ARMV8_ID_AA64ISAR2_EL1_APA3);
601 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar2El1, ARMV8_ID_AA64ISAR2_EL1_MOPS);
602 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar2El1, ARMV8_ID_AA64ISAR2_EL1_BC);
603 CPUID_GST_FEATURE_RET(u64RegIdAa64Isar2El1, ARMV8_ID_AA64ISAR2_EL1_PACFRAC);
604
605 /* ID_AA64PFR0_EL1 */
606 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr0El1, ARMV8_ID_AA64PFR0_EL1_EL0);
607 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr0El1, ARMV8_ID_AA64PFR0_EL1_EL1);
608 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr0El1, ARMV8_ID_AA64PFR0_EL1_EL2);
609 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr0El1, ARMV8_ID_AA64PFR0_EL1_EL3);
610 CPUID_GST_FEATURE_RET_NOT_IMPL(u64RegIdAa64Pfr0El1, ARMV8_ID_AA64PFR0_EL1_FP, ARMV8_ID_AA64PFR0_EL1_FP_NOT_IMPL); /* Special not implemented value. */
611 CPUID_GST_FEATURE_RET_NOT_IMPL(u64RegIdAa64Pfr0El1, ARMV8_ID_AA64PFR0_EL1_ADVSIMD, ARMV8_ID_AA64PFR0_EL1_ADVSIMD_NOT_IMPL); /* Special not implemented value. */
612 CPUID_GST_FEATURE_IGN(u64RegIdAa64Pfr0El1, ARMV8_ID_AA64PFR0_EL1_GIC);
613 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr0El1, ARMV8_ID_AA64PFR0_EL1_RAS);
614 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr0El1, ARMV8_ID_AA64PFR0_EL1_SVE);
615 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr0El1, ARMV8_ID_AA64PFR0_EL1_SEL2);
616 /** @todo MPAM */
617 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr0El1, ARMV8_ID_AA64PFR0_EL1_AMU);
618 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr0El1, ARMV8_ID_AA64PFR0_EL1_DIT);
619 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr0El1, ARMV8_ID_AA64PFR0_EL1_RME);
620 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr0El1, ARMV8_ID_AA64PFR0_EL1_CSV2);
621 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr0El1, ARMV8_ID_AA64PFR0_EL1_CSV3);
622
623 /* ID_AA64PFR1_EL1 */
624 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr1El1, ARMV8_ID_AA64PFR1_EL1_BT);
625 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr1El1, ARMV8_ID_AA64PFR1_EL1_SSBS);
626 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr1El1, ARMV8_ID_AA64PFR1_EL1_MTE);
627 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr1El1, ARMV8_ID_AA64PFR1_EL1_RASFRAC);
628 /** @todo MPAM. */
629 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr1El1, ARMV8_ID_AA64PFR1_EL1_SME);
630 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr1El1, ARMV8_ID_AA64PFR1_EL1_RNDRTRAP);
631 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr1El1, ARMV8_ID_AA64PFR1_EL1_CSV2FRAC);
632 CPUID_GST_FEATURE_RET(u64RegIdAa64Pfr1El1, ARMV8_ID_AA64PFR1_EL1_NMI);
633
634 /* ID_AA64MMFR0_EL1 */
635 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_PARANGE);
636 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_ASIDBITS);
637 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_BIGEND);
638 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_SNSMEM);
639 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_BIGENDEL0);
640 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_TGRAN16);
641 CPUID_GST_FEATURE_RET_NOT_IMPL(u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_TGRAN64, ARMV8_ID_AA64MMFR0_EL1_TGRAN64_NOT_IMPL);
642 CPUID_GST_FEATURE_RET_NOT_IMPL(u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_TGRAN4, ARMV8_ID_AA64MMFR0_EL1_TGRAN4_NOT_IMPL);
643 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_TGRAN16_2);
644 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_TGRAN64_2);
645 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_TGRAN4_2);
646 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_EXS);
647 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_FGT);
648 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr0El1, ARMV8_ID_AA64MMFR0_EL1_ECV);
649
650 /* ID_AA64MMFR1_EL1 */
651 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr1El1, ARMV8_ID_AA64MMFR1_EL1_HAFDBS);
652 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr1El1, ARMV8_ID_AA64MMFR1_EL1_VMIDBITS);
653 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr1El1, ARMV8_ID_AA64MMFR1_EL1_VHE);
654 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr1El1, ARMV8_ID_AA64MMFR1_EL1_HPDS);
655 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr1El1, ARMV8_ID_AA64MMFR1_EL1_LO);
656 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr1El1, ARMV8_ID_AA64MMFR1_EL1_PAN);
657 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr1El1, ARMV8_ID_AA64MMFR1_EL1_SPECSEI);
658 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr1El1, ARMV8_ID_AA64MMFR1_EL1_XNX);
659 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr1El1, ARMV8_ID_AA64MMFR1_EL1_TWED);
660 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr1El1, ARMV8_ID_AA64MMFR1_EL1_ETS);
661 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr1El1, ARMV8_ID_AA64MMFR1_EL1_HCX);
662 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr1El1, ARMV8_ID_AA64MMFR1_EL1_AFP);
663 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr1El1, ARMV8_ID_AA64MMFR1_EL1_NTLBPA);
664 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr1El1, ARMV8_ID_AA64MMFR1_EL1_TIDCP1);
665 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr1El1, ARMV8_ID_AA64MMFR1_EL1_CMOW);
666
667 /* ID_AA64MMFR2_EL1 */
668 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr2El1, ARMV8_ID_AA64MMFR2_EL1_CNP);
669 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr2El1, ARMV8_ID_AA64MMFR2_EL1_UAO);
670 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr2El1, ARMV8_ID_AA64MMFR2_EL1_LSM);
671 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr2El1, ARMV8_ID_AA64MMFR2_EL1_IESB);
672 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr2El1, ARMV8_ID_AA64MMFR2_EL1_VARANGE);
673 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr2El1, ARMV8_ID_AA64MMFR2_EL1_CCIDX);
674 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr2El1, ARMV8_ID_AA64MMFR2_EL1_CNP);
675 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr2El1, ARMV8_ID_AA64MMFR2_EL1_NV);
676 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr2El1, ARMV8_ID_AA64MMFR2_EL1_ST);
677 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr2El1, ARMV8_ID_AA64MMFR2_EL1_AT);
678 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr2El1, ARMV8_ID_AA64MMFR2_EL1_IDS);
679 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr2El1, ARMV8_ID_AA64MMFR2_EL1_FWB);
680 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr2El1, ARMV8_ID_AA64MMFR2_EL1_TTL);
681 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr2El1, ARMV8_ID_AA64MMFR2_EL1_BBM);
682 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr2El1, ARMV8_ID_AA64MMFR2_EL1_EVT);
683 CPUID_GST_FEATURE_RET(u64RegIdAa64Mmfr2El1, ARMV8_ID_AA64MMFR2_EL1_E0PD);
684
685 /* ID_AA64DFR0_EL1 */
686 CPUID_GST_FEATURE_RET(u64RegIdAa64Dfr0El1, ARMV8_ID_AA64DFR0_EL1_DEBUGVER);
687 CPUID_GST_FEATURE_RET(u64RegIdAa64Dfr0El1, ARMV8_ID_AA64DFR0_EL1_TRACEVER);
688 CPUID_GST_FEATURE_RET(u64RegIdAa64Dfr0El1, ARMV8_ID_AA64DFR0_EL1_PMUVER);
689 CPUID_GST_FEATURE_RET(u64RegIdAa64Dfr0El1, ARMV8_ID_AA64DFR0_EL1_BRPS);
690 CPUID_GST_FEATURE_RET(u64RegIdAa64Dfr0El1, ARMV8_ID_AA64DFR0_EL1_WRPS);
691 CPUID_GST_FEATURE_RET(u64RegIdAa64Dfr0El1, ARMV8_ID_AA64DFR0_EL1_CTXCMPS);
692 CPUID_GST_FEATURE_RET(u64RegIdAa64Dfr0El1, ARMV8_ID_AA64DFR0_EL1_PMSVER);
693 CPUID_GST_FEATURE_RET(u64RegIdAa64Dfr0El1, ARMV8_ID_AA64DFR0_EL1_DOUBLELOCK);
694 CPUID_GST_FEATURE_RET(u64RegIdAa64Dfr0El1, ARMV8_ID_AA64DFR0_EL1_TRACEFILT);
695 CPUID_GST_FEATURE_RET(u64RegIdAa64Dfr0El1, ARMV8_ID_AA64DFR0_EL1_TRACEBUFFER);
696 CPUID_GST_FEATURE_RET(u64RegIdAa64Dfr0El1, ARMV8_ID_AA64DFR0_EL1_MTPMU);
697 CPUID_GST_FEATURE_RET(u64RegIdAa64Dfr0El1, ARMV8_ID_AA64DFR0_EL1_BRBE);
698 CPUID_GST_FEATURE_RET(u64RegIdAa64Dfr0El1, ARMV8_ID_AA64DFR0_EL1_HPMN0);
699
700#undef CPUID_GST_FEATURE_RET
701#undef CPUID_GST_FEATURE_RET_NOT_IMPL
702#undef CPUID_GST_FEATURE_WRN
703#undef CPUID_GST_FEATURE_EMU
704#undef CPUID_GST_FEATURE_IGN
705
706 /*
707 * We're good, commit the CPU ID registers.
708 */
709 pVM->cpum.s.GuestIdRegs = *pGuestIdRegs;
710 return VINF_SUCCESS;
711}
712
713
714/**
715 * Loads the CPU ID leaves saved by pass 0, ARMv8 targets.
716 *
717 * @returns VBox status code.
718 * @param pVM The cross context VM structure.
719 * @param pSSM The saved state handle.
720 * @param uVersion The format version.
721 */
722int cpumR3LoadCpuIdArmV8(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion)
723{
724 CPUMARMV8IDREGS GuestIdRegs;
725 int rc = SSMR3GetStructEx(pSSM, &GuestIdRegs, sizeof(GuestIdRegs), 0, g_aCpumArmV8IdRegsFields, NULL);
726 AssertRCReturn(rc, rc);
727
728 return cpumR3LoadCpuIdInner(pVM, pSSM, uVersion, &GuestIdRegs);
729}
730
731
732/*
733 *
734 *
735 * CPUID Info Handler.
736 * CPUID Info Handler.
737 * CPUID Info Handler.
738 *
739 *
740 */
741
742/** CLIDR_EL1 field descriptions. */
743static DBGFREGSUBFIELD const g_aClidrEl1Fields[] =
744{
745 DBGFREGSUBFIELD_RO("Ctype1\0" "Cache 1 type field", 0, 3, 0),
746 DBGFREGSUBFIELD_RO("Ctype2\0" "Cache 2 type field", 3, 3, 0),
747 DBGFREGSUBFIELD_RO("Ctype3\0" "Cache 3 type field", 6, 3, 0),
748 DBGFREGSUBFIELD_RO("Ctype4\0" "Cache 4 type field", 9, 3, 0),
749 DBGFREGSUBFIELD_RO("Ctype5\0" "Cache 5 type field", 12, 3, 0),
750 DBGFREGSUBFIELD_RO("Ctype6\0" "Cache 6 type field", 15, 3, 0),
751 DBGFREGSUBFIELD_RO("Ctype7\0" "Cache 7 type field", 18, 3, 0),
752 DBGFREGSUBFIELD_RO("LoUIS\0" "Level of Unification Inner Shareable", 21, 3, 0),
753 DBGFREGSUBFIELD_RO("LoC\0" "Level of Coherence for the cache hierarchy", 24, 3, 0),
754 DBGFREGSUBFIELD_RO("LoUU\0" "Level of Unification Uniprocessor", 27, 3, 0),
755 DBGFREGSUBFIELD_RO("ICB\0" "Inner cache boundary", 30, 3, 0),
756 DBGFREGSUBFIELD_RO("Ttype1\0" "Cache 1 - Tag cache type", 33, 2, 0),
757 DBGFREGSUBFIELD_RO("Ttype2\0" "Cache 2 - Tag cache type", 35, 2, 0),
758 DBGFREGSUBFIELD_RO("Ttype3\0" "Cache 3 - Tag cache type", 37, 2, 0),
759 DBGFREGSUBFIELD_RO("Ttype4\0" "Cache 4 - Tag cache type", 39, 2, 0),
760 DBGFREGSUBFIELD_RO("Ttype5\0" "Cache 5 - Tag cache type", 41, 2, 0),
761 DBGFREGSUBFIELD_RO("Ttype6\0" "Cache 6 - Tag cache type", 43, 2, 0),
762 DBGFREGSUBFIELD_RO("Ttype7\0" "Cache 7 - Tag cache type", 45, 2, 0),
763 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 47, 17, 0),
764 DBGFREGSUBFIELD_TERMINATOR()
765};
766
767
768/** ID_AA64PFR0_EL1 field descriptions. */
769static DBGFREGSUBFIELD const g_aIdAa64PfR0Fields[] =
770{
771 DBGFREGSUBFIELD_RO("EL0\0" "EL0 Exception level handling", 0, 4, 0),
772 DBGFREGSUBFIELD_RO("EL1\0" "EL1 Exception level handling", 4, 4, 0),
773 DBGFREGSUBFIELD_RO("EL2\0" "EL2 Exception level handling", 8, 4, 0),
774 DBGFREGSUBFIELD_RO("EL3\0" "EL3 Exception level handling", 12, 4, 0),
775 DBGFREGSUBFIELD_RO("FP\0" "Floating-point", 16, 4, 0),
776 DBGFREGSUBFIELD_RO("AdvSIMD\0" "Advanced SIMD", 20, 4, 0),
777 DBGFREGSUBFIELD_RO("GIC\0" "System register GIC CPU interface", 24, 4, 0),
778 DBGFREGSUBFIELD_RO("RAS\0" "RAS Extension version", 28, 4, 0),
779 DBGFREGSUBFIELD_RO("SVE\0" "Scalable Vector Extension", 32, 4, 0),
780 DBGFREGSUBFIELD_RO("SEL2\0" "Secure EL2", 36, 4, 0),
781 DBGFREGSUBFIELD_RO("MPAM\0" "MPAM Extension major version number", 40, 4, 0),
782 DBGFREGSUBFIELD_RO("AMU\0" "Activity Monitors Extension support", 44, 4, 0),
783 DBGFREGSUBFIELD_RO("DIT\0" "Data Independent Timing", 48, 4, 0),
784 DBGFREGSUBFIELD_RO("RME\0" "Realm Management Extension", 52, 4, 0),
785 DBGFREGSUBFIELD_RO("CSV2\0" "Speculative use of out of branch targets", 56, 4, 0),
786 DBGFREGSUBFIELD_RO("CSV3\0" "Speculative use of faulting data", 60, 4, 0),
787 DBGFREGSUBFIELD_TERMINATOR()
788};
789
790
791/** ID_AA64PFR1_EL1 field descriptions. */
792static DBGFREGSUBFIELD const g_aIdAa64PfR1Fields[] =
793{
794 DBGFREGSUBFIELD_RO("BT\0" "Branch Target Identification mechanism", 0, 4, 0),
795 DBGFREGSUBFIELD_RO("SSBS\0" "Speculative Store Bypassing controls", 4, 4, 0),
796 DBGFREGSUBFIELD_RO("MTE\0" "Memory Tagging Extension support", 8, 4, 0),
797 DBGFREGSUBFIELD_RO("RAS_frac\0" "RAS Extension fractional field", 12, 4, 0),
798 DBGFREGSUBFIELD_RO("MPAM_frac\0" "MPAM Extension minor version", 16, 4, 0),
799 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 20, 4, 0),
800 DBGFREGSUBFIELD_RO("SME\0" "Scalable Matrix Extension", 24, 4, 0),
801 DBGFREGSUBFIELD_RO("RNDR_trap\0" "Random Number trap to EL3", 28, 4, 0),
802 DBGFREGSUBFIELD_RO("CSV2_frac\0" "CSV2 fractional version field", 32, 4, 0),
803 DBGFREGSUBFIELD_RO("NMI\0" "Non-maskable Interrupt support", 36, 4, 0),
804 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 40, 4, 0),
805 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 44, 4, 0),
806 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 48, 4, 0),
807 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 52, 4, 0),
808 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 56, 4, 0),
809 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 60, 4, 0),
810 DBGFREGSUBFIELD_TERMINATOR()
811};
812
813
814/** ID_AA64ISAR0_EL1 field descriptions. */
815static DBGFREGSUBFIELD const g_aIdAa64IsaR0Fields[] =
816{
817 DBGFREGSUBFIELD_RO("AES\0" "AES instruction support in AArch64", 4, 4, 0),
818 DBGFREGSUBFIELD_RO("SHA1\0" "SHA1 instruction support in AArch64", 8, 4, 0),
819 DBGFREGSUBFIELD_RO("SHA2\0" "SHA256/512 instruction support in AArch64", 12, 4, 0),
820 DBGFREGSUBFIELD_RO("CRC32\0" "CRC32 instruction support in AArch64", 16, 4, 0),
821 DBGFREGSUBFIELD_RO("ATOMIC\0" "Atomic instruction support in AArch64", 20, 4, 0),
822 DBGFREGSUBFIELD_RO("TME\0" "TME instruction support in AArch64", 24, 4, 0),
823 DBGFREGSUBFIELD_RO("RDM\0" "SQRDMLAH/SQRDMLSH instruction support in AArch64", 28, 4, 0),
824 DBGFREGSUBFIELD_RO("SHA3\0" "SHA3 instruction support in AArch64", 32, 4, 0),
825 DBGFREGSUBFIELD_RO("SM3\0" "SM3 instruction support in AArch64", 36, 4, 0),
826 DBGFREGSUBFIELD_RO("SM4\0" "SM4 instruction support in AArch64", 40, 4, 0),
827 DBGFREGSUBFIELD_RO("DP\0" "Dot Product instruction support in AArch64", 44, 4, 0),
828 DBGFREGSUBFIELD_RO("FHM\0" "FMLAL/FMLSL instruction support in AArch64", 48, 4, 0),
829 DBGFREGSUBFIELD_RO("TS\0" "Flag manipulation instruction support in AArch64", 52, 4, 0),
830 DBGFREGSUBFIELD_RO("TLB\0" "TLB maintenance instruction support in AArch64", 56, 4, 0),
831 DBGFREGSUBFIELD_RO("RNDR\0" "Random number instruction support in AArch64", 60, 4, 0),
832 DBGFREGSUBFIELD_TERMINATOR()
833};
834
835
836/** ID_AA64ISAR1_EL1 field descriptions. */
837static DBGFREGSUBFIELD const g_aIdAa64IsaR1Fields[] =
838{
839 DBGFREGSUBFIELD_RO("DPB\0" "Data Persistance writeback support in AArch64", 0, 4, 0),
840 DBGFREGSUBFIELD_RO("APA\0" "QARMA5 PAuth support in AArch64", 4, 4, 0),
841 DBGFREGSUBFIELD_RO("API\0" "Impl defined PAuth support in AArch64", 8, 4, 0),
842 DBGFREGSUBFIELD_RO("JSCVT\0" "FJCVTZS instruction support in AArch64", 12, 4, 0),
843 DBGFREGSUBFIELD_RO("FCMA\0" "FCMLA/FCADD instruction support in AArch64", 16, 4, 0),
844 DBGFREGSUBFIELD_RO("LRCPC\0" "RCpc instruction support in AArch64", 20, 4, 0),
845 DBGFREGSUBFIELD_RO("GPA\0" "QARMA5 code authentication support in AArch64", 24, 4, 0),
846 DBGFREGSUBFIELD_RO("GPI\0" "Impl defined code authentication support in AArch64", 28, 4, 0),
847 DBGFREGSUBFIELD_RO("FRINTTS\0" "FRINT{32,64}{Z,X} instruction support in AArch64", 32, 4, 0),
848 DBGFREGSUBFIELD_RO("SB\0" "SB instruction support in AArch64", 36, 4, 0),
849 DBGFREGSUBFIELD_RO("SPECRES\0" "Prediction invalidation support in AArch64", 40, 4, 0),
850 DBGFREGSUBFIELD_RO("BF16\0" "BFloat16 support in AArch64", 44, 4, 0),
851 DBGFREGSUBFIELD_RO("DGH\0" "Data Gathering Hint support in AArch64", 48, 4, 0),
852 DBGFREGSUBFIELD_RO("I8MM\0" "Int8 matrix mul instruction support in AArch64", 52, 4, 0),
853 DBGFREGSUBFIELD_RO("XS\0" "XS attribute support in AArch64", 56, 4, 0),
854 DBGFREGSUBFIELD_RO("LS64\0" "LD64B and ST64B* instruction support in AArch64", 60, 4, 0),
855 DBGFREGSUBFIELD_TERMINATOR()
856};
857
858
859/** ID_AA64ISAR2_EL1 field descriptions. */
860static DBGFREGSUBFIELD const g_aIdAa64IsaR2Fields[] =
861{
862 DBGFREGSUBFIELD_RO("WFxT\0" "WFET/WFIT intruction support in AArch64", 0, 4, 0),
863 DBGFREGSUBFIELD_RO("RPRES\0" "Reciprocal 12 bit mantissa support in AArch64", 4, 4, 0),
864 DBGFREGSUBFIELD_RO("GPA3\0" "QARMA3 code authentication support in AArch64", 8, 4, 0),
865 DBGFREGSUBFIELD_RO("APA3\0" "QARMA3 PAuth support in AArch64", 12, 4, 0),
866 DBGFREGSUBFIELD_RO("MOPS\0" "Memory Copy and Set instruction support in AArch64", 16, 4, 0),
867 DBGFREGSUBFIELD_RO("BC\0" "BC instruction support in AArch64", 20, 4, 0),
868 DBGFREGSUBFIELD_RO("PAC_frac\0" "ConstPACField() returns TRUE", 24, 4, 0),
869 DBGFREGSUBFIELD_TERMINATOR()
870};
871
872
873/** ID_AA64MMFR0_EL1 field descriptions. */
874static DBGFREGSUBFIELD const g_aIdAa64MmfR0Fields[] =
875{
876 DBGFREGSUBFIELD_RO("PARange\0" "Physical address width", 0, 4, 0),
877 DBGFREGSUBFIELD_RO("ASIDBits\0" "Number of ASID bits", 4, 4, 0),
878 DBGFREGSUBFIELD_RO("BigEnd\0" "Mixed-endian configuration support", 8, 4, 0),
879 DBGFREGSUBFIELD_RO("SNSMem\0" "Secure and Non-secure memory distinction", 12, 4, 0),
880 DBGFREGSUBFIELD_RO("BigEndEL0\0" "Mixed-endian support in EL0 only", 16, 4, 0),
881 DBGFREGSUBFIELD_RO("TGran16\0" "16KiB memory granule size", 20, 4, 0),
882 DBGFREGSUBFIELD_RO("TGran64\0" "64KiB memory granule size", 24, 4, 0),
883 DBGFREGSUBFIELD_RO("TGran4\0" "4KiB memory granule size", 28, 4, 0),
884 DBGFREGSUBFIELD_RO("TGran16_2\0" "16KiB memory granule size at stage 2", 32, 4, 0),
885 DBGFREGSUBFIELD_RO("TGran64_2\0" "64KiB memory granule size at stage 2", 36, 4, 0),
886 DBGFREGSUBFIELD_RO("TGran4_2\0" "4KiB memory granule size at stage 2", 40, 4, 0),
887 DBGFREGSUBFIELD_RO("ExS\0" "Disabling context synchronizing exception", 44, 4, 0),
888 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 48, 4, 0),
889 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 52, 4, 0),
890 DBGFREGSUBFIELD_RO("FGT\0" "Fine-grained trap controls support", 56, 4, 0),
891 DBGFREGSUBFIELD_RO("ECV\0" "Enhanced Counter Virtualization support", 60, 4, 0),
892 DBGFREGSUBFIELD_TERMINATOR()
893};
894
895
896/** ID_AA64MMFR1_EL1 field descriptions. */
897static DBGFREGSUBFIELD const g_aIdAa64MmfR1Fields[] =
898{
899 DBGFREGSUBFIELD_RO("HAFDBS\0" "Hardware updates to Access/Dirty state", 0, 4, 0),
900 DBGFREGSUBFIELD_RO("VMIDBit\0" "Number of VMID bits", 4, 4, 0),
901 DBGFREGSUBFIELD_RO("VH\0" "Virtualization Host Extensions", 8, 4, 0),
902 DBGFREGSUBFIELD_RO("HPDS\0" "Hierarchical Permission Disables", 12, 4, 0),
903 DBGFREGSUBFIELD_RO("LO\0" "LORegions support", 16, 4, 0),
904 DBGFREGSUBFIELD_RO("PAN\0" "Privileged Access Never", 20, 4, 0),
905 DBGFREGSUBFIELD_RO("SpecSEI\0" "SError interrupt exception for speculative reads", 24, 4, 0),
906 DBGFREGSUBFIELD_RO("XNX\0" "Execute-never control support", 28, 4, 0),
907 DBGFREGSUBFIELD_RO("TWED\0" "Configurable delayed WFE trapping", 32, 4, 0),
908 DBGFREGSUBFIELD_RO("ETS\0" "Enhanced Translation Synchronization support", 36, 4, 0),
909 DBGFREGSUBFIELD_RO("HCX\0" "HCRX_EL2 support", 40, 4, 0),
910 DBGFREGSUBFIELD_RO("AFP\0" "FPCR.{AH,FIZ,NEP} support", 44, 4, 0),
911 DBGFREGSUBFIELD_RO("nTLBPA\0" "Caching of translation table walks", 48, 4, 0),
912 DBGFREGSUBFIELD_RO("TIDCP1\0" "FEAT_TIDCP1 support", 52, 4, 0),
913 DBGFREGSUBFIELD_RO("CMOW\0" "Cache maintenance instruction permission", 56, 4, 0),
914 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 60, 4, 0),
915 DBGFREGSUBFIELD_TERMINATOR()
916};
917
918
919/** ID_AA64MMFR2_EL1 field descriptions. */
920static DBGFREGSUBFIELD const g_aIdAa64MmfR2Fields[] =
921{
922 DBGFREGSUBFIELD_RO("CnP\0" "Common not Private translation support", 0, 4, 0),
923 DBGFREGSUBFIELD_RO("UAO\0" "User Access Override", 4, 4, 0),
924 DBGFREGSUBFIELD_RO("LSM\0" "LSMAOE/nTLSMD bit support", 8, 4, 0),
925 DBGFREGSUBFIELD_RO("IESB\0" "IESB bit support in SCTLR_ELx", 12, 4, 0),
926 DBGFREGSUBFIELD_RO("VARange\0" "Large virtual address space support", 16, 4, 0),
927 DBGFREGSUBFIELD_RO("CCIDX\0" "64-bit CCSIDR_EL1 format", 20, 4, 0),
928 DBGFREGSUBFIELD_RO("NV\0" "Nested Virtualization support", 24, 4, 0),
929 DBGFREGSUBFIELD_RO("ST\0" "Small translation table support", 28, 4, 0),
930 DBGFREGSUBFIELD_RO("AT\0" "Unaligned single-copy atomicity support", 32, 4, 0),
931 DBGFREGSUBFIELD_RO("IDS\0" "FEAT_IDST support", 36, 4, 0),
932 DBGFREGSUBFIELD_RO("FWB\0" "HCR_EL2.FWB support", 40, 4, 0),
933 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 44, 4, 0),
934 DBGFREGSUBFIELD_RO("TTL\0" "TTL field support in address operations", 48, 4, 0),
935 DBGFREGSUBFIELD_RO("BBM\0" "FEAT_BBM support", 52, 4, 0),
936 DBGFREGSUBFIELD_RO("EVT\0" "Enhanced Virtualization Traps support", 56, 4, 0),
937 DBGFREGSUBFIELD_RO("E0PD\0" "E0PD mechanism support", 60, 4, 0),
938 DBGFREGSUBFIELD_TERMINATOR()
939};
940
941
942/** ID_AA64DFR0_EL1 field descriptions. */
943static DBGFREGSUBFIELD const g_aIdAa64DfR0Fields[] =
944{
945 DBGFREGSUBFIELD_RO("DebugVer\0" "Debug architecture version", 0, 4, 0),
946 DBGFREGSUBFIELD_RO("TraceVer\0" "Trace support", 4, 4, 0),
947 DBGFREGSUBFIELD_RO("PMUVer\0" "Performance Monitors Extension version", 8, 4, 0),
948 DBGFREGSUBFIELD_RO("BRPs\0" "Number of breakpoints minus 1", 12, 4, 0),
949 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 16, 4, 0),
950 DBGFREGSUBFIELD_RO("WRPs\0" "Number of watchpoints minus 1", 20, 4, 0),
951 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 24, 4, 0),
952 DBGFREGSUBFIELD_RO("CTX_CMPs\0" "Number of context-aware breakpoints minus 1", 28, 4, 0),
953 DBGFREGSUBFIELD_RO("PMSVer\0" "Statistical Profiling Extension version", 32, 4, 0),
954 DBGFREGSUBFIELD_RO("DoubleLock\0" "OS Double Lock support", 36, 4, 0),
955 DBGFREGSUBFIELD_RO("TraceFilt\0" "Armv8.4 Self-hosted Trace Extension version", 40, 4, 0),
956 DBGFREGSUBFIELD_RO("TraceBuffer\0" "Trace Buffer Extension", 44, 4, 0),
957 DBGFREGSUBFIELD_RO("MTPMU\0" "Multi-threaded PMU extension", 48, 4, 0),
958 DBGFREGSUBFIELD_RO("BRBE\0" "Branch Record Buffer Extension", 52, 4, 0),
959 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 56, 4, 0),
960 DBGFREGSUBFIELD_RO("HPMN0\0" "Zero PMU event counters for guest", 60, 4, 0),
961 DBGFREGSUBFIELD_TERMINATOR()
962};
963
964
965/** ID_AA64DFR1_EL1 field descriptions. */
966static DBGFREGSUBFIELD const g_aIdAa64DfR1Fields[] =
967{
968 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 0, 4, 0),
969 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 4, 4, 0),
970 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 8, 4, 0),
971 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 12, 4, 0),
972 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 16, 4, 0),
973 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 20, 4, 0),
974 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 24, 4, 0),
975 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 28, 4, 0),
976 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 32, 4, 0),
977 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 36, 4, 0),
978 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 40, 4, 0),
979 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 44, 4, 0),
980 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 48, 4, 0),
981 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 52, 4, 0),
982 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 56, 4, 0),
983 DBGFREGSUBFIELD_RO("Res0\0" "Reserved", 60, 4, 0),
984 DBGFREGSUBFIELD_TERMINATOR()
985};
986
987
988/** ID_AA64AFR0_EL1 field descriptions. */
989static DBGFREGSUBFIELD const g_aIdAa64AfR0Fields[] =
990{
991 DBGFREGSUBFIELD_RO("ImpDef\0" "Implementation defined", 0, 32, 0),
992 DBGFREGSUBFIELD_TERMINATOR()
993};
994
995
996/** ID_AA64AFR1_EL1 field descriptions. */
997static DBGFREGSUBFIELD const g_aIdAa64AfR1Fields[] =
998{
999 DBGFREGSUBFIELD_RO("ImpDef\0" "Implementation defined", 0, 32, 0),
1000 DBGFREGSUBFIELD_TERMINATOR()
1001};
1002
1003
1004static void cpumR3CpuIdInfoMnemonicListU64(PCDBGFINFOHLP pHlp, uint64_t uVal, PCDBGFREGSUBFIELD pDesc,
1005 const char *pszLeadIn, uint32_t cchWidth)
1006{
1007 if (pszLeadIn)
1008 pHlp->pfnPrintf(pHlp, "%*s", cchWidth, pszLeadIn);
1009
1010 for (uint32_t iBit = 0; iBit < 64; iBit++)
1011 if (RT_BIT_64(iBit) & uVal)
1012 {
1013 while ( pDesc->pszName != NULL
1014 && iBit >= (uint32_t)pDesc->iFirstBit + pDesc->cBits)
1015 pDesc++;
1016 if ( pDesc->pszName != NULL
1017 && iBit - (uint32_t)pDesc->iFirstBit < (uint32_t)pDesc->cBits)
1018 {
1019 if (pDesc->cBits == 1)
1020 pHlp->pfnPrintf(pHlp, " %s", pDesc->pszName);
1021 else
1022 {
1023 uint64_t uFieldValue = uVal >> pDesc->iFirstBit;
1024 if (pDesc->cBits < 64)
1025 uFieldValue &= RT_BIT_64(pDesc->cBits) - UINT64_C(1);
1026 pHlp->pfnPrintf(pHlp, pDesc->cBits < 4 ? " %s=%llu" : " %s=%#llx", pDesc->pszName, uFieldValue);
1027 iBit = pDesc->iFirstBit + pDesc->cBits - 1;
1028 }
1029 }
1030 else
1031 pHlp->pfnPrintf(pHlp, " %u", iBit);
1032 }
1033 if (pszLeadIn)
1034 pHlp->pfnPrintf(pHlp, "\n");
1035}
1036
1037
1038static void cpumR3CpuIdInfoVerboseCompareListU64(PCDBGFINFOHLP pHlp, uint64_t uVal1, uint64_t uVal2, PCDBGFREGSUBFIELD pDesc,
1039 uint32_t cchWidth)
1040{
1041 uint32_t uCombined = uVal1 | uVal2;
1042 for (uint32_t iBit = 0; iBit < 64; iBit++)
1043 if ( (RT_BIT_64(iBit) & uCombined)
1044 || (iBit == pDesc->iFirstBit && pDesc->pszName) )
1045 {
1046 while ( pDesc->pszName != NULL
1047 && iBit >= (uint32_t)pDesc->iFirstBit + pDesc->cBits)
1048 pDesc++;
1049
1050 if ( pDesc->pszName != NULL
1051 && iBit - (uint32_t)pDesc->iFirstBit < (uint32_t)pDesc->cBits)
1052 {
1053 size_t cchMnemonic = strlen(pDesc->pszName);
1054 const char *pszDesc = pDesc->pszName + cchMnemonic + 1;
1055 size_t cchDesc = strlen(pszDesc);
1056 uint32_t uFieldValue1 = uVal1 >> pDesc->iFirstBit;
1057 uint32_t uFieldValue2 = uVal2 >> pDesc->iFirstBit;
1058 if (pDesc->cBits < 64)
1059 {
1060 uFieldValue1 &= RT_BIT_64(pDesc->cBits) - UINT64_C(1);
1061 uFieldValue2 &= RT_BIT_64(pDesc->cBits) - UINT64_C(1);
1062 }
1063
1064 pHlp->pfnPrintf(pHlp, pDesc->cBits < 5 ? " %s - %s%*s= %u (%u)\n" : " %s - %s%*s= %#x (%#x)\n",
1065 pDesc->pszName, pszDesc,
1066 cchMnemonic + 3 + cchDesc < cchWidth ? cchWidth - (cchMnemonic + 3 + cchDesc) : 1, "",
1067 uFieldValue1, uFieldValue2);
1068
1069 iBit = pDesc->iFirstBit + pDesc->cBits - 1U;
1070 pDesc++;
1071 }
1072 else
1073 pHlp->pfnPrintf(pHlp, " %2u - Reserved%*s= %u (%u)\n", iBit, 13 < cchWidth ? cchWidth - 13 : 1, "",
1074 RT_BOOL(uVal1 & RT_BIT_64(iBit)), RT_BOOL(uVal2 & RT_BIT_64(iBit)));
1075 }
1076}
1077
1078
1079/**
1080 * Produces a detailed summary of standard leaf 0x00000007.
1081 *
1082 * @param pHlp The info helper functions.
1083 * @param pszIdReg The ID register name.
1084 * @param u64IdRegHost The host value of the ID register.
1085 * @param u64IdRegGuest The guest value of the ID register.
1086 * @param pDesc The field descriptor.
1087 * @param fVerbose Whether to be very verbose or not.
1088 */
1089static void cpumR3CpuIdInfoIdRegDetails(PCDBGFINFOHLP pHlp, const char *pszIdReg, uint64_t u64IdRegHost, uint64_t u64IdRegGuest,
1090 PCDBGFREGSUBFIELD pDesc, bool fVerbose)
1091{
1092 pHlp->pfnPrintf(pHlp, "ID register %s: Host %#RX64 Guest %#RX64\n", pszIdReg, u64IdRegHost, u64IdRegGuest);
1093 if (fVerbose)
1094 {
1095 pHlp->pfnPrintf(pHlp, " Mnemonic - Description = guest (host)\n");
1096 cpumR3CpuIdInfoVerboseCompareListU64(pHlp, u64IdRegGuest, u64IdRegHost, pDesc, 56);
1097 }
1098 else
1099 cpumR3CpuIdInfoMnemonicListU64(pHlp, u64IdRegGuest, pDesc, "Features:", 36);
1100}
1101
1102
1103/**
1104 * Display the guest CpuId leaves.
1105 *
1106 * @param pVM The cross context VM structure.
1107 * @param pHlp The info helper functions.
1108 * @param pszArgs "terse", "default" or "verbose".
1109 */
1110DECLCALLBACK(void) cpumR3CpuIdInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
1111{
1112 /*
1113 * Parse the argument.
1114 */
1115 unsigned iVerbosity = 1;
1116 if (pszArgs)
1117 {
1118 pszArgs = RTStrStripL(pszArgs);
1119 if (!strcmp(pszArgs, "terse"))
1120 iVerbosity--;
1121 else if (!strcmp(pszArgs, "verbose"))
1122 iVerbosity++;
1123 }
1124
1125 /** @todo MIDR_EL1. */
1126
1127 cpumR3CpuIdInfoIdRegDetails(pHlp, "CLIDR_EL1",
1128 pVM->cpum.s.HostIdRegs.u64RegClidrEl1,
1129 pVM->cpum.s.GuestIdRegs.u64RegClidrEl1,
1130 g_aClidrEl1Fields, iVerbosity > 1);
1131
1132 cpumR3CpuIdInfoIdRegDetails(pHlp, "ID_AA64PFR0_EL1",
1133 pVM->cpum.s.HostIdRegs.u64RegIdAa64Pfr0El1,
1134 pVM->cpum.s.GuestIdRegs.u64RegIdAa64Pfr0El1,
1135 g_aIdAa64PfR0Fields, iVerbosity > 1);
1136
1137 cpumR3CpuIdInfoIdRegDetails(pHlp, "ID_AA64PFR1_EL1",
1138 pVM->cpum.s.HostIdRegs.u64RegIdAa64Pfr1El1,
1139 pVM->cpum.s.GuestIdRegs.u64RegIdAa64Pfr1El1,
1140 g_aIdAa64PfR1Fields, iVerbosity > 1);
1141
1142 cpumR3CpuIdInfoIdRegDetails(pHlp, "ID_AA64ISAR0_EL1",
1143 pVM->cpum.s.HostIdRegs.u64RegIdAa64Isar0El1,
1144 pVM->cpum.s.GuestIdRegs.u64RegIdAa64Isar0El1,
1145 g_aIdAa64IsaR0Fields, iVerbosity > 1);
1146
1147 cpumR3CpuIdInfoIdRegDetails(pHlp, "ID_AA64ISAR1_EL1",
1148 pVM->cpum.s.HostIdRegs.u64RegIdAa64Isar1El1,
1149 pVM->cpum.s.GuestIdRegs.u64RegIdAa64Isar1El1,
1150 g_aIdAa64IsaR1Fields, iVerbosity > 1);
1151
1152 cpumR3CpuIdInfoIdRegDetails(pHlp, "ID_AA64ISAR2_EL1",
1153 pVM->cpum.s.HostIdRegs.u64RegIdAa64Isar2El1,
1154 pVM->cpum.s.GuestIdRegs.u64RegIdAa64Isar2El1,
1155 g_aIdAa64IsaR2Fields, iVerbosity > 1);
1156
1157 cpumR3CpuIdInfoIdRegDetails(pHlp, "ID_AA64MMFR0_EL1",
1158 pVM->cpum.s.HostIdRegs.u64RegIdAa64Mmfr0El1,
1159 pVM->cpum.s.GuestIdRegs.u64RegIdAa64Mmfr0El1,
1160 g_aIdAa64MmfR0Fields, iVerbosity > 1);
1161
1162 cpumR3CpuIdInfoIdRegDetails(pHlp, "ID_AA64MMFR1_EL1",
1163 pVM->cpum.s.HostIdRegs.u64RegIdAa64Mmfr1El1,
1164 pVM->cpum.s.GuestIdRegs.u64RegIdAa64Mmfr1El1,
1165 g_aIdAa64MmfR1Fields, iVerbosity > 1);
1166
1167 cpumR3CpuIdInfoIdRegDetails(pHlp, "ID_AA64MMFR2_EL1",
1168 pVM->cpum.s.HostIdRegs.u64RegIdAa64Mmfr2El1,
1169 pVM->cpum.s.GuestIdRegs.u64RegIdAa64Mmfr2El1,
1170 g_aIdAa64MmfR2Fields, iVerbosity > 1);
1171
1172 cpumR3CpuIdInfoIdRegDetails(pHlp, "ID_AA64DFR0_EL1",
1173 pVM->cpum.s.HostIdRegs.u64RegIdAa64Dfr0El1,
1174 pVM->cpum.s.GuestIdRegs.u64RegIdAa64Dfr0El1,
1175 g_aIdAa64DfR0Fields, iVerbosity > 1);
1176
1177 cpumR3CpuIdInfoIdRegDetails(pHlp, "ID_AA64DFR1_EL1",
1178 pVM->cpum.s.HostIdRegs.u64RegIdAa64Dfr1El1,
1179 pVM->cpum.s.GuestIdRegs.u64RegIdAa64Dfr1El1,
1180 g_aIdAa64DfR1Fields, iVerbosity > 1);
1181
1182 cpumR3CpuIdInfoIdRegDetails(pHlp, "ID_AA64AFR0_EL1",
1183 pVM->cpum.s.HostIdRegs.u64RegIdAa64Afr0El1,
1184 pVM->cpum.s.GuestIdRegs.u64RegIdAa64Afr0El1,
1185 g_aIdAa64AfR0Fields, iVerbosity > 1);
1186
1187 cpumR3CpuIdInfoIdRegDetails(pHlp, "ID_AA64AFR1_EL1",
1188 pVM->cpum.s.HostIdRegs.u64RegIdAa64Afr1El1,
1189 pVM->cpum.s.GuestIdRegs.u64RegIdAa64Afr1El1,
1190 g_aIdAa64AfR1Fields, iVerbosity > 1);
1191}
1192
1193
1194/**
1195 * Display the guest CPU features.
1196 *
1197 * @param pVM The cross context VM structure.
1198 * @param pHlp The info helper functions.
1199 * @param pszArgs "default" or "verbose".
1200 */
1201DECLCALLBACK(void) cpumR3CpuFeatInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
1202{
1203 /*
1204 * Parse the argument.
1205 */
1206 bool fVerbose = false;
1207 if (pszArgs)
1208 {
1209 pszArgs = RTStrStripL(pszArgs);
1210 if (!strcmp(pszArgs, "verbose"))
1211 fVerbose = true;
1212 }
1213
1214 if (fVerbose)
1215 pHlp->pfnPrintf(pHlp, " Features = guest (host)\n");
1216 else
1217 pHlp->pfnPrintf(pHlp, " Features = guest\n");
1218
1219
1220#define LOG_CPU_FEATURE(a_FeatNm, a_Flag) \
1221 do { \
1222 if (fVerbose) \
1223 pHlp->pfnPrintf(pHlp, " %*s = %u (%u)\n", 41, #a_FeatNm, pVM->cpum.s.GuestFeatures.a_Flag, pVM->cpum.s.HostFeatures.s.a_Flag); \
1224 else \
1225 pHlp->pfnPrintf(pHlp, " %*s = %u\n", 41, #a_FeatNm, pVM->cpum.s.GuestFeatures.a_Flag); \
1226 } while (0)
1227
1228 /* Not really features. */
1229 LOG_CPU_FEATURE(FEAT_TGRAN4K, fTGran4K);
1230 LOG_CPU_FEATURE(FEAT_TGRAN16K, fTGran16K);
1231 LOG_CPU_FEATURE(FEAT_TGRAN64K, fTGran64K);
1232
1233 /* Offical ARM FEAT_* definitions start here. */
1234 LOG_CPU_FEATURE(FEAT_AdvSIMD, fAdvSimd);
1235 LOG_CPU_FEATURE(FEAT_AES, fAes);
1236 LOG_CPU_FEATURE(FEAT_PMULL, fPmull);
1237 LOG_CPU_FEATURE(FEAT_CP15DISABLE2, fCp15Disable2);
1238 LOG_CPU_FEATURE(FEAT_CSV2, fCsv2);
1239 LOG_CPU_FEATURE(FEAT_CSV2_1p1, fCsv21p1);
1240 LOG_CPU_FEATURE(FEAT_CSV2_1p2, fCsv21p2);
1241 LOG_CPU_FEATURE(FEAT_CSV3, fCsv3);
1242 LOG_CPU_FEATURE(FEAT_DGH, fDgh);
1243 LOG_CPU_FEATURE(FEAT_DOUBLELOCK, fDoubleLock);
1244 LOG_CPU_FEATURE(FEAT_ETS2, fEts2);
1245 LOG_CPU_FEATURE(FEAT_FP, fFp);
1246 LOG_CPU_FEATURE(FEAT_IVIPT, fIvipt);
1247 LOG_CPU_FEATURE(FEAT_PCSRv8, fPcsrV8);
1248 LOG_CPU_FEATURE(FEAT_SPECRES, fSpecres);
1249 LOG_CPU_FEATURE(FEAT_RAS, fRas);
1250 LOG_CPU_FEATURE(FEAT_SB, fSb);
1251 LOG_CPU_FEATURE(FEAT_SHA1, fSha1);
1252 LOG_CPU_FEATURE(FEAT_SHA256, fSha256);
1253 LOG_CPU_FEATURE(FEAT_SSBS, fSsbs);
1254 LOG_CPU_FEATURE(FEAT_SSBS2, fSsbs2);
1255 LOG_CPU_FEATURE(FEAT_CRC32, fCrc32);
1256 LOG_CPU_FEATURE(FEAT_nTLBPA, fNTlbpa);
1257 LOG_CPU_FEATURE(FEAT_Debugv8p1, fDebugV8p1);
1258 LOG_CPU_FEATURE(FEAT_HPDS, fHpds);
1259 LOG_CPU_FEATURE(FEAT_LOR, fLor);
1260 LOG_CPU_FEATURE(FEAT_LSE, fLse);
1261 LOG_CPU_FEATURE(FEAT_PAN, fPan);
1262 LOG_CPU_FEATURE(FEAT_PMUv3p1, fPmuV3p1);
1263 LOG_CPU_FEATURE(FEAT_RDM, fRdm);
1264 LOG_CPU_FEATURE(FEAT_HAFDBS, fHafdbs);
1265 LOG_CPU_FEATURE(FEAT_VHE, fVhe);
1266 LOG_CPU_FEATURE(FEAT_VMID16, fVmid16);
1267 LOG_CPU_FEATURE(FEAT_AA32BF16, fAa32Bf16);
1268 LOG_CPU_FEATURE(FEAT_AA32HPD, fAa32Hpd);
1269 LOG_CPU_FEATURE(FEAT_AA32I8MM, fAa32I8mm);
1270 LOG_CPU_FEATURE(FEAT_PAN2, fPan2);
1271 LOG_CPU_FEATURE(FEAT_BF16, fBf16);
1272 LOG_CPU_FEATURE(FEAT_DPB2, fDpb2);
1273 LOG_CPU_FEATURE(FEAT_DPB, fDpb);
1274 LOG_CPU_FEATURE(FEAT_Debugv8p2, fDebugV8p2);
1275 LOG_CPU_FEATURE(FEAT_DotProd, fDotProd);
1276 LOG_CPU_FEATURE(FEAT_EVT, fEvt);
1277 LOG_CPU_FEATURE(FEAT_F32MM, fF32mm);
1278 LOG_CPU_FEATURE(FEAT_F64MM, fF64mm);
1279 LOG_CPU_FEATURE(FEAT_FHM, fFhm);
1280 LOG_CPU_FEATURE(FEAT_FP16, fFp16);
1281 LOG_CPU_FEATURE(FEAT_I8MM, fI8mm);
1282 LOG_CPU_FEATURE(FEAT_IESB, fIesb);
1283 LOG_CPU_FEATURE(FEAT_LPA, fLpa);
1284 LOG_CPU_FEATURE(FEAT_LSMAOC, fLsmaoc);
1285 LOG_CPU_FEATURE(FEAT_LVA, fLva);
1286 LOG_CPU_FEATURE(FEAT_MPAM, fMpam);
1287 LOG_CPU_FEATURE(FEAT_PCSRv8p2, fPcsrV8p2);
1288 LOG_CPU_FEATURE(FEAT_SHA3, fSha3);
1289 LOG_CPU_FEATURE(FEAT_SHA512, fSha512);
1290 LOG_CPU_FEATURE(FEAT_SM3, fSm3);
1291 LOG_CPU_FEATURE(FEAT_SM4, fSm4);
1292 LOG_CPU_FEATURE(FEAT_SPE, fSpe);
1293 LOG_CPU_FEATURE(FEAT_SVE, fSve);
1294 LOG_CPU_FEATURE(FEAT_TTCNP, fTtcnp);
1295 LOG_CPU_FEATURE(FEAT_HPDS2, fHpds2);
1296 LOG_CPU_FEATURE(FEAT_XNX, fXnx);
1297 LOG_CPU_FEATURE(FEAT_UAO, fUao);
1298 LOG_CPU_FEATURE(FEAT_VPIPT, fVpipt);
1299 LOG_CPU_FEATURE(FEAT_CCIDX, fCcidx);
1300 LOG_CPU_FEATURE(FEAT_FCMA, fFcma);
1301 LOG_CPU_FEATURE(FEAT_DoPD, fDopd);
1302 LOG_CPU_FEATURE(FEAT_EPAC, fEpac);
1303 LOG_CPU_FEATURE(FEAT_FPAC, fFpac);
1304 LOG_CPU_FEATURE(FEAT_FPACCOMBINE, fFpacCombine);
1305 LOG_CPU_FEATURE(FEAT_JSCVT, fJscvt);
1306 LOG_CPU_FEATURE(FEAT_LRCPC, fLrcpc);
1307 LOG_CPU_FEATURE(FEAT_NV, fNv);
1308 LOG_CPU_FEATURE(FEAT_PACQARMA5, fPacQarma5);
1309 LOG_CPU_FEATURE(FEAT_PACIMP, fPacImp);
1310 LOG_CPU_FEATURE(FEAT_PAuth, fPAuth);
1311 LOG_CPU_FEATURE(FEAT_PAuth2, fPAuth2);
1312 LOG_CPU_FEATURE(FEAT_SPEv1p1, fSpeV1p1);
1313 LOG_CPU_FEATURE(FEAT_AMUv1, fAmuV1);
1314 LOG_CPU_FEATURE(FEAT_CNTSC, fCntsc);
1315 LOG_CPU_FEATURE(FEAT_Debugv8p4, fDebugV8p4);
1316 LOG_CPU_FEATURE(FEAT_DoubleFault, fDoubleFault);
1317 LOG_CPU_FEATURE(FEAT_DIT, fDit);
1318 LOG_CPU_FEATURE(FEAT_FlagM, fFlagM);
1319 LOG_CPU_FEATURE(FEAT_IDST, fIdst);
1320 LOG_CPU_FEATURE(FEAT_LRCPC2, fLrcpc2);
1321 LOG_CPU_FEATURE(FEAT_LSE2, fLse2);
1322 LOG_CPU_FEATURE(FEAT_NV2, fNv2);
1323 LOG_CPU_FEATURE(FEAT_PMUv3p4, fPmuV3p4);
1324 LOG_CPU_FEATURE(FEAT_RASv1p1, fRasV1p1);
1325 LOG_CPU_FEATURE(FEAT_RASSAv1p1, fRassaV1p1);
1326 LOG_CPU_FEATURE(FEAT_S2FWB, fS2Fwb);
1327 LOG_CPU_FEATURE(FEAT_SEL2, fSecEl2);
1328 LOG_CPU_FEATURE(FEAT_TLBIOS, fTlbios);
1329 LOG_CPU_FEATURE(FEAT_TLBIRANGE, fTlbirange);
1330 LOG_CPU_FEATURE(FEAT_TRF, fTrf);
1331 LOG_CPU_FEATURE(FEAT_TTL, fTtl);
1332 LOG_CPU_FEATURE(FEAT_BBM, fBbm);
1333 LOG_CPU_FEATURE(FEAT_TTST, fTtst);
1334 LOG_CPU_FEATURE(FEAT_BTI, fBti);
1335 LOG_CPU_FEATURE(FEAT_FlagM2, fFlagM2);
1336 LOG_CPU_FEATURE(FEAT_ExS, fExs);
1337 LOG_CPU_FEATURE(FEAT_E0PD, fE0Pd);
1338 LOG_CPU_FEATURE(FEAT_FRINTTS, fFrintts);
1339 LOG_CPU_FEATURE(FEAT_GTG, fGtg);
1340 LOG_CPU_FEATURE(FEAT_MTE, fMte);
1341 LOG_CPU_FEATURE(FEAT_MTE2, fMte2);
1342 LOG_CPU_FEATURE(FEAT_PMUv3p5, fPmuV3p5);
1343 LOG_CPU_FEATURE(FEAT_RNG, fRng);
1344 LOG_CPU_FEATURE(FEAT_AMUv1p1, fAmuV1p1);
1345 LOG_CPU_FEATURE(FEAT_ECV, fEcv);
1346 LOG_CPU_FEATURE(FEAT_FGT, fFgt);
1347 LOG_CPU_FEATURE(FEAT_MPAMv0p1, fMpamV0p1);
1348 LOG_CPU_FEATURE(FEAT_MPAMv1p1, fMpamV1p1);
1349 LOG_CPU_FEATURE(FEAT_MTPMU, fMtPmu);
1350 LOG_CPU_FEATURE(FEAT_TWED, fTwed);
1351 LOG_CPU_FEATURE(FEAT_ETMv4, fEtmV4);
1352 LOG_CPU_FEATURE(FEAT_ETMv4p1, fEtmV4p1);
1353 LOG_CPU_FEATURE(FEAT_ETMv4p2, fEtmV4p2);
1354 LOG_CPU_FEATURE(FEAT_ETMv4p3, fEtmV4p3);
1355 LOG_CPU_FEATURE(FEAT_ETMv4p4, fEtmV4p4);
1356 LOG_CPU_FEATURE(FEAT_ETMv4p5, fEtmV4p5);
1357 LOG_CPU_FEATURE(FEAT_ETMv4p6, fEtmV4p6);
1358 LOG_CPU_FEATURE(FEAT_GICv3, fGicV3);
1359 LOG_CPU_FEATURE(FEAT_GICv3p1, fGicV3p1);
1360 LOG_CPU_FEATURE(FEAT_GICv3_TDIR, fGicV3Tdir);
1361 LOG_CPU_FEATURE(FEAT_GICv4, fGicV4);
1362 LOG_CPU_FEATURE(FEAT_GICv4p1, fGicV4p1);
1363 LOG_CPU_FEATURE(FEAT_PMUv3, fPmuV3);
1364 LOG_CPU_FEATURE(FEAT_ETE, fEte);
1365 LOG_CPU_FEATURE(FEAT_ETEv1p1, fEteV1p1);
1366 LOG_CPU_FEATURE(FEAT_ETEv1p2, fEteV1p2);
1367 LOG_CPU_FEATURE(FEAT_SVE2, fSve2);
1368 LOG_CPU_FEATURE(FEAT_SVE_AES, fSveAes);
1369 LOG_CPU_FEATURE(FEAT_SVE_PMULL128, fSvePmull128);
1370 LOG_CPU_FEATURE(FEAT_SVE_BitPerm, fSveBitPerm);
1371 LOG_CPU_FEATURE(FEAT_SVE_SHA3, fSveSha3);
1372 LOG_CPU_FEATURE(FEAT_SVE_SM4, fSveSm4);
1373 LOG_CPU_FEATURE(FEAT_TME, fTme);
1374 LOG_CPU_FEATURE(FEAT_TRBE, fTrbe);
1375 LOG_CPU_FEATURE(FEAT_SME, fSme);
1376
1377 LOG_CPU_FEATURE(FEAT_AFP, fAfp);
1378 LOG_CPU_FEATURE(FEAT_HCX, fHcx);
1379 LOG_CPU_FEATURE(FEAT_LPA2, fLpa2);
1380 LOG_CPU_FEATURE(FEAT_LS64, fLs64);
1381 LOG_CPU_FEATURE(FEAT_LS64_V, fLs64V);
1382 LOG_CPU_FEATURE(FEAT_LS64_ACCDATA, fLs64Accdata);
1383 LOG_CPU_FEATURE(FEAT_MTE3, fMte3);
1384 LOG_CPU_FEATURE(FEAT_PAN3, fPan3);
1385 LOG_CPU_FEATURE(FEAT_PMUv3p7, fPmuV3p7);
1386 LOG_CPU_FEATURE(FEAT_RPRES, fRpres);
1387 LOG_CPU_FEATURE(FEAT_RME, fRme);
1388 LOG_CPU_FEATURE(FEAT_SME_FA64, fSmeFA64);
1389 LOG_CPU_FEATURE(FEAT_SME_F64F64, fSmeF64F64);
1390 LOG_CPU_FEATURE(FEAT_SME_I16I64, fSmeI16I64);
1391 LOG_CPU_FEATURE(FEAT_SPEv1p2, fSpeV1p2);
1392 LOG_CPU_FEATURE(FEAT_EBF16, fEbf16);
1393 LOG_CPU_FEATURE(FEAT_WFxT, fWfxt);
1394 LOG_CPU_FEATURE(FEAT_XS, fXs);
1395 LOG_CPU_FEATURE(FEAT_BRBE, fBrbe);
1396
1397 LOG_CPU_FEATURE(FEAT_CMOW, fCmow);
1398 LOG_CPU_FEATURE(FEAT_CONSTPACFIELD, fConstPacField);
1399 LOG_CPU_FEATURE(FEAT_Debugv8p8, fDebugV8p8);
1400 LOG_CPU_FEATURE(FEAT_HBC, fHbc);
1401 LOG_CPU_FEATURE(FEAT_HPMN0, fHpmn0);
1402 LOG_CPU_FEATURE(FEAT_NMI, fNmi);
1403 LOG_CPU_FEATURE(FEAT_GICv3_NMI, fGicV3Nmi);
1404 LOG_CPU_FEATURE(FEAT_MOPS, fMops);
1405 LOG_CPU_FEATURE(FEAT_PACQARMA3, fPacQarma3);
1406 LOG_CPU_FEATURE(FEAT_PMUv3_TH, fPmuV3Th);
1407 LOG_CPU_FEATURE(FEAT_PMUv3p8, fPmuV3p8);
1408 LOG_CPU_FEATURE(FEAT_PMUv3_EXT64, fPmuV3Ext64);
1409 LOG_CPU_FEATURE(FEAT_PMUv3_EXT32, fPmuV3Ext32);
1410 LOG_CPU_FEATURE(FEAT_PMUv3_EXT, fPmuV3Ext);
1411 LOG_CPU_FEATURE(FEAT_RNG_TRAP, fRngTrap);
1412 LOG_CPU_FEATURE(FEAT_SPEv1p3, fSpeV1p3);
1413 LOG_CPU_FEATURE(FEAT_TIDCP1, fTidcp1);
1414 LOG_CPU_FEATURE(FEAT_BRBEv1p1, fBrbeV1p1);
1415
1416 LOG_CPU_FEATURE(FEAT_ABLE, fAble);
1417 LOG_CPU_FEATURE(FEAT_ADERR, fAderr);
1418 LOG_CPU_FEATURE(FEAT_AIE, fAie);
1419 LOG_CPU_FEATURE(FEAT_ANERR, fAnerr);
1420 LOG_CPU_FEATURE(FEAT_BWE, fBwe);
1421 LOG_CPU_FEATURE(FEAT_CLRBHB, fClrBhb);
1422 LOG_CPU_FEATURE(FEAT_CHK, fChk);
1423 LOG_CPU_FEATURE(FEAT_CSSC, fCssc);
1424 LOG_CPU_FEATURE(FEAT_CSV2_3, fCsv2v3);
1425 LOG_CPU_FEATURE(FEAT_D128, fD128);
1426 LOG_CPU_FEATURE(FEAT_Debugv8p9, fDebugV8p9);
1427 LOG_CPU_FEATURE(FEAT_DoubleFault2, fDoubleFault2);
1428 LOG_CPU_FEATURE(FEAT_EBEP, fEbep);
1429 LOG_CPU_FEATURE(FEAT_ECBHB, fEcBhb);
1430 LOG_CPU_FEATURE(FEAT_EDHSR, fEdhsr);
1431 LOG_CPU_FEATURE(FEAT_ETEv1p3, fEteV1p3);
1432 LOG_CPU_FEATURE(FEAT_FGT2, fFgt2);
1433 LOG_CPU_FEATURE(FEAT_GCS, fGcs);
1434 LOG_CPU_FEATURE(FEAT_HAFT, fHaft);
1435 LOG_CPU_FEATURE(FEAT_ITE, fIte);
1436 LOG_CPU_FEATURE(FEAT_LRCPC3, fLrcpc3);
1437 LOG_CPU_FEATURE(FEAT_LSE128, fLse128);
1438 LOG_CPU_FEATURE(FEAT_LVA3, fLva3);
1439 LOG_CPU_FEATURE(FEAT_MEC, fMec);
1440 LOG_CPU_FEATURE(FEAT_MTE4, fMte4);
1441 LOG_CPU_FEATURE(FEAT_MTE_CANONICAL_TAGS, fMteCanonicalTags);
1442 LOG_CPU_FEATURE(FEAT_MTE_TAGGED_FAR, fMteTaggedFar);
1443 LOG_CPU_FEATURE(FEAT_MTE_STORE_ONLY, fMteStoreOnly);
1444 LOG_CPU_FEATURE(FEAT_MTE_NO_ADDRESS_TAGS, fMteNoAddressTags);
1445 LOG_CPU_FEATURE(FEAT_MTE_ASYM_FAULT, fMteAsymFault);
1446 LOG_CPU_FEATURE(FEAT_MTE_ASYNC, fMteAsync);
1447 LOG_CPU_FEATURE(FEAT_MTE_PERM_S1, fMtePermS1);
1448 LOG_CPU_FEATURE(FEAT_PCSRv8p9, fPcsrV8p9);
1449 LOG_CPU_FEATURE(FEAT_S1PIE, fS1Pie);
1450 LOG_CPU_FEATURE(FEAT_S2PIE, fS2Pie);
1451 LOG_CPU_FEATURE(FEAT_S1POE, fS1Poe);
1452 LOG_CPU_FEATURE(FEAT_S2POE, fS2Poe);
1453 LOG_CPU_FEATURE(FEAT_PFAR, fPfar);
1454 LOG_CPU_FEATURE(FEAT_PMUv3p9, fPmuV3p9);
1455 LOG_CPU_FEATURE(FEAT_PMUv3_EDGE, fPmuV3Edge);
1456 LOG_CPU_FEATURE(FEAT_PMUv3_ICNTR, fPmuV3Icntr);
1457 LOG_CPU_FEATURE(FEAT_PMUv3_SS, fPmuV3Ss);
1458 LOG_CPU_FEATURE(FEAT_PRFMSLC, fPrfmSlc);
1459 LOG_CPU_FEATURE(FEAT_RASv2, fRasV2);
1460 LOG_CPU_FEATURE(FEAT_RASSAv2, fRasSaV2);
1461 LOG_CPU_FEATURE(FEAT_RPRFM, fRprfm);
1462 LOG_CPU_FEATURE(FEAT_SCTLR2, fSctlr2);
1463 LOG_CPU_FEATURE(FEAT_SEBEP, fSebep);
1464 LOG_CPU_FEATURE(FEAT_SME_F16F16, fSmeF16F16);
1465 LOG_CPU_FEATURE(FEAT_SME2, fSme2);
1466 LOG_CPU_FEATURE(FEAT_SME2p1, fSme2p1);
1467 LOG_CPU_FEATURE(FEAT_SPECRES2, fSpecres2);
1468 LOG_CPU_FEATURE(FEAT_SPMU, fSpmu);
1469 LOG_CPU_FEATURE(FEAT_SPEv1p4, fSpeV1p4);
1470 LOG_CPU_FEATURE(FEAT_SPE_CRR, fSpeCrr);
1471 LOG_CPU_FEATURE(FEAT_SPE_FDS, fSpeFds);
1472 LOG_CPU_FEATURE(FEAT_SVE2p1, fSve2p1);
1473 LOG_CPU_FEATURE(FEAT_SVE_B16B16, fSveB16B16);
1474 LOG_CPU_FEATURE(FEAT_SYSINSTR128, fSysInstr128);
1475 LOG_CPU_FEATURE(FEAT_SYSREG128, fSysReg128);
1476 LOG_CPU_FEATURE(FEAT_TCR2, fTcr2);
1477 LOG_CPU_FEATURE(FEAT_THE, fThe);
1478 LOG_CPU_FEATURE(FEAT_TRBE_EXT, fTrbeExt);
1479 LOG_CPU_FEATURE(FEAT_TRBE_MPAM, fTrbeMpam);
1480#undef LOG_CPU_FEATURE
1481}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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