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