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 bytes.)
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.