1use crate::{AsHandleRef, Handle, HandleBased, HandleRef, Resource, Status, ok, sys};
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 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(Handle::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 =
70 Iommu::create_stub(&Resource::from(Handle::invalid()), IommuDescStub::default());
71 assert_eq!(status, Err(Status::BAD_HANDLE));
72 }
73
74 #[test]
75 fn iommu_create_valid() {
76 use zx::{Channel, HandleBased, MonotonicInstant};
77 let (client_end, server_end) = Channel::create();
78 connect_channel_to_protocol::<fkernel::IommuResourceMarker>(server_end).unwrap();
79 let service = fkernel::IommuResourceSynchronousProxy::new(client_end);
80 let resource =
81 service.get(MonotonicInstant::INFINITE).expect("couldn't get iommu resource");
82 let resource = unsafe { Resource::from(Handle::from_raw(resource.into_raw())) };
86 let iommu = Iommu::create_stub(&resource, IommuDescStub::default()).unwrap();
87 assert!(!iommu.as_handle_ref().is_invalid());
88
89 let info = iommu.as_handle_ref().basic_info().unwrap();
90 assert_eq!(info.object_type, ObjectType::IOMMU);
91 }
92}