What is all of this OF, FDT, UEFI and ACPI about?

After my work on the ARMv8 LAMP server bring up, I've beentrying to understand more about the firmware on ARM SoCs. Lately, there havebeen many mentions of acronyms such as OF, FDT, UEFI and ACPI. In this post, Iwould like to share what I found out. Please do not hesitate to comment where Iam wrong. I am less confused than before, but still haven’t achieved enlightenment.

Many standards or types of firmware exist. As an example,the so called Open Firmware (OFW, OF) is an open, platform independent firmwarestandard (IEEE 1275). OF has been successful with SPARC and PowerPCarchitectures. As an example, Apple’s PowerPC Macs have been using OF-compliantfirmware. The standard defines the interface that the operating system uses toquery the specifics of the underlying hardware system. As an example, OF allowsthe operating system to easily query the address, interrupt, clocks, voltage regulators, etc., ofa hardware component in an embedded system. Thus, those hardware detailsdo not have to be hard-coded in the OS, which makes a lot of sense.

However, for a long time this has been done specifically forLinux and ARM architectures. In the old ARM support of the Linux kernel, eachSoC or board had its own hardware-specific code. Often, even drivers whichcould be shared with other SoC families have been put underneath theboard-specific code with hardcoded properties of the underlying SoC. With theincreasing number of ARM SoCs, the resulting code duplication, and LinusTorvalds's comment in the Linux kernel mailing list (“Gaah. Guys, this wholeARM thing is a f*cking pain in the ass.” 2011, http://lkml.org/lkml/2011/3/17/492),something had to be done. A goal has been set to build a single Linux kernelwhich would boot on different ARM SoCs. This is similar to the Intel world,where a single kernel image works on multiple PCs.

Driven by many forces, Linux for ARM has been changed in away where the underlying hardware is described in a specification separate fromthe kernel. The ARM kernel image, which is only specific to the instruction set(e.g., v7 kernel, v8/aarch64 kernel), is reading in this hardware specificationat boot time and dynamically configures the device drivers for the enumeratedhardware components. The specification used here is the so called “devicetree”. The device tree data-structure is a subset of the previously mentionedopen firmware standard. In order to overcome the requirement to also move to anOF compliant firmware (boot loader), the so called FlattenedDevice Tree (FDT) format has been adopted. The FDT format is a simplified way (see example below) of passing devicetree information to the kernel without requiring an OF compliant firmware. FDTis rooted at the Linux implementation of OF.

ethernet@40044000 {	compatible = "snps,dwmac";	reg = <0 0x40044000 0 0x10000>;	interrupts = <0 23 0 0 23 0 >;	interrupt-names = "macirq", "eth_wake_irq";	clocks = <&smbclk>;	clock-names = "stmmaceth";	mac-address = [4255FD60FA1D];	phy-mode = "gmii";		};

Listing 1: Example for a DesignWare GMAC description in a Flattened Device Tree

The ARM Linux move to use devicetree has been done in incremental steps and is still ongoing. Not only does theSoC specific code need to change, but also the drivers e.g., read theconfiguration from the device tree, instead of a hardcoded C data structure. Ithas not been that long (December 2012) since the first Linux kernel (v3.7) supportingdevice trees was released.

At Synopsys, we have also adopteddevice trees for our virtual prototypes. The virtual prototype, which can beconstructed and configured out of a model of arbitrary hardware components (e.gARM core, Synopsys DesignWare IP, custom hardware, etc.) automatically generatesa flattened device tree file. Thus, out of the box Linux can be booted onalmost any arbitrary hardware configuration. The use model here is specificallytargeting device driver development for IP where no HW exists yet (such as USB3.1, eMMC 5.0, UFS 2.0). The user can quickly put a virtual SoC prototype inplace, which is sufficient to start the driver development without worrying aboutporting the Linux kernel to the virtual SoC.

However, the device tree is notthe end of the road. While researching in the areas of Linux, ARMv8 and whatneeds to be done on the software side for the emerging data center market; I stumbledover UEFI and ACPI. Initially, the more I read about it, the more questions thananswers popped up.

Unified Extensible Firmware Interface (UEFI)
The Unified Extensible Firmware Interface , short UEFI, like OF is a firmware standard. UEFI is originally rooted at Intel based on the so called EFI specification which was developed for the Intel/HP Itanium systems in the mid-90s. The
UEFI specification (version 2.4) counts 2,226 pages and covers many aspects such as the protocols to access the hardware devices that the firmware exposes to the OS or UEFI applications. UEFI also specifies the operation of a secure boot and the signing of drivers etc. UEFI even covers the processor bindings which allow exchange of UEFI modules, such as drivers, in binary form. ARMv8 was added to the UEFI specification v2.4 only in July 2013. Supporting UEFI will be necessary in order to achieve uniform boot configuration of ARM-based servers in a data center. So, that the configuration is independent of the details of the underlying hardware platform. But, UEFI adoption may go even beyond the application in micro-servers. At the UEFI Summerfest in July 2013, ARM recommended UEFI as the preferred boot-loader for their 64bit architectures.  The UEFI enablement is driven by the Linaro Enterprise Group (LEG).

