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