From: Timur Tabi <ttabi@nvidia.com>
To: Alexandre Courbot <acourbot@nvidia.com>
Cc: John Hubbard <jhubbard@nvidia.com>,
Eliot Courtney <ecourtney@nvidia.com>,
"nova-gpu@lists.linux.dev" <nova-gpu@lists.linux.dev>,
Zhi Wang <zhiw@nvidia.com>, "gary@garyguo.net" <gary@garyguo.net>,
"mcgrof@kernel.org" <mcgrof@kernel.org>,
"dakr@kernel.org" <dakr@kernel.org>,
"rust-for-linux@vger.kernel.org" <rust-for-linux@vger.kernel.org>,
"driver-core@lists.linux.dev" <driver-core@lists.linux.dev>,
"ojeda@kernel.org" <ojeda@kernel.org>,
"russ.weight@linux.dev" <russ.weight@linux.dev>
Subject: Re: [PATCH v3 2/7] gpu: nova-core: add TLV parser for firmware files
Date: Wed, 8 Jul 2026 20:12:55 +0000 [thread overview]
Message-ID: <ffddffcc750393ca5f719abe27f8a3d6eeb6bf31.camel@nvidia.com> (raw)
In-Reply-To: <DJR9ZWAN4OCT.3GRDS8LGOZ16Y@nvidia.com>
On Mon, 2026-07-06 at 15:31 +0900, Alexandre Courbot wrote:
> > +==================================
> > +TLV Tags in Nova Firmware Images
> > +==================================
> > +
> > +Nova firmware images use a Type-Length-Value (TLV) format to encapsulate
> > +firmware components and metadata. The TLV file begins with a 4-byte "magic"
> > +header that contains the string "NVFW". Following the header is a sequence of
> > +TLV blocks.
> > +
> > +Each block consists of a 4-byte tag of ASCII characters, a 4-byte length
> > +encoded as a little-endian unsigned integer, and a sequence of bytes, the size
> > +of which is equal to the length rounded up to the next multiple of 4.
> > +
> > +The driver code that reads the TLV and uses its contents is called the parser.
> > +It is the responsibility of the parser to handle missing or malformed tags,
> > +lengths, and values in the TLV.
>
> I guess that last paragraph is kind of expected - spelling it out loud
> without being specific as to how to handle missing or malformed tags is
> just confusing. I think it can just be dropped?
I think the docs need a statement somewhere that "parsers" should handle missing or invalid tags,
and that that there is no expectation that when a TLV is created, that all the tags are there or
that they are even the correct format or anything like that.
> >
> > +
> > +``NSIG`` (u32) - ``num_sigs``
> > + Number of signatures included in the ``SIGN`` tag. A value of 0 indicates
> > + unsigned firmware and that there is no ``SIGN`` tag.
>
> Shall we say "A value of 0 or absence of this tag" for coverage? ... Or
> not, see my review of patch 3.
Hmmm... I'm not really crazy about that idea, because then there is incentive to make all u32 tags
act that way. Sometimes 0 is just another number, and not a synonym for "None".
> >
> > +
> > +struct TlvBlock<'a> {
> > + tag: &'a [u8; 4],
> > + value: &'a [u8],
> > +}
> > +
> > +/// On-wire TLV block header: 4-byte ASCII tag + little-endian payload length (bytes, excluding
> > +/// padding to a 4-byte boundary).
> > +struct TlvBlockHeader<'a> {
> > + tag: &'a [u8; 4],
>
> This struct doesn't need a lifetime - it can store `tag` as `[u8; 4]`.
> Same for the `tag` member of `TlvBlock`. Everything above them (`find`,
> `get_bytes`, etc) can still take a reference to the array for
> convenience as we use the `b"ABCD"` syntax, but for these two the
> reference is just inefficient without reason.
Ok. This change resulted in a cascading effect and I had to change a lot of &[u8; 4] into [u8; 4],
but I didn't want to change all of them. Which is better:
pub(crate) fn get_bytes(&self, tag: &[u8; 4]) -> Result<&'a [u8]> {
...
tlv.get_bytes(b"BLOB")?
or
pub(crate) fn get_bytes(&self, tag: [u8; 4]) -> Result<&'a [u8]> {
...
tlv.get_bytes(*b"BLOB")?
> > +
> > +/// The payload of a validated TLV (type, length, value) firmware image.
>
> I think we can just say "A validated TLV", as payload makes it sound
> like this is the payload of a given key within the TLV firmware.
Well, it's the part after the "NVFW" header. The "payload" of an actual get is the "value".
I'll change it to:
/// The post-header part of a validated TLV (type, length, value) firmware image.
>
>
> One thing I'd like to eventually add (for the record; as a follow-up is
> ok) is an abstraction of the `BLOB`/`FILE` distinction: maybe a
> `get_payload` method that returns either a reference to the `BLOB`
> section, or creates a `VVec` to load the references firmware file. Its
> return type would be an `enum` with an `AsRef<[u8]>` implementation and
> a `to_owned(self) -> VVec<u8>` method so individual firmware
> implementations can get the representation they need without caring
> about the underlying storage type.
Yes, I definitely want to do that in the future also.
next prev parent reply other threads:[~2026-07-08 20:12 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-02 19:27 [PATCH v3 0/7] Transition Nova Core to TLV firmare images Timur Tabi
2026-07-02 19:27 ` [PATCH v3 1/7] rust: firmware: add request_into_buf() Timur Tabi
2026-07-03 2:51 ` Alvin Sun
2026-07-03 3:06 ` Timur Tabi
2026-07-03 13:51 ` Danilo Krummrich
2026-07-06 6:30 ` Alexandre Courbot
2026-07-06 10:50 ` Danilo Krummrich
2026-07-07 2:54 ` Timur Tabi
2026-07-07 5:10 ` Alexandre Courbot
2026-07-07 13:32 ` Danilo Krummrich
2026-07-02 19:27 ` [PATCH v3 2/7] gpu: nova-core: add TLV parser for firmware files Timur Tabi
2026-07-02 19:45 ` Timur Tabi
2026-07-06 6:31 ` Alexandre Courbot
2026-07-07 2:56 ` Timur Tabi
2026-07-07 5:13 ` Alexandre Courbot
2026-07-08 22:48 ` Timur Tabi
2026-07-09 3:43 ` Alexandre Courbot
2026-07-06 6:31 ` Alexandre Courbot
2026-07-08 20:12 ` Timur Tabi [this message]
2026-07-09 1:55 ` Alexandre Courbot
2026-07-02 19:27 ` [PATCH v3 3/7] gpu: nova-core: transition booter_load to TLV images Timur Tabi
2026-07-06 6:31 ` Alexandre Courbot
2026-07-08 20:46 ` Timur Tabi
2026-07-09 3:51 ` Alexandre Courbot
2026-07-02 19:27 ` [PATCH v3 4/7] gpu: nova-core: transition gsp " Timur Tabi
2026-07-02 19:27 ` [PATCH v3 5/7] gpu: nova-core: transition gen_bootloader " Timur Tabi
2026-07-06 6:31 ` Alexandre Courbot
2026-07-08 22:26 ` Timur Tabi
2026-07-09 2:24 ` Alexandre Courbot
2026-07-02 19:27 ` [PATCH v3 6/7] gpu: nova-core: transition fsp " Timur Tabi
2026-07-02 19:27 ` [PATCH v3 7/7] gpu: nova-core: update firmware module info for " Timur Tabi
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=ffddffcc750393ca5f719abe27f8a3d6eeb6bf31.camel@nvidia.com \
--to=ttabi@nvidia.com \
--cc=acourbot@nvidia.com \
--cc=dakr@kernel.org \
--cc=driver-core@lists.linux.dev \
--cc=ecourtney@nvidia.com \
--cc=gary@garyguo.net \
--cc=jhubbard@nvidia.com \
--cc=mcgrof@kernel.org \
--cc=nova-gpu@lists.linux.dev \
--cc=ojeda@kernel.org \
--cc=russ.weight@linux.dev \
--cc=rust-for-linux@vger.kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox