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 pub fn set_arm32_state(&mut self, qregs: &[u128; 16], fpsr: u32, fpcr: u32) {
61 self.state.q = *qregs;
62 self.state.fpsr = fpsr;
63 self.state.fpcr = fpcr;
64 }
65}
66
67impl ExtendedPstateState {
68 #[cfg(target_arch = "x86_64")]
69 pub fn with_strategy(strategy: x86_64::Strategy) -> Self {
70 Self { state: x86_64::State::with_strategy(strategy) }
71 }
72
73 pub fn reset(&mut self) {
74 self.state.reset()
75 }
76
77 #[cfg(target_arch = "aarch64")]
78 pub fn get_arm64_qregs(&self) -> &[u128; 32] {
79 &self.state.q
80 }
81
82 #[cfg(target_arch = "aarch64")]
83 pub fn get_arm64_fpsr(&self) -> u32 {
84 self.state.fpsr
85 }
86
87 #[cfg(target_arch = "aarch64")]
88 pub fn get_arm64_fpcr(&self) -> u32 {
89 self.state.fpcr
90 }
91
92 #[cfg(target_arch = "aarch64")]
93 pub fn set_arm64_state(&mut self, qregs: &[u128; 32], fpsr: u32, fpcr: u32) {
94 self.state.q = *qregs;
95 self.state.fpsr = fpsr;
96 self.state.fpcr = fpcr;
97 }
98
99 #[cfg(target_arch = "aarch64")]
100 pub fn with_sve(has_sve: bool) -> Self {
101 Self { state: aarch64::State { has_sve: u8::from(has_sve), ..Default::default() } }
102 }
103
104 #[cfg(target_arch = "aarch64")]
105 pub fn has_arm64_sve(&self) -> bool {
106 self.state.has_sve != 0
107 }
108
109 #[cfg(target_arch = "aarch64")]
110 pub fn get_arm64_p_regs(&self) -> &[u16; 16] {
111 &self.state.p
112 }
113
114 #[cfg(target_arch = "aarch64")]
115 pub fn get_arm64_ffr(&self) -> u16 {
116 self.state.ffr
117 }
118
119 #[cfg(target_arch = "aarch64")]
120 pub fn set_arm64_sve_state(&mut self, p_regs: &[u16; 16], ffr: u16) {
121 self.state.p = *p_regs;
122 self.state.ffr = ((1u32 << ffr.trailing_ones()) - 1) as u16;
130 }
131
132 #[cfg(target_arch = "aarch64")]
133 pub fn reset_arm64_sve_state(&mut self) {
134 self.state.p = [0; 16];
135 self.state.ffr = 0;
136 }
137
138 #[cfg(target_arch = "aarch64")]
140 pub fn get_arm64_sve_vl_inherit(&self) -> bool {
141 self.state.sve_vl_inherit != 0
142 }
143
144 #[cfg(target_arch = "aarch64")]
145 pub fn set_arm64_sve_vl_inherit(&mut self, inherit: bool) {
146 self.state.sve_vl_inherit = u8::from(inherit);
147 }
148
149 #[cfg(target_arch = "riscv64")]
150 pub fn get_riscv64_state(&self) -> &riscv64::State {
151 &self.state
152 }
153
154 #[cfg(target_arch = "riscv64")]
155 pub fn get_riscv64_state_mut(&mut self) -> &mut riscv64::State {
156 &mut self.state
157 }
158
159 #[cfg(target_arch = "x86_64")]
160 pub fn get_x64_xsave_area(&self) -> [u8; X64_XSAVE_AREA_SIZE] {
161 #[allow(
162 clippy::undocumented_unsafe_blocks,
163 reason = "Force documented unsafe blocks in Starnix"
164 )]
165 unsafe {
166 std::mem::transmute(self.state.buffer)
167 }
168 }
169
170 #[cfg(target_arch = "x86_64")]
171 pub fn set_x64_xsave_area(&mut self, xsave_area: [u8; X64_XSAVE_AREA_SIZE]) {
172 self.state.set_xsave_area(xsave_area);
173 }
174}
175
176#[repr(C)]
180pub union ExtendedPstatePointer {
181 pub extended_pstate: *mut ExtendedPstateState,
182 #[cfg(target_arch = "aarch64")]
183 pub extended_aarch32_pstate: *mut ExtendedAarch32PstateState,
184}
185
186unsafe extern "C" {
188 pub fn save_extended_pstate(state_addr: usize);
189 pub fn restore_extended_pstate(state_addr: usize);
190
191 #[cfg(target_arch = "aarch64")]
192 pub fn save_extended_aarch32_pstate(state_addr: usize);
193 #[cfg(target_arch = "aarch64")]
194 pub fn restore_extended_aarch32_pstate(state_addr: usize);
195}