Re: [PATCH v6 2/2] schemas: Add schema for U-Boot driver model 'phase tags'

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Rob,

On Wed, 18 Jan 2023 at 13:34, Rob Herring <robh@xxxxxxxxxx> wrote:
>
> On Fri, Jan 13, 2023 at 2:58 PM Simon Glass <sjg@xxxxxxxxxxxx> wrote:
> >
> > U-Boot has some particular challenges with device tree and devices:
> >
> > - U-Boot has multiple build phases, such as a Secondary Program Loader
> >   (SPL) phase which typically runs in a pre-SDRAM environment where code
> >   and data space are limited. In particular, there may not be enough
> >   space for the full device tree blob. U-Boot uses various automated
> >   techniques to reduce the size from perhaps 40KB to 3KB. It is not
> >   always possible to handle these tags entirely at build time, since
> >   U-Boot proper must have the full device tree, even though we do not
> >   want it to process all nodes until after relocation.
> > - Some U-Boot phases needs to run before the clocks are properly set up,
> >   where the CPU may be running very slowly. Therefore it is important to
> >   bind only those devices which are actually needed in that phase
> > - U-Boot uses lazy initialisation for its devices, with 'bind' and
> >   'probe' being separate steps. Even if a device is bound, it is not
> >   actually probed until it is used. This is necessary to keep the boot
> >   time reasonable, e.g. to under a second
> >
> > The phases of U-Boot in order are: TPL, VPL, SPL, U-Boot (first
> > pre-relocation, then post-relocation). ALl but the last two are optional.
> >
> > For the above reasons, U-Boot only includes the full device tree in the
> > final 'U-Boot proper' build. Even then, before relocation U-Boot only
> > processes nodes which are marked as being needed.
> >
> > For this to work, U-Boot's driver model[1] provides a way to mark device
> > tree nodes as applicable for a particular phase. This works by adding a
> > tag to the node, e.g.:
> >
> >    cru: clock-controller@ff760000 {
> >       bootph-all;
> >       compatible = "rockchip,rk3399-cru";
> >       reg = <0x0 0xff760000 0x0 0x1000>;
> >       rockchip,grf = <&grf>;
> >       #clock-cells = <1>;
> >       #reset-cells = <1>;
> >       ...
> >    };
> >
> > Here the "bootph-all" tag indicates that the node must be present in all
> > phases, since the clock driver is required.
> >
> > There has been discussion over the years about whether this could be done
> > in a property instead, e.g.
> >
> >    options {
> >       bootph-all = <&cru> <&gpio_a> ...;
> >       ...
> >    };
> >
> > Some problems with this:
> >
> > - we need to be able to merge several such tags from different .dtsi files
> >   since many boards have their own specific requirements
> > - it is hard to find and cross-reference the affected nodes
> > - it is more error-prone
> > - it requires significant tool rework in U-Boot, including fdtgrep and
> >   the build system
> > - is harder (slower, more code) to process since it involves scanning
> >   another node/property to find out what to do with a particular node
> > - we don't want to add phandle arguments to the above since we are
> >   referring, e.g., to the clock device as a whole, not a paricular clock
> > - the of-platdata feature[2], which converts device tree to C for even
> >   more constrained environments, would need to become aware of the
> >   /options node
> >
> > There is also the question about whether this needs to be U-Boot-specific,
> > or whether the tags could be generic. From what I can tell, U-Boot is the
> > only bootloader which seriously attempts to use a runtime device tree in
> > all cases. For this version, an attempt is made to name the phases in a
> > generic manner.
> >
> > It should also be noted that the approach provided here has stood the test
> > of time, used in U-Boot for 8 years so far.
> >
> > So add the schema for this. This will allow a major class of schema
> > exceptions to be dropped from the U-Boot source tree.
> >
> > This being sent to the mailing list since it might attract more review.
> > A PR will be sent when this has had some review. That is why the file
> > path is set up for https://github.com/devicetree-org/dt-schema rather
> > than the Linux kernel.
> >
> > [1] https://u-boot.readthedocs.io/en/latest/develop/driver-model/index.html
> > [2] https://u-boot.readthedocs.io/en/latest/develop/driver-model/of-plat.html
> >
> > Signed-off-by: Simon Glass <sjg@xxxxxxxxxxxx>
> > ---
> >
> > Changes in v6:
> > - Use 'bootph' instead of 'phase'
> > - Use | instead of , in patternProperties
> > - Drop mention of 40KB for device-tree size
> > - Rework description of handling of parent nodes
> > - Use separate properties for each boot phase
> > - Update validation example at the top of bootphases.dts
> >
> > Changes in v5:
> > - Fix instructions to run test
> > - Update binding title
> > - Use 'phase-' instead of 'phase,'
> >
> > Changes in v4:
> > - Drop some unnecessary context from the commit message
> > - Explain why parent nodes do not automatically inherit their children's
> >   tags
> > - Rename the tags to use a phase,xxx format, explaining each one
> >
> > Changes in v3:
> > - Fix an incorrect schema path in $id
> >
> > Changes in v2:
> > - Expand docs to include a description of each tag
> > - Fix some typos and unclear wording
> >
> >  dtschema/lib.py              |  5 +++
> >  dtschema/schemas/bootph.yaml | 86 ++++++++++++++++++++++++++++++++++++
> >  test/bootphases.dts          | 22 +++++++++
> >  3 files changed, 113 insertions(+)
> >  create mode 100644 dtschema/schemas/bootph.yaml
> >  create mode 100644 test/bootphases.dts
> >
> > diff --git a/dtschema/lib.py b/dtschema/lib.py
> > index c7b6cb9..95a4f10 100644
> > --- a/dtschema/lib.py
> > +++ b/dtschema/lib.py
> > @@ -493,6 +493,11 @@ def fixup_node_props(schema):
> >      schema['properties'].setdefault('status', True)
> >      schema['properties'].setdefault('secure-status', True)
> >      schema['properties'].setdefault('$nodename', True)
> > +    schema['properties'].setdefault('bootph-pre-sram', True)
> > +    schema['properties'].setdefault('bootph-verify', True)
> > +    schema['properties'].setdefault('bootph-pre-ram', True)
> > +    schema['properties'].setdefault('bootph-some-ram', True)
> > +    schema['properties'].setdefault('bootph-all', True)
> >
> >      keys = list()
> >      if 'properties' in schema:
> > diff --git a/dtschema/schemas/bootph.yaml b/dtschema/schemas/bootph.yaml
> > new file mode 100644
> > index 0000000..275c4da
> > --- /dev/null
> > +++ b/dtschema/schemas/bootph.yaml
> > @@ -0,0 +1,86 @@
> > +# SPDX-License-Identifier: BSD-2-Clause
> > +# Copyright 2022 Google LLC
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/bootph.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Boot-phase-specific device nodes
> > +
> > +maintainers:
> > +  - Simon Glass <sjg@xxxxxxxxxxxx>
> > +
> > +description: |
> > +  Some programs run in memory-constrained environments yet want to make use
> > +  of device tree.
> > +
> > +  The full device tree is often quite large relative to the available memory
> > +  of a boot phase, so cannot fit into every phase of the boot process. Even
> > +  when memory is not a problem, some phases may wish to limit which device
> > +  nodes are present, so as to reduce execution time.
> > +
> > +  This binding supports adding tags to device tree nodes to allow them to be
> > +  marked according to the phases where they should be included.
> > +
> > +  Without any tags, nodes are included only in the final phase, where all
> > +  memory is available. Any untagged nodes are dropped from previous phases
> > +  and are ignored before the final phase is reached.
> > +
> > +  The build process produces a separate executable for each phase. It can
> > +  use fdtgrep to drop any nodes which are not needed for a particular build.
> > +  For example, the pre-sram build will drop any nodes which are not marked
> > +  with bootph-pre-sram or bootph-all tags.
> > +
> > +  Note that phase builds may drop the tags, since they have served their
> > +  purpose by that point. So when looking at phase-specific device tree files
> > +  you may not see these tags.
> > +
> > +  Multiple tags can be used in the same node.
> > +
> > +  Tags in a child node are implied to be present in all parent nodes as well.
> > +  This is important, since some missing properties (such as "ranges", or
> > +  "compatible") can cause the child node to be ignored or incorrectly
> > +  parsed.
> > +
> > +  That said, at present, fdtgrep applies tags only to the node they are
> > +  added to, not to any parents. This means U-Boot device tree files often
> > +  add the same tag to parent nodes, rather than relying on tooling to do
> > +  this. This is a limitation of fdtgrep and it will be addressed so that
> > +  'Linux DTs' do not need to do this.
> > +
> > +  The available tags are describes as properties below, in order of phase
>
> described
>
> > +  execution.
> > +
>
> I think your issue testing is you need a 'select: true' here. 'select'
> is how we test whether a schema should be applied to a node. The
> default is to use compatible or $nodename for matching. You have
> neither, so select is false.

