Hi Tom,
Thanks for your interest in the SC7180 TF-A port! You're asking fair questions about a difficult situation, so let me try to add some background:
The binary component policy was actually written specifically as part of the discussions about adding the SC7180 port, to lay some guidelines and ground rules about how to deal with binary components (which already existed in some other platform ports beforehand). This case was discussed in-depth with the project leaders and the trustedfirmware.org Board beforehand, and it was always understood that this would have to be a tricky compromise. As you may know, devices (e.g. Android phones) with Qualcomm chipsets generally do not run TF-A, but instead run Qualcomm's proprietary trusted OS and secure monitor (QTEE). The TF-A port was more of an experimental side project (which has by now resulted in a few SC7180-based Chromebooks being sold with TF-A, but the much larger phone market continues to use QTEE), so unfortunately the TF project's position to make demands is not yet as solid as you may think. Basically, we could have either made these compromises or continue to not support Qualcomm chipsets at all, so due to their prevalence in the ecosystem we decided it would be worth it to start like this, try to make the situation as good as it can get, and then hopefully improve on that in future chipset generations.
The binary policy is meant as more of a decision guideline and individual cases are ultimately up to the Board. FWIW maybe I slightly mis-summarized the policy in the text added to the contributing.rst document -- I think saying that the *majority* of the platform port (in terms of bytes of code) should be open source, while a good ambition in general, was never realistic for SC7180. The full document in https://git.trustedfirmware.org/tf-binaries.git/tree/readme.rst instead says "Binary components that contain all meaningful functionality of a platform port" are not accepted -- the intention is that there are pieces large enough to be worth modifying in the open source part, while allowing vendors to keep functionality proprietary that they absolutely do not want (or are not allowed) to disclose. For SC7180, things like UART, SPMI, PMIC and RNG drivers as well as SMC validation are implemented in open source (and as you noticed some of those were ported piecemeal at later points of the development process). I'll be the first to admit that this isn't a lot and we absolutely want to do more, but it is a tricky and very time-consuming process both in identifying the exact parts that can be open-sourced without IP concerns and then actually doing the work (since the qtiseclib code is still proprietary even if there is a Linux driver for the same subsystem, we can't just copy things over, it has to be carefully rewritten and revalidated). The state you see the SC7180 port in right now is basically just as far as we got over the course of this project (and believe me it took a lot of effort already, even if it may not look like much). Hopefully we can make further progress with the next chipset.
Also, just as a note, we didn't actually end up hosting qtiseclib in the TF binary repository in the end, due to concerns about details in the license text that couldn't be resolved. It is instead hosted by the coreboot.org project at the moment. I'm not sure if this technically means that the TF binary component policy applies to this blob or not (from a strict reading of the text I would say it doesn't), but that's not really that relevant... like I said, in the end the Board makes final decisions about whether a platform port is accepted into the repository or not on a case by case basis, and the policy is just a general guideline. The general goal is to make sure the TF-A ports are actually useful to open source developers while allowing for pragmatic compromises in tricky situations like this, and in this case we decided that allowing this port would be more useful than not (although it's certainly on the edge).
On Tue, Jul 20, 2021 at 2:05 AM Tom Johnsen tomjohnsen@protonmail.com wrote:
Hello!
I recently discovered the TF-A port for QTI SC7180 and was very happy to see this. I always thought it would have been great if Qualcomm made (open-source) TF-A ports for their platforms. For example, I would be interested in TF-A for the DragonBoard 820c (APQ8096E). Unfortunately, after talking to some other people I have been told it is unlikely that Qualcomm will ever have this. :-/
I am not much of a firmware developer but I was curious so I wanted to check how much SoC-specific code is actually needed for a TF-A port. At first I was surprised - the QTI platform ports seem fairly simple, there is not much SoC-specific code at all. However, it looks like the reason for that is that almost all of the SoC-specific code is actually contained in a proprietary "qtiseclib" blob that is statically linked into the bl31.bin.
I did not really expect to see something like that in a public open-source project, especially not one as security-critical as TF-A. It looks like some binary components are indeed allowed as per the Contribution Guidelines (1). Yet, after reading them and looking at the code again I wonder how the amount of functionality implemented in the "qtiseclib" could really conform to these guidelines?
I quote them here (from (1)) for convenience:
Binary components must be restricted to only the specific functionality that cannot be open-sourced and must be linked into a larger open-source platform port. The majority of the platform port must still be implemented in open source. Platform ports that are merely a thin wrapper around a binary component that contains all the actual code will not be accepted.
There are two main reasons why I do not think that the "qtiseclib" conforms to these guidelines.
--- 1. "Majority of the platform port must be open-source" ---
I have built TF-A for QTI SC7180 according to the documentation (2). The resulting bl31.bin has a size of 182088 bytes. The linker conveniently produces a "bl31.map" file that shows exactly which part of the binary comes from which component of the TF-A port. It can be analyzed easily, for example with fpv-gcc (3).
The following table shows the distribution of the bl31.bin:
+-------------+----------+-----+ | Component | Size (B) | % | +-------------+----------+-----+ | libqtisec.a | 147344 | 81% | | Other BL31 | 23838 | 13% | | plat/qti | 5222 | 3% | | Padding | 3863 | 2% | | libc.a | 1821 | 1% | +-------------+----------+-----+
Clearly, the libqtisec.a dominates with 81%. The open-source part of the QTI TF-A platform port (plat/qti) is merely 3% of the final binary.
Perhaps it is just large static data tables? The following table shows only the distribution of .text symbols (excluding libc and "Other BL31"):
+-------------+----------+-----+ | Component | Size (B) | % | +-------------+----------+-----+ | libqtisec.a | 75792 | 95% | | plat/qti | 3920 | 5% | +-------------+----------+-----+
I do not see any way to interpret this as "the majority of the platform port is open-source". It is hard to find any substantial functionality that does not end up calling into the proprietary qtiseclib. In my opinion, the port is hardly more than "a thin wrapper around a binary component" which is explicitly forbidden in the guidelines.
--- 2. "Binary components should be as minimal as possible" ---
It is hard to judge this given that the license for "qtiseclib" (obviously) does not allow reverse-engineering. However, just judging from some of the symbol names that I see visibly in the "bl31.map" Qualcomm seems to have spent little effort to keep the binary component actually minimal.
"qtiseclib" also contains code for IP blocks that have public open-source drivers in Linux, including for:
- TLMM (GPIO)
- GCC (Clocks)
- rpmh
Perhaps some "secret" registers are programmed there but it is hard to believe that there is no overlap that could have been made open-source.
This is also quite visible based on changes that were made later. The PRNG and SPMI driver were moved out of "qtiseclib" later (4, 5) and both can be found similarly in Linux.
--- Conclusion ---
How does this conform to the Binary Components policy that is part of the contribution guidelines? Was this not checked during review?
All in all I cannot help but get the feeling that Qualcomm has fairly little interest to have open-source firmware. Not even simple hardware initialization that probably exists similarly in open-source drivers has been implemented in open-source code. The resulting bl31.bin can be hardly called "open-source" when 81% of it is actually proprietary.
If this is intended and considered acceptable I suggest rewriting the "Binary Components" policy to explicitly allow vendors to require any amount of proprietary code for their TF-A ports. Personally, I think this is a very bad idea though and just encourages all other vendors to do the same in the future. TF-A (as a trusted reference implementation) is in a good position to make certain demands that must be met for inclusion in the upstream tree.
I am mainly sad about this because this certainly means that only Qualcomm can make such ports by providing the "qtiseclib" that contains most of the functionality. Perhaps open-source code could have been adjusted by the community to other platforms with some effort.
Thanks for reading. ~ Tom
(1) https://trustedfirmware-a.readthedocs.io/en/latest/process/contributing.html... (2) https://trustedfirmware-a.readthedocs.io/en/latest/plat/qti.html (3) https://github.com/ebs-universe/fpv-gcc (4) https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/4885 (5) https://review.trustedfirmware.org/c/TF-A/trusted-firmware-a/+/4409