[TF-A] [RFC] Proposed location to host the firmware handoff specification.

Julius Werner jwerner at chromium.org
Sat Jul 9 03:35:25 CEST 2022

Hi Jose,

Can you provide a bit more background on where this proposal suddenly
came from and what considerations went into its design? The mailing
list discussion from last year sort of petered out without much
concrete agreement, and now you're here with a full specification.
It's hard to provide feedback on a finished document that doesn't
include any justification for the design choices it makes and without
knowing what concrete requirements may have influenced it.

With that caveat (of not knowing why you made the choices you did and
what good reasons you may have had), here are the main concerns I came
up with on a first read:

1. Where did the requirement for 16-byte alignment come from? It seems
a bit excessive considering that no data field is actually larger than
4 bytes (and it looks like it influenced several other choices in the
spec, e.g. unnecessarily large transfer entry header because the bytes
to the alignment boundary have to be filled anyway). For something
that's supposed to be the "lightweight" alternative to more elaborate
formats, this design doesn't really feel that lightweight anymore.

2. The table entry header seems unnecessarily large. What's the point
of including a "header length" field when that field will always
contain a 16? I think you could easily get away with half the size
here (just 4 bytes tag and 4 bytes data size). (While we're at it, the
whole table header is also a bit large... do we really expect to need
2^32 possible versions? You could easily shrink that down to 16

3. It's not exactly clear what the table header's "version" field is
supposed to mean. What exactly would cause us to increase the version?
What should a reader do when it reads an unknown version field? It
would probably be a good idea for the final document to specify that
in more detail, and I'd maybe consider splitting the version number in
a major version and minor version byte (major version = fully
incompatible to older readers; minor version = added meaning to
previously reserved fields, but older readers can continue to read the
fields they know about).

4. I don't think a strict definition of entry type ranges is a good
idea, particularly if "standard" and "OEM" are the only two options.
In my experience such systems (e.g. same situation with ARM SMC FIDs)
just mean that nothing ever gets added in the "standard" bucket
because the barrier to inclusion is way too high, and so in practice
everyone will throw every use case they have into the remaining
free-for-all bucket ("OEM" in this case), which quickly leads to a
mess of overlapping IDs and in the end nobody can ever share a tag
between two different platforms even if they actually end up needing
the same thing. I think you can't expect things like this to
self-organize in advance, and the only way it can work in practice is
that things which were originally added by one contributor become a
de-facto standard over time as others adopt them. The way to allow and
promote that would be to have a simple, low-barrier registration
mechanism for new tags -- e.g. just by submitting a patch to the
repository that also holds the spec itself which would just need the
tag name, ID, and simple specification of the contained data, open for
everyone and every use case they might have. With 4 billion tags, I
think we wouldn't need to worry about running out any time soon. This
would allow all the different firmware projects and hardware vendors
using this standard to iterate quickly on their own needs, deprecate
tags and add new versions as needed, and if over time specific tags
become widely used/useful de-facto standards other stakeholders can
start supporting them without having to worry about tag clashes. (If
you want more organization than just one big free-for-all bucket you
could still have that, of course... e.g. allocate smaller chunks of 1K
tags each to each firmware project or hardware vendor or whatever as
needed. But the important part is that the barrier to adding new tags
should be low and the chunks should not overlap, so the 1K tags
allocated to U-Boot should be different from the 1K tags allocated to
TF-A, and if U-Boot comes up with a good tag definition where we end
up seeing that it would be useful if TF-A reused the same format, we
can just use that tag without risk of it already being defined as
something else in TF-A context.)

5. Embedding large data structures like a full FDT or ACPI table
directly by value in this structure seems like a bad idea and too
inflexible in practice. These kinds of structures may be generated at
different points in the boot process (some of which may or may not use
the transfer list standard), they may need to be modified (including
growing/shrinking in size) at various points, and they may need to be
placed in special locations in memory. Besides, the transfer list
design requires it to be copied in various cases (e.g. to expand
beyond max_length), so it seems primarily suited for small blocks of
data and including a huge external structure by value would be very
inefficient. I'd recommend making reference tags for these instead
that just include a (physical, absolute) pointer to the actual
structure, its length, and maybe a checksum.

More information about the U-Boot mailing list