From: Alexandre Courbot Date: Sat, 6 Jun 2026 12:43:06 +0000 (+0900) Subject: rust: io: use the `bitfield!` macro in `register!` X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=01504bc3b7d1ffc1f05ad507ebdc5400e45e9a4d;p=thirdparty%2Flinux.git rust: io: use the `bitfield!` macro in `register!` 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 Acked-by: Danilo Krummrich Signed-off-by: Alexandre Courbot Reviewed-by: Yury Norov Link: https://patch.msgid.link/20260606-bitfield-v5-3-b92188820914@nvidia.com Signed-off-by: Miguel Ojeda --- diff --git a/rust/kernel/io/register.rs b/rust/kernel/io/register.rs index abc49926abfe7..388647f28292e 100644 --- a/rust/kernel/io/register.rs +++ b/rust/kernel/io/register.rs @@ -956,11 +956,10 @@ macro_rules! register { ( @bitfield $(#[$attr:meta])* $vis:vis struct $name:ident($storage:ty) { $($fields:tt)* } ) => { - $crate::register!(@bitfield_core + $crate::bitfield!( #[allow(non_camel_case_types)] - $(#[$attr])* $vis $name $storage + $(#[$attr])* $vis struct $name($storage) { $($fields)* } ); - $crate::register!(@bitfield_fields $vis $name $storage { $($fields)* }); }; // Implementations shared by all registers types. @@ -1016,245 +1015,4 @@ macro_rules! register { impl $crate::io::register::RelativeRegisterArray for $name {} }; - - // Defines the wrapper `$name` type and its conversions from/to the storage type. - (@bitfield_core $(#[$attr:meta])* $vis:vis $name:ident $storage:ty) => { - $(#[$attr])* - #[repr(transparent)] - #[derive(Clone, Copy, PartialEq, Eq)] - $vis struct $name { - inner: $storage, - } - - #[allow(dead_code)] - impl $name { - /// Creates a bitfield from a raw value. - #[inline(always)] - $vis const fn from_raw(value: $storage) -> Self { - Self{ inner: value } - } - - /// Turns this bitfield into its raw value. - /// - /// This is similar to the [`From`] implementation, but is shorter to invoke in - /// most cases. - #[inline(always)] - $vis const fn into_raw(self) -> $storage { - self.inner - } - } - - // SAFETY: `$storage` is `Zeroable` and `$name` is transparent. - unsafe impl ::pin_init::Zeroable for $name {} - - impl ::core::convert::From<$name> for $storage { - #[inline(always)] - fn from(val: $name) -> $storage { - val.into_raw() - } - } - - impl ::core::convert::From<$storage> for $name { - #[inline(always)] - fn from(val: $storage) -> $name { - Self::from_raw(val) - } - } - }; - - // Definitions requiring knowledge of individual fields: private and public field accessors, - // and `Debug` implementation. - (@bitfield_fields $vis:vis $name:ident $storage:ty { - $($(#[doc = $doc:expr])* $hi:literal:$lo:literal $field:ident - $(?=> $try_into_type:ty)? - $(=> $into_type:ty)? - ; - )* - } - ) => { - #[allow(dead_code)] - impl $name { - $( - $crate::register!(@private_field_accessors $vis $name $storage : $hi:$lo $field); - $crate::register!( - @public_field_accessors $(#[doc = $doc])* $vis $name $storage : $hi:$lo $field - $(?=> $try_into_type)? - $(=> $into_type)? - ); - )* - } - - $crate::register!(@debug $name { $($field;)* }); - }; - - // Private field accessors working with the exact `Bounded` type for the field. - ( - @private_field_accessors $vis:vis $name:ident $storage:ty : $hi:tt:$lo:tt $field:ident - ) => { - ::kernel::macros::paste!( - $vis const [<$field:upper _RANGE>]: ::core::ops::RangeInclusive = $lo..=$hi; - $vis const [<$field:upper _MASK>]: $storage = - ((((1 << $hi) - 1) << 1) + 1) - ((1 << $lo) - 1); - $vis const [<$field:upper _SHIFT>]: u32 = $lo; - ); - - ::kernel::macros::paste!( - fn [<__ $field>](self) -> - ::kernel::num::Bounded<$storage, { $hi + 1 - $lo }> { - // Left shift to align the field's MSB with the storage MSB. - const ALIGN_TOP: u32 = $storage::BITS - ($hi + 1); - // Right shift to move the top-aligned field to bit 0 of the storage. - const ALIGN_BOTTOM: u32 = ALIGN_TOP + $lo; - - // Extract the field using two shifts. `Bounded::shr` produces the correctly-sized - // output type. - let val = ::kernel::num::Bounded::<$storage, { $storage::BITS }>::from( - self.inner << ALIGN_TOP - ); - val.shr::() - } - - const fn [<__with_ $field>]( - mut self, - value: ::kernel::num::Bounded<$storage, { $hi + 1 - $lo }>, - ) -> Self - { - const MASK: $storage = <$name>::[<$field:upper _MASK>]; - const SHIFT: u32 = <$name>::[<$field:upper _SHIFT>]; - - let value = value.get() << SHIFT; - self.inner = (self.inner & !MASK) | value; - - self - } - ); - }; - - // Public accessors for fields infallibly (`=>`) converted to a type. - ( - @public_field_accessors $(#[doc = $doc:expr])* $vis:vis $name:ident $storage:ty : - $hi:literal:$lo:literal $field:ident => $into_type:ty - ) => { - ::kernel::macros::paste!( - - $(#[doc = $doc])* - #[doc = "Returns the value of this field."] - #[inline(always)] - $vis fn $field(self) -> $into_type - { - self.[<__ $field>]().into() - } - - $(#[doc = $doc])* - #[doc = "Sets this field to the given `value`."] - #[inline(always)] - $vis fn [](self, value: $into_type) -> Self - { - self.[<__with_ $field>](value.into()) - } - - ); - }; - - // Public accessors for fields fallibly (`?=>`) converted to a type. - ( - @public_field_accessors $(#[doc = $doc:expr])* $vis:vis $name:ident $storage:ty : - $hi:tt:$lo:tt $field:ident ?=> $try_into_type:ty - ) => { - ::kernel::macros::paste!( - - $(#[doc = $doc])* - #[doc = "Returns the value of this field."] - #[inline(always)] - $vis fn $field(self) -> - Result< - $try_into_type, - <$try_into_type as ::core::convert::TryFrom< - ::kernel::num::Bounded<$storage, { $hi + 1 - $lo }> - >>::Error - > - { - self.[<__ $field>]().try_into() - } - - $(#[doc = $doc])* - #[doc = "Sets this field to the given `value`."] - #[inline(always)] - $vis fn [](self, value: $try_into_type) -> Self - { - self.[<__with_ $field>](value.into()) - } - - ); - }; - - // Public accessors for fields not converted to a type. - ( - @public_field_accessors $(#[doc = $doc:expr])* $vis:vis $name:ident $storage:ty : - $hi:tt:$lo:tt $field:ident - ) => { - ::kernel::macros::paste!( - - $(#[doc = $doc])* - #[doc = "Returns the value of this field."] - #[inline(always)] - $vis fn $field(self) -> - ::kernel::num::Bounded<$storage, { $hi + 1 - $lo }> - { - self.[<__ $field>]() - } - - $(#[doc = $doc])* - #[doc = "Sets this field to the compile-time constant `VALUE`."] - #[inline(always)] - $vis const fn [](self) -> Self { - self.[<__with_ $field>]( - ::kernel::num::Bounded::<$storage, { $hi + 1 - $lo }>::new::() - ) - } - - $(#[doc = $doc])* - #[doc = "Sets this field to the given `value`."] - #[inline(always)] - $vis fn []( - self, - value: T, - ) -> Self - where T: Into<::kernel::num::Bounded<$storage, { $hi + 1 - $lo }>>, - { - self.[<__with_ $field>](value.into()) - } - - $(#[doc = $doc])* - #[doc = "Tries to set this field to `value`, returning an error if it is out of range."] - #[inline(always)] - $vis fn []( - self, - value: T, - ) -> ::kernel::error::Result - where T: ::kernel::num::TryIntoBounded<$storage, { $hi + 1 - $lo }>, - { - Ok( - self.[<__with_ $field>]( - value.try_into_bounded().ok_or(::kernel::error::code::EOVERFLOW)? - ) - ) - } - - ); - }; - - // `Debug` implementation. - (@debug $name:ident { $($field:ident;)* }) => { - impl ::kernel::fmt::Debug for $name { - fn fmt(&self, f: &mut ::kernel::fmt::Formatter<'_>) -> ::kernel::fmt::Result { - f.debug_struct(stringify!($name)) - .field("", &::kernel::prelude::fmt!("{:#x}", self.inner)) - $( - .field(stringify!($field), &self.$field()) - )* - .finish() - } - } - }; }