blob: e63cbc677fa3f1bb5fe9498eb6836bf166be2b57 [file] [log] [blame]
// Copyright 2022 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 bti objects.
use crate::ok;
use crate::{AsHandleRef, Handle, HandleBased, HandleRef, Iommu, Status};
use fuchsia_zircon_sys as sys;
/// An object representing a Zircon Bus Transaction Initiator object.
/// See [BTI Documentation](https://fuchsia.dev/fuchsia-src/reference/kernel_objects/bus_transaction_initiator) for details.
///
/// As essentially a subtype of `Handle`, it can be freely interconverted.
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(transparent)]
pub struct Bti(Handle);
impl_handle_based!(Bti);
impl Bti {
// Create a Bus Transaction Initiator object.
// Wraps the
// [`zx_bti_create`](https://fuchsia.dev/fuchsia-src/reference/syscalls/bti_create) system call to create a bti.
pub fn create(iommu: &Iommu, id: u64) -> Result<Bti, Status> {
let mut bti_handle = sys::zx_handle_t::default();
let status = unsafe {
// SAFETY: regular system call with no unsafe parameters.
sys::zx_bti_create(iommu.raw_handle(), 0, id, &mut bti_handle)
};
ok(status)?;
unsafe {
// SAFETY: The syscall docs claim that upon success, bti_handle will be a valid
// handle to bti object.
Ok(Bti::from(Handle::from_raw(bti_handle)))
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{IommuDescDummy, ObjectType, Resource, Vmo};
use fidl_fuchsia_boot as fboot;
use fuchsia_component::client::connect_channel_to_protocol;
#[test]
fn create_bti_invalid_handle() {
let status = Bti::create(&Iommu::from(Handle::invalid()), 0);
assert_eq!(status, Err(Status::BAD_HANDLE));
}
#[test]
fn create_bti_wrong_handle() {
let vmo = Vmo::create(0).unwrap();
let wrong_handle = unsafe { Iommu::from(Handle::from_raw(vmo.into_raw())) };
let status = Bti::create(&wrong_handle, 0);
assert_eq!(status, Err(Status::WRONG_TYPE));
}
fn create_iommu() -> Iommu {
use fuchsia_zircon::{Channel, HandleBased, Time};
let (client_end, server_end) = Channel::create();
connect_channel_to_protocol::<fboot::RootResourceMarker>(server_end).unwrap();
let service = fboot::RootResourceSynchronousProxy::new(client_end);
let resource = service.get(Time::INFINITE).expect("couldn't get root resource");
// This test and fuchsia-zircon are different crates, so we need
// to use from_raw to convert between the fuchsia_zircon handle and this test handle.
// See https://fxbug.dev/42173139 for details.
let resource = unsafe { Resource::from(Handle::from_raw(resource.into_raw())) };
Iommu::create_dummy(&resource, IommuDescDummy::default()).unwrap()
}
#[test]
fn create_from_valid_iommu() {
let iommu = create_iommu();
let bti = Bti::create(&iommu, 0).unwrap();
let info = bti.as_handle_ref().basic_info().unwrap();
assert_eq!(info.object_type, ObjectType::BTI);
}
}