twizzler_driver/dma/
object.rs1use std::sync::{Arc, Mutex};
2
3use twizzler::object::{ObjID, Object, RawObject};
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
12#[derive(Clone)]
16pub struct DmaObject {
17 obj: Object<()>,
18 pub(crate) releasable_pins: Arc<Mutex<Vec<u32>>>,
19}
20
21impl DmaObject {
22 pub fn slice_region<T: DeviceSync>(
25 &self,
26 offset: usize,
27 len: usize,
28 access: Access,
29 options: DmaOptions,
30 ) -> DmaSliceRegion<T> {
31 let nr_bytes = core::mem::size_of::<T>()
32 .checked_mul(len)
33 .expect("Value of len too large");
34 assert!(nr_bytes + offset < MAX_SIZE - NULLPAGE_SIZE * 2);
35 let virt = self.obj.lea_mut(offset, nr_bytes).unwrap();
36 DmaSliceRegion::new_with_virt(
37 core::mem::size_of::<T>() * len,
38 access,
39 options,
40 offset,
41 len,
42 virt,
43 self.clone(),
44 )
45 }
46
47 fn _region<T: DeviceSync>(&self, access: Access, options: DmaOptions) -> DmaRegion<T> {
50 DmaRegion::new(
51 core::mem::size_of::<T>(),
52 access,
53 options,
54 NULLPAGE_SIZE,
55 None,
56 )
57 }
58
59 pub fn object(&self) -> &Object<()> {
61 &self.obj
62 }
63
64 pub fn new<T>(obj: Object<T>) -> Self {
66 Self {
67 obj: unsafe { obj.cast() },
68 releasable_pins: Arc::new(Mutex::new(Vec::new())),
69 }
70 }
71}
72
73pub(crate) fn release_pin(id: ObjID, token: u32) {
74 let _ = sys_kaction(
75 KactionCmd::Generic(KactionGenericCmd::ReleasePin),
76 Some(id),
77 token as u64,
78 0,
79 KactionFlags::empty(),
80 );
81}
82
83impl Drop for DmaObject {
84 fn drop(&mut self) {
85 let pins = self.releasable_pins.lock().unwrap();
86 for pin in &*pins {
87 release_pin(self.object().id(), *pin);
88 }
89 }
90}
91
92impl<T> From<Object<T>> for DmaObject {
93 fn from(obj: Object<T>) -> Self {
94 Self::new(obj)
95 }
96}