183 changes: 96 additions & 87 deletions Documentation/infrastructure/builders.md
Expand Up @@ -8,8 +8,8 @@ Let a jenkins admin know that you’re interested in setting up a jenkins
build system.

For a permanent build system, this should generally be a dedicated
machine that is not generally being used for other purposes. The
coreboot builds are very intensive.
machine workstation or server class machine that is not generally being
used for other purposes. The coreboot builds are very intensive.

It's also best to be aware that although we don't know of any security
issues, the jenkins-node image is run with the privileged flag which
Expand All @@ -26,34 +26,40 @@ Currently active Jenkins admins:
* Patrick Georgi:
* Email: [patrick@georgi-clan.de](mailto:patrick@georgi-clan.de)
* IRC: pgeorgi

* Martin Roth:
* Email: [gaumless@gmail.com](mailto:gaumless@gmail.com)
* IRC: martinr

### Build Machine requirements

For a builder, we need a fast system with lots of threads and plenty of
RAM. The builder builds and stores the git repos and output in tmpfs
along with the ccache save area, so if there isn't enough memory, the
builds will slow down because of smaller ccache areas and can run into
"out of storage space" errors.
For a builder, we need a very fast system with lots of threads and
plenty of RAM. The builder builds and stores the git repos and output
in tmpfs along with the ccache save area, so if there isn't enough
memory, the builds will slow down because of smaller ccache areas and
can run into "out of storage space" errors.

#### Current Build Machines

To give an idea of what a suitable build machine might be, currently the
coreboot project has 3 active jenkins build machines.
coreboot project has 4 active jenkins build machines.

* Congenialbuilder - 128 threads, 256GiB RAM
* Fastest Passing coreboot gerrit build: 4 min, 30 sec
* Slowest Passing coreboot gerrit build: 9 min, 56 sec
These times are taken from the week of Feb 21 - Feb 28, 2022

* Congenialbuilder - 128 threads, 256GiB RAM
* Fastest Passing coreboot gerrit build: 6 min, 47 sec
* Slowest Passing coreboot gerrit build: 14 min

* Gleeful builder - 64 thread, 64GiB RAM
* Fastest Passing coreboot gerrit build: 6 min, 6 sec
* Slowest Passing coreboot gerrit build, 34 min
* Gleefulbuilder - 64 threads, 64GiB RAM
* Fastest Passing coreboot gerrit build: 10 min
* Slowest Passing coreboot gerrit build: 46 min

* Fabulousbuilder - 64 threads, 64GiB RAM
* Fastest Passing coreboot gerrit build: 7 min, 56 sec
* Slowest Passing coreboot gerrit build: 56 min (No ccache)

* Ultron (9elements) - 48 threads, 128GiB RAM
* Fastest Passing coreboot gerrit build: 6 min, 32 sec
* Slowest Passing coreboot gerrit build: 44 min
* Fastest Passing coreboot gerrit build: 12
* Slowest Passing coreboot gerrit build: 58 min