Initially, it was totally unclear to me how UEFI would impact a device tree based Linux kernel. I have started to experiment with the open source of Intel’s UEFI implementation called EDK2/Tianocore. Today, there is already an EDK2 port available for ARMv8. To my surprise, I learned that UEFI works very well with the device tree used by the ARM Linux kernel. Since the kernel is not requiring an OF firmware, and uses the simplified flattened device tree (FDT), the UEFI firmware just passes the FDT information to the kernel. However, the EDK2 implementation of UEFI itself is not configured via a FDT. Bringing-up a UEFI firmware on a new ARM platform requires drivers and a platform description ( EDK II DSC specification) keeping similar information as a device tree (e.g., memory map, interrupts etc.).

In my experiments, I have been using the configuration for the Versatile Express platform which is supported by one of our reference virtual prototypes, the VDK for ARM v7/v8 and DesignWare. Of course, all the public information, read me and how-to documents from Linaro have been very educating and greatly appreciated. Apart from debugging the EDK2 firmware, everything went pretty smooth from the beginning.

I have been interested in debugging since I have tried to bring up a driver for the Synopsys DesignWare eMMC interface IP for UEFI. In EDK2, most drivers of the driver execution environment are dynamically loaded as shared libraries (.dll) and symbols are not available unless you load them manually in the debugger. It has been easy to overcome this by having the DLL load mechanism triggering a small script in my virtual prototype which extracts the filename and address from the firmware and loads the symbol file from the host PC. With that, source code level debugging has been easy (e.g. in ARM’s DS-5 as well as Lauterbach’s TRACE32). I have implemented many other small helper functions on top of my virtual prototype (using scripting), such as dynamically enabling/disabling debug messages for DLLs, forwarding debug messages into our analysis database for correlation with function and register traces etc.

Figure 1:  UEFI aware debug and trace using Virtual Prototypes (ARM’s DS-5 & Synopsys VPExplorer)

Figure 1 shows a typical debug flow. I have been re-using an eMMC driver from the EDK2 support for the Samsung Exynos 5250 SoC. The driver was not cleanly encapsulated and had a lot of Exynos SoC specific code. Thus, I had to change it in many places, which didn’t work initially (what’s new J ). The firmware has been reporting a time-out when interfacing with the eMMC. The eMMC model inside the virtual prototype told me (yes, models can talk to you vs. silently failing hardware), that an illegal command was sent to the eMMC. Using register and function tracing I have been able to spot the problem in the driver. The flow nicely shows how the visibility of virtual prototypes can help debugging. Also, this is helpful on low level SoC drivers such as clock and voltage regulation.

What makes me wonder is that all the nice orthogonalization of hardware achieved in the Linux kernel through device trees is not reflected in UEFI. Looking at EDK2, there is again a lot of SoC specific code and un-shared infrastructure. Similar as in the old days of ARM Linux, directories exist for Samsung Exynos, Arndale, TI Beagle Board, ARM’s Versatile Express. Obviously, supporting UEFI for ARM not only means making sure it works for ARM v7 and v8, but also requires writing a lot of device drivers for IP residing in ARM SoCs. I am not sure what the plans are here for UEFI to not repeat the mess that happened with Linux. What I am sure about is the level of interest we are seeing using virtual prototypes for the development of UEFI drivers right now.

Next to bringing up drivers, the support for UEFI secure boot on ARM seems to be another big construction area. In that context, another piece of software is popping up, the ARM Trusted Firmware. This is an open source project defining the part of the firmware which runs in the highest privileged exception level 3 (EL3) on an ARMv8 architecture. Thus, it will be located even underneath/before UEFI which runs with less privileges. A detailed introduction into this complex boot flow has been presented at Linaro Connect in October 2013.

Another item of confusion on my horizon is the Advanced Configuration and Power Interface (ACPI), a standard for runtime configuration of the hardware (established with Intel and Microsoft). The scope of ACPI is again very large and comprises system run-time configuration, power and thermal management as well as RAS (Reliability Accessibility Serviceability, e.g. hardware error handling) support. ACPI has been declared as the preferred runtime interface for ARMv8 servers. ACPI enablement is also driven by the Linaro Enterprise Group. ACPI appears to have much more interference with Linux than UEFI. It greatly overlaps with what is being specified in a device tree and I am looking forward to see how this is being picked up in the Linux kernel.  Hopefully, I have the chance to get my hands on it at some time to see also how virtual prototypes can help debugging and testing.

Other recent, more detailed readings on this topic:

As a summary, I can conclude: Firmware is not easy.

Achim Nohl is a technical marketing manager for virtual prototyping at Synopsys. He actively publishes technical articles, conference papers and blog posts around the topic of developing embedded software using virtual prototypes. His specialty is bringing up firmware, drivers and operating systems for the most recent CPUs and IPs. Achim holds a diploma degree in electrical engineering from the Institute for Integrated Signal Processing Systems at the Aachen University of Technology, Germany. Before joining Synopsys, Achim has worked in various engineering and marketing roles for LISATek and CoWare.

1 thought on “What is all of this OF, FDT, UEFI and ACPI about?

  1. All these layers are designed with the idea of one kernel that runs on different sets of hardware. This is the sort of thing that is important for distribution oriented software eg. Ubuntu or having one Android release that boots across a wide range of dif

    Log in to Reply

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.