use crate::{error::EfiError, pi::protocols::cpu_arch::CpuFlushType};
use core::num::NonZeroU64;
use r_efi::efi;
cfg_if::cfg_if! {
if #[cfg(not(target_os = "uefi"))] {
#[cfg_attr(coverage, coverage(off))]
pub mod stub;
type Arch = stub::StubArch;
#[doc(hidden)]
pub use stub::*;
} else if #[cfg(target_arch = "aarch64")] {
#[cfg_attr(coverage, coverage(off))] pub mod aarch64;
type Arch = aarch64::AArch64;
} else if #[cfg(target_arch = "x86_64")] {
#[cfg_attr(coverage, coverage(off))] pub mod x64;
type Arch = x64::X64;
}
}
#[allow(unused)]
trait ArchSupport: Interrupts + CacheMgmt + Timer {}
trait Interrupts {
fn enable_interrupts();
fn disable_interrupts();
fn interrupts_enabled() -> bool;
fn enable_interrupts_and_sleep();
}
#[cfg(feature = "core")]
pub fn enable_interrupts() {
<Arch as Interrupts>::enable_interrupts();
}
#[cfg(feature = "core")]
pub fn disable_interrupts() {
<Arch as Interrupts>::disable_interrupts();
}
pub fn interrupts_enabled() -> bool {
<Arch as Interrupts>::interrupts_enabled()
}
pub fn enable_interrupts_and_sleep() {
<Arch as Interrupts>::enable_interrupts_and_sleep()
}
pub(crate) fn with_interrupts_disabled<F, R>(f: F) -> R
where
F: FnOnce() -> R,
{
let enabled = <Arch as Interrupts>::interrupts_enabled();
if enabled {
<Arch as Interrupts>::disable_interrupts();
}
let result = f();
if enabled {
<Arch as Interrupts>::enable_interrupts();
}
result
}
trait CacheMgmt {
fn flush_data_cache(start: efi::PhysicalAddress, length: u64, flush_type: CpuFlushType) -> Result<(), EfiError>;
fn cache_writeback_granule() -> u32;
}
trait Timer {
fn get_timer_value() -> u64;
fn get_timer_frequency() -> Option<NonZeroU64>;
}
pub fn flush_data_cache(start: efi::PhysicalAddress, length: u64, flush_type: CpuFlushType) -> Result<(), EfiError> {
<Arch as CacheMgmt>::flush_data_cache(start, length, flush_type)
}
pub fn get_timer_value() -> u64 {
<Arch as Timer>::get_timer_value()
}
pub fn get_timer_frequency() -> Option<NonZeroU64> {
<Arch as Timer>::get_timer_frequency()
}
pub fn cache_writeback_granule() -> u32 {
<Arch as CacheMgmt>::cache_writeback_granule()
}