FSP-S Issues

Introduction

FSP is an ABI that allows silicon vendors to provide pre-compiled binaries of their silicon-initialization code for the integration into firmware frameworks such as coreboot. Current, 2.x versions of FSP describe three binaries with rough responsibilities:

  • FSP-T: Sets up a temporary RAM environment (usually some sort of Cache as RAM, CAR) among other things.

  • FSP-M: Initializes the memory (DRAM) controller, among other things.

  • FSP-S: Performs various silicon-initialization steps left.

However, what operations these binaries perform exactly and what operations are left to the firmware framework, is neither specified nor documented.

Historically, all these responsibilities were left to coreboot. Later, pre-compiled reference code for the memory-controller initialization was introduced, then for other silicon init, and finally there are attempts to replace coreboot's CAR setup with FSP-T.

While the FSP-M integration saves coreboot developers time, because of the complex nature of the memory-controller initialization, the integration of FSP-S turns out to be harder than implementing the necessary code natively in coreboot. We'll discuss why that is the case and provide an incomplete list of issues with current FSP-S binaries.

To wrap it up, the current design and implementation of FSP requires a huge commitment to documentation and communication that doesn't exist. The lack thereof leads to a bug-driven development that potentially costs Intel's customers millions of dollars. This could be easily avoided by an open-source approach for FSP-S, which would only need a few hundred lines of platform-specific code in coreboot. Even a partial open-source solution could lower costs on all sides and produce higher quality code at a shorter time to market.

Bug Fixing

Many companies rely on the pre-built FSP binaries. Yet, there is no common procedure to get bugs fixed or even acknowledged. This leads to an increase of workarounds in firmware frameworks, especially for older hardware generations.

In the past, the coreboot community discovered and tried to report several FSP bugs, but they hardly ever got addressed. This means that the community has to awkwardly work around these issues and hope that the bug is fixed in a new FSP release, which may never happen if the platform is too old.

Moreover, patching bugs directly in the pre-built FSP binaries is prohibited by their license. This forces OEMs to ship products with known bugs when workarounds in the firmware framework are impossible.

Lack of Documentation

Many of the initialization steps performed by FSP-S are merely translating mainboard-specific configuration into register settings. This is reflected by a list of hundreds of configuration options of FSP-S. While these steps are quite simple, the additional translation from FSP options to register values heavily increases the integration costs. Not only are the register settings usually much better documented than their FSP counterparts, but FSP also uses different terms so that the existing hardware documentation often can't assist developers when dealing with FSP.

On top, FSP sometimes adds unnecessary complexity. For instance, breaking a single register write into multiple, interdependent configuration options, where setting these options alone needs more code compared to a native implementation.

FSP-S also performs locking of several registers so that they can't be written anymore afterwards. It is not documented what locks are set by FSP. This creates heavy security issues for multiple reasons:

  • One either has to assume that FSP doesn't perform any locking and do it redundantly in the firmware framework, or expensively test what is locked and keep doing so for every new FSP revision.

  • Some registers may be locked before they are configured in a secure manner. This may result in workarounds in the firmware framework to configure things early. Sometimes it's even impossible to do so, because relevant information isn't available yet.

This shows that, no matter how many options are implemented in FSP-S, there will always be things that must be controlled by the firmware framework. Locking should either be a separate, last step in FSP, or be left entirely to the firmware framework. And most of all, the locking has to be documented.

Arbitrary Interface Changes

Within coreboot, we try to keep code-compatibility with older hardware generations. The FSP ABI isn't stable, however. Even when the hardware doesn't change between minor platform updates, the configuration settings of FSP are sometimes adapted without backwards compatibility in mind. This increases costs, just to translate configuration data from one representation to another only to let FSP translate it again. In such cases, directly configuring registers from coreboot, would save two layers of indirection.

Another problem is the disappearance of options in newer FSP releases. See [SpiFlashCfgLockDown UPD vanished after KBL] (https://github.com/IntelFsp/FSP/issues/25), for instance. Current coreboot code seems to still rely on this option. It boots, though, only security assumptions may be broken. Which again shows, locking shouldn't be part of FSP, or at least optional.

FSP Switches SAI

A problem that multiplies with the lack of documentation is that FSP-S switches to POSTBOOT_SAI on newer platforms. After this switch, function blocks that act separately from the CPU may ignore access requests to their registers because the CPU is not authenticated as privileged anymore. While it probably tries to achieve the opposite, the SAI switch undermines firmware quality and security.

  • In some firmware frameworks FSP may run long before End-of-Post, this means most of the framework runs with POSTBOOT_SAI.

  • In the EDS, implications of the SAI switch are not documented. Virtually for every register, it is unknown if it is still accessible after the SAI switch. This seems to be a problem for developers both inside and outside of Intel.

  • The SAI switch seems to force the firmware framework to do some things in SMM. However, the use of SMM as a more privileged execution mode is generally discouraged. This means FSP forces firmware development to go backwards.

Especially the lack of documentation leads to many bugs in firmware. Even Intel developers working on coreboot don't seem to know the implications of the SAI switch or lack the resources to re-evaluate all code wrt. the SAI switch.

Missing Communication and Responsibility

All the aforementioned issues lead to an increased need to communicate with Intel insiders, not only for corporate partners but also individual community members. However, Intel seems to avoid most public communication channels, like discussions on IRC, GitHub issues, mailing lists.

No official contact for coordination of the FSP integration seems to exist. After contributing code to the coreboot project, Intel developers often don't maintain it and are not available for further questions.

Issues opened for the official FSP binaries on GitHub are mostly ignored. Sometimes they are closed without any resolution. Issues about the insecure design of FSP are completely ignored.

Mitigations

None of the listed issues would exist if FSP were open-source and the initialization steps could be integrated into coreboot, like they were before. An open-source approach would not only cut costs heavily but might also decrease time-to-market if the whole coreboot community could work together on new platforms.

However, in the absence of such a firmware-development utopia, there may be more realistic approaches. As mentioned earlier, not all of FSP has a negative impact on development performance. FSP-M, for instance, rarely causes trouble. And due to its complex nature, it is no surprise if memory-controller initialization is kept secret. The configuration done by FSP-S, on the other hand, overlaps with many of coreboot's responsibilities.

One approach could be to split FSP-S further up and identify parts that are preferably closed source and parts that could as well be reimplemented in coreboot. However, if parts that are left closed source change the state of the execution environment (e.g. switch SAI), or finalize any settings, the ABI would have to change to solve all aforementioned issues. Such an approach would need careful planning and a much stronger involvement of Intel in the open-source community. The current FSP ABI was designed without any input from the coreboot community, and as a result, is nearly incompatible.

A cheaper solution for all sides seems to be to release the FSP-S source code as is, under a license that would allow integration into coreboot or a native re-implementation. To our knowledge, FSP-S contains nothing that hasn't been published for earlier silicon generations. And our experience with coreboot shows that a native open-source implementation maximizes re-usability for future generations, leads to most secure and maintainable code, and hence, minimizes development costs and time to market.

Another approach could be to align older platforms with open-source coreboot, step by step. Currently, everything from Skylake on relies on FSP-S. However, it seems Intel has already abandoned development for this platform (while the coreboot integration was never finished). It would seem reasonable to release abandoned code to the public, or at least clear existing documentation for older platforms from NDAs.