use core::{ ops::{Index, IndexMut}, slice::SliceIndex, }; use bitfield_struct::{bitenum, bitfield}; use mammoth::physical_box::PhysicalBox; #[bitenum] #[repr(u8)] #[derive(Debug)] pub enum TrbType { #[fallback] Reserved = 0, NoOp = 8, } #[bitfield(u128)] pub struct TransferRequestBlock { parameter: u64, status: u32, cycle: bool, evaluate_next: bool, flag_2: bool, flag_3: bool, flag_4: bool, flag_5: bool, flag_6: bool, flag_7: bool, flag_8: bool, flag_9: bool, #[bits(6)] trb_type: u8, control: u16, } impl TransferRequestBlock {} trait TypedTrb { fn from_trb(trb: TransferRequestBlock) -> Self where Self: From, { trb.into_bits().into() } fn to_trb(self) -> TransferRequestBlock where Self: Into, { Into::::into(self).into() } } #[bitfield(u128)] pub struct TrbNoOp { __: u64, __: u32, cycle: bool, evaluate_next: bool, __: bool, __: bool, chain: bool, #[bits(default = true)] interrupt_on_completion: bool, #[bits(4)] __: u8, #[bits(6, default = TrbType::NoOp)] trb_type: TrbType, __: u16, } impl TypedTrb for TrbNoOp {} #[repr(transparent)] pub struct TrbRing(PhysicalBox<[TransferRequestBlock]>); impl TrbRing { pub fn new(size: usize) -> Self { Self(PhysicalBox::default_with_count( TransferRequestBlock::default(), size, )) } pub fn len(&self) -> usize { self.0.len() } pub fn physical_address(&self) -> usize { self.0.physical_address() } } impl Index for TrbRing where I: SliceIndex<[TransferRequestBlock]>, { type Output = I::Output; fn index(&self, index: I) -> &Self::Output { &self.0[index] } } impl IndexMut for TrbRing where I: SliceIndex<[TransferRequestBlock]>, { fn index_mut(&mut self, index: I) -> &mut Self::Output { &mut self.0[index] } }