2 * QEMU Hypervisor.framework support for Apple Silicon
4 * Copyright 2020 Alexander Graf <agraf@csgraf.de>
5 * Copyright 2020 Google LLC
7 * This work is licensed under the terms of the GNU GPL, version 2 or later.
8 * See the COPYING file in the top-level directory.
12 #include "qemu/osdep.h"
13 #include "qemu/error-report.h"
15 #include "sysemu/runstate.h"
16 #include "sysemu/hvf.h"
17 #include "sysemu/hvf_int.h"
18 #include "sysemu/hw_accel.h"
22 #include <mach/mach_time.h>
24 #include "exec/address-spaces.h"
26 #include "qemu/main-loop.h"
27 #include "sysemu/cpus.h"
28 #include "arm-powerctl.h"
29 #include "target/arm/cpu.h"
30 #include "target/arm/internals.h"
31 #include "trace/trace-target_arm_hvf.h"
32 #include "migration/vmstate.h"
34 #include "exec/gdbstub.h"
36 #define MDSCR_EL1_SS_SHIFT 0
37 #define MDSCR_EL1_MDE_SHIFT 15
39 static uint16_t dbgbcr_regs
[] = {
40 HV_SYS_REG_DBGBCR0_EL1
,
41 HV_SYS_REG_DBGBCR1_EL1
,
42 HV_SYS_REG_DBGBCR2_EL1
,
43 HV_SYS_REG_DBGBCR3_EL1
,
44 HV_SYS_REG_DBGBCR4_EL1
,
45 HV_SYS_REG_DBGBCR5_EL1
,
46 HV_SYS_REG_DBGBCR6_EL1
,
47 HV_SYS_REG_DBGBCR7_EL1
,
48 HV_SYS_REG_DBGBCR8_EL1
,
49 HV_SYS_REG_DBGBCR9_EL1
,
50 HV_SYS_REG_DBGBCR10_EL1
,
51 HV_SYS_REG_DBGBCR11_EL1
,
52 HV_SYS_REG_DBGBCR12_EL1
,
53 HV_SYS_REG_DBGBCR13_EL1
,
54 HV_SYS_REG_DBGBCR14_EL1
,
55 HV_SYS_REG_DBGBCR15_EL1
,
57 static uint16_t dbgbvr_regs
[] = {
58 HV_SYS_REG_DBGBVR0_EL1
,
59 HV_SYS_REG_DBGBVR1_EL1
,
60 HV_SYS_REG_DBGBVR2_EL1
,
61 HV_SYS_REG_DBGBVR3_EL1
,
62 HV_SYS_REG_DBGBVR4_EL1
,
63 HV_SYS_REG_DBGBVR5_EL1
,
64 HV_SYS_REG_DBGBVR6_EL1
,
65 HV_SYS_REG_DBGBVR7_EL1
,
66 HV_SYS_REG_DBGBVR8_EL1
,
67 HV_SYS_REG_DBGBVR9_EL1
,
68 HV_SYS_REG_DBGBVR10_EL1
,
69 HV_SYS_REG_DBGBVR11_EL1
,
70 HV_SYS_REG_DBGBVR12_EL1
,
71 HV_SYS_REG_DBGBVR13_EL1
,
72 HV_SYS_REG_DBGBVR14_EL1
,
73 HV_SYS_REG_DBGBVR15_EL1
,
75 static uint16_t dbgwcr_regs
[] = {
76 HV_SYS_REG_DBGWCR0_EL1
,
77 HV_SYS_REG_DBGWCR1_EL1
,
78 HV_SYS_REG_DBGWCR2_EL1
,
79 HV_SYS_REG_DBGWCR3_EL1
,
80 HV_SYS_REG_DBGWCR4_EL1
,
81 HV_SYS_REG_DBGWCR5_EL1
,
82 HV_SYS_REG_DBGWCR6_EL1
,
83 HV_SYS_REG_DBGWCR7_EL1
,
84 HV_SYS_REG_DBGWCR8_EL1
,
85 HV_SYS_REG_DBGWCR9_EL1
,
86 HV_SYS_REG_DBGWCR10_EL1
,
87 HV_SYS_REG_DBGWCR11_EL1
,
88 HV_SYS_REG_DBGWCR12_EL1
,
89 HV_SYS_REG_DBGWCR13_EL1
,
90 HV_SYS_REG_DBGWCR14_EL1
,
91 HV_SYS_REG_DBGWCR15_EL1
,
93 static uint16_t dbgwvr_regs
[] = {
94 HV_SYS_REG_DBGWVR0_EL1
,
95 HV_SYS_REG_DBGWVR1_EL1
,
96 HV_SYS_REG_DBGWVR2_EL1
,
97 HV_SYS_REG_DBGWVR3_EL1
,
98 HV_SYS_REG_DBGWVR4_EL1
,
99 HV_SYS_REG_DBGWVR5_EL1
,
100 HV_SYS_REG_DBGWVR6_EL1
,
101 HV_SYS_REG_DBGWVR7_EL1
,
102 HV_SYS_REG_DBGWVR8_EL1
,
103 HV_SYS_REG_DBGWVR9_EL1
,
104 HV_SYS_REG_DBGWVR10_EL1
,
105 HV_SYS_REG_DBGWVR11_EL1
,
106 HV_SYS_REG_DBGWVR12_EL1
,
107 HV_SYS_REG_DBGWVR13_EL1
,
108 HV_SYS_REG_DBGWVR14_EL1
,
109 HV_SYS_REG_DBGWVR15_EL1
,
112 static inline int hvf_arm_num_brps(hv_vcpu_config_t config
)
116 ret
= hv_vcpu_config_get_feature_reg(config
, HV_FEATURE_REG_ID_AA64DFR0_EL1
,
119 return FIELD_EX64(val
, ID_AA64DFR0
, BRPS
) + 1;
122 static inline int hvf_arm_num_wrps(hv_vcpu_config_t config
)
126 ret
= hv_vcpu_config_get_feature_reg(config
, HV_FEATURE_REG_ID_AA64DFR0_EL1
,
129 return FIELD_EX64(val
, ID_AA64DFR0
, WRPS
) + 1;
132 void hvf_arm_init_debug(void)
134 hv_vcpu_config_t config
;
135 config
= hv_vcpu_config_create();
137 max_hw_bps
= hvf_arm_num_brps(config
);
139 g_array_sized_new(true, true, sizeof(HWBreakpoint
), max_hw_bps
);
141 max_hw_wps
= hvf_arm_num_wrps(config
);
143 g_array_sized_new(true, true, sizeof(HWWatchpoint
), max_hw_wps
);
146 #define HVF_SYSREG(crn, crm, op0, op1, op2) \
147 ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP, crn, crm, op0, op1, op2)
148 #define PL1_WRITE_MASK 0x4
150 #define SYSREG_OP0_SHIFT 20
151 #define SYSREG_OP0_MASK 0x3
152 #define SYSREG_OP0(sysreg) ((sysreg >> SYSREG_OP0_SHIFT) & SYSREG_OP0_MASK)
153 #define SYSREG_OP1_SHIFT 14
154 #define SYSREG_OP1_MASK 0x7
155 #define SYSREG_OP1(sysreg) ((sysreg >> SYSREG_OP1_SHIFT) & SYSREG_OP1_MASK)
156 #define SYSREG_CRN_SHIFT 10
157 #define SYSREG_CRN_MASK 0xf
158 #define SYSREG_CRN(sysreg) ((sysreg >> SYSREG_CRN_SHIFT) & SYSREG_CRN_MASK)
159 #define SYSREG_CRM_SHIFT 1
160 #define SYSREG_CRM_MASK 0xf
161 #define SYSREG_CRM(sysreg) ((sysreg >> SYSREG_CRM_SHIFT) & SYSREG_CRM_MASK)
162 #define SYSREG_OP2_SHIFT 17
163 #define SYSREG_OP2_MASK 0x7
164 #define SYSREG_OP2(sysreg) ((sysreg >> SYSREG_OP2_SHIFT) & SYSREG_OP2_MASK)
166 #define SYSREG(op0, op1, crn, crm, op2) \
167 ((op0 << SYSREG_OP0_SHIFT) | \
168 (op1 << SYSREG_OP1_SHIFT) | \
169 (crn << SYSREG_CRN_SHIFT) | \
170 (crm << SYSREG_CRM_SHIFT) | \
171 (op2 << SYSREG_OP2_SHIFT))
172 #define SYSREG_MASK \
173 SYSREG(SYSREG_OP0_MASK, \
178 #define SYSREG_OSLAR_EL1 SYSREG(2, 0, 1, 0, 4)
179 #define SYSREG_OSLSR_EL1 SYSREG(2, 0, 1, 1, 4)
180 #define SYSREG_OSDLR_EL1 SYSREG(2, 0, 1, 3, 4)
181 #define SYSREG_CNTPCT_EL0 SYSREG(3, 3, 14, 0, 1)
182 #define SYSREG_PMCR_EL0 SYSREG(3, 3, 9, 12, 0)
183 #define SYSREG_PMUSERENR_EL0 SYSREG(3, 3, 9, 14, 0)
184 #define SYSREG_PMCNTENSET_EL0 SYSREG(3, 3, 9, 12, 1)
185 #define SYSREG_PMCNTENCLR_EL0 SYSREG(3, 3, 9, 12, 2)
186 #define SYSREG_PMINTENCLR_EL1 SYSREG(3, 0, 9, 14, 2)
187 #define SYSREG_PMOVSCLR_EL0 SYSREG(3, 3, 9, 12, 3)
188 #define SYSREG_PMSWINC_EL0 SYSREG(3, 3, 9, 12, 4)
189 #define SYSREG_PMSELR_EL0 SYSREG(3, 3, 9, 12, 5)
190 #define SYSREG_PMCEID0_EL0 SYSREG(3, 3, 9, 12, 6)
191 #define SYSREG_PMCEID1_EL0 SYSREG(3, 3, 9, 12, 7)
192 #define SYSREG_PMCCNTR_EL0 SYSREG(3, 3, 9, 13, 0)
193 #define SYSREG_PMCCFILTR_EL0 SYSREG(3, 3, 14, 15, 7)
195 #define SYSREG_ICC_AP0R0_EL1 SYSREG(3, 0, 12, 8, 4)
196 #define SYSREG_ICC_AP0R1_EL1 SYSREG(3, 0, 12, 8, 5)
197 #define SYSREG_ICC_AP0R2_EL1 SYSREG(3, 0, 12, 8, 6)
198 #define SYSREG_ICC_AP0R3_EL1 SYSREG(3, 0, 12, 8, 7)
199 #define SYSREG_ICC_AP1R0_EL1 SYSREG(3, 0, 12, 9, 0)
200 #define SYSREG_ICC_AP1R1_EL1 SYSREG(3, 0, 12, 9, 1)
201 #define SYSREG_ICC_AP1R2_EL1 SYSREG(3, 0, 12, 9, 2)
202 #define SYSREG_ICC_AP1R3_EL1 SYSREG(3, 0, 12, 9, 3)
203 #define SYSREG_ICC_ASGI1R_EL1 SYSREG(3, 0, 12, 11, 6)
204 #define SYSREG_ICC_BPR0_EL1 SYSREG(3, 0, 12, 8, 3)
205 #define SYSREG_ICC_BPR1_EL1 SYSREG(3, 0, 12, 12, 3)
206 #define SYSREG_ICC_CTLR_EL1 SYSREG(3, 0, 12, 12, 4)
207 #define SYSREG_ICC_DIR_EL1 SYSREG(3, 0, 12, 11, 1)
208 #define SYSREG_ICC_EOIR0_EL1 SYSREG(3, 0, 12, 8, 1)
209 #define SYSREG_ICC_EOIR1_EL1 SYSREG(3, 0, 12, 12, 1)
210 #define SYSREG_ICC_HPPIR0_EL1 SYSREG(3, 0, 12, 8, 2)
211 #define SYSREG_ICC_HPPIR1_EL1 SYSREG(3, 0, 12, 12, 2)
212 #define SYSREG_ICC_IAR0_EL1 SYSREG(3, 0, 12, 8, 0)
213 #define SYSREG_ICC_IAR1_EL1 SYSREG(3, 0, 12, 12, 0)
214 #define SYSREG_ICC_IGRPEN0_EL1 SYSREG(3, 0, 12, 12, 6)
215 #define SYSREG_ICC_IGRPEN1_EL1 SYSREG(3, 0, 12, 12, 7)
216 #define SYSREG_ICC_PMR_EL1 SYSREG(3, 0, 4, 6, 0)
217 #define SYSREG_ICC_RPR_EL1 SYSREG(3, 0, 12, 11, 3)
218 #define SYSREG_ICC_SGI0R_EL1 SYSREG(3, 0, 12, 11, 7)
219 #define SYSREG_ICC_SGI1R_EL1 SYSREG(3, 0, 12, 11, 5)
220 #define SYSREG_ICC_SRE_EL1 SYSREG(3, 0, 12, 12, 5)
222 #define SYSREG_MDSCR_EL1 SYSREG(2, 0, 0, 2, 2)
223 #define SYSREG_DBGBVR0_EL1 SYSREG(2, 0, 0, 0, 4)
224 #define SYSREG_DBGBCR0_EL1 SYSREG(2, 0, 0, 0, 5)
225 #define SYSREG_DBGWVR0_EL1 SYSREG(2, 0, 0, 0, 6)
226 #define SYSREG_DBGWCR0_EL1 SYSREG(2, 0, 0, 0, 7)
227 #define SYSREG_DBGBVR1_EL1 SYSREG(2, 0, 0, 1, 4)
228 #define SYSREG_DBGBCR1_EL1 SYSREG(2, 0, 0, 1, 5)
229 #define SYSREG_DBGWVR1_EL1 SYSREG(2, 0, 0, 1, 6)
230 #define SYSREG_DBGWCR1_EL1 SYSREG(2, 0, 0, 1, 7)
231 #define SYSREG_DBGBVR2_EL1 SYSREG(2, 0, 0, 2, 4)
232 #define SYSREG_DBGBCR2_EL1 SYSREG(2, 0, 0, 2, 5)
233 #define SYSREG_DBGWVR2_EL1 SYSREG(2, 0, 0, 2, 6)
234 #define SYSREG_DBGWCR2_EL1 SYSREG(2, 0, 0, 2, 7)
235 #define SYSREG_DBGBVR3_EL1 SYSREG(2, 0, 0, 3, 4)
236 #define SYSREG_DBGBCR3_EL1 SYSREG(2, 0, 0, 3, 5)
237 #define SYSREG_DBGWVR3_EL1 SYSREG(2, 0, 0, 3, 6)
238 #define SYSREG_DBGWCR3_EL1 SYSREG(2, 0, 0, 3, 7)
239 #define SYSREG_DBGBVR4_EL1 SYSREG(2, 0, 0, 4, 4)
240 #define SYSREG_DBGBCR4_EL1 SYSREG(2, 0, 0, 4, 5)
241 #define SYSREG_DBGWVR4_EL1 SYSREG(2, 0, 0, 4, 6)
242 #define SYSREG_DBGWCR4_EL1 SYSREG(2, 0, 0, 4, 7)
243 #define SYSREG_DBGBVR5_EL1 SYSREG(2, 0, 0, 5, 4)
244 #define SYSREG_DBGBCR5_EL1 SYSREG(2, 0, 0, 5, 5)
245 #define SYSREG_DBGWVR5_EL1 SYSREG(2, 0, 0, 5, 6)
246 #define SYSREG_DBGWCR5_EL1 SYSREG(2, 0, 0, 5, 7)
247 #define SYSREG_DBGBVR6_EL1 SYSREG(2, 0, 0, 6, 4)
248 #define SYSREG_DBGBCR6_EL1 SYSREG(2, 0, 0, 6, 5)
249 #define SYSREG_DBGWVR6_EL1 SYSREG(2, 0, 0, 6, 6)
250 #define SYSREG_DBGWCR6_EL1 SYSREG(2, 0, 0, 6, 7)
251 #define SYSREG_DBGBVR7_EL1 SYSREG(2, 0, 0, 7, 4)
252 #define SYSREG_DBGBCR7_EL1 SYSREG(2, 0, 0, 7, 5)
253 #define SYSREG_DBGWVR7_EL1 SYSREG(2, 0, 0, 7, 6)
254 #define SYSREG_DBGWCR7_EL1 SYSREG(2, 0, 0, 7, 7)
255 #define SYSREG_DBGBVR8_EL1 SYSREG(2, 0, 0, 8, 4)
256 #define SYSREG_DBGBCR8_EL1 SYSREG(2, 0, 0, 8, 5)
257 #define SYSREG_DBGWVR8_EL1 SYSREG(2, 0, 0, 8, 6)
258 #define SYSREG_DBGWCR8_EL1 SYSREG(2, 0, 0, 8, 7)
259 #define SYSREG_DBGBVR9_EL1 SYSREG(2, 0, 0, 9, 4)
260 #define SYSREG_DBGBCR9_EL1 SYSREG(2, 0, 0, 9, 5)
261 #define SYSREG_DBGWVR9_EL1 SYSREG(2, 0, 0, 9, 6)
262 #define SYSREG_DBGWCR9_EL1 SYSREG(2, 0, 0, 9, 7)
263 #define SYSREG_DBGBVR10_EL1 SYSREG(2, 0, 0, 10, 4)
264 #define SYSREG_DBGBCR10_EL1 SYSREG(2, 0, 0, 10, 5)
265 #define SYSREG_DBGWVR10_EL1 SYSREG(2, 0, 0, 10, 6)
266 #define SYSREG_DBGWCR10_EL1 SYSREG(2, 0, 0, 10, 7)
267 #define SYSREG_DBGBVR11_EL1 SYSREG(2, 0, 0, 11, 4)
268 #define SYSREG_DBGBCR11_EL1 SYSREG(2, 0, 0, 11, 5)
269 #define SYSREG_DBGWVR11_EL1 SYSREG(2, 0, 0, 11, 6)
270 #define SYSREG_DBGWCR11_EL1 SYSREG(2, 0, 0, 11, 7)
271 #define SYSREG_DBGBVR12_EL1 SYSREG(2, 0, 0, 12, 4)
272 #define SYSREG_DBGBCR12_EL1 SYSREG(2, 0, 0, 12, 5)
273 #define SYSREG_DBGWVR12_EL1 SYSREG(2, 0, 0, 12, 6)
274 #define SYSREG_DBGWCR12_EL1 SYSREG(2, 0, 0, 12, 7)
275 #define SYSREG_DBGBVR13_EL1 SYSREG(2, 0, 0, 13, 4)
276 #define SYSREG_DBGBCR13_EL1 SYSREG(2, 0, 0, 13, 5)
277 #define SYSREG_DBGWVR13_EL1 SYSREG(2, 0, 0, 13, 6)
278 #define SYSREG_DBGWCR13_EL1 SYSREG(2, 0, 0, 13, 7)
279 #define SYSREG_DBGBVR14_EL1 SYSREG(2, 0, 0, 14, 4)
280 #define SYSREG_DBGBCR14_EL1 SYSREG(2, 0, 0, 14, 5)
281 #define SYSREG_DBGWVR14_EL1 SYSREG(2, 0, 0, 14, 6)
282 #define SYSREG_DBGWCR14_EL1 SYSREG(2, 0, 0, 14, 7)
283 #define SYSREG_DBGBVR15_EL1 SYSREG(2, 0, 0, 15, 4)
284 #define SYSREG_DBGBCR15_EL1 SYSREG(2, 0, 0, 15, 5)
285 #define SYSREG_DBGWVR15_EL1 SYSREG(2, 0, 0, 15, 6)
286 #define SYSREG_DBGWCR15_EL1 SYSREG(2, 0, 0, 15, 7)
288 #define WFX_IS_WFE (1 << 0)
290 #define TMR_CTL_ENABLE (1 << 0)
291 #define TMR_CTL_IMASK (1 << 1)
292 #define TMR_CTL_ISTATUS (1 << 2)
294 static void hvf_wfi(CPUState
*cpu
);
296 typedef struct HVFVTimer
{
297 /* Vtimer value during migration and paused state */
301 static HVFVTimer vtimer
;
303 typedef struct ARMHostCPUFeatures
{
304 ARMISARegisters isar
;
307 uint32_t reset_sctlr
;
308 const char *dtb_compatible
;
309 } ARMHostCPUFeatures
;
311 static ARMHostCPUFeatures arm_host_cpu_features
;
313 struct hvf_reg_match
{
318 static const struct hvf_reg_match hvf_reg_match
[] = {
319 { HV_REG_X0
, offsetof(CPUARMState
, xregs
[0]) },
320 { HV_REG_X1
, offsetof(CPUARMState
, xregs
[1]) },
321 { HV_REG_X2
, offsetof(CPUARMState
, xregs
[2]) },
322 { HV_REG_X3
, offsetof(CPUARMState
, xregs
[3]) },
323 { HV_REG_X4
, offsetof(CPUARMState
, xregs
[4]) },
324 { HV_REG_X5
, offsetof(CPUARMState
, xregs
[5]) },
325 { HV_REG_X6
, offsetof(CPUARMState
, xregs
[6]) },
326 { HV_REG_X7
, offsetof(CPUARMState
, xregs
[7]) },
327 { HV_REG_X8
, offsetof(CPUARMState
, xregs
[8]) },
328 { HV_REG_X9
, offsetof(CPUARMState
, xregs
[9]) },
329 { HV_REG_X10
, offsetof(CPUARMState
, xregs
[10]) },
330 { HV_REG_X11
, offsetof(CPUARMState
, xregs
[11]) },
331 { HV_REG_X12
, offsetof(CPUARMState
, xregs
[12]) },
332 { HV_REG_X13
, offsetof(CPUARMState
, xregs
[13]) },
333 { HV_REG_X14
, offsetof(CPUARMState
, xregs
[14]) },
334 { HV_REG_X15
, offsetof(CPUARMState
, xregs
[15]) },
335 { HV_REG_X16
, offsetof(CPUARMState
, xregs
[16]) },
336 { HV_REG_X17
, offsetof(CPUARMState
, xregs
[17]) },
337 { HV_REG_X18
, offsetof(CPUARMState
, xregs
[18]) },
338 { HV_REG_X19
, offsetof(CPUARMState
, xregs
[19]) },
339 { HV_REG_X20
, offsetof(CPUARMState
, xregs
[20]) },
340 { HV_REG_X21
, offsetof(CPUARMState
, xregs
[21]) },
341 { HV_REG_X22
, offsetof(CPUARMState
, xregs
[22]) },
342 { HV_REG_X23
, offsetof(CPUARMState
, xregs
[23]) },
343 { HV_REG_X24
, offsetof(CPUARMState
, xregs
[24]) },
344 { HV_REG_X25
, offsetof(CPUARMState
, xregs
[25]) },
345 { HV_REG_X26
, offsetof(CPUARMState
, xregs
[26]) },
346 { HV_REG_X27
, offsetof(CPUARMState
, xregs
[27]) },
347 { HV_REG_X28
, offsetof(CPUARMState
, xregs
[28]) },
348 { HV_REG_X29
, offsetof(CPUARMState
, xregs
[29]) },
349 { HV_REG_X30
, offsetof(CPUARMState
, xregs
[30]) },
350 { HV_REG_PC
, offsetof(CPUARMState
, pc
) },
353 static const struct hvf_reg_match hvf_fpreg_match
[] = {
354 { HV_SIMD_FP_REG_Q0
, offsetof(CPUARMState
, vfp
.zregs
[0]) },
355 { HV_SIMD_FP_REG_Q1
, offsetof(CPUARMState
, vfp
.zregs
[1]) },
356 { HV_SIMD_FP_REG_Q2
, offsetof(CPUARMState
, vfp
.zregs
[2]) },
357 { HV_SIMD_FP_REG_Q3
, offsetof(CPUARMState
, vfp
.zregs
[3]) },
358 { HV_SIMD_FP_REG_Q4
, offsetof(CPUARMState
, vfp
.zregs
[4]) },
359 { HV_SIMD_FP_REG_Q5
, offsetof(CPUARMState
, vfp
.zregs
[5]) },
360 { HV_SIMD_FP_REG_Q6
, offsetof(CPUARMState
, vfp
.zregs
[6]) },
361 { HV_SIMD_FP_REG_Q7
, offsetof(CPUARMState
, vfp
.zregs
[7]) },
362 { HV_SIMD_FP_REG_Q8
, offsetof(CPUARMState
, vfp
.zregs
[8]) },
363 { HV_SIMD_FP_REG_Q9
, offsetof(CPUARMState
, vfp
.zregs
[9]) },
364 { HV_SIMD_FP_REG_Q10
, offsetof(CPUARMState
, vfp
.zregs
[10]) },
365 { HV_SIMD_FP_REG_Q11
, offsetof(CPUARMState
, vfp
.zregs
[11]) },
366 { HV_SIMD_FP_REG_Q12
, offsetof(CPUARMState
, vfp
.zregs
[12]) },
367 { HV_SIMD_FP_REG_Q13
, offsetof(CPUARMState
, vfp
.zregs
[13]) },
368 { HV_SIMD_FP_REG_Q14
, offsetof(CPUARMState
, vfp
.zregs
[14]) },
369 { HV_SIMD_FP_REG_Q15
, offsetof(CPUARMState
, vfp
.zregs
[15]) },
370 { HV_SIMD_FP_REG_Q16
, offsetof(CPUARMState
, vfp
.zregs
[16]) },
371 { HV_SIMD_FP_REG_Q17
, offsetof(CPUARMState
, vfp
.zregs
[17]) },
372 { HV_SIMD_FP_REG_Q18
, offsetof(CPUARMState
, vfp
.zregs
[18]) },
373 { HV_SIMD_FP_REG_Q19
, offsetof(CPUARMState
, vfp
.zregs
[19]) },
374 { HV_SIMD_FP_REG_Q20
, offsetof(CPUARMState
, vfp
.zregs
[20]) },
375 { HV_SIMD_FP_REG_Q21
, offsetof(CPUARMState
, vfp
.zregs
[21]) },
376 { HV_SIMD_FP_REG_Q22
, offsetof(CPUARMState
, vfp
.zregs
[22]) },
377 { HV_SIMD_FP_REG_Q23
, offsetof(CPUARMState
, vfp
.zregs
[23]) },
378 { HV_SIMD_FP_REG_Q24
, offsetof(CPUARMState
, vfp
.zregs
[24]) },
379 { HV_SIMD_FP_REG_Q25
, offsetof(CPUARMState
, vfp
.zregs
[25]) },
380 { HV_SIMD_FP_REG_Q26
, offsetof(CPUARMState
, vfp
.zregs
[26]) },
381 { HV_SIMD_FP_REG_Q27
, offsetof(CPUARMState
, vfp
.zregs
[27]) },
382 { HV_SIMD_FP_REG_Q28
, offsetof(CPUARMState
, vfp
.zregs
[28]) },
383 { HV_SIMD_FP_REG_Q29
, offsetof(CPUARMState
, vfp
.zregs
[29]) },
384 { HV_SIMD_FP_REG_Q30
, offsetof(CPUARMState
, vfp
.zregs
[30]) },
385 { HV_SIMD_FP_REG_Q31
, offsetof(CPUARMState
, vfp
.zregs
[31]) },
388 struct hvf_sreg_match
{
394 static struct hvf_sreg_match hvf_sreg_match
[] = {
395 { HV_SYS_REG_DBGBVR0_EL1
, HVF_SYSREG(0, 0, 14, 0, 4) },
396 { HV_SYS_REG_DBGBCR0_EL1
, HVF_SYSREG(0, 0, 14, 0, 5) },
397 { HV_SYS_REG_DBGWVR0_EL1
, HVF_SYSREG(0, 0, 14, 0, 6) },
398 { HV_SYS_REG_DBGWCR0_EL1
, HVF_SYSREG(0, 0, 14, 0, 7) },
400 { HV_SYS_REG_DBGBVR1_EL1
, HVF_SYSREG(0, 1, 14, 0, 4) },
401 { HV_SYS_REG_DBGBCR1_EL1
, HVF_SYSREG(0, 1, 14, 0, 5) },
402 { HV_SYS_REG_DBGWVR1_EL1
, HVF_SYSREG(0, 1, 14, 0, 6) },
403 { HV_SYS_REG_DBGWCR1_EL1
, HVF_SYSREG(0, 1, 14, 0, 7) },
405 { HV_SYS_REG_DBGBVR2_EL1
, HVF_SYSREG(0, 2, 14, 0, 4) },
406 { HV_SYS_REG_DBGBCR2_EL1
, HVF_SYSREG(0, 2, 14, 0, 5) },
407 { HV_SYS_REG_DBGWVR2_EL1
, HVF_SYSREG(0, 2, 14, 0, 6) },
408 { HV_SYS_REG_DBGWCR2_EL1
, HVF_SYSREG(0, 2, 14, 0, 7) },
410 { HV_SYS_REG_DBGBVR3_EL1
, HVF_SYSREG(0, 3, 14, 0, 4) },
411 { HV_SYS_REG_DBGBCR3_EL1
, HVF_SYSREG(0, 3, 14, 0, 5) },
412 { HV_SYS_REG_DBGWVR3_EL1
, HVF_SYSREG(0, 3, 14, 0, 6) },
413 { HV_SYS_REG_DBGWCR3_EL1
, HVF_SYSREG(0, 3, 14, 0, 7) },
415 { HV_SYS_REG_DBGBVR4_EL1
, HVF_SYSREG(0, 4, 14, 0, 4) },
416 { HV_SYS_REG_DBGBCR4_EL1
, HVF_SYSREG(0, 4, 14, 0, 5) },
417 { HV_SYS_REG_DBGWVR4_EL1
, HVF_SYSREG(0, 4, 14, 0, 6) },
418 { HV_SYS_REG_DBGWCR4_EL1
, HVF_SYSREG(0, 4, 14, 0, 7) },
420 { HV_SYS_REG_DBGBVR5_EL1
, HVF_SYSREG(0, 5, 14, 0, 4) },
421 { HV_SYS_REG_DBGBCR5_EL1
, HVF_SYSREG(0, 5, 14, 0, 5) },
422 { HV_SYS_REG_DBGWVR5_EL1
, HVF_SYSREG(0, 5, 14, 0, 6) },
423 { HV_SYS_REG_DBGWCR5_EL1
, HVF_SYSREG(0, 5, 14, 0, 7) },
425 { HV_SYS_REG_DBGBVR6_EL1
, HVF_SYSREG(0, 6, 14, 0, 4) },
426 { HV_SYS_REG_DBGBCR6_EL1
, HVF_SYSREG(0, 6, 14, 0, 5) },
427 { HV_SYS_REG_DBGWVR6_EL1
, HVF_SYSREG(0, 6, 14, 0, 6) },
428 { HV_SYS_REG_DBGWCR6_EL1
, HVF_SYSREG(0, 6, 14, 0, 7) },
430 { HV_SYS_REG_DBGBVR7_EL1
, HVF_SYSREG(0, 7, 14, 0, 4) },
431 { HV_SYS_REG_DBGBCR7_EL1
, HVF_SYSREG(0, 7, 14, 0, 5) },
432 { HV_SYS_REG_DBGWVR7_EL1
, HVF_SYSREG(0, 7, 14, 0, 6) },
433 { HV_SYS_REG_DBGWCR7_EL1
, HVF_SYSREG(0, 7, 14, 0, 7) },
435 { HV_SYS_REG_DBGBVR8_EL1
, HVF_SYSREG(0, 8, 14, 0, 4) },
436 { HV_SYS_REG_DBGBCR8_EL1
, HVF_SYSREG(0, 8, 14, 0, 5) },
437 { HV_SYS_REG_DBGWVR8_EL1
, HVF_SYSREG(0, 8, 14, 0, 6) },
438 { HV_SYS_REG_DBGWCR8_EL1
, HVF_SYSREG(0, 8, 14, 0, 7) },
440 { HV_SYS_REG_DBGBVR9_EL1
, HVF_SYSREG(0, 9, 14, 0, 4) },
441 { HV_SYS_REG_DBGBCR9_EL1
, HVF_SYSREG(0, 9, 14, 0, 5) },
442 { HV_SYS_REG_DBGWVR9_EL1
, HVF_SYSREG(0, 9, 14, 0, 6) },
443 { HV_SYS_REG_DBGWCR9_EL1
, HVF_SYSREG(0, 9, 14, 0, 7) },
445 { HV_SYS_REG_DBGBVR10_EL1
, HVF_SYSREG(0, 10, 14, 0, 4) },
446 { HV_SYS_REG_DBGBCR10_EL1
, HVF_SYSREG(0, 10, 14, 0, 5) },
447 { HV_SYS_REG_DBGWVR10_EL1
, HVF_SYSREG(0, 10, 14, 0, 6) },
448 { HV_SYS_REG_DBGWCR10_EL1
, HVF_SYSREG(0, 10, 14, 0, 7) },
450 { HV_SYS_REG_DBGBVR11_EL1
, HVF_SYSREG(0, 11, 14, 0, 4) },
451 { HV_SYS_REG_DBGBCR11_EL1
, HVF_SYSREG(0, 11, 14, 0, 5) },
452 { HV_SYS_REG_DBGWVR11_EL1
, HVF_SYSREG(0, 11, 14, 0, 6) },
453 { HV_SYS_REG_DBGWCR11_EL1
, HVF_SYSREG(0, 11, 14, 0, 7) },
455 { HV_SYS_REG_DBGBVR12_EL1
, HVF_SYSREG(0, 12, 14, 0, 4) },
456 { HV_SYS_REG_DBGBCR12_EL1
, HVF_SYSREG(0, 12, 14, 0, 5) },
457 { HV_SYS_REG_DBGWVR12_EL1
, HVF_SYSREG(0, 12, 14, 0, 6) },
458 { HV_SYS_REG_DBGWCR12_EL1
, HVF_SYSREG(0, 12, 14, 0, 7) },
460 { HV_SYS_REG_DBGBVR13_EL1
, HVF_SYSREG(0, 13, 14, 0, 4) },
461 { HV_SYS_REG_DBGBCR13_EL1
, HVF_SYSREG(0, 13, 14, 0, 5) },
462 { HV_SYS_REG_DBGWVR13_EL1
, HVF_SYSREG(0, 13, 14, 0, 6) },
463 { HV_SYS_REG_DBGWCR13_EL1
, HVF_SYSREG(0, 13, 14, 0, 7) },
465 { HV_SYS_REG_DBGBVR14_EL1
, HVF_SYSREG(0, 14, 14, 0, 4) },
466 { HV_SYS_REG_DBGBCR14_EL1
, HVF_SYSREG(0, 14, 14, 0, 5) },
467 { HV_SYS_REG_DBGWVR14_EL1
, HVF_SYSREG(0, 14, 14, 0, 6) },
468 { HV_SYS_REG_DBGWCR14_EL1
, HVF_SYSREG(0, 14, 14, 0, 7) },
470 { HV_SYS_REG_DBGBVR15_EL1
, HVF_SYSREG(0, 15, 14, 0, 4) },
471 { HV_SYS_REG_DBGBCR15_EL1
, HVF_SYSREG(0, 15, 14, 0, 5) },
472 { HV_SYS_REG_DBGWVR15_EL1
, HVF_SYSREG(0, 15, 14, 0, 6) },
473 { HV_SYS_REG_DBGWCR15_EL1
, HVF_SYSREG(0, 15, 14, 0, 7) },
475 #ifdef SYNC_NO_RAW_REGS
477 * The registers below are manually synced on init because they are
478 * marked as NO_RAW. We still list them to make number space sync easier.
480 { HV_SYS_REG_MDCCINT_EL1
, HVF_SYSREG(0, 2, 2, 0, 0) },
481 { HV_SYS_REG_MIDR_EL1
, HVF_SYSREG(0, 0, 3, 0, 0) },
482 { HV_SYS_REG_MPIDR_EL1
, HVF_SYSREG(0, 0, 3, 0, 5) },
483 { HV_SYS_REG_ID_AA64PFR0_EL1
, HVF_SYSREG(0, 4, 3, 0, 0) },
485 { HV_SYS_REG_ID_AA64PFR1_EL1
, HVF_SYSREG(0, 4, 3, 0, 2) },
486 { HV_SYS_REG_ID_AA64DFR0_EL1
, HVF_SYSREG(0, 5, 3, 0, 0) },
487 { HV_SYS_REG_ID_AA64DFR1_EL1
, HVF_SYSREG(0, 5, 3, 0, 1) },
488 { HV_SYS_REG_ID_AA64ISAR0_EL1
, HVF_SYSREG(0, 6, 3, 0, 0) },
489 { HV_SYS_REG_ID_AA64ISAR1_EL1
, HVF_SYSREG(0, 6, 3, 0, 1) },
491 /* We keep the hardware MMFR0 around. HW limits are there anyway */
492 { HV_SYS_REG_ID_AA64MMFR0_EL1
, HVF_SYSREG(0, 7, 3, 0, 0) },
494 { HV_SYS_REG_ID_AA64MMFR1_EL1
, HVF_SYSREG(0, 7, 3, 0, 1) },
495 { HV_SYS_REG_ID_AA64MMFR2_EL1
, HVF_SYSREG(0, 7, 3, 0, 2) },
497 { HV_SYS_REG_MDSCR_EL1
, HVF_SYSREG(0, 2, 2, 0, 2) },
498 { HV_SYS_REG_SCTLR_EL1
, HVF_SYSREG(1, 0, 3, 0, 0) },
499 { HV_SYS_REG_CPACR_EL1
, HVF_SYSREG(1, 0, 3, 0, 2) },
500 { HV_SYS_REG_TTBR0_EL1
, HVF_SYSREG(2, 0, 3, 0, 0) },
501 { HV_SYS_REG_TTBR1_EL1
, HVF_SYSREG(2, 0, 3, 0, 1) },
502 { HV_SYS_REG_TCR_EL1
, HVF_SYSREG(2, 0, 3, 0, 2) },
504 { HV_SYS_REG_APIAKEYLO_EL1
, HVF_SYSREG(2, 1, 3, 0, 0) },
505 { HV_SYS_REG_APIAKEYHI_EL1
, HVF_SYSREG(2, 1, 3, 0, 1) },
506 { HV_SYS_REG_APIBKEYLO_EL1
, HVF_SYSREG(2, 1, 3, 0, 2) },
507 { HV_SYS_REG_APIBKEYHI_EL1
, HVF_SYSREG(2, 1, 3, 0, 3) },
508 { HV_SYS_REG_APDAKEYLO_EL1
, HVF_SYSREG(2, 2, 3, 0, 0) },
509 { HV_SYS_REG_APDAKEYHI_EL1
, HVF_SYSREG(2, 2, 3, 0, 1) },
510 { HV_SYS_REG_APDBKEYLO_EL1
, HVF_SYSREG(2, 2, 3, 0, 2) },
511 { HV_SYS_REG_APDBKEYHI_EL1
, HVF_SYSREG(2, 2, 3, 0, 3) },
512 { HV_SYS_REG_APGAKEYLO_EL1
, HVF_SYSREG(2, 3, 3, 0, 0) },
513 { HV_SYS_REG_APGAKEYHI_EL1
, HVF_SYSREG(2, 3, 3, 0, 1) },
515 { HV_SYS_REG_SPSR_EL1
, HVF_SYSREG(4, 0, 3, 0, 0) },
516 { HV_SYS_REG_ELR_EL1
, HVF_SYSREG(4, 0, 3, 0, 1) },
517 { HV_SYS_REG_SP_EL0
, HVF_SYSREG(4, 1, 3, 0, 0) },
518 { HV_SYS_REG_AFSR0_EL1
, HVF_SYSREG(5, 1, 3, 0, 0) },
519 { HV_SYS_REG_AFSR1_EL1
, HVF_SYSREG(5, 1, 3, 0, 1) },
520 { HV_SYS_REG_ESR_EL1
, HVF_SYSREG(5, 2, 3, 0, 0) },
521 { HV_SYS_REG_FAR_EL1
, HVF_SYSREG(6, 0, 3, 0, 0) },
522 { HV_SYS_REG_PAR_EL1
, HVF_SYSREG(7, 4, 3, 0, 0) },
523 { HV_SYS_REG_MAIR_EL1
, HVF_SYSREG(10, 2, 3, 0, 0) },
524 { HV_SYS_REG_AMAIR_EL1
, HVF_SYSREG(10, 3, 3, 0, 0) },
525 { HV_SYS_REG_VBAR_EL1
, HVF_SYSREG(12, 0, 3, 0, 0) },
526 { HV_SYS_REG_CONTEXTIDR_EL1
, HVF_SYSREG(13, 0, 3, 0, 1) },
527 { HV_SYS_REG_TPIDR_EL1
, HVF_SYSREG(13, 0, 3, 0, 4) },
528 { HV_SYS_REG_CNTKCTL_EL1
, HVF_SYSREG(14, 1, 3, 0, 0) },
529 { HV_SYS_REG_CSSELR_EL1
, HVF_SYSREG(0, 0, 3, 2, 0) },
530 { HV_SYS_REG_TPIDR_EL0
, HVF_SYSREG(13, 0, 3, 3, 2) },
531 { HV_SYS_REG_TPIDRRO_EL0
, HVF_SYSREG(13, 0, 3, 3, 3) },
532 { HV_SYS_REG_CNTV_CTL_EL0
, HVF_SYSREG(14, 3, 3, 3, 1) },
533 { HV_SYS_REG_CNTV_CVAL_EL0
, HVF_SYSREG(14, 3, 3, 3, 2) },
534 { HV_SYS_REG_SP_EL1
, HVF_SYSREG(4, 1, 3, 4, 0) },
537 int hvf_get_registers(CPUState
*cpu
)
539 ARMCPU
*arm_cpu
= ARM_CPU(cpu
);
540 CPUARMState
*env
= &arm_cpu
->env
;
543 hv_simd_fp_uchar16_t fpval
;
546 for (i
= 0; i
< ARRAY_SIZE(hvf_reg_match
); i
++) {
547 ret
= hv_vcpu_get_reg(cpu
->accel
->fd
, hvf_reg_match
[i
].reg
, &val
);
548 *(uint64_t *)((void *)env
+ hvf_reg_match
[i
].offset
) = val
;
552 for (i
= 0; i
< ARRAY_SIZE(hvf_fpreg_match
); i
++) {
553 ret
= hv_vcpu_get_simd_fp_reg(cpu
->accel
->fd
, hvf_fpreg_match
[i
].reg
,
555 memcpy((void *)env
+ hvf_fpreg_match
[i
].offset
, &fpval
, sizeof(fpval
));
560 ret
= hv_vcpu_get_reg(cpu
->accel
->fd
, HV_REG_FPCR
, &val
);
562 vfp_set_fpcr(env
, val
);
565 ret
= hv_vcpu_get_reg(cpu
->accel
->fd
, HV_REG_FPSR
, &val
);
567 vfp_set_fpsr(env
, val
);
569 ret
= hv_vcpu_get_reg(cpu
->accel
->fd
, HV_REG_CPSR
, &val
);
571 pstate_write(env
, val
);
573 for (i
= 0; i
< ARRAY_SIZE(hvf_sreg_match
); i
++) {
574 if (hvf_sreg_match
[i
].cp_idx
== -1) {
578 if (cpu
->accel
->guest_debug_enabled
) {
579 /* Handle debug registers */
580 switch (hvf_sreg_match
[i
].reg
) {
581 case HV_SYS_REG_DBGBVR0_EL1
:
582 case HV_SYS_REG_DBGBCR0_EL1
:
583 case HV_SYS_REG_DBGWVR0_EL1
:
584 case HV_SYS_REG_DBGWCR0_EL1
:
585 case HV_SYS_REG_DBGBVR1_EL1
:
586 case HV_SYS_REG_DBGBCR1_EL1
:
587 case HV_SYS_REG_DBGWVR1_EL1
:
588 case HV_SYS_REG_DBGWCR1_EL1
:
589 case HV_SYS_REG_DBGBVR2_EL1
:
590 case HV_SYS_REG_DBGBCR2_EL1
:
591 case HV_SYS_REG_DBGWVR2_EL1
:
592 case HV_SYS_REG_DBGWCR2_EL1
:
593 case HV_SYS_REG_DBGBVR3_EL1
:
594 case HV_SYS_REG_DBGBCR3_EL1
:
595 case HV_SYS_REG_DBGWVR3_EL1
:
596 case HV_SYS_REG_DBGWCR3_EL1
:
597 case HV_SYS_REG_DBGBVR4_EL1
:
598 case HV_SYS_REG_DBGBCR4_EL1
:
599 case HV_SYS_REG_DBGWVR4_EL1
:
600 case HV_SYS_REG_DBGWCR4_EL1
:
601 case HV_SYS_REG_DBGBVR5_EL1
:
602 case HV_SYS_REG_DBGBCR5_EL1
:
603 case HV_SYS_REG_DBGWVR5_EL1
:
604 case HV_SYS_REG_DBGWCR5_EL1
:
605 case HV_SYS_REG_DBGBVR6_EL1
:
606 case HV_SYS_REG_DBGBCR6_EL1
:
607 case HV_SYS_REG_DBGWVR6_EL1
:
608 case HV_SYS_REG_DBGWCR6_EL1
:
609 case HV_SYS_REG_DBGBVR7_EL1
:
610 case HV_SYS_REG_DBGBCR7_EL1
:
611 case HV_SYS_REG_DBGWVR7_EL1
:
612 case HV_SYS_REG_DBGWCR7_EL1
:
613 case HV_SYS_REG_DBGBVR8_EL1
:
614 case HV_SYS_REG_DBGBCR8_EL1
:
615 case HV_SYS_REG_DBGWVR8_EL1
:
616 case HV_SYS_REG_DBGWCR8_EL1
:
617 case HV_SYS_REG_DBGBVR9_EL1
:
618 case HV_SYS_REG_DBGBCR9_EL1
:
619 case HV_SYS_REG_DBGWVR9_EL1
:
620 case HV_SYS_REG_DBGWCR9_EL1
:
621 case HV_SYS_REG_DBGBVR10_EL1
:
622 case HV_SYS_REG_DBGBCR10_EL1
:
623 case HV_SYS_REG_DBGWVR10_EL1
:
624 case HV_SYS_REG_DBGWCR10_EL1
:
625 case HV_SYS_REG_DBGBVR11_EL1
:
626 case HV_SYS_REG_DBGBCR11_EL1
:
627 case HV_SYS_REG_DBGWVR11_EL1
:
628 case HV_SYS_REG_DBGWCR11_EL1
:
629 case HV_SYS_REG_DBGBVR12_EL1
:
630 case HV_SYS_REG_DBGBCR12_EL1
:
631 case HV_SYS_REG_DBGWVR12_EL1
:
632 case HV_SYS_REG_DBGWCR12_EL1
:
633 case HV_SYS_REG_DBGBVR13_EL1
:
634 case HV_SYS_REG_DBGBCR13_EL1
:
635 case HV_SYS_REG_DBGWVR13_EL1
:
636 case HV_SYS_REG_DBGWCR13_EL1
:
637 case HV_SYS_REG_DBGBVR14_EL1
:
638 case HV_SYS_REG_DBGBCR14_EL1
:
639 case HV_SYS_REG_DBGWVR14_EL1
:
640 case HV_SYS_REG_DBGWCR14_EL1
:
641 case HV_SYS_REG_DBGBVR15_EL1
:
642 case HV_SYS_REG_DBGBCR15_EL1
:
643 case HV_SYS_REG_DBGWVR15_EL1
:
644 case HV_SYS_REG_DBGWCR15_EL1
: {
646 * If the guest is being debugged, the vCPU's debug registers
647 * are holding the gdbstub's view of the registers (set in
648 * hvf_arch_update_guest_debug()).
649 * Since the environment is used to store only the guest's view
650 * of the registers, don't update it with the values from the
651 * vCPU but simply keep the values from the previous
654 const ARMCPRegInfo
*ri
;
655 ri
= get_arm_cp_reginfo(arm_cpu
->cp_regs
, hvf_sreg_match
[i
].key
);
656 val
= read_raw_cp_reg(env
, ri
);
658 arm_cpu
->cpreg_values
[hvf_sreg_match
[i
].cp_idx
] = val
;
664 ret
= hv_vcpu_get_sys_reg(cpu
->accel
->fd
, hvf_sreg_match
[i
].reg
, &val
);
667 arm_cpu
->cpreg_values
[hvf_sreg_match
[i
].cp_idx
] = val
;
669 assert(write_list_to_cpustate(arm_cpu
));
671 aarch64_restore_sp(env
, arm_current_el(env
));
676 int hvf_put_registers(CPUState
*cpu
)
678 ARMCPU
*arm_cpu
= ARM_CPU(cpu
);
679 CPUARMState
*env
= &arm_cpu
->env
;
682 hv_simd_fp_uchar16_t fpval
;
685 for (i
= 0; i
< ARRAY_SIZE(hvf_reg_match
); i
++) {
686 val
= *(uint64_t *)((void *)env
+ hvf_reg_match
[i
].offset
);
687 ret
= hv_vcpu_set_reg(cpu
->accel
->fd
, hvf_reg_match
[i
].reg
, val
);
691 for (i
= 0; i
< ARRAY_SIZE(hvf_fpreg_match
); i
++) {
692 memcpy(&fpval
, (void *)env
+ hvf_fpreg_match
[i
].offset
, sizeof(fpval
));
693 ret
= hv_vcpu_set_simd_fp_reg(cpu
->accel
->fd
, hvf_fpreg_match
[i
].reg
,
698 ret
= hv_vcpu_set_reg(cpu
->accel
->fd
, HV_REG_FPCR
, vfp_get_fpcr(env
));
701 ret
= hv_vcpu_set_reg(cpu
->accel
->fd
, HV_REG_FPSR
, vfp_get_fpsr(env
));
704 ret
= hv_vcpu_set_reg(cpu
->accel
->fd
, HV_REG_CPSR
, pstate_read(env
));
707 aarch64_save_sp(env
, arm_current_el(env
));
709 assert(write_cpustate_to_list(arm_cpu
, false));
710 for (i
= 0; i
< ARRAY_SIZE(hvf_sreg_match
); i
++) {
711 if (hvf_sreg_match
[i
].cp_idx
== -1) {
715 if (cpu
->accel
->guest_debug_enabled
) {
716 /* Handle debug registers */
717 switch (hvf_sreg_match
[i
].reg
) {
718 case HV_SYS_REG_DBGBVR0_EL1
:
719 case HV_SYS_REG_DBGBCR0_EL1
:
720 case HV_SYS_REG_DBGWVR0_EL1
:
721 case HV_SYS_REG_DBGWCR0_EL1
:
722 case HV_SYS_REG_DBGBVR1_EL1
:
723 case HV_SYS_REG_DBGBCR1_EL1
:
724 case HV_SYS_REG_DBGWVR1_EL1
:
725 case HV_SYS_REG_DBGWCR1_EL1
:
726 case HV_SYS_REG_DBGBVR2_EL1
:
727 case HV_SYS_REG_DBGBCR2_EL1
:
728 case HV_SYS_REG_DBGWVR2_EL1
:
729 case HV_SYS_REG_DBGWCR2_EL1
:
730 case HV_SYS_REG_DBGBVR3_EL1
:
731 case HV_SYS_REG_DBGBCR3_EL1
:
732 case HV_SYS_REG_DBGWVR3_EL1
:
733 case HV_SYS_REG_DBGWCR3_EL1
:
734 case HV_SYS_REG_DBGBVR4_EL1
:
735 case HV_SYS_REG_DBGBCR4_EL1
:
736 case HV_SYS_REG_DBGWVR4_EL1
:
737 case HV_SYS_REG_DBGWCR4_EL1
:
738 case HV_SYS_REG_DBGBVR5_EL1
:
739 case HV_SYS_REG_DBGBCR5_EL1
:
740 case HV_SYS_REG_DBGWVR5_EL1
:
741 case HV_SYS_REG_DBGWCR5_EL1
:
742 case HV_SYS_REG_DBGBVR6_EL1
:
743 case HV_SYS_REG_DBGBCR6_EL1
:
744 case HV_SYS_REG_DBGWVR6_EL1
:
745 case HV_SYS_REG_DBGWCR6_EL1
:
746 case HV_SYS_REG_DBGBVR7_EL1
:
747 case HV_SYS_REG_DBGBCR7_EL1
:
748 case HV_SYS_REG_DBGWVR7_EL1
:
749 case HV_SYS_REG_DBGWCR7_EL1
:
750 case HV_SYS_REG_DBGBVR8_EL1
:
751 case HV_SYS_REG_DBGBCR8_EL1
:
752 case HV_SYS_REG_DBGWVR8_EL1
:
753 case HV_SYS_REG_DBGWCR8_EL1
:
754 case HV_SYS_REG_DBGBVR9_EL1
:
755 case HV_SYS_REG_DBGBCR9_EL1
:
756 case HV_SYS_REG_DBGWVR9_EL1
:
757 case HV_SYS_REG_DBGWCR9_EL1
:
758 case HV_SYS_REG_DBGBVR10_EL1
:
759 case HV_SYS_REG_DBGBCR10_EL1
:
760 case HV_SYS_REG_DBGWVR10_EL1
:
761 case HV_SYS_REG_DBGWCR10_EL1
:
762 case HV_SYS_REG_DBGBVR11_EL1
:
763 case HV_SYS_REG_DBGBCR11_EL1
:
764 case HV_SYS_REG_DBGWVR11_EL1
:
765 case HV_SYS_REG_DBGWCR11_EL1
:
766 case HV_SYS_REG_DBGBVR12_EL1
:
767 case HV_SYS_REG_DBGBCR12_EL1
:
768 case HV_SYS_REG_DBGWVR12_EL1
:
769 case HV_SYS_REG_DBGWCR12_EL1
:
770 case HV_SYS_REG_DBGBVR13_EL1
:
771 case HV_SYS_REG_DBGBCR13_EL1
:
772 case HV_SYS_REG_DBGWVR13_EL1
:
773 case HV_SYS_REG_DBGWCR13_EL1
:
774 case HV_SYS_REG_DBGBVR14_EL1
:
775 case HV_SYS_REG_DBGBCR14_EL1
:
776 case HV_SYS_REG_DBGWVR14_EL1
:
777 case HV_SYS_REG_DBGWCR14_EL1
:
778 case HV_SYS_REG_DBGBVR15_EL1
:
779 case HV_SYS_REG_DBGBCR15_EL1
:
780 case HV_SYS_REG_DBGWVR15_EL1
:
781 case HV_SYS_REG_DBGWCR15_EL1
:
783 * If the guest is being debugged, the vCPU's debug registers
784 * are already holding the gdbstub's view of the registers (set
785 * in hvf_arch_update_guest_debug()).
791 val
= arm_cpu
->cpreg_values
[hvf_sreg_match
[i
].cp_idx
];
792 ret
= hv_vcpu_set_sys_reg(cpu
->accel
->fd
, hvf_sreg_match
[i
].reg
, val
);
796 ret
= hv_vcpu_set_vtimer_offset(cpu
->accel
->fd
, hvf_state
->vtimer_offset
);
802 static void flush_cpu_state(CPUState
*cpu
)
804 if (cpu
->vcpu_dirty
) {
805 hvf_put_registers(cpu
);
806 cpu
->vcpu_dirty
= false;
810 static void hvf_set_reg(CPUState
*cpu
, int rt
, uint64_t val
)
814 flush_cpu_state(cpu
);
817 r
= hv_vcpu_set_reg(cpu
->accel
->fd
, HV_REG_X0
+ rt
, val
);
822 static uint64_t hvf_get_reg(CPUState
*cpu
, int rt
)
827 flush_cpu_state(cpu
);
830 r
= hv_vcpu_get_reg(cpu
->accel
->fd
, HV_REG_X0
+ rt
, &val
);
837 static bool hvf_arm_get_host_cpu_features(ARMHostCPUFeatures
*ahcf
)
839 ARMISARegisters host_isar
= {};
840 const struct isar_regs
{
844 { HV_SYS_REG_ID_AA64PFR0_EL1
, &host_isar
.id_aa64pfr0
},
845 { HV_SYS_REG_ID_AA64PFR1_EL1
, &host_isar
.id_aa64pfr1
},
846 { HV_SYS_REG_ID_AA64DFR0_EL1
, &host_isar
.id_aa64dfr0
},
847 { HV_SYS_REG_ID_AA64DFR1_EL1
, &host_isar
.id_aa64dfr1
},
848 { HV_SYS_REG_ID_AA64ISAR0_EL1
, &host_isar
.id_aa64isar0
},
849 { HV_SYS_REG_ID_AA64ISAR1_EL1
, &host_isar
.id_aa64isar1
},
850 /* Add ID_AA64ISAR2_EL1 here when HVF supports it */
851 { HV_SYS_REG_ID_AA64MMFR0_EL1
, &host_isar
.id_aa64mmfr0
},
852 { HV_SYS_REG_ID_AA64MMFR1_EL1
, &host_isar
.id_aa64mmfr1
},
853 { HV_SYS_REG_ID_AA64MMFR2_EL1
, &host_isar
.id_aa64mmfr2
},
856 hv_return_t r
= HV_SUCCESS
;
857 hv_vcpu_exit_t
*exit
;
860 ahcf
->dtb_compatible
= "arm,arm-v8";
861 ahcf
->features
= (1ULL << ARM_FEATURE_V8
) |
862 (1ULL << ARM_FEATURE_NEON
) |
863 (1ULL << ARM_FEATURE_AARCH64
) |
864 (1ULL << ARM_FEATURE_PMU
) |
865 (1ULL << ARM_FEATURE_GENERIC_TIMER
);
867 /* We set up a small vcpu to extract host registers */
869 if (hv_vcpu_create(&fd
, &exit
, NULL
) != HV_SUCCESS
) {
873 for (i
= 0; i
< ARRAY_SIZE(regs
); i
++) {
874 r
|= hv_vcpu_get_sys_reg(fd
, regs
[i
].reg
, regs
[i
].val
);
876 r
|= hv_vcpu_get_sys_reg(fd
, HV_SYS_REG_MIDR_EL1
, &ahcf
->midr
);
877 r
|= hv_vcpu_destroy(fd
);
879 ahcf
->isar
= host_isar
;
882 * A scratch vCPU returns SCTLR 0, so let's fill our default with the M1
883 * boot SCTLR from https://github.com/AsahiLinux/m1n1/issues/97
885 ahcf
->reset_sctlr
= 0x30100180;
887 * SPAN is disabled by default when SCTLR.SPAN=1. To improve compatibility,
888 * let's disable it on boot and then allow guest software to turn it on by
891 ahcf
->reset_sctlr
|= 0x00800000;
893 /* Make sure we don't advertise AArch32 support for EL0/EL1 */
894 if ((host_isar
.id_aa64pfr0
& 0xff) != 0x11) {
898 return r
== HV_SUCCESS
;
901 void hvf_arm_set_cpu_features_from_host(ARMCPU
*cpu
)
903 if (!arm_host_cpu_features
.dtb_compatible
) {
904 if (!hvf_enabled() ||
905 !hvf_arm_get_host_cpu_features(&arm_host_cpu_features
)) {
907 * We can't report this error yet, so flag that we need to
908 * in arm_cpu_realizefn().
910 cpu
->host_cpu_probe_failed
= true;
915 cpu
->dtb_compatible
= arm_host_cpu_features
.dtb_compatible
;
916 cpu
->isar
= arm_host_cpu_features
.isar
;
917 cpu
->env
.features
= arm_host_cpu_features
.features
;
918 cpu
->midr
= arm_host_cpu_features
.midr
;
919 cpu
->reset_sctlr
= arm_host_cpu_features
.reset_sctlr
;
922 void hvf_arch_vcpu_destroy(CPUState
*cpu
)
926 int hvf_arch_init_vcpu(CPUState
*cpu
)
928 ARMCPU
*arm_cpu
= ARM_CPU(cpu
);
929 CPUARMState
*env
= &arm_cpu
->env
;
930 uint32_t sregs_match_len
= ARRAY_SIZE(hvf_sreg_match
);
931 uint32_t sregs_cnt
= 0;
937 asm volatile("mrs %0, cntfrq_el0" : "=r"(arm_cpu
->gt_cntfrq_hz
));
939 /* Allocate enough space for our sysreg sync */
940 arm_cpu
->cpreg_indexes
= g_renew(uint64_t, arm_cpu
->cpreg_indexes
,
942 arm_cpu
->cpreg_values
= g_renew(uint64_t, arm_cpu
->cpreg_values
,
944 arm_cpu
->cpreg_vmstate_indexes
= g_renew(uint64_t,
945 arm_cpu
->cpreg_vmstate_indexes
,
947 arm_cpu
->cpreg_vmstate_values
= g_renew(uint64_t,
948 arm_cpu
->cpreg_vmstate_values
,
951 memset(arm_cpu
->cpreg_values
, 0, sregs_match_len
* sizeof(uint64_t));
953 /* Populate cp list for all known sysregs */
954 for (i
= 0; i
< sregs_match_len
; i
++) {
955 const ARMCPRegInfo
*ri
;
956 uint32_t key
= hvf_sreg_match
[i
].key
;
958 ri
= get_arm_cp_reginfo(arm_cpu
->cp_regs
, key
);
960 assert(!(ri
->type
& ARM_CP_NO_RAW
));
961 hvf_sreg_match
[i
].cp_idx
= sregs_cnt
;
962 arm_cpu
->cpreg_indexes
[sregs_cnt
++] = cpreg_to_kvm_id(key
);
964 hvf_sreg_match
[i
].cp_idx
= -1;
967 arm_cpu
->cpreg_array_len
= sregs_cnt
;
968 arm_cpu
->cpreg_vmstate_array_len
= sregs_cnt
;
970 assert(write_cpustate_to_list(arm_cpu
, false));
972 /* Set CP_NO_RAW system registers on init */
973 ret
= hv_vcpu_set_sys_reg(cpu
->accel
->fd
, HV_SYS_REG_MIDR_EL1
,
977 ret
= hv_vcpu_set_sys_reg(cpu
->accel
->fd
, HV_SYS_REG_MPIDR_EL1
,
978 arm_cpu
->mp_affinity
);
981 ret
= hv_vcpu_get_sys_reg(cpu
->accel
->fd
, HV_SYS_REG_ID_AA64PFR0_EL1
, &pfr
);
983 pfr
|= env
->gicv3state
? (1 << 24) : 0;
984 ret
= hv_vcpu_set_sys_reg(cpu
->accel
->fd
, HV_SYS_REG_ID_AA64PFR0_EL1
, pfr
);
987 /* We're limited to underlying hardware caps, override internal versions */
988 ret
= hv_vcpu_get_sys_reg(cpu
->accel
->fd
, HV_SYS_REG_ID_AA64MMFR0_EL1
,
989 &arm_cpu
->isar
.id_aa64mmfr0
);
995 void hvf_kick_vcpu_thread(CPUState
*cpu
)
997 cpus_kick_thread(cpu
);
998 hv_vcpus_exit(&cpu
->accel
->fd
, 1);
1001 static void hvf_raise_exception(CPUState
*cpu
, uint32_t excp
,
1004 ARMCPU
*arm_cpu
= ARM_CPU(cpu
);
1005 CPUARMState
*env
= &arm_cpu
->env
;
1007 cpu
->exception_index
= excp
;
1008 env
->exception
.target_el
= 1;
1009 env
->exception
.syndrome
= syndrome
;
1011 arm_cpu_do_interrupt(cpu
);
1014 static void hvf_psci_cpu_off(ARMCPU
*arm_cpu
)
1016 int32_t ret
= arm_set_cpu_off(arm_cpu
->mp_affinity
);
1017 assert(ret
== QEMU_ARM_POWERCTL_RET_SUCCESS
);
1021 * Handle a PSCI call.
1023 * Returns 0 on success
1024 * -1 when the PSCI call is unknown,
1026 static bool hvf_handle_psci_call(CPUState
*cpu
)
1028 ARMCPU
*arm_cpu
= ARM_CPU(cpu
);
1029 CPUARMState
*env
= &arm_cpu
->env
;
1030 uint64_t param
[4] = {
1036 uint64_t context_id
, mpidr
;
1037 bool target_aarch64
= true;
1038 CPUState
*target_cpu_state
;
1044 trace_hvf_psci_call(param
[0], param
[1], param
[2], param
[3],
1045 arm_cpu
->mp_affinity
);
1048 case QEMU_PSCI_0_2_FN_PSCI_VERSION
:
1049 ret
= QEMU_PSCI_VERSION_1_1
;
1051 case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE
:
1052 ret
= QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED
; /* No trusted OS */
1054 case QEMU_PSCI_0_2_FN_AFFINITY_INFO
:
1055 case QEMU_PSCI_0_2_FN64_AFFINITY_INFO
:
1060 target_cpu_state
= arm_get_cpu_by_id(mpidr
);
1061 if (!target_cpu_state
) {
1062 ret
= QEMU_PSCI_RET_INVALID_PARAMS
;
1065 target_cpu
= ARM_CPU(target_cpu_state
);
1067 ret
= target_cpu
->power_state
;
1070 /* Everything above affinity level 0 is always on. */
1074 case QEMU_PSCI_0_2_FN_SYSTEM_RESET
:
1075 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET
);
1077 * QEMU reset and shutdown are async requests, but PSCI
1078 * mandates that we never return from the reset/shutdown
1079 * call, so power the CPU off now so it doesn't execute
1082 hvf_psci_cpu_off(arm_cpu
);
1084 case QEMU_PSCI_0_2_FN_SYSTEM_OFF
:
1085 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN
);
1086 hvf_psci_cpu_off(arm_cpu
);
1088 case QEMU_PSCI_0_1_FN_CPU_ON
:
1089 case QEMU_PSCI_0_2_FN_CPU_ON
:
1090 case QEMU_PSCI_0_2_FN64_CPU_ON
:
1093 context_id
= param
[3];
1094 ret
= arm_set_cpu_on(mpidr
, entry
, context_id
,
1095 target_el
, target_aarch64
);
1097 case QEMU_PSCI_0_1_FN_CPU_OFF
:
1098 case QEMU_PSCI_0_2_FN_CPU_OFF
:
1099 hvf_psci_cpu_off(arm_cpu
);
1101 case QEMU_PSCI_0_1_FN_CPU_SUSPEND
:
1102 case QEMU_PSCI_0_2_FN_CPU_SUSPEND
:
1103 case QEMU_PSCI_0_2_FN64_CPU_SUSPEND
:
1104 /* Affinity levels are not supported in QEMU */
1105 if (param
[1] & 0xfffe0000) {
1106 ret
= QEMU_PSCI_RET_INVALID_PARAMS
;
1109 /* Powerdown is not supported, we always go into WFI */
1113 case QEMU_PSCI_0_1_FN_MIGRATE
:
1114 case QEMU_PSCI_0_2_FN_MIGRATE
:
1115 ret
= QEMU_PSCI_RET_NOT_SUPPORTED
;
1117 case QEMU_PSCI_1_0_FN_PSCI_FEATURES
:
1119 case QEMU_PSCI_0_2_FN_PSCI_VERSION
:
1120 case QEMU_PSCI_0_2_FN_MIGRATE_INFO_TYPE
:
1121 case QEMU_PSCI_0_2_FN_AFFINITY_INFO
:
1122 case QEMU_PSCI_0_2_FN64_AFFINITY_INFO
:
1123 case QEMU_PSCI_0_2_FN_SYSTEM_RESET
:
1124 case QEMU_PSCI_0_2_FN_SYSTEM_OFF
:
1125 case QEMU_PSCI_0_1_FN_CPU_ON
:
1126 case QEMU_PSCI_0_2_FN_CPU_ON
:
1127 case QEMU_PSCI_0_2_FN64_CPU_ON
:
1128 case QEMU_PSCI_0_1_FN_CPU_OFF
:
1129 case QEMU_PSCI_0_2_FN_CPU_OFF
:
1130 case QEMU_PSCI_0_1_FN_CPU_SUSPEND
:
1131 case QEMU_PSCI_0_2_FN_CPU_SUSPEND
:
1132 case QEMU_PSCI_0_2_FN64_CPU_SUSPEND
:
1133 case QEMU_PSCI_1_0_FN_PSCI_FEATURES
:
1136 case QEMU_PSCI_0_1_FN_MIGRATE
:
1137 case QEMU_PSCI_0_2_FN_MIGRATE
:
1139 ret
= QEMU_PSCI_RET_NOT_SUPPORTED
;
1146 env
->xregs
[0] = ret
;
1150 static bool is_id_sysreg(uint32_t reg
)
1152 return SYSREG_OP0(reg
) == 3 &&
1153 SYSREG_OP1(reg
) == 0 &&
1154 SYSREG_CRN(reg
) == 0 &&
1155 SYSREG_CRM(reg
) >= 1 &&
1156 SYSREG_CRM(reg
) < 8;
1159 static uint32_t hvf_reg2cp_reg(uint32_t reg
)
1161 return ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP
,
1162 (reg
>> SYSREG_CRN_SHIFT
) & SYSREG_CRN_MASK
,
1163 (reg
>> SYSREG_CRM_SHIFT
) & SYSREG_CRM_MASK
,
1164 (reg
>> SYSREG_OP0_SHIFT
) & SYSREG_OP0_MASK
,
1165 (reg
>> SYSREG_OP1_SHIFT
) & SYSREG_OP1_MASK
,
1166 (reg
>> SYSREG_OP2_SHIFT
) & SYSREG_OP2_MASK
);
1169 static bool hvf_sysreg_read_cp(CPUState
*cpu
, uint32_t reg
, uint64_t *val
)
1171 ARMCPU
*arm_cpu
= ARM_CPU(cpu
);
1172 CPUARMState
*env
= &arm_cpu
->env
;
1173 const ARMCPRegInfo
*ri
;
1175 ri
= get_arm_cp_reginfo(arm_cpu
->cp_regs
, hvf_reg2cp_reg(reg
));
1178 if (ri
->accessfn(env
, ri
, true) != CP_ACCESS_OK
) {
1182 if (ri
->type
& ARM_CP_CONST
) {
1183 *val
= ri
->resetvalue
;
1184 } else if (ri
->readfn
) {
1185 *val
= ri
->readfn(env
, ri
);
1187 *val
= CPREG_FIELD64(env
, ri
);
1189 trace_hvf_vgic_read(ri
->name
, *val
);
1196 static int hvf_sysreg_read(CPUState
*cpu
, uint32_t reg
, uint32_t rt
)
1198 ARMCPU
*arm_cpu
= ARM_CPU(cpu
);
1199 CPUARMState
*env
= &arm_cpu
->env
;
1203 case SYSREG_CNTPCT_EL0
:
1204 val
= qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL
) /
1205 gt_cntfrq_period_ns(arm_cpu
);
1207 case SYSREG_PMCR_EL0
:
1208 val
= env
->cp15
.c9_pmcr
;
1210 case SYSREG_PMCCNTR_EL0
:
1212 val
= env
->cp15
.c15_ccnt
;
1215 case SYSREG_PMCNTENCLR_EL0
:
1216 val
= env
->cp15
.c9_pmcnten
;
1218 case SYSREG_PMOVSCLR_EL0
:
1219 val
= env
->cp15
.c9_pmovsr
;
1221 case SYSREG_PMSELR_EL0
:
1222 val
= env
->cp15
.c9_pmselr
;
1224 case SYSREG_PMINTENCLR_EL1
:
1225 val
= env
->cp15
.c9_pminten
;
1227 case SYSREG_PMCCFILTR_EL0
:
1228 val
= env
->cp15
.pmccfiltr_el0
;
1230 case SYSREG_PMCNTENSET_EL0
:
1231 val
= env
->cp15
.c9_pmcnten
;
1233 case SYSREG_PMUSERENR_EL0
:
1234 val
= env
->cp15
.c9_pmuserenr
;
1236 case SYSREG_PMCEID0_EL0
:
1237 case SYSREG_PMCEID1_EL0
:
1238 /* We can't really count anything yet, declare all events invalid */
1241 case SYSREG_OSLSR_EL1
:
1242 val
= env
->cp15
.oslsr_el1
;
1244 case SYSREG_OSDLR_EL1
:
1245 /* Dummy register */
1247 case SYSREG_ICC_AP0R0_EL1
:
1248 case SYSREG_ICC_AP0R1_EL1
:
1249 case SYSREG_ICC_AP0R2_EL1
:
1250 case SYSREG_ICC_AP0R3_EL1
:
1251 case SYSREG_ICC_AP1R0_EL1
:
1252 case SYSREG_ICC_AP1R1_EL1
:
1253 case SYSREG_ICC_AP1R2_EL1
:
1254 case SYSREG_ICC_AP1R3_EL1
:
1255 case SYSREG_ICC_ASGI1R_EL1
:
1256 case SYSREG_ICC_BPR0_EL1
:
1257 case SYSREG_ICC_BPR1_EL1
:
1258 case SYSREG_ICC_DIR_EL1
:
1259 case SYSREG_ICC_EOIR0_EL1
:
1260 case SYSREG_ICC_EOIR1_EL1
:
1261 case SYSREG_ICC_HPPIR0_EL1
:
1262 case SYSREG_ICC_HPPIR1_EL1
:
1263 case SYSREG_ICC_IAR0_EL1
:
1264 case SYSREG_ICC_IAR1_EL1
:
1265 case SYSREG_ICC_IGRPEN0_EL1
:
1266 case SYSREG_ICC_IGRPEN1_EL1
:
1267 case SYSREG_ICC_PMR_EL1
:
1268 case SYSREG_ICC_SGI0R_EL1
:
1269 case SYSREG_ICC_SGI1R_EL1
:
1270 case SYSREG_ICC_SRE_EL1
:
1271 case SYSREG_ICC_CTLR_EL1
:
1272 /* Call the TCG sysreg handler. This is only safe for GICv3 regs. */
1273 if (!hvf_sysreg_read_cp(cpu
, reg
, &val
)) {
1274 hvf_raise_exception(cpu
, EXCP_UDEF
, syn_uncategorized());
1277 case SYSREG_DBGBVR0_EL1
:
1278 case SYSREG_DBGBVR1_EL1
:
1279 case SYSREG_DBGBVR2_EL1
:
1280 case SYSREG_DBGBVR3_EL1
:
1281 case SYSREG_DBGBVR4_EL1
:
1282 case SYSREG_DBGBVR5_EL1
:
1283 case SYSREG_DBGBVR6_EL1
:
1284 case SYSREG_DBGBVR7_EL1
:
1285 case SYSREG_DBGBVR8_EL1
:
1286 case SYSREG_DBGBVR9_EL1
:
1287 case SYSREG_DBGBVR10_EL1
:
1288 case SYSREG_DBGBVR11_EL1
:
1289 case SYSREG_DBGBVR12_EL1
:
1290 case SYSREG_DBGBVR13_EL1
:
1291 case SYSREG_DBGBVR14_EL1
:
1292 case SYSREG_DBGBVR15_EL1
:
1293 val
= env
->cp15
.dbgbvr
[SYSREG_CRM(reg
)];
1295 case SYSREG_DBGBCR0_EL1
:
1296 case SYSREG_DBGBCR1_EL1
:
1297 case SYSREG_DBGBCR2_EL1
:
1298 case SYSREG_DBGBCR3_EL1
:
1299 case SYSREG_DBGBCR4_EL1
:
1300 case SYSREG_DBGBCR5_EL1
:
1301 case SYSREG_DBGBCR6_EL1
:
1302 case SYSREG_DBGBCR7_EL1
:
1303 case SYSREG_DBGBCR8_EL1
:
1304 case SYSREG_DBGBCR9_EL1
:
1305 case SYSREG_DBGBCR10_EL1
:
1306 case SYSREG_DBGBCR11_EL1
:
1307 case SYSREG_DBGBCR12_EL1
:
1308 case SYSREG_DBGBCR13_EL1
:
1309 case SYSREG_DBGBCR14_EL1
:
1310 case SYSREG_DBGBCR15_EL1
:
1311 val
= env
->cp15
.dbgbcr
[SYSREG_CRM(reg
)];
1313 case SYSREG_DBGWVR0_EL1
:
1314 case SYSREG_DBGWVR1_EL1
:
1315 case SYSREG_DBGWVR2_EL1
:
1316 case SYSREG_DBGWVR3_EL1
:
1317 case SYSREG_DBGWVR4_EL1
:
1318 case SYSREG_DBGWVR5_EL1
:
1319 case SYSREG_DBGWVR6_EL1
:
1320 case SYSREG_DBGWVR7_EL1
:
1321 case SYSREG_DBGWVR8_EL1
:
1322 case SYSREG_DBGWVR9_EL1
:
1323 case SYSREG_DBGWVR10_EL1
:
1324 case SYSREG_DBGWVR11_EL1
:
1325 case SYSREG_DBGWVR12_EL1
:
1326 case SYSREG_DBGWVR13_EL1
:
1327 case SYSREG_DBGWVR14_EL1
:
1328 case SYSREG_DBGWVR15_EL1
:
1329 val
= env
->cp15
.dbgwvr
[SYSREG_CRM(reg
)];
1331 case SYSREG_DBGWCR0_EL1
:
1332 case SYSREG_DBGWCR1_EL1
:
1333 case SYSREG_DBGWCR2_EL1
:
1334 case SYSREG_DBGWCR3_EL1
:
1335 case SYSREG_DBGWCR4_EL1
:
1336 case SYSREG_DBGWCR5_EL1
:
1337 case SYSREG_DBGWCR6_EL1
:
1338 case SYSREG_DBGWCR7_EL1
:
1339 case SYSREG_DBGWCR8_EL1
:
1340 case SYSREG_DBGWCR9_EL1
:
1341 case SYSREG_DBGWCR10_EL1
:
1342 case SYSREG_DBGWCR11_EL1
:
1343 case SYSREG_DBGWCR12_EL1
:
1344 case SYSREG_DBGWCR13_EL1
:
1345 case SYSREG_DBGWCR14_EL1
:
1346 case SYSREG_DBGWCR15_EL1
:
1347 val
= env
->cp15
.dbgwcr
[SYSREG_CRM(reg
)];
1350 if (is_id_sysreg(reg
)) {
1351 /* ID system registers read as RES0 */
1355 cpu_synchronize_state(cpu
);
1356 trace_hvf_unhandled_sysreg_read(env
->pc
, reg
,
1362 hvf_raise_exception(cpu
, EXCP_UDEF
, syn_uncategorized());
1366 trace_hvf_sysreg_read(reg
,
1373 hvf_set_reg(cpu
, rt
, val
);
1378 static void pmu_update_irq(CPUARMState
*env
)
1380 ARMCPU
*cpu
= env_archcpu(env
);
1381 qemu_set_irq(cpu
->pmu_interrupt
, (env
->cp15
.c9_pmcr
& PMCRE
) &&
1382 (env
->cp15
.c9_pminten
& env
->cp15
.c9_pmovsr
));
1385 static bool pmu_event_supported(uint16_t number
)
1390 /* Returns true if the counter (pass 31 for PMCCNTR) should count events using
1391 * the current EL, security state, and register configuration.
1393 static bool pmu_counter_enabled(CPUARMState
*env
, uint8_t counter
)
1396 bool enabled
, filtered
= true;
1397 int el
= arm_current_el(env
);
1399 enabled
= (env
->cp15
.c9_pmcr
& PMCRE
) &&
1400 (env
->cp15
.c9_pmcnten
& (1 << counter
));
1402 if (counter
== 31) {
1403 filter
= env
->cp15
.pmccfiltr_el0
;
1405 filter
= env
->cp15
.c14_pmevtyper
[counter
];
1409 filtered
= filter
& PMXEVTYPER_U
;
1410 } else if (el
== 1) {
1411 filtered
= filter
& PMXEVTYPER_P
;
1414 if (counter
!= 31) {
1416 * If not checking PMCCNTR, ensure the counter is setup to an event we
1419 uint16_t event
= filter
& PMXEVTYPER_EVTCOUNT
;
1420 if (!pmu_event_supported(event
)) {
1425 return enabled
&& !filtered
;
1428 static void pmswinc_write(CPUARMState
*env
, uint64_t value
)
1431 for (i
= 0; i
< pmu_num_counters(env
); i
++) {
1432 /* Increment a counter's count iff: */
1433 if ((value
& (1 << i
)) && /* counter's bit is set */
1434 /* counter is enabled and not filtered */
1435 pmu_counter_enabled(env
, i
) &&
1436 /* counter is SW_INCR */
1437 (env
->cp15
.c14_pmevtyper
[i
] & PMXEVTYPER_EVTCOUNT
) == 0x0) {
1439 * Detect if this write causes an overflow since we can't predict
1440 * PMSWINC overflows like we can for other events
1442 uint32_t new_pmswinc
= env
->cp15
.c14_pmevcntr
[i
] + 1;
1444 if (env
->cp15
.c14_pmevcntr
[i
] & ~new_pmswinc
& INT32_MIN
) {
1445 env
->cp15
.c9_pmovsr
|= (1 << i
);
1446 pmu_update_irq(env
);
1449 env
->cp15
.c14_pmevcntr
[i
] = new_pmswinc
;
1454 static bool hvf_sysreg_write_cp(CPUState
*cpu
, uint32_t reg
, uint64_t val
)
1456 ARMCPU
*arm_cpu
= ARM_CPU(cpu
);
1457 CPUARMState
*env
= &arm_cpu
->env
;
1458 const ARMCPRegInfo
*ri
;
1460 ri
= get_arm_cp_reginfo(arm_cpu
->cp_regs
, hvf_reg2cp_reg(reg
));
1464 if (ri
->accessfn(env
, ri
, false) != CP_ACCESS_OK
) {
1469 ri
->writefn(env
, ri
, val
);
1471 CPREG_FIELD64(env
, ri
) = val
;
1474 trace_hvf_vgic_write(ri
->name
, val
);
1481 static int hvf_sysreg_write(CPUState
*cpu
, uint32_t reg
, uint64_t val
)
1483 ARMCPU
*arm_cpu
= ARM_CPU(cpu
);
1484 CPUARMState
*env
= &arm_cpu
->env
;
1486 trace_hvf_sysreg_write(reg
,
1495 case SYSREG_PMCCNTR_EL0
:
1497 env
->cp15
.c15_ccnt
= val
;
1500 case SYSREG_PMCR_EL0
:
1504 /* The counter has been reset */
1505 env
->cp15
.c15_ccnt
= 0;
1510 for (i
= 0; i
< pmu_num_counters(env
); i
++) {
1511 env
->cp15
.c14_pmevcntr
[i
] = 0;
1515 env
->cp15
.c9_pmcr
&= ~PMCR_WRITABLE_MASK
;
1516 env
->cp15
.c9_pmcr
|= (val
& PMCR_WRITABLE_MASK
);
1520 case SYSREG_PMUSERENR_EL0
:
1521 env
->cp15
.c9_pmuserenr
= val
& 0xf;
1523 case SYSREG_PMCNTENSET_EL0
:
1524 env
->cp15
.c9_pmcnten
|= (val
& pmu_counter_mask(env
));
1526 case SYSREG_PMCNTENCLR_EL0
:
1527 env
->cp15
.c9_pmcnten
&= ~(val
& pmu_counter_mask(env
));
1529 case SYSREG_PMINTENCLR_EL1
:
1531 env
->cp15
.c9_pminten
|= val
;
1534 case SYSREG_PMOVSCLR_EL0
:
1536 env
->cp15
.c9_pmovsr
&= ~val
;
1539 case SYSREG_PMSWINC_EL0
:
1541 pmswinc_write(env
, val
);
1544 case SYSREG_PMSELR_EL0
:
1545 env
->cp15
.c9_pmselr
= val
& 0x1f;
1547 case SYSREG_PMCCFILTR_EL0
:
1549 env
->cp15
.pmccfiltr_el0
= val
& PMCCFILTR_EL0
;
1552 case SYSREG_OSLAR_EL1
:
1553 env
->cp15
.oslsr_el1
= val
& 1;
1555 case SYSREG_OSDLR_EL1
:
1556 /* Dummy register */
1558 case SYSREG_ICC_AP0R0_EL1
:
1559 case SYSREG_ICC_AP0R1_EL1
:
1560 case SYSREG_ICC_AP0R2_EL1
:
1561 case SYSREG_ICC_AP0R3_EL1
:
1562 case SYSREG_ICC_AP1R0_EL1
:
1563 case SYSREG_ICC_AP1R1_EL1
:
1564 case SYSREG_ICC_AP1R2_EL1
:
1565 case SYSREG_ICC_AP1R3_EL1
:
1566 case SYSREG_ICC_ASGI1R_EL1
:
1567 case SYSREG_ICC_BPR0_EL1
:
1568 case SYSREG_ICC_BPR1_EL1
:
1569 case SYSREG_ICC_CTLR_EL1
:
1570 case SYSREG_ICC_DIR_EL1
:
1571 case SYSREG_ICC_EOIR0_EL1
:
1572 case SYSREG_ICC_EOIR1_EL1
:
1573 case SYSREG_ICC_HPPIR0_EL1
:
1574 case SYSREG_ICC_HPPIR1_EL1
:
1575 case SYSREG_ICC_IAR0_EL1
:
1576 case SYSREG_ICC_IAR1_EL1
:
1577 case SYSREG_ICC_IGRPEN0_EL1
:
1578 case SYSREG_ICC_IGRPEN1_EL1
:
1579 case SYSREG_ICC_PMR_EL1
:
1580 case SYSREG_ICC_SGI0R_EL1
:
1581 case SYSREG_ICC_SGI1R_EL1
:
1582 case SYSREG_ICC_SRE_EL1
:
1583 /* Call the TCG sysreg handler. This is only safe for GICv3 regs. */
1584 if (!hvf_sysreg_write_cp(cpu
, reg
, val
)) {
1585 hvf_raise_exception(cpu
, EXCP_UDEF
, syn_uncategorized());
1588 case SYSREG_MDSCR_EL1
:
1589 env
->cp15
.mdscr_el1
= val
;
1591 case SYSREG_DBGBVR0_EL1
:
1592 case SYSREG_DBGBVR1_EL1
:
1593 case SYSREG_DBGBVR2_EL1
:
1594 case SYSREG_DBGBVR3_EL1
:
1595 case SYSREG_DBGBVR4_EL1
:
1596 case SYSREG_DBGBVR5_EL1
:
1597 case SYSREG_DBGBVR6_EL1
:
1598 case SYSREG_DBGBVR7_EL1
:
1599 case SYSREG_DBGBVR8_EL1
:
1600 case SYSREG_DBGBVR9_EL1
:
1601 case SYSREG_DBGBVR10_EL1
:
1602 case SYSREG_DBGBVR11_EL1
:
1603 case SYSREG_DBGBVR12_EL1
:
1604 case SYSREG_DBGBVR13_EL1
:
1605 case SYSREG_DBGBVR14_EL1
:
1606 case SYSREG_DBGBVR15_EL1
:
1607 env
->cp15
.dbgbvr
[SYSREG_CRM(reg
)] = val
;
1609 case SYSREG_DBGBCR0_EL1
:
1610 case SYSREG_DBGBCR1_EL1
:
1611 case SYSREG_DBGBCR2_EL1
:
1612 case SYSREG_DBGBCR3_EL1
:
1613 case SYSREG_DBGBCR4_EL1
:
1614 case SYSREG_DBGBCR5_EL1
:
1615 case SYSREG_DBGBCR6_EL1
:
1616 case SYSREG_DBGBCR7_EL1
:
1617 case SYSREG_DBGBCR8_EL1
:
1618 case SYSREG_DBGBCR9_EL1
:
1619 case SYSREG_DBGBCR10_EL1
:
1620 case SYSREG_DBGBCR11_EL1
:
1621 case SYSREG_DBGBCR12_EL1
:
1622 case SYSREG_DBGBCR13_EL1
:
1623 case SYSREG_DBGBCR14_EL1
:
1624 case SYSREG_DBGBCR15_EL1
:
1625 env
->cp15
.dbgbcr
[SYSREG_CRM(reg
)] = val
;
1627 case SYSREG_DBGWVR0_EL1
:
1628 case SYSREG_DBGWVR1_EL1
:
1629 case SYSREG_DBGWVR2_EL1
:
1630 case SYSREG_DBGWVR3_EL1
:
1631 case SYSREG_DBGWVR4_EL1
:
1632 case SYSREG_DBGWVR5_EL1
:
1633 case SYSREG_DBGWVR6_EL1
:
1634 case SYSREG_DBGWVR7_EL1
:
1635 case SYSREG_DBGWVR8_EL1
:
1636 case SYSREG_DBGWVR9_EL1
:
1637 case SYSREG_DBGWVR10_EL1
:
1638 case SYSREG_DBGWVR11_EL1
:
1639 case SYSREG_DBGWVR12_EL1
:
1640 case SYSREG_DBGWVR13_EL1
:
1641 case SYSREG_DBGWVR14_EL1
:
1642 case SYSREG_DBGWVR15_EL1
:
1643 env
->cp15
.dbgwvr
[SYSREG_CRM(reg
)] = val
;
1645 case SYSREG_DBGWCR0_EL1
:
1646 case SYSREG_DBGWCR1_EL1
:
1647 case SYSREG_DBGWCR2_EL1
:
1648 case SYSREG_DBGWCR3_EL1
:
1649 case SYSREG_DBGWCR4_EL1
:
1650 case SYSREG_DBGWCR5_EL1
:
1651 case SYSREG_DBGWCR6_EL1
:
1652 case SYSREG_DBGWCR7_EL1
:
1653 case SYSREG_DBGWCR8_EL1
:
1654 case SYSREG_DBGWCR9_EL1
:
1655 case SYSREG_DBGWCR10_EL1
:
1656 case SYSREG_DBGWCR11_EL1
:
1657 case SYSREG_DBGWCR12_EL1
:
1658 case SYSREG_DBGWCR13_EL1
:
1659 case SYSREG_DBGWCR14_EL1
:
1660 case SYSREG_DBGWCR15_EL1
:
1661 env
->cp15
.dbgwcr
[SYSREG_CRM(reg
)] = val
;
1664 cpu_synchronize_state(cpu
);
1665 trace_hvf_unhandled_sysreg_write(env
->pc
, reg
,
1671 hvf_raise_exception(cpu
, EXCP_UDEF
, syn_uncategorized());
1678 static int hvf_inject_interrupts(CPUState
*cpu
)
1680 if (cpu
->interrupt_request
& CPU_INTERRUPT_FIQ
) {
1681 trace_hvf_inject_fiq();
1682 hv_vcpu_set_pending_interrupt(cpu
->accel
->fd
, HV_INTERRUPT_TYPE_FIQ
,
1686 if (cpu
->interrupt_request
& CPU_INTERRUPT_HARD
) {
1687 trace_hvf_inject_irq();
1688 hv_vcpu_set_pending_interrupt(cpu
->accel
->fd
, HV_INTERRUPT_TYPE_IRQ
,
1695 static uint64_t hvf_vtimer_val_raw(void)
1698 * mach_absolute_time() returns the vtimer value without the VM
1699 * offset that we define. Add our own offset on top.
1701 return mach_absolute_time() - hvf_state
->vtimer_offset
;
1704 static uint64_t hvf_vtimer_val(void)
1706 if (!runstate_is_running()) {
1707 /* VM is paused, the vtimer value is in vtimer.vtimer_val */
1708 return vtimer
.vtimer_val
;
1711 return hvf_vtimer_val_raw();
1714 static void hvf_wait_for_ipi(CPUState
*cpu
, struct timespec
*ts
)
1717 * Use pselect to sleep so that other threads can IPI us while we're
1720 qatomic_set_mb(&cpu
->thread_kicked
, false);
1721 qemu_mutex_unlock_iothread();
1722 pselect(0, 0, 0, 0, ts
, &cpu
->accel
->unblock_ipi_mask
);
1723 qemu_mutex_lock_iothread();
1726 static void hvf_wfi(CPUState
*cpu
)
1728 ARMCPU
*arm_cpu
= ARM_CPU(cpu
);
1733 int64_t ticks_to_sleep
;
1738 if (cpu
->interrupt_request
& (CPU_INTERRUPT_HARD
| CPU_INTERRUPT_FIQ
)) {
1739 /* Interrupt pending, no need to wait */
1743 r
= hv_vcpu_get_sys_reg(cpu
->accel
->fd
, HV_SYS_REG_CNTV_CTL_EL0
, &ctl
);
1746 if (!(ctl
& 1) || (ctl
& 2)) {
1747 /* Timer disabled or masked, just wait for an IPI. */
1748 hvf_wait_for_ipi(cpu
, NULL
);
1752 r
= hv_vcpu_get_sys_reg(cpu
->accel
->fd
, HV_SYS_REG_CNTV_CVAL_EL0
, &cval
);
1755 ticks_to_sleep
= cval
- hvf_vtimer_val();
1756 if (ticks_to_sleep
< 0) {
1760 cntfrq
= gt_cntfrq_period_ns(arm_cpu
);
1761 seconds
= muldiv64(ticks_to_sleep
, cntfrq
, NANOSECONDS_PER_SECOND
);
1762 ticks_to_sleep
-= muldiv64(seconds
, NANOSECONDS_PER_SECOND
, cntfrq
);
1763 nanos
= ticks_to_sleep
* cntfrq
;
1766 * Don't sleep for less than the time a context switch would take,
1767 * so that we can satisfy fast timer requests on the same CPU.
1768 * Measurements on M1 show the sweet spot to be ~2ms.
1770 if (!seconds
&& nanos
< (2 * SCALE_MS
)) {
1774 ts
= (struct timespec
) { seconds
, nanos
};
1775 hvf_wait_for_ipi(cpu
, &ts
);
1778 static void hvf_sync_vtimer(CPUState
*cpu
)
1780 ARMCPU
*arm_cpu
= ARM_CPU(cpu
);
1785 if (!cpu
->accel
->vtimer_masked
) {
1786 /* We will get notified on vtimer changes by hvf, nothing to do */
1790 r
= hv_vcpu_get_sys_reg(cpu
->accel
->fd
, HV_SYS_REG_CNTV_CTL_EL0
, &ctl
);
1793 irq_state
= (ctl
& (TMR_CTL_ENABLE
| TMR_CTL_IMASK
| TMR_CTL_ISTATUS
)) ==
1794 (TMR_CTL_ENABLE
| TMR_CTL_ISTATUS
);
1795 qemu_set_irq(arm_cpu
->gt_timer_outputs
[GTIMER_VIRT
], irq_state
);
1798 /* Timer no longer asserting, we can unmask it */
1799 hv_vcpu_set_vtimer_mask(cpu
->accel
->fd
, false);
1800 cpu
->accel
->vtimer_masked
= false;
1804 int hvf_vcpu_exec(CPUState
*cpu
)
1806 ARMCPU
*arm_cpu
= ARM_CPU(cpu
);
1807 CPUARMState
*env
= &arm_cpu
->env
;
1809 hv_vcpu_exit_t
*hvf_exit
= cpu
->accel
->exit
;
1811 bool advance_pc
= false;
1813 if (!(cpu
->singlestep_enabled
& SSTEP_NOIRQ
) &&
1814 hvf_inject_interrupts(cpu
)) {
1815 return EXCP_INTERRUPT
;
1822 flush_cpu_state(cpu
);
1824 qemu_mutex_unlock_iothread();
1825 assert_hvf_ok(hv_vcpu_run(cpu
->accel
->fd
));
1828 uint64_t exit_reason
= hvf_exit
->reason
;
1829 uint64_t syndrome
= hvf_exit
->exception
.syndrome
;
1830 uint32_t ec
= syn_get_ec(syndrome
);
1833 qemu_mutex_lock_iothread();
1834 switch (exit_reason
) {
1835 case HV_EXIT_REASON_EXCEPTION
:
1836 /* This is the main one, handle below. */
1838 case HV_EXIT_REASON_VTIMER_ACTIVATED
:
1839 qemu_set_irq(arm_cpu
->gt_timer_outputs
[GTIMER_VIRT
], 1);
1840 cpu
->accel
->vtimer_masked
= true;
1842 case HV_EXIT_REASON_CANCELED
:
1843 /* we got kicked, no exit to process */
1846 g_assert_not_reached();
1849 hvf_sync_vtimer(cpu
);
1852 case EC_SOFTWARESTEP
: {
1855 if (!cpu
->singlestep_enabled
) {
1856 error_report("EC_SOFTWARESTEP but single-stepping not enabled");
1860 case EC_AA64_BKPT
: {
1863 cpu_synchronize_state(cpu
);
1865 if (!hvf_find_sw_breakpoint(cpu
, env
->pc
)) {
1866 /* Re-inject into the guest */
1868 hvf_raise_exception(cpu
, EXCP_BKPT
, syn_aa64_bkpt(0));
1872 case EC_BREAKPOINT
: {
1875 cpu_synchronize_state(cpu
);
1877 if (!find_hw_breakpoint(cpu
, env
->pc
)) {
1878 error_report("EC_BREAKPOINT but unknown hw breakpoint");
1882 case EC_WATCHPOINT
: {
1885 cpu_synchronize_state(cpu
);
1888 find_hw_watchpoint(cpu
, hvf_exit
->exception
.virtual_address
);
1890 error_report("EXCP_DEBUG but unknown hw watchpoint");
1892 cpu
->watchpoint_hit
= wp
;
1895 case EC_DATAABORT
: {
1896 bool isv
= syndrome
& ARM_EL_ISV
;
1897 bool iswrite
= (syndrome
>> 6) & 1;
1898 bool s1ptw
= (syndrome
>> 7) & 1;
1899 uint32_t sas
= (syndrome
>> 22) & 3;
1900 uint32_t len
= 1 << sas
;
1901 uint32_t srt
= (syndrome
>> 16) & 0x1f;
1902 uint32_t cm
= (syndrome
>> 8) & 0x1;
1905 trace_hvf_data_abort(env
->pc
, hvf_exit
->exception
.virtual_address
,
1906 hvf_exit
->exception
.physical_address
, isv
,
1907 iswrite
, s1ptw
, len
, srt
);
1910 /* We don't cache MMIO regions */
1918 val
= hvf_get_reg(cpu
, srt
);
1919 address_space_write(&address_space_memory
,
1920 hvf_exit
->exception
.physical_address
,
1921 MEMTXATTRS_UNSPECIFIED
, &val
, len
);
1923 address_space_read(&address_space_memory
,
1924 hvf_exit
->exception
.physical_address
,
1925 MEMTXATTRS_UNSPECIFIED
, &val
, len
);
1926 hvf_set_reg(cpu
, srt
, val
);
1932 case EC_SYSTEMREGISTERTRAP
: {
1933 bool isread
= (syndrome
>> 0) & 1;
1934 uint32_t rt
= (syndrome
>> 5) & 0x1f;
1935 uint32_t reg
= syndrome
& SYSREG_MASK
;
1940 sysreg_ret
= hvf_sysreg_read(cpu
, reg
, rt
);
1942 val
= hvf_get_reg(cpu
, rt
);
1943 sysreg_ret
= hvf_sysreg_write(cpu
, reg
, val
);
1946 advance_pc
= !sysreg_ret
;
1951 if (!(syndrome
& WFX_IS_WFE
)) {
1956 cpu_synchronize_state(cpu
);
1957 if (arm_cpu
->psci_conduit
== QEMU_PSCI_CONDUIT_HVC
) {
1958 if (!hvf_handle_psci_call(cpu
)) {
1959 trace_hvf_unknown_hvc(env
->xregs
[0]);
1960 /* SMCCC 1.3 section 5.2 says every unknown SMCCC call returns -1 */
1964 trace_hvf_unknown_hvc(env
->xregs
[0]);
1965 hvf_raise_exception(cpu
, EXCP_UDEF
, syn_uncategorized());
1969 cpu_synchronize_state(cpu
);
1970 if (arm_cpu
->psci_conduit
== QEMU_PSCI_CONDUIT_SMC
) {
1973 if (!hvf_handle_psci_call(cpu
)) {
1974 trace_hvf_unknown_smc(env
->xregs
[0]);
1975 /* SMCCC 1.3 section 5.2 says every unknown SMCCC call returns -1 */
1979 trace_hvf_unknown_smc(env
->xregs
[0]);
1980 hvf_raise_exception(cpu
, EXCP_UDEF
, syn_uncategorized());
1984 cpu_synchronize_state(cpu
);
1985 trace_hvf_exit(syndrome
, ec
, env
->pc
);
1986 error_report("0x%llx: unhandled exception ec=0x%x", env
->pc
, ec
);
1992 flush_cpu_state(cpu
);
1994 r
= hv_vcpu_get_reg(cpu
->accel
->fd
, HV_REG_PC
, &pc
);
1997 r
= hv_vcpu_set_reg(cpu
->accel
->fd
, HV_REG_PC
, pc
);
2000 /* Handle single-stepping over instructions which trigger a VM exit */
2001 if (cpu
->singlestep_enabled
) {
2009 static const VMStateDescription vmstate_hvf_vtimer
= {
2010 .name
= "hvf-vtimer",
2012 .minimum_version_id
= 1,
2013 .fields
= (VMStateField
[]) {
2014 VMSTATE_UINT64(vtimer_val
, HVFVTimer
),
2015 VMSTATE_END_OF_LIST()
2019 static void hvf_vm_state_change(void *opaque
, bool running
, RunState state
)
2021 HVFVTimer
*s
= opaque
;
2024 /* Update vtimer offset on all CPUs */
2025 hvf_state
->vtimer_offset
= mach_absolute_time() - s
->vtimer_val
;
2026 cpu_synchronize_all_states();
2028 /* Remember vtimer value on every pause */
2029 s
->vtimer_val
= hvf_vtimer_val_raw();
2033 int hvf_arch_init(void)
2035 hvf_state
->vtimer_offset
= mach_absolute_time();
2036 vmstate_register(NULL
, 0, &vmstate_hvf_vtimer
, &vtimer
);
2037 qemu_add_vm_change_state_handler(hvf_vm_state_change
, &vtimer
);
2039 hvf_arm_init_debug();
2044 static const uint32_t brk_insn
= 0xd4200000;
2046 int hvf_arch_insert_sw_breakpoint(CPUState
*cpu
, struct hvf_sw_breakpoint
*bp
)
2048 if (cpu_memory_rw_debug(cpu
, bp
->pc
, (uint8_t *)&bp
->saved_insn
, 4, 0) ||
2049 cpu_memory_rw_debug(cpu
, bp
->pc
, (uint8_t *)&brk_insn
, 4, 1)) {
2055 int hvf_arch_remove_sw_breakpoint(CPUState
*cpu
, struct hvf_sw_breakpoint
*bp
)
2057 static uint32_t brk
;
2059 if (cpu_memory_rw_debug(cpu
, bp
->pc
, (uint8_t *)&brk
, 4, 0) ||
2061 cpu_memory_rw_debug(cpu
, bp
->pc
, (uint8_t *)&bp
->saved_insn
, 4, 1)) {
2067 int hvf_arch_insert_hw_breakpoint(vaddr addr
, vaddr len
, int type
)
2070 case GDB_BREAKPOINT_HW
:
2071 return insert_hw_breakpoint(addr
);
2072 case GDB_WATCHPOINT_READ
:
2073 case GDB_WATCHPOINT_WRITE
:
2074 case GDB_WATCHPOINT_ACCESS
:
2075 return insert_hw_watchpoint(addr
, len
, type
);
2081 int hvf_arch_remove_hw_breakpoint(vaddr addr
, vaddr len
, int type
)
2084 case GDB_BREAKPOINT_HW
:
2085 return delete_hw_breakpoint(addr
);
2086 case GDB_WATCHPOINT_READ
:
2087 case GDB_WATCHPOINT_WRITE
:
2088 case GDB_WATCHPOINT_ACCESS
:
2089 return delete_hw_watchpoint(addr
, len
, type
);
2095 void hvf_arch_remove_all_hw_breakpoints(void)
2097 if (cur_hw_wps
> 0) {
2098 g_array_remove_range(hw_watchpoints
, 0, cur_hw_wps
);
2100 if (cur_hw_bps
> 0) {
2101 g_array_remove_range(hw_breakpoints
, 0, cur_hw_bps
);
2106 * Update the vCPU with the gdbstub's view of debug registers. This view
2107 * consists of all hardware breakpoints and watchpoints inserted so far while
2108 * debugging the guest.
2110 static void hvf_put_gdbstub_debug_registers(CPUState
*cpu
)
2112 hv_return_t r
= HV_SUCCESS
;
2115 for (i
= 0; i
< cur_hw_bps
; i
++) {
2116 HWBreakpoint
*bp
= get_hw_bp(i
);
2117 r
= hv_vcpu_set_sys_reg(cpu
->accel
->fd
, dbgbcr_regs
[i
], bp
->bcr
);
2119 r
= hv_vcpu_set_sys_reg(cpu
->accel
->fd
, dbgbvr_regs
[i
], bp
->bvr
);
2122 for (i
= cur_hw_bps
; i
< max_hw_bps
; i
++) {
2123 r
= hv_vcpu_set_sys_reg(cpu
->accel
->fd
, dbgbcr_regs
[i
], 0);
2125 r
= hv_vcpu_set_sys_reg(cpu
->accel
->fd
, dbgbvr_regs
[i
], 0);
2129 for (i
= 0; i
< cur_hw_wps
; i
++) {
2130 HWWatchpoint
*wp
= get_hw_wp(i
);
2131 r
= hv_vcpu_set_sys_reg(cpu
->accel
->fd
, dbgwcr_regs
[i
], wp
->wcr
);
2133 r
= hv_vcpu_set_sys_reg(cpu
->accel
->fd
, dbgwvr_regs
[i
], wp
->wvr
);
2136 for (i
= cur_hw_wps
; i
< max_hw_wps
; i
++) {
2137 r
= hv_vcpu_set_sys_reg(cpu
->accel
->fd
, dbgwcr_regs
[i
], 0);
2139 r
= hv_vcpu_set_sys_reg(cpu
->accel
->fd
, dbgwvr_regs
[i
], 0);
2145 * Update the vCPU with the guest's view of debug registers. This view is kept
2146 * in the environment at all times.
2148 static void hvf_put_guest_debug_registers(CPUState
*cpu
)
2150 ARMCPU
*arm_cpu
= ARM_CPU(cpu
);
2151 CPUARMState
*env
= &arm_cpu
->env
;
2152 hv_return_t r
= HV_SUCCESS
;
2155 for (i
= 0; i
< max_hw_bps
; i
++) {
2156 r
= hv_vcpu_set_sys_reg(cpu
->accel
->fd
, dbgbcr_regs
[i
],
2157 env
->cp15
.dbgbcr
[i
]);
2159 r
= hv_vcpu_set_sys_reg(cpu
->accel
->fd
, dbgbvr_regs
[i
],
2160 env
->cp15
.dbgbvr
[i
]);
2164 for (i
= 0; i
< max_hw_wps
; i
++) {
2165 r
= hv_vcpu_set_sys_reg(cpu
->accel
->fd
, dbgwcr_regs
[i
],
2166 env
->cp15
.dbgwcr
[i
]);
2168 r
= hv_vcpu_set_sys_reg(cpu
->accel
->fd
, dbgwvr_regs
[i
],
2169 env
->cp15
.dbgwvr
[i
]);
2174 static inline bool hvf_arm_hw_debug_active(CPUState
*cpu
)
2176 return ((cur_hw_wps
> 0) || (cur_hw_bps
> 0));
2179 static void hvf_arch_set_traps(void)
2182 bool should_enable_traps
= false;
2183 hv_return_t r
= HV_SUCCESS
;
2185 /* Check whether guest debugging is enabled for at least one vCPU; if it
2186 * is, enable exiting the guest on all vCPUs */
2188 should_enable_traps
|= cpu
->accel
->guest_debug_enabled
;
2191 /* Set whether debug exceptions exit the guest */
2192 r
= hv_vcpu_set_trap_debug_exceptions(cpu
->accel
->fd
,
2193 should_enable_traps
);
2196 /* Set whether accesses to debug registers exit the guest */
2197 r
= hv_vcpu_set_trap_debug_reg_accesses(cpu
->accel
->fd
,
2198 should_enable_traps
);
2203 void hvf_arch_update_guest_debug(CPUState
*cpu
)
2205 ARMCPU
*arm_cpu
= ARM_CPU(cpu
);
2206 CPUARMState
*env
= &arm_cpu
->env
;
2208 /* Check whether guest debugging is enabled */
2209 cpu
->accel
->guest_debug_enabled
= cpu
->singlestep_enabled
||
2210 hvf_sw_breakpoints_active(cpu
) ||
2211 hvf_arm_hw_debug_active(cpu
);
2213 /* Update debug registers */
2214 if (cpu
->accel
->guest_debug_enabled
) {
2215 hvf_put_gdbstub_debug_registers(cpu
);
2217 hvf_put_guest_debug_registers(cpu
);
2220 cpu_synchronize_state(cpu
);
2222 /* Enable/disable single-stepping */
2223 if (cpu
->singlestep_enabled
) {
2224 env
->cp15
.mdscr_el1
=
2225 deposit64(env
->cp15
.mdscr_el1
, MDSCR_EL1_SS_SHIFT
, 1, 1);
2226 pstate_write(env
, pstate_read(env
) | PSTATE_SS
);
2228 env
->cp15
.mdscr_el1
=
2229 deposit64(env
->cp15
.mdscr_el1
, MDSCR_EL1_SS_SHIFT
, 1, 0);
2232 /* Enable/disable Breakpoint exceptions */
2233 if (hvf_arm_hw_debug_active(cpu
)) {
2234 env
->cp15
.mdscr_el1
=
2235 deposit64(env
->cp15
.mdscr_el1
, MDSCR_EL1_MDE_SHIFT
, 1, 1);
2237 env
->cp15
.mdscr_el1
=
2238 deposit64(env
->cp15
.mdscr_el1
, MDSCR_EL1_MDE_SHIFT
, 1, 0);
2241 hvf_arch_set_traps();
2244 inline bool hvf_arch_supports_guest_debug(void)