[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