Files
yggdrasil/kernel/src/mem/mod.rs
T

68 lines
2.2 KiB
Rust

//! Memory management utilities and types
use core::{
ffi::c_void,
mem::{align_of, size_of},
};
use libk_mm::{address::PhysicalAddress, device::DeviceMemoryMapping};
/// Offset applied to the physical kernel image when translating it into the virtual address space
pub const KERNEL_VIRT_OFFSET: usize = kernel_arch::KERNEL_VIRT_OFFSET;
/// Reads a value from an arbitrary physical address.
///
/// # Safety
///
/// The caller must ensure the correct origin of the address, its alignment and that the access is
/// properly synchronized.
pub unsafe fn read_memory<T>(address: PhysicalAddress) -> T {
let io =
unsafe { DeviceMemoryMapping::map(address, size_of::<T>(), Default::default()).unwrap() };
let address = io.address();
if address.is_multiple_of(align_of::<T>()) {
unsafe { (address as *const T).read_volatile() }
} else {
unsafe { (address as *const T).read_unaligned() }
}
}
/// Writes a value to an arbitrary physical address.
///
/// # Safety
///
/// The caller must ensure the correct origin of the address, its alignment and that the access is
/// properly synchronized.
pub unsafe fn write_memory<T>(address: PhysicalAddress, value: T) {
let io =
unsafe { DeviceMemoryMapping::map(address, size_of::<T>(), Default::default()).unwrap() };
let address = io.address();
if address.is_multiple_of(align_of::<T>()) {
unsafe { (address as *mut T).write_volatile(value) }
} else {
unsafe { (address as *mut T).write_unaligned(value) }
}
}
#[unsafe(no_mangle)]
unsafe extern "C" fn memcpy(p0: *mut c_void, p1: *const c_void, len: usize) -> *mut c_void {
unsafe { compiler_builtins::mem::memcpy(p0 as _, p1 as _, len) as _ }
}
#[unsafe(no_mangle)]
unsafe extern "C" fn memcmp(p0: *const c_void, p1: *const c_void, len: usize) -> i32 {
unsafe { compiler_builtins::mem::memcmp(p0 as _, p1 as _, len) }
}
#[unsafe(no_mangle)]
unsafe extern "C" fn memmove(dst: *mut c_void, src: *const c_void, len: usize) -> *mut c_void {
unsafe { compiler_builtins::mem::memmove(dst as _, src as _, len) as _ }
}
#[unsafe(no_mangle)]
unsafe extern "C" fn memset(dst: *mut c_void, val: i32, len: usize) -> *mut c_void {
unsafe { compiler_builtins::mem::memset(dst as _, val, len) as _ }
}