From: Jarkko Sakkinen <jarkko@kernel.org>
To: Danilo Krummrich <dakr@kernel.org>
Cc: airlied@gmail.com, simona@ffwll.ch, corbet@lwn.net,
maarten.lankhorst@linux.intel.com, mripard@kernel.org,
tzimmermann@suse.de, ajanulgu@redhat.com, lyude@redhat.com,
pstanner@redhat.com, zhiw@nvidia.com, cjia@nvidia.com,
jhubbard@nvidia.com, bskeggs@nvidia.com, acurrid@nvidia.com,
ojeda@kernel.org, alex.gaynor@gmail.com, boqun.feng@gmail.com,
gary@garyguo.net, bjorn3_gh@protonmail.com,
benno.lossin@proton.me, a.hindborg@kernel.org,
aliceryhl@google.com, tmgross@umich.edu,
gregkh@linuxfoundation.org, mcgrof@kernel.org,
russ.weight@linux.dev, dri-devel@lists.freedesktop.org,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
nouveau@lists.freedesktop.org, rust-for-linux@vger.kernel.org
Subject: Re: [PATCH v5 2/5] rust: firmware: introduce `firmware::ModInfoBuilder`
Date: Tue, 4 Mar 2025 21:15:22 +0200 [thread overview]
Message-ID: <Z8dRSp13fsvEF9HR@kernel.org> (raw)
In-Reply-To: <20250304173555.2496-3-dakr@kernel.org>
On Tue, Mar 04, 2025 at 06:34:49PM +0100, Danilo Krummrich wrote:
> The `firmware` field of the `module!` only accepts literal strings,
> which is due to the fact that it is implemented as a proc macro.
>
> Some drivers require a lot of firmware files (such as nova-core) and
> hence benefit from more flexibility composing firmware path strings.
>
> The `firmware::ModInfoBuilder` is a helper component to flexibly compose
> firmware path strings for the .modinfo section in const context.
>
> It is meant to be used in combination with `kernel::module_firmware!`,
> which is introduced in a subsequent patch.
Ditto.
>
> Co-developed-by: Alice Ryhl <aliceryhl@google.com>
> Signed-off-by: Alice Ryhl <aliceryhl@google.com>
> Signed-off-by: Danilo Krummrich <dakr@kernel.org>
> ---
> rust/kernel/firmware.rs | 98 +++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 98 insertions(+)
>
> diff --git a/rust/kernel/firmware.rs b/rust/kernel/firmware.rs
> index c5162fdc95ff..6e6972d94597 100644
> --- a/rust/kernel/firmware.rs
> +++ b/rust/kernel/firmware.rs
> @@ -115,3 +115,101 @@ unsafe impl Send for Firmware {}
> // SAFETY: `Firmware` only holds a pointer to a C `struct firmware`, references to which are safe to
> // be used from any thread.
> unsafe impl Sync for Firmware {}
> +
> +/// Builder for firmware module info.
> +///
> +/// [`ModInfoBuilder`] is a helper component to flexibly compose firmware paths strings for the
> +/// .modinfo section in const context.
> +///
> +/// It is meant to be used in combination with [`kernel::module_firmware!`].
> +///
> +/// For more details and an example, see [`kernel::module_firmware!`].
> +pub struct ModInfoBuilder<const N: usize> {
> + buf: [u8; N],
> + n: usize,
> + module_name: &'static CStr,
> +}
> +
> +impl<const N: usize> ModInfoBuilder<N> {
> + /// Create an empty builder instance.
> + pub const fn new(module_name: &'static CStr) -> Self {
> + Self {
> + buf: [0; N],
> + n: 0,
> + module_name,
> + }
> + }
> +
> + const fn push_internal(mut self, bytes: &[u8]) -> Self {
> + let mut j = 0;
> +
> + if N == 0 {
> + self.n += bytes.len();
> + return self;
> + }
> +
> + while j < bytes.len() {
> + if self.n < N {
> + self.buf[self.n] = bytes[j];
> + }
> + self.n += 1;
> + j += 1;
> + }
> + self
> + }
> +
> + /// Push an additional path component.
> + ///
> + /// After a new [`ModInfoBuilder`] instance has been created, [`ModInfoBuilder::prepare`] must
> + /// be called before adding path components.
> + pub const fn push(self, s: &str) -> Self {
> + if N != 0 && self.n == 0 {
> + crate::build_error!("Must call prepare() before push().");
> + }
> +
> + self.push_internal(s.as_bytes())
> + }
> +
> + const fn prepare_module_name(self) -> Self {
> + let mut this = self;
> + let module_name = this.module_name;
> +
> + if !this.module_name.is_empty() {
> + this = this.push_internal(module_name.as_bytes_with_nul());
> +
> + if N != 0 {
> + // Re-use the space taken by the NULL terminator and swap it with the '.' separator.
> + this.buf[this.n - 1] = b'.';
> + }
> + }
> +
> + this.push_internal(b"firmware=")
> + }
> +
> + /// Prepare for the next module info entry.
> + ///
> + /// Must be called before [`ModInfoBuilder::push`] can be called.
> + pub const fn prepare(self) -> Self {
> + self.push_internal(b"\0").prepare_module_name()
> + }
> +
> + /// Build the byte array.
> + pub const fn build(self) -> [u8; N] {
> + // Add the final NULL terminator.
> + let this = self.push_internal(b"\0");
> +
> + if this.n == N {
> + this.buf
> + } else {
> + crate::build_error!("Length mismatch.");
> + }
> + }
> +}
> +
> +impl ModInfoBuilder<0> {
> + /// Return the length of the byte array to build.
> + pub const fn build_length(self) -> usize {
> + // Compensate for the NULL terminator added by `build`.
> + self.n + 1
> + }
> +}
> --
> 2.48.1
>
>
BR, Jarkko
next prev parent reply other threads:[~2025-03-04 19:15 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-04 17:34 [PATCH v5 0/5] Initial Nova Core series Danilo Krummrich
2025-03-04 17:34 ` [PATCH v5 1/5] rust: module: add type `LocalModule` Danilo Krummrich
2025-03-04 19:14 ` Jarkko Sakkinen
2025-03-05 21:07 ` Miguel Ojeda
2025-03-04 17:34 ` [PATCH v5 2/5] rust: firmware: introduce `firmware::ModInfoBuilder` Danilo Krummrich
2025-03-04 19:15 ` Jarkko Sakkinen [this message]
2025-03-05 22:30 ` Benno Lossin
2025-03-05 22:38 ` Danilo Krummrich
2025-03-05 23:36 ` Benno Lossin
2025-03-05 23:57 ` Danilo Krummrich
2025-03-06 0:24 ` Benno Lossin
2025-03-06 1:29 ` Danilo Krummrich
2025-03-06 1:35 ` Benno Lossin
2025-03-06 1:48 ` Danilo Krummrich
2025-03-04 17:34 ` [PATCH v5 3/5] rust: firmware: add `module_firmware!` macro Danilo Krummrich
2025-03-04 19:17 ` Jarkko Sakkinen
2025-03-06 0:31 ` Benno Lossin
2025-03-06 1:04 ` Danilo Krummrich
2025-03-06 1:27 ` Benno Lossin
2025-03-06 1:38 ` Danilo Krummrich
2025-03-06 1:42 ` Benno Lossin
2025-03-04 17:34 ` [PATCH v5 4/5] gpu: nova-core: add initial driver stub Danilo Krummrich
2025-03-06 12:38 ` Alexandre Courbot
2025-03-04 17:34 ` [PATCH v5 5/5] gpu: nova-core: add initial documentation Danilo Krummrich
2025-03-06 12:41 ` Alexandre Courbot
2025-03-06 12:56 ` FUJITA Tomonori
2025-03-06 13:45 ` Danilo Krummrich
2025-03-06 13:59 ` FUJITA Tomonori
2025-03-05 19:56 ` [PATCH v5 0/5] Initial Nova Core series Danilo Krummrich
2025-03-05 23:27 ` Luis Chamberlain
2025-03-05 23:40 ` Danilo Krummrich
2025-03-06 0:06 ` Luis Chamberlain
2025-03-06 6:39 ` Greg KH
2025-03-06 17:19 ` Russ Weight
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=Z8dRSp13fsvEF9HR@kernel.org \
--to=jarkko@kernel.org \
--cc=a.hindborg@kernel.org \
--cc=acurrid@nvidia.com \
--cc=airlied@gmail.com \
--cc=ajanulgu@redhat.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=bskeggs@nvidia.com \
--cc=cjia@nvidia.com \
--cc=corbet@lwn.net \
--cc=dakr@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=jhubbard@nvidia.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lyude@redhat.com \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mcgrof@kernel.org \
--cc=mripard@kernel.org \
--cc=nouveau@lists.freedesktop.org \
--cc=ojeda@kernel.org \
--cc=pstanner@redhat.com \
--cc=russ.weight@linux.dev \
--cc=rust-for-linux@vger.kernel.org \
--cc=simona@ffwll.ch \
--cc=tmgross@umich.edu \
--cc=tzimmermann@suse.de \
--cc=zhiw@nvidia.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 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.