yggdrasil/src/arch/mod.rs

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;
}