summaryrefslogtreecommitdiff
path: root/rust/kernel/io/register.rs
AgeCommit message (Collapse)Author
2026-09-06rust: io: register: unify handling of register with/without bitfieldsGary Guo
Move the `FixedRegister` from a property of register to become a property of type. Name the new trait `FixedIoLoc` indicating if I/O location of a type is unique for a specific base. Thus, bitfields become just a special case of this (where type is unique because we're generating it in the register macro), and expose feature to registers without inline bitfield definition with the `#[unique]` attribute. Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Gary Guo <gary@garyguo.net> Tested-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://patch.msgid.link/20260901-typed_register-v4-16-5552b1d59525@garyguo.net Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-09-06rust: io: register: remove `Register` trait and cleanup macroGary Guo
With the removal of relative registers, there are only two type of registers left, fixed register and register arrays. There is not much benefit in having a common super trait for them anymore, thus remove it, and cleanup the macro rules associated with it. Signed-off-by: Gary Guo <gary@garyguo.net> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Tested-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://patch.msgid.link/20260901-typed_register-v4-15-5552b1d59525@garyguo.net Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-09-06rust: io: register: remove relative registersGary Guo
Relative registers can be better served by projection to subregion instead of ad-hoc handling in register macro. Projection composes better (e.g. it natively allows relative registers of relative registers without needing additional support). Remove relative register support, and update the documentation to demonstrate how projection and subregions can be used to achieve this instead. Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Gary Guo <gary@garyguo.net> Tested-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://patch.msgid.link/20260901-typed_register-v4-14-5552b1d59525@garyguo.net Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-09-06rust: io: register: support fixed offset register without bitfieldGary Guo
Add a rule to allow creating `IoLoc` in `register!()` using an existing type and not create a bitfield. Add an example to demonstrate this for FIFO registers. This rule is also going to be used to create subregions for registers; the example of doing so will be added later when relative registers are removed. Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Gary Guo <gary@garyguo.net> Tested-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://patch.msgid.link/20260901-typed_register-v4-11-5552b1d59525@garyguo.net Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-09-06rust: io: register: make register have a typed baseGary Guo
Previously `register!` defined registers can be used on any untyped I/O regions. With all users specifying their desired register type now, propagate the specified type and restrict I/O access only when type matches. Also, add an `io_project!` example which is enabled by this change. Signed-off-by: Gary Guo <gary@garyguo.net> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Tested-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://patch.msgid.link/20260901-typed_register-v4-10-5552b1d59525@garyguo.net Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-09-06rust: io: register: allow explicit base type specificationGary Guo
Currently registers work for all untyped I/O regions, which is not ideal. It allows registers defined for device A to work for another device B and there is no safeguarding at all. All users of the `register!` macro know what type it will be operating on, and that type is consistent across the driver. Therefore, add a `base` parameter to `register!`. Currently this parameter is unused in the generated code; it will be used when all users of `register!` is converted to gain the parameter. Signed-off-by: Gary Guo <gary@garyguo.net> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Tested-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://patch.msgid.link/20260901-typed_register-v4-6-5552b1d59525@garyguo.net [ Remove unnecessary #[allow(unused)] from the 'base' field. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-09-06rust: io: perform conversions using `AsRepr`Gary Guo
For types that are layout-compatible with an I/O capable type, we would want the ability to use them directly for I/O operations. E.g. bitfield! { pub struct Foo(u32) { ... } } #[repr(C)] struct Bar { foo: Foo, } let mmio: Mmio<'_, Bar> = ...; io_read!(mmio, .foo) Currently this feature is available from `register!()` macro but not otherwise available with `io_read!`, `io_write!`. Support this by performing conversions to I/O primitives via the `AsRepr`/`AsReprMut` trait. This makes the `IoLoc::IoType` and `Register::Storage` redundant; thus remove them; also convert register methods to use the `read_val` and `write_val` instead. Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Gary Guo <gary@garyguo.net> Tested-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://patch.msgid.link/20260901-typed_register-v4-4-5552b1d59525@garyguo.net Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-09-03rust: io: register: reimplement as proc macroGary Guo
The existing `register!` macro is implemented as a declarative macro. Reimplement it as proc macro instead, with no functional changes intended. The old implementation produces unhelpful diagnostics when things go wrong. For example, for code like register! { pub(crate) TESTREG(u32) { 31:0 data; } } which misses out the "@ offset" part of the specification, and the following error is produced: error: no rules expected `{` --> test.rs:42:5 | 42 | / register! { 43 | | pub(crate) TESTREG(u32) { 44 | | 31:0 data; ... | 100 | | } | |_____^ no rules expected this token in macro call which isn't very helpful. With the proc macro implementation, the following error is produced: error: expected `@` or `=>` --> tests.rs:43:33 | 43 | pub(crate) TESTREG(u32) { | ^ which is much more helpful. Apart from diagnostics, proc macro also has a benefit of not having follow-set restrictions, which makes syntax like register!(name: ty @ offset); possible; declarative macro will reject this as `@` is not in the follow-set of "ty" metavariable kind. Signed-off-by: Gary Guo <gary@garyguo.net> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Tested-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://patch.msgid.link/20260901-typed_register-v4-1-5552b1d59525@garyguo.net [ Fix typo in module-level doc comment and fix ArrayDef syntax description to match the actual macro syntax. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-08-03rust: io: register: use path fragment for alias destinationAlexandre Courbot
The destination of an alias is always another register, i.e. a `struct` type. Replace the `ident` fragment with a `path` one in the internal rules: `path` is more accurate, and allows referencing registers using a qualified path instead of only identifiers visible from the current module. This covers all aliases, except the relative register ones which are to be removed soon. The public rule cannot be updated yet because a `+` can still be matched after the alias; add a TODO item to update it after relative registers are removed. Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://patch.msgid.link/20260724-registers_fix-v2-3-a0fb58b02185@nvidia.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-08-03rust: io: register: remove unused rule argumentsAlexandre Courbot
A few arguments passed to internal rules are never used and just add unneeded complexity. Remove them to simplify the rules a bit. Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://patch.msgid.link/20260724-registers_fix-v2-2-a0fb58b02185@nvidia.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-08-03rust: io: register: dispatch shortcut rules internallyAlexandre Courbot
A couple of shortcut rules redispatch an already normalized declaration through the public register! entry point. This is unneeded - the public rule should only be invoked by users. Dispatch directly to the appropriate internal @reg rule instead. Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: Gary Guo <gary@garyguo.net> Link: https://patch.msgid.link/20260724-registers_fix-v2-1-a0fb58b02185@nvidia.com Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-13Merge patch series "rust: I/O type generalization and projection"Danilo Krummrich
Gary Guo <gary@garyguo.net> says: This series presents a major rework of I/O types, as a summary: - Make I/O regions typed. The existing untyped region still exists with a dynamically sized `Region` type. - Create I/O view types to represent subregion of a full I/O region mapped. A projection macro is added to allow safely create such subviews. - Split I/O traits, make I/O views play a central role, avoid duplicate monomorphization and less `unsafe` code. - Add a `SysMem` backend, and make `Coherent` implement `Io`. - Add copying methods (memcpy_{from,to}io and friends). This series generalize `Mmio` type from just an untyped region to typed representations (so `MmioRaw<T>` is `__iomem *T`). This allows us to remove the `IoKnownSize` trait; the information is sourced from just the pointer from the `KnownSize` trait instead. Building on top of that, `Mmio` and `ConfigSpace` have been converted to typed views of I/O regions rather than just a big chunk of untyped I/O memory. These changes made it possible to implement `Io` trait for `Coherent<T>`. Shared system memory, `SysMem` is also added to the series, given it similarity in implementation compared to `Coherent`. In fact, the series use `SysMem` to implement `Coherent`'s I/O methods. Built on these generalization, this series add `io_project!()`. `io_project!()` performs a safe way to project a bigger view to a small subviews, and some Nova code has been converted in this series to demonstrate cleanups possible with this addition. New `io_read!()`, `io_write!()` has been added that supersedes `dma_read!()`, `dma_write!()` macro. Although, they work for primitives only (to be exact, types that the backend is `IoCapable` of). One feature that was lost from the old `dma_read!()` and `dma_write!()` series was the ability to read/write a large structs. However, the semantics was unclear to begin with, as there was no guarantee about their atomicity even for structs that were small enough to fit in u32. Suggested-by: Danilo Krummrich <dakr@kernel.org> Link: https://rust-for-linux.zulipchat.com/#narrow/channel/288089-General/topic/Generic.20I.2FO.20backends/near/571198078 Link: https://patch.msgid.link/20260706-io_projection-v6-0-72cd5d055d54@garyguo.net Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11rust: io: implement `Mmio` as view typeGary Guo
Implement `Mmio` as view type and convert `RelaxedMmio` to view type as well. I/O implementations of `MmioOwned` are changed to delegate to the `Mmio` view type. All existing users of `MmioOwned` in the documentation which do not actually reflect the owning semantics is converted. Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Gary Guo <gary@garyguo.net> Tested-by: Daniel Almeida <daniel.almeida@collabora.com> Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com> Link: https://patch.msgid.link/20260706-io_projection-v6-7-72cd5d055d54@garyguo.net Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11rust: io: rename `Mmio` to `MmioOwned`Gary Guo
Most users would more commonly reach out to a view of `Mmio` rather than an owned instance of `Mmio`. Only implementor of `Io` like `Bar` or `IoMem` would need the owned version. Thus, rename `Mmio` to `MmioOwned` so that the name `Mmio` can be used for the view type instead. Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Gary Guo <gary@garyguo.net> Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com> Suggested-by: Danilo Krummrich <dakr@kernel.org> Link: https://rust-for-linux.zulipchat.com/#narrow/channel/288089-General/topic/Generic.20I.2FO.20backends/near/571198078 Link: https://patch.msgid.link/20260706-io_projection-v6-6-72cd5d055d54@garyguo.net Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-11rust: io: restrict untyped IO access and `register!` to `Region`Gary Guo
Currently the `Io` trait exposes a bunch of untyped IO accesses, but if the `Io` region itself is typed, then it might be weird to have let io: Mmio<u32> = /* ... */; io.read8(1); while not unsound, it is surely strange. Thus, restrict the untyped methods and also the register macro to `Region` type only. Implement it by adding a generic type to `IoLoc` indicating allowed base types. This also paves the way to add typed register blocks in the future; for example, we could use this mechanism to block driver A's `register!()` generated macro from being used on driver B's MMIO. The same mechanism could be used for relative IO registers. These are future opportunities, and for now restrict everything to require `IoLoc<Region<SIZE>, _>`. Suggested-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://lore.kernel.org/rust-for-linux/DHLB3RO3OSF5.2R7F27U99BKLN@nvidia.com/ Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Gary Guo <gary@garyguo.net> Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com> Link: https://patch.msgid.link/20260706-io_projection-v6-3-72cd5d055d54@garyguo.net Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-07-03rust: io: fix example in `register!` macroLink Mauve
In this example, an u32 register is split in two u8 in big-endian order, but the high byte is actually defined as taking nine bits instead of eight. This is completely inconsequential, as I expect most users will just copy the bit ranges from their datasheets, but it doesn’t hurt to fix that typo. Signed-off-by: Link Mauve <linkmauve@linkmauve.fr> Acked-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: Gary Guo <gary@garyguo.net> Link: https://patch.msgid.link/20260701160357.29031-1-linkmauve@linkmauve.fr Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-06-10rust: make `build_assert` module the home of related macrosGary Guo
Given the macro scoping rules, all macros are rendered twice, in the module and in the top-level of kernel crate. Add `#[doc(hidden)]` to the macro definition and `#[doc(inline)]` to the re-export inside `build_assert` module so the top-level items are hidden. [ Sadly, because the definition is hidden, `rustdoc` decides to not list them as re-exports in the `prelude` page anymore, even if we refer to the not-actually-hidden item. - Miguel ] Acked-by: Danilo Krummrich <dakr@kernel.org> Reviewed-by: Alice Ryhl <aliceryhl@google.com> Acked-by: Alexandre Courbot <acourbot@nvidia.com> Acked-by: FUJITA Tomonori <fujita.tomonori@gmail.com> Acked-by: Boqun Feng <boqun@kernel.org> Signed-off-by: Gary Guo <gary@garyguo.net> Link: https://patch.msgid.link/20260609142637.373347-1-gary@kernel.org [ Kept a single declaration in the prelude, and reworded since they already had `no_inline`. Removed other imports from `predefine` since we now use the prelude. - Miguel ] Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2026-06-09rust: io: use the `bitfield!` macro in `register!`Alexandre Courbot
Replace the local bitfield rules by the equivalent invocation of the `bitfield!` macro. No functional change should be introduced as the `bitfield!` macro has been extracted from the rules of `register!`. Acked-by: Yury Norov <yury.norov@gmail.com> Acked-by: Danilo Krummrich <dakr@kernel.org> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: Yury Norov <ynorov@nvidia.com> Link: https://patch.msgid.link/20260606-bitfield-v5-3-b92188820914@nvidia.com Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2026-03-17rust: io: introduce `write_reg` and `LocatedRegister`Alexandre Courbot
Some I/O types, like fixed address registers, carry their location alongside their values. For these types, the regular `Io::write` method can lead into repeating the location information twice: once to provide the location itself, another time to build the value. We are also considering supporting making all register values carry their full location information for convenience and safety. Add a new `Io::write_reg` method that takes a single argument implementing `LocatedRegister`, a trait that decomposes implementors into a `(location, value)` tuple. This allows write operations on fixed offset registers to be done while specifying their name only once. Suggested-by: Danilo Krummrich <dakr@kernel.org> Link: https://lore.kernel.org/all/DH0XBLXZD81K.22SWIZ1ZAOW1@kernel.org/ Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://patch.msgid.link/20260314-register-v9-8-86805b2f7e9d@nvidia.com [ Replace FIFO with VERSION register in the examples. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
2026-03-17rust: io: add `register!` macroAlexandre Courbot
Add a macro for defining hardware register types with I/O accessors. Each register field is represented as a `Bounded` of the appropriate bit width, ensuring field values are never silently truncated. Fields can optionally be converted to/from custom types, either fallibly or infallibly. The address of registers can be direct, relative, or indexed, supporting most of the patterns in which registers are arranged. Suggested-by: Danilo Krummrich <dakr@kernel.org> Link: https://lore.kernel.org/all/20250306222336.23482-6-dakr@kernel.org/ Co-developed-by: Gary Guo <gary@garyguo.net> Signed-off-by: Gary Guo <gary@garyguo.net> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://patch.msgid.link/20260314-register-v9-7-86805b2f7e9d@nvidia.com [ * Improve wording and formatting of doc-comments, * Import build_assert!(), * Add missing inline annotations, * Call static_assert!() with absolute path, * Use expect instead of allow. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>