Merge remote-tracking branch 'upstream/master' into system76

Change-Id: Idceb013b3495324b8d84a388ea5ee5b5ea4b69db
This commit is contained in:
Jeremy Soller
2020-07-20 11:54:36 -06:00
2885 changed files with 281440 additions and 31007 deletions

5
.gitmodules vendored
View File

@@ -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/blobs vendored

1
3rdparty/qc_blobs vendored Submodule

Submodule 3rdparty/qc_blobs added at 126fef6b99

2
3rdparty/vboot vendored

View File

@@ -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>

View File

@@ -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>

View File

@@ -2,7 +2,7 @@
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXOPTS ?=
SPHINXBUILD = sphinx-build
SPHINXAUTOBUILD = sphinx-autobuild
PAPER =

View File

@@ -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

View File

@@ -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', {

View 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

View File

@@ -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

View 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;
}
```

View File

@@ -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)

View File

@@ -15,7 +15,7 @@ from [Gigabyte].
+---------------------+------------+
| Size | 4 MiB |
+---------------------+------------+
| In circuit flashing | Yes |
| In circuit flashing | No |
+---------------------+------------+
| Package | SOIC-8 |
+---------------------+------------+

View File

@@ -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 |
+---------------------+------------+
```

View File

@@ -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)

View File

@@ -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

View File

@@ -0,0 +1,19 @@
# ThinkPad Lenovo X230s
## Disassembly Instructions
You must remove the following parts to access the SPI flash chip:
![x230s_bc_removed](x230s_bc_removed.jpg)
* Base cover
The [Hardware Maintenance Manual](https://download.lenovo.com/ibmdl/pub/pc/pccbbs/
mobiles_pdf/x230s_hmm_en_0c10860_01.pdf) could be used as a guidance of disassembly.
The SPI flash chip (W25Q128.V in the form of SOIC-8 for the author's X230s, but varying is possible)
is located at the circled place.
Unlike [most Ivy Bridge ThinkPads](Ivy_Bridge_series.md), X230s has a single 16MiB SPI flash chip.
The general [flashing tutorial](../../flash_tutorial/index.md) has more details.

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View 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

View 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

View 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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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)

View 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

View File

@@ -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`).

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View 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"

View File

@@ -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=

View File

@@ -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); \

View File

@@ -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

View File

@@ -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

View File

@@ -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..."

View File

@@ -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

View File

@@ -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();
}

View File

@@ -28,7 +28,7 @@
*/
OUTPUT_FORMAT("elf64-littleaarch64","elf64-littleaarch64", "elf64-littleaarch64")
OUTPUT_ARCH(arm64)
OUTPUT_ARCH(aarch64)
ENTRY(_entry)

View File

@@ -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.

View File

@@ -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();

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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))

View 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));
}

View File

@@ -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,

View File

@@ -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__ */

View File

@@ -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

View 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 };
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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
View 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
View 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;
}

View File

@@ -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
View 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();
}

View File

@@ -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-"

View File

@@ -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

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#include <stdint.h>
#include <types.h>
#include <arch/cache.h>
#include <arch/exception.h>

View File

@@ -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();

View File

@@ -7,7 +7,6 @@
#define ARM_CACHE_H
#include <stddef.h>
#include <stdint.h>
/*
* Cache maintenance API

View File

@@ -2,7 +2,6 @@
#ifndef ARMV7_H
#define ARMV7_H
#include <types.h>
/* Cortex-A9 revisions */
#define MIDR_CORTEX_A9_R0P1 0x410FC091

View File

@@ -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) */

View File

@@ -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 */

View File

@@ -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)

View File

@@ -1,6 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause */
#include <stdint.h>
#include <types.h>
#include <arch/barrier.h>
#include <arch/exception.h>

View File

@@ -11,7 +11,6 @@
#ifndef __ASSEMBLER__
#include <stddef.h>
#include <stdint.h>
#include <arch/barrier.h>
/* dcache clean by virtual address to PoC */

View File

@@ -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)

View File

@@ -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)

View File

@@ -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>

View File

@@ -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

View File

@@ -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
View 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;
}
}

View File

@@ -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

View File

@@ -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>

View File

@@ -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();

View File

@@ -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

View File

@@ -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 */

View File

@@ -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!");

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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

View File

@@ -3,7 +3,6 @@
#ifndef __ARCH_EBDA_H
#define __ARCH_EBDA_H
#include <stdint.h>
#include <stddef.h>
#define X86_BDA_SIZE 0x200

View File

@@ -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)

View File

@@ -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