VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR3/DBGFCpu.cpp@ 107227

Last change on this file since 107227 was 107227, checked in by vboxsync, 8 weeks ago

VMM: Cleaning up ARMv8 / x86 split. jiraref:VBP-1470

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.2 KB
Line 
1/* $Id: DBGFCpu.cpp 107227 2024-12-04 15:20:14Z vboxsync $ */
2/** @file
3 * DBGF - Debugger Facility, CPU State Accessors.
4 */
5
6/*
7 * Copyright (C) 2009-2024 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_DBGF
33#define VMCPU_INCL_CPUM_GST_CTX /* For CPUM_IMPORT_EXTRN_RET(). */
34#include <VBox/vmm/dbgf.h>
35#include <VBox/vmm/cpum.h>
36#include "DBGFInternal.h"
37#include <VBox/vmm/vm.h>
38#include <VBox/vmm/uvm.h>
39#include <iprt/errcore.h>
40#include <VBox/log.h>
41#include <VBox/param.h>
42#include <iprt/assert.h>
43
44
45/**
46 * Wrapper around CPUMGetGuestMode.
47 *
48 * @returns VINF_SUCCESS.
49 * @param pVM The cross context VM structure.
50 * @param idCpu The current CPU ID.
51 * @param penmMode Where to return the mode.
52 */
53static DECLCALLBACK(int) dbgfR3CpuGetMode(PVM pVM, VMCPUID idCpu, CPUMMODE *penmMode)
54{
55 Assert(idCpu == VMMGetCpuId(pVM));
56 PVMCPU pVCpu = VMMGetCpuById(pVM, idCpu);
57#ifdef VBOX_VMM_TARGET_ARMV8
58 CPUM_IMPORT_EXTRN_RET(pVCpu, CPUMCTX_EXTRN_PSTATE);
59#elif defined(VBOX_VMM_TARGET_X86)
60 CPUM_IMPORT_EXTRN_RET(pVCpu, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_EFER);
61#else
62# error "port me"
63#endif
64 *penmMode = CPUMGetGuestMode(pVCpu);
65 return VINF_SUCCESS;
66}
67
68
69/**
70 * Get the current CPU mode.
71 *
72 * @returns The CPU mode on success, CPUMMODE_INVALID on failure.
73 * @param pUVM The user mode VM handle.
74 * @param idCpu The target CPU ID.
75 */
76VMMR3DECL(CPUMMODE) DBGFR3CpuGetMode(PUVM pUVM, VMCPUID idCpu)
77{
78 UVM_ASSERT_VALID_EXT_RETURN(pUVM, CPUMMODE_INVALID);
79 VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, CPUMMODE_INVALID);
80 AssertReturn(idCpu < pUVM->pVM->cCpus, CPUMMODE_INVALID);
81
82 CPUMMODE enmMode;
83 int rc = VMR3ReqPriorityCallWaitU(pUVM, idCpu, (PFNRT)dbgfR3CpuGetMode, 3, pUVM->pVM, idCpu, &enmMode);
84 if (RT_FAILURE(rc))
85 return CPUMMODE_INVALID;
86 return enmMode;
87}
88
89
90/**
91 * Wrapper around CPUMIsGuestIn64BitCode.
92 *
93 * @returns VINF_SUCCESS.
94 * @param pVM The cross context VM structure.
95 * @param idCpu The current CPU ID.
96 * @param pfIn64BitCode Where to return the result.
97 */
98static DECLCALLBACK(int) dbgfR3CpuIn64BitCode(PVM pVM, VMCPUID idCpu, bool *pfIn64BitCode)
99{
100 Assert(idCpu == VMMGetCpuId(pVM));
101 PVMCPU pVCpu = VMMGetCpuById(pVM, idCpu);
102#ifdef VBOX_VMM_TARGET_ARMV8
103 CPUM_IMPORT_EXTRN_RET(pVCpu, CPUMCTX_EXTRN_PSTATE);
104#elif defined(VBOX_VMM_TARGET_X86)
105 CPUM_IMPORT_EXTRN_RET(pVCpu, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_EFER);
106#else
107# error "port me"
108#endif
109 *pfIn64BitCode = CPUMIsGuestIn64BitCode(pVCpu);
110 return VINF_SUCCESS;
111}
112
113
114/**
115 * Checks if the given CPU is executing 64-bit code or not.
116 *
117 * @returns true / false accordingly.
118 * @param pUVM The user mode VM handle.
119 * @param idCpu The target CPU ID.
120 */
121VMMR3DECL(bool) DBGFR3CpuIsIn64BitCode(PUVM pUVM, VMCPUID idCpu)
122{
123 UVM_ASSERT_VALID_EXT_RETURN(pUVM, false);
124 VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, false);
125 AssertReturn(idCpu < pUVM->pVM->cCpus, false);
126
127 bool fIn64BitCode;
128 int rc = VMR3ReqPriorityCallWaitU(pUVM, idCpu, (PFNRT)dbgfR3CpuIn64BitCode, 3, pUVM->pVM, idCpu, &fIn64BitCode);
129 if (RT_FAILURE(rc))
130 return false;
131 return fIn64BitCode;
132}
133
134
135#ifdef VBOX_VMM_TARGET_X86
136/**
137 * Wrapper around CPUMIsGuestInV86Code.
138 *
139 * @returns VINF_SUCCESS.
140 * @param pVM The cross context VM structure.
141 * @param idCpu The current CPU ID.
142 * @param pfInV86Code Where to return the result.
143 */
144static DECLCALLBACK(int) dbgfR3CpuInV86Code(PVM pVM, VMCPUID idCpu, bool *pfInV86Code)
145{
146 Assert(idCpu == VMMGetCpuId(pVM));
147 PVMCPU pVCpu = VMMGetCpuById(pVM, idCpu);
148 CPUM_IMPORT_EXTRN_RET(pVCpu, CPUMCTX_EXTRN_RFLAGS);
149 *pfInV86Code = CPUMIsGuestInV86ModeEx(CPUMQueryGuestCtxPtr(pVCpu));
150 return VINF_SUCCESS;
151}
152#endif
153
154
155/**
156 * Checks if the given CPU is executing V8086 code or not.
157 *
158 * @returns true / false accordingly.
159 * @param pUVM The user mode VM handle.
160 * @param idCpu The target CPU ID.
161 */
162VMMR3DECL(bool) DBGFR3CpuIsInV86Code(PUVM pUVM, VMCPUID idCpu)
163{
164 UVM_ASSERT_VALID_EXT_RETURN(pUVM, false);
165 VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, false);
166 AssertReturn(idCpu < pUVM->pVM->cCpus, false);
167
168#ifdef VBOX_VMM_TARGET_X86
169 bool fInV86Code;
170 int rc = VMR3ReqPriorityCallWaitU(pUVM, idCpu, (PFNRT)dbgfR3CpuInV86Code, 3, pUVM->pVM, idCpu, &fInV86Code);
171 if (RT_FAILURE(rc))
172 return false;
173 return fInV86Code;
174#else
175 return false;
176#endif
177}
178
179
180/**
181 * Get the number of CPUs (or threads if you insist).
182 *
183 * @returns The number of CPUs
184 * @param pUVM The user mode VM handle.
185 */
186VMMR3DECL(VMCPUID) DBGFR3CpuGetCount(PUVM pUVM)
187{
188 UVM_ASSERT_VALID_EXT_RETURN(pUVM, 1);
189 return pUVM->cCpus;
190}
191
192
193/**
194 * Returns the state of the given CPU as a human readable string.
195 *
196 * @returns Pointer to the human readable CPU state string.
197 * @param pUVM The user mode VM handle.
198 * @param idCpu The target CPU ID.
199 */
200VMMR3DECL(const char *) DBGFR3CpuGetState(PUVM pUVM, VMCPUID idCpu)
201{
202 UVM_ASSERT_VALID_EXT_RETURN(pUVM, NULL);
203 VM_ASSERT_VALID_EXT_RETURN(pUVM->pVM, NULL);
204 AssertReturn(idCpu < pUVM->pVM->cCpus, NULL);
205
206 PVMCPU pVCpu = VMMGetCpuById(pUVM->pVM, idCpu);
207 VMCPUSTATE enmCpuState = (VMCPUSTATE)ASMAtomicReadU32((volatile uint32_t *)&pVCpu->enmState);
208
209 switch (enmCpuState)
210 {
211 case VMCPUSTATE_INVALID: return "<INVALID>";
212 case VMCPUSTATE_STOPPED: return "Stopped";
213 case VMCPUSTATE_STARTED: return "Started";
214 case VMCPUSTATE_STARTED_HM: return "Started (HM)";
215 case VMCPUSTATE_STARTED_EXEC: return "Started (Exec)";
216 case VMCPUSTATE_STARTED_EXEC_NEM: return "Started (Exec NEM)";
217 case VMCPUSTATE_STARTED_EXEC_NEM_WAIT: return "Started (Exec NEM Wait)";
218 case VMCPUSTATE_STARTED_EXEC_NEM_CANCELED: return "Started (Exec NEM Canceled)";
219 case VMCPUSTATE_STARTED_HALTED: return "Started (Halted)";
220 case VMCPUSTATE_END: return "END";
221 default: break;
222 }
223
224 AssertMsgFailedReturn(("Unknown CPU state %u\n", enmCpuState), "<UNKNOWN>");
225}
226
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