twizzler_driver/dma/
object.rs1use std::sync::Mutex;
2
3use twizzler::object::{ObjID, Object};
4use twizzler_abi::{
5 kso::{KactionCmd, KactionFlags, KactionGenericCmd},
6 object::{MAX_SIZE, NULLPAGE_SIZE},
7 syscall::sys_kaction,
8};
9
10use super::{Access, DeviceSync, DmaOptions, DmaRegion, DmaSliceRegion};
11
12pub struct DmaObject {
16 obj: Object<()>,
17 pub(crate) releasable_pins: Mutex<Vec<u32>>,
18}
19
20impl DmaObject {
21 fn _slice_region<T: DeviceSync>(
25 &self,
26 len: usize,
27 access: Access,
28 options: DmaOptions,
29 ) -> DmaSliceRegion<T> {
30 let nr_bytes = core::mem::size_of::<T>()
31 .checked_mul(len)
32 .expect("Value of len too large");
33 assert!(nr_bytes < MAX_SIZE - NULLPAGE_SIZE * 2);
34 DmaSliceRegion::new(
35 core::mem::size_of::<T>() * len,
36 access,
37 options,
38 NULLPAGE_SIZE,
39 len,
40 None,
41 )
42 }
43
44 fn _region<T: DeviceSync>(&self, access: Access, options: DmaOptions) -> DmaRegion<T> {
48 DmaRegion::new(
49 core::mem::size_of::<T>(),
50 access,
51 options,
52 NULLPAGE_SIZE,
53 None,
54 )
55 }
56
57 pub fn object(&self) -> &Object<()> {
59 &self.obj
60 }
61
62 pub fn new<T>(obj: Object<T>) -> Self {
64 Self {
65 obj: unsafe { obj.cast() },
66 releasable_pins: Mutex::new(Vec::new()),
67 }
68 }
69}
70
71pub(crate) fn release_pin(id: ObjID, token: u32) {
72 let _ = sys_kaction(
73 KactionCmd::Generic(KactionGenericCmd::ReleasePin),
74 Some(id),
75 token as u64,
76 0,
77 KactionFlags::empty(),
78 );
79}
80
81impl Drop for DmaObject {
82 fn drop(&mut self) {
83 let pins = self.releasable_pins.lock().unwrap();
84 for pin in &*pins {
85 release_pin(self.object().id(), *pin);
86 }
87 }
88}
89
90impl<T> From<Object<T>> for DmaObject {
91 fn from(obj: Object<T>) -> Self {
92 Self::new(obj)
93 }
94}