From: Danilo Krummrich <dakr@kernel.org>
To: Alexandre Courbot <acourbot@nvidia.com>
Cc: "Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <benno.lossin@proton.me>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org
Subject: Re: [PATCH RFC] rust: add macros to define registers layout
Date: Thu, 13 Mar 2025 18:14:03 +0100 [thread overview]
Message-ID: <Z9MSW4VAjqWd4NmY@pollux> (raw)
In-Reply-To: <20250313-registers-v1-1-8d498537e8b2@nvidia.com>
Hi Alex,
Thanks for working on a generic solution for this! Few comments below.
On Thu, Mar 13, 2025 at 11:48:25PM +0900, Alexandre Courbot wrote:
> Add two macros, reg_def!() and reg_def_rel!(), that define a given
> register's layout and provide accessors for absolute or relative
> offsets, respectively.
>
> The following example (taken from the rustdoc) helps understanding how
> they are used:
>
> reg_def!(Boot0@0x00000100, "Basic revision information about the chip";
Should we call the macro just `register!`?
> 3:0 minor_rev => as u8, "minor revision of the chip";
> 7:4 major_rev => as u8, "major revision of the chip";
> 28:20 chipset => try_into Chipset, "chipset model"
I think we probably need an argument indicating whether the register field is
{RW, RO, WO}, such that we can generate the corresponding accessors / set the
corresponding masks.
> );
>
> This defines a `Boot0` type which can be read or written from offset
> `0x100` of an `Io` region. It is composed of 3 fields, for instance
> `minor_rev` is made of the 4 less significant bits of the register. Each
> field can be accessed and modified using helper methods:
>
> // Read from offset `0x100`.
> let boot0 = Boot0.read(&bar);
> pr_info!("chip revision: {}.{}", boot0.major_rev(), boot0.minor_rev());
>
> // `Chipset::try_from` will be called with the value of the field and
> // returns an error if the value is invalid.
> let chipset = boot0.chipset()?;
>
> // Update some fields and write the value back.
> boot0.set_major_rev(3).set_minor_rev(10).write(&bar);
>
> Fields are made accessible using one of the following strategies:
>
> - `as <type>` simply casts the field value to the requested type.
> - `as_bit <type>` turns the field into a boolean and calls
> <type>::from()` with the obtained value. To be used with single-bit
> fields.
> - `into <type>` calls `<type>::from()` on the value of the field. It is
> expected to handle all the possible values for the bit range selected.
> - `try_into <type>` calls `<type>::try_from()` on the value of the field
> and returns its result.
I like that, including the conversion seems pretty convenient.
>
> The documentation strings are optional. If present, they will be added
> to the type or the field getter and setter methods they are attached to.
>
> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
> ---
> I have written these initially for the nova-core driver, then it has
> been suggested that they might be useful outside of it as well, so here
> goes.
Feel free to add my Suggested-by. You can also refer to the corresponding task
in our nova-core task list.
>
> This is my first serious attempt at writing Rust macros and I am sure
> there is a lot that is wrong with them, but I'd like to get early
> feedback and see whether this is actually something we want for the
> kernel in general.
>
> The following in particular needs to be improved, suggestions are
> welcome:
>
> - Inner types other than `u32` need to be supported - this can probably
> just be an extra parameter of the macro.
Can't we figure this out from the bit mask in the macro?
> - The syntax can certainly be improved. I've tried to some with
> something that makes the register layout obvious, while fitting within
> the expectations of the Rust macro parser, but my lack of experience
> certainly shows here.
Did you consider proc macros for more flexibility?
> - We probably need an option to make some fields or whole registers
> read-only.
Ah, I see, you thought of this already.
> - The I/O offset and read/write methods should be optional, so the
> layout part can be used for things that are not registers.
I guess you think of shared memory? For DMA we already have the dma_read! and
dma_write! macros that may fit in.
next prev parent reply other threads:[~2025-03-13 17:14 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-13 14:48 [PATCH RFC] rust: add macros to define registers layout Alexandre Courbot
2025-03-13 15:00 ` Boqun Feng
2025-03-13 15:02 ` Alexandre Courbot
2025-03-13 17:14 ` Danilo Krummrich [this message]
2025-03-15 14:21 ` Alexandre Courbot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Z9MSW4VAjqWd4NmY@pollux \
--to=dakr@kernel.org \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=benno.lossin@proton.me \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=gary@garyguo.net \
--cc=linux-kernel@vger.kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.