-
-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Transparent 'Raw TRB type' #169
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: Hiroki Tokunaga <[email protected]>
Thanks for the PR. Can I postpone the review until I finish implementing the test os? It's not easy to review a large PR without any tests. |
Sorry for the long delay. I stopped writing a test program for this crate because I'm now in doubt if I really need it (See #159 (comment)). I'll review this PR it in a few days. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the PR, and again, sorry for the long delay. Sorry, I haven't completely reviewed your code yet, and I understand this is still a draft PR, but I leave a few comments.
} | ||
rw_zero_trailing!( | ||
pub, self, | ||
self.0; 4~; "64-byte aligned", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.0; 4~; "64-byte aligned", | |
self.0; 4~; "16-byte aligned", |
@@ -3,7 +3,7 @@ | |||
use super::ExtendedCapability; | |||
use accessor::single; | |||
use accessor::Mapper; | |||
use bit_field::BitField; | |||
// use bit_field::BitField; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// use bit_field::BitField; |
@@ -2,7 +2,7 @@ | |||
|
|||
use accessor::single; | |||
use accessor::Mapper; | |||
use bit_field::BitField; | |||
// use bit_field::BitField; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// use bit_field::BitField; |
@@ -8,7 +8,7 @@ use accessor::marker::Readable; | |||
use accessor::single; | |||
use accessor::Mapper; | |||
use core::convert::TryFrom; | |||
use core::convert::TryInto; | |||
// use core::convert::TryInto; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// use core::convert::TryInto; |
/// # Panics | ||
/// | ||
/// This method will panic if `len >= 4096`. | ||
pub unsafe fn new(base: *const event::TRB, len: usize) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd change the type of base
to u64
because we need the physical address of a ring, not a virtual one.
/// Returns the mutable slice that this entry is representing. | ||
pub fn as_mut_slice(&mut self) -> &mut [event::TRB] { | ||
unsafe { | ||
let base = self.ring_segment_base_address() as usize as *mut _; | ||
let len = self.len(); | ||
|
||
core::slice::from_raw_parts_mut(base, len) | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
} | ||
} | ||
} | ||
impl EventRingSegmentTableEntry { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason to separate impl
s?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be better to define only the EventRingSegmentTableEntry
type with a correct alignment and necessary field getters/setters because an ERST entry contains physical, not virtual, addresses of rings and the size of the table is variable.
Also, could you split this change to another PR? It'd be easier to review.
); | ||
|
||
/// Returns the value of the ring segment end address. | ||
pub fn ring_segment_bound_address(&self) -> u64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ring_segment_end_address
might be better, but I'm not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A trailing newline is preferred.
To implement this I rewrote virtually all macros to make them more general, accepting visibility and indexing base expression arguments.
Effectively, these changes are supposed to reflect what I expressed in the issue #161 . Changes includes:
trb::{transfer|command|event}
now has its ownAllowedType
enum and a transparent rawTRB
type.Event Ring Segment would be
&[event::TRB]
and Command Ring&mut [command::TRB]
, and so on.transfer::TRB
implementsFrom<transfer::Normal>
. Converselytransfer::Normal
implementsTryFrom<transfer::TRB>
, which performs type and RSVDZ checks.Cycle bits should be handled by ring buffer implementation or by xhc.
AllowedType
s and the concrete types,trb::Type
andtrb::{transfer|command|event}::Allowed
are removed.if let Some
-ingTryFrom::<Concrete>::try_from(trb)
is the only choice now. Hopefully we can also write a macro for this. Current state isn't that bad though, especially for the users (just like me) who don't match every possible TRB types, but check if the type matches with a few supported types and only process them.Since this is a HUGE breaking change, many minor API changes are involved on refactoring. These includes (but not limited to):
transfer::DataStage
andtransfer::StatusStage
both haddirection
bit but their types were different. (One wasDirection
while the other was boolean.) This was fixed so that both types are boolean.transfer::Isoch
, the field representing Transfer Burst Count can be either 'TD Size/TBC' or 'TBC/TRBSts'. The latter is even RSVDZ in some situations. So I renamedtransfer_burst_count
intotbc_or_sts
. (That's one reason why I'm against the RSVDZ checkings in.try_from()
.)See here to compare previous implementation(
ring::trb
) and mine(ring::block
) in parallel.On last commits, I removed previous
ring::trb
and the name is taken by previousring::block
.(Disclaimer: currently I haven't tested anything. Only rustc says it's fine and built docs looked nice.)