xref: /aosp_15_r20/external/coreboot/Documentation/lib/fw_config.md (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1# Firmware Configuration Interface in coreboot
2
3## Motivation
4
5The firmware configuration interface in coreboot is designed to support a wide variety of
6configuration options in that are dictated by the hardware at runtime.  This allows a single
7BIOS image to be used across a wide variety of devices which may have key differences but are
8otherwise similar enough to use the same coreboot build target.
9
10The initial implementation is designed to take advantage of a bitmask returned by the Embedded
11Controller on Google ChromeOS devices which allows the manufacturer to use the same firmware
12image across multiple devices by selecting various options at runtime.  See the ChromiumOS
13[Firmware Config][1] documentation for more information.
14
15This firmware configuration interface differs from the CMOS option interface in that this
16bitmask value is not intended as a user-configurable setting as the configuration values must
17match the actual hardware.  In the case where a user was to swap their hardware this value
18would need to be updated or overridden.
19
20## Device Presence
21
22One common example of why a firmware configuration interface is important is determining if a
23device is present in the system.  With some bus topologies and hardware mechanisms it is
24possible to probe and enumerate this at runtime:
25
26- PCI is a self-discoverable bus and is very easy to handle.
27- I2C devices can often be probed with a combination of bus and address.
28- The use of GPIOs with external strap to ground or different voltages can be used to detect
29presence of a device.
30
31However there are several cases where this is insufficient:
32
33- I2C peripherals that require different drivers but have the same bus address cannot be
34uniquely identified at runtime.
35- A mainboard may be designed with multiple daughter board combinations which contain devices
36and configurations that cannot be detected.
37- While presence detect GPIOs are a convenient way for a single device presence, they are
38unable to distinguish between different devices so it can require a large number of GPIOs to
39support relatively few options.
40
41This presence detection can impact different stages of boot:
42
43### ACPI
44
45Devices that are not present should not provide an ACPI device indicating that they are
46present or the operating system may not be able to handle it correctly.
47
48The ACPI devices are largely driven by chips defined in the mainboard `devicetree.cb` and
49the variant overridetree.cb.  This means it is important to be able to specify when a device
50is present or not directly in `devicetree.cb` itself.  Otherwise each mainboard needs custom
51code to parse the tree and disable unused devices.
52
53### GPIO
54
55GPIOs with multiple functions may need to be configured correctly depending on the attached
56device.  Given the wide variety of GPIO configuration possibilities it is not feasible to
57specify all combinations directly in `devicetree.cb` and it is best left to code provided by
58the mainboard.
59
60### FSP UPD
61
62Enabling and disabling devices may require altering FSP UPD values that are provided to the
63various stages of FSP.  These options are also not easy to specify multiple times for
64different configurations in `devicetree.cb` and can be provided by the mainboard as code.
65
66## Firmware Configuration Interface
67
68The firmware configuration interface can be enabled by selecting `CONFIG_FW_CONFIG` and also
69providing a source for the value by defining an additional Kconfig option defined below.
70
71If the firmware configuration interface is disabled via Kconfig then all probe attempts will
72return true.
73
74## Firmware Configuration Value
75
76The 64-bit value used as the firmware configuration bitmask is meant to be determined at runtime
77but could also be defined at compile time if needed.
78
79There are two supported sources for providing this information to coreboot.
80
81### CBFS
82
83The value can be provided with a 64-bit raw value in CBFS that is read by coreboot.  The value
84can be set at build time but also adjusted in an existing image with `cbfstool`.
85
86To enable this select the `CONFIG_FW_CONFIG_CBFS` option in the build configuration and add a
87raw 64-bit value to CBFS with the name of the current prefix at `CONFIG_FW_PREFIX/fw_config`.
88
89When `fw_config_probe_device()` or `fw_config_probe()` is called it will look for the specified
90file in CBFS use the value it contains when matching fields and options.
91
92### Embedded Controller
93
94Google ChromeOS devices support an Embedded Controller interface for reading and writing the
95firmware configuration value, along with other board-specific information.  It is possible for
96coreboot to read this value at boot on systems that support this feature.
97
98This option is selected by default for the mainboards that use it with
99`CONFIG_FW_CONFIG_CHROME_EC_CBI` and it is not typically necessary to adjust the value.  It is
100possible by enabling the CBFS source and coreboot will look in CBFS first for a valid value
101before asking the embedded controller.
102
103It is also possible to adjust the value in the embedded controller *(after disabling write
104protection)* with the `ectool` command in a ChromeOS environment.
105
106For more information on the firmware configuration field on ChromeOS devices see the Chromium
107documentation for [Firmware Config][1] and [Board Info][2].
108
109[1]: http://chromium.googlesource.com/chromiumos/docs/+/HEAD/design_docs/firmware_config.md
110[2]: http://chromium.googlesource.com/chromiumos/docs/+/HEAD/design_docs/cros_board_info.md
111
112## Firmware Configuration Table
113
114The firmware configuration table itself is defined in the mainboard `devicetree.cb` with
115special tokens for defining fields and options.
116
117The table itself is enclosed in a `fw_config` token and terminated with `end` and it contains
118a mix of field and option definitions.
119
120Each field is defined by providing the field name and the start and end bit marking the exact
121location in the bitmask.  Field names must be at least three characters long in order to
122satisfy the sconfig parser requirements and they must be unique with non-overlapping masks.
123
124	field <name> <start-bit> <end-bit> [option...] end
125
126For single-bit fields only one number is needed:
127
128	field <name> <bit> [option...] end
129
130A field definition can also contain multiple sets of bit masks, which can be dis-contiguous.
131They are treated as if they are contiguous when defining option values.  This allows for
132extending fields even after the bits after its current masks are occupied.
133
134	field <name> <start-bit0> <end-bit0> | <start-bit1> <end-bit1> | ...
135
136For example, if more audio options need to be supported:
137
138	field AUDIO 3 3
139		option AUDIO_0  0
140		option AUDIO_1  1
141	end
142	field OTHER 4 4
143		...
144	end
145
146the following can be done:
147
148	field AUDIO 3 3 | 5 5
149		option AUDIO_FOO   0
150		option AUDIO_BLAH  1
151		option AUDIO_BAR   2
152		option AUDIO_BAZ   3
153	end
154	field OTHER 4 4
155		...
156	end
157
158In that case, the AUDIO masks are extended like so:
159
160	#define FW_CONFIG_FIELD_AUDIO_MASK						0x28
161	#define FW_CONFIG_FIELD_AUDIO_OPTION_AUDIO_FOO_VALUE	0x0
162	#define FW_CONFIG_FIELD_AUDIO_OPTION_AUDIO_BLAH_VALUE	0x8
163	#define FW_CONFIG_FIELD_AUDIO_OPTION_AUDIO_BAR_VALUE	0x20
164	#define FW_CONFIG_FIELD_AUDIO_OPTION_AUDIO_BAz_VALUE	0x28
165
166Each `field` definition starts a new block that can be composed of zero or more field options,
167and it is terminated with `end`.
168
169Inside the field block the options can be defined by providing the option name and the field
170value that this option represents when the bit offsets are used to apply a mask and shift.
171Option names must also be at least three characters for the sconfig parser.
172
173	option <name> <value>
174
175It is possible for there to be multiple `fw_config` blocks and for subsequent `field` blocks
176to add additional `option` definitions to the existing field.  These subsequent definitions
177should not provide the field bitmask as it has already been defined earlier in the file and
178this is just matching an existing field by name.
179
180	field <name> [option...] end
181
182This allows a baseboard to define the major fields and options in `devicetree.cb` and a board
183variant to add specific options to fields in or define new fields in the unused bitmask in
184`overridetree.cb`.
185
186It is not possible to redefine a field mask or override the value of an existing option this
187way, only to add new options to a field or new fields to the table.
188
189### Firmware Configuration Table Example
190
191In this example a baseboard defines a simple boolean feature that is enabled or disabled
192depending on the value of bit 0, and a field at bits 1-2 that indicates which daughter board
193is attached.
194
195The baseboard itself defines one daughter board and the variant adds two more possibilities.
196This way each variant can support multiple possible daughter boards in addition to the one
197that was defined by the baseboard.
198
199#### devicetree.cb
200
201    fw_config
202        field FEATURE 0
203            option DISABLED 0
204            option ENABLED 1
205        end
206        field DAUGHTER_BOARD 1 2
207            option NONE 0
208            option REFERENCE_DB 1
209        end
210    end
211
212#### overridetree.cb
213
214    fw_config
215        field DAUGHTER_BOARD
216            option VARIANT_DB_ONE 2
217            option VARIANT_DB_TWO 3
218        end
219    end
220
221The result of this table defined in `devicetree.cb` is a list of constants that can be used
222to check if fields match the firmware configuration options determined at runtime with a
223simple check of the field mask and the option value.
224
225#### static.h
226
227```c
228/* field: FEATURE */
229#define FW_CONFIG_FIELD_FEATURE_NAME "FEATURE"
230#define FW_CONFIG_FIELD_FEATURE_MASK 0x00000001
231#define FW_CONFIG_FIELD_FEATURE_OPTION_DISABLED_NAME "DISABLED"
232#define FW_CONFIG_FIELD_FEATURE_OPTION_DISABLED_VALUE 0x00000000
233#define FW_CONFIG_FIELD_FEATURE_OPTION_ENABLED_NAME "ENABLED"
234#define FW_CONFIG_FIELD_FEATURE_OPTION_ENABLED_VALUE 0x00000001
235
236/* field: DAUGHTER_BOARD */
237#define FW_CONFIG_FIELD_DAUGHTER_BOARD_NAME "DAUGHTER_BOARD"
238#define FW_CONFIG_FIELD_DAUGHTER_BOARD_MASK 0x00000006
239#define FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_NONE_NAME "NONE"
240#define FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_NONE_VALUE 0x00000000
241#define FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_REFERENCE_DB_NAME "REFERENCE_DB"
242#define FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_REFERENCE_DB_VALUE 0x00000002
243#define FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_VARIANT_DB_ONE_NAME "VARIANT_DB_ONE"
244#define FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_VARIANT_DB_ONE_VALUE 0x00000004
245#define FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_VARIANT_DB_TWO_NAME "VARIANT_DB_TWO"
246#define FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_VARIANT_DB_TWO_VALUE 0x00000006
247```
248
249## Device Probing
250
251One use of the firmware configuration interface in devicetree is to allow device probing to be
252specified directly with the devices themselves.  A new `probe` token is introduced to allow a
253device to be probed by field and option name.  Multiple `probe` entries may be present for
254each device and any successful probe will consider the device to be present.
255
256### Probing Example
257
258Continuing with the previous example this device would be considered present if the field
259`DAUGHTER_BOARD` was set to either `VARIANT_DB_ONE` or `VARIANT_DB_TWO`:
260
261#### overridetree.cb
262
263    chip drivers/generic/example
264        device generic 0 on
265            probe DAUGHTER_BOARD VARIANT_DB_ONE
266            probe DAUGHTER_BOARD VARIANT_DB_TWO
267        end
268    end
269
270If the field were set to any other option, including `NONE` and `REFERENCE_DB` and any
271undefined value then the device would be disabled.
272
273### Probe Overrides
274
275When a device is declared with a probe in the baseboard `devicetree.cb` and the same device
276is also present in the `overridetree.cb` then the probing information from the baseboard
277is discarded and the override device must provide all necessary probing information.
278
279In this example a device is listed in the baseboard with `DAUGHTER_BOARD` field probing for
280`REFERENCE_DB` as a field option,  It is also defined as an override device with the field
281probing for the `VARIANT_DB_ONE` option instead.
282
283In this case only the probe listed in the override is checked and a field option of
284`REFERENCE_DB` will not mark this device present.  If both options are desired then the
285override device must list both.  This allows an override device to remove a probe entry that
286was defined in the baseboard.
287
288#### devicetree.cb
289
290    chip drivers/generic/example
291	    device generic 0 on
292		    probe DAUGHTER_BOARD REFERENCE_DB
293	    end
294	end
295
296#### overridetree.cb
297
298    chip drivers/generic/example
299	    device generic 0 on
300		    probe DAUGHTER_BOARD VARIANT_DB_ONE
301	    end
302	end
303
304### Automatic Device Probing
305
306At boot time the firmware configuration interface will walk the device tree and apply any
307probe entries that were defined in `devicetree.cb`.  This probing takes effect before the
308`BS_DEV_ENUMERATE` step during the boot state machine in ramstage.
309
310Devices that have a probe list but do do not find a match are disabled by setting
311`dev->enabled = 0` but the chip `enable_dev()` and device `enable()` handlers will still
312be executed to allow any device disable code to execute.
313
314The result of this probe definition is to provide an array of structures describing each
315field and option to check.
316
317#### fw_config.h
318
319```c
320/**
321 * struct fw_config - Firmware configuration field and option.
322 * @field_name: Name of the field that this option belongs to.
323 * @option_name: Name of the option within this field.
324 * @mask: Bitmask of the field.
325 * @value: Value of the option within the mask.
326 */
327struct fw_config {
328	const char *field_name;
329	const char *option_name;
330	uint64_t mask;
331	uint64_t value;
332};
333```
334
335#### static.c
336
337```c
338STORAGE struct fw_config __devN_probe_list[] = {
339	{
340		.field_name = FW_CONFIG_FIELD_DAUGHTER_BOARD_NAME,
341		.option_name = FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_VARIANT_DB_ONE_NAME,
342		.mask = FW_CONFIG_FIELD_DAUGHTER_BOARD_MASK,
343		.value = FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_VARIANT_DB_ONE_VALUE
344	},
345	{
346		.field_name = FW_CONFIG_FIELD_DAUGHTER_BOARD_NAME,
347		.option_name = FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_VARIANT_DB_TWO_NAME,
348		.mask = FW_CONFIG_FIELD_DAUGHTER_BOARD_MASK,
349		.value = FW_CONFIG_FIELD_DAUGHTER_BOARD_OPTION_VARIANT_DB_TWO_VALUE
350	},
351	{ }
352};
353```
354
355### Runtime Probing
356
357The device driver probing allows for seamless integration with the mainboard but it is only
358effective in ramstage and for specific devices declared in devicetree.cb.  There are other
359situations where code may need to probe or check the value of a field in romstage or at other
360points in ramstage.  For this reason it is also possible to use the firmware configuration
361interface directly.
362
363```c
364/**
365 * fw_config_probe() - Check if field and option matches.
366 * @match: Structure containing field and option to probe.
367 *
368 * Return %true if match is found, %false if match is not found.
369 */
370bool fw_config_probe(const struct fw_config *match);
371```
372
373The argument provided to this function can be created from a macro for easy use:
374
375	FW_CONFIG(field, option)
376
377This example has a mainboard check if a feature is disabled and set an FSP UPD before memory
378training.  This example expects that the default value of this `register` is set to `true` in
379`devicetree.cb` and this code is disabling that feature before FSP is executed.
380
381```c
382#include <fw_config.h>
383
384void mainboard_memory_init_params(FSPM_UPD *mupd)
385{
386	if (fw_config_probe(FW_CONFIG(FEATURE, DISABLED))
387		mupd->ExampleFeature = false;
388}
389```
390