1use core::ptr::NonNull;
2
3use safa_abi::errors::ErrorStatus;
4use safa_abi::mem::{MemMapFlags, RawMemMapConfig};
5
6use crate::syscalls::types::{IntoSyscallArg, Ri};
7
8use super::types::{OptionalPtrMut, RequiredPtr};
9use super::SyscallNum;
10
11impl IntoSyscallArg for MemMapFlags {
12 type RegResults = (usize,);
13 fn into_syscall_arg(self) -> Self::RegResults {
14 (unsafe { core::mem::transmute::<_, u8>(self) } as usize,)
15 }
16}
17
18define_syscall! {
19 SyscallNum::SysMemMap => {
20 sysmem_map(memmap_config: RequiredPtr<RawMemMapConfig>, flags: MemMapFlags, out_res_id: OptionalPtrMut<Ri>, out_start_addr: OptionalPtrMut<NonNull<u8>>)
22 }
23}
24
25pub fn map(
31 addr_hint: *const (),
32 page_count: usize,
33 guard_pages_count: usize,
34 resource_to_map: Option<Ri>,
35 resource_off: Option<isize>,
36 mut flags: MemMapFlags,
37) -> Result<(Ri, NonNull<[u8]>), ErrorStatus> {
38 let (ri, off) = if let Some(ri) = resource_to_map {
39 let off = resource_off.unwrap_or_default();
40 flags = flags | MemMapFlags::MAP_RESOURCE;
41 (ri, off)
42 } else {
43 (0, 0)
44 };
45
46 let conf = RawMemMapConfig {
47 resource_off: off,
48 resource_to_map: ri,
49 guard_pages_count,
50 page_count,
51 addr_hint,
52 };
53
54 let mut res_id_results = 0xAAAAAAAAAAAAAAAAusize;
55 let mut start_addr_results =
56 unsafe { NonNull::new_unchecked(0xAAAAAAAAAAAAAAAAusize as *mut u8) };
57 let (result_ri, result_start_addr) = unsafe {
58 err_from_u16!(
59 sysmem_map(
60 RequiredPtr::new_unchecked(&raw const conf as *mut _),
61 flags,
62 RequiredPtr::new(&raw mut res_id_results).into(),
63 RequiredPtr::new(&raw mut start_addr_results).into()
64 ),
65 (res_id_results, start_addr_results)
66 )?
67 };
68
69 let len = page_count * 4096;
71 let slice = unsafe { core::slice::from_raw_parts_mut(result_start_addr.as_ptr(), len) };
72
73 unsafe { Ok((result_ri, NonNull::new_unchecked(slice))) }
74}