VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMAll/CPUMAllRegs-armv8.cpp@ 99748

Last change on this file since 99748 was 99576, checked in by vboxsync, 20 months ago

VMM: Preparations for getting interrupts injected into the guest. With ARMv8 there are two types of interrupts (normal interrupts and fast interrupts) which need to be mapped to forced action flags. Because the PIC and APIC flags are not needed those are mapped to IRQs and FIQs on ARM respectively, bugref:10389

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.0 KB
Line 
1/* $Id: CPUMAllRegs-armv8.cpp 99576 2023-05-03 10:24:27Z vboxsync $ */
2/** @file
3 * CPUM - CPU Monitor(/Manager) - Getters and Setters, ARMv8 variant.
4 */
5
6/*
7 * Copyright (C) 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#define LOG_GROUP LOG_GROUP_CPUM
33#include <VBox/vmm/cpum.h>
34#include <VBox/vmm/dbgf.h>
35#include <VBox/vmm/apic.h>
36#include <VBox/vmm/pgm.h>
37#include <VBox/vmm/mm.h>
38#include <VBox/vmm/em.h>
39#include <VBox/vmm/nem.h>
40#include <VBox/vmm/hm.h>
41#include "CPUMInternal-armv8.h"
42#include <VBox/vmm/vmcc.h>
43#include <VBox/err.h>
44#include <VBox/dis.h>
45#include <VBox/log.h>
46#include <VBox/vmm/hm.h>
47#include <VBox/vmm/tm.h>
48
49#include <iprt/armv8.h>
50#include <iprt/assert.h>
51#include <iprt/asm.h>
52#ifdef IN_RING3
53# include <iprt/thread.h>
54#endif
55
56
57/*********************************************************************************************************************************
58* Defined Constants And Macros *
59*********************************************************************************************************************************/
60/**
61 * Converts a CPUMCPU::Guest pointer into a VMCPU pointer.
62 *
63 * @returns Pointer to the Virtual CPU.
64 * @param a_pGuestCtx Pointer to the guest context.
65 */
66#define CPUM_GUEST_CTX_TO_VMCPU(a_pGuestCtx) RT_FROM_MEMBER(a_pGuestCtx, VMCPU, cpum.s.Guest)
67
68/** @def CPUM_INT_ASSERT_NOT_EXTRN
69 * Macro for asserting that @a a_fNotExtrn are present.
70 *
71 * @param a_pVCpu The cross context virtual CPU structure of the calling EMT.
72 * @param a_fNotExtrn Mask of CPUMCTX_EXTRN_XXX bits to check.
73 */
74#define CPUM_INT_ASSERT_NOT_EXTRN(a_pVCpu, a_fNotExtrn) \
75 AssertMsg(!((a_pVCpu)->cpum.s.Guest.fExtrn & (a_fNotExtrn)), \
76 ("%#RX64; a_fNotExtrn=%#RX64\n", (a_pVCpu)->cpum.s.Guest.fExtrn, (a_fNotExtrn)))
77
78
79/**
80 * Queries the pointer to the internal CPUMCTX structure.
81 *
82 * @returns The CPUMCTX pointer.
83 * @param pVCpu The cross context virtual CPU structure.
84 */
85VMMDECL(PCPUMCTX) CPUMQueryGuestCtxPtr(PVMCPU pVCpu)
86{
87 return &pVCpu->cpum.s.Guest;
88}
89
90
91VMMDECL(uint64_t) CPUMGetGuestFlatPC(PVMCPU pVCpu)
92{
93 CPUM_INT_ASSERT_NOT_EXTRN(pVCpu, CPUMCTX_EXTRN_PC);
94 return pVCpu->cpum.s.Guest.Pc.u64;
95}
96
97
98VMMDECL(uint64_t) CPUMGetGuestFlatSP(PVMCPU pVCpu)
99{
100 CPUM_INT_ASSERT_NOT_EXTRN(pVCpu, CPUMCTX_EXTRN_SP);
101 AssertReleaseFailed(); /** @todo Exception level. */
102 return pVCpu->cpum.s.Guest.aSpReg[0].u64;
103}
104
105
106/**
107 * Returns whether IRQs are currently masked.
108 *
109 * @returns true if IRQs are masked as indicated by the PState value.
110 * @param pVCpu The cross context virtual CPU structure.
111 */
112VMMDECL(bool) CPUMGetGuestIrqMasked(PVMCPUCC pVCpu)
113{
114 CPUM_INT_ASSERT_NOT_EXTRN(pVCpu, CPUMCTX_EXTRN_PSTATE);
115 return RT_BOOL(pVCpu->cpum.s.Guest.fPState & ARMV8_SPSR_EL2_AARCH64_I);
116}
117
118
119/**
120 * Returns whether FIQs are currently masked.
121 *
122 * @returns true if FIQs are masked as indicated by the PState value.
123 * @param pVCpu The cross context virtual CPU structure.
124 */
125VMMDECL(bool) CPUMGetGuestFiqMasked(PVMCPUCC pVCpu)
126{
127 CPUM_INT_ASSERT_NOT_EXTRN(pVCpu, CPUMCTX_EXTRN_PSTATE);
128 return RT_BOOL(pVCpu->cpum.s.Guest.fPState & ARMV8_SPSR_EL2_AARCH64_F);
129}
130
131
132/**
133 * Gets the host CPU vendor.
134 *
135 * @returns CPU vendor.
136 * @param pVM The cross context VM structure.
137 */
138VMMDECL(CPUMCPUVENDOR) CPUMGetHostCpuVendor(PVM pVM)
139{
140 RT_NOREF(pVM);
141 //AssertReleaseFailed();
142 return CPUMCPUVENDOR_UNKNOWN;
143}
144
145
146/**
147 * Gets the host CPU microarchitecture.
148 *
149 * @returns CPU microarchitecture.
150 * @param pVM The cross context VM structure.
151 */
152VMMDECL(CPUMMICROARCH) CPUMGetHostMicroarch(PCVM pVM)
153{
154 RT_NOREF(pVM);
155 AssertReleaseFailed();
156 return kCpumMicroarch_Unknown;
157}
158
159
160/**
161 * Gets the guest CPU vendor.
162 *
163 * @returns CPU vendor.
164 * @param pVM The cross context VM structure.
165 */
166VMMDECL(CPUMCPUVENDOR) CPUMGetGuestCpuVendor(PVM pVM)
167{
168 RT_NOREF(pVM);
169 //AssertReleaseFailed();
170 return CPUMCPUVENDOR_UNKNOWN;
171}
172
173
174/**
175 * Gets the guest CPU microarchitecture.
176 *
177 * @returns CPU microarchitecture.
178 * @param pVM The cross context VM structure.
179 */
180VMMDECL(CPUMMICROARCH) CPUMGetGuestMicroarch(PCVM pVM)
181{
182 RT_NOREF(pVM);
183 AssertReleaseFailed();
184 return kCpumMicroarch_Unknown;
185}
186
187
188/**
189 * Gets the maximum number of physical and linear address bits supported by the
190 * guest.
191 *
192 * @param pVM The cross context VM structure.
193 * @param pcPhysAddrWidth Where to store the physical address width.
194 * @param pcLinearAddrWidth Where to store the linear address width.
195 */
196VMMDECL(void) CPUMGetGuestAddrWidths(PCVM pVM, uint8_t *pcPhysAddrWidth, uint8_t *pcLinearAddrWidth)
197{
198 AssertPtr(pVM);
199 AssertReturnVoid(pcPhysAddrWidth);
200 AssertReturnVoid(pcLinearAddrWidth);
201 AssertReleaseFailed();
202}
203
204
205/**
206 * Tests if the guest has the paging enabled (PG).
207 *
208 * @returns true if in real mode, otherwise false.
209 * @param pVCpu The cross context virtual CPU structure.
210 */
211VMMDECL(bool) CPUMIsGuestPagingEnabled(PCVMCPU pVCpu)
212{
213 RT_NOREF(pVCpu);
214 AssertReleaseFailed();
215 return false;
216}
217
218
219/**
220 * Tests if the guest is running in 64 bits mode or not.
221 *
222 * @returns true if in 64 bits protected mode, otherwise false.
223 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
224 */
225VMMDECL(bool) CPUMIsGuestIn64BitCode(PVMCPU pVCpu)
226{
227 RT_NOREF(pVCpu);
228 AssertReleaseFailed();
229 return false;
230}
231
232
233/**
234 * Helper for CPUMIsGuestIn64BitCodeEx that handles lazy resolving of hidden CS
235 * registers.
236 *
237 * @returns true if in 64 bits protected mode, otherwise false.
238 * @param pCtx Pointer to the current guest CPU context.
239 */
240VMM_INT_DECL(bool) CPUMIsGuestIn64BitCodeSlow(PCPUMCTX pCtx)
241{
242 return CPUMIsGuestIn64BitCode(CPUM_GUEST_CTX_TO_VMCPU(pCtx));
243}
244
245
246/**
247 * Sets the specified changed flags (CPUM_CHANGED_*).
248 *
249 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
250 * @param fChangedAdd The changed flags to add.
251 */
252VMMDECL(void) CPUMSetChangedFlags(PVMCPU pVCpu, uint32_t fChangedAdd)
253{
254 pVCpu->cpum.s.fChanged |= fChangedAdd;
255}
256
257
258/**
259 * Checks if the guest debug state is active.
260 *
261 * @returns boolean
262 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
263 */
264VMMDECL(bool) CPUMIsGuestDebugStateActive(PVMCPU pVCpu)
265{
266 return RT_BOOL(pVCpu->cpum.s.fUseFlags & CPUM_USED_DEBUG_REGS_GUEST);
267}
268
269
270/**
271 * Checks if the hyper debug state is active.
272 *
273 * @returns boolean
274 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
275 */
276VMMDECL(bool) CPUMIsHyperDebugStateActive(PVMCPU pVCpu)
277{
278 return RT_BOOL(pVCpu->cpum.s.fUseFlags & CPUM_USED_DEBUG_REGS_HYPER);
279}
280
281
282/**
283 * Mark the guest's debug state as inactive.
284 *
285 * @returns boolean
286 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
287 * @todo This API doesn't make sense any more.
288 */
289VMMDECL(void) CPUMDeactivateGuestDebugState(PVMCPU pVCpu)
290{
291 Assert(!(pVCpu->cpum.s.fUseFlags & (CPUM_USED_DEBUG_REGS_GUEST | CPUM_USED_DEBUG_REGS_HYPER)));
292 NOREF(pVCpu);
293}
294
295
296/**
297 * Get the current exception level of the guest.
298 *
299 * @returns EL
300 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
301 */
302VMMDECL(uint32_t) CPUMGetGuestEL(PVMCPU pVCpu)
303{
304 RT_NOREF(pVCpu);
305 AssertReleaseFailed();
306 return 0;
307}
308
309
310/**
311 * Gets the current guest CPU mode.
312 *
313 * If paging mode is what you need, check out PGMGetGuestMode().
314 *
315 * @returns The CPU mode.
316 * @param pVCpu The cross context virtual CPU structure.
317 */
318VMMDECL(CPUMMODE) CPUMGetGuestMode(PVMCPU pVCpu)
319{
320 CPUM_INT_ASSERT_NOT_EXTRN(pVCpu, CPUMCTX_EXTRN_PC | CPUMCTX_EXTRN_PSTATE);
321 AssertReleaseFailed();
322 return CPUMMODE_REAL;
323}
324
325
326/**
327 * Figure whether the CPU is currently executing 16, 32 or 64 bit code.
328 *
329 * @returns 16, 32 or 64.
330 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
331 */
332VMMDECL(uint32_t) CPUMGetGuestCodeBits(PVMCPU pVCpu)
333{
334 CPUM_INT_ASSERT_NOT_EXTRN(pVCpu, CPUMCTX_EXTRN_PC | CPUMCTX_EXTRN_PSTATE);
335 AssertReleaseFailed();
336 return 16;
337}
338
339
340VMMDECL(DISCPUMODE) CPUMGetGuestDisMode(PVMCPU pVCpu)
341{
342 CPUM_INT_ASSERT_NOT_EXTRN(pVCpu, CPUMCTX_EXTRN_PC | CPUMCTX_EXTRN_PSTATE);
343 AssertReleaseFailed();
344 return DISCPUMODE_16BIT;
345}
346
347
348/**
349 * Used to dynamically imports state residing in NEM or HM.
350 *
351 * This is a worker for the CPUM_IMPORT_EXTRN_RET() macro and various IEM ones.
352 *
353 * @returns VBox status code.
354 * @param pVCpu The cross context virtual CPU structure of the calling thread.
355 * @param fExtrnImport The fields to import.
356 * @thread EMT(pVCpu)
357 */
358VMM_INT_DECL(int) CPUMImportGuestStateOnDemand(PVMCPUCC pVCpu, uint64_t fExtrnImport)
359{
360 VMCPU_ASSERT_EMT(pVCpu);
361 if (pVCpu->cpum.s.Guest.fExtrn & fExtrnImport)
362 {
363 switch (pVCpu->cpum.s.Guest.fExtrn & CPUMCTX_EXTRN_KEEPER_MASK)
364 {
365 case CPUMCTX_EXTRN_KEEPER_NEM:
366 {
367 int rc = NEMImportStateOnDemand(pVCpu, fExtrnImport);
368 Assert(rc == VINF_SUCCESS || RT_FAILURE_NP(rc));
369 return rc;
370 }
371
372 default:
373 AssertLogRelMsgFailedReturn(("%#RX64 vs %#RX64\n", pVCpu->cpum.s.Guest.fExtrn, fExtrnImport), VERR_CPUM_IPE_2);
374 }
375 }
376 return VINF_SUCCESS;
377}
378
379
380/**
381 * Translates a microarchitecture enum value to the corresponding string
382 * constant.
383 *
384 * @returns Read-only string constant (omits "kCpumMicroarch_" prefix). Returns
385 * NULL if the value is invalid.
386 *
387 * @param enmMicroarch The enum value to convert.
388 *
389 * @todo Doesn't really belong here but for now there is no other Armv8 CPUM source file.
390 */
391VMMDECL(const char *) CPUMMicroarchName(CPUMMICROARCH enmMicroarch)
392{
393 switch (enmMicroarch)
394 {
395#define CASE_RET_STR(enmValue) case enmValue: return #enmValue + (sizeof("kCpumMicroarch_") - 1)
396 CASE_RET_STR(kCpumMicroarch_Apple_M1);
397#undef CASE_RET_STR
398 }
399
400 return NULL;
401}
Note: See TracBrowser for help on using the repository browser.

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