Open
Description
Currently, there are two register set arrays(ports and interrupters) but their designs are different and both have several issues:
- Since Allow updating single fields of InterrupterRegisterSet #142, interrupter type became a struct of accessors so that each field can be accessed independently. Port register set is still a struct of data fields and can't be updated field-wise. More consistent design between two register set arrays is required.
- Making new
PortRegisterSet
to pair withPort
(just likeInterrupterRegisterSet
pairs withInterrupter
) is inefficient and violates DRY principle. - Current indexing method of interrupters (
InterrupterRegisterSet::interrupter(&self, i)
) actually maps and unmaps 5 physical addresses per indexing. I'm concerned about that if (un)mapping cost is more than zero, this would not be the optimal implementation.
I've crated a PR(toku-sa-n/accessor#44) for accessor .at(i)
and .set_at(i)
syntax for this purpose. Applying those changes in xhci crate, I've made a commit but I can't make it a PR until the accessor crate PR has been merged, so I opened this issue.
Changes
- Removed
InterrupterRegisterSet
(as non-mapping array-like type as it is now) andInterrupter
(as struct of accessors) - The name
InterrupterRegisterSet
is used for the indexed item type(struct of data field) of IRS array. InterrupterRegisterSet
andPortRegisterSet
both implementsaccessor::array::BoundSetGeneric
trait to use.set_at(i)
method.
implementation detail
Internally `accessor::array::BoundSetGeneric` trait is implemented by deriving `BoundSetGenericOfInterrupterRegisterSet` and `BoundSetGenericOfPortRegisterSet` types.Usecase
- (before)
use xhci::Registers;
// let regs: Registers<M>;
let erdp = regs.interrupter_register_set.interrupter(i).erdp.read_volatile();
let portsc = regs.port_register_set.read_volatile_at(i).portsc;
- (after)
use xhci::Registers;
use xhci::accessor::array::BoundSetGeneric; // for `.set_at(i)` method
// let regs: Registers<M>;
let erdp = regs.interrupter_register_set.set_at(i).erdp.read_volatile();
let portsc = regs.port_register_set.set_at(i).portsc.read_volatile();
Metadata
Metadata
Assignees
Labels
No labels