I feel like I have the opposite problem, in that the validation is not
actually happening, i.e. it isn't failing with something like
bootph-pre-sramxxx or anything else I put into the node:

I do see this:

dtc -O dtb -o test.dtb test/bootphases.dts && tools/dt-validate -m test.dtb
test.dtb: /some-device: failed to match any schema with compatible:
['vendor,soc1-ip']

but even changing it into a 'cpus' node it still lets me any any
random property I like.

>
> > +properties:
> > +  bootph-pre-sram:
> > +    type: boolean
> > +    description: |
>
> Don't need '|' unless you want to preserve line endings.
>
> Otherwise, looks good. Send a PR.

OK, ta.

>
> > +      Enable this node when SRAM is not available. This phase must set up
> > +      some SRAM or cache-as-RAM so it can obtain data/BSS space to use
> > +      during execution.
> > +
> > +  bootph-verify:
> > +    type: boolean
> > +    description: |
> > +      Enable this node in the verification step, which decides which of the
> > +      available images should be run next.
> > +
> > +  bootph-pre-ram:
> > +    type: boolean
> > +    description: |
> > +      Enable this node in the phase that sets up SDRAM.
> > +
> > +  bootph-some-ram:
> > +    type: boolean
> > +    description: |
> > +      Enable this node in the phase that is run after SDRAM is working but
> > +      before all of it is available. Some RAM is available but it is limited
> > +      (e.g. it may be split into two pieces by the location of the running
> > +      program) because the program code is not yet relocated out of the way.
> > +
> > +  bootph-all:
> > +    type: boolean
> > +    description: |
> > +      Include this node in all phases (for U-Boot see enum u_boot_phase).
> > +
> > +additionalProperties: true
> > diff --git a/test/bootphases.dts b/test/bootphases.dts
> > new file mode 100644
> > index 0000000..037c626
> > --- /dev/null
> > +++ b/test/bootphases.dts
> > @@ -0,0 +1,22 @@
> > +// SPDX-License-Identifier: BSD-2-Clause
> > +// Copyright 2022 Google LLC
> > +
> > +// An attempt to provide a device tree to validate the phase properties
> > +
> > +// dtc -O dtb -o test.dtb test/bootphases.dts && tools/dt-validate test.dtb
> > +
> > +
> > +/dts-v1/;
> > +
> > +/ {
> > +       model = "none";
> > +       compatible = "foo";
> > +
> > +       #address-cells = <1>;
> > +       #size-cells = <1>;
> > +
> > +       some-device {
> > +               compatible = "vendor,soc1-ip";
> > +               bootph-pre-sram;
> > +       };
> > +};
> > --
> > 2.39.0.314.g84b9a713c41-goog
> >

Regards,
Simon



[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux