use crate::{ok, AsHandleRef, Handle, HandleBased, HandleRef, Iommu, Status};
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(transparent)]
pub struct Bti(Handle);
impl_handle_based!(Bti);
impl Bti {
pub fn create(iommu: &Iommu, id: u64) -> Result<Bti, Status> {
let mut bti_handle = crate::sys::zx_handle_t::default();
let status = unsafe {
crate::sys::zx_bti_create(iommu.raw_handle(), 0, id, &mut bti_handle)
};
ok(status)?;
unsafe {
Ok(Bti::from(Handle::from_raw(bti_handle)))
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{IommuDescDummy, ObjectType, Resource, Vmo};
use fidl_fuchsia_kernel as fkernel;
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 zx::{Channel, HandleBased, MonotonicInstant};
let (client_end, server_end) = Channel::create();
connect_channel_to_protocol::<fkernel::IommuResourceMarker>(server_end).unwrap();
let service = fkernel::IommuResourceSynchronousProxy::new(client_end);
let resource =
service.get(MonotonicInstant::INFINITE).expect("couldn't get iommu resource");
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);
}
}