use core::sync::atomic::{self, Ordering};
use crate::{bsp::__smp_define, irq::irqflags::local_irq_disable, println, smp::smp_send_stop};
cfg_if::cfg_if! {
if #[cfg(target_arch = "aarch64")] {
mod aarch64;
use aarch64::*;
} else {
mod dummy;
use dummy::*;
}
}
#[inline(always)]
pub(crate) fn set_this_processor_id(id: usize) {
arch_set_my_processor_id(id);
}
#[inline(always)]
pub fn this_processor_id() -> usize {
arch_my_processor_id()
}
#[inline(always)]
pub fn cpu_relax() {
arch_cpu_relax();
}
#[inline(always)]
pub fn cpu_wfe() {
arch_cpu_wfe();
}
#[inline(always)]
pub fn nr_cpus() -> usize {
unsafe { __smp_define().nr_cpus() }
}
#[inline(always)]
pub fn barrier() {
atomic::compiler_fence(Ordering::SeqCst);
}
#[inline(always)]
pub fn smp_mb_acquire() {
arch_smp_mb_acquire();
}
#[inline(always)]
pub fn smp_mb_release() {
arch_smp_mb_release();
}
#[inline(always)]
pub fn smp_wmb() {
smp_mb_release();
}
#[inline(always)]
pub fn smp_rmb() {
smp_mb_acquire();
}
#[inline(always)]
pub fn smp_mb() {
arch_smp_mb();
}
#[inline(always)]
pub fn isb() {
arch_isb();
}
#[inline(always)]
fn dummy_cpu_on(cpu: usize, _entry_point: usize) -> bool {
cpu == this_processor_id()
}
pub(crate) static mut PROCESSOR_CPU_ON: fn(usize, usize) -> bool = dummy_cpu_on;
#[inline(always)]
fn dummy_sys_restart() {}
pub(crate) static mut PROCESSOR_SYS_RESTART: fn() = dummy_sys_restart;
#[inline(always)]
fn dummy_sys_poweroff() {}
pub(crate) static mut PROCESSOR_SYS_POWEROFF: fn() = dummy_sys_poweroff;
pub fn machine_power_off() -> ! {
local_irq_disable();
smp_send_stop();
unsafe {
PROCESSOR_SYS_POWEROFF();
}
println!("Power off failed -- System halted");
loop {
cpu_relax();
}
}
pub fn machine_restart() -> ! {
local_irq_disable();
smp_send_stop();
unsafe {
PROCESSOR_SYS_RESTART();
}
println!("Reboot failed -- System halted");
loop {
cpu_relax();
}
}