[PATCH 1/2] rpi: Copy properties from firmware dtb to the loaded dtb

Peter Robinson pbrobinson at gmail.com
Fri Sep 9 14:51:51 CEST 2022


Hi Antoine,

> >> The RPI firmware adjusts several property values in the dtb it passes
> >> to u-boot depending on the board/SoC revision. Inherit some of these
> >> when u-boot loads a dtb itself. Specificaly copy:
> >>
> >> * /model: The firmware provides a more specific string
> >> * /memreserve: The firmware defines a reserved range, better keep it
> >
> > Is this the CMA range or a different one? If so this makes sense.
>
> This a different range than that of the CMA (which itself is defined at
> /reserved-memory/linux,cma): it's a reserved memory range for the
> VideoCore module on the SoC. In the case of the rpi 400 (and sister
> boards like 4B based on the same chip), the dummy value in the DTB is
> patched by the firmware to a dynamic value set in config.txt; absent
> this config, the default amount is 76 MiBs (see: datasheet
> https://datasheets.raspberrypi.com/bcm2711/bcm2711-peripherals.pdf and
> rpi config reference
> https://www.raspberrypi.com/documentation/computers/config_txt.html#memory-options).
> I can see this happening on my board, where looking at the device tree
> on a running system:
>
> memreserve = <0x3b400000 0x4c00000>; // 0x4c00000 == 76 MiBs
>
> Note the start of the range is also patched in. Given the dynamic nature
> of this setting on at least bcm2711 rpi boards, I think this is worth
> carrying over.

The gpu_mem is used by the old firmware based closed source video
driver, the old version of the camera driver and a few other things.
If those aren't used it's generally recommended to reduce it as a low
as possible on the rpi4 if you're using the upstream kernel drivers
etc. although I do agree it makes sense to reserve it.

Given the newer open driver, which is now the default for rpi4 even in
Raspian, uses CMA for it's memory I think it also makes sense to pass
through the the CMA setting if set as well.

> >> * emmc2bus and pcie0 dma-ranges: The C0T revision of the bcm2711 Soc (as
> >>    present on rpi 400 and some rpi 4B boards) has different values for
> >>    these then the B0T revision. So these need to be adjusted to boot on
> >>    these boards
> >> * blconfig: The firmware defines the memory area where the blconfig
> >>    stored. Copy those over so it can be enabled.
> >> * /chosen/kaslr-seed: The firmware generates a kaslr seed, take advantage
> >>    of that.
> >
> > U-Boot has a rpi4 iproc_rng200 driver for this and provides it via the
> > UEFI random seed as well, if you're booting using UEFI that takes
> > precedence so providing this might not be useful but also it doesn't
> > matter much.
> >
> >> Signed-off-by: Sjoerd Simons <sjoerd at collabora.com>
> >
> > Reviewed-by: Peter Robinson <pbrobinson at gmail.com>
> > Tested-by: Peter Robinson <pbrobinson at gmail.com>
> >
> > Tested on RPi400 and it solves the issues with the kernel DT I've seen
> > plus some RPi4s although no the rev 1.3+ devices that also have the
> > newer SoC rev that's the same in the rpi400
> >
> >> ---
> >>   board/raspberrypi/rpi/rpi.c | 48 +++++++++++++++++++++++++++++++++++++
> >>   1 file changed, 48 insertions(+)
> >>
> >> diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
> >> index 17b8108cc8..28b6f52506 100644
> >> --- a/board/raspberrypi/rpi/rpi.c
> >> +++ b/board/raspberrypi/rpi/rpi.c
> >> @@ -504,10 +504,58 @@ void *board_fdt_blob_setup(int *err)
> >>          return (void *)fw_dtb_pointer;
> >>   }
> >>
> >> +int copy_property(void *dst, void *src, char *path, char *property)
> >> +{
> >> +       int dst_offset, src_offset;
> >> +       const fdt32_t *prop;
> >> +       int len;
> >> +
> >> +       src_offset = fdt_path_offset(src, path);
> >> +       dst_offset = fdt_path_offset(dst, path);
> >> +
> >> +       if (src_offset < 0 || dst_offset < 0)
> >> +               return -1;
> >> +
> >> +       prop = fdt_getprop(src, src_offset, property, &len);
> >> +       if (!prop)
> >> +               return -1;
> >> +
> >> +       return fdt_setprop(dst, dst_offset, property, prop, len);
> >> +}
> >> +
> >> +/* Copy tweaks from the firmware dtb to the loaded dtb */
> >> +void  update_fdt_from_fw(void *fdt, void *fw_fdt)
> >> +{
> >> +       /* Using dtb from firmware directly; leave it alone */
> >> +       if (fdt == fw_fdt)
> >> +               return;
> >> +
> >> +       /* The firmware provides a more precie model; so copy that */
> >> +       copy_property(fdt, fw_fdt, "/", "model");
> >> +
> >> +       /* memory reserve as suggested by the firmware */
> >> +       copy_property(fdt, fw_fdt, "/", "memreserve");
> >> +
> >> +       /* Adjust dma-ranges for the SD card and PCI bus as they can depend on
> >> +        * the SoC revision
> >> +        */
> >> +       copy_property(fdt, fw_fdt, "emmc2bus", "dma-ranges");
> >> +       copy_property(fdt, fw_fdt, "pcie0", "dma-ranges");
> >> +
> >> +       /* Bootloader configuration template exposes as nvmem */
> >> +       if (copy_property(fdt, fw_fdt, "blconfig", "reg") == 0)
> >> +               copy_property(fdt, fw_fdt, "blconfig", "status");
> >> +
> >> +       /* kernel address randomisation seed as provided by the firmware */
> >> +       copy_property(fdt, fw_fdt, "/chosen", "kaslr-seed");
> >> +}
> >> +
> >>   int ft_board_setup(void *blob, struct bd_info *bd)
> >>   {
> >>          int node;
> >>
> >> +       update_fdt_from_fw(blob, (void *)fw_dtb_pointer);
> >> +
> >>          node = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer");
> >>          if (node < 0)
> >>                  fdt_simplefb_add_node(blob);
> >> --
> >> 2.37.1
> >>


More information about the U-Boot mailing list