Friday, May 6, 2022

And then there were 99

One of the more satisfying areas in tech I’ve done involved creating a component based firmware model for early, space-constrained firmware execution, namely the Pre-EFI Initialization (PEI) architecture. I created both the specification, design and initial implementation. 

The journey to creation of PEI began in the late 1990’s. At that time the Extensible Firmware Interfaced (EFI) specification was defined, but the EFI ‘sample’ code was layered on top of a PC/AT BIOS or other precursor firmware. In 2000 there was a request to have a component-based firmware model for interoperable industry enabling. 

To that end, the PEI infrastructure includes a small core that is responsible for memory management, service registration, service discovery, and executable module dispatch. PEI Modules, or “PEIM’s”, can be PE/COFF executables or a subset of the PE/COFF referred to as a “Terse Executable”, or TE Image. The input of the PEI phase entails the machine reset and the output of the phase is a set of usable system memory that can be persist into the operating system runtime, along with the cause of the restart, or ‘boot mode.’

[from beyond bios book]



The problem being addressed was to allow for composing executable modules from different business entities, such as the CPU vendor for host CPU initialization, board vendor for platform specific logic, reusable generic infrastructure, and 3rd party silicon providers. These executables could range from a simple platform-specific PEIM that samples a general purpose I/O and publishes a flash map up into a module responsible for link and memory initialization built from 10’s of thousands of lines of ANSI C code. Given that the system on a chip vendor exposing the memory and fabric initialization can be different than the platform vendor, the ability to segregate the logic into separate executable modules was a requirement.  Correspondingly, some of the PEIM’s may only be delivered in binary, thus requiring a strong contract between the various units of execution.  The latter contract entailed the use of PEIM-to-PEIM interfaces, or sets of interfaces named by a Globally Unique Identifier (GUID). The PEI modules are stored in a container known as a Firmware Volume (FV). Typically a system will have a least two FV’s: one for the PEI Modules and another for the larger UEFI and DXE modules.

Compounding the need for module interoperability, the PEI phase had to eXecute-In-Place (XIP) from a memory-mapped store immediately after the machine reset. During this early phase the main DRAM complex has not been initialized, and the execution path to the SPI NOR-attached storage is typically slow, so the PEI core and modules had to be optimized to minimize both code size and memory usage.  Specifically, the memory for this early phase entailed the use of the process Cache As RAM (CAR).

The usage of CAR, both for single and later parallel PEI instances, was another innovation I drove from the PEI definition. This usage of PEI allowed for writing C code for even the earliest flows, especially the notoriously complex DDR initialization sequences. Prior to CAR the original design of PEI entailed an assembly-language, register-based software model with ‘call levels’ mapped to various sets of the CPU register set. We discovered that writing code with these ‘level’s’ instead of common idioms like a call stack was untenable, as was factoring large algorithmic routines in assembly. The latter made writing portable, re-usable code difficult. Also, as IP blocks were shared between different CPU cores, not having re-usable C code compounded the software development costs.

The PEI infrastructure started with the register-based model that was ultimately abandoned and then moved to the CAR-based software model in an Intel-defined capability in 2001, and finally culminated in the UEFI Platform Initialization (PI) specification http://www.uefi.org/sites/default/files/resources/PI_Spec_1_6.pdf, volume 1, on http://www.UEFI.org. There is a corresponding open source implementation of the EFI Developer Kit II (EDKII)-based PEI core at https://github.com/tianocore/edk2/tree/master/MdeModulePkg/Core/Pei with some sample platform and silicon PEIM’s at https://github.com/tianocore/edk2-platforms/tree/devel-MinPlatform/Platform/Intel/MinPlatformPkg/PlatformInit/PlatformInitPei. The UEFI Platform Initialization (PI) specific provides guidelines on how the PEI core operates, its core services, the TE definition, and the output state of the PEI phase, or the Hand-off-blocks (HOBs).  The latter decouples the PEI core from the later state of platform initialization.

PEI has bindings to several architectures, including Itanium, IA32, x64, 32-bit ARM and Aarch64. Today the ARM licensees and ARM Ltd. for 32-bit and Aarch64 servers and client, AMD client and servers, and all of Intel products provide PEI-based silicon enabling. Given the BSD licensing of the EDKII, commercial BIOS vendors and many OEM’s have their own instance of the PEI core. Silicon providers deliver PEI modules as binaries and/or source as either licensed closed source or open source. Regrettably, most of the critical silicon specific flows for memory initialization are either in a proprietary boot ROM or binary blob, not open source. In order to accommodate the various open source host firmware communities, Intel provides a variant of a PEI Firmware Volume with a set of additional API’s called the Intel Firmware Support Package (FSP) https://www.intel.com/fsp.  The latter specification has a set of simple services that allow for coreboot https://www.apress.com/us/book/9781484200711 or EDKII https://www.intel.com/content/dam/develop/external/us/en/documents/a-tour-beyond-bios-using-the-intel-firmware-support-package-with-the-efi-developer-kit-ii-fsp2-0-820293.pdf to ingest the PEI modules. 

