On Friday 29 July 2022 12:07:38 Tom Rini wrote: > Start by describing in general the best practices for how to implement > configuration of some aspect of U-Boot. This generally means finding > the right choices for when something should be static or dynamically > configured and enabled. Then further document when to use CONFIG or CFG > namespaces for static configuration. > > Signed-off-by: Tom Rini <tr...@konsulko.com> > --- > Changes in v3: > - Drop RFC prefix. > - Incorporate most of the specific wording changes Heinrich requested > against v2. > - Heinrich disliked the "namespace" wording in v2, and that in turn was > a hold over from when this talked only about CONFIG vs CFG. Remove > that word entirely and instead talk about configuration mechanisms. > Reword a number of sections and examples so that they read better or > hopefully more clearly now that we talk about different mechanisms. > - Expand on when to use each configuration mechanism. Generally don't > refer to CONFIG but instead Kconfig. > > RFCv2: > - Based on Pali's feedback, remove the README section and start a new > section in this document to cover when to use each namespace. Try and > be clear about when to use "hidden" Kconfig options rather than CFG as > well. > - Based on Heinrich's feedback, rename this to system_configuration.rst > and include some introductory remarks on when to use some dynamic or > static configuration. Link to the driver model code for dynamic > configuration and then explain the CONFIG vs CFG namespaces for static > configuration. > > RFCv1: > - This is essentially my idea on how to better handle the problem of > CONFIG values that just don't fit in Kconfig because it makes much > more sense to define them statically for a given SoC or calculate them > from other values, and so on. One example here would be to revert > c7fad78ec0ee ("Convert CONFIG_SYS_BR0_PRELIM et al to Kconfig") and > re-name these to CFG_SYS_.. instead. Another big example here would be > a global search-and-replace of 's/CONFIG_HPS_/CFG_HPS_/g' as that's > all tool-generated. Not all CONFIG_SYS_ options would get this as > boolean choices are well handled in Kconfig, and that may not be clear > enough in what I wrote here? > --- > README | 21 ----- > doc/develop/index.rst | 1 + > doc/develop/system_configuration.rst | 132 +++++++++++++++++++++++++++ > 3 files changed, 133 insertions(+), 21 deletions(-) > create mode 100644 doc/develop/system_configuration.rst > > diff --git a/README b/README > index 2c4bde0b3297..623f35907217 100644 > --- a/README > +++ b/README > @@ -166,27 +166,6 @@ Directory Hierarchy: > Software Configuration: > ======================= > > -Configuration is usually done using C preprocessor defines; the > -rationale behind that is to avoid dead code whenever possible. > - > -There are two classes of configuration variables: > - > -* Configuration _OPTIONS_: > - These are selectable by the user and have names beginning with > - "CONFIG_". > - > -* Configuration _SETTINGS_: > - These depend on the hardware etc. and should not be meddled with if > - you don't know what you're doing; they have names beginning with > - "CONFIG_SYS_". > - > -Previously, all configuration was done by hand, which involved creating > -symbolic links and editing configuration files manually. More recently, > -U-Boot has added the Kbuild infrastructure used by the Linux kernel, > -allowing you to use the "make menuconfig" command to configure your > -build. > - > - > Selection of Processor Architecture and Board Type: > --------------------------------------------------- > > diff --git a/doc/develop/index.rst b/doc/develop/index.rst > index 73741ceb6a2f..7c41e3f1b6e5 100644 > --- a/doc/develop/index.rst > +++ b/doc/develop/index.rst > @@ -13,6 +13,7 @@ General > designprinciples > process > release_cycle > + system_configuration > > Implementation > -------------- > diff --git a/doc/develop/system_configuration.rst > b/doc/develop/system_configuration.rst > new file mode 100644 > index 000000000000..1279d12cb7ae > --- /dev/null > +++ b/doc/develop/system_configuration.rst > @@ -0,0 +1,132 @@ > +.. SPDX-License-Identifier: GPL-2.0+ > + > +System configuration > +==================== > + > +There are a number of different aspects to configuring U-Boot to build and > then > +run on a given platform or set of platforms. Broadly speaking, some aspects > of > +the world can be configured at run time and others must be done at build > time. > +In general run time configuration is preferred over build time configuration. > +But when making these decisions, we also need to consider if we're talking > about > +a feature that could be useful to virtually every platform or something > specific > +to a single hardware platform. The resulting image size is also another > +important consideration. Finally, run time configuration has additional > overhead > +both in terms of resource requirements and wall clock time. All of this means > +that care must be taken when writing new code to select the most appropriate > +configuration mechanism. > + > +When adding new features to U-Boot, be they a new subsystem or SoC support or > +new platform for an existing supported SoC, the preferred configuration order > +is: > + > +#. Hardware based run time configuration. Examples of this include reading > + processor specific registers, or a set of board specific GPIOs or an > EEPROM > + with a known format to it. These are the cases where we either cannot or > + should not be relying on device tree checks. We use this for cases such as > + optimized boot time or starting with a generic device tree and then > enabling > + or disabling features as we boot. > + > +#. Making use of our Kconfig infrastructure and C preprocessor macros that > have > + the prefix ``CONFIG``. This is the primary method of build time > + configuration. This is generally the best fit for when we want to enable > or > + disable some sort of feature, such as the SoC or network support. The > + ``CONFIG`` prefix for C preprocessor macros is strictly reserved for > Kconfig > + usage only. > + > +#. Making use of the :doc:`device tree <devicetree/control>` to determine at > + run time how to configure a feature that we have enabled via Kconfig. For > + example, we would use Kconfig to enable an i2c chip driver, but use the > device > + tree to know where the i2c chip resides in memory and other details we > need > + in order to configure the bus. > + > +#. Making use of C header files directly and defining C preprocessor macros > that > + have the ``CFG`` prefix. While the ``CFG`` prefix is reserved for this > build > + time configuration mechanism, the usage is ad hoc. This is to be used > when the > + previously mentioned mechanisms are not possible, or for legacy code that > has > + not been converted. > + > +Dynamic run time configuration methods. > +--------------------------------------- > + > +Details of hardware specific run time configuration methods are found within > the > +documentation for a given processor family or board. > + > +Details of how to use run time configuration based on :doc:`driver model > +<driver-model/index>` are covered in that documentation section. > + > +Static build time configuration methods > +--------------------------------------- > + > +There are two mechanisms used to control the build time configuration of > U-Boot. > +One is utilizing Kconfig and ``CONFIG`` prefixed macros and the other is ad > hoc > +usage of ``CFG`` prefixed macros. Both of these are used when it is either > not > +possible or not practical to make a run time determination about some > +functionality of the hardware or a required software feature or similar. > Each of > +these has their own places where they are better suited than the other for > use. > + > +The `Kconfig language > +<https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html>`_ is > well > +documented and used in a number of projects, including the Linux kernel. We > +implement this with the Kconfig files found throughout our sources. This > +mechanism is the preferred way of exposing new configuration options as there > +are a number of ways for both users and system integrators to manage and > change > +these options. Some common examples here are to enable a specific command > within > +U-Boot or even a whole subsystem such as NAND flash or network connectivity. > + > +The ``CFG`` mechanism is implemented directly as C preprocessor values or > +macros, depending on what they are in turn describing. While we have some > +functionality that is very reasonable to expose to the end user to enable or > +disable we have other places where we need to describe things such as > register > +locations or values, memory map ranges and so on. When practical, we should > be > +getting these values from the device tree. However, there are cases where > this > +is either not practical due to when we need the information and may not have > a > +device tree yet or due to legacy reasons code has not been rewritten. > + > +When to use each mechanism > +^^^^^^^^^^^^^^^^^^^^^^^^^^ > + > +While there are some cases where it should be fairly obvious where to use > each > +namespace, as for example a command would done via Kconfig, a new i2c driver > +should use Kconfig and be configured via driver model and a header of values > +generated by an external tool should be ``CFG``, there will be cases where > it's > +less clear and one needs to take care when implementing it. In general, > +configuration *options* should be done in Kconfig and configuration > *settings* > +should done in driver model or ``CFG``. Let us discuss things to keep in mind > +when picking the appropriate mechanism. > + > +A thing to keep in mind is that we have a strong preference for using > Kconfig as > +the primary build time configuration mechanism. Options expressed this way > let > +us easily express dependencies and abstractions. In addition, given that many > +projects use this mechanism means it has a broad set of tooling and existing > +knowledge base. > + > +Consider the example of a SHA256 hardware acceleration engine. This would be > a > +feature of the SoC and so something to not ask the user if it exists, but we > +would want to have our generic framework for such engines be optionally > +available and depend on knowing we have this engine on a given hardware > +platform. Expressing this should be done as a hidden Kconfig symbol that is > +``select``'ed by the SoC symbol which would in turn be ``select``'ed by the > +board option, which is user visible. Hardware features that are either > present > +or not present should be expressed in Kconfig and in a similar manner, > features > +which will always have a constant value such as "this SoC always has 4 cores > and > +4 threads per core" should be as well. > + > +This brings us to differentiating between a configuration *setting* versus a > +hardware feature. To build on the previous example, while we may know the > number > +of cores and threads, it's possible that within a given family of SoCs the > base > +addresses of peripherals has changed, but the register offsets within have > not. > +The preference in this case is to get our information from the device tree > and > +perform run time configuration. However, this is not always practical and in > +those cases we instead rely on the ``CFG`` mechanism. While it would be > possible > +to use Kconfig in this case, it would result in using calculated rather than > +constructed values, resulting in less clear code. Consider the example of a > set > +of register values for a memory controller. Defining this as a series of > logical > +ORs and shifts based on other defines is more clear than the Kconfig entry > that > +set the calculated value alone. > + > +When it has been determined that the practical solution is to utilize the > +``CFG`` mechanism, the next decision is where to place these settings. It is > +strongly encouraged to place these in the architecture header files, if they > are > +generic to a given SoC, or under the board directory if board specific. > Placing > +them under the board.h file in the *include/configs/* directory should be > seen > +as a last resort. > -- > 2.25.1 >
Acked-by: Pali Rohár <p...@kernel.org>