-
-
Notifications
You must be signed in to change notification settings - Fork 9
Transparent 'Raw TRB type' #169
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
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", |
| 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; |
| 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; |
| 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 impls?
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 ownAllowedTypeenum and a transparent rawTRBtype.Event Ring Segment would be
&[event::TRB]and Command Ring&mut [command::TRB], and so on.transfer::TRBimplementsFrom<transfer::Normal>. Converselytransfer::NormalimplementsTryFrom<transfer::TRB>, which performs type and RSVDZ checks.Cycle bits should be handled by ring buffer implementation or by xhc.
AllowedTypes and the concrete types,trb::Typeandtrb::{transfer|command|event}::Allowedare 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::DataStageandtransfer::StatusStageboth haddirectionbit but their types were different. (One wasDirectionwhile 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_countintotbc_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::trband 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.)