Given that Intel uses UEFI PI EDKII based PEI modules to validate and enable its SOC’s, having the same critical code usable by various open or closed source host firmware frameworks, from U-boot to coreboot to UEFI to custom RTOS loading argues for the business value of container strategies like Intel FSP to deliver the PEIM’s.

PEI and the PI specification are really a business-to-business technology, namely silicon to OEM.  This is distinct from the UEFI specification which has both business-to-business, Original Equipment Manufacturer (OEM) to independent hardware vendor (IHV) and operating system vendor (OSV), and business-to-consumer, such as OEM to enthusiast or writing UEFI applications.

PEI isn’t universal, though. A native U-Boot SPL or coreboot romstage may not resemble PEI, or the alternate firmware boot flow such as OpenPower and its PEI-equivalent called HostBoot, or the RISC-V Freedom Unleashed’s FSBL. Also, the business-to-business interoperability or richness of PEI are not required for certain classes of platform designs.  Given the above caveats, though, I would say PEI has been a success given the mainstream CPU vendor usage, although it isn’t the only way to perform this initialization.

And I remember working on this tech in the early 2000's. A patent attorney helping to draft some of the material said 'no one is patenting this type of material.' Some work like expired https://patents.google.com/patent/US7103529B2/en filed in 2001 cited by https://scholar.google.com/scholar?oi=bibs&hl=en&cites=8788045269349566754&as_sdt=5&as_ylo=2022&as_yhi=2022 for their work on firmware sand boxing in products 20 years later.  Perhaps this, and PEI during 2001, can fall under the theme of 'value of working on unpopular things.' Once they become popular, the jfk quote kicks in about 'success has many patents but failure is an orphan.'

I hear other strange history, namely some parties outside of Intel working on EFI in 1997 and 1996 when IBI, the EFI predecessor, didn't commence until 1998. FSP started in 2012, but some folks mention it as being 14 years old.

Helping finish and scale is valuable. No need to claim inventorship/creation. Sometimes tech companies encourage that pernicious behavior as part of the promotion process. This leads to the 'pump and dump' phenomena I mentioned earlier http://vzimmer.blogspot.com/2019/02/tiano-147-and-22-or-anniversarynext7.html. And I'm still amazed by the tech market. From the feast-to-famine on hiring to the interesting organization psychology. For example, reading https://www.warp.dev/blog/problems-with-promotion-oriented-cultures reminds me of my PDD reference in March posting http://vzimmer.blogspot.com/2022/03/ that shared similar sentiment with this May article

The dark side of 'finishing' is the loose ends.  mention the capsule/variable tweet w nikolaj and tianocore infosec.  https://www.goodreads.com/quotes/276615-another-flaw-in-the-human-character-is-that-everybody-wants, which remind me of https://twitter.com/pietrushnic/status/1514741511203794945 and discussion with https://twitter.com/vincentzimmer/status/1501826510738522113.

Another reminder of finishing was helping stand up the EDKII infosec group https://tianocore.org/security. The journey went from chasing items like https://invisiblethingslab.com/resources/misc09/Quest%20To%20The%20Core%20(public).pdf and its ilk, curating bespoke list at https://edk2-docs.gitbook.io/security-advisory/, including epic fixes like https://edk2-docs.gitbook.io/security-advisory/boot_failure_related_to_uefi_variable_usage#description. Then leveraging the notification mechanism of https://uefi.org/security mantis tickets to until https://tianocore.org/security was ready. Some of the process



 was inspired by other open source projects like Xen https://xenproject.org/developers/security-policy/. The latest was ensuring that EDKII could issue its own CVE's as a CNA https://www.ami.com/ami-and-industry-partners-drive-acceptance-of-tianocore-as-cve-numbering-authority-cna-by-the-common-vulnerabilities-and-exposures-cve-program/#:~:text=The%20acceptance%20of%20TianoCore%20as%20a%20CNA%20by%20the%20CVE,%2Frequest_id.html%23cna_participants, including learning how to curate the json for issues and being tested by Mitre prior to achieving this milestone. There are still rough edges to work out, such as commitment from community, tragedy of commons, permissive license where folks can fix and not give back, such as marc jones mentions in http://vzimmer.blogspot.com/2020/12/musings-about-firmware-cultures.html

fin (99)

No comments: