Re: [PATCH v2 11/16] rust: io: register: support fixed offset register without bitfield
"Gary Guo" <[email protected]> Wed, 05 Aug 2026 18:05:35 +0100
| Newsgroups | dev.linux.lists.sashiko-reviews,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-pci |
|---|---|
| Message-ID | <[email protected]> |
On Wed Aug 5, 2026 at 5:50 PM BST, sashiko-bot wrote: > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: > - [Low] The `register!` macro documentation provides an example defining a FIFO register (`TX_FIFO`) with a `u32` type. This violates the subsystem guidelines which mandate that FIFOs must use stream accessors (no byteswapping). Using a `u32` register type implies standard register access (e.g., `writel`), which will byteswap on big-endian architectures and corrupt stream data. Additionally, the macro's syntax rule `$ty: ident $(:: $path_frag:ident)*` restricts the type to paths, preventing developers from directly specifying a byte array (e.g., `[u8; 4]`) as the type to properly model a byteswap-free stream. > -- > > --- Patch [11]: [PATCH v2 11/16] rust: io: register: support fixed offset register without bitfield --- > commit a13a899311e93c249f5925eff4ce304f82a4cb69 > Author: Gary Guo <[email protected]> > > rust: io: register: support fixed offset register without bitfield > > Add a rule to allow creating `IoLoc` in `regiser!()` using an existing type > and not create a bitfield. Add an example to demonstrate this for FIFO > registers. > >> diff --git a/rust/kernel/io/register.rs b/rust/kernel/io/register.rs >> index dc800fc711722..49a61da106c7d 100644 >> --- a/rust/kernel/io/register.rs >> +++ b/rust/kernel/io/register.rs > > [ ... ] > >> @@ -499,6 +516,19 @@ fn into_io_op(self) -> (FixedRegisterLoc<T>, T) { >> /// In this example, `SCRATCH_BOOT_STATUS` uses the same I/O address as `SCRATCH`, while providing >> /// its own `completed` field. >> /// >> +/// If you do not wish to have a bitfield defined, you can also create a register using an existing >> +/// type. >> +/// >> +/// ```no_run >> +/// # use kernel::io::*; >> +/// register! { >> +/// base: Region<0x1000>; >> +/// >> +/// /// TX FIFO register. >> +/// pub TX_FIFO: u32 @ 0x00001000; > > [Severity: Low] > Does this example promote an anti-pattern for FIFO access? > > Using u32 for a FIFO implies standard register I/O accessors (like writel or > readl), which will perform byte-swapping on big-endian architectures. > According to the I/O accessor subsystem guidelines, FIFOs should use stream > accessors without byteswapping to prevent data corruption. Sashiko is misunderstanding the use case here, this is for intent here is for PIO FIFO where you read one word as a time for a fixed location, not streaming (otherwise the signature here would be `pub TX_FIFO: [u32; FIFO_SIZE] @ ...`). I'll see if I can have a better example in the next version. Perhaps pub UART_RX: u8 @ ...; ? Best, Gary > > Would it be better to avoid using a FIFO as the example here, or use a type > that enforces stream semantics? > >> +/// } >> +/// ``` >> +/// >> /// ## Relative registers > > [ ... ] > >> @@ -826,6 +856,23 @@ fn into_io_op(self) -> (FixedRegisterLoc<T>, T) { >> macro_rules! register { >> (base: $reg_base:ty;) => {}; >> >> + // Creates a register at a fixed offset of the MMIO space with provided type. >> + ( >> + base: $reg_base:ty; >> + // `$ty` cannot be `:ty` due to follow-set restrictions. >> + $(#[$attr:meta])* $vis:vis $name:ident: $ty: ident $(:: $path_frag:ident)* > > [Severity: Low] > Does this macro rule prevent developers from specifying inline byte arrays > (like [u8; 4]) as the register type? > > Since the type matcher is restricted to identifiers and paths, it seems > developers wouldn't be able to directly define a byte array to properly model > a byteswap-free stream without defining a separate type alias first. > > Could this be adjusted to support array syntax, or is the limitation strict > enough to require type aliases for stream buffers? > >> + $(@ $offset:literal)? >> + $(=> $alias:path $([$alias_idx:expr])? )?; >> + $($rest:tt)* >> + ) => {