60 changes: 60 additions & 0 deletions Documentation/mainboard/hp/hp_sure_start.md
@@ -0,0 +1,60 @@
# HP Sure Start

According to the [HP Sure Start Technical Whitepaper], HP Sure Start is a chipset
and processor independent firmware intrusion detection and automatic repair system.
It is implemented in HP notebooks since 2013, and desktops since 2015.

This document talks about some mechanism of HP Sure Start on some machines, and
the method to bypass it.

## Laptops with SMSC MEC1322 embedded controller

Haswell EliteBook, ZBook and ProBook 600 series use SMSC MEC1322 embedded controller.
The EC firmware implements HP Sure Start.

A Haswell EliteBook has two flash chips. According to the strings in the EC firmware,
the 16MiB flash chip that stores the BIOS firmware is called the *system flash*, and
the 2MiB flash chip that stores part of the system flash content is called the
*private flash*. A Haswell ProBook 600 series laptop also uses MEC1322 and has similar
EC firmware, but the HP Sure Start functions are not enabled.

The private flash is connected to the EC, and is not accessible by the OS.
It contains the following:

- HP Sure Start policy header (starting with the string "POLI")
- A copy of the Intel Flash Descriptor
- A copy of the GbE firmware
- Machine Unique Data (MUD)
- Hashes of the IFD, GbE firmware and MUD, the hash algorithm is unknown
- A copy of the bootblock, UEFI PEI stage, and microcode

If the IFD of the system flash does not match the hash in the private flash, for example,
modifying the IFD with ``ifdtool -u`` or ``me_cleaner -S``, the EC will recover the IFD.

If the content of the private flash is lost, the EC firmware will still copy the IFD,
bootblock and PEI to the private flash. However, the IFD is not protected after that.

HP Sure Start also verifies bootblock, PEI, and microcode without using the private flash.
EC firmware reads them from an absolute address of the system flash chip, which is
hardcoded in the EC firmware. It looks like this verification is done with a digital
signature. If the PEI volume is modified, EC firmware will recover it using the copy
in the private flash. If the private flash has no valid copies of the PEI volume, and
the PEI volume is modified, the machine will refuse to boot with the CapsLock LED blinking.

## Bypassing HP Sure Start

First search the mainboard for the flash chips. If there are two flash chips,
the smaller one may be the private flash.

For Intel boards, try to modify the IFD with ``ifdtool -u``, power on and shut down
the machine, then read the flash again. If the IFD is not modified, it is likely to
be recovered from the private flash. Find the private flash and erase it, then the IFD
can be modified.

To bypass the bootblock and PEI verification, we can modify the IFD to make the
BIOS region not overlap with the protected region. Since the EC firmware is usually
located at the high address of the flash chip (and in the protected region),
we can leave it untouched, and do not need to extract the EC firmware to put it in
the coreboot image.

[HP Sure Start Technical Whitepaper]: http://h10032.www1.hp.com/ctg/Manual/c05163901
10 changes: 10 additions & 0 deletions Documentation/mainboard/index.md
Expand Up @@ -26,6 +26,10 @@ This section contains documentation about coreboot on specific mainboards.

- [CN81XX EVB SFF](cavium/cn8100_sff_evb.md)

## Clevo

- [N130WU / N131WU](clevo/n130wu/index.md)

## Dell

- [OptiPlex 9010 SFF](dell/optiplex_9010.md)
Expand Down Expand Up @@ -61,15 +65,21 @@ The boards in this section are not real mainboards, but emulators.
### EliteBook series

- [HP Laptops with KBC1126 EC](hp/hp_kbc1126_laptops.md)
- [HP Sure Start](hp/hp_sure_start.md)
- [EliteBook 2560p](hp/2560p.md)
- [EliteBook 8760w](hp/8760w.md)
- [EliteBook Folio 9480m](hp/folio_9480m.md)

## Intel

- [DG43GT](intel/dg43gt.md)
- [IceLake RVP](intel/icelake_rvp.md)
- [KBLRVP11](intel/kblrvp11.md)

## Kontron

- [mAL-10](kontron/mal10.md)

## Lenovo

- [Mainboard codenames](lenovo/codenames.md)
Expand Down
106 changes: 106 additions & 0 deletions Documentation/mainboard/kontron/mal10.md
@@ -0,0 +1,106 @@
# Kontron mAL10 Computer-on-Modules platform

The Kontron [mAL10] COMe is a credit card sized Computer-on-Modules
platform based on the Intel Atom E3900 Series, Pentium and Celeron
processors.

## Technology

```eval_rst
+------------------+----------------------------------+
| COMe Type | mini pin-out type 10 |
+------------------+----------------------------------+
| SoC | Intel Atom x5-E3940 (4 core) |
+------------------+----------------------------------+
| GPU | Intel HD Graphics 500 |
+------------------+----------------------------------+
| Coprocessor | Intel TXE 3.0 |
+------------------+----------------------------------+
| RAM | 8GB DDR3L |
+------------------+----------------------------------+
| eMMC Flash | 32GB eMMC pSLC |
+------------------+----------------------------------+
| USB3 | x2 |
+------------------+----------------------------------+
| USB2 | x6 |
+------------------+----------------------------------+
| SATA | x2 |
+------------------+----------------------------------+
| LAN | Intel I210IT, I211AT |
+------------------+----------------------------------+
| Super IO/EC | Kontron CPLD/EC |
+------------------+----------------------------------+
| HWM | NCT7802 |
+------------------+----------------------------------+
```

## Building coreboot

The following commands will build a working image:

```bash
make distclean
make defconfig KBUILD_DEFCONFIG=configs/config.kontron_mal10
make
```
## Payloads
- SeaBIOS
- Tianocore
- Linux as payload

## Flashing coreboot

The SPI flash can be accessed internally using [flashrom].
The following command is used to flash BIOS region.

```bash
$ flashrom -p internal --ifd -i bios -w coreboot.rom --noverify-all
```

## Hardware Monitor

The Nuvoton [NCT7802Y] is a hardware monitoring IC, capable of monitor critical
system parameters including power supply voltages, fan speeds, and temperatures.
The remote inputs can be connected to CPU/GPU thermal diode or any thermal diode
sensors and thermistor.

- 6 temperature sensors;
- 5 voltage sensors;
- 3 fan speed sensors;
- 4 sets of temperature setting points.

PECI is not supported by Apollo Lake Pentium/Celeron/Atom processors and the CPU
temperature value is taken from a thermal resistor (NTC) that is placed very
close to the CPU.

## Known issues

- Works only with Tianocore "UEFIPayload" payload edk2-stable201903-1569-g3e63a91
Booting with the "CorebootPayload" [crashes].
- Tianocore outputs video through an external GPU only.

## Untested

- IGD/LVDS
- SDIO

## Tested and working

