From 7fcce9c487ef1a41e8a2950c820c85f74b9a3f7b Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Wed, 4 Jul 2018 07:37:45 +0000 Subject: [PATCH] loader: fdt: Try to load every possible DTB from u-boot U-Boot setup a few variables : - fdt_addr which is the board static dtb (most of the time loaded before u-boot or coming from some hardware like a ROM) - fdt_addr_r which is a location in RAM that holds the DTB loaded by u-boot or before u-boot In the case of u-boot + rpi firmware the DTB is loaded in RAM but the location still end up in the fdt_addr variable and the fdt_addr_r variable exist. Change the behavior so we test that a DTB exists for every possible variable : - fdt_addr_r is checked first as if u-boot needed to modify it the correct DTB will live there. - fdt_addr is checked second as if we run on a hardware with DTB in ROM it means that we what/need to run that - fdtaddr looks like a FreeBSD-ism but since I'm not sure leave it. Reviewed by: gonzo Differential Revision: https://reviews.freebsd.org/D16101 --- stand/uboot/fdt/uboot_fdt.c | 46 ++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/stand/uboot/fdt/uboot_fdt.c b/stand/uboot/fdt/uboot_fdt.c index aed7885e961c..417ec4aeb6eb 100644 --- a/stand/uboot/fdt/uboot_fdt.c +++ b/stand/uboot/fdt/uboot_fdt.c @@ -39,6 +39,30 @@ __FBSDID("$FreeBSD$"); #define STR(number) #number #define STRINGIFY(number) STR(number) +static int +fdt_platform_load_from_ubenv(const char *var) +{ + struct fdt_header *hdr; + const char *s; + char *p; + + s = ub_env_get(var); + if (s == NULL || *s == '\0') + return (1); + + hdr = (struct fdt_header *)strtoul(s, &p, 16); + if (*p != '\0') + return (1); + + if (fdt_load_dtb_addr(hdr) == 0) { + printf("Using DTB provided by U-Boot at " + "address %p.\n", hdr); + return (0); + } + + return (1); +} + int fdt_platform_load_dtb(void) { @@ -53,22 +77,12 @@ fdt_platform_load_dtb(void) * variable for fdt data loaded into ram is fdt_addr_r, so try that * first. Board vendors also use both fdtaddr and fdt_addr names. */ - s = ub_env_get("fdt_addr_r"); - if (s == NULL) - s = ub_env_get("fdtaddr"); - if (s == NULL) - s = ub_env_get("fdt_addr"); - if (s != NULL && *s != '\0') { - hdr = (struct fdt_header *)strtoul(s, &p, 16); - if (*p == '\0') { - if (fdt_load_dtb_addr(hdr) == 0) { - printf("Using DTB provided by U-Boot at " - "address %p.\n", hdr); - rv = 0; - goto exit; - } - } - } + if ((rv = fdt_platform_load_from_ubenv("fdt_addr_r")) == 0) + goto exit; + if ((rv = fdt_platform_load_from_ubenv("fdt_addr")) == 0) + goto exit; + if ((rv = fdt_platform_load_from_ubenv("fdtaddr")) == 0) + goto exit; rv = 1;