Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standard data type for firmware binaries #51

Open
J-Alves opened this issue Nov 19, 2024 · 13 comments
Open

Standard data type for firmware binaries #51

J-Alves opened this issue Nov 19, 2024 · 13 comments

Comments

@J-Alves
Copy link

J-Alves commented Nov 19, 2024

Hi,

In the context of the Hafnium project, we are exploring the use of Transfer List structures to package the artefacts of each partition. Hafnium is the reference implementation for S-EL2 firmware for an aarch64 architecture, following the FF-A standard.
The idea is to load a TL per partition agregating the artefacts the SPMC needs to process. Each TL will be signed with independent keys from each provider to enforce the trusted boot flow; hence, there is a need for a TL package per SP.

Currently, the same effect is achieved with an impdef package, which is not very scalable. TLs seem appealing due to the well-curated specification, availability of a firmware library and build tool in TF-A which can be used.

The data types required are:

  • FDT.
  • Partitions Binary.
  • HOB List (optional).

The FDT and HOB types are part of the standard data types.
I couldn't find a standard data type that could be used for the partition binary. Presently, using the custom data type range.

I would like to obtain feedback from the community on the idea of adding the binary data type.
Any objections as to why there shouldn't be such a type?
If there are no objections, what would be the best way to do the respective update to the specification?

Best regards,
João Alves

@mathias-arm
Copy link
Contributor

Different use case but similar needs. What do you think about #9 and #10?

@J-Alves
Copy link
Author

J-Alves commented Nov 19, 2024

Hi,

Thanks for providing reference to those.

IIUC, the GUID would discriminate between the different SP binaries.

This is not needed in my case, as we have the FF-A UUID as the identifier for the SP at the system level. It also seems to imply a sanity check on the GUID within the SPMC. I don't think It seems unnecessary.

Let me know if I am missing something.

Cheers

@jwerner-chromium
Copy link
Contributor

The general idea is that if none of the existing tags are suitable for your use case, you should just send a PR to add a new tag in the standardized ID range with whatever format you need. You can start a new block for tags related to Hafnium (e.g. at 0x200). See https://github.com/FirmwareHandoff/firmware_handoff/blob/main/source/transfer_list.rst#entry-type-allocation for details. If the format proves useful enough other projects may choose to reuse it later, and if not that's fine too.

You should not be using tags in the custom (non-standardized) range (starting 0xfff000) for anything you expect to use long-term in open-source code.

@danh-arm
Copy link
Contributor

This is a new use-case for TLs. TLs are designed to allow well-specified data to be passed between firmware images, allowing the data to be dynamically updated and relocated along the way. This use-case is about loading static data and parsing it in a single component. It's a contract between the SP packaging tool and the SPMC implementation. TLs seem a bit overkill for this but I'm not against it if it's useful.

My main concern is why does this need to be specified rather than IMP DEF? Are we intending to package and sign SPs independently from the SPMC implementation? Will we be implementing/testing multiple SPMC implementations to work with a given set of SP binary packages? If the answer's no, then I'd say let's solve this problem when we need to.

If you do want to proceed, then I'd also ask what information is contained in the FDT? Is this the FF-A manifest entry? If so, there's already a related TE defined for that here, although the current wording is specific to the SPMC manifest. I guess we could genericize this to be any FF-A manifest entry (since they are self-describing)? If it's something else, then that data might need to be further specified. The standard FDT entry is intended for the hardware device tree used by the OS.

I agree you'd need a new TE for the SP binary. I guess we could define a standard TE to cover any image binary, but for that to be useful there would need to be an identifier for the specific image binary. Given that you don't need an identifier, I think creating a TE in the Trusted Firmware range specifically for the SP binary is better. I'm assuming there's no use-case to pass multiple SP binaries in a TL, otherwise we're back to the problem of needing an identifier.

@J-Alves
Copy link
Author

J-Alves commented Nov 20, 2024

Thanks for the pertinent questions/points.
I will try to answer your questions.

This is a new use-case for TLs. TLs are designed to allow well-specified data to be passed between firmware images, allowing the data to be dynamically updated and relocated along the way. This use-case is about loading static data and parsing it in a single component. It's a contract between the SP packaging tool and the SPMC implementation. TLs seem a bit overkill for this but I'm not against it if it's useful.

There is no use for the SPMC to extend the TL, but this may change.

My main concern is why does this need to be specified rather than IMP DEF?

We have had an implementation-defined format up until now. However, we are now faced with a problem in which we need to statically allocate a region for a HOB list. The previous package format doesn't serve this purpose anymore. TLs format and packaging scales better. In the future, if we have to extend the package with more static data, we might need change again the impdef package. Every time we iterate on this package, we need to make sure it is backwards compatible. This is where I saw value in TLs. It seems good to future-proof the data consumed by the SPMC, and if an entry is missing it is easy to check that through the TEs types. It doesn't require a big change in the build of the package and code refactoring to consume it. Hafnium itself doesn't yet consume data propagated via TL. But this could also change, even though there is no immediate ask. Adopting this could also mean we reduce a bit of complexity, and share code with the unpacking of the SP.

Will we be implementing/testing multiple SPMC implementations to work with a given set of SP binary packages?
Currently, we are looking to do in hafnium. Other SPMC's implementations haven't been considered yet. Though I could ping the respective arm internal teams to see if there is value.

If you do want to proceed, then I'd also ask what information is contained in the FDT? Is this the FF-A manifest entry? If so, there's already a related TE defined for that here, although the current wording is specific to the SPMC manifest. I guess we could genericize this to be any FF-A manifest entry (since they are self-describing)? If it's something else, then that data might need to be further specified. The standard FDT entry is intended for the hardware device tree used by the OS.

