mod cpu_arch_protocol;
#[cfg(all(target_os = "uefi", target_arch = "aarch64"))]
mod hw_interrupt_protocol;
mod perf_timer;
pub(crate) use cpu_arch_protocol::CpuArchProtocolInstaller;
#[cfg(all(target_os = "uefi", target_arch = "aarch64"))]
pub(crate) use hw_interrupt_protocol::HwInterruptProtocolInstaller;
pub(crate) use perf_timer::PerfTimer;
use patina_internal_cpu::{cpu::EfiCpu, interrupts::Interrupts};
#[derive(Debug, PartialEq)]
pub struct GicBases {
pub(crate) gicd: u64,
pub(crate) gicr: u64,
}
impl GicBases {
#[coverage(off)]
pub unsafe fn new(gicd_base: u64, gicr_base: u64) -> Self {
GicBases { gicd: gicd_base, gicr: gicr_base }
}
}
#[cfg_attr(test, mockall::automock)]
pub trait CpuInfo {
#[cfg(target_arch = "aarch64")]
fn gic_bases() -> GicBases;
#[inline(always)]
fn perf_timer_frequency() -> Option<u64> {
None
}
}
#[coverage(off)]
pub fn initialize_cpu_subsystem() -> crate::error::Result<(EfiCpu, Interrupts)> {
let mut cpu = EfiCpu::default();
cpu.initialize().inspect_err(|err| {
log::error!("Failed to initialize CPU subsystem: {:?}", err);
})?;
let mut interrupt_manager = Interrupts::new();
interrupt_manager.initialize().inspect_err(|err| {
log::error!("Failed to initialize Interrupt Manager: {:?}", err);
})?;
Ok((cpu, interrupt_manager))
}
#[cfg(test)]
#[coverage(off)]
mod tests {
use super::*;
#[test]
fn test_cpu_info_trait_defaults_do_not_change() {
struct TestPlatform;
impl CpuInfo for TestPlatform {
#[cfg(target_arch = "aarch64")]
fn gic_bases() -> GicBases {
unsafe { GicBases::new(0, 0) }
}
}
assert!(<TestPlatform as CpuInfo>::perf_timer_frequency().is_none());
}
}