1 // note from the spec:
2 // When the context record field is larger than the register being stored in it, the upper bits of the
3 // context record field are unused and ignored
4 /// Universal EFI_SYSTEM_CONTEXT definition
5 /// This is passed to debug callbacks
6 #[repr(C)]
7 #[allow(missing_debug_implementations)]
8 pub union SystemContext {
9     ebc: *mut SystemContextEBC,
10     riscv_32: *mut SystemContextRiscV32,
11     riscv_64: *mut SystemContextRiscV64,
12     riscv_128: *mut SystemContextRiscV128,
13     ia32: *mut SystemContextIA32,
14     x64: *mut SystemContextX64,
15     ipf: *mut SystemContextIPF,
16     arm: *mut SystemContextARM,
17     aarch64: *mut SystemContextAARCH64,
18 }
19 
20 /// System context for virtual EBC processors
21 #[repr(C)]
22 #[derive(Debug, Clone, Copy)]
23 pub struct SystemContextEBC {
24     r0: u64,
25     r1: u64,
26     r2: u64,
27     r3: u64,
28     r4: u64,
29     r5: u64,
30     r6: u64,
31     r7: u64,
32     flags: u64,
33     control_flags: u64,
34     ip: u64,
35 }
36 
37 #[repr(C)]
38 #[derive(Debug, Clone, Copy)]
39 pub struct SystemContextRiscV32 {
40     // Integer registers
41     zero: u32,
42     ra: u32,
43     sp: u32,
44     gp: u32,
45     tp: u32,
46     t0: u32,
47     t1: u32,
48     t2: u32,
49     s0fp: u32,
50     s1: u32,
51     a0: u32,
52     a1: u32,
53     a2: u32,
54     a3: u32,
55     a4: u32,
56     a5: u32,
57     a6: u32,
58     a7: u32,
59     s2: u32,
60     s3: u32,
61     s4: u32,
62     s5: u32,
63     s6: u32,
64     s7: u32,
65     s8: u32,
66     s9: u32,
67     s10: u32,
68     s11: u32,
69     t3: u32,
70     t4: u32,
71     t5: u32,
72     t6: u32,
73     // Float registers for F, D, and Q Standard Extensions
74     ft0: u128,
75     ft1: u128,
76     ft2: u128,
77     ft3: u128,
78     ft4: u128,
79     ft5: u128,
80     ft6: u128,
81     ft7: u128,
82     fs0: u128,
83     fs1: u128,
84     fa0: u128,
85     fa1: u128,
86     fa2: u128,
87     fa3: u128,
88     fa4: u128,
89     fa5: u128,
90     fa6: u128,
91     fa7: u128,
92     fs2: u128,
93     fs3: u128,
94     fs4: u128,
95     fs5: u128,
96     fs6: u128,
97     fs7: u128,
98     fs8: u128,
99     fs9: u128,
100     fs10: u128,
101     fs11: u128,
102     ft8: u128,
103     ft9: u128,
104     ft10: u128,
105     ft11: u128,
106 }
107 
108 #[repr(C)]
109 #[derive(Debug, Clone, Copy)]
110 pub struct SystemContextRiscV64 {
111     // Integer registers
112     zero: u64,
113     ra: u64,
114     sp: u64,
115     gp: u64,
116     tp: u64,
117     t0: u64,
118     t1: u64,
119     t2: u64,
120     s0fp: u64,
121     s1: u64,
122     a0: u64,
123     a1: u64,
124     a2: u64,
125     a3: u64,
126     a4: u64,
127     a5: u64,
128     a6: u64,
129     a7: u64,
130     s2: u64,
131     s3: u64,
132     s4: u64,
133     s5: u64,
134     s6: u64,
135     s7: u64,
136     s8: u64,
137     s9: u64,
138     s10: u64,
139     s11: u64,
140     t3: u64,
141     t4: u64,
142     t5: u64,
143     t6: u64,
144     // Floating registers for F, D, and Q Standard Extensions
145     ft0: u128,
146     ft1: u128,
147     ft2: u128,
148     ft3: u128,
149     ft4: u128,
150     ft5: u128,
151     ft6: u128,
152     ft7: u128,
153     fs0: u128,
154     fs1: u128,
155     fa0: u128,
156     fa1: u128,
157     fa2: u128,
158     fa3: u128,
159     fa4: u128,
160     fa5: u128,
161     fa6: u128,
162     fa7: u128,
163     fs2: u128,
164     fs3: u128,
165     fs4: u128,
166     fs5: u128,
167     fs6: u128,
168     fs7: u128,
169     fs8: u128,
170     fs9: u128,
171     fs10: u128,
172     fs11: u128,
173     ft8: u128,
174     ft9: u128,
175     ft10: u128,
176     ft11: u128,
177 }
178 
179 #[repr(C)]
180 #[derive(Debug, Clone, Copy)]
181 pub struct SystemContextRiscV128 {
182     // Integer registers
183     zero: u128,
184     ra: u128,
185     sp: u128,
186     gp: u128,
187     tp: u128,
188     t0: u128,
189     t1: u128,
190     t2: u128,
191     s0fp: u128,
192     s1: u128,
193     a0: u128,
194     a1: u128,
195     a2: u128,
196     a3: u128,
197     a4: u128,
198     a5: u128,
199     a6: u128,
200     a7: u128,
201     s2: u128,
202     s3: u128,
203     s4: u128,
204     s5: u128,
205     s6: u128,
206     s7: u128,
207     s8: u128,
208     s9: u128,
209     s10: u128,
210     s11: u128,
211     t3: u128,
212     t4: u128,
213     t5: u128,
214     t6: u128,
215     // Floating registers for F, D, and Q Standard Extensions
216     ft0: u128,
217     ft1: u128,
218     ft2: u128,
219     ft3: u128,
220     ft4: u128,
221     ft5: u128,
222     ft6: u128,
223     ft7: u128,
224     fs0: u128,
225     fs1: u128,
226     fa0: u128,
227     fa1: u128,
228     fa2: u128,
229     fa3: u128,
230     fa4: u128,
231     fa5: u128,
232     fa6: u128,
233     fa7: u128,
234     fs2: u128,
235     fs3: u128,
236     fs4: u128,
237     fs5: u128,
238     fs6: u128,
239     fs7: u128,
240     fs8: u128,
241     fs9: u128,
242     fs10: u128,
243     fs11: u128,
244     ft8: u128,
245     ft9: u128,
246     ft10: u128,
247     ft11: u128,
248 }
249 
250 /// System context for IA-32 processors (x86)
251 #[repr(C)]
252 #[derive(Debug, Clone, Copy)]
253 pub struct SystemContextIA32 {
254     exception_data: u32, // additional data pushed on the stack by some types of exceptions
255     fx_save_state: FxSaveStateIA32,
256     dr0: u32,
257     dr1: u32,
258     dr2: u32,
259     dr3: u32,
260     dr6: u32,
261     dr7: u32,
262     cr0: u32,
263     cr1: u32, // Noted as "Reserved" in the UEFI Specification
264     cr2: u32,
265     cr3: u32,
266     cr4: u32,
267     eflags: u32,
268     ldtr: u32,
269     tr: u32,
270     gdtr: [u32; 2],
271     idtr: [u32; 2],
272     eip: u32,
273     gs: u32,
274     fs: u32,
275     es: u32,
276     ds: u32,
277     cs: u32,
278     ss: u32,
279     edi: u32,
280     esi: u32,
281     ebp: u32,
282     esp: u32,
283     ebx: u32,
284     edx: u32,
285     ecx: u32,
286     eax: u32,
287 }
288 
289 /// FP / MMX / XMM registers for IA-32
290 #[repr(C)]
291 #[derive(Debug, Clone, Copy)]
292 pub struct FxSaveStateIA32 {
293     fcw: u16,
294     fsw: u16,
295     ftw: u16,
296     opcode: u16,
297     eip: u32,
298     cs: u16,
299     reserved_1: u16,
300     data_offset: u32,
301     ds: u16,
302     reserved_2: [u8; 10],
303     st0mm0: [u8; 10],
304     reserved_3: [u8; 6],
305     st1mm1: [u8; 10],
306     reserved_4: [u8; 6],
307     st2mm2: [u8; 10],
308     reserved_5: [u8; 6],
309     st3mm3: [u8; 10],
310     reserved_6: [u8; 6],
311     st4mm4: [u8; 10],
312     reserved_7: [u8; 6],
313     st5mm5: [u8; 10],
314     reserved_8: [u8; 6],
315     st6mm6: [u8; 10],
316     reserved_9: [u8; 6],
317     st7mm7: [u8; 10],
318     reserved_10: [u8; 6],
319     xmm0: [u8; 16],
320     xmm1: [u8; 16],
321     xmm2: [u8; 16],
322     xmm3: [u8; 16],
323     xmm4: [u8; 16],
324     xmm5: [u8; 16],
325     xmm6: [u8; 16],
326     xmm7: [u8; 16],
327     reserved_11: [u8; 14 * 16],
328 }
329 
330 /// System context for x64 processors
331 #[repr(C)]
332 #[derive(Debug, Clone, Copy)]
333 pub struct SystemContextX64 {
334     exception_data: u64, // additional data pushed on the stack by some types of exceptions
335     fx_save_state: FxSaveStateX64,
336     dr0: u64,
337     dr1: u64,
338     dr2: u64,
339     dr3: u64,
340     dr6: u64,
341     dr7: u64,
342     cr0: u64,
343     cr1: u64, // Noted as "Reserved" in the UEFI Specification
344     cr2: u64,
345     cr3: u64,
346     cr4: u64,
347     cr8: u64,
348     rflags: u64,
349     ldtr: u64,
350     tr: u64,
351     gdtr: [u64; 2],
352     idtr: [u64; 2],
353     rip: u64,
354     gs: u64,
355     fs: u64,
356     es: u64,
357     ds: u64,
358     cs: u64,
359     ss: u64,
360     rdi: u64,
361     rsi: u64,
362     rbp: u64,
363     rsp: u64,
364     rbx: u64,
365     rdx: u64,
366     rcx: u64,
367     rax: u64,
368     r8: u64,
369     r9: u64,
370     r10: u64,
371     r11: u64,
372     r12: u64,
373     r13: u64,
374     r14: u64,
375     r15: u64,
376 }
377 
378 /// FP / MMX / XMM registers for X64
379 #[repr(C)]
380 #[derive(Debug, Clone, Copy)]
381 pub struct FxSaveStateX64 {
382     fcw: u16,
383     fsw: u16,
384     ftw: u16,
385     opcode: u16,
386     rip: u64,
387     data_offset: u64,
388     reserved_1: [u8; 8],
389     st0mm0: [u8; 10],
390     reserved_2: [u8; 6],
391     st1mm1: [u8; 10],
392     reserved_3: [u8; 6],
393     st2mm2: [u8; 10],
394     reserved_4: [u8; 6],
395     st3mm3: [u8; 10],
396     reserved_5: [u8; 6],
397     st4mm4: [u8; 10],
398     reserved_6: [u8; 6],
399     st5mm5: [u8; 10],
400     reserved_7: [u8; 6],
401     st6mm6: [u8; 10],
402     reserved_8: [u8; 6],
403     st7mm7: [u8; 10],
404     reserved_9: [u8; 6],
405     xmm0: [u8; 16],
406     xmm1: [u8; 16],
407     xmm2: [u8; 16],
408     xmm3: [u8; 16],
409     xmm4: [u8; 16],
410     xmm5: [u8; 16],
411     xmm6: [u8; 16],
412     xmm7: [u8; 16],
413     reserved_11: [u8; 14 * 16], // spec goes right from `Reserved9` to `Reserved11`
414 }
415 
416 #[repr(C)]
417 #[derive(Debug, Clone, Copy)]
418 pub struct SystemContextIPF {
419     reserved: u64,
420     r1: u64,
421     r2: u64,
422     r3: u64,
423     r4: u64,
424     r5: u64,
425     r6: u64,
426     r7: u64,
427     r8: u64,
428     r9: u64,
429     r10: u64,
430     r11: u64,
431     r12: u64,
432     r13: u64,
433     r14: u64,
434     r15: u64,
435     r16: u64,
436     r17: u64,
437     r18: u64,
438     r19: u64,
439     r20: u64,
440     r21: u64,
441     r22: u64,
442     r23: u64,
443     r24: u64,
444     r25: u64,
445     r26: u64,
446     r27: u64,
447     r28: u64,
448     r29: u64,
449     r30: u64,
450     r31: u64,
451     f2: [u64; 2],
452     f3: [u64; 2],
453     f4: [u64; 2],
454     f5: [u64; 2],
455     f6: [u64; 2],
456     f7: [u64; 2],
457     f8: [u64; 2],
458     f9: [u64; 2],
459     f10: [u64; 2],
460     f11: [u64; 2],
461     f12: [u64; 2],
462     f13: [u64; 2],
463     f14: [u64; 2],
464     f15: [u64; 2],
465     f16: [u64; 2],
466     f17: [u64; 2],
467     f18: [u64; 2],
468     f19: [u64; 2],
469     f20: [u64; 2],
470     f21: [u64; 2],
471     f22: [u64; 2],
472     f23: [u64; 2],
473     f24: [u64; 2],
474     f25: [u64; 2],
475     f26: [u64; 2],
476     f27: [u64; 2],
477     f28: [u64; 2],
478     f29: [u64; 2],
479     f30: [u64; 2],
480     f31: [u64; 2],
481     pr: u64,
482     b0: u64,
483     b1: u64,
484     b2: u64,
485     b3: u64,
486     b4: u64,
487     b5: u64,
488     b6: u64,
489     b7: u64,
490     // application registers
491     ar_rsc: u64,
492     ar_bsp: u64,
493     ar_bspstore: u64,
494     ar_rnat: u64,
495     ar_fcr: u64,
496     ar_eflag: u64,
497     ar_csd: u64,
498     ar_ssd: u64,
499     ar_cflg: u64,
500     ar_fsr: u64,
501     ar_fir: u64,
502     ar_fdr: u64,
503     ar_ccv: u64,
504     ar_unat: u64,
505     ar_fpsr: u64,
506     ar_pfs: u64,
507     ar_lc: u64,
508     ar_ec: u64,
509     // control registers
510     cr_dcr: u64,
511     cr_itm: u64,
512     cr_iva: u64,
513     cr_pta: u64,
514     cr_ipsr: u64,
515     cr_isr: u64,
516     cr_iip: u64,
517     cr_ifa: u64,
518     cr_itir: u64,
519     cr_iipa: u64,
520     cr_ifs: u64,
521     cr_iim: u64,
522     cr_iha: u64,
523     // debug registers
524     dbr0: u64,
525     dbr1: u64,
526     dbr2: u64,
527     dbr3: u64,
528     dbr4: u64,
529     dbr5: u64,
530     dbr6: u64,
531     dbr7: u64,
532     ibr0: u64,
533     ibr1: u64,
534     ibr2: u64,
535     ibr3: u64,
536     ibr4: u64,
537     ibr5: u64,
538     ibr6: u64,
539     ibr7: u64,
540     // virtual Registers
541     int_nat: u64, // nat bits for r1-r31
542 }
543 
544 /// System context for ARM processors
545 #[repr(C)]
546 #[derive(Debug, Clone, Copy)]
547 pub struct SystemContextARM {
548     r0: u32,
549     r1: u32,
550     r2: u32,
551     r3: u32,
552     r4: u32,
553     r5: u32,
554     r6: u32,
555     r7: u32,
556     r8: u32,
557     r9: u32,
558     r10: u32,
559     r11: u32,
560     r12: u32,
561     sp: u32,
562     lr: u32,
563     pc: u32,
564     cpsr: u32,
565     dfsr: u32,
566     dfar: u32,
567     ifsr: u32,
568 }
569 
570 /// System context for AARCH64 processors
571 #[repr(C)]
572 #[derive(Debug, Clone, Copy)]
573 pub struct SystemContextAARCH64 {
574     // General Purpose Registers
575     x0: u64,
576     x1: u64,
577     x2: u64,
578     x3: u64,
579     x4: u64,
580     x5: u64,
581     x6: u64,
582     x7: u64,
583     x8: u64,
584     x9: u64,
585     x10: u64,
586     x11: u64,
587     x12: u64,
588     x13: u64,
589     x14: u64,
590     x15: u64,
591     x16: u64,
592     x17: u64,
593     x18: u64,
594     x19: u64,
595     x20: u64,
596     x21: u64,
597     x22: u64,
598     x23: u64,
599     x24: u64,
600     x25: u64,
601     x26: u64,
602     x27: u64,
603     x28: u64,
604     fp: u64, // x29 - Frame Pointer
605     lr: u64, // x30 - Link Register
606     sp: u64, // x31 - Stack Pointer
607     // FP/SIMD Registers
608     v0: [u64; 2],
609     v1: [u64; 2],
610     v2: [u64; 2],
611     v3: [u64; 2],
612     v4: [u64; 2],
613     v5: [u64; 2],
614     v6: [u64; 2],
615     v7: [u64; 2],
616     v8: [u64; 2],
617     v9: [u64; 2],
618     v10: [u64; 2],
619     v11: [u64; 2],
620     v12: [u64; 2],
621     v13: [u64; 2],
622     v14: [u64; 2],
623     v15: [u64; 2],
624     v16: [u64; 2],
625     v17: [u64; 2],
626     v18: [u64; 2],
627     v19: [u64; 2],
628     v20: [u64; 2],
629     v21: [u64; 2],
630     v22: [u64; 2],
631     v23: [u64; 2],
632     v24: [u64; 2],
633     v25: [u64; 2],
634     v26: [u64; 2],
635     v27: [u64; 2],
636     v28: [u64; 2],
637     v29: [u64; 2],
638     v30: [u64; 2],
639     v31: [u64; 2],
640     elr: u64,  // Exception Link Register
641     spsr: u64, // Saved Processor Status Register
642     fpsr: u64, // Floating Point Status Register
643     esr: u64,  // Exception Syndrome Register
644     far: u64,  // Fault Address Register
645 }
646