fidl_data_zbi/
cpu.rs

1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// DO NOT EDIT.
6// Generated from FIDL library `zbi` by zither, a Fuchsia platform tool.
7
8#![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        /// The associated processor boots the system and is the last to be shutdown.
23        const PRIMARY = 1 << 0;
24
25        /// The associated processor handles all interrupts. Some architectures
26        /// will not have such a processor.
27        const INTERRUPT = 1 << 1;
28  }
29}
30
31#[repr(C)]
32#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
33pub struct TopologyArm64Info {
34    /// Cluster ids for each level, one being closest to the cpu.
35    /// These map to aff1, aff2, and aff3 values in the ARM registers.
36    pub cluster_1_id: u8,
37    pub cluster_2_id: u8,
38    pub cluster_3_id: u8,
39
40    /// Id of the cpu inside of the bottom-most cluster, aff0 value.
41    pub cpu_id: u8,
42
43    /// The GIC interface number for this processor.
44    /// In GIC v3+ this is not necessary as the processors are addressed by their
45    /// affinity routing (all cluster ids followed by cpu_id).
46    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    /// ID that represents this logical CPU (i.e., hart) in SBI.
60    pub hart_id: u64,
61
62    /// Index into the ZBI_TYPE_RISCV64_ISA_STRTAB string table payload giving
63    /// the start of the associated ISA string.
64    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// TODO(https://github.com/rust-lang/rust/issues/49804): Define anonymously.
84#[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    /// Relative performance level of this processor in the system. The value is
140    /// interpreted as the performance of this processor relative to the maximum
141    /// performance processor in the system. No specific values are required for
142    /// the performance level, only that the following relationship holds:
143    ///
144    ///   Pmax is the value of performance_class for the maximum performance
145    ///   processor in the system, operating at its maximum operating point.
146    ///
147    ///   P is the value of performance_class for this processor, operating at
148    ///   its maximum operating point.
149    ///
150    ///   R is the performance ratio of this processor to the maximum performance
151    ///   processor in the system in the range (0.0, 1.0].
152    ///
153    ///   R = (P + 1) / (Pmax + 1)
154    ///
155    /// If accuracy is limited, choose a conservative value that slightly under-
156    /// estimates the performance of lower-performance processors.
157    pub performance_class: u8,
158}
159
160#[repr(C)]
161#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
162pub struct TopologyCache {
163    /// Unique id of this cache node. No other semantics are assumed.
164    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    /// Starting memory addresses of the numa region.
183    pub start: u64,
184
185    /// Size in bytes of the numa region.
186    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// TODO(https://github.com/rust-lang/rust/issues/49804): Define anonymously.
208#[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/// The ZBI_TYPE_CPU_TOPOLOGY payload consists of an array of
290/// zbi_topology_node_t, giving a flattened tree-like description of the CPU
291/// configuration according to the entity hierarchy.
292#[repr(C)]
293#[derive(Clone, Copy)]
294pub struct TopologyNode {
295    pub entity: TopologyEntity,
296    pub parent_index: u16,
297}