1use crate::aarch64::Aarch64PartitionCapabilities;
5use crate::state::HvRegisterState;
6use crate::state::StateElement;
7use crate::state::state_trait;
8use aarch64defs::Cpsr64;
9use aarch64defs::SctlrEl1;
10use hvdef::HvArm64RegisterName;
11use hvdef::HvRegisterValue;
12use inspect::Inspect;
13use mesh_protobuf::Protobuf;
14use vm_topology::processor::aarch64::Aarch64VpInfo;
15
16#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Protobuf, Inspect)]
17#[mesh(package = "virt.aarch64")]
18pub struct Registers {
19 #[inspect(hex)]
20 #[mesh(1)]
21 pub x0: u64,
22 #[inspect(hex)]
23 #[mesh(2)]
24 pub x1: u64,
25 #[inspect(hex)]
26 #[mesh(3)]
27 pub x2: u64,
28 #[inspect(hex)]
29 #[mesh(4)]
30 pub x3: u64,
31 #[inspect(hex)]
32 #[mesh(5)]
33 pub x4: u64,
34 #[inspect(hex)]
35 #[mesh(6)]
36 pub x5: u64,
37 #[inspect(hex)]
38 #[mesh(7)]
39 pub x6: u64,
40 #[inspect(hex)]
41 #[mesh(8)]
42 pub x7: u64,
43 #[inspect(hex)]
44 #[mesh(9)]
45 pub x8: u64,
46 #[inspect(hex)]
47 #[mesh(10)]
48 pub x9: u64,
49 #[inspect(hex)]
50 #[mesh(11)]
51 pub x10: u64,
52 #[inspect(hex)]
53 #[mesh(12)]
54 pub x11: u64,
55 #[inspect(hex)]
56 #[mesh(13)]
57 pub x12: u64,
58 #[inspect(hex)]
59 #[mesh(14)]
60 pub x13: u64,
61 #[inspect(hex)]
62 #[mesh(15)]
63 pub x14: u64,
64 #[inspect(hex)]
65 #[mesh(16)]
66 pub x15: u64,
67 #[inspect(hex)]
68 #[mesh(17)]
69 pub x16: u64,
70 #[inspect(hex)]
71 #[mesh(18)]
72 pub x17: u64,
73 #[inspect(hex)]
74 #[mesh(19)]
75 pub x18: u64,
76 #[inspect(hex)]
77 #[mesh(20)]
78 pub x19: u64,
79 #[inspect(hex)]
80 #[mesh(21)]
81 pub x20: u64,
82 #[inspect(hex)]
83 #[mesh(22)]
84 pub x21: u64,
85 #[inspect(hex)]
86 #[mesh(23)]
87 pub x22: u64,
88 #[inspect(hex)]
89 #[mesh(24)]
90 pub x23: u64,
91 #[inspect(hex)]
92 #[mesh(25)]
93 pub x24: u64,
94 #[inspect(hex)]
95 #[mesh(26)]
96 pub x25: u64,
97 #[inspect(hex)]
98 #[mesh(27)]
99 pub x26: u64,
100 #[inspect(hex)]
101 #[mesh(28)]
102 pub x27: u64,
103 #[inspect(hex)]
104 #[mesh(29)]
105 pub x28: u64,
106 #[inspect(hex)]
107 #[mesh(30)]
108 pub fp: u64,
109 #[inspect(hex)]
110 #[mesh(31)]
111 pub lr: u64,
112 #[inspect(hex)]
113 #[mesh(32)]
114 pub sp_el0: u64,
115 #[inspect(hex)]
116 #[mesh(33)]
117 pub sp_el1: u64,
118 #[inspect(hex)]
119 #[mesh(34)]
120 pub pc: u64,
121 #[inspect(hex)]
122 #[mesh(35)]
123 pub cpsr: u64,
124}
125
126impl HvRegisterState<HvArm64RegisterName, 35> for Registers {
127 fn names(&self) -> &'static [HvArm64RegisterName; 35] {
128 &[
129 HvArm64RegisterName::X0,
130 HvArm64RegisterName::X1,
131 HvArm64RegisterName::X2,
132 HvArm64RegisterName::X3,
133 HvArm64RegisterName::X4,
134 HvArm64RegisterName::X5,
135 HvArm64RegisterName::X6,
136 HvArm64RegisterName::X7,
137 HvArm64RegisterName::X8,
138 HvArm64RegisterName::X9,
139 HvArm64RegisterName::X10,
140 HvArm64RegisterName::X11,
141 HvArm64RegisterName::X12,
142 HvArm64RegisterName::X13,
143 HvArm64RegisterName::X14,
144 HvArm64RegisterName::X15,
145 HvArm64RegisterName::X16,
146 HvArm64RegisterName::X17,
147 HvArm64RegisterName::X18,
148 HvArm64RegisterName::X19,
149 HvArm64RegisterName::X20,
150 HvArm64RegisterName::X21,
151 HvArm64RegisterName::X22,
152 HvArm64RegisterName::X23,
153 HvArm64RegisterName::X24,
154 HvArm64RegisterName::X25,
155 HvArm64RegisterName::X26,
156 HvArm64RegisterName::X27,
157 HvArm64RegisterName::X28,
158 HvArm64RegisterName::XFp,
159 HvArm64RegisterName::XLr,
160 HvArm64RegisterName::XSpEl0,
161 HvArm64RegisterName::XSpElx,
162 HvArm64RegisterName::XPc,
163 HvArm64RegisterName::Cpsr,
164 ]
165 }
166
167 fn get_values<'a>(&self, it: impl Iterator<Item = &'a mut HvRegisterValue>) {
168 let &Self {
169 x0,
170 x1,
171 x2,
172 x3,
173 x4,
174 x5,
175 x6,
176 x7,
177 x8,
178 x9,
179 x10,
180 x11,
181 x12,
182 x13,
183 x14,
184 x15,
185 x16,
186 x17,
187 x18,
188 x19,
189 x20,
190 x21,
191 x22,
192 x23,
193 x24,
194 x25,
195 x26,
196 x27,
197 x28,
198 fp,
199 lr,
200 sp_el0,
201 sp_el1,
202 pc,
203 cpsr,
204 } = self;
205 for (dest, src) in it.zip([
206 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18,
207 x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, fp, lr, sp_el0, sp_el1, pc, cpsr,
208 ]) {
209 *dest = src.into()
210 }
211 }
212
213 fn set_values(&mut self, mut it: impl Iterator<Item = HvRegisterValue>) {
214 let Self {
215 x0,
216 x1,
217 x2,
218 x3,
219 x4,
220 x5,
221 x6,
222 x7,
223 x8,
224 x9,
225 x10,
226 x11,
227 x12,
228 x13,
229 x14,
230 x15,
231 x16,
232 x17,
233 x18,
234 x19,
235 x20,
236 x21,
237 x22,
238 x23,
239 x24,
240 x25,
241 x26,
242 x27,
243 x28,
244 fp,
245 lr,
246 sp_el0,
247 sp_el1,
248 pc,
249 cpsr,
250 } = self;
251 for (dest, src) in [
252 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18,
253 x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, fp, lr, sp_el0, sp_el1, pc, cpsr,
254 ]
255 .into_iter()
256 .zip(&mut it)
257 {
258 *dest = src.as_u64();
259 }
260 }
261}
262
263impl StateElement<Aarch64PartitionCapabilities, Aarch64VpInfo> for Registers {
264 fn is_present(_caps: &Aarch64PartitionCapabilities) -> bool {
265 true
266 }
267
268 fn at_reset(_caps: &Aarch64PartitionCapabilities, _vp_info: &Aarch64VpInfo) -> Self {
269 Self {
270 x0: 0,
271 x1: 0,
272 x2: 0,
273 x3: 0,
274 x4: 0,
275 x5: 0,
276 x6: 0,
277 x7: 0,
278 x8: 0,
279 x9: 0,
280 x10: 0,
281 x11: 0,
282 x12: 0,
283 x13: 0,
284 x14: 0,
285 x15: 0,
286 x16: 0,
287 x17: 0,
288 x18: 0,
289 x19: 0,
290 x20: 0,
291 x21: 0,
292 x22: 0,
293 x23: 0,
294 x24: 0,
295 x25: 0,
296 x26: 0,
297 x27: 0,
298 x28: 0,
299 fp: 0,
300 lr: 0,
301 sp_el0: 0,
302 sp_el1: 0,
303 pc: 0,
304 cpsr: Cpsr64::new()
305 .with_sp(true)
306 .with_el(1)
307 .with_f(true)
308 .with_i(true)
309 .with_a(true)
310 .with_d(true)
311 .into(),
312 }
313 }
314}
315
316#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Protobuf, Inspect)]
317#[mesh(package = "virt.aarch64")]
318pub struct SystemRegisters {
319 #[inspect(hex)]
320 #[mesh(1)]
321 pub sctlr_el1: u64,
322 #[inspect(hex)]
323 #[mesh(2)]
324 pub ttbr0_el1: u64,
325 #[inspect(hex)]
326 #[mesh(3)]
327 pub ttbr1_el1: u64,
328 #[inspect(hex)]
329 #[mesh(4)]
330 pub tcr_el1: u64,
331 #[inspect(hex)]
332 #[mesh(5)]
333 pub esr_el1: u64,
334 #[inspect(hex)]
335 #[mesh(6)]
336 pub far_el1: u64,
337 #[inspect(hex)]
338 #[mesh(7)]
339 pub mair_el1: u64,
340 #[inspect(hex)]
341 #[mesh(8)]
342 pub elr_el1: u64,
343 #[inspect(hex)]
344 #[mesh(9)]
345 pub vbar_el1: u64,
346}
347
348impl HvRegisterState<HvArm64RegisterName, 9> for SystemRegisters {
349 fn names(&self) -> &'static [HvArm64RegisterName; 9] {
350 &[
351 HvArm64RegisterName::SctlrEl1,
352 HvArm64RegisterName::Ttbr0El1,
353 HvArm64RegisterName::Ttbr1El1,
354 HvArm64RegisterName::TcrEl1,
355 HvArm64RegisterName::EsrEl1,
356 HvArm64RegisterName::FarEl1,
357 HvArm64RegisterName::MairEl1,
358 HvArm64RegisterName::ElrEl1,
359 HvArm64RegisterName::VbarEl1,
360 ]
361 }
362
363 fn get_values<'a>(&self, it: impl Iterator<Item = &'a mut HvRegisterValue>) {
364 let &Self {
365 sctlr_el1,
366 ttbr0_el1,
367 ttbr1_el1,
368 tcr_el1,
369 esr_el1,
370 far_el1,
371 mair_el1,
372 elr_el1,
373 vbar_el1,
374 } = self;
375 for (dest, src) in it.zip([
376 sctlr_el1, ttbr0_el1, ttbr1_el1, tcr_el1, esr_el1, far_el1, mair_el1, elr_el1, vbar_el1,
377 ]) {
378 *dest = src.into();
379 }
380 }
381
382 fn set_values(&mut self, it: impl Iterator<Item = HvRegisterValue>) {
383 let Self {
384 sctlr_el1,
385 ttbr0_el1,
386 ttbr1_el1,
387 tcr_el1,
388 esr_el1,
389 far_el1,
390 mair_el1,
391 elr_el1,
392 vbar_el1,
393 } = self;
394 for (src, dest) in it.zip([
395 sctlr_el1, ttbr0_el1, ttbr1_el1, tcr_el1, esr_el1, far_el1, mair_el1, elr_el1, vbar_el1,
396 ]) {
397 *dest = src.as_u64();
398 }
399 }
400}
401
402impl StateElement<Aarch64PartitionCapabilities, Aarch64VpInfo> for SystemRegisters {
403 fn is_present(_caps: &Aarch64PartitionCapabilities) -> bool {
404 true
405 }
406
407 fn at_reset(_caps: &Aarch64PartitionCapabilities, _vp: &Aarch64VpInfo) -> Self {
408 Self {
409 sctlr_el1: u64::from(
412 SctlrEl1::new()
413 .with_eos(true)
414 .with_tscxt(true)
415 .with_eis(true)
416 .with_span(true)
417 .with_n_tlsmd(true)
418 .with_lsmaoe(true),
419 ),
420 ttbr0_el1: 0,
421 ttbr1_el1: 0,
422 tcr_el1: 0,
423 esr_el1: 0,
424 far_el1: 0,
425 mair_el1: 0,
426 elr_el1: 0,
427 vbar_el1: 0,
428 }
429 }
430}
431
432state_trait! {
433 "Per-VP state",
434 AccessVpState,
435 Aarch64PartitionCapabilities,
436 Aarch64VpInfo,
437 VpSavedState,
438 "virt.aarch64",
439 (1, "registers", registers, set_registers, Registers),
440 (2, "system_registers", system_registers, set_system_registers, SystemRegisters),
441}