diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2022-11-14 16:54:36 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2022-11-14 16:54:36 +0100 |
commit | 082680652836cd17f2e0bb3da5bec35789e93483 (patch) | |
tree | 9fe6b06cade79c42c319370ac0f87d6cb4b01d4d | |
parent | f1b22deeb6ed8bfef865990b8404874e66f9b4d7 (diff) | |
parent | 473e5fc818d667d742b4388da8b420e888f2ba28 (diff) | |
download | barebox-082680652836cd17f2e0bb3da5bec35789e93483.tar.gz |
Merge branch 'for-next/arm64-entry'
-rw-r--r-- | Documentation/devel/porting.rst | 26 | ||||
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | arch/arm/cpu/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/cpu/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/cpu/head_64.S | 33 | ||||
-rw-r--r-- | arch/arm/include/asm/barebox-arm-head.h | 17 | ||||
-rw-r--r-- | arch/arm/include/asm/barebox-arm.h | 45 | ||||
-rw-r--r-- | arch/arm/lib/pbl.lds.S | 9 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/include/mach/barebox-arm-head.h | 17 | ||||
-rw-r--r-- | images/Makefile | 1 | ||||
-rw-r--r-- | include/asm-generic/memory_layout.h | 7 |
11 files changed, 92 insertions, 69 deletions
diff --git a/Documentation/devel/porting.rst b/Documentation/devel/porting.rst index dea5ebd1c5..f95e8cbba3 100644 --- a/Documentation/devel/porting.rst +++ b/Documentation/devel/porting.rst @@ -195,14 +195,15 @@ Looking at other boards you might see some different patterns: by using ``ENTRY_FUNCTION_WITHSTACK``, which will take care to initialize the stack beforehand. If either a barebox assembly entry point, ``ENTRY_FUNCTION_WITHSTACK`` or earlier firmware has set up the stack, there is - no reason to use ``__naked``, just use ``ENTRY_FNCTION_WITHSTACK`` with a zero + no reason to use ``__naked``, just use ``ENTRY_FUNCTION_WITHSTACK`` with a zero stack top. ``noinline`` Compiler code inlining is oblivious to stack manipulation in inline assembly. If you want to ensure a new function has its own stack frame (e.g. after setting up the stack in a ``__naked`` function), you must jump to - a ``__noreturn noinline`` function. + a ``__noreturn noinline`` function. This is already handled by + ``ENTRY_FUNCTION_WITHSTACK``. ``arm_setup_stack`` For 32-bit ARM, ``arm_setup_stack`` initializes the stack @@ -214,7 +215,7 @@ Looking at other boards you might see some different patterns: ``__dtb_z_my_board_start[];`` Because the PBL normally doesn't parse anything out of the device tree blob, boards can benefit from keeping the device tree blob - compressed and only unpack it in barebox proper. Such LZO-compressed device trees + compressed and only unpack it in barebox proper. Such compressed device trees are prefixed with ``__dtb_z_``. It's usually a good idea to use this. ``imx6q_barebox_entry(...);`` @@ -232,7 +233,7 @@ Looking at other boards you might see some different patterns: ``*_start_image(...)/*_load_image(...)/*_xload_*(...)`` If the SRAM couldn't fit both PBL and the compressed barebox proper, PBL - will need to chainload full barebox binary from disk. + will need to chainload full barebox binary from the boot medium. Repeating previous advice: The specifics about how different SoCs handle things can vary widely. You're best served by mimicking a similar recently @@ -404,9 +405,18 @@ New header format ================= Your loader may require a specific header or format. If the header is meant -to be executable, it should preferably be added as inline assembly to -the start of the PBL entry points. See ``__barebox_arm_head`` and -``__barebox_riscv_header``. Otherwise, add a new tool to ``scripts/`` +to be executable, it should be written in assembly. +If the C compiler for that platform supports ``__attribute__((naked))``, it +can be written in inline assembly inside such a naked function. See for +example ``__barebox_arm_head`` for ARM32 or ``__barebox_riscv_header`` for RISC-V. + +For platforms, without naked function support, inline assembly may not be used +and the entry point should be written in a dedicated assembly file. +This is the case with ARM64, see for example ``__barebox_arm64_head`` and the +``ENTRY_PROC`` macro. + +Another way, which is often used for non-executable headers with extra +meta-information like a checksum, is adding a new tool to ``scripts/`` and have it run as part the image build process. ``images/`` contains various examples. @@ -434,7 +444,7 @@ well as its prerequisites like clocks, resets or pin multiplexers. Examples for this are the i.MX xload functions. Some BootROMs boot from a FAT file system. There is vfat support in the PBL. Refer to the sama5d2 -baord support for an example. +board support for an example. Core drivers ============ @@ -660,8 +660,7 @@ KBUILD_CFLAGS += $(call cc-option,-fno-stack-check) KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none) # We don't have the necessary infrastructure to benefit from ARMv8.3+ pointer -# authentication. On older CPUs, they are interpreted as NOPs and blot the -# code and break less portable code that expects a very specific code layout +# authentication. On older CPUs, they are interpreted as NOPs bloating the code KBUILD_CFLAGS += $(call cc-option,-mbranch-protection=none) KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) diff --git a/arch/arm/cpu/Kconfig b/arch/arm/cpu/Kconfig index 9b5a833abf..3ef3604737 100644 --- a/arch/arm/cpu/Kconfig +++ b/arch/arm/cpu/Kconfig @@ -16,6 +16,7 @@ config CPU_64 bool select PHYS_ADDR_T_64BIT select HAVE_PBL_IMAGE + select HAVE_PBL_MULTI_IMAGES select HAS_DMA # Select CPU types depending on the architecture selected. This selects diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile index c0993c1abe..7674c1464c 100644 --- a/arch/arm/cpu/Makefile +++ b/arch/arm/cpu/Makefile @@ -13,6 +13,8 @@ AFLAGS_hyp.pbl.o :=-Wa,-march=armv7-a -Wa,-mcpu=all obj-y += start.o entry.o entry_ll$(S64).o KASAN_SANITIZE_start.o := n +pbl-$(CONFIG_CPU_64) += head_64.o + pbl-$(CONFIG_BOARD_ARM_GENERIC_DT) += board-dt-2nd.o pbl-$(CONFIG_BOARD_ARM_GENERIC_DT_AARCH64) += board-dt-2nd-aarch64.o diff --git a/arch/arm/cpu/head_64.S b/arch/arm/cpu/head_64.S new file mode 100644 index 0000000000..f934e96c6e --- /dev/null +++ b/arch/arm/cpu/head_64.S @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include <linux/linkage.h> +#include <asm/barebox-arm64.h> +#include <asm/image.h> + +/* Linker will point these at board-specific symbols */ +.globl __pbl_board_stack_top +.globl __pbl_board_entry + +.section .text_head_prologue_common, "x" +ENTRY(__barebox_arm64_head) + nop + adr x9, __pbl_board_stack_top + ldr w9, [x9] + cbz x9, 1f + mov sp, x9 +1: +#ifdef CONFIG_PBL_BREAK + brk #17 + nop +#else + nop + nop +#endif + b __pbl_board_entry + .org 0x20 + .asciz "barebox" + .word 0xffffffff + .word _barebox_image_size /* image size to copy */ + .rept 8 + .word 0x55555555 + .endr +END(__barebox_arm64_head) diff --git a/arch/arm/include/asm/barebox-arm-head.h b/arch/arm/include/asm/barebox-arm-head.h index 099e1bef3c..1a1d58c1aa 100644 --- a/arch/arm/include/asm/barebox-arm-head.h +++ b/arch/arm/include/asm/barebox-arm-head.h @@ -18,13 +18,13 @@ void barebox_arm_reset_vector(uint32_t r0, uint32_t r1, uint32_t r2); #define ARM_HEAD_SPARE_OFS 0x30 #define ARM_HEAD_SPARE_MARKER 0x55555555 +#ifdef CONFIG_CPU_32 #ifdef CONFIG_HAVE_MACH_ARM_HEAD #include <mach/barebox-arm-head.h> #else static inline void __barebox_arm_head(void) { __asm__ __volatile__ ( -#ifdef CONFIG_CPU_32 #ifdef CONFIG_THUMB2_BAREBOX ".arm\n" "adr r9, 1f + 1\n" @@ -45,31 +45,17 @@ static inline void __barebox_arm_head(void) "1: b 1b\n" "1: b 1b\n" #endif -#else - /* 5 instructions added by ENTRY_FUNCTION */ - /* two instruction long function prologue */ - /* only use if stack is initialized! */ - "b 2f\n" -#endif ".asciz \"barebox\"\n" -#ifdef CONFIG_CPU_32 ".word _text\n" /* text base. If copied there, * barebox can skip relocation */ -#else - ".word 0xffffffff\n" -#endif ".word _barebox_image_size\n" /* image size to copy */ ".rept 8\n" ".word 0x55555555\n" ".endr\n" "2:\n" #ifdef CONFIG_PBL_BREAK -#ifdef CONFIG_CPU_V8 - "brk #17\n" -#else "bkpt #17\n" -#endif "nop\n" #else "nop\n" @@ -85,6 +71,7 @@ static inline void barebox_arm_head(void) ); } #endif +#endif #endif /* __ASSEMBLY__ */ diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h index a34f77f2ab..dd12f642d9 100644 --- a/arch/arm/include/asm/barebox-arm.h +++ b/arch/arm/include/asm/barebox-arm.h @@ -136,24 +136,7 @@ static inline unsigned long arm_mem_barebox_image(unsigned long membase, } } -#ifdef CONFIG_CPU_64 - -#define ____emit_entry_prologue(name, instr, ...) do { \ - static __attribute__ ((unused,section(".text_head_prologue_" __stringify(name)))) \ - const u32 __entry_prologue[] = {(instr), ##__VA_ARGS__}; \ - barrier_data(__entry_prologue); \ -} while(0) - -#define __emit_entry_prologue(name, instr1, instr2, instr3, instr4, instr5) \ - ____emit_entry_prologue(name, instr1, instr2, instr3, instr4, instr5) - -#define __ARM_SETUP_STACK(name, stack_top) \ - __emit_entry_prologue(name, 0x14000002 /* b pc+0x8 */, \ - stack_top /* 32-bit literal */, \ - 0x18ffffe9 /* ldr w9, top */, \ - 0xb4000049 /* cbz x9, pc+0x8 */, \ - 0x9100013f /* mov sp, x9 */) -#else +#ifndef CONFIG_CPU_64 #define __ARM_SETUP_STACK(name, stack_top) if (stack_top) arm_setup_stack(stack_top) #endif @@ -166,6 +149,9 @@ static inline unsigned long arm_mem_barebox_image(unsigned long membase, * code block will not be inlined and may spill to stack right away. */ #ifdef CONFIG_CPU_64 + +void __barebox_arm64_head(ulong x0, ulong x1, ulong x2); + #define ENTRY_FUNCTION_WITHSTACK(name, stack_top, arg0, arg1, arg2) \ void name(ulong r0, ulong r1, ulong r2); \ \ @@ -174,39 +160,44 @@ static inline unsigned long arm_mem_barebox_image(unsigned long membase, void __section(.text_head_entry_##name) name \ (ulong r0, ulong r1, ulong r2) \ { \ - __barebox_arm_head(); \ - __ARM_SETUP_STACK(name, stack_top); \ + static __section(.pbl_board_stack_top_##name) \ + const u32 __stack_top = (stack_top); \ + __keep_symbolref(__barebox_arm64_head); \ + __keep_symbolref(__stack_top); \ __##name(r0, r1, r2); \ } \ static void noinline __##name \ (ulong arg0, ulong arg1, ulong arg2) + +#define ENTRY_FUNCTION(name, arg0, arg1, arg2) \ + ENTRY_FUNCTION_WITHSTACK(name, 0, arg0, arg1, arg2) + #else #define ENTRY_FUNCTION_WITHSTACK(name, stack_top, arg0, arg1, arg2) \ static void ____##name(ulong, ulong, ulong); \ ENTRY_FUNCTION(name, arg0, arg1, arg2) \ { \ - __ARM_SETUP_STACK(name, stack_top); \ + if (stack_top) \ + arm_setup_stack(stack_top); \ ____##name(arg0, arg1, arg2); \ } \ static void noinline ____##name \ (ulong arg0, ulong arg1, ulong arg2) -#endif - #define ENTRY_FUNCTION(name, arg0, arg1, arg2) \ void name(ulong r0, ulong r1, ulong r2); \ \ static void __##name(ulong, ulong, ulong); \ \ - void NAKED __section(.text_head_entry_##name) name \ + void __naked __section(.text_head_entry_##name) name \ (ulong r0, ulong r1, ulong r2) \ { \ __barebox_arm_head(); \ - __ARM_SETUP_STACK(name, 0); \ __##name(r0, r1, r2); \ } \ - static void NAKED noinline __##name \ - (ulong arg0, ulong arg1, ulong arg2) + static void __naked noinline __##name \ + (ulong arg0, ulong arg1, ulong arg2) +#endif /* * When using compressed images in conjunction with relocatable images diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S index ae1babdcfd..114ec7bc81 100644 --- a/arch/arm/lib/pbl.lds.S +++ b/arch/arm/lib/pbl.lds.S @@ -44,6 +44,15 @@ SECTIONS . = ALIGN(4); .rodata : { *(.rodata*) } + . = ALIGN(4); + __pbl_board_stack_top = .; + .rodata.pbl_board_stack_top : { + *(.pbl_board_stack_top_*) + /* Dummy for when BootROM sets up usable stack */ + LONG(0x00000000); + } + ASSERT(. - __pbl_board_stack_top <= 8, "Only One PBL per Image allowed") + .barebox_imd : { BAREBOX_IMD } _etext = .; /* End of text and rodata section */ diff --git a/arch/arm/mach-mvebu/include/mach/barebox-arm-head.h b/arch/arm/mach-mvebu/include/mach/barebox-arm-head.h index 12f8cfc5a0..2ef3377402 100644 --- a/arch/arm/mach-mvebu/include/mach/barebox-arm-head.h +++ b/arch/arm/mach-mvebu/include/mach/barebox-arm-head.h @@ -6,7 +6,6 @@ static inline void __barebox_arm_head(void) { __asm__ __volatile__ ( -#ifdef CONFIG_CPU_32 #ifdef CONFIG_THUMB2_BAREBOX ".arm\n" "adr r9, 1f + 1\n" @@ -27,22 +26,10 @@ static inline void __barebox_arm_head(void) "1: b 1b\n" "1: b 1b\n" #endif -#else - "b 2f\n" - "nop\n" - "nop\n" - "nop\n" - "nop\n" - "nop\n" -#endif ".asciz \"barebox\"\n" -#ifdef CONFIG_CPU_32 ".word _text\n" /* text base. If copied there, * barebox can skip relocation */ -#else - ".word 0xffffffff\n" -#endif ".word _barebox_image_size\n" /* image size to copy */ /* @@ -58,11 +45,7 @@ static inline void __barebox_arm_head(void) ".endr\n" "2:\n" #ifdef CONFIG_PBL_BREAK -#ifdef CONFIG_CPU_V8 - "brk #17\n" -#else "bkpt #17\n" -#endif "nop\n" #else "nop\n" diff --git a/images/Makefile b/images/Makefile index 218a24ff1d..aa5814710f 100644 --- a/images/Makefile +++ b/images/Makefile @@ -59,6 +59,7 @@ $(pbl-lds): $(obj)/../arch/$(SRCARCH)/lib/pbl.lds.S FORCE quiet_cmd_elf__ ?= LD $@ cmd_elf__ ?= $(LD) $(LDFLAGS_pbl) --gc-sections \ -e $(2) -Map $@.map $(LDFLAGS_$(@F)) -o $@ \ + --defsym=__pbl_board_entry=$(2) \ -T $(pbl-lds) \ --whole-archive $(BAREBOX_PBL_OBJS) $(obj)/piggy.o \ $(obj)/sha_sum.o diff --git a/include/asm-generic/memory_layout.h b/include/asm-generic/memory_layout.h index 5cfd2a43a0..7593e18da1 100644 --- a/include/asm-generic/memory_layout.h +++ b/include/asm-generic/memory_layout.h @@ -23,4 +23,11 @@ #define MALLOC_SIZE CONFIG_MALLOC_SIZE #define STACK_SIZE CONFIG_STACK_SIZE +/* + * This generates a useless load from the specified symbol + * to ensure linker garbage collection doesn't delete it + */ +#define __keep_symbolref(sym) \ + __asm__ __volatile__("": :"r"(&sym) :) + #endif /* __ASM_GENERIC_MEMORY_LAYOUT_H */ |