1#![allow(unused_imports)]
9
10use bitflags::bitflags;
11use zerocopy::{FromBytes, IntoBytes};
12
13pub const MAX_SMT: u64 = 4;
14
15#[repr(C)]
16#[derive(IntoBytes, FromBytes, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
17pub struct TopologyProcessorFlags(u16);
18
19bitflags! {
20 impl TopologyProcessorFlags : u16 {
21
22 const PRIMARY = 1 << 0;
24
25 const INTERRUPT = 1 << 1;
28 }
29}
30
31#[repr(C)]
32#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
33pub struct TopologyArm64Info {
34 pub cluster_1_id: u8,
37 pub cluster_2_id: u8,
38 pub cluster_3_id: u8,
39
40 pub cpu_id: u8,
42
43 pub gic_id: u8,
47}
48
49#[repr(C)]
50#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
51pub struct TopologyX64Info {
52 pub apic_ids: [u32; 4],
53 pub apic_id_count: u32,
54}
55
56#[repr(C)]
57#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
58pub struct TopologyRiscv64Info {
59 pub hart_id: u64,
61
62 pub isa_strtab_index: u32,
65 pub reserved: u32,
66}
67
68#[repr(C)]
69#[derive(Clone, Copy)]
70pub struct TopologyArchitectureInfo {
71 pub discriminant: TopologyArchitectureInfoDiscriminant,
72 pub variant: TopologyArchitectureInfoVariant,
73}
74
75#[repr(u64)]
76#[derive(Clone, Copy, Debug, Eq, IntoBytes, PartialEq)]
77pub enum TopologyArchitectureInfoDiscriminant {
78 Arm64 = 1,
79 X64 = 2,
80 Riscv64 = 3,
81}
82
83#[repr(C)]
85#[derive(Clone, Copy)]
86pub union TopologyArchitectureInfoVariant {
87 pub arm64: TopologyArm64Info,
88 pub x64: TopologyX64Info,
89 pub riscv64: TopologyRiscv64Info,
90}
91
92impl TopologyArchitectureInfo {
93 pub fn is_arm64(&self) -> bool {
94 self.discriminant == TopologyArchitectureInfoDiscriminant::Arm64
95 }
96
97 pub fn as_arm64(&mut self) -> Option<&mut TopologyArm64Info> {
98 if self.is_arm64() {
99 return None;
100 }
101 unsafe { Some(&mut self.variant.arm64) }
102 }
103
104 pub fn is_x64(&self) -> bool {
105 self.discriminant == TopologyArchitectureInfoDiscriminant::X64
106 }
107
108 pub fn as_x64(&mut self) -> Option<&mut TopologyX64Info> {
109 if self.is_x64() {
110 return None;
111 }
112 unsafe { Some(&mut self.variant.x64) }
113 }
114
115 pub fn is_riscv64(&self) -> bool {
116 self.discriminant == TopologyArchitectureInfoDiscriminant::Riscv64
117 }
118
119 pub fn as_riscv64(&mut self) -> Option<&mut TopologyRiscv64Info> {
120 if self.is_riscv64() {
121 return None;
122 }
123 unsafe { Some(&mut self.variant.riscv64) }
124 }
125}
126
127#[repr(C)]
128#[derive(Clone, Copy)]
129pub struct TopologyProcessor {
130 pub architecture_info: TopologyArchitectureInfo,
131 pub flags: TopologyProcessorFlags,
132 pub logical_ids: [u16; 4],
133 pub logical_id_count: u8,
134}
135
136#[repr(C)]
137#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
138pub struct TopologyCluster {
139 pub performance_class: u8,
158}
159
160#[repr(C)]
161#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
162pub struct TopologyCache {
163 pub cache_id: u32,
165}
166
167#[repr(C)]
168#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
169pub struct TopologyDie {
170 pub reserved: u64,
171}
172
173#[repr(C)]
174#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
175pub struct TopologySocket {
176 pub reserved: u64,
177}
178
179#[repr(C)]
180#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
181pub struct TopologyNumaRegion {
182 pub start: u64,
184
185 pub size: u64,
187}
188
189#[repr(C)]
190#[derive(Clone, Copy)]
191pub struct TopologyEntity {
192 pub discriminant: TopologyEntityDiscriminant,
193 pub variant: TopologyEntityVariant,
194}
195
196#[repr(u64)]
197#[derive(Clone, Copy, Debug, Eq, IntoBytes, PartialEq)]
198pub enum TopologyEntityDiscriminant {
199 Processor = 1,
200 Cluster = 2,
201 Cache = 3,
202 Die = 4,
203 Socket = 5,
204 NumaRegion = 6,
205}
206
207#[repr(C)]
209#[derive(Clone, Copy)]
210pub union TopologyEntityVariant {
211 pub processor: TopologyProcessor,
212 pub cluster: TopologyCluster,
213 pub cache: TopologyCache,
214 pub die: TopologyDie,
215 pub socket: TopologySocket,
216 pub numa_region: TopologyNumaRegion,
217}
218
219impl TopologyEntity {
220 pub fn is_processor(&self) -> bool {
221 self.discriminant == TopologyEntityDiscriminant::Processor
222 }
223
224 pub fn as_processor(&mut self) -> Option<&mut TopologyProcessor> {
225 if self.is_processor() {
226 return None;
227 }
228 unsafe { Some(&mut self.variant.processor) }
229 }
230
231 pub fn is_cluster(&self) -> bool {
232 self.discriminant == TopologyEntityDiscriminant::Cluster
233 }
234
235 pub fn as_cluster(&mut self) -> Option<&mut TopologyCluster> {
236 if self.is_cluster() {
237 return None;
238 }
239 unsafe { Some(&mut self.variant.cluster) }
240 }
241
242 pub fn is_cache(&self) -> bool {
243 self.discriminant == TopologyEntityDiscriminant::Cache
244 }
245
246 pub fn as_cache(&mut self) -> Option<&mut TopologyCache> {
247 if self.is_cache() {
248 return None;
249 }
250 unsafe { Some(&mut self.variant.cache) }
251 }
252
253 pub fn is_die(&self) -> bool {
254 self.discriminant == TopologyEntityDiscriminant::Die
255 }
256
257 pub fn as_die(&mut self) -> Option<&mut TopologyDie> {
258 if self.is_die() {
259 return None;
260 }
261 unsafe { Some(&mut self.variant.die) }
262 }
263
264 pub fn is_socket(&self) -> bool {
265 self.discriminant == TopologyEntityDiscriminant::Socket
266 }
267
268 pub fn as_socket(&mut self) -> Option<&mut TopologySocket> {
269 if self.is_socket() {
270 return None;
271 }
272 unsafe { Some(&mut self.variant.socket) }
273 }
274
275 pub fn is_numa_region(&self) -> bool {
276 self.discriminant == TopologyEntityDiscriminant::NumaRegion
277 }
278
279 pub fn as_numa_region(&mut self) -> Option<&mut TopologyNumaRegion> {
280 if self.is_numa_region() {
281 return None;
282 }
283 unsafe { Some(&mut self.variant.numa_region) }
284 }
285}
286
287pub const TOPOLOGY_NO_PARENT: u16 = 0xffff;
288
289#[repr(C)]
293#[derive(Clone, Copy)]
294pub struct TopologyNode {
295 pub entity: TopologyEntity,
296 pub parent_index: u16,
297}