All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFCv2] doc: develop: Describe system configuration
@ 2022-07-28 18:53 Tom Rini
  2022-07-28 19:05 ` Pali Rohár
  2022-07-29  7:03 ` Heinrich Schuchardt
  0 siblings, 2 replies; 10+ messages in thread
From: Tom Rini @ 2022-07-28 18:53 UTC (permalink / raw)
  To: u-boot; +Cc: Pali Rohár, Simon Glass, Heinrich Schuchardt

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 <trini@konsulko.com>
---
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 | 121 +++++++++++++++++++++++++++
 3 files changed, 122 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..bb09d1f974d4
--- /dev/null
+++ b/doc/develop/system_configuration.rst
@@ -0,0 +1,121 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+U-Boot 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 is preferred over build time. But when making these
+decision, we also need to consider if we're talking about 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, the overall requirements of being able to do run time detection will
+have an impact on if it's possible or not.
+
+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:
+
+#. Simple run time. One example here are chip revision checks. Another is
+   knowing that we've checked GPIOs and are on revision B of a platform, rather
+   than doing a more expensive device tree check. This allows us to use a single
+   device tree for revision A and B in this case and perform fixups as needed
+   rather than storing two device trees.
+
+#. Making use of our Kconfig infrastructure and the ``CONFIG`` namespace. The
+   primary method of build time configuration is done via the ``CONFIG``
+   namespace and Kconfig infrastructure. 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.
+
+#. 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 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 the ``CFG`` namespace. This is
+   useful when for various reasons we cannot get configuration values that we
+   need from the device tree so instead have them defined in a header and use
+   the prefix ``CFG_`` in their definition.
+
+Dynamic run time configuration methods.
+---------------------------------------
+
+For more information in general on how to make use of this please start with the
+:doc:`driver model <driver-model/index>` documentation.
+
+Static build time configuration methods
+---------------------------------------
+
+There are two namespaces used to control the build time configuration of
+U-Boot, ``CONFIG`` and ``CFG``. 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 first of these, ``CONFIG``` is managed in the `Kconfig language
+<https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html>`_ that is
+most commonly associated with the Linux kernel and the Kconfig files found
+throughout our sources. Adding options to this namespace 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 second of these, ``CFG`` is implemented directly as C preprocessor values or
+macros, depending on what they are in turn describing. The nature of U-Boot
+means that 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 namespace
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+While there are some cases where it should be fairly obvious where to use each
+namespace, as for example a command would be ``CONFIG`` 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. In general,
+configuration *options* should be ``CONFIG`` and configuration *settings* should
+be ``CFG``. Since it is not always clear however, let us discuss things to
+keep in mind when adding to either namespace.
+
+A thing to keep in mind is that we have a strong preference for using the
+``CONFIG`` namespace first. Options expressed this way let us make use of the
+Kconfig language to express dependencies and abstractions. 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 symbol that is ``select``'ed by the SoC symbol which would in turn
+be ``select``'ed by the board option, which is user visible. This means that
+hardware features that are either present or not present should be in the
+``CONFIG`` namespace 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.
+And for practical reasons, we cannot get this information at run time from the
+device tree. This is a case where it is reasonable to instead make use of the
+``CFG`` namespace and that it is pure C preprocessor macros to define that
+``CFG_SYS_FOO_REG`` is ``(CFG_SYS_FOO_BASE + 0x200)`` and have blocks of those
+under ``#if defined(CONFIG_SOC_FOO1) ... #elif defined(CONFIG_SOC_FOO2) ...
+#endif`` in a system header file. Another example here is register values. Often
+it will make the most sense to construct these from other values and then using
+masks and shifts to turn a list of "magic values" in to something that is easier
+for humans to parse as well.
+
+When it has been determined that the practical solution for where to have
+something is in the ``CFG`` namespace, 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


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [RFCv2] doc: develop: Describe system configuration
  2022-07-28 18:53 [RFCv2] doc: develop: Describe system configuration Tom Rini
@ 2022-07-28 19:05 ` Pali Rohár
  2022-07-28 19:18   ` Tom Rini
  2022-07-29  7:03 ` Heinrich Schuchardt
  1 sibling, 1 reply; 10+ messages in thread
From: Pali Rohár @ 2022-07-28 19:05 UTC (permalink / raw)
  To: Tom Rini; +Cc: u-boot, Simon Glass, Heinrich Schuchardt

