313 changes: 313 additions & 0 deletions Documentation/drivers/dptf.md
@@ -0,0 +1,313 @@
# Intel DPTF implementations in coreboot

## Introduction

Intel Dynamic Platform and Thermal Framework is a framework that can be used to
help regulate the thermal properties (i.e., temperature) of an Intel-based
computer. It does this by allowing the system designer to specify the different
components that can generate heat, and/or dissipate heat. Under DPTF, the
different components are referred to as `participants`. The different types of
functionality available in DPTF are specified in terms of different `policies`.

## Components ("Participants")

The participants that can be involved in the current implementation are:
- CPU (monolithic from a DPTF point-of-view)
- Note that the CPU's internal temperature sensor is used here
- 1 fan
- Up to 4 temperature sensors (TSRs)
- Battery charger

## Policies

In the current implementation, there are 3 different policies available:

### Passive Policy

The purpose of this policy is to monitor participant temperatures and is capable
of controlling performance and throttling available on platform devices in order
to regulate the temperatures of each participant. The temperature threshold
points are defined by a `_PSV` ACPI object within each participant.

### Critical Policy

The Critical Policy is used for gracefully suspending or powering off the system
when the temperature of participants exceeds critical threshold
temperatures. Suspend is effected by specifying temperatures in a `_CRT` object
for a participant, and poweroff is effected by specifying a temperature
threshold in a `_HOT` ACPI object.

### Active Policy

This policy monitors the temperature of participants and controls fans to spin
at varying speeds. These speeds are defined by the platform, and will be enabled
depending on the various temperatures reported by participants.

# Note about units

ACPI uses unusual units for specifying various physical measurements. For
example, temperatures are specified in 10ths of a degree K, and time is measured
in tenths of a second. Those oddities are abstracted away in the DPTF library,
by using degrees C for temperature, milliseconds for time, mW for power, and mA
for current.

## Differences from the static ASL files (soc/intel/common/acpi/dptf/*.asl)

1) TCPU had many redundant methods. The many references to \_SB.CP00._* are not
created anymore in recent SoCs and the ACPI spec says these are optional objects
anyway. The defaults that were returned by these methods were redundant (all
data was a 0). The following Methods were removed:

* _TSS
* _TPC
* _PTC
* _TSD
* _TDL
* _PSS
* _PDL

2) There is no more implicit inclusion of _ACn methods for TCPU (these must be
specified in the devicetree entries or by calling the DPTF acpigen API).

# ACPI Tables

DPTF relies on an assortment of ACPI tables to provide parameters to the DPTF
application. We will discuss the more important ones here.

1) _TRT - Thermal Relationship Table

This table is used when the Passive Policy is enabled, and is used to represent
the thermal relationships in the system that can be controlled passively (i.e.,
by throttling participants). A passive policy is defined by a Source (which
generates heat), a Target (typically a temperature sensor), a Sampling Period
(how often to check the temperature), an activation temperature threshold (for
when to begin throttling), and a relative priority.

2) _ART - Active Relationship Table

This table is used when the Active Policy is enabled, and is used to represent
active cooling relationships (i.e., which TSRs the fan can cool). An active
policy contains a Target (the device the fan can cool), a Weight to control
which participant needs more attention than others, and a list of temperature /
fan percentage pairs. The list of pairs defines the fan control percentage that
should be applied when the TSR reaches each successive threshold (_AC0 is the
highest threshold, and represents the highest fan control percentage).

3) PPCC - Participant Power Control Capabilities

This table is used to describe parameters for controlling the SoC's Running
Average Power Limits (RAPL, see below).

4) _FPS - Fan Performance States

This table describes the various fan speeds available for DPTF to use, along with
various informational properties.

5) PPSS - Participant Performance Supported States

This table describes performance states supported by a participant (typically
the battery charger).

# ACPI Methods

The Active and Passive policies also provide for short Methods to define
different kinds of temperature thresholds.

1) _AC0, _AC1, _AC2, _AC3, ..., _AC9

These Methods can provide up to 10 temperature thresholds. What these do is set
temperatures which act as the thresholds to active rows (fan speeds) in the
ART. _AC0 is intended to be the highest temperature thresholds, and the lowest
one can be any of them; leave the rest defined as 0 and they will be omitted
from the output.

These are optional and are enabled by selecting the Active Policy.

2) _PSV

_PSV is a temperature threshold that is used to indicate to DPTF that it should
begin taking passive measures (i.e., throttling of the Source) in order to
reduce the temperature of the Target in question. It will check on the
temperature according to the given sampling period.

This is optional and is enabled by selecting the Passive Policy.

3) _CRT and _HOT

When the temperature of the Source reaches the threshold specified in _CRT, then
the system is supposed to execute a "graceful suspend". Similarly, when the Source
reaches the temperature specified in _HOT, then the system is supposed to execute
a "graceful shutdown".

These are optional, and are enabled by selecting the Critical Policy.

# How to use the devicetree entries

The `drivers/intel/dptf` chip driver is organized into several sections:
- Policies
- Controls
- Options

The Policies section (`policies.active`, `policies.passive`, and
`policies.critical`) is where the components of each policy are defined.

## Active Policy

Each Active Policy is defined in terms of 4 parts:
1) A Source (this is implicitly defined as TFN1, the system fan)
2) A Target (this is the device that can be affected by the policy, i.e.,
this is a device that can be cooled by the fan)
3) A 'Weight', which is defined as the Source's contribution to the Target's
cooling capability (as a percentage, 0-100, often just left at 100).
4) A list of temperature-fan percentage pairs, which define temperature
thresholds that, when the Target reaches, the fan is defined to spin
at the corresponding percentage of full duty cycle.

An example definition in the devicetree:
```C
register "policies.active[0]" = "{
.target=DPTF_CPU,
.weight=100,
.thresholds={TEMP_PCT(85, 90),
TEMP_PCT(80, 69),
TEMP_PCT(75, 56),
TEMP_PCT(70, 46),
TEMP_PCT(65, 36),}}"
```

This example sets up a policy wherein the CPU temperature sensor can be cooled
by the fan. The 'weight' of this policy is 100% (this policy contributes 100% of
the CPU's active cooling capability). When the CPU temperature first crosses
65C, the fan is defined to spin at 36% of its duty cycle, and so forth up the
rest of the table (note that it *must* be defined from highest temperature/
percentage on down to the lowest).

## Passive Policy

Each Passive Policy is defined in terms of 5 parts:
1) Source - The device that can be throttled
2) Target - The device that controls the amount of throttling
3) Period - How often to check the temperature of the Target
4) Trip point - What temperature threshold to start throttling
5) Priority - A number indicating the relative priority between different
Policies

An example definition in the devicetree:
```C
register "policies.passive[0]" = "DPTF_PASSIVE(CHARGER, TEMP_SENSOR_1, 65, 60000)"
```

This example sets up a policy to begin throttling the charger performance when
temperature sensor 1 reaches 65C. The sampling period here is 60000 ms (60 s).
The Priority is defaulted to 100 in this case.

## Critical Policy

Each Critical Policy is defined in terms of 3 parts:
1) Source - A device that can trigger a critical event
2) Type - What type of critical event to trigger (S4-entry or shutdown)
3) Temperature - The temperature threshold that will cause the entry into S4 or
to shutdown the system.

An example definition in the devicetree:

```C
register "policies.critical[1]" = "DPTF_CRITICAL(CPU, 75, SHUTDOWN)"
```

This example sets up a policy wherein ACPI will cause the system to shutdown
(in a "graceful" manner) when the CPU temperature reaches 75C.

## Power Limits

Control over the SoC's Running Average Power Limits (RAPL) is one of the tools
that DPTF uses to enact Passive policies. DPTF can control both PL1 and PL2, if
the PPCC table is provided for the TCPU object. Each power limit is given the
following options:
1) Minimum power (in mW)
2) Maximum power (in mW)
3) Minimum time window (in ms)
4) Maximum time window (in ms)
5) Granularity, or minimum step size to control limits (in mW)

An example:
```C
register "controls.power_limits.pl1" = "{
.min_power = 3000,
.max_power = 15000,
.time_window_min = 28 * MSECS_PER_SEC,
.time_window_max = 32 * MSECS_PER_SEC,
.granularity = 200,}"
```

This example allow DPTF to control the SoC's PL1 level to between 3W and 15W,
over a time interval ranging from 28 to 32 seconds, and it can move PL1 in
increments of 200 mW.

## Charger Performance

The battery charger can be a large contributor of unwanted heat in a system that
has one. Controlling the rate of charging is another tool that DPTF uses to enact
Passive Policies. Each entry in the PPSS table consists of:
1) A 'Control' value - an opaque value that the platform firmware uses
to initiate a transition to the specified performance state. DPTF will call an
ACPI method called `TCHG.SPPC` (Set Participant Performance Capability) if
applicable, and will pass this opaque control value as its argument.
2) The intended charging rate (in mA).

Example:
```C
register "controls.charger_perf[0]" = "{ 255, 1700 }"
register "controls.charger_perf[1]" = "{ 24, 1500 }"
register "controls.charger_perf[2]" = "{ 16, 1000 }"
register "controls.charger_perf[3]" = "{ 8, 500 }"
```

In this example, when DPTF decides to throttle the charger, it has four different
performance states to choose from.

## Fan Performance

When using DPTF, the system fan (`TFN1`) is the device responsible for actively
cooling the other temperature sensors on the mainboard. A fan speed table can be
provided to DPTF to assist with fan control. Each entry holds the following:
1) Percentage of full duty to spin the fan at
2) Speed - Speed of the fan at that percentage; informational only, but given in
RPM
3) Noise - Amount of noise created by the fan at that percentage; informational
only, but given in tenths of a decibel (centibel).
4) Power - Amount of power consumed by the fan at that percentage; informational
only, but given in mA.

Example:
```C
register "controls.fan_perf[0]" = "{ 90, 6700, 220, 2200, }"
register "controls.fan_perf[1]" = "{ 80, 5800, 180, 1800, }"
register "controls.fan_perf[2]" = "{ 70, 5000, 145, 1450, }"
register "controls.fan_perf[3]" = "{ 60, 4900, 115, 1150, }"
register "controls.fan_perf[4]" = "{ 50, 3838, 90, 900, }"
register "controls.fan_perf[5]" = "{ 40, 2904, 55, 550, }"
register "controls.fan_perf[6]" = "{ 30, 2337, 30, 300, }"
register "controls.fan_perf[7]" = "{ 20, 1608, 15, 150, }"
register "controls.fan_perf[8]" = "{ 10, 800, 10, 100, }"
register "controls.fan_perf[9]" = "{ 0, 0, 0, 50, }"
```

In this example, the fan has 10 different performance states, each in an even
increment of 10 percentage points. This is common when specifying fine-grained
control of the fan, wherein DPTF will interpolate between the percentages in the
table for a given temperature threshold.

## Options

### Fan
1) Fine-grained control - a boolean (see Fan Performance section above)
2) Step-size - Recommended minimum step size (in percentage points) to adjust
the fan speed when using fine-grained control (ranges from 1 - 9).
3) Low-speed notify - If true, the platform will issue a `Notify (0x80)` to the
fan device if a low fan speed is detected.

### Temperature sensors
1) Hysteresis - The amount of hysteresis implemented in either circuitry or
the firmware that reads the temperature sensor (in degrees C).
2) Name - This name is applied to the _STR property of the sensor
40 changes: 0 additions & 40 deletions Documentation/mainboard/google/dragonegg.md

This file was deleted.

5 changes: 1 addition & 4 deletions Documentation/mainboard/index.md
Expand Up @@ -51,10 +51,6 @@ The boards in this section are not real mainboards, but emulators.

- [GA-H61M-S2PV](gigabyte/ga-h61m-s2pv.md)

## Google

- [Dragonegg](google/dragonegg.md)

## HP

- [Compaq 8200 Elite SFF](hp/compaq_8200_sff.md)
Expand Down Expand Up @@ -102,6 +98,7 @@ The boards in this section are not real mainboards, but emulators.
- [W530](lenovo/w530.md)
- [T430 / T530 / X230 / W530 common](lenovo/Ivy_Bridge_series.md)
- [T431s](lenovo/t431s.md)
- [X230s](lenovo/x230s.md)
- [Internal flashing](lenovo/ivb_internal_flashing.md)

### Haswell series
Expand Down
2 changes: 1 addition & 1 deletion Documentation/mainboard/lenovo/Ivy_Bridge_series.md
@@ -1,6 +1,6 @@
# Lenovo Ivy Bridge series

This information is valid for all supported models, except T430s and T431s.
This information is valid for all supported models, except T430s, [T431s](t431s.md) and [X230s](x230s.md).

