113 lines
2 KiB
Rust
113 lines
2 KiB
Rust
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<u128>,
|
|
{
|
|
trb.into_bits().into()
|
|
}
|
|
|
|
fn to_trb(self) -> TransferRequestBlock
|
|
where
|
|
Self: Into<u128>,
|
|
{
|
|
Into::<u128>::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<I> Index<I> for TrbRing
|
|
where
|
|
I: SliceIndex<[TransferRequestBlock]>,
|
|
{
|
|
type Output = I::Output;
|
|
|
|
fn index(&self, index: I) -> &Self::Output {
|
|
&self.0[index]
|
|
}
|
|
}
|
|
|
|
impl<I> IndexMut<I> for TrbRing
|
|
where
|
|
I: SliceIndex<[TransferRequestBlock]>,
|
|
{
|
|
fn index_mut(&mut self, index: I) -> &mut Self::Output {
|
|
&mut self.0[index]
|
|
}
|
|
}
|