88 lines
2.6 KiB
Rust

//! Provides architecture/platform-specific implementation details
use abi::error::Error;
use device_api::{
interrupt::{IpiDeliveryTarget, IpiMessage},
ResetDevice,
};
use kernel_arch::{Architecture, ArchitectureImpl};
use libk_mm::table::EntryLevel;
#[cfg(any(target_arch = "aarch64", rust_analyzer))]
pub mod aarch64;
#[cfg(any(target_arch = "aarch64", rust_analyzer))]
pub use aarch64::{AArch64 as PlatformImpl, PLATFORM};
#[cfg(any(target_arch = "x86_64", target_arch = "x86", rust_analyzer))]
pub mod x86;
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
pub mod x86_64;
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
pub use x86_64::{PLATFORM, X86_64 as PlatformImpl};
#[cfg(any(target_arch = "x86", rust_analyzer))]
pub mod i686;
#[cfg(any(target_arch = "x86", rust_analyzer))]
pub use i686::{I686 as PlatformImpl, PLATFORM};
#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "x86")))]
compile_error!("Unsupported architecture");
/// Architecture-specific lowest level of page mapping
pub type L3 = <PlatformImpl as Platform>::L3;
// Architecture interfaces
/// Interface for an architecture-specific facilities
#[allow(unused)]
pub trait Platform {
/// Address, to which "zero" address is mapped in the virtual address space
const KERNEL_VIRT_OFFSET: usize;
/// Lowest page entry level, usually 4KiB pages
type L3: EntryLevel;
/// Starts up the application processors that may be present in the system.
///
/// # Safety
///
/// Only safe to call once during system init.
unsafe fn start_application_processors(&self) {}
// Architecture intrinsics
/// Adds a reset device to the system
fn register_reset_device(&self, reset: &'static dyn ResetDevice) -> Result<(), Error> {
Err(Error::NotImplemented)
}
/// Sends a message to the requested set of CPUs through an interprocessor interrupt.
///
/// # Note
///
/// u64 limits the number of targetable CPUs to (only) 64. Platform-specific implementations
/// may impose narrower restrictions.
///
/// # Safety
///
/// As the call may alter the flow of execution on CPUs, this function is unsafe.
unsafe fn send_ipi(&self, target: IpiDeliveryTarget, msg: IpiMessage) -> Result<(), Error> {
Ok(())
}
/// Performs a CPU reset.
///
/// # Safety
///
/// The caller must ensure it is actually safe to reset, i.e. no critical processes will be
/// aborted and no data will be lost.
unsafe fn reset(&self) -> ! {
ArchitectureImpl::set_interrupt_mask(true);
loop {
ArchitectureImpl::wait_for_interrupt();
}
}
}