While investigating using the i.MX 8 for the Librem 5 phone we found an issue that would have been problematic for us to obtain the Free Software Foundation’s “Respects Your Freedom” (RYF) hardware endorsement:

In U-Boot there are a number of firmware blobs that need to be loaded into the DDR PHY so that it can be trained to work with DDR4. This training is done on every boot.

The normal boot sequence for the i.MX 8 is that the internal ROM loader loads the Secondary Program Loader (SPL) which, in this case, is a small version of U-Boot that can initialize the DDR and load the full U-Boot into DDR to finish the boot process. Very early in the SPL, the training blobs get loaded into the DDR PHY and the training sequence is run. The DDR training procedure is completely un-documented so re-writing the firmware blobs with free/libre or open source versions would be an arduous process.

We can’t ignore the DDR PHY because it is interface between the i.MX 8 internal buses and the DDR4 chips outside of the SOC. The DDR PHY is also part of the i.MX 8 silicon so we can’t just replace the DDR PHY with a different one. It also appears that all DDR PHY’s required this training to work with DDR4, so going to a different SOC wouldn’t solve it either.

The RYF has a “secondary processor” exclusion that can be granted on a case by case basis. We will leverage this exclusion to load and train the DDR PHY on the i.MX 8. We will use a secondary processor to keep binary blobs out of u-boot and the kernel.

Luckily, the i.MX 8 has some A53 cores and an M4 core all on the same silicon. The A53 cores run U-Boot and the Linux kernel and the M4 can run bare metal code or a number of liberated Real Time Operating Systems (RTOSes). We decided to write some bare metal M4 code to do the DDR PHY training.

The M4 has access to all of the peripherals attached to the i.MX 8 so our initial proof of concept reads the DDR PHY firmware from the MMC card and then the M4 takes over to load it into the DDR PHY. Then U-Boot runs the training algorithm and initializes the DDR.

This is more challenging than it might sound because the M4 processor can be booted by U-Boot but it is usually done after the DDR is initialized. Luckily the i.MX 8 also has some on chip RAM that the M4 can use. The U-Boot SPL uses all of the Tightly Coupled Memories (TCM) during boot so we needed to load the M4 firmware into the On-Chip RAM (OCRAM). There is a simple message loop in our bare metal code that allows the A53 core to send messages to the M4 to load the training firmware into the DDR PHY.

This implementation keeps the A53 core “clean” of binary firmware blobs and the M4 is the “secondary processor” that handles the blobs.

Continuing towards RYF Endorsement of the Librem 5

We will be modifying this proof of concept for the delivery of the dev kit and the Librem 5 phone. To further separate the binary blobs from the A53 cores, we will add an SPI flash chip to store the firmware. The SPI flash will be read only so the firmware blobs can’t be modified without the user knowing.

This approach to the binary blobs has been accepted by the FSF under the “secondary processor” exception so we are clear to move forward with the i.MX 8 processor.

We will continue to keep the FSF updated on our progress, share our hardware for testing, and advance toward the high-bar goal of having the Librem 5 attain the gold-standard of the Free Software Foundation’s Respects Your Freedom endorsement.