// Copyright 2017 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.

//! Type-safe bindings for Zircon vmar objects.

use bitflags::bitflags;
use crate::ok;
use crate::{AsHandleRef, Handle, HandleBased, HandleRef, Status, Unowned, Vmo};
use fuchsia_zircon_sys as sys;

/// An object representing a Zircon
/// [virtual memory address region](https://fuchsia.googlesource.com/zircon/+/master/docs/objects/vm_address_region.md).
///
/// As essentially a subtype of `Handle`, it can be freely interconverted.
#[derive(Debug, Eq, PartialEq)]
#[repr(transparent)]
pub struct Vmar(Handle);
impl_handle_based!(Vmar);

impl Vmar {
    pub fn root_self() -> Unowned<'static, Vmar> {
        unsafe {
            let handle = sys::zx_vmar_root_self();
            Unowned::from_raw_handle(handle)
        }
    }

    pub fn allocate(
        &self, offset: usize, size: usize, flags: VmarFlags,
    ) -> Result<(Vmar, usize), Status> {
        let mut mapped = 0;
        let mut handle = 0;
        let status = unsafe {
            sys::zx_vmar_allocate(
                self.raw_handle(),
                flags.bits(),
                offset,
                size,
                &mut handle,
                &mut mapped,
            )
        };
        ok(status)?;
        unsafe { Ok((Vmar::from(Handle::from_raw(handle)), mapped)) }
    }

    pub fn map(
        &self, vmar_offset: usize, vmo: &Vmo, vmo_offset: u64, len: usize, flags: VmarFlags,
    ) -> Result<usize, Status> {
        let flags = VmarFlagsExtended::from_bits_truncate(flags.bits());
        unsafe {
            self.map_unsafe(vmar_offset, vmo, vmo_offset, len, flags)
        }
    }

    /// Directly call zx_vmar_map.
    ///
    /// # Safety
    ///
    /// This function is unsafe because certain flags to `zx_vmar_map` may
    /// replace an existing mapping which is referenced elsewhere.
    pub unsafe fn map_unsafe(
        &self, vmar_offset: usize, vmo: &Vmo, vmo_offset: u64, len: usize,
        flags: VmarFlagsExtended,
    ) -> Result<usize, Status> {
        let mut mapped = 0;
        let status = sys::zx_vmar_map(
            self.0.raw_handle(),
            flags.bits(),
            vmar_offset,
            vmo.raw_handle(),
            vmo_offset,
            len,
            &mut mapped,
        );
        ok(status).map(|_| mapped)
    }

    pub unsafe fn unmap(&self, addr: usize, len: usize) -> Result<(), Status> {
        ok(sys::zx_vmar_unmap(self.0.raw_handle(), addr, len))
    }

    pub unsafe fn protect(&self, addr: usize, len: usize, flags: VmarFlags) -> Result<(), Status> {
        ok(sys::zx_vmar_protect(self.raw_handle(), flags.bits(), addr, len))
    }

    pub unsafe fn destroy(&self) -> Result<(), Status> {
        ok(sys::zx_vmar_destroy(self.raw_handle()))
    }
}

// TODO(smklein): Ideally we would have two separate sets of bitflags,
// and a union of both of them.
bitflags! {
    /// Flags to VMAR routines which are considered safe.
    #[repr(transparent)]
    pub struct VmarFlags: sys::zx_vm_option_t {
        const PERM_READ             = sys::ZX_VM_PERM_READ;
        const PERM_WRITE            = sys::ZX_VM_PERM_WRITE;
        const PERM_EXECUTE          = sys::ZX_VM_PERM_EXECUTE;
        const COMPACT               = sys::ZX_VM_COMPACT;
        const SPECIFIC              = sys::ZX_VM_SPECIFIC;
        const CAN_MAP_SPECIFIC      = sys::ZX_VM_CAN_MAP_SPECIFIC;
        const CAN_MAP_READ          = sys::ZX_VM_CAN_MAP_READ;
        const CAN_MAP_WRITE         = sys::ZX_VM_CAN_MAP_WRITE;
        const CAN_MAP_EXECUTE       = sys::ZX_VM_CAN_MAP_EXECUTE;
        const MAP_RANGE             = sys::ZX_VM_MAP_RANGE;
        const REQUIRE_NON_RESIZABLE = sys::ZX_VM_REQUIRE_NON_RESIZABLE;
    }
}

bitflags! {
    /// Flags to all VMAR routines.
    #[repr(transparent)]
    pub struct VmarFlagsExtended: sys::zx_vm_option_t {
        const PERM_READ          = sys::ZX_VM_PERM_READ;
        const PERM_WRITE         = sys::ZX_VM_PERM_WRITE;
        const PERM_EXECUTE       = sys::ZX_VM_PERM_EXECUTE;
        const COMPACT            = sys::ZX_VM_COMPACT;
        const SPECIFIC           = sys::ZX_VM_SPECIFIC;
        const SPECIFIC_OVERWRITE = sys::ZX_VM_SPECIFIC_OVERWRITE;
        const CAN_MAP_SPECIFIC   = sys::ZX_VM_CAN_MAP_SPECIFIC;
        const CAN_MAP_READ       = sys::ZX_VM_CAN_MAP_READ;
        const CAN_MAP_WRITE      = sys::ZX_VM_CAN_MAP_WRITE;
        const CAN_MAP_EXECUTE    = sys::ZX_VM_CAN_MAP_EXECUTE;
    }
}
