88 lines
2.6 KiB
Rust
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();
|
|
}
|
|
}
|
|
}
|