68 lines
2.2 KiB
Rust
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 _ }
|
|
}
|