[PATCH v2 05/16] rust: io: register extract offset computation to helper rules

Gary Guo <[email protected]>
Newsgroups dev.linux.lists.nova-gpu,dev.linux.lists.driver-core,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci,org.kernel.vger.rust-for-linux
Message-ID <[email protected]>
Create a helper rule for register offset computation so there can be a
single rule for fixed offset registers.

Similarly, extract stride computation to helper rules.

Signed-off-by: Gary Guo <[email protected]>
---
 rust/kernel/io/register.rs | 115 ++++++++++++++-------------------------------
 1 file changed, 36 insertions(+), 79 deletions(-)

diff --git a/rust/kernel/io/register.rs b/rust/kernel/io/register.rs
index 91804c1ca117..e4039e31b4e7 100644
--- a/rust/kernel/io/register.rs
+++ b/rust/kernel/io/register.rs
@@ -789,27 +789,19 @@ macro_rules! register {
     () => {};
 
     // Creates a register at a fixed offset of the MMIO space.
+    //
+    // This handles all of the fixed offset `@ offset`, alias of register `=> alias` and alias of
+    // register array element `=> alias[idx]` cases.
     (
-        $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) @ $offset:literal
-            { $($fields:tt)* }
-        $($rest:tt)*
-    ) => {
-        $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storage) { $($fields)* });
-        $crate::register!(@io_base $name @ $offset);
-        $crate::register!(@io_fixed $(#[$attr])* $vis $name);
-        $crate::register!($($rest)*);
-    };
-
-    // Creates an alias register of fixed offset register `alias` with its own fields.
-    (
-        $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) => $alias:ident
-            { $($fields:tt)* }
+        $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty)
+            $(@ $offset:literal)?
+            $(=> $alias:path $([$alias_idx:expr])? )?
+        { $($fields:tt)* }
         $($rest:tt)*
     ) => {
         $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storage) { $($fields)* });
-        $crate::register!(
-            @io_base $name @
-            <$alias as $crate::io::register::Register>::OFFSET
+        $crate::register!(@io_base $name
+            @ $crate::register!(@offset $(@ $offset)? $(=> $alias $([$alias_idx])?)?)
         );
         $crate::register!(@io_fixed $(#[$attr])* $vis $name);
         $crate::register!($($rest)*);
@@ -834,9 +826,7 @@ macro_rules! register {
         $($rest:tt)*
     ) => {
         $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storage) { $($fields)* });
-        $crate::register!(
-            @io_base $name @ <$alias as $crate::io::register::Register>::OFFSET
-        );
+        $crate::register!(@io_base $name @ $crate::register!(@offset => $alias));
         $crate::register!(@io_relative $vis $name @ $base);
         $crate::register!($($rest)*);
     };
@@ -844,76 +834,28 @@ macro_rules! register {
     // Creates an array of registers at a fixed offset of the MMIO space.
     (
         $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty)
-            [ $size:expr, stride = $stride:expr ] @ $offset:literal { $($fields:tt)* }
+            [ $size:expr $(, stride = $stride:expr)? ] @ $offset:literal { $($fields:tt)* }
         $($rest:tt)*
     ) => {
-        $crate::build_assert::static_assert!(::core::mem::size_of::<$storage>() <= $stride);
-
         $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storage) { $($fields)* });
         $crate::register!(@io_base $name @ $offset);
-        $crate::register!(@io_array $vis $name [ $size, stride = $stride ]);
-        $crate::register!($($rest)*);
-    };
-
-    // Shortcut for contiguous array of registers (stride == size of element).
-    (
-        $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) [ $size:expr ] @ $offset:literal
-            { $($fields:tt)* }
-        $($rest:tt)*
-    ) => {
-        $crate::register!(
-            $(#[$attr])* $vis $name($storage) [ $size, stride = ::core::mem::size_of::<$storage>() ]
-                @ $offset { $($fields)* }
-        );
-        $crate::register!($($rest)*);
-    };
-
-    // Creates an alias of register `idx` of array of registers `alias` with its own fields.
-    (
-        $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) => $alias:ident [ $idx:expr ]
-            { $($fields:tt)* }
-        $($rest:tt)*
-    ) => {
-        $crate::build_assert::static_assert!(
-            $idx < <$alias as $crate::io::register::RegisterArray>::SIZE
+        $crate::register!(@io_array $vis $name
+            [ $size, stride = $crate::register!(@stride $storage $(, $stride)?) ]
         );
-
-        $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storage) { $($fields)* });
-        $crate::register!(
-            @io_base $name @
-            <$alias as $crate::io::register::Register>::OFFSET
-                + $idx * <$alias as $crate::io::register::RegisterArray>::STRIDE
-        );
-        $crate::register!(@io_fixed $(#[$attr])* $vis $name);
         $crate::register!($($rest)*);
     };
 
     // Creates an array of registers at a relative offset from a base address provider.
     (
         $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty)
-            [ $size:expr, stride = $stride:expr ]
+            [ $size:expr $(, stride = $stride:expr)? ]
             @ $base:ident + $offset:literal { $($fields:tt)* }
         $($rest:tt)*
     ) => {
-        $crate::build_assert::static_assert!(::core::mem::size_of::<$storage>() <= $stride);
-
         $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storage) { $($fields)* });
         $crate::register!(@io_base $name @ $offset);
-        $crate::register!(
-            @io_relative_array $vis $name [ $size, stride = $stride ] @ $base + $offset
-        );
-        $crate::register!($($rest)*);
-    };
-
-    // Shortcut for contiguous array of relative registers (stride == size of element).
-    (
-        $(#[$attr:meta])* $vis:vis $name:ident ($storage:ty) [ $size:expr ]
-            @ $base:ident + $offset:literal { $($fields:tt)* }
-        $($rest:tt)*
-    ) => {
-        $crate::register!(
-            $(#[$attr])* $vis $name($storage) [ $size, stride = ::core::mem::size_of::<$storage>() ]
-                @ $base + $offset { $($fields)* }
+        $crate::register!(@io_relative_array $vis $name
+            [ $size, stride = $crate::register!(@stride $storage $(, $stride)?) ] @ $base + $offset
         );
         $crate::register!($($rest)*);
     };
@@ -930,11 +872,7 @@ macro_rules! register {
         );
 
         $crate::register!(@bitfield $(#[$attr])* $vis struct $name($storage) { $($fields)* });
-        $crate::register!(
-            @io_base $name @
-                <$alias as $crate::io::register::Register>::OFFSET +
-                $idx * <$alias as $crate::io::register::RegisterArray>::STRIDE
-        );
+        $crate::register!(@io_base $name @ $crate::register!(@offset => $alias [$idx]));
         $crate::register!(@io_relative $vis $name @ $base);
         $crate::register!($($rest)*);
     };
@@ -954,6 +892,25 @@ macro_rules! register {
         );
     };
 
+    // Offset computation helper rules.
+    (@offset @ $offset:expr) => { $offset };
+    (@offset => $alias:path) => { <$alias as $crate::io::register::Register>::OFFSET };
+    (@offset => $alias:path [$idx:expr]) => {{
+        $crate::build_assert::static_assert!(
+            $idx < <$alias as $crate::io::register::RegisterArray>::SIZE
+        );
+
+        <$alias as $crate::io::register::Register>::OFFSET +
+            $idx * <$alias as $crate::io::register::RegisterArray>::STRIDE
+    }};
+
+    // Stride computation helper rules.
+    (@stride $ty: ty, $stride: expr) => {{
+        $crate::build_assert::static_assert!(::core::mem::size_of::<$ty>() <= $stride);
+        $stride
+    }};
+    (@stride $ty: ty) => { ::core::mem::size_of::<$ty>() };
+
     // Implementations shared by all registers types.
     (@io_base $name:ident @ $offset:expr) => {
         impl $crate::io::register::Register for $name {

-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.