Duncan Laurie has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/41209 )
Change subject: fw_config: Add firmware configuration interface
......................................................................
fw_config: Add firmware configuration interface
This change introduces a new top-level interface for interacting with a
bitmask providing firmware configuration information.
This is motivated by Chromebook mainboards that need to support multiple
different configurations at runtime with the same BIOS. In these devices
the Embedded Controller provides a bitmask that can be broken down into
different fields and each field can be broken down into different options.
The firmware configuration interface is intended to be easily adapted by
device drivers and mainboards and lead to less code duplication for new
mainboards that make use of this feature by providing common functions and
integration into devicetree.cb.
BUG=b:147462631
TEST=this provides a new interface that is tested in subsequent commits
Change-Id: I1e889c235a81545e2ec0e3a34dfa750ac828a330
Signed-off-by: Duncan Laurie <dlaurie(a)google.com>
---
A Documentation/lib/fw_config.md
M Documentation/lib/index.md
A src/include/fw_config.h
M src/lib/Kconfig
M src/lib/Makefile.inc
A src/lib/fw_config.c
6 files changed, 742 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/09/41209/1
diff --git a/Documentation/lib/fw_config.md b/Documentation/lib/fw_config.md
new file mode 100644
index 0000000..6f769d6
--- /dev/null
+++ b/Documentation/lib/fw_config.md
@@ -0,0 +1,406 @@
+# 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 be a variant of the same baseboard.
+
+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. A different
+implementation could use a file in CBFS or a hard coded value in Kconfig for different images
+to make the selected configuration options static.
+
+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 consists of two inputs:
+
+1. The table of fields and options that represent the board-specific bitmask.
+2. The bitmask of selected options for a particular hardware combination.
+
+Both of these are provided by the mainboard itself because it is the source of truth for the
+possible combinations of SoC and devices.
+
+### Mainboard Table
+
+To use the firmware configuration interface the mainboard provides a table defining the fields
+within the bitmask and what each of the various options are within each field.
+
+The list of fields is terminated by an empty field where `field.name == NULL`.
+
+### Field List
+
+The table provides a `struct fw_config_field` for each field within the bitmask and contains
+the name of that field as well as the starting offset and the mask of bits to be included.
+
+Each field also contains a list of `struct fw_config_option` which is terminated by an empty
+entry where `option.name == NULL`.
+
+```c
+/**
+ * struct fw_config_field - Descriptor for field within firmware configuration bitmask.
+ * @name: Name of this field.
+ * @mask: Mask value that indicates which bits are in this field.
+ * @shift: Offset within the 32-bit value where this field starts.
+ * @option: List of field options.
+ */
+struct fw_config_field {
+ const char *name;
+ uint32_t mask;
+ size_t shift;
+ struct fw_config_option option[FW_CONFIG_OPTION_MAX];
+};
+```
+
+### Option List
+
+Each field can contain multiple `struct fw_config_option` definitions, and one should be
+provided for each possible field option. Options must be unique and there is no provision in
+this design for multiple options that have the same value or name.
+
+Each field option in the list consists of a name and the expected field value, as well as a
+callback function. This callback will be executed at boot if the option matches the value of
+the field returned by the mainboard.
+
+```c
+/**
+ * struct fw_config_option - Descriptor for option within a field.
+ * @name: Name of this field option.
+ * @value: Value of this option.
+ * @callback: Function callback for when this option is selected.
+ */
+struct fw_config_option {
+ const char *name;
+ uint32_t value;
+ fw_config_option_cb *callback;
+};
+```
+
+Helper macros are provided which make it easier to write the firmware configuration table and
+allow the fields to be specified on one line.
+
+ FW_CONFIG_FIELD(name, mask, shift)
+ FW_CONFIG_OPTION(name, value)
+ FW_CONFIG_OPTION_CB(name, value, callback)
+
+### Probe List
+
+The probe list provides a set of field and option names to match against the mainboard table
+and value. Each entry specifies the name of the field within the firmware configuration
+bitmask and the name of the option within that field that should be checked.
+
+This list allows for a driver probe to check for multiple matches, either multiple options
+from the same field or from different fields.
+
+An array of these structures is typically provided in a driver chip configuration structure
+and filled out by the mainboard in `devicetree.cb`.
+
+```c
+/**
+ * struct fw_config_probe - Descriptor for a firmware configuration probe match.
+ * @field: Name of the field to match.
+ * @option: Name of the option within the field to match.
+ */
+struct fw_config_probe {
+ const char *field;
+ const char *option;
+};
+```
+
+A helper macro is provided to make it easier to add matches for driver probing. Note that
+with this macro the name strings should not be enclosed in quotes, in order to allow this to
+be easily used in `devicetree.cb`:
+
+ FW_CONFIG_MATCH(field_name, option_name)
+
+### Interface Library
+
+In addition to the structures there are some defined library functions that are intended for
+use by drivers and mainboards.
+
+#### Match Field and Option
+
+This function searches the mainboard table for a matching field and option name. It takes
+a single field and option name to search for and returns a boolean value that indicates
+whether the field and option was found in the table.
+
+This is intended for mainboards that may need to to additional processing outside of the
+automated probing and callback interface. For example during romstage it may be necessary
+to check if a given field and option is enabled and adjust a parameter to FSP-M.
+
+```c
+/**
+ * fw_config_match() - Check provided field and option name against mainboard table.
+ * @field_name: Name of the field that this option belongs to.
+ * @option_name: Name of the option within the field to find.
+ *
+ * Return %true if option is a match, %false if option does not match.
+ */
+bool fw_config_match(const char *field_name, const char *option_name);
+```
+
+#### Probe Device
+
+This interface is used by device drivers to probe a list of field and option names where any
+match in the list is considered a successful probe. A device declared in `devicetree.cb` may
+be considered present by more than one option, and any entry in the list is considered a
+positive match.
+
+```c
+/**
+ * fw_config_probe() - Check each field and option against match_list.
+ * @match_list: List of fw_config field and option names to check.
+ *
+ * Return %true if match is found, %false if match is not found.
+ */
+bool fw_config_probe(const struct fw_config_probe *match_list);
+```
+
+## Mainboard Integration
+
+There are several requirements that the mainboard is expected to provide for the firmware
+configuration interface.
+
+### Configuration Table
+
+The mainboard must provide a function that returns the table of fields and options as well as
+the current firmware configuration value.
+
+The table itself can be declared as a static structure in the mainboard code. Here we show a
+boolean 1-bit field for `FEATURE` which is at bit offset 0 and can be set to either `ENABLE`
+or `DISABLE`.
+
+```c
+static const struct fw_config_field mainboard_fw_config[] = {
+ {
+ FW_CONFIG_FIELD("FEATURE", 0x1, 0),
+ .option = {
+ FW_CONFIG_OPTION("DISABLE", 0),
+ FW_CONFIG_OPTION("ENABLE", 1),
+ }
+ },
+ { }
+};
+```
+
+### Configuration Value
+
+The actual selection of firmware configuration options is done based on a 32-bit mask that
+is provided by the mainboard. This value can be read from a variety of different sources:
+
+- Chrome OS boards typically retrieve the firmware configuration value from the Embedded
+Controller via a mailbox function.
+- The value could be hard coded in Kconfig or in the source directly.
+- The value could be provided in CBFS and added to the image after building.
+- The value could be stored directly in flash or CMOS.
+
+In this example the value is read from the Chrome OS Embedded Controller and provided together
+with the pointer to the mainboard firmware configuration table.
+
+```c
+size_t mainboard_get_fw_config(const struct fw_config_field **table, uint32_t *config)
+{
+ if (google_chromeec_cbi_get_fw_config(config) < 0) {
+ printk(BIOS_ERR, "Could not get fw_config from EC\n");
+ return 0;
+ }
+
+ *table = mainboard_fw_config;
+ return ARRAY_SIZE(mainboard_fw_config);
+}
+```
+
+### Option Callbacks
+
+The table of fields and values can optionally contain a callback function for each defined
+option. This allows the mainboard to do special configuration to support the particular
+selected option.
+
+During boot the table of fields is compared against the mainboard provided bitmask and
+callbacks will be executed for the option that matches within each field. This happens before
+the device driver enable stage to allow the mainboard to alter the device tree if needed.
+
+Continuing with the previous example if the value returned by the mainboard at boot has
+`bit 0 == 0` then the `FEATURE` field option will be set to `DISABLE` and the provided callback
+`feature_disable_cb()` will be executed. If the field value is 1 then the field option will
+be set to `ENABLE` and the provided callback `feature_enable_cb()` will be executed.
+
+```c
+static void feature_disable_cb(const struct fw_config_option *option)
+{
+ const struct pad_config disable_pads[] = {
+ PAD_NC(GPP_S0, NONE),
+ PAD_NC(GPP_S1, NONE),
+ };
+ gpio_configure_pads(disable_pads, ARRAY_SIZE(disable_pads));
+}
+
+static void feature_enable_cb(const struct fw_config_option *option)
+{
+ const struct pad_config enable_pads[] = {
+ PAD_CFG_NF(GPP_S0, NONE, DEEP, NF1),
+ PAD_CFG_NF(GPP_S1, NONE, DEEP, NF1),
+ };
+ gpio_configure_pads(enable_pads, ARRAY_SIZE(enable_pads));
+}
+
+static const struct fw_config_field mainboard_fw_config[] = {
+ {
+ FW_CONFIG_FIELD("FEATURE", 0x1, 0),
+ .option = {
+ FW_CONFIG_OPTION_CB("DISABLE", 0, feature_disable_cb),
+ FW_CONFIG_OPTION_CB("ENABLE", 1, feature_enable_cb),
+ }
+ },
+ { }
+};
+```
+
+### Device Driver Probing
+
+When a device driver supports the firmware configuration interface the probe matches can be
+specified directly in `devicetree.cb` together with the driver. This relies on an array of
+`struct fw_config_probe` to allow multiple matches to be specified. This is a convenient
+way to disable drivers for hardware that does not exist in the system, preventing the system
+from allocating resources or generating ACPI code for that device.
+
+This `devicetree.cb` example is based on the table provided in previous examples. If the
+`FEATURE` field is set to `ENABLE` then this match will be true and the device will be
+considered present. If the field was set to `DISABLE` then the device would be disabled in
+the driver by clearing the `enabled` flag in the device structure, and it would not execute
+any callback.
+
+```
+device pci 15.0 on
+ chip drivers/i2c/generic
+ register "desc" = ""Example Probed Device""
+ register "fw_config_probe" = "true"
+ register "fw_config" = "{ FW_CONFIG_MATCH(FEATURE, ENABLE) }"
+ device i2c ff on end
+ end
+end
+```
+
+## Driver Integration
+
+Driver support for firmware configuration needs only a few changes:
+
+1) Add an array of `struct fw_config_probe` to the chip configuration in `chip.h`, along with
+an enable flag to make it clear that this probing is expected.
+2) Call `fw_config_probe()` from the drivers `chip.enable_dev()` function and supply the list
+of matches to check from `devicetree.cb` as an argument.
+3) Disable the device if the probe returns false.
+
+### Example: Driver Chip Configuration
+
+```c
+struct drivers_example_config {
+ bool fw_config_probe;
+ struct fw_config_probe fw_config[FW_CONFIG_PROBE_MAX];
+};
+```
+
+### Example: Driver Enable Function
+
+```c
+static void drivers_example_enable(struct device *dev)
+{
+ struct drivers_example_config *config = dev->chip_info;
+
+ if (config->fw_config_probe && !fw_config_probe(config->fw_config))
+ dev->enabled = 0;
+}
+struct chip_operations drivers_example_ops = {
+ CHIP_NAME("Example Driver")
+ .enable_dev = drivers_example_enable
+};
+```
+
+## Other Uses
+
+The device driver probing and callback interface allow for seamless integration with the
+mainboard, but both are designed for ramstage and there are other situations where code may
+need to probe or check the value of a field in romstage or other points in ramstage. For
+this reason it is also possible to use the firmware configuration interface directly.
+
+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 option is set to `true` in
+`devicetree.cb` and this code is disabling that feature before FSP is executed.
+
+```c
+void mainboard_memory_init_params(FSPM_UPD *mupd)
+{
+ if (fw_config_match("FEATURE", "DISABLE"))
+ mupd->ExampleFeature = false;
+}
+```
+
+### Modifying the Firmware Configuration
+
+The actual implementation of retrieving the firmware configuration value is left up to the
+individual mainboard. If the value comes from Kconfig it is easy to adjust in the local
+config file. If it comes from CBFS it could be updated after building the image.
+
+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 not typically
+necessary to adjust this value, but it is possible *(after disabling write protection)* by using
+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/firmw…
+[2]: http://chromium.googlesource.com/chromiumos/docs/+/master/design_docs/cros_…
diff --git a/Documentation/lib/index.md b/Documentation/lib/index.md
index 99b8061..d64b4e9 100644
--- a/Documentation/lib/index.md
+++ b/Documentation/lib/index.md
@@ -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)
diff --git a/src/include/fw_config.h b/src/include/fw_config.h
new file mode 100644
index 0000000..a2780e5
--- /dev/null
+++ b/src/include/fw_config.h
@@ -0,0 +1,149 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* This file is part of the coreboot project. */
+
+#ifndef __FW_CONFIG__
+#define __FW_CONFIG__
+
+#include <stdint.h>
+#include <types.h>
+
+/**
+ * enum fw_config_max - Limits on firmware configuration structures.
+ * @FW_CONFIG_PROBE_MAX: Default limit of probe entries for a driver.
+ * @FW_CONFIG_OPTION_MAX: Limit on the number of options within a field.
+ */
+enum fw_config_max {
+ FW_CONFIG_PROBE_MAX = 8,
+ FW_CONFIG_OPTION_MAX = 32
+};
+
+/**
+ * fw_config_option_cb() - Callback for option to do extra work.
+ * @option: Option that was discovered.
+ */
+struct fw_config_option;
+typedef void fw_config_option_cb(const struct fw_config_option *option);
+
+/**
+ * struct fw_config_option - Descriptor for option within a field.
+ * @name: Name of this field option.
+ * @value: Value of this option.
+ * @callback: Function callback for when this option is selected.
+ */
+struct fw_config_option {
+ const char *name;
+ uint32_t value;
+ fw_config_option_cb *callback;
+};
+
+/**
+ * struct fw_config_field - Descriptor for field within firmware configuration bitmask.
+ * @name: Name of this field.
+ * @mask: Mask value that indicates which bits are in this field.
+ * @shift: Offset within the 32-bit value where this field starts.
+ * @option: List of field options.
+ */
+struct fw_config_field {
+ const char *name;
+ uint32_t mask;
+ size_t shift;
+ struct fw_config_option option[FW_CONFIG_OPTION_MAX];
+};
+
+/**
+ * struct fw_config_probe - Descriptor for a firmware configuration probe match.
+ * @field: Name of the field to match.
+ * @option: Name of the option within the field to match.
+ */
+struct fw_config_probe {
+ const char *field;
+ const char *option;
+};
+
+/**
+ * FW_CONFIG_FIELD() - Helper macro for defining a field.
+ * @__name: Name of this field.
+ * @__mask: Bitmask for extracting this field.
+ * @__shift: Bit offset where this field starts.
+ */
+#define FW_CONFIG_FIELD(__name, __mask, __shift) \
+ .name = (__name), \
+ .mask = (__mask), \
+ .shift = (__shift)
+
+/**
+ * FW_CONFIG_OPTION_CB() - Helper macro for defining a field option with a callback.
+ * @__name; Name of the field option.
+ * @__value: Value for this option after field shift and mask are applied.
+ * @__callback: Function to be called if the field is set to this option.
+ */
+#define FW_CONFIG_OPTION_CB(__name, __value, __callback) { \
+ .name = (__name), \
+ .value = (__value), \
+ .callback = (__callback) \
+}
+
+/**
+ * FW_CONFIG_OPTION() - Helper macro for defining a field option without a callback.
+ * @__name; Name of the field option.
+ * @__value: Value for this option after field shift and mask are applied.
+ */
+#define FW_CONFIG_OPTION(__name, __value) FW_CONFIG_OPTION_CB(__name, __value, NULL)
+
+/**
+ * FW_CONFIG_MATCH() - Helper macro for defining a field and option to match against.
+ * @__field: Name of the field to match.
+ * @__option: Name of the field option to match.
+ */
+#define FW_CONFIG_MATCH(__field, __option) { \
+ .field = #__field, \
+ .option = #__option, \
+}
+
+/**
+ * mainboard_get_fw_config() - Get table of fields and config value from mainboard.
+ * This is defined as a weak function in lib/fw_config.c
+ * and can be overridden by the mainboard.
+ * @table: Pointer to list of fields that is provided by the mainboard. The list is
+ * terminated by an empty entry where the field name is NULL.
+ * @config: Pointer to 32-bit integer of mainboard firmware configuration value.
+ *
+ * Return number of entries in mainboard_table, zero if table is not found.
+ */
+size_t mainboard_get_fw_config(const struct fw_config_field **table, uint32_t *config);
+
+#if CONFIG(FW_CONFIG)
+
+/**
+ * fw_config_match() - Check provided field and option name against mainboard table.
+ * @field_name: Name of the field that this option belongs to.
+ * @option_name: Name of the option within the field to find.
+ *
+ * Return %true if option is a match, %false if option does not match.
+ */
+bool fw_config_match(const char *field_name, const char *option_name);
+
+/**
+ * fw_config_probe() - Check each field and option against match_list.
+ * @match_list: List of fw_config field and option names to check.
+ *
+ * Return %true if match is found, %false if match is not found.
+ */
+bool fw_config_probe(const struct fw_config_probe *match_list);
+
+#else /* CONFIG(FW_CONFIG) */
+
+static inline bool fw_config_match(const char *field_name, const char *option_name)
+{
+ /* Always return true when probing with disabled fw_config. */
+ return true;
+}
+static inline bool fw_config_probe(const struct fw_config_probe *match_list)
+{
+ /* Always return true when probing with disabled fw_config. */
+ return true;
+}
+
+#endif /* CONFIG(FW_CONFIG) */
+
+#endif /* __FW_CONFIG__ */
diff --git a/src/lib/Kconfig b/src/lib/Kconfig
index dd9974a..78a1eb8 100644
--- a/src/lib/Kconfig
+++ b/src/lib/Kconfig
@@ -75,3 +75,11 @@
If your platform really doesn't want to use an FMAP cache (e.g. due to
space constraints), you can select this to disable warnings and save
a bit more code.
+
+config FW_CONFIG
+ bool
+ default n
+ help
+ Enable support for probing devices with fw_config. This is a simple
+ bitmask broken into fields and options which can be provided by an
+ Embedded Controller or CBFS.
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index c03aea1..126ad0d 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -67,6 +67,7 @@
$(eval rmodules_$(arch)-y += rmodule.ld))
romstage-y += fmap.c
+romstage-$(CONFIG_FW_CONFIG) += fw_config.c
romstage-y += delay.c
romstage-y += cbfs.c
romstage-$(CONFIG_COMPRESS_RAMSTAGE) += lzma.c lzmadecode.c
@@ -106,6 +107,7 @@
ramstage-y += coreboot_table.c
ramstage-y += bootmem.c
ramstage-y += fmap.c
+ramstage-$(CONFIG_FW_CONFIG) += fw_config.c
ramstage-y += memchr.c
ramstage-y += memcmp.c
ramstage-y += malloc.c
diff --git a/src/lib/fw_config.c b/src/lib/fw_config.c
new file mode 100644
index 0000000..4364728
--- /dev/null
+++ b/src/lib/fw_config.c
@@ -0,0 +1,176 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* This file is part of the coreboot project. */
+
+#include <bootstate.h>
+#include <commonlib/helpers.h>
+#include <console/console.h>
+#include <fw_config.h>
+#include <stdint.h>
+#include <string.h>
+#include <types.h>
+
+MAYBE_STATIC_BSS const struct fw_config_field *mainboard_table;
+MAYBE_STATIC_BSS uint32_t mainboard_config;
+
+__weak size_t mainboard_get_fw_config(const struct fw_config_field **table, uint32_t *config)
+{
+ return 0;
+}
+
+/**
+ * fw_config_prepare() - Check and set up mainboard table and config value.
+ *
+ * Return %false if mainboard does not provide table, otherwise %true.
+ */
+static bool fw_config_prepare(void)
+{
+ if (!mainboard_table) {
+ /* Get mainboard table and config value. */
+ if (!mainboard_get_fw_config(&mainboard_table, &mainboard_config)) {
+ printk(BIOS_WARNING,
+ "%s: Mainboard did not provide firmware configuration table.\n",
+ __func__);
+ return false;
+ }
+ }
+ return true;
+}
+
+/**
+ * fw_config_check_option() - Check this option against the mainboard config.
+ * @field: Field that this option belongs to.
+ * @option: Option that should be checked.
+ *
+ * Return %true if option matches, %false if it does not.
+ */
+static inline bool fw_config_check_option(const struct fw_config_field *field,
+ const struct fw_config_option *option)
+{
+ return option->value == ((mainboard_config >> field->shift) & field->mask);
+}
+
+/**
+ * fw_config_find_option() - Find matching option in the provided field.
+ * @field: The field to search.
+ * @option_name: The name of the option to look for.
+ *
+ * Return pointer to option that is found, NULL if no match is found.
+ */
+static const struct fw_config_option *
+fw_config_find_option(const struct fw_config_field *field, const char *option_name)
+{
+ size_t entry;
+
+ for (entry = 0; entry < FW_CONFIG_OPTION_MAX; entry++) {
+ const struct fw_config_option *option = &field->option[entry];
+
+ /* Stop at the first undefined option in the list. */
+ if (!option || !option->name)
+ break;
+
+ /* Check this option name to see if it matches. */
+ if (strncmp(option->name, option_name, strlen(option->name)) == 0)
+ return option;
+ }
+ return NULL;
+}
+
+/**
+ * fw_config_find_field() - Find matching field in the mainboard table.
+ * @field_name: The name of the field to look for.
+ *
+ * Return pointer to field that is found, NULL if no match is found or no table is defined.
+ */
+static const struct fw_config_field *fw_config_find_field(const char *field_name)
+{
+ const struct fw_config_field *field;
+
+ if (!fw_config_prepare())
+ return NULL;
+
+ /* Look for matching field name first. */
+ for (field = mainboard_table; field && field->name; field++) {
+ if (strncmp(field->name, field_name, strlen(field->name)) == 0)
+ return field;
+ }
+ return NULL;
+}
+
+bool fw_config_match(const char *field_name, const char *option_name)
+{
+ const struct fw_config_field *field;
+ const struct fw_config_option *option;
+
+ /* Always return true when probing with missing fw_config. */
+ if (!fw_config_prepare())
+ return true;
+
+ /* Find the field that matches probed field name. */
+ field = fw_config_find_field(field_name);
+ if (!field)
+ return false;
+
+ /* Find the option in this field that matches probed option name. */
+ option = fw_config_find_option(field, option_name);
+ if (option && fw_config_check_option(field, option)) {
+ printk(BIOS_INFO, "%s: match found for %s:%s\n", __func__,
+ field_name, option_name);
+ return true;
+ }
+
+ return false;
+}
+
+bool fw_config_probe(const struct fw_config_probe *match_list)
+{
+ size_t entry;
+
+ /* Always return true when probing with missing fw_config. */
+ if (!fw_config_prepare())
+ return true;
+
+ /* Check each entry in the probe list provided by the caller. */
+ for (entry = 0; entry < FW_CONFIG_PROBE_MAX; entry++) {
+ const struct fw_config_probe *match = &match_list[entry];
+
+ /* Stop at the first undefined match in the list. */
+ if (!match || !match->option)
+ break;
+
+ /* Check for a match with this option. */
+ if (fw_config_match(match->field, match->option))
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * fw_config_run_callbacks() - Find matching options and execute provided callbacks.
+ * Callbacks are executed before device enable functions are called.
+ */
+static void fw_config_run_callbacks(void *unused)
+{
+ const struct fw_config_field *field;
+
+ if (!fw_config_prepare())
+ return;
+
+ /* Go through each field and find which option is selected. */
+ for (field = mainboard_table; field && field->name; field++) {
+ size_t entry;
+
+ for (entry = 0; entry < FW_CONFIG_OPTION_MAX; entry++) {
+ const struct fw_config_option *option = &field->option[entry];
+
+ /* Stop at the first undefined option in the list. */
+ if (!option || !option->name)
+ break;
+
+ /* Call provided callback if option is selected. */
+ if (option->callback && fw_config_check_option(field, option))
+ option->callback(option);
+ }
+ }
+}
+BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_ENTRY, fw_config_run_callbacks, NULL);
--
To view, visit https://review.coreboot.org/c/coreboot/+/41209
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I1e889c235a81545e2ec0e3a34dfa750ac828a330
Gerrit-Change-Number: 41209
Gerrit-PatchSet: 1
Gerrit-Owner: Duncan Laurie <dlaurie(a)chromium.org>
Gerrit-MessageType: newchange
Matt DeVillier has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/25416 )
Change subject: soc/intel/apollolake: Save/restore GMA OpRegion address
......................................................................
Patch Set 5:
> Patch Set 5:
>
> CB:40724 has been merged. What needs to happen to this patch train?
this specific patch is superseded by the (merged) change in CB:40725 so I'll abandon it.
CB:40593 and CB:40594 need some adjustment to work under Linux, right now they just provide enough of an interface for Windows to make use of the vendor/driver backlight controls
--
To view, visit https://review.coreboot.org/c/coreboot/+/25416
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I4123998b0ab3c263c6a9ff14084a0d8808e5f4cd
Gerrit-Change-Number: 25416
Gerrit-PatchSet: 5
Gerrit-Owner: Matt DeVillier <matt.devillier(a)gmail.com>
Gerrit-Reviewer: Andrey Petrov <andrey.petrov(a)gmail.com>
Gerrit-Reviewer: Angel Pons <th3fanbus(a)gmail.com>
Gerrit-Reviewer: Matt DeVillier <matt.devillier(a)gmail.com>
Gerrit-Reviewer: Nico Huber <nico.h(a)gmx.de>
Gerrit-Reviewer: Patrick Rudolph <siro(a)das-labor.org>
Gerrit-Reviewer: Paul Menzel <paulepanter(a)users.sourceforge.net>
Gerrit-Reviewer: build bot (Jenkins) <no-reply(a)coreboot.org>
Gerrit-CC: Patrick Georgi <pgeorgi(a)google.com>
Gerrit-Comment-Date: Tue, 02 Jun 2020 16:23:30 +0000
Gerrit-HasComments: No
Gerrit-Has-Labels: No
Gerrit-MessageType: comment
Hello build bot (Jenkins), Patrick Georgi, Martin Roth, Maulik V Vaghela, Aamir Bohra, Ronak Kanabar, Patrick Rudolph,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/41062
to look at the new patch set (#14).
Change subject: soc/intel/jasperlake: Apply FiVR related settings
......................................................................
soc/intel/jasperlake: Apply FiVR related settings
Set optimized values for FiVR to shut the VCCIN_AUX_SHUTDOWN
power rails during SOix.
BUG=None
BRANCH=None
TEST=Build and boot dedede and check VCCIN_AUX_SHUTDOWN rails
are shut.
Change-Id: Ief81fe481c94abef9754881cf1f454699fafa52e
Signed-off-by: Meera Ravindranath <meera.ravindranath(a)intel.com>
---
M src/soc/intel/jasperlake/fsp_params.c
1 file changed, 33 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/62/41062/14
--
To view, visit https://review.coreboot.org/c/coreboot/+/41062
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ief81fe481c94abef9754881cf1f454699fafa52e
Gerrit-Change-Number: 41062
Gerrit-PatchSet: 14
Gerrit-Owner: Meera Ravindranath <meera.ravindranath(a)intel.com>
Gerrit-Reviewer: Aamir Bohra <aamir.bohra(a)intel.com>
Gerrit-Reviewer: Martin Roth <martinroth(a)google.com>
Gerrit-Reviewer: Maulik V Vaghela <maulik.v.vaghela(a)intel.com>
Gerrit-Reviewer: Patrick Georgi <pgeorgi(a)google.com>
Gerrit-Reviewer: Patrick Rudolph <siro(a)das-labor.org>
Gerrit-Reviewer: Ronak Kanabar <ronak.kanabar(a)intel.com>
Gerrit-Reviewer: build bot (Jenkins) <no-reply(a)coreboot.org>
Gerrit-CC: Paul Menzel <paulepanter(a)users.sourceforge.net>
Gerrit-MessageType: newpatchset
Hello build bot (Jenkins), Patrick Georgi, Martin Roth, Maulik V Vaghela, Aamir Bohra, Ronak Kanabar, Patrick Rudolph,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/41062
to look at the new patch set (#13).
Change subject: soc/intel/jasperlake: Apply FiVR related settings
......................................................................
soc/intel/jasperlake: Apply FiVR related settings
Set optimized values for FiVR to shut the VCCIN_AUX_SHUTDOWN
power rails during SOix.
BUG=None
BRANCH=None
TEST=Build and boot dedede and check VCCIN_AUX_SHUTDOWN rails
are shut.
Change-Id: Ief81fe481c94abef9754881cf1f454699fafa52e
Signed-off-by: Meera Ravindranath <meera.ravindranath(a)intel.com>
---
M src/soc/intel/jasperlake/fsp_params.c
1 file changed, 33 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/62/41062/13
--
To view, visit https://review.coreboot.org/c/coreboot/+/41062
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ief81fe481c94abef9754881cf1f454699fafa52e
Gerrit-Change-Number: 41062
Gerrit-PatchSet: 13
Gerrit-Owner: Meera Ravindranath <meera.ravindranath(a)intel.com>
Gerrit-Reviewer: Aamir Bohra <aamir.bohra(a)intel.com>
Gerrit-Reviewer: Martin Roth <martinroth(a)google.com>
Gerrit-Reviewer: Maulik V Vaghela <maulik.v.vaghela(a)intel.com>
Gerrit-Reviewer: Patrick Georgi <pgeorgi(a)google.com>
Gerrit-Reviewer: Patrick Rudolph <siro(a)das-labor.org>
Gerrit-Reviewer: Ronak Kanabar <ronak.kanabar(a)intel.com>
Gerrit-Reviewer: build bot (Jenkins) <no-reply(a)coreboot.org>
Gerrit-CC: Paul Menzel <paulepanter(a)users.sourceforge.net>
Gerrit-MessageType: newpatchset
Raul Rangel has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/25345 )
Change subject: soc/amd/stoneyridge: Generate SPCR table
......................................................................
Patch Set 6:
(1 comment)
https://review.coreboot.org/c/coreboot/+/25345/6/src/soc/amd/stoneyridge/ua…
File src/soc/amd/stoneyridge/uart.c:
https://review.coreboot.org/c/coreboot/+/25345/6/src/soc/amd/stoneyridge/ua…
PS6, Line 41: AMDCZ
> Works for me, not that I will get to this any time soon... […]
I think we can remove all the special AMDCZ handling. The AMD part uses DW IP. The driver supports reading the fixed clock rate: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/master:src/t…
So if we pass that along then I think the kernel will configure the IP correctly so we can boot with console=ttyS0 even when coreboot hasn't setup the UART.
I need to try this out on zork.
--
To view, visit https://review.coreboot.org/c/coreboot/+/25345
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Icc98bcf4f8c070b8002bcc795254b19f928c741b
Gerrit-Change-Number: 25345
Gerrit-PatchSet: 6
Gerrit-Owner: Martin Roth <martinroth(a)google.com>
Gerrit-Reviewer: Aaron Durbin <adurbin(a)chromium.org>
Gerrit-Reviewer: Daniel Kurtz <djkurtz(a)chromium.org>
Gerrit-Reviewer: Daniel Kurtz <djkurtz(a)google.com>
Gerrit-Reviewer: Martin Roth <martinroth(a)google.com>
Gerrit-Reviewer: Paul Menzel <paulepanter(a)users.sourceforge.net>
Gerrit-Reviewer: build bot (Jenkins) <no-reply(a)coreboot.org>
Gerrit-CC: Marshall Dawson <marshalldawson3rd(a)gmail.com>
Gerrit-CC: Raul Rangel <rrangel(a)chromium.org>
Gerrit-CC: Richard Spiegel <richard.spiegel(a)silverbackltd.com>
Gerrit-Comment-Date: Tue, 02 Jun 2020 15:25:48 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Daniel Kurtz <djkurtz(a)google.com>
Comment-In-Reply-To: Raul Rangel <rrangel(a)chromium.org>
Comment-In-Reply-To: Martin Roth <martinroth(a)google.com>
Comment-In-Reply-To: Marshall Dawson <marshalldawson3rd(a)gmail.com>
Gerrit-MessageType: comment