Merge remote-tracking branch 'upstream/master' into system76
Change-Id: Idceb013b3495324b8d84a388ea5ee5b5ea4b69db
This commit is contained in:
5
.gitmodules
vendored
5
.gitmodules
vendored
@@ -46,3 +46,8 @@
|
||||
path = 3rdparty/cmocka
|
||||
url = https://review.coreboot.org/cmocka.git
|
||||
update = none
|
||||
[submodule "3rdparty/qc_blobs"]
|
||||
path = 3rdparty/qc_blobs
|
||||
url = ../qc_blobs.git
|
||||
update = none
|
||||
ignore = dirty
|
||||
|
2
3rdparty/amd_blobs
vendored
2
3rdparty/amd_blobs
vendored
Submodule 3rdparty/amd_blobs updated: 0ac1af437d...1ac6d42bf3
2
3rdparty/blobs
vendored
2
3rdparty/blobs
vendored
Submodule 3rdparty/blobs updated: 7ad2d22452...bbe5d99780
2
3rdparty/libgfxinit
vendored
2
3rdparty/libgfxinit
vendored
Submodule 3rdparty/libgfxinit updated: 8fc8e49a93...3318bf2680
2
3rdparty/libhwbase
vendored
2
3rdparty/libhwbase
vendored
Submodule 3rdparty/libhwbase updated: bd0ed91cb9...a3edc6ef32
1
3rdparty/qc_blobs
vendored
Submodule
1
3rdparty/qc_blobs
vendored
Submodule
Submodule 3rdparty/qc_blobs added at 126fef6b99
2
3rdparty/vboot
vendored
2
3rdparty/vboot
vendored
Submodule 3rdparty/vboot updated: c531000f85...68de90c7e2
@@ -222,7 +222,7 @@
|
||||
<li>Add the acpi_create_fadt routine
|
||||
<ol type="I">
|
||||
<li>fill in the ACPI header</li>
|
||||
<li>Call the acpi_fill_in_fadt routine</li>
|
||||
<li>Call the acpi_fill_fadt routine</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ol>
|
||||
|
@@ -667,7 +667,7 @@ Use the following steps to debug the call to TempRamInit:
|
||||
</li>
|
||||
<li>Create a acpi.c module:
|
||||
<ol type="A">
|
||||
<li>Add the acpi_fill_in_fadt routine and initialize the values above</li>
|
||||
<li>Add the acpi_fill_fadt routine and initialize the values above</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ol>
|
||||
|
@@ -2,7 +2,7 @@
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD = sphinx-build
|
||||
SPHINXAUTOBUILD = sphinx-autobuild
|
||||
PAPER =
|
||||
|
@@ -42,13 +42,23 @@ At the moment *$n* is 4, which results in identity mapping the lower 4 GiB.
|
||||
* Fix compilation errors - *DONE*
|
||||
* Fix linker errors - *TODO*
|
||||
* Add x86_64 rmodule support - *DONE*
|
||||
* Add x86_64 exception handlers - *TODO*
|
||||
* Add x86_64 exception handlers - *DONE*
|
||||
* Setup page tables for long mode - *DONE*
|
||||
* Add assembly code for long mode - *DONE*
|
||||
* Add assembly code for SMM - *DONE*
|
||||
* Add assembly code for postcar stage - *TODO*
|
||||
* Add assembly code to return to protected mode - *TODO*
|
||||
* Implement reference code for mainboard `emulation/qemu-q35` - *TODO*
|
||||
|
||||
## Future work
|
||||
|
||||
1. Fine grained page tables for SMM:
|
||||
* Must not have execute and write permissions for the same page.
|
||||
* Must allow only that TSEG pages can be marked executable
|
||||
* Must reside in SMRAM
|
||||
2. Support 64bit PCI BARs above 4GiB
|
||||
3. Place and run code above 4GiB
|
||||
|
||||
## Porting other boards
|
||||
* Fix compilation errors
|
||||
* Test how well CAR works with x86_64 and paging
|
||||
|
@@ -1,6 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import subprocess
|
||||
from recommonmark.parser import CommonMarkParser
|
||||
import sphinx
|
||||
|
||||
# Get Sphinx version
|
||||
major = 0
|
||||
minor = 0
|
||||
patchlevel = 0
|
||||
version = sphinx.__version__.split(".")
|
||||
if len(version) > 1:
|
||||
major = int(version[0])
|
||||
minor = int(version[1])
|
||||
if len(version) > 2:
|
||||
patchlevel = int(version[2])
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
@@ -25,7 +37,18 @@ release = subprocess.check_output(('git', 'describe')).decode("utf-8")
|
||||
# The short X.Y version.
|
||||
version = release.split("-")[0]
|
||||
|
||||
extensions = ['sphinxcontrib.ditaa']
|
||||
extensions = []
|
||||
# Load recommonmark, supported since 1.8+
|
||||
if major >= 2 or (major == 1 and minor >= 8):
|
||||
extensions += ['recommonmark']
|
||||
|
||||
# Try to load DITAA
|
||||
try:
|
||||
import sphinxcontrib.ditaa
|
||||
except ImportError:
|
||||
print("Error: Please install sphinxcontrib.ditaa for ASCII art conversion\n")
|
||||
else:
|
||||
extensions += 'sphinxcontrib.ditaa'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
@@ -187,6 +210,8 @@ class MyCommonMarkParser(CommonMarkParser):
|
||||
|
||||
def setup(app):
|
||||
from recommonmark.transform import AutoStructify
|
||||
# Load recommonmark on old Sphinx
|
||||
if major == 1 and minor < 8:
|
||||
app.add_source_parser('.md', MyCommonMarkParser)
|
||||
|
||||
app.add_config_value('recommonmark_config', {
|
||||
|
313
Documentation/drivers/dptf.md
Normal file
313
Documentation/drivers/dptf.md
Normal file
@@ -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
|
@@ -5,7 +5,7 @@ storage driver.
|
||||
|
||||
## SMMSTORE
|
||||
|
||||
SMMSTORE is a SMM mediated driver to read from, write to and erase a
|
||||
SMMSTORE is a [SMM] mediated driver to read from, write to and erase a
|
||||
predefined region in flash. It can be enabled by setting
|
||||
`CONFIG_SMMSTORE=y` in menuconfig.
|
||||
|
||||
@@ -117,7 +117,18 @@ INPUT:
|
||||
- `val`: pointer to the value data
|
||||
- `valsize`: size of the value data
|
||||
|
||||
#### Security
|
||||
|
||||
Pointers provided by the payload or OS are checked to not overlap with the SMM.
|
||||
That protects the SMM handler from being manipulated.
|
||||
|
||||
*However there's no validation done on the source or destination pointing to
|
||||
DRAM. A malicious application that is able to issue SMIs could extract arbitrary
|
||||
data or modify the currently running kernel.*
|
||||
|
||||
## External links
|
||||
|
||||
* [A Tour Beyond BIOS Implementing UEFI Authenticated Variables in SMM with EDKI](https://software.intel.com/sites/default/files/managed/cf/ea/a_tour_beyond_bios_implementing_uefi_authenticated_variables_in_smm_with_edkii.pdf)
|
||||
Note, this differs significantly from coreboot's implementation.
|
||||
|
||||
[SMM]: ../security/smm.md
|
||||
|
353
Documentation/lib/fw_config.md
Normal file
353
Documentation/lib/fw_config.md
Normal file
@@ -0,0 +1,353 @@
|
||||
# Firmware Configuration Interface in coreboot
|
||||
|
||||
## Motivation
|
||||
|
||||
The firmware configuration interface in coreboot is designed to support a wide variety of
|
||||
configuration options in that are dictated by the hardware at runtime. This allows a single
|
||||
BIOS image to be used across a wide variety of devices which may have key differences but are
|
||||
otherwise similar enough to use the same coreboot build target.
|
||||
|
||||
The initial implementation is designed to take advantage of a bitmask returned by the Embedded
|
||||
Controller on Google Chrome OS devices which allows the manufacturer to use the same firmware
|
||||
image across multiple devices by selecting various options at runtime. See the Chromium OS
|
||||
[Firmware Config][1] documentation for more information.
|
||||
|
||||
This firmware configuration interface differs from the CMOS option interface in that this
|
||||
bitmask value is not intended as a user-configurable setting as the configuration values must
|
||||
match the actual hardware. In the case where a user was to swap their hardware this value
|
||||
would need to be updated or overridden.
|
||||
|
||||
## Device Presence
|
||||
|
||||
One common example of why a firmware configuration interface is important is determining if a
|
||||
device is present in the system. With some bus topologies and hardware mechanisms it is
|
||||
possible to probe and enumerate this at runtime:
|
||||
|
||||
- PCI is a self-discoverable bus and is very easy to handle.
|
||||
- I2C devices can often be probed with a combination of bus and address.
|
||||
- The use of GPIOs with external strap to ground or different voltages can be used to detect
|
||||
presence of a device.
|
||||
|
||||
However there are several cases where this is insufficient:
|
||||
|
||||
- I2C peripherals that require different drivers but have the same bus address cannot be
|
||||
uniquely identified at runtime.
|
||||
- A mainboard may be designed with multiple daughter board combinations which contain devices
|
||||
and configurations that cannot be detected.
|
||||
- While presence detect GPIOs are a convenient way for a single device presence, they are
|
||||
unable to distinguish between different devices so it can require a large number of GPIOs to
|
||||
support relatively few options.
|
||||
|
||||
This presence detection can impact different stages of boot:
|
||||
|
||||
### ACPI
|
||||
|
||||
Devices that are not present should not provide an ACPI device indicating that they are
|
||||
present or the operating system may not be able to handle it correctly.
|
||||
|
||||
The ACPI devices are largely driven by chips defined in the mainboard `devicetree.cb` and
|
||||
the variant overridetree.cb. This means it is important to be able to specify when a device
|
||||
is present or not directly in `devicetree.cb` itself. Otherwise each mainboard needs custom
|
||||
code to parse the tree and disable unused devices.
|
||||
|
||||
### GPIO
|
||||
|
||||
GPIOs with multiple functions may need to be configured correctly depending on the attached
|
||||
device. Given the wide variety of GPIO configuration possibilities it is not feasible to
|
||||
specify all combinations directly in `devicetree.cb` and it is best left to code provided by
|
||||
the mainboard.
|
||||
|
||||
### FSP UPD
|
||||
|
||||
Enabling and disabling devices may require altering FSP UPD values that are provided to the
|
||||
various stages of FSP. These options are also not easy to specify multiple times for
|
||||
different configurations in `devicetree.cb` and can be provided by the mainboard as code.
|
||||
|
||||
## Firmware Configuration Interface
|
||||
|
||||
The firmware configuration interface can be enabled by selecting `CONFIG_FW_CONFIG` and also
|
||||
providing a source for the value by defining an additional Kconfig option defined below.
|
||||
|
||||
If the firmware configuration interface is disabled via Kconfig then all probe attempts will
|
||||
return true.
|
||||
|
||||
## Firmware Configuration Value
|
||||
|
||||
The 32bit value used as the firmware configuration bitmask is meant to be determined at runtime
|
||||
but could also be defined at compile time if needed.
|
||||
|
||||
There are two supported sources for providing this information to coreboot.
|
||||
|
||||
### CBFS
|
||||
|
||||
The value can be provided with a 32bit raw value in CBFS that is read by coreboot. The value
|
||||
can be set at build time but also adjusted in an existing image with `cbfstool`.
|
||||
|
||||
To enable this select the `CONFIG_FW_CONFIG_CBFS` option in the build configuration and add a
|
||||
raw 32bit value to CBFS with the name of the current prefix at `CONFIG_FW_PREFIX/fw_config`.
|
||||
|
||||
When `fw_config_probe_device()` or `fw_config_probe()` is called it will look for the specified
|
||||
file in CBFS use the value it contains when matching fields and options.
|
||||
|
||||
### Embedded Controller
|
||||
|
||||
Google Chrome OS devices support an Embedded Controller interface for reading and writing the
|
||||
firmware configuration value, along with other board-specific information. It is possible for
|
||||
coreboot to read this value at boot on systems that support this feature.
|
||||
|
||||
This option is selected by default for the mainboards that use it with
|
||||
`CONFIG_FW_CONFIG_CHROME_EC_CBI` and it is not typically necessary to adjust the value. It is
|
||||
possible by enabling the CBFS source and coreboot will look in CBFS first for a valid value
|
||||
before asking the embedded controller.
|
||||
|
||||
It is also possible to adjust the value in the embedded controller *(after disabling write
|
||||
protection)* with the `ectool` command in a Chrome OS environment.
|
||||
|
||||
For more information on the firmware configuration field on Chrome OS devices see the Chromium
|
||||
documentation for [Firmware Config][1] and [Board Info][2].
|
||||
|
||||
[1]: http://chromium.googlesource.com/chromiumos/docs/+/master/design_docs/firmware_config.md
|
||||
[2]: http://chromium.googlesource.com/chromiumos/docs/+/master/design_docs/cros_board_info.md
|
||||
|
||||
## Firmware Configuration Table
|
||||
|
||||
The firmware configuration table itself is defined in the mainboard `devicetree.cb` with
|
||||
special tokens for defining fields and options.
|
||||
|
||||
The table itself is enclosed in a `fw_config` token and terminated with `end` and it contains
|
||||
a mix of field and option definitions.
|
||||
|
||||
Each field is defined by providing the field name and the start and end bit marking the exact
|
||||
location in the bitmask. Field names must be at least three characters long in order to
|
||||
satisfy the sconfig parser requirements and they must be unique with non-overlapping masks.
|
||||
|
||||
field <name> <start-bit> <end-bit> [option...] end
|
||||
|
||||
For single-bit fields only one number is needed:
|
||||
|
||||
field <name> <bit> [option...] end
|
||||
|
||||
Each `field` definition starts a new block that can be composed of zero or more field options,
|
||||
and it is terminated with `end`.
|
||||
|
||||
Inside the field block the options can be defined by providing the option name and the field
|
||||
value that this option represents when the bit offsets are used to apply a mask and shift.
|
||||
Option names must also be at least three characters for the sconfig parser.
|
||||
|
||||
option <name> <value>
|
||||
|
||||
It is possible for there to be multiple `fw_config` blocks and for subsequent `field` blocks
|
||||
to add additional `option` definitions to the existing field. These subsequent definitions
|
||||
should not provide the field bitmask as it has already been defined earlier in the file and
|
||||
this is just matching an existing field by name.
|
||||
|
||||
field <name> [option...] end
|
||||
|
||||
This allows a baseboard to define the major fields and options in `devicetree.cb` and a board
|
||||
variant to add specific options to fields in or define new fields in the unused bitmask in
|
||||
`overridetree.cb`.
|
||||
|
||||
It is not possible to redefine a field mask or override the value of an existing option this
|
||||
way, only to add new options to a field or new fields to the table.
|
||||
|
||||
### Firmware Configuration Table Example
|
||||
|
||||
In this example a baseboard defines a simple boolean feature that is enabled or disabled
|
||||
depending on the value of bit 0, and a field at bits 1-2 that indicates which daughter board
|
||||
is attached.
|
||||
|
||||
The baseboard itself defines one daughter board and the variant adds two more possibilities.
|
||||
This way each variant can support multiple possible daughter boards in addition to the one
|
||||
that was defined by the baseboard.
|
||||
|
||||
#### devicetree.cb
|
||||
|
||||
fw_config
|
||||
field FEATURE 0
|
||||
option DISABLED 0
|
||||
option ENABLED 1
|
||||
end
|
||||
field DAUGHTER_BOARD 1 2
|
||||
option NONE 0
|
||||
option REFERENCE_DB 1
|
||||
end
|
||||
end
|
||||
|
||||
#### overridetree.cb
|
||||
|
||||
fw_config
|
||||
field DAUGHTER_BOARD
|
||||
option VARIANT_DB_ONE 2
|
||||
option VARIANT_DB_TWO 3
|
||||
end
|
||||
end
|
||||
|
||||
The result of this table defined in `devicetree.cb` is a list of constants that can be used
|
||||
to check if fields match the firmware configuration options determined at runtime with a
|
||||
simple check of the field mask and the option value.
|
||||
|
||||
#### static.h
|
||||
|
||||
```c
|
||||
/* field: FEATURE */
|
||||
#define FW_CONFIG_FIELD_FEATURE_NAME "FEATURE"
|
||||
#define FW_CONFIG_FIELD_FEATURE_MASK 0x00000001
|
||||
#define FW_CONFIG_FIELD_FEATURE_OPTION_DISABLED_NAME "DISABLED"
|
||||
#define FW_CONFIG_FIELD_FEATURE_OPTION_DISABLED_VALUE 0x00000000
|
||||
#define FW_CONFIG_FIELD_FEATURE_OPTION_ENABLED_NAME "ENABLED"
|
||||
#define FW_CONFIG_FIELD_FEATURE_OPTION_ENABLED_VALUE 0x00000001
|
||||
|
||||
/* field: DAUGHTER_BOARD */
|
||||
#define FW_CONFIG_FIELD_DAUGHTER_BOARD_NAME "DAUGHTER_BOARD"
|
||||
#define FW_CONFIG_FIELD_DAUGHTER_BOARD_MASK 0x00000006
|
||||
#define FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_NONE_NAME "NONE"
|
||||
#define FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_NONE_VALUE 0x00000000
|
||||
#define FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_REFERENCE_DB_NAME "REFERENCE_DB"
|
||||
#define FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_REFERENCE_DB_VALUE 0x00000002
|
||||
#define FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_VARIANT_DB_ONE_NAME "VARIANT_DB_ONE"
|
||||
#define FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_VARIANT_DB_ONE_VALUE 0x00000004
|
||||
#define FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_VARIANT_DB_TWO_NAME "VARIANT_DB_TWO"
|
||||
#define FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_VARIANT_DB_TWO_VALUE 0x00000006
|
||||
```
|
||||
|
||||
## Device Probing
|
||||
|
||||
One use of the firmware configuration interface in devicetree is to allow device probing to be
|
||||
specified directly with the devices themselves. A new `probe` token is introduced to allow a
|
||||
device to be probed by field and option name. Multiple `probe` entries may be present for
|
||||
each device and any successful probe will consider the device to be present.
|
||||
|
||||
### Probing Example
|
||||
|
||||
Continuing with the previous example this device would be considered present if the field
|
||||
`DAUGHTER_BOARD` was set to either `VARIANT_DB_ONE` or `VARIANT_DB_TWO`:
|
||||
|
||||
#### overridetree.cb
|
||||
|
||||
chip drivers/generic/example
|
||||
device generic 0 on
|
||||
probe DAUGHTER_BOARD VARIANT_DB_ONE
|
||||
probe DAUGHTER_BOARD VARIANT_DB_TWO
|
||||
end
|
||||
end
|
||||
|
||||
If the field were set to any other option, including `NONE` and `REFERENCE_DB` and any
|
||||
undefined value then the device would be disabled.
|
||||
|
||||
### Probe Overrides
|
||||
|
||||
When a device is declared with a probe in the baseboard `devicetree.cb` and the same device
|
||||
is also present in the `overridetree.cb` then the probing information from the baseboard
|
||||
is discarded and the override device must provide all necessary probing information.
|
||||
|
||||
In this example a device is listed in the baseboard with `DAUGHTER_BOARD` field probing for
|
||||
`REFERENCE_DB` as a field option, It is also defined as an override device with the field
|
||||
probing for the `VARIANT_DB_ONE` option instead.
|
||||
|
||||
In this case only the probe listed in the override is checked and a field option of
|
||||
`REFERENCE_DB` will not mark this device present. If both options are desired then the
|
||||
override device must list both. This allows an override device to remove a probe entry that
|
||||
was defined in the baseboard.
|
||||
|
||||
#### devicetree.cb
|
||||
|
||||
chip drivers/generic/example
|
||||
device generic 0 on
|
||||
probe DAUGHTER_BOARD REFERENCE_DB
|
||||
end
|
||||
end
|
||||
|
||||
#### overridetree.cb
|
||||
|
||||
chip drivers/generic/example
|
||||
device generic 0 on
|
||||
probe DAUGHTER_BOARD VARIANT_DB_ONE
|
||||
end
|
||||
end
|
||||
|
||||
### Automatic Device Probing
|
||||
|
||||
At boot time the firmware configuration interface will walk the device tree and apply any
|
||||
probe entries that were defined in `devicetree.cb`. This probing takes effect before the
|
||||
`BS_DEV_ENUMERATE` step during the boot state machine in ramstage.
|
||||
|
||||
Devices that have a probe list but do do not find a match are disabled by setting
|
||||
`dev->enabled = 0` but the chip `enable_dev()` and device `enable()` handlers will still
|
||||
be executed to allow any device disable code to execute.
|
||||
|
||||
The result of this probe definition is to provide an array of structures describing each
|
||||
field and option to check.
|
||||
|
||||
#### fw_config.h
|
||||
|
||||
```c
|
||||
/**
|
||||
* struct fw_config - Firmware configuration field and option.
|
||||
* @field_name: Name of the field that this option belongs to.
|
||||
* @option_name: Name of the option within this field.
|
||||
* @mask: Bitmask of the field.
|
||||
* @value: Value of the option within the mask.
|
||||
*/
|
||||
struct fw_config {
|
||||
const char *field_name;
|
||||
const char *option_name;
|
||||
uint32_t mask;
|
||||
uint32_t value;
|
||||
};
|
||||
```
|
||||
|
||||
#### static.c
|
||||
|
||||
```c
|
||||
STORAGE struct fw_config __devN_probe_list[] = {
|
||||
{
|
||||
.field_name = FW_CONFIG_FIELD_DAUGHTER_BOARD_NAME,
|
||||
.option_name = FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_VARIANT_DB_ONE_NAME,
|
||||
.mask = FW_CONFIG_FIELD_DAUGHTER_BOARD_MASK,
|
||||
.value = FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_VARIANT_DB_ONE_VALUE
|
||||
},
|
||||
{
|
||||
.field_name = FW_CONFIG_FIELD_DAUGHTER_BOARD_NAME,
|
||||
.option_name = FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_VARIANT_DB_TWO_NAME,
|
||||
.mask = FW_CONFIG_FIELD_DAUGHTER_BOARD_MASK,
|
||||
.value = FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_VARIANT_DB_TWO_VALUE
|
||||
},
|
||||
{ }
|
||||
};
|
||||
```
|
||||
|
||||
### Runtime Probing
|
||||
|
||||
The device driver probing allows for seamless integration with the mainboard but it is only
|
||||
effective in ramstage and for specific devices declared in devicetree.cb. There are other
|
||||
situations where code may need to probe or check the value of a field in romstage or at other
|
||||
points in ramstage. For this reason it is also possible to use the firmware configuration
|
||||
interface directly.
|
||||
|
||||
```c
|
||||
/**
|
||||
* fw_config_probe() - Check if field and option matches.
|
||||
* @match: Structure containing field and option to probe.
|
||||
*
|
||||
* Return %true if match is found, %false if match is not found.
|
||||
*/
|
||||
bool fw_config_probe(const struct fw_config *match);
|
||||
```
|
||||
|
||||
The argument provided to this function can be created from a macro for easy use:
|
||||
|
||||
FW_CONFIG(field, option)
|
||||
|
||||
This example has a mainboard check if a feature is disabled and set an FSP UPD before memory
|
||||
training. This example expects that the default value of this `register` is set to `true` in
|
||||
`devicetree.cb` and this code is disabling that feature before FSP is executed.
|
||||
|
||||
```c
|
||||
#include <fw_config.h>
|
||||
|
||||
void mainboard_memory_init_params(FSPM_UPD *mupd)
|
||||
{
|
||||
if (fw_config_probe_one(FW_CONFIG(FEATURE, DISABLED))
|
||||
mupd->ExampleFeature = false;
|
||||
}
|
||||
```
|
@@ -3,7 +3,7 @@
|
||||
This section contains documentation about coreboot internal technical
|
||||
information and libraries.
|
||||
|
||||
## Structure and layout
|
||||
- [Flashmap and Flashmap Descriptor](flashmap.md)
|
||||
- [ABI data consumption](abi-data-consumption.md)
|
||||
- [Timestamps](timestamp.md)
|
||||
- [Firmware Configuration Interface](fw_config.md)
|
||||
|
@@ -15,7 +15,7 @@ from [Gigabyte].
|
||||
+---------------------+------------+
|
||||
| Size | 4 MiB |
|
||||
+---------------------+------------+
|
||||
| In circuit flashing | Yes |
|
||||
| In circuit flashing | No |
|
||||
+---------------------+------------+
|
||||
| Package | SOIC-8 |
|
||||
+---------------------+------------+
|
||||
|
@@ -1,40 +0,0 @@
|
||||
# Google Dragonegg (Chromebook)
|
||||
|
||||
This page describes how to run coreboot on the google dragonegg board.
|
||||
|
||||
Dragonegg is based on Intel Ice Lake platform, please refer to below link to get more details
|
||||
```eval_rst
|
||||
:doc:`../../soc/intel/icelake/iceLake_coreboot_development`
|
||||
```
|
||||
|
||||
## Building coreboot
|
||||
|
||||
* Follow build instructions mentioned in Ice Lake document
|
||||
```eval_rst
|
||||
:doc:`../../soc/intel/icelake/iceLake_coreboot_development`
|
||||
```
|
||||
|
||||
* The default options for this board should result in a fully working image:
|
||||
```bash
|
||||
# echo "CONFIG_VENDOR_GOOGLE=y" > .config
|
||||
# echo "CONFIG_BOARD_GOOGLE_DRAGONEGG=y" >> .config
|
||||
# make olddefconfig && make
|
||||
```
|
||||
|
||||
## Flashing coreboot
|
||||
|
||||
```eval_rst
|
||||
+---------------------+------------+
|
||||
| Type | Value |
|
||||
+=====================+============+
|
||||
| Socketed flash | no |
|
||||
+---------------------+------------+
|
||||
| Vendor | Winbond |
|
||||
+---------------------+------------+
|
||||
| Size | 32 MiB |
|
||||
+---------------------+------------+
|
||||
| Internal flashing | yes |
|
||||
+---------------------+------------+
|
||||
| External flashing | yes |
|
||||
+---------------------+------------+
|
||||
```
|
@@ -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)
|
||||
@@ -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
|
||||
@@ -116,6 +113,10 @@ The boards in this section are not real mainboards, but emulators.
|
||||
|
||||
- [MS-7707](msi/ms7707/ms7707.md)
|
||||
|
||||
## OCP
|
||||
|
||||
- [Tioga Pass](ocp/tiogapass.md)
|
||||
|
||||
## Open Cellular
|
||||
|
||||
- [Elgon](opencellular/elgon.md)
|
||||
@@ -130,6 +131,10 @@ The boards in this section are not real mainboards, but emulators.
|
||||
|
||||
- [PQ7-M107](portwell/pq7-m107.md)
|
||||
|
||||
## Prodrive
|
||||
|
||||
- [Hermes](prodrive/hermes.md)
|
||||
|
||||
## Protectli
|
||||
|
||||
- [FW2B / FW4B](protectli/fw2b_fw4b.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
|
||||
|
19
Documentation/mainboard/lenovo/x230s.md
Normal file
19
Documentation/mainboard/lenovo/x230s.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# ThinkPad Lenovo X230s
|
||||
|
||||
## Disassembly Instructions
|
||||
|
||||
You must remove the following parts to access the SPI flash chip:
|
||||
|
||||

|
||||
|
||||
* 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.
|
BIN
Documentation/mainboard/lenovo/x230s_bc_removed.jpg
Normal file
BIN
Documentation/mainboard/lenovo/x230s_bc_removed.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 42 KiB |
128
Documentation/mainboard/ocp/deltalake.md
Normal file
128
Documentation/mainboard/ocp/deltalake.md
Normal file
@@ -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
|
100
Documentation/mainboard/ocp/tiogapass.md
Normal file
100
Documentation/mainboard/ocp/tiogapass.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# OCP Tioga Pass
|
||||
|
||||
This page describes coreboot support status for the [OCP] (Open Compute Project)
|
||||
Tioga Pass server platform.
|
||||
|
||||
## Introduction
|
||||
|
||||
OCP Tioga Pass server platform was contributed by Facebook, and was accepted
|
||||
in 2019. The design collateral including datasheet can be found at [OCP Tioga Pass].
|
||||
|
||||
Since complete EE design collateral is open sourced, anyone can build server
|
||||
as-is or a variant based on the original design. It can also be purchased from [OCP Market Place].
|
||||
An off-the-shelf version is available, as well as rack ready version. With the
|
||||
off-the-shelf version, the server can be plugged into wall power outlet.
|
||||
|
||||
With the off-the-shelf version of Tioga Pass, a complete software solution is
|
||||
available. [Off-the-shelf Host Firmware] takes the approach of UEFI/Linuxboot.
|
||||
|
||||
coreboot as of release 4.13 is a proof-of-concept project between Facebook,
|
||||
Intel, Wiwynn and Quanta. The context is described at [OCP Tioga Pass POC Blog].
|
||||
|
||||
## Required blobs
|
||||
|
||||
This board currently requires:
|
||||
- FSP blob: The blob (Intel Skylake Scalable Processor Firmware Support Package)
|
||||
is not yet available to the public. The binary is at POC status, hopefully
|
||||
someday an IBV is able to obtain the privilege to maintain it.
|
||||
- Microcode: `3rdparty/intel-microcode/intel-ucode/06-55-04`
|
||||
- ME binary: The binary can be extracted from [Off-the-shelf Host Firmware].
|
||||
|
||||
## Payload
|
||||
- Linuxboot: This is necessary only if you use Linuxboot as coreboot payload.
|
||||
U-root as initramfs, is used in the POC activity. It can be extracted from
|
||||
[Off-the-shelf Host Firmware], or 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 mb --force --update <path to coreboot image>
|
||||
|
||||
To power off/on the host:
|
||||
power-util mb off
|
||||
power-util mb on
|
||||
|
||||
To connect to console through SOL (Serial Over Lan):
|
||||
sol-util mb
|
||||
|
||||
## Known issues / feature gaps
|
||||
- C6 state is not supported. Workaround is to disable C6 support through
|
||||
target OS and Linuxboot kernel paramter, such as "cpuidle.off=1".
|
||||
- SMI handlers are not implemented.
|
||||
- xSDT tables are not fully populated, such as processor/socket devices,
|
||||
PCIe bridge devices.
|
||||
- There is boot stability issue. Occasionally the boot hangs at ramstage
|
||||
with following message "BIOS PCU Misc Config Read timed out."
|
||||
- If [CB 40500 patchset] is not merged, when PCIe riser card is used,
|
||||
boot fails.
|
||||
- PCIe devices connected to socket 1 may not work, because FSP
|
||||
does not support PCIe topology input for socket 1.k
|
||||
- SMBIOS type 7 and type 17 are not populated.
|
||||
|
||||
## Working
|
||||
The solution was developed using Linuxboot payload. The Linuxboot
|
||||
kernel versions tried are 4.16.18 and 5.2.9. The initramfs image is
|
||||
u-root.
|
||||
- Most SMBIOS types
|
||||
- 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/DMAR/DSDT/FACP/FACS/HPET/MCFG/SPMI/SRAT/SLIT/SSDT
|
||||
|
||||
## Technology
|
||||
|
||||
```eval_rst
|
||||
+------------------------+---------------------------------------------+
|
||||
| Processor (2 sockets) | Intel Skylake Scalable Processor LGA3647 |
|
||||
+------------------------+---------------------------------------------+
|
||||
| BMC | Aspeed AST 2500 |
|
||||
+------------------------+---------------------------------------------+
|
||||
| PCH | Intel Lewisburg C621 |
|
||||
+------------------------+---------------------------------------------+
|
||||
```
|
||||
|
||||
[flashrom]: https://flashrom.org/Flashrom
|
||||
[OCP]: https://www.opencompute.org/
|
||||
[OCP Tioga Pass]: https://www.opencompute.org/contributions?query=Tioga%20Pass%20v1.0
|
||||
[OCP Market Place]: https://www.opencompute.org/products/109/wiwynn-tioga-pass-advanced-2u-ocp-server-up-to-768gb-12-dimm-slots-4-ssds-for-io-performance
|
||||
[Off-the-shelf Host Firmware]: https://github.com/linuxboot/book/blob/master/case_studies/TiogaPass/README.md
|
||||
[OCP Tioga Pass POC Blog]: https://www.opencompute.org/blog/linux-firmware-boots-up-server-powered-by-intelr-xeonr-scalable-processor
|
||||
[All about u-root]: https://github.com/linuxboot/book/tree/master/u-root
|
||||
[CB 40500 patchset]: https://review.coreboot.org/c/coreboot/+/40500
|
54
Documentation/mainboard/prodrive/hermes.md
Normal file
54
Documentation/mainboard/prodrive/hermes.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Hermes
|
||||
|
||||
Hermes is a regular ATX board designed for workstation PCs.
|
||||
|
||||
The board features:
|
||||
* 5 PCIe 16x Gen3 slots
|
||||
* 4 ECC capable DDR4 DIMMs
|
||||
* 5 dedicated Ethernet ports
|
||||
* 1 BMC Ethernet port
|
||||
* VGA
|
||||
* COM port
|
||||
* 2 COM port headers
|
||||
* 4 SATA ports,
|
||||
* NVMe M2 slot
|
||||
* CNVi M2 slot
|
||||
* 3 optional DisplayPort outputs
|
||||
* optional TPM2
|
||||
|
||||
## Required proprietary blobs
|
||||
|
||||
- [Intel FSP2.0]
|
||||
- Intel SPS
|
||||
|
||||
## Flashing coreboot
|
||||
|
||||
* The BIOS flash can be updated over the BMC, but the update file has a proprietary format
|
||||
* For development a dediprog compatible pinheader is present which allows to use an EM100
|
||||
|
||||
## Known issues
|
||||
|
||||
- MRC caching does not work on cold boot with Intel SPS (see [Intel FSP2.0])
|
||||
|
||||
## Technology
|
||||
|
||||
```eval_rst
|
||||
+------------------+--------------------------------------------------+
|
||||
| CPU | CoffeeLake + CoffeeLake R (Core + Xeon) |
|
||||
+------------------+--------------------------------------------------+
|
||||
| PCH | Intel C246 |
|
||||
+------------------+--------------------------------------------------+
|
||||
| Coprocessor | Intel SPS (server version of the ME) |
|
||||
+------------------+--------------------------------------------------+
|
||||
| Super I/O | none |
|
||||
+------------------+--------------------------------------------------+
|
||||
| BMC | Aspeed AST2500 |
|
||||
+------------------+--------------------------------------------------+
|
||||
```
|
||||
|
||||
## Extra links
|
||||
|
||||
[flashrom]: https://flashrom.org/Flashrom
|
||||
[flashing tutorial]: ../../../../flash_tutorial/ext_power.md
|
||||
[Intel FSP2.0]: ../../../../soc/intel/fsp/index.md
|
||||
[AST2500]: https://www.aspeedtech.com/products.php?fPath=20&rId=440
|
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
|
@@ -13,4 +13,30 @@ Update this document with changes that should be in the release notes.
|
||||
Significant changes
|
||||
-------------------
|
||||
|
||||
### Hidden PCI devices
|
||||
|
||||
This new functionality takes advantage of the existing 'hidden' keyword in the
|
||||
devicetree. Since no existing boards were using the keyword, its usage was
|
||||
repurposed to make dealing with some unique PCI devices easier. The particular
|
||||
case here is Intel's PMC (Power Management Controller). During the FSP-S run,
|
||||
the PMC device is made hidden, meaning that its config space looks as if there
|
||||
is no device there (Vendor ID reads as 0xFFFF_FFFF). However, the device does
|
||||
have fixed resources, both MMIO and I/O. These were previously recorded in
|
||||
different places (MMIO was typically an SA fixed resource, and I/O was treated
|
||||
as an LPC resource). With this change, when a device in the tree is marked as
|
||||
'hidden', it is not probed (`pci_probe_dev()`) but rather assumed to exist so
|
||||
that its resources can be placed in a more natural location. This also adds the
|
||||
ability for the device to participate in SSDT generation.
|
||||
|
||||
### Tools for generating SPDs for LP4x memory on TGL and JSL
|
||||
|
||||
A set of new tools `gen_spd.go` and `gen_part_id.go` are added to automate the
|
||||
process of generating SPDs for LP4x memory and assigning hardware strap IDs for
|
||||
memory parts used on TGL and JSL based boards. The SPD data obtained from memory
|
||||
part vendors has to be massaged to format it correctly as per JEDEC and Intel MRC
|
||||
expectations. These tools take a list of memory parts describing their physical
|
||||
attributes as per their datasheet and convert those attributes into SPD files for
|
||||
the platforms. More details about the tools are added in
|
||||
[README.md](https://review.coreboot.org/plugins/gitiles/coreboot/+/refs/heads/master/util/spd_tools/intel/lp4x/README.md).
|
||||
|
||||
### Add significant changes here
|
||||
|
@@ -13,3 +13,7 @@ This section describes documentation about the security architecture of coreboot
|
||||
- [Intel TXT in general](intel/txt.md)
|
||||
- [Intel TXT Initial Boot Block](intel/txt_ibb.md)
|
||||
- [Intel Authenticated Code Modules](intel/acm.md)
|
||||
|
||||
## SMM
|
||||
|
||||
- [System Management Mode](smm.md)
|
||||
|
29
Documentation/security/smm.md
Normal file
29
Documentation/security/smm.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# x86 System Managment Mode
|
||||
|
||||
## Introduction
|
||||
|
||||
The code running in System Management Mode (SMM) provides runtime services
|
||||
to applications running in [ring0]. It has a higher privilege level than
|
||||
[ring0] and resides in the SMRAM region which cannot be accessed from [ring0].
|
||||
|
||||
SMM can be entered by issuing System Managment Interrupts (SMIs).
|
||||
|
||||
## Secure data exchange
|
||||
|
||||
In order to not leak SMM internals or accidentally overwrite parts of SMM,
|
||||
[ring0] provided data (pointers, offsets, sizes, ...) must be checked before
|
||||
using them in SMM.
|
||||
|
||||
There exist two methods to verify data:
|
||||
|
||||
```C
|
||||
/* Returns true if the region overlaps with the SMM */
|
||||
bool smm_region_overlaps_handler(struct region *r);
|
||||
```
|
||||
|
||||
```C
|
||||
/* Returns true if the memory pointed to overlaps with SMM reserved memory. */
|
||||
static inline bool smm_points_to_smram(const void *ptr, const size_t len);
|
||||
```
|
||||
|
||||
[ring0]: https://en.wikipedia.org/wiki/Protection_ring
|
@@ -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`).
|
||||
|
||||
|
641
MAINTAINERS
641
MAINTAINERS
@@ -133,65 +133,101 @@ Maintainers List (try to look for most precise areas first)
|
||||
|
||||
-----------------------------------
|
||||
|
||||
RISC-V ARCHITECTURE
|
||||
M: Ronald Minnich <rminnich@gmail.com>
|
||||
R: Philipp Hug <philipp@hug.cx>
|
||||
S: Maintained
|
||||
F: src/arch/riscv/
|
||||
F: src/soc/sifive/
|
||||
F: src/soc/ucb/
|
||||
F: src/mainboard/emulation/*-riscv/
|
||||
F: src/mainboard/sifive/
|
||||
F: util/riscv/
|
||||
|
||||
PPC64 ARCHITECTURE
|
||||
M: Ronald Minnich <rminnich@gmail.com>
|
||||
M: Timothy Pearson <tpearson@raptorengineeringinc.com>
|
||||
S: Maintained
|
||||
F: src/arch/ppc64/
|
||||
F: src/cpu/qemu-power8/
|
||||
F: src/mainboard/emulation/qemu-power8/
|
||||
|
||||
LENOVO EC
|
||||
M: Alexander Couzens <lynxis@fe80.eu>
|
||||
S: Maintained
|
||||
F: src/ec/lenovo/
|
||||
|
||||
LENOVO MAINBOARDS
|
||||
M: Alexander Couzens <lynxis@fe80.eu>
|
||||
M: Patrick Rudolph <siro@das-labor.org>
|
||||
S: Maintained
|
||||
F: src/mainboard/lenovo/
|
||||
|
||||
LENOVO G505S MAINBOARD
|
||||
M: Mike Banon <mikebdp2@gmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/lenovo/g505s/
|
||||
################################################################################
|
||||
# Mainboards
|
||||
################################################################################
|
||||
|
||||
APPLE MAINBOARDS
|
||||
M: Evgeny Zinoviev <me@ch1p.io>
|
||||
S: Maintained
|
||||
F: src/mainboard/apple/
|
||||
|
||||
|
||||
|
||||
ASROCK B85M PRO4 MAINBOARD
|
||||
M: Angel Pons <th3fanbus@gmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/asrock/b85m_pro4/
|
||||
|
||||
ASROCK G41C-GS MAINBOARD & VARIANTS
|
||||
M: Angel Pons <th3fanbus@gmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/asrock/g41c-gs/
|
||||
|
||||
ASROCK H81M-HDS MAINBOARD
|
||||
M: Tristan Corrick <tristan@corrick.kiwi>
|
||||
S: Maintained
|
||||
F: src/mainboard/asrock/h81m-hds/
|
||||
|
||||
|
||||
|
||||
ASUS AM1I-A MAINBOARD
|
||||
M: Mike Banon <mikebdp2@gmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/asus/am1i-a/
|
||||
|
||||
ASUS MAXIMUS IV GENE-Z MAINBOARD
|
||||
M: Tristan Corrick <tristan@corrick.kiwi>
|
||||
S: Maintained
|
||||
F: src/mainboard/asus/maximus_iv_gene-z/
|
||||
|
||||
ASUS P5QC PRO MAINBOARD & VARIANTS
|
||||
M: Angel Pons <th3fanbus@gmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/asus/p5qc/
|
||||
|
||||
ASUS P5QPL-AM MAINBOARD & VARIANTS
|
||||
M: Angel Pons <th3fanbus@gmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/asus/p5qpl-am/
|
||||
|
||||
ASUS P8H61-M LX MAINBOARD
|
||||
M: Tristan Corrick <tristan@corrick.kiwi>
|
||||
S: Maintained
|
||||
F: src/mainboard/asus/p8h61-m_lx/
|
||||
|
||||
ASUS P8H61-M LX3 R2.0 MAINBOARD
|
||||
M: Angel Pons <th3fanbus@gmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/asus/p8h61-m_lx3_r2_0/
|
||||
|
||||
ASUS P8H61-M PRO MAINBOARD
|
||||
M: Angel Pons <th3fanbus@gmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/asus/p8h61-m_pro/
|
||||
|
||||
ASUS P8Z77-M PRO MAINBOARD
|
||||
M: Vlado Cibic <vladocb@protonmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/asus/p8z77-m_pro/
|
||||
|
||||
ASUS P8Z77-V LX2 MAINBOARD
|
||||
M: Angel Pons <th3fanbus@gmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/asus/p8z77-v_lx2/
|
||||
|
||||
|
||||
|
||||
FACEBOOK FBG1701 MAINBOARD
|
||||
M: Frans Hendriks <fhendriks@eltan.com>
|
||||
M: Wim Vervoorn <wvervoorn@eltan.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/facebook/fbg1701/
|
||||
|
||||
FACEBOOK MONOLITH MAINBOARD
|
||||
M: Frans Hendriks <fhendriks@eltan.com>
|
||||
M: Wim Vervoorn <wvervoorn@eltan.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/facebook/monolith/
|
||||
|
||||
|
||||
|
||||
GETAC P470 MAINBOARD
|
||||
M: Patrick Georgi <patrick@georgi.software>
|
||||
S: Maintained
|
||||
F: src/mainboard/getac/p470
|
||||
|
||||
INTEL PINEVIEW CHIPSET
|
||||
M: Damien Zammit <damien@zamaudio.com>
|
||||
S: Odd Fixes
|
||||
F: src/northbridge/intel/pineview/
|
||||
|
||||
INTEL D510MO MAINBOARD
|
||||
M: Damien Zammit <damien@zamaudio.com>
|
||||
S: Odd Fixes
|
||||
F: src/mainboard/intel/d510mo
|
||||
|
||||
INTEL X4X CHIPSET
|
||||
M: Damien Zammit <damien@zamaudio.com>
|
||||
S: Odd Fixes
|
||||
F: src/northbridge/intel/x4x/
|
||||
|
||||
GIGABYTE GA-G41M-ES2L MAINBOARD
|
||||
M: Damien Zammit <damien@zamaudio.com>
|
||||
@@ -203,6 +239,8 @@ M: Angel Pons <th3fanbus@gmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/gigabyte/ga-h61m-series
|
||||
|
||||
|
||||
|
||||
GOOGLE PANTHER MAINBOARD
|
||||
M: Stefan Reinauer <stefan.reinauer@coreboot.org>
|
||||
S: Supported
|
||||
@@ -222,23 +260,232 @@ F: src/mainboard/google/parrot/
|
||||
F: src/mainboard/google/slippy/
|
||||
F: src/mainboard/google/stout/
|
||||
|
||||
|
||||
|
||||
INTEL D510MO MAINBOARD
|
||||
M: Damien Zammit <damien@zamaudio.com>
|
||||
S: Odd Fixes
|
||||
F: src/mainboard/intel/d510mo
|
||||
|
||||
INTEL STRAGO MAINBOARD
|
||||
M: Hannah Williams <hannah.williams@intel.com>
|
||||
S: Supported
|
||||
F: /src/mainboard/intel/strago/
|
||||
|
||||
|
||||
|
||||
LENOVO MAINBOARDS
|
||||
M: Alexander Couzens <lynxis@fe80.eu>
|
||||
M: Patrick Rudolph <siro@das-labor.org>
|
||||
S: Maintained
|
||||
F: src/mainboard/lenovo/
|
||||
|
||||
LENOVO G505S MAINBOARD
|
||||
M: Mike Banon <mikebdp2@gmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/lenovo/g505s/
|
||||
|
||||
|
||||
|
||||
LIBRETREND LT1000 MAINBOARD
|
||||
M: Piotr Król <piotr.krol@3mdeb.com>
|
||||
M: Michał Żygowski <michal.zygowski@3mdeb.com>
|
||||
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>
|
||||
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: Maintained
|
||||
F: src/mainboard/ocp/tiogapass
|
||||
|
||||
|
||||
|
||||
OPENCELLULAR MAINBOARDS
|
||||
M: Christian Walter <christian.walter@9elements.com>
|
||||
M: Patrick Rudolph <patrick.rudolph@9elements.com>
|
||||
S: Supported
|
||||
F: src/mainboard/opencellular/elgon/
|
||||
|
||||
|
||||
|
||||
PC ENGINES ALL MAINBOARDS
|
||||
M: Piotr Król <piotr.krol@3mdeb.com>
|
||||
M: Michał Żygowski <michal.zygowski@3mdeb.com>
|
||||
S: Supported
|
||||
F: src/mainboard/pcengines/
|
||||
|
||||
|
||||
|
||||
PORTWELL PQ-M107 MAINBOARD
|
||||
M: Frans Hendriks <fhendriks@eltan.com>
|
||||
M: Wim Vervoorn <wvervoorn@eltan.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/portwell/m107/
|
||||
|
||||
|
||||
|
||||
PROTECTLI ALL MAINBOARDS
|
||||
M: Piotr Król <piotr.krol@3mdeb.com>
|
||||
M: Michał Żygowski <michal.zygowski@3mdeb.com>
|
||||
S: Maintained
|
||||
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
|
||||
F: src/mainboard/purism
|
||||
|
||||
|
||||
|
||||
SAMSUNG CHROMEOS MAINBOARDS
|
||||
M: Matt DeVillier <MrChromebox@gmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/samsung/lumpy/
|
||||
F: src/mainboard/samsung/stumpy/
|
||||
|
||||
|
||||
|
||||
SIEMENS MC_xxxx MAINBOARDS
|
||||
M: Werner Zeh <werner.zeh@siemens.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/siemens/mc_apl1/
|
||||
|
||||
|
||||
|
||||
SUPERMICRO X10SLM+-F MAINBOARD
|
||||
M: Tristan Corrick <tristan@corrick.kiwi>
|
||||
S: Maintained
|
||||
F: src/mainboard/supermicro/x10slm-f/
|
||||
|
||||
SUPERMICRO X11-LGA1151-SERIES
|
||||
M: Michael Niewöhner <foss@mniewoehner.de>
|
||||
S: Maintained
|
||||
F: src/mainboard/supermicro/x11-lga1151-series
|
||||
|
||||
################################################################################
|
||||
# Architectures
|
||||
################################################################################
|
||||
|
||||
ARM ARCHITECTURE
|
||||
M: Julius Werner <jwerner@chromium.org>
|
||||
S: Supported
|
||||
F: src/arch/arm/
|
||||
F: src/arch/arm64/
|
||||
F: src/soc/mediatek/
|
||||
F: src/soc/nvidia/
|
||||
F: src/soc/rockchip/
|
||||
F: util/nvidia/
|
||||
F: util/rockchip/
|
||||
|
||||
PPC64 ARCHITECTURE
|
||||
M: Ronald Minnich <rminnich@gmail.com>
|
||||
M: Timothy Pearson <tpearson@raptorengineeringinc.com>
|
||||
S: Maintained
|
||||
F: src/arch/ppc64/
|
||||
F: src/cpu/qemu-power8/
|
||||
F: src/mainboard/emulation/qemu-power8/
|
||||
|
||||
RISC-V ARCHITECTURE
|
||||
M: Ronald Minnich <rminnich@gmail.com>
|
||||
R: Philipp Hug <philipp@hug.cx>
|
||||
S: Maintained
|
||||
F: src/arch/riscv/
|
||||
F: src/soc/sifive/
|
||||
F: src/soc/ucb/
|
||||
F: src/mainboard/emulation/*-riscv/
|
||||
F: src/mainboard/sifive/
|
||||
F: util/riscv/
|
||||
|
||||
X86 ARCHITECTURE
|
||||
F: src/arch/x86/
|
||||
F: src/cpu/x86/
|
||||
F: src/drivers/pc80/
|
||||
F: src/include/pc80/
|
||||
F: src/include/cpu/x86/
|
||||
|
||||
################################################################################
|
||||
# Embedded Controllers
|
||||
################################################################################
|
||||
|
||||
LENOVO EC
|
||||
M: Alexander Couzens <lynxis@fe80.eu>
|
||||
S: Maintained
|
||||
F: src/ec/lenovo/
|
||||
|
||||
################################################################################
|
||||
# Northbridges
|
||||
################################################################################
|
||||
|
||||
INTEL HASWELL NORTHBRIDGE
|
||||
M: Angel Pons <th3fanbus@gmail.com>
|
||||
S: Maintained
|
||||
F: src/northbridge/intel/haswell/
|
||||
|
||||
INTEL PINEVIEW CHIPSET
|
||||
M: Damien Zammit <damien@zamaudio.com>
|
||||
M: Angel Pons <th3fanbus@gmail.com>
|
||||
S: Odd Fixes
|
||||
F: src/northbridge/intel/pineview/
|
||||
|
||||
INTEL SANDYBRIDGE NORTHBRIDGE
|
||||
M: Angel Pons <th3fanbus@gmail.com>
|
||||
S: Maintained
|
||||
F: src/northbridge/intel/sandybridge/
|
||||
|
||||
INTEL X4X CHIPSET
|
||||
M: Damien Zammit <damien@zamaudio.com>
|
||||
M: Angel Pons <th3fanbus@gmail.com>
|
||||
S: Odd Fixes
|
||||
F: src/northbridge/intel/x4x/
|
||||
|
||||
################################################################################
|
||||
# Platforms
|
||||
################################################################################
|
||||
|
||||
AMD SUPPORT
|
||||
F: src/vendorcode/amd/
|
||||
F: src/cpu/amd/
|
||||
F: src/northbridge/amd/
|
||||
F: src/southbridge/amd/
|
||||
F: src/include/cpu/amd/
|
||||
|
||||
INTEL SUPPORT
|
||||
M: Patrick Rudolph <siro@das-labor.org>
|
||||
S: Maintained
|
||||
F: src/vendorcode/intel/
|
||||
F: src/cpu/intel/
|
||||
F: src/northbridge/intel/
|
||||
F: src/southbridge/intel/
|
||||
F: src/soc/intel/
|
||||
F: src/drivers/intel/
|
||||
F: src/include/cpu/intel/
|
||||
|
||||
INTEL FSP DENVERTON-NS SOC & HARCUVAR CRB
|
||||
M: Vanessa Eusebio <vanessa.f.eusebio@intel.com>
|
||||
M: David Guckian <david.guckian@intel.com>
|
||||
@@ -259,10 +506,14 @@ M: Andrey Petrov <andrey.petrov@gmail.com>
|
||||
S: Maintained
|
||||
F: src/drivers/intel/fsp2_0/
|
||||
|
||||
INTEL STRAGO MAINBOARD
|
||||
M: Hannah Williams <hannah.williams@intel.com>
|
||||
S: Supported
|
||||
F: /src/mainboard/intel/strago/
|
||||
################################################################################
|
||||
# Systems on a Chip
|
||||
################################################################################
|
||||
|
||||
INTEL APOLLOLAKE_SOC
|
||||
M: Andrey Petrov <andrey.petrov@gmail.com>
|
||||
S: Maintained
|
||||
F: src/soc/intel/apollolake/
|
||||
|
||||
INTEL BRASWELL SOC
|
||||
M: Piotr Król <piotr.krol@3mdeb.com>
|
||||
@@ -272,146 +523,17 @@ S: Maintained
|
||||
F: /src/soc/intel/braswell
|
||||
F: /src/vendorcode/intel/fsp/fsp1_1/braswell
|
||||
|
||||
INTEL APOLLOLAKE_SOC
|
||||
M: Andrey Petrov <andrey.petrov@gmail.com>
|
||||
S: Maintained
|
||||
F: src/soc/intel/apollolake/
|
||||
|
||||
ASROCK G41C-GS MAINBOARD & VARIANTS
|
||||
M: Angel Pons <th3fanbus@gmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/asrock/g41c-gs/
|
||||
|
||||
ASROCK H81M-HDS MAINBOARD
|
||||
M: Tristan Corrick <tristan@corrick.kiwi>
|
||||
S: Maintained
|
||||
F: src/mainboard/asrock/h81m-hds/
|
||||
|
||||
ASUS AM1I-A MAINBOARD
|
||||
M: Mike Banon <mikebdp2@gmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/asus/am1i-a/
|
||||
|
||||
ASUS MAXIMUS IV GENE-Z MAINBOARD
|
||||
M: Tristan Corrick <tristan@corrick.kiwi>
|
||||
S: Maintained
|
||||
F: src/mainboard/asus/maximus_iv_gene-z/
|
||||
|
||||
ASUS P5QC PRO MAINBOARD & VARIANTS
|
||||
M: Angel Pons <th3fanbus@gmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/asus/p5qc/
|
||||
|
||||
ASUS P8H61-M LX MAINBOARD
|
||||
M: Tristan Corrick <tristan@corrick.kiwi>
|
||||
S: Maintained
|
||||
F: src/mainboard/asus/p8h61-m_lx/
|
||||
|
||||
ASUS P8H61-M PRO MAINBOARD
|
||||
M: Angel Pons <th3fanbus@gmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/asus/p8h61-m_pro/
|
||||
|
||||
ASUS P8Z77-M PRO MAINBOARD
|
||||
M: Vlado Cibic <vladocb@protonmail.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/asus/p8z77-m_pro/
|
||||
|
||||
LIBRETREND LT1000 MAINBOARD
|
||||
M: Piotr Król <piotr.krol@3mdeb.com>
|
||||
M: Michał Żygowski <michal.zygowski@3mdeb.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/libretrend/lt1000
|
||||
|
||||
PC ENGINES ALL MAINBOARDS
|
||||
M: Piotr Król <piotr.krol@3mdeb.com>
|
||||
M: Michał Żygowski <michal.zygowski@3mdeb.com>
|
||||
S: Supported
|
||||
F: src/mainboard/pcengines/
|
||||
|
||||
PROTECTLI ALL MAINBOARDS
|
||||
M: Piotr Król <piotr.krol@3mdeb.com>
|
||||
M: Michał Żygowski <michal.zygowski@3mdeb.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/protectli/
|
||||
|
||||
SIEMENS MC_xxxx MAINBOARDS
|
||||
M: Werner Zeh <werner.zeh@siemens.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/siemens/mc_apl1/
|
||||
|
||||
SUPERMICRO X10SLM+-F MAINBOARD
|
||||
M: Tristan Corrick <tristan@corrick.kiwi>
|
||||
S: Maintained
|
||||
F: src/mainboard/supermicro/x10slm-f/
|
||||
|
||||
SUPERMICRO X11-LGA1151-SERIES
|
||||
M: Michael Niewöhner <foss@mniewoehner.de>
|
||||
S: Maintained
|
||||
F: src/mainboard/supermicro/x11-lga1151-series
|
||||
|
||||
FACEBOOK FBG1701 MAINBOARD
|
||||
M: Frans Hendriks <fhendriks@eltan.com>
|
||||
M: Wim Vervoorn <wvervoorn@eltan.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/facebook/fbg1701/
|
||||
|
||||
FACEBOOK MONOLITH MAINBOARD
|
||||
M: Frans Hendriks <fhendriks@eltan.com>
|
||||
M: Wim Vervoorn <wvervoorn@eltan.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/facebook/monolith/
|
||||
|
||||
OCP TIOGAPASS MAINBOARD
|
||||
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: Maintained
|
||||
F: src/mainboard/ocp/tiogapass
|
||||
|
||||
PORTWELL PQ-M107 MAINBOARD
|
||||
M: Frans Hendriks <fhendriks@eltan.com>
|
||||
M: Wim Vervoorn <wvervoorn@eltan.com>
|
||||
S: Maintained
|
||||
F: src/mainboard/portwell/m107/
|
||||
|
||||
ASPEED AST2050 DRIVER & COMMON CODE
|
||||
M: Timothy Pearson <tpearson@raptorengineeringinc.com>
|
||||
S: Supported
|
||||
F: src/drivers/aspeed/common/
|
||||
F: src/drivers/aspeed/ast2050/
|
||||
|
||||
ABUILD
|
||||
M: Patrick Georgi <patrick@georgi-clan.de>
|
||||
M: Martin Roth <gaumless@gmail.com>
|
||||
S: Supported
|
||||
F: util/abuild/
|
||||
|
||||
ACPI
|
||||
F: src/acpi/
|
||||
F: src/arch/x86/acpi/
|
||||
F: util/acpi/
|
||||
|
||||
LZ4 COMPRESSION
|
||||
M: Julius Werner <jwerner@chromium.org>
|
||||
S: Supported
|
||||
F: src/commonlib/lz4*
|
||||
F: payloads/libpayload/liblz4/
|
||||
F: util/cbfstool/lz4/
|
||||
|
||||
ARM ARCHITECTURE
|
||||
M: Julius Werner <jwerner@chromium.org>
|
||||
S: Supported
|
||||
F: src/arch/arm/
|
||||
F: src/arch/arm64/
|
||||
F: src/soc/mediatek/
|
||||
F: src/soc/nvidia/
|
||||
F: src/soc/rockchip/
|
||||
F: util/nvidia/
|
||||
F: util/rockchip/
|
||||
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
|
||||
@@ -422,30 +544,67 @@ F: src/soc/samsung/
|
||||
F: util/exynos/
|
||||
F: util/ipqheader/
|
||||
|
||||
X86 ARCHITECTURE
|
||||
F: src/arch/x86/
|
||||
F: src/cpu/x86/
|
||||
F: src/drivers/pc80/
|
||||
F: src/include/pc80/
|
||||
F: src/include/cpu/x86/
|
||||
################################################################################
|
||||
# Payloads
|
||||
################################################################################
|
||||
|
||||
INTEL SUPPORT
|
||||
M: Patrick Rudolph <siro@das-labor.org>
|
||||
S: Maintained
|
||||
F: src/vendorcode/intel/
|
||||
F: src/cpu/intel/
|
||||
F: src/northbridge/intel/
|
||||
F: src/southbridge/intel/
|
||||
F: src/soc/intel/
|
||||
F: src/drivers/intel/
|
||||
F: src/include/cpu/intel/
|
||||
NVRAM
|
||||
F: util/nvramtool/
|
||||
F: payloads/nvramcui/
|
||||
|
||||
AMD SUPPORT
|
||||
F: src/vendorcode/amd/
|
||||
F: src/cpu/amd/
|
||||
F: src/northbridge/amd/
|
||||
F: src/southbridge/amd/
|
||||
F: src/include/cpu/amd/
|
||||
LIBPAYLOAD
|
||||
F: payloads/libpayload/
|
||||
|
||||
COREINFO PAYLOAD
|
||||
F: payloads/coreinfo/
|
||||
|
||||
EXTERNAL PAYLOADS INTEGRATION
|
||||
M: Stefan Reinauer <stefan.reinauer@coreboot.org>
|
||||
M: Martin Roth <gaumless@gmail.com>
|
||||
F: payloads/external
|
||||
|
||||
LINUXBOOT PAYLOAD INTEGRATION
|
||||
M: Christian Walter <christian.walter@9elements.com>
|
||||
M: Marcello Sylvester Bauer <info@marcellobauer.com>
|
||||
S: Supported
|
||||
F: payloads/external/LinuxBoot
|
||||
|
||||
################################################################################
|
||||
# Utilities
|
||||
################################################################################
|
||||
|
||||
ABUILD
|
||||
M: Patrick Georgi <patrick@georgi-clan.de>
|
||||
M: Martin Roth <gaumless@gmail.com>
|
||||
S: Supported
|
||||
F: util/abuild/
|
||||
|
||||
BOARD STATUS
|
||||
F: util/board_status/
|
||||
|
||||
BUILD SYSTEM
|
||||
M: Patrick Georgi <patrick@georgi-clan.de>
|
||||
M: Martin Roth <gaumless@gmail.com>
|
||||
S: Supported
|
||||
F: Makefile
|
||||
F: *.inc
|
||||
F: src/include/kconfig.h
|
||||
F: util/kconfig/
|
||||
F: util/sconfig/
|
||||
F: util/xcompile/
|
||||
F: util/genbuild_h/
|
||||
|
||||
TOOLCHAIN
|
||||
F: util/crossgcc/
|
||||
|
||||
DOCKER
|
||||
M: Martin Roth <gaumless@gmail.com>
|
||||
S: Supported
|
||||
F: util/docker/
|
||||
|
||||
GIT
|
||||
F: .git*
|
||||
F: /util/gitconfig
|
||||
|
||||
LINT SCRIPTS
|
||||
M: Patrick Georgi <patrick@georgi-clan.de>
|
||||
@@ -453,6 +612,10 @@ M: Martin Roth <gaumless@gmail.com>
|
||||
S: Supported
|
||||
F: util/lint/
|
||||
|
||||
IFDTOOL
|
||||
M: Stefan Reinauer <stefan.reinauer@coreboot.org>
|
||||
F: util/ifdtool/
|
||||
|
||||
INTELTOOL
|
||||
M: Stefan Reinauer <stefan.reinauer@coreboot.org>
|
||||
F: util/inteltool/
|
||||
@@ -467,24 +630,27 @@ W: https://github.com/corna/me_cleaner
|
||||
S: Maintained
|
||||
F: util/me_cleaner/
|
||||
|
||||
IFDTOOL
|
||||
M: Stefan Reinauer <stefan.reinauer@coreboot.org>
|
||||
F: util/ifdtool/
|
||||
################################################################################
|
||||
# Miscellaneous
|
||||
################################################################################
|
||||
|
||||
BUILD SYSTEM
|
||||
M: Patrick Georgi <patrick@georgi-clan.de>
|
||||
M: Martin Roth <gaumless@gmail.com>
|
||||
ASPEED AST2050 DRIVER & COMMON CODE
|
||||
M: Timothy Pearson <tpearson@raptorengineeringinc.com>
|
||||
S: Supported
|
||||
F: Makefile
|
||||
F: *.inc
|
||||
F: src/include/kconfig.h
|
||||
F: util/kconfig/
|
||||
F: util/sconfig/
|
||||
F: util/xcompile/
|
||||
F: util/genbuild_h/
|
||||
F: src/drivers/aspeed/common/
|
||||
F: src/drivers/aspeed/ast2050/
|
||||
|
||||
BOARD STATUS
|
||||
F: util/board_status/
|
||||
ACPI
|
||||
F: src/acpi/
|
||||
F: src/arch/x86/acpi/
|
||||
F: util/acpi/
|
||||
|
||||
LZ4 COMPRESSION
|
||||
M: Julius Werner <jwerner@chromium.org>
|
||||
S: Supported
|
||||
F: src/commonlib/lz4*
|
||||
F: payloads/libpayload/liblz4/
|
||||
F: util/cbfstool/lz4/
|
||||
|
||||
BINARY OBJECTS
|
||||
F: 3rdparty/blobs/
|
||||
@@ -518,27 +684,6 @@ F: src/console/
|
||||
F: src/include/console/
|
||||
F: src/drivers/uart/
|
||||
|
||||
NVRAM
|
||||
F: util/nvramtool/
|
||||
F: payloads/nvramcui/
|
||||
|
||||
LIBPAYLOAD
|
||||
F: payloads/libpayload/
|
||||
|
||||
COREINFO PAYLOAD
|
||||
F: payloads/coreinfo/
|
||||
|
||||
EXTERNAL PAYLOADS INTEGRATION
|
||||
M: Stefan Reinauer <stefan.reinauer@coreboot.org>
|
||||
M: Martin Roth <gaumless@gmail.com>
|
||||
F: payloads/external
|
||||
|
||||
LINUXBOOT PAYLOAD INTEGRATION
|
||||
M: Christian Walter <christian.walter@9elements.com>
|
||||
M: Marcello Sylvester Bauer <info@marcellobauer.com>
|
||||
S: Supported
|
||||
F: payloads/external/LinuxBoot
|
||||
|
||||
VERIFIED BOOT 2
|
||||
M: Aaron Durbin <adurbin@chromium.org>
|
||||
F: src/security/vboot/
|
||||
@@ -549,18 +694,6 @@ S: Supported
|
||||
F: src/drivers/*/tpm/
|
||||
F: src/security/tpm
|
||||
|
||||
DOCKER
|
||||
M: Martin Roth <gaumless@gmail.com>
|
||||
S: Supported
|
||||
F: util/docker/
|
||||
|
||||
TOOLCHAIN
|
||||
F: util/crossgcc/
|
||||
|
||||
GIT
|
||||
F: .git*
|
||||
F: /util/gitconfig
|
||||
|
||||
SUPERIOS & SUPERIOTOOL
|
||||
M: Felix Held <felix-coreboot@felixheld.de>
|
||||
S: Maintained
|
||||
|
19
Makefile
19
Makefile
@@ -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
|
||||
|
||||
@@ -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'
|
||||
@@ -103,7 +103,7 @@ ifeq ($(strip $(HAVE_DOTCONFIG)),)
|
||||
NOCOMPILE:=1
|
||||
endif
|
||||
ifneq ($(MAKECMDGOALS),)
|
||||
ifneq ($(filter %config %clean cross% clang iasl gnumake lint% help% what-jenkins-does,$(MAKECMDGOALS)),)
|
||||
ifneq ($(filter %config %clean cross% clang iasl lint% help% what-jenkins-does,$(MAKECMDGOALS)),)
|
||||
NOCOMPILE:=1
|
||||
endif
|
||||
ifneq ($(filter %clean lint% help% what-jenkins-does,$(MAKECMDGOALS)),)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
29
Makefile.inc
29
Makefile.inc
@@ -13,6 +13,7 @@ CONFIG_CBFS_PREFIX:=$(call strip_quotes,$(CONFIG_CBFS_PREFIX))
|
||||
CONFIG_FMDFILE:=$(call strip_quotes,$(CONFIG_FMDFILE))
|
||||
CONFIG_DEVICETREE:=$(call strip_quotes, $(CONFIG_DEVICETREE))
|
||||
CONFIG_OVERRIDE_DEVICETREE:=$(call strip_quotes, $(CONFIG_OVERRIDE_DEVICETREE))
|
||||
CONFIG_MEMLAYOUT_LD_FILE:=$(call strip_quotes, $(CONFIG_MEMLAYOUT_LD_FILE))
|
||||
|
||||
#######################################################################
|
||||
# misleadingly named, this is the coreboot version
|
||||
@@ -98,6 +99,13 @@ classes-y := ramstage romstage bootblock decompressor postcar smm smmstub cpu_mi
|
||||
$(call add-special-class,all)
|
||||
all-handler = $(foreach class,bootblock verstage romstage postcar ramstage,$(eval $(class)-y += $(2)))
|
||||
|
||||
$(call add-special-class,verstage_x86)
|
||||
ifeq ($(CONFIG_ARCH_VERSTAGE_X86_32)$(CONFIG_ARCH_VERSTAGE_X86_64),y)
|
||||
verstage_x86-handler = $(eval verstage-y += $(2))
|
||||
else
|
||||
verstage_x86-handler =
|
||||
endif
|
||||
|
||||
# Add dynamic classes for rmodules
|
||||
$(foreach supported_arch,$(ARCH_SUPPORTED), \
|
||||
$(eval $(call define_class,rmodules_$(supported_arch),$(supported_arch))))
|
||||
@@ -188,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
|
||||
@@ -609,6 +620,13 @@ smm-c-deps+=$(DEVICETREE_STATIC_C)
|
||||
.PHONY: devicetree
|
||||
devicetree: $(DEVICETREE_STATIC_C)
|
||||
|
||||
ramstage-y += $(CONFIG_MEMLAYOUT_LD_FILE)
|
||||
romstage-y += $(CONFIG_MEMLAYOUT_LD_FILE)
|
||||
bootblock-y += $(CONFIG_MEMLAYOUT_LD_FILE)
|
||||
verstage-y += $(CONFIG_MEMLAYOUT_LD_FILE)
|
||||
postcar-y += $(CONFIG_MEMLAYOUT_LD_FILE)
|
||||
decompressor-y += $(CONFIG_MEMLAYOUT_LD_FILE)
|
||||
|
||||
#######################################################################
|
||||
# Clean up rules
|
||||
clean-abuild:
|
||||
@@ -1169,11 +1187,10 @@ $(CONFIG_CBFS_PREFIX)/romstage-options := -S ".car.data"
|
||||
ifneq ($(CONFIG_NO_XIP_EARLY_STAGES),y)
|
||||
$(CONFIG_CBFS_PREFIX)/romstage-options += --xip
|
||||
|
||||
# If XIP_ROM_SIZE isn't being used don't overly constrain romstage by passing
|
||||
# -P with a default value.
|
||||
ifneq ($(CONFIG_NO_FIXED_XIP_ROM_SIZE),y)
|
||||
$(CONFIG_CBFS_PREFIX)/romstage-options += -P $(CONFIG_XIP_ROM_SIZE)
|
||||
endif # CONFIG_NO_FIXED_XIP_ROM_SIZE
|
||||
# For efficient MTRR utilisation use natural alignment for romstage.
|
||||
ifeq ($(CONFIG_SETUP_XIP_CACHE),y)
|
||||
$(CONFIG_CBFS_PREFIX)/romstage-options += --pow2page
|
||||
endif # CONFIG_SETUP_XIP_CACHE
|
||||
|
||||
endif # CONFIG_NO_XIP_EARLY_STAGES
|
||||
endif # CONFIG_ARCH_ROMSTAGE_X86_32 / CONFIG_ARCH_ROMSTAGE_X86_64
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
17
configs/builder/config.ocp.deltalake
Normal file
17
configs/builder/config.ocp.deltalake
Normal file
@@ -0,0 +1,17 @@
|
||||
# type this to get working .config:
|
||||
# make defconfig KBUILD_DEFCONFIG=configs/builder/config.ocp.deltalake
|
||||
|
||||
CONFIG_VENDOR_OCP=y
|
||||
CONFIG_BOARD_OCP_DELTALAKE=y
|
||||
CONFIG_HAVE_IFD_BIN=y
|
||||
CONFIG_HAVE_ME_BIN=y
|
||||
CONFIG_DO_NOT_TOUCH_DESCRIPTOR_REGION=y
|
||||
CONFIG_USE_CPU_MICROCODE_CBFS_BINS=y
|
||||
CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_BINS=y
|
||||
CONFIG_CPU_UCODE_BINARIES="site-local/deltalake/mbf5065a.mcb"
|
||||
CONFIG_ADD_FSP_BINARIES=y
|
||||
CONFIG_FSP_T_FILE="site-local/deltalake/Server_T.fd"
|
||||
CONFIG_FSP_M_FILE="site-local/deltalake/Server_M.fd"
|
||||
CONFIG_FSP_S_FILE="site-local/deltalake/Server_S.fd"
|
||||
CONFIG_ME_BIN_PATH="site-local/deltalake/flashregion_2_intel_me.bin"
|
||||
CONFIG_IFD_BIN_PATH="site-local/deltalake/flashregion_0_flashdescriptor.bin"
|
4
payloads/external/Makefile.inc
vendored
4
payloads/external/Makefile.inc
vendored
@@ -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)
|
||||
@@ -253,7 +253,7 @@ payloads/external/iPXE/ipxe/ipxe.rom ipxe: $(DOTCONFIG) $(PXE_CONFIG_SCRIPT)
|
||||
CONFIG_TTYS0_BAUD=$(CONFIG_TTYS0_BAUD) \
|
||||
CONFIG_SCRIPT=$(PXE_CONFIG_SCRIPT) \
|
||||
CONFIG_HAS_SCRIPT=$(CONFIG_PXE_ADD_SCRIPT) \
|
||||
CONFIG_PXE_NO_PROMT=$(CONFIG_PXE_NO_PROMT) \
|
||||
CONFIG_PXE_NO_PROMPT=$(CONFIG_PXE_NO_PROMPT) \
|
||||
CONFIG_PXE_HAS_HTTPS=$(CONFIG_PXE_HAS_HTTPS) \
|
||||
MFLAGS= MAKEFLAGS=
|
||||
|
||||
|
3
payloads/external/depthcharge/Makefile
vendored
3
payloads/external/depthcharge/Makefile
vendored
@@ -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); \
|
||||
|
2
payloads/external/iPXE/Kconfig
vendored
2
payloads/external/iPXE/Kconfig
vendored
@@ -78,7 +78,7 @@ config PXE_SERIAL_CONSOLE
|
||||
|
||||
Unselect to let only SeaBIOS handle printing output.
|
||||
|
||||
config PXE_NO_PROMT
|
||||
config PXE_NO_PROMPT
|
||||
bool "Do not show prompt to boot from PXE"
|
||||
default n
|
||||
depends on BUILD_IPXE
|
||||
|
6
payloads/external/iPXE/Makefile
vendored
6
payloads/external/iPXE/Makefile
vendored
@@ -45,14 +45,14 @@ ifeq ($(CONSOLE_SERIAL),yy)
|
||||
sed 's|#define\s*COMCONSOLE.*|#define COMCONSOLE $(IPXE_UART)|' "$(project_dir)/src/config/serial.h" > "$(project_dir)/src/config/serial.h.tmp"
|
||||
sed 's|#define\s*COMSPEED.*|#define COMSPEED $(CONFIG_TTYS0_BAUD)|' "$(project_dir)/src/config/serial.h.tmp" > "$(project_dir)/src/config/serial.h"
|
||||
endif
|
||||
ifneq ($(filter y,$(CONFIG_HAS_SCRIPT) $(CONFIG_PXE_NO_PROMT)),)
|
||||
ifneq ($(filter y,$(CONFIG_HAS_SCRIPT) $(CONFIG_PXE_NO_PROMPT)),)
|
||||
cp "$(project_dir)/src/config/general.h" "$(project_dir)/src/config/general.h.cb"
|
||||
endif
|
||||
ifeq ($(CONFIG_HAS_SCRIPT),y)
|
||||
sed 's|//#define\s*IMAGE_SCRIPT.*|#define IMAGE_SCRIPT|' "$(project_dir)/src/config/general.h" > "$(project_dir)/src/config/general.h.tmp"
|
||||
mv "$(project_dir)/src/config/general.h.tmp" "$(project_dir)/src/config/general.h"
|
||||
endif
|
||||
ifeq ($(CONFIG_PXE_NO_PROMT),y)
|
||||
ifeq ($(CONFIG_PXE_NO_PROMPT),y)
|
||||
sed 's|#define\s*BANNER_TIMEOUT.*|#define BANNER_TIMEOUT 0|' "$(project_dir)/src/config/general.h" > "$(project_dir)/src/config/general.h.tmp"
|
||||
mv "$(project_dir)/src/config/general.h.tmp" "$(project_dir)/src/config/general.h"
|
||||
endif
|
||||
@@ -74,7 +74,7 @@ ifeq ($(CONSOLE_SERIAL),yy)
|
||||
cp "$(project_dir)/src/config/console.h.cb" "$(project_dir)/src/config/console.h"
|
||||
cp "$(project_dir)/src/config/serial.h.cb" "$(project_dir)/src/config/serial.h"
|
||||
endif
|
||||
ifneq ($(filter y,$(CONFIG_HAS_SCRIPT) $(CONFIG_PXE_NO_PROMT)),)
|
||||
ifneq ($(filter y,$(CONFIG_HAS_SCRIPT) $(CONFIG_PXE_NO_PROMPT)),)
|
||||
cp "$(project_dir)/src/config/general.h.cb" "$(project_dir)/src/config/general.h"
|
||||
endif
|
||||
|
||||
|
2
payloads/external/tianocore/Makefile
vendored
2
payloads/external/tianocore/Makefile
vendored
@@ -69,7 +69,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..."
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
{
|
||||
@@ -111,12 +110,6 @@ 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();
|
||||
}
|
||||
|
||||
|
@@ -28,7 +28,7 @@
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf64-littleaarch64","elf64-littleaarch64", "elf64-littleaarch64")
|
||||
OUTPUT_ARCH(arm64)
|
||||
OUTPUT_ARCH(aarch64)
|
||||
|
||||
ENTRY(_entry)
|
||||
|
||||
|
@@ -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
|
||||
@@ -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.
|
||||
|
@@ -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.");
|
||||
@@ -124,9 +124,17 @@ 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"
|
||||
@@ -134,15 +142,22 @@ void apic_delay(unsigned int usec)
|
||||
* 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) {}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
@@ -280,6 +306,7 @@ 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,
|
||||
@@ -287,6 +314,7 @@ void apic_init(void)
|
||||
|
||||
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();
|
||||
|
@@ -86,6 +86,10 @@ usb_poll (void)
|
||||
{
|
||||
if (usb_hcs == 0)
|
||||
return;
|
||||
|
||||
if (usb_poll_prepare)
|
||||
usb_poll_prepare();
|
||||
|
||||
hci_t *controller = usb_hcs;
|
||||
while (controller != NULL) {
|
||||
int i;
|
||||
|
@@ -129,7 +129,12 @@ xhci_switchback_ppt_ports(pcidev_t addr)
|
||||
static long
|
||||
xhci_handshake(volatile u32 *const reg, u32 mask, u32 wait_for, long timeout_us)
|
||||
{
|
||||
while ((*reg & mask) != wait_for && timeout_us--) udelay(1);
|
||||
if (timeout_us <= 0)
|
||||
return 0;
|
||||
while ((*reg & mask) != wait_for && timeout_us != 0) {
|
||||
--timeout_us;
|
||||
udelay(1);
|
||||
}
|
||||
return timeout_us;
|
||||
}
|
||||
|
||||
|
@@ -28,6 +28,7 @@
|
||||
|
||||
#include <libpayload.h>
|
||||
#include <cbfs.h>
|
||||
#include <fpmath.h>
|
||||
#include <sysinfo.h>
|
||||
#include "bitmap.h"
|
||||
|
||||
@@ -60,6 +61,37 @@ static const struct vector vzero = {
|
||||
.y = 0,
|
||||
};
|
||||
|
||||
struct blend_value {
|
||||
uint8_t alpha;
|
||||
struct rgb_color rgb;
|
||||
};
|
||||
|
||||
static struct blend_value blend = {
|
||||
.alpha = 0,
|
||||
.rgb.red = 0,
|
||||
.rgb.green = 0,
|
||||
.rgb.blue = 0,
|
||||
};
|
||||
|
||||
int set_blend(const struct rgb_color *rgb, uint8_t alpha)
|
||||
{
|
||||
if (rgb == NULL)
|
||||
return CBGFX_ERROR_INVALID_PARAMETER;
|
||||
|
||||
blend.alpha = alpha;
|
||||
blend.rgb = *rgb;
|
||||
|
||||
return CBGFX_SUCCESS;
|
||||
}
|
||||
|
||||
void clear_blend(void)
|
||||
{
|
||||
blend.alpha = 0;
|
||||
blend.rgb.red = 0;
|
||||
blend.rgb.green = 0;
|
||||
blend.rgb.blue = 0;
|
||||
}
|
||||
|
||||
static void add_vectors(struct vector *out,
|
||||
const struct vector *v1, const struct vector *v2)
|
||||
{
|
||||
@@ -85,13 +117,9 @@ static void add_fractions(struct fraction *out,
|
||||
n = (int64_t)f1->n * f2->d + (int64_t)f2->n * f1->d;
|
||||
d = (int64_t)f1->d * f2->d;
|
||||
/* Simplest way to reduce the fraction until fitting in int32_t */
|
||||
shift = log2(MAX(ABS(n), ABS(d)) >> 31);
|
||||
if (shift > 0) {
|
||||
n >>= shift;
|
||||
d >>= shift;
|
||||
}
|
||||
out->n = n;
|
||||
out->d = d;
|
||||
shift = log2(MAX(ABS(n), ABS(d)) >> 31) + 1;
|
||||
out->n = n >> shift;
|
||||
out->d = d >> shift;
|
||||
}
|
||||
|
||||
static void add_scales(struct scale *out,
|
||||
@@ -113,36 +141,57 @@ static int transform_vector(struct vector *out,
|
||||
{
|
||||
if (!is_valid_scale(a))
|
||||
return CBGFX_ERROR_INVALID_PARAMETER;
|
||||
out->x = a->x.n * in->x / a->x.d + offset->x;
|
||||
out->y = a->y.n * in->y / a->y.d + offset->y;
|
||||
out->x = (int64_t)a->x.n * in->x / a->x.d + offset->x;
|
||||
out->y = (int64_t)a->y.n * in->y / a->y.d + offset->y;
|
||||
return CBGFX_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if v is exclusively within box, 0 if v is inclusively within box,
|
||||
* or -1 otherwise. Note that only the right and bottom edges are examined.
|
||||
* or -1 otherwise.
|
||||
*/
|
||||
static int within_box(const struct vector *v, const struct rect *bound)
|
||||
{
|
||||
if (v->x < bound->offset.x + bound->size.width &&
|
||||
if (v->x > bound->offset.x &&
|
||||
v->y > bound->offset.y &&
|
||||
v->x < bound->offset.x + bound->size.width &&
|
||||
v->y < bound->offset.y + bound->size.height)
|
||||
return 1;
|
||||
else if (v->x <= bound->offset.x + bound->size.width &&
|
||||
else if (v->x >= bound->offset.x &&
|
||||
v->y >= bound->offset.y &&
|
||||
v->x <= bound->offset.x + bound->size.width &&
|
||||
v->y <= bound->offset.y + bound->size.height)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function that applies color and opacity from blend struct
|
||||
* into the color.
|
||||
*/
|
||||
static inline uint8_t apply_blend(uint8_t color, uint8_t blend_color)
|
||||
{
|
||||
if (blend.alpha == 0 || color == blend_color)
|
||||
return color;
|
||||
|
||||
return (color * (256 - blend.alpha) +
|
||||
blend_color * blend.alpha) / 256;
|
||||
}
|
||||
|
||||
static inline uint32_t calculate_color(const struct rgb_color *rgb,
|
||||
uint8_t invert)
|
||||
{
|
||||
uint32_t color = 0;
|
||||
color |= (rgb->red >> (8 - fbinfo->red_mask_size))
|
||||
|
||||
color |= (apply_blend(rgb->red, blend.rgb.red)
|
||||
>> (8 - fbinfo->red_mask_size))
|
||||
<< fbinfo->red_mask_pos;
|
||||
color |= (rgb->green >> (8 - fbinfo->green_mask_size))
|
||||
color |= (apply_blend(rgb->green, blend.rgb.green)
|
||||
>> (8 - fbinfo->green_mask_size))
|
||||
<< fbinfo->green_mask_pos;
|
||||
color |= (rgb->blue >> (8 - fbinfo->blue_mask_size))
|
||||
color |= (apply_blend(rgb->blue, blend.rgb.blue)
|
||||
>> (8 - fbinfo->blue_mask_size))
|
||||
<< fbinfo->blue_mask_pos;
|
||||
if (invert)
|
||||
color ^= 0xffffffff;
|
||||
@@ -468,33 +517,116 @@ int clear_screen(const struct rgb_color *rgb)
|
||||
return CBGFX_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bi-linear Interpolation
|
||||
*
|
||||
* It estimates the value of a middle point (tx, ty) using the values from four
|
||||
* adjacent points (q00, q01, q10, q11).
|
||||
*/
|
||||
static uint32_t bli(uint32_t q00, uint32_t q10, uint32_t q01, uint32_t q11,
|
||||
struct fraction *tx, struct fraction *ty)
|
||||
static int pal_to_rgb(uint8_t index, const struct bitmap_palette_element_v3 *pal,
|
||||
size_t palcount, struct rgb_color *out)
|
||||
{
|
||||
uint32_t r0 = (tx->n * q10 + (tx->d - tx->n) * q00) / tx->d;
|
||||
uint32_t r1 = (tx->n * q11 + (tx->d - tx->n) * q01) / tx->d;
|
||||
uint32_t p = (ty->n * r1 + (ty->d - ty->n) * r0) / ty->d;
|
||||
return p;
|
||||
if (index >= palcount) {
|
||||
LOG("Color index %d exceeds palette boundary\n", index);
|
||||
return CBGFX_ERROR_BITMAP_DATA;
|
||||
}
|
||||
|
||||
out->red = pal[index].red;
|
||||
out->green = pal[index].green;
|
||||
out->blue = pal[index].blue;
|
||||
return CBGFX_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* We're using the Lanczos resampling algorithm to rescale images to a new size.
|
||||
* Since output size is often not cleanly divisible by input size, an output
|
||||
* pixel (ox,oy) corresponds to a point that lies in the middle between several
|
||||
* input pixels (ix,iy), meaning that if you transformed the coordinates of the
|
||||
* output pixel into the input image space, they would be fractional. To sample
|
||||
* the color of this "virtual" pixel with fractional coordinates, we gather the
|
||||
* 6x6 grid of nearest real input pixels in a sample array. Then we multiply the
|
||||
* color values for each of those pixels (separately for red, green and blue)
|
||||
* with a "weight" value that was calculated from the distance between that
|
||||
* input pixel and the fractional output pixel coordinates. This is done for
|
||||
* both X and Y dimensions separately. The combined weights for all 36 sample
|
||||
* pixels add up to 1.0, so by adding up the multiplied color values we get the
|
||||
* interpolated color for the output pixel.
|
||||
*
|
||||
* The CONFIG_LP_CBGFX_FAST_RESAMPLE option let's the user change the 'a'
|
||||
* parameter from the Lanczos weight formula from 3 to 2, which effectively
|
||||
* reduces the size of the sample array from 6x6 to 4x4. This is a bit faster
|
||||
* but doesn't look as good. Most use cases should be fine without it.
|
||||
*/
|
||||
#if CONFIG(LP_CBGFX_FAST_RESAMPLE)
|
||||
#define LNCZ_A 2
|
||||
#else
|
||||
#define LNCZ_A 3
|
||||
#endif
|
||||
|
||||
/*
|
||||
* When walking the sample array we often need to start at a pixel close to our
|
||||
* fractional output pixel (for convenience we choose the pixel on the top-left
|
||||
* which corresponds to the integer parts of the output pixel coordinates) and
|
||||
* then work our way outwards in both directions from there. Arrays in C must
|
||||
* start at 0 but we'd really prefer indexes to go from -2 to 3 (for 6x6)
|
||||
* instead, so that this "start pixel" could be 0. Since we cannot do that,
|
||||
* define a constant for the index of that "0th" pixel instead.
|
||||
*/
|
||||
#define S0 (LNCZ_A - 1)
|
||||
|
||||
/* The size of the sample array, which we need a lot. */
|
||||
#define SSZ (LNCZ_A * 2)
|
||||
|
||||
/*
|
||||
* This is implementing the Lanczos kernel according to:
|
||||
* https://en.wikipedia.org/wiki/Lanczos_resampling
|
||||
*
|
||||
* / 1 if x = 0
|
||||
* L(x) = < a * sin(pi * x) * sin(pi * x / a) / (pi^2 * x^2) if -a < x <= a
|
||||
* \ 0 otherwise
|
||||
*/
|
||||
static fpmath_t lanczos_weight(fpmath_t in, int off)
|
||||
{
|
||||
/*
|
||||
* |in| is the output pixel coordinate scaled into the input pixel
|
||||
* space. |off| is the offset in the sample array for the pixel whose
|
||||
* weight we're calculating. (off - S0) is the distance from that
|
||||
* sample pixel to the S0 pixel, and the fractional part of |in|
|
||||
* (in - floor(in)) is by definition the distance between S0 and the
|
||||
* output pixel.
|
||||
*
|
||||
* So (off - S0) - (in - floor(in)) is the distance from the sample
|
||||
* pixel to S0 minus the distance from S0 to the output pixel, aka
|
||||
* the distance from the sample pixel to the output pixel.
|
||||
*/
|
||||
fpmath_t x = fpisub(off - S0, fpsubi(in, fpfloor(in)));
|
||||
|
||||
if (fpequals(x, fp(0)))
|
||||
return fp(1);
|
||||
|
||||
/* x * 2 / a can save some instructions if a == 2 */
|
||||
fpmath_t x2a = x;
|
||||
if (LNCZ_A != 2)
|
||||
x2a = fpmul(x, fpfrac(2, LNCZ_A));
|
||||
|
||||
fpmath_t x_times_pi = fpmul(x, fppi());
|
||||
|
||||
/*
|
||||
* Rather than using sinr(pi*x), we leverage the "one-based" sine
|
||||
* function (see <fpmath.h>) with sin1(2*x) so that the pi is eliminated
|
||||
* since multiplication by an integer is a slightly faster operation.
|
||||
*/
|
||||
fpmath_t tmp = fpmuli(fpdiv(fpsin1(fpmuli(x, 2)), x_times_pi), LNCZ_A);
|
||||
return fpdiv(fpmul(tmp, fpsin1(x2a)), x_times_pi);
|
||||
}
|
||||
|
||||
static int draw_bitmap_v3(const struct vector *top_left,
|
||||
const struct scale *scale,
|
||||
const struct vector *dim,
|
||||
const struct vector *dim_org,
|
||||
const struct bitmap_header_v3 *header,
|
||||
const struct bitmap_palette_element_v3 *pal,
|
||||
const uint8_t *pixel_array,
|
||||
uint8_t invert)
|
||||
const uint8_t *pixel_array, uint8_t invert)
|
||||
{
|
||||
const int bpp = header->bits_per_pixel;
|
||||
int32_t dir;
|
||||
struct vector p;
|
||||
int32_t ox, oy; /* output (resampled) pixel coordinates */
|
||||
int32_t ix, iy; /* input (source image) pixel coordinates */
|
||||
int sx, sy; /* index into |sample| (not ringbuffer adjusted) */
|
||||
|
||||
if (header->compression) {
|
||||
LOG("Compressed bitmaps are not supported\n");
|
||||
@@ -508,10 +640,6 @@ static int draw_bitmap_v3(const struct vector *top_left,
|
||||
LOG("Unsupported bits per pixel: %d\n", bpp);
|
||||
return CBGFX_ERROR_BITMAP_FORMAT;
|
||||
}
|
||||
if (scale->x.n == 0 || scale->y.n == 0) {
|
||||
LOG("Scaling out of range\n");
|
||||
return CBGFX_ERROR_SCALE_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
const int32_t y_stride = ROUNDUP(dim_org->width * bpp / 8, 4);
|
||||
/*
|
||||
@@ -530,63 +658,202 @@ static int draw_bitmap_v3(const struct vector *top_left,
|
||||
p.y += dim->height - 1;
|
||||
dir = -1;
|
||||
}
|
||||
/*
|
||||
* Plot pixels scaled by the bilinear interpolation. We scan over the
|
||||
* image on canvas (using d) and find the corresponding pixel in the
|
||||
* bitmap data (using s0, s1).
|
||||
*
|
||||
* When d hits the right bottom corner, s0 also hits the right bottom
|
||||
* corner of the pixel array because that's how scale->x and scale->y
|
||||
* have been set. Since the pixel array size is already validated in
|
||||
* parse_bitmap_header_v3, s0 is guaranteed not to exceed pixel array
|
||||
* boundary.
|
||||
*/
|
||||
struct vector s0, s1, d;
|
||||
struct fraction tx, ty;
|
||||
for (d.y = 0; d.y < dim->height; d.y++, p.y += dir) {
|
||||
s0.y = d.y * scale->y.d / scale->y.n;
|
||||
s1.y = s0.y;
|
||||
if (s1.y + 1 < dim_org->height)
|
||||
s1.y++;
|
||||
ty.d = scale->y.n;
|
||||
ty.n = (d.y * scale->y.d) % scale->y.n;
|
||||
const uint8_t *data0 = pixel_array + s0.y * y_stride;
|
||||
const uint8_t *data1 = pixel_array + s1.y * y_stride;
|
||||
|
||||
/* Don't waste time resampling when the scale is 1:1. */
|
||||
if (dim_org->width == dim->width && dim_org->height == dim->height) {
|
||||
for (oy = 0; oy < dim->height; oy++, p.y += dir) {
|
||||
p.x = top_left->x;
|
||||
for (d.x = 0; d.x < dim->width; d.x++, p.x++) {
|
||||
s0.x = d.x * scale->x.d / scale->x.n;
|
||||
s1.x = s0.x;
|
||||
if (s1.x + 1 < dim_org->width)
|
||||
s1.x++;
|
||||
tx.d = scale->x.n;
|
||||
tx.n = (d.x * scale->x.d) % scale->x.n;
|
||||
uint8_t c00 = data0[s0.x];
|
||||
uint8_t c10 = data0[s1.x];
|
||||
uint8_t c01 = data1[s0.x];
|
||||
uint8_t c11 = data1[s1.x];
|
||||
if (c00 >= header->colors_used
|
||||
|| c10 >= header->colors_used
|
||||
|| c01 >= header->colors_used
|
||||
|| c11 >= header->colors_used) {
|
||||
LOG("Color index exceeds palette boundary\n");
|
||||
for (ox = 0; ox < dim->width; ox++, p.x++) {
|
||||
struct rgb_color rgb;
|
||||
if (pal_to_rgb(pixel_array[oy * y_stride + ox],
|
||||
pal, header->colors_used, &rgb))
|
||||
return CBGFX_ERROR_BITMAP_DATA;
|
||||
set_pixel(&p, calculate_color(&rgb, invert));
|
||||
}
|
||||
const struct rgb_color rgb = {
|
||||
.red = bli(pal[c00].red, pal[c10].red,
|
||||
pal[c01].red, pal[c11].red,
|
||||
&tx, &ty),
|
||||
.green = bli(pal[c00].green, pal[c10].green,
|
||||
pal[c01].green, pal[c11].green,
|
||||
&tx, &ty),
|
||||
.blue = bli(pal[c00].blue, pal[c10].blue,
|
||||
pal[c01].blue, pal[c11].blue,
|
||||
&tx, &ty),
|
||||
}
|
||||
return CBGFX_SUCCESS;
|
||||
}
|
||||
|
||||
/* Precalculate the X-weights for every possible ox so that we only have
|
||||
to multiply weights together in the end. */
|
||||
fpmath_t (*weight_x)[SSZ] = malloc(sizeof(fpmath_t) * SSZ * dim->width);
|
||||
if (!weight_x)
|
||||
return CBGFX_ERROR_UNKNOWN;
|
||||
for (ox = 0; ox < dim->width; ox++) {
|
||||
for (sx = 0; sx < SSZ; sx++) {
|
||||
fpmath_t ixfp = fpfrac(ox * dim_org->width, dim->width);
|
||||
weight_x[ox][sx] = lanczos_weight(ixfp, sx);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For every sy in the sample array, we directly cache a pointer into
|
||||
* the .BMP pixel array for the start of the corresponding line. On the
|
||||
* edges of the image (where we don't have any real pixels to fill all
|
||||
* lines in the sample array), we just reuse the last valid lines inside
|
||||
* the image for all lines that would lie outside.
|
||||
*/
|
||||
const uint8_t *ypix[SSZ];
|
||||
for (sy = 0; sy < SSZ; sy++) {
|
||||
if (sy <= S0)
|
||||
ypix[sy] = pixel_array;
|
||||
else if (sy - S0 >= dim_org->height)
|
||||
ypix[sy] = ypix[sy - 1];
|
||||
else
|
||||
ypix[sy] = &pixel_array[y_stride * (sy - S0)];
|
||||
}
|
||||
|
||||
/* iy and ix track the input pixel corresponding to sample[S0][S0]. */
|
||||
iy = 0;
|
||||
for (oy = 0; oy < dim->height; oy++, p.y += dir) {
|
||||
struct rgb_color sample[SSZ][SSZ];
|
||||
|
||||
/* Like with X weights, we also cache all Y weights. */
|
||||
fpmath_t iyfp = fpfrac(oy * dim_org->height, dim->height);
|
||||
fpmath_t weight_y[SSZ];
|
||||
for (sy = 0; sy < SSZ; sy++)
|
||||
weight_y[sy] = lanczos_weight(iyfp, sy);
|
||||
|
||||
/*
|
||||
* If we have a new input pixel line between the last oy and
|
||||
* this one, we have to adjust iy forward. When upscaling, this
|
||||
* is not always the case for each new output line. When
|
||||
* downscaling, we may even cross more than one line per output
|
||||
* pixel.
|
||||
*/
|
||||
while (fpfloor(iyfp) > iy) {
|
||||
iy++;
|
||||
|
||||
/* Shift ypix array up to center around next iy line. */
|
||||
for (sy = 0; sy < SSZ - 1; sy++)
|
||||
ypix[sy] = ypix[sy + 1];
|
||||
|
||||
/* Calculate the last ypix that is being shifted in,
|
||||
but beware of reaching the end of the input image. */
|
||||
if (iy + LNCZ_A < dim_org->height)
|
||||
ypix[SSZ - 1] = &pixel_array[y_stride *
|
||||
(iy + LNCZ_A)];
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the sample array for this line. For pixels to the
|
||||
* left of S0 there are no corresponding input pixels so just
|
||||
* copy the S0 values over.
|
||||
*
|
||||
* Also initialize the equals counter, which counts how many of
|
||||
* the latest pixels were exactly equal. We know the columns
|
||||
* left of S0 must be equal to S0, so start with that number.
|
||||
*/
|
||||
int equals = S0 * SSZ;
|
||||
uint8_t last_equal = ypix[0][0];
|
||||
for (sy = 0; sy < SSZ; sy++) {
|
||||
for (sx = S0; sx < SSZ; sx++) {
|
||||
if (sx >= dim_org->width) {
|
||||
sample[sx][sy] = sample[sx - 1][sy];
|
||||
equals++;
|
||||
continue;
|
||||
}
|
||||
uint8_t i = ypix[sy][sx - S0];
|
||||
if (pal_to_rgb(i, pal, header->colors_used,
|
||||
&sample[sx][sy]))
|
||||
goto bitmap_error;
|
||||
if (i == last_equal) {
|
||||
equals++;
|
||||
} else {
|
||||
last_equal = i;
|
||||
equals = 1;
|
||||
}
|
||||
}
|
||||
for (sx = S0 - 1; sx >= 0; sx--)
|
||||
sample[sx][sy] = sample[S0][sy];
|
||||
}
|
||||
|
||||
ix = 0;
|
||||
p.x = top_left->x;
|
||||
for (ox = 0; ox < dim->width; ox++, p.x++) {
|
||||
/* Adjust ix forward, same as iy above. */
|
||||
fpmath_t ixfp = fpfrac(ox * dim_org->width, dim->width);
|
||||
while (fpfloor(ixfp) > ix) {
|
||||
ix++;
|
||||
|
||||
/*
|
||||
* We want to reuse the sample columns we
|
||||
* already have, but we don't want to copy them
|
||||
* all around for every new column either.
|
||||
* Instead, treat the X dimension of the sample
|
||||
* array like a ring buffer indexed by ix. rx is
|
||||
* the ringbuffer-adjusted offset of the new
|
||||
* column in sample (the rightmost one) we're
|
||||
* trying to fill.
|
||||
*/
|
||||
int rx = (SSZ - 1 + ix) % SSZ;
|
||||
for (sy = 0; sy < SSZ; sy++) {
|
||||
if (ix + LNCZ_A >= dim_org->width) {
|
||||
sample[rx][sy] = sample[(SSZ - 2
|
||||
+ ix) % SSZ][sy];
|
||||
equals++;
|
||||
continue;
|
||||
}
|
||||
uint8_t i = ypix[sy][ix + LNCZ_A];
|
||||
if (i == last_equal) {
|
||||
if (equals++ >= (SSZ * SSZ))
|
||||
continue;
|
||||
} else {
|
||||
last_equal = i;
|
||||
equals = 1;
|
||||
}
|
||||
if (pal_to_rgb(i, pal,
|
||||
header->colors_used,
|
||||
&sample[rx][sy]))
|
||||
goto bitmap_error;
|
||||
}
|
||||
}
|
||||
|
||||
/* If all pixels in sample are equal, fast path. */
|
||||
if (equals >= (SSZ * SSZ)) {
|
||||
set_pixel(&p, calculate_color(&sample[0][0],
|
||||
invert));
|
||||
continue;
|
||||
}
|
||||
|
||||
fpmath_t red = fp(0);
|
||||
fpmath_t green = fp(0);
|
||||
fpmath_t blue = fp(0);
|
||||
for (sy = 0; sy < SSZ; sy++) {
|
||||
for (sx = 0; sx < SSZ; sx++) {
|
||||
int rx = (sx + ix) % SSZ;
|
||||
fpmath_t weight = fpmul(weight_x[ox][sx],
|
||||
weight_y[sy]);
|
||||
red = fpadd(red, fpmuli(weight,
|
||||
sample[rx][sy].red));
|
||||
green = fpadd(green, fpmuli(weight,
|
||||
sample[rx][sy].green));
|
||||
blue = fpadd(blue, fpmuli(weight,
|
||||
sample[rx][sy].blue));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Weights *should* sum up to 1.0 (making this not
|
||||
* necessary) but just to hedge against rounding errors
|
||||
* we should clamp color values to their legal limits.
|
||||
*/
|
||||
struct rgb_color rgb = {
|
||||
.red = MAX(0, MIN(UINT8_MAX, fpround(red))),
|
||||
.green = MAX(0, MIN(UINT8_MAX, fpround(green))),
|
||||
.blue = MAX(0, MIN(UINT8_MAX, fpround(blue))),
|
||||
};
|
||||
|
||||
set_pixel(&p, calculate_color(&rgb, invert));
|
||||
}
|
||||
}
|
||||
|
||||
free(weight_x);
|
||||
return CBGFX_SUCCESS;
|
||||
|
||||
bitmap_error:
|
||||
free(weight_x);
|
||||
return CBGFX_ERROR_BITMAP_DATA;
|
||||
}
|
||||
|
||||
static int get_bitmap_file_header(const void *bitmap, size_t size,
|
||||
@@ -780,7 +1047,6 @@ int draw_bitmap(const void *bitmap, size_t size,
|
||||
const struct bitmap_palette_element_v3 *palette;
|
||||
const uint8_t *pixel_array;
|
||||
struct vector top_left, dim, dim_org;
|
||||
struct scale scale;
|
||||
int rv;
|
||||
const uint8_t pivot = flags & PIVOT_MASK;
|
||||
const uint8_t invert = (flags & INVERT_COLORS) >> INVERT_SHIFT;
|
||||
@@ -799,12 +1065,6 @@ int draw_bitmap(const void *bitmap, size_t size,
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
/* Calculate self scale */
|
||||
scale.x.n = dim.width;
|
||||
scale.x.d = dim_org.width;
|
||||
scale.y.n = dim.height;
|
||||
scale.y.d = dim_org.height;
|
||||
|
||||
/* Calculate coordinate */
|
||||
rv = calculate_position(&dim, pos_rel, pivot, &top_left);
|
||||
if (rv)
|
||||
@@ -816,7 +1076,7 @@ int draw_bitmap(const void *bitmap, size_t size,
|
||||
return rv;
|
||||
}
|
||||
|
||||
return draw_bitmap_v3(&top_left, &scale, &dim, &dim_org,
|
||||
return draw_bitmap_v3(&top_left, &dim, &dim_org,
|
||||
&header, palette, pixel_array, invert);
|
||||
}
|
||||
|
||||
@@ -827,7 +1087,6 @@ int draw_bitmap_direct(const void *bitmap, size_t size,
|
||||
const struct bitmap_palette_element_v3 *palette;
|
||||
const uint8_t *pixel_array;
|
||||
struct vector dim;
|
||||
struct scale scale;
|
||||
int rv;
|
||||
|
||||
if (cbgfx_init())
|
||||
@@ -839,19 +1098,13 @@ int draw_bitmap_direct(const void *bitmap, size_t size,
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
/* Calculate self scale */
|
||||
scale.x.n = 1;
|
||||
scale.x.d = 1;
|
||||
scale.y.n = 1;
|
||||
scale.y.d = 1;
|
||||
|
||||
rv = check_boundary(top_left, &dim, &screen);
|
||||
if (rv) {
|
||||
LOG("Bitmap image exceeds screen boundary\n");
|
||||
return rv;
|
||||
}
|
||||
|
||||
return draw_bitmap_v3(top_left, &scale, &dim, &dim,
|
||||
return draw_bitmap_v3(top_left, &dim, &dim,
|
||||
&header, palette, pixel_array, 0);
|
||||
}
|
||||
|
||||
|
@@ -73,6 +73,7 @@ static void gdb_output_write(const void *buffer, size_t count)
|
||||
if (!gdb_state.resumed) {
|
||||
/* Must be a die_if() in GDB (or a bug), so bail out and die. */
|
||||
gdb_exit(-1);
|
||||
if (CONFIG(LP_VIDEO_CONSOLE))
|
||||
video_console_init();
|
||||
puts("GDB died, redirecting its last words to the screen:\n");
|
||||
console_write(buffer, count);
|
||||
|
@@ -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
payloads/libpayload/include/fpmath.h
Normal file
234
payloads/libpayload/include/fpmath.h
Normal file
@@ -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));
|
||||
}
|
@@ -344,6 +344,13 @@ static inline void usb_debug(const char *fmt, ...)
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* To be implemented by libpayload-client. It's called by the USB
|
||||
* stack just before iterating over known devices to poll them for
|
||||
* status change.
|
||||
*/
|
||||
void __attribute__((weak)) usb_poll_prepare (void);
|
||||
|
||||
/**
|
||||
* To be implemented by libpayload-client. It's called by the USB stack
|
||||
* when a new USB device is found which isn't claimed by a built in driver,
|
||||
|
@@ -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__ */
|
||||
|
@@ -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
payloads/libpayload/libc/fpmath.c
Normal file
149
payloads/libpayload/libc/fpmath.c
Normal file
@@ -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 };
|
||||
}
|
100
src/Kconfig
100
src/Kconfig
@@ -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
|
||||
@@ -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
|
||||
@@ -323,6 +332,33 @@ config BOOTSPLASH_FILE
|
||||
The path and filename of the file to use as graphical bootsplash
|
||||
screen. The file format has to be jpg.
|
||||
|
||||
config FW_CONFIG
|
||||
bool "Firmware Configuration Probing"
|
||||
default n
|
||||
help
|
||||
Enable support for probing devices with fw_config. This is a simple
|
||||
bitmask broken into fields and options for probing.
|
||||
|
||||
config FW_CONFIG_SOURCE_CBFS
|
||||
bool "Obtain Firmware Configuration value from CBFS"
|
||||
depends on FW_CONFIG
|
||||
default n
|
||||
help
|
||||
With this option enabled coreboot will look for the 32bit firmware
|
||||
configuration value in CBFS at the selected prefix with the file name
|
||||
"fw_config". This option will override other sources and allow the
|
||||
local image to preempt the mainboard selected source.
|
||||
|
||||
config FW_CONFIG_SOURCE_CHROMEEC_CBI
|
||||
bool "Obtain Firmware Configuration value from Google Chrome EC CBI"
|
||||
depends on FW_CONFIG && EC_GOOGLE_CHROMEEC
|
||||
default n
|
||||
help
|
||||
This option tells coreboot to read the firmware configuration value
|
||||
from the Google Chrome Embedded Controller CBI interface. This source
|
||||
is not tried if FW_CONFIG_SOURCE_CBFS is enabled and the value was
|
||||
found in CBFS.
|
||||
|
||||
config HAVE_RAMPAYLOAD
|
||||
bool
|
||||
|
||||
@@ -390,7 +426,7 @@ config OVERRIDE_DEVICETREE
|
||||
|
||||
config FMDFILE
|
||||
string "fmap description file in fmd format"
|
||||
default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/chromeos.fmd" if CHROMEOS
|
||||
default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/chromeos.fmd" if CHROMEOS
|
||||
default ""
|
||||
help
|
||||
The build system creates a default FMAP from ROM_SIZE and CBFS_SIZE,
|
||||
@@ -529,7 +565,6 @@ source "src/console/Kconfig"
|
||||
config HAVE_ACPI_RESUME
|
||||
bool
|
||||
default n
|
||||
depends on RELOCATABLE_RAMSTAGE
|
||||
|
||||
config DISABLE_ACPI_HIBERNATE
|
||||
bool
|
||||
@@ -628,10 +663,6 @@ config HAVE_PIRQ_TABLE
|
||||
Whether or not the PIRQ table is actually generated by coreboot
|
||||
is configurable by the user via GENERATE_PIRQ_TABLE.
|
||||
|
||||
config COMMON_FADT
|
||||
bool
|
||||
default n
|
||||
|
||||
config ACPI_NHLT
|
||||
bool
|
||||
default n
|
||||
@@ -707,19 +738,15 @@ config MAINBOARD_SMBIOS_PRODUCT_NAME
|
||||
help
|
||||
Override the default Product name stored in SMBIOS structures.
|
||||
|
||||
config SMBIOS_ENCLOSURE_TYPE
|
||||
hex
|
||||
depends on GENERATE_SMBIOS_TABLES
|
||||
default 0x09 if SYSTEM_TYPE_LAPTOP
|
||||
default 0x1e if SYSTEM_TYPE_TABLET
|
||||
default 0x1f if SYSTEM_TYPE_CONVERTIBLE
|
||||
default 0x20 if SYSTEM_TYPE_DETACHABLE
|
||||
default 0x03
|
||||
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
|
||||
System Enclosure or Chassis Types as defined in SMBIOS specification.
|
||||
The default value is SMBIOS_ENCLOSURE_DESKTOP (0x03) but laptop,
|
||||
convertible, or tablet enclosure will be used if the appropriate
|
||||
system type is selected.
|
||||
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
|
||||
|
||||
@@ -820,6 +847,10 @@ config DEBUG_SMI
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config DEBUG_PERIODIC_SMI
|
||||
bool "Trigger SMI periodically"
|
||||
depends on DEBUG_SMI
|
||||
|
||||
# Only visible if debug level is DEBUG (7) or SPEW (8) as it does additional
|
||||
# printk(BIOS_DEBUG, ...) calls.
|
||||
config DEBUG_MALLOC
|
||||
@@ -1173,6 +1204,15 @@ config BOOTBLOCK_CUSTOM
|
||||
# src/lib/bootblock.c#main() C entry point.
|
||||
bool
|
||||
|
||||
config MEMLAYOUT_LD_FILE
|
||||
string
|
||||
default "src/mainboard/\$(CONFIG_MAINBOARD_DIR)/memlayout.ld"
|
||||
help
|
||||
This variable allows SoC/mainboard to supply in a custom linker file
|
||||
if required. This determines the linker file used for all the stages
|
||||
(bootblock, romstage, verstage, ramstage, postcar) in
|
||||
src/arch/${ARCH}/Makefile.inc.
|
||||
|
||||
###############################################################################
|
||||
# Set default values for symbols created before mainboards. This allows the
|
||||
# option to be displayed in the general menu, but the default to be loaded in
|
||||
|
@@ -24,6 +24,9 @@ config ACPI_INTEL_HARDWARE_SLEEP_VALUES
|
||||
Provide common definitions for Intel hardware PM1_CNT register sleep
|
||||
values.
|
||||
|
||||
config ACPI_NO_SMI_GNVS
|
||||
bool
|
||||
|
||||
config ACPI_NO_PCAT_8259
|
||||
bool
|
||||
help
|
||||
|
@@ -4,10 +4,13 @@ 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
|
||||
ramstage-y += device.c
|
||||
ramstage-$(CONFIG_CHROMEOS) += chromeos-gnvs.c
|
||||
ramstage-y += gnvs.c
|
||||
ramstage-y += pld.c
|
||||
ramstage-y += sata.c
|
||||
ramstage-y += soundwire.c
|
||||
@@ -16,8 +19,5 @@ ifneq ($(wildcard src/mainboard/$(MAINBOARDDIR)/acpi_tables.c),)
|
||||
ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/acpi_tables.c
|
||||
endif
|
||||
$(eval $(call asl_template,dsdt))
|
||||
ifneq ($(wildcard src/mainboard/$(MAINBOARDDIR)/fadt.c),)
|
||||
ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/fadt.c
|
||||
endif
|
||||
|
||||
endif # CONFIG_GENERATE_ACPI_TABLES
|
||||
endif # CONFIG_HAVE_ACPI_TABLES
|
||||
|
@@ -1219,7 +1219,10 @@ void acpi_write_bert(acpi_bert_t *bert, uintptr_t region, size_t length)
|
||||
header->checksum = acpi_checksum((void *)bert, header->length);
|
||||
}
|
||||
|
||||
#if CONFIG(COMMON_FADT)
|
||||
__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) { }
|
||||
|
||||
void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
|
||||
{
|
||||
acpi_header_t *header = &(fadt->header);
|
||||
@@ -1238,13 +1241,16 @@ void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
|
||||
header->asl_compiler_revision = asl_revision;
|
||||
|
||||
fadt->firmware_ctrl = (unsigned long) facs;
|
||||
fadt->dsdt = (unsigned long) dsdt;
|
||||
|
||||
fadt->x_firmware_ctl_l = (unsigned long)facs;
|
||||
fadt->x_firmware_ctl_h = 0;
|
||||
|
||||
fadt->dsdt = (unsigned long) dsdt;
|
||||
fadt->x_dsdt_l = (unsigned long)dsdt;
|
||||
fadt->x_dsdt_h = 0;
|
||||
|
||||
/* should be 0 ACPI 3.0 */
|
||||
fadt->reserved = 0;
|
||||
|
||||
if (CONFIG(SYSTEM_TYPE_CONVERTIBLE) ||
|
||||
CONFIG(SYSTEM_TYPE_LAPTOP))
|
||||
fadt->preferred_pm_profile = PM_MOBILE;
|
||||
@@ -1254,12 +1260,16 @@ 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);
|
||||
mainboard_fill_fadt(fadt);
|
||||
|
||||
header->checksum =
|
||||
acpi_checksum((void *) fadt, header->length);
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned long __weak fw_cfg_acpi_tables(unsigned long start)
|
||||
{
|
||||
|
@@ -339,6 +339,18 @@ void acpigen_write_scope(const char *name)
|
||||
acpigen_emit_namestring(name);
|
||||
}
|
||||
|
||||
void acpigen_get_package_op_element(uint8_t package_op, unsigned int element, uint8_t dest_op)
|
||||
{
|
||||
/* <dest_op> = DeRefOf (<package_op>[<element]) */
|
||||
acpigen_write_store();
|
||||
acpigen_emit_byte(DEREF_OP);
|
||||
acpigen_emit_byte(INDEX_OP);
|
||||
acpigen_emit_byte(package_op);
|
||||
acpigen_write_integer(element);
|
||||
acpigen_emit_byte(ZERO_OP); /* Ignore Index() Destination */
|
||||
acpigen_emit_byte(dest_op);
|
||||
}
|
||||
|
||||
void acpigen_write_processor(u8 cpuindex, u32 pblock_addr, u8 pblock_len)
|
||||
{
|
||||
/*
|
||||
@@ -730,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.
|
||||
*/
|
||||
@@ -1268,6 +1291,20 @@ void acpigen_write_if_and(uint8_t arg1, uint8_t arg2)
|
||||
acpigen_emit_byte(arg2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generates ACPI code for checking if operand1 and operand2 are equal.
|
||||
* Both operand1 and operand2 are ACPI ops.
|
||||
*
|
||||
* If (Lequal (op,1 op2))
|
||||
*/
|
||||
void acpigen_write_if_lequal_op_op(uint8_t op1, uint8_t op2)
|
||||
{
|
||||
acpigen_write_if();
|
||||
acpigen_emit_byte(LEQUAL_OP);
|
||||
acpigen_emit_byte(op1);
|
||||
acpigen_emit_byte(op2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generates ACPI code for checking if operand1 and operand2 are equal, where,
|
||||
* operand1 is ACPI op and operand2 is an integer.
|
||||
@@ -1341,6 +1378,12 @@ void acpigen_write_return_singleton_buffer(uint8_t arg)
|
||||
acpigen_write_return_byte_buffer(&arg, 1);
|
||||
}
|
||||
|
||||
void acpigen_write_return_op(uint8_t arg)
|
||||
{
|
||||
acpigen_emit_byte(RETURN_OP);
|
||||
acpigen_emit_byte(arg);
|
||||
}
|
||||
|
||||
void acpigen_write_return_byte(uint8_t arg)
|
||||
{
|
||||
acpigen_emit_byte(RETURN_OP);
|
||||
@@ -1768,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]);
|
||||
@@ -1786,7 +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->active_low)
|
||||
acpigen_write_xor(LOCAL0_OP, 1, LOCAL0_OP);
|
||||
}
|
||||
|
||||
@@ -1913,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
src/acpi/acpigen_dptf.c
Normal file
486
src/acpi/acpigen_dptf.c
Normal file
@@ -0,0 +1,486 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <acpi/acpigen.h>
|
||||
#include <acpi/acpigen_dptf.h>
|
||||
|
||||
/* Defaults */
|
||||
#define DEFAULT_RAW_UNIT "ma"
|
||||
|
||||
/* DPTF-specific UUIDs */
|
||||
#define DPTF_PASSIVE_POLICY_1_0_UUID "42A441D6-AE6A-462B-A84B-4A8CE79027D3"
|
||||
#define DPTF_CRITICAL_POLICY_UUID "97C68AE7-15FA-499c-B8C9-5DA81D606E0A"
|
||||
#define DPTF_ACTIVE_POLICY_UUID "3A95C389-E4B8-4629-A526-C52C88626BAE"
|
||||
|
||||
enum {
|
||||
ART_REVISION = 0,
|
||||
DEFAULT_PRIORITY = 100,
|
||||
DEFAULT_TRIP_POINT = 0xFFFFFFFFull,
|
||||
DEFAULT_WEIGHT = 100,
|
||||
DPTF_MAX_ART_THRESHOLDS = 10,
|
||||
PPCC_REVISION = 2,
|
||||
RAPL_PL1_INDEX = 0,
|
||||
RAPL_PL2_INDEX = 1,
|
||||
};
|
||||
|
||||
/* Convert degrees C to 1/10 degree Kelvin for ACPI */
|
||||
static int to_acpi_temp(int deg_c)
|
||||
{
|
||||
return deg_c * 10 + 2732;
|
||||
}
|
||||
|
||||
/* Converts ms to 1/10th second for ACPI */
|
||||
static int to_acpi_time(int ms)
|
||||
{
|
||||
return ms / 100;
|
||||
}
|
||||
|
||||
/* Writes out a 0-argument non-Serialized Method that returns an Integer */
|
||||
static void write_simple_return_method(const char *name, int value)
|
||||
{
|
||||
acpigen_write_method(name, 0);
|
||||
acpigen_write_return_integer(value);
|
||||
acpigen_pop_len(); /* Method */
|
||||
}
|
||||
|
||||
/* Writes out 'count' ZEROs in a row */
|
||||
static void write_zeros(int count)
|
||||
{
|
||||
for (; count; --count)
|
||||
acpigen_write_integer(0);
|
||||
}
|
||||
|
||||
/* Return the assigned namestring of any participant */
|
||||
static const char *namestring_of(enum dptf_participant participant)
|
||||
{
|
||||
switch (participant) {
|
||||
case DPTF_CPU:
|
||||
return "TCPU";
|
||||
case DPTF_CHARGER:
|
||||
return "TCHG";
|
||||
case DPTF_FAN:
|
||||
return "TFN1";
|
||||
case DPTF_TEMP_SENSOR_0:
|
||||
return "TSR0";
|
||||
case DPTF_TEMP_SENSOR_1:
|
||||
return "TSR1";
|
||||
case DPTF_TEMP_SENSOR_2:
|
||||
return "TSR2";
|
||||
case DPTF_TEMP_SENSOR_3:
|
||||
return "TSR3";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper to get Scope for participants underneath \_SB.DPTF */
|
||||
static const char *scope_of(enum dptf_participant participant)
|
||||
{
|
||||
static char scope[16];
|
||||
|
||||
if (participant == DPTF_CPU)
|
||||
snprintf(scope, sizeof(scope), TCPU_SCOPE ".%s", namestring_of(participant));
|
||||
else
|
||||
snprintf(scope, sizeof(scope), DPTF_DEVICE_PATH ".%s",
|
||||
namestring_of(participant));
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
/*
|
||||
* Most of the DPTF participants are underneath the \_SB.DPTF scope, so we can just get away
|
||||
* with using the simple namestring for references, but the TCPU has a different scope, so
|
||||
* either an absolute or relative path must be used instead.
|
||||
*/
|
||||
static const char *path_of(enum dptf_participant participant)
|
||||
{
|
||||
if (participant == DPTF_CPU)
|
||||
return scope_of(participant);
|
||||
else
|
||||
return namestring_of(participant);
|
||||
}
|
||||
|
||||
/* Write out scope of a participant */
|
||||
void dptf_write_scope(enum dptf_participant participant)
|
||||
{
|
||||
acpigen_write_scope(scope_of(participant));
|
||||
}
|
||||
|
||||
/*
|
||||
* This table describes active cooling relationships between the system's fan and the
|
||||
* temperature sensors that it can have an effect on. As ever-increasing temperature thresholds
|
||||
* are crossed (_AC9.._AC0, low to high), the corresponding fan percentages listed in this table
|
||||
* are used to increase the speed of the fan in order to speed up cooling.
|
||||
*/
|
||||
static void write_active_relationship_table(const struct dptf_active_policy *policies,
|
||||
int max_count)
|
||||
{
|
||||
char *pkg_count;
|
||||
int i, j;
|
||||
|
||||
/* Nothing to do */
|
||||
if (!max_count || policies[0].target == DPTF_NONE)
|
||||
return;
|
||||
|
||||
acpigen_write_scope(DPTF_DEVICE_PATH);
|
||||
acpigen_write_method("_ART", 0);
|
||||
|
||||
/* Return this package */
|
||||
acpigen_emit_byte(RETURN_OP);
|
||||
|
||||
/* Keep track of items added to the package */
|
||||
pkg_count = acpigen_write_package(1); /* The '1' here is for the revision */
|
||||
acpigen_write_integer(ART_REVISION);
|
||||
|
||||
for (i = 0; i < max_count; ++i) {
|
||||
/*
|
||||
* These have to be filled out from AC0 down to AC9, filling in only as many
|
||||
* as are used. As soon as one isn't filled in, we're done.
|
||||
*/
|
||||
if (policies[i].target == DPTF_NONE)
|
||||
break;
|
||||
|
||||
(*pkg_count)++;
|
||||
|
||||
/* Source, Target, Percent, Fan % for each of _AC0 ... _AC9 */
|
||||
acpigen_write_package(13);
|
||||
acpigen_emit_namestring(path_of(DPTF_FAN));
|
||||
acpigen_emit_namestring(path_of(policies[i].target));
|
||||
acpigen_write_integer(DEFAULT_IF_0(policies[i].weight, DEFAULT_WEIGHT));
|
||||
|
||||
/* Write out fan %; corresponds with target's _ACx methods */
|
||||
for (j = 0; j < DPTF_MAX_ART_THRESHOLDS; ++j)
|
||||
acpigen_write_integer(policies[i].thresholds[j].fan_pct);
|
||||
|
||||
acpigen_pop_len(); /* inner Package */
|
||||
}
|
||||
|
||||
acpigen_pop_len(); /* outer Package */
|
||||
acpigen_pop_len(); /* Method _ART */
|
||||
acpigen_pop_len(); /* Scope */
|
||||
}
|
||||
|
||||
/*
|
||||
* _AC9 through _AC0 represent temperature thresholds, in increasing order, defined from _AC0
|
||||
* down, that, when reached, DPTF will activate TFN1 in order to actively cool the temperature
|
||||
* sensor(s). As increasing thresholds are reached, the fan is spun faster.
|
||||
*/
|
||||
static void write_active_cooling_methods(const struct dptf_active_policy *policies,
|
||||
int max_count)
|
||||
{
|
||||
char name[5];
|
||||
int i, j;
|
||||
|
||||
/* Nothing to do */
|
||||
if (!max_count || policies[0].target == DPTF_NONE)
|
||||
return;
|
||||
|
||||
for (i = 0; i < max_count; ++i) {
|
||||
if (policies[i].target == DPTF_NONE)
|
||||
break;
|
||||
|
||||
dptf_write_scope(policies[i].target);
|
||||
|
||||
/* Write out as many of _AC0 through _AC9 that are applicable */
|
||||
for (j = 0; j < DPTF_MAX_ACX; ++j) {
|
||||
if (!policies[i].thresholds[j].temp)
|
||||
break;
|
||||
|
||||
snprintf(name, sizeof(name), "_AC%1X", j);
|
||||
write_simple_return_method(name, to_acpi_temp(
|
||||
policies[i].thresholds[j].temp));
|
||||
}
|
||||
|
||||
acpigen_pop_len(); /* Scope */
|
||||
}
|
||||
}
|
||||
|
||||
void dptf_write_active_policies(const struct dptf_active_policy *policies, int max_count)
|
||||
{
|
||||
write_active_relationship_table(policies, max_count);
|
||||
write_active_cooling_methods(policies, max_count);
|
||||
}
|
||||
|
||||
/*
|
||||
* This writes out the Thermal Relationship Table, which describes the thermal relationships
|
||||
* between participants in a thermal zone. This information is used to passively cool (i.e.,
|
||||
* throttle) the Source (source of heat), in order to indirectly cool the Target (temperature
|
||||
* sensor).
|
||||
*/
|
||||
static void write_thermal_relationship_table(const struct dptf_passive_policy *policies,
|
||||
int max_count)
|
||||
{
|
||||
char *pkg_count;
|
||||
int i;
|
||||
|
||||
/* Nothing to do */
|
||||
if (!max_count || policies[0].source == DPTF_NONE)
|
||||
return;
|
||||
|
||||
acpigen_write_scope(DPTF_DEVICE_PATH);
|
||||
|
||||
/*
|
||||
* A _TRT Revision (TRTR) of 1 means that the 'Priority' field is an arbitrary priority
|
||||
* value to be used for this specific relationship. The priority value determines the
|
||||
* order in which various sources are used in a passive thermal action for a given
|
||||
* target.
|
||||
*/
|
||||
acpigen_write_name_integer("TRTR", 1);
|
||||
|
||||
/* Thermal Relationship Table */
|
||||
acpigen_write_method("_TRT", 0);
|
||||
|
||||
/* Return this package */
|
||||
acpigen_emit_byte(RETURN_OP);
|
||||
pkg_count = acpigen_write_package(0);
|
||||
|
||||
for (i = 0; i < max_count; ++i) {
|
||||
/* Stop writing the table once an entry is empty */
|
||||
if (policies[i].source == DPTF_NONE)
|
||||
break;
|
||||
|
||||
/* Keep track of outer package item count */
|
||||
(*pkg_count)++;
|
||||
|
||||
acpigen_write_package(8);
|
||||
|
||||
/* Source, Target, Priority, Sampling Period */
|
||||
acpigen_emit_namestring(path_of(policies[i].source));
|
||||
acpigen_emit_namestring(path_of(policies[i].target));
|
||||
acpigen_write_integer(DEFAULT_IF_0(policies[i].priority, DEFAULT_PRIORITY));
|
||||
acpigen_write_integer(to_acpi_time(policies[i].period));
|
||||
|
||||
/* Reserved */
|
||||
write_zeros(4);
|
||||
|
||||
acpigen_pop_len(); /* Package */
|
||||
}
|
||||
|
||||
acpigen_pop_len(); /* Package */
|
||||
acpigen_pop_len(); /* Method */
|
||||
acpigen_pop_len(); /* Scope */
|
||||
}
|
||||
|
||||
/*
|
||||
* When a temperature sensor measures above its the temperature returned in its _PSV Method,
|
||||
* DPTF will begin throttling Sources in order to indirectly cool the sensor.
|
||||
*/
|
||||
static void write_all_PSV(const struct dptf_passive_policy *policies, int max_count)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < max_count; ++i) {
|
||||
if (policies[i].source == DPTF_NONE)
|
||||
break;
|
||||
|
||||
dptf_write_scope(policies[i].target);
|
||||
write_simple_return_method("_PSV", to_acpi_temp(policies[i].temp));
|
||||
acpigen_pop_len(); /* Scope */
|
||||
}
|
||||
}
|
||||
|
||||
void dptf_write_passive_policies(const struct dptf_passive_policy *policies, int max_count)
|
||||
{
|
||||
write_thermal_relationship_table(policies, max_count);
|
||||
write_all_PSV(policies, max_count);
|
||||
}
|
||||
|
||||
void dptf_write_critical_policies(const struct dptf_critical_policy *policies, int max_count)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < max_count; ++i) {
|
||||
if (policies[i].source == DPTF_NONE)
|
||||
break;
|
||||
|
||||
dptf_write_scope(policies[i].source);
|
||||
|
||||
/* Choose _CRT or _HOT */
|
||||
write_simple_return_method(policies[i].type == DPTF_CRITICAL_SHUTDOWN ?
|
||||
"_CRT" : "_HOT", to_acpi_temp(policies[i].temp));
|
||||
|
||||
acpigen_pop_len(); /* Scope */
|
||||
}
|
||||
}
|
||||
|
||||
void dptf_write_charger_perf(const struct dptf_charger_perf *states, int max_count)
|
||||
{
|
||||
char *pkg_count;
|
||||
int i;
|
||||
|
||||
if (!max_count || !states[0].control)
|
||||
return;
|
||||
|
||||
dptf_write_scope(DPTF_CHARGER);
|
||||
|
||||
/* PPSS - Participant Performance Supported States */
|
||||
acpigen_write_method("PPSS", 0);
|
||||
acpigen_emit_byte(RETURN_OP);
|
||||
|
||||
pkg_count = acpigen_write_package(0);
|
||||
for (i = 0; i < max_count; ++i) {
|
||||
if (!states[i].control)
|
||||
break;
|
||||
|
||||
(*pkg_count)++;
|
||||
|
||||
/*
|
||||
* 0, 0, 0, 0, # Reserved
|
||||
* Control, Raw Performance, Raw Unit, 0 # Reserved
|
||||
*/
|
||||
acpigen_write_package(8);
|
||||
write_zeros(4);
|
||||
acpigen_write_integer(states[i].control);
|
||||
acpigen_write_integer(states[i].raw_perf);
|
||||
acpigen_write_string(DEFAULT_RAW_UNIT);
|
||||
acpigen_write_integer(0);
|
||||
acpigen_pop_len(); /* inner Package */
|
||||
}
|
||||
|
||||
acpigen_pop_len(); /* outer Package */
|
||||
acpigen_pop_len(); /* Method PPSS */
|
||||
acpigen_pop_len(); /* Scope */
|
||||
}
|
||||
|
||||
void dptf_write_fan_perf(const struct dptf_fan_perf *states, int max_count)
|
||||
{
|
||||
char *pkg_count;
|
||||
int i;
|
||||
|
||||
if (!max_count || !states[0].percent)
|
||||
return;
|
||||
|
||||
dptf_write_scope(DPTF_FAN);
|
||||
|
||||
/* _FPS - Fan Performance States */
|
||||
acpigen_write_name("_FPS");
|
||||
pkg_count = acpigen_write_package(0);
|
||||
|
||||
for (i = 0; i < max_count; ++i) {
|
||||
/*
|
||||
* Some _FPS tables do include a last entry where Percent is 0, but Power is
|
||||
* called out, so this table is finished when both are zero.
|
||||
*/
|
||||
if (!states[i].percent && !states[i].power)
|
||||
break;
|
||||
|
||||
(*pkg_count)++;
|
||||
acpigen_write_package(5);
|
||||
acpigen_write_integer(states[i].percent);
|
||||
acpigen_write_integer(DEFAULT_TRIP_POINT);
|
||||
acpigen_write_integer(states[i].speed);
|
||||
acpigen_write_integer(states[i].noise_level);
|
||||
acpigen_write_integer(states[i].power);
|
||||
acpigen_pop_len(); /* inner Package */
|
||||
}
|
||||
|
||||
acpigen_pop_len(); /* Package */
|
||||
acpigen_pop_len(); /* Scope */
|
||||
}
|
||||
|
||||
void dptf_write_power_limits(const struct dptf_power_limits *limits)
|
||||
{
|
||||
char *pkg_count;
|
||||
|
||||
/* Nothing to do */
|
||||
if (!limits->pl1.min_power && !limits->pl2.min_power)
|
||||
return;
|
||||
|
||||
dptf_write_scope(DPTF_CPU);
|
||||
acpigen_write_method("PPCC", 0);
|
||||
|
||||
pkg_count = acpigen_write_package(1); /* 1 for the Revision */
|
||||
acpigen_write_integer(PPCC_REVISION); /* revision */
|
||||
|
||||
if (limits->pl1.min_power) {
|
||||
(*pkg_count)++;
|
||||
acpigen_write_package(6);
|
||||
acpigen_write_integer(RAPL_PL1_INDEX);
|
||||
acpigen_write_integer(limits->pl1.min_power);
|
||||
acpigen_write_integer(limits->pl1.max_power);
|
||||
acpigen_write_integer(limits->pl1.time_window_min);
|
||||
acpigen_write_integer(limits->pl1.time_window_max);
|
||||
acpigen_write_integer(limits->pl1.granularity);
|
||||
acpigen_pop_len(); /* inner Package */
|
||||
}
|
||||
|
||||
if (limits->pl2.min_power) {
|
||||
(*pkg_count)++;
|
||||
acpigen_write_package(6);
|
||||
acpigen_write_integer(RAPL_PL2_INDEX);
|
||||
acpigen_write_integer(limits->pl2.min_power);
|
||||
acpigen_write_integer(limits->pl2.max_power);
|
||||
acpigen_write_integer(limits->pl2.time_window_min);
|
||||
acpigen_write_integer(limits->pl2.time_window_max);
|
||||
acpigen_write_integer(limits->pl2.granularity);
|
||||
acpigen_pop_len(); /* inner Package */
|
||||
}
|
||||
|
||||
acpigen_pop_len(); /* outer Package */
|
||||
acpigen_pop_len(); /* Method */
|
||||
acpigen_pop_len(); /* Scope */
|
||||
}
|
||||
|
||||
void dptf_write_STR(const char *str)
|
||||
{
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
acpigen_write_name_string("_STR", str);
|
||||
}
|
||||
|
||||
void dptf_write_fan_options(bool fine_grained, int step_size, bool low_speed_notify)
|
||||
{
|
||||
acpigen_write_name("_FIF");
|
||||
acpigen_write_package(4);
|
||||
|
||||
acpigen_write_integer(0); /* Revision */
|
||||
acpigen_write_integer(fine_grained);
|
||||
acpigen_write_integer(step_size);
|
||||
acpigen_write_integer(low_speed_notify);
|
||||
acpigen_pop_len(); /* Package */
|
||||
}
|
||||
|
||||
void dptf_write_tsr_hysteresis(uint8_t hysteresis)
|
||||
{
|
||||
if (!hysteresis)
|
||||
return;
|
||||
|
||||
acpigen_write_name_integer("GTSH", hysteresis);
|
||||
}
|
||||
|
||||
void dptf_write_enabled_policies(const struct dptf_active_policy *active_policies,
|
||||
int active_count,
|
||||
const struct dptf_passive_policy *passive_policies,
|
||||
int passive_count,
|
||||
const struct dptf_critical_policy *critical_policies,
|
||||
int critical_count)
|
||||
{
|
||||
bool is_active_used;
|
||||
bool is_passive_used;
|
||||
bool is_critical_used;
|
||||
int pkg_count;
|
||||
|
||||
is_active_used = (active_count && active_policies[0].target != DPTF_NONE);
|
||||
is_passive_used = (passive_count && passive_policies[0].target != DPTF_NONE);
|
||||
is_critical_used = (critical_count && critical_policies[0].source != DPTF_NONE);
|
||||
pkg_count = is_active_used + is_passive_used + is_critical_used;
|
||||
|
||||
if (!pkg_count)
|
||||
return;
|
||||
|
||||
acpigen_write_scope(DPTF_DEVICE_PATH);
|
||||
acpigen_write_name("IDSP");
|
||||
acpigen_write_package(pkg_count);
|
||||
|
||||
if (is_active_used)
|
||||
acpigen_write_uuid(DPTF_ACTIVE_POLICY_UUID);
|
||||
|
||||
if (is_passive_used)
|
||||
acpigen_write_uuid(DPTF_PASSIVE_POLICY_1_0_UUID);
|
||||
|
||||
if (is_critical_used)
|
||||
acpigen_write_uuid(DPTF_CRITICAL_POLICY_UUID);
|
||||
|
||||
acpigen_pop_len(); /* Package */
|
||||
acpigen_pop_len(); /* Scope */
|
||||
}
|
17
src/acpi/chromeos-gnvs.c
Normal file
17
src/acpi/chromeos-gnvs.c
Normal file
@@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <acpi/acpi_gnvs.h>
|
||||
#include <ec/google/chromeec/ec.h>
|
||||
#include <vendorcode/google/chromeos/gnvs.h>
|
||||
|
||||
void gnvs_assign_chromeos(void)
|
||||
{
|
||||
chromeos_acpi_t *gnvs_chromeos = gnvs_chromeos_ptr();
|
||||
chromeos_init_chromeos_acpi(gnvs_chromeos);
|
||||
|
||||
/* EC can override to ECFW_RW. */
|
||||
gnvs_chromeos->vbt2 = ACTIVE_ECFW_RO;
|
||||
|
||||
if (CONFIG(EC_GOOGLE_CHROMEEC) && !google_ec_running_ro())
|
||||
gnvs_chromeos->vbt2 = ACTIVE_ECFW_RW;
|
||||
}
|
@@ -53,7 +53,7 @@ const char *acpi_device_name(const struct device *dev)
|
||||
return NULL;
|
||||
|
||||
/* Check for device specific handler */
|
||||
if (dev->ops->acpi_name)
|
||||
if (dev->ops && dev->ops->acpi_name)
|
||||
return dev->ops->acpi_name(dev);
|
||||
|
||||
/* Walk up the tree to find if any parent can identify this device */
|
||||
@@ -523,6 +523,80 @@ void acpi_device_write_spi(const struct acpi_spi *spi)
|
||||
acpi_device_fill_len(desc_length);
|
||||
}
|
||||
|
||||
/* UART Serial Bus - UARTSerialBusV2() */
|
||||
void acpi_device_write_uart(const struct acpi_uart *uart)
|
||||
{
|
||||
void *desc_length, *type_length;
|
||||
uint16_t flags;
|
||||
|
||||
/* Byte 0: Descriptor Type */
|
||||
acpigen_emit_byte(ACPI_DESCRIPTOR_SERIAL_BUS);
|
||||
|
||||
/* Byte 1+2: Length (filled in later) */
|
||||
desc_length = acpi_device_write_zero_len();
|
||||
|
||||
/* Byte 3: Revision ID */
|
||||
acpigen_emit_byte(ACPI_UART_SERIAL_BUS_REVISION_ID);
|
||||
|
||||
/* Byte 4: Resource Source Index is Reserved */
|
||||
acpigen_emit_byte(0);
|
||||
|
||||
/* Byte 5: Serial Bus Type is UART */
|
||||
acpigen_emit_byte(ACPI_SERIAL_BUS_TYPE_UART);
|
||||
|
||||
/*
|
||||
* Byte 6: Flags
|
||||
* [7:2]: 0 => Reserved
|
||||
* [1]: 1 => ResourceConsumer
|
||||
* [0]: 0 => ControllerInitiated
|
||||
*/
|
||||
acpigen_emit_byte(BIT(1));
|
||||
|
||||
/*
|
||||
* Byte 7-8: Type Specific Flags
|
||||
* [15:8]: 0 => Reserved
|
||||
* [7]: 0 => Little Endian, 1 => Big Endian
|
||||
* [6:4]: Data bits
|
||||
* [3:2]: Stop bits
|
||||
* [1:0]: Flow control
|
||||
*/
|
||||
flags = uart->flow_control & 3;
|
||||
flags |= (uart->stop_bits & 3) << 2;
|
||||
flags |= (uart->data_bits & 7) << 4;
|
||||
flags |= (uart->endian & 1) << 7;
|
||||
acpigen_emit_word(flags);
|
||||
|
||||
/* Byte 9: Type Specific Revision ID */
|
||||
acpigen_emit_byte(ACPI_UART_TYPE_SPECIFIC_REVISION_ID);
|
||||
|
||||
/* Byte 10-11: Type Data Length */
|
||||
type_length = acpi_device_write_zero_len();
|
||||
|
||||
/* Byte 12-15: Initial Baud Rate */
|
||||
acpigen_emit_dword(uart->initial_baud_rate);
|
||||
|
||||
/* Byte 16-17: RX FIFO size */
|
||||
acpigen_emit_word(uart->rx_fifo_bytes);
|
||||
|
||||
/* Byte 18-19: TX FIFO size */
|
||||
acpigen_emit_word(uart->tx_fifo_bytes);
|
||||
|
||||
/* Byte 20: Parity */
|
||||
acpigen_emit_byte(uart->parity);
|
||||
|
||||
/* Byte 21: Lines Enabled */
|
||||
acpigen_emit_byte(uart->lines_in_use);
|
||||
|
||||
/* Fill in Type Data Length */
|
||||
acpi_device_fill_len(type_length);
|
||||
|
||||
/* Byte 22+: ResourceSource */
|
||||
acpigen_emit_string(uart->resource);
|
||||
|
||||
/* Fill in Descriptor Length */
|
||||
acpi_device_fill_len(desc_length);
|
||||
}
|
||||
|
||||
/* PowerResource() with Enable and/or Reset control */
|
||||
void acpi_device_add_power_res(const struct acpi_power_res_params *params)
|
||||
{
|
||||
@@ -658,10 +732,48 @@ static void acpi_dp_free(struct acpi_dp *dp)
|
||||
}
|
||||
}
|
||||
|
||||
void acpi_dp_write(struct acpi_dp *table)
|
||||
static bool acpi_dp_write_properties(struct acpi_dp *prop, const char *uuid)
|
||||
{
|
||||
struct acpi_dp *dp;
|
||||
char *prop_count = NULL;
|
||||
|
||||
/* Print base properties */
|
||||
for (dp = prop; dp; dp = dp->next) {
|
||||
if (dp->type == ACPI_DP_TYPE_TABLE ||
|
||||
dp->type == ACPI_DP_TYPE_CHILD ||
|
||||
dp->type == ACPI_DP_TYPE_PACKAGE)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* The UUID and package is only added when
|
||||
* we come across the first property. This
|
||||
* is to avoid creating a zero-length package
|
||||
* in situations where there are only children.
|
||||
*/
|
||||
if (!prop_count) {
|
||||
/* ToUUID (dp->uuid) */
|
||||
acpigen_write_uuid(uuid);
|
||||
/*
|
||||
* Package (PROP), element count determined as
|
||||
* it is populated
|
||||
*/
|
||||
prop_count = acpigen_write_package(0);
|
||||
}
|
||||
(*prop_count)++;
|
||||
acpi_dp_write_property(dp);
|
||||
}
|
||||
if (prop_count) {
|
||||
/* Package (PROP) length, if a package was written */
|
||||
acpigen_pop_len();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void acpi_dp_write_(struct acpi_dp *table)
|
||||
{
|
||||
struct acpi_dp *dp, *prop;
|
||||
char *dp_count, *prop_count = NULL;
|
||||
char *dp_count;
|
||||
int child_count = 0;
|
||||
|
||||
if (!table || table->type != ACPI_DP_TYPE_TABLE || !table->next)
|
||||
@@ -677,37 +789,17 @@ void acpi_dp_write(struct acpi_dp *table)
|
||||
dp_count = acpigen_write_package(0);
|
||||
|
||||
/* Print base properties */
|
||||
for (dp = prop; dp; dp = dp->next) {
|
||||
if (dp->type == ACPI_DP_TYPE_CHILD) {
|
||||
child_count++;
|
||||
} else {
|
||||
/*
|
||||
* The UUID and package is only added when
|
||||
* we come across the first property. This
|
||||
* is to avoid creating a zero-length package
|
||||
* in situations where there are only children.
|
||||
*/
|
||||
if (!prop_count) {
|
||||
if (acpi_dp_write_properties(prop, table->uuid))
|
||||
*dp_count += 2;
|
||||
/* ToUUID (ACPI_DP_UUID) */
|
||||
acpigen_write_uuid(ACPI_DP_UUID);
|
||||
/*
|
||||
* Package (PROP), element count determined as
|
||||
* it is populated
|
||||
*/
|
||||
prop_count = acpigen_write_package(0);
|
||||
}
|
||||
(*prop_count)++;
|
||||
acpi_dp_write_property(dp);
|
||||
}
|
||||
}
|
||||
if (prop_count) {
|
||||
/* Package (PROP) length, if a package was written */
|
||||
acpigen_pop_len();
|
||||
}
|
||||
|
||||
/* Count child properties */
|
||||
for (dp = prop; dp; dp = dp->next)
|
||||
if (dp->type == ACPI_DP_TYPE_CHILD)
|
||||
child_count++;
|
||||
|
||||
/* Add child properties to the base table */
|
||||
if (child_count) {
|
||||
/* Update DP package count to 2 or 4 */
|
||||
/* Update DP package count */
|
||||
*dp_count += 2;
|
||||
/* ToUUID (ACPI_DP_CHILD_UUID) */
|
||||
acpigen_write_uuid(ACPI_DP_CHILD_UUID);
|
||||
@@ -722,13 +814,24 @@ void acpi_dp_write(struct acpi_dp *table)
|
||||
acpigen_pop_len();
|
||||
}
|
||||
|
||||
/* Write packages of properties with unique UUID */
|
||||
for (dp = prop; dp; dp = dp->next)
|
||||
if (dp->type == ACPI_DP_TYPE_PACKAGE)
|
||||
if (acpi_dp_write_properties(dp->child, dp->uuid))
|
||||
*dp_count += 2;
|
||||
|
||||
/* Package (DP) length */
|
||||
acpigen_pop_len();
|
||||
|
||||
/* 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);
|
||||
@@ -746,6 +849,7 @@ static struct acpi_dp *acpi_dp_new(struct acpi_dp *dp, enum acpi_dp_type type,
|
||||
memset(new, 0, sizeof(*new));
|
||||
new->type = type;
|
||||
new->name = name;
|
||||
new->uuid = ACPI_DP_UUID;
|
||||
|
||||
if (dp) {
|
||||
/* Add to end of property list */
|
||||
@@ -863,6 +967,22 @@ struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name,
|
||||
return new;
|
||||
}
|
||||
|
||||
struct acpi_dp *acpi_dp_add_package(struct acpi_dp *dp, struct acpi_dp *package)
|
||||
{
|
||||
struct acpi_dp *new;
|
||||
|
||||
if (!dp || !package || package->type != ACPI_DP_TYPE_TABLE)
|
||||
return NULL;
|
||||
|
||||
new = acpi_dp_new(dp, ACPI_DP_TYPE_PACKAGE, NULL);
|
||||
if (new) {
|
||||
new->uuid = package->name;
|
||||
new->child = package;
|
||||
}
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
struct acpi_dp *acpi_dp_add_array(struct acpi_dp *dp, struct acpi_dp *array)
|
||||
{
|
||||
struct acpi_dp *new;
|
||||
|
69
src/acpi/gnvs.c
Normal file
69
src/acpi/gnvs.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <acpi/acpi_gnvs.h>
|
||||
#include <acpi/acpigen.h>
|
||||
#include <cbmem.h>
|
||||
#include <console/console.h>
|
||||
#include <string.h>
|
||||
#include <types.h>
|
||||
|
||||
static void *gnvs;
|
||||
|
||||
void *acpi_get_gnvs(void)
|
||||
{
|
||||
if (gnvs)
|
||||
return gnvs;
|
||||
|
||||
gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
|
||||
if (gnvs)
|
||||
return gnvs;
|
||||
|
||||
printk(BIOS_ERR, "Unable to locate Global NVS\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void gnvs_assign_cbmc(void)
|
||||
{
|
||||
uint32_t *gnvs_cbmc = gnvs_cbmc_ptr();
|
||||
if (gnvs_cbmc)
|
||||
*gnvs_cbmc = (uintptr_t)cbmem_find(CBMEM_ID_CONSOLE);
|
||||
}
|
||||
|
||||
void *gnvs_get_or_create(void)
|
||||
{
|
||||
size_t gnvs_size;
|
||||
|
||||
if (gnvs)
|
||||
return gnvs;
|
||||
|
||||
gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
|
||||
if (gnvs)
|
||||
return gnvs;
|
||||
|
||||
gnvs_size = gnvs_size_of_array();
|
||||
|
||||
gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, gnvs_size);
|
||||
if (!gnvs)
|
||||
return gnvs;
|
||||
|
||||
memset(gnvs, 0, gnvs_size);
|
||||
|
||||
if (CONFIG(CONSOLE_CBMEM))
|
||||
gnvs_assign_cbmc();
|
||||
|
||||
if (CONFIG(CHROMEOS))
|
||||
gnvs_assign_chromeos();
|
||||
|
||||
return gnvs;
|
||||
}
|
||||
|
||||
void acpi_inject_nvsa(void)
|
||||
{
|
||||
uintptr_t gnvs_address = (uintptr_t)acpi_get_gnvs();
|
||||
if (!gnvs_address)
|
||||
return;
|
||||
|
||||
acpigen_write_scope("\\");
|
||||
acpigen_write_name_dword("NVSA", gnvs_address);
|
||||
acpigen_pop_len();
|
||||
}
|
@@ -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-"
|
||||
|
@@ -50,11 +50,11 @@ bootblock-y += stages.c
|
||||
|
||||
$(objcbfs)/bootblock.debug: $$(bootblock-objs)
|
||||
@printf " LINK $(subst $(obj)/,,$(@))\n"
|
||||
$(LD_bootblock) $(LDFLAGS_bootblock) -o $@ -L$(obj) -T $(call src-to-obj,bootblock,src/mainboard/$(MAINBOARDDIR)/memlayout.ld) --whole-archive --start-group $(filter-out %.ld,$(bootblock-objs)) --end-group
|
||||
$(LD_bootblock) $(LDFLAGS_bootblock) -o $@ -L$(obj) -T $(call src-to-obj,bootblock,$(CONFIG_MEMLAYOUT_LD_FILE)) --whole-archive --start-group $(filter-out %.ld,$(bootblock-objs)) --end-group
|
||||
|
||||
$(objcbfs)/decompressor.debug: $$(decompressor-objs)
|
||||
@printf " LINK $(subst $(obj)/,,$(@))\n"
|
||||
$(LD_bootblock) $(LDFLAGS_bootblock) -o $@ -L$(obj) -T $(call src-to-obj,decompressor,src/mainboard/$(MAINBOARDDIR)/memlayout.ld) --whole-archive --start-group $(filter-out %.ld,$(decompressor-objs)) --end-group
|
||||
$(LD_bootblock) $(LDFLAGS_bootblock) -o $@ -L$(obj) -T $(call src-to-obj,decompressor,$(CONFIG_MEMLAYOUT_LD_FILE)) --whole-archive --start-group $(filter-out %.ld,$(decompressor-objs)) --end-group
|
||||
|
||||
endif # CONFIG_ARCH_BOOTBLOCK_ARM
|
||||
|
||||
@@ -66,7 +66,7 @@ ifeq ($(CONFIG_ARCH_VERSTAGE_ARM),y)
|
||||
|
||||
$(objcbfs)/verstage.debug: $$(verstage-objs)
|
||||
@printf " LINK $(subst $(obj)/,,$(@))\n"
|
||||
$(LD_verstage) $(LDFLAGS_verstage) -o $@ -L$(obj) -T $(call src-to-obj,verstage,src/mainboard/$(MAINBOARDDIR)/memlayout.ld) --whole-archive --start-group $(filter-out %.ld,$(verstage-objs)) --end-group
|
||||
$(LD_verstage) $(LDFLAGS_verstage) -o $@ -L$(obj) -T $(call src-to-obj,verstage,$(CONFIG_MEMLAYOUT_LD_FILE)) --whole-archive --start-group $(filter-out %.ld,$(verstage-objs)) --end-group
|
||||
|
||||
verstage-y += boot.c
|
||||
verstage-y += div0.c
|
||||
@@ -99,7 +99,7 @@ rmodules_arm-y += eabi_compat.c
|
||||
|
||||
$(objcbfs)/romstage.debug: $$(romstage-objs)
|
||||
@printf " LINK $(subst $(obj)/,,$(@))\n"
|
||||
$(LD_romstage) $(LDFLAGS_romstage) -o $@ -L$(obj) -T $(call src-to-obj,romstage,src/mainboard/$(MAINBOARDDIR)/memlayout.ld) --whole-archive --start-group $(filter-out %.ld,$(romstage-objs)) --end-group
|
||||
$(LD_romstage) $(LDFLAGS_romstage) -o $@ -L$(obj) -T $(call src-to-obj,romstage,$(CONFIG_MEMLAYOUT_LD_FILE)) --whole-archive --start-group $(filter-out %.ld,$(romstage-objs)) --end-group
|
||||
|
||||
endif # CONFIG_ARCH_ROMSTAGE_ARM
|
||||
|
||||
@@ -128,6 +128,6 @@ ramstage-srcs += $(wildcard src/mainboard/$(MAINBOARDDIR)/mainboard.c)
|
||||
|
||||
$(objcbfs)/ramstage.debug: $$(ramstage-objs)
|
||||
@printf " CC $(subst $(obj)/,,$(@))\n"
|
||||
$(LD_ramstage) $(LDFLAGS_ramstage) -o $@ -L$(obj) -T $(call src-to-obj,ramstage,src/mainboard/$(MAINBOARDDIR)/memlayout.ld) --whole-archive --start-group $(filter-out %.ld,$(ramstage-objs)) --end-group
|
||||
$(LD_ramstage) $(LDFLAGS_ramstage) -o $@ -L$(obj) -T $(call src-to-obj,ramstage,$(CONFIG_MEMLAYOUT_LD_FILE)) --whole-archive --start-group $(filter-out %.ld,$(ramstage-objs)) --end-group
|
||||
|
||||
endif # CONFIG_ARCH_RAMSTAGE_ARM
|
||||
|
@@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <types.h>
|
||||
#include <arch/cache.h>
|
||||
#include <arch/exception.h>
|
||||
|
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
|
@@ -7,7 +7,6 @@
|
||||
#define ARM_CACHE_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Cache maintenance API
|
||||
|
@@ -2,7 +2,6 @@
|
||||
|
||||
#ifndef ARMV7_H
|
||||
#define ARMV7_H
|
||||
#include <types.h>
|
||||
|
||||
/* Cortex-A9 revisions */
|
||||
#define MIDR_CORTEX_A9_R0P1 0x410FC091
|
||||
|
@@ -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) */
|
||||
|
@@ -1,54 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef ARCH_SMP_SPINLOCK_H
|
||||
#define ARCH_SMP_SPINLOCK_H
|
||||
|
||||
/* FIXME: implement this for ARM */
|
||||
#error "implement this for ARM"
|
||||
#if 0
|
||||
/*
|
||||
* Your basic SMP spinlocks, allowing only a single CPU anywhere
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
volatile unsigned int lock;
|
||||
} spinlock_t;
|
||||
|
||||
|
||||
#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 }
|
||||
#define DECLARE_SPIN_LOCK(x) static spinlock_t x = SPIN_LOCK_UNLOCKED;
|
||||
|
||||
#define barrier() (__asm__ __volatile__("" : : : "memory"))
|
||||
#define spin_is_locked(x) (*(volatile char *)(&(x)->lock) != 0)
|
||||
#define spin_unlock_wait(x) do { barrier(); } while (spin_is_locked(x))
|
||||
|
||||
static __always_inline void spin_lock(spinlock_t *lock)
|
||||
{
|
||||
unsigned long tmp;
|
||||
__asm__ __volatile__ (
|
||||
"1: ldrex %0, [%1]\n"
|
||||
" teq %0, #0\n"
|
||||
" strexeq %0, %2, [%1]\n"
|
||||
" teqeq %0, #0\n"
|
||||
" bne 1b\n"
|
||||
: "=&r" (tmp)
|
||||
: "r" (&lock->lock), "r" (1)
|
||||
: "cc"
|
||||
);
|
||||
barrier();
|
||||
}
|
||||
|
||||
static __always_inline void spin_unlock(spinlock_t *lock)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
" str %1, [%0]\n"
|
||||
:
|
||||
: "r" (&lock->lock), "r" (0)
|
||||
: "cc"
|
||||
);
|
||||
}
|
||||
|
||||
#define cpu_relax() barrier()
|
||||
|
||||
#endif
|
||||
#endif /* ARCH_SMP_SPINLOCK_H */
|
@@ -45,11 +45,11 @@ bootblock-y += memmove.S
|
||||
|
||||
$(objcbfs)/bootblock.debug: $$(bootblock-objs) $(obj)/config.h
|
||||
@printf " LINK $(subst $(obj)/,,$(@))\n"
|
||||
$(LD_bootblock) $(LDFLAGS_bootblock) -o $@ -L$(obj) --whole-archive --start-group $(filter-out %.ld,$(bootblock-objs)) --end-group -T $(call src-to-obj,bootblock,src/mainboard/$(MAINBOARDDIR)/memlayout.ld)
|
||||
$(LD_bootblock) $(LDFLAGS_bootblock) -o $@ -L$(obj) --whole-archive --start-group $(filter-out %.ld,$(bootblock-objs)) --end-group -T $(call src-to-obj,bootblock,$(CONFIG_MEMLAYOUT_LD_FILE))
|
||||
|
||||
$(objcbfs)/decompressor.debug: $$(decompressor-objs) $(obj)/config.h
|
||||
@printf " LINK $(subst $(obj)/,,$(@))\n"
|
||||
$(LD_bootblock) $(LDFLAGS_bootblock) -o $@ -L$(obj) --whole-archive --start-group $(filter-out %.ld,$(decompressor-objs)) --end-group -T $(call src-to-obj,decompressor,src/mainboard/$(MAINBOARDDIR)/memlayout.ld)
|
||||
$(LD_bootblock) $(LDFLAGS_bootblock) -o $@ -L$(obj) --whole-archive --start-group $(filter-out %.ld,$(decompressor-objs)) --end-group -T $(call src-to-obj,decompressor,$(CONFIG_MEMLAYOUT_LD_FILE))
|
||||
|
||||
endif # CONFIG_ARCH_BOOTBLOCK_ARM64
|
||||
|
||||
@@ -61,7 +61,7 @@ ifeq ($(CONFIG_ARCH_VERSTAGE_ARM64),y)
|
||||
|
||||
$(objcbfs)/verstage.debug: $$(verstage-objs)
|
||||
@printf " LINK $(subst $(obj)/,,$(@))\n"
|
||||
$(LD_verstage) $(LDFLAGS_verstage) -o $@ -L$(obj) --whole-archive --start-group $(filter-out %.ld,$(verstage-objs)) --end-group -T $(call src-to-obj,verstage,src/mainboard/$(MAINBOARDDIR)/memlayout.ld)
|
||||
$(LD_verstage) $(LDFLAGS_verstage) -o $@ -L$(obj) --whole-archive --start-group $(filter-out %.ld,$(verstage-objs)) --end-group -T $(call src-to-obj,verstage,$(CONFIG_MEMLAYOUT_LD_FILE))
|
||||
|
||||
verstage-y += boot.c
|
||||
verstage-y += div0.c
|
||||
@@ -99,7 +99,7 @@ rmodules_arm64-y += eabi_compat.c
|
||||
|
||||
$(objcbfs)/romstage.debug: $$(romstage-objs)
|
||||
@printf " LINK $(subst $(obj)/,,$(@))\n"
|
||||
$(LD_romstage) $(LDFLAGS_romstage) -o $@ -L$(obj) --whole-archive --start-group $(filter-out %.ld,$(romstage-objs)) --end-group -T $(call src-to-obj,romstage,src/mainboard/$(MAINBOARDDIR)/memlayout.ld)
|
||||
$(LD_romstage) $(LDFLAGS_romstage) -o $@ -L$(obj) --whole-archive --start-group $(filter-out %.ld,$(romstage-objs)) --end-group -T $(call src-to-obj,romstage,$(CONFIG_MEMLAYOUT_LD_FILE))
|
||||
|
||||
endif # CONFIG_ARCH_ROMSTAGE_ARM64
|
||||
|
||||
@@ -134,7 +134,7 @@ ramstage-srcs += $(wildcard src/mainboard/$(MAINBOARDDIR)/mainboard.c)
|
||||
|
||||
$(objcbfs)/ramstage.debug: $$(ramstage-objs)
|
||||
@printf " CC $(subst $(obj)/,,$(@))\n"
|
||||
$(LD_ramstage) $(LDFLAGS_ramstage) -o $@ -L$(obj) --whole-archive --start-group $(filter-out %.ld,$(ramstage-objs)) --end-group -T $(call src-to-obj,ramstage,src/mainboard/$(MAINBOARDDIR)/memlayout.ld)
|
||||
$(LD_ramstage) $(LDFLAGS_ramstage) -o $@ -L$(obj) --whole-archive --start-group $(filter-out %.ld,$(ramstage-objs)) --end-group -T $(call src-to-obj,ramstage,$(CONFIG_MEMLAYOUT_LD_FILE))
|
||||
|
||||
# Build ARM Trusted Firmware (BL31)
|
||||
|
||||
|
@@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <types.h>
|
||||
#include <arch/barrier.h>
|
||||
#include <arch/exception.h>
|
||||
|
@@ -11,7 +11,6 @@
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <arch/barrier.h>
|
||||
|
||||
/* dcache clean by virtual address to PoC */
|
||||
|
@@ -24,7 +24,7 @@ bootblock-generic-ccopts += $(ppc64_flags)
|
||||
$(objcbfs)/bootblock.debug: $$(bootblock-objs)
|
||||
@printf " LINK $(subst $(obj)/,,$(@))\n"
|
||||
$(LD_bootblock) $(LDFLAGS_bootblock) -o $@ -L$(obj) \
|
||||
-T $(call src-to-obj,bootblock,src/mainboard/$(MAINBOARDDIR)/memlayout.ld) --whole-archive --start-group $(filter-out %.ld,$(bootblock-objs)) \
|
||||
-T $(call src-to-obj,bootblock,$(CONFIG_MEMLAYOUT_LD_FILE)) --whole-archive --start-group $(filter-out %.ld,$(bootblock-objs)) \
|
||||
$(LIBGCC_FILE_NAME_bootblock) --end-group $(COMPILER_RT_bootblock)
|
||||
|
||||
endif
|
||||
@@ -50,7 +50,7 @@ romstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
|
||||
|
||||
$(objcbfs)/romstage.debug: $$(romstage-objs)
|
||||
@printf " LINK $(subst $(obj)/,,$(@))\n"
|
||||
$(LD_romstage) $(LDFLAGS_romstage) -o $@ -L$(obj) -T $(call src-to-obj,romstage,src/mainboard/$(MAINBOARDDIR)/memlayout.ld) --whole-archive --start-group $(filter-out %.ld,$(romstage-objs)) --end-group $(COMPILER_RT_romstage)
|
||||
$(LD_romstage) $(LDFLAGS_romstage) -o $@ -L$(obj) -T $(call src-to-obj,romstage,$(CONFIG_MEMLAYOUT_LD_FILE)) --whole-archive --start-group $(filter-out %.ld,$(romstage-objs)) --end-group $(COMPILER_RT_romstage)
|
||||
|
||||
romstage-c-ccopts += $(ppc64_flags)
|
||||
romstage-S-ccopts += $(ppc64_asm_flags)
|
||||
@@ -83,7 +83,7 @@ ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/mainboard.c
|
||||
|
||||
$(objcbfs)/ramstage.debug: $$(ramstage-objs)
|
||||
@printf " CC $(subst $(obj)/,,$(@))\n"
|
||||
$(LD_ramstage) $(LDFLAGS_ramstage) -o $@ -L$(obj) -T $(call src-to-obj,ramstage,src/mainboard/$(MAINBOARDDIR)/memlayout.ld) --whole-archive --start-group $(filter-out %.ld,$(ramstage-objs)) --end-group $(COMPILER_RT_ramstage)
|
||||
$(LD_ramstage) $(LDFLAGS_ramstage) -o $@ -L$(obj) -T $(call src-to-obj,ramstage,$(CONFIG_MEMLAYOUT_LD_FILE)) --whole-archive --start-group $(filter-out %.ld,$(ramstage-objs)) --end-group $(COMPILER_RT_ramstage)
|
||||
|
||||
ramstage-c-ccopts += $(ppc64_flags)
|
||||
ramstage-S-ccopts += $(ppc64_asm_flags)
|
||||
|
@@ -64,7 +64,7 @@ bootblock-$(CONFIG_RISCV_USE_ARCH_TIMER) += arch_timer.c
|
||||
$(objcbfs)/bootblock.debug: $$(bootblock-objs)
|
||||
@printf " LINK $(subst $(obj)/,,$(@))\n"
|
||||
$(LD_bootblock) $(LDFLAGS_bootblock) -o $@ -L$(obj) \
|
||||
-T $(call src-to-obj,bootblock,src/mainboard/$(MAINBOARDDIR)/memlayout.ld) --whole-archive --start-group $(filter-out %.ld,$(bootblock-objs)) \
|
||||
-T $(call src-to-obj,bootblock,$(CONFIG_MEMLAYOUT_LD_FILE)) --whole-archive --start-group $(filter-out %.ld,$(bootblock-objs)) \
|
||||
$(LIBGCC_FILE_NAME_bootblock) --end-group $(COMPILER_RT_bootblock)
|
||||
|
||||
bootblock-c-ccopts += $(riscv_flags)
|
||||
@@ -99,7 +99,7 @@ romstage-$(CONFIG_RISCV_USE_ARCH_TIMER) += arch_timer.c
|
||||
|
||||
$(objcbfs)/romstage.debug: $$(romstage-objs)
|
||||
@printf " LINK $(subst $(obj)/,,$(@))\n"
|
||||
$(LD_romstage) $(LDFLAGS_romstage) -o $@ -L$(obj) -T $(call src-to-obj,romstage,src/mainboard/$(MAINBOARDDIR)/memlayout.ld) --whole-archive --start-group $(filter-out %.ld,$(romstage-objs)) --end-group $(COMPILER_RT_romstage)
|
||||
$(LD_romstage) $(LDFLAGS_romstage) -o $@ -L$(obj) -T $(call src-to-obj,romstage,$(CONFIG_MEMLAYOUT_LD_FILE)) --whole-archive --start-group $(filter-out %.ld,$(romstage-objs)) --end-group $(COMPILER_RT_romstage)
|
||||
|
||||
romstage-c-ccopts += $(riscv_flags)
|
||||
romstage-S-ccopts += $(riscv_asm_flags)
|
||||
@@ -148,7 +148,7 @@ ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/mainboard.c
|
||||
|
||||
$(objcbfs)/ramstage.debug: $$(ramstage-objs)
|
||||
@printf " CC $(subst $(obj)/,,$(@))\n"
|
||||
$(LD_ramstage) $(LDFLAGS_ramstage) -o $@ -L$(obj) -T $(call src-to-obj,ramstage,src/mainboard/$(MAINBOARDDIR)/memlayout.ld) --whole-archive --start-group $(filter-out %.ld,$(ramstage-objs)) --end-group $(COMPILER_RT_ramstage)
|
||||
$(LD_ramstage) $(LDFLAGS_ramstage) -o $@ -L$(obj) -T $(call src-to-obj,ramstage,$(CONFIG_MEMLAYOUT_LD_FILE)) --whole-archive --start-group $(filter-out %.ld,$(ramstage-objs)) --end-group $(COMPILER_RT_ramstage)
|
||||
|
||||
ramstage-c-ccopts += $(riscv_flags)
|
||||
ramstage-S-ccopts += $(riscv_asm_flags)
|
||||
|
@@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <cbfs.h>
|
||||
#include <commonlib/bsd/compression.h>
|
||||
#include <console/console.h>
|
||||
#include <bootmem.h>
|
||||
|
@@ -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
|
||||
@@ -162,7 +156,7 @@ config HAVE_CMOS_DEFAULT
|
||||
|
||||
config CMOS_DEFAULT_FILE
|
||||
string
|
||||
default "src/mainboard/$(MAINBOARDDIR)/cmos.default"
|
||||
default "src/mainboard/\$(MAINBOARDDIR)/cmos.default"
|
||||
depends on HAVE_CMOS_DEFAULT
|
||||
|
||||
config IOAPIC_INTERRUPTS_ON_FSB
|
||||
@@ -316,4 +310,8 @@ config MAX_ACPI_TABLE_SIZE_KB
|
||||
help
|
||||
Set the maximum size of all ACPI tables in KiB.
|
||||
|
||||
config MEMLAYOUT_LD_FILE
|
||||
string
|
||||
default "src/arch/x86/memlayout.ld"
|
||||
|
||||
endif
|
||||
|
@@ -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)' > $@
|
||||
|
||||
@@ -67,14 +67,13 @@ endef
|
||||
define early_x86_stage
|
||||
# $1 stage name
|
||||
# $2 oformat
|
||||
$(1)-y += memlayout.ld
|
||||
|
||||
# The '.' include path is needed for the generated assembly.inc file.
|
||||
$(1)-S-ccopts += -I.
|
||||
|
||||
$$(objcbfs)/$(1).debug: $$$$($(1)-libs) $$$$($(1)-objs)
|
||||
@printf " LINK $$(subst $$(obj)/,,$$(@))\n"
|
||||
$$(LD_$(1)) $$(LDFLAGS_$(1)) -o $$@ -L$$(obj) $$(COMPILER_RT_FLAGS_$(1)) --whole-archive --start-group $$(filter-out %.ld,$$($(1)-objs)) $$($(1)-libs) --no-whole-archive $$(COMPILER_RT_$(1)) --end-group -T $(call src-to-obj,$(1),$(dir)/memlayout.ld) --oformat $(2)
|
||||
$$(LD_$(1)) $$(LDFLAGS_$(1)) -o $$@ -L$$(obj) $$(COMPILER_RT_FLAGS_$(1)) --whole-archive --start-group $$(filter-out %.ld,$$($(1)-objs)) $$($(1)-libs) --no-whole-archive $$(COMPILER_RT_$(1)) --end-group -T $(call src-to-obj,$(1),$(CONFIG_MEMLAYOUT_LD_FILE)) --oformat $(2)
|
||||
-LANG=C LC_ALL= $$(OBJCOPY_$(1)) --only-section .illegal_globals $$(@) $$(objcbfs)/$(1)_null.offenders >/dev/null 2>&1
|
||||
if [ -z "$$$$($$(NM_$(1)) $$(objcbfs)/$(1)_null.offenders 2>&1 | grep 'no symbols')" ];then \
|
||||
echo "Forbidden global variables in $(1):"; \
|
||||
@@ -82,33 +81,26 @@ $$(objcbfs)/$(1).debug: $$$$($(1)-libs) $$$$($(1)-objs)
|
||||
fi
|
||||
endef
|
||||
|
||||
###############################################################################
|
||||
# all (bootblock,verstage,romstage,postcar,ramstage)
|
||||
###############################################################################
|
||||
|
||||
ifeq ($(CONFIG_ARCH_X86),y)
|
||||
|
||||
all-$(CONFIG_HAVE_CF9_RESET) += cf9_reset.c
|
||||
all-y += boot.c
|
||||
all-y += memcpy.c
|
||||
all-y += memset.c
|
||||
all-y += cpu_common.c
|
||||
all-y += post.c
|
||||
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
# bootblock
|
||||
###############################################################################
|
||||
|
||||
ifeq ($(CONFIG_ARCH_BOOTBLOCK_X86_32)$(CONFIG_ARCH_BOOTBLOCK_X86_64),y)
|
||||
|
||||
bootblock-y += boot.c
|
||||
bootblock-y += post.c
|
||||
bootblock-y += cpu_common.c
|
||||
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
|
||||
bootblock-y += id.S
|
||||
bootblock-$(CONFIG_HAVE_CF9_RESET) += cf9_reset.c
|
||||
|
||||
$(call src-to-obj,bootblock,$(dir)/id.S): $(obj)/build.h
|
||||
|
||||
bootblock-y += bootblock_crt0.S
|
||||
@@ -129,10 +121,16 @@ endif # CONFIG_ARCH_BOOTBLOCK_X86_32 / CONFIG_ARCH_BOOTBLOCK_X86_64
|
||||
|
||||
ifeq ($(CONFIG_ARCH_VERSTAGE_X86_32)$(CONFIG_ARCH_VERSTAGE_X86_64),y)
|
||||
|
||||
verstage-y += boot.c
|
||||
verstage-y += post.c
|
||||
verstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += gdt_init.S
|
||||
verstage-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c
|
||||
verstage-$(CONFIG_IDT_IN_EVERY_STAGE) += idt.S
|
||||
verstage-$(CONFIG_HAVE_CF9_RESET) += cf9_reset.c
|
||||
|
||||
verstage-y += cpu_common.c
|
||||
verstage-y += memset.c
|
||||
verstage-y += memcpy.c
|
||||
verstage-y += memmove.c
|
||||
verstage-$(CONFIG_X86_TOP4G_BOOTMEDIA_MAP) += mmap_boot.c
|
||||
# If verstage is a separate stage it means there's no need
|
||||
@@ -161,16 +159,21 @@ endif # CONFIG_ARCH_VERSTAGE_X86_32 / CONFIG_ARCH_VERSTAGE_X86_64
|
||||
ifeq ($(CONFIG_ARCH_ROMSTAGE_X86_32)$(CONFIG_ARCH_ROMSTAGE_X86_64),y)
|
||||
|
||||
romstage-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.c
|
||||
romstage-y += boot.c
|
||||
romstage-y += post.c
|
||||
# gdt_init.S is included by entry32.inc when romstage is the first C
|
||||
# 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
|
||||
romstage-y += memcpy.c
|
||||
romstage-y += memmove.c
|
||||
romstage-y += memset.c
|
||||
romstage-$(CONFIG_X86_TOP4G_BOOTMEDIA_MAP) += mmap_boot.c
|
||||
romstage-y += postcar_loader.c
|
||||
romstage-$(CONFIG_COLLECT_TIMESTAMPS_TSC) += timestamp.c
|
||||
romstage-$(CONFIG_HAVE_CF9_RESET) += cf9_reset.c
|
||||
|
||||
romstage-srcs += $(wildcard $(src)/mainboard/$(MAINBOARDDIR)/romstage.c)
|
||||
romstage-libs ?=
|
||||
@@ -196,21 +199,26 @@ $(eval $(call create_class_compiler,postcar,x86_32))
|
||||
postcar-generic-ccopts += -D__POSTCAR__
|
||||
|
||||
postcar-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.c
|
||||
postcar-y += boot.c
|
||||
postcar-y += post.c
|
||||
postcar-y += gdt_init.S
|
||||
postcar-y += cpu_common.c
|
||||
postcar-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c
|
||||
postcar-$(CONFIG_IDT_IN_EVERY_STAGE) += idt.S
|
||||
postcar-y += exit_car.S
|
||||
postcar-y += memcpy.c
|
||||
postcar-y += memmove.c
|
||||
postcar-y += memlayout.ld
|
||||
postcar-y += memset.c
|
||||
postcar-$(CONFIG_X86_TOP4G_BOOTMEDIA_MAP) += mmap_boot.c
|
||||
postcar-y += postcar.c
|
||||
postcar-$(CONFIG_COLLECT_TIMESTAMPS_TSC) += timestamp.c
|
||||
postcar-$(CONFIG_HAVE_CF9_RESET) += cf9_reset.c
|
||||
|
||||
LDFLAGS_postcar += -Map $(objcbfs)/postcar.map
|
||||
|
||||
$(objcbfs)/postcar.debug: $$(postcar-objs)
|
||||
@printf " LINK $(subst $(obj)/,,$(@))\n"
|
||||
$(LD_postcar) $(LDFLAGS_postcar) -o $@ -L$(obj) $(COMPILER_RT_FLAGS_postcar) --whole-archive --start-group $(filter-out %.ld,$^) --no-whole-archive $(COMPILER_RT_postcar) --end-group -T $(call src-to-obj,postcar,src/arch/x86/memlayout.ld)
|
||||
$(LD_postcar) $(LDFLAGS_postcar) -o $@ -L$(obj) $(COMPILER_RT_FLAGS_postcar) --whole-archive --start-group $(filter-out %.ld,$^) --no-whole-archive $(COMPILER_RT_postcar) --end-group -T $(call src-to-obj,postcar,$(CONFIG_MEMLAYOUT_LD_FILE))
|
||||
|
||||
$(objcbfs)/postcar.elf: $(objcbfs)/postcar.debug.rmod
|
||||
cp $< $@
|
||||
@@ -227,17 +235,21 @@ $(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
|
||||
ramstage-y += post.c
|
||||
ramstage-y += c_start.S
|
||||
ramstage-y += cpu.c
|
||||
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 += memlayout.ld
|
||||
ramstage-y += memcpy.c
|
||||
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_GENERATE_PIRQ_TABLE) += pirq_routing.c
|
||||
@@ -248,22 +260,23 @@ ramstage-$(CONFIG_COOP_MULTITASKING) += thread.c
|
||||
ramstage-$(CONFIG_COOP_MULTITASKING) += thread_switch.S
|
||||
ramstage-$(CONFIG_COLLECT_TIMESTAMPS_TSC) += timestamp.c
|
||||
ramstage-$(CONFIG_HAVE_ACPI_RESUME) += wakeup.S
|
||||
ramstage-$(CONFIG_HAVE_CF9_RESET) += cf9_reset.c
|
||||
|
||||
ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32),y)
|
||||
rmodules_x86_32-y += memcpy.c
|
||||
rmodules_x86_32-y += memmove.c
|
||||
rmodules_x86_32-y += memset.c
|
||||
else
|
||||
|
||||
rmodules_x86_64-y += memcpy.c
|
||||
rmodules_x86_64-y += memmove.c
|
||||
rmodules_x86_64-y += memset.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32),y)
|
||||
target-objcopy=-O elf32-i386 -B i386
|
||||
LD_MACHINE =-m elf_i386
|
||||
endif
|
||||
ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_64),y)
|
||||
target-objcopy=-O elf64-x86-64 -B i386:x86-64
|
||||
LD_MACHINE =-m elf_x86_64
|
||||
endif
|
||||
|
||||
ramstage-srcs += $(wildcard src/mainboard/$(MAINBOARDDIR)/mainboard.c)
|
||||
@@ -275,31 +288,20 @@ 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,src/arch/x86/memlayout.ld)
|
||||
$(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,src/arch/x86/memlayout.ld)
|
||||
$(LD_ramstage) $(CPPFLAGS) $(LDFLAGS_ramstage) -o $@ -L$(obj) $< -T $(call src-to-obj,ramstage,$(CONFIG_MEMLAYOUT_LD_FILE))
|
||||
|
||||
$(objgenerated)/ramstage.o: $$(ramstage-objs) $(COMPILER_RT_ramstage) $$(ramstage-libs)
|
||||
@printf " CC $(subst $(obj)/,,$(@))\n"
|
||||
ifeq ($(CONFIG_ARCH_RAMSTAGE_X86_32),y)
|
||||
$(LD_ramstage) -m elf_i386 -r -o $@ $(COMPILER_RT_FLAGS_ramstage) --whole-archive --start-group $(filter-out %.ld,$(ramstage-objs)) $(ramstage-libs) --no-whole-archive $(COMPILER_RT_ramstage) --end-group
|
||||
else
|
||||
$(LD_ramstage) -m elf_x86_64 -r -o $@ $(COMPILER_RT_FLAGS_ramstage) --whole-archive --start-group $(filter-out %.ld,$(ramstage-objs)) $(ramstage-libs) --no-whole-archive $(COMPILER_RT_ramstage) --end-group
|
||||
endif
|
||||
$(LD_ramstage) $(LD_MACHINE) -r -o $@ $(COMPILER_RT_FLAGS_ramstage) --whole-archive --start-group $(filter-out %.ld,$(ramstage-objs)) $(ramstage-libs) --no-whole-archive $(COMPILER_RT_ramstage) --end-group
|
||||
|
||||
endif # CONFIG_ARCH_RAMSTAGE_X86_32 / CONFIG_ARCH_RAMSTAGE_X86_64
|
||||
|
||||
|
20
src/arch/x86/acpi.c
Normal file
20
src/arch/x86/acpi.c
Normal file
@@ -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;
|
||||
}
|
||||
}
|
@@ -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
|
||||
|
@@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <bootstate.h>
|
||||
#include <cbmem.h>
|
||||
#include <console/console.h>
|
||||
#include <cpu/x86/name.h>
|
||||
|
@@ -4,14 +4,11 @@
|
||||
#include <string.h>
|
||||
#include <acpi/acpi.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <cbmem.h>
|
||||
#include <commonlib/helpers.h>
|
||||
#include <cpu/x86/smm.h>
|
||||
#include <fallback.h>
|
||||
#include <timestamp.h>
|
||||
#include <program_loading.h>
|
||||
#include <romstage_handoff.h>
|
||||
#include <symbols.h>
|
||||
#include <cpu/x86/smm.h>
|
||||
|
||||
#if ENV_RAMSTAGE || ENV_POSTCAR
|
||||
|
||||
@@ -81,16 +78,8 @@ void __weak mainboard_suspend_resume(void)
|
||||
|
||||
void acpi_resume(void *wake_vec)
|
||||
{
|
||||
if (CONFIG(HAVE_SMI_HANDLER)) {
|
||||
void *gnvs_address = cbmem_find(CBMEM_ID_ACPI_GNVS);
|
||||
|
||||
/* Restore GNVS pointer in SMM if found */
|
||||
if (gnvs_address) {
|
||||
printk(BIOS_DEBUG, "Restore GNVS pointer to %p\n",
|
||||
gnvs_address);
|
||||
smm_setup_structures(gnvs_address, NULL, NULL);
|
||||
}
|
||||
}
|
||||
/* Restore GNVS pointer in SMM if found. */
|
||||
apm_control(APM_CNT_GNVS_UPDATE);
|
||||
|
||||
/* Call mainboard resume handler first, if defined. */
|
||||
mainboard_suspend_resume();
|
||||
|
@@ -1,5 +1,8 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
/* CACHE_ROM_SIZE defined here. */
|
||||
#include <cpu/x86/mtrr.h>
|
||||
|
||||
/* This file is included inside a SECTIONS block */
|
||||
. = CONFIG_DCACHE_RAM_BASE;
|
||||
.car.data . (NOLOAD) : {
|
||||
@@ -73,6 +76,27 @@
|
||||
|
||||
_car_region_end = . + CONFIG_DCACHE_RAM_SIZE - (. - _car_region_start);
|
||||
}
|
||||
. = _car_region_end;
|
||||
.car.mrc_var . (NOLOAD) : {
|
||||
. += CONFIG_DCACHE_RAM_MRC_VAR_SIZE;
|
||||
}
|
||||
|
||||
#if ENV_BOOTBLOCK
|
||||
_car_mtrr_end = .;
|
||||
_car_mtrr_start = _car_region_start;
|
||||
|
||||
_car_mtrr_size = _car_mtrr_end - _car_mtrr_start;
|
||||
_car_mtrr_sz_log2 = 1 << LOG2CEIL(_car_mtrr_size);
|
||||
_car_mtrr_mask = ~(MAX(4096, _car_mtrr_sz_log2) - 1);
|
||||
|
||||
#if !CONFIG(NO_XIP_EARLY_STAGES)
|
||||
_xip_program_sz_log2 = 1 << LOG2CEIL(_ebootblock - _bootblock);
|
||||
_xip_mtrr_mask = ~(MAX(4096, _xip_program_sz_log2) - 1);
|
||||
#endif
|
||||
|
||||
_rom_mtrr_mask = ~(CACHE_ROM_SIZE - 1);
|
||||
_rom_mtrr_base = _rom_mtrr_mask;
|
||||
#endif
|
||||
|
||||
/* Global variables are not allowed in romstage
|
||||
* This section is checked during stage creation to ensure
|
||||
|
@@ -1,13 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <cbmem.h>
|
||||
|
||||
#if CONFIG(CBMEM_TOP_BACKUP)
|
||||
|
||||
void *cbmem_top_chipset(void)
|
||||
{
|
||||
/* Top of CBMEM is at highest usable DRAM address below 4GiB. */
|
||||
return (void *)restore_top_of_low_cacheable();
|
||||
}
|
||||
|
||||
#endif /* CBMEM_TOP_BACKUP */
|
@@ -1,47 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
/* This file is included inside a SECTIONS block */
|
||||
|
||||
_STACK_SIZE = CONFIG_EARLYRAM_BSP_STACK_SIZE;
|
||||
_ = ASSERT(_STACK_SIZE > 0x0, "EARLYRAM_BSP_STACK_SIZE is not configured");
|
||||
|
||||
_CONSOLE_SIZE = CONFIG_PRERAM_CBMEM_CONSOLE_SIZE;
|
||||
_ = ASSERT(_CONSOLE_SIZE > 0x0, "PRERAM_CBMEM_CONSOLE_SIZE is not configured");
|
||||
|
||||
_TIMESTAMPS_SIZE = 0x200;
|
||||
#if !CONFIG(NO_FMAP_CACHE)
|
||||
_FMAP_SIZE = FMAP_SIZE;
|
||||
#else
|
||||
_FMAP_SIZE = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The PRERAM_CBMEM_CONSOLE, TIMESTAMP, and FMAP_CACHE regions are shared
|
||||
* between the pre-ram stages (bootblock, romstage, etc). We need to assign a
|
||||
* fixed size and consistent link address so they can be shared between stages.
|
||||
*
|
||||
* The stack area is not shared between stages, but is defined here for
|
||||
* convenience.
|
||||
*/
|
||||
. = CONFIG_X86_RESET_VECTOR - ARCH_STACK_ALIGN_SIZE - _STACK_SIZE - _CONSOLE_SIZE - _TIMESTAMPS_SIZE - _FMAP_SIZE - VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE;
|
||||
|
||||
_ = ASSERT(. > _eprogram, "Not enough room for .earlyram.data. Try increasing C_ENV_BOOTBLOCK_SIZE, or decreasing either EARLYRAM_BSP_STACK_SIZE or PRERAM_CBMEM_CONSOLE_SIZE.");
|
||||
|
||||
.stack ALIGN(ARCH_STACK_ALIGN_SIZE) (NOLOAD) : {
|
||||
EARLYRAM_STACK(., _STACK_SIZE)
|
||||
}
|
||||
|
||||
.persistent ALIGN(ARCH_POINTER_ALIGN_SIZE) (NOLOAD) : {
|
||||
PRERAM_CBMEM_CONSOLE(., _CONSOLE_SIZE)
|
||||
TIMESTAMP(., _TIMESTAMPS_SIZE)
|
||||
#if !CONFIG(NO_FMAP_CACHE)
|
||||
FMAP_CACHE(., FMAP_SIZE)
|
||||
#endif
|
||||
|
||||
#if CONFIG(VBOOT_STARTS_IN_BOOTBLOCK)
|
||||
ALIGN_COUNTER(16);
|
||||
VBOOT2_WORK(., VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE)
|
||||
#endif
|
||||
}
|
||||
|
||||
_ = ASSERT(. <= CONFIG_X86_RESET_VECTOR, "Earlyram data regions don't fit below the reset vector!");
|
@@ -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"
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
@@ -1,52 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <types.h>
|
||||
#include <string.h>
|
||||
#include <cbmem.h>
|
||||
#include <commonlib/helpers.h>
|
||||
#include <console/console.h>
|
||||
#include <cpu/x86/gdt.h>
|
||||
|
||||
/* i386 lgdt argument */
|
||||
struct gdtarg {
|
||||
u16 limit;
|
||||
#ifdef __x86_64__
|
||||
u64 base;
|
||||
#else
|
||||
u32 base;
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Copy GDT to new location and reload it.
|
||||
* FIXME: We only do this for BSP CPU.
|
||||
*/
|
||||
static void move_gdt(int is_recovery)
|
||||
{
|
||||
void *newgdt;
|
||||
u16 num_gdt_bytes;
|
||||
struct gdtarg gdtarg;
|
||||
|
||||
/* ramstage is already in high memory. No need to use a new gdt. */
|
||||
if (CONFIG(RELOCATABLE_RAMSTAGE))
|
||||
return;
|
||||
|
||||
newgdt = cbmem_find(CBMEM_ID_GDT);
|
||||
num_gdt_bytes = (uintptr_t)&gdt_end - (uintptr_t)&gdt;
|
||||
if (!newgdt) {
|
||||
newgdt = cbmem_add(CBMEM_ID_GDT, ALIGN_UP(num_gdt_bytes, 512));
|
||||
if (!newgdt) {
|
||||
printk(BIOS_ERR, "Error: Could not relocate GDT.\n");
|
||||
return;
|
||||
}
|
||||
memcpy((void *)newgdt, &gdt, num_gdt_bytes);
|
||||
}
|
||||
printk(BIOS_DEBUG, "Moving GDT to %p...", newgdt);
|
||||
|
||||
gdtarg.base = (uintptr_t)newgdt;
|
||||
gdtarg.limit = num_gdt_bytes - 1;
|
||||
|
||||
__asm__ __volatile__ ("lgdt %0\n\t" : : "m" (gdtarg));
|
||||
printk(BIOS_DEBUG, "ok\n");
|
||||
}
|
||||
RAMSTAGE_CBMEM_INIT_HOOK(move_gdt)
|
@@ -109,6 +109,68 @@ vec19:
|
||||
|
||||
.global int_hand
|
||||
int_hand:
|
||||
#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
|
||||
|
||||
push %rbx
|
||||
push %rdx
|
||||
push %rcx
|
||||
push %rax
|
||||
|
||||
/* 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
|
||||
|
||||
/* Restore stack pointer from backup */
|
||||
mov %rbp, %rsp
|
||||
|
||||
pop %rax
|
||||
pop %rcx
|
||||
pop %rdx
|
||||
pop %rbx
|
||||
|
||||
pop %rbp
|
||||
pop %rsi
|
||||
pop %rdi
|
||||
|
||||
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
|
||||
@@ -116,33 +178,6 @@ int_hand:
|
||||
* 12(%esp) cs
|
||||
* 16(%esp) eflags
|
||||
*/
|
||||
#ifdef __x86_64__
|
||||
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 */
|
||||
call x86_exception
|
||||
pop %rax /* Drop the pointer */
|
||||
|
||||
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 */
|
||||
#else
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %ebp
|
||||
|
@@ -3,7 +3,6 @@
|
||||
#ifndef __ARCH_EBDA_H
|
||||
#define __ARCH_EBDA_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define X86_BDA_SIZE 0x200
|
||||
|
@@ -6,7 +6,7 @@
|
||||
#if !defined(__ASSEMBLER__)
|
||||
#include <stdint.h>
|
||||
|
||||
#define DOWNTO8(A) \
|
||||
#define LONG_DOWNTO8(A) \
|
||||
union { \
|
||||
struct { \
|
||||
union { \
|
||||
@@ -21,7 +21,7 @@
|
||||
uint32_t e##A##x; \
|
||||
} __packed;
|
||||
|
||||
#define DOWNTO16(A) \
|
||||
#define LONG_DOWNTO16(A) \
|
||||
union { \
|
||||
struct { \
|
||||
uint16_t A; \
|
||||
@@ -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)
|
||||
|
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <cpu/x86/mtrr.h>
|
||||
|
||||
void mainboard_romstage_entry(void);
|
||||
|
||||
@@ -16,10 +17,8 @@ void mainboard_romstage_entry(void);
|
||||
|
||||
struct postcar_frame {
|
||||
uintptr_t stack;
|
||||
uint32_t upper_mask;
|
||||
int max_var_mtrrs;
|
||||
int num_var_mtrrs;
|
||||
int skip_common_mtrr;
|
||||
struct var_mtrr_context ctx;
|
||||
};
|
||||
|
||||
/*
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user