From: Joel Fernandes <joelagnelf@nvidia.com>
To: Elle Rhumsaa <elle@weathered-steel.dev>,
Yury Norov <yury.norov@gmail.com>,
Greg KH <gregkh@linuxfoundation.org>
Cc: Danilo Krummrich <dakr@kernel.org>,
Benno Lossin <lossin@kernel.org>,
linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org,
dri-devel@lists.freedesktop.org, acourbot@nvidia.com,
Alistair Popple <apopple@nvidia.com>,
Miguel Ojeda <ojeda@kernel.org>,
Alex Gaynor <alex.gaynor@gmail.com>,
Boqun Feng <boqun.feng@gmail.com>, Gary Guo <gary@garyguo.net>,
bjorn3_gh@protonmail.com,
Andreas Hindborg <a.hindborg@kernel.org>,
Alice Ryhl <aliceryhl@google.com>,
Trevor Gross <tmgross@umich.edu>,
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>,
John Hubbard <jhubbard@nvidia.com>, Timur Tabi <ttabi@nvidia.com>,
joel@joelfernandes.org,
Daniel Almeida <daniel.almeida@collabora.com>,
nouveau@lists.freedesktop.org
Subject: Re: [PATCH v4 1/6] nova-core: bitfield: Move bitfield-specific code from register! into new macro
Date: Thu, 25 Sep 2025 09:05:53 +0200 [thread overview]
Message-ID: <2e001ee7-6713-4867-8b81-3955327ebe18@nvidia.com> (raw)
In-Reply-To: <d61820e5-ee8b-4c25-8c25-81921d3a7071@weathered-steel.dev>
On 9/24/2025 10:01 PM, Elle Rhumsaa wrote:
>
>>
>> On 9/24/2025 4:38 PM, Yury Norov wrote:
>>> On Wed, Sep 24, 2025 at 12:52:41PM +0200, Greg KH wrote:
>>>> On Sun, Sep 21, 2025 at 03:47:55PM +0200, Danilo Krummrich wrote:
>>>>> On Sun Sep 21, 2025 at 2:45 PM CEST, Greg KH wrote:
>>>>>> Again, regmap handles this all just fine, why not just make bindings to
>>>>>> that api here instead?
>>>>> The idea is to use this for the register!() macro, e.g.
>>>>>
>>>>> register!(NV_PMC_BOOT_0 @ 0x00000000, "Basic revision information about
>>>>> the GPU" {
>>>>> 28:24 architecture_0 as u8, "Lower bits of the architecture";
>>>>> 23:20 implementation as u8, "Implementation version of the
>>>>> architecture";
>>>>> 8:8 architecture_1 as u8, "MSB of the architecture";
>>>>> 7:4 major_revision as u8, "Major revision of the chip";
>>>>> 3:0 minor_revision as u8, "Minor revision of the chip";
>>>>> });
>>>>>
>>>>> (More examples in [1].)
>>>> Wonderful, but I fail to see where the endian-ness of this is set
>>>> anywhere. Am I just missing that? The regmap api enforces this idea,
>>>> and so the
>>>>
>>>>> This generates a structure with the relevant accessors; we can also implement
>>>>> additional logic, such as:
>>>>>
>>>>> impl NV_PMC_BOOT_0 {
>>>>> /// Combines `architecture_0` and `architecture_1` to obtain the
>>>>> architecture of the chip.
>>>>> pub(crate) fn architecture(self) -> Result<Architecture> {
>>>>> Architecture::try_from(
>>>>> self.architecture_0() | (self.architecture_1() <<
>>>>> Self::ARCHITECTURE_0_RANGE.len()),
>>>>> )
>>>>> }
>>>>>
>>>>> /// Combines `architecture` and `implementation` to obtain a code
>>>>> unique to the chipset.
>>>>> pub(crate) fn chipset(self) -> Result<Chipset> {
>>>>> self.architecture()
>>>>> .map(|arch| {
>>>>> ((arch as u32) << Self::IMPLEMENTATION_RANGE.len())
>>>>> | u32::from(self.implementation())
>>>>> })
>>>>> .and_then(Chipset::try_from)
>>>>> }
>>>>> }
>>>>>
>>>>> This conviniently allows us to read the register with
>>>>>
>>>>> let boot0 = regs::NV_PMC_BOOT_0::read(bar);
>>>>>
>>>>> and obtain an instance of the entire Chipset structure with
>>>>>
>>>>> let chipset = boot0.chipset()?;
>>>>>
>>>>> or pass it to a constructor that creates a Revision instance
>>>>>
>>>>> let rev = Revision::from_boot0(boot0);
>>>>>
>>>>> Analogously it allows us to modify and write registers without having to mess
>>>>> with error prone shifts, masks and casts, because that code is generated by
>>>>> the
>>>>> register!() macro. (Of course, unless we have more complicated cases where
>>>>> multiple fields have to be combined as illustrated above.)
>>>>>
>>>>> Note that bar is of type pci::Bar<BAR0_SIZE> where BAR0_SIZE in our case is
>>>>> SZ_16M.
>>>>>
>>>>> However, the type required by read() as generated by the register!() macro
>>>>> actually only requires something that implements an I/O backend, i.e
>>>>> kernel::io::Io<SIZE>.
>>>>>
>>>>> pci::Bar is a specific implementation of kernel::io::Io.
>>>>>
>>>>> With this we can let the actual I/O backend handle the endianness of the bus.
>>>> Ok, great, but right now it's not doing that from what I am seeing when
>>>> reading the code. Shouldn't IoMem::new() take that as an argument?
>>>>
>>>> But, that feels odd as our current iomem api in C doesn't care about
>>>> endian issues at all because it "assumes" that the caller has already
>>>> handle this properly and all that the caller "wants" is to write/read to
>>>> some memory chunk and not twiddle bits.
>>>>
>>>>> (Actually, we could even implement an I/O backend that uses regmap.)
>>>> That would probably be best to do eventually as most platform drivers
>>>> use regmap today as it's the sanest api we have at the moment.
>>>>
>>>>> So, I think the register!() stuff is rather orthogonal.
>>>> I think it's very relevant as people seem to just be "assuming" that all
>>>> the world (hardware and cpus) are little-endian, while in reality, they
>>>> are anything but. As proof, the code that uses this register!() logic
>>>> today totally ignores endian issues and just assumes that it is both
>>>> running on a little-endian system, AND the hardware is little-endian.
>>>>
>>>> As a crazy example, look at the USB host controllers that at runtime,
>>>> have to be queried to determine what endian they are running on and the
>>>> kernel drivers have to handle this "on the fly". Yes, one can argue
>>>> that the hardware developers who came up with that should be forced to
>>>> write the drivers as penance for such sins, but in the end, it's us that
>>>> has to deal with it...
>>>>
>>>> So ignoring it will get us quite a ways forward with controlling sane
>>>> hardware on sane systems, but when s390 finally realizes they can be
>>>> writing their drivers in rust, we are going to have to have these
>>>> conversations again :)
>>> Hi Greg, all,
>>>
>>> Endianess is not the only problem when dealing with registers mapped
>>> to the memory, right?
>>>
>>> I recall some built-in 12-bit ADCs in 8-bit AVR microcontrollers. That
>>> required to read 4-bit LO register before 8-bit HI, if you didn't want to
>>> loose those 4 bits.
>>>
>>> Bitfields don't address that issue as well. In my understanding, it's
>>> done on purpose: bitfields encapsulate shifts and masks, and don't
>>> pretend that they are suitable for direct access to a hardware.
>>>
>>> Notice another rust bitfield project. It tries to account for endianess
>>> and everything else:
>>>
>>> https://docs.rs/bitfield-struct/latest/bitfield_struct/
>>>
>>> I didn't ask explicitly, and maybe it's a good time to ask now: Joel,
>>> Danilo and everyone, have you considered adopting this project in
>>> kernel?
>>>
>>> The bitfield_struct builds everything into the structure:
>>>
>>> use bitfield_struct::bitfield;
>>> #[bitfield(u8, order = Msb)]
>>> struct MyMsbByte {
>>> /// The first field occupies the *most* significant bits
>>> #[bits(4)]
>>> kind: usize,
>>> system: bool,
>>> #[bits(2)]
>>> level: usize,
>>> present: bool
>>> }
>> Thanks for raising this. The syntax seems quite different from what we need, in
>> particular since register! macro is based on our bitfield! macro, this syntax is
>> incompatible with the need to specify bit ranges, not just the number of bits.
>> In other words, it appears the out-of-crate does not satisfy the requirement.
>> They have to specific 'order' property mainly because they don't have the notion
>> of bitfield index, just number of bits.
>>
>> Regarding endianness in that crate, it appears to be configurable based on
>> user's requirement so we can make it such if needed for any kernel usecases. But
>> the default in that crate is native-endianness just like our implementation
>> right?
>>
>> Thanks.
>>
> You might be interested in an implementation that we worked on that just uses
> `macro_rules`: https://docs.rs/bitfielder/latest/bitfielder/
>
> It's not the same syntax as what you use, but you might be able to find some
> inspiration in how we dealt with endianness. We also have implementations for
> reading bitfields from byte arrays, if you're interested.
Looks similar. About the additional features, in time we can certainly add
support for it if it makes sense. I am sure we will improve support for
additional use cases after it is merged.
>
> Either way, thanks for your continued work on this patch series.
Of course! Will have the v5 out soon, but I am also traveling international to
get back home at the moment :).
- Joel
next prev parent reply other threads:[~2025-09-25 7:06 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-20 18:22 [PATCH v4 0/6] Introduce bitfield and move register macro to rust/kernel/ Joel Fernandes
2025-09-20 18:22 ` [PATCH v4 1/6] nova-core: bitfield: Move bitfield-specific code from register! into new macro Joel Fernandes
2025-09-21 9:36 ` Greg KH
2025-09-21 9:59 ` Miguel Ojeda
2025-09-21 11:23 ` Greg KH
2025-09-21 12:33 ` Benno Lossin
2025-09-21 12:45 ` Greg KH
2025-09-21 13:47 ` Danilo Krummrich
2025-09-23 6:38 ` Behme Dirk (XC-CP/ESD1)
2025-09-24 10:52 ` Greg KH
2025-09-24 11:28 ` Danilo Krummrich
2025-09-24 12:04 ` Greg KH
2025-09-24 14:38 ` Yury Norov
2025-09-24 15:53 ` Danilo Krummrich
2025-09-24 17:46 ` Joel Fernandes
2025-09-24 20:01 ` Elle Rhumsaa
2025-09-25 7:05 ` Joel Fernandes [this message]
2025-09-23 22:24 ` Joel Fernandes
2025-09-24 10:40 ` Greg KH
2025-09-29 19:26 ` Joel Fernandes
2025-09-29 19:37 ` Greg KH
2025-09-29 19:45 ` Joel Fernandes
2025-09-29 20:25 ` Danilo Krummrich
2025-09-21 13:49 ` Danilo Krummrich
2025-09-29 6:16 ` Alexandre Courbot
2025-09-29 19:36 ` Joel Fernandes
2025-09-20 18:22 ` [PATCH v4 2/6] nova-core: bitfield: Add support for different storage widths Joel Fernandes
2025-09-29 6:22 ` Alexandre Courbot
2025-09-29 19:47 ` Joel Fernandes
2025-09-20 18:22 ` [PATCH v4 3/6] nova-core: bitfield: Add support for custom visiblity Joel Fernandes
2025-09-29 6:28 ` Alexandre Courbot
2025-09-29 20:20 ` Joel Fernandes
2025-09-20 18:22 ` [PATCH v4 4/6] rust: Move register and bitfield macros out of Nova Joel Fernandes
2025-09-29 6:30 ` Alexandre Courbot
2025-09-20 18:22 ` [PATCH v4 5/6] rust: Add KUNIT tests for bitfield Joel Fernandes
2025-09-20 18:22 ` [PATCH v4 6/6] rust: bitfield: Use 'as' operator for setter type conversion Joel Fernandes
2025-09-29 6:47 ` Alexandre Courbot
2025-09-29 20:32 ` Joel Fernandes
2025-09-29 13:59 ` Miguel Ojeda
2025-09-29 14:44 ` Alexandre Courbot
2025-09-29 15:17 ` Miguel Ojeda
2025-09-30 12:03 ` Joel Fernandes
2025-09-29 15:26 ` Yury Norov
2025-09-29 20:46 ` Joel Fernandes
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=2e001ee7-6713-4867-8b81-3955327ebe18@nvidia.com \
--to=joelagnelf@nvidia.com \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=airlied@gmail.com \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=apopple@nvidia.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=elle@weathered-steel.dev \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=jhubbard@nvidia.com \
--cc=joel@joelfernandes.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=nouveau@lists.freedesktop.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=simona@ffwll.ch \
--cc=tmgross@umich.edu \
--cc=ttabi@nvidia.com \
--cc=tzimmermann@suse.de \
--cc=yury.norov@gmail.com \
/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
all inboxes | Powered by JetHome®