[PATCH u-boot 24/39] ARM: make gd a function call for LTO and set via set_gd()

Marek Behún marek.behun at nic.cz
Sun Mar 7 05:25:23 CET 2021


On ARM, the gd pointer is stored in registers r9 / x18. For this the
-ffixed-r9 / -ffixed-x18 flag is used when compiling, but using global
register variables causes errors when building with LTO, and these
errors are very difficult to overcome.

Richard Biener says [1]:
  Note that global register vars shouldn't be used with LTO and if they
  are restricted to just a few compilation units the recommended fix is
  to build those CUs without -flto.

We cannot do this for U-Boot since all CUs use -ffixed-reg flag.

It seems that with LTO we could in fact store the gd pointer differently
and gain performance or size benefit by allowing the compiler to use
r9 / x18. But this would need more work.

So for now, when building with LTO, go the clang way, and instead of
declaring gd a global register variable, we make it a function call via
macro.

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68384

Signed-off-by: Marek Behún <marek.behun at nic.cz>
---
 arch/arm/cpu/arm926ejs/mxs/spl_boot.c |  2 +-
 arch/arm/include/asm/global_data.h    |  2 +-
 arch/arm/mach-exynos/spl_boot.c       |  2 +-
 arch/arm/mach-imx/imx8m/soc.c         |  2 +-
 arch/arm/mach-imx/spl_imx_romapi.c    | 16 ++++++++--------
 5 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
index a16a15e79d..66406cc857 100644
--- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
+++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
@@ -122,7 +122,7 @@ void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr,
 {
 	struct mxs_spl_data *data = MXS_SPL_DATA;
 	uint8_t bootmode = mxs_get_bootmode_index();
-	gd = &gdata;
+	set_gd(&gdata);
 
 	mxs_spl_fixup_vectors();
 
diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h
index bb82efafa6..2aff1c467c 100644
--- a/arch/arm/include/asm/global_data.h
+++ b/arch/arm/include/asm/global_data.h
@@ -91,7 +91,7 @@ struct arch_global_data {
 
 #include <asm-generic/global_data.h>
 
-#ifdef __clang__
+#if defined(__clang__) || defined(CONFIG_LTO)
 
 #define DECLARE_GLOBAL_DATA_PTR
 #define gd	get_gd()
diff --git a/arch/arm/mach-exynos/spl_boot.c b/arch/arm/mach-exynos/spl_boot.c
index 27f0dac182..722449881a 100644
--- a/arch/arm/mach-exynos/spl_boot.c
+++ b/arch/arm/mach-exynos/spl_boot.c
@@ -279,7 +279,7 @@ void memzero(void *s, size_t n)
  */
 static void setup_global_data(gd_t *gdp)
 {
-	gd = gdp;
+	set_gd(gdp);
 	memzero((void *)gd, sizeof(gd_t));
 	gd->flags |= GD_FLG_RELOC;
 	gd->baudrate = CONFIG_BAUDRATE;
diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c
index 5f37282ff1..15d0da7060 100644
--- a/arch/arm/mach-imx/imx8m/soc.c
+++ b/arch/arm/mach-imx/imx8m/soc.c
@@ -509,7 +509,7 @@ enum boot_device get_boot_device(void)
 
 	ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot,
 					  ((uintptr_t)&boot) ^ QUERY_BT_DEV);
-	gd = pgd;
+	set_gd(pgd);
 
 	if (ret != ROM_API_OKAY) {
 		puts("ROMAPI: failure at query_boot_info\n");
diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c
index 9f4d95982e..d2085dabd3 100644
--- a/arch/arm/mach-imx/spl_imx_romapi.c
+++ b/arch/arm/mach-imx/spl_imx_romapi.c
@@ -45,7 +45,7 @@ static ulong spl_romapi_read_seekable(struct spl_load_info *load,
 
 	ret = g_rom_api->download_image(buf, offset, byte,
 					((uintptr_t)buf) ^ offset ^ byte);
-	gd = pgd;
+	set_gd(pgd);
 
 	if (ret == ROM_API_OKAY)
 		return count;
@@ -73,7 +73,7 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image,
 	ret |= g_rom_api->query_boot_infor(QUERY_IMG_OFF, &image_offset,
 					   ((uintptr_t)&image_offset) ^ QUERY_IMG_OFF);
 
-	gd = pgd;
+	set_gd(pgd);
 
 	if (ret != ROM_API_OKAY) {
 		puts("ROMAPI: Failure query boot infor pagesize/offset\n");
@@ -94,7 +94,7 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image,
 	size = ALIGN(sizeof(struct image_header), pagesize);
 	ret = g_rom_api->download_image((u8 *)header, offset, size,
 					((uintptr_t)header) ^ offset ^ size);
-	gd = pgd;
+	set_gd(pgd);
 
 	if (ret != ROM_API_OKAY) {
 		printf("ROMAPI: download failure offset 0x%x size 0x%x\n",
@@ -180,7 +180,7 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,
 
 	ret = g_rom_api->query_boot_infor(QUERY_PAGE_SZ, &pagesize,
 					  ((uintptr_t)&pagesize) ^ QUERY_PAGE_SZ);
-	gd = pgd;
+	set_gd(pgd);
 
 	if (ret != ROM_API_OKAY)
 		puts("failure at query_boot_info\n");
@@ -192,7 +192,7 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,
 	for (i = 0; i < 640; i++) {
 		ret = g_rom_api->download_image(p, 0, pg,
 						((uintptr_t)p) ^ pg);
-		gd = pgd;
+		set_gd(pgd);
 
 		if (ret != ROM_API_OKAY) {
 			puts("Steam(USB) download failure\n");
@@ -213,7 +213,7 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,
 
 	if (p - pfit < sizeof(struct fdt_header)) {
 		ret = g_rom_api->download_image(p, 0, pg,  ((uintptr_t)p) ^ pg);
-		gd = pgd;
+		set_gd(pgd);
 
 		if (ret != ROM_API_OKAY) {
 			puts("Steam(USB) download failure\n");
@@ -237,7 +237,7 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image,
 
 		ret = g_rom_api->download_image(p, 0, imagesize,
 						((uintptr_t)p) ^ imagesize);
-		gd = pgd;
+		set_gd(pgd);
 
 		p += imagesize;
 
@@ -280,7 +280,7 @@ int board_return_to_bootrom(struct spl_image_info *spl_image,
 
 	ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot,
 					  ((uintptr_t)&boot) ^ QUERY_BT_DEV);
-	gd =  pgd;
+	set_gd(pgd);
 
 	if (ret != ROM_API_OKAY) {
 		puts("ROMAPI: failure at query_boot_info\n");
-- 
2.26.2



More information about the U-Boot mailing list