Tom Rini | 486c5ef | 2022-07-29 12:07:38 -0400 | [diff] [blame] | 1 | .. SPDX-License-Identifier: GPL-2.0+ |
| 2 | |
| 3 | System configuration |
| 4 | ==================== |
| 5 | |
| 6 | There are a number of different aspects to configuring U-Boot to build and then |
| 7 | run on a given platform or set of platforms. Broadly speaking, some aspects of |
| 8 | the world can be configured at run time and others must be done at build time. |
| 9 | In general run time configuration is preferred over build time configuration. |
| 10 | But when making these decisions, we also need to consider if we're talking about |
| 11 | a feature that could be useful to virtually every platform or something specific |
| 12 | to a single hardware platform. The resulting image size is also another |
| 13 | important consideration. Finally, run time configuration has additional overhead |
| 14 | both in terms of resource requirements and wall clock time. All of this means |
| 15 | that care must be taken when writing new code to select the most appropriate |
| 16 | configuration mechanism. |
| 17 | |
| 18 | When adding new features to U-Boot, be they a new subsystem or SoC support or |
| 19 | new platform for an existing supported SoC, the preferred configuration order |
| 20 | is: |
| 21 | |
| 22 | #. Hardware based run time configuration. Examples of this include reading |
| 23 | processor specific registers, or a set of board specific GPIOs or an EEPROM |
| 24 | with a known format to it. These are the cases where we either cannot or |
| 25 | should not be relying on device tree checks. We use this for cases such as |
| 26 | optimized boot time or starting with a generic device tree and then enabling |
| 27 | or disabling features as we boot. |
| 28 | |
| 29 | #. Making use of our Kconfig infrastructure and C preprocessor macros that have |
| 30 | the prefix ``CONFIG``. This is the primary method of build time |
| 31 | configuration. This is generally the best fit for when we want to enable or |
| 32 | disable some sort of feature, such as the SoC or network support. The |
| 33 | ``CONFIG`` prefix for C preprocessor macros is strictly reserved for Kconfig |
| 34 | usage only. |
| 35 | |
| 36 | #. Making use of the :doc:`device tree <devicetree/control>` to determine at |
| 37 | run time how to configure a feature that we have enabled via Kconfig. For |
| 38 | example, we would use Kconfig to enable an I2C chip driver, but use the device |
| 39 | tree to know where the I2C chip resides in memory and other details we need |
| 40 | in order to configure the bus. |
| 41 | |
| 42 | #. Making use of C header files directly and defining C preprocessor macros that |
| 43 | have the ``CFG`` prefix. While the ``CFG`` prefix is reserved for this build |
| 44 | time configuration mechanism, the usage is ad hoc. This is to be used when the |
| 45 | previously mentioned mechanisms are not possible, or for legacy code that has |
| 46 | not been converted. |
| 47 | |
| 48 | Dynamic run time configuration methods. |
| 49 | --------------------------------------- |
| 50 | |
| 51 | Details of hardware specific run time configuration methods are found within the |
| 52 | documentation for a given processor family or board. |
| 53 | |
| 54 | Details of how to use run time configuration based on :doc:`driver model |
| 55 | <driver-model/index>` are covered in that documentation section. |
| 56 | |
| 57 | Static build time configuration methods |
| 58 | --------------------------------------- |
| 59 | |
| 60 | There are two mechanisms used to control the build time configuration of U-Boot. |
| 61 | One is utilizing Kconfig and ``CONFIG`` prefixed macros and the other is ad hoc |
| 62 | usage of ``CFG`` prefixed macros. Both of these are used when it is either not |
| 63 | possible or not practical to make a run time determination about some |
| 64 | functionality of the hardware or a required software feature or similar. Each of |
| 65 | these has their own places where they are better suited than the other for use. |
| 66 | |
| 67 | The `Kconfig language |
| 68 | <https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html>`_ is well |
| 69 | documented and used in a number of projects, including the Linux kernel. We |
| 70 | implement this with the Kconfig files found throughout our sources. This |
| 71 | mechanism is the preferred way of exposing new configuration options as there |
| 72 | are a number of ways for both users and system integrators to manage and change |
| 73 | these options. Some common examples here are to enable a specific command within |
| 74 | U-Boot or even a whole subsystem such as NAND flash or network connectivity. |
| 75 | |
| 76 | The ``CFG`` mechanism is implemented directly as C preprocessor values or |
| 77 | macros, depending on what they are in turn describing. While we have some |
| 78 | functionality that is very reasonable to expose to the end user to enable or |
| 79 | disable we have other places where we need to describe things such as register |
| 80 | locations or values, memory map ranges and so on. When practical, we should be |
| 81 | getting these values from the device tree. However, there are cases where this |
| 82 | is either not practical due to when we need the information and may not have a |
| 83 | device tree yet or due to legacy reasons code has not been rewritten. |
| 84 | |
| 85 | When to use each mechanism |
| 86 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 87 | |
| 88 | While there are some cases where it should be fairly obvious where to use each |
Maxim Cournoyer | 4322898 | 2022-12-16 21:09:40 -0500 | [diff] [blame] | 89 | mechanism, as for example a command would be done via Kconfig, a new I2C driver |
Tom Rini | 486c5ef | 2022-07-29 12:07:38 -0400 | [diff] [blame] | 90 | should use Kconfig and be configured via driver model and a header of values |
| 91 | generated by an external tool should be ``CFG``, there will be cases where it's |
| 92 | less clear and one needs to take care when implementing it. In general, |
| 93 | configuration *options* should be done in Kconfig and configuration *settings* |
Maxim Cournoyer | 4322898 | 2022-12-16 21:09:40 -0500 | [diff] [blame] | 94 | should be done in driver model or ``CFG``. Let us discuss things to keep in mind |
Tom Rini | 486c5ef | 2022-07-29 12:07:38 -0400 | [diff] [blame] | 95 | when picking the appropriate mechanism. |
| 96 | |
| 97 | A thing to keep in mind is that we have a strong preference for using Kconfig as |
| 98 | the primary build time configuration mechanism. Options expressed this way let |
| 99 | us easily express dependencies and abstractions. In addition, given that many |
| 100 | projects use this mechanism means it has a broad set of tooling and existing |
| 101 | knowledge base. |
| 102 | |
| 103 | Consider the example of a SHA256 hardware acceleration engine. This would be a |
| 104 | feature of the SoC and so something to not ask the user if it exists, but we |
| 105 | would want to have our generic framework for such engines be optionally |
| 106 | available and depend on knowing we have this engine on a given hardware |
| 107 | platform. Expressing this should be done as a hidden Kconfig symbol that is |
| 108 | ``select``'ed by the SoC symbol which would in turn be ``select``'ed by the |
| 109 | board option, which is user visible. Hardware features that are either present |
| 110 | or not present should be expressed in Kconfig and in a similar manner, features |
| 111 | which will always have a constant value such as "this SoC always has 4 cores and |
| 112 | 4 threads per core" should be as well. |
| 113 | |
| 114 | This brings us to differentiating between a configuration *setting* versus a |
| 115 | hardware feature. To build on the previous example, while we may know the number |
| 116 | of cores and threads, it's possible that within a given family of SoCs the base |
| 117 | addresses of peripherals has changed, but the register offsets within have not. |
| 118 | The preference in this case is to get our information from the device tree and |
| 119 | perform run time configuration. However, this is not always practical and in |
| 120 | those cases we instead rely on the ``CFG`` mechanism. While it would be possible |
| 121 | to use Kconfig in this case, it would result in using calculated rather than |
| 122 | constructed values, resulting in less clear code. Consider the example of a set |
| 123 | of register values for a memory controller. Defining this as a series of logical |
| 124 | ORs and shifts based on other defines is more clear than the Kconfig entry that |
Maxim Cournoyer | 4322898 | 2022-12-16 21:09:40 -0500 | [diff] [blame] | 125 | sets the calculated value alone. |
Tom Rini | 486c5ef | 2022-07-29 12:07:38 -0400 | [diff] [blame] | 126 | |
| 127 | When it has been determined that the practical solution is to utilize the |
| 128 | ``CFG`` mechanism, the next decision is where to place these settings. It is |
| 129 | strongly encouraged to place these in the architecture header files, if they are |
| 130 | generic to a given SoC, or under the board directory if board specific. Placing |
| 131 | them under the board.h file in the *include/configs/* directory should be seen |
| 132 | as a last resort. |