1use crate::{sys, Status};
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_physmem() -> u64 {
23 unsafe { sys::zx_system_get_physmem() }
24}
25
26pub fn system_get_num_cpus() -> u32 {
32 unsafe { sys::zx_system_get_num_cpus() }
33}
34
35#[derive(Debug, Copy, Clone, Eq, PartialEq)]
37#[repr(u32)]
38pub enum FeatureKind {
39 HardwareBreakpointCount = sys::ZX_FEATURE_KIND_HW_BREAKPOINT_COUNT,
40 HardwareWatchpointCount = sys::ZX_FEATURE_KIND_HW_WATCHPOINT_COUNT,
41}
42
43impl Into<u32> for FeatureKind {
44 fn into(self) -> u32 {
45 match self {
46 FeatureKind::HardwareBreakpointCount => sys::ZX_FEATURE_KIND_HW_BREAKPOINT_COUNT,
47 FeatureKind::HardwareWatchpointCount => sys::ZX_FEATURE_KIND_HW_WATCHPOINT_COUNT,
48 }
49 }
50}
51
52mod private {
55 pub struct Internal;
56}
57
58pub trait FeatureFlags: bitflags::Flags {
60 fn kind(_: private::Internal) -> u32;
61}
62
63bitflags! {
64 #[repr(transparent)]
65 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
66 pub struct VirtualMemoryFeatureFlags: u32 {
67 const VM_CAN_MAP_XOM = (1<<0);
69
70 const _ = !0;
72 }
73}
74
75impl FeatureFlags for VirtualMemoryFeatureFlags {
76 fn kind(_: private::Internal) -> u32 {
77 sys::ZX_FEATURE_KIND_VM
78 }
79}
80
81bitflags! {
82 #[repr(transparent)]
83 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
84 pub struct CpuFeatureFlags: u32 {
85
86 const HAS_CPU_FEATURES = (1<<0);
88
89 #[cfg(target_arch = "aarch64")]
91 const ARM64_FEATURE_ISA_FP = sys::ZX_ARM64_FEATURE_ISA_FP;
92 #[cfg(target_arch = "aarch64")]
93 const ARM64_FEATURE_ISA_ASIMD = sys::ZX_ARM64_FEATURE_ISA_ASIMD;
94 #[cfg(target_arch = "aarch64")]
95 const ARM64_FEATURE_ISA_AES = sys::ZX_ARM64_FEATURE_ISA_AES;
96 #[cfg(target_arch = "aarch64")]
97 const ARM64_FEATURE_ISA_PMULL = sys::ZX_ARM64_FEATURE_ISA_PMULL;
98 #[cfg(target_arch = "aarch64")]
99 const ARM64_FEATURE_ISA_SHA1 = sys::ZX_ARM64_FEATURE_ISA_SHA1;
100 #[cfg(target_arch = "aarch64")]
101 const ARM64_FEATURE_ISA_SHA256 = sys::ZX_ARM64_FEATURE_ISA_SHA256;
102 #[cfg(target_arch = "aarch64")]
103 const ARM64_FEATURE_ISA_CRC32 = sys::ZX_ARM64_FEATURE_ISA_CRC32;
104 #[cfg(target_arch = "aarch64")]
105 const ARM64_FEATURE_ISA_ATOMICS = sys::ZX_ARM64_FEATURE_ISA_ATOMICS;
106 #[cfg(target_arch = "aarch64")]
107 const ARM64_FEATURE_ISA_RDM = sys::ZX_ARM64_FEATURE_ISA_RDM;
108 #[cfg(target_arch = "aarch64")]
109 const ARM64_FEATURE_ISA_SHA3 = sys::ZX_ARM64_FEATURE_ISA_SHA3;
110 #[cfg(target_arch = "aarch64")]
111 const ARM64_FEATURE_ISA_SM3 = sys::ZX_ARM64_FEATURE_ISA_SM3;
112 #[cfg(target_arch = "aarch64")]
113 const ARM64_FEATURE_ISA_SM4 = sys::ZX_ARM64_FEATURE_ISA_SM4;
114 #[cfg(target_arch = "aarch64")]
115 const ARM64_FEATURE_ISA_DP = sys::ZX_ARM64_FEATURE_ISA_DP;
116 #[cfg(target_arch = "aarch64")]
117 const ARM64_FEATURE_ISA_DPB = sys::ZX_ARM64_FEATURE_ISA_DPB;
118 #[cfg(target_arch = "aarch64")]
119 const ARM64_FEATURE_ISA_FHM = sys::ZX_ARM64_FEATURE_ISA_FHM;
120 #[cfg(target_arch = "aarch64")]
121 const ARM64_FEATURE_ISA_TS = sys::ZX_ARM64_FEATURE_ISA_TS;
122 #[cfg(target_arch = "aarch64")]
123 const ARM64_FEATURE_ISA_RNDR = sys::ZX_ARM64_FEATURE_ISA_RNDR;
124 #[cfg(target_arch = "aarch64")]
125 const ARM64_FEATURE_ISA_SHA512 = sys::ZX_ARM64_FEATURE_ISA_SHA512;
126 #[cfg(target_arch = "aarch64")]
127 const ARM64_FEATURE_ISA_I8MM = sys::ZX_ARM64_FEATURE_ISA_I8MM;
128 #[cfg(target_arch = "aarch64")]
129 const ARM64_FEATURE_ISA_SVE = sys::ZX_ARM64_FEATURE_ISA_SVE;
130 #[cfg(target_arch = "aarch64")]
131 const ARM64_FEATURE_ISA_ARM32 = sys::ZX_ARM64_FEATURE_ISA_ARM32;
132
133 #[cfg(target_arch = "aarch64")]
135 const ARM64_FEATURE_ISA_SHA2 = sys::ZX_ARM64_FEATURE_ISA_SHA256;
136
137 const _ = !0;
139 }
140}
141
142impl FeatureFlags for CpuFeatureFlags {
143 fn kind(_: private::Internal) -> u32 {
144 sys::ZX_FEATURE_KIND_CPU
145 }
146}
147
148bitflags! {
149 #[repr(transparent)]
150 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
151 pub struct AddressTaggingFeatureFlags: u32 {
152 #[cfg(target_arch = "aarch64")]
154 const ARM64_FEATURE_ADDRESS_TAGGING_TBI = sys::ZX_ARM64_FEATURE_ADDRESS_TAGGING_TBI;
155
156 const _ = !0;
158 }
159}
160
161impl FeatureFlags for AddressTaggingFeatureFlags {
162 fn kind(_: private::Internal) -> u32 {
163 sys::ZX_FEATURE_KIND_ADDRESS_TAGGING
164 }
165}
166
167pub fn system_get_feature_flags<F: FeatureFlags>() -> Result<F, Status>
173where
174 F: bitflags::Flags<Bits = u32>,
175{
176 let mut raw_features: u32 = 0;
177 let access = private::Internal;
178 Status::ok(unsafe {
179 sys::zx_system_get_features(F::kind(access), &mut raw_features as *mut u32)
180 })
181 .and_then(|_status| Ok(F::from_bits_retain(raw_features)))
182}
183
184pub fn system_get_feature_count(kind: FeatureKind) -> Result<u32, Status> {
190 let mut raw_features: u32 = 0;
191 Status::ok(unsafe { sys::zx_system_get_features(kind as u32, &mut raw_features as *mut u32) })
192 .and_then(|_status| Ok(raw_features))
193}
194
195#[cfg(test)]
196mod tests {
197 use super::*;
198
199 #[test]
200 fn system_get_features_cpu_kind() {
201 let result = system_get_feature_flags()
203 .map(|flags: CpuFeatureFlags| flags & CpuFeatureFlags::HAS_CPU_FEATURES);
204
205 #[cfg(target_arch = "aarch64")]
207 assert_eq!(result, Ok(CpuFeatureFlags::HAS_CPU_FEATURES));
208
209 #[cfg(not(target_arch = "aarch64"))]
210 assert_eq!(result, Err(Status::NOT_SUPPORTED));
211 }
212
213 #[test]
214 fn system_get_features_other_kinds() {
215 assert!(system_get_feature_flags::<VirtualMemoryFeatureFlags>().is_ok());
216 assert!(system_get_feature_flags::<AddressTaggingFeatureFlags>().is_ok());
217 assert!(system_get_feature_count(FeatureKind::HardwareBreakpointCount).is_ok());
218 assert!(system_get_feature_count(FeatureKind::HardwareWatchpointCount).is_ok());
219 }
220}