## Flashing coreboot
```eval_rst
Expand Down
19 changes: 19 additions & 0 deletions Documentation/mainboard/lenovo/x230s.md
@@ -0,0 +1,19 @@
# ThinkPad Lenovo X230s

## Disassembly Instructions

You must remove the following parts to access the SPI flash chip:

![x230s_bc_removed](x230s_bc_removed.jpg)

* Base cover

The [Hardware Maintenance Manual](https://download.lenovo.com/ibmdl/pub/pc/pccbbs/
mobiles_pdf/x230s_hmm_en_0c10860_01.pdf) could be used as a guidance of disassembly.

The SPI flash chip (W25Q128.V in the form of SOIC-8 for the author's X230s, but varying is possible)
is located at the circled place.

Unlike [most Ivy Bridge ThinkPads](Ivy_Bridge_series.md), X230s has a single 16MiB SPI flash chip.

The general [flashing tutorial](../../flash_tutorial/index.md) has more details.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
128 changes: 128 additions & 0 deletions Documentation/mainboard/ocp/deltalake.md
@@ -0,0 +1,128 @@
# OCP Delta Lake

This page describes coreboot support status for the [OCP] (Open Compute Project)
Delta Lake server platform.

## Introduction

OCP Delta Lake server platform is a component of multi-host server system
Yosemite-V3. Both were announced by Facebook and Intel in [OCP virtual summit 2020].

Delta Lake server is a single socket Cooper Lake Scalable Processor server.

Yosemite-V3 has multiple configurations. Depending on configurations, it may
host up to 4 Delta Lake servers in one sled.

Yosemite-V3 and Delta Lake are currently in DVT phase. Facebook, Intel and partners
jointly develop FSP/coreboot/LinuxBoot stack on Delta Lake as an alternative solution.

## Required blobs

This board currently requires:
- FSP blob: The blob (Intel Cooper Lake Scalable Processor Firmware Support Package)
is not yet available to the public. It will be made public some time after the MP
(Mass Production) of CooperLake Scalable Processor when the FSP is mature.
- Microcode: Not yet available to the public.
- ME binary: Not yet available to the public.

## Payload
- LinuxBoot: This is necessary only if you use LinuxBoot as coreboot payload.
U-root as initramfs, is used in the joint development. It can be built
following [All about u-root].

## Flashing coreboot

To do in-band FW image update, use [flashrom]:
flashrom -p internal:ich_spi_mode=hwseq -c "Opaque flash chip" --ifd \
-i bios --noverify-all -w <path to coreboot image>

From OpenBMC, to update FW image:
fw-util slotx --update bios <path to coreboot image>

To power off/on the host:
power-util slotx off
power-util slotx on

To connect to console through SOL (Serial Over Lan):
sol-util slotx

## Working features
The solution is developed using LinuxBoot payload with Linux kernel 5.2.9, and [u-root]
as initramfs.
- SMBIOS:
- Type 0 -- BIOS Information
- Type 1 -- System Information
- Type 2 -- Baseboard Information
- Type 3 -- System Enclosure or Chassis
- Type 4 -- Processor Information
- Type 8 -- Port Connector Information
- Type 9 -- PCI Slot Information
- Type 11 -- OEM String
- Type 13 -- BIOS Language Information
- Type 16 -- Physical Memory Array
- Type 19 -- Memory Array Mapped Address
- Type 127 -- End-of-Table

- BMC integration:
- BMC readiness check
- IPMI commands
- watchdog timer
- POST complete pin acknowledgement
- SEL record generation
- Early serial output
- port 80h direct to GPIO
- ACPI tables: APIC/DSDT/FACP/FACS/HPET/MCFG/SPMI/SRAT/SLIT/SSDT
- Skipping memory training upon subsequent reboots by using MRC cache
- BMC crash dump
- Error injection through ITP

## Firmware configurations
[ChromeOS VPD] is used to store most of the firmware configurations.
RO_VPD region holds default values, while RW_VPD region holds customized
values.

VPD variables supported are:
- firmware_version: This variable holds overall firmware version. coreboot
uses that value to populate smbios type 1 version field.

## Known issues
- Even though CPX-SP FSP is based on FSP 2.2 framework, it does not
support FSP_USES_CB_STACK. An IPS ticket is filed with Intel.
- VT-d is not supported. An IPS ticket is filed with Intel.
- PCIe bifuration is not supported. An IPS ticket is filed with Intel.
- ME based power capping. This is a bug in ME. An IPS ticket is filed
with Intel.
- RO_VPD region as well as other RO regions are not write protected.
- HECI is not set up correctly, so BMC is not able to get PCH and DIMM
temperature sensor readings.

## Feature gaps
- Delta Lake DVT is not supported, as we only have Delta Lake EVT servers
at the moment.
- SMBIOS:
- Type 7 -- Cache Information
- Type 17 -- Memory Device
- Type 38 -- IPMI Device Information
- Type 41 -- Onboard Devices Extended Information
- ACPI:
- DMAR
- PFR/CBnT

## Technology

```eval_rst
+------------------------+---------------------------------------------+
| Processor (1 socket) | Intel Cooper Lake Scalable Processor |
+------------------------+---------------------------------------------+
| BMC | Aspeed AST 2500 |
+------------------------+---------------------------------------------+
| PCH | Intel Lewisburg C621 |
+------------------------+---------------------------------------------+
```

[OCP]: https://www.opencompute.org
[OCP virtual summit 2020]: https://www.opencompute.org/summit/virtual-summit/schedule
[flashrom]: https://flashrom.org/Flashrom
[All about u-root]: https://github.com/linuxboot/book/tree/master/u-root
[u-root]: https://u-root.org/
[ChromeOS VPD]: https://chromium.googlesource.com/chromiumos/platform/vpd/+/master/README.md
4 changes: 2 additions & 2 deletions Documentation/mainboard_io_trap_handler_sample.c
Expand Up @@ -20,7 +20,7 @@ int mainboard_io_trap_handler(int smif)
switch (smif) {
case 0x99:
printk(BIOS_DEBUG, "Sample\n");
smm_get_gnvs()->smif = 0;
gnvs->smif = 0;
break;
default:
return 0;
Expand All @@ -32,6 +32,6 @@ int mainboard_io_trap_handler(int smif)
* For now, we force the return value to 0 and log all traps to
* see what's going on.
*/
//smm_get_gnvs()->smif = 0;
//gnvs->smif = 0;
return 1;
}
16 changes: 14 additions & 2 deletions Documentation/tutorial/part1.md
Expand Up @@ -19,9 +19,21 @@ Download, configure, and build coreboot
$ cd coreboot

### Step 3 - Build the coreboot toolchain
Please note that this can take a significant amount of time.
Please note that this can take a significant amount of time. Use `CPUS=` to
specify number of `make` jobs to run in parallel.

$ make crossgcc-i386 CPUS=$(nproc)
This will list toolchain options and supported architectures:

$ make help_toolchain

Here are some examples:

$ make crossgcc-i386 CPUS=$(nproc) # build i386 toolchain
$ make crossgcc-aarch64 CPUS=$(nproc) # build Aarch64 toolchain
$ make crossgcc-riscv CPUS=$(nproc) # build RISC-V toolchain

Note that the i386 toolchain is currently used for all x86 platforms, including
x86_64.

Also note that you can possibly use your system toolchain, but the results are
not reproducible, and may have issues, so this is not recommended. See step 5
Expand Down
3 changes: 1 addition & 2 deletions Documentation/tutorial/part2.md
Expand Up @@ -108,8 +108,7 @@ in the source files. To see errors that are already present, build the files in
the repository by running `make lint` in the coreboot directory. Alternatively,
if you want to run `make lint` on a specific directory, run:

for file in $(git ls-files | grep <filepath>); do \
util/lint/checkpatch.pl --file $file --terse; done
util/lint/lint-007-checkpatch <filepath>

where `filepath` is the filepath of the directory (ex. `src/cpu/amd/car`).

Expand Down
29 changes: 29 additions & 0 deletions MAINTAINERS
Expand Up @@ -294,6 +294,15 @@ S: Maintained
F: src/mainboard/libretrend/lt1000


OCP DELTALAKE MAINBOARD
M: Jonathan Zhang <jonzhang@fb.com>
M: Reddy Chagam <anjaneya.chagam@intel.com>
M: Johnny Lin <Johnny_Lin@wiwynn.com>
M: Morgan Jang <Morgan_Jang@wiwynn.com>
M: Ryback Hung <<Ryback.Hung@quantatw.com>
M: Bryant Ou <Bryant.Ou@quantatw.com>
S: Supported
F: src/mainboard/ocp/deltalake

OCP TIOGAPASS MAINBOARD
M: Jonathan Zhang <jonzhang@fb.com>
Expand Down Expand Up @@ -339,6 +348,14 @@ F: src/mainboard/protectli/



PRODRIVE HERMES MAINBOARD
M: Christian Walter <christian.walter@9elements.com>
M: Patrick Rudolph <patrick.rudolph@9elements.com>
S: Maintained
F: src/mainboard/prodrive/hermes



PURISM MAINBOARDS
M: Matt DeVillier <matt.devillier@puri.sm>
S: Supported
Expand Down Expand Up @@ -506,6 +523,18 @@ S: Maintained
F: /src/soc/intel/braswell
F: /src/vendorcode/intel/fsp/fsp1_1/braswell

INTEL Xeon Sacalable Processor Family
M: Jonathan Zhang <jonzhang@fb.com>
M: Reddy Chagam <anjaneya.chagam@intel.com>
M: Johnny Lin <Johnny_Lin@wiwynn.com>
M: Morgan Jang <Morgan_Jang@wiwynn.com>
M: Ryback Hung <<Ryback.Hung@quantatw.com>
M: Bryant Ou <Bryant.Ou@quantatw.com>
S: Supported
F: src/soc/intel/xeon_sp
F: src/vendorcode/intel/fsp/fsp2_0/skylake_sp
F: src/vendorcode/intel/fsp/fsp2_0/copperlake_sp

ORPHANED ARM SOCS
S: Orphaned
F: src/cpu/armltd/
Expand Down
17 changes: 14 additions & 3 deletions Makefile
Expand Up @@ -61,8 +61,6 @@ endif
# Disable implicit/built-in rules to make Makefile errors fail fast.
.SUFFIXES:

HOSTCC := $(if $(shell type gcc 2>/dev/null),gcc,cc)
HOSTCXX = g++
HOSTCFLAGS := -g
HOSTCXXFLAGS := -g

Expand All @@ -83,6 +81,8 @@ help_coreboot help::
@echo ' distclean - Remove build artifacts and config files'
@echo ' doxygen - Build doxygen documentation for coreboot'
@echo ' doxyplatform - Build doxygen documentation for the current platform'
@echo ' sphinx - Build sphinx documentation for coreboot'
@echo ' sphinx-lint - Build sphinx documenttion for coreboot with warnings as errors'
@echo ' filelist - Show files used in current build'
@echo ' printall - print makefile info for debugging'
@echo ' gitconfig - set up git to submit patches to coreboot'
Expand Down Expand Up @@ -126,6 +126,11 @@ endif
rm -f $@.tmp

ifeq ($(NOCOMPILE),1)
# We also don't use .xcompile in the no-compile situations, so
# provide some reasonable defaults.
HOSTCC ?= $(if $(shell type gcc 2>/dev/null),gcc,cc)
HOSTCXX ?= g++

include $(TOPLEVEL)/Makefile.inc
include $(TOPLEVEL)/payloads/Makefile.inc
include $(TOPLEVEL)/util/testing/Makefile.inc
Expand Down Expand Up @@ -419,6 +424,12 @@ cscope-project: clean-cscope $(obj)/project_filelist.txt
cscope:
cscope -bR

sphinx:
$(MAKE) -C Documentation -f Makefile.sphinx html

sphinx-lint:
$(MAKE) SPHINXOPTS=-W -C Documentation -f Makefile.sphinx html

doxy: doxygen
doxygen:
$(DOXYGEN) Documentation/Doxyfile.coreboot
Expand Down Expand Up @@ -465,5 +476,5 @@ distclean: clean clean-ctags clean-cscope distclean-payloads distclean-utils
rm -rf coreboot-builds coreboot-builds-chromeos
rm -f abuild*.xml junit.xml* util/lint/junit.xml

.PHONY: $(PHONY) clean clean-for-update clean-cscope cscope distclean doxygen doxy doxygen_simple
.PHONY: $(PHONY) clean clean-for-update clean-cscope cscope distclean doxygen doxy doxygen_simple sphinx sphinx-lint
.PHONY: ctags-project cscope-project clean-ctags
5 changes: 4 additions & 1 deletion Makefile.inc
Expand Up @@ -196,12 +196,15 @@ ifeq ($(CONFIG_USE_BLOBS),y)
# until expressly requested and enabled with --checkout
forgetthis:=$(if $(GIT),$(shell git submodule update --init --checkout 3rdparty/blobs))
forgetthis:=$(if $(GIT),$(shell git submodule update --init --checkout 3rdparty/intel-microcode))
ifeq ($(CONFIG_PLATFORM_USES_FSP1_0)$(CONFIG_PLATFORM_USES_FSP1_1)$(CONFIG_PLATFORM_USES_FSP2_0),y)
ifeq ($(CONFIG_FSP_USE_REPO),y)
forgetthis:=$(if $(GIT),$(shell git submodule update --init --checkout 3rdparty/fsp))
endif
ifeq ($(CONFIG_USE_AMD_BLOBS),y)
forgetthis:=$(if $(GIT),$(shell git submodule update --init --checkout 3rdparty/amd_blobs))
endif
ifeq ($(CONFIG_USE_QC_BLOBS),y)
forgetthis:=$(if $(GIT),$(shell git submodule update --init --checkout 3rdparty/qc_blobs))
endif
endif
UPDATED_SUBMODULES:=1
COREBOOT_EXPORTS += UPDATED_SUBMODULES
Expand Down
1 change: 0 additions & 1 deletion configs/builder/config.lenovo_t420
Expand Up @@ -12,7 +12,6 @@ CONFIG_NO_POST=y
CONFIG_GBE_BIN_PATH="site-local/gbe.bin"
CONFIG_PCIEXP_CLK_PM=y
CONFIG_PCIEXP_L1_SUB_STATE=y
CONFIG_LPC_TPM=y
CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x80000
CONFIG_PAYLOAD_NONE=y
CONFIG_ONBOARD_VGA_IS_PRIMARY=y
1 change: 0 additions & 1 deletion configs/builder/config.lenovo_t420s
Expand Up @@ -12,7 +12,6 @@ CONFIG_NO_POST=y
CONFIG_GBE_BIN_PATH="site-local/gbe.bin"
CONFIG_PCIEXP_CLK_PM=y
CONFIG_PCIEXP_L1_SUB_STATE=y
CONFIG_LPC_TPM=y
CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x80000
CONFIG_PAYLOAD_NONE=y
CONFIG_ONBOARD_VGA_IS_PRIMARY=y
1 change: 0 additions & 1 deletion configs/builder/config.lenovo_t430s
Expand Up @@ -12,7 +12,6 @@ CONFIG_NO_POST=y
CONFIG_GBE_BIN_PATH="site-local/gbe.bin"
CONFIG_PCIEXP_CLK_PM=y
CONFIG_PCIEXP_L1_SUB_STATE=y
CONFIG_LPC_TPM=y
CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x80000
CONFIG_PAYLOAD_NONE=y
CONFIG_ONBOARD_VGA_IS_PRIMARY=y
1 change: 0 additions & 1 deletion configs/builder/config.lenovo_t520
Expand Up @@ -12,7 +12,6 @@ CONFIG_NO_POST=y
CONFIG_GBE_BIN_PATH="site-local/gbe.bin"
CONFIG_PCIEXP_CLK_PM=y
CONFIG_PCIEXP_L1_SUB_STATE=y
CONFIG_LPC_TPM=y
CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x80000
CONFIG_PAYLOAD_NONE=y
CONFIG_ONBOARD_VGA_IS_PRIMARY=y
1 change: 0 additions & 1 deletion configs/builder/config.lenovo_t530
Expand Up @@ -12,7 +12,6 @@ CONFIG_NO_POST=y
CONFIG_GBE_BIN_PATH="site-local/gbe.bin"
CONFIG_PCIEXP_CLK_PM=y
CONFIG_PCIEXP_L1_SUB_STATE=y
CONFIG_LPC_TPM=y
CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x80000
CONFIG_PAYLOAD_NONE=y
CONFIG_ONBOARD_VGA_IS_PRIMARY=y
1 change: 0 additions & 1 deletion configs/builder/config.lenovo_x220
Expand Up @@ -12,7 +12,6 @@ CONFIG_NO_POST=y
CONFIG_GBE_BIN_PATH="site-local/gbe.bin"
CONFIG_PCIEXP_CLK_PM=y
CONFIG_PCIEXP_L1_SUB_STATE=y
CONFIG_LPC_TPM=y
CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x80000
CONFIG_PAYLOAD_NONE=y
CONFIG_ONBOARD_VGA_IS_PRIMARY=y
1 change: 0 additions & 1 deletion configs/builder/config.lenovo_x220i
Expand Up @@ -12,7 +12,6 @@ CONFIG_NO_POST=y
CONFIG_GBE_BIN_PATH="site-local/gbe.bin"
CONFIG_PCIEXP_CLK_PM=y
CONFIG_PCIEXP_L1_SUB_STATE=y
CONFIG_LPC_TPM=y
CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x80000
CONFIG_PAYLOAD_NONE=y
CONFIG_ONBOARD_VGA_IS_PRIMARY=y
1 change: 0 additions & 1 deletion configs/builder/config.lenovo_x230
Expand Up @@ -12,7 +12,6 @@ CONFIG_NO_POST=y
CONFIG_GBE_BIN_PATH="site-local/gbe.bin"
CONFIG_PCIEXP_CLK_PM=y
CONFIG_PCIEXP_L1_SUB_STATE=y
CONFIG_LPC_TPM=y
CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x80000
CONFIG_PAYLOAD_NONE=y
CONFIG_ONBOARD_VGA_IS_PRIMARY=y
4 changes: 2 additions & 2 deletions configs/config.pcengines_apu1
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.12.0.2"
CONFIG_LOCALVERSION="v4.12.0.3"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_NO_GFX_INIT=y
Expand All @@ -19,4 +19,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.18"
CONFIG_SORTBOOTORDER_REVISION_ID="v4.6.19"
4 changes: 2 additions & 2 deletions configs/config.pcengines_apu2
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.12.0.2"
CONFIG_LOCALVERSION="v4.12.0.3"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_BOARD_PCENGINES_APU2=y
Expand All @@ -21,4 +21,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.18"
CONFIG_SORTBOOTORDER_REVISION_ID="v4.6.19"
4 changes: 2 additions & 2 deletions configs/config.pcengines_apu3
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.12.0.2"
CONFIG_LOCALVERSION="v4.12.0.3"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_BOARD_PCENGINES_APU3=y
Expand All @@ -21,4 +21,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.18"
CONFIG_SORTBOOTORDER_REVISION_ID="v4.6.19"
4 changes: 2 additions & 2 deletions configs/config.pcengines_apu4
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.12.0.2"
CONFIG_LOCALVERSION="v4.12.0.3"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_BOARD_PCENGINES_APU4=y
Expand All @@ -21,4 +21,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.18"
CONFIG_SORTBOOTORDER_REVISION_ID="v4.6.19"
4 changes: 2 additions & 2 deletions configs/config.pcengines_apu5
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v4.12.0.2"
CONFIG_LOCALVERSION="v4.12.0.3"
CONFIG_VENDOR_PCENGINES=y
CONFIG_PAYLOAD_CONFIGFILE="$(top)/src/mainboard/$(MAINBOARDDIR)/seabios_config"
CONFIG_BOARD_PCENGINES_APU5=y
Expand All @@ -21,4 +21,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.18"
CONFIG_SORTBOOTORDER_REVISION_ID="v4.6.19"
File renamed without changes.
2 changes: 1 addition & 1 deletion payloads/external/Makefile.inc
Expand Up @@ -19,7 +19,7 @@ endif
ifeq ($(CONFIG_PAYLOAD_DEPTHCHARGE),y)
PAYLOAD_CONFIG=payloads/external/depthcharge/depthcharge/.config
$(PAYLOAD_CONFIG): payloads/external/depthcharge/depthcharge/build/depthcharge.elf
ifeq ($(call strip_quotes,$(CONFIG_MAINBOARD_DEPTHCHARGE))),)
ifeq ($(call strip_quotes,$(CONFIG_MAINBOARD_DEPTHCHARGE)),)
BOARD=$(call ws_to_under,$(call strip_quotes,$(call tolower,$(CONFIG_MAINBOARD_PART_NUMBER))))
else
BOARD=$(CONFIG_MAINBOARD_DEPTHCHARGE)
Expand Down
3 changes: 1 addition & 2 deletions payloads/external/depthcharge/Makefile
Expand Up @@ -50,8 +50,7 @@ fetch: $(project_dir)

# Check out the requested version of the tree
# Don't write a file for master branch so the latest remote version is always used
$(project_dir)/.version_$(TAG-y):
$(MAKE) fetch
$(project_dir)/.version_$(TAG-y): fetch
echo " Checking out $(project_name) revision $(TAG-y)"
rm -f $(project_dir)/.version_*
cd $(project_dir); \
Expand Down
2 changes: 1 addition & 1 deletion payloads/external/tianocore/Makefile
Expand Up @@ -66,7 +66,7 @@ update: $(project_dir)
else \
echo " Working directory not clean; will not overwrite"; \
fi; \
git submodule update --init --recursive
git submodule update --init

checktools:
echo "Checking uuid-dev..."
Expand Down
13 changes: 13 additions & 0 deletions payloads/libpayload/Kconfig
Expand Up @@ -334,6 +334,19 @@ config FONT_SCALE_FACTOR
By default (value of 0), the scale factor is automatically
calculated to ensure at least 130 columns (when possible).

config CBGFX_FAST_RESAMPLE
bool "CBGFX: use faster (less pretty) image scaling"
default n
help
When payloads use the CBGFX library to draw .BMPs on the screen,
they will be resampled with an anti-aliasing filter to scale to the
requested output size. The default implementation should normally be
fast enough, but if desired this option can make it about 50-100%
faster at the cost of quality. (It changes the 'a' parameter in the
Lanczos resampling algorithm from 3 to 2.)

Only affects .BMPs that aren't already provided at the right size.

config PC_I8042
bool "A common PC i8042 driver"
default y if PC_KEYBOARD || PC_MOUSE
Expand Down
9 changes: 1 addition & 8 deletions payloads/libpayload/arch/arm64/exception.c
Expand Up @@ -32,7 +32,6 @@

u64 exception_stack[2*KiB] __attribute__((aligned(16)));
u64 *exception_stack_end = exception_stack + ARRAY_SIZE(exception_stack);
extern unsigned int test_exc;

struct exception_handler_info
{
Expand Down Expand Up @@ -111,13 +110,7 @@ void exception_dispatch(struct exception_state *state, int idx)
/* Few words below SP in case we need state from a returned function. */
dump_stack(state->sp - 32, 512);

if (test_exc) {
state->elr += 4;
test_exc = 0;
printf("returning back now\n");
}
else
halt();
halt();
}

void exception_init(void)
Expand Down
2 changes: 1 addition & 1 deletion payloads/libpayload/arch/arm64/libpayload.ldscript
Expand Up @@ -28,7 +28,7 @@
*/

OUTPUT_FORMAT("elf64-littleaarch64","elf64-littleaarch64", "elf64-littleaarch64")
OUTPUT_ARCH(arm64)
OUTPUT_ARCH(aarch64)

ENTRY(_entry)

Expand Down
15 changes: 0 additions & 15 deletions payloads/libpayload/arch/arm64/main.c
Expand Up @@ -35,19 +35,6 @@ int main_argc; /**< The argc value to pass to main() */
/** The argv value to pass to main() */
char *main_argv[MAX_ARGC_COUNT];

unsigned int test_exc;

static int test_exception(void)
{
uint64_t *a = (uint64_t *)0xfffffffff0000000ULL;

test_exc = 1;

printf("%llx\n", *a);

return 0;
}

/*
* Func: pre_sysinfo_scan_mmu_setup
* Desc: We need to setup and enable MMU before we can go to scan coreboot
Expand Down Expand Up @@ -126,10 +113,8 @@ void start_main(void)
console_init();
#endif

printf("ARM64: Libpayload %s\n",__func__);
exception_init();

test_exception();
/*
* Any other system init that has to happen before the
* user gets control goes here.
Expand Down
34 changes: 31 additions & 3 deletions payloads/libpayload/arch/x86/apic.c
Expand Up @@ -104,7 +104,7 @@ uint8_t apic_id(void)
return id;
}

void apic_delay(unsigned int usec)
void apic_start_delay(unsigned int usec)
{
die_if(!ticks_per_ms, "apic_init_timer was not run.");
die_if(timer_waiting, "timer already started.");
Expand All @@ -124,25 +124,40 @@ void apic_delay(unsigned int usec)
timer_waiting = 1;

apic_write32(APIC_TIMER_INIT_COUNT, ticks);
enable_interrupts();
}


void apic_wait_delay(void)
{
/* Loop in case another interrupt has fired and resumed execution. */
do {
disable_interrupts();
/* Note: when we test timer_waiting, interrupts are disabled by the line
* above and the cli below. */
while (timer_waiting) {
asm volatile(
"sti\n\t"
"hlt\n\t"
/* Disable interrupts to prevent a race condition
* between checking timer_waiting and executing the hlt
* instruction again. */
"cli\n\t");
} while (timer_waiting);
}

/* Leave hardware interrupts enabled. */
enable_interrupts();
}

void apic_delay(unsigned int usec)
{
apic_start_delay(usec);
apic_wait_delay();
}

static void timer_interrupt_handler(u8 vector)
{
timer_waiting = 0;
apic_eoi(APIC_TIMER_VECTOR);
}

static void suprious_interrupt_handler(u8 vector) {}
Expand Down Expand Up @@ -204,6 +219,7 @@ static void apic_reset_all_lvts(void)
uint8_t max = apic_max_lvt_entries();
for (int i = 0; i <= max; ++i) {
uint32_t offset = APIC_LVT_TIMER + APIC_LVT_SIZE * i;
apic_eoi(i);
apic_write32(offset, APIC_MASKED_BIT);
}
}
Expand Down Expand Up @@ -248,6 +264,16 @@ static void apic_init_timer(void)
apic_write32(APIC_LVT_TIMER, APIC_TIMER_VECTOR);
}

static void apic_sw_disable(void)
{
uint32_t reg = apic_read32(APIC_SPURIOUS);

reg &= ~APIC_SW_ENABLED_BIT;
printf("%s: writing %#x to %#x\n", __func__, reg, APIC_SPURIOUS);

apic_write32(APIC_SPURIOUS, reg);
}

static void apic_sw_enable(void)
{
uint32_t reg = apic_read32(APIC_SPURIOUS);
Expand Down Expand Up @@ -280,13 +306,15 @@ void apic_init(void)
die_if(!(apic_capabilities() & XACPI), "APIC is not supported");

apic_bar_reg = _rdmsr(APIC_BASE_MSR);
printf("apic_bar_reg is 0x%llx\n", apic_bar_reg);

die_if(!(apic_bar_reg & XAPIC_ENABLED_BIT), "APIC is not enabled");
die_if(apic_bar_reg & X2APIC_ENABLED_BIT,
"APIC is configured in x2APIC mode which is not supported");

apic_bar = (uint32_t)(apic_bar_reg & APIC_BASE_MASK);

apic_sw_disable();
apic_reset_all_lvts();
apic_set_task_priority(0);
apic_setup_spurious();
Expand Down
2 changes: 1 addition & 1 deletion payloads/libpayload/drivers/usb/xhci_private.h
Expand Up @@ -363,7 +363,7 @@ typedef struct erst_entry {
#define CAP_CSZ_LEN 1

#define CAP_MASK(tok) MASK(CAP_##tok##_START, CAP_##tok##_LEN)
#define CAP_GET(tok, cap) (((cap)->CAP_##tok##_FIELD & CAP_MASK(tok)) \
#define CAP_GET(tok, cap) ((read32(&(cap)->CAP_##tok##_FIELD) & CAP_MASK(tok)) \
>> CAP_##tok##_START)

#define CTXSIZE(xhci) (CAP_GET(CSZ, (xhci)->capreg) ? 64 : 32)
Expand Down
451 changes: 352 additions & 99 deletions payloads/libpayload/drivers/video/graphics.c

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions payloads/libpayload/include/cbgfx.h
Expand Up @@ -210,3 +210,33 @@ int draw_bitmap_direct(const void *bitmap, size_t size,
* in the original size are returned.
*/
int get_bitmap_dimension(const void *bitmap, size_t sz, struct scale *dim_rel);

/**
* Setup alpha and rgb values for alpha blending. When alpha is != 0,
* this enables a translucent layer of color (defined by rgb) to be
* blended at a given translucency (alpha) to all things drawn. Call
* clear_blend() to disable alpha blending.
*
* @param[in] rgb Color for transparency
* @param[in] alpha Opacity of color, from 0-255 where
* 0 = completely transparent (no blending)
* 255 = max alpha argument
*
* @return CBGFX_* error codes
*/
int set_blend(const struct rgb_color *rgb, uint8_t alpha);

/**
* Clear alpha and rgb values, thus disabling any alpha blending.
*
* @return CBGFX_* error codes
*/
void clear_blend(void);

/**
* For calculating Alpha value from % opacity
* For reference:
* 255 = max alpha argument
* 0 = min alpha argument, 0% opacity
*/
#define ALPHA(percentage) MIN(255, (256 * percentage / 100))
234 changes: 234 additions & 0 deletions payloads/libpayload/include/fpmath.h
@@ -0,0 +1,234 @@
/*
*
* Copyright (C) 2020 Google, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#include <stdint.h>

/*
* This file implements operations for a simple 32.32 fixed-point math type.
* This is intended for speed-critical stuff (e.g. graphics) so there are
* intentionally no overflow checks or assertions, and operations are written
* to prefer speed over precision (e.g. multiplying by 1 may lose precision).
* For best results, only use for applications where 16.16 would fit.
*/

typedef struct { /* wrap in struct to prevent direct access */
int64_t v;
} fpmath_t;

#define FPMATH_SHIFT 32 /* define where to place the decimal point */

/* Turn an integer into an fpmath_t. */
static inline fpmath_t fp(int32_t a)
{
return (fpmath_t){ .v = (int64_t)a << FPMATH_SHIFT };
}

/* Create an fpmath_t from a fraction. (numerator / denominator) */
static inline fpmath_t fpfrac(int32_t numerator, int32_t denominator)
{
return (fpmath_t){ .v = ((int64_t)numerator << FPMATH_SHIFT) / denominator };
}

/* Turn an fpmath_t back into an integer, rounding towards -INF. */
static inline int32_t fpfloor(fpmath_t a)
{
return a.v >> FPMATH_SHIFT;
}

/* Turn an fpmath_t back into an integer, rounding towards nearest. */
static inline int32_t fpround(fpmath_t a)
{
return (a.v + ((int64_t)1 << (FPMATH_SHIFT - 1))) >> FPMATH_SHIFT;
}

/* Turn an fpmath_t back into an integer, rounding towards +INF. */
static inline int32_t fpceil(fpmath_t a)
{
return (a.v + ((int64_t)1 << FPMATH_SHIFT) - 1) >> FPMATH_SHIFT;
}

/* Add two fpmath_t. (a + b) */
static inline fpmath_t fpadd(fpmath_t a, fpmath_t b)
{
return (fpmath_t){ .v = a.v + b.v };
}

/* Add an fpmath_t and an integer. (a + b) */
static inline fpmath_t fpaddi(fpmath_t a, int32_t b)
{
return (fpmath_t){ .v = a.v + ((int64_t)b << FPMATH_SHIFT) };
}

/* Subtract one fpmath_t from another. (a + b) */
static inline fpmath_t fpsub(fpmath_t a, fpmath_t b)
{
return (fpmath_t){ .v = a.v - b.v };
}

/* Subtract an integer from an fpmath_t. (a - b) */
static inline fpmath_t fpsubi(fpmath_t a, int32_t b)
{
return (fpmath_t){ .v = a.v - ((int64_t)b << FPMATH_SHIFT) };
}

/* Subtract an fpmath_t from an integer. (a - b) */
static inline fpmath_t fpisub(int32_t a, fpmath_t b)
{
return (fpmath_t){ .v = ((int64_t)a << FPMATH_SHIFT) - b.v };
}

/* Multiply two fpmath_t. (a * b)
Looses 16 bits fractional precision on each. */
static inline fpmath_t fpmul(fpmath_t a, fpmath_t b)
{
return (fpmath_t){ .v = (a.v >> (FPMATH_SHIFT/2)) * (b.v >> (FPMATH_SHIFT/2)) };
}

/* Multiply an fpmath_t and an integer. (a * b) */
static inline fpmath_t fpmuli(fpmath_t a, int32_t b)
{
return (fpmath_t){ .v = a.v * b };
}

/* Divide an fpmath_t by another. (a / b)
Truncates integral part of a to 16 bits! Careful with this one! */
static inline fpmath_t fpdiv(fpmath_t a, fpmath_t b)
{
return (fpmath_t){ .v = (a.v << (FPMATH_SHIFT/2)) / (b.v >> (FPMATH_SHIFT/2)) };
}

/* Divide an fpmath_t by an integer. (a / b) */
static inline fpmath_t fpdivi(fpmath_t a, int32_t b)
{
return (fpmath_t){ .v = a.v / b };
}

/* Calculate absolute value of an fpmath_t. (ABS(a)) */
static inline fpmath_t fpabs(fpmath_t a)
{
return (fpmath_t){ .v = (a.v < 0 ? -a.v : a.v) };
}

/* Return true iff two fpmath_t are exactly equal. (a == b)
Like with floats, you probably don't want to use this most of the time. */
static inline int fpequals(fpmath_t a, fpmath_t b)
{
return a.v == b.v;
}

/* Return true iff one fpmath_t is less than another. (a < b) */
static inline int fpless(fpmath_t a, fpmath_t b)
{
return a.v < b.v;
}

/* Return true iff one fpmath_t is more than another. (a > b) */
static inline int fpmore(fpmath_t a, fpmath_t b)
{
return a.v > b.v;
}

/* Return the smaller of two fpmath_t. (MIN(a, b)) */
static inline fpmath_t fpmin(fpmath_t a, fpmath_t b)
{
if (a.v < b.v)
return a;
else
return b;
}

/* Return the larger of two fpmath_t. (MAX(a, b)) */
static inline fpmath_t fpmax(fpmath_t a, fpmath_t b)
{
if (a.v > b.v)
return a;
else
return b;
}

/* Return the constant PI as an fpmath_t. */
static inline fpmath_t fppi(void)
{
/* Rounded (uint64_t)(M_PI * (1UL << 60)) to nine hex digits. */
return (fpmath_t){ .v = 0x3243f6a89 };
}

/*
* Returns the "one-based" sine of an fpmath_t, meaning the input is interpreted as if the range
* 0.0-1.0 corresponded to 0.0-PI/2 for radians. This is mostly here as the base primitives for
* the other trig stuff, but it may be useful to use directly if your input value already needs
* to be multiplied by some factor of PI and you want to save the instructions (and precision)
* for multiplying it in just so that the trig functions can divide it right out again.
*/
fpmath_t fpsin1(fpmath_t x);

/* Returns the "one-based" cosine of an fpmath_t (analogous definition to fpsin1()). */
static inline fpmath_t fpcos1(fpmath_t x)
{
return fpsin1(fpaddi(x, 1));
}

/* Returns the sine of an fpmath_t interpreted as radians. */
static inline fpmath_t fpsinr(fpmath_t radians)
{
return fpsin1(fpdiv(radians, fpdivi(fppi(), 2)));
}

/* Returns the sine of an fpmath_t interpreted as degrees. */
static inline fpmath_t fpsind(fpmath_t degrees)
{
return fpsin1(fpdivi(degrees, 90));
}

/* Returns the cosine of an fpmath_t interpreted as radians. */
static inline fpmath_t fpcosr(fpmath_t radians)
{
return fpcos1(fpdiv(radians, fpdivi(fppi(), 2)));
}

/* Returns the cosine of an fpmath_t interpreted as degrees. */
static inline fpmath_t fpcosd(fpmath_t degrees)
{
return fpcos1(fpdivi(degrees, 90));
}

/* Returns the tangent of an fpmath_t interpreted as radians.
No guard rails, don't call this at the poles or you'll divide by 0! */
static inline fpmath_t fptanr(fpmath_t radians)
{
fpmath_t one_based = fpdiv(radians, fpdivi(fppi(), 2));
return fpdiv(fpsin1(one_based), fpcos1(one_based));
}

/* Returns the tangent of an fpmath_t interpreted as degrees.
No guard rails, don't call this at the poles or you'll divide by 0! */
static inline fpmath_t fptand(fpmath_t degrees)
{
fpmath_t one_based = fpdivi(degrees, 90);
return fpdiv(fpsin1(one_based), fpcos1(one_based));
}
2 changes: 2 additions & 0 deletions payloads/libpayload/include/x86/arch/apic.h
Expand Up @@ -40,5 +40,7 @@ uint8_t apic_id(void);
void apic_eoi(uint8_t vector);

void apic_delay(unsigned int usec);
void apic_start_delay(unsigned int usec);
void apic_wait_delay(void);

#endif /* __ARCH_X86_INCLUDES_ARCH_APIC_H__ */
1 change: 1 addition & 0 deletions payloads/libpayload/libc/Makefile.inc
Expand Up @@ -38,3 +38,4 @@ libc-$(CONFIG_LP_LIBC) += hexdump.c
libc-$(CONFIG_LP_LIBC) += die.c
libc-$(CONFIG_LP_LIBC) += coreboot.c
libc-$(CONFIG_LP_LIBC) += fmap.c
libc-$(CONFIG_LP_LIBC) += fpmath.c
149 changes: 149 additions & 0 deletions payloads/libpayload/libc/fpmath.c
@@ -0,0 +1,149 @@
/*
*
* Copyright (C) 2020 Google, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#include <fpmath.h>

/*
* This table represents one ascending arc of the sine curve, i.e. the values sin(x) for
* 0.0 <= x < PI/2. We divide that range into 256 equidistant points and store the corresponding
* sine values for those points. Since the values lie in the range 0.0 <= sin(x) < 1.0, in order
* to make the most use of the bytes we store, we map them to the range from 0 to 2^16.
*
* Generated with:
*
* for (i = 0; i < 256; i++) {
* double s = sin((double)i * M_PI / 2 / 256);
* uint16_t u = fmin(round(s * (1 << 16)), (1 << 16));
* printf("0x%04x,%s", u, i % 8 == 7 ? "\n" : " ");
* }
*
* In order to make sure the second access for linear interpolation (see below) cannot overrun
* the array, we stick a final 257th value 0xffff at the end. (It should really be 0x10000,
* but... this is good enough.)
*/

/* Table size as power of two. If we ever want to change the table size, updating this value
should make everything else fall back into place again (hopefully). */
#define TP2 8

static const uint16_t fpsin_table[(1 << TP2) + 1] = {
0x0000, 0x0192, 0x0324, 0x04b6, 0x0648, 0x07da, 0x096c, 0x0afe,
0x0c90, 0x0e21, 0x0fb3, 0x1144, 0x12d5, 0x1466, 0x15f7, 0x1787,
0x1918, 0x1aa8, 0x1c38, 0x1dc7, 0x1f56, 0x20e5, 0x2274, 0x2402,
0x2590, 0x271e, 0x28ab, 0x2a38, 0x2bc4, 0x2d50, 0x2edc, 0x3067,
0x31f1, 0x337c, 0x3505, 0x368e, 0x3817, 0x399f, 0x3b27, 0x3cae,
0x3e34, 0x3fba, 0x413f, 0x42c3, 0x4447, 0x45cb, 0x474d, 0x48cf,
0x4a50, 0x4bd1, 0x4d50, 0x4ecf, 0x504d, 0x51cb, 0x5348, 0x54c3,
0x563e, 0x57b9, 0x5932, 0x5aaa, 0x5c22, 0x5d99, 0x5f0f, 0x6084,
0x61f8, 0x636b, 0x64dd, 0x664e, 0x67be, 0x692d, 0x6a9b, 0x6c08,
0x6d74, 0x6edf, 0x7049, 0x71b2, 0x731a, 0x7480, 0x75e6, 0x774a,
0x78ad, 0x7a10, 0x7b70, 0x7cd0, 0x7e2f, 0x7f8c, 0x80e8, 0x8243,
0x839c, 0x84f5, 0x864c, 0x87a1, 0x88f6, 0x8a49, 0x8b9a, 0x8ceb,
0x8e3a, 0x8f88, 0x90d4, 0x921f, 0x9368, 0x94b0, 0x95f7, 0x973c,
0x9880, 0x99c2, 0x9b03, 0x9c42, 0x9d80, 0x9ebc, 0x9ff7, 0xa130,
0xa268, 0xa39e, 0xa4d2, 0xa605, 0xa736, 0xa866, 0xa994, 0xaac1,
0xabeb, 0xad14, 0xae3c, 0xaf62, 0xb086, 0xb1a8, 0xb2c9, 0xb3e8,
0xb505, 0xb620, 0xb73a, 0xb852, 0xb968, 0xba7d, 0xbb8f, 0xbca0,
0xbdaf, 0xbebc, 0xbfc7, 0xc0d1, 0xc1d8, 0xc2de, 0xc3e2, 0xc4e4,
0xc5e4, 0xc6e2, 0xc7de, 0xc8d9, 0xc9d1, 0xcac7, 0xcbbc, 0xccae,
0xcd9f, 0xce8e, 0xcf7a, 0xd065, 0xd14d, 0xd234, 0xd318, 0xd3fb,
0xd4db, 0xd5ba, 0xd696, 0xd770, 0xd848, 0xd91e, 0xd9f2, 0xdac4,
0xdb94, 0xdc62, 0xdd2d, 0xddf7, 0xdebe, 0xdf83, 0xe046, 0xe107,
0xe1c6, 0xe282, 0xe33c, 0xe3f4, 0xe4aa, 0xe55e, 0xe610, 0xe6bf,
0xe76c, 0xe817, 0xe8bf, 0xe966, 0xea0a, 0xeaab, 0xeb4b, 0xebe8,
0xec83, 0xed1c, 0xedb3, 0xee47, 0xeed9, 0xef68, 0xeff5, 0xf080,
0xf109, 0xf18f, 0xf213, 0xf295, 0xf314, 0xf391, 0xf40c, 0xf484,
0xf4fa, 0xf56e, 0xf5df, 0xf64e, 0xf6ba, 0xf724, 0xf78c, 0xf7f1,
0xf854, 0xf8b4, 0xf913, 0xf96e, 0xf9c8, 0xfa1f, 0xfa73, 0xfac5,
0xfb15, 0xfb62, 0xfbad, 0xfbf5, 0xfc3b, 0xfc7f, 0xfcc0, 0xfcfe,
0xfd3b, 0xfd74, 0xfdac, 0xfde1, 0xfe13, 0xfe43, 0xfe71, 0xfe9c,
0xfec4, 0xfeeb, 0xff0e, 0xff30, 0xff4e, 0xff6b, 0xff85, 0xff9c,
0xffb1, 0xffc4, 0xffd4, 0xffe1, 0xffec, 0xfff5, 0xfffb, 0xffff,
0xffff,
};

/* x is in the "one-based" scale, so x == 1.0 is the top of the curve (PI/2 in radians). */
fpmath_t fpsin1(fpmath_t x)
{
/*
* When doing things like sin(x)/x, tiny errors can quickly become big problems, so just
* returning the nearest table value we have is not good enough (our fpmath_t has four
* times as much fractional precision as the sine table). A good and fast enough remedy
* is to linearly interpolate between the two nearest table values v1 and v2.
* (There are better but slower interpolations so we intentionally choose this one.)
*
* Most of this math can be done in 32 bits (because we're just operating on fractional
* parts in the 0.0-1.0 range anyway), so to help our 32-bit platforms a bit we keep it
* there as long as possible and only go back to an int64_t at the end.
*/
uint32_t v1, v2;

/*
* Since x is "one-based" the part that maps to our curve (0.0 to PI/2 in radians) just
* happens to be exactly the fractional part of the fpmath_t, easy to extract.
*/
int index = (x.v >> (FPMATH_SHIFT - TP2)) & ((1 << TP2) - 1);

/*
* In our one-based input domain, the period of the sine function is exactly 4.0. By
* extracting the first bit of the integral part of the fpmath_t we can check if it is
* odd-numbered (1.0-2.0, 3.0-4.0, etc.) or even numbered (0.0-1.0, 2.0-3.0, etc.), and
* that tells us whether we are in a "rising" (away from 0) or "falling" (towards 0)
* part of the sine curve. Our table curve is rising, so for the falling parts we have
* to mirror the curve horizontally by using the complement of our input index.
*/
if (x.v & ((int64_t)1 << FPMATH_SHIFT)) {
v1 = fpsin_table[(1 << TP2) - index];
v2 = fpsin_table[(1 << TP2) - index - 1];
} else {
v1 = fpsin_table[index];
v2 = fpsin_table[index + 1];
}

/*
* Linear interpolation: sin(x) is interpolated as the closest number sin(x0) to the
* left of x we have in our table, plus the distance of that value to the closest number
* to the right of x (sin(x1)) times the fractional distance of x to x0. Since the table
* is conveniently exactly 256 values, x0 is exactly the upper 8 bits of the fractional
* part of x, meaning all fractional bits below that represent exactly the distance we
* need to interpolate over. (There are 24 of them but we need to multiply them with
* 16-bit table values to fit exactly 32 bits, so we discard the lowest 8 bits.)
*/
uint32_t val = (v1 << (FPMATH_SHIFT - 16)) +
(v2 - v1) * ((x.v >> (16 - TP2)) & 0xffff);

/*
* Just like the first integral bit told us whether we need to mirror horizontally, the
* second can tell us to mirror vertically. In 2.0-4.0, 6.0-8.0, etc. of the input range
* the sine is negative, and in 0.0-2.0, 4.0-6.0, etc. it is positive.
*/
if (x.v & ((int64_t)2 << FPMATH_SHIFT))
return (fpmath_t){ .v = -(int64_t)val };
else
return (fpmath_t){ .v = val };
}
44 changes: 31 additions & 13 deletions src/Kconfig
Expand Up @@ -234,6 +234,26 @@ config USE_AMD_BLOBS
Note that for some products, omitting PSP, SMU images, or other items
may result in a nonbooting coreboot.rom.

config USE_QC_BLOBS
bool "Allow QC blobs repository (selecting this agrees to the license!)"
depends on USE_BLOBS
help
This draws in the qc_blobs repository, which contains binary files
distributed by Qualcomm that are required to build firmware for
certain Qualcomm SoCs (including QcLib, QC-SEC, qtiseclib and QUP
firmware). If you say Y here you are implicitly agreeing to the
Qualcomm license agreement which can be found at:
https://review.coreboot.org/cgit/qc_blobs.git/tree/LICENSE

*****************************************************
PLEASE MAKE SURE YOU READ AND AGREE TO ALL TERMS IN
ABOVE LICENSE AGREEMENT BEFORE SELECTING THIS OPTION!
*****************************************************

Not selecting this option means certain Qualcomm SoCs and related
mainboards cannot be built and will be hidden from the "Mainboards"
section.

config COVERAGE
bool "Code coverage support"
depends on COMPILER_GCC
Expand All @@ -250,20 +270,9 @@ config UBSAN
say N because it adds a small performance penalty and may abort
on code that happens to work in spite of the UB.

config RELOCATABLE_RAMSTAGE
bool
default y if ARCH_X86
select RELOCATABLE_MODULES
help
The reloctable ramstage support allows for the ramstage to be built
as a relocatable module. The stage loader can identify a place
out of the OS way so that copying memory is unnecessary during an S3
wake. When selecting this option the romstage is responsible for
determing a stack location to use for loading the ramstage.

choice
prompt "Stage Cache for ACPI S3 resume"
default NO_STAGE_CACHE if !HAVE_ACPI_RESUME || !RELOCATABLE_RAMSTAGE
default NO_STAGE_CACHE if !HAVE_ACPI_RESUME
default TSEG_STAGE_CACHE if SMM_TSEG

config NO_STAGE_CACHE
Expand Down Expand Up @@ -556,7 +565,6 @@ source "src/console/Kconfig"
config HAVE_ACPI_RESUME
bool
default n
depends on RELOCATABLE_RAMSTAGE

config DISABLE_ACPI_HIBERNATE
bool
Expand Down Expand Up @@ -730,6 +738,16 @@ config MAINBOARD_SMBIOS_PRODUCT_NAME
help
Override the default Product name stored in SMBIOS structures.

config VPD_SMBIOS_VERSION
bool "Populates SMBIOS type 0 version from the VPD_RO variable 'firmware_version'"
default n
depends on VPD && GENERATE_SMBIOS_TABLES
help
Selecting this option will read firmware_version from
VPD_RO and override SMBIOS type 0 version. One special
scenario of using this feature is to assign a BIOS version
to a coreboot image without the need to rebuild from source.

endmenu

source "payloads/Kconfig"
Expand Down
1 change: 1 addition & 0 deletions src/acpi/Makefile.inc
Expand Up @@ -4,6 +4,7 @@ ifeq ($(CONFIG_HAVE_ACPI_TABLES),y)

ramstage-y += acpi.c
ramstage-y += acpigen.c
ramstage-y += acpigen_dptf.c
ramstage-y += acpigen_dsm.c
ramstage-y += acpigen_ps2_keybd.c
ramstage-y += acpigen_usb.c
Expand Down
5 changes: 4 additions & 1 deletion src/acpi/acpi.c
Expand Up @@ -752,7 +752,7 @@ void acpi_create_hpet(acpi_hpet_t *hpet)
header->revision = get_acpi_table_revision(HPET);

/* Fill out HPET address. */
addr->space_id = 0; /* Memory */
addr->space_id = ACPI_ADDRESS_SPACE_MEMORY;
addr->bit_width = 64;
addr->bit_offset = 0;
addr->addrl = CONFIG_HPET_ADDRESS & 0xffffffff;
Expand Down Expand Up @@ -1219,6 +1219,7 @@ void acpi_write_bert(acpi_bert_t *bert, uintptr_t region, size_t length)
header->checksum = acpi_checksum((void *)bert, header->length);
}

__weak void arch_fill_fadt(acpi_fadt_t *fadt) { }
__weak void soc_fill_fadt(acpi_fadt_t *fadt) { }
__weak void mainboard_fill_fadt(acpi_fadt_t *fadt) { }

Expand Down Expand Up @@ -1259,6 +1260,8 @@ void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
else
fadt->preferred_pm_profile = PM_DESKTOP;

arch_fill_fadt(fadt);

acpi_fill_fadt(fadt);

soc_fill_fadt(fadt);
Expand Down
30 changes: 24 additions & 6 deletions src/acpi/acpigen.c
Expand Up @@ -742,6 +742,17 @@ void acpigen_write_STA(uint8_t status)
acpigen_pop_len();
}

void acpigen_write_STA_ext(const char *namestring)
{
/*
* Method (_STA, 0, NotSerialized) { Return (ext_val) }
*/
acpigen_write_method("_STA", 0);
acpigen_emit_byte(RETURN_OP);
acpigen_emit_namestring(namestring);
acpigen_pop_len();
}

/*
* Generates a func with max supported P-states.
*/
Expand Down Expand Up @@ -1800,15 +1811,15 @@ int __weak acpigen_soc_clear_tx_gpio(unsigned int gpio_num)
*/
int acpigen_enable_tx_gpio(struct acpi_gpio *gpio)
{
if (gpio->polarity == ACPI_GPIO_ACTIVE_HIGH)
return acpigen_soc_set_tx_gpio(gpio->pins[0]);
else
if (gpio->active_low)
return acpigen_soc_clear_tx_gpio(gpio->pins[0]);
else
return acpigen_soc_set_tx_gpio(gpio->pins[0]);
}

int acpigen_disable_tx_gpio(struct acpi_gpio *gpio)
{
if (gpio->polarity == ACPI_GPIO_ACTIVE_LOW)
if (gpio->active_low)
return acpigen_soc_set_tx_gpio(gpio->pins[0]);
else
return acpigen_soc_clear_tx_gpio(gpio->pins[0]);
Expand All @@ -1818,15 +1829,15 @@ void acpigen_get_rx_gpio(struct acpi_gpio *gpio)
{
acpigen_soc_read_rx_gpio(gpio->pins[0]);

if (gpio->polarity == ACPI_GPIO_ACTIVE_LOW)
if (gpio->active_low)
acpigen_write_xor(LOCAL0_OP, 1, LOCAL0_OP);
}

void acpigen_get_tx_gpio(struct acpi_gpio *gpio)
{
acpigen_soc_get_tx_gpio(gpio->pins[0]);

if (gpio->polarity == ACPI_GPIO_ACTIVE_LOW)
if (gpio->active_low)
acpigen_write_xor(LOCAL0_OP, 1, LOCAL0_OP);
}

Expand Down Expand Up @@ -1953,3 +1964,10 @@ void acpigen_write_ADR_soundwire_device(const struct soundwire_address *address)
(((uint64_t)address->part_id & 0xffff) << 8) |
(((uint64_t)address->class & 0xff)));
}

void acpigen_notify(const char *namestr, int value)
{
acpigen_emit_byte(NOTIFY_OP);
acpigen_emit_namestring(namestr);
acpigen_write_integer(value);
}
486 changes: 486 additions & 0 deletions src/acpi/acpigen_dptf.c

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion src/acpi/chromeos-gnvs.c
@@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpi_gnvs.h>
#include <types.h>
#include <ec/google/chromeec/ec.h>
#include <vendorcode/google/chromeos/gnvs.h>

Expand Down
9 changes: 7 additions & 2 deletions src/acpi/device.c
Expand Up @@ -770,7 +770,7 @@ static bool acpi_dp_write_properties(struct acpi_dp *prop, const char *uuid)
return false;
}

void acpi_dp_write(struct acpi_dp *table)
static void acpi_dp_write_(struct acpi_dp *table)
{
struct acpi_dp *dp, *prop;
char *dp_count;
Expand Down Expand Up @@ -826,7 +826,12 @@ void acpi_dp_write(struct acpi_dp *table)
/* Recursively parse children into separate tables */
for (dp = prop; dp; dp = dp->next)
if (dp->type == ACPI_DP_TYPE_CHILD)
acpi_dp_write(dp->child);
acpi_dp_write_(dp->child);
}

void acpi_dp_write(struct acpi_dp *table)
{
acpi_dp_write_(table);

/* Clean up */
acpi_dp_free(table);
Expand Down
3 changes: 1 addition & 2 deletions src/acpi/soundwire.c
Expand Up @@ -6,8 +6,7 @@
#include <commonlib/helpers.h>
#include <device/soundwire.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stddef.h>

/* Specification-defined prefix for SoundWire properties. */
#define SDW_PFX "mipi-sdw-"
Expand Down
4 changes: 2 additions & 2 deletions src/arch/arm/armv7/mmu.c
Expand Up @@ -118,7 +118,7 @@ static void mmu_fill_table(pte_t *table, u32 start_idx, u32 end_idx,

/* Invalidate the TLB entries. */
for (i = start_idx; i < end_idx; i++)
tlbimvaa(offset + (i << shift));
tlbimva(offset + (i << shift));
dsb();
isb();
}
Expand Down Expand Up @@ -152,7 +152,7 @@ static pte_t *mmu_create_subtable(pte_t *pgd_entry)
*pgd_entry = (pte_t)(uintptr_t)table | ATTR_NEXTLEVEL;
dccmvac((uintptr_t)pgd_entry);
dsb();
tlbimvaa(start_addr);
tlbimva(start_addr);
dsb();
isb();

Expand Down
1 change: 0 additions & 1 deletion src/arch/arm/include/armv4/arch/cache.h
Expand Up @@ -7,7 +7,6 @@
#define ARM_CACHE_H

#include <stddef.h>
#include <stdint.h>

/*
* Cache maintenance API
Expand Down
1 change: 0 additions & 1 deletion src/arch/arm/include/armv7.h
Expand Up @@ -2,7 +2,6 @@

#ifndef ARMV7_H
#define ARMV7_H
#include <types.h>

/* Cortex-A9 revisions */
#define MIDR_CORTEX_A9_R0P1 0x410FC091
Expand Down
6 changes: 3 additions & 3 deletions src/arch/arm/include/armv7/arch/cache.h
Expand Up @@ -73,10 +73,10 @@ static inline void tlbiall(void)
asm volatile ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0) : "memory");
}

/* invalidate unified TLB by MVA, all ASID */
static inline void tlbimvaa(unsigned long mva)
/* invalidate unified TLB by MVA and ASID */
static inline void tlbimva(unsigned long mva)
{
asm volatile ("mcr p15, 0, %0, c8, c7, 3" : : "r" (mva) : "memory");
asm volatile ("mcr p15, 0, %0, c8, c7, 1" : : "r" (mva) : "memory");
}

/* write data access control register (DACR) */
Expand Down
54 changes: 0 additions & 54 deletions src/arch/arm/include/smp/spinlock.h

This file was deleted.

1 change: 0 additions & 1 deletion src/arch/arm64/include/armv8/arch/cache.h
Expand Up @@ -11,7 +11,6 @@
#ifndef __ASSEMBLER__

#include <stddef.h>
#include <stdint.h>
#include <arch/barrier.h>

/* dcache clean by virtual address to PoC */
Expand Down
6 changes: 0 additions & 6 deletions src/arch/x86/Kconfig
Expand Up @@ -133,12 +133,6 @@ config NUM_IPI_STARTS
int
default 2

config CBMEM_TOP_BACKUP
def_bool n
help
Platform implements non-volatile storage to cache cbmem_top()
over stage transitions and optionally also over S3 suspend.

config PRERAM_CBMEM_CONSOLE_SIZE
hex
default 0xc00
Expand Down
13 changes: 3 additions & 10 deletions src/arch/x86/Makefile.inc
Expand Up @@ -50,7 +50,7 @@ pci$(stripped_vgabios_dgpu_id).rom-type := optionrom
# into a single generated file.
crt0s = $(cpu_incs-y)

$(objgenerated)/assembly.inc: $$(crt0s)
$(objgenerated)/assembly.inc: build-dirs $$(crt0s)
@printf " GEN $(subst $(obj)/,,$(@))\n"
printf '$(foreach crt0,$(crt0s),#include "$(crt0)"\n)' > $@

Expand Down Expand Up @@ -94,6 +94,7 @@ bootblock-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c
bootblock-$(CONFIG_IDT_IN_EVERY_STAGE) += idt.S
bootblock-y += memcpy.c
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_BOOTBLOCK_NORMAL) += bootblock_normal.c
Expand Down Expand Up @@ -163,7 +164,6 @@ romstage-y += post.c
# gdt_init.S is included by entry32.inc when romstage is the first C
# environment.
romstage-y += gdt_init.S
romstage-y += cbmem.c
romstage-y += cpu_common.c
romstage-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c
romstage-$(CONFIG_IDT_IN_EVERY_STAGE) += idt.S
Expand Down Expand Up @@ -235,6 +235,7 @@ $(CONFIG_CBFS_PREFIX)/postcar-compression := none

ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32)$(CONFIG_ARCH_RAMSTAGE_X86_64),y)

ramstage-y += acpi.c
ramstage-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.c
ramstage-$(CONFIG_ACPI_BERT) += acpi_bert_storage.c
ramstage-y += boot.c
Expand All @@ -245,7 +246,6 @@ ramstage-y += cpu_common.c
ramstage-y += ebda.c
ramstage-y += exception.c
ramstage-y += idt.S
ramstage-y += gdt.c
ramstage-$(CONFIG_IOAPIC) += ioapic.c
ramstage-y += memcpy.c
ramstage-y += memmove.c
Expand Down Expand Up @@ -288,20 +288,13 @@ endif
ifeq ($(CONFIG_GENERATE_PIRQ_TABLE),y)
ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/irq_tables.c
endif
ifneq ($(wildcard src/mainboard/$(MAINBOARDDIR)/reset.c),)
ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/reset.c
endif

ramstage-libs ?=

ifeq ($(CONFIG_RELOCATABLE_RAMSTAGE),y)

# The rmodule_link definition creates an elf file with .rmod extension.
$(objcbfs)/ramstage.elf: $(objcbfs)/ramstage.debug.rmod
cp $< $@

endif

$(objcbfs)/ramstage.debug: $(objgenerated)/ramstage.o $(call src-to-obj,ramstage,$(CONFIG_MEMLAYOUT_LD_FILE))
@printf " CC $(subst $(obj)/,,$(@))\n"
$(LD_ramstage) $(CPPFLAGS) $(LDFLAGS_ramstage) -o $@ -L$(obj) $< -T $(call src-to-obj,ramstage,$(CONFIG_MEMLAYOUT_LD_FILE))
Expand Down
20 changes: 20 additions & 0 deletions src/arch/x86/acpi.c
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpi.h>
#include <cf9_reset.h>

void arch_fill_fadt(acpi_fadt_t *fadt)
{
if (CONFIG(HAVE_CF9_RESET)) {
fadt->reset_reg.space_id = ACPI_ADDRESS_SPACE_IO;
fadt->reset_reg.bit_width = 8;
fadt->reset_reg.bit_offset = 0;
fadt->reset_reg.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
fadt->reset_reg.addrl = RST_CNT;
fadt->reset_reg.addrh = 0;

fadt->reset_value = RST_CPU | SYS_RST;

fadt->flags |= ACPI_FADT_RESET_REGISTER;
}
}
15 changes: 0 additions & 15 deletions src/arch/x86/acpi/debug.asl
@@ -1,20 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */

/*
#include <acpi/acpi.h>
DefinitionBlock (
"DSDT.AML",
"DSDT",
0x01,
OEM_ID,
ACPI_TABLE_CREATOR,
0x00010001
)
{
#include "debug.asl"
}
*/

/*
* 0x80: POST_BASE
* 0x3F8: DEBCOM_BASE
Expand Down
13 changes: 0 additions & 13 deletions src/arch/x86/cbmem.c

This file was deleted.

44 changes: 41 additions & 3 deletions src/arch/x86/exception.c
Expand Up @@ -489,12 +489,38 @@ void x86_exception(struct eregs *info)
put_packet(out_buffer);
}
#else /* !CONFIG_GDB_STUB */
#define MDUMP_SIZE 0x80

int logical_processor = 0;

#if ENV_RAMSTAGE
logical_processor = cpu_index();
#endif
u8 *code;
#ifdef __x86_64__
#define MDUMP_SIZE 0x100
printk(BIOS_EMERG,
"CPU Index %d - APIC %d Unexpected Exception:\n"
"%lld @ %02llx:%016llx - Halting\n"
"Code: %lld rflags: %016llx cr2: %016llx\n"
"rax: %016llx rbx: %016llx\n"
"rcx: %016llx rdx: %016llx\n"
"rdi: %016llx rsi: %016llx\n"
"rbp: %016llx rsp: %016llx\n"
"r08: %016llx r09: %016llx\n"
"r10: %016llx r11: %016llx\n"
"r12: %016llx r13: %016llx\n"
"r14: %016llx r15: %016llx\n",
logical_processor, (unsigned int)lapicid(),
info->vector, info->cs, info->rip,
info->error_code, info->rflags, read_cr2(),
info->rax, info->rbx, info->rcx, info->rdx,
info->rdi, info->rsi, info->rbp, info->rsp,
info->r8, info->r9, info->r10, info->r11,
info->r12, info->r13, info->r14, info->r15);
code = (u8 *)((uintptr_t)info->rip - (MDUMP_SIZE >> 2));
#else
#define MDUMP_SIZE 0x80

printk(BIOS_EMERG,
"CPU Index %d - APIC %d Unexpected Exception:"
"%d @ %02x:%08x - Halting\n"
Expand All @@ -506,7 +532,8 @@ void x86_exception(struct eregs *info)
info->error_code, info->eflags, read_cr2(),
info->eax, info->ebx, info->ecx, info->edx,
info->edi, info->esi, info->ebp, info->esp);
u8 *code = (u8 *)((uintptr_t)info->eip - (MDUMP_SIZE >> 1));
code = (u8 *)((uintptr_t)info->eip - (MDUMP_SIZE >> 1));
#endif
/* Align to 8-byte boundary please, and print eight bytes per row.
* This is done to make DRAM burst timing/reordering errors more
* evident from the looking at the dump */
Expand All @@ -517,7 +544,18 @@ void x86_exception(struct eregs *info)
printk(BIOS_EMERG, "\n%p:\t", code + i);
printk(BIOS_EMERG, "%.2x ", code[i]);
}
die("");

/* Align to 4-byte boundary and up the stack. */
u32 *ptr = (u32 *)(ALIGN_DOWN((uintptr_t)info->esp, sizeof(u32)) + MDUMP_SIZE - 4);
for (i = 0; i < MDUMP_SIZE / sizeof(u32); ++i, --ptr) {
printk(BIOS_EMERG, "\n%p:\t0x%08x", ptr, *ptr);
if ((uintptr_t)ptr == info->ebp)
printk(BIOS_EMERG, " <-ebp");
else if ((uintptr_t)ptr == info->esp)
printk(BIOS_EMERG, " <-esp");
}

die("\n");
#endif
}

Expand Down
52 changes: 0 additions & 52 deletions src/arch/x86/gdt.c

This file was deleted.

63 changes: 49 additions & 14 deletions src/arch/x86/idt.S
Expand Up @@ -109,40 +109,75 @@ vec19:

.global int_hand
int_hand:
/* At this point, on x86-32, on the stack there is:
* 0(%esp) vector
* 4(%esp) error code
* 8(%esp) eip
* 12(%esp) cs
* 16(%esp) eflags
*/
#ifdef __x86_64__
/* At this point, on x86-64, on the stack there is:
* 0(%rsp) vector
* 8(%rsp) error code
* 16(%rsp) rip
* 24(%rsp) cs
* 32(%rsp) rflags
* 40(%rsp) rsp
* 48(%rsp) ss
*/
push %r15
push %r14
push %r13
push %r12
push %r11
push %r10
push %r9
push %r8

push %rdi
push %rsi
push %rbp
/* Original stack pointer */
lea 32(%rsp), %rbp
push %rbp

push %rbx
push %rdx
push %rcx
push %rax

push %rsp /* Pointer to structure on the stack */
/* Pass pointer to struct as first argument */
mov %rsp, %rdi

/* Back up stack pointer */
mov %rsp, %rbp

/* Align stack to 16 bytes. */
and $(~0xf), %rsp

call x86_exception
pop %rax /* Drop the pointer */

/* Restore stack pointer from backup */
mov %rbp, %rsp

pop %rax
pop %rcx
pop %rdx
pop %rbx
pop %rbp /* Ignore saved %rsp value */

pop %rbp
pop %rsi
pop %rdi

add $8, %rsp /* pop of the vector and error code */
pop %r8
pop %r9
pop %r10
pop %r11
pop %r12
pop %r13
pop %r14
pop %r15

add $16, %rsp /* pop of the vector and error code */
#else
/* At this point, on x86-32, on the stack there is:
* 0(%esp) vector
* 4(%esp) error code
* 8(%esp) eip
* 12(%esp) cs
* 16(%esp) eflags
*/
pushl %edi
pushl %esi
pushl %ebp
Expand Down
1 change: 0 additions & 1 deletion src/arch/x86/include/arch/ebda.h
Expand Up @@ -3,7 +3,6 @@
#ifndef __ARCH_EBDA_H
#define __ARCH_EBDA_H

#include <stdint.h>
#include <stddef.h>

#define X86_BDA_SIZE 0x200
Expand Down
59 changes: 49 additions & 10 deletions src/arch/x86/include/arch/registers.h
Expand Up @@ -6,7 +6,7 @@
#if !defined(__ASSEMBLER__)
#include <stdint.h>

#define DOWNTO8(A) \
#define LONG_DOWNTO8(A) \
union { \
struct { \
union { \
Expand All @@ -21,7 +21,7 @@
uint32_t e##A##x; \
} __packed;

#define DOWNTO16(A) \
#define LONG_DOWNTO16(A) \
union { \
struct { \
uint16_t A; \
Expand All @@ -30,21 +30,60 @@
uint32_t e##A; \
} __packed;

#define QUAD_DOWNTO8(A) \
union { \
LONG_DOWNTO8(A) \
uint64_t r##A##x; \
} __packed

#define QUAD_DOWNTO16(A) \
union {\
LONG_DOWNTO16(A) \
uint64_t r##A; \
} __packed

#ifdef __ARCH_x86_64__
struct eregs {
DOWNTO8(a);
DOWNTO8(c);
DOWNTO8(d);
DOWNTO8(b);
DOWNTO16(sp);
DOWNTO16(bp);
DOWNTO16(si);
DOWNTO16(di);
QUAD_DOWNTO8(a);
QUAD_DOWNTO8(c);
QUAD_DOWNTO8(d);
QUAD_DOWNTO8(b);
QUAD_DOWNTO16(bp);
QUAD_DOWNTO16(si);
QUAD_DOWNTO16(di);
uint64_t r8;
uint64_t r9;
uint64_t r10;
uint64_t r11;
uint64_t r12;
uint64_t r13;
uint64_t r14;
uint64_t r15;
uint64_t vector;
uint64_t error_code;
uint64_t rip;
uint64_t cs;
uint64_t rflags;
QUAD_DOWNTO16(sp);
uint64_t ss;
};
#else
struct eregs {
LONG_DOWNTO8(a);
LONG_DOWNTO8(c);
LONG_DOWNTO8(d);
LONG_DOWNTO8(b);
LONG_DOWNTO16(sp);
LONG_DOWNTO16(bp);
LONG_DOWNTO16(si);
LONG_DOWNTO16(di);
uint32_t vector;
uint32_t error_code;
uint32_t eip;
uint32_t cs;
uint32_t eflags;
};
#endif
#endif // !ASSEMBLER

#if CONFIG(COMPILER_LLVM_CLANG)
Expand Down
3 changes: 1 addition & 2 deletions src/arch/x86/memlayout.ld
Expand Up @@ -13,8 +13,7 @@ SECTIONS
* conditionalize with macros.
*/
#if ENV_RAMSTAGE
RAMSTAGE(CONFIG_RAMBASE, (CONFIG(RELOCATABLE_RAMSTAGE) ? 8M :
CONFIG_RAMTOP - CONFIG_RAMBASE))
RAMSTAGE(CONFIG_RAMBASE, 8M)

#elif ENV_ROMSTAGE
/* The 1M size is not allocated. It's just for basic size checking.
Expand Down
6 changes: 0 additions & 6 deletions src/arch/x86/mpspec.c
Expand Up @@ -240,12 +240,6 @@ void smp_write_intsrc(struct mp_config_table *mc,
mpc->mpc_dstapic = dstapic;
mpc->mpc_dstirq = dstirq;
smp_add_mpc_entry(mc, sizeof(*mpc));
#ifdef DEBUG_MPTABLE
printk(BIOS_DEBUG,
"add intsrc srcbus 0x%x srcbusirq 0x%x, dstapic 0x%x, dstirq 0x%x\n",
srcbus, srcbusirq, dstapic, dstirq);
hexdump(__func__, mpc, sizeof(*mpc));
#endif
}

/*
Expand Down
1 change: 0 additions & 1 deletion src/arch/x86/postcar_loader.c
Expand Up @@ -3,7 +3,6 @@
#include <arch/romstage.h>
#include <cbmem.h>
#include <console/console.h>
#include <cpu/cpu.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/smm.h>
Expand Down
109 changes: 89 additions & 20 deletions src/arch/x86/smbios.c
Expand Up @@ -19,6 +19,8 @@
#if CONFIG(CHROMEOS)
#include <vendorcode/google/chromeos/gnvs.h>
#endif
#include <drivers/vpd/vpd.h>
#include <stdlib.h>

#define update_max(len, max_len, stmt) \
do { \
Expand Down Expand Up @@ -368,12 +370,64 @@ static int create_smbios_type17_for_dimm(struct dimm_info *dimm,
return t->length + smbios_string_table_len(t->eos);
}

const char *__weak smbios_mainboard_bios_version(void)
#define VERSION_VPD "firmware_version"
static const char *vpd_get_bios_version(void)
{
if (strlen(CONFIG_LOCALVERSION))
int size;
const char *s;
char *version;

s = vpd_find(VERSION_VPD, &size, VPD_RO);
if (!s) {
printk(BIOS_ERR, "Find version from VPD %s failed\n", VERSION_VPD);
return NULL;
}

version = malloc(size + 1);
if (!version) {
printk(BIOS_ERR, "Failed to malloc %d bytes for VPD version\n", size + 1);
return NULL;
}
memcpy(version, s, size);
version[size] = '\0';
printk(BIOS_DEBUG, "Firmware version %s from VPD %s\n", version, VERSION_VPD);
return version;
}

static const char *get_bios_version(void)
{
const char *s;

#define SPACES \
" "

if (CONFIG(CHROMEOS))
return SPACES;

if (CONFIG(VPD_SMBIOS_VERSION)) {
s = vpd_get_bios_version();
if (s != NULL)
return s;
}

s = smbios_mainboard_bios_version();
if (s != NULL)
return s;

if (strlen(CONFIG_LOCALVERSION) != 0) {
printk(BIOS_DEBUG, "BIOS version set to CONFIG_LOCALVERSION: '%s'\n",
CONFIG_LOCALVERSION);
return CONFIG_LOCALVERSION;
else
return coreboot_version;
}

printk(BIOS_DEBUG, "SMBIOS firmware version is set to coreboot_version: '%s'\n",
coreboot_version);
return coreboot_version;
}

const char *__weak smbios_mainboard_bios_version(void)
{
return NULL;
}

static int smbios_write_type0(unsigned long *current, int handle)
Expand All @@ -387,27 +441,14 @@ static int smbios_write_type0(unsigned long *current, int handle)
t->length = len - 2;

t->vendor = smbios_add_string(t->eos, "coreboot");
#if !CONFIG(CHROMEOS)
t->bios_release_date = smbios_add_string(t->eos, coreboot_dmi_date);

t->bios_version = smbios_add_string(t->eos,
smbios_mainboard_bios_version());
#else
#define SPACES \
" "
t->bios_release_date = smbios_add_string(t->eos, coreboot_dmi_date);
#if CONFIG(HAVE_ACPI_TABLES)
#if CONFIG(CHROMEOS) && CONFIG(HAVE_ACPI_TABLES)
u32 version_offset = (u32)smbios_string_table_len(t->eos);
#endif
t->bios_version = smbios_add_string(t->eos, SPACES);

#if CONFIG(HAVE_ACPI_TABLES)
/* SMBIOS offsets start at 1 rather than 0 */
chromeos_get_chromeos_acpi()->vbt10 =
(u32)t->eos + (version_offset - 1);
chromeos_get_chromeos_acpi()->vbt10 = (u32)t->eos + (version_offset - 1);
#endif
#endif /* CONFIG_CHROMEOS */

t->bios_version = smbios_add_string(t->eos, get_bios_version());
uint32_t rom_size = CONFIG_ROM_SIZE;
rom_size = MIN(CONFIG_ROM_SIZE, 16 * MiB);
t->bios_rom_size = (rom_size / 65535) - 1;
Expand Down Expand Up @@ -923,6 +964,34 @@ static int smbios_write_type7_cache_parameters(unsigned long *current,

return len;
}

int smbios_write_type8(unsigned long *current, int *handle,
const struct port_information *port,
size_t num_ports)
{
int len = sizeof(struct smbios_type8);
unsigned int totallen = 0, i;

for (i = 0; i < num_ports; i++, port++) {
struct smbios_type8 *t = (struct smbios_type8 *)*current;
memset(t, 0, sizeof(struct smbios_type8));
t->type = SMBIOS_PORT_CONNECTOR_INFORMATION;
t->handle = *handle;
t->length = len - 2;
t->internal_reference_designator =
smbios_add_string(t->eos, port->internal_reference_designator);
t->internal_connector_type = port->internal_connector_type;
t->external_reference_designator =
smbios_add_string(t->eos, port->external_reference_designator);
t->external_connector_type = port->external_connector_type;
t->port_type = port->port_type;
*handle += 1;
*current += t->length + smbios_string_table_len(t->eos);
totallen += t->length + smbios_string_table_len(t->eos);
}
return totallen;
}

int smbios_write_type9(unsigned long *current, int *handle,
const char *name, const enum misc_slot_type type,
const enum slot_data_bus_bandwidth bandwidth,
Expand Down
2 changes: 1 addition & 1 deletion src/commonlib/include/commonlib/coreboot_tables.h
Expand Up @@ -79,7 +79,7 @@ enum {
LB_TAG_MMC_INFO = 0x0035,
LB_TAG_TCPA_LOG = 0x0036,
LB_TAG_FMAP = 0x0037,
LB_TAG_DRTM_LOG = 0x0038,
LB_TAG_PLATFORM_BLOB_VERSION = 0x0038,
LB_TAG_CMOS_OPTION_TABLE = 0x00c8,
LB_TAG_OPTION = 0x00c9,
LB_TAG_OPTION_ENUM = 0x00ca,
Expand Down
1 change: 0 additions & 1 deletion src/commonlib/include/commonlib/region.h
Expand Up @@ -4,7 +4,6 @@
#define _REGION_H_

#include <sys/types.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <commonlib/mem_pool.h>
Expand Down
2 changes: 1 addition & 1 deletion src/cpu/amd/mtrr/amd_mtrr.c
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <cbmem.h>
#include <amdblocks/biosram.h>
#include <console/console.h>
#include <device/device.h>
#include <arch/cpu.h>
Expand Down
1 change: 0 additions & 1 deletion src/cpu/intel/haswell/Makefile.inc
@@ -1,5 +1,4 @@
ramstage-y += haswell_init.c
romstage-y += romstage.c
romstage-y += ../car/romstage.c

ramstage-y += acpi.c
Expand Down
37 changes: 0 additions & 37 deletions src/cpu/intel/haswell/finalize.c
Expand Up @@ -4,43 +4,6 @@
#include <cpu/x86/msr.h>
#include "haswell.h"

/* MSR Documentation based on
* "Sandy Bridge Processor Family BIOS Writer's Guide (BWG)"
* Document Number 504790
* Revision 1.6.0, June 2012 */

void intel_cpu_haswell_finalize_smm(void)
{
#if 0
/* Lock C-State MSR */
msr_set_bit(MSR_PKG_CST_CONFIG_CONTROL, 15);

/* Lock AES-NI only if supported */
if (cpuid_ecx(1) & (1 << 25))
msr_set_bit(MSR_FEATURE_CONFIG, 0);

#ifdef LOCK_POWER_CONTROL_REGISTERS
/*
* Lock the power control registers.
*
* These registers can be left unlocked if modifying power
* limits from the OS is desirable. Modifying power limits
* from the OS can be especially useful for experimentation
* during early phases of system bringup while the thermal
* power envelope is being proven.
*/

msr_set_bit(MSR_PP0_CURRENT_CONFIG, 31);
msr_set_bit(MSR_PP1_CURRENT_CONFIG, 31);
msr_set_bit(MSR_PKG_POWER_LIMIT, 63);
msr_set_bit(MSR_PP0_POWER_LIMIT, 31);
msr_set_bit(MSR_PP1_POWER_LIMIT, 31);
#endif

/* Lock TM interrupts - route thermal events to all processors */
msr_set_bit(MSR_MISC_PWR_MGMT, 22);

/* Lock memory configuration to protect SMM */
msr_set_bit(MSR_LT_LOCK_MEMORY, 0);
#endif
}
10 changes: 0 additions & 10 deletions src/cpu/intel/haswell/haswell.h
Expand Up @@ -118,16 +118,6 @@
# error "CONFIG_IED_REGION_SIZE is not a power of 2"
#endif

struct pei_data;
struct rcba_config_instruction;
struct romstage_params {
struct pei_data *pei_data;
const void *gpio_map;
const struct rcba_config_instruction *rcba_config;
void (*copy_spd)(struct pei_data *);
};
void romstage_common(const struct romstage_params *params);

/* Lock MSRs */
void intel_cpu_haswell_finalize_smm(void);

Expand Down
84 changes: 0 additions & 84 deletions src/cpu/intel/haswell/romstage.c

This file was deleted.

1 change: 0 additions & 1 deletion src/cpu/intel/model_1067x/model_1067x_init.c
Expand Up @@ -4,7 +4,6 @@
#include <device/device.h>
#include <cpu/cpu.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/mp.h>
#include <cpu/x86/lapic.h>
#include <cpu/intel/speedstep.h>
#include <cpu/x86/cache.h>
Expand Down
26 changes: 0 additions & 26 deletions src/cpu/intel/model_2065x/model_2065x_init.c
Expand Up @@ -147,13 +147,6 @@ static void configure_misc(void)
msr.lo = 0;
msr.hi = 0;
wrmsr(IA32_THERM_INTERRUPT, msr);

#ifdef DISABLED
/* Enable package critical interrupt only */
msr.lo = 1 << 4;
msr.hi = 0;
wrmsr(IA32_PACKAGE_THERM_INTERRUPT, msr);
#endif
}

static void enable_lapic_tpr(void)
Expand Down Expand Up @@ -188,22 +181,6 @@ static void set_max_ratio(void)
((perf_ctl.lo >> 8) & 0xff) * IRONLAKE_BCLK);
}

static void set_energy_perf_bias(u8 policy)
{
#ifdef DISABLED
msr_t msr;

/* Energy Policy is bits 3:0 */
msr = rdmsr(IA32_ENERGY_PERF_BIAS);
msr.lo &= ~0xf;
msr.lo |= policy & 0xf;
wrmsr(IA32_ENERGY_PERF_BIAS, msr);

printk(BIOS_DEBUG, "model_x06ax: energy policy set to %u\n",
policy);
#endif
}

static void configure_mca(void)
{
msr_t msr;
Expand Down Expand Up @@ -247,9 +224,6 @@ static void model_2065x_init(struct device *cpu)
/* Thermal throttle activation offset */
configure_thermal_target();

/* Set energy policy */
set_energy_perf_bias(ENERGY_POLICY_NORMAL);

/* Set Max Ratio */
set_max_ratio();

Expand Down
1 change: 0 additions & 1 deletion src/cpu/intel/model_206ax/common.c
@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <types.h>
#include <cpu/x86/msr.h>
#include "model_206ax.h"

Expand Down
18 changes: 0 additions & 18 deletions src/cpu/intel/model_206ax/finalize.c
Expand Up @@ -16,24 +16,6 @@ void intel_model_206ax_finalize_smm(void)
if (cpuid_ecx(1) & (1 << 25))
msr_set_bit(MSR_FEATURE_CONFIG, 0);

#ifdef LOCK_POWER_CONTROL_REGISTERS
/*
* Lock the power control registers.
*
* These registers can be left unlocked if modifying power
* limits from the OS is desirable. Modifying power limits
* from the OS can be especially useful for experimentation
* during early phases of system bringup while the thermal
* power envelope is being proven.
*/

msr_set_bit(MSR_PP0_CURRENT_CONFIG, 31);
msr_set_bit(MSR_PP1_CURRENT_CONFIG, 31);
msr_set_bit(MSR_PKG_POWER_LIMIT, 63);
msr_set_bit(MSR_PP0_POWER_LIMIT, 31);
msr_set_bit(MSR_PP1_POWER_LIMIT, 31);
#endif

/* Lock TM interrupts - route thermal events to all processors */
msr_set_bit(MSR_MISC_PWR_MGMT, 22);

Expand Down
1 change: 0 additions & 1 deletion src/cpu/intel/speedstep/acpi.c
Expand Up @@ -5,7 +5,6 @@
#include <acpi/acpi.h>
#include <acpi/acpigen.h>
#include <arch/cpu.h>
#include <cpu/x86/msr.h>
#include <cpu/intel/fsb.h>
#include <cpu/intel/speedstep.h>
#include <device/device.h>
Expand Down
84 changes: 84 additions & 0 deletions src/cpu/x86/64bit/exit32.inc
@@ -0,0 +1,84 @@
/* SPDX-License-Identifier: GPL-2.0-only */

/*
* For droping from long mode to protected mode.
*
* For reference see "AMD64 ArchitectureProgrammer's Manual Volume 2",
* Document 24593-Rev. 3.31-July 2019 Chapter 5.3
*
* Clobbers: rax, rbx, rcx, rdx
*/
.code64

#include <cpu/x86/msr.h>
#include <cpu/x86/cr.h>
#include <arch/rom_segs.h>

drop_longmode:
/* Ensure cache is clean. */
wbinvd

/* Set 32-bit code segment and ss */
mov $ROM_CODE_SEG, %rcx
/* SetCodeSelector32 will drop us to protected mode on return */
call SetCodeSelector32

/* Skip SetCodeSelector32 */
.code32
jmp __longmode_compatibility

.align 8
.code64
SetCodeSelector32:
# pop the return address from stack
pop %rbx

# save rsp because we need to push it after ss
mov %rsp, %rdx

# use iret to jump to a 32-bit offset in a new code segment
# iret will pop cs:rip, flags, then ss:rsp
mov %ss, %ax # need to push ss, but push ss instuction
push %rax # not valid in x64 mode, so use ax
push %rdx # the rsp to load
pushfq # push rflags
push %rcx # cx is code segment selector from caller
push %rbx # push the IP for the next instruction

# the iretq will behave like ret, with the new cs/ss value loaded
iretq

.align 4
.code32
__longmode_compatibility:
/* Running in 32-bit compatibility mode */

/* Use flat data segment */
movl $ROM_DATA_SEG, %eax
movl %eax, %ds
movl %eax, %es
movl %eax, %ss
movl %eax, %fs
movl %eax, %gs

/* Disable paging. */
movl %cr0, %eax
andl $(~CR0_PG), %eax
movl %eax, %cr0

/* Disable long mode. */
movl $(IA32_EFER), %ecx
rdmsr
andl $(~EFER_LME), %eax
wrmsr

/* Disable PAE. */
movl %cr4, %eax
andl $(~CR4_PAE), %eax
movl %eax, %cr4

/* Clear page table register */
xor %eax, %eax
movl %eax, %cr3

__longmode_exit:
1 change: 0 additions & 1 deletion src/cpu/x86/lapic/apic_timer.c
Expand Up @@ -4,7 +4,6 @@
#include <console/console.h>
#include <delay.h>
#include <thread.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/lapic.h>

void init_timer(void)
Expand Down
2 changes: 2 additions & 0 deletions src/cpu/x86/smm/smm_module_handler.c
Expand Up @@ -91,6 +91,8 @@ static void smi_restore_pci_address(void)

static const struct smm_runtime *smm_runtime;

struct global_nvs *gnvs;

void *smm_get_save_state(int cpu)
{
char *base;
Expand Down
2 changes: 2 additions & 0 deletions src/cpu/x86/smm/smm_module_loader.c
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <string.h>
#include <acpi/acpi_gnvs.h>
#include <rmodule.h>
#include <cpu/x86/smm.h>
#include <commonlib/helpers.h>
Expand Down Expand Up @@ -261,6 +262,7 @@ static int smm_module_setup_stub(void *smbase, size_t smm_size,
stub_params->runtime.smm_size = smm_size;
stub_params->runtime.save_state_size = params->per_cpu_save_state_size;
stub_params->runtime.num_cpus = params->num_concurrent_stacks;
stub_params->runtime.gnvs_ptr = (uintptr_t)acpi_get_gnvs();

/* Initialize the APIC id to CPU number table to be 1:1 */
for (i = 0; i < params->num_concurrent_stacks; i++)
Expand Down
2 changes: 2 additions & 0 deletions src/cpu/x86/smm/smm_stub.S
Expand Up @@ -36,6 +36,8 @@ save_state_size:
.long 0
num_cpus:
.long 0
gnvs_ptr:
.long 0
/* allows the STM to bring up SMM in 32-bit mode */
start32_offset:
.long smm_trampoline32 - _start
Expand Down
46 changes: 45 additions & 1 deletion src/cpu/x86/smm/smmhandler.S
Expand Up @@ -8,6 +8,7 @@
*/

#include <cpu/x86/lapic_def.h>
#include <cpu/x86/msr.h>

/*
* +--------------------------------+ 0xaffff
Expand Down Expand Up @@ -42,6 +43,14 @@

#define SMM_HANDLER_OFFSET 0x0000

#if defined(__x86_64__)
.bss
ia32efer_backup_eax:
.long
ia32efer_backup_edx:
.long
#endif

/* initially SMM is some sort of real mode. Let gcc know
* how to treat the SMM handler stub
*/
Expand Down Expand Up @@ -159,12 +168,44 @@ untampered_lapic:
/* Get SMM revision */
movl $0xa8000 + 0x7efc, %ebx /* core 0 address */
subl %ebp, %ebx /* subtract core X offset */

#if defined(__x86_64__)
/* Backup IA32_EFER. Preserves ebx. */
movl $(IA32_EFER), %ecx
rdmsr
movl %eax, ia32efer_backup_eax
movl %edx, ia32efer_backup_edx

/* Enable long mode. Preserves ebx. */
#include <cpu/x86/64bit/entry64.inc>

mov (%ebx), %rdi

#else
movl (%ebx), %eax
pushl %eax
#endif

/* Call 32bit C handler */
/* Call C handler */
call smi_handler

#if defined(__x86_64__)
/*
* The only reason to go back to protected mode is that RSM doesn't restore
* MSR registers and MSR IA32_EFER was modified by entering long mode.
* Drop to protected mode to safely operate on the IA32_EFER MSR.
*/

/* Disable long mode. */
#include <cpu/x86/64bit/exit32.inc>

/* Restore IA32_EFER as RSM doesn't restore MSRs. */
movl $(IA32_EFER), %ecx
movl ia32efer_backup_eax, %eax
movl ia32efer_backup_edx, %edx
wrmsr
#endif

/* To return, just do rsm. It will "clean up" protected mode */
rsm

Expand All @@ -190,6 +231,9 @@ smm_gdt:
.word 0xffff, 0x0000
.byte 0x00, 0x93, 0xcf, 0x00

/* gdt selector 0x18, flat code segment (64-bit) */
.word 0xffff, 0x0000
.byte 0x00, 0x9b, 0xaf, 0x00
smm_gdt_end:


Expand Down
21 changes: 0 additions & 21 deletions src/device/cardbus_device.c
Expand Up @@ -51,23 +51,6 @@ static void cardbus_record_bridge_resource(struct device *dev, resource_t moving
resource->size = min_size;
}

static void cardbus_size_bridge_resource(struct device *dev, unsigned int index)
{
struct resource *resource;
resource_t min_size;

resource = find_resource(dev, index);
if (resource) {
min_size = resource->size;
/*
* Always allocate at least the minimum size to a
* cardbus bridge in case a new card is plugged in.
*/
if (resource->size < min_size)
resource->size = min_size;
}
}

void cardbus_read_resources(struct device *dev)
{
resource_t moving_base, moving_limit, moving;
Expand All @@ -88,7 +71,6 @@ void cardbus_read_resources(struct device *dev)
/* Initialize the I/O space constraints on the current bus. */
cardbus_record_bridge_resource(dev, moving, CARDBUS_IO_SIZE,
PCI_CB_IO_BASE_0, IORESOURCE_IO);
cardbus_size_bridge_resource(dev, PCI_CB_IO_BASE_0);

/* See which bridge I/O resources are implemented. */
moving_base = pci_moving_config32(dev, PCI_CB_IO_BASE_1);
Expand Down Expand Up @@ -118,8 +100,6 @@ void cardbus_read_resources(struct device *dev)
type |= IORESOURCE_PREFETCH;
cardbus_record_bridge_resource(dev, moving, CARDBUS_MEM_SIZE,
PCI_CB_MEMORY_BASE_0, type);
if (type & IORESOURCE_PREFETCH)
cardbus_size_bridge_resource(dev, PCI_CB_MEMORY_BASE_0);

/* See which bridge memory resources are implemented. */
moving_base = pci_moving_config32(dev, PCI_CB_MEMORY_BASE_1);
Expand All @@ -129,7 +109,6 @@ void cardbus_read_resources(struct device *dev)
/* Initialize the memory space constraints on the current bus. */
cardbus_record_bridge_resource(dev, moving, CARDBUS_MEM_SIZE,
PCI_CB_MEMORY_BASE_1, IORESOURCE_MEM);
cardbus_size_bridge_resource(dev, PCI_CB_MEMORY_BASE_1);

compact_resources(dev);
}
Expand Down
5 changes: 0 additions & 5 deletions src/device/pci_device.c
Expand Up @@ -1631,11 +1631,6 @@ void pci_assign_irqs(struct device *dev, const unsigned char pIntAtoD[4])

pci_write_config8(dev, PCI_INTERRUPT_LINE, pIntAtoD[line - 1]);

#ifdef PARANOID_IRQ_ASSIGNMENTS
irq = pci_read_config8(pdev, PCI_INTERRUPT_LINE);
printk(BIOS_DEBUG, " Readback = %d\n", irq);
#endif

#if CONFIG(PC80_SYSTEM)
/* Change to level triggered. */
i8259_configure_irq_trigger(pIntAtoD[line - 1],
Expand Down