From: "Alexandre Courbot" <acourbot@nvidia.com>
To: "Daniel Almeida" <daniel.almeida@collabora.com>
Cc: "Danilo Krummrich" <dakr@kernel.org>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
"Maxime Ripard" <mripard@kernel.org>,
"Thomas Zimmermann" <tzimmermann@suse.de>,
"Beata Michalska" <beata.michalska@arm.com>,
<nouveau@lists.freedesktop.org>,
<dri-devel@lists.freedesktop.org>,
<rust-for-linux@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v2 15/19] gpu: nova-core: register: redesign relative registers
Date: Mon, 28 Jul 2025 14:07:35 +0900 [thread overview]
Message-ID: <DBNFEW6TF3JZ.1WW0SFGRXXJYI@nvidia.com> (raw)
In-Reply-To: <F19649A8-3002-4BAC-8FBF-095CF67B3946@collabora.com>
On Sat Jul 26, 2025 at 3:56 AM JST, Daniel Almeida wrote:
> Hi Alex,
>
>> On 18 Jul 2025, at 04:26, Alexandre Courbot <acourbot@nvidia.com> wrote:
>>
>> The relative registers are currently very unsafe to use: callers can
>> specify any constant as the base address for access, meaning they can
>> effectively interpret any I/O address as any relative register.
>>
>> Ideally, valid base addresses for a family of registers should be
>> explicitly defined in the code, and could only be used with the relevant
>> registers
>>
>> This patch changes the relative register declaration into this:
>>
>> register!(REGISTER_NAME @ BaseTrait[offset] ...
>>
>> Where `BaseTrait` is the name of a ZST used as a parameter of the
>> `RegisterBase<>` trait to define a trait unique to a class of register.
>> This specialized trait is then implemented for every type that provides
>> a valid base address, enabling said types to be passed as the base
>> address provider for the register's I/O accessor methods.
>>
>> This design thus makes it impossible to pass an unexpected base address
>> to a relative register, and, since the valid bases are all known at
>> compile-time, also guarantees that all I/O accesses are done within the
>> valid bounds of the I/O range.
>>
>> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
>
>
> I think it would be helpful to showcase a before/after in the commit message. IIUC, we'd go from:
Agreed, that would help understand the change better.
>
> /// Putting a `+` before the address of the register makes it relative to a base: the `read` and
> /// `write` methods take a `base` argument that is added to the specified address before access:
> ///
> /// ```no_run
> /// register!(CPU_CTL @ +0x0000010, "CPU core control" {
> /// 0:0 start as bool, "Start the CPU core";
> /// });
>
>
> To:
>
> /// ```no_run
> /// // Type used to identify the base.
> /// pub(crate) struct CpuCtlBase;
> ///
> /// // ZST describing `CPU0`.
> /// struct Cpu0;
> /// impl RegisterBase<CpuCtlBase> for Cpu0 {
> /// const BASE: usize = 0x100;
> /// }
> /// // Singleton of `CPU0` used to identify it.
> /// const CPU0: Cpu0 = Cpu0;
> ///
> /// // ZST describing `CPU1`.
> /// struct Cpu1;
> /// impl RegisterBase<CpuCtlBase> for Cpu1 {
> /// const BASE: usize = 0x200;
> /// }
> /// // Singleton of `CPU1` used to identify it.
> /// const CPU1: Cpu1 = Cpu1;
>
> So you can still pass whatever base you want, the difference (in this
> particular aspect) is whether it's specified in the macro itself, or as an
> associated constant of RegisterBase<Foo>?
The difference between the two designs is that with the former one, the
code reading the register could pass any base it wanted (any number!),
whereas with the new one that base must come from an explicitly-defined
type (which implementation is controlled by the party defining the
register), which reduces the risk of typos and mixups. The type system
ensures that you cannot e.g. pass the base of a GPU to a CPU for
instance, whereas the previous approach had no such protection.
>
> In any case, have you considered what happens when the number of "CPUs" in your
> example grows larger? I can only speak for Tyr, where (IIUC), I'd have to
> define 16 structs, each representing a single AS region, i.e.:
>
> +pub(crate) const MMU_BASE: usize = 0x2400;
> +pub(crate) const MMU_AS_SHIFT: usize = 6;
> +
> +const fn mmu_as(as_nr: usize) -> usize {
> + MMU_BASE + (as_nr << MMU_AS_SHIFT)
> +
> +pub(crate) struct AsRegister(usize);
> +
> +impl AsRegister {
> + fn new(as_nr: usize, offset: usize) -> Result<Self> {
> + if as_nr >= 32 {
> + Err(EINVAL)
> + } else {
> + Ok(AsRegister(mmu_as(as_nr) + offset))
> + }
> + }
>
> It's still somewhat manageable, but I wonder if there are usecases out there
> (in other drivers/devices) where this number will be even higher, which will
> make this pattern impossible to implement.
If the range separating each instance is the same fixed number, then
this sounds like a good chance to use a register array with a stride of
`(1 << MMU_AS_SHIFT)`. But I suspect you figured that out. :)
next prev parent reply other threads:[~2025-07-28 5:07 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-18 7:26 [PATCH v2 00/19] gpu: nova-core: register!() macro improvements Alexandre Courbot
2025-07-18 7:26 ` [PATCH v2 01/19] gpu: nova-core: register: minor grammar and spelling fixes Alexandre Courbot
2025-07-25 16:14 ` Daniel Almeida
2025-07-25 20:43 ` John Hubbard
2025-07-28 4:59 ` Alexandre Courbot
2025-07-28 7:51 ` Steven Price
2025-07-28 11:43 ` Alexandre Courbot
2025-07-28 13:25 ` Steven Price
2025-07-29 13:47 ` Alexandre Courbot
2025-07-30 9:27 ` Steven Price
2025-07-30 12:47 ` Daniel Almeida
2025-07-18 7:26 ` [PATCH v2 02/19] gpu: nova-core: register: fix typo Alexandre Courbot
2025-07-18 19:05 ` Boqun Feng
2025-07-22 12:38 ` Alexandre Courbot
2025-07-25 16:18 ` Daniel Almeida
2025-07-18 7:26 ` [PATCH v2 03/19] gpu: nova-core: register: allow fields named `offset` Alexandre Courbot
2025-07-25 16:20 ` Daniel Almeida
2025-07-18 7:26 ` [PATCH v2 04/19] gpu: nova-core: register: improve documentation for basic registers Alexandre Courbot
2025-07-25 16:49 ` Daniel Almeida
2025-07-18 7:26 ` [PATCH v2 05/19] gpu: nova-core: register: simplify @leaf_accessor rule Alexandre Courbot
2025-07-25 16:53 ` Daniel Almeida
2025-07-18 7:26 ` [PATCH v2 06/19] gpu: nova-core: register: remove `try_` accessors for relative registers Alexandre Courbot
2025-07-25 16:55 ` Daniel Almeida
2025-07-18 7:26 ` [PATCH v2 07/19] gpu: nova-core: register: move OFFSET declaration to I/O impl block Alexandre Courbot
2025-07-25 17:03 ` Daniel Almeida
2025-07-28 5:02 ` Alexandre Courbot
2025-07-18 7:26 ` [PATCH v2 08/19] gpu: nova-core: register: fix documentation and indentation Alexandre Courbot
2025-07-25 17:04 ` Daniel Almeida
2025-07-18 7:26 ` [PATCH v2 09/19] gpu: nova-core: register: add missing doccomments for fixed registers I/O accessors Alexandre Courbot
2025-07-25 17:06 ` Daniel Almeida
2025-07-18 7:26 ` [PATCH v2 10/19] gpu: nova-core: register: add fields dispatcher internal rule Alexandre Courbot
2025-07-25 17:38 ` Daniel Almeida
2025-07-18 7:26 ` [PATCH v2 11/19] gpu: nova-core: register: improve `Debug` implementation Alexandre Courbot
2025-07-25 17:49 ` Daniel Almeida
2025-07-18 7:26 ` [PATCH v2 12/19] gpu: nova-core: register: generate correct `Default` implementation Alexandre Courbot
2025-07-25 17:53 ` Daniel Almeida
2025-07-18 7:26 ` [PATCH v2 13/19] gpu: nova-core: register: split @io rule into fixed and relative versions Alexandre Courbot
2025-07-25 17:58 ` Daniel Almeida
2025-07-18 7:26 ` [PATCH v2 14/19] gpu: nova-core: register: use #[inline(always)] for all methods Alexandre Courbot
2025-07-25 17:59 ` Daniel Almeida
2025-07-18 7:26 ` [PATCH v2 15/19] gpu: nova-core: register: redesign relative registers Alexandre Courbot
2025-07-25 18:56 ` Daniel Almeida
2025-07-28 5:07 ` Alexandre Courbot [this message]
2025-07-18 7:26 ` [PATCH v2 16/19] gpu: nova-core: falcon: add distinct base address for PFALCON2 Alexandre Courbot
2025-07-18 20:23 ` John Hubbard
2025-07-22 12:39 ` Alexandre Courbot
2025-07-18 7:26 ` [PATCH v2 17/19] gpu: nova-core: register: add support for register arrays Alexandre Courbot
2025-07-25 19:12 ` Daniel Almeida
2025-07-25 19:13 ` Daniel Almeida
2025-07-28 5:12 ` Alexandre Courbot
2025-07-18 7:26 ` [PATCH v2 18/19] gpu: nova-core: falcon: use register arrays for FUSE registers Alexandre Courbot
2025-07-18 7:26 ` [PATCH v2 19/19] gpu: nova-core: register: add support for relative array registers Alexandre Courbot
2025-08-14 22:52 ` [PATCH v2 00/19] gpu: nova-core: register!() macro improvements Lyude Paul
2025-08-15 4:44 ` 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=DBNFEW6TF3JZ.1WW0SFGRXXJYI@nvidia.com \
--to=acourbot@nvidia.com \
--cc=airlied@gmail.com \
--cc=beata.michalska@arm.com \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=nouveau@lists.freedesktop.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=simona@ffwll.ch \
--cc=tzimmermann@suse.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).