diff --git a/Makefile b/Makefile index 7b0ef5b..6386bef 100644 --- a/Makefile +++ b/Makefile @@ -245,8 +245,13 @@ GCC_V_OUTPUT := $(shell $(CC) -v 2>&1) +ifneq ($(findstring armlink,$(notdir $(LD))),) +TF_LDFLAGS += --diag_error=warning --lto_level=O1 +TF_LDFLAGS += --remove --info=unused,unusedsymbols +else TF_LDFLAGS += --fatal-warnings -O1 TF_LDFLAGS += --gc-sections +endif TF_LDFLAGS += $(TF_LDFLAGS_$(ARCH)) DTC_FLAGS += -I dts -O dtb @@ -714,6 +719,10 @@ $(eval $(call add_define,DYN_DISABLE_AUTH)) endif +ifneq ($(findstring armlink,$(notdir $(LD))),) +$(eval $(call add_define,USE_ARM_LINK)) +endif + ################################################################################ # Build targets ################################################################################ @@ -728,8 +737,12 @@ # Check if deprecated declarations and cpp warnings should be treated as error or not. ifeq (${ERROR_DEPRECATED},0) +ifneq ($(findstring clang,$(notdir $(CC))),) + CPPFLAGS += -Wno-error=deprecated-declarations +else CPPFLAGS += -Wno-error=deprecated-declarations -Wno-error=cpp endif +endif $(eval $(call MAKE_LIB_DIRS)) $(eval $(call MAKE_LIB,c)) diff --git a/docs/plat/nvidia-tegra.rst b/docs/plat/nvidia-tegra.rst index 7ed0f2c..6a03b12 100644 --- a/docs/plat/nvidia-tegra.rst +++ b/docs/plat/nvidia-tegra.rst @@ -82,6 +82,16 @@ Tegra210: TLK and Trusty Tegra186: Trusty +Scatter files +============= + +Tegra platforms currently support scatter files and ld.S scripts. The scatter +files help support ARMLINK linker to generate BL31 binaries. For now, there +exists a common scatter file, plat/nvidia/tegra/scat/bl31.scat, for all Tegra +SoCs. The `LINKER` build variable needs to point to the ARMLINK binary for +the scatter file to be used. Tegra platforms have verified BL31 image generation +with ARMCLANG (compilation) and ARMLINK (linking) for the Tegra186 platforms. + Preparing the BL31 image to run on Tegra SoCs ============================================= diff --git a/docs/user-guide.rst b/docs/user-guide.rst index b602956..d3c63c7 100644 --- a/docs/user-guide.rst +++ b/docs/user-guide.rst @@ -729,6 +729,12 @@ Note: when ``EL3_EXCEPTION_HANDLING`` is ``1``, ``TSP_NS_INTR_ASYNC_PREEMPT`` must also be set to ``1``. +- ``USE_ARM_LINK``: This flag determines whether to enable support for ARM + linker. When the ``LINKER`` build variable points to the armlink linker, + this flag is enabled automatically. To enable support for armlink, platforms + will have to provide a scatter file for the BL image. Currently, Tegra + platforms use the armlink support to compile BL3-1 images. + - ``USE_COHERENT_MEM``: This flag determines whether to include the coherent memory region in the BL memory map or not (see "Use of Coherent memory in TF-A" section in `Firmware Design`_). It can take the value 1 diff --git a/include/common/bl_common.h b/include/common/bl_common.h index 9817ec7..457dc2a 100644 --- a/include/common/bl_common.h +++ b/include/common/bl_common.h @@ -57,6 +57,48 @@ #define FIQ_AARCH32 U(0xe) #define SERROR_AARCH32 U(0xf) +/* + * Mapping to connect linker symbols from .ld.S with their counterparts + * from .scat for the BL31 image + */ +#if defined(USE_ARM_LINK) +#define __BL31_END__ Load$$LR$$LR_END$$Base +#define __BSS_START__ Load$$LR$$LR_BSS$$Base +#define __BSS_END__ Load$$LR$$LR_BSS$$Limit +#define __BSS_SIZE__ Load$$LR$$LR_BSS$$Length +#define __COHERENT_RAM_START__ Load$$LR$$LR_COHERENT_RAM$$Base +#define __COHERENT_RAM_END_UNALIGNED__ Load$$__COHERENT_RAM_EPILOGUE_UNALIGNED__$$Base +#define __COHERENT_RAM_END__ Load$$LR$$LR_COHERENT_RAM$$Limit +#define __COHERENT_RAM_UNALIGNED_SIZE__ Load$$__COHERENT_RAM__$$Length +#define __CPU_OPS_START__ Load$$__CPU_OPS__$$Base +#define __CPU_OPS_END__ Load$$__CPU_OPS__$$Limit +#define __DATA_START__ Load$$__DATA__$$Base +#define __DATA_END__ Load$$__DATA__$$Limit +#define __GOT_START__ Load$$__GOT__$$Base +#define __GOT_END__ Load$$__GOT__$$Limit +#define __PERCPU_BAKERY_LOCK_START__ Load$$__BAKERY_LOCKS__$$Base +#define __PERCPU_BAKERY_LOCK_END__ Load$$__BAKERY_LOCKS_EPILOGUE__$$Base +#define __PMF_SVC_DESCS_START__ Load$$__PMF_SVC_DESCS__$$Base +#define __PMF_SVC_DESCS_END__ Load$$__PMF_SVC_DESCS__$$Limit +#define __PMF_TIMESTAMP_START__ Load$$__PMF_TIMESTAMP__$$Base +#define __PMF_TIMESTAMP_END__ Load$$__PER_CPU_TIMESTAMPS__$$Limit +#define __PMF_PERCPU_TIMESTAMP_END__ Load$$__PMF_TIMESTAMP_EPILOGUE__$$Base +#define __RELA_END__ Load$$__RELA__$$Limit +#define __RELA_START__ Load$$__RELA__$$Base +#define __RODATA_START__ Load$$__RODATA__$$Base +#define __RODATA_END__ Load$$__RODATA_EPILOGUE__$$Base +#define __RT_SVC_DESCS_START__ Load$$__RT_SVC_DESCS__$$Base +#define __RT_SVC_DESCS_END__ Load$$__RT_SVC_DESCS__$$Limit +#define __RW_START__ Load$$LR$$LR_RW_DATA$$Base +#define __RW_END__ Load$$LR$$LR_END$$Base +#define __SPM_SHIM_EXCEPTIONS_START__ Load$$__SPM_SHIM_EXCEPTIONS__$$Base +#define __SPM_SHIM_EXCEPTIONS_END__ Load$$__SPM_SHIM_EXCEPTIONS_EPILOGUE__$$Base +#define __STACKS_START__ Load$$__STACKS__$$Base +#define __STACKS_END__ Load$$__STACKS__$$Limit +#define __TEXT_START__ Load$$__TEXT__$$Base +#define __TEXT_END__ Load$$__TEXT_EPILOGUE__$$Base +#endif /* USE_ARM_LINK */ + #ifndef __ASSEMBLY__ #include diff --git a/include/lib/el3_runtime/pubsub.h b/include/lib/el3_runtime/pubsub.h index 9c303f5..64fe5cc 100644 --- a/include/lib/el3_runtime/pubsub.h +++ b/include/lib/el3_runtime/pubsub.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,13 +7,11 @@ #ifndef PUBSUB_H #define PUBSUB_H -#define __pubsub_start_sym(event) __pubsub_##event##_start -#define __pubsub_end_sym(event) __pubsub_##event##_end - #ifdef __LINKER__ /* For the linker ... */ - +#define __pubsub_start_sym(event) __pubsub_##event##_start +#define __pubsub_end_sym(event) __pubsub_##event##_end #define __pubsub_section(event) __pubsub_##event /* @@ -21,10 +19,22 @@ * contexts. In linker context, this collects pubsub sections for each event, * placing guard symbols around each. */ +#if defined(USE_ARM_LINK) +#define REGISTER_PUBSUB_EVENT(event) \ + __pubsub_start_sym(event) +0 FIXED \ + { \ + *(__pubsub_section(event)) \ + } \ + __pubsub_end_sym(event) +0 FIXED EMPTY 0 \ + { \ + /* placeholder */ \ + } +#else #define REGISTER_PUBSUB_EVENT(event) \ __pubsub_start_sym(event) = .; \ KEEP(*(__pubsub_section(event))); \ __pubsub_end_sym(event) = . +#endif #else /* __LINKER__ */ @@ -36,6 +46,14 @@ #include +#if defined(USE_ARM_LINK) +#define __pubsub_start_sym(event) Load$$__pubsub_##event##_start$$Base +#define __pubsub_end_sym(event) Load$$__pubsub_##event##_end$$Base +#else +#define __pubsub_start_sym(event) __pubsub_##event##_start +#define __pubsub_end_sym(event) __pubsub_##event##_end +#endif + #define __pubsub_section(event) __section("__pubsub_" #event) /* diff --git a/lib/cpus/aarch32/cpu_helpers.S b/lib/cpus/aarch32/cpu_helpers.S index f84cd0d..f37a33d 100644 --- a/lib/cpus/aarch32/cpu_helpers.S +++ b/lib/cpus/aarch32/cpu_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,6 +8,7 @@ #include #include #include +#include #include #if defined(IMAGE_BL1) || defined(IMAGE_BL32) || (defined(IMAGE_BL2) && BL2_AT_EL3) diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S index 74d7bb2..de1177c 100644 --- a/lib/cpus/aarch64/cpu_helpers.S +++ b/lib/cpus/aarch64/cpu_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk index 4a264d7..5d33954 100644 --- a/make_helpers/build_macros.mk +++ b/make_helpers/build_macros.mk @@ -355,8 +355,13 @@ .PHONY : lib${1}_dirs lib${1}_dirs: | ${BUILD_DIR} ${LIB_DIR} ${ROMLIB_DIR} ${LIBWRAPPER_DIR} libraries: ${LIB_DIR}/lib$(1).a +ifneq ($(findstring armlink,$(notdir $(LD))),) +LDPATHS = --userlibpath=${LIB_DIR} +LDLIBS += --library=$(1) +else LDPATHS = -L${LIB_DIR} LDLIBS += -l$(1) +endif ifeq ($(USE_ROMLIB),1) LIBWRAPPER = -lwrappers @@ -421,9 +426,18 @@ const char version_string[] = "${VERSION_STRING}";' | \ $$(CC) $$(TF_CFLAGS) $$(CFLAGS) -xc -c - -o $(BUILD_DIR)/build_message.o endif +ifneq ($(findstring armlink,$(notdir $(LD))),) + $$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) --entry=bl${1}_entrypoint \ + --predefine="-D__LINKER__=$(__LINKER__)" \ + --predefine="-DTF_CFLAGS=$(TF_CFLAGS)" \ + --map --list="$(MAPFILE)" --scatter=${PLAT_DIR}/scat/bl${1}.scat \ + $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) \ + $(BUILD_DIR)/build_message.o $(OBJS) +else $$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Map=$(MAPFILE) \ --script $(LINKERFILE) $(BUILD_DIR)/build_message.o \ $(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) +endif $(DUMP): $(ELF) $${ECHO} " OD $$@" diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk index 6ef1900..b429eb7 100644 --- a/plat/nvidia/tegra/platform.mk +++ b/plat/nvidia/tegra/platform.mk @@ -59,3 +59,18 @@ INCLUDES += -Iinclude/lib/libc \ -Iinclude/lib/libc/$(ARCH) \ + +ifneq ($(findstring armlink,$(notdir $(LD))),) +# o suppress warnings for section mismatches, undefined symbols +# o use only those libraries that are specified in the input file +# list to resolve references +# o create a static callgraph of functions +# o resolve undefined symbols to el3_panic +# o include only required sections +TF_LDFLAGS += --diag_suppress=L6314,L6332 --no_scanlib --callgraph +TF_LDFLAGS += --unresolved=el3_panic +TF_LDFLAGS += --keep="*(__pubsub*)" --keep="*(rt_svc_descs*)" --keep="*(*cpu_ops)" +ifeq (${ENABLE_PMF},1) +TF_LDFLAGS += --keep="*(*pmf_svc_descs*)" +endif +endif diff --git a/plat/nvidia/tegra/scat/bl31.scat b/plat/nvidia/tegra/scat/bl31.scat new file mode 100644 index 0000000..2f5fd9e --- /dev/null +++ b/plat/nvidia/tegra/scat/bl31.scat @@ -0,0 +1,284 @@ +#! armclang -E -x c + +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#define PAGE_SIZE (1024 * 4) + +LR_START BL31_BASE +{ + __BL31_START__ +0 FIXED EMPTY 0 + { + /* placeholder */ + } + + /* BL31_BASE address must be aligned on a page boundary. */ + ScatterAssert((ImageBase(__BL31_START__) AND 0xFFF) == 0) +} + +LR_TEXT BL31_BASE +{ + __TEXT__ +0 FIXED + { + *(:gdef:bl31_entrypoint, +FIRST) + *(.text*) + *(.vectors) + .ANY1(+RO-CODE) + } + + __TEXT_EPILOGUE__ AlignExpr(+0, PAGE_SIZE) FIXED EMPTY 0 + { + /* section delimiter */ + } +} + +LR_RO_DATA +0 +{ + __RODATA__ AlignExpr(ImageLimit(LR_TEXT), 0) FIXED + { + *(.rodata*) + .ANY2(+RO-DATA) + } + + /* Ensure 8-byte alignment for descriptors and ensure inclusion */ + __RT_SVC_DESCS__ AlignExpr(ImageLimit(__RODATA__), 8) FIXED + { + *(rt_svc_descs) + } + +#if ENABLE_PMF + /* Ensure 8-byte alignment for descriptors and ensure inclusion */ + __PMF_SVC_DESCS__ AlignExpr(ImageLimit(__RT_SVC_DESCS__), 8) FIXED + { + *(pmf_svc_descs) + } +#endif /* ENABLE_PMF */ + + /* + * Ensure 8-byte alignment for cpu_ops so that its fields are also + * aligned. + */ + __CPU_OPS__ AlignExpr(+0, 8) FIXED + { + *(cpu_ops) + } + + /* + * Keep the .got section in the RO section as it is patched + * prior to enabling the MMU and having the .got in RO is better for + * security. GOT is a table of addresses so ensure 8-byte alignment. + */ + __GOT__ AlignExpr(ImageLimit(__CPU_OPS__), 8) FIXED + { + *(.got) + } + + /* Place pubsub sections for events */ + __PUBSUB_EVENTS__ AlignExpr(+0, 8) EMPTY 0 + { + /* placeholder */ + } + +#include + + __RODATA_EPILOGUE__ AlignExpr(+0, PAGE_SIZE) FIXED EMPTY 0 + { + /* section delimiter */ + } +} + + /* cpu_ops must always be defined */ + ScatterAssert(ImageLength(__CPU_OPS__) > 0) + +#if ENABLE_SPM +LR_SPM +0 +{ + /* + * Exception vectors of the SPM shim layer. They must be aligned to a 2K + * address, but we need to place them in a separate page so that we can set + * individual permissions to them, so the actual alignment needed is 4K. + * + * There's no need to include this into the RO section of BL31 because it + * doesn't need to be accessed by BL31. + */ + __SPM_SHIM_EXCEPTIONS__ AlignExpr(ImageLimit(LR_RO_DATA), PAGE_SIZE) FIXED + { + *(.spm_shim_exceptions) + } + + __SPM_SHIM_EXCEPTIONS_EPILOGUE__ AlignExpr(ImageLimit(__SPM_SHIM_EXCEPTIONS__), PAGE_SIZE) FIXED + { + /* placeholder */ + } +} +#endif + +LR_RW_DATA +0 +{ + __DATA__ AlignExpr(+0, 16) FIXED + { + *(.data*) + *(.constdata) + *(locale$$data) + } +} + +LR_RELA +0 +{ + /* + * .rela.dyn needs to come after .data for the read-elf utility to parse + * this section correctly. Ensure 8-byte alignment so that the fields of + * RELA data structure are aligned. + */ + __RELA__ AlignExpr(ImageLimit(LR_RW_DATA), 8) FIXED + { + *(.rela.dyn) + } +} + +#ifdef BL31_PROGBITS_LIMIT + /* BL31 progbits has exceeded its limit. */ + ScatterAssert(ImageLimit(LR_RELA) <= BL31_PROGBITS_LIMIT) +#endif + +LR_STACKS +0 +{ + __STACKS__ AlignExpr(+0, 64) FIXED + { + *(tzfw_normal_stacks) + } +} + +#define __BAKERY_LOCK_SIZE__ (ImageLimit(__BAKERY_LOCKS_EPILOGUE__) - \ + ImageBase(__BAKERY_LOCKS__)) +#define BAKERY_LOCK_SIZE (__BAKERY_LOCK_SIZE__ * (PLATFORM_CORE_COUNT - 1)) +#define __PMF_TIMESTAMP_SIZE__ (ImageLimit(__PMF_TIMESTAMP__) - \ + ImageBase(__PMF_TIMESTAMP__)) +#define PER_CPU_TIMESTAMP_SIZE (__PMF_TIMESTAMP_SIZE__ * (PLATFORM_CORE_COUNT - 1)) + +LR_BSS +0 +{ + __BSS__ AlignExpr(ImageLimit(LR_STACKS), 256) FIXED + { + *(.bss*) + *(COMDAT) + } + +#if !USE_COHERENT_MEM + /* + * Bakery locks are stored in normal .bss memory + * + * Each lock's data is spread across multiple cache lines, one per CPU, + * but multiple locks can share the same cache line. + * The compiler will allocate enough memory for one CPU's bakery locks, + * the remaining cache lines are allocated by the linker script + */ + __BAKERY_LOCKS__ AlignExpr(ImageLimit(__BSS__), CACHE_WRITEBACK_GRANULE) FIXED + { + *(bakery_lock) + } + + __BAKERY_LOCKS_EPILOGUE__ AlignExpr(ImageLimit(__BAKERY_LOCKS__), CACHE_WRITEBACK_GRANULE) FIXED EMPTY 0 + { + /* section delimiter */ + } + + __PER_CPU_BAKERY_LOCKS__ ImageLimit(__BAKERY_LOCKS_EPILOGUE__) FIXED FILL 0 BAKERY_LOCK_SIZE + { + /* padded memory section to store per cpu bakery locks */ + } + +#ifdef PLAT_PERCPU_BAKERY_LOCK_SIZE + /* PLAT_PERCPU_BAKERY_LOCK_SIZE does not match bakery lock requirements */ + ScatterAssert(__PER_CPU_BAKERY_LOCK_SIZE__ == PLAT_PERCPU_BAKERY_LOCK_SIZE) +#endif +#endif + +#if ENABLE_PMF + /* + * Time-stamps are stored in normal .bss memory + * + * The compiler will allocate enough memory for one CPU's time-stamps, + * the remaining memory for other CPU's is allocated by the + * linker script + */ + __PMF_TIMESTAMP__ AlignExpr(+0, CACHE_WRITEBACK_GRANULE) FIXED EMPTY CACHE_WRITEBACK_GRANULE + { + /* store timestamps in this carved out memory */ + } + + __PMF_TIMESTAMP_EPILOGUE__ AlignExpr(ImageLimit(__PMF_TIMESTAMP__), CACHE_WRITEBACK_GRANULE) FIXED EMPTY 0 + { + /* + * placeholder to make __PMF_TIMESTAMP_START__ end on a + * CACHE_WRITEBACK_GRANULE boundary + */ + } + + __PER_CPU_TIMESTAMPS__ +0 FIXED FILL 0 PER_CPU_TIMESTAMP_SIZE + { + /* padded memory section to store per cpu timestamps */ + } +#endif /* ENABLE_PMF */ +} + +LR_XLAT_TABLE +0 +{ + xlat_table +0 FIXED + { + *(xlat_table) + } +} + +#if USE_COHERENT_MEM +LR_COHERENT_RAM +0 +{ + /* + * The base address of the coherent memory section must be page-aligned (4K) + * to guarantee that the coherent data are stored on their own pages and + * are not mixed with normal data. This is required to set up the correct + * memory attributes for the coherent data page tables. + */ + __COHERENT_RAM__ AlignExpr(+0, PAGE_SIZE) FIXED + { + /* + * Bakery locks are stored in coherent memory + * + * Each lock's data is contiguous and fully allocated by the compiler + */ + *(bakery_lock) + *(tzfw_coherent_mem) + } + + __COHERENT_RAM_EPILOGUE_UNALIGNED__ +0 FIXED EMPTY 0 + { + /* section delimiter */ + } + + /* + * Memory page(s) mapped to this section will be marked + * as device memory. No other unexpected data must creep in. + * Ensure the rest of the current memory page is unused. + */ + __COHERENT_RAM_EPILOGUE__ AlignExpr(ImageLimit(__COHERENT_RAM_START__), PAGE_SIZE) FIXED EMPTY 0 + { + /* section delimiter */ + } +} +#endif + +LR_END +0 +{ + __BL31_END__ +0 FIXED EMPTY 0 + { + /* placeholder */ + } + + /* BL31 image has exceeded its limit. */ + ScatterAssert(ImageLimit(__BL31_END__) <= BL31_LIMIT) +}