On Thursday 28 July 2022 14:53:49 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 <trini@konsulko.com>
> ---
> 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 | 121 +++++++++++++++++++++++++++
>  3 files changed, 122 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..bb09d1f974d4
> --- /dev/null
> +++ b/doc/develop/system_configuration.rst
> @@ -0,0 +1,121 @@
> +.. SPDX-License-Identifier: GPL-2.0+
> +
> +U-Boot 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 is preferred over build time. But when making these
> +decision, we also need to consider if we're talking about 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, the overall requirements of being able to do run time detection will
> +have an impact on if it's possible or not.
> +
> +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:
> +
> +#. Simple run time. One example here are chip revision checks. Another is
> +   knowing that we've checked GPIOs and are on revision B of a platform, rather
> +   than doing a more expensive device tree check. This allows us to use a single
> +   device tree for revision A and B in this case and perform fixups as needed
> +   rather than storing two device trees.
> +
> +#. Making use of our Kconfig infrastructure and the ``CONFIG`` namespace. The
> +   primary method of build time configuration is done via the ``CONFIG``
> +   namespace and Kconfig infrastructure. 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.
> +
> +#. 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 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 the ``CFG`` namespace. This is
> +   useful when for various reasons we cannot get configuration values that we
> +   need from the device tree so instead have them defined in a header and use
> +   the prefix ``CFG_`` in their definition.
> +
> +Dynamic run time configuration methods.
> +---------------------------------------
> +
> +For more information in general on how to make use of this please start with the
> +:doc:`driver model <driver-model/index>` documentation.
> +
> +Static build time configuration methods
> +---------------------------------------
> +
> +There are two namespaces used to control the build time configuration of
> +U-Boot, ``CONFIG`` and ``CFG``. 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 first of these, ``CONFIG``` is managed in the `Kconfig language
> +<https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html>`_ that is
> +most commonly associated with the Linux kernel and the Kconfig files found
> +throughout our sources. Adding options to this namespace 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 second of these, ``CFG`` is implemented directly as C preprocessor values or
> +macros, depending on what they are in turn describing. The nature of U-Boot
> +means that 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 namespace
> +^^^^^^^^^^^^^^^^^^^^^^^^^^
> +
> +While there are some cases where it should be fairly obvious where to use each
> +namespace, as for example a command would be ``CONFIG`` 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. In general,
> +configuration *options* should be ``CONFIG`` and configuration *settings* should
> +be ``CFG``. Since it is not always clear however, let us discuss things to
> +keep in mind when adding to either namespace.
> +
> +A thing to keep in mind is that we have a strong preference for using the
> +``CONFIG`` namespace first. Options expressed this way let us make use of the
> +Kconfig language to express dependencies and abstractions. 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 symbol that is ``select``'ed by the SoC symbol which would in turn
> +be ``select``'ed by the board option, which is user visible. This means that
> +hardware features that are either present or not present should be in the
> +``CONFIG`` namespace 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.
> +And for practical reasons, we cannot get this information at run time from the
> +device tree. This is a case where it is reasonable to instead make use of the
> +``CFG`` namespace and that it is pure C preprocessor macros to define that
> +``CFG_SYS_FOO_REG`` is ``(CFG_SYS_FOO_BASE + 0x200)`` and have blocks of those
> +under ``#if defined(CONFIG_SOC_FOO1) ... #elif defined(CONFIG_SOC_FOO2) ...
> +#endif`` in a system header file. Another example here is register values. Often
> +it will make the most sense to construct these from other values and then using
> +masks and shifts to turn a list of "magic values" in to something that is easier
> +for humans to parse as well.
> +
> +When it has been determined that the practical solution for where to have
> +something is in the ``CFG`` namespace, 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
> 

Sounds good.

The only missing bit of information for me, which I really do not know
still remain... Where, how and in which format to store board specific
CFG option which is required for architecture or SoC for proper setup?

It cannot be in board/ subdir because arch/ code cannot use it (and even
do not know which include file should use). It cannot be in arch/ subdir
because it is SoC specific (e.g. arch would have to use long spaghetti
#if defined(BOARD_1) ... #elif defined(BOARD_2) ... #endif block). And
it cannot be in include/configs/ because you do not like it and do not
want it here.

Currently this issue is _un_solved by using CONFIG option either in
Kconfig or in include/configs/ ... and both options are not ideal.

I just do not see how to solve this problem.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFCv2] doc: develop: Describe system configuration
  2022-07-28 19:05 ` Pali Rohár
@ 2022-07-28 19:18   ` Tom Rini
  2022-07-28 19:21     ` Pali Rohár
  0 siblings, 1 reply; 10+ messages in thread
From: Tom Rini @ 2022-07-28 19:18 UTC (permalink / raw)
  To: Pali Rohár; +Cc: u-boot, Simon Glass, Heinrich Schuchardt

