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