Skip to main content

vm/
vm_object_physical.rs

1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use super::vm_object::VmObject;
6use core::marker::{PhantomData, PhantomPinned};
7use core::ptr::NonNull;
8use fbl::RefPtr;
9use kalloc::AllocError;
10use kernel::types::PAddr;
11use zx_status::Status;
12
13#[repr(C)]
14/// VMO representing a physical range of memory
15pub struct VmObjectPhysical {
16    _data: [u8; 0],
17    _marker: PhantomData<PhantomPinned>,
18}
19
20unsafe extern "C" {
21    fn cpp_vm_object_physical_get_ref_counted(vmo: *const VmObjectPhysical)
22    -> *mut fbl::RefCounted;
23    fn cpp_vm_object_physical_free(vmo: *mut VmObjectPhysical);
24    fn cpp_vm_object_physical_create(
25        base: PAddr,
26        size: usize,
27        out_status: *mut i32,
28    ) -> *mut VmObjectPhysical;
29    fn cpp_vm_object_physical_as_vm_object(vmo: *mut VmObjectPhysical) -> *mut VmObject;
30}
31
32impl VmObjectPhysical {
33    /// Create a new physical VMO for the given physical region.
34    pub fn create(base: PAddr, size: usize) -> Result<RefPtr<VmObjectPhysical>, Status> {
35        let mut status = 0;
36        let raw = unsafe { cpp_vm_object_physical_create(base, size, &mut status) };
37        Status::ok(status)?;
38        unsafe { RefPtr::try_from_raw(raw).ok_or(Status::NO_MEMORY) }
39    }
40
41    /// Cast a pointer to a VmObjectPhysical to its base VmObject.
42    pub fn cast(vmo: NonNull<VmObjectPhysical>) -> NonNull<VmObject> {
43        unsafe { NonNull::new_unchecked(cpp_vm_object_physical_as_vm_object(vmo.as_ptr())) }
44    }
45}
46
47impl fbl::HasRefCount for VmObjectPhysical {
48    fn ref_count(&self) -> &fbl::RefCounted {
49        unsafe { &*cpp_vm_object_physical_get_ref_counted(self as *const _) }
50    }
51}
52
53unsafe impl fbl::Recyclable for VmObjectPhysical {
54    unsafe fn recycle(ptr: NonNull<Self>) {
55        unsafe {
56            cpp_vm_object_physical_free(ptr.as_ptr());
57        }
58    }
59
60    fn allocate(_value: Self) -> Result<NonNull<Self>, AllocError> {
61        Err(AllocError)
62    }
63}