- Kontron CPLD/EC (Serial ports, I2C port)
- NCT7802 [HWM](#Hardware Monitor)
- USB2/3
- Gigabit Ethernet ports
- eMMC
- SATA
- PCIe ports
- IGD/DP

## TODO
- Onboard audio (codec IDT 92HD73C1X5, currently disabled)
- S3 suspend/resume

[mAL10]: https://www.kontron.com/products/iot/iot-industry-4.0/iot-ready-boards-and-modules/com-express/com-express-mini/come-mal10-e2-.html
[W25Q128FV]: https://www.winbond.com/resource-files/w25q128fv%20rev.m%2005132016%20kms.pdf
[flashrom]: https://flashrom.org/Flashrom
[NCT7802Y]: https://www.nuvoton.com/products/cloud-computing/hardware-monitors/desktop-server-series/nct7802y/?__locale=en
[crashes]: https://pastebin.com/cpCfrPCL
51 changes: 29 additions & 22 deletions Documentation/mainboard/purism/librem_mini.md
@@ -1,16 +1,19 @@
# Purism Librem Mini
# Purism Librem Mini (v1, v2)

This page describes how to run coreboot on the [Purism Librem Mini].

```eval_rst
+------------------+--------------------------------------------------+
| CPU | Intel Core i7-8565U |
| CPU | Intel Core i7-8565U/8665U (v1) |
| | Intel Core i7-10510U (v2) |
+------------------+--------------------------------------------------+
| PCH | Whiskey Lake / Cannon Point LP |
| PCH | Whiskey Lake / Cannon Point LP (v1) |
| | Comet Lake LP Premium (Comet Lake-U) (v2) |
+------------------+--------------------------------------------------+
| Super I/O, EC | ITE IT8528E |
+------------------+--------------------------------------------------+
| Coprocessor | Intel Management Engine (CSME 12.x) |
| Coprocessor | Intel Management Engine (CSME 12.x) (v1) |
| | Intel Management Engine (CSME 14.x) (v2) |
+------------------+--------------------------------------------------+
```

Expand All @@ -34,9 +37,9 @@ only the BIOS region is being modified).
+-----------------+---------------------------------+---------------------+
```

FSP-M and FSP-S are obtained after splitting the Coffee Lake FSP binary (done
automatically by the coreboot build system and included into the image) from
the `3rdparty/fsp` submodule.
FSP-M and FSP-S are obtained after splitting the FSP binary (done automatically
by the coreboot build system and included into the image; Coffee Lake for v1,
Comet Lake for v2) from the `3rdparty/fsp` submodule.

Microcode updates are automatically included into the coreboot image by the build
system from the `3rdparty/intel-microcode` submodule. Official Purism release
Expand All @@ -50,12 +53,14 @@ the [purism-blobs] repository.

## Intel Management Engine

The Librem Mini uses version 12.x of the Intel Management Engine (ME) /
Converged Security Engine (CSE). The ME/CSE is disabled using the High
Assurance Platform (HAP) bit, which puts the ME into a disabled state
The Librem Mini uses version 12.x (v1) or 14.x (v2) of the Intel Management
Engine (ME) / Converged Security Engine (CSE). The ME/CSE is disabled using
the High Assurance Platform (HAP) bit, which puts the ME into a disabled state
after platform bring-up (BUP) and disables all PCI/HECI interfaces.
This can be verified via the coreboot cbmem utility:
`sudo ./cbmem -1 | grep 'ME:'`

`sudo ./cbmem -1 | grep 'ME:'`

provided coreboot has been modified to output the ME status even when
the PCI device is not visible/active (as it is in Purism's release builds).

Expand All @@ -64,8 +69,9 @@ the PCI device is not visible/active (as it is in Purism's release builds).
### Internal programming

The main SPI flash can be accessed using [flashrom]. The first version
supporting the chipset is flashrom v1.2. Firmware an be easily flashed
with internal programmer (either BIOS region or full image).
supporting the chipset is flashrom v1.2 (v1.2-107-gb1f858f or later needed
for the Mini v2). Firmware an be easily flashed with internal programmer
(either BIOS region or full image).

### External programming

Expand All @@ -91,25 +97,26 @@ desoldering it from the mainboard.
## Known issues

* SeaBIOS can be finicky with detecting USB devices
* Booting can sometimes hang when a bootsplash image is used with SeaBIOS
and VGA option ROM display init, related to display mode changing
* Issues with some SATA devices have been mitigated by limiting the SATA speed to 3Gbps
until the correct HSIO PHY settings can be determined.
* Mode switching with VGA option ROM display init can be slow and sometimes hangs
* Some SATA devices on the 2.5" interface can have issues operating at 6 Gbps,
despite the HSIO PHY settings being set optimally via experimentation. These devices
may show errors in dmesg and drop down to 3 Gbps, but should not fail to boot.
The same issue is present on the AMI vendor firmware.

## Working

* External displays via HDMI/DislpayPort with VGA option ROM or FSP/GOP init
(no libgfxinit support yet)
* SeaBIOS (1.13.x), Tianocore (CorebootPayloadpkg), Heads (Purism downstream) payloads
* External displays via HDMI/DisplayPort with VGA option ROM or FSP/GOP init
(no libgfxinit support yet)
* SeaBIOS (1.14), Tianocore (CorebootPayloadPkg), Heads (Purism downstream) payloads
* Ethernet, m.2 2230 Wi-Fi
* System firmware updates via flashrom
* PCIe NVMe
* m.2 and SATA III
* Audio via front 3.5mm jack, HDMI, and DisplayPort
* SMBus (reading SPD from DIMMs)
* Initialization with CFL FSP 2.0
* Initialization with FSP 2.0 (CFL for v1, CML for v2)
* S3 Suspend/Resume
* Booting PureOS 9.x, Debian 10.x, Qubes 4.0.3, Linux Mint 19.3, Windows 10 2004
* Booting PureOS 10.x, Debian 11.x, Qubes 4.1.0-alpha1, Linux Mint 20, Windows 10 2004

## Not working / untested

Expand Down
13 changes: 7 additions & 6 deletions Documentation/releases/checklist.md
Expand Up @@ -75,7 +75,8 @@ be more frequent than was needed, so we scaled it back to twice a year.
- [ ] Test the release from the actual release tarballs.
- [ ] Push signed Tag to repo.
- [ ] Announce that the release tag is done on IRC.
- [ ] Upload release files to web server
- [ ] Upload release files to web server.
- [ ] Also extract the release notes and place them on the web server.
- [ ] Upload crossgcc sources to web server.
- [ ] Update download page to point to files, push to repo.
- [ ] Write and publish blog post with release notes.
Expand Down Expand Up @@ -197,16 +198,16 @@ the coreboot server, and put them in the release directory at
````

People can now see the release tarballs on the website at
https://www.coreboot.org/releases/
<https://www.coreboot.org/releases/>

The downloads page is the official place to download the releases from, and it needs to be updated with links to the new release tarballs and .sig files. It can be found at https://review.coreboot.org/cgit/homepage.git/tree/downloads.html
The downloads page is the official place to download the releases from, and it needs to be updated with links to the new release tarballs and .sig files. It can be found at <https://review.coreboot.org/cgit/homepage.git/tree/downloads.html>

Here is an example commit to change it: https://review.coreboot.org/#/c/19515/
Here is an example commit to change it: <https://review.coreboot.org/c/homepage/+/19515>

## Upload crossgcc sources
Sometimes the source files for older revisions of
crossgcc disappear. To deal with that we maintain a mirror at
https://www.coreboot.org/releases/crossgcc-sources/ where we host the
<https://www.coreboot.org/releases/crossgcc-sources/> where we host the
sources used by the crossgcc scripts that are part of coreboot releases.

Run
Expand All @@ -220,7 +221,7 @@ sources. Download them yourself and copy them into the crossgcc-sources
directory on the server.

## After the release is complete
Post the release notes on https://blogs.coreboot.org
Post the release notes on <https://blogs.coreboot.org>

## Making a branch
At times we will need to create a branch, generally for patch fixes.
Expand Down
221 changes: 210 additions & 11 deletions Documentation/releases/coreboot-4.13-relnotes.md
@@ -1,18 +1,114 @@
Upcoming release - coreboot 4.13
coreboot 4.13
================================

The 4.13 release is planned for November 2020.
coreboot 4.13 was released on November 20th, 2020.

Update this document with changes that should be in the release notes.
Since 4.12 there were 4200 new commits by over 234 developers.
Of these, about 72 contributed to coreboot for the first time.

* Please use Markdown.
* See the past few release notes for the general format.
* The chip and board additions and removals will be updated right
before the release, so those do not need to be added.
Thank you to all developers who again helped made coreboot better
than ever, and a big welcome to our new contributors!

New mainboards
--------------

- Acer G43T-AM3
- AMD Cereme
- Asus A88XM-E FM2+
- Biostar TH61-ITX
- BostenTech GBYT4
- Clevo L140CU/L141CU
- Dell OptiPlex 9010
- Example Min86 (fake board)
- Google Ambassador
- Google Asurada
- Google Berknip
- Google Boldar
- Google Boten
- Google Burnet
- Google Cerise
- Google Coachz
- Google Dalboz
- Google Dauntless
- Google Delbin
- Google Dirinboz
- Google Dooly
- Google Drawcia
- Google Eldrid
- Google Elemi
- Google Esche
- Google Ezkinil
- Google Faffy
- Google Fennel
- Google Genesis
- Google Hayato
- Google Lantis
- Google Lindar
- Google Madoo
- Google Magolor
- Google Metaknight
- Google Morphius
- Google Noibat
- Google Pompom
- Google Shuboz
- Google Stern
- Google Terrador
- Google Todor
- Google Trembyle
- Google Vilboz
- Google Voema
- Google Volteer2
- Google Voxel
- Google Willow
- Google Woomax
- Google Wyvern
- HP EliteBook 2560p
- HP EliteBook Folio 9480m
- HP ProBook 6360b
- Intel Alderlake-P RVP
- Kontron COMe-bSL6
- Lenovo ThinkPad X230s
- Open Compute Project DeltaLake
- Prodrive Hermes
- Purism Librem Mini
- Purism Librem Mini v2
- Siemens Chili
- Supermicro X11SSH-F
- System76 lemp9

Removed mainboards
------------------

- Google Cheza
- Google DragonEgg
- Google Ripto
- Google Sushi
- Open Compute Project SonoraPass

Significant changes
-------------------

### Native refcode implementation for Bay Trail

Bay Trail no longer needs a refcode binary to function properly. The refcode
was reimplemented as coreboot code, which should be functionally equivalent.
Thus, coreboot only needs to run the MRC.bin to successfully boot Bay Trail.

### Unusual config files to build test more code

There's some new highly-unusual config files, whose only purpose is to coerce
Jenkins into build-testing several disabled-by-default coreboot config options.
This prevents them from silently decaying over time because of build failures.

### Initial support for Intel Trusted eXecution Technology

coreboot now supports enabling Intel TXT. Though it's not feature-complete yet,
the code allows successfully launching tboot, a Measured Launch Environment. It
was tested on Haswell using an Asrock B85M Pro4 mainboard with TPM 2.0 on LPC.
Though support for other platforms is still not ready, it is being worked on.
The Haswell MRC.bin needs to be patched so as to enable DPR. Given that the MRC
binary cannot be redistributed, the best long-term solution is to replace it.

### Hidden PCI devices

This new functionality takes advantage of the existing 'hidden' keyword in the
Expand Down Expand Up @@ -41,21 +137,124 @@ the platforms. More details about the tools are added in

### New version of SMM loader

A new version of the SMM loader which accomodates platforms with over 32 CPU
A new version of the SMM loader which accommodates platforms with over 32
CPU threads. The existing version of SMM loader uses a 64K code/data
segment and only a limited number of CPU threads can fit into one segment
(because of save state, STM, other features, etc). This loader extends beyond
the 64K segment to accomodate additional CPUs and in theory allows as many
the 64K segment to accommodate additional CPUs and in theory allows as many
CPU threads as possible limited only by SMRAM space and not by 64K. By default
this loader version is disabled. Please see cpu/x86/Kconfig for more info.

### Address Sanitizer

coreboot now has an in-built Address Sanitizer, a runtime memory debugger
designed to find out-of-bounds access and use-after-scope bugs. It is made
available on all x86 platforms in ramstage and on QEMU i440fx, Intel Apollo
Lake, and Haswell in romstage. Further, it can be enabled in romstage on other
x86 platforms as well. Refer [ASan documentation](../technotes/asan.md) for
more info.

### Initial support for x86_64

The x86_64 code support has been revived and enabled for qemu. While it started
The x86_64 code support has been revived and enabled for QEMU. While it started
as PoC and the only supported platform is an emulator, there's interest in
enabling additional platforms. It would allow to access more than 4GiB of memory
at runtime and possibly brings optimised code for faster execution times.
It still needs changes in assembly, fixed integer to pointer conversions in C,
wrappers for blobs, support for running Option ROMs, among other things.

### Add significant changes here
### Preparations to minimize enabling PCI bus mastering

For security reasons, bus mastering should be enabled as late as possible. In
coreboot, it's usually not necessary and payloads should only enable it for
devices they use. Since not all payloads enable bus mastering properly yet,
some Kconfig options were added as an intermediate step to give some sort of
"backwards compatibility", which allow enabling or disabling bus mastering by
groups.

Currently available groups are:

* PCI bridges
* Any devices

For now, "Any devices" is enabled by default to keep the traditional behaviour,
which also includes all other options. This is currently necessary, for instance,
for libpayload-based payloads as the drivers don't enable bus mastering for PCI
bridges.

Exceptional cases, that may still need early bus master enabling in the future,
should get their own per-reason Kconfig option. Ideally before the next release.

### Early runtime configurability of the console log level

Traditionally, we didn't allow the log level of the `romstage` console
to be changed at runtime (e.g. via `get_option()`). It turned out that
the technical constraints for this (no global variables in `romstage`)
vanished long ago, though. The new behaviour is to query `get_option()`
now from the second stage that uses the console on. In other words, if
the `bootblock` already enables the console, the `romstage` log level
can be changed via `get_option()`. Keeping the log level of the first
console static ensures that we can see console output even if there's
a bug in the more involved code to query options.

### Resource allocator v4

A new revision of resource allocator v4 is now added to coreboot that supports
mutiple ranges for allocating resources. Unlike the previous allocator (v3), it does
not use the topmost available window for allocation. Instead, it uses the first
window within the address space that is available and satisfies the resource request.
This allows utilization of the entire available address space and also allows
allocation above the 4G boundary. The old resource allocator v3 is still retained for
some AMD platforms that do not conform to the requirements of the allocator.

Deprecations
------------

### PCI bus master configuration options

In order to minimize the usage of PCI bus mastering, the options we introduced in
this release will be dropped in a future release again. For more details, please
see [Preparations to minimize enabling PCI bus mastering](#preparations-to-minimize-enabling-pci-bus-mastering-in-coreboot).

### Resource allocator v3

Resource allocator v3 is retained in coreboot tree because the following platforms
do not conform to the requirements of the resource allocation i.e. not all the fixed
resources of the platform are provided during the `read_resources()` operation:

* northbridge/amd/pi/00630F01
* northbridge/amd/pi/00730F01
* northbridge/amd/pi/00660F01
* northbridge/amd/agesa/family14
* northbridge/amd/agesa/family15tn
* northbridge/amd/agesa/family16kb

In order to have a single unified allocator in coreboot, this notice is being added
to ensure that the platforms listed above are fixed before the next release. If there
is interest in maintaining support for these platforms beyond the next release,
please ensure that the platforms are fixed to conform to the expectations of resource
allocation.

Notes
-----

### Intel microcode updates

Intel microcode updates tagged *microcode-20200616* are still included in our
builds. Note, [Intel released new microcode updates]
(https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files/blob/main/releasenote.md)
tagged

1. *microcode-20201110*
2. *microcode-20201112*
3. *microcode-20201118*

with security updates for [INTEL-SA-00381]
(https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00381.html)
and [INTEL-SA-00389]
(https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00389.html).

Due to too short time for rigorous testing and bad experience with botched
microcode updates in the past, these new updates are not included. Users wanting
to use those, can apply them in the operating system, or update the submodule
pointer themselves.
16 changes: 16 additions & 0 deletions Documentation/releases/coreboot-4.14-relnotes.md
@@ -0,0 +1,16 @@
Upcoming release - coreboot 4.14
================================

The 4.14 release is planned for May 2021.

Update this document with changes that should be in the release notes.

* Please use Markdown.
* See the past few release notes for the general format.
* The chip and board additions and removals will be updated right
before the release, so those do not need to be added.

Significant changes
-------------------

### Add significant changes here
3 changes: 2 additions & 1 deletion Documentation/releases/index.md
Expand Up @@ -13,6 +13,7 @@ Release notes for previous releases
* [4.10 - July 2019](coreboot-4.10-relnotes.md)
* [4.11 - November 2019](coreboot-4.11-relnotes.md)
* [4.12 - May 2020](coreboot-4.12-relnotes.md)
* [4.13 - November 2020](coreboot-4.13-relnotes.md)

The checklist contains instructions to ensure that a release covers all
important things and provides a reliable format for tarballs, branch
Expand All @@ -24,4 +25,4 @@ Upcoming release
----------------

Please add to the release notes as changes are added:
* [4.13 - November 2020](coreboot-4.13-relnotes.md)
* [4.14 - May 2021](coreboot-4.14-relnotes.md)
47 changes: 37 additions & 10 deletions Documentation/security/vboot/list_vboot.md
Expand Up @@ -8,6 +8,8 @@
- Facebook Monolith

## Google
- Asurada
- Hayato
- Auron_Paine (Acer C740 Chromebook)
- Auron_Yuna (Acer Chromebook 15 (C910/CB5-531))
- Buddy (Acer Chromebase 24)
Expand All @@ -20,7 +22,6 @@
- Tricky (Dell Chromebox 3010)
- Zako (HP Chromebox G1)
- Butterfly (HP Pavilion Chromebook 14)
- Cheza
- Banon (Acer Chromebook 15 (CB3-532))
- Celes (Samsung Chromebook 3)
- Cyan (Acer Chromebook R11 (C738T))
Expand All @@ -35,7 +36,6 @@
- Daisy (Samsung Chromebook (2012))
- Deltan
- Deltaur
- DragonEgg
- Drallion
- Eve (Google Pixelbook)
- Fizz
Expand All @@ -58,20 +58,27 @@
- Rainier
- Akemi
- Dratini
- Duffy Legacy (32MB)
- Duffy
- Faffy
- Hatch
- Jinlon
- Kaisa Legacy (32MB)
- Kaisa
- Kohaku
- Kindred
- Helios
- Mushu
- Palkia
- Nightfury
- Noibat
- Puff
- Helios_Diskswap
- Stryke
- Sushi
- Wyvern
- Dooly
- Ambassador
- Genesis
- Guado (ASUS Chromebox CN62)
- Jecht
- Rikku (Acer Chromebox CXI2)
Expand All @@ -91,6 +98,12 @@
- Juniper
- Kappa
- Damu
- Cerise
- Stern
- Willow
- Esche
- Burnet
- Fennel
- Link (Google Chromebook Pixel (2013))
- Mistral
- Nyan
Expand All @@ -101,13 +114,13 @@
- Hana (Lenovo N23 Yoga Chromebook)
- Parrot (Acer C7/C710 Chromebook)
- Peach Pit (Samsung Chromebook 2 11\")
- Atlas
- Atlas (Google Pixelbook Go)
- Poppy
- Nami
- Nautilus
- Nocturne
- Rammus
- Soraka
- Nautilus (Samsung Chromebook Plus (V2 / LTE))
- Nocturne (Google Pixel Slate)
- Rammus (Asus Chromebook C425, Flip C433, Flip C434)
- Soraka (HP Chromebook x2)
- Banjo (Acer Chromebook 15 (CB3-531))
- Candy (Dell Chromebook 11 3120)
- Clapper (Lenovo N20 Chromebook)
Expand Down Expand Up @@ -139,22 +152,34 @@
- Smaug (Google Pixel C)
- Storm (OnHub Router TGR1900)
- Stout (Lenovo Thinkpad X131e Chromebook)
- Trogdor
- Lazor
- Bubs
- Coachz
- Lazor
- Pompom
- Trogdor
- Veyron_Jaq (Haier Chromebook 11)
- Veyron_Jerry (Hisense Chromebook 11)
- Veyron_Mighty (Haier Chromebook 11(edu))
- Veyron_Minnie (ASUS Chromebook Flip C100)
- Veyron_Speedy (ASUS C201 Chromebook)
- Veyron_Mickey (Asus Chromebit CS10)
- Veyron_Rialto
- Dalboz
- Vilboz
- Ezkinil
- Morphius
- Trembyle
- Berknip
- Woomax
- Dirinboz
- Shuboz

## HP
- Z220 SFF Workstation

## Intel
- Alderlake-P RVP
- Alderlake-P RVP with Chrome EC
- Basking Ridge CRB
- Cannonlake U LPDDR4 RVP
- Cannonlake Y LPDDR4 RVP
Expand Down Expand Up @@ -207,6 +232,7 @@
- ThinkPad X1
- ThinkPad X230
- ThinkPad X230t
- ThinkPad X230s
- ThinkPad X60 / X60s / X60t

## OpenCellular
Expand All @@ -227,6 +253,7 @@
## Supermicro
- X11SSH-TF
- X11SSM-F
- X11SSH-F

## UP
- Squared
49 changes: 42 additions & 7 deletions MAINTAINERS
Expand Up @@ -212,7 +212,7 @@ CLEVO MAINBOARDS
M: Felix Singer <felixsinger@posteo.net>
M: Michael Niewöhner <foss@mniewoehner.de>
S: Supported
F: src/mainboard/clevo
F: src/mainboard/clevo/



Expand Down Expand Up @@ -282,6 +282,21 @@ F: /src/mainboard/intel/strago/



KONTRON BSL6 MAINBOARD
M: Felix Singer <felixsinger@posteo.net>
M: Nico Huber <nico.h@gmx.de>
S: Supported
F: src/mainboard/kontron/bsl6/

KONTRON MAL10 MAINBOARD
M: Maxim Polyakov <max.senia.poliak@gmail.com>
M: Nico Huber <nico.h@gmx.de>
M: Felix Singer <felixsinger@posteo.net>
S: Supported
F: src/mainboard/kontron/mal10/



LENOVO MAINBOARDS
M: Alexander Couzens <lynxis@fe80.eu>
M: Patrick Rudolph <siro@das-labor.org>
Expand Down Expand Up @@ -379,6 +394,12 @@ F: src/mainboard/samsung/stumpy/



SIEMENS CHILI MAINBAORD
M: Felix Singer <felixsinger@posteo.net>
M: Nico Huber <nico.h@gmx.de>
S: Supported
F: src/mainboard/siemens/chili/

SIEMENS MC_xxxx MAINBOARDS
M: Werner Zeh <werner.zeh@siemens.com>
S: Maintained
Expand All @@ -401,7 +422,7 @@ F: src/mainboard/supermicro/x10slm-f/
SUPERMICRO X11-LGA1151-SERIES
M: Michael Niewöhner <foss@mniewoehner.de>
S: Maintained
F: src/mainboard/supermicro/x11-lga1151-series
F: src/mainboard/supermicro/x11-lga1151-series/

################################################################################
# Architectures
Expand Down Expand Up @@ -506,12 +527,13 @@ F: src/drivers/intel/
F: src/include/cpu/intel/

INTEL FSP DENVERTON-NS SOC & HARCUVAR CRB
M: Suresh Bellampalli <suresh.bellampalli@intel.com>
M: Vanessa Eusebio <vanessa.f.eusebio@intel.com>
M: David Guckian <david.guckian@intel.com>
S: Odd Fixes
M: Michal Motyl <michalx.motyl@intel.com>
M: Mariusz Szafranski <mariuszx.szafranski@intel.com>
S: Maintained
F: src/mainboard/intel/harcuvar/
F: src/soc/intel/denverton_ns/
F: src/vendorcode/intel/fsp/fsp2_0/denverton_ns/

INTEL FSP 1.1
M: Lee Leahy <leroy.p.leahy@intel.com>
Expand All @@ -529,6 +551,14 @@ F: src/drivers/intel/fsp2_0/
# Systems on a Chip
################################################################################

AMD Picasso
M: Marshall Dawson <marshalldawson3rd@gmail.com>
M: Felix Held <felix-coreboot@felixheld.de>
M: Jason Glenesk <jason.glenesk@gmail.com>
S: Maintained
F: src/soc/amd/picasso
F: src/vendorcode/amd/fsp/picasso

INTEL APOLLOLAKE_SOC
M: Andrey Petrov <andrey.petrov@gmail.com>
S: Maintained
Expand Down Expand Up @@ -694,8 +724,13 @@ OPTION ROM EXECUTION & X86EMU
F: src/device/oprom/

CBFS
F: src/include/cbfs.h
F: src/commonlib/bsd/include/commonlib/bsd/cbfs_serialized.h
M: Julius Werner <jwerner@chromium.org>
F: src/include/cbfs*
F: src/commonlib/bsd/include/commonlib/bsd/cbfs*
F: src/commonlib/bsd/cbfs*
F: src/lib/cbfs.c

CBFSTOOL
F: util/cbfstool/

CBMEM
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Expand Up @@ -440,10 +440,10 @@ doxygen_simple:
doxyplatform doxygen_platform: $(obj)/project_filelist.txt
echo
echo "Building doxygen documentation for $(CONFIG_MAINBOARD_PART_NUMBER)"
export DOXYGEN_OUTPUT_DIR="$(DOXYGEN_OUTPUT_DIR)/$(CONFIG_MAINBOARD_VENDOR)/$(CONFIG_MAINBOARD_PART_NUMBER)"; \
export DOXYGEN_OUTPUT_DIR="$$( echo $(DOXYGEN_OUTPUT_DIR)/$(call strip_quotes, $(CONFIG_MAINBOARD_VENDOR))_$(call strip_quotes, $(CONFIG_MAINBOARD_PART_NUMBER)) | sed 's|[^A-Za-z0-9/]|_|g' )"; \
mkdir -p "$$DOXYGEN_OUTPUT_DIR"; \
export DOXYFILES="$$(cat $(obj)/project_filelist.txt | grep -v '\.ld$$' | sed 's/\.aml/\.dsl/' | tr '\n' ' ')"; \
export DOXYGEN_PLATFORM="$(CONFIG_MAINBOARD_DIR) ($(CONFIG_MAINBOARD_PART_NUMBER)) version $(KERNELVERSION)"; \
export DOXYGEN_PLATFORM="$(call strip_quotes, $(CONFIG_MAINBOARD_DIR)) \($(call strip_quotes, $(CONFIG_MAINBOARD_PART_NUMBER))\) version $(KERNELVERSION)"; \
$(DOXYGEN) Documentation/doxygen/Doxyfile.coreboot_platform

doxyclean: doxygen-clean
Expand Down
33 changes: 15 additions & 18 deletions Makefile.inc
Expand Up @@ -35,7 +35,8 @@ COREBOOT_EXPORTS += KERNELVERSION
# Basic component discovery
MAINBOARDDIR=$(call strip_quotes,$(CONFIG_MAINBOARD_DIR))
VARIANT_DIR:=$(call strip_quotes,$(CONFIG_VARIANT_DIR))
COREBOOT_EXPORTS += MAINBOARDDIR VARIANT_DIR
CARRIER_DIR:=$(call strip_quotes,$(CONFIG_CARRIER_DIR))
COREBOOT_EXPORTS += MAINBOARDDIR VARIANT_DIR CARRIER_DIR

## Final build results, which CBFSTOOL uses to create the final
## rom image file, are placed under $(objcbfs).
Expand Down Expand Up @@ -83,7 +84,7 @@ subdirs-y += src/superio
subdirs-y += $(wildcard src/drivers/*) $(wildcard src/drivers/*/*) $(wildcard src/drivers/*/*/*)
subdirs-y += src/cpu src/vendorcode
subdirs-y += util/cbfstool util/sconfig util/nvramtool util/pgtblgen util/amdfwtool
subdirs-y += util/futility util/marvell util/bincfg util/supermicro
subdirs-y += util/futility util/marvell util/bincfg util/supermicro util/qemu
subdirs-y += $(wildcard src/arch/*)
subdirs-y += src/mainboard/$(MAINBOARDDIR)
subdirs-y += src/security
Expand Down Expand Up @@ -732,6 +733,16 @@ TXTIBB :=

endif

ifeq ($(CONFIG_INTEL_CBNT_SUPPORT),y)

CBNTIBB := --cbnt

else

CBNTIBB :=

endif # CONFIG_INTEL_CBNT_SUPPORT

ifeq ($(CONFIG_COMPRESS_BOOTBLOCK),y)

$(objcbfs)/bootblock.lz4: $(objcbfs)/bootblock.elf $(objutil)/cbfstool/cbfs-compression-tool
Expand Down Expand Up @@ -1063,6 +1074,7 @@ $(obj)/fmap.fmap: $(obj)/fmap.fmd $(FMAPTOOL)
ifeq ($(CONFIG_INTEL_ADD_TOP_SWAP_BOOTBLOCK),y)
TS_OPTIONS := -j $(CONFIG_INTEL_TOP_SWAP_BOOTBLOCK_SIZE)
endif

ifneq ($(CONFIG_UPDATE_IMAGE),y)
$(obj)/coreboot.pre: $(objcbfs)/bootblock.bin $$(prebuilt-files) $(CBFSTOOL) $(IFITTOOL) $$(cpu_ucode_cbfs_file) $(obj)/fmap.fmap $(obj)/fmap.desc
$(CBFSTOOL) $@.tmp create -M $(obj)/fmap.fmap -r $(shell cat $(obj)/fmap.desc)
Expand All @@ -1072,6 +1084,7 @@ ifeq ($(CONFIG_ARCH_X86),y)
-n bootblock \
-t bootblock \
$(TXTIBB) \
$(CBNTIBB) \
-b -$(call file-size,$(objcbfs)/bootblock.bin) $(cbfs-autogen-attributes) \
$(TS_OPTIONS)
else # ifeq ($(CONFIG_ARCH_X86),y)
Expand Down Expand Up @@ -1122,22 +1135,6 @@ $(obj)/coreboot.rom: $(obj)/coreboot.pre $(RAMSTAGE) $(CBFSTOOL) $$(INTERMEDIATE
# file (filled with \377 = 0xff) and copy the CBFS image over it.
dd if=/dev/zero bs=$(call _toint,$(CONFIG_ROM_SIZE)) count=1 2> /dev/null | tr '\000' '\377' > $@.tmp
dd if=$(obj)/coreboot.pre of=$@.tmp bs=8192 conv=notrunc 2> /dev/null
ifneq ($(CONFIG_SEABIOS_PS2_TIMEOUT),)
ifneq ($(CONFIG_SEABIOS_PS2_TIMEOUT),0)
ifneq ($(CONFIG_UPDATE_IMAGE),y)
@printf " SeaBIOS Wait up to $(CONFIG_SEABIOS_PS2_TIMEOUT) ms for PS/2 keyboard controller initialization\n"
$(CBFSTOOL) $@.tmp add-int -i $(CONFIG_SEABIOS_PS2_TIMEOUT) -n etc/ps2-keyboard-spinup
endif
endif
endif
ifeq ($(CONFIG_SEABIOS_ADD_SERCON_PORT_FILE),y)
@printf " SeaBIOS Add sercon-port file\n"
$(CBFSTOOL) $@.tmp add-int -i $(CONFIG_SEABIOS_SERCON_PORT_ADDR) -n etc/sercon-port
endif
ifeq ($(CONFIG_SEABIOS_THREAD_OPTIONROMS),y)
@printf " SeaBIOS Thread optionroms\n"
$(CBFSTOOL) $@.tmp add-int -i 2 -n etc/threads
endif
ifeq ($(CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE),y)
ifneq ($(CONFIG_UPDATE_IMAGE),y) # never update the bootblock
ifeq ($(CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_HEADER),y)
Expand Down
@@ -1,11 +1,15 @@
# Not meant for actual use. Exercises, among other things:
# Not meant for actual use, but rather to build-test individual options.
# If keeping this combination of options buildable becomes too hard in
# the future, then this config can be split into several smaller chunks.
# Exercises, among other things:
# + Code coverage
# + UBSAN
# + Debug options
# + SMMSTORE
# + Silicon Image SIL3114 driver
# + Genesys Logic GL9763E driver
# + EM100 support
# + SMM module loader V2
CONFIG_COVERAGE=y
CONFIG_UBSAN=y
CONFIG_VENDOR_ASROCK=y
Expand Down Expand Up @@ -41,4 +45,5 @@ CONFIG_DEBUG_COVERAGE=y
CONFIG_DEBUG_BOOT_STATE=y
CONFIG_DEBUG_ADA_CODE=y
CONFIG_HAVE_EM100_SUPPORT=y
CONFIG_X86_SMM_LOADER_VERSION2=y
CONFIG_EM100=y
2 changes: 1 addition & 1 deletion configs/config.pcengines_apu1
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.12.0.6"
CONFIG_LOCALVERSION="v4.13.0.1"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_NO_GFX_INIT=y
Expand Down
2 changes: 1 addition & 1 deletion configs/config.pcengines_apu2
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.12.0.6"
CONFIG_LOCALVERSION="v4.13.0.1"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_BOARD_PCENGINES_APU2=y
Expand Down
2 changes: 1 addition & 1 deletion configs/config.pcengines_apu3
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.12.0.6"
CONFIG_LOCALVERSION="v4.13.0.1"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_BOARD_PCENGINES_APU3=y
Expand Down
2 changes: 1 addition & 1 deletion configs/config.pcengines_apu4
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.12.0.6"
CONFIG_LOCALVERSION="v4.13.0.1"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_BOARD_PCENGINES_APU4=y
Expand Down
2 changes: 1 addition & 1 deletion configs/config.pcengines_apu5
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.12.0.6"
CONFIG_LOCALVERSION="v4.13.0.1"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_BOARD_PCENGINES_APU5=y
Expand Down
2 changes: 1 addition & 1 deletion configs/config.pcengines_apu6
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.12.0.6"
CONFIG_LOCALVERSION="v4.13.0.1"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_BOARD_PCENGINES_APU6=y
Expand Down
41 changes: 41 additions & 0 deletions configs/config.portwell_m107.debug_smmstore_oxpcie_em100spi
@@ -0,0 +1,41 @@
# Not meant for actual use, but rather to build-test individual options.
# If keeping this combination of options buildable becomes too hard in
# the future, then this config can be split into several smaller chunks.
# Exercises, among other things:
# + SMMSTORE
# + OXPCIE support
# + FSP MP init
# + EM100Pro SPI console
# + Debug options
CONFIG_VENDOR_PORTWELL=y
CONFIG_CONSOLE_POST=y
# CONFIG_CONSOLE_SERIAL is not set
CONFIG_ENABLE_BUILTIN_COM1=y
CONFIG_ONBOARD_MEM_KINGSTON=y
CONFIG_USE_INTEL_FSP_MP_INIT=y
CONFIG_SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE=y
CONFIG_SOC_INTEL_DEBUG_CONSENT=y
CONFIG_PCIEXP_HOTPLUG=y
CONFIG_PCIEXP_HOTPLUG_PREFETCH_MEM_BELOW_4G=y
CONFIG_SOFTWARE_I2C=y
CONFIG_SMMSTORE=y
CONFIG_SPI_FLASH_NO_FAST_READ=y
CONFIG_DRIVERS_UART_OXPCIE=y
CONFIG_DRIVERS_GENESYSLOGIC_GL9755=y
CONFIG_DISPLAY_HOBS=y
CONFIG_DISPLAY_VBT=y
CONFIG_DISPLAY_FSP_ENTRY_POINTS=y
CONFIG_DISPLAY_UPD_DATA=y
CONFIG_EM100PRO_SPI_CONSOLE=y
CONFIG_DISPLAY_MTRRS=y
CONFIG_GDB_STUB=y
CONFIG_GDB_WAIT=y
CONFIG_FATAL_ASSERTS=y
CONFIG_DEBUG_CBFS=y
CONFIG_DEBUG_SMBUS=y
CONFIG_DEBUG_SMI=y
CONFIG_DEBUG_PERIODIC_SMI=y
CONFIG_DEBUG_MALLOC=y
CONFIG_DEBUG_CONSOLE_INIT=y
CONFIG_REALMODE_DEBUG=y
CONFIG_DEBUG_BOOT_STATE=y
15 changes: 15 additions & 0 deletions configs/config.scaleway_tagada
@@ -0,0 +1,15 @@
CONFIG_VENDOR_SCALEWAY=y
CONFIG_BOARD_SCALEWAY_TAGADA=y
CONFIG_CBFS_SIZE=0x400000
CONFIG_CONSOLE_POST=y
# CONFIG_DRIVERS_INTEL_WIFI is not set
# CONFIG_IQAT_ENABLE is not set
CONFIG_LEGACY_UART_MODE=y
CONFIG_USE_DENVERTON_NS_FSP_CAR=y
CONFIG_SPI_FLASH_NO_FAST_READ=y
CONFIG_PAYLOAD_ELF=y
CONFIG_PAYLOAD_FILE="UEFIPAYLOAD.fd"
CONFIG_DISPLAY_FSP_CALLS_AND_STATUS=y
CONFIG_DISPLAY_FSP_HEADER=y
CONFIG_DEBUG_CBFS=y
CONFIG_DEBUG_BOOT_STATE=y
2 changes: 2 additions & 0 deletions payloads/coreinfo/.gitignore
@@ -0,0 +1,2 @@
lpbuild/
lp.config*
9 changes: 9 additions & 0 deletions payloads/coreinfo/Kconfig
Expand Up @@ -42,6 +42,15 @@ config PAYLOAD_INFO_VERSION
help
The version number of this payload.

config LTO
bool "Use link time optimization (LTO)"
default n
help
Compile with link time optimization. This can often decrease the
final binary size, but may increase compilation time. This option
is most effective when LTO is also enabled in libpayload, which
is done separately.

endmenu

menu "Modules"
Expand Down
6 changes: 5 additions & 1 deletion payloads/coreinfo/Makefile
Expand Up @@ -76,9 +76,13 @@ ifneq ($(strip $(HAVE_DOTCONFIG)),)
include $(src)/.config
real-all: $(TARGET)

ifeq ($(CONFIG_LTO),y)
CFLAGS += -flto
endif

$(TARGET): $(src)/.config $(coreinfo_obj)/config.h $(OBJS) libpayload
printf " LPCC $(subst $(CURDIR)/,,$(@)) (LINK)\n"
$(LPCC) -o $@ $(OBJS)
$(LPCC) $(CFLAGS) -o $@ $(OBJS)
$(OBJCOPY) --only-keep-debug $@ $(TARGET).debug
$(OBJCOPY) --strip-debug $@
$(OBJCOPY) --add-gnu-debuglink=$(TARGET).debug $@
Expand Down
10 changes: 10 additions & 0 deletions payloads/external/.gitignore
@@ -0,0 +1,10 @@
depthcharge/depthcharge/
FILO/filo/
GRUB2/grub2/
LinuxBoot/linuxboot/
SeaBIOS/seabios/
tianocore/tianocore/
tint/tint/
U-Boot/u-boot/
Memtest86Plus/memtest86plus/
iPXE/ipxe/
4 changes: 2 additions & 2 deletions payloads/external/FILO/Kconfig
Expand Up @@ -5,9 +5,9 @@ choice
default FILO_STABLE

config FILO_STABLE
bool "0.6.0"
bool "tested"
help
Stable FILO version
Tested FILO version

config FILO_MASTER
bool "HEAD"
Expand Down
2 changes: 1 addition & 1 deletion payloads/external/FILO/Makefile
@@ -1,6 +1,6 @@
TAG-$(CONFIG_FILO_MASTER)=origin/master
NAME-$(CONFIG_FILO_MASTER)=MASTER
TAG-$(CONFIG_FILO_STABLE)=22baa6bde9339029edfafa421b3d4a7be159edad
TAG-$(CONFIG_FILO_STABLE)=c2fa1ea6125c63e84cdf7779c37d76da8c5bc412
NAME-$(CONFIG_FILO_STABLE)=STABLE

project_git_repo=https://review.coreboot.org/filo.git
Expand Down
4 changes: 0 additions & 4 deletions payloads/external/LinuxBoot/Kconfig
@@ -1,7 +1,3 @@
##
## Copyright (C) 2017 Facebook Inc.
## Copyright (C) 2018 9elements Cyber Security
##
## SPDX-License-Identifier: GPL-2.0-only

if PAYLOAD_LINUXBOOT
Expand Down
3 changes: 0 additions & 3 deletions payloads/external/LinuxBoot/Kconfig.name
@@ -1,6 +1,3 @@
##
## Copyright (C) 2017 Facebook Inc.
##
## SPDX-License-Identifier: GPL-2.0-only

config PAYLOAD_LINUXBOOT
Expand Down
4 changes: 0 additions & 4 deletions payloads/external/LinuxBoot/Makefile
@@ -1,7 +1,3 @@
##
## Copyright (C) 2017 Facebook Inc.
## Copyright (C) 2018 9elements Cyber Security
##
## SPDX-License-Identifier: GPL-2.0-only

project_dir=linuxboot
Expand Down
4 changes: 0 additions & 4 deletions payloads/external/LinuxBoot/targets/linux.mk
@@ -1,7 +1,3 @@
##
## Copyright (C) 2017 Facebook Inc.
## Copyright (C) 2018 9elements Cyber Security
##
## SPDX-License-Identifier: GPL-2.0-only

SHELL := /bin/bash
Expand Down
4 changes: 0 additions & 4 deletions payloads/external/LinuxBoot/targets/u-root.mk
@@ -1,7 +1,3 @@
##
## Copyright (C) 2017 Facebook Inc.
## Copyright (C) 2018 9elements Cyber Security
##
## SPDX-License-Identifier: GPL-2.0-only

project_dir=$(shell pwd)/linuxboot
Expand Down
32 changes: 25 additions & 7 deletions payloads/external/Makefile.inc
@@ -1,10 +1,3 @@
################################################################################
##
##
## Copyright (C) 2009-2010 coresystems GmbH
## Copyright (C) 2015 Google Inc.
## Copyright (C) 2017 Facebook Inc.
##
## SPDX-License-Identifier: GPL-2.0-only

# set up payload config and version files for later inclusion
Expand Down Expand Up @@ -150,6 +143,31 @@ etc/sercon-port-file := $(strip $(CONFIG_SEABIOS_SERCON_PORT_FILE))
etc/sercon-port-type := raw
endif

ifneq ($(CONFIG_SEABIOS_PS2_TIMEOUT),)
ifneq ($(CONFIG_SEABIOS_PS2_TIMEOUT),0)
ifneq ($(CONFIG_UPDATE_IMAGE),y)
INTERMEDIATE+=seabios_ps2_timeout
seabios_ps2_timeout: $(obj)/coreboot.pre $(CBFSTOOL)
@printf " SeaBIOS Wait up to $(CONFIG_SEABIOS_PS2_TIMEOUT) ms for PS/2 keyboard controller initialization\n"
$(CBFSTOOL) $< add-int -i $(CONFIG_SEABIOS_PS2_TIMEOUT) -n etc/ps2-keyboard-spinup
endif
endif
endif

ifeq ($(CONFIG_SEABIOS_ADD_SERCON_PORT_FILE),y)
INTERMEDIATE+=seabios_sercon
seabios_sercon: $(obj)/coreboot.pre $(CBFSTOOL)
@printf " SeaBIOS Add sercon-port file\n"
$(CBFSTOOL) $< add-int -i $(CONFIG_SEABIOS_SERCON_PORT_ADDR) -n etc/sercon-port
endif

ifeq ($(CONFIG_SEABIOS_THREAD_OPTIONROMS),y)
INTERMEDIATE+=seabios_thread_optionroms
seabios_thread_optionroms: $(obj)/coreboot.pre $(CBFSTOOL)
@printf " SeaBIOS Thread optionroms\n"
$(CBFSTOOL) $< add-int -i 2 -n etc/threads
endif

# Depthcharge

payloads/external/depthcharge/depthcharge/build/depthcharge.elf depthcharge: $(DOTCONFIG) $(CBFSTOOL)
Expand Down
4 changes: 0 additions & 4 deletions payloads/external/Memtest86Plus/Makefile
@@ -1,7 +1,3 @@
##
##
## Copyright (C) 2016 Google Inc.
##
## SPDX-License-Identifier: GPL-2.0-only

TAG-$(CONFIG_MEMTEST_MASTER)=origin/master
Expand Down
4 changes: 0 additions & 4 deletions payloads/external/U-Boot/Makefile
@@ -1,7 +1,3 @@
##
##
## Copyright (C) 2015 Google Inc.
##
## SPDX-License-Identifier: GPL-2.0-only

# 2019-4 tag
Expand Down
4 changes: 0 additions & 4 deletions payloads/external/Yabits/Makefile
@@ -1,7 +1,3 @@
##
##
## Copyright (C) 2016 Google Inc.
##
## SPDX-License-Identifier: GPL-2.0-only

TAG-$(CONFIG_YABITS_MASTER)=origin/master
Expand Down
2 changes: 0 additions & 2 deletions payloads/external/iPXE/Kconfig
@@ -1,5 +1,3 @@
##
##
## SPDX-License-Identifier: GPL-2.0-only

config PXE
Expand Down
4 changes: 0 additions & 4 deletions payloads/external/iPXE/Makefile
@@ -1,7 +1,3 @@
##
##
## Copyright (C) 2016 Google Inc.
##
## SPDX-License-Identifier: GPL-2.0-only

# 2019.3 - Last commit of March 2019
Expand Down
4 changes: 0 additions & 4 deletions payloads/external/tianocore/Makefile
@@ -1,7 +1,3 @@
##
##
## Copyright (C) 2017 Google Inc.
##
## SPDX-License-Identifier: GPL-2.0-only

# force the shell to bash - the edksetup.sh script doesn't work with dash
Expand Down
1 change: 1 addition & 0 deletions payloads/libpayload/.gitignore
@@ -0,0 +1 @@
install/
8 changes: 8 additions & 0 deletions payloads/libpayload/Kconfig
Expand Up @@ -79,6 +79,14 @@ config COMPILER_LLVM_CLANG

endchoice

config LTO
bool "Use link time optimization (LTO)"
default n
depends on COMPILER_GCC
help
Compile with link time optimization. This can often decrease the
final binary size, but may increase compilation time.

config REMOTEGDB
bool "Remote GDB stub"
default n
Expand Down
7 changes: 6 additions & 1 deletion payloads/libpayload/Makefile.inc
Expand Up @@ -55,7 +55,8 @@ subdirs-$(CONFIG_LP_CBFS) += libcbfs
subdirs-$(CONFIG_LP_LZMA) += liblzma
subdirs-$(CONFIG_LP_LZ4) += liblz4

INCLUDES := -Iinclude -Iinclude/$(ARCHDIR-y) -I$(obj) -include include/kconfig.h
INCLUDES := -Iinclude -Iinclude/$(ARCHDIR-y) -I$(obj)
INCLUDES += -include include/kconfig.h -include include/compiler.h

CFLAGS += $(EXTRA_CFLAGS) $(INCLUDES) -Os -pipe -nostdinc -ggdb3
CFLAGS += -nostdlib -fno-builtin -ffreestanding -fomit-frame-pointer
Expand All @@ -64,6 +65,10 @@ CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wmissing-prototypes -Wvla
CFLAGS += -Wwrite-strings -Wredundant-decls -Wno-trigraphs -Wimplicit-fallthrough
CFLAGS += -Wstrict-aliasing -Wshadow -Werror

ifeq ($(CONFIG_LP_LTO),y)
CFLAGS += -flto
endif

$(obj)/libpayload-config.h: $(KCONFIG_AUTOHEADER)
cmp $@ $< 2>/dev/null || cp $< $@

Expand Down
119 changes: 116 additions & 3 deletions payloads/libpayload/arch/x86/timer.c
Expand Up @@ -33,6 +33,10 @@

#include <libpayload.h>
#include <arch/rdtsc.h>
#include <arch/cpuid.h>
#include <arch/msr.h>

#define MSR_PLATFORM_INFO 0xce

/**
* @ingroup arch
Expand All @@ -41,11 +45,11 @@
uint32_t cpu_khz;

/**
* Calculate the speed of the processor for use in delays.
* @brief Measure the speed of the processor for use in delays
*
* @return The CPU speed in kHz.
*/
unsigned int get_cpu_speed(void)
static unsigned int calibrate_pit(void)
{
unsigned long long start, end;
const uint32_t clock_rate = 1193182; // 1.193182 MHz
Expand All @@ -71,7 +75,116 @@ unsigned int get_cpu_speed(void)
* clock_rate / (interval * 1000). Multiply that by the number of
* measured clocks to get the kHz value.
*/
cpu_khz = (end - start) * clock_rate / (1000 * interval);
return (end - start) * clock_rate / (1000 * interval);
}

/**
* @brief Calculates the core clock frequency via CPUID 0x15
*
* Newer Intel CPUs report their core clock in CPUID leaf 0x15. Early models
* supporting this leaf didn't provide the nominal crystal frequency in ecx,
* hence we use hard coded values for them.
*/
static int get_cpu_khz_xtal(void)
{
uint32_t ecx, edx, num, denom;
uint64_t nominal;

if (cpuid_max() < 0x15)
return -1;
cpuid(0x15, denom, num, ecx, edx);

if (denom == 0 || num == 0)
return -1;

if (ecx != 0) {
nominal = ecx;
} else {
if (cpuid_family() != 6)
return -1;

switch (cpuid_model()) {
case SKYLAKE_U_Y:
case SKYLAKE_S_H:
case KABYLAKE_U_Y:
case KABYLAKE_S_H:
nominal = 24000000;
break;
case APOLLOLAKE:
nominal = 19200000;
break;
default:
return -1;
}
}

return nominal * num / denom / 1000;
}

/**
* @brief Returns three times the bus clock in kHz
*
* The result of calculations with the returned value shall be divided by 3.
* This helps to avoid rounding errors.
*/
static int get_bus_khz_x3(void)
{
if (cpuid_family() != 6)
return -1;

switch (cpuid_model()) {
case NEHALEM:
return 400 * 1000; /* 133 MHz */
case SANDYBRIDGE:
case IVYBRIDGE:
case HASWELL:
case HASWELL_U:
case HASWELL_GT3E:
case BROADWELL:
case BROADWELL_U:
return 300 * 1000; /* 100 MHz */
default:
return -1;
}
}

/**
* @brief Returns the calculated CPU frequency
*
* Over the years, multiple ways to discover the CPU frequency have been
* exposed through CPUID and MSRs. Try the most recent and accurate first
* (crystal information in CPUID leaf 0x15) and then fall back to older
* methods.
*
* This should cover all Intel Core i processors at least. For older
* processors we fall back to the PIT calibration.
*/
static int get_cpu_khz_fast(void)
{
/* Try core crystal clock frequency first (supposed to be more accurate). */
const int cpu_khz_xtal = get_cpu_khz_xtal();
if (cpu_khz_xtal > 0)
return cpu_khz_xtal;

/* Try `bus clock * speedstep multiplier`. */
const int bus_x3 = get_bus_khz_x3();
if (bus_x3 <= 0)
return -1;
/*
* Systems with an invariant TSC report the multiplier (maximum
* non-turbo ratio) in MSR_PLATFORM_INFO[15:8].
*/
const unsigned int mult = _rdmsr(MSR_PLATFORM_INFO) >> 8 & 0xff;
return bus_x3 * mult / 3;
}

unsigned int get_cpu_speed(void)
{
const int cpu_khz_fast = get_cpu_khz_fast();
if (cpu_khz_fast > 0)
cpu_khz = (unsigned int)cpu_khz_fast;
else
cpu_khz = calibrate_pit();

return cpu_khz;
}
3 changes: 2 additions & 1 deletion payloads/libpayload/bin/lpgcc
Expand Up @@ -152,7 +152,8 @@ fi
trygccoption -fno-stack-protector
[ $? -eq 0 ] && _CFLAGS="$_CFLAGS -fno-stack-protector"

_CFLAGS="$_CFLAGS -include $BASE/../include/kconfig.h -I`$DEFAULT_CC $_ARCHEXTRA -print-search-dirs | head -n 1 | cut -d' ' -f2`include"
_CFLAGS="$_CFLAGS -include $BASE/../include/kconfig.h -include $BASE/../include/compiler.h"
_CFLAGS="$_CFLAGS -I`$DEFAULT_CC $_ARCHEXTRA -print-search-dirs | head -n 1 | cut -d' ' -f2`include"

_LDFLAGS="-L$BASE/../lib -L$_LIBDIR $_LDSCRIPT -static"

Expand Down
3 changes: 0 additions & 3 deletions payloads/libpayload/configs/config.cheza

This file was deleted.

2 changes: 1 addition & 1 deletion payloads/libpayload/drivers/i8042/i8042.c
Expand Up @@ -159,7 +159,7 @@ static u8 i8042_wait_cmd_rdy(void)
*/
static u8 i8042_wait_data_rdy(void)
{
int retries = 10000;
int retries = 30000;
while (retries-- && !(read_status() & OBF))
udelay(50);

Expand Down
4 changes: 1 addition & 3 deletions payloads/libpayload/drivers/storage/storage.c
Expand Up @@ -28,9 +28,7 @@

#include <libpayload.h>
#include <pci/pci.h>
#if CONFIG(LP_STORAGE_AHCI)
# include <storage/ahci.h>
#endif
#include <storage/ahci.h>
#include <storage/storage.h>

static storage_dev_t **devices = NULL;
Expand Down
17 changes: 10 additions & 7 deletions payloads/libpayload/drivers/usb/ehci.c
Expand Up @@ -28,6 +28,7 @@

//#define USB_DEBUG

#include <inttypes.h>
#include <libpayload.h>
#include <arch/barrier.h>
#include <arch/cache.h>
Expand All @@ -46,15 +47,15 @@ static void dump_td(u32 addr)
usb_debug("|..[OUT]............................................|\n");
else
usb_debug("|..[]...............................................|\n");
usb_debug("|:|============ EHCI TD at [0x%08lx] ==========|:|\n", addr);
usb_debug("|:| ERRORS = [%ld] | TOKEN = [0x%08lx] | |:|\n",
usb_debug("|:|============ EHCI TD at [0x%08"PRIx32"] ==========|:|\n", addr);
usb_debug("|:| ERRORS = [%"PRId32"] | TOKEN = [0x%08"PRIx32"] | |:|\n",
3 - ((td->token & QTD_CERR_MASK) >> QTD_CERR_SHIFT), td->token);
usb_debug("|:+-----------------------------------------------+:|\n");
usb_debug("|:| Next qTD [0x%08lx] |:|\n", td->next_qtd);
usb_debug("|:| Next qTD [0x%08"PRIx32"] |:|\n", td->next_qtd);
usb_debug("|:+-----------------------------------------------+:|\n");
usb_debug("|:| Alt. Next qTD [0x%08lx] |:|\n", td->alt_next_qtd);
usb_debug("|:| Alt. Next qTD [0x%08"PRIx32"] |:|\n", td->alt_next_qtd);
usb_debug("|:+-----------------------------------------------+:|\n");
usb_debug("|:| | Bytes to Transfer |[%05ld] |:|\n", (td->token & QTD_TOTAL_LEN_MASK) >> 16);
usb_debug("|:| | Bytes to Transfer |[%05"PRId32"] |:|\n", (td->token & QTD_TOTAL_LEN_MASK) >> 16);
usb_debug("|:| | PID CODE: | [%ld] |:|\n", (td->token & (3UL << 8)) >> 8);
usb_debug("|:| | Interrupt On Complete (IOC) | [%ld] |:|\n", (td->token & (1UL << 15)) >> 15);
usb_debug("|:| | Status Active | [%ld] |:|\n", (td->token & (1UL << 7)) >> 7);
Expand Down Expand Up @@ -277,9 +278,11 @@ static int wait_for_tds(qtd_t *head)
if (cur->next_qtd & 1) {
break;
}
if (0) dump_td(virt_to_phys(cur));
if (0)
dump_td(virt_to_phys(cur));
/* helps debugging the TD chain */
if (0) usb_debug("\nmoving from %x to %x\n", cur, phys_to_virt(cur->next_qtd));
if (0)
usb_debug("\nmoving from %p to %p\n", cur, phys_to_virt(cur->next_qtd));
cur = phys_to_virt(cur->next_qtd);
}
return result;
Expand Down
19 changes: 10 additions & 9 deletions payloads/libpayload/drivers/usb/ohci.c
Expand Up @@ -29,6 +29,7 @@
//#define USB_DEBUG

#include <arch/virtual.h>
#include <inttypes.h>
#include <usb/usb.h>
#include "ohci_private.h"
#include "ohci.h"
Expand Down Expand Up @@ -59,7 +60,7 @@ dump_td (td_t *cur)
else
usb_debug("|..[]...............................................|\n");
usb_debug("|:|============ OHCI TD at [0x%08lx] ==========|:|\n", virt_to_phys(cur));
usb_debug("|:| ERRORS = [%ld] | CONFIG = [0x%08lx] | |:|\n",
usb_debug("|:| ERRORS = [%ld] | CONFIG = [0x%08"PRIx32"] | |:|\n",
3 - ((cur->config & (3UL << 26)) >> 26), cur->config);
usb_debug("|:+-----------------------------------------------+:|\n");
usb_debug("|:| C | Condition Code | [%02ld] |:|\n", (cur->config & (0xFUL << 28)) >> 28);
Expand All @@ -69,11 +70,11 @@ dump_td (td_t *cur)
usb_debug("|:| I | Data Toggle | [%ld] |:|\n", (cur->config & (3UL << 24)) >> 24);
usb_debug("|:| G | Error Count | [%ld] |:|\n", (cur->config & (3UL << 26)) >> 26);
usb_debug("|:+-----------------------------------------------+:|\n");
usb_debug("|:| Current Buffer Pointer [0x%08lx] |:|\n", cur->current_buffer_pointer);
usb_debug("|:| Current Buffer Pointer [0x%08"PRIx32"] |:|\n", cur->current_buffer_pointer);
usb_debug("|:+-----------------------------------------------+:|\n");
usb_debug("|:| Next TD [0x%08lx] |:|\n", cur->next_td);
usb_debug("|:| Next TD [0x%08"PRIx32"] |:|\n", cur->next_td);
usb_debug("|:+-----------------------------------------------+:|\n");
usb_debug("|:| Current Buffer End [0x%08lx] |:|\n", cur->buffer_end);
usb_debug("|:| Current Buffer End [0x%08"PRIx32"] |:|\n", cur->buffer_end);
usb_debug("|:|-----------------------------------------------|:|\n");
usb_debug("|...................................................|\n");
usb_debug("+---------------------------------------------------+\n");
Expand All @@ -88,9 +89,9 @@ dump_ed (ed_t *cur)
usb_debug("+---------------------------------------------------+\n");
usb_debug("| Next Endpoint Descriptor [0x%08lx] |\n", cur->next_ed & ~0xFUL);
usb_debug("+---------------------------------------------------+\n");
usb_debug("| | @ 0x%08lx : |\n", cur->config);
usb_debug("| | @ 0x%08"PRIx32" : |\n", cur->config);
usb_debug("| C | Maximum Packet Length | [%04ld] |\n", ((cur->config & (0x3fffUL << 16)) >> 16));
usb_debug("| O | Function Address | [%04ld] |\n", cur->config & 0x7F);
usb_debug("| O | Function Address | [%04"PRIx32"] |\n", cur->config & 0x7F);
usb_debug("| N | Endpoint Number | [%02ld] |\n", (cur->config & (0xFUL << 7)) >> 7);
usb_debug("| F | Endpoint Direction | [%ld] |\n", ((cur->config & (3UL << 11)) >> 11));
usb_debug("| I | Endpoint Speed | [%ld] |\n", ((cur->config & (1UL << 13)) >> 13));
Expand Down Expand Up @@ -468,7 +469,7 @@ ohci_control (usbdev_t *dev, direction_t dir, int drlen, void *setup, int dalen,
head->tail_pointer = virt_to_phys(final_td);
head->head_pointer = virt_to_phys(first_td);

usb_debug("ohci_control(): doing transfer with %x. first_td at %x\n",
usb_debug("%s(): doing transfer with %x. first_td at %"PRIxPTR"\n", __func__,
head->config & ED_FUNC_MASK, virt_to_phys(first_td));
#ifdef USB_DEBUG
dump_ed(head);
Expand Down Expand Up @@ -506,7 +507,7 @@ ohci_bulk (endpoint_t *ep, int dalen, u8 *src, int finalize)
td_t *cur, *next;
int remaining = dalen;
u8 *data = src;
usb_debug("bulk: %x bytes from %x, finalize: %x, maxpacketsize: %x\n", dalen, src, finalize, ep->maxpacketsize);
usb_debug("bulk: %x bytes from %p, finalize: %x, maxpacketsize: %x\n", dalen, src, finalize, ep->maxpacketsize);

if (!dma_coherent(src)) {
data = OHCI_INST(ep->dev->controller)->dma_buffer;
Expand Down Expand Up @@ -596,7 +597,7 @@ ohci_bulk (endpoint_t *ep, int dalen, u8 *src, int finalize)
head->tail_pointer = virt_to_phys(cur);
head->head_pointer = virt_to_phys(first_td) | (ep->toggle?ED_TOGGLE:0);

usb_debug("doing bulk transfer with %x(%x). first_td at %x, last %x\n",
usb_debug("doing bulk transfer with %x(%x). first_td at %"PRIxPTR", last %"PRIxPTR"\n",
head->config & ED_FUNC_MASK,
(head->config & ED_EP_MASK) >> ED_EP_SHIFT,
virt_to_phys(first_td), virt_to_phys(cur));
Expand Down
58 changes: 30 additions & 28 deletions payloads/libpayload/drivers/usb/ohci_private.h
Expand Up @@ -36,27 +36,27 @@
// FIXME: fake
typedef enum { CMD} reg;

enum {
enum HcRhDescriptorAReg {
NumberDownstreamPorts = 1 << 0,
PowerSwitchingMode = 1 << 8,
NoPowerSwitching = 1 << 9,
DeviceType = 1 << 10,
OverCurrentProtectionMode = 1 << 11,
NoOverCurrentProtection = 1 << 12,
PowerOnToPowerGoodTime = 1 << 24
} HcRhDescriptorAReg;
};

enum {
enum HcRhDescriptorAMask {
NumberDownstreamPortsMask = MASK(0, 8),
PowerOnToPowerGoodTimeMask = MASK(24, 8)
} HcRhDescriptorAMask;
};

enum {
enum HcRhDescriptorBReg {
DeviceRemovable = 1 << 0,
PortPowerControlMask = 1 << 16
} HcRhDescriptorBReg;
};

enum {
enum HcRhPortStatusRead {
CurrentConnectStatus = 1 << 0,
PortEnableStatus = 1 << 1,
PortSuspendStatus = 1 << 2,
Expand All @@ -69,38 +69,40 @@
PortSuspendStatusChange = 1 << 18,
PortOverCurrentIndicatorChange = 1 << 19,
PortResetStatusChange = 1 << 20
} HcRhPortStatusRead;
enum {
};

enum HcRhPortStatusSet {
ClearPortEnable = 1 << 0,
SetPortEnable = 1 << 1,
SetPortSuspend = 1 << 2,
ClearSuspendStatus = 1 << 3,
SetPortReset = 1 << 4,
SetPortPower = 1 << 8,
ClearPortPower = 1 << 9,
} HcRhPortStatusSet;
};

enum {
enum HcRhStatusReg {
LocalPowerStatus = 1 << 0,
OverCurrentIndicator = 1 << 1,
DeviceRemoteWakeupEnable = 1 << 15,
LocalPowerStatusChange = 1 << 16,
OverCurrentIndicatorChange = 1 << 17,
ClearRemoteWakeupEnable = 1 << 31
} HcRhStatusReg;
};

enum {
enum HcFmIntervalOffset {
FrameInterval = 1 << 0,
FSLargestDataPacket = 1 << 16,
FrameIntervalToggle = 1 << 31
} HcFmIntervalOffset;
enum {
};

enum HcFmIntervalMask {
FrameIntervalMask = MASK(0, 14),
FSLargestDataPacketMask = MASK(16, 15),
FrameIntervalToggleMask = MASK(31, 1)
} HcFmIntervalMask;
};

enum {
enum HcControlReg {
ControlBulkServiceRatio = 1 << 0,
PeriodicListEnable = 1 << 2,
IsochronousEnable = 1 << 3,
Expand All @@ -110,12 +112,12 @@
InterruptRouting = 1 << 8,
RemoteWakeupConnected = 1 << 9,
RemoteWakeupEnable = 1 << 10
} HcControlReg;
};

enum {
enum HcControlMask {
ControlBulkServiceRatioMask = MASK(0, 2),
HostControllerFunctionalStateMask = MASK(6, 2)
} HcControlMask;
};

enum {
USBReset = 0*HostControllerFunctionalState,
Expand All @@ -124,24 +126,24 @@
USBSuspend = 3*HostControllerFunctionalState
};

enum {
enum HcCommandStatusReg {
HostControllerReset = 1 << 0,
ControlListFilled = 1 << 1,
BulkListFilled = 1 << 2,
OwnershipChangeRequest = 1 << 3,
SchedulingOverrunCount = 1 << 16
} HcCommandStatusReg;
};

enum {
enum HcCommandStatusMask {
SchedulingOverrunCountMask = MASK(16, 2)
} HcCommandStatusMask;
};

enum {
enum HcFmRemainingReg {
FrameRemaining = 1 << 0,
FrameRemainingToggle = 1 << 31
} HcFmRemainingReg;
};

enum {
enum HcInterruptStatusReg {
SchedulingOverrung = 1 << 0,
WritebackDoneHead = 1 << 1,
StartofFrame = 1 << 2,
Expand All @@ -150,7 +152,7 @@
FrameNumberOverflow = 1 << 5,
RootHubStatusChange = 1 << 6,
OwnershipChange = 1 << 30
} HcInterruptStatusReg;
};

typedef struct {
// Control and Status Partition
Expand Down
9 changes: 5 additions & 4 deletions payloads/libpayload/drivers/usb/uhci.c
Expand Up @@ -29,6 +29,7 @@
//#define USB_DEBUG

#include <arch/virtual.h>
#include <inttypes.h>
#include <usb/usb.h>
#include "uhci.h"
#include "uhci_private.h"
Expand Down Expand Up @@ -79,14 +80,14 @@ static void td_dump(td_t *td)
(td->ptr & (1UL << 2)) >> 2, (td->ptr & (1UL << 1)) >> 1, td->ptr & 1UL);
usb_debug("|:+-----------------------------------------------+:|\n");
usb_debug("|:| T | Maximum Length | [%04lx] |:|\n", (td->token & (0x7FFUL << 21)) >> 21);
usb_debug("|:| O | PID CODE | [%04lx] |:|\n", td->token & 0xFF);
usb_debug("|:| K | Endpoint | [%04lx] |:|\n", (td->token & TD_EP_MASK) >> TD_EP_SHIFT);
usb_debug("|:| O | PID CODE | [%04"PRIx32"] |:|\n", td->token & 0xFF);
usb_debug("|:| K | Endpoint | [%04"PRIx32"] |:|\n", (td->token & TD_EP_MASK) >> TD_EP_SHIFT);
usb_debug("|:| E | Device Address | [%04lx] |:|\n", (td->token & (0x7FUL << 8)) >> 8);
usb_debug("|:| N | Data Toggle | [%lx] |:|\n", (td->token & (1UL << 19)) >> 19);
usb_debug("|:+-----------------------------------------------+:|\n");
usb_debug("|:| C | Short Packet Detector | [%lx] |:|\n", (td->ctrlsts & (1UL << 29)) >> 29);
usb_debug("|:| O | Error Counter | [%lx] |:|\n",
(td->ctrlsts & (3UL << TD_COUNTER_SHIFT)) >> TD_COUNTER_SHIFT);
(td->ctrlsts & (3UL << TD_COUNTER_SHIFT)) >> TD_COUNTER_SHIFT);
usb_debug("|:| N | Low Speed Device | [%lx] |:|\n", (td->ctrlsts & (1UL << 26)) >> 26);
usb_debug("|:| T | Isochronous Select | [%lx] |:|\n", (td->ctrlsts & (1UL << 25)) >> 25);
usb_debug("|:| R | Interrupt on Complete (IOC) | [%lx] |:|\n", (td->ctrlsts & (1UL << 24)) >> 24);
Expand All @@ -101,7 +102,7 @@ static void td_dump(td_t *td)
usb_debug("|:| S ----------------------------------------|:|\n");
usb_debug("|:| | Actual Length | [%04lx] |:|\n", td->ctrlsts & 0x7FFUL);
usb_debug("|:+-----------------------------------------------+:|\n");
usb_debug("|:| Buffer pointer [0x%08lx] |:|\n", td->bufptr);
usb_debug("|:| Buffer pointer [0x%08"PRIx32"] |:|\n", td->bufptr);
usb_debug("|:|-----------------------------------------------|:|\n");
usb_debug("|...................................................|\n");
usb_debug("+---------------------------------------------------+\n");
Expand Down
3 changes: 2 additions & 1 deletion payloads/libpayload/drivers/usb/usb.c
Expand Up @@ -28,6 +28,7 @@

//#define USB_DEBUG

#include <inttypes.h>
#include <libpayload-config.h>
#include <usb/usb.h>

Expand Down Expand Up @@ -229,7 +230,7 @@ get_free_address (hci_t *controller)
int i = controller->latest_address + 1;
for (; i != controller->latest_address; i++) {
if (i >= ARRAY_SIZE(controller->devices) || i < 1) {
usb_debug("WARNING: Device addresses for controller %#x"
usb_debug("WARNING: Device addresses for controller %#" PRIxPTR
" wrapped around!\n", controller->reg_base);
i = 0;
continue;
Expand Down
12 changes: 6 additions & 6 deletions payloads/libpayload/drivers/usb/xhci.c
Expand Up @@ -194,7 +194,7 @@ xhci_init (unsigned long physical_bar)
xhci->hcrreg = phys_to_virt(physical_bar) + xhci->capreg->rtsoff;
xhci->dbreg = phys_to_virt(physical_bar) + xhci->capreg->dboff;

xhci_debug("regbase: 0x%"PRIx32"\n", physical_bar);
xhci_debug("regbase: 0x%"PRIxPTR"\n", physical_bar);
xhci_debug("caplen: 0x%"PRIx32"\n", CAP_GET(CAPLEN, xhci->capreg));
xhci_debug("rtsoff: 0x%"PRIx32"\n", xhci->capreg->rtsoff);
xhci_debug("dboff: 0x%"PRIx32"\n", xhci->capreg->dboff);
Expand All @@ -208,8 +208,8 @@ xhci_init (unsigned long physical_bar)
}

xhci_debug("context size: %dB\n", CTXSIZE(xhci));
xhci_debug("maxslots: 0x%02lx\n", CAP_GET(MAXSLOTS, xhci->capreg));
xhci_debug("maxports: 0x%02lx\n", CAP_GET(MAXPORTS, xhci->capreg));
xhci_debug("maxslots: 0x%02"PRIx32"\n", CAP_GET(MAXSLOTS, xhci->capreg));
xhci_debug("maxports: 0x%02"PRIx32"\n", CAP_GET(MAXPORTS, xhci->capreg));
const unsigned pagesize = xhci->opreg->pagesize << 12;
xhci_debug("pagesize: 0x%04x\n", pagesize);

Expand Down Expand Up @@ -374,7 +374,7 @@ xhci_reinit (hci_t *controller)

/* Initialize command ring */
xhci_init_cycle_ring(&xhci->cr, COMMAND_RING_SIZE);
xhci_debug("command ring @%p (0x%08x)\n",
xhci_debug("command ring @%p (0x%08"PRIxPTR")\n",
xhci->cr.ring, virt_to_phys(xhci->cr.ring));
xhci->opreg->crcr_lo = virt_to_phys(xhci->cr.ring) | CRCR_RCS;
xhci->opreg->crcr_hi = 0;
Expand All @@ -384,9 +384,9 @@ xhci_reinit (hci_t *controller)

/* Initialize event ring */
xhci_reset_event_ring(&xhci->er);
xhci_debug("event ring @%p (0x%08x)\n",
xhci_debug("event ring @%p (0x%08"PRIxPTR")\n",
xhci->er.ring, virt_to_phys(xhci->er.ring));
xhci_debug("ERST Max: 0x%lx -> 0x%lx entries\n",
xhci_debug("ERST Max: 0x%"PRIx32" -> 0x%x entries\n",
CAP_GET(ERST_MAX, xhci->capreg),
1 << CAP_GET(ERST_MAX, xhci->capreg));
memset((void*)xhci->ev_ring_table, 0x00, sizeof(erst_entry_t));
Expand Down
1 change: 0 additions & 1 deletion payloads/libpayload/include/cbfs_core.h
Expand Up @@ -49,7 +49,6 @@
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <compiler.h>

/** These are standard values for the known compression
alogrithms that coreboot knows about for stages and
Expand Down
17 changes: 11 additions & 6 deletions payloads/libpayload/include/coreboot_tables.h
Expand Up @@ -80,6 +80,7 @@ enum {
CB_TAG_TCPA_LOG = 0x0036,
CB_TAG_FMAP = 0x0037,
CB_TAG_SMMSTOREV2 = 0x0039,
CB_TAG_BOARD_CONFIG = 0x0040,
CB_TAG_CMOS_OPTION_TABLE = 0x00c8,
CB_TAG_OPTION = 0x00c9,
CB_TAG_OPTION_ENUM = 0x00ca,
Expand Down Expand Up @@ -260,12 +261,6 @@ struct cb_x86_rom_mtrr {
uint32_t index;
};

struct cb_strapping_id {
uint32_t tag;
uint32_t size;
uint32_t id_code;
};

struct cb_spi_flash {
uint32_t tag;
uint32_t size;
Expand Down Expand Up @@ -317,6 +312,16 @@ struct cb_mmc_info {
int32_t early_cmd1_status;
};

struct cb_board_config {
uint32_t tag;
uint32_t size;

struct cbuint64 fw_config;
uint32_t board_id;
uint32_t ram_code;
uint32_t sku_id;
};

#define CB_MAX_SERIALNO_LENGTH 32

struct cb_cmos_option_table {
Expand Down
1 change: 0 additions & 1 deletion payloads/libpayload/include/libpayload.h
Expand Up @@ -44,7 +44,6 @@

#include <stdbool.h>
#include <libpayload-config.h>
#include <compiler.h>
#include <cbgfx.h>
#include <ctype.h>
#include <die.h>
Expand Down
9 changes: 8 additions & 1 deletion payloads/libpayload/include/sysinfo.h
Expand Up @@ -107,11 +107,18 @@ struct sysinfo_t {
uintptr_t mrc_cache;
uintptr_t acpi_gnvs;

#define UNDEFINED_STRAPPING_ID (~0)
#define UNDEFINED_STRAPPING_ID (~0)
#define UNDEFINED_FW_CONFIG ~((uint64_t)0)
u32 board_id;
u32 ram_code;
u32 sku_id;

/*
* A payload using this field is responsible for ensuring it checks its
* value against UNDEFINED_FW_CONFIG before using it.
*/
u64 fw_config;

uintptr_t wifi_calibration;
uint64_t ramoops_buffer;
uint32_t ramoops_buffer_size;
Expand Down
2 changes: 1 addition & 1 deletion payloads/libpayload/include/usb/usb.h
Expand Up @@ -334,7 +334,7 @@ int usb_interface_check(u16 vendor, u16 device);
#define USB_QUIRK_TEST (1 << 31)
#define USB_QUIRK_NONE 0

static inline void usb_debug(const char *fmt, ...)
static inline void __attribute__((format(printf, 1, 2))) usb_debug(const char *fmt, ...)
{
#ifdef USB_DEBUG
va_list ap;
Expand Down
16 changes: 16 additions & 0 deletions payloads/libpayload/include/x86/arch/cpuid.h
Expand Up @@ -64,4 +64,20 @@ static inline unsigned int cpuid_model(void)
return (eax & 0xf0000) >> (16 - 4) | (eax & 0xf0) >> 4;
}

enum intel_fam6_model {
NEHALEM = 0x25,
SANDYBRIDGE = 0x2a,
IVYBRIDGE = 0x3a,
HASWELL = 0x3c,
BROADWELL_U = 0x3d,
HASWELL_U = 0x45,
HASWELL_GT3E = 0x46,
BROADWELL = 0x47,
SKYLAKE_U_Y = 0x4e,
APOLLOLAKE = 0x5c,
SKYLAKE_S_H = 0x5e,
KABYLAKE_U_Y = 0x8e,
KABYLAKE_S_H = 0x9e,
};

#endif
32 changes: 9 additions & 23 deletions payloads/libpayload/libc/coreboot.c
Expand Up @@ -143,22 +143,13 @@ static void cb_parse_acpi_gnvs(unsigned char *ptr, struct sysinfo_t *info)
info->acpi_gnvs = get_cbmem_addr(ptr);
}

static void cb_parse_board_id(unsigned char *ptr, struct sysinfo_t *info)
static void cb_parse_board_config(unsigned char *ptr, struct sysinfo_t *info)
{
struct cb_strapping_id *const cbbid = (struct cb_strapping_id *)ptr;
info->board_id = cbbid->id_code;
}

static void cb_parse_ram_code(unsigned char *ptr, struct sysinfo_t *info)
{
struct cb_strapping_id *const ram_code = (struct cb_strapping_id *)ptr;
info->ram_code = ram_code->id_code;
}

static void cb_parse_sku_id(unsigned char *ptr, struct sysinfo_t *info)
{
struct cb_strapping_id *const sku_id = (struct cb_strapping_id *)ptr;
info->sku_id = sku_id->id_code;
struct cb_board_config *const config = (struct cb_board_config *)ptr;
info->fw_config = cb_unpack64(config->fw_config);
info->board_id = config->board_id;
info->ram_code = config->ram_code;
info->sku_id = config->sku_id;
}

#if CONFIG(LP_NVRAM)
Expand Down Expand Up @@ -290,6 +281,7 @@ int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
info->board_id = UNDEFINED_STRAPPING_ID;
info->ram_code = UNDEFINED_STRAPPING_ID;
info->sku_id = UNDEFINED_STRAPPING_ID;
info->fw_config = UNDEFINED_FW_CONFIG;

/* Now, walk the tables. */
ptr += header->header_bytes;
Expand Down Expand Up @@ -381,14 +373,8 @@ int cb_parse_header(void *addr, int len, struct sysinfo_t *info)
case CB_TAG_ACPI_GNVS:
cb_parse_acpi_gnvs(ptr, info);
break;
case CB_TAG_BOARD_ID:
cb_parse_board_id(ptr, info);
break;
case CB_TAG_RAM_CODE:
cb_parse_ram_code(ptr, info);
break;
case CB_TAG_SKU_ID:
cb_parse_sku_id(ptr, info);
case CB_TAG_BOARD_CONFIG:
cb_parse_board_config(ptr, info);
break;
case CB_TAG_WIFI_CALIBRATION:
cb_parse_wifi_calibration(ptr, info);
Expand Down
2 changes: 2 additions & 0 deletions payloads/nvramcui/.gitignore
@@ -0,0 +1,2 @@
build
libpayload
19 changes: 19 additions & 0 deletions src/Kconfig
Expand Up @@ -915,6 +915,15 @@ config DEBUG_MALLOC

If unsure, say N.

# Only visible if DEBUG_SPEW (8) is set.
config DEBUG_RESOURCES
bool "Output verbose PCI MEM and IO resource debug messages" if DEFAULT_CONSOLE_LOGLEVEL_8
default n
help
This option enables additional PCI memory and IO debug messages.
Note: This option will increase the size of the coreboot image.
If unsure, say N.

config DEBUG_CONSOLE_INIT
bool "Debug console initialisation code"
default n
Expand Down Expand Up @@ -1114,6 +1123,16 @@ config TRACE
of calling function. Please note some printk related functions
are omitted from trace to have good looking console dumps.

config DEBUG_FUNC
bool "Enable function entry and exit reporting macros" if DEFAULT_CONSOLE_LOGLEVEL_8
default n
help
This option enables additional function entry and exit debug messages
for select functions. If supported, this is less output than
the TRACE option.
Note: This option will increase the size of the coreboot image.
If unsure, say N.

config DEBUG_COVERAGE
bool "Debug code coverage"
default n
Expand Down
3 changes: 3 additions & 0 deletions src/acpi/Makefile.inc
Expand Up @@ -3,6 +3,7 @@
ifeq ($(CONFIG_HAVE_ACPI_TABLES),y)

ramstage-y += acpi.c
ramstage-y += acpi_pm.c
ramstage-y += acpigen.c
ramstage-y += acpigen_dptf.c
ramstage-y += acpigen_dsm.c
Expand All @@ -15,6 +16,8 @@ ramstage-y += pld.c
ramstage-y += sata.c
ramstage-y += soundwire.c

postcar-y += acpi_pm.c

ifneq ($(wildcard src/mainboard/$(MAINBOARDDIR)/acpi_tables.c),)
ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/acpi_tables.c
endif
Expand Down
13 changes: 3 additions & 10 deletions src/acpi/acpi.c
Expand Up @@ -468,7 +468,7 @@ void acpi_create_ssdt_generator(acpi_header_t *ssdt, const char *oem_table_id)
{
struct device *dev;
for (dev = all_devices; dev; dev = dev->next)
if (dev->ops && dev->ops->acpi_fill_ssdt)
if (dev->enabled && dev->ops && dev->ops->acpi_fill_ssdt)
dev->ops->acpi_fill_ssdt(dev);
current = (unsigned long) acpigen_get_current();
}
Expand Down Expand Up @@ -1251,14 +1251,7 @@ void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
/* should be 0 ACPI 3.0 */
fadt->reserved = 0;

if (CONFIG(SYSTEM_TYPE_CONVERTIBLE) ||
CONFIG(SYSTEM_TYPE_LAPTOP))
fadt->preferred_pm_profile = PM_MOBILE;
else if (CONFIG(SYSTEM_TYPE_DETACHABLE) ||
CONFIG(SYSTEM_TYPE_TABLET))
fadt->preferred_pm_profile = PM_TABLET;
else
fadt->preferred_pm_profile = PM_DESKTOP;
fadt->preferred_pm_profile = acpi_get_preferred_pm_profile();

arch_fill_fadt(fadt);

Expand Down Expand Up @@ -1541,7 +1534,7 @@ void *acpi_find_wakeup_vector(void)
void *wake_vec;
int i;

if (!acpi_is_wakeup())
if (!acpi_is_wakeup_s3())
return NULL;

printk(BIOS_DEBUG, "Trying to find the wakeup vector...\n");
Expand Down
50 changes: 50 additions & 0 deletions src/acpi/acpi_pm.c
@@ -0,0 +1,50 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpi.h>
#include <console/console.h>
#include <romstage_handoff.h>
#include <smbios.h>

/* This is filled with acpi_handoff_wakeup_s3() call early in ramstage. */
static int acpi_slp_type = -1;

static void acpi_handoff_wakeup(void)
{
if (acpi_slp_type < 0) {
if (romstage_handoff_is_resume()) {
printk(BIOS_DEBUG, "S3 Resume\n");
acpi_slp_type = ACPI_S3;
} else {
printk(BIOS_DEBUG, "Normal boot\n");
acpi_slp_type = ACPI_S0;
}
}
}

int acpi_handoff_wakeup_s3(void)
{
acpi_handoff_wakeup();
return (acpi_slp_type == ACPI_S3);
}

void __weak mainboard_suspend_resume(void)
{
}

/* Default mapping to ACPI FADT preferred_pm_profile field. */
uint8_t acpi_get_preferred_pm_profile(void)
{
switch (smbios_mainboard_enclosure_type()) {
case SMBIOS_ENCLOSURE_LAPTOP:
case SMBIOS_ENCLOSURE_CONVERTIBLE:
return PM_MOBILE;
case SMBIOS_ENCLOSURE_DETACHABLE:
case SMBIOS_ENCLOSURE_TABLET:
return PM_TABLET;
case SMBIOS_ENCLOSURE_DESKTOP:
return PM_DESKTOP;
case SMBIOS_ENCLOSURE_UNKNOWN:
default:
return PM_UNSPECIFIED;
}
}
103 changes: 99 additions & 4 deletions src/acpi/acpigen.c
Expand Up @@ -10,6 +10,8 @@

#define ACPIGEN_MAXLEN 0xfffff

#define CPPC_PACKAGE_NAME "GCPC"

#include <lib.h>
#include <string.h>
#include <acpi/acpigen.h>
Expand Down Expand Up @@ -340,7 +342,7 @@ void acpigen_write_scope(const char *name)

void acpigen_get_package_op_element(uint8_t package_op, unsigned int element, uint8_t dest_op)
{
/* <dest_op> = DeRefOf (<package_op>[<element]) */
/* <dest_op> = DeRefOf (<package_op>[<element>]) */
acpigen_write_store();
acpigen_emit_byte(DEREF_OP);
acpigen_emit_byte(INDEX_OP);
Expand All @@ -350,6 +352,52 @@ void acpigen_get_package_op_element(uint8_t package_op, unsigned int element, ui
acpigen_emit_byte(dest_op);
}

void acpigen_set_package_op_element_int(uint8_t package_op, unsigned int element, uint64_t src)
{
/* DeRefOf (<package>[<element>]) = <src> */
acpigen_write_store();
acpigen_write_integer(src);
acpigen_emit_byte(DEREF_OP);
acpigen_emit_byte(INDEX_OP);
acpigen_emit_byte(package_op);
acpigen_write_integer(element);
acpigen_emit_byte(ZERO_OP); /* Ignore Index() Destination */
}

void acpigen_get_package_element(const char *package, unsigned int element, uint8_t dest_op)
{
/* <dest_op> = <package>[<element>] */
acpigen_write_store();
acpigen_emit_byte(INDEX_OP);
acpigen_emit_namestring(package);
acpigen_write_integer(element);
acpigen_emit_byte(ZERO_OP); /* Ignore Index() Destination */
acpigen_emit_byte(dest_op);
}

void acpigen_set_package_element_int(const char *package, unsigned int element, uint64_t src)
{
/* <package>[<element>] = <src> */
acpigen_write_store();
acpigen_write_integer(src);
acpigen_emit_byte(INDEX_OP);
acpigen_emit_namestring(package);
acpigen_write_integer(element);
acpigen_emit_byte(ZERO_OP); /* Ignore Index() Destination */
}

void acpigen_set_package_element_namestr(const char *package, unsigned int element,
const char *src)
{
/* <package>[<element>] = <src> */
acpigen_write_store();
acpigen_emit_namestring(src);
acpigen_emit_byte(INDEX_OP);
acpigen_emit_namestring(package);
acpigen_write_integer(element);
acpigen_emit_byte(ZERO_OP); /* Ignore Index() Destination */
}

void acpigen_write_processor(u8 cpuindex, u32 pblock_addr, u8 pblock_len)
{
/*
Expand Down Expand Up @@ -1318,6 +1366,14 @@ void acpigen_write_debug_op(uint8_t op)
acpigen_emit_ext_op(DEBUG_OP);
}

/* Store (str, DEBUG) */
void acpigen_write_debug_namestr(const char *str)
{
acpigen_write_store();
acpigen_emit_namestring(str);
acpigen_emit_ext_op(DEBUG_OP);
}

void acpigen_write_if(void)
{
acpigen_emit_byte(IF_OP);
Expand Down Expand Up @@ -1453,6 +1509,12 @@ void acpigen_write_return_integer(uint64_t arg)
acpigen_write_integer(arg);
}

void acpigen_write_return_namestr(const char *arg)
{
acpigen_emit_byte(RETURN_OP);
acpigen_emit_namestring(arg);
}

void acpigen_write_return_string(const char *arg)
{
acpigen_emit_byte(RETURN_OP);
Expand Down Expand Up @@ -1578,8 +1640,6 @@ void acpigen_write_dsm_uuid_arr(struct dsm_uuid *ids, size_t count)
acpigen_pop_len(); /* Method _DSM */
}

#define CPPC_PACKAGE_NAME "\\GCPC"

void acpigen_write_CPPC_package(const struct cppc_config *config)
{
u32 i;
Expand Down Expand Up @@ -1621,9 +1681,12 @@ void acpigen_write_CPPC_package(const struct cppc_config *config)

void acpigen_write_CPPC_method(void)
{
char pscope[16];
snprintf(pscope, sizeof(pscope), CONFIG_ACPI_CPU_STRING "." CPPC_PACKAGE_NAME, 0);

acpigen_write_method("_CPC", 0);
acpigen_emit_byte(RETURN_OP);
acpigen_emit_namestring(CPPC_PACKAGE_NAME);
acpigen_emit_namestring(pscope);
acpigen_pop_len();
}

Expand Down Expand Up @@ -2095,3 +2158,35 @@ void acpigen_write_xpss_object(const struct acpi_xpss_sw_pstate *pstate_values,

acpigen_pop_len();
}

/* Delay up to wait_ms until provided namestr matches expected value. */
void acpigen_write_delay_until_namestr_int(uint32_t wait_ms, const char *name, uint64_t value)
{
uint32_t wait_ms_segment = 1;
uint32_t segments = wait_ms;

/* Sleep in 16ms segments if delay is more than 32ms. */
if (wait_ms > 32) {
wait_ms_segment = 16;
segments = wait_ms / 16;
}

acpigen_write_store_int_to_op(segments, LOCAL7_OP);
acpigen_emit_byte(WHILE_OP);
acpigen_write_len_f();
acpigen_emit_byte(LGREATER_OP);
acpigen_emit_byte(LOCAL7_OP);
acpigen_emit_byte(ZERO_OP);

/* If name is not provided then just delay in a loop. */
if (name) {
acpigen_write_if_lequal_namestr_int(name, value);
acpigen_emit_byte(BREAK_OP);
acpigen_pop_len(); /* If */
}

acpigen_write_sleep(wait_ms_segment);
acpigen_emit_byte(DECREMENT_OP);
acpigen_emit_byte(LOCAL7_OP);
acpigen_pop_len(); /* While */
}
10 changes: 0 additions & 10 deletions src/arch/x86/Kconfig
Expand Up @@ -88,16 +88,6 @@ config AP_IN_SIPI_WAIT
default n
depends on ARCH_X86 && SMP

config X86_RESET_VECTOR
hex
depends on ARCH_X86
default 0xfffffff0
help
Specify the location of the x86 reset vector. In traditional devices
this must match the architectural reset vector to produce a bootable
image. Nontraditional designs may use this to position the reset
vector into its desired location.

config RESET_VECTOR_IN_RAM
bool
depends on ARCH_X86
Expand Down
2 changes: 0 additions & 2 deletions src/arch/x86/Makefile.inc
Expand Up @@ -158,7 +158,6 @@ endif # CONFIG_ARCH_VERSTAGE_X86_32 / CONFIG_ARCH_VERSTAGE_X86_64

ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32)$(CONFIG_ARCH_ROMSTAGE_X86_64),y)

romstage-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.c
romstage-y += boot.c
romstage-y += post.c
# gdt_init.S is included by entry32.inc when romstage is the first C
Expand Down Expand Up @@ -202,7 +201,6 @@ $(eval $(call create_class_compiler,postcar,x86_64))
endif
postcar-generic-ccopts += -D__POSTCAR__

postcar-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.c
postcar-y += boot.c
postcar-y += post.c
postcar-y += gdt_init.S
Expand Down
64 changes: 8 additions & 56 deletions src/arch/x86/acpi_s3.c
Expand Up @@ -8,45 +8,6 @@
#include <cpu/x86/smm.h>
#include <fallback.h>
#include <timestamp.h>
#include <romstage_handoff.h>

#if ENV_RAMSTAGE || ENV_POSTCAR

/* This is filled with acpi_is_wakeup() call early in ramstage. */
static int acpi_slp_type = -1;

static void acpi_handoff_wakeup(void)
{
if (acpi_slp_type < 0) {
if (romstage_handoff_is_resume()) {
printk(BIOS_DEBUG, "S3 Resume\n");
acpi_slp_type = ACPI_S3;
} else {
printk(BIOS_DEBUG, "Normal boot\n");
acpi_slp_type = ACPI_S0;
}
}
}

int acpi_is_wakeup(void)
{
acpi_handoff_wakeup();
/* Both resume from S2 and resume from S3 restart at CPU reset */
return (acpi_slp_type == ACPI_S3 || acpi_slp_type == ACPI_S2);
}

int acpi_is_wakeup_s3(void)
{
acpi_handoff_wakeup();
return (acpi_slp_type == ACPI_S3);
}

int acpi_is_wakeup_s4(void)
{
acpi_handoff_wakeup();
return (acpi_slp_type == ACPI_S4);
}
#endif /* ENV_RAMSTAGE */

#define WAKEUP_BASE 0x600

Expand All @@ -55,22 +16,6 @@ asmlinkage void (*acpi_do_wakeup)(uintptr_t vector) = (void *)WAKEUP_BASE;
extern unsigned char __wakeup;
extern unsigned int __wakeup_size;

static void acpi_jump_to_wakeup(void *vector)
{
/* Copy wakeup trampoline in place. */
memcpy((void *)WAKEUP_BASE, &__wakeup, __wakeup_size);

set_boot_successful();

timestamp_add_now(TS_ACPI_WAKE_JUMP);

acpi_do_wakeup((uintptr_t)vector);
}

void __weak mainboard_suspend_resume(void)
{
}

void __noreturn acpi_resume(void *wake_vec)
{
/* Restore GNVS pointer in SMM if found. */
Expand All @@ -79,8 +24,15 @@ void __noreturn acpi_resume(void *wake_vec)
/* Call mainboard resume handler first, if defined. */
mainboard_suspend_resume();

/* Copy wakeup trampoline in place. */
memcpy((void *)WAKEUP_BASE, &__wakeup, __wakeup_size);

set_boot_successful();

timestamp_add_now(TS_ACPI_WAKE_JUMP);

post_code(POST_OS_RESUME);
acpi_jump_to_wakeup(wake_vec);
acpi_do_wakeup((uintptr_t)wake_vec);

die("Failed the jump to wakeup vector\n");
}
19 changes: 9 additions & 10 deletions src/arch/x86/car.ld
Expand Up @@ -11,18 +11,17 @@
/* Page table pre-allocation. CONFIG_DCACHE_RAM_BASE should be 4KiB
* aligned when using this option. */
_pagetables = . ;
. += 4096 * CONFIG_NUM_CAR_PAGE_TABLE_PAGES;
. += 4096 * CONFIG_NUM_CAR_PAGE_TABLE_PAGES;
_epagetables = . ;
#endif
#if CONFIG(VBOOT_STARTS_IN_BOOTBLOCK)
/* Vboot work buffer only needs to be available when verified boot
* starts in bootblock. */
#if CONFIG(VBOOT_STARTS_IN_BOOTBLOCK)
VBOOT2_WORK(., 12K)
#endif
/* Vboot measured boot TCPA log measurements.
* Needs to be transferred until CBMEM is available
*/
#if CONFIG(TPM_MEASURED_BOOT)
/* Vboot measured boot TCPA log measurements.
* Needs to be transferred until CBMEM is available */
TPM_TCPA_LOG(., 2K)
#endif
/* Stack for CAR stages. Since it persists across all stages that
Expand All @@ -33,8 +32,8 @@
_ecar_stack = .;
/* The pre-ram cbmem console as well as the timestamp region are fixed
* in size. Therefore place them above the car global section so that
* multiple stages (romstage and verstage) have a consistent
* link address of these shared objects. */
* multiple stages (romstage and verstage) have a consistent
* link address of these shared objects. */
PRERAM_CBMEM_CONSOLE(., CONFIG_PRERAM_CBMEM_CONSOLE_SIZE)
#if CONFIG(PAGING_IN_CACHE_AS_RAM)
. = ALIGN(32);
Expand All @@ -55,8 +54,8 @@

_car_ehci_dbg_info = .;
/* Reserve sizeof(struct ehci_dbg_info). */
. += 80;
_ecar_ehci_dbg_info = .;
. += 80;
_ecar_ehci_dbg_info = .;

/* _bss and _ebss provide symbols to per-stage
* variables that are not shared like the timestamp and the pre-ram
Expand Down Expand Up @@ -110,7 +109,7 @@ _rom_mtrr_base = _rom_mtrr_mask;
. = 0xffffff00;
.illegal_globals . : {
*(EXCLUDE_FILE ("*/libagesa.*.a:" "*/romstage*/buildOpts.o" "*/romstage*/agesawrapper.o" "*/vendorcode/amd/agesa/*" "*/vendorcode/amd/cimx/*") .data)
*(EXCLUDE_FILE ("*/libagesa.*.a:" "*/romstage*/buildOpts.o" "*/romstage*/agesawrapper.o" "*/vendorcode/amd/agesa/*" "*/vendorcode/amd/cimx/*") .data.*)
*(EXCLUDE_FILE ("*/libagesa.*.a:" "*/romstage*/buildOpts.o" "*/romstage*/agesawrapper.o" "*/vendorcode/amd/agesa/*" "*/vendorcode/amd/cimx/*") .data.*)
}

_bogus = ASSERT((CONFIG_DCACHE_RAM_SIZE == 0) || (SIZEOF(.car.data) <= CONFIG_DCACHE_RAM_SIZE), "Cache as RAM area is too full");
Expand Down
2 changes: 1 addition & 1 deletion src/arch/x86/id.ld
@@ -1,7 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */

SECTIONS {
. = (CONFIG_X86_RESET_VECTOR - CONFIG_ID_SECTION_OFFSET) + 0x10 - (__id_end - __id_start);
. = (0xffffffff - CONFIG_ID_SECTION_OFFSET) - (__id_end - __id_start) + 1;
.id (.): {
KEEP(*(.id))
}
Expand Down
2 changes: 1 addition & 1 deletion src/arch/x86/memlayout.ld
Expand Up @@ -28,7 +28,7 @@ SECTIONS

#include "car.ld"
#elif ENV_BOOTBLOCK
BOOTBLOCK(CONFIG_X86_RESET_VECTOR - CONFIG_C_ENV_BOOTBLOCK_SIZE + 0x10,
BOOTBLOCK(0xffffffff - CONFIG_C_ENV_BOOTBLOCK_SIZE + 1,
CONFIG_C_ENV_BOOTBLOCK_SIZE)

#include "car.ld"
Expand Down
24 changes: 20 additions & 4 deletions src/arch/x86/smbios.c
Expand Up @@ -463,6 +463,12 @@ static int get_socket_type(void)
return 0x02; /* Unknown */
}

unsigned int __weak smbios_memory_error_correction_type(struct memory_info *meminfo)
{
return meminfo->ecc_capable ?
MEMORY_ARRAY_ECC_SINGLE_BIT : MEMORY_ARRAY_ECC_NONE;
}

unsigned int __weak smbios_processor_external_clock(void)
{
return 0; /* Unknown */
Expand Down Expand Up @@ -493,6 +499,12 @@ unsigned int __weak smbios_cache_conf_operation_mode(u8 level)
return SMBIOS_CACHE_OP_MODE_UNKNOWN; /* Unknown */
}

/* Returns the processor voltage in 100mV units */
unsigned int __weak smbios_cpu_get_voltage(void)
{
return 0; /* Unknown */
}

static size_t get_number_of_caches(struct cpuid_result res_deterministic_cache)
{
size_t max_logical_cpus_sharing_cache = 0;
Expand Down Expand Up @@ -595,6 +607,7 @@ static int smbios_write_type3(unsigned long *current, int handle)

static int smbios_write_type4(unsigned long *current, int handle)
{
unsigned int cpu_voltage;
struct cpuid_result res;
struct smbios_type4 *t = (struct smbios_type4 *)*current;
int len = sizeof(struct smbios_type4);
Expand Down Expand Up @@ -686,6 +699,9 @@ static int smbios_write_type4(unsigned long *current, int handle)
}
}
t->processor_characteristics = characteristics | smbios_processor_characteristics();
cpu_voltage = smbios_cpu_get_voltage();
if (cpu_voltage > 0)
t->voltage = 0x80 | cpu_voltage;

*current += len;
return len;
Expand Down Expand Up @@ -1025,8 +1041,7 @@ static int smbios_write_type16(unsigned long *current, int *handle)

t->location = MEMORY_ARRAY_LOCATION_SYSTEM_BOARD;
t->use = MEMORY_ARRAY_USE_SYSTEM;
t->memory_error_correction = meminfo->ecc_capable ?
MEMORY_ARRAY_ECC_SINGLE_BIT : MEMORY_ARRAY_ECC_NONE;
t->memory_error_correction = smbios_memory_error_correction_type(meminfo);

/* no error information handle available */
t->memory_error_information_handle = 0xFFFE;
Expand Down Expand Up @@ -1068,7 +1083,7 @@ static int smbios_write_type17(unsigned long *current, int *handle, int type16)
return totallen;
}

static int smbios_write_type19(unsigned long *current, int *handle)
static int smbios_write_type19(unsigned long *current, int *handle, int type16)
{
struct smbios_type19 *t = (struct smbios_type19 *)*current;
int len = sizeof(struct smbios_type19);
Expand All @@ -1084,6 +1099,7 @@ static int smbios_write_type19(unsigned long *current, int *handle)
t->type = SMBIOS_MEMORY_ARRAY_MAPPED_ADDRESS;
t->length = len - 2;
t->handle = *handle;
t->memory_array_handle = type16;

for (i = 0; i < meminfo->dimm_cnt && i < ARRAY_SIZE(meminfo->dimm); i++) {
if (meminfo->dimm[i].dimm_size > 0) {
Expand Down Expand Up @@ -1335,7 +1351,7 @@ unsigned long smbios_write_tables(unsigned long current)
const int type16 = handle;
update_max(len, max_struct_size, smbios_write_type16(&current, &handle));
update_max(len, max_struct_size, smbios_write_type17(&current, &handle, type16));
update_max(len, max_struct_size, smbios_write_type19(&current, &handle));
update_max(len, max_struct_size, smbios_write_type19(&current, &handle, type16));
update_max(len, max_struct_size, smbios_write_type32(&current, handle++));

update_max(len, max_struct_size, smbios_walk_device_tree(all_devices,
Expand Down
14 changes: 14 additions & 0 deletions src/commonlib/Makefile.inc
Expand Up @@ -30,6 +30,20 @@ ramstage-y += cbfs.c
smm-y += cbfs.c
postcar-y += cbfs.c

bootblock-y += bsd/cbfs_private.c
verstage-y += bsd/cbfs_private.c
romstage-y += bsd/cbfs_private.c
postcar-y += bsd/cbfs_private.c
ramstage-y += bsd/cbfs_private.c
smm-y += bsd/cbfs_private.c

bootblock-y += bsd/cbfs_mcache.c
verstage-y += bsd/cbfs_mcache.c
romstage-y += bsd/cbfs_mcache.c
postcar-y += bsd/cbfs_mcache.c
ramstage-y += bsd/cbfs_mcache.c
smm-y += bsd/cbfs_mcache.c

decompressor-y += bsd/lz4_wrapper.c
bootblock-y += bsd/lz4_wrapper.c
verstage-y += bsd/lz4_wrapper.c
Expand Down
143 changes: 143 additions & 0 deletions src/commonlib/bsd/cbfs_mcache.c
@@ -0,0 +1,143 @@
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later */

#include <assert.h>
#include <commonlib/bsd/cbfs_private.h>

/*
* A CBFS metadata cache is an in memory data structure storing CBFS file headers (= metadata).
* It is defined by its start pointer and size. It contains a sequence of variable-length
* union mcache_entry entries. There is no overall header structure for the cache.
*
* Each mcache_entry is the raw metadata for a CBFS file (including attributes) in the same form
* as stored on flash (i.e. values in big-endian), except that the CBFS magic signature in the
* first 8 bytes ('LARCHIVE') is overwritten with mcache-internal bookkeeping data. The first 4
* bytes are a magic number (MCACHE_MAGIC_FILE) and the next 4 bytes are the absolute offset in
* bytes on the cbfs_dev_t that this metadata blob was found at. (Note that depending on the
* implementation of cbfs_dev_t, this offset may still be relative to the start of a subregion
* of the underlying storage device.)
*
* The length of an mcache_entry (i.e. length of the underlying metadata blob) is encoded in the
* metadata (entry->file.h.offset). The next mcache_entry begins at the next
* CBFS_MCACHE_ALIGNMENT boundary after that. The cache is terminated by a special 4-byte
* mcache_entry that consists only of a magic number (MCACHE_MAGIC_END or MCACHE_MAGIC_FULL).
*/

#define MCACHE_MAGIC_FILE 0x454c4946 /* 'FILE' */
#define MCACHE_MAGIC_FULL 0x4c4c5546 /* 'FULL' */
#define MCACHE_MAGIC_END 0x444e4524 /* '$END' */

union mcache_entry {
union cbfs_mdata file;
struct { /* These fields exactly overlap file.h.magic */
uint32_t magic;
uint32_t offset;
};
};

struct cbfs_mcache_build_args {
void *mcache;
void *end;
int count;
};

static cb_err_t build_walker(cbfs_dev_t dev, size_t offset, const union cbfs_mdata *mdata,
size_t already_read, void *arg)
{
struct cbfs_mcache_build_args *args = arg;
union mcache_entry *entry = args->mcache;
const uint32_t data_offset = be32toh(mdata->h.offset);

if (args->end - args->mcache < data_offset)
return CB_CBFS_CACHE_FULL;

if (cbfs_copy_fill_metadata(args->mcache, mdata, already_read, dev, offset))
return CB_CBFS_IO;

entry->magic = MCACHE_MAGIC_FILE;
entry->offset = offset;

args->mcache += ALIGN_UP(data_offset, CBFS_MCACHE_ALIGNMENT);
args->count++;

return CB_CBFS_NOT_FOUND;
}

cb_err_t cbfs_mcache_build(cbfs_dev_t dev, void *mcache, size_t size,
struct vb2_hash *metadata_hash)
{
struct cbfs_mcache_build_args args = {
.mcache = mcache,
.end = mcache + ALIGN_DOWN(size, CBFS_MCACHE_ALIGNMENT)
- sizeof(uint32_t), /* leave space for terminating magic */
.count = 0,
};

assert(size > sizeof(uint32_t) && IS_ALIGNED((uintptr_t)mcache, CBFS_MCACHE_ALIGNMENT));
cb_err_t ret = cbfs_walk(dev, build_walker, &args, metadata_hash, 0);
union mcache_entry *entry = args.mcache;
if (ret == CB_CBFS_NOT_FOUND) {
ret = CB_SUCCESS;
entry->magic = MCACHE_MAGIC_END;
} else if (ret == CB_CBFS_CACHE_FULL) {
ERROR("mcache overflow, should increase CBFS_MCACHE size!\n");
entry->magic = MCACHE_MAGIC_FULL;
}

LOG("mcache @%p built for %d files, used %#zx of %#zx bytes\n", mcache,
args.count, args.mcache + sizeof(entry->magic) - mcache, size);
return ret;
}

cb_err_t cbfs_mcache_lookup(const void *mcache, size_t mcache_size, const char *name,
union cbfs_mdata *mdata_out, size_t *data_offset_out)
{
const size_t namesize = strlen(name) + 1; /* Count trailing \0 so we can memcmp() it. */
const void *end = mcache + mcache_size;
const void *current = mcache;

while (current + sizeof(uint32_t) < end) {
const union mcache_entry *entry = current;

if (entry->magic == MCACHE_MAGIC_END)
return CB_CBFS_NOT_FOUND;
if (entry->magic == MCACHE_MAGIC_FULL)
return CB_CBFS_CACHE_FULL;

assert(entry->magic == MCACHE_MAGIC_FILE);
const uint32_t data_offset = be32toh(entry->file.h.offset);
const uint32_t data_length = be32toh(entry->file.h.len);
if (namesize <= data_offset - offsetof(union cbfs_mdata, filename) &&
memcmp(name, entry->file.filename, namesize) == 0) {
LOG("Found '%s' @%#x size %#x in mcache @%p\n",
name, entry->offset, data_length, current);
*data_offset_out = entry->offset + data_offset;
memcpy(mdata_out, &entry->file, data_offset);
return CB_SUCCESS;
}

current += ALIGN_UP(data_offset, CBFS_MCACHE_ALIGNMENT);
}

ERROR("CBFS mcache overflow!\n");
return CB_ERR;
}

size_t cbfs_mcache_real_size(const void *mcache, size_t mcache_size)
{
const void *end = mcache + mcache_size;
const void *current = mcache;

while (current + sizeof(uint32_t) < end) {
const union mcache_entry *entry = current;

if (entry->magic == MCACHE_MAGIC_FULL || entry->magic == MCACHE_MAGIC_END) {
current += sizeof(entry->magic);
break;
}

assert(entry->magic == MCACHE_MAGIC_FILE);
current += ALIGN_UP(be32toh(entry->file.h.offset), CBFS_MCACHE_ALIGNMENT);
}

return current - mcache;
}
161 changes: 161 additions & 0 deletions src/commonlib/bsd/cbfs_private.c
@@ -0,0 +1,161 @@
/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later */

#include <commonlib/bsd/cbfs_private.h>
#include <assert.h>

static cb_err_t read_next_header(cbfs_dev_t dev, size_t *offset, struct cbfs_file *buffer)
{
const size_t devsize = cbfs_dev_size(dev);
DEBUG("Looking for next file @%#zx...\n", *offset);
*offset = ALIGN_UP(*offset, CBFS_ALIGNMENT);
while (*offset + sizeof(*buffer) < devsize) {
if (cbfs_dev_read(dev, buffer, *offset, sizeof(*buffer)) != sizeof(*buffer))
return CB_CBFS_IO;

if (memcmp(buffer->magic, CBFS_FILE_MAGIC, sizeof(buffer->magic)) == 0)
return CB_SUCCESS;

*offset += CBFS_ALIGNMENT;
}

DEBUG("End of CBFS reached\n");
return CB_CBFS_NOT_FOUND;
}

cb_err_t cbfs_walk(cbfs_dev_t dev, cb_err_t (*walker)(cbfs_dev_t dev, size_t offset,
const union cbfs_mdata *mdata,
size_t already_read, void *arg),
void *arg, struct vb2_hash *metadata_hash, enum cbfs_walk_flags flags)
{
const bool do_hash = CBFS_ENABLE_HASHING && metadata_hash;
struct vb2_digest_context dc;
vb2_error_t vbrv;

assert(CBFS_ENABLE_HASHING || (!metadata_hash && !(flags & CBFS_WALK_WRITEBACK_HASH)));
if (do_hash && (vbrv = vb2_digest_init(&dc, metadata_hash->algo))) {
ERROR("Metadata hash digest (%d) init error: %#x\n", metadata_hash->algo, vbrv);
return CB_ERR_ARG;
}

size_t offset = 0;
cb_err_t ret_header;
cb_err_t ret_walker = CB_CBFS_NOT_FOUND;
union cbfs_mdata mdata;
while ((ret_header = read_next_header(dev, &offset, &mdata.h)) == CB_SUCCESS) {
const uint32_t attr_offset = be32toh(mdata.h.attributes_offset);
const uint32_t data_offset = be32toh(mdata.h.offset);
const uint32_t data_length = be32toh(mdata.h.len);
const uint32_t type = be32toh(mdata.h.type);
const bool empty = (type == CBFS_TYPE_DELETED || type == CBFS_TYPE_DELETED2);

DEBUG("Found CBFS header @%#zx (type %d, attr +%#x, data +%#x, length %#x)\n",
offset, type, attr_offset, data_offset, data_length);
if (data_offset > sizeof(mdata)) {
ERROR("File metadata @%#zx too large\n", offset);
goto next_file;
}

if (empty && !(flags & CBFS_WALK_INCLUDE_EMPTY))
goto next_file;

/* When hashing we need to read everything. Otherwise skip the attributes.
attr_offset may be 0, which means there are no attributes. */
ssize_t todo;
if (do_hash || attr_offset == 0)
todo = data_offset - sizeof(mdata.h);
else
todo = attr_offset - sizeof(mdata.h);
if (todo <= 0 || data_offset < attr_offset) {
ERROR("Corrupt file header @%#zx\n", offset);
goto next_file;
}

/* Read the rest of the metadata (filename, and possibly attributes). */
assert(todo > 0 && todo <= sizeof(mdata) - sizeof(mdata.h));
if (cbfs_dev_read(dev, mdata.raw + sizeof(mdata.h),
offset + sizeof(mdata.h), todo) != todo)
return CB_CBFS_IO;
DEBUG("File name: '%s'\n", mdata.filename);

if (do_hash && !empty && vb2_digest_extend(&dc, mdata.raw, data_offset))
return CB_ERR;

if (walker && ret_walker == CB_CBFS_NOT_FOUND)
ret_walker = walker(dev, offset, &mdata, sizeof(mdata.h) + todo, arg);

/* Return IO errors immediately. For others, finish the hash first if needed. */
if (ret_walker == CB_CBFS_IO || (ret_walker != CB_CBFS_NOT_FOUND && !do_hash))
return ret_walker;

next_file:
offset += data_offset + data_length;
}

if (ret_header != CB_CBFS_NOT_FOUND)
return ret_header;

if (do_hash) {
uint8_t real_hash[VB2_MAX_DIGEST_SIZE];
size_t hash_size = vb2_digest_size(metadata_hash->algo);
if (vb2_digest_finalize(&dc, real_hash, hash_size))
return CB_ERR;
if (flags & CBFS_WALK_WRITEBACK_HASH)
memcpy(metadata_hash->raw, real_hash, hash_size);
else if (memcmp(metadata_hash->raw, real_hash, hash_size) != 0)
return CB_CBFS_HASH_MISMATCH;
}

return ret_walker;
}

cb_err_t cbfs_copy_fill_metadata(union cbfs_mdata *dst, const union cbfs_mdata *src,
size_t already_read, cbfs_dev_t dev, size_t offset)
{
/* First, copy the stuff that cbfs_walk() already read for us. */
memcpy(dst, src, already_read);

/* Then read in whatever metadata may be left (will only happen in non-hashing case). */
const size_t todo = be32toh(src->h.offset) - already_read;
assert(todo <= sizeof(*dst) - already_read);
if (todo && cbfs_dev_read(dev, dst->raw + already_read, offset + already_read,
todo) != todo)
return CB_CBFS_IO;
return CB_SUCCESS;
}

struct cbfs_lookup_args {
union cbfs_mdata *mdata_out;
const char *name;
size_t namesize;
size_t *data_offset_out;
};

static cb_err_t lookup_walker(cbfs_dev_t dev, size_t offset, const union cbfs_mdata *mdata,
size_t already_read, void *arg)
{
struct cbfs_lookup_args *args = arg;

/* Check if the name we're looking for could fit, then we can safely memcmp() it. */
if (args->namesize > already_read - offsetof(union cbfs_mdata, filename) ||
memcmp(args->name, mdata->filename, args->namesize) != 0)
return CB_CBFS_NOT_FOUND;

LOG("Found '%s' @%#zx size %#x\n", args->name, offset, be32toh(mdata->h.len));
if (cbfs_copy_fill_metadata(args->mdata_out, mdata, already_read, dev, offset))
return CB_CBFS_IO;

*args->data_offset_out = offset + be32toh(mdata->h.offset);
return CB_SUCCESS;
}

cb_err_t cbfs_lookup(cbfs_dev_t dev, const char *name, union cbfs_mdata *mdata_out,
size_t *data_offset_out, struct vb2_hash *metadata_hash)
{
struct cbfs_lookup_args args = {
.mdata_out = mdata_out,
.name = name,
.namesize = strlen(name) + 1, /* Count trailing \0 so we can memcmp() it. */
.data_offset_out = data_offset_out,
};
return cbfs_walk(dev, lookup_walker, &args, metadata_hash, 0);
}
6 changes: 6 additions & 0 deletions src/commonlib/bsd/include/commonlib/bsd/cb_err.h
Expand Up @@ -34,6 +34,12 @@ enum cb_err {
CB_I2C_PROTOCOL_ERROR = -302, /**< Data lost or spurious slave
device response, try again? */
CB_I2C_TIMEOUT = -303, /**< Transmission timed out */

/* CBFS errors */
CB_CBFS_IO = -400, /**< Underlying I/O error */
CB_CBFS_NOT_FOUND = -401, /**< File not found in directory */
CB_CBFS_HASH_MISMATCH = -402, /**< Master hash validation failed */
CB_CBFS_CACHE_FULL = -403, /**< Metadata cache overflowed */
};

/* Don't typedef the enum directly, so the size is unambiguous for serialization. */
Expand Down