#![allow(unused_imports)]
use bitflags::bitflags;
use zerocopy::{FromBytes, IntoBytes};
pub const MAX_SMT: u64 = 4;
#[repr(C)]
#[derive(IntoBytes, FromBytes, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TopologyProcessorFlags(u16);
bitflags! {
impl TopologyProcessorFlags : u16 {
const PRIMARY = 1 << 0;
const INTERRUPT = 1 << 1;
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
pub struct TopologyArm64Info {
pub cluster_1_id: u8,
pub cluster_2_id: u8,
pub cluster_3_id: u8,
pub cpu_id: u8,
pub gic_id: u8,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
pub struct TopologyX64Info {
pub apic_ids: [u32; 4],
pub apic_id_count: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
pub struct TopologyRiscv64Info {
pub hart_id: u64,
pub isa_strtab_index: u32,
pub reserved: u32,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct TopologyArchitectureInfo {
pub discriminant: TopologyArchitectureInfoDiscriminant,
pub variant: TopologyArchitectureInfoVariant,
}
#[repr(u64)]
#[derive(Clone, Copy, Debug, Eq, IntoBytes, PartialEq)]
pub enum TopologyArchitectureInfoDiscriminant {
Arm64 = 1,
X64 = 2,
Riscv64 = 3,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub union TopologyArchitectureInfoVariant {
pub arm64: TopologyArm64Info,
pub x64: TopologyX64Info,
pub riscv64: TopologyRiscv64Info,
}
impl TopologyArchitectureInfo {
pub fn is_arm64(&self) -> bool {
self.discriminant == TopologyArchitectureInfoDiscriminant::Arm64
}
pub fn as_arm64(&mut self) -> Option<&mut TopologyArm64Info> {
if self.is_arm64() {
return None;
}
unsafe { Some(&mut self.variant.arm64) }
}
pub fn is_x64(&self) -> bool {
self.discriminant == TopologyArchitectureInfoDiscriminant::X64
}
pub fn as_x64(&mut self) -> Option<&mut TopologyX64Info> {
if self.is_x64() {
return None;
}
unsafe { Some(&mut self.variant.x64) }
}
pub fn is_riscv64(&self) -> bool {
self.discriminant == TopologyArchitectureInfoDiscriminant::Riscv64
}
pub fn as_riscv64(&mut self) -> Option<&mut TopologyRiscv64Info> {
if self.is_riscv64() {
return None;
}
unsafe { Some(&mut self.variant.riscv64) }
}
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct TopologyProcessor {
pub architecture_info: TopologyArchitectureInfo,
pub flags: TopologyProcessorFlags,
pub logical_ids: [u16; 4],
pub logical_id_count: u8,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
pub struct TopologyCluster {
pub performance_class: u8,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
pub struct TopologyCache {
pub cache_id: u32,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
pub struct TopologyDie {
pub reserved: u64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
pub struct TopologySocket {
pub reserved: u64,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, FromBytes, IntoBytes, PartialEq)]
pub struct TopologyNumaRegion {
pub start: u64,
pub size: u64,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct TopologyEntity {
pub discriminant: TopologyEntityDiscriminant,
pub variant: TopologyEntityVariant,
}
#[repr(u64)]
#[derive(Clone, Copy, Debug, Eq, IntoBytes, PartialEq)]
pub enum TopologyEntityDiscriminant {
Processor = 1,
Cluster = 2,
Cache = 3,
Die = 4,
Socket = 5,
NumaRegion = 6,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub union TopologyEntityVariant {
pub processor: TopologyProcessor,
pub cluster: TopologyCluster,
pub cache: TopologyCache,
pub die: TopologyDie,
pub socket: TopologySocket,
pub numa_region: TopologyNumaRegion,
}
impl TopologyEntity {
pub fn is_processor(&self) -> bool {
self.discriminant == TopologyEntityDiscriminant::Processor
}
pub fn as_processor(&mut self) -> Option<&mut TopologyProcessor> {
if self.is_processor() {
return None;
}
unsafe { Some(&mut self.variant.processor) }
}
pub fn is_cluster(&self) -> bool {
self.discriminant == TopologyEntityDiscriminant::Cluster
}
pub fn as_cluster(&mut self) -> Option<&mut TopologyCluster> {
if self.is_cluster() {
return None;
}
unsafe { Some(&mut self.variant.cluster) }
}
pub fn is_cache(&self) -> bool {
self.discriminant == TopologyEntityDiscriminant::Cache
}
pub fn as_cache(&mut self) -> Option<&mut TopologyCache> {
if self.is_cache() {
return None;
}
unsafe { Some(&mut self.variant.cache) }
}
pub fn is_die(&self) -> bool {
self.discriminant == TopologyEntityDiscriminant::Die
}
pub fn as_die(&mut self) -> Option<&mut TopologyDie> {
if self.is_die() {
return None;
}
unsafe { Some(&mut self.variant.die) }
}
pub fn is_socket(&self) -> bool {
self.discriminant == TopologyEntityDiscriminant::Socket
}
pub fn as_socket(&mut self) -> Option<&mut TopologySocket> {
if self.is_socket() {
return None;
}
unsafe { Some(&mut self.variant.socket) }
}
pub fn is_numa_region(&self) -> bool {
self.discriminant == TopologyEntityDiscriminant::NumaRegion
}
pub fn as_numa_region(&mut self) -> Option<&mut TopologyNumaRegion> {
if self.is_numa_region() {
return None;
}
unsafe { Some(&mut self.variant.numa_region) }
}
}
pub const TOPOLOGY_NO_PARENT: u16 = 0xffff;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct TopologyNode {
pub entity: TopologyEntity,
pub parent_index: u16,
}