1#[cfg(target_arch = "x86_64")]
6pub mod x86_64;
7
8#[cfg(target_arch = "x86_64")]
9pub use x86_64::XSAVE_AREA_SIZE as X64_XSAVE_AREA_SIZE;
10
11#[cfg(target_arch = "x86_64")]
12pub use x86_64::SUPPORTED_XSAVE_FEATURES as X64_SUPPORTED_XSAVE_FEATURES;
13
14#[cfg(target_arch = "aarch64")]
15mod aarch64;
16
17#[cfg(target_arch = "riscv64")]
18pub mod riscv64;
19
20#[derive(Clone, Copy, Default)]
21#[repr(C)]
22pub struct ExtendedPstateState {
23 #[cfg(target_arch = "x86_64")]
24 state: x86_64::State,
25
26 #[cfg(target_arch = "aarch64")]
27 state: aarch64::State,
28
29 #[cfg(target_arch = "riscv64")]
30 state: riscv64::State,
31}
32
33#[cfg(target_arch = "aarch64")]
34#[derive(Clone, Copy, Default)]
37#[repr(C)]
38pub struct ExtendedAarch32PstateState {
39 state: aarch64::Aarch32State,
40}
41
42#[cfg(target_arch = "aarch64")]
43impl ExtendedAarch32PstateState {
44 pub fn reset(&mut self) {
45 self.state.reset()
46 }
47
48 pub fn get_arm32_qregs(&self) -> &[u128; 16] {
49 &self.state.q
50 }
51
52 pub fn get_arm32_fpsr(&self) -> u32 {
53 self.state.fpsr
54 }
55
56 pub fn get_arm32_fpcr(&self) -> u32 {
57 self.state.fpcr
58 }
59}
60
61impl ExtendedPstateState {
62 #[cfg(target_arch = "x86_64")]
63 pub fn with_strategy(strategy: x86_64::Strategy) -> Self {
64 Self { state: x86_64::State::with_strategy(strategy) }
65 }
66
67 pub fn reset(&mut self) {
68 self.state.reset()
69 }
70
71 #[cfg(target_arch = "aarch64")]
72 pub fn get_arm64_qregs(&self) -> &[u128; 32] {
73 &self.state.q
74 }
75
76 #[cfg(target_arch = "aarch64")]
77 pub fn get_arm64_fpsr(&self) -> u32 {
78 self.state.fpsr
79 }
80
81 #[cfg(target_arch = "aarch64")]
82 pub fn get_arm64_fpcr(&self) -> u32 {
83 self.state.fpcr
84 }
85
86 #[cfg(target_arch = "aarch64")]
87 pub fn set_arm64_state(&mut self, qregs: &[u128; 32], fpsr: u32, fpcr: u32) {
88 self.state.q = *qregs;
89 self.state.fpsr = fpsr;
90 self.state.fpcr = fpcr;
91 }
92
93 #[cfg(target_arch = "riscv64")]
94 pub fn get_riscv64_state(&self) -> &riscv64::State {
95 &self.state
96 }
97
98 #[cfg(target_arch = "riscv64")]
99 pub fn get_riscv64_state_mut(&mut self) -> &mut riscv64::State {
100 &mut self.state
101 }
102
103 #[cfg(target_arch = "x86_64")]
104 pub fn get_x64_xsave_area(&self) -> [u8; X64_XSAVE_AREA_SIZE] {
105 #[allow(
106 clippy::undocumented_unsafe_blocks,
107 reason = "Force documented unsafe blocks in Starnix"
108 )]
109 unsafe {
110 std::mem::transmute(self.state.buffer)
111 }
112 }
113
114 #[cfg(target_arch = "x86_64")]
115 pub fn set_x64_xsave_area(&mut self, xsave_area: [u8; X64_XSAVE_AREA_SIZE]) {
116 self.state.set_xsave_area(xsave_area);
117 }
118}
119
120#[repr(C)]
124pub union ExtendedPstatePointer {
125 pub extended_pstate: *mut ExtendedPstateState,
126 #[cfg(target_arch = "aarch64")]
127 pub extended_aarch32_pstate: *mut ExtendedAarch32PstateState,
128}
129
130unsafe extern "C" {
132 pub fn save_extended_pstate(state_addr: usize);
133 pub fn restore_extended_pstate(state_addr: usize);
134
135 #[cfg(target_arch = "aarch64")]
136 pub fn save_extended_aarch32_pstate(state_addr: usize);
137 #[cfg(target_arch = "aarch64")]
138 pub fn restore_extended_aarch32_pstate(state_addr: usize);
139}