### Jenkins Builds
Expand All @@ -67,13 +73,13 @@ You can see all the builds here:
[https://qa.coreboot.org/](https://qa.coreboot.org/)

Most of the time on the builders is taken up by the coreboot master and
gerrit builds.
coreboot gerrit builds.

* [coreboot gerrit build](https://qa.coreboot.org/job/coreboot-gerrit/)
*[coreboot gerrit build](https://qa.coreboot.org/job/coreboot-gerrit/)
([Time trend](https://qa.coreboot.org/job/coreboot-gerrit/buildTimeTrend))


* [coreboot master build](https://qa.coreboot.org/job/coreboot/)
*[coreboot master build](https://qa.coreboot.org/job/coreboot/)
([Time trend](https://qa.coreboot.org/job/coreboot/buildTimeTrend))


Expand All @@ -85,8 +91,8 @@ hour.

On a system with 32 cores, it was tested with this command:

```
$ stress-ng --cpu 20 --io 6 --vm 6 --vm-bytes 1G --verify --metrics-brief -t 60m
```sh
stress-ng --cpu 20 --io 6 --vm 6 --vm-bytes 1G --verify --metrics-brief -t 60m
```

You can watch the temperature with the sensors package or with ‘acpi -t’
Expand All @@ -96,8 +102,8 @@ You can check for thermal throttling by running this command and seeing
if the values go down on any of the cores after it's been running for a
while.

```
$ while [ true ]; do clear; cat /proc/cpuinfo | grep 'cpu MHz' ; sleep 1; done
```sh
while [ true ]; do clear; cat /proc/cpuinfo | grep 'cpu MHz' ; sleep 1; done
```

If the machine throttles or resets, you probably need to upgrade the
Expand Down Expand Up @@ -127,10 +133,23 @@ the machine remotely (if you allow them).

### Install and set up docker

Install docker by following the
[directions](https://docs.docker.com/engine/install/) on the docker
site. These instructions keep changing, so just check the latest
information.
Install docker by following [the
directions](https://docs.docker.com/engine/install/) on the docker site.
These instructions keep changing, so just check the latest information.


### Set up the system for the jenkins builder

As a regular user - *Not root*, run:

```sh
sudo mkdir -p ${COREBOOT_JENKINS_CACHE_DIR}
sudo mkdir -p ${COREBOOT_JENKINS_CCACHE_DIR}
sudo chown $(whoami):$(whoami) ${COREBOOT_JENKINS_CCACHE_DIR}
sudo chown $(whoami):$(whoami) ${COREBOOT_JENKINS_CACHE_DIR}
wget http://www.dediprog.com/save/78.rar/to/EM100Pro.rar
mv EM100Pro.rar ${COREBOOT_JENKINS_CACHE_DIR}
```


#### Set up environment variables
Expand All @@ -139,12 +158,12 @@ To make configuration and the later commands easier, these should go in
your shell's .rc file. Note that you only need to set them if you're
using something other than the default.

```
```sh
# Set the port used on your machine to connect to jenkins.
export COREBOOT_JENKINS_PORT=49151

# Set the revision of the container from docker hub
export DOCKER_COMMIT=65718760fa
# Set the revision of the container from [docker hub](https://hub.docker.com/repository/docker/coreboot/coreboot-sdk)
export DOCKER_COMMIT=2021-09-23_b0d87f753c

# Set the location of where the jenkins cache directory will be.
export COREBOOT_JENKINS_CACHE_DIR="/srv/docker/coreboot-builder/cache"
Expand All @@ -161,13 +180,13 @@ continuing to the next step.

From the coreboot directory, run

```
```sh
make -C util/docker help
```

This will show you the available targets and variables needed:

```
```text
Commands for working with docker images:
coreboot-sdk - Build coreboot-sdk container
upload-coreboot-sdk - Upload coreboot-sdk to hub.docker.com
Expand Down Expand Up @@ -199,22 +218,10 @@ Variables:
DOCKER_COMMIT=65718760fa
```

### Set up the system for the jenkins builder

As a regular user - *Not root*, run:

```
sudo mkdir -p ${COREBOOT_JENKINS_CACHE_DIR}
sudo mkdir -p ${COREBOOT_JENKINS_CCACHE_DIR}
sudo chown $(whoami):$(whoami) ${COREBOOT_JENKINS_CCACHE_DIR}
sudo chown $(whoami):$(whoami) ${COREBOOT_JENKINS_CACHE_DIR}
wget http://www.dediprog.com/save/78.rar/to/EM100Pro.rar
mv EM100Pro.rar ${COREBOOT_JENKINS_CACHE_DIR}
```

### Install the coreboot jenkins builder

```
```sh
make -C util/docker docker-jenkins-server
```

Expand All @@ -226,17 +233,17 @@ machine profile on qa.coreboot.org.

They need to know:
* Your external IP address or domain name. If you don’t have a static
IP, make sure you have a dynamic dns hostname configured.
IP, make sure you have a dynamic dns hostname configured.
* The port on your machine and firewall that’s exposed for jenkins:
`$COREBOOT_JENKINS_PORT`
`$COREBOOT_JENKINS_PORT`
* The core count of the machine.
* How much memory is available on the machine. This helps determine
the amount of memory used for ccache.
the amount of memory used for ccache.


### First build
On the first build after a machine is reset, it will frequently take
20-25 minutes to do the entire what-jenkins-does build while the ccache
an hour to do the entire what-jenkins-does build while the ccache
is getting filled up and the entire coreboot repo gets downloaded. As
the ccache gets populated, the build time will drop.

Expand All @@ -245,39 +252,40 @@ the ccache gets populated, the build time will drop.


### How to log in to the docker instance for debugging
```
$ make -C util/docker docker-jenkins-attach
$ su coreboot
$ cd ~/slave-root/workspace
$ bash

```sh
make -C util/docker docker-jenkins-attach
su coreboot
cd ~/slave-root/workspace
bash
```


WARNING: This should not be used to make changes to the build system,
but just to debug issues. Changes to the build system are highly
but just to debug issues. Changes to the build system image are highly
discouraged as it leads to situations where patches can pass the build
testing on one builder and fail on another builder. Any changes that are
made in the image will be lost on the next update, so if you
accidentally change something, you can remove the containers and images
and update to get a fresh installation.
accidentally change something, you can remove the containers and images,
then update to get a fresh installation.


### How to download containers/images for a fresh installation and remove old containers

To delete the old containers & images:

```
$ docker stop $COREBOOT_JENKINS_CONTAINER
$ docker rm $COREBOOT_JENKINS_CONTAINER
$ docker images # lists all existing images
$ docker rmi XXXX # Use the image ID found in the above command.
```sh
docker stop $COREBOOT_JENKINS_CONTAINER
docker rm $COREBOOT_JENKINS_CONTAINER
docker images # lists all existing images
docker rmi XXXX # Use the image ID found in the above command.
```

To get and run the new coreboot-jenkins image, change the value in the
`DOCKER_COMMIT` variable to the new image value.

```
$ make -C util/docker docker-jenkins-server
```sh
make -C util/docker docker-jenkins-server
```

#### Getting ready to push the docker images
Expand All @@ -291,15 +299,15 @@ Get an admin to add the account to the coreboot team on hub.docker.com
Make sure your credentials are configured on your host machine by
running

```
$ docker login
```sh
docker login
```

This will prompt you for your docker username, password, and your email
address, and write out to ~/.docker/config.json. Without this file, you
won’t be able to push the images.

#### Updating the Dockerfiles:
#### Updating the Dockerfiles

The coreboot-sdk Dockerfile will need to be updated when any additional
dependencies are added. Both the coreboot-sdk and the
Expand All @@ -310,60 +318,60 @@ files are stored in the coreboot repo under coreboot/util/docker.
Read the [dockerfile best practices](https://docs.docker.com/v1.8/articles/dockerfile_best-practices/)
page before updating the files.

#### Rebuilding the coreboot-sdk docker image to update the toolchain:
#### Rebuilding the coreboot-sdk docker image to update the toolchain

```
$ make -C util/docker coreboot-sdk
```sh
make -C util/docker coreboot-sdk
```

This takes a relatively long time.

#### Test the coreboot-sdk docker image:
#### Test the coreboot-sdk docker image

There are two methods of running the docker image - interactively as a
shell, or doing the build directly. Running interactively as a shell is
useful for early testing, because it allows you to update the image
(without any changes getting saved) and re-test builds. This saves the
time of having to rebuild the image for every issue you find.

#### Running the docker image interactively:
#### Running the docker image interactively

Run:

```
$ make -C util/docker docker-jenkins-server
$ make -C util/docker docker-jenkins-attach
```sh
make -C util/docker docker-jenkins-server
make -C util/docker docker-jenkins-attach
```

#### Running the build directly:
#### Running the build directly

From the coreboot directory:

```
$ make -C util/docker docker-build-coreboot
```sh
make -C util/docker docker-build-coreboot
```

You’ll also want to test building the other projects and payloads:
ChromeEC, flashrom, memtest86+, em100, Grub2, SeaBIOS, iPXE, coreinfo,
nvramcui, tint...

#### Pushing the coreboot-sdk image to hub.docker.com for use:
#### Pushing the coreboot-sdk image to hub.docker.com for use

When you’re satisfied with the testing, push the coreboot-sdk image to
the hub.docker.com

```
$ make -C util/docker upload-coreboot-sdk
```sh
make -C util/docker upload-coreboot-sdk
```

#### Building and pushing the coreboot-jenkins-node docker image:
#### Building and pushing the coreboot-jenkins-node docker image

This docker image is pretty simple, so there’s not really any testing
that needs to be done.

```
$ make -C util/docker coreboot-jenkins-node
$ make -C util/docker upload-coreboot-jenkins-node
```sh
make -C util/docker coreboot-jenkins-node
make -C util/docker upload-coreboot-jenkins-node
```

### Coverity Setup
Expand All @@ -376,14 +384,15 @@ to be marked as a coverity builder.

Download the Linux-64 coverity build tool and decompress it into your
cache directory as defined by the `$COREBOOT_JENKINS_CACHE_DIR` variable
on the jenkins server.

[https://scan.coverity.com/download](https://scan.coverity.com/download)

Rename the directory from its original name
(cov-analysis-linux64-7.7.0.4) to ‘coverity’, or better, create a
symlink:

```
```sh
ln -s cov-analysis-linux64-7.7.0.4 coverity
```

Expand Down
9 changes: 7 additions & 2 deletions Documentation/infrastructure/index.md
@@ -1,6 +1,11 @@
# coreboot infrastructure
# Project infrastructure & services

This section contains documentation about our infrastructure

## Services

* [Project services](services.md)

This section contains documentation about coreboot infrastructure

## Jenkins builders and builds
* [Setting up Jenkins build machines](builders.md)
Expand Down
File renamed without changes.
326 changes: 326 additions & 0 deletions Documentation/releases/boards_supported_on_branches.md

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions Documentation/security/vboot/list_vboot.md
Expand Up @@ -73,8 +73,6 @@
- Ultima (Lenovo Yoga 11e G3)
- Wizpig
- Daisy (Samsung Chromebook (2012))
- Deltan
- Deltaur
- Drallion
- Eve (Google Pixelbook)
- Fizz
Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS
Expand Up @@ -450,6 +450,7 @@ SIEMENS MC_xxxx MAINBOARDS
M: Werner Zeh <werner.zeh@siemens.com>
S: Maintained
F: src/mainboard/siemens/mc_apl1/
F: src/mainboard/siemens/mc_ehl/



Expand Down
37 changes: 9 additions & 28 deletions Makefile.inc
Expand Up @@ -270,7 +270,7 @@ EMPTY_RESOURCE_TEMPLATE_WARNING = 3150
# For existing ASL code, ignore this warnings
IASL_MISSING_DEPENDENCY = 3141

IASL_WARNINGS_LIST = $(EMPTY_RESOURCE_TEMPLATE_WARNING) $(REDUNDANT_OFFSET_REMARK)
IASL_WARNINGS_LIST = $(EMPTY_RESOURCE_TEMPLATE_WARNING)

ifeq ($(CONFIG_IGNORE_IASL_MISSING_DEPENDENCY),y)
IASL_WARNINGS_LIST += $(IASL_MISSING_DEPENDENCY)
Expand Down Expand Up @@ -337,7 +337,7 @@ endef
# arg1: C source file
# arg2: binary file
cbfs-files-processor-struct= \
$(eval $(2): $(1) $(obj)/build.h $(KCONFIG_AUTOHEADER); \
$(eval $(2): $(1) $(obj)/build.h $(obj)/fmap_config.h $(KCONFIG_AUTOHEADER); \
printf " CC+STRIP $(1)\n"; \
$(CC_ramstage) -MMD $(CPPFLAGS_ramstage) $(CFLAGS_ramstage) --param asan-globals=0 $$(ramstage-c-ccopts) -include $(KCONFIG_AUTOHEADER) -MT $(2) -o $(2).tmp -c $(1) && \
$(OBJCOPY_ramstage) -O binary --set-section-flags .bss*=alloc,contents,load $(2).tmp $(2); \
Expand Down Expand Up @@ -1105,33 +1105,8 @@ endif
$(shell rm -f $(obj)/coreboot.pre)

ifneq ($(CONFIG_UPDATE_IMAGE),y)
$(obj)/coreboot.pre: $(objcbfs)/bootblock.bin $$(prebuilt-files) $(CBFSTOOL) $(obj)/fmap.fmap $(obj)/fmap.desc
$(obj)/coreboot.pre: $$(prebuilt-files) $(CBFSTOOL) $(obj)/fmap.fmap $(obj)/fmap.desc
$(CBFSTOOL) $@.tmp create -M $(obj)/fmap.fmap -r $(shell cat $(obj)/fmap.desc)
ifeq ($(CONFIG_ARCH_X86),y)
$(CBFSTOOL) $@.tmp add \
-f $(objcbfs)/bootblock.bin \
-n bootblock \
-t bootblock \
$(TXTIBB) \
-b -$(call file-size,$(objcbfs)/bootblock.bin) $(cbfs-autogen-attributes) \
$(TS_OPTIONS) \
$(CBFSTOOL_ADD_CMD_OPTIONS)
else # ifeq ($(CONFIG_ARCH_X86),y)
$(CBFSTOOL) $@.tmp write -u \
-r BOOTBLOCK \
-f $(objcbfs)/bootblock.bin
# make space for the CBFS master header pointer. "ptr_" is just
# arbitrary 4 bytes that will be overwritten by add-master-header.
printf "ptr_" > $@.tmp.2
$(CBFSTOOL) $@.tmp add \
-f $@.tmp.2 \
-n "header pointer" \
-t "cbfs header" \
-b -4 \
$(CBFSTOOL_ADD_CMD_OPTIONS)
rm -f $@.tmp.2
endif # ifeq ($(CONFIG_ARCH_X86),y)
$(CBFSTOOL) $@.tmp add-master-header $(TS_OPTIONS) $(CBFSTOOL_ADD_CMD_OPTIONS)
$(prebuild-files) true
mv $@.tmp $@
else # ifneq ($(CONFIG_UPDATE_IMAGE),y)
Expand Down Expand Up @@ -1161,6 +1136,12 @@ add_intermediate = \
$(1): $(obj)/coreboot.pre $(2) | $(INTERMEDIATE) \
$(eval INTERMEDIATE+=$(1)) $(eval PHONY+=$(1))

ifneq ($(CONFIG_ARCH_X86),y)
$(call add_intermediate, add_bootblock, $(objcbfs)/bootblock.bin)
printf " FMAP writing BOOTBLOCK region\n"
$(CBFSTOOL) $< write -u -r BOOTBLOCK -f $(objcbfs)/bootblock.bin
endif

$(obj)/coreboot.rom: $(obj)/coreboot.pre $(CBFSTOOL) $(IFITTOOL) $$(INTERMEDIATE)
@printf " CBFS $(subst $(obj)/,,$(@))\n"
# The full ROM may be larger than the CBFS part, so create an empty
Expand Down
1 change: 1 addition & 0 deletions configs/config.lenovo_t400_vboot_and_debug
Expand Up @@ -12,3 +12,4 @@ CONFIG_DEBUG_BOOT_STATE=y
CONFIG_DEBUG_ADA_CODE=y
CONFIG_H8_FN_KEY_AS_VBOOT_RECOVERY_SW=y
CONFIG_VBOOT=y
CONFIG_USE_EXP_X86_64_SUPPORT=y
10 changes: 5 additions & 5 deletions configs/config.pcengines_apu1
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.16.0.3"
CONFIG_LOCALVERSION="v4.16.0.4"
CONFIG_VENDOR_PCENGINES=y
CONFIG_CBFS_SIZE=0x00200000
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
Expand All @@ -10,9 +10,11 @@ CONFIG_SUBSYSTEM_VENDOR_ID=0x0000
CONFIG_SUBSYSTEM_DEVICE_ID=0x0000
CONFIG_TPM2=y
CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1=y
CONFIG_CONSOLE_USE_ANSI_ESCAPES=n
CONFIG_CONSOLE_USE_LOGLEVEL_PREFIX=n
CONFIG_POST_IO_PORT=0x80
CONFIG_SEABIOS_REVISION=y
CONFIG_SEABIOS_REVISION_ID="rel-1.14.0.1"
CONFIG_SEABIOS_REVISION_ID="rel-1.16.0.1"
CONFIG_SEABIOS_BOOTORDER_FILE="$(top)/src/mainboard/$(MAINBOARDDIR)/bootorder"
CONFIG_SEABIOS_DEBUG_LEVEL=0
CONFIG_SEABIOS_SERCON_PORT_ADDR=0x3f8
Expand All @@ -27,6 +29,4 @@ CONFIG_SORTBOOTORDER_SECONDARY_PAYLOAD=y
CONFIG_MEMTEST_REVISION=y
CONFIG_MEMTEST_REVISION_ID="0b756257276729c1a12bc1d95e7a1f044894bda2"
CONFIG_SORTBOOTORDER_REVISION=y
CONFIG_SORTBOOTORDER_REVISION_ID="v4.6.22"
CONFIG_CONSOLE_USE_ANSI_ESCAPES=n
CONFIG_CONSOLE_USE_LOGLEVEL_PREFIX=n
CONFIG_SORTBOOTORDER_REVISION_ID="v4.6.23"
10 changes: 5 additions & 5 deletions configs/config.pcengines_apu2
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.16.0.3"
CONFIG_LOCALVERSION="v4.16.0.4"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_PXE_ROM_ID="8086,157b"
Expand All @@ -13,9 +13,11 @@ CONFIG_SUBSYSTEM_VENDOR_ID=0x0000
CONFIG_SUBSYSTEM_DEVICE_ID=0x0000
CONFIG_TPM2=y
CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1=y
CONFIG_CONSOLE_USE_ANSI_ESCAPES=n
CONFIG_CONSOLE_USE_LOGLEVEL_PREFIX=n
CONFIG_POST_IO_PORT=0x80
CONFIG_SEABIOS_REVISION=y
CONFIG_SEABIOS_REVISION_ID="rel-1.14.0.1"
CONFIG_SEABIOS_REVISION_ID="rel-1.16.0.1"
CONFIG_SEABIOS_BOOTORDER_IN_FMAP=y
CONFIG_SEABIOS_BOOTORDER_FILE="$(top)/src/mainboard/$(MAINBOARDDIR)/variants/$(CONFIG_VARIANT_DIR)/bootorder"
CONFIG_SEABIOS_DEBUG_LEVEL=0
Expand All @@ -31,6 +33,4 @@ CONFIG_SORTBOOTORDER_SECONDARY_PAYLOAD=y
CONFIG_MEMTEST_REVISION=y
CONFIG_MEMTEST_REVISION_ID="0b756257276729c1a12bc1d95e7a1f044894bda2"
CONFIG_SORTBOOTORDER_REVISION=y
CONFIG_SORTBOOTORDER_REVISION_ID="v4.6.22"
CONFIG_CONSOLE_USE_ANSI_ESCAPES=n
CONFIG_CONSOLE_USE_LOGLEVEL_PREFIX=n
CONFIG_SORTBOOTORDER_REVISION_ID="v4.6.23"
10 changes: 5 additions & 5 deletions configs/config.pcengines_apu3
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.16.0.3"
CONFIG_LOCALVERSION="v4.16.0.4"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_PXE_ROM_ID="8086,1539"
Expand All @@ -13,9 +13,11 @@ CONFIG_SUBSYSTEM_VENDOR_ID=0x0000
CONFIG_SUBSYSTEM_DEVICE_ID=0x0000
CONFIG_TPM2=y
CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1=y
CONFIG_CONSOLE_USE_ANSI_ESCAPES=n
CONFIG_CONSOLE_USE_LOGLEVEL_PREFIX=n
CONFIG_POST_IO_PORT=0x80
CONFIG_SEABIOS_REVISION=y
CONFIG_SEABIOS_REVISION_ID="rel-1.14.0.1"
CONFIG_SEABIOS_REVISION_ID="rel-1.16.0.1"
CONFIG_SEABIOS_BOOTORDER_IN_FMAP=y
CONFIG_SEABIOS_BOOTORDER_FILE="$(top)/src/mainboard/$(MAINBOARDDIR)/variants/$(CONFIG_VARIANT_DIR)/bootorder"
CONFIG_SEABIOS_DEBUG_LEVEL=0
Expand All @@ -31,6 +33,4 @@ CONFIG_SORTBOOTORDER_SECONDARY_PAYLOAD=y
CONFIG_MEMTEST_REVISION=y
CONFIG_MEMTEST_REVISION_ID="0b756257276729c1a12bc1d95e7a1f044894bda2"
CONFIG_SORTBOOTORDER_REVISION=y
CONFIG_SORTBOOTORDER_REVISION_ID="v4.6.22"
CONFIG_CONSOLE_USE_ANSI_ESCAPES=n
CONFIG_CONSOLE_USE_LOGLEVEL_PREFIX=n
CONFIG_SORTBOOTORDER_REVISION_ID="v4.6.23"
10 changes: 5 additions & 5 deletions configs/config.pcengines_apu4
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.16.0.3"
CONFIG_LOCALVERSION="v4.16.0.4"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_PXE_ROM_ID="8086,1539"
Expand All @@ -13,9 +13,11 @@ CONFIG_SUBSYSTEM_VENDOR_ID=0x0000
CONFIG_SUBSYSTEM_DEVICE_ID=0x0000
CONFIG_TPM2=y
CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1=y
CONFIG_CONSOLE_USE_ANSI_ESCAPES=n
CONFIG_CONSOLE_USE_LOGLEVEL_PREFIX=n
CONFIG_POST_IO_PORT=0x80
CONFIG_SEABIOS_REVISION=y
CONFIG_SEABIOS_REVISION_ID="rel-1.14.0.1"
CONFIG_SEABIOS_REVISION_ID="rel-1.16.0.1"
CONFIG_SEABIOS_BOOTORDER_IN_FMAP=y
CONFIG_SEABIOS_BOOTORDER_FILE="$(top)/src/mainboard/$(MAINBOARDDIR)/variants/$(CONFIG_VARIANT_DIR)/bootorder"
CONFIG_SEABIOS_DEBUG_LEVEL=0
Expand All @@ -31,6 +33,4 @@ CONFIG_SORTBOOTORDER_SECONDARY_PAYLOAD=y
CONFIG_MEMTEST_REVISION=y
CONFIG_MEMTEST_REVISION_ID="0b756257276729c1a12bc1d95e7a1f044894bda2"
CONFIG_SORTBOOTORDER_REVISION=y
CONFIG_SORTBOOTORDER_REVISION_ID="v4.6.22"
CONFIG_CONSOLE_USE_ANSI_ESCAPES=n
CONFIG_CONSOLE_USE_LOGLEVEL_PREFIX=n
CONFIG_SORTBOOTORDER_REVISION_ID="v4.6.23"
10 changes: 5 additions & 5 deletions configs/config.pcengines_apu5
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.16.0.3"
CONFIG_LOCALVERSION="v4.16.0.4"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_PXE_ROM_ID="8086,1539"
Expand All @@ -13,9 +13,11 @@ CONFIG_SUBSYSTEM_VENDOR_ID=0x0000
CONFIG_SUBSYSTEM_DEVICE_ID=0x0000
CONFIG_TPM2=y
CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1=y
CONFIG_CONSOLE_USE_ANSI_ESCAPES=n
CONFIG_CONSOLE_USE_LOGLEVEL_PREFIX=n
CONFIG_POST_IO_PORT=0x80
CONFIG_SEABIOS_REVISION=y
CONFIG_SEABIOS_REVISION_ID="rel-1.14.0.1"
CONFIG_SEABIOS_REVISION_ID="rel-1.16.0.1"
CONFIG_SEABIOS_BOOTORDER_IN_FMAP=y
CONFIG_SEABIOS_BOOTORDER_FILE="$(top)/src/mainboard/$(MAINBOARDDIR)/variants/$(CONFIG_VARIANT_DIR)/bootorder"
CONFIG_SEABIOS_DEBUG_LEVEL=0
Expand All @@ -31,6 +33,4 @@ CONFIG_SORTBOOTORDER_SECONDARY_PAYLOAD=y
CONFIG_MEMTEST_REVISION=y
CONFIG_MEMTEST_REVISION_ID="0b756257276729c1a12bc1d95e7a1f044894bda2"
CONFIG_SORTBOOTORDER_REVISION=y
CONFIG_SORTBOOTORDER_REVISION_ID="v4.6.22"
CONFIG_CONSOLE_USE_ANSI_ESCAPES=n
CONFIG_CONSOLE_USE_LOGLEVEL_PREFIX=n
CONFIG_SORTBOOTORDER_REVISION_ID="v4.6.23"
10 changes: 5 additions & 5 deletions configs/config.pcengines_apu6
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.16.0.3"
CONFIG_LOCALVERSION="v4.16.0.4"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_PXE_ROM_ID="8086,1539"
Expand All @@ -13,9 +13,11 @@ CONFIG_SUBSYSTEM_VENDOR_ID=0x0000
CONFIG_SUBSYSTEM_DEVICE_ID=0x0000
CONFIG_TPM2=y
CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1=y
CONFIG_CONSOLE_USE_ANSI_ESCAPES=n
CONFIG_CONSOLE_USE_LOGLEVEL_PREFIX=n
CONFIG_POST_IO_PORT=0x80
CONFIG_SEABIOS_REVISION=y
CONFIG_SEABIOS_REVISION_ID="rel-1.14.0.1"
CONFIG_SEABIOS_REVISION_ID="rel-1.16.0.1"
CONFIG_SEABIOS_BOOTORDER_IN_FMAP=y
CONFIG_SEABIOS_BOOTORDER_FILE="$(top)/src/mainboard/$(MAINBOARDDIR)/variants/$(CONFIG_VARIANT_DIR)/bootorder"
CONFIG_SEABIOS_DEBUG_LEVEL=0
Expand All @@ -31,6 +33,4 @@ CONFIG_SORTBOOTORDER_SECONDARY_PAYLOAD=y
CONFIG_MEMTEST_REVISION=y
CONFIG_MEMTEST_REVISION_ID="0b756257276729c1a12bc1d95e7a1f044894bda2"
CONFIG_SORTBOOTORDER_REVISION=y
CONFIG_SORTBOOTORDER_REVISION_ID="v4.6.22"
CONFIG_CONSOLE_USE_ANSI_ESCAPES=n
CONFIG_CONSOLE_USE_LOGLEVEL_PREFIX=n
CONFIG_SORTBOOTORDER_REVISION_ID="v4.6.23"
1 change: 0 additions & 1 deletion payloads/coreinfo/coreboot_module.c
Expand Up @@ -186,7 +186,6 @@ static int parse_header(void *addr, int len)
switch (rec->tag) {
case CB_TAG_FORWARD:
return parse_header((void *)(unsigned long)((struct cb_forward *)rec)->forward, 1);
break;
case CB_TAG_MEMORY:
parse_memory(ptr);
break;
Expand Down
29 changes: 15 additions & 14 deletions payloads/libpayload/drivers/storage/nvme.c
Expand Up @@ -147,7 +147,7 @@ static void nvme_detach_device(struct storage_dev *dev)
if (delete_admin_queues(nvme))
printf("NVME ERROR: Failed to delete admin queues\n");

write32(nvme->config + 0x1c, 0);
write32(nvme->config + 0x14, 0);

int status, timeout = (read64(nvme->config) >> 24 & 0xff) * 500;
do {
Expand Down Expand Up @@ -321,7 +321,7 @@ static void nvme_init(pcidev_t dev)

void *pci_bar0 = phys_to_virt(pci_read_config32(dev, 0x10) & ~0x3ff);

if (!(((read64(pci_bar0) >> 37) & 0xff) == 0x01)) {
if (!(read64(pci_bar0) >> 37 & 0x01)) {
printf("NVMe ERROR: PCIe device does not support the NVMe command set\n");
return;
}
Expand All @@ -341,60 +341,61 @@ static void nvme_init(pcidev_t dev)

if (!nvme->prp_list) {
printf("NVMe ERROR: Failed to allocate buffer for PRP list\n");
goto abort;
goto _free_abort;
}

const uint32_t cc = NVME_CC_EN | NVME_CC_CSS | NVME_CC_MPS | NVME_CC_AMS | NVME_CC_SHN
| NVME_CC_IOSQES | NVME_CC_IOCQES;

write32(nvme->config + 0x1c, 0);
write32(nvme->config + 0x14, 0);

int status, timeout = (read64(nvme->config) >> 24 & 0xff) * 500;
do {
status = read32(nvme->config + 0x1c) & 0x3;
if (status == 0x2) {
printf("NVMe ERROR: Failed to disable controller. FATAL ERROR\n");
goto abort;
goto _free_abort;
}
if (timeout < 0) {
printf("NVMe ERROR: Failed to disable controller. Timeout.\n");
goto abort;
goto _free_abort;
}
timeout -= 10;
mdelay(10);
} while (status != 0x0);
if (create_admin_queues(nvme))
goto abort;
goto _free_abort;
write32(nvme->config + 0x14, cc);

timeout = (read64(nvme->config) >> 24 & 0xff) * 500;
do {
status = read32(nvme->config + 0x1c) & 0x3;
if (status == 0x2)
goto abort;
goto _delete_admin_abort;
if (timeout < 0)
goto abort;
goto _delete_admin_abort;
timeout -= 10;
mdelay(10);
} while (status != 0x1);

uint16_t command = pci_read_config16(dev, PCI_COMMAND);
pci_write_config16(dev, PCI_COMMAND, command | PCI_COMMAND_MASTER);
if (create_io_completion_queue(nvme))
goto abort;
goto _delete_admin_abort;
if (create_io_submission_queue(nvme))
goto abort;
goto _delete_completion_abort;
storage_attach_device((storage_dev_t *)nvme);
printf("NVMe init done.\n");
return;

abort:
printf("NVMe init failed.\n");
delete_io_submission_queue(nvme);
_delete_completion_abort:
delete_io_completion_queue(nvme);
_delete_admin_abort:
delete_admin_queues(nvme);
_free_abort:
free(nvme->prp_list);
free(nvme);
printf("NVMe init failed.\n");
}

void nvme_initialize(struct pci_dev *dev)
Expand Down
2 changes: 1 addition & 1 deletion payloads/libpayload/include/arm/arch/barrier.h
Expand Up @@ -33,7 +33,7 @@
*
*/

#ifndef __ARCH_BARRIER_H_
#ifndef __ARCH_BARRIER_H__
#define __ARCH_BARRIER_H__

#include <arch/cache.h>
Expand Down
2 changes: 1 addition & 1 deletion payloads/libpayload/include/arm64/arch/barrier.h
Expand Up @@ -33,7 +33,7 @@
*
*/

#ifndef __ARCH_BARRIER_H_
#ifndef __ARCH_BARRIER_H__
#define __ARCH_BARRIER_H__

#include <arch/cache.h>
Expand Down
2 changes: 1 addition & 1 deletion payloads/libpayload/include/x86/arch/barrier.h
Expand Up @@ -27,7 +27,7 @@
*
*/

#ifndef __ARCH_BARRIER_H_
#ifndef __ARCH_BARRIER_H__
#define __ARCH_BARRIER_H__

#define mb()
Expand Down
35 changes: 12 additions & 23 deletions payloads/nvramcui/nvramcui.c
Expand Up @@ -49,22 +49,19 @@ static void render_form(FORM *form)
wclear(der);
wrefresh(der);
delwin(der);
copywin(inner_w, w, line, 0, 1, 1,
min(numlines, getmaxy(inner_w) - line), 68, 0);
copywin(inner_w, w, line, 0, 1, 1, min(numlines, getmaxy(inner_w) - line), 68, 0);
wmove(w, y + 1 - line, x + 1);
wrefresh(w);
}

/* determine number of options, and maximum option name length */
static int count_cmos_options(struct cb_cmos_entries *option, int *numopts,
int *maxlength)
static int count_cmos_options(struct cb_cmos_entries *option, int *numopts, int *maxlength)
{
int n_opts = 0;
int max_l = 0;

while (option) {
if ((option->config != 'r') &&
(strcmp("check_sum", (char *)option->name) != 0)) {
if ((option->config != 'r') && (strcmp("check_sum", (char *)option->name) != 0)) {
max_l = max(max_l, strlen((char *)option->name));
n_opts++;
}
Expand All @@ -81,12 +78,11 @@ static int count_cmos_options(struct cb_cmos_entries *option, int *numopts,
*maxlength = max_l;

return 0;

}

/* walk over options, fetch details */
static void cmos_walk_options(struct cb_cmos_option_table *opttbl,
FIELD **fields, int numopts, int maxlength)
static void cmos_walk_options(struct cb_cmos_option_table *opttbl, FIELD **fields, int numopts,
int maxlength)
{
struct cb_cmos_entries *option = first_cmos_entry(opttbl);
int i;
Expand All @@ -96,16 +92,13 @@ static void cmos_walk_options(struct cb_cmos_option_table *opttbl,
(strcmp("check_sum", (char *)option->name) == 0)) {
option = next_cmos_entry(option);
}
fields[2 * i] =
new_field(1, strlen((char *)option->name), i * 2, 1, 0, 0);
fields[2 * i] = new_field(1, strlen((char *)option->name), i * 2, 1, 0, 0);
set_field_buffer(fields[2 * i], 0, (char *)option->name);
field_opts_off(fields[2 * i], O_ACTIVE);

fields[2 * i + 1] =
new_field(1, 40, i * 2, maxlength + 2, 0, 0);
fields[2 * i + 1] = new_field(1, 40, i * 2, maxlength + 2, 0, 0);
char *buf = NULL;
int fail =
get_option_as_string(use_nvram, opttbl, &buf, (char *)option->name);
int fail = get_option_as_string(use_nvram, opttbl, &buf, (char *)option->name);
switch (option->config) {
case 'h': {
set_field_type(fields[2 * i + 1], TYPE_INTEGER, 0, 0,
Expand All @@ -130,8 +123,7 @@ static void cmos_walk_options(struct cb_cmos_option_table *opttbl,

while (cmos_enum) {
numvals++;
cmos_enum = next_cmos_enum_of_id(
cmos_enum, option->config_id);
cmos_enum = next_cmos_enum_of_id(cmos_enum, option->config_id);
}

char **values = malloc(sizeof(char *) * (numvals + 1));
Expand All @@ -142,13 +134,11 @@ static void cmos_walk_options(struct cb_cmos_option_table *opttbl,
while (cmos_enum) {
values[cnt] = (char *)cmos_enum->text;
cnt++;
cmos_enum = next_cmos_enum_of_id(
cmos_enum, option->config_id);
cmos_enum = next_cmos_enum_of_id(cmos_enum, option->config_id);
}
values[cnt] = NULL;
field_opts_off(fields[2 * i + 1], O_EDIT);
set_field_type(fields[2 * i + 1], TYPE_ENUM, values, 1,
1);
set_field_type(fields[2 * i + 1], TYPE_ENUM, values, 1, 1);
free(values); // copied by set_field_type
break;
}
Expand All @@ -161,8 +151,7 @@ static void cmos_walk_options(struct cb_cmos_option_table *opttbl,
// underline is non-trivial on VGA text
set_field_back(fields[2 * i + 1], A_UNDERLINE);
#endif
field_opts_off(fields[2 * i + 1],
O_BLANK | O_AUTOSKIP | O_NULLOK);
field_opts_off(fields[2 * i + 1], O_BLANK | O_AUTOSKIP | O_NULLOK);

option = next_cmos_entry(option);
}
Expand Down
7 changes: 7 additions & 0 deletions src/Kconfig
Expand Up @@ -312,6 +312,7 @@ config ASAN
default n
select ASAN_IN_ROMSTAGE if HAVE_ASAN_IN_ROMSTAGE
select ASAN_IN_RAMSTAGE if HAVE_ASAN_IN_RAMSTAGE
depends on COMPILER_GCC
help
Enable address sanitizer - runtime memory debugger,
designed to find out-of-bounds accesses and use-after-scope bugs.
Expand Down Expand Up @@ -1327,6 +1328,12 @@ config BOOTBLOCK_CUSTOM
# src/lib/bootblock.c#main() C entry point.
bool

config BOOTBLOCK_IN_CBFS
bool
default y if ARCH_X86
help
Select this on platforms that have a top aligned bootblock inside cbfs.

config MEMLAYOUT_LD_FILE
string
default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/memlayout.ld"
Expand Down
1 change: 1 addition & 0 deletions src/acpi/acpigen_usb.c
Expand Up @@ -106,6 +106,7 @@ static void add_device_references(struct acpi_dp *dsd,
add_device_ref(dsd, "orientation-switch", config->orientation_switch);
add_device_ref(dsd, "usb-role-switch", config->usb_role_switch);
add_device_ref(dsd, "mode-switch", config->mode_switch);
add_device_ref(dsd, "retimer-switch", config->retimer_switch);
}

void acpigen_write_typec_connector(const struct typec_connector_class_config *config,
Expand Down
5 changes: 4 additions & 1 deletion src/acpi/gnvs.c
Expand Up @@ -2,6 +2,7 @@

#include <acpi/acpi_gnvs.h>
#include <acpi/acpigen.h>
#include <bootstate.h>
#include <cbmem.h>
#include <console/console.h>
#include <soc/nvs.h>
Expand All @@ -11,7 +12,7 @@
static struct global_nvs *gnvs;
static void *dnvs;

void acpi_create_gnvs(void)
static void acpi_create_gnvs(void *unused)
{
const size_t gnvs_size = ALIGN_UP(sizeof(struct global_nvs), sizeof(uint64_t));
const size_t dnvs_size = ALIGN_UP(size_of_dnvs(), sizeof(uint64_t));
Expand All @@ -34,6 +35,8 @@ void acpi_create_gnvs(void)
gnvs->cbmc = (uintptr_t)cbmem_find(CBMEM_ID_CONSOLE);
}

BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_EXIT, acpi_create_gnvs, NULL);

void *acpi_get_gnvs(void)
{
if (gnvs)
Expand Down
2 changes: 1 addition & 1 deletion src/arch/riscv/include/arch/barrier.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause */

#ifndef __ARCH_BARRIER_H_
#ifndef __ARCH_BARRIER_H__
#define __ARCH_BARRIER_H__

static inline void mb(void) { asm volatile("fence"); }
Expand Down
32 changes: 32 additions & 0 deletions src/arch/x86/Kconfig
Expand Up @@ -320,6 +320,38 @@ config MEMLAYOUT_LD_FILE
string
default "src/arch/x86/memlayout.ld"

config DEBUG_HW_BREAKPOINTS
bool
default y
help
Enable support for hardware data and instruction breakpoints through
the x86 debug registers

config DEBUG_HW_BREAKPOINTS_IN_ALL_STAGES
bool
default y
depends on DEBUG_HW_BREAKPOINTS && IDT_IN_EVERY_STAGE

config DEBUG_NULL_DEREF_BREAKPOINTS
bool
default y
depends on DEBUG_HW_BREAKPOINTS
help
Enable support for catching null dereferences and instruction execution

config DEBUG_NULL_DEREF_BREAKPOINTS_IN_ALL_STAGES
bool
default y
depends on DEBUG_NULL_DEREF_BREAKPOINTS && DEBUG_HW_BREAKPOINTS_IN_ALL_STAGES

config DEBUG_NULL_DEREF_HALT
bool
default n
depends on DEBUG_NULL_DEREF_BREAKPOINTS
help
When enabled null dereferences and instruction fetches will halt execution.
Otherwise an error will be printed.

# Some EC need an "EC firmware pointer" (a data structure hinting the address
# of its firmware blobs) being put at a fixed position. Its space
# (__section__(".ecfw_ptr")) should be reserved if it lies in the range of a
Expand Down
23 changes: 23 additions & 0 deletions src/arch/x86/Makefile.inc
Expand Up @@ -78,6 +78,7 @@ endef
ifeq ($(CONFIG_ARCH_BOOTBLOCK_X86_32)$(CONFIG_ARCH_BOOTBLOCK_X86_64),y)

bootblock-y += boot.c
bootblock-$(CONFIG_DEBUG_HW_BREAKPOINTS_IN_ALL_STAGES) += breakpoint.c
bootblock-y += post.c
bootblock-y += cpu_common.c
bootblock-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c
Expand All @@ -87,6 +88,7 @@ bootblock-y += memset.c
bootblock-y += memmove.c
bootblock-$(CONFIG_COLLECT_TIMESTAMPS_TSC) += timestamp.c
bootblock-$(CONFIG_X86_TOP4G_BOOTMEDIA_MAP) += mmap_boot.c
bootblock-$(CONFIG_DEBUG_NULL_DEREF_BREAKPOINTS_IN_ALL_STAGES) += null_breakpoint.c
bootblock-$(CONFIG_BOOTBLOCK_NORMAL) += bootblock_normal.c
bootblock-y += gdt_init.S
bootblock-y += id.S
Expand All @@ -100,6 +102,17 @@ else
$(eval $(call early_x86_stage,bootblock,elf64-x86-64))
endif

ifneq ($(CONFIG_UPDATE_IMAGE),y)
ifeq ($(CONFIG_BOOTBLOCK_IN_CBFS),y)
$(call add_intermediate, add_bootblock, $(objcbfs)/bootblock.bin)
@printf " CBFS $(subst $(obj)/,,$(@))\n"
$(CBFSTOOL) $< add -f $(objcbfs)/bootblock.bin -n bootblock -t bootblock $(TXTIBB) -b -$(call file-size,$(objcbfs)/bootblock.bin) \
$(cbfs-autogen-attributes) $(TS_OPTIONS) $(CBFSTOOL_ADD_CMD_OPTIONS)
else # Make sure the bootblock gets build, if only for buildtesting
$(call add_intermediate, gen_bootblock, $(objcbfs)/bootblock.bin)
endif
endif

$(call src-to-obj,bootblock,$(dir)/walkcbfs.S): $(obj)/fmap_config.h
bootblock-y += walkcbfs.S

Expand All @@ -113,6 +126,7 @@ ifeq ($(CONFIG_ARCH_VERSTAGE_X86_32)$(CONFIG_ARCH_VERSTAGE_X86_64),y)

verstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += assembly_entry.S
verstage-y += boot.c
verstage-$(CONFIG_DEBUG_HW_BREAKPOINTS_IN_ALL_STAGES) += breakpoint.c
verstage-y += post.c
verstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += gdt_init.S
verstage-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c
Expand All @@ -124,6 +138,7 @@ verstage-y += memset.c
verstage-y += memcpy.c
verstage-y += memmove.c
verstage-$(CONFIG_X86_TOP4G_BOOTMEDIA_MAP) += mmap_boot.c
verstage-$(CONFIG_DEBUG_NULL_DEREF_BREAKPOINTS_IN_ALL_STAGES) += null_breakpoint.c
# If verstage is a separate stage it means there's no need
# for a chipset-specific car_stage_entry() so use the generic one
# which just calls verstage().
Expand All @@ -149,6 +164,7 @@ ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32)$(CONFIG_ARCH_ROMSTAGE_X86_64),y)

romstage-y += assembly_entry.S
romstage-y += boot.c
romstage-$(CONFIG_DEBUG_HW_BREAKPOINTS_IN_ALL_STAGES) += breakpoint.c
romstage-y += post.c
romstage-y += gdt_init.S
romstage-y += cpu_common.c
Expand All @@ -158,6 +174,7 @@ romstage-y += memcpy.c
romstage-y += memmove.c
romstage-y += memset.c
romstage-$(CONFIG_X86_TOP4G_BOOTMEDIA_MAP) += mmap_boot.c
romstage-$(CONFIG_DEBUG_NULL_DEREF_BREAKPOINTS_IN_ALL_STAGES) += null_breakpoint.c
romstage-y += postcar_loader.c
romstage-$(CONFIG_COLLECT_TIMESTAMPS_TSC) += timestamp.c
romstage-$(CONFIG_HAVE_CF9_RESET) += cf9_reset.c
Expand Down Expand Up @@ -190,6 +207,7 @@ endif
postcar-generic-ccopts += -D__POSTCAR__

postcar-y += boot.c
postcar-$(CONFIG_DEBUG_HW_BREAKPOINTS_IN_ALL_STAGES) += breakpoint.c
postcar-y += post.c
postcar-y += gdt_init.S
postcar-y += cpu_common.c
Expand All @@ -200,6 +218,7 @@ postcar-y += memcpy.c
postcar-y += memmove.c
postcar-y += memset.c
postcar-$(CONFIG_X86_TOP4G_BOOTMEDIA_MAP) += mmap_boot.c
postcar-$(CONFIG_DEBUG_NULL_DEREF_BREAKPOINTS_IN_ALL_STAGES) += null_breakpoint.c
postcar-y += postcar.c
postcar-$(CONFIG_COLLECT_TIMESTAMPS_TSC) += timestamp.c
postcar-$(CONFIG_HAVE_CF9_RESET) += cf9_reset.c
Expand Down Expand Up @@ -234,6 +253,7 @@ ramstage-y += c_start.S
ramstage-y += c_exit.S
ramstage-y += cpu.c
ramstage-y += cpu_common.c
ramstage-$(CONFIG_DEBUG_HW_BREAKPOINTS) += breakpoint.c
ramstage-y += ebda.c
ramstage-y += exception.c
ramstage-y += idt.S
Expand All @@ -243,6 +263,7 @@ ramstage-y += memmove.c
ramstage-y += memset.c
ramstage-$(CONFIG_X86_TOP4G_BOOTMEDIA_MAP) += mmap_boot.c
ramstage-$(CONFIG_GENERATE_MP_TABLE) += mpspec.c
ramstage-$(CONFIG_DEBUG_NULL_DEREF_BREAKPOINTS) += null_breakpoint.c
ramstage-$(CONFIG_GENERATE_PIRQ_TABLE) += pirq_routing.c
ramstage-y += rdrand.c
ramstage-$(CONFIG_GENERATE_SMBIOS_TABLES) += smbios.c
Expand Down Expand Up @@ -297,11 +318,13 @@ $(objgenerated)/ramstage.o: $$(ramstage-objs) $(COMPILER_RT_ramstage) $$(ramstag

endif # CONFIG_ARCH_RAMSTAGE_X86_32 / CONFIG_ARCH_RAMSTAGE_X86_64

smm-$(CONFIG_DEBUG_HW_BREAKPOINTS_IN_ALL_STAGES) += breakpoint.c
smm-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c
smm-$(CONFIG_IDT_IN_EVERY_STAGE) += idt.S
smm-y += memcpy.c
smm-y += memmove.c
smm-y += memset.c
smm-$(CONFIG_X86_TOP4G_BOOTMEDIA_MAP) += mmap_boot.c
smm-$(CONFIG_DEBUG_NULL_DEREF_BREAKPOINTS_IN_ALL_STAGES) += null_breakpoint.c

smm-srcs += $(wildcard src/mainboard/$(MAINBOARDDIR)/smihandler.c)
9 changes: 0 additions & 9 deletions src/arch/x86/acpi/debug.asl
@@ -1,10 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */

/*
* 0x80: POST_BASE
* 0x3F8: DEBCOM_BASE
* X80: POST_REGION
* P80: PORT80
*
* CREG: DEBCOM_REGION
* CUAR: DEBCOM_UART
Expand All @@ -17,12 +14,6 @@
* DEBUG_INIT DINI
*/

OperationRegion(X80, SystemIO, 0x80, 1)
Field(X80, ByteAcc, NoLock, Preserve)
{
P80, 8
}

OperationRegion(CREG, SystemIO, 0x3F8, 8)
Field(CREG, ByteAcc, NoLock, Preserve)
{
Expand Down
17 changes: 17 additions & 0 deletions src/arch/x86/acpi/post.asl
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#if CONFIG(POST_IO)

/* POST code support, typically on port 80 */
OperationRegion (POST, SystemIO, CONFIG_POST_IO_PORT, 1)
Field (POST, ByteAcc, Lock, Preserve)
{
DBG0, 8
}

#else

/* Dummy placeholder to avoid issues */
Name (DBG0, 0)

#endif
5 changes: 3 additions & 2 deletions src/arch/x86/acpi_bert_storage.c
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <bootstate.h>
#include <cbmem.h>
#include <console/console.h>
#include <cpu/x86/name.h>
Expand Down Expand Up @@ -577,7 +578,7 @@ __weak void bert_reserved_region(void **start, size_t *size)
*size = 0;
}

static void bert_storage_setup(int unused)
static void bert_storage_setup(void *unused)
{
/* Always start with a blank bert region. Make sure nothing is
* maintained across reboots or resumes.
Expand All @@ -596,4 +597,4 @@ static void bert_storage_setup(int unused)
memset(bert_region_base, 0, bert_region_size);
}

RAMSTAGE_CBMEM_INIT_HOOK(bert_storage_setup)
BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_EXIT, bert_storage_setup, NULL);
9 changes: 7 additions & 2 deletions src/arch/x86/bootblock.ld
Expand Up @@ -73,9 +73,14 @@ SECTIONS {
_X86_RESET_VECTOR = .;
.reset . : {
*(.reset);
. = 15;
BYTE(0x00);
. = _X86_RESET_VECTOR_FILLING;
BYTE(0);
}
. = 0xfffffffc;
.header_pointer . : {
KEEP(*(.header_pointer));
}
_X86_RESET_VECTOR_FILLING = 15 - SIZEOF(.header_pointer);
_ebootblock = .;
}

Expand Down
300 changes: 300 additions & 0 deletions src/arch/x86/breakpoint.c
@@ -0,0 +1,300 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <arch/registers.h>
#include <arch/breakpoint.h>
#include <console/console.h>
#include <stdint.h>
#include <types.h>

#define DEBUG_REGISTER_COUNT 4

/* Each enable field is 2 bits and starts at bit 0 */
#define DEBUG_CTRL_ENABLE_SHIFT(index) (2 * (index))
#define DEBUG_CTRL_ENABLE_MASK(index) (0x3 << DEBUG_CTRL_ENABLE_SHIFT(index))
#define DEBUG_CTRL_ENABLE(index, enable) ((enable) << DEBUG_CTRL_ENABLE_SHIFT(index))

/* Each breakpoint has a length and type, each is two bits and start at bit 16 */
#define DEBUG_CTRL_LT_SHIFT(index) (4 * (index) + 16)
#define DEBUG_CTRL_LT_MASK(index) (0xf << DEBUG_CTRL_LT_SHIFT(index))
#define DEBUG_CTRL_LT(index, len, type) ((((len) << 2 | (type))) << DEBUG_CTRL_LT_SHIFT(index))

/* Each field is one bit, starting at bit 0 */
#define DEBUG_STATUS_BP_HIT_MASK(index) (1 << (index))
#define DEBUG_STATUS_GET_BP_HIT(index, value) \
(((value) & DEBUG_STATUS_BP_HIT_MASK(index)) >> (index))

/* Breakpoint lengths values */
#define DEBUG_CTRL_LEN_1 0x0
#define DEBUG_CTRL_LEN_2 0x1
#define DEBUG_CTRL_LEN_8 0x2
#define DEBUG_CTRL_LEN_4 0x3

/* Breakpoint enable values */
#define DEBUG_CTRL_ENABLE_LOCAL 0x1
#define DEBUG_CTRL_ENABLE_GLOBAL 0x2

/* eflags/rflags bit to continue execution after hitting an instruction breakpoint */
#define FLAGS_RESUME (1 << 16)

struct breakpoint {
bool allocated;
enum breakpoint_type type;
breakpoint_handler handler;
};

static struct breakpoint breakpoints[DEBUG_REGISTER_COUNT];

static inline bool debug_write_addr_reg(int index, uintptr_t value)
{
switch (index) {
case 0:
asm("mov %0, %%dr0" ::"r"(value));
break;

case 1:
asm("mov %0, %%dr1" ::"r"(value));
break;

case 2:
asm("mov %0, %%dr2" ::"r"(value));
break;

case 3:
asm("mov %0, %%dr3" ::"r"(value));
break;

default:
return false;
}

return true;
}

static inline uintptr_t debug_read_status(void)
{
uintptr_t ret = 0;

asm("mov %%dr6, %0" : "=r"(ret));
return ret;
}

static inline void debug_write_status(uintptr_t value)
{
asm("mov %0, %%dr6" ::"r"(value));
}

static inline uintptr_t debug_read_control(void)
{
uintptr_t ret = 0;

asm("mov %%dr7, %0" : "=r"(ret));
return ret;
}

static inline void debug_write_control(uintptr_t value)
{
asm("mov %0, %%dr7" ::"r"(value));
}

static enum breakpoint_result allocate_breakpoint(struct breakpoint_handle *out_handle,
enum breakpoint_type type)
{
for (int i = 0; i < DEBUG_REGISTER_COUNT; i++) {
if (breakpoints[i].allocated)
continue;

breakpoints[i].allocated = true;
breakpoints[i].handler = NULL;
breakpoints[i].type = type;
out_handle->bp = i;
return BREAKPOINT_RES_OK;
}

return BREAKPOINT_RES_NONE_AVAILABLE;
}

static enum breakpoint_result validate_handle(struct breakpoint_handle handle)
{
int bp = handle.bp;

if (bp < 0 || bp >= DEBUG_REGISTER_COUNT || !breakpoints[bp].allocated)
return BREAKPOINT_RES_INVALID_HANDLE;

return BREAKPOINT_RES_OK;
}

enum breakpoint_result breakpoint_create_instruction(struct breakpoint_handle *out_handle,
void *virt_addr)
{
enum breakpoint_result res =
allocate_breakpoint(out_handle, BREAKPOINT_TYPE_INSTRUCTION);

if (res != BREAKPOINT_RES_OK)
return res;

int bp = out_handle->bp;
if (!debug_write_addr_reg(bp, (uintptr_t)virt_addr))
return BREAKPOINT_RES_INVALID_HANDLE;

uintptr_t control = debug_read_control();
control &= ~DEBUG_CTRL_LT_MASK(bp);
control |= DEBUG_CTRL_LT(bp, DEBUG_CTRL_LEN_1, BREAKPOINT_TYPE_INSTRUCTION);
debug_write_control(control);
return BREAKPOINT_RES_OK;
}

enum breakpoint_result breakpoint_create_data(struct breakpoint_handle *out_handle,
void *virt_addr, size_t len, bool write_only)
{
uintptr_t len_value = 0;

switch (len) {
case 1:
len_value = DEBUG_CTRL_LEN_1;
break;

case 2:
len_value = DEBUG_CTRL_LEN_2;
break;

case 4:
len_value = DEBUG_CTRL_LEN_4;
break;

case 8:
/* Only supported on 64-bit CPUs */
if (!ENV_X86_64)
return BREAKPOINT_RES_INVALID_LENGTH;
len_value = DEBUG_CTRL_LEN_8;
break;

default:
return BREAKPOINT_RES_INVALID_LENGTH;
}

enum breakpoint_type type =
write_only ? BREAKPOINT_TYPE_DATA_WRITE : BREAKPOINT_TYPE_DATA_RW;
enum breakpoint_result res = allocate_breakpoint(out_handle, type);
if (res != BREAKPOINT_RES_OK)
return res;

int bp = out_handle->bp;
if (!debug_write_addr_reg(bp, (uintptr_t)virt_addr))
return BREAKPOINT_RES_INVALID_HANDLE;

uintptr_t control = debug_read_control();
control &= ~DEBUG_CTRL_LT_MASK(bp);
control |= DEBUG_CTRL_LT(bp, len_value, type);
debug_write_control(control);
return BREAKPOINT_RES_OK;
}

enum breakpoint_result breakpoint_remove(struct breakpoint_handle handle)
{
enum breakpoint_result res = validate_handle(handle);

if (res != BREAKPOINT_RES_OK)
return res;
breakpoint_enable(handle, false);

int bp = handle.bp;
breakpoints[bp].allocated = false;
return BREAKPOINT_RES_OK;
}

enum breakpoint_result breakpoint_enable(struct breakpoint_handle handle, bool enabled)
{
enum breakpoint_result res = validate_handle(handle);

if (res != BREAKPOINT_RES_OK)
return res;

uintptr_t control = debug_read_control();
int bp = handle.bp;
control &= ~DEBUG_CTRL_ENABLE_MASK(bp);
if (enabled)
control |= DEBUG_CTRL_ENABLE(bp, DEBUG_CTRL_ENABLE_GLOBAL);
debug_write_control(control);
return BREAKPOINT_RES_OK;
}

enum breakpoint_result breakpoint_get_type(struct breakpoint_handle handle,
enum breakpoint_type *type)
{
enum breakpoint_result res = validate_handle(handle);

if (res != BREAKPOINT_RES_OK)
return res;

*type = breakpoints[handle.bp].type;
return BREAKPOINT_RES_OK;
}

enum breakpoint_result breakpoint_set_handler(struct breakpoint_handle handle,
breakpoint_handler handler)
{
enum breakpoint_result res = validate_handle(handle);

if (res != BREAKPOINT_RES_OK)
return res;

breakpoints[handle.bp].handler = handler;
return BREAKPOINT_RES_OK;
}

static enum breakpoint_result is_breakpoint_hit(struct breakpoint_handle handle, bool *out_hit)
{
enum breakpoint_result res = validate_handle(handle);

if (res != BREAKPOINT_RES_OK)
return res;

uintptr_t status = debug_read_status();
*out_hit = DEBUG_STATUS_GET_BP_HIT(handle.bp, status);

return BREAKPOINT_RES_OK;
}

int breakpoint_dispatch_handler(struct eregs *info)
{
bool instr_bp_hit = 0;

for (int i = 0; i < DEBUG_REGISTER_COUNT; i++) {
struct breakpoint_handle handle = { i };
bool hit = false;
enum breakpoint_type type;

if (is_breakpoint_hit(handle, &hit) != BREAKPOINT_RES_OK || !hit)
continue;

if (breakpoint_get_type(handle, &type) != BREAKPOINT_RES_OK)
continue;

instr_bp_hit |= type == BREAKPOINT_TYPE_INSTRUCTION;

/* Call the breakpoint handler. */
if (breakpoints[handle.bp].handler) {
int ret = breakpoints[handle.bp].handler(handle, info);
/* A non-zero return value indicates a fatal error. */
if (ret)
return ret;
}
}

/* Clear hit breakpoints. */
uintptr_t status = debug_read_status();
for (int i = 0; i < DEBUG_REGISTER_COUNT; i++) {
status &= ~DEBUG_STATUS_BP_HIT_MASK(i);
}
debug_write_status(status);

if (instr_bp_hit) {
/* Set the resume flag so the same breakpoint won't be hit immediately. */
#if ENV_X86_64
info->rflags |= FLAGS_RESUME;
#else
info->eflags |= FLAGS_RESUME;
#endif
}

return 0;
}
19 changes: 16 additions & 3 deletions src/arch/x86/ebda.c
@@ -1,9 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <stdint.h>
#include <acpi/acpi.h>
#include <arch/ebda.h>
#include <bootstate.h>
#include <commonlib/endian.h>
#include <stdint.h>

#define X86_BDA_SIZE 0x200
#define X86_BDA_BASE ((void *)0x400)
#define X86_EBDA_SEGMENT ((void *)0x40e)
#define X86_EBDA_LOWMEM ((void *)0x413)

#define DEFAULT_EBDA_LOWMEM (1024 << 10)
#define DEFAULT_EBDA_SEGMENT 0xF600
#define DEFAULT_EBDA_SIZE 0x400


static void *get_ebda_start(void)
{
Expand Down Expand Up @@ -40,7 +50,7 @@ static void setup_ebda(u32 low_memory_size, u16 ebda_segment, u16 ebda_size)
write_le16(ebda, ebda_kb);
}

void setup_default_ebda(void)
static void setup_default_ebda(void *unused)
{
if (acpi_is_wakeup_s3())
return;
Expand All @@ -49,3 +59,6 @@ void setup_default_ebda(void)
DEFAULT_EBDA_SEGMENT,
DEFAULT_EBDA_SIZE);
}

/* Ensure EBDA is prepared before Option ROMs. */
BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, setup_default_ebda, NULL);
13 changes: 11 additions & 2 deletions src/arch/x86/exception.c
@@ -1,7 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <arch/cpu.h>
#include <arch/breakpoint.h>
#include <arch/null_breakpoint.h>
#include <arch/exception.h>
#include <arch/registers.h>
#include <commonlib/helpers.h>
#include <console/console.h>
#include <console/streams.h>
Expand Down Expand Up @@ -371,7 +373,7 @@ static void put_packet(char *buffer)
}
#endif /* CONFIG_GDB_STUB */

#include <arch/registers.h>
#define DEBUG_VECTOR 1

void x86_exception(struct eregs *info);

Expand Down Expand Up @@ -488,6 +490,11 @@ void x86_exception(struct eregs *info)
int logical_processor = 0;
u32 apic_id = CONFIG(SMP) ? lapicid() : 0;

if (info->vector == DEBUG_VECTOR) {
if (breakpoint_dispatch_handler(info) == 0)
return;
}

#if ENV_RAMSTAGE
logical_processor = cpu_index();
#endif
Expand Down Expand Up @@ -657,4 +664,6 @@ asmlinkage void exception_init(void)
}

load_idt(idt, sizeof(idt));

null_breakpoint_init();
}
126 changes: 5 additions & 121 deletions src/arch/x86/exit_car.S
Expand Up @@ -4,37 +4,6 @@
#include <cpu/x86/cr.h>
#include <cpu/x86/cache.h>

.section ".module_parameters", "aw", @progbits
/* stack_top indicates the stack to pull MTRR information from. */
.global post_car_stack_top
post_car_stack_top:
.long 0
.long 0

#if ENV_X86_64
.code64
.macro pop_eax_edx
pop %rax
mov %rax, %rdx
shr $32, %rdx
.endm
.macro pop_ebx_esi
pop %rbx
mov %rbx, %rsi
shr $32, %rsi
.endm
#else
.code32
.macro pop_eax_edx
pop %eax
pop %edx
.endm
.macro pop_ebx_esi
pop %ebx
pop %esi
.endm
#endif

/* Place the stack in the bss section. It's not necessary to define it in the
* the linker script. */
.section .bss, "aw", @nobits
Expand Down Expand Up @@ -89,107 +58,22 @@ skip_clflush:
mov %cr0, %rax
and $(~(CR0_CD | CR0_NW)), %eax
mov %rax, %cr0

/* Ensure cache is clean. */
invd

/* Set up new stack. */
movabs post_car_stack_top, %rax
mov %rax, %rsp
#else
mov %cr0, %eax
and $(~(CR0_CD | CR0_NW)), %eax
mov %eax, %cr0

#endif
/* Ensure cache is clean. */
invd

/* Set up new stack. */
mov post_car_stack_top, %esp
#endif
/*
* Honor variable MTRR information pushed on the stack with the
* following layout:
*
* Offset: Value
* ...
* 0x14: MTRR mask 0 63:32
* 0x10: MTRR mask 0 31:0
* 0x0c: MTRR base 0 63:32
* 0x08: MTRR base 0 31:0
* 0x04: Number of variable MTRRs to set
* 0x00: Number of variable MTRRs to clear
*/

#if CONFIG(SOC_SETS_MSRS)

mov %esp, %ebp
/* Need to align stack to 16 bytes at the call instruction. Therefore
account for the 1 push. */
andl $0xfffffff0, %esp
#if ENV_X86_64
mov %rbp, %rdi
#else
sub $12, %esp
push %ebp
#endif

call soc_set_mtrrs
/* Ignore fixing up %esp since we're setting it a new value. */

/* eax: new top_of_stack with setup_stack_and_mtrrs data removed */
movl %eax, %esp
/* Align stack to 16 bytes at call instruction. */
andl $0xfffffff0, %esp
call soc_enable_mtrrs
#else /* CONFIG_SOC_SETS_MSRS */
/* Clear variable MTRRs. */
pop_ebx_esi /* ebx: Number to clear, esi: Number to set */
test %ebx, %ebx
jz 2f
xor %eax, %eax
xor %edx, %edx
mov $(MTRR_PHYS_BASE(0)), %ecx
1:
wrmsr
inc %ecx
wrmsr
inc %ecx
dec %ebx
jnz 1b
2:

/* Set Variable MTRRs based on stack contents. */
test %esi, %esi
jz 2f
mov $(MTRR_PHYS_BASE(0)), %ecx
1:
/* Write MTRR base. */
pop_eax_edx
wrmsr
inc %ecx
/* Write MTRR mask. */
pop_eax_edx
wrmsr
inc %ecx

dec %esi
jnz 1b
2:

/* Enable MTRR. */
mov $(MTRR_DEF_TYPE_MSR), %ecx
rdmsr
/* Make default type uncacheable. */
and $(~(MTRR_DEF_TYPE_MASK)), %eax
or $(MTRR_DEF_TYPE_EN), %eax
wrmsr
#endif /* CONFIG_SOC_SETS_MSRS */

movl $_estack, %esp
/* Align stack to 16 bytes at call instruction. */
andl $0xfffffff0, %esp

/* Call this in assembly as some platforms like to mess with the bootflow and
call into main directly from chipset_teardown_car. */
call postcar_mtrr_setup

/* Call into main for postcar. */
call main
/* Should never return. */
Expand Down
58 changes: 58 additions & 0 deletions src/arch/x86/include/arch/breakpoint.h
@@ -0,0 +1,58 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _BREAKPOINT_H_
#define _BREAKPOINT_H_

#include <arch/registers.h>
#include <types.h>

#if CONFIG(DEBUG_HW_BREAKPOINTS) && \
(CONFIG(DEBUG_HW_BREAKPOINTS_IN_ALL_STAGES) || ENV_RAMSTAGE)
struct breakpoint_handle {
int bp;
};

typedef int (*breakpoint_handler)(struct breakpoint_handle, struct eregs *info);

enum breakpoint_result {
BREAKPOINT_RES_OK = 0,
BREAKPOINT_RES_NONE_AVAILABLE = -1,
BREAKPOINT_RES_INVALID_HANDLE = -2,
BREAKPOINT_RES_INVALID_LENGTH = -3
};

enum breakpoint_type {
BREAKPOINT_TYPE_INSTRUCTION = 0x0,
BREAKPOINT_TYPE_DATA_WRITE = 0x1,
BREAKPOINT_TYPE_IO = 0x2,
BREAKPOINT_TYPE_DATA_RW = 0x3,
};

/* Creates an instruction breakpoint at the given address. */
enum breakpoint_result breakpoint_create_instruction(struct breakpoint_handle *out_handle,
void *virt_addr);
/* Creates a data breakpoint at the given address for len bytes. */
enum breakpoint_result breakpoint_create_data(struct breakpoint_handle *out_handle,
void *virt_addr, size_t len, bool write_only);
/* Removes a given breakpoint. */
enum breakpoint_result breakpoint_remove(struct breakpoint_handle handle);
/* Enables or disables a given breakpoint. */
enum breakpoint_result breakpoint_enable(struct breakpoint_handle handle, bool enabled);
/* Returns the type of a breakpoint. */
enum breakpoint_result breakpoint_get_type(struct breakpoint_handle handle,
enum breakpoint_type *type);
/*
* Sets a handler function to be called when the breakpoint is hit. The handler should return 0
* to continue or any other value to halt execution as a fatal error.
*/
enum breakpoint_result breakpoint_set_handler(struct breakpoint_handle handle,
breakpoint_handler handler);
/* Called by x86_exception to dispatch breakpoint exceptions to the correct handler. */
int breakpoint_dispatch_handler(struct eregs *info);
#else
static inline int breakpoint_dispatch_handler(struct eregs *info)
{
/* Not implemented */
return 0;
}
#endif
#endif /* _BREAKPOINT_H_ */
19 changes: 0 additions & 19 deletions src/arch/x86/include/arch/ebda.h

This file was deleted.

16 changes: 16 additions & 0 deletions src/arch/x86/include/arch/null_breakpoint.h
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _NULL_BREAKPOINT_H_
#define _NULL_BREAKPOINT_H_

#if CONFIG(DEBUG_NULL_DEREF_BREAKPOINTS) && \
(CONFIG(DEBUG_NULL_DEREF_BREAKPOINTS_IN_ALL_STAGES) || ENV_RAMSTAGE)

/* Places data and instructions breakpoints at address zero. */
void null_breakpoint_init(void);
#else
static inline void null_breakpoint_init(void)
{
/* Not implemented */
}
#endif
#endif /* _NULL_BREAKPOINT_H_ */
23 changes: 2 additions & 21 deletions src/arch/x86/include/arch/romstage.h
Expand Up @@ -16,18 +16,10 @@ void mainboard_romstage_entry(void);
*/

struct postcar_frame {
uintptr_t stack;
int skip_common_mtrr;
struct var_mtrr_context ctx;
struct var_mtrr_context *mtrr;
};

/*
* Initialize postcar_frame object allocating stack from cbmem,
* with stack_size == 0, default 4 KiB is allocated.
* Returns 0 on success, < 0 on error.
*/
int postcar_frame_init(struct postcar_frame *pcf, size_t stack_size);

/*
* Add variable MTRR covering the provided range with MTRR type.
*/
Expand All @@ -51,18 +43,7 @@ void fill_postcar_frame(struct postcar_frame *pcf);
* prepare_and_run_postcar() determines the stack to use after
* cache-as-ram is torn down as well as the MTRR settings to use.
*/
void prepare_and_run_postcar(struct postcar_frame *pcf);

/*
* Load and run a program that takes control of execution that
* tears down CAR and loads ramstage. The postcar_frame object
* indicates how to set up the frame. If caching is enabled at
* the time of the call it is up to the platform code to handle
* coherency with dirty lines in the cache using some mechanism
* such as platform_prog_run() because run_postcar_phase()
* utilizes prog_run() internally.
*/
void run_postcar_phase(struct postcar_frame *pcf);
void prepare_and_run_postcar(void);

/*
* Systems without a native coreboot cache-as-ram teardown may implement
Expand Down
10 changes: 1 addition & 9 deletions src/arch/x86/include/arch/smp/mpspec.h
Expand Up @@ -3,6 +3,7 @@
#ifndef __ASM_MPSPEC_H
#define __ASM_MPSPEC_H

#include <acpi/acpi.h>
#include <device/device.h>
#include <cpu/x86/lapic_def.h>

Expand Down Expand Up @@ -120,15 +121,6 @@ enum mp_irq_source_types {
mp_ExtINT = 3
};

#define MP_IRQ_POLARITY_DEFAULT 0x0
#define MP_IRQ_POLARITY_HIGH 0x1
#define MP_IRQ_POLARITY_LOW 0x3
#define MP_IRQ_POLARITY_MASK 0x3
#define MP_IRQ_TRIGGER_DEFAULT 0x0
#define MP_IRQ_TRIGGER_EDGE 0x4
#define MP_IRQ_TRIGGER_LEVEL 0xc
#define MP_IRQ_TRIGGER_MASK 0xc

struct mpc_config_lintsrc {
u8 mpc_type;
u8 mpc_irqtype;
Expand Down
1 change: 0 additions & 1 deletion src/arch/x86/mpspec.c
Expand Up @@ -6,7 +6,6 @@
#include <arch/ioapic.h>
#include <arch/smp/mpspec.h>
#include <string.h>
#include <arch/cpu.h>
#include <cpu/cpu.h>
#include <cpu/x86/lapic.h>
#include <drivers/generic/ioapic/chip.h>
Expand Down
67 changes: 67 additions & 0 deletions src/arch/x86/null_breakpoint.c
@@ -0,0 +1,67 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <arch/breakpoint.h>
#include <arch/null_breakpoint.h>
#include <bootstate.h>
#include <console/console.h>
#include <stdint.h>

static struct breakpoint_handle null_deref_bp;
static struct breakpoint_handle null_fetch_bp;

static int handle_fetch_breakpoint(struct breakpoint_handle handle, struct eregs *regs)
{
printk(BIOS_ERR, "Instruction fetch from address zero\n");
return CONFIG(DEBUG_NULL_DEREF_HALT);
}

static int handle_deref_breakpoint(struct breakpoint_handle handle, struct eregs *regs)
{
#if ENV_X86_64
printk(BIOS_ERR, "Null dereference at rip: 0x%llx \n", regs->rip);
#else
printk(BIOS_ERR, "Null dereference at eip: 0x%x \n", regs->eip);
#endif
return CONFIG(DEBUG_NULL_DEREF_HALT);
}

static void create_deref_breakpoint(void)
{
enum breakpoint_result res =
breakpoint_create_data(&null_deref_bp, NULL, sizeof(uintptr_t), false);

if (res != BREAKPOINT_RES_OK) {
printk(BIOS_ERR, "Failed to create NULL dereference breakpoint\n");
return;
}

breakpoint_set_handler(null_deref_bp, &handle_deref_breakpoint);
breakpoint_enable(null_deref_bp, true);
}

static void create_instruction_breakpoint(void)
{
enum breakpoint_result res = breakpoint_create_instruction(&null_fetch_bp, NULL);

if (res != BREAKPOINT_RES_OK) {
printk(BIOS_ERR, "Failed to create address zero instruction fetch breakpoint\n");
return;
}

breakpoint_set_handler(null_fetch_bp, &handle_fetch_breakpoint);
breakpoint_enable(null_fetch_bp, true);
}

void null_breakpoint_init(void)
{
create_deref_breakpoint();
create_instruction_breakpoint();
}

static void null_breakpoint_disable(void *unused)
{
breakpoint_remove(null_fetch_bp);
breakpoint_remove(null_deref_bp);
}

BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, null_breakpoint_disable, NULL);
BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, null_breakpoint_disable, NULL);
97 changes: 29 additions & 68 deletions src/arch/x86/postcar_loader.c
Expand Up @@ -13,65 +13,34 @@
#include <timestamp.h>
#include <security/vboot/vboot_common.h>

static inline void stack_push(struct postcar_frame *pcf, uint32_t val)
static size_t var_mtrr_ctx_size(void)
{
uint32_t *ptr;

pcf->stack -= sizeof(val);
ptr = (void *)pcf->stack;
*ptr = val;
}

static void postcar_frame_prepare(struct postcar_frame *pcf)
{
var_mtrr_context_init(&pcf->ctx, pcf);
int mtrr_count = get_var_mtrr_count();
return sizeof(struct var_mtrr_context) + mtrr_count * 2 * sizeof(msr_t);
}

int postcar_frame_init(struct postcar_frame *pcf, size_t stack_size)
static int postcar_frame_init(struct postcar_frame *pcf)
{
void *stack;
memset(pcf, 0, sizeof(*pcf));

/*
* Use default postcar stack size of 4 KiB. This value should
* not be decreased, because if mainboards use vboot, 1 KiB will
* not be enough anymore.
*/
struct var_mtrr_context *ctx;

if (stack_size == 0)
stack_size = 4 * KiB;

stack = cbmem_add(CBMEM_ID_ROMSTAGE_RAM_STACK, stack_size);
if (stack == NULL) {
printk(BIOS_ERR, "Couldn't add %zd byte stack in cbmem.\n",
stack_size);
ctx = cbmem_add(CBMEM_ID_ROMSTAGE_RAM_STACK, var_mtrr_ctx_size());
if (ctx == NULL) {
printk(BIOS_ERR, "Couldn't add var_mtrr_ctx setup in cbmem.\n");
return -1;
}

postcar_frame_prepare(pcf);
pcf->stack = (uintptr_t)stack;
pcf->stack += stack_size;
return 0;
}

static void postcar_var_mtrr_set(const struct var_mtrr_context *ctx,
uintptr_t addr, size_t size,
msr_t base, msr_t mask)
{
struct postcar_frame *pcf = ctx->arg;
pcf->mtrr = ctx;
var_mtrr_context_init(pcf->mtrr);

printk(BIOS_DEBUG, "MTRR Range: Start=%lx End=%lx (Size %zx)\n",
addr, addr + size - 1, size);

stack_push(pcf, mask.hi);
stack_push(pcf, mask.lo);
stack_push(pcf, base.hi);
stack_push(pcf, base.lo);
return 0;
}

void postcar_frame_add_mtrr(struct postcar_frame *pcf,
uintptr_t addr, size_t size, int type)
{
var_mtrr_set_with_cb(&pcf->ctx, addr, size, type, postcar_var_mtrr_set);
var_mtrr_set(pcf->mtrr, addr, size, type);
}

void postcar_frame_add_romcache(struct postcar_frame *pcf, int type)
Expand All @@ -90,40 +59,34 @@ static void postcar_frame_common_mtrrs(struct postcar_frame *pcf)
postcar_frame_add_romcache(pcf, MTRR_TYPE_WRPROT);
}

static void run_postcar_phase(struct postcar_frame *pcf);

/* prepare_and_run_postcar() determines the stack to use after
* cache-as-ram is torn down as well as the MTRR settings to use. */
void prepare_and_run_postcar(struct postcar_frame *pcf)
void prepare_and_run_postcar(void)
{
if (postcar_frame_init(pcf, 0))
struct postcar_frame pcf;

if (postcar_frame_init(&pcf))
die("Unable to initialize postcar frame.\n");

fill_postcar_frame(pcf);
fill_postcar_frame(&pcf);

postcar_frame_common_mtrrs(pcf);
postcar_frame_common_mtrrs(&pcf);

run_postcar_phase(pcf);
run_postcar_phase(&pcf);
/* We do not return here. */
}

static void postcar_commit_mtrrs(struct postcar_frame *pcf)
{
/*
* Place the number of used variable MTRRs on stack then max number
* of variable MTRRs supported in the system.
*/
stack_push(pcf, pcf->ctx.used_var_mtrrs);
stack_push(pcf, pcf->ctx.max_var_mtrrs);
}

static void finalize_load(uintptr_t *stack_top_ptr, uintptr_t stack_top)
static void finalize_load(uintptr_t *reloc_params, uintptr_t mtrr_frame_ptr)
{
*stack_top_ptr = stack_top;
*reloc_params = mtrr_frame_ptr;
/*
* Signal to rest of system that another update was made to the
* postcar program prior to running it.
*/
prog_segment_loaded((uintptr_t)stack_top_ptr, sizeof(uintptr_t),
SEG_FINAL);
prog_segment_loaded((uintptr_t)reloc_params, sizeof(uintptr_t), SEG_FINAL);
prog_segment_loaded((uintptr_t)mtrr_frame_ptr, var_mtrr_ctx_size(), SEG_FINAL);
}

static void load_postcar_cbfs(struct prog *prog, struct postcar_frame *pcf)
Expand All @@ -144,7 +107,7 @@ static void load_postcar_cbfs(struct prog *prog, struct postcar_frame *pcf)
die_with_post_code(POST_INVALID_ROM,
"No parameters found in after CAR program.\n");

finalize_load(rsl.params, pcf->stack);
finalize_load(rsl.params, (uintptr_t)pcf->mtrr);

stage_cache_add(STAGE_POSTCAR, prog);
}
Expand Down Expand Up @@ -172,19 +135,17 @@ static void postcar_cache_invalid(void)
board_reset();
}

void run_postcar_phase(struct postcar_frame *pcf)
static void run_postcar_phase(struct postcar_frame *pcf)
{
struct prog prog =
PROG_INIT(PROG_POSTCAR, CONFIG_CBFS_PREFIX "/postcar");

postcar_commit_mtrrs(pcf);

if (resume_from_stage_cache()) {
stage_cache_load_stage(STAGE_POSTCAR, &prog);
/* This is here to allow platforms to pass different stack
parameters between S3 resume and normal boot. On the
platforms where the values are the same it's a nop. */
finalize_load(prog.arg, pcf->stack);
finalize_load(prog.arg, (uintptr_t)pcf->mtrr);

if (prog_entry(&prog) == NULL)
postcar_cache_invalid();
Expand Down
2 changes: 1 addition & 1 deletion src/commonlib/bsd/include/commonlib/bsd/elog.h
Expand Up @@ -3,7 +3,7 @@
#ifndef _COMMONLIB_BSD_ELOG_H_
#define _COMMONLIB_BSD_ELOG_H_

#include <inttypes.h>
#include <stdint.h>

#include <commonlib/bsd/cb_err.h>

Expand Down
12 changes: 6 additions & 6 deletions src/commonlib/bsd/include/commonlib/bsd/mem_chip_info.h
Expand Up @@ -14,16 +14,16 @@ enum mem_chip_type {
};

struct mem_chip_info {
uint8_t type; /* enum mem_chip_type */
uint8_t type; /* enum mem_chip_type */
uint8_t num_channels;
uint8_t reserved[6];
struct mem_chip_channel {
uint64_t density;
uint8_t io_width;
uint8_t manufacturer_id;
uint8_t revision_id[2];
uint64_t density; /* number in _bytes_, not Megabytes! */
uint8_t io_width; /* should be `8`, `16`, `32` or `64` */
uint8_t manufacturer_id; /* raw value from MR5 */
uint8_t revision_id[2]; /* raw values from MR6 and MR7 */
uint8_t reserved[4];
uint8_t serial_id[8]; /* LPDDR5 only */
uint8_t serial_id[8]; /* LPDDR5 only, MR47 - MR54 */
} channel[0];
};

Expand Down
2 changes: 1 addition & 1 deletion src/commonlib/fsp_relocate.c
Expand Up @@ -18,7 +18,7 @@
#pragma pack(pop)

#include <commonlib/helpers.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>

Expand Down
2 changes: 1 addition & 1 deletion src/commonlib/include/commonlib/coreboot_tables.h
Expand Up @@ -552,7 +552,7 @@ struct lb_tpm_physical_presence {
uint32_t ppi_address; /* Address of ACPI PPI communication buffer */
uint8_t tpm_version; /* 1: TPM1.2, 2: TPM2.0 */
uint8_t ppi_version; /* BCD encoded */
} __packed;
};


/*
Expand Down
26 changes: 24 additions & 2 deletions src/commonlib/include/commonlib/timestamp_serialized.h
Expand Up @@ -144,9 +144,9 @@ enum timestamp_id {
/* 990+ reserved for vendorcode extensions (990-999: Intel ME continued) */
TS_ME_ROM_START = 990,

/* 1000+ reserved for payloads (1000-1200: ChromeOS depthcharge) */
/* 1000+ reserved for payloads */

/* Depthcharge entry IDs start at 1000 */
/* 1000-1200: Depthcharge */
TS_DC_START = 1000,

TS_RO_PARAMS_INIT = 1001,
Expand All @@ -164,6 +164,16 @@ enum timestamp_id {

TS_KERNEL_START = 1101,
TS_KERNEL_DECOMPRESSION = 1102,

/* 1200-1300: Chrome OS Hypervisor */
TS_CRHV_BOOT = 1200,
TS_CRHV_PLATFORM_INIT = 1201,
TS_CRHV_SERVICES_STARTED = 1202,
TS_CRHV_HW_PASSTRHOUGH_START = 1203,
TS_CRHV_HW_PASSTRHOUGH_END = 1204,
TS_CRHV_PSTORE_START = 1205,
TS_CRHV_PSTORE_END = 1206,
TS_CRHV_VMM_START = 1207,
};

#define TS_NAME_DEF(id, id_end, desc) {(id), (id_end), STRINGIFY(id), (desc)}
Expand Down Expand Up @@ -333,6 +343,18 @@ static const struct timestamp_id_to_name {

TS_NAME_DEF(TS_KERNEL_START, 0, "jumping to kernel"),
TS_NAME_DEF(TS_KERNEL_DECOMPRESSION, 0, "starting kernel decompression/relocation"),

/* Chrome OS hypervisor */
TS_NAME_DEF(TS_CRHV_BOOT, 0, "hypervisor boot finished"),
TS_NAME_DEF(TS_CRHV_PLATFORM_INIT, 0, "hypervisor platform initialized"),
TS_NAME_DEF(TS_CRHV_SERVICES_STARTED, 0, "hypervisor services started"),
TS_NAME_DEF(TS_CRHV_HW_PASSTRHOUGH_START, TS_CRHV_HW_PASSTRHOUGH_END,
"hypervisor hardware passtrough setup start"),
TS_NAME_DEF(TS_CRHV_HW_PASSTRHOUGH_END, 0,
"hypervisor hardware passtrhough setup complete"),
TS_NAME_DEF(TS_CRHV_PSTORE_START, TS_CRHV_PSTORE_END, "hypervisor pstore init start"),
TS_NAME_DEF(TS_CRHV_PSTORE_END, 0, "hypervisor pstore init complete"),
TS_NAME_DEF(TS_CRHV_VMM_START, 0, "hypervisor OS VMM start"),
};

#endif
1 change: 1 addition & 0 deletions src/console/Kconfig
Expand Up @@ -268,6 +268,7 @@ endif
config CONSOLE_SPI_FLASH
bool "SPI Flash console output"
default n
depends on BOOT_DEVICE_SPI_FLASH
select BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY if !COMMON_CBFS_SPI_WRAPPER
help
Send coreboot debug output to the SPI Flash in the FMAP CONSOLE area
Expand Down
1 change: 0 additions & 1 deletion src/cpu/amd/agesa/family14/model_14_init.c
Expand Up @@ -6,7 +6,6 @@
#include <cpu/x86/mtrr.h>
#include <cpu/amd/mtrr.h>
#include <device/device.h>
#include <cpu/x86/pae.h>
#include <cpu/cpu.h>
#include <cpu/x86/cache.h>
#include <acpi/acpi.h>
Expand Down
1 change: 0 additions & 1 deletion src/cpu/amd/agesa/family15tn/model_15_init.c
Expand Up @@ -7,7 +7,6 @@
#include <cpu/amd/mtrr.h>
#include <cpu/x86/smm.h>
#include <device/device.h>
#include <cpu/x86/pae.h>
#include <cpu/cpu.h>
#include <cpu/x86/cache.h>
#include <acpi/acpi.h>
Expand Down
1 change: 0 additions & 1 deletion src/cpu/amd/agesa/family16kb/model_16_init.c
Expand Up @@ -6,7 +6,6 @@
#include <cpu/x86/mtrr.h>
#include <cpu/amd/mtrr.h>
#include <device/device.h>
#include <cpu/x86/pae.h>
#include <cpu/cpu.h>
#include <cpu/x86/cache.h>
#include <acpi/acpi.h>
Expand Down
2 changes: 0 additions & 2 deletions src/cpu/amd/pi/00730F01/model_16_init.c
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <cbmem.h>
#include <commonlib/helpers.h>
#include <console/console.h>
#include <cpu/amd/microcode.h>
Expand All @@ -10,7 +9,6 @@
#include <cpu/amd/mtrr.h>
#include <device/device.h>
#include <device/pci.h>
#include <cpu/x86/pae.h>
#include <cpu/cpu.h>
#include <cpu/x86/cache.h>
#include <smp/node.h>
Expand Down
4 changes: 1 addition & 3 deletions src/cpu/intel/car/romstage.c
Expand Up @@ -14,8 +14,6 @@
following as a guideline for acceptable stack usage. */
#define DCACHE_RAM_ROMSTAGE_STACK_SIZE 0x2000

static struct postcar_frame early_mtrrs;

static void romstage_main(void)
{
int i;
Expand Down Expand Up @@ -54,7 +52,7 @@ static void romstage_main(void)
if (CONFIG(SMM_TSEG))
smm_list_regions();

prepare_and_run_postcar(&early_mtrrs);
prepare_and_run_postcar();
/* We do not return here. */
}

Expand Down
1 change: 0 additions & 1 deletion src/cpu/intel/haswell/haswell_init.c
Expand Up @@ -2,7 +2,6 @@

#include <console/console.h>
#include <device/device.h>
#include <acpi/acpi.h>
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/msr.h>
Expand Down
3 changes: 0 additions & 3 deletions src/cpu/intel/model_2065x/model_2065x.h
Expand Up @@ -53,9 +53,6 @@
/* Lock MSRs */
void intel_model_2065x_finalize_smm(void);

/* Configure power limits for turbo mode */
void set_power_limits(u8 power_limit_1_time);

/* Sanity check config options. */
#if (CONFIG_SMM_TSEG_SIZE <= CONFIG_SMM_RESERVED_SIZE)
# error "CONFIG_SMM_TSEG_SIZE <= CONFIG_SMM_RESERVED_SIZE"
Expand Down
1 change: 0 additions & 1 deletion src/cpu/intel/model_2065x/model_2065x_init.c
Expand Up @@ -3,7 +3,6 @@
#include <assert.h>
#include <console/console.h>
#include <device/device.h>
#include <acpi/acpi.h>
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/msr.h>
Expand Down
2 changes: 0 additions & 2 deletions src/cpu/intel/model_206ax/model_206ax_init.c
Expand Up @@ -2,8 +2,6 @@

#include <console/console.h>
#include <device/device.h>
#include <acpi/acpi.h>
#include <arch/cpu.h>
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/msr.h>
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/intel/socket_FCBGA559/Kconfig
Expand Up @@ -17,7 +17,7 @@ config DCACHE_RAM_BASE

config DCACHE_RAM_SIZE
hex
default 0x4000
default 0x8000

config DCACHE_BSP_STACK_SIZE
hex
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/intel/socket_p/Kconfig
Expand Up @@ -12,7 +12,7 @@ config DCACHE_RAM_BASE

config DCACHE_RAM_SIZE
hex
default 0x8000
default 0x10000

config DCACHE_BSP_STACK_SIZE
hex
Expand Down
19 changes: 19 additions & 0 deletions src/cpu/x86/64bit/Makefile.inc
@@ -0,0 +1,19 @@
bootblock-y += mode_switch.S
ifneq ($(CONFIG_VBOOT_STARTS_BEFORE_BOOTBLOCK),y)
verstage-y += mode_switch.S
endif
romstage-y += mode_switch.S
postcar-y += mode_switch.S
ramstage-y += mode_switch.S

# Add --defsym=_start=0 to suppress a linker warning.
$(objcbfs)/pt: $(dir)/pt.S
$(CC_bootblock) $(CFLAGS_bootblock) $(CPPFLAGS_bootblock) -o $@.tmp $< -Wl,--section-start=.rodata=$(CONFIG_ARCH_X86_64_PGTBL_LOC),--defsym=_start=0
$(OBJCOPY_ramstage) -Obinary -j .rodata $@.tmp $@
rm $@.tmp

cbfs-files-y += pagetables
pagetables-file := $(objcbfs)/pt
pagetables-type := raw
pagetables-compression := none
pagetables-COREBOOT-position := $(CONFIG_ARCH_X86_64_PGTBL_LOC)
35 changes: 35 additions & 0 deletions src/cpu/x86/64bit/pt.S
@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0-only */

/*
* For reference see "AMD64 Architecture Programmer's Manual Volume 2",
* Document 24593-Rev. 3.31-July 2019 Chapter 5.3.4
*
* Page table attributes: WB, User+Supervisor, Present, Writeable, Accessed, Dirty
*/

.section .rodata
#define _PRES (1ULL << 0)
#define _RW (1ULL << 1)
#define _US (1ULL << 2)
#define _A (1ULL << 5)
#define _D (1ULL << 6)
#define _PS (1ULL << 7)
#define _GEN_DIR(a) (_PRES + _RW + _US + _A + (a))
#define _GEN_PAGE(a) (_PRES + _RW + _US + _PS + _A + _D + (a))

.global PM4LE
.align 32
PM4LE:
.quad _GEN_DIR(PDPE_table)

.align 4096
PDE_tables: /* identity map 2MiB pages */
.rept 2048
.quad _GEN_PAGE(0x200000 * ((. - PDE_tables) >> 3))
.endr

.align 4096
PDPE_table: /* Point to PDE */
.rept 4
.quad _GEN_DIR(PDE_tables + 4096 * ((. - PDPE_table) >> 3))
.endr
4 changes: 2 additions & 2 deletions src/cpu/x86/Makefile.inc
Expand Up @@ -3,8 +3,8 @@ subdirs-y += mtrr
subdirs-y += pae
subdirs-$(CONFIG_HAVE_SMI_HANDLER) += smm
subdirs-$(CONFIG_UDELAY_TSC) += tsc

all-$(CONFIG_ARCH_ALL_STAGES_X86_64) += 64bit/mode_switch.S
# Use ARCH_BOOTBLOCK_X86_64 as a proxy for knowing if 64bit is going to be used
subdirs-$(CONFIG_ARCH_BOOTBLOCK_X86_64) += 64bit

subdirs-$(CONFIG_PARALLEL_MP) += name
ramstage-$(CONFIG_PARALLEL_MP) += mp_init.c
Expand Down
22 changes: 0 additions & 22 deletions src/cpu/x86/fpu_enable.inc

This file was deleted.

67 changes: 57 additions & 10 deletions src/cpu/x86/mp_init.c
Expand Up @@ -3,7 +3,6 @@
#include <console/console.h>
#include <string.h>
#include <rmodule.h>
#include <arch/cpu.h>
#include <commonlib/helpers.h>
#include <cpu/cpu.h>
#include <cpu/intel/microcode.h>
Expand Down Expand Up @@ -860,6 +859,15 @@ static void trigger_smm_relocation(void)

static struct mp_callback *ap_callbacks[CONFIG_MAX_CPUS];

enum AP_STATUS {
/* AP takes the task but not yet finishes */
AP_BUSY = 1,
/* AP finishes the task or no task to run yet */
AP_NOT_BUSY
};

static atomic_t ap_status[CONFIG_MAX_CPUS];

static struct mp_callback *read_callback(struct mp_callback **slot)
{
struct mp_callback *ret;
Expand All @@ -881,10 +889,10 @@ static void store_callback(struct mp_callback **slot, struct mp_callback *val)
);
}

static enum cb_err run_ap_work(struct mp_callback *val, long expire_us)
static enum cb_err run_ap_work(struct mp_callback *val, long expire_us, bool wait_ap_finish)
{
int i;
int cpus_accepted;
int cpus_accepted, cpus_finish;
struct stopwatch sw;
int cur_cpu;

Expand Down Expand Up @@ -914,16 +922,28 @@ static enum cb_err run_ap_work(struct mp_callback *val, long expire_us)

do {
cpus_accepted = 0;
cpus_finish = 0;

for (i = 0; i < ARRAY_SIZE(ap_callbacks); i++) {
if (cur_cpu == i)
continue;
if (read_callback(&ap_callbacks[i]) == NULL)

if (read_callback(&ap_callbacks[i]) == NULL) {
cpus_accepted++;
/* Only increase cpus_finish if AP took the task and not busy */
if (atomic_read(&ap_status[i]) == AP_NOT_BUSY)
cpus_finish++;
}
}

/*
* if wait_ap_finish is true, need to make sure all CPUs finish task and return
* else just need to make sure all CPUs take task
*/
if (cpus_accepted == global_num_aps)
return CB_SUCCESS;
if (!wait_ap_finish || (cpus_finish == global_num_aps))
return CB_SUCCESS;

} while (expire_us <= 0 || !stopwatch_expired(&sw));

printk(BIOS_CRIT, "CRITICAL ERROR: AP call expired. %d/%d CPUs accepted.\n",
Expand All @@ -949,23 +969,32 @@ static void ap_wait_for_instruction(void)

per_cpu_slot = &ap_callbacks[cur_cpu];

/* Init ap_status[cur_cpu] to AP_NOT_BUSY and ready to take job */
atomic_set(&ap_status[cur_cpu], AP_NOT_BUSY);

while (1) {
struct mp_callback *cb = read_callback(per_cpu_slot);

if (cb == NULL) {
asm ("pause");
continue;
}
/*
* Set ap_status to AP_BUSY before store_callback(per_cpu_slot, NULL).
* it's to let BSP know APs take tasks and busy to avoid race condition.
*/
atomic_set(&ap_status[cur_cpu], AP_BUSY);

/* Copy to local variable before signaling consumption. */
memcpy(&lcb, cb, sizeof(lcb));
mfence();
store_callback(per_cpu_slot, NULL);
if (lcb.logical_cpu_number && (cur_cpu !=
lcb.logical_cpu_number))
continue;
else

if (lcb.logical_cpu_number == MP_RUN_ON_ALL_CPUS ||
(cur_cpu == lcb.logical_cpu_number))
lcb.func(lcb.arg);

atomic_set(&ap_status[cur_cpu], AP_NOT_BUSY);
}
}

Expand All @@ -974,7 +1003,15 @@ enum cb_err mp_run_on_aps(void (*func)(void *), void *arg, int logical_cpu_num,
{
struct mp_callback lcb = { .func = func, .arg = arg,
.logical_cpu_number = logical_cpu_num};
return run_ap_work(&lcb, expire_us);
return run_ap_work(&lcb, expire_us, false);
}

static enum cb_err mp_run_on_aps_and_wait_for_complete(void (*func)(void *), void *arg,
int logical_cpu_num, long expire_us)
{
struct mp_callback lcb = { .func = func, .arg = arg,
.logical_cpu_number = logical_cpu_num};
return run_ap_work(&lcb, expire_us, true);
}

enum cb_err mp_run_on_all_aps(void (*func)(void *), void *arg, long expire_us,
Expand Down Expand Up @@ -1009,6 +1046,16 @@ enum cb_err mp_run_on_all_cpus(void (*func)(void *), void *arg)
return mp_run_on_aps(func, arg, MP_RUN_ON_ALL_CPUS, 1000 * USECS_PER_MSEC);
}

enum cb_err mp_run_on_all_cpus_synchronously(void (*func)(void *), void *arg)
{
/* Run on BSP first. */
func(arg);

/* For up to 1 second for AP to finish previous work. */
return mp_run_on_aps_and_wait_for_complete(func, arg, MP_RUN_ON_ALL_CPUS,
1000 * USECS_PER_MSEC);
}

enum cb_err mp_park_aps(void)
{
struct stopwatch sw;
Expand Down
2 changes: 2 additions & 0 deletions src/cpu/x86/mtrr/Makefile.inc
@@ -1,13 +1,15 @@
ramstage-y += mtrr.c

ramstage-y += mtrrlib.c
postcar-y += mtrrlib.c
romstage-y += mtrrlib.c
bootblock-y += mtrrlib.c
verstage_x86-y += mtrrlib.c

romstage-y += earlymtrr.c
bootblock-y += earlymtrr.c
verstage_x86-y += earlymtrr.c
postcar-y += earlymtrr.c

bootblock-y += debug.c
romstage-y += debug.c
Expand Down
39 changes: 23 additions & 16 deletions src/cpu/x86/mtrr/earlymtrr.c
Expand Up @@ -5,20 +5,17 @@
#include <cpu/x86/msr.h>
#include <console/console.h>
#include <commonlib/bsd/helpers.h>
#include <stdint.h>

void var_mtrr_context_init(struct var_mtrr_context *ctx, void *arg)
void var_mtrr_context_init(struct var_mtrr_context *ctx)
{
ctx->upper_mask = (1U << (cpu_phys_address_size() - 32)) - 1;
ctx->max_var_mtrrs = get_var_mtrr_count();
ctx->used_var_mtrrs = 0;
ctx->arg = arg;
}

int var_mtrr_set_with_cb(struct var_mtrr_context *ctx, uintptr_t addr, size_t size,
int type, void (*callback)(const struct var_mtrr_context *ctx,
uintptr_t base_addr, size_t size,
msr_t base, msr_t mask))
int var_mtrr_set(struct var_mtrr_context *ctx, uintptr_t addr, size_t size, int type)
{
const uint32_t upper_mask = (1U << (cpu_phys_address_size() - 32)) - 1;
/* Utilize additional MTRRs if the specified size is greater than the
base address alignment. */
while (size != 0) {
Expand Down Expand Up @@ -47,9 +44,10 @@ int var_mtrr_set_with_cb(struct var_mtrr_context *ctx, uintptr_t addr, size_t si

base.hi = (uint64_t)addr >> 32;
base.lo = addr | type;
mask.hi = ctx->upper_mask;
mask.hi = upper_mask;
mask.lo = ~(mtrr_size - 1) | MTRR_PHYS_MASK_VALID;
callback(ctx, addr, mtrr_size, base, mask);
ctx->mtrr[ctx->used_var_mtrrs].base = base;
ctx->mtrr[ctx->used_var_mtrrs].mask = mask;
ctx->used_var_mtrrs++;

size -= mtrr_size;
Expand All @@ -59,16 +57,25 @@ int var_mtrr_set_with_cb(struct var_mtrr_context *ctx, uintptr_t addr, size_t si
return 0;
}

static void set_mtrr(const struct var_mtrr_context *ctx, uintptr_t base_addr, size_t size,
msr_t base, msr_t mask)
/* Romstage sets up a MTRR context in cbmem and sets up this pointer in postcar stage. */
__attribute__((used, __section__(".module_parameters"))) const volatile uintptr_t post_car_mtrrs;

void commit_mtrr_setup(const struct var_mtrr_context *ctx)
{
int i = var_mtrr_context_current_mtrr(ctx);
clear_all_var_mtrr();

wrmsr(MTRR_PHYS_BASE(i), base);
wrmsr(MTRR_PHYS_MASK(i), mask);
for (int i = 0; i < ctx->used_var_mtrrs; i++) {
wrmsr(MTRR_PHYS_BASE(i), ctx->mtrr[i].base);
wrmsr(MTRR_PHYS_MASK(i), ctx->mtrr[i].mask);
}
/* Enable MTRR */
msr_t mtrr_def_type = rdmsr(MTRR_DEF_TYPE_MSR);
mtrr_def_type.lo &= MTRR_DEF_TYPE_MASK;
mtrr_def_type.lo |= MTRR_DEF_TYPE_EN;
wrmsr(MTRR_DEF_TYPE_MSR, mtrr_def_type);
}

int var_mtrr_set(struct var_mtrr_context *ctx, uintptr_t addr, size_t size, int type)
void postcar_mtrr_setup(void)
{
return var_mtrr_set_with_cb(ctx, addr, size, type, set_mtrr);
commit_mtrr_setup((const struct var_mtrr_context *)post_car_mtrrs);
}
8 changes: 0 additions & 8 deletions src/device/device.c
Expand Up @@ -12,9 +12,6 @@
#include <stdlib.h>
#include <string.h>
#include <smp/spinlock.h>
#if ENV_X86
#include <arch/ebda.h>
#endif
#include <timer.h>

/** Pointer to the last device */
Expand Down Expand Up @@ -566,11 +563,6 @@ void dev_initialize(void)

printk(BIOS_INFO, "Initializing devices...\n");

#if ENV_X86
/* Ensure EBDA is prepared before Option ROMs. */
setup_default_ebda();
#endif

/* First call the mainboard init. */
init_dev(&dev_root);

Expand Down
1 change: 0 additions & 1 deletion src/device/dram/lpddr4.c
@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <console/console.h>
#include <cbmem.h>
#include <device/device.h>
#include <device/dram/lpddr4.h>
#include <memory_info.h>
Expand Down
3 changes: 3 additions & 0 deletions src/drivers/amd/agesa/heapmanager.c
@@ -1,6 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#pragma pack(push)
#include <AGESA.h>
#pragma pack(pop)

#include <amdlib.h>

#include <cbmem.h>
Expand Down
12 changes: 10 additions & 2 deletions src/drivers/amd/agesa/mtrr_fixme.c
Expand Up @@ -9,6 +9,7 @@
#include <cpu/x86/msr.h>
#include <cpu/x86/mtrr.h>
#include <northbridge/amd/agesa/agesa_helper.h>
#include <romstage_handoff.h>

static void set_range_uc(u32 base, u32 size)
{
Expand Down Expand Up @@ -51,14 +52,15 @@ void fixup_cbmem_to_UC(int s3resume)
set_range_uc(top_of_ram - 8 * MiB, 4 * MiB);
}

void recover_postcar_frame(struct postcar_frame *pcf, int s3resume)
static void recover_postcar_frame(struct postcar_frame *pcf)
{
msr_t base, mask;
int i;
int s3resume = romstage_handoff_is_resume();

/* Replicate non-UC MTRRs as left behind by AGESA.
*/
for (i = 0; i < pcf->ctx.max_var_mtrrs; i++) {
for (i = 0; i < pcf->mtrr->max_var_mtrrs; i++) {
mask = rdmsr(MTRR_PHYS_MASK(i));
base = rdmsr(MTRR_PHYS_BASE(i));
u32 size = ~(mask.lo & ~0xfff) + 1;
Expand Down Expand Up @@ -86,3 +88,9 @@ void recover_postcar_frame(struct postcar_frame *pcf, int s3resume)
MTRR_TYPE_WRBACK);
}
}

void fill_postcar_frame(struct postcar_frame *pcf)
{
pcf->skip_common_mtrr = 1;
recover_postcar_frame(pcf);
}
6 changes: 1 addition & 5 deletions src/drivers/amd/agesa/romstage.c
Expand Up @@ -33,7 +33,6 @@ static void ap_romstage_main(void);

static void romstage_main(void)
{
struct postcar_frame pcf;
struct sysinfo romstage_state;
struct sysinfo *cb = &romstage_state;
int cbmem_initted = 0;
Expand Down Expand Up @@ -78,10 +77,7 @@ static void romstage_main(void)

romstage_handoff_init(cb->s3resume);

postcar_frame_init(&pcf, HIGH_ROMSTAGE_STACK_SIZE);
recover_postcar_frame(&pcf, cb->s3resume);

run_postcar_phase(&pcf);
prepare_and_run_postcar();
/* We do not return. */
}

Expand Down
10 changes: 2 additions & 8 deletions src/drivers/crb/Kconfig
@@ -1,17 +1,11 @@
config CRB_TPM
bool
default n
help
CRB TPM driver is enabled!
Mainboard has Command Response Buffer support

config CRB_TPM_BASE_ADDRESS
hex
default 0xfed40000
help
Base Address of the CRB TPM Command Structure

config MAINBOARD_HAS_CRB_TPM
bool
default n
select CRB_TPM
help
Mainboard has Command Response Buffer support
8 changes: 3 additions & 5 deletions src/drivers/crb/Makefile.inc
@@ -1,5 +1,3 @@
bootblock-$(CONFIG_CRB_TPM) += tis.c tpm.c
verstage-$(CONFIG_CRB_TPM) += tis.c tpm.c
romstage-$(CONFIG_CRB_TPM) += tis.c tpm.c
ramstage-$(CONFIG_CRB_TPM) += tis.c tpm.c
postcar-$(CONFIG_CRB_TPM) += tis.c tpm.c
ifeq ($(CONFIG_CRB_TPM),y)
all-y += tis.c tpm.c
endif
1 change: 0 additions & 1 deletion src/drivers/generic/ioapic/ioapic.c
Expand Up @@ -3,7 +3,6 @@
#include <device/device.h>
#include "chip.h"
#include <arch/ioapic.h>
#include <cpu/x86/lapic.h>

static void ioapic_init(struct device *dev)
{
Expand Down
1 change: 0 additions & 1 deletion src/drivers/i2c/cs42l42/cs42l42.c
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpi.h>
#include <acpi/acpi_device.h>
#include <acpi/acpigen.h>
#include <console/console.h>
Expand Down
1 change: 0 additions & 1 deletion src/drivers/i2c/max98373/max98373.c
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpi.h>
#include <acpi/acpi_device.h>
#include <acpi/acpigen.h>
#include <console/console.h>
Expand Down
1 change: 0 additions & 1 deletion src/drivers/i2c/max98390/max98390.c
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <acpi/acpi.h>
#include <acpi/acpi_device.h>
#include <acpi/acpigen.h>
#include <console/console.h>
Expand Down
1 change: 0 additions & 1 deletion src/drivers/i2c/max98927/max98927.c
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpi.h>
#include <acpi/acpi_device.h>
#include <acpi/acpigen.h>
#include <console/console.h>
Expand Down
1 change: 0 additions & 1 deletion src/drivers/i2c/nau8825/nau8825.c
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpi.h>
#include <acpi/acpi_device.h>
#include <acpi/acpigen.h>
#include <console/console.h>
Expand Down
1 change: 0 additions & 1 deletion src/drivers/i2c/rt1011/rt1011.c
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpi.h>
#include <acpi/acpi_device.h>
#include <acpi/acpigen.h>
#include <console/console.h>
Expand Down
1 change: 0 additions & 1 deletion src/drivers/i2c/rt5663/rt5663.c
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpi.h>
#include <acpi/acpi_device.h>
#include <acpi/acpigen.h>
#include <console/console.h>
Expand Down
38 changes: 7 additions & 31 deletions src/drivers/i2c/tpm/Kconfig
Expand Up @@ -3,40 +3,10 @@ config I2C_TPM
help
I2C TPM driver is enabled!

config MAINBOARD_HAS_I2C_TPM_ATMEL
bool
default n
select I2C_TPM
help
Board has an Atmel I2C TPM support

config MAINBOARD_HAS_I2C_TPM_CR50
bool
default n
select I2C_TPM
help
Board has a Cr50 I2C TPM support

config MAINBOARD_HAS_I2C_TPM_GENERIC
bool
default n
select I2C_TPM
help
Board has a generic I2C TPM support

config MAINBOARD_NEEDS_I2C_TI50_WORKAROUND
bool
default n
help
Ti50 FW versions below 0.15 don't support the firmware_version or board_cfg registers,
and trying to access them causes I2C errors. This config will skip accesses to these
registers, and should be selected for boards using Ti50 chips with FW < 0.15. The config
will be removed once all Ti50 stocks are updated to 0.15 or higher.

config DRIVER_TIS_DEFAULT
bool
depends on I2C_TPM
default n if MAINBOARD_HAS_I2C_TPM_ATMEL
default n if TPM_ATMEL
default y

config DRIVER_TPM_I2C_BUS
Expand All @@ -58,3 +28,9 @@ config DRIVER_TPM_DISPLAY_TIS_BYTES
bool "TPM: Display the TIS transactions to I2C TPM chip"
default n
depends on I2C_TPM

config TPM_ATMEL
bool
default n
help
The mainboard has an Atmel TPM chip.
30 changes: 10 additions & 20 deletions src/drivers/i2c/tpm/Makefile.inc
@@ -1,25 +1,15 @@
ramstage-$(CONFIG_DRIVER_TIS_DEFAULT) += tis.c
romstage-$(CONFIG_DRIVER_TIS_DEFAULT) += tis.c
verstage-$(CONFIG_DRIVER_TIS_DEFAULT) += tis.c
bootblock-$(CONFIG_DRIVER_TIS_DEFAULT) += tis.c
postcar-$(CONFIG_DRIVER_TIS_DEFAULT) += tis.c
ifeq ($(CONFIG_TPM)$(CONFIG_I2C_TPM),yy)

ramstage-$(CONFIG_MAINBOARD_HAS_I2C_TPM_ATMEL) += tis_atmel.c
romstage-$(CONFIG_MAINBOARD_HAS_I2C_TPM_ATMEL) += tis_atmel.c
verstage-$(CONFIG_MAINBOARD_HAS_I2C_TPM_ATMEL) += tis_atmel.c
bootblock-$(CONFIG_MAINBOARD_HAS_I2C_TPM_ATMEL) += tis_atmel.c
postcar-$(CONFIG_MAINBOARD_HAS_I2C_TPM_ATMEL) += tis_atmel.c
all-$(CONFIG_DRIVER_TIS_DEFAULT) += tis.c

ramstage-$(CONFIG_MAINBOARD_HAS_I2C_TPM_GENERIC) += tpm.c
romstage-$(CONFIG_MAINBOARD_HAS_I2C_TPM_GENERIC) += tpm.c
verstage-$(CONFIG_MAINBOARD_HAS_I2C_TPM_GENERIC) += tpm.c
bootblock-$(CONFIG_MAINBOARD_HAS_I2C_TPM_GENERIC) += tpm.c
postcar-$(CONFIG_MAINBOARD_HAS_I2C_TPM_GENERIC) += tpm.c
ifeq ($(CONFIG_TPM_ATMEL),y)
all-y += tis_atmel.c
else ifeq ($(CONFIG_TPM_GOOGLE),y)
all-y += cr50.c
else
all-y += tpm.c
endif

ramstage-$(CONFIG_MAINBOARD_HAS_I2C_TPM_CR50) += cr50.c
romstage-$(CONFIG_MAINBOARD_HAS_I2C_TPM_CR50) += cr50.c
verstage-$(CONFIG_MAINBOARD_HAS_I2C_TPM_CR50) += cr50.c
bootblock-$(CONFIG_MAINBOARD_HAS_I2C_TPM_CR50) += cr50.c
postcar-$(CONFIG_MAINBOARD_HAS_I2C_TPM_CR50) += cr50.c
endif

ramstage-$(CONFIG_DRIVER_I2C_TPM_ACPI) += chip.c
12 changes: 5 additions & 7 deletions src/drivers/i2c/tpm/cr50.c
Expand Up @@ -36,6 +36,7 @@
#define CR50_TIMEOUT_NOIRQ_MS 20 /* Timeout for TPM ready without IRQ */
#define CR50_TIMEOUT_IRQ_MS 100 /* Timeout for TPM ready with IRQ */
#define CR50_DID_VID 0x00281ae0L
#define TI50_DID_VID 0x504a6666L

struct tpm_inf_dev {
int bus;
Expand Down Expand Up @@ -455,7 +456,7 @@ static int cr50_i2c_probe(struct tpm_chip *chip, uint32_t *did_vid)
rc = cr50_i2c_read(TPM_DID_VID(0), (uint8_t *)did_vid, 4);

/* Exit once DID and VID verified */
if (!rc && (*did_vid == CR50_DID_VID)) {
if (!rc && (*did_vid == CR50_DID_VID || *did_vid == TI50_DID_VID)) {
printk(BIOS_INFO, "done! DID_VID 0x%08x\n", *did_vid);
return 0;
}
Expand All @@ -474,7 +475,6 @@ static int cr50_i2c_probe(struct tpm_chip *chip, uint32_t *did_vid)

int tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr)
{
struct cr50_firmware_version ver;
uint32_t did_vid = 0;

if (dev_addr == 0) {
Expand All @@ -500,12 +500,10 @@ int tpm_vendor_init(struct tpm_chip *chip, unsigned int bus, uint32_t dev_addr)
printk(BIOS_DEBUG, "cr50 TPM 2.0 (i2c %u:0x%02x id 0x%x)\n",
bus, dev_addr, did_vid >> 16);

/* Ti50 FW version under 0.15 doesn't support board cfg command
TODO: remove this flag after all stocks Ti50 uprev to 0.15 or above */
if (!CONFIG(MAINBOARD_NEEDS_I2C_TI50_WORKAROUND) && tpm_first_access_this_boot()) {
if (tpm_first_access_this_boot()) {
/* This is called for the side-effect of printing the version string. */
cr50_get_firmware_version(&ver);
cr50_set_board_cfg();
cr50_get_firmware_version(NULL);
cr50_set_board_cfg();
}

chip->is_open = 1;
Expand Down
3 changes: 3 additions & 0 deletions src/drivers/intel/dptf/chip.h
Expand Up @@ -59,6 +59,9 @@ struct drivers_intel_dptf_config {
struct {
uint32_t oem_variables[DPTF_OEM_VARIABLE_COUNT];
} oem_data;

/* Rest of platform Power */
uint32_t prop;
};

#endif /* _DRIVERS_INTEL_DPTF_CHIP_H_ */
18 changes: 14 additions & 4 deletions src/drivers/intel/dptf/dptf.c
Expand Up @@ -372,7 +372,8 @@ static void write_tpch_methods(const struct dptf_platform_info *platform_info)
acpigen_write_device_end(); /* TPCH Device */
}

static void write_create_tpwr(const struct dptf_platform_info *platform_info)
static void write_create_tpwr(const struct drivers_intel_dptf_config *config,
const struct dptf_platform_info *platform_info)
{
acpigen_write_device("TPWR");
acpigen_write_name("_HID");
Expand All @@ -382,12 +383,21 @@ static void write_create_tpwr(const struct dptf_platform_info *platform_info)
acpigen_write_name_string("_STR", DEFAULT_POWER_STR);
acpigen_write_name_integer("PTYP", DPTF_GENERIC_PARTICIPANT_TYPE_POWER);
acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);

/* PROP method */
if(config->prop != 0) {
acpigen_write_method_serialized("PROP", 0);
acpigen_emit_byte(RETURN_OP);
acpigen_write_integer(config->prop);
acpigen_pop_len(); /* Method PROP */
}
acpigen_write_device_end(); /* TPWR Power Participant Device */
}

static void write_tpwr_methods(const struct dptf_platform_info *platform_info)
static void write_tpwr_methods(const struct drivers_intel_dptf_config *config,
const struct dptf_platform_info *platform_info)
{
write_create_tpwr(platform_info);
write_create_tpwr(config, platform_info);
}

static void write_create_tbat(const struct dptf_platform_info *platform_info)
Expand Down Expand Up @@ -449,7 +459,7 @@ static void write_device_definitions(const struct device *dev)
write_tpch_methods(platform_info);

if (CONFIG(DRIVERS_INTEL_DPTF_SUPPORTS_TPWR))
write_tpwr_methods(platform_info);
write_tpwr_methods(config, platform_info);

if (CONFIG(DRIVERS_INTEL_DPTF_SUPPORTS_TBAT))
write_tbat_methods(platform_info);
Expand Down