moana_std 0.1.4

moana 用户标准库
Documentation
//! mem 系列 syscall 用户态接口

use moa_uapi::{
    error::{
        ERR_BUSY, ERR_FAULT, ERR_INVAL, ERR_NO_RESOURCE, ERR_NOT_FOUND, ERR_NOT_SUPPORTED, ERR_PERM,
    },
    mem::{CacheOp, MemCreateArgs, MemHandle, Paddr},
    sysnr::{
        SYSNR_MEM_CACHE_OP, SYSNR_MEM_COPY, SYSNR_MEM_CREATE, SYSNR_MEM_PHYS_ADDR, SYSNR_MEM_READ,
        SYSNR_MEM_RELEASE, SYSNR_MEM_WRITE,
    },
};

/// mem 系列 syscall 返回类型
pub type Result<T> = core::result::Result<T, MemError>;

define_syscall_error! {
    /// mem 系列 syscall 错误
    pub enum MemError {
        /// 权限不足
        Perm = ERR_PERM,
        /// 句柄不存在
        NotFound = ERR_NOT_FOUND,
        /// 无效参数
        Inval = ERR_INVAL,
        /// 资源配额耗尽
        NoResource = ERR_NO_RESOURCE,
        /// 无效指针
        Fault = ERR_FAULT,
        /// 操作不支持
        NotSupported = ERR_NOT_SUPPORTED,
        /// 有活跃映射未释放
        Busy = ERR_BUSY,
    }
}

/// 创建内存对象
///
/// 通过 `MemCreateArgs::lazy` / `contiguous` / `pager` 构造参数。
pub fn mem_create(args: &MemCreateArgs) -> Result<MemHandle> {
    let ret =
        unsafe { super::arch::syscall1(SYSNR_MEM_CREATE, args as *const MemCreateArgs as usize) };
    if ret < 0 { Err(MemError::from_raw(ret)) } else { Ok(MemHandle::from_raw(ret as u32)) }
}

/// 释放内存对象
///
/// 需先 unmap 所有映射,有活跃映射时返回 `ERR_BUSY`。
pub fn mem_release(mem: MemHandle) -> Result<()> {
    let ret = unsafe { super::arch::syscall1(SYSNR_MEM_RELEASE, mem.raw() as usize) };
    if ret < 0 { Err(MemError::from_raw(ret)) } else { Ok(()) }
}

/// 写入内存对象
///
/// 将调用者 `data` 写入 `MemObject` 的 `offset` 处。
pub fn mem_write(mem: MemHandle, offset: usize, data: &[u8]) -> Result<()> {
    let ret = unsafe {
        super::arch::syscall4(
            SYSNR_MEM_WRITE,
            mem.raw() as usize,
            offset,
            data.as_ptr() as usize,
            data.len(),
        )
    };
    if ret < 0 { Err(MemError::from_raw(ret)) } else { Ok(()) }
}

/// 读取内存对象
///
/// 将 `MemObject` 的 `offset` 处数据读入调用者 `buf`。
pub fn mem_read(mem: MemHandle, offset: usize, buf: &mut [u8]) -> Result<()> {
    let ret = unsafe {
        super::arch::syscall4(
            SYSNR_MEM_READ,
            mem.raw() as usize,
            offset,
            buf.as_mut_ptr() as usize,
            buf.len(),
        )
    };
    if ret < 0 { Err(MemError::from_raw(ret)) } else { Ok(()) }
}

/// 内存对象间拷贝
///
/// 内核直接在物理页间拷贝,不经过用户态。
pub fn mem_copy(
    dst: MemHandle,
    dst_offset: usize,
    src: MemHandle,
    src_offset: usize,
    len: usize,
) -> Result<()> {
    let ret = unsafe {
        super::arch::syscall5(
            SYSNR_MEM_COPY,
            dst.raw() as usize,
            dst_offset,
            src.raw() as usize,
            src_offset,
            len,
        )
    };
    if ret < 0 { Err(MemError::from_raw(ret)) } else { Ok(()) }
}

/// 获取内存对象指定偏移处的物理地址
///
/// 仅 Contiguous 和 Physical 类型有效。
pub fn mem_phys_addr(mem: MemHandle, offset: usize) -> Result<Paddr> {
    let ret = unsafe { super::arch::syscall2(SYSNR_MEM_PHYS_ADDR, mem.raw() as usize, offset) };
    if ret < 0 { Err(MemError::from_raw(ret)) } else { Ok(Paddr::from_raw(ret as usize)) }
}

/// 对内存对象执行 cache 操作
///
/// 仅 Contiguous 和 Physical 类型有效(DMA 场景)。
pub fn mem_cache_op(mem: MemHandle, offset: usize, len: usize, op: CacheOp) -> Result<()> {
    let ret = unsafe {
        super::arch::syscall4(SYSNR_MEM_CACHE_OP, mem.raw() as usize, offset, len, op as usize)
    };
    if ret < 0 { Err(MemError::from_raw(ret)) } else { Ok(()) }
}