twizzler_driver/dma/
object.rsuse std::sync::Mutex;
use twizzler_abi::{
kso::{KactionCmd, KactionFlags, KactionGenericCmd},
object::{MAX_SIZE, NULLPAGE_SIZE},
syscall::sys_kaction,
};
use twizzler_object::{ObjID, Object};
use super::{Access, DeviceSync, DmaOptions, DmaRegion, DmaSliceRegion};
pub struct DmaObject {
obj: Object<()>,
pub(crate) releasable_pins: Mutex<Vec<u32>>,
}
impl DmaObject {
fn _slice_region<T: DeviceSync>(
&self,
len: usize,
access: Access,
options: DmaOptions,
) -> DmaSliceRegion<T> {
let nr_bytes = core::mem::size_of::<T>()
.checked_mul(len)
.expect("Value of len too large");
assert!(nr_bytes < MAX_SIZE - NULLPAGE_SIZE * 2);
DmaSliceRegion::new(
core::mem::size_of::<T>() * len,
access,
options,
NULLPAGE_SIZE,
len,
None,
)
}
fn _region<T: DeviceSync>(&self, access: Access, options: DmaOptions) -> DmaRegion<T> {
DmaRegion::new(
core::mem::size_of::<T>(),
access,
options,
NULLPAGE_SIZE,
None,
)
}
pub fn object(&self) -> &Object<()> {
&self.obj
}
pub fn new<T>(obj: Object<T>) -> Self {
Self {
obj: unsafe { obj.transmute() },
releasable_pins: Mutex::new(Vec::new()),
}
}
}
pub(crate) fn release_pin(id: ObjID, token: u32) {
let _ = sys_kaction(
KactionCmd::Generic(KactionGenericCmd::ReleasePin),
Some(id),
token as u64,
0,
KactionFlags::empty(),
);
}
impl Drop for DmaObject {
fn drop(&mut self) {
let pins = self.releasable_pins.lock().unwrap();
for pin in &*pins {
release_pin(self.object().id(), *pin);
}
}
}
impl<T> From<Object<T>> for DmaObject {
fn from(obj: Object<T>) -> Self {
Self::new(obj)
}
}