lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <aPozw8TGp85YdmNU@arm.com>
Date: Thu, 23 Oct 2025 15:55:15 +0200
From: Beata Michalska <beata.michalska@....com>
To: Joel Fernandes <joelagnelf@...dia.com>
Cc: "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
	"rust-for-linux@...r.kernel.org" <rust-for-linux@...r.kernel.org>,
	"dri-devel@...ts.freedesktop.org" <dri-devel@...ts.freedesktop.org>,
	"dakr@...nel.org" <dakr@...nel.org>,
	Alexandre Courbot <acourbot@...dia.com>,
	Alistair Popple <apopple@...dia.com>,
	Miguel Ojeda <ojeda@...nel.org>,
	Alex Gaynor <alex.gaynor@...il.com>,
	Boqun Feng <boqun.feng@...il.com>, Gary Guo <gary@...yguo.net>,
	"bjorn3_gh@...tonmail.com" <bjorn3_gh@...tonmail.com>,
	Benno Lossin <lossin@...nel.org>,
	Andreas Hindborg <a.hindborg@...nel.org>,
	Alice Ryhl <aliceryhl@...gle.com>, Trevor Gross <tmgross@...ch.edu>,
	David Airlie <airlied@...il.com>, Simona Vetter <simona@...ll.ch>,
	Maarten Lankhorst <maarten.lankhorst@...ux.intel.com>,
	Maxime Ripard <mripard@...nel.org>,
	Thomas Zimmermann <tzimmermann@...e.de>,
	John Hubbard <jhubbard@...dia.com>, Timur Tabi <ttabi@...dia.com>,
	"joel@...lfernandes.org" <joel@...lfernandes.org>,
	Elle Rhumsaa <elle@...thered-steel.dev>,
	Yury Norov <yury.norov@...il.com>,
	Daniel Almeida <daniel.almeida@...labora.com>,
	Andrea Righi <arighi@...dia.com>,
	"nouveau@...ts.freedesktop.org" <nouveau@...ts.freedesktop.org>
Subject: Re: [PATCH v6 4/5] rust: Move register and bitfield macros out of
 Nova

On Wed, Oct 22, 2025 at 07:37:55PM +0000, Joel Fernandes wrote:
> Hi Beata,
> 
> > On Oct 22, 2025, at 2:41 PM, Beata Michalska <beata.michalska@....com> wrote:
> > 
> > Hi Joel,
> > 
> > I know I'm chiming in a bit late, so apologies for that.
> 
> No problem.
> 
> > 
> > The register! macro does seem to be a solid foundation for MMIO register
> > definitions, thought there are few points that could be potentially
> > [re]considered.
> 
> I agree. Just to clarify, Alexandre is the main developer of the register macro. I just
> attempted to move the code and made some improvements :). I replied below:
> 
> > 
> > The current design assumes a fixed, compile-time-known MMIO region size.
> > It does not cover cases when the region size is known only at runtime.
> > I do appreciate that in cases like that, we are loosing all the deliberate
> > compile-time checks but it might be necessary to provide support for those as
> > well (at some point at least).
> 
> Sure that could be useful if you have a use case.
I guess everything that would use IoRequest::iomap(self), which generates
Io<SIZE=0> which is a game over for the macro.
> 
> > 
> > On the (potential) improvement side:
> > 
> > Allowing offsets to be expressions rather than literals would make the macro
> > easier to use for regions defined at a fixed base offset, where subsequent
> > offsets are derived from that base, i.e:
> > 
> > REG_1_BASE    -> 0x100
> > REG_1_STATUS    -> REG_1_BASE + 0x0
> > REG_1_CONTROL    -> REG_1_BASE + 0x04
> 
> This is already possible with the register macro using relative-registers (RegisterBase) right?
Probably though the use case I had in mind is relative array of registers.
It's fine to use the macro as is for few registers, having a significant number
of those gets cumbersome though. Unless I am misreading things.
> 
> > ...
> > 
> > The alias mechanism is a nice touch. It might be worth allowing arrays of
> > registers with explicit aliases to be defined in a single macro invocation,
> > instead of repeating similar definitions, smth along the lines of:
> > 
> >  register!(
> >      REG_STATUS @ 0x300[8; STRIDE] {
> >          0:0 enabled as bool;
> >          3:1 mode as u8;
> >          7:4 flags as u8;
> >      }
> >      aliases {
> >          REG_STATUS_ENABLED[0] {
> >              0:0 enabled as bool;
> >          }
> >          REG_STATUS_MODE[0] {
> >              3:1 mode as u8;
> >          }
> >          REG_STATUS_FLAGS[4] {
> >              7:4 flags as u8;
> >          }
> >      }
> 
> The aliasing might be better do embed as syntax in the Bitfield itself,
> instead of additional aliases{} blocks.
> By the way, array of registers is also supported already as you may know.
I was referring to aliasing having in mind array of registers.

> 
> >  );
> > 
> > 
> > Finally, for runtime values such as indexes, it could be useful to verify once
> > and then allow infallible reads/writes through some kind access token.
> 
> Why? The verification is already done at compile-time AFAICS.
Well, that's the point. Those are runtime values, and as of now, the only
support for those is for arrays of registers when one, when using try_xxx
methods, ends up with check being performed each time the method is called.

