summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2022-11-14 16:54:36 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2022-11-14 16:54:36 +0100
commit082680652836cd17f2e0bb3da5bec35789e93483 (patch)
tree9fe6b06cade79c42c319370ac0f87d6cb4b01d4d
parentf1b22deeb6ed8bfef865990b8404874e66f9b4d7 (diff)
parent473e5fc818d667d742b4388da8b420e888f2ba28 (diff)
downloadbarebox-082680652836cd17f2e0bb3da5bec35789e93483.tar.gz
Merge branch 'for-next/arm64-entry'
-rw-r--r--Documentation/devel/porting.rst26
-rw-r--r--Makefile3
-rw-r--r--arch/arm/cpu/Kconfig1
-rw-r--r--arch/arm/cpu/Makefile2
-rw-r--r--arch/arm/cpu/head_64.S33
-rw-r--r--arch/arm/include/asm/barebox-arm-head.h17
-rw-r--r--arch/arm/include/asm/barebox-arm.h45
-rw-r--r--arch/arm/lib/pbl.lds.S9
-rw-r--r--arch/arm/mach-mvebu/include/mach/barebox-arm-head.h17
-rw-r--r--images/Makefile1
-rw-r--r--include/asm-generic/memory_layout.h7
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
============
diff --git a/Makefile b/Makefile
index dd6cb471e1..fc11189d23 100644
--- a/Makefile
+++ b/Makefile
@@ -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 */