1use crate::{ok, AsHandleRef, Handle, HandleBased, HandleRef, Iommu, Status};
8
9#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
14#[repr(transparent)]
15pub struct Bti(Handle);
16impl_handle_based!(Bti);
17
18impl Bti {
19 pub fn create(iommu: &Iommu, id: u64) -> Result<Bti, Status> {
23 let mut bti_handle = crate::sys::zx_handle_t::default();
24 let status = unsafe {
25 crate::sys::zx_bti_create(iommu.raw_handle(), 0, id, &mut bti_handle)
27 };
28 ok(status)?;
29 unsafe {
30 Ok(Bti::from(Handle::from_raw(bti_handle)))
33 }
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40 use crate::{IommuDescDummy, ObjectType, Resource, Vmo};
41 use fidl_fuchsia_kernel as fkernel;
42 use fuchsia_component::client::connect_channel_to_protocol;
43
44 #[test]
45 fn create_bti_invalid_handle() {
46 let status = Bti::create(&Iommu::from(Handle::invalid()), 0);
47 assert_eq!(status, Err(Status::BAD_HANDLE));
48 }
49
50 #[test]
51 fn create_bti_wrong_handle() {
52 let vmo = Vmo::create(0).unwrap();
53 let wrong_handle = unsafe { Iommu::from(Handle::from_raw(vmo.into_raw())) };
54
55 let status = Bti::create(&wrong_handle, 0);
56 assert_eq!(status, Err(Status::WRONG_TYPE));
57 }
58
59 fn create_iommu() -> Iommu {
60 use zx::{Channel, HandleBased, MonotonicInstant};
61 let (client_end, server_end) = Channel::create();
62 connect_channel_to_protocol::<fkernel::IommuResourceMarker>(server_end).unwrap();
63 let service = fkernel::IommuResourceSynchronousProxy::new(client_end);
64 let resource =
65 service.get(MonotonicInstant::INFINITE).expect("couldn't get iommu resource");
66 let resource = unsafe { Resource::from(Handle::from_raw(resource.into_raw())) };
70 Iommu::create_dummy(&resource, IommuDescDummy::default()).unwrap()
71 }
72
73 #[test]
74 fn create_from_valid_iommu() {
75 let iommu = create_iommu();
76 let bti = Bti::create(&iommu, 0).unwrap();
77
78 let info = bti.as_handle_ref().basic_info().unwrap();
79 assert_eq!(info.object_type, ObjectType::BTI);
80 }
81}