twizzler_driver/device/
mmio.rs1use twizzler::object::{ObjID, Object, RawObject};
2use twizzler_abi::{
3 device::{MmioInfo, SubObjectType, MMIO_OFFSET},
4 object::NULLPAGE_SIZE,
5};
6use twizzler_rt_abi::{object::MapFlags, Result};
7use volatile::access::{ReadOnly, ReadWrite};
8
9use super::Device;
10
11pub struct MmioObject {
13 obj: Object<MmioInfo>,
14}
15
16impl MmioObject {
17 pub(crate) fn new(id: ObjID) -> Result<Self> {
18 Ok(Self {
19 obj: unsafe { Object::map_unchecked(id, MapFlags::READ | MapFlags::WRITE) }?,
20 })
21 }
22
23 pub fn get_info(&self) -> &MmioInfo {
25 unsafe { self.obj.base_ptr::<MmioInfo>().as_ref().unwrap() }
26 }
27
28 pub unsafe fn get_mmio_offset<T>(
33 &self,
34 offset: usize,
35 ) -> volatile::VolatileRef<'_, T, ReadOnly> {
36 let ptr = self.obj.base_ptr::<u8>();
37 volatile::VolatileRef::from_ref(
38 (ptr.add(MMIO_OFFSET + offset).sub(NULLPAGE_SIZE) as *mut T)
39 .as_mut()
40 .unwrap(),
41 )
42 }
43
44 pub unsafe fn get_mmio_offset_mut<T>(
49 &self,
50 offset: usize,
51 ) -> volatile::VolatileRef<'_, T, ReadWrite> {
52 let ptr = self.obj.base_ptr::<u8>();
53 volatile::VolatileRef::from_mut_ref(
54 (ptr.add(MMIO_OFFSET + offset).sub(NULLPAGE_SIZE) as *mut T)
55 .as_mut()
56 .unwrap(),
57 )
58 }
59}
60
61impl Device {
62 pub fn get_mmio(&self, idx: u8) -> Option<MmioObject> {
64 let id = self.get_subobj(SubObjectType::Mmio.into(), idx)?;
65 MmioObject::new(id).ok()
66 }
67}