86 lines
2.5 KiB
Rust
86 lines
2.5 KiB
Rust
//! Provides architecture/platform-specific implementation details
|
|
|
|
use abi::error::Error;
|
|
use cfg_if::cfg_if;
|
|
|
|
/// Returns an absolute address to the given symbol
|
|
#[macro_export]
|
|
macro_rules! absolute_address {
|
|
($sym:expr) => {{
|
|
let mut _x: usize;
|
|
#[cfg(target_arch = "aarch64")]
|
|
unsafe {
|
|
core::arch::asm!("ldr {0}, ={1}", out(reg) _x, sym $sym);
|
|
}
|
|
#[cfg(target_arch = "x86_64")]
|
|
unsafe {
|
|
core::arch::asm!("movabsq ${1}, {0}", out(reg) _x, sym $sym, options(att_syntax));
|
|
}
|
|
_x
|
|
}};
|
|
}
|
|
|
|
pub mod aarch64;
|
|
cfg_if! {
|
|
if #[cfg(target_arch = "aarch64")] {
|
|
|
|
pub use aarch64::{AArch64 as ArchitectureImpl, ARCHITECTURE, PlatformImpl, PLATFORM};
|
|
} else if #[cfg(target_arch = "x86_64")] {
|
|
pub mod x86_64;
|
|
|
|
pub use x86_64::{
|
|
X86_64 as ArchitectureImpl,
|
|
X86_64 as PlatformImpl,
|
|
ARCHITECTURE,
|
|
ARCHITECTURE as PLATFORM
|
|
};
|
|
} else {
|
|
compile_error!("Architecture is not supported");
|
|
}
|
|
}
|
|
|
|
/// Describes messages sent from some CPU to others
|
|
#[derive(Clone, Copy, PartialEq, Debug)]
|
|
#[repr(u64)]
|
|
pub enum CpuMessage {
|
|
/// Indicates that the sender CPU entered kernel panic and wants other CPUs to follow
|
|
Panic,
|
|
}
|
|
|
|
/// Interface for an architecture-specific facilities
|
|
pub trait Architecture {
|
|
/// Address, to which "zero" address is mapped in the virtual address space
|
|
const KERNEL_VIRT_OFFSET: usize;
|
|
|
|
/// Initializes the memory management unit and sets up virtual memory management.
|
|
/// `bsp` flag is provided to make sure mapping tables are only initialized once in a SMP
|
|
/// system.
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// Unsafe to call if the MMU has already been initialized.
|
|
unsafe fn init_mmu(&self, bsp: bool);
|
|
|
|
/// Allocates a virtual mapping for the specified physical memory region
|
|
fn map_device_pages(&self, phys: usize, count: usize) -> Result<usize, Error>;
|
|
|
|
// Architecture intrinsics
|
|
|
|
/// Suspends CPU until an interrupt is received
|
|
fn wait_for_interrupt();
|
|
|
|
/// Sets the local CPU's interrupt mask.
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// Enabling interrupts may lead to unexpected behavior unless the context explicitly expects
|
|
/// them.
|
|
unsafe fn set_interrupt_mask(mask: bool);
|
|
|
|
/// Returns the local CPU's interrupt mask
|
|
fn interrupt_mask() -> bool;
|
|
|
|
/// Returns the count of present CPUs, including the BSP
|
|
fn cpu_count() -> usize;
|
|
}
|