[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <ACAA327A-AE2B-4D21-B8C5-C66BB5E09B7C@nvidia.com>
Date: Wed, 22 Oct 2025 19:37:55 +0000
From: Joel Fernandes <joelagnelf@...dia.com>
To: Beata Michalska <beata.michalska@....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
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.
>
> 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?
> ...
>
> 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.
> );
>
>
> 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.
> 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