From e5e9ccdb0c070d3066e7d778e5e2b563acd7ba98 Mon Sep 17 00:00:00 2001 From: Andrey Skvortsov Date: Fri, 8 Dec 2023 17:07:07 +0300 Subject: [PATCH 1/3] fix(rockchip): add support for building with LTO enabled Using the asm .incbin statement in C sources breaks gcc wrapper. Build fails with a following errors: /tmp/ccRXHTU4.s: Assembler messages: /tmp/ccRXHTU4.s:34: Warning: dwarf line number information for .pmusram.incbin ignored ... /tmp/ccRXHTU4.s:2119: Warning: dwarf line number information for .pmusram.incbin ignored /tmp/ccRXHTU4.s:112497: Error: leb128 operand is an undefined symbol: .LVU5 /tmp/ccRXHTU4.s:112498: Error: leb128 operand is an undefined symbol: .LVU6 /tmp/ccRXHTU4.s:112507: Error: leb128 operand is an undefined symbol: .LVU9 ... /tmp/ccRXHTU4.s:115407: Error: leb128 operand is an undefined symbol: .LVU668 /tmp/ccRXHTU4.s:115408: Error: leb128 operand is an undefined symbol: .LVU710 /tmp/ccRXHTU4.s:115409: Error: leb128 operand is an undefined symbol: .LVU713 lto-wrapper: fatal error: aarch64-none-elf-gcc returned 1 exit status compilation terminated. aarch64-none-elf/bin/ld: error: lto-wrapper failed collect2: error: ld returned 1 exit status Fix it in a similar way to what the Linux kernel does, see commit 919aa45e43a84d40c27c83f6117cfa6542cee14e (MODSIGN: Avoid using .incbin in C source). [1] 1. https://lkml.org/lkml/2012/12/4/136 Change-Id: Iecc19729ce59e8c3b3c30fa37b1fddef95e83c96 Signed-off-by: Andrey Skvortsov --- plat/rockchip/rk3399/drivers/pmu/pmu_fw.S | 21 +++++++++++++++++++++ plat/rockchip/rk3399/drivers/pmu/pmu_fw.c | 22 ---------------------- plat/rockchip/rk3399/platform.mk | 6 +++--- 3 files changed, 24 insertions(+), 25 deletions(-) create mode 100644 plat/rockchip/rk3399/drivers/pmu/pmu_fw.S delete mode 100644 plat/rockchip/rk3399/drivers/pmu/pmu_fw.c diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.S b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.S new file mode 100644 index 000000000..26f331317 --- /dev/null +++ b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.S @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* convoluted way to make sure that the define is pasted just the right way */ +.macro INCBIN file sym sec + .section \sec + .global \sym + .type \sym, @object + .align 4 +\sym : + .incbin \file + .size \sym , .-\sym + .global \sym\()_end +\sym\()_end : +.endm + +INCBIN ""RK3399M0FW"", "rk3399m0_bin", ".sram.incbin" +INCBIN ""RK3399M0PMUFW"", "rk3399m0pmu_bin", ".pmusram.incbin" diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c deleted file mode 100644 index 25596b188..000000000 --- a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* convoluted way to make sure that the define is pasted just the right way */ -#define INCBIN(file, sym, sec) \ - __asm__( \ - ".section " sec "\n" \ - ".global " sym "\n" \ - ".type " sym ", %object\n" \ - ".align 4\n" \ - sym ":\n" \ - ".incbin \"" file "\"\n" \ - ".size " sym ", .-" sym "\n" \ - ".global " sym "_end\n" \ - sym "_end:\n" \ - ) - -INCBIN(RK3399M0FW, "rk3399m0_bin", ".sram.incbin"); -INCBIN(RK3399M0PMUFW, "rk3399m0pmu_bin", ".pmusram.incbin"); diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk index aba67c2fe..2394dcea9 100644 --- a/plat/rockchip/rk3399/platform.mk +++ b/plat/rockchip/rk3399/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2016-2024, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -61,7 +61,7 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \ ${RK_PLAT_SOC}/plat_sip_calls.c \ ${RK_PLAT_SOC}/drivers/gpio/rk3399_gpio.c \ ${RK_PLAT_SOC}/drivers/pmu/pmu.c \ - ${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c \ + ${RK_PLAT_SOC}/drivers/pmu/pmu_fw.S \ ${RK_PLAT_SOC}/drivers/pmu/m0_ctl.c \ ${RK_PLAT_SOC}/drivers/pwm/pwm.c \ ${RK_PLAT_SOC}/drivers/secure/secure.c \ @@ -102,7 +102,7 @@ endif # CCACHE_EXTRAFILES is needed because ccache doesn't handle .incbin export CCACHE_EXTRAFILES ${BUILD_PLAT}/bl31/pmu_fw.o: CCACHE_EXTRAFILES=$(RK3399M0FW):$(RK3399M0PMUFW) -${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c: $(RK3399M0FW) +${RK_PLAT_SOC}/drivers/pmu/pmu_fw.S: $(RK3399M0FW) $(eval $(call MAKE_PREREQ_DIR,${BUILD_M0},${BUILD_PLAT})) .PHONY: $(RK3399M0FW) From 31f80efeefaee2c59db50a46cabe2b5fdf20e4ae Mon Sep 17 00:00:00 2001 From: Andrey Skvortsov Date: Fri, 8 Dec 2023 18:04:51 +0300 Subject: [PATCH 2/3] fix(build): enforce single partition for LTO build For example, build for PLAT=fvp SPD=spmd fails with a following error when LTO is enabled using GCC 13.2.1: aarch64-none-elf/bin/ld: /tmp/ccrG0Z8D.ltrans0.ltrans.o: in function `spmd_smc_forward': arm-trusted-firmware/services/std_svc/spmd/spmd_main.c:749:(.text+0xbe50): undefined reference to `rdist_ctx' aarch64-none-elf/bin/ld: arm-trusted-firmware/services/std_svc/spmd/spmd_main.c:749:(.text+0xbe58): undefined reference to `dist_ctx' collect2: error: ld returned 1 exit status Access to rdist_ctx and dist_ctx is defined using inline assembler like __asm__ volatile ("ldr %0, =rdist_ctx" : "=r" (v) : "X" (rdist_ctx)); Access assembler function definitions moved to a different ltrans then actual variables. Partitioner doesn't take into account defined and used symbols in inline assembler. Depending on compiler partitioner decision the same code builds for some platforms successfully. This is a known gcc problem 1. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57703 2. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46820 TF-A source code isn't that big and enforcing single partitioning will not affect build performance, but will fix problems with 'undefined references' related to inline assembler. Change-Id: I72955ab0318f72b588d3a246824f99a48a92d8ef Signed-off-by: Andrey Skvortsov --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 2892f215a..4fc8a7045 100644 --- a/Makefile +++ b/Makefile @@ -325,6 +325,7 @@ else ifeq ($($(ARCH)-ld-id),gnu-gcc) ifeq ($(ENABLE_LTO),1) ifeq (${ARCH},aarch64) TF_LDFLAGS += -flto -fuse-linker-plugin + TF_LDFLAGS += -flto-partition=one endif endif #(ENABLE_LTO) From acf0076ae2e52d1662052f8e6772681d82cc3780 Mon Sep 17 00:00:00 2001 From: Andrey Skvortsov Date: Sat, 24 Feb 2024 00:50:05 +0300 Subject: [PATCH 3/3] build(fpga): correctly handle gcc as linker for LTO When LTO is enabled and gcc is used as a linker, then option for a linker have to be provided with a -Wl prefix to gcc. To build PLAT=arm_fpga with LTO enabled extra '-nostdlib' has to be supplied to the linker at least, otherwise build fails with an error about many undefined references in libc. Since this option is defined as part of common TF_LDFLAGS already, just use that variable with couple extra options. Change-Id: Iaab72d894317c91af5b7d770652e4353b32aae88 Signed-off-by: Andrey Skvortsov --- plat/arm/board/arm_fpga/platform.mk | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk index c9c248fff..ec0b19e7b 100644 --- a/plat/arm/board/arm_fpga/platform.mk +++ b/plat/arm/board/arm_fpga/platform.mk @@ -127,8 +127,14 @@ $(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/rom_trampoline.S,bl31 $(eval $(call MAKE_S,$(BUILD_PLAT),plat/arm/board/arm_fpga/kernel_trampoline.S,bl31)) $(eval $(call MAKE_LD,$(BUILD_PLAT)/build_axf.ld,plat/arm/board/arm_fpga/build_axf.ld.S,bl31)) +ifeq ($($(ARCH)-ld-id),gnu-gcc) + PLAT_LDFLAGS += -Wl,--strip-debug +else + PLAT_LDFLAGS += --strip-debug +endif + bl31.axf: bl31 dtbs ${BUILD_PLAT}/rom_trampoline.o ${BUILD_PLAT}/kernel_trampoline.o ${BUILD_PLAT}/build_axf.ld $(ECHO) " LD $@" - $(Q)$($(ARCH)-ld) -T ${BUILD_PLAT}/build_axf.ld -L ${BUILD_PLAT} --strip-debug -s -n -o ${BUILD_PLAT}/bl31.axf + $(Q)$($(ARCH)-ld) -T ${BUILD_PLAT}/build_axf.ld -L ${BUILD_PLAT} $(TF_LDFLAGS) $(PLAT_LDFLAGS) -s -n -o ${BUILD_PLAT}/bl31.axf all: bl31.axf