blob: b283785d83c2c2cf6602048b24d0bc32c6e6a6c8 [file]
// Copyright 2026 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use super::vm_object::VmObject;
use core::marker::{PhantomData, PhantomPinned};
use core::ptr::NonNull;
use fbl::RefPtr;
use kalloc::AllocError;
use kernel::types::PAddr;
use zx_status::Status;
#[repr(C)]
/// VMO representing a physical range of memory
pub struct VmObjectPhysical {
_data: [u8; 0],
_marker: PhantomData<PhantomPinned>,
}
unsafe extern "C" {
fn cpp_vm_object_physical_get_ref_counted(vmo: *const VmObjectPhysical)
-> *mut fbl::RefCounted;
fn cpp_vm_object_physical_free(vmo: *mut VmObjectPhysical);
fn cpp_vm_object_physical_create(
base: PAddr,
size: usize,
out_status: *mut i32,
) -> *mut VmObjectPhysical;
fn cpp_vm_object_physical_as_vm_object(vmo: *mut VmObjectPhysical) -> *mut VmObject;
}
impl VmObjectPhysical {
/// Create a new physical VMO for the given physical region.
pub fn create(base: PAddr, size: usize) -> Result<RefPtr<VmObjectPhysical>, Status> {
let mut status = 0;
let raw = unsafe { cpp_vm_object_physical_create(base, size, &mut status) };
Status::ok(status)?;
unsafe { RefPtr::try_from_raw(raw).ok_or(Status::NO_MEMORY) }
}
/// Cast a pointer to a VmObjectPhysical to its base VmObject.
pub fn cast(vmo: NonNull<VmObjectPhysical>) -> NonNull<VmObject> {
unsafe { NonNull::new_unchecked(cpp_vm_object_physical_as_vm_object(vmo.as_ptr())) }
}
}
impl fbl::HasRefCount for VmObjectPhysical {
fn ref_count(&self) -> &fbl::RefCounted {
unsafe { &*cpp_vm_object_physical_get_ref_counted(self as *const _) }
}
}
unsafe impl fbl::Recyclable for VmObjectPhysical {
unsafe fn recycle(ptr: NonNull<Self>) {
unsafe {
cpp_vm_object_physical_free(ptr.as_ptr());
}
}
fn allocate(_value: Self) -> Result<NonNull<Self>, AllocError> {
Err(AllocError)
}
}