---
BR
Beata
> 
> > That might make runtime-safe access patterns simpler and more efficient.
> 
> Because it is compile-time, it is already runtime efficient :)
> 
> > I'm still pondering on how that could look like though (implementation-wise)
> 
> Patches welcomed! For now this still lives in nova-core and Alex is working
> on adding support for BoundedInt after which we can move it out.
> 
> Thanks,
> 
>  - Joel
> 
> 
> > ---
> > BR
> > Beata
> > 
> >> On Fri, Oct 03, 2025 at 11:47:47AM -0400, Joel Fernandes wrote:
> >> Out of broad need for the register and bitfield macros in Rust, move
> >> them out of nova into the kernel crate. Several usecases need them (Nova
> >> is already using these and Tyr developers said they need them).
> >> 
> >> bitfield moved into kernel crate - defines bitfields in Rust.
> >> register moved into io module - defines hardware registers and accessors.
> >> 
> >> Reviewed-by: Alexandre Courbot <acourbot@...dia.com>
> >> Reviewed-by: Elle Rhumsaa <elle@...thered-steel.dev>
> >> Signed-off-by: Joel Fernandes <joelagnelf@...dia.com>
> >> ---
> >> drivers/gpu/nova-core/falcon.rs               |  2 +-
> >> drivers/gpu/nova-core/falcon/gsp.rs           |  4 +-
> >> drivers/gpu/nova-core/falcon/sec2.rs          |  2 +-
> >> drivers/gpu/nova-core/nova_core.rs            |  3 -
> >> drivers/gpu/nova-core/regs.rs                 |  6 +-
> >> .../gpu/nova-core => rust/kernel}/bitfield.rs | 27 ++++-----
> >> rust/kernel/io.rs                             |  1 +
> >> .../macros.rs => rust/kernel/io/register.rs   | 58 ++++++++++---------
> >> rust/kernel/lib.rs                            |  1 +
> >> 9 files changed, 54 insertions(+), 50 deletions(-)
> >> rename {drivers/gpu/nova-core => rust/kernel}/bitfield.rs (91%)
> >> rename drivers/gpu/nova-core/regs/macros.rs => rust/kernel/io/register.rs (93%)
> >> 
> >> diff --git a/drivers/gpu/nova-core/falcon.rs b/drivers/gpu/nova-core/falcon.rs
> >> index 37e6298195e4..a15fa98c8614 100644
> >> --- a/drivers/gpu/nova-core/falcon.rs
> >> +++ b/drivers/gpu/nova-core/falcon.rs
> >> @@ -6,6 +6,7 @@
> >> use hal::FalconHal;
> >> use kernel::device;
> >> use kernel::dma::DmaAddress;
> >> +use kernel::io::register::RegisterBase;
> >> use kernel::prelude::*;
> >> use kernel::sync::aref::ARef;
> >> use kernel::time::Delta;
> >> @@ -14,7 +15,6 @@
> >> use crate::driver::Bar0;
> >> use crate::gpu::Chipset;
> >> use crate::regs;
> >> -use crate::regs::macros::RegisterBase;
> >> use crate::util;
> >> 
> >> pub(crate) mod gsp;
> >> diff --git a/drivers/gpu/nova-core/falcon/gsp.rs b/drivers/gpu/nova-core/falcon/gsp.rs
> >> index f17599cb49fa..cd4960e997c8 100644
> >> --- a/drivers/gpu/nova-core/falcon/gsp.rs
> >> +++ b/drivers/gpu/nova-core/falcon/gsp.rs
> >> @@ -1,9 +1,11 @@
> >> // SPDX-License-Identifier: GPL-2.0
> >> 
> >> +use kernel::io::register::RegisterBase;
> >> +
> >> use crate::{
> >>     driver::Bar0,
> >>     falcon::{Falcon, FalconEngine, PFalcon2Base, PFalconBase},
> >> -    regs::{self, macros::RegisterBase},
> >> +    regs::self,
> >> };
> >> 
> >> /// Type specifying the `Gsp` falcon engine. Cannot be instantiated.
> >> diff --git a/drivers/gpu/nova-core/falcon/sec2.rs b/drivers/gpu/nova-core/falcon/sec2.rs
> >> index 815786c8480d..81717868a8a8 100644
> >> --- a/drivers/gpu/nova-core/falcon/sec2.rs
> >> +++ b/drivers/gpu/nova-core/falcon/sec2.rs
> >> @@ -1,7 +1,7 @@
> >> // SPDX-License-Identifier: GPL-2.0
> >> 
> >> use crate::falcon::{FalconEngine, PFalcon2Base, PFalconBase};
> >> -use crate::regs::macros::RegisterBase;
> >> +use kernel::io::register::RegisterBase;
> >> 
> >> /// Type specifying the `Sec2` falcon engine. Cannot be instantiated.
> >> pub(crate) struct Sec2(());
> >> diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs
> >> index 112277c7921e..fffcaee2249f 100644
> >> --- a/drivers/gpu/nova-core/nova_core.rs
> >> +++ b/drivers/gpu/nova-core/nova_core.rs
> >> @@ -2,9 +2,6 @@
> >> 
> >> //! Nova Core GPU Driver
> >> 
> >> -#[macro_use]
> >> -mod bitfield;
> >> -
> >> mod dma;
> >> mod driver;
> >> mod falcon;
> >> diff --git a/drivers/gpu/nova-core/regs.rs b/drivers/gpu/nova-core/regs.rs
> >> index 206dab2e1335..1f08e6d4045a 100644
> >> --- a/drivers/gpu/nova-core/regs.rs
> >> +++ b/drivers/gpu/nova-core/regs.rs
> >> @@ -4,15 +4,13 @@
> >> // but are mapped to types.
> >> #![allow(non_camel_case_types)]
> >> 
> >> -#[macro_use]
> >> -pub(crate) mod macros;
> >> -
> >> use crate::falcon::{
> >>     DmaTrfCmdSize, FalconCoreRev, FalconCoreRevSubversion, FalconFbifMemType, FalconFbifTarget,
> >>     FalconModSelAlgo, FalconSecurityModel, PFalcon2Base, PFalconBase, PeregrineCoreSelect,
> >> };
> >> use crate::gpu::{Architecture, Chipset};
> >> use kernel::prelude::*;
> >> +use kernel::register;
> >> 
> >> // PMC
> >> 
> >> @@ -331,6 +329,7 @@ pub(crate) fn mem_scrubbing_done(self) -> bool {
> >> 
> >> pub(crate) mod gm107 {
> >>     // FUSE
> >> +    use kernel::register;
> >> 
> >>     register!(NV_FUSE_STATUS_OPT_DISPLAY @ 0x00021c04 {
> >>         0:0     display_disabled as bool;
> >> @@ -339,6 +338,7 @@ pub(crate) mod gm107 {
> >> 
> >> pub(crate) mod ga100 {
> >>     // FUSE
> >> +    use kernel::register;
> >> 
> >>     register!(NV_FUSE_STATUS_OPT_DISPLAY @ 0x00820c04 {
> >>         0:0     display_disabled as bool;
> >> diff --git a/drivers/gpu/nova-core/bitfield.rs b/rust/kernel/bitfield.rs
> >> similarity index 91%
> >> rename from drivers/gpu/nova-core/bitfield.rs
> >> rename to rust/kernel/bitfield.rs
> >> index cbedbb0078f6..09cd5741598c 100644
> >> --- a/drivers/gpu/nova-core/bitfield.rs
> >> +++ b/rust/kernel/bitfield.rs
> >> @@ -9,7 +9,7 @@
> >> /// # Syntax
> >> ///
> >> /// ```rust
> >> -/// use nova_core::bitfield;
> >> +/// use kernel::bitfield;
> >> ///
> >> /// #[derive(Debug, Clone, Copy, Default)]
> >> /// enum Mode {
> >> @@ -82,10 +82,11 @@
> >> ///   the result.
> >> /// - `as <type> ?=> <try_into_type>` calls `<try_into_type>`'s `TryFrom::<<type>>` implementation
> >> ///   and returns the result. This is useful with fields for which not all values are valid.
> >> +#[macro_export]
> >> macro_rules! bitfield {
> >>     // Main entry point - defines the bitfield struct with fields
> >>     ($vis:vis struct $name:ident($storage:ty) $(, $comment:literal)? { $($fields:tt)* }) => {
> >> -        bitfield!(@core $vis $name $storage $(, $comment)? { $($fields)* });
> >> +        ::kernel::bitfield!(@core $vis $name $storage $(, $comment)? { $($fields)* });
> >>     };
> >> 
> >>     // All rules below are helpers.
> >> @@ -114,7 +115,7 @@ fn from(val: $name) -> $storage {
> >>             }
> >>         }
> >> 
> >> -        bitfield!(@fields_dispatcher $vis $name $storage { $($fields)* });
> >> +        ::kernel::bitfield!(@fields_dispatcher $vis $name $storage { $($fields)* });
> >>     };
> >> 
> >>     // Captures the fields and passes them to all the implementers that require field information.
> >> @@ -130,7 +131,7 @@ fn from(val: $name) -> $storage {
> >>         )*
> >>     }
> >>     ) => {
> >> -        bitfield!(@field_accessors $vis $name $storage {
> >> +        ::kernel::bitfield!(@field_accessors $vis $name $storage {
> >>             $(
> >>                 $hi:$lo $field as $type
> >>                 $(?=> $try_into_type)?
> >> @@ -139,8 +140,8 @@ fn from(val: $name) -> $storage {
> >>             ;
> >>             )*
> >>         });
> >> -        bitfield!(@debug $name { $($field;)* });
> >> -        bitfield!(@default $name { $($field;)* });
> >> +        ::kernel::bitfield!(@debug $name { $($field;)* });
> >> +        ::kernel::bitfield!(@default $name { $($field;)* });
> >>     };
> >> 
> >>     // Defines all the field getter/setter methods for `$name`.
> >> @@ -155,13 +156,13 @@ fn from(val: $name) -> $storage {
> >>         }
> >>     ) => {
> >>         $(
> >> -            bitfield!(@check_field_bounds $hi:$lo $field as $type);
> >> +            ::kernel::bitfield!(@check_field_bounds $hi:$lo $field as $type);
> >>         )*
> >> 
> >>         #[allow(dead_code)]
> >>         impl $name {
> >>             $(
> >> -            bitfield!(@field_accessor $vis $name $storage, $hi:$lo $field as $type
> >> +            ::kernel::bitfield!(@field_accessor $vis $name $storage, $hi:$lo $field as $type
> >>                 $(?=> $try_into_type)?
> >>                 $(=> $into_type)?
> >>                 $(, $comment)?
> >> @@ -198,7 +199,7 @@ impl $name {
> >>         @field_accessor $vis:vis $name:ident $storage:ty, $hi:tt:$lo:tt $field:ident as bool => $into_type:ty
> >>             $(, $comment:literal)?;
> >>     ) => {
> >> -        bitfield!(
> >> +        ::kernel::bitfield!(
> >>             @leaf_accessor $vis $name $storage, $hi:$lo $field
> >>             { |f| <$into_type>::from(if f != 0 { true } else { false }) }
> >>             $into_type => $into_type $(, $comment)?;
> >> @@ -209,7 +210,7 @@ impl $name {
> >>     (
> >>         @field_accessor $vis:vis $name:ident $storage:ty, $hi:tt:$lo:tt $field:ident as bool $(, $comment:literal)?;
> >>     ) => {
> >> -        bitfield!(@field_accessor $vis $name $storage, $hi:$lo $field as bool => bool $(, $comment)?;);
> >> +        ::kernel::bitfield!(@field_accessor $vis $name $storage, $hi:$lo $field as bool => bool $(, $comment)?;);
> >>     };
> >> 
> >>     // Catches the `?=>` syntax for non-boolean fields.
> >> @@ -217,7 +218,7 @@ impl $name {
> >>         @field_accessor $vis:vis $name:ident $storage:ty, $hi:tt:$lo:tt $field:ident as $type:tt ?=> $try_into_type:ty
> >>             $(, $comment:literal)?;
> >>     ) => {
> >> -        bitfield!(@leaf_accessor $vis $name $storage, $hi:$lo $field
> >> +        ::kernel::bitfield!(@leaf_accessor $vis $name $storage, $hi:$lo $field
> >>             { |f| <$try_into_type>::try_from(f as $type) } $try_into_type =>
> >>             ::core::result::Result<
> >>                 $try_into_type,
> >> @@ -231,7 +232,7 @@ impl $name {
> >>         @field_accessor $vis:vis $name:ident $storage:ty, $hi:tt:$lo:tt $field:ident as $type:tt => $into_type:ty
> >>             $(, $comment:literal)?;
> >>     ) => {
> >> -        bitfield!(@leaf_accessor $vis $name $storage, $hi:$lo $field
> >> +        ::kernel::bitfield!(@leaf_accessor $vis $name $storage, $hi:$lo $field
> >>             { |f| <$into_type>::from(f as $type) } $into_type => $into_type $(, $comment)?;);
> >>     };
> >> 
> >> @@ -240,7 +241,7 @@ impl $name {
> >>         @field_accessor $vis:vis $name:ident $storage:ty, $hi:tt:$lo:tt $field:ident as $type:tt
> >>             $(, $comment:literal)?;
> >>     ) => {
> >> -        bitfield!(@field_accessor $vis $name $storage, $hi:$lo $field as $type => $type $(, $comment)?;);
> >> +        ::kernel::bitfield!(@field_accessor $vis $name $storage, $hi:$lo $field as $type => $type $(, $comment)?;);
> >>     };
> >> 
> >>     // Generates the accessor methods for a single field.
> >> diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs
> >> index 03b467722b86..a79b603604b1 100644
> >> --- a/rust/kernel/io.rs
> >> +++ b/rust/kernel/io.rs
> >> @@ -8,6 +8,7 @@
> >> use crate::{bindings, build_assert, ffi::c_void};
> >> 
> >> pub mod mem;
> >> +pub mod register;
> >> pub mod resource;
> >> 
> >> pub use resource::Resource;
> >> diff --git a/drivers/gpu/nova-core/regs/macros.rs b/rust/kernel/io/register.rs
> >> similarity index 93%
> >> rename from drivers/gpu/nova-core/regs/macros.rs
> >> rename to rust/kernel/io/register.rs
> >> index c0a5194e8d97..c24d956f122f 100644
> >> --- a/drivers/gpu/nova-core/regs/macros.rs
> >> +++ b/rust/kernel/io/register.rs
> >> @@ -17,7 +17,8 @@
> >> /// The `T` generic argument is used to distinguish which base to use, in case a type provides
> >> /// several bases. It is given to the `register!` macro to restrict the use of the register to
> >> /// implementors of this particular variant.
> >> -pub(crate) trait RegisterBase<T> {
> >> +pub trait RegisterBase<T> {
> >> +    /// The base address for the register.
> >>     const BASE: usize;
> >> }
> >> 
> >> @@ -26,7 +27,7 @@ pub(crate) trait RegisterBase<T> {
> >> ///
> >> /// Example:
> >> ///
> >> -/// ```no_run
> >> +/// ```ignore
> >> /// register!(BOOT_0 @ 0x00000100, "Basic revision information about the GPU" {
> >> ///    3:0     minor_revision as u8, "Minor revision of the chip";
> >> ///    7:4     major_revision as u8, "Major revision of the chip";
> >> @@ -39,7 +40,7 @@ pub(crate) trait RegisterBase<T> {
> >> /// significant bits of the register. Each field can be accessed and modified using accessor
> >> /// methods:
> >> ///
> >> -/// ```no_run
> >> +/// ```ignore
> >> /// // Read from the register's defined offset (0x100).
> >> /// let boot0 = BOOT_0::read(&bar);
> >> /// pr_info!("chip revision: {}.{}", boot0.major_revision(), boot0.minor_revision());
> >> @@ -61,7 +62,7 @@ pub(crate) trait RegisterBase<T> {
> >> /// It is also possible to create a alias register by using the `=> ALIAS` syntax. This is useful
> >> /// for cases where a register's interpretation depends on the context:
> >> ///
> >> -/// ```no_run
> >> +/// ```ignore
> >> /// register!(SCRATCH @ 0x00000200, "Scratch register" {
> >> ///    31:0     value as u32, "Raw value";
> >> /// });
> >> @@ -111,7 +112,7 @@ pub(crate) trait RegisterBase<T> {
> >> /// this register needs to implement `RegisterBase<Base>`. Here is the above example translated
> >> /// into code:
> >> ///
> >> -/// ```no_run
> >> +/// ```ignore
> >> /// // Type used to identify the base.
> >> /// pub(crate) struct CpuCtlBase;
> >> ///
> >> @@ -162,7 +163,7 @@ pub(crate) trait RegisterBase<T> {
> >> /// compile-time or runtime bound checking. Simply define their address as `Address[Size]`, and add
> >> /// an `idx` parameter to their `read`, `write` and `alter` methods:
> >> ///
> >> -/// ```no_run
> >> +/// ```ignore
> >> /// # fn no_run() -> Result<(), Error> {
> >> /// # fn get_scratch_idx() -> usize {
> >> /// #   0x15
> >> @@ -211,7 +212,7 @@ pub(crate) trait RegisterBase<T> {
> >> /// Combining the two features described in the sections above, arrays of registers accessible from
> >> /// a base can also be defined:
> >> ///
> >> -/// ```no_run
> >> +/// ```ignore
> >> /// # fn no_run() -> Result<(), Error> {
> >> /// # fn get_scratch_idx() -> usize {
> >> /// #   0x15
> >> @@ -273,28 +274,29 @@ pub(crate) trait RegisterBase<T> {
> >> /// # Ok(())
> >> /// # }
> >> /// ```
> >> +#[macro_export]
> >> macro_rules! register {
> >>     // Creates a register at a fixed offset of the MMIO space.
> >>     ($name:ident @ $offset:literal $(, $comment:literal)? { $($fields:tt)* } ) => {
> >> -        bitfield!(pub(crate) struct $name(u32) $(, $comment)? { $($fields)* } );
> >> +        ::kernel::bitfield!(pub(crate) struct $name(u32) $(, $comment)? { $($fields)* } );
> >>         register!(@io_fixed $name @ $offset);
> >>     };
> >> 
> >>     // Creates an alias register of fixed offset register `alias` with its own fields.
> >>     ($name:ident => $alias:ident $(, $comment:literal)? { $($fields:tt)* } ) => {
> >> -        bitfield!(pub(crate) struct $name(u32) $(, $comment)? { $($fields)* } );
> >> +        ::kernel::bitfield!(pub(crate) struct $name(u32) $(, $comment)? { $($fields)* } );
> >>         register!(@io_fixed $name @ $alias::OFFSET);
> >>     };
> >> 
> >>     // Creates a register at a relative offset from a base address provider.
> >>     ($name:ident @ $base:ty [ $offset:literal ] $(, $comment:literal)? { $($fields:tt)* } ) => {
> >> -        bitfield!(pub(crate) struct $name(u32) $(, $comment)? { $($fields)* } );
> >> +        ::kernel::bitfield!(pub(crate) struct $name(u32) $(, $comment)? { $($fields)* } );
> >>         register!(@io_relative $name @ $base [ $offset ]);
> >>     };
> >> 
> >>     // Creates an alias register of relative offset register `alias` with its own fields.
> >>     ($name:ident => $base:ty [ $alias:ident ] $(, $comment:literal)? { $($fields:tt)* }) => {
> >> -        bitfield!(pub(crate) struct $name(u32) $(, $comment)? { $($fields)* } );
> >> +        ::kernel::bitfield!(pub(crate) struct $name(u32) $(, $comment)? { $($fields)* } );
> >>         register!(@io_relative $name @ $base [ $alias::OFFSET ]);
> >>     };
> >> 
> >> @@ -305,7 +307,7 @@ macro_rules! register {
> >>         }
> >>     ) => {
> >>         static_assert!(::core::mem::size_of::<u32>() <= $stride);
> >> -        bitfield!(pub(crate) struct $name(u32) $(, $comment)? { $($fields)* } );
> >> +        ::kernel::bitfield!(pub(crate) struct $name(u32) $(, $comment)? { $($fields)* } );
> >>         register!(@io_array $name @ $offset [ $size ; $stride ]);
> >>     };
> >> 
> >> @@ -326,7 +328,7 @@ macro_rules! register {
> >>             $(, $comment:literal)? { $($fields:tt)* }
> >>     ) => {
> >>         static_assert!(::core::mem::size_of::<u32>() <= $stride);
> >> -        bitfield!(pub(crate) struct $name(u32) $(, $comment)? { $($fields)* } );
> >> +        ::kernel::bitfield!(pub(crate) struct $name(u32) $(, $comment)? { $($fields)* } );
> >>         register!(@io_relative_array $name @ $base [ $offset [ $size ; $stride ] ]);
> >>     };
> >> 
> >> @@ -348,7 +350,7 @@ macro_rules! register {
> >>         }
> >>     ) => {
> >>         static_assert!($idx < $alias::SIZE);
> >> -        bitfield!(pub(crate) struct $name(u32) $(, $comment)? { $($fields)* } );
> >> +        ::kernel::bitfield!(pub(crate) struct $name(u32) $(, $comment)? { $($fields)* } );
> >>         register!(@io_relative $name @ $base [ $alias::OFFSET + $idx * $alias::STRIDE ] );
> >>     };
> >> 
> >> @@ -357,7 +359,7 @@ macro_rules! register {
> >>     // to avoid it being interpreted in place of the relative register array alias rule.
> >>     ($name:ident => $alias:ident [ $idx:expr ] $(, $comment:literal)? { $($fields:tt)* }) => {
> >>         static_assert!($idx < $alias::SIZE);
> >> -        bitfield!(pub(crate) struct $name(u32) $(, $comment)? { $($fields)* } );
> >> +        ::kernel::bitfield!(pub(crate) struct $name(u32) $(, $comment)? { $($fields)* } );
> >>         register!(@io_fixed $name @ $alias::OFFSET + $idx * $alias::STRIDE );
> >>     };
> >> 
> >> @@ -414,12 +416,12 @@ pub(crate) fn read<const SIZE: usize, T, B>(
> >>                 base: &B,
> >>             ) -> Self where
> >>                 T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
> >> -                B: crate::regs::macros::RegisterBase<$base>,
> >> +                B: ::kernel::io::register::RegisterBase<$base>,
> >>             {
> >>                 const OFFSET: usize = $name::OFFSET;
> >> 
> >>                 let value = io.read32(
> >> -                    <B as crate::regs::macros::RegisterBase<$base>>::BASE + OFFSET
> >> +                    <B as ::kernel::io::register::RegisterBase<$base>>::BASE + OFFSET
> >>                 );
> >> 
> >>                 Self(value)
> >> @@ -435,13 +437,13 @@ pub(crate) fn write<const SIZE: usize, T, B>(
> >>                 base: &B,
> >>             ) where
> >>                 T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
> >> -                B: crate::regs::macros::RegisterBase<$base>,
> >> +                B: ::kernel::io::register::RegisterBase<$base>,
> >>             {
> >>                 const OFFSET: usize = $name::OFFSET;
> >> 
> >>                 io.write32(
> >>                     self.0,
> >> -                    <B as crate::regs::macros::RegisterBase<$base>>::BASE + OFFSET
> >> +                    <B as ::kernel::io::register::RegisterBase<$base>>::BASE + OFFSET
> >>                 );
> >>             }
> >> 
> >> @@ -455,7 +457,7 @@ pub(crate) fn alter<const SIZE: usize, T, B, F>(
> >>                 f: F,
> >>             ) where
> >>                 T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
> >> -                B: crate::regs::macros::RegisterBase<$base>,
> >> +                B: ::kernel::io::register::RegisterBase<$base>,
> >>                 F: ::core::ops::FnOnce(Self) -> Self,
> >>             {
> >>                 let reg = f(Self::read(io, base));
> >> @@ -600,11 +602,11 @@ pub(crate) fn read<const SIZE: usize, T, B>(
> >>                 idx: usize,
> >>             ) -> Self where
> >>                 T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
> >> -                B: crate::regs::macros::RegisterBase<$base>,
> >> +                B: ::kernel::io::register::RegisterBase<$base>,
> >>             {
> >>                 build_assert!(idx < Self::SIZE);
> >> 
> >> -                let offset = <B as crate::regs::macros::RegisterBase<$base>>::BASE +
> >> +                let offset = <B as ::kernel::io::register::RegisterBase<$base>>::BASE +
> >>                     Self::OFFSET + (idx * Self::STRIDE);
> >>                 let value = io.read32(offset);
> >> 
> >> @@ -622,11 +624,11 @@ pub(crate) fn write<const SIZE: usize, T, B>(
> >>                 idx: usize
> >>             ) where
> >>                 T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
> >> -                B: crate::regs::macros::RegisterBase<$base>,
> >> +                B: ::kernel::io::register::RegisterBase<$base>,
> >>             {
> >>                 build_assert!(idx < Self::SIZE);
> >> 
> >> -                let offset = <B as crate::regs::macros::RegisterBase<$base>>::BASE +
> >> +                let offset = <B as ::kernel::io::register::RegisterBase<$base>>::BASE +
> >>                     Self::OFFSET + (idx * Self::STRIDE);
> >> 
> >>                 io.write32(self.0, offset);
> >> @@ -643,7 +645,7 @@ pub(crate) fn alter<const SIZE: usize, T, B, F>(
> >>                 f: F,
> >>             ) where
> >>                 T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
> >> -                B: crate::regs::macros::RegisterBase<$base>,
> >> +                B: ::kernel::io::register::RegisterBase<$base>,
> >>                 F: ::core::ops::FnOnce(Self) -> Self,
> >>             {
> >>                 let reg = f(Self::read(io, base, idx));
> >> @@ -662,7 +664,7 @@ pub(crate) fn try_read<const SIZE: usize, T, B>(
> >>                 idx: usize,
> >>             ) -> ::kernel::error::Result<Self> where
> >>                 T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
> >> -                B: crate::regs::macros::RegisterBase<$base>,
> >> +                B: ::kernel::io::register::RegisterBase<$base>,
> >>             {
> >>                 if idx < Self::SIZE {
> >>                     Ok(Self::read(io, base, idx))
> >> @@ -684,7 +686,7 @@ pub(crate) fn try_write<const SIZE: usize, T, B>(
> >>                 idx: usize,
> >>             ) -> ::kernel::error::Result where
> >>                 T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
> >> -                B: crate::regs::macros::RegisterBase<$base>,
> >> +                B: ::kernel::io::register::RegisterBase<$base>,
> >>             {
> >>                 if idx < Self::SIZE {
> >>                     Ok(self.write(io, base, idx))
> >> @@ -707,7 +709,7 @@ pub(crate) fn try_alter<const SIZE: usize, T, B, F>(
> >>                 f: F,
> >>             ) -> ::kernel::error::Result where
> >>                 T: ::core::ops::Deref<Target = ::kernel::io::Io<SIZE>>,
> >> -                B: crate::regs::macros::RegisterBase<$base>,
> >> +                B: ::kernel::io::register::RegisterBase<$base>,
> >>                 F: ::core::ops::FnOnce(Self) -> Self,
> >>             {
> >>                 if idx < Self::SIZE {
> >> diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
> >> index fcffc3988a90..8f8260090c02 100644
> >> --- a/rust/kernel/lib.rs
> >> +++ b/rust/kernel/lib.rs
> >> @@ -63,6 +63,7 @@
> >> pub mod alloc;
> >> #[cfg(CONFIG_AUXILIARY_BUS)]
> >> pub mod auxiliary;
> >> +pub mod bitfield;
> >> pub mod bits;
> >> #[cfg(CONFIG_BLOCK)]
> >> pub mod block;
> >> --
> >> 2.34.1
> >> 
> >> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