[RFC PATCH] rpi: copy the EMMC controller configuration from firmware-supplied DT
François Ozog
francois.ozog at linaro.org
Wed Sep 29 13:43:16 CEST 2021
Hi
It looks real strange to ignore the authoritative entity and try to patch a
wrong DTB embedded in U-Boot.
Arm SystemReady is definitively aligning to the authoritative entities in
the platform to give U-Boot the right basis on which it can apply
additional overlays (providing it has a way to verify origin and integrity).
Couldn’t you find a cleaner way to just leverage the previous boot DTB ?
There is another discussion thread on similar thing with RISCV.
Le mer. 29 sept. 2021 à 13:30, K900 <me at 0upti.me> a écrit :
> We need this to boot with a custom DTB on BCM2711C0-based Pi 4s
>
> Signed-off-by: Ilya Katsnelson <me at 0upti.me>
> ---
> board/raspberrypi/rpi/rpi.c | 63 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 63 insertions(+)
>
> diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c
> index 372b26b6f2..f074540091 100644
> --- a/board/raspberrypi/rpi/rpi.c
> +++ b/board/raspberrypi/rpi/rpi.c
> @@ -495,6 +495,67 @@ void *board_fdt_blob_setup(void)
> return (void *)fw_dtb_pointer;
> }
>
> +void copy_emmc_config(void *our_fdt)
> +{
> + /*
> + * As of 2021-09-28, the Pi 4 has two different revisions, one
> using a
> + * B0 stepping of the BCM2711 SoC, and one using a C0 stepping.
> + *
> + * The two SoC versions have different, incompatible DMA mappings
> for
> + * the on-board eMMC controller, which would normally make them
> require
> + * two different DTs.
> + *
> + * Unfortunately for us, the different revisions don't actually
> _use_
> + * different DTs - instead, the proprietary stage0 bootloader
> reads the DT,
> + * patches it in-memory, then passes the corrected DT to the OS.
> + *
> + * In our case, the OS is actually U-Boot, and U-Boot can choose to
> + * completely disregard the firmware-supplied DT and load a custom
> one
> + * instead, which is used by, e.g., NixOS.
> + *
> + * When that happens, the DT patches applied by the firmware are
> also
> + * thrown out, which leads to BCM2711C0 boards being unable to boot
> + * due to them trying to use the hardcoded DMA mappings in the DT
> + * (which are for the B0 revision).
> + *
> + * Work around that by manually copying the DMA region setup from
> the
> + * firmware-provided DT into whatever DT we're actually being asked
> + * to load.
> + A*/
> + void *fw_fdt = (void *)fw_dtb_pointer;
> + int fw_emmc_node;
> + int our_emmc_node;
> + int length;
> + const void *fw_value;
> + int result;
> +
> + fw_emmc_node = fdt_path_offset(fw_fdt, "emmc2bus");
> + if (fw_emmc_node < 0) {
> + printf("RPi: Failed to find EMMC config in FW DT: %d\n",
> fw_emmc_node);
> + return;
> + }
> +
> + our_emmc_node = fdt_path_offset(our_fdt, "emmc2bus");
> + if (our_emmc_node < 0) {
> + printf("RPi: Failed to find EMMC config in our DT: %d\n",
> our_emmc_node);
> + return;
> + }
> +
> + *fw_value = fdt_getprop(fw_fdt, fw_emmc_node, "dma-ranges",
> &length);
> + if (!fw_value) {
> + printf("RPi: Failed to get EMMC DMA ranges property from
> FW DT: %d\n", length);
> + return;
> + }
> +
> + result = fdt_setprop(our_fdt, our_emmc_node, "dma-ranges",
> fw_value, length);
> + if (result != 0) {
> + printf("RPi: Failed to set EMMC DMA ranges property in our
> DT: %d\n", result);
> + return;
> + }
> +
> + printf("RPi: successfully copied FW DT EMMC configuration to our
> DT!\n");
> +}
> +
> int ft_board_setup(void *blob, struct bd_info *bd)
> {
> int node;
> @@ -509,5 +570,7 @@ int ft_board_setup(void *blob, struct bd_info *bd)
> EFI_RESERVED_MEMORY_TYPE);
> #endif
>
> + copy_emmc_config(blob);
> +
> return 0;
> }
> --
> 2.33.0
>
> --
François-Frédéric Ozog | *Director Business Development*
T: +33.67221.6485
francois.ozog at linaro.org | Skype: ffozog
More information about the U-Boot
mailing list