[PATCH 1/2] board_f: fix use of GD_FLG_SKIP_RELOC

From: Peng Fan peng.fan@nxp.com
When dtb is padded in the end of U-Boot binary, dtb should always be relocated whether GD_FLG_SKIP_RELOC set or not, otherwise dtb maybe corrupted.
Need copy old gd contents to new_gd area, this may not needed on x86 or arc, but needed for ARM64, because crt0_64.S points x18 to new_gd, considering gd is a small area, and common/board_f.c also use new_gd, so let's always copy it.
Signed-off-by: Peng Fan peng.fan@nxp.com --- common/board_f.c | 8 ++++---- include/asm-generic/global_data.h | 4 ++++ lib/asm-offsets.c | 2 ++ 3 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/common/board_f.c b/common/board_f.c index 3dc0eaa59c..54a306df7d 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -621,13 +621,13 @@ static int init_post(void) static int reloc_fdt(void) { if (!IS_ENABLED(CONFIG_OF_EMBED)) { - if (gd->flags & GD_FLG_SKIP_RELOC) - return 0; if (gd->new_fdt) { memcpy(gd->new_fdt, gd->fdt_blob, fdt_totalsize(gd->fdt_blob)); gd->fdt_blob = gd->new_fdt; } + if (gd->flags & GD_FLG_SKIP_RELOC) + return 0; }
return 0; @@ -673,6 +673,8 @@ static int reloc_bloblist(void)
static int setup_reloc(void) { + memcpy(gd->new_gd, (char *)gd, sizeof(gd_t)); + if (gd->flags & GD_FLG_SKIP_RELOC) { debug("Skipping relocation due to flag\n"); return 0; @@ -691,8 +693,6 @@ static int setup_reloc(void) gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE; #endif #endif - memcpy(gd->new_gd, (char *)gd, sizeof(gd_t)); - debug("Relocation Offset is: %08lx\n", gd->reloc_off); debug("Relocating to %08lx, new gd at %08lx, sp at %08lx\n", gd->relocaddr, (ulong)map_to_sysmem(gd->new_gd), diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 16fd305a65..4a3f8be047 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -600,6 +600,10 @@ enum gd_flags { GD_FLG_SMP_READY = 0x80000, };
+#else + +#define GD_FLG_SKIP_RELOC 0x00800 + #endif /* __ASSEMBLY__ */
#endif /* __ASM_GENERIC_GBL_DATA_H */ diff --git a/lib/asm-offsets.c b/lib/asm-offsets.c index c691066332..de130574cd 100644 --- a/lib/asm-offsets.c +++ b/lib/asm-offsets.c @@ -43,5 +43,7 @@ int main(void)
DEFINE(GD_ENV_ADDR, offsetof(struct global_data, env_addr));
+ DEFINE(GD_FLAGS, offsetof(struct global_data, flags)); + return 0; }

On 10/13/21 11:54 AM, Peng Fan (OSS) wrote:
From: Peng Fan peng.fan@nxp.com
When dtb is padded in the end of U-Boot binary, dtb should always be relocated whether GD_FLG_SKIP_RELOC set or not, otherwise dtb maybe corrupted.
Need copy old gd contents to new_gd area, this may not needed on x86 or arc, but needed for ARM64, because crt0_64.S points x18 to new_gd, considering gd is a small area, and common/board_f.c also use new_gd, so let's always copy it.
Have a look at these patches:
https://patchwork.ozlabs.org/project/uboot/patch/20211010215209.872181-1-mar... https://patchwork.ozlabs.org/project/uboot/patch/20211010215209.872181-2-mar... https://patchwork.ozlabs.org/project/uboot/patch/20211010214410.870766-1-mar...

Subject: Re: [PATCH 1/2] board_f: fix use of GD_FLG_SKIP_RELOC
On 10/13/21 11:54 AM, Peng Fan (OSS) wrote:
From: Peng Fan peng.fan@nxp.com
When dtb is padded in the end of U-Boot binary, dtb should always be relocated whether GD_FLG_SKIP_RELOC set or not, otherwise dtb maybe corrupted.
Need copy old gd contents to new_gd area, this may not needed on x86 or arc, but needed for ARM64, because crt0_64.S points x18 to new_gd, considering gd is a small area, and common/board_f.c also use new_gd, so let's always copy it.
Have a look at these patches:
https://patchwork.ozlabs.org/project/uboot/patch/20211010215209.872181 -1-marek.vasut@gmail.com/ https://patchwork.ozlabs.org/project/uboot/patch/20211010215209.872181 -2-marek.vasut@gmail.com/ https://patchwork.ozlabs.org/project/uboot/patch/20211010214410.870766 -1-marek.vasut+renesas@gmail.com/
Oh, I should check mails before I work on this. Will look at your patches.
Thanks, Peng.

From: Peng Fan peng.fan@nxp.com
U-Boot binary is quite large with more options enabled, it not hurt on real silicon with high performance. But on simulation platform, it is quite slow to relocate the U-Boot binary to new address, so let's support skipping relocation.
Users could use 'gd->flags |= GD_FLG_SKIP_RELOC;' in board_early_init_f or other place that early than relocate_code.
Signed-off-by: Peng Fan peng.fan@nxp.com --- arch/arm/lib/crt0_64.S | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S index 680e674fa3..d57ca84ee4 100644 --- a/arch/arm/lib/crt0_64.S +++ b/arch/arm/lib/crt0_64.S @@ -12,6 +12,7 @@ #include <config.h> #include <asm-offsets.h> #include <asm/macro.h> +#include <asm-generic/global_data.h> #include <linux/linkage.h>
/* @@ -95,6 +96,7 @@ ENTRY(_main) bl board_init_f
#if !defined(CONFIG_SPL_BUILD) + ldr x1, [x18, #GD_FLAGS] /* * Set up intermediate environment (new sp and gd) and call * relocate_code(addr_moni). Trick here is that we'll return @@ -122,6 +124,10 @@ ENTRY(_main) ldr x9, [x18, #GD_RELOC_OFF] /* x9 <- gd->reloc_off */ add lr, lr, x9 /* new return address after relocation */ ldr x0, [x18, #GD_RELOCADDR] /* x0 <- gd->relocaddr */ + + tst x1, #GD_FLG_SKIP_RELOC + bne relocation_return + b relocate_code
relocation_return:

Hi Peng,
On Wed, 13 Oct 2021 at 03:18, Peng Fan (OSS) peng.fan@oss.nxp.com wrote:
From: Peng Fan peng.fan@nxp.com
U-Boot binary is quite large with more options enabled, it not hurt on real silicon with high performance. But on simulation platform, it is quite slow to relocate the U-Boot binary to new address, so let's support skipping relocation.
Users could use 'gd->flags |= GD_FLG_SKIP_RELOC;' in board_early_init_f or other place that early than relocate_code.
Signed-off-by: Peng Fan peng.fan@nxp.com
arch/arm/lib/crt0_64.S | 6 ++++++ 1 file changed, 6 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org
diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S index 680e674fa3..d57ca84ee4 100644 --- a/arch/arm/lib/crt0_64.S +++ b/arch/arm/lib/crt0_64.S @@ -12,6 +12,7 @@ #include <config.h> #include <asm-offsets.h> #include <asm/macro.h> +#include <asm-generic/global_data.h> #include <linux/linkage.h>
/* @@ -95,6 +96,7 @@ ENTRY(_main) bl board_init_f
#if !defined(CONFIG_SPL_BUILD)
ldr x1, [x18, #GD_FLAGS]
/*
- Set up intermediate environment (new sp and gd) and call
- relocate_code(addr_moni). Trick here is that we'll return
@@ -122,6 +124,10 @@ ENTRY(_main) ldr x9, [x18, #GD_RELOC_OFF] /* x9 <- gd->reloc_off */ add lr, lr, x9 /* new return address after relocation */ ldr x0, [x18, #GD_RELOCADDR] /* x0 <- gd->relocaddr */
tst x1, #GD_FLG_SKIP_RELOC
bne relocation_return
Could we document this feature somewhere, or add a comment here as to why this is useful?
b relocate_code
relocation_return:
2.30.0
Regards, SImon
participants (3)
-
Marek Vasut
-
Peng Fan (OSS)
-
Simon Glass