1use crate::arch_vm_aspace::ArchMmuFlags;
6use crate::vm_object::VmObject;
7use core::marker::{PhantomData, PhantomPinned};
8use core::ptr::NonNull;
9use fbl::RefPtr;
10use kalloc::AllocError;
11use zx_status::Status;
12
13unsafe extern "C" {
14 fn cpp_vm_mapping_get_ref_counted(mapping: *mut VmMapping) -> *mut fbl::RefCounted;
15 fn cpp_vm_mapping_free(mapping: *mut VmMapping);
16 fn cpp_vm_mapping_destroy(mapping: *mut VmMapping) -> i32;
17 fn cpp_vm_mapping_base(mapping: *mut VmMapping) -> usize;
18 fn cpp_vm_mapping_size(mapping: *mut VmMapping) -> usize;
19 fn cpp_vm_mapping_flags(mapping: *mut VmMapping) -> u32;
20 fn cpp_vm_mapping_object_offset(mapping: *mut VmMapping) -> u64;
21 fn cpp_vm_mapping_decommit_range(mapping: *mut VmMapping, offset: usize, len: usize) -> i32;
22 fn cpp_vm_mapping_map_range(
23 mapping: *mut VmMapping,
24 offset: usize,
25 len: usize,
26 commit: bool,
27 ignore_existing: bool,
28 ) -> i32;
29 fn cpp_vm_mapping_debug_unmap(mapping: *mut VmMapping, base: usize, size: usize) -> i32;
30 fn cpp_vm_mapping_debug_protect(
31 mapping: *mut VmMapping,
32 base: usize,
33 size: usize,
34 new_arch_mmu_flags: ArchMmuFlags,
35 ) -> i32;
36 fn cpp_vm_mapping_vmo(mapping: *mut VmMapping) -> *const VmObject;
37}
38
39#[repr(C)]
43pub struct VmMapping {
44 _data: [u8; 0],
45 _marker: PhantomData<PhantomPinned>,
46}
47
48impl VmMapping {
49 fn as_mut_ptr(&self) -> *mut VmMapping {
50 self as *const VmMapping as *mut VmMapping
51 }
52
53 pub fn destroy(&self) -> Result<(), Status> {
55 Status::ok(unsafe { cpp_vm_mapping_destroy(self.as_mut_ptr()) })
56 }
57
58 pub fn base(&self) -> usize {
60 unsafe { cpp_vm_mapping_base(self.as_mut_ptr()) }
61 }
62
63 pub fn size(&self) -> usize {
65 unsafe { cpp_vm_mapping_size(self.as_mut_ptr()) }
66 }
67
68 pub fn flags(&self) -> u32 {
70 unsafe { cpp_vm_mapping_flags(self.as_mut_ptr()) }
71 }
72
73 pub fn object_offset(&self) -> u64 {
75 unsafe { cpp_vm_mapping_object_offset(self.as_mut_ptr()) }
76 }
77
78 pub fn decommit_range(&self, offset: usize, len: usize) -> Result<(), Status> {
81 Status::ok(unsafe { cpp_vm_mapping_decommit_range(self.as_mut_ptr(), offset, len) })
82 }
83
84 pub fn map_range(
90 &self,
91 offset: usize,
92 len: usize,
93 commit: bool,
94 ignore_existing: bool,
95 ) -> Result<(), Status> {
96 Status::ok(unsafe {
97 cpp_vm_mapping_map_range(self.as_mut_ptr(), offset, len, commit, ignore_existing)
98 })
99 }
100
101 pub fn debug_unmap(&self, base: usize, size: usize) -> Result<(), Status> {
103 Status::ok(unsafe { cpp_vm_mapping_debug_unmap(self.as_mut_ptr(), base, size) })
104 }
105
106 pub fn debug_protect(
108 &self,
109 base: usize,
110 size: usize,
111 new_arch_mmu_flags: ArchMmuFlags,
112 ) -> Result<(), Status> {
113 Status::ok(unsafe {
114 cpp_vm_mapping_debug_protect(self.as_mut_ptr(), base, size, new_arch_mmu_flags)
115 })
116 }
117
118 pub fn vmo(&self) -> Option<RefPtr<VmObject>> {
120 unsafe { RefPtr::try_from_raw(cpp_vm_mapping_vmo(self.as_mut_ptr())) }
121 }
122}
123
124impl fbl::HasRefCount for VmMapping {
125 fn ref_count(&self) -> &fbl::RefCounted {
126 unsafe { &*cpp_vm_mapping_get_ref_counted(self.as_mut_ptr()) }
127 }
128}
129
130unsafe impl fbl::Recyclable for VmMapping {
131 unsafe fn recycle(ptr: NonNull<Self>) {
132 unsafe {
133 cpp_vm_mapping_free(ptr.as_ptr());
134 }
135 }
136
137 fn allocate(_value: Self) -> Result<NonNull<Self>, AllocError> {
138 Err(AllocError)
139 }
140}