[-- Attachment #1: Type: text/plain, Size: 2203 bytes --]

On Thu, Jul 28, 2022 at 09:05:07PM +0200, Pali Rohár wrote:
> On Thursday 28 July 2022 14:53:49 Tom Rini wrote:
[snip]
> > +When it has been determined that the practical solution for where to have
> > +something is in the ``CFG`` namespace, 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.
> 
> Sounds good.
> 
> The only missing bit of information for me, which I really do not know
> still remain... Where, how and in which format to store board specific
> CFG option which is required for architecture or SoC for proper setup?
> 
> It cannot be in board/ subdir because arch/ code cannot use it (and even
> do not know which include file should use). It cannot be in arch/ subdir
> because it is SoC specific (e.g. arch would have to use long spaghetti
> #if defined(BOARD_1) ... #elif defined(BOARD_2) ... #endif block). And
> it cannot be in include/configs/ because you do not like it and do not
> want it here.
> 
> Currently this issue is _un_solved by using CONFIG option either in
> Kconfig or in include/configs/ ... and both options are not ideal.
> 
> I just do not see how to solve this problem.

I think it's fine to have things in quite literally <asm/arch/soc.h>
(which we have a few of already) and then as needed #if / #elif / #endif
for SoC changes.  Much of this _could_ be instead pulled from device
trees.  But that's unlikely to happen for a number of platforms.  And
for the board specific cases which are not converted to come out of
device tree, include/configs/board.h isn't going to be able to go away
for that platform just yet.

So in a round about way, yes, I'm just punting on the problem because I
suspect the "right" answer is converting to driver model in a more
complete way and pulling the information from the device tree.  But I
accept there's not a desire on anyones part to invest that much time in
a dead end platform.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFCv2] doc: develop: Describe system configuration
  2022-07-28 19:18   ` Tom Rini
@ 2022-07-28 19:21     ` Pali Rohár
  2022-07-28 19:26       ` Tom Rini
  0 siblings, 1 reply; 10+ messages in thread
From: Pali Rohár @ 2022-07-28 19:21 UTC (permalink / raw)
  To: Tom Rini; +Cc: u-boot, Simon Glass, Heinrich Schuchardt

On Thursday 28 July 2022 15:18:03 Tom Rini wrote:
> On Thu, Jul 28, 2022 at 09:05:07PM +0200, Pali Rohár wrote:
> > On Thursday 28 July 2022 14:53:49 Tom Rini wrote:
> [snip]
> > > +When it has been determined that the practical solution for where to have
> > > +something is in the ``CFG`` namespace, 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.
> > 
> > Sounds good.
> > 
> > The only missing bit of information for me, which I really do not know
> > still remain... Where, how and in which format to store board specific
> > CFG option which is required for architecture or SoC for proper setup?
> > 
> > It cannot be in board/ subdir because arch/ code cannot use it (and even
> > do not know which include file should use). It cannot be in arch/ subdir
> > because it is SoC specific (e.g. arch would have to use long spaghetti
> > #if defined(BOARD_1) ... #elif defined(BOARD_2) ... #endif block). And
> > it cannot be in include/configs/ because you do not like it and do not
> > want it here.
> > 
> > Currently this issue is _un_solved by using CONFIG option either in
> > Kconfig or in include/configs/ ... and both options are not ideal.
> > 
> > I just do not see how to solve this problem.
> 
> I think it's fine to have things in quite literally <asm/arch/soc.h>
> (which we have a few of already) and then as needed #if / #elif / #endif
> for SoC changes.  Much of this _could_ be instead pulled from device
> trees.  But that's unlikely to happen for a number of platforms.  And
> for the board specific cases which are not converted to come out of
> device tree, include/configs/board.h isn't going to be able to go away
> for that platform just yet.
> 
> So in a round about way, yes, I'm just punting on the problem because I
> suspect the "right" answer is converting to driver model in a more
> complete way and pulling the information from the device tree.  But I
> accept there's not a desire on anyones part to invest that much time in
> a dead end platform.
> 
> -- 
> Tom

Driver model and device tree is probably the better place. But in case
such option is required for SoC setup to allow U-Boot to access device
tree then it cannot be in device tree...

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFCv2] doc: develop: Describe system configuration
  2022-07-28 19:21     ` Pali Rohár
@ 2022-07-28 19:26       ` Tom Rini
  2022-07-28 19:43         ` Pali Rohár
  0 siblings, 1 reply; 10+ messages in thread
From: Tom Rini @ 2022-07-28 19:26 UTC (permalink / raw)
  To: Pali Rohár; +Cc: u-boot, Simon Glass, Heinrich Schuchardt

[-- Attachment #1: Type: text/plain, Size: 3191 bytes --]

On Thu, Jul 28, 2022 at 09:21:52PM +0200, Pali Rohár wrote:
> On Thursday 28 July 2022 15:18:03 Tom Rini wrote:
> > On Thu, Jul 28, 2022 at 09:05:07PM +0200, Pali Rohár wrote:
> > > On Thursday 28 July 2022 14:53:49 Tom Rini wrote:
> > [snip]
> > > > +When it has been determined that the practical solution for where to have
> > > > +something is in the ``CFG`` namespace, 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.
> > > 
> > > Sounds good.
> > > 
> > > The only missing bit of information for me, which I really do not know
> > > still remain... Where, how and in which format to store board specific
> > > CFG option which is required for architecture or SoC for proper setup?
> > > 
> > > It cannot be in board/ subdir because arch/ code cannot use it (and even
> > > do not know which include file should use). It cannot be in arch/ subdir
> > > because it is SoC specific (e.g. arch would have to use long spaghetti
> > > #if defined(BOARD_1) ... #elif defined(BOARD_2) ... #endif block). And
> > > it cannot be in include/configs/ because you do not like it and do not
> > > want it here.
> > > 
> > > Currently this issue is _un_solved by using CONFIG option either in
> > > Kconfig or in include/configs/ ... and both options are not ideal.
> > > 
> > > I just do not see how to solve this problem.
> > 
> > I think it's fine to have things in quite literally <asm/arch/soc.h>
> > (which we have a few of already) and then as needed #if / #elif / #endif
> > for SoC changes.  Much of this _could_ be instead pulled from device
> > trees.  But that's unlikely to happen for a number of platforms.  And
> > for the board specific cases which are not converted to come out of
> > device tree, include/configs/board.h isn't going to be able to go away
> > for that platform just yet.
> > 
> > So in a round about way, yes, I'm just punting on the problem because I
> > suspect the "right" answer is converting to driver model in a more
> > complete way and pulling the information from the device tree.  But I
> > accept there's not a desire on anyones part to invest that much time in
> > a dead end platform.
> 
> Driver model and device tree is probably the better place. But in case
> such option is required for SoC setup to allow U-Boot to access device
> tree then it cannot be in device tree...

I guess I need an example value or two please, that can't reside in
<arch/asm/soc.h> nor can be delayed long enough to come from the device
tree instead.

One thing that we can and do in some platforms do today is have SPL use
a correct-enough simplified device tree so we always enable enough
clocks/mux to have GPIOs work to determine the real rev we're on and
pass the correct tree to full U-Boot.  I don't think we have the hooks
to re-evaluate the tree in full U-Boot, but perhaps we do need that.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFCv2] doc: develop: Describe system configuration
  2022-07-28 19:26       ` Tom Rini
@ 2022-07-28 19:43         ` Pali Rohár
  2022-07-28 21:27           ` Tom Rini
  0 siblings, 1 reply; 10+ messages in thread
From: Pali Rohár @ 2022-07-28 19:43 UTC (permalink / raw)
  To: Tom Rini; +Cc: u-boot, Simon Glass, Heinrich Schuchardt

On Thursday 28 July 2022 15:26:08 Tom Rini wrote:
> On Thu, Jul 28, 2022 at 09:21:52PM +0200, Pali Rohár wrote:
> > On Thursday 28 July 2022 15:18:03 Tom Rini wrote:
> > > On Thu, Jul 28, 2022 at 09:05:07PM +0200, Pali Rohár wrote:
> > > > On Thursday 28 July 2022 14:53:49 Tom Rini wrote:
> > > [snip]
> > > > > +When it has been determined that the practical solution for where to have
> > > > > +something is in the ``CFG`` namespace, 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.
> > > > 
> > > > Sounds good.
> > > > 
> > > > The only missing bit of information for me, which I really do not know
> > > > still remain... Where, how and in which format to store board specific
> > > > CFG option which is required for architecture or SoC for proper setup?
> > > > 
> > > > It cannot be in board/ subdir because arch/ code cannot use it (and even
> > > > do not know which include file should use). It cannot be in arch/ subdir
> > > > because it is SoC specific (e.g. arch would have to use long spaghetti
> > > > #if defined(BOARD_1) ... #elif defined(BOARD_2) ... #endif block). And
> > > > it cannot be in include/configs/ because you do not like it and do not
> > > > want it here.
> > > > 
> > > > Currently this issue is _un_solved by using CONFIG option either in
> > > > Kconfig or in include/configs/ ... and both options are not ideal.
> > > > 
> > > > I just do not see how to solve this problem.
> > > 
> > > I think it's fine to have things in quite literally <asm/arch/soc.h>
> > > (which we have a few of already) and then as needed #if / #elif / #endif
> > > for SoC changes.  Much of this _could_ be instead pulled from device
> > > trees.  But that's unlikely to happen for a number of platforms.  And
> > > for the board specific cases which are not converted to come out of
> > > device tree, include/configs/board.h isn't going to be able to go away
> > > for that platform just yet.
> > > 
> > > So in a round about way, yes, I'm just punting on the problem because I
> > > suspect the "right" answer is converting to driver model in a more
> > > complete way and pulling the information from the device tree.  But I
> > > accept there's not a desire on anyones part to invest that much time in
> > > a dead end platform.
> > 
> > Driver model and device tree is probably the better place. But in case
> > such option is required for SoC setup to allow U-Boot to access device
> > tree then it cannot be in device tree...
> 
> I guess I need an example value or two please, that can't reside in
> <arch/asm/soc.h> nor can be delayed long enough to come from the device
> tree instead.

For example those powerpc preliminary local bus settings which
configures boot device memory mappings. Boot source is chosen by user
(currently by selecting appropriate defconfig file). It is something
which is board specific (based on board wiring), for each boot source
different and instruct u-boot in early stage to correctly map remaining
part of u-boot binary where is stored DTB blob.

I can imagine such #if / #elif / #elfi / .... block in som arch/ file
with more extensions to include also sub-#if block for boot source...
but well such monster #ifdef hell is unmaintainable.

Look for example how many defconfig files are there for P[12]* boards.
For every one you would have to introduce #elif chain.

But this is just an example. I can imagine similar issues on other
platforms which have RDB boards with tons of boot source options.

I know also ARM64 based boards which have boot strapping options to skip
integrated BootROM and start booting directly from CS or other device
local bus.

> One thing that we can and do in some platforms do today is have SPL use
> a correct-enough simplified device tree so we always enable enough
> clocks/mux to have GPIOs work to determine the real rev we're on and
> pass the correct tree to full U-Boot.  I don't think we have the hooks
> to re-evaluate the tree in full U-Boot, but perhaps we do need that.
> 
> -- 
> Tom

We have such hooks, in proper U-Boot it is possible to do small
modifications in DTB blob prior binding drivers. I'm preparing patches
for Omnia board which use this feature. So it is not only possible but
it is already working.

But in case device tree is not accessible yet (due to very early stage)
then such hooks do not help.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFCv2] doc: develop: Describe system configuration
  2022-07-28 19:43         ` Pali Rohár
@ 2022-07-28 21:27           ` Tom Rini
  0 siblings, 0 replies; 10+ messages in thread
From: Tom Rini @ 2022-07-28 21:27 UTC (permalink / raw)
  To: Pali Rohár; +Cc: u-boot, Simon Glass, Heinrich Schuchardt

[-- Attachment #1: Type: text/plain, Size: 5831 bytes --]

On Thu, Jul 28, 2022 at 09:43:23PM +0200, Pali Rohár wrote:
> On Thursday 28 July 2022 15:26:08 Tom Rini wrote:
> > On Thu, Jul 28, 2022 at 09:21:52PM +0200, Pali Rohár wrote:
> > > On Thursday 28 July 2022 15:18:03 Tom Rini wrote:
> > > > On Thu, Jul 28, 2022 at 09:05:07PM +0200, Pali Rohár wrote:
> > > > > On Thursday 28 July 2022 14:53:49 Tom Rini wrote:
> > > > [snip]
> > > > > > +When it has been determined that the practical solution for where to have
> > > > > > +something is in the ``CFG`` namespace, 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.
> > > > > 
> > > > > Sounds good.
> > > > > 
> > > > > The only missing bit of information for me, which I really do not know
> > > > > still remain... Where, how and in which format to store board specific
> > > > > CFG option which is required for architecture or SoC for proper setup?
> > > > > 
> > > > > It cannot be in board/ subdir because arch/ code cannot use it (and even
> > > > > do not know which include file should use). It cannot be in arch/ subdir
> > > > > because it is SoC specific (e.g. arch would have to use long spaghetti
> > > > > #if defined(BOARD_1) ... #elif defined(BOARD_2) ... #endif block). And
> > > > > it cannot be in include/configs/ because you do not like it and do not
> > > > > want it here.
> > > > > 
> > > > > Currently this issue is _un_solved by using CONFIG option either in
> > > > > Kconfig or in include/configs/ ... and both options are not ideal.
> > > > > 
> > > > > I just do not see how to solve this problem.
> > > > 
> > > > I think it's fine to have things in quite literally <asm/arch/soc.h>
> > > > (which we have a few of already) and then as needed #if / #elif / #endif
> > > > for SoC changes.  Much of this _could_ be instead pulled from device
> > > > trees.  But that's unlikely to happen for a number of platforms.  And
> > > > for the board specific cases which are not converted to come out of
> > > > device tree, include/configs/board.h isn't going to be able to go away
> > > > for that platform just yet.
> > > > 
> > > > So in a round about way, yes, I'm just punting on the problem because I
> > > > suspect the "right" answer is converting to driver model in a more
> > > > complete way and pulling the information from the device tree.  But I
> > > > accept there's not a desire on anyones part to invest that much time in
> > > > a dead end platform.
> > > 
> > > Driver model and device tree is probably the better place. But in case
> > > such option is required for SoC setup to allow U-Boot to access device
> > > tree then it cannot be in device tree...
> > 
> > I guess I need an example value or two please, that can't reside in
> > <arch/asm/soc.h> nor can be delayed long enough to come from the device
> > tree instead.
> 
> For example those powerpc preliminary local bus settings which
> configures boot device memory mappings. Boot source is chosen by user
> (currently by selecting appropriate defconfig file). It is something
> which is board specific (based on board wiring), for each boot source
> different and instruct u-boot in early stage to correctly map remaining
> part of u-boot binary where is stored DTB blob.
> 
> I can imagine such #if / #elif / #elfi / .... block in som arch/ file
> with more extensions to include also sub-#if block for boot source...
> but well such monster #ifdef hell is unmaintainable.
> 
> Look for example how many defconfig files are there for P[12]* boards.
> For every one you would have to introduce #elif chain.
> 
> But this is just an example. I can imagine similar issues on other
> platforms which have RDB boards with tons of boot source options.
> 
> I know also ARM64 based boards which have boot strapping options to skip
> integrated BootROM and start booting directly from CS or other device
> local bus.

Alright.  We know what the boot source is, since it's also a Kconfig
option.  If they're SoC specific, because we need to write in specific
values to say "boot MMC #1", hex under arch/.../Kconfig that depends on
SOC && BOOTMODE_FOO.  If they're board specific, because it's something
like "we need to set timing value 0x100 because of the lengths of the
traces on the PCB", hex under board/.../Kconfig that depends on
BOOTMODE_FOO.

And if it becomes a matter of "OR together these 5 different values"
then maybe we just can't kill off include/config/board.h after all, and
that just has to be where the board specific CFG_FOO things live.

> > One thing that we can and do in some platforms do today is have SPL use
> > a correct-enough simplified device tree so we always enable enough
> > clocks/mux to have GPIOs work to determine the real rev we're on and
> > pass the correct tree to full U-Boot.  I don't think we have the hooks
> > to re-evaluate the tree in full U-Boot, but perhaps we do need that.
> 
> We have such hooks, in proper U-Boot it is possible to do small
> modifications in DTB blob prior binding drivers. I'm preparing patches
> for Omnia board which use this feature. So it is not only possible but
> it is already working.

Maybe it was some other case that was being asked about where it was
wanting to re-process the whole device tree, not just modify some nodes.

> But in case device tree is not accessible yet (due to very early stage)
> then such hooks do not help.

This should be solved either by CFG_FOO or CONFIG_FOO that's not
prompted for.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFCv2] doc: develop: Describe system configuration
  2022-07-28 18:53 [RFCv2] doc: develop: Describe system configuration Tom Rini
  2022-07-28 19:05 ` Pali Rohár
@ 2022-07-29  7:03 ` Heinrich Schuchardt
  2022-07-29 11:57   ` Tom Rini
  2022-07-29 14:46   ` Tom Rini
  1 sibling, 2 replies; 10+ messages in thread
From: Heinrich Schuchardt @ 2022-07-29  7:03 UTC (permalink / raw)
  To: Tom Rini; +Cc: Pali Rohár, Simon Glass, u-boot

On 7/28/22 20:53, 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 <trini@konsulko.com>
> ---
> 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 | 121 +++++++++++++++++++++++++++
>   3 files changed, 122 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..bb09d1f974d4
> --- /dev/null
> +++ b/doc/develop/system_configuration.rst
> @@ -0,0 +1,121 @@
> +.. SPDX-License-Identifier: GPL-2.0+
> +
> +U-Boot system configuration

Thanks Tom for adding this helpful text on configuration. Overall we
should even more move the focus from "namespace" to configuration
mechanism. See below.


%s/U-Boot system/System/

We know that we are talking about U-Boot.

> +===========================
> +
> +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 is preferred over build time. But when making these

%s/run time/run time configuration/
%s/build time/build time configuration/

> +decision, we also need to consider if we're talking about feature that could be

%s/decision/decisions/

%s/feature/a feature/

> +useful to virtually every platform or something specific to a single hardware
> +platform. The resulting image size is also another important consideration.
> +Finally, the overall requirements of being able to do run time detection will
> +have an impact on if it's possible or not.

I guess you mean that run time detection is not always feasible? How about:

"Run time detection depends on the physical hardware and may not always
be possible."

> +
> +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:
> +
> +#. Simple run time. One example here are chip revision checks. Another is

%s/Simple run time\./Run time feature detection./

> +   knowing that we've checked GPIOs and are on revision B of a platform, rather

Do you mean: "On some boards the revision may be detected by reading
GPIOs."?

> +   than doing a more expensive device tree check. This allows us to use a single
> +   device tree for revision A and B in this case and perform fixups as needed
> +   rather than storing two device trees.
> +
> +#. Making use of our Kconfig infrastructure and the ``CONFIG`` namespace. The
> +   primary method of build time configuration is done via the ``CONFIG``
> +   namespace and Kconfig infrastructure. 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.
> +
> +#. 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 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 the ``CFG`` namespace. This is
> +   useful when for various reasons we cannot get configuration values that we
> +   need from the device tree so instead have them defined in a header and use
> +   the prefix ``CFG_`` in their definition.
> +
> +Dynamic run time configuration methods.
> +---------------------------------------
> +
> +For more information in general on how to make use of this please start with the
> +:doc:`driver model <driver-model/index>` documentation.
> +
> +Static build time configuration methods
> +---------------------------------------
> +
> +There are two namespaces used to control the build time configuration of

The focus on the word 'namespaces' does not provide clarity here. The
choice is between:

* defining configuration variables via Kconfig
* defining configuration variables via headers files

The namespace thing is secondary to this choice.

> +U-Boot, ``CONFIG`` and ``CFG``. 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 first of these, ``CONFIG``` is managed in the `Kconfig language
> +<https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html>`_ that is
> +most commonly associated with the Linux kernel and the Kconfig files found
> +throughout our sources. Adding options to this namespace 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 second of these, ``CFG`` is implemented directly as C preprocessor values or
> +macros, depending on what they are in turn describing. The nature of U-Boot
> +means that while we have some functionality that is very reasonable to expose to

%s/The nature of U-Boot means that while/While/

The removed words do not add clarity.

> +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,

%s/tree \./tree./

> +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 namespace
> +^^^^^^^^^^^^^^^^^^^^^^^^^^

The paragraphs below are not about namespaces but about when to use
Kconfig and when to use arch/Soc/board specific constants defined in
headers.

> +
> +While there are some cases where it should be fairly obvious where to use each
> +namespace, as for example a command would be ``CONFIG`` 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. In general,
> +configuration *options* should be ``CONFIG`` and configuration *settings* should
> +be ``CFG``. Since it is not always clear however, let us discuss things to
> +keep in mind when adding to either namespace.

Why can't we make this is a hard rule:

If it is in Kconfig it is CONFIG_.
It is is not in Kconfig it is CFG_

Nothing comes to my mind where such a rule cannot be applied.

> +
> +A thing to keep in mind is that we have a strong preference for using the
> +``CONFIG`` namespace first. Options expressed this way let us make use of the

The usage of namespace is irritating me here.

"We prefer to use Kconfig."

Best regards

Heinrich


> +Kconfig language to express dependencies and abstractions. 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 symbol that is ``select``'ed by the SoC symbol which would in turn
> +be ``select``'ed by the board option, which is user visible. This means that
> +hardware features that are either present or not present should be in the
> +``CONFIG`` namespace 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.
> +And for practical reasons, we cannot get this information at run time from the
> +device tree. This is a case where it is reasonable to instead make use of the
> +``CFG`` namespace and that it is pure C preprocessor macros to define that
> +``CFG_SYS_FOO_REG`` is ``(CFG_SYS_FOO_BASE + 0x200)`` and have blocks of those
> +under ``#if defined(CONFIG_SOC_FOO1) ... #elif defined(CONFIG_SOC_FOO2) ...
> +#endif`` in a system header file. Another example here is register values. Often
> +it will make the most sense to construct these from other values and then using
> +masks and shifts to turn a list of "magic values" in to something that is easier
> +for humans to parse as well.
> +
> +When it has been determined that the practical solution for where to have
> +something is in the ``CFG`` namespace, 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.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFCv2] doc: develop: Describe system configuration
  2022-07-29  7:03 ` Heinrich Schuchardt
@ 2022-07-29 11:57   ` Tom Rini
  2022-07-29 14:46   ` Tom Rini
  1 sibling, 0 replies; 10+ messages in thread
From: Tom Rini @ 2022-07-29 11:57 UTC (permalink / raw)
  To: Heinrich Schuchardt; +Cc: Pali Rohár, Simon Glass, u-boot

[-- Attachment #1: Type: text/plain, Size: 11205 bytes --]

On Fri, Jul 29, 2022 at 09:03:00AM +0200, Heinrich Schuchardt wrote:
> On 7/28/22 20:53, 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 <trini@konsulko.com>
> > ---
> > 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 | 121 +++++++++++++++++++++++++++
> >   3 files changed, 122 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..bb09d1f974d4
> > --- /dev/null
> > +++ b/doc/develop/system_configuration.rst
> > @@ -0,0 +1,121 @@
> > +.. SPDX-License-Identifier: GPL-2.0+
> > +
> > +U-Boot system configuration
> 
> Thanks Tom for adding this helpful text on configuration. Overall we
> should even more move the focus from "namespace" to configuration
> mechanism. See below.
> 
> 
> %s/U-Boot system/System/
> 
> We know that we are talking about U-Boot.
> 
> > +===========================
> > +
> > +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 is preferred over build time. But when making these
> 
> %s/run time/run time configuration/
> %s/build time/build time configuration/
> 
> > +decision, we also need to consider if we're talking about feature that could be
> 
> %s/decision/decisions/
> 
> %s/feature/a feature/
> 
> > +useful to virtually every platform or something specific to a single hardware
> > +platform. The resulting image size is also another important consideration.
> > +Finally, the overall requirements of being able to do run time detection will
> > +have an impact on if it's possible or not.
> 
> I guess you mean that run time detection is not always feasible? How about:
> 
> "Run time detection depends on the physical hardware and may not always
> be possible."
> 
> > +
> > +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:
> > +
> > +#. Simple run time. One example here are chip revision checks. Another is
> 
> %s/Simple run time\./Run time feature detection./
> 
> > +   knowing that we've checked GPIOs and are on revision B of a platform, rather
> 
> Do you mean: "On some boards the revision may be detected by reading
> GPIOs."?
> 
> > +   than doing a more expensive device tree check. This allows us to use a single
> > +   device tree for revision A and B in this case and perform fixups as needed
> > +   rather than storing two device trees.
> > +
> > +#. Making use of our Kconfig infrastructure and the ``CONFIG`` namespace. The
> > +   primary method of build time configuration is done via the ``CONFIG``
> > +   namespace and Kconfig infrastructure. 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.
> > +
> > +#. 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 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 the ``CFG`` namespace. This is
> > +   useful when for various reasons we cannot get configuration values that we
> > +   need from the device tree so instead have them defined in a header and use
> > +   the prefix ``CFG_`` in their definition.
> > +
> > +Dynamic run time configuration methods.
> > +---------------------------------------
> > +
> > +For more information in general on how to make use of this please start with the
> > +:doc:`driver model <driver-model/index>` documentation.
> > +
> > +Static build time configuration methods
> > +---------------------------------------
> > +
> > +There are two namespaces used to control the build time configuration of
> 
> The focus on the word 'namespaces' does not provide clarity here. The
> choice is between:
> 
> * defining configuration variables via Kconfig
> * defining configuration variables via headers files
> 
> The namespace thing is secondary to this choice.
> 
> > +U-Boot, ``CONFIG`` and ``CFG``. 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 first of these, ``CONFIG``` is managed in the `Kconfig language
> > +<https://www.kernel.org/doc/html/latest/kbuild/kconfig-language.html>`_ that is
> > +most commonly associated with the Linux kernel and the Kconfig files found
> > +throughout our sources. Adding options to this namespace 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 second of these, ``CFG`` is implemented directly as C preprocessor values or
> > +macros, depending on what they are in turn describing. The nature of U-Boot
> > +means that while we have some functionality that is very reasonable to expose to
> 
> %s/The nature of U-Boot means that while/While/
> 
> The removed words do not add clarity.
> 
> > +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,
> 
> %s/tree \./tree./
> 
> > +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 namespace
> > +^^^^^^^^^^^^^^^^^^^^^^^^^^
> 
> The paragraphs below are not about namespaces but about when to use
> Kconfig and when to use arch/Soc/board specific constants defined in
> headers.
> 
> > +
> > +While there are some cases where it should be fairly obvious where to use each
> > +namespace, as for example a command would be ``CONFIG`` 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. In general,
> > +configuration *options* should be ``CONFIG`` and configuration *settings* should
> > +be ``CFG``. Since it is not always clear however, let us discuss things to
> > +keep in mind when adding to either namespace.
> 
> Why can't we make this is a hard rule:
> 
> If it is in Kconfig it is CONFIG_.
> It is is not in Kconfig it is CFG_
> 
> Nothing comes to my mind where such a rule cannot be applied.
> 
> > +
> > +A thing to keep in mind is that we have a strong preference for using the
> > +``CONFIG`` namespace first. Options expressed this way let us make use of the
> 
> The usage of namespace is irritating me here.
> 
> "We prefer to use Kconfig."

Thanks for the feedback.  I think we're overall in agreement on what I'm
trying to say, just now how to say it.  I'll integrate what you've said
here and try and rework a few parts for v3.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [RFCv2] doc: develop: Describe system configuration
  2022-07-29  7:03 ` Heinrich Schuchardt
  2022-07-29 11:57   ` Tom Rini
@ 2022-07-29 14:46   ` Tom Rini
  1 sibling, 0 replies; 10+ messages in thread
From: Tom Rini @ 2022-07-29 14:46 UTC (permalink / raw)
  To: Heinrich Schuchardt; +Cc: Pali Rohár, Simon Glass, u-boot

[-- Attachment #1: Type: text/plain, Size: 1228 bytes --]

On Fri, Jul 29, 2022 at 09:03:00AM +0200, Heinrich Schuchardt wrote:
> On 7/28/22 20:53, 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.
[snip]
> > +#. Simple run time. One example here are chip revision checks. Another is
> 
> %s/Simple run time\./Run time feature detection./

I'm trying to differentiate between "check this register content" or
"read this EEPROM" from "parse the device tree, look for compatible
strings".  I'll try and reword this differently.

> 
> > +   knowing that we've checked GPIOs and are on revision B of a platform, rather
> 
> Do you mean: "On some boards the revision may be detected by reading
> GPIOs."?

I'm trying to give some useful examples, but not every example.  So yes,
the check GPIOs A/B/C and see what we get example.

Instead of "simple" I'm going to say hardware based, reword the section
and try and not get too deep in to details.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2022-07-29 14:46 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-28 18:53 [RFCv2] doc: develop: Describe system configuration Tom Rini
2022-07-28 19:05 ` Pali Rohár
2022-07-28 19:18   ` Tom Rini
2022-07-28 19:21     ` Pali Rohár
2022-07-28 19:26       ` Tom Rini
2022-07-28 19:43         ` Pali Rohár
2022-07-28 21:27           ` Tom Rini
2022-07-29  7:03 ` Heinrich Schuchardt
2022-07-29 11:57   ` Tom Rini
2022-07-29 14:46   ` Tom Rini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.