diff mbox series

rpi: Copy properties from firmware dtb to the loaded dtb

Message ID 20210822143656.289891-1-sjoerd@collabora.com
State Superseded
Delegated to: Matthias Brugger
Headers show
Series rpi: Copy properties from firmware dtb to the loaded dtb | expand

Commit Message

Sjoerd Simons Aug. 22, 2021, 2:36 p.m. UTC
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
* 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.

Signed-off-by: Sjoerd Simons <sjoerd@collabora.com>
---

 board/raspberrypi/rpi/rpi.c | 47 +++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

Comments

Peter Robinson Aug. 24, 2021, 7:15 a.m. UTC | #1
Hi Sjoerd,

> 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:

Overall this looks great.

> * /model: The firmware provides a more specific string
> * /memreserve: The firmware defines a reserved range, better keep it
> * 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.

There's also a random seed provided by the RNG_IPROC200 in U-Boot
itself, maybe if this seed provides for all generations of the rpi it
might be a better option, also usedul if this would update the seed in
U-Boot for things like the UEFI seed.

It would also likely be useful to deal with a few other pieces that
the RPi firmware provides like CMA and whether or not the serial UART
is enabled for console so it can be adjusted in U-Boot whether it
takes control of the uart. There's been a few reports over time where
U-Boot clobbers the serial port when people are trying to use it for
other things.

I'll give this a test in the next few days.

Peter

> Signed-off-by: Sjoerd Simons <sjoerd@collabora.com>
> ---
>
>  board/raspberrypi/rpi/rpi.c | 47 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
>
> diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
> index df52a4689f..d9467f4bda 100644
> --- a/board/raspberrypi/rpi/rpi.c
> +++ b/board/raspberrypi/rpi/rpi.c
> @@ -495,8 +495,55 @@ void *board_fdt_blob_setup(void)
>         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)
>  {
> +       update_fdt_from_fw(blob, (void *)fw_dtb_pointer);
>         /*
>          * For now, we simply always add the simplefb DT node. Later, we
>          * should be more intelligent, and e.g. only do this if no enabled DT
> --
> 2.33.0
>
diff mbox series

Patch

diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
index df52a4689f..d9467f4bda 100644
--- a/board/raspberrypi/rpi/rpi.c
+++ b/board/raspberrypi/rpi/rpi.c
@@ -495,8 +495,55 @@  void *board_fdt_blob_setup(void)
 	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)
 {
+	update_fdt_from_fw(blob, (void *)fw_dtb_pointer);
 	/*
 	 * For now, we simply always add the simplefb DT node. Later, we
 	 * should be more intelligent, and e.g. only do this if no enabled DT