1use crate::{Status, sys};
6use bitflags::bitflags;
7
8pub fn system_get_page_size() -> u32 {
14 unsafe { sys::zx_system_get_page_size() }
15}
16
17pub fn system_get_dcache_line_size() -> u32 {
23 unsafe { sys::zx_system_get_dcache_line_size() }
24}
25
26pub fn system_get_physmem() -> u64 {
32 unsafe { sys::zx_system_get_physmem() }
33}
34
35pub fn system_get_num_cpus() -> u32 {
41 unsafe { sys::zx_system_get_num_cpus() }
42}
43
44#[derive(Debug, Copy, Clone, Eq, PartialEq)]
46#[repr(u32)]
47pub enum FeatureKind {
48 HardwareBreakpointCount = sys::ZX_FEATURE_KIND_HW_BREAKPOINT_COUNT,
49 HardwareWatchpointCount = sys::ZX_FEATURE_KIND_HW_WATCHPOINT_COUNT,
50}
51
52impl Into<u32> for FeatureKind {
53 fn into(self) -> u32 {
54 match self {
55 FeatureKind::HardwareBreakpointCount => sys::ZX_FEATURE_KIND_HW_BREAKPOINT_COUNT,
56 FeatureKind::HardwareWatchpointCount => sys::ZX_FEATURE_KIND_HW_WATCHPOINT_COUNT,
57 }
58 }
59}
60
61mod private {
64 pub struct Internal;
65}
66
67pub trait FeatureFlags: bitflags::Flags {
69 fn kind(_: private::Internal) -> u32;
70}
71
72bitflags! {
73 #[repr(transparent)]
74 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
75 pub struct VirtualMemoryFeatureFlags: u32 {
76 const VM_CAN_MAP_XOM = (1<<0);
78
79 const _ = !0;
81 }
82}
83
84impl FeatureFlags for VirtualMemoryFeatureFlags {
85 fn kind(_: private::Internal) -> u32 {
86 sys::ZX_FEATURE_KIND_VM
87 }
88}
89
90bitflags! {
91 #[repr(transparent)]
92 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
93 pub struct CpuFeatureFlags: u32 {
94
95 const HAS_CPU_FEATURES = (1<<0);
97
98 #[cfg(target_arch = "aarch64")]
100 const ARM64_FEATURE_ISA_FP = sys::ZX_ARM64_FEATURE_ISA_FP;
101 #[cfg(target_arch = "aarch64")]
102 const ARM64_FEATURE_ISA_ASIMD = sys::ZX_ARM64_FEATURE_ISA_ASIMD;
103 #[cfg(target_arch = "aarch64")]
104 const ARM64_FEATURE_ISA_AES = sys::ZX_ARM64_FEATURE_ISA_AES;
105 #[cfg(target_arch = "aarch64")]
106 const ARM64_FEATURE_ISA_PMULL = sys::ZX_ARM64_FEATURE_ISA_PMULL;
107 #[cfg(target_arch = "aarch64")]
108 const ARM64_FEATURE_ISA_SHA1 = sys::ZX_ARM64_FEATURE_ISA_SHA1;
109 #[cfg(target_arch = "aarch64")]
110 const ARM64_FEATURE_ISA_SHA256 = sys::ZX_ARM64_FEATURE_ISA_SHA256;
111 #[cfg(target_arch = "aarch64")]
112 const ARM64_FEATURE_ISA_CRC32 = sys::ZX_ARM64_FEATURE_ISA_CRC32;
113 #[cfg(target_arch = "aarch64")]
114 const ARM64_FEATURE_ISA_ATOMICS = sys::ZX_ARM64_FEATURE_ISA_ATOMICS;
115 #[cfg(target_arch = "aarch64")]
116 const ARM64_FEATURE_ISA_RDM = sys::ZX_ARM64_FEATURE_ISA_RDM;
117 #[cfg(target_arch = "aarch64")]
118 const ARM64_FEATURE_ISA_SHA3 = sys::ZX_ARM64_FEATURE_ISA_SHA3;
119 #[cfg(target_arch = "aarch64")]
120 const ARM64_FEATURE_ISA_SM3 = sys::ZX_ARM64_FEATURE_ISA_SM3;
121 #[cfg(target_arch = "aarch64")]
122 const ARM64_FEATURE_ISA_SM4 = sys::ZX_ARM64_FEATURE_ISA_SM4;
123 #[cfg(target_arch = "aarch64")]
124 const ARM64_FEATURE_ISA_DP = sys::ZX_ARM64_FEATURE_ISA_DP;
125 #[cfg(target_arch = "aarch64")]
126 const ARM64_FEATURE_ISA_DPB = sys::ZX_ARM64_FEATURE_ISA_DPB;
127 #[cfg(target_arch = "aarch64")]
128 const ARM64_FEATURE_ISA_FHM = sys::ZX_ARM64_FEATURE_ISA_FHM;
129 #[cfg(target_arch = "aarch64")]
130 const ARM64_FEATURE_ISA_TS = sys::ZX_ARM64_FEATURE_ISA_TS;
131 #[cfg(target_arch = "aarch64")]
132 const ARM64_FEATURE_ISA_RNDR = sys::ZX_ARM64_FEATURE_ISA_RNDR;
133 #[cfg(target_arch = "aarch64")]
134 const ARM64_FEATURE_ISA_SHA512 = sys::ZX_ARM64_FEATURE_ISA_SHA512;
135 #[cfg(target_arch = "aarch64")]
136 const ARM64_FEATURE_ISA_I8MM = sys::ZX_ARM64_FEATURE_ISA_I8MM;
137 #[cfg(target_arch = "aarch64")]
138 const ARM64_FEATURE_ISA_SVE = sys::ZX_ARM64_FEATURE_ISA_SVE;
139 #[cfg(target_arch = "aarch64")]
140 const ARM64_FEATURE_ISA_ARM32 = sys::ZX_ARM64_FEATURE_ISA_ARM32;
141 #[cfg(target_arch = "aarch64")]
142 const ARM64_FEATURE_ISA_MOPS = sys::ZX_ARM64_FEATURE_ISA_MOPS;
143
144 #[cfg(target_arch = "aarch64")]
146 const ARM64_FEATURE_ISA_SHA2 = sys::ZX_ARM64_FEATURE_ISA_SHA256;
147
148 const _ = !0;
150 }
151}
152
153impl FeatureFlags for CpuFeatureFlags {
154 fn kind(_: private::Internal) -> u32 {
155 sys::ZX_FEATURE_KIND_CPU
156 }
157}
158
159bitflags! {
160 #[repr(transparent)]
162 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
163 pub struct CpuSveFeatureFlags: u32 {
164 #[cfg(target_arch = "aarch64")]
166 const ARM64_FEATURE_ISA_SVEI8MM = sys::ZX_ARM64_FEATURE_ISA_SVEI8MM;
167 #[cfg(target_arch = "aarch64")]
168 const ARM64_FEATURE_ISA_SVEF32MM = sys::ZX_ARM64_FEATURE_ISA_SVEF32MM;
169 #[cfg(target_arch = "aarch64")]
170 const ARM64_FEATURE_ISA_SVEF64MM = sys::ZX_ARM64_FEATURE_ISA_SVEF64MM;
171 #[cfg(target_arch = "aarch64")]
172 const ARM64_FEATURE_ISA_SVEBF16 = sys::ZX_ARM64_FEATURE_ISA_SVEBF16;
173 #[cfg(target_arch = "aarch64")]
174 const ARM64_FEATURE_ISA_SVE2 = sys::ZX_ARM64_FEATURE_ISA_SVE2;
175 #[cfg(target_arch = "aarch64")]
176 const ARM64_FEATURE_ISA_SVEAES = sys::ZX_ARM64_FEATURE_ISA_SVEAES;
177 #[cfg(target_arch = "aarch64")]
178 const ARM64_FEATURE_ISA_SVEPMULL = sys::ZX_ARM64_FEATURE_ISA_SVEPMULL;
179 #[cfg(target_arch = "aarch64")]
180 const ARM64_FEATURE_ISA_SVEBITPERM = sys::ZX_ARM64_FEATURE_ISA_SVEBITPERM;
181 #[cfg(target_arch = "aarch64")]
182 const ARM64_FEATURE_ISA_SVESHA3 = sys::ZX_ARM64_FEATURE_ISA_SVESHA3;
183 #[cfg(target_arch = "aarch64")]
184 const ARM64_FEATURE_ISA_SVESM4 = sys::ZX_ARM64_FEATURE_ISA_SVESM4;
185
186 const _ = !0;
188 }
189}
190
191impl FeatureFlags for CpuSveFeatureFlags {
192 fn kind(_: private::Internal) -> u32 {
193 sys::ZX_FEATURE_KIND_CPU_SVE
194 }
195}
196
197bitflags! {
198 #[repr(transparent)]
199 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
200 pub struct AddressTaggingFeatureFlags: u32 {
201 #[cfg(target_arch = "aarch64")]
203 const ARM64_FEATURE_ADDRESS_TAGGING_TBI = sys::ZX_ARM64_FEATURE_ADDRESS_TAGGING_TBI;
204
205 const _ = !0;
207 }
208}
209
210impl FeatureFlags for AddressTaggingFeatureFlags {
211 fn kind(_: private::Internal) -> u32 {
212 sys::ZX_FEATURE_KIND_ADDRESS_TAGGING
213 }
214}
215
216pub fn system_get_feature_flags<F: FeatureFlags>() -> Result<F, Status>
222where
223 F: bitflags::Flags<Bits = u32>,
224{
225 let mut raw_features: u32 = 0;
226 let access = private::Internal;
227 Status::ok(unsafe {
228 sys::zx_system_get_features(F::kind(access), &mut raw_features as *mut u32)
229 })
230 .and_then(|_status| Ok(F::from_bits_retain(raw_features)))
231}
232
233pub fn system_get_feature_count(kind: FeatureKind) -> Result<u32, Status> {
239 let mut raw_features: u32 = 0;
240 Status::ok(unsafe { sys::zx_system_get_features(kind as u32, &mut raw_features as *mut u32) })
241 .and_then(|_status| Ok(raw_features))
242}
243
244#[derive(Debug, Copy, Clone, Eq, PartialEq)]
246#[repr(u32)]
247pub enum SystemEventKind {
248 OutOfMemory = sys::ZX_SYSTEM_EVENT_OUT_OF_MEMORY,
249 MemoryPressureCritical = sys::ZX_SYSTEM_EVENT_MEMORY_PRESSURE_CRITICAL,
250 MemoryPressureWarning = sys::ZX_SYSTEM_EVENT_MEMORY_PRESSURE_WARNING,
251 MemoryPressureNormal = sys::ZX_SYSTEM_EVENT_MEMORY_PRESSURE_NORMAL,
252 ImminentOutOfMemory = sys::ZX_SYSTEM_EVENT_IMMINENT_OUT_OF_MEMORY,
253}
254
255pub fn system_get_event(
261 root_job: &crate::Job,
262 kind: SystemEventKind,
263) -> Result<crate::Event, Status> {
264 let mut event_handle = sys::ZX_HANDLE_INVALID;
265 Status::ok(unsafe {
267 sys::zx_system_get_event(root_job.raw_handle(), kind as u32, &mut event_handle)
268 })?;
269 Ok(unsafe { crate::Event::from(crate::NullableHandle::from_raw(event_handle)) })
271}
272
273#[cfg(test)]
274mod tests {
275 use super::*;
276
277 #[test]
278 fn system_get_features_cpu_kind() {
279 let result = system_get_feature_flags()
281 .map(|flags: CpuFeatureFlags| flags & CpuFeatureFlags::HAS_CPU_FEATURES);
282
283 #[cfg(target_arch = "aarch64")]
285 assert_eq!(result, Ok(CpuFeatureFlags::HAS_CPU_FEATURES));
286
287 #[cfg(not(target_arch = "aarch64"))]
288 assert_eq!(result, Err(Status::NOT_SUPPORTED));
289 }
290
291 #[test]
292 fn system_get_features_other_kinds() {
293 assert!(system_get_feature_flags::<VirtualMemoryFeatureFlags>().is_ok());
294 assert!(system_get_feature_flags::<AddressTaggingFeatureFlags>().is_ok());
295 assert!(system_get_feature_flags::<CpuSveFeatureFlags>().is_ok());
296 assert!(system_get_feature_count(FeatureKind::HardwareBreakpointCount).is_ok());
297 assert!(system_get_feature_count(FeatureKind::HardwareWatchpointCount).is_ok());
298 }
299
300 #[test]
301 fn system_get_event_access_denied() {
302 let job = fuchsia_runtime::job_default();
303 assert_eq!(
304 zx::system_get_event(&job, zx::SystemEventKind::MemoryPressureNormal),
305 Err(zx::Status::ACCESS_DENIED)
306 );
307 }
308}