1use crate::{ok, sys, AsHandleRef, Handle, HandleBased, HandleRef, Resource, Status};
8
9#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
13#[repr(transparent)]
14pub struct Iommu(Handle);
15impl_handle_based!(Iommu);
16
17#[repr(C)]
19#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]
20pub struct IommuDescDummy {
21 padding1: u8,
22}
23
24impl Iommu {
25 pub fn create_dummy(resource: &Resource, desc: IommuDescDummy) -> Result<Iommu, Status> {
30 let mut iommu_handle = sys::zx_handle_t::default();
31 let status = unsafe {
32 sys::zx_iommu_create(
36 resource.raw_handle(),
37 sys::ZX_IOMMU_TYPE_DUMMY,
38 std::ptr::from_ref(&desc).cast::<u8>(),
39 std::mem::size_of_val(&desc),
40 &mut iommu_handle,
41 )
42 };
43 ok(status)?;
44 unsafe {
45 Ok(Iommu::from(Handle::from_raw(iommu_handle)))
48 }
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55 use crate::ObjectType;
56 use fidl_fuchsia_kernel as fkernel;
57 use fuchsia_component::client::connect_channel_to_protocol;
58
59 #[test]
60 fn iommu_create_invalid_resource() {
61 let status =
62 Iommu::create_dummy(&Resource::from(Handle::invalid()), IommuDescDummy::default());
63 assert_eq!(status, Err(Status::BAD_HANDLE));
64 }
65
66 #[test]
67 fn iommu_create_valid() {
68 use zx::{Channel, HandleBased, MonotonicInstant};
69 let (client_end, server_end) = Channel::create();
70 connect_channel_to_protocol::<fkernel::IommuResourceMarker>(server_end).unwrap();
71 let service = fkernel::IommuResourceSynchronousProxy::new(client_end);
72 let resource =
73 service.get(MonotonicInstant::INFINITE).expect("couldn't get iommu resource");
74 let resource = unsafe { Resource::from(Handle::from_raw(resource.into_raw())) };
78 let iommu = Iommu::create_dummy(&resource, IommuDescDummy::default()).unwrap();
79 assert!(!iommu.as_handle_ref().is_invalid());
80
81 let info = iommu.as_handle_ref().basic_info().unwrap();
82 assert_eq!(info.object_type, ObjectType::IOMMU);
83 }
84}