# Devicetree ## Introduction to the coreboot devicetree The first thing that may come to mind when one hears "DeviceTree" is a different sort of description file that is generally passed to the Linux kernel to describe a system's components. Both that devicetree and coreboot's devicetree serve fundamentally the same purpose, but are otherwise unrelated and have completely different syntax. The term devicetree was used long before either version was created, and was initially used in coreboot as a generic term. coreboot's devicetree's main use is to define and describe the runtime configuration and settings of the hardware on a board, chip or device level. It defines which of the functions of the chips on the board are enabled, and how they're configured. The devicetree file is parsed during the build process by a utility named `sconfig`, which translates the devicetree into a tree of C structures containing the included devices. This code is placed in the file `static.c` and a couple of header files, all under the `build` directory. This file is then built into the binaries for the various coreboot stages and is referred to during the coreboot boot process. For the early stages of the coreboot boot process, the data that is generated by `sconfig` is a useful resource, but this structure is the critical architectural glue of ramstage. This structure gets filled in with pointers to every chip's initialization code, allowing ramstage to find and initialize those devices through the `chip_operations` structures. ### History of coreboot's devicetree The initial devicetree in coreboot was introduced in 2003 by Ron Minnich as a part of the linuxbios config file, 'config.lb'. At this point both the devicetree and config options were in the same file. In 2009, when Kconfig was added into the coreboot build, devicetree was split out into its own file for each mainboard in a commit with this message: ```text devicetree.cb The devicetree that formerly resided in src/mainboard/*/*/Config.lb. Just without the build system crap ``` The devicetree structure was initially mainly used only in ramstage for PCI device enumeration, configuration and resource allocation. It has since expanded for use in the pre-ram stages as a read-only structure. The language used in the devicetree has been expanded greatly since it was first introduced as well, adding new features every year or so. ### Devicetree Registers In coreboot, the devicetree register setting is one of the two main methods used to configure a board's properties. In this way, devicetree is similar in function to Kconfig. It's more flexible in many ways as it can specify not only single values, but also arrays or structures. It's also even more static than Kconfig because there's no update mechanism for it other than editing the devicetree files. Chip-specific configuration values are often set using `register` definitions within a `chip` block, corresponding to a `struct` defined in the chip's `chip.h` file. For example, in a `chip drivers/gpio/acpi` block, you might set a GPE: ```text register "gpe0_sts" = "0x42" ``` ### Adding new static configuration options: Devicetree or Kconfig When adding options for a new board or chip, there is frequently a decision that needs to be made about how the option should be added. Using the devicetree or Kconfig are the two typical methods of build-time configuration. Below are some general guidelines on when to use each. Kconfig should be used if the option configures the build in a Makefile, or if the option is something that should be user selectable. Kconfig is also preferred if the configuration is a global option and not limited to a single chip. Another thing Kconfig excels at is handling decisions based on other configuration options, which devicetree cannot do. Devicetree should obviously be used to define the hardware hierarchy. It's also preferred if the option is only used in C code and is static for a mainboard, or if the option is chip-specific. As mentioned earlier, devicetree registers can also define structures or arrays, which Kconfig cannot. Both Kconfig and devicetree can be used in C code for runtime configuration, but there's a significant difference in how they are handled. Because Kconfig generates a `#define` for the choice, the compiler can eliminate code paths not used by the option. Devicetree options, however, are actual runtime selections, and the code for all choices remains in the final build. ## Basic Devicetree Syntax The coreboot devicetree uses a custom language parsed by the `sconfig` utility. Here's a brief overview of the main keywords and concepts: * **`chip `**: Defines a collection of devices associated with the code in the specified directory. `sconfig` may also parse a `chip.h` file within this directory for register definitions. * **`device [on|off] [alias ] ... end`**: Defines a specific hardware device. * ``: Specifies the device type (e.g., `pci`, `cpu_cluster`, `i2c`). * ``: A unique identifier for the device within its type/bus (e.g., PCI BDF `17.0`, I2C address `0x50`). * `on`/`off`: Enables or disables the device definition. * `alias `: Assigns a human-readable alias for referencing this device elsewhere (often used in `chipset.cb`). * `end`: Marks the end of the device definition block. Registers and other properties are defined between `device` and `end`. * **`register "" = `**: Sets the value of a configuration register defined in the corresponding `chip.h` structure. The value can be a number, string, or complex structure initialization. * **`probe