1#![warn(missing_docs)]
6
7use std::ops::Deref;
10use zx::sys::{zx_handle_t, zx_paddr_t};
11
12mod ffi;
13
14#[derive(Debug)]
16pub struct FakeBti(zx::Bti);
17
18impl Deref for FakeBti {
19 type Target = zx::Bti;
20
21 fn deref(&self) -> &Self::Target {
22 &self.0
23 }
24}
25
26impl FakeBti {
27 #[inline(always)]
29 pub fn phys_addr() -> usize {
30 unsafe { ffi::g_fake_bti_phys_addr }
32 }
33
34 pub fn create() -> Result<Self, zx::Status> {
36 let handle = {
37 let mut raw_handle = zx_handle_t::default();
38 unsafe {
40 zx::ok(ffi::fake_bti_create(&mut raw_handle))?;
41 }
42 unsafe { zx::NullableHandle::from_raw(raw_handle) }
44 };
45 Ok(Self(handle.into()))
46 }
47
48 pub fn set_paddrs(&self, paddrs: &[zx_paddr_t]) {
52 unsafe {
54 zx::ok(ffi::fake_bti_set_paddrs(self.0.raw_handle(), paddrs.as_ptr(), paddrs.len()))
56 .unwrap();
57 }
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[fuchsia::test]
66 fn create() {
67 let bti = FakeBti::create().expect("create failed");
68 let info = bti.info().expect("info failed");
69 assert!(info.minimum_contiguity > 0);
70 }
71
72 #[fuchsia::test]
73 fn pin_vmo() {
74 let bti = FakeBti::create().expect("create failed");
75 let vmo = zx::Vmo::create(16384).expect("create VMO failed");
76 let mut paddrs = [zx_paddr_t::default(); 4];
77 let _pmt = bti
78 .pin(zx::BtiOptions::PERM_READ, &vmo, 0, 16384, &mut paddrs[..])
79 .expect("pin failed");
80
81 let expected = FakeBti::phys_addr();
82 assert_eq!(paddrs, [expected, expected, expected, expected]);
83 }
84
85 #[fuchsia::test]
86 fn create_and_pin_contiguous_vmo() {
87 let bti = FakeBti::create().expect("create failed");
88 let vmo = zx::Vmo::create_contiguous(&bti, 16384, 0).expect("create contiguous VMO failed");
89 let mut paddr = [zx_paddr_t::default()];
90 let _pmt = bti
91 .pin(
92 zx::BtiOptions::PERM_READ | zx::BtiOptions::CONTIGUOUS,
93 &vmo,
94 0,
95 16384,
96 &mut paddr[..],
97 )
98 .expect("pin failed");
99
100 assert_eq!(paddr, [FakeBti::phys_addr()]);
101 }
102
103 #[fuchsia::test]
104 fn pin_with_paddrs() {
105 let bti = FakeBti::create().expect("create failed");
106 bti.set_paddrs(&[4096, 16384, 65536]);
107 let vmo = zx::Vmo::create(3 * 4096).expect("create VMO failed");
108 {
109 let mut paddrs = [zx_paddr_t::default(); 3];
110 let _pmt = bti
111 .pin(zx::BtiOptions::PERM_READ, &vmo, 0, 3 * 4096, &mut paddrs[..])
112 .expect("pin failed");
113 assert_eq!(paddrs, [4096, 16384, 65536]);
114 }
115 bti.set_paddrs(&[4096, 8192]);
116 {
117 let mut paddrs = [zx_paddr_t::default(); 2];
118 let _pmt = bti
119 .pin(zx::BtiOptions::PERM_READ, &vmo, 0, 2 * 4096, &mut paddrs[..])
120 .expect("pin failed");
121 assert_eq!(paddrs, [4096, 8192]);
122 }
123 }
124}