From: "Alexandre Courbot" <acourbot@nvidia.com>
To: "Danilo Krummrich" <dakr@kernel.org>
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: Sat, 15 Mar 2025 23:21:48 +0900 [thread overview]
Message-ID: <D8GWNOPYRQN3.GO3XVERSQUXH@nvidia.com> (raw)
In-Reply-To: <Z9MSW4VAjqWd4NmY@pollux>
On Fri Mar 14, 2025 at 2:14 AM JST, Danilo Krummrich wrote:
> 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!`?
I was thinking this is maybe too generic, but yeah it probably makes
sense. ^_^;
>
>> 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.
Sure!
>
>>
>> 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?
We probably can't do that reliably IIUC - a 32-bit register might only
have its 8 LSBs holding useful data, it would still need to be read
using a 32-bit access nonetheless... Or maybe I misunderstood your
suggestion?
>
>> - 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?
Another rabbit hole to dive into. ^_^;
That would probably allow a better syntax, while at the same time
solving the issue of the exported helper macros. Let me give it a try.
>
>> - 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.
Right, in this case you wouldn't need to access the value through Io,
and only the field helpers make sense - so I guess they are orthogonal
with the Io access impl in the end.
prev parent reply other threads:[~2025-03-15 14:21 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
2025-03-15 14:21 ` Alexandre Courbot [this message]
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=D8GWNOPYRQN3.GO3XVERSQUXH@nvidia.com \
--to=acourbot@nvidia.com \
--cc=a.hindborg@kernel.org \
--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=dakr@kernel.org \
--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.