pipewire_native_spa/interface/
cpu.rs1use bitflags::bitflags;
6use std::{any::Any, pin::Pin};
7
8use pipewire_native_macros::EnumU32;
9
10use super::plugin::Interface;
11
12pub const FORCE: &str = "cpu.force";
13pub const VM: &str = "cpu.vm";
14
15bitflags! {
16 #[repr(C)]
17 #[derive(Debug, Clone, Copy, PartialEq, Eq, EnumU32)]
18 pub struct X86CpuFlags: u32 {
19 const MMX = (1<<0); const MMXEXT = (1<<1); const AMD_3DNOW = (1<<2); const SSE = (1<<3); const SSE2 = (1<<4); const AMD_3DNOWEXT = (1<<5); const SSE3 = (1<<6); const SSSE3 = (1<<7); const SSE41 = (1<<8); const SSE42 = (1<<9); const AESNI = (1<<10); const AVX = (1<<11); const XOP = (1<<12); const FMA4 = (1<<13); const CMOV = (1<<14); const AVX2 = (1<<15); const FMA3 = (1<<16); const BMI1 = (1<<17); const BMI2 = (1<<18); const AVX512 = (1<<19); const SLOW_UNALIGNED = (1<<20); const _ = !0; }
42}
43
44bitflags! {
45 #[repr(C)]
46 #[derive(Debug, Clone, Copy, PartialEq, Eq, EnumU32)]
47 pub struct PpcCpuFlags: u32 {
48 const ALTIVEC = (1<<0); const VSX = (1<<1); const POWER8 = (1<<2); const _ = !0; }
53}
54
55bitflags! {
56 #[repr(C)]
57 #[derive(Debug, Clone, Copy, PartialEq, Eq, EnumU32)]
58 pub struct ArmCpuFlags : u32 {
59 const ARMV5TE = (1 << 0);
60 const ARMV6 = (1 << 1);
61 const ARMV6T2 = (1 << 2);
62 const VFP = (1 << 3);
63 const VFPV3 = (1 << 4);
64 const NEON = (1 << 5);
65 const ARMV8 = (1 << 6);
66 const _ = !0; }
68}
69
70bitflags! {
71 #[repr(C)]
72 #[derive(Debug, Clone, Copy, PartialEq, Eq, EnumU32)]
73 pub struct RiscvCpuFlags : u32 {
74 const RISCV_V = (1 << 0);
75 const _ = !0; }
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Eq)]
80pub enum CpuFlags {
81 X86(X86CpuFlags),
82 Arm(ArmCpuFlags),
83 Ppc(PpcCpuFlags),
84 Riscv(RiscvCpuFlags),
85}
86
87impl TryFrom<u32> for CpuFlags {
88 type Error = ();
89
90 fn try_from(value: u32) -> Result<Self, Self::Error> {
91 #[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
92 return Ok(CpuFlags::X86(X86CpuFlags::from_bits(value).ok_or(())?));
93 #[cfg(any(target_arch = "aarch64", target_arch = "arm"))]
94 return Ok(CpuFlags::Arm(ArmCpuFlags::from_bits(value).ok_or(())?));
95 #[cfg(any(target_arch = "powerpc64", target_arch = "powerpc"))]
96 return Ok(CpuFlags::Ppc(PpcCpuFlags::from_bits(value).ok_or(())?));
97 #[cfg(target_arch = "riscv64")]
98 return Ok(CpuFlags::Riscv(RiscvCpuFlags::from_bits(value).ok_or(())?));
99 }
100}
101
102impl From<CpuFlags> for u32 {
103 fn from(value: CpuFlags) -> Self {
104 match value {
105 CpuFlags::X86(flags) => flags.bits(),
106 CpuFlags::Arm(flags) => flags.bits(),
107 CpuFlags::Ppc(flags) => flags.bits(),
108 CpuFlags::Riscv(flags) => flags.bits(),
109 }
110 }
111}
112
113#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumU32)]
114pub enum CpuVm {
115 None = 0,
116 Other,
117 Kvm,
118 Qemu,
119 Bochs,
120 Xen,
121 Uml,
122 Vmware,
123 Oracle,
124 Microsoft,
125 Zvm,
126 Parallels,
127 Bhyve,
128 Qnx,
129 Acrn,
130 PowerVm,
131}
132
133impl std::fmt::Display for CpuVm {
134 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135 let res = match self {
136 CpuVm::None => "0",
137 CpuVm::Other => "other",
138 CpuVm::Kvm => "kvm",
139 CpuVm::Qemu => "qemu",
140 CpuVm::Bochs => "bochs",
141 CpuVm::Xen => "xen",
142 CpuVm::Uml => "uml",
143 CpuVm::Vmware => "vmware",
144 CpuVm::Oracle => "oracle",
145 CpuVm::Microsoft => "microsoft",
146 CpuVm::Zvm => "zvm",
147 CpuVm::Parallels => "parallels",
148 CpuVm::Bhyve => "bhyve",
149 CpuVm::Qnx => "qnx",
150 CpuVm::Acrn => "acrn",
151 CpuVm::PowerVm => "powervm",
152 };
153
154 write!(f, "{}", res)
155 }
156}
157
158pub struct CpuImpl {
159 pub inner: Pin<Box<dyn Any>>,
160
161 pub get_flags: fn(this: &CpuImpl) -> CpuFlags,
162 pub force_flags: fn(this: &CpuImpl, flags: CpuFlags) -> i32,
163 pub get_count: fn(this: &CpuImpl) -> u32,
164 pub get_max_align: fn(this: &CpuImpl) -> u32,
165 pub get_vm_type: fn(this: &CpuImpl) -> CpuVm,
166 pub zero_denormals: fn(this: &CpuImpl, enable: bool) -> i32,
167}
168
169impl CpuImpl {
170 pub fn get_flags(&self) -> CpuFlags {
171 (self.get_flags)(self)
172 }
173
174 pub fn force_flags(&self, flags: CpuFlags) -> i32 {
175 (self.force_flags)(self, flags)
176 }
177
178 pub fn get_count(&self) -> u32 {
179 (self.get_count)(self)
180 }
181
182 pub fn get_max_align(&self) -> u32 {
183 (self.get_max_align)(self)
184 }
185
186 pub fn get_vm_type(&self) -> CpuVm {
187 (self.get_vm_type)(self)
188 }
189
190 pub fn zero_denormals(&self, enable: bool) -> i32 {
191 (self.zero_denormals)(self, enable)
192 }
193}
194
195impl Interface for CpuImpl {
196 unsafe fn make_native(&self) -> *mut super::ffi::CInterface {
197 crate::support::ffi::cpu::make_native(self)
198 }
199
200 unsafe fn free_native(cpu: *mut super::ffi::CInterface) {
201 crate::support::ffi::cpu::free_native(cpu)
202 }
203}
204
205unsafe impl Send for CpuImpl {}
206unsafe impl Sync for CpuImpl {}