It is the FF-A manifest indeed. I am open to having a more specific type as well for this.

I agree you'd need a new TE for the SP binary. I guess we could define a standard TE to cover any image binary, but for that to be useful there would need to be an identifier for the specific image binary. Given that you don't need an identifier, I think creating a TE in the Trusted Firmware range specifically for the SP binary is better. I'm assuming there's no use-case to pass multiple SP binaries in a TL, otherwise, we're back to the problem of needing an identifier.

Not with this use-case yet.

Let me know if this sounds reasonable to you.

Thanks a lot for the comments.

@danh-arm
Copy link
Contributor

OK, you've convinced me this is a reasonable use-case.

It is the FF-A manifest indeed. I am open to having a more specific type as well for this.

Given that an FF-A manifest is self-describing, it should be possible to define a single TE for this. A TL could safely contain multiple TEs of this type. I think this is preferable to defining multiple TEs for all the different FF-A manifest types.

@raymo200915 Do you think it would be OK to rename XFERLIST_DT_SPMC_MANIFEST to something more generic, e.g. XFERLIST_DT_FFA_MANIFEST?

Let me know if this sounds reasonable to you.

Yes, I'm OK with adding a TE in the Trusted Firmware range for an SP binary.

@raymo200915
Copy link
Contributor

OK, you've convinced me this is a reasonable use-case.

It is the FF-A manifest indeed. I am open to having a more specific type as well for this.

Given that an FF-A manifest is self-describing, it should be possible to define a single TE for this. A TL could safely contain multiple TEs of this type. I think this is preferable to defining multiple TEs for all the different FF-A manifest types.

Currently the implementation does not support multiple TEs with same TE ID (It returns always the first one when lookup).
There was some discussion under the context of #31 - To support multiple entries using an array, but if the data is not self-describing this won't work, at least an additional "entry index" is needed to identify which element in the array.

@raymo200915 Do you think it would be OK to rename XFERLIST_DT_SPMC_MANIFEST to something more generic, e.g. XFERLIST_DT_FFA_MANIFEST?

This should be fine as they are self-describing but the renamed entry should be moved out from the range defined for Trusted Firmware.

Let me know if this sounds reasonable to you.

Yes, I'm OK with adding a TE in the Trusted Firmware range for an SP binary.

@J-Alves
Copy link
Author

J-Alves commented Dec 7, 2024

Hi,

Thank you all for the feedback.

Please help review the pull request:
#52

Cheers!

@danh-arm
Copy link
Contributor

Hi @raymo200915. Sorry for the late reply.

Currently the implementation does not support multiple TEs with same TE ID (It returns always the first one when lookup).

I think this will need fixing at some point. Note the latest spec says this:
"The same tag ID may occur multiple times in the TL to represent multiple instances of the same kind of object."

There was some discussion under the context of #31 - To support multiple entries using an array, but if the data is not self-describing this won't work, at least an additional "entry index" is needed to identify which element in the array.

Yes, that case was problematic because ep_info isn't self-describing. The consumer had to implicitly know which ep_info to use based on ordering. We should be OK for FF-A manifests because they contain an ID field.

@raymo200915
Copy link
Contributor

Hi @raymo200915. Sorry for the late reply.

Currently the implementation does not support multiple TEs with same TE ID (It returns always the first one when lookup).

I think this will need fixing at some point. Note the latest spec says this: "The same tag ID may occur multiple times in the TL to represent multiple instances of the same kind of object."

There was some discussion under the context of #31 - To support multiple entries using an array, but if the data is not self-describing this won't work, at least an additional "entry index" is needed to identify which element in the array.

Yes, that case was problematic because ep_info isn't self-describing. The consumer had to implicitly know which ep_info to use based on ordering. We should be OK for FF-A manifests because they contain an ID field.

Do we have a plan to support those non-selfdescribing ones? I am going to update the transfer list library to support multiple entries with same id when we have an idea to deal with non-selfdescribing data, or we can make the assumption that only selfdescribing data are accepted to be in the array.

@danh-arm
Copy link
Contributor

Do we have a plan to support those non-self-describing ones? I am going to update the transfer list library to support multiple entries with same id when we have an idea to deal with non-selfdescribing data, or we can make the assumption that only selfdescribing data are accepted to be in the array.

I don't think we have consensus on this yet. See the discussion in #49. Perhaps it's best to wait for that to resolve before adding new functionality.

@manish-pandey-arm
Copy link
Contributor

I am going to update the transfer list library to support multiple entries with same id when we have an idea to deal with non-selfdescribing data,

I saw you mentioning about Transfer list library in other discussions as well, just curious to know is it some standalone library or is it part of some project(TF-A/OP-TEE) ?

@raymo200915
Copy link
Contributor

I am going to update the transfer list library to support multiple entries with same id when we have an idea to deal with non-selfdescribing data,

I saw you mentioning about Transfer list library in other discussions as well, just curious to know is it some standalone library or is it part of some project(TF-A/OP-TEE) ?

The ones in TF-A/OP-TEE and U-Boot. TF-A and OP-TEE are sharing 90%+ same code while U-Boot is using its existing bloblist library.

J-Alves added a commit to J-Alves/firmware_handoff that referenced this issue Dec 19, 2024
Specify an FF-A manifest TE type to the trusted firmware
range.

This entry is to be used in the TL package containing
an SP's artefacts, created at build time using the
tlc tool from TF-A, and consumed by an SPMC implementation.

For the moment, Hafnium as the S-EL2 SPMC is used.

This patchset resolves issue FirmwareHandoff#51:
FirmwareHandoff#51

Signed-off-by: J-Alves <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants