use core::{
mem::offset_of,
sync::atomic::{AtomicUsize, Ordering},
};
pub use semx_cpumask::{Cpumask, CpumaskIter, NR_CPUS};
#[derive(Clone, Copy)]
pub enum PsciCompatible {
Psci0_1,
Psci0_2,
Psci1_0,
}
#[derive(Clone, Copy)]
pub enum PsciEnableMethod {
Hvc,
Smc,
}
#[derive(Clone, Copy)]
pub enum CpuBootMethod {
Psci {
compatible: PsciCompatible,
enable_method: PsciEnableMethod,
cpu_on: usize,
},
Sbi,
}
#[derive(Clone, Copy)]
pub struct SmpDefine {
boot_method: CpuBootMethod,
hwid: [usize; NR_CPUS],
nr_cpus: usize,
}
impl SmpDefine {
pub const fn create(
boot_method: CpuBootMethod,
hwid: [usize; NR_CPUS],
nr_cpus: usize,
) -> Self {
Self { boot_method, hwid, nr_cpus }
}
#[inline(always)]
pub fn boot_method(&self) -> CpuBootMethod {
self.boot_method
}
#[inline(always)]
pub fn hwid(&self, cpu: usize) -> usize {
self.hwid[cpu]
}
#[inline(always)]
pub fn nr_cpus(&self) -> usize {
self.nr_cpus
}
}
#[derive(Default)]
#[repr(C)]
pub struct SecondaryData {
stack: AtomicUsize,
task: AtomicUsize,
}
impl SecondaryData {
pub const fn new() -> Self {
Self { stack: AtomicUsize::new(0), task: AtomicUsize::new(0) }
}
pub fn set_stack(&self, base: usize) {
self.stack.store(base, Ordering::Relaxed);
}
pub fn set_task(&self, task: usize) {
self.task.store(task, Ordering::Relaxed);
}
}
pub const CPU_BOOT_STACK: usize = offset_of!(SecondaryData, stack);
pub const CPU_BOOT_TASK: usize = offset_of!(SecondaryData, task);