#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum UserAccessError {
Fault,
}
#[repr(u32)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum UserAtomicU32Op {
Set = 0,
Add = 1,
Or = 2,
AndNot = 3,
Xor = 4,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum UserAtomicError {
Fault,
Retry,
}
unsafe extern "C" {
fn __axcpu_user_read_u32(address: *const u32, value: *mut u32) -> u32;
fn __axcpu_user_atomic_u32(
address: *mut u32,
operation: u32,
argument: u32,
old_value: *mut u32,
) -> u32;
}
pub unsafe fn user_read_u32(address: *const u32) -> Result<u32, UserAccessError> {
let mut value = 0;
let status = unsafe { __axcpu_user_read_u32(address, &mut value) };
match status {
0 => Ok(value),
1 => Err(UserAccessError::Fault),
_ => unreachable!("architecture returned an invalid user read status"),
}
}
pub unsafe fn user_atomic_u32(
address: *mut u32,
operation: UserAtomicU32Op,
argument: u32,
) -> Result<u32, UserAtomicError> {
let mut old_value = 0;
let status =
unsafe { __axcpu_user_atomic_u32(address, operation as u32, argument, &mut old_value) };
match status {
0 => Ok(old_value),
1 => Err(UserAtomicError::Fault),
2 => Err(UserAtomicError::Retry),
_ => unreachable!("architecture returned an invalid user atomic status"),
}
}