From: Ahmad Fatoum <a.fatoum@pengutronix.de> To: barebox@lists.infradead.org Cc: ukl@pengutronix.de, Ahmad Fatoum <a.fatoum@pengutronix.de> Subject: [PATCH 1/3] ARM: implement ENTRY_FUNCTION_WITHSTACK Date: Thu, 2 Dec 2021 08:42:54 +0100 Message-ID: <20211202074256.200325-1-a.fatoum@pengutronix.de> (raw) The point of ENTRY_FUNCTION is to write the entry point in C. Due to lack of __naked on ARM64, the start of the entry point will have prologue using stack and it's not possible to set up the stack safely without branching into non-inline assembly[0]. On ARM32, where we got __naked, we have the potential for a different problem: If BootROM sets up stack for us and we branch to a naked function, which doesn't set up its own stack, compiler may decide to spill local variables overwriting instructions it had already run[1]. For code reuse between ARM and ARM64, it would be nice to use the same entry point structure for both. Currently, the only way is to write it in non-inline assembly using the ENTRY_PROC macro. This introduces another way: the ARM64 barebox header has enough space for 8 instructions of which 5 are unused (2 instructions compiler prologue + 1 instruction to jump after the header), we could place a stack setup routine there to avoid having to write a separate assembly file. For ARM32, we just call arm_setup_stack and branch out directly after, freeing board porters of the burden of getting it right. Add a new ENTRY_FUNCTION_WITHSTACK to realize this. [0]: 76bced6fe146 ("ARM: document arm_setup_stack() pitfalls"), [1]: b51b15ba1738 ("RISC-V: board-dt-2nd: move low level init into nonnaked function") Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> --- arch/arm/include/asm/barebox-arm-head.h | 6 +--- arch/arm/include/asm/barebox-arm.h | 45 +++++++++++++++++++++++++ arch/arm/lib/pbl.lds.S | 1 + 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/arch/arm/include/asm/barebox-arm-head.h b/arch/arm/include/asm/barebox-arm-head.h index 187d12c9fc8d..3e8da0da7c0a 100644 --- a/arch/arm/include/asm/barebox-arm-head.h +++ b/arch/arm/include/asm/barebox-arm-head.h @@ -44,14 +44,10 @@ static inline void __barebox_arm_head(void) "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" - "nop\n" - "nop\n" - "nop\n" - "nop\n" - "nop\n" #endif ".asciz \"barebox\"\n" #ifdef CONFIG_CPU_32 diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h index cfb5943f33d6..d70de6d5e6e6 100644 --- a/arch/arm/include/asm/barebox-arm.h +++ b/arch/arm/include/asm/barebox-arm.h @@ -161,6 +161,51 @@ static inline unsigned long arm_mem_barebox_image(unsigned long membase, } } +#ifdef CONFIG_CPU_64 + +#define ____emit_entry_prologue(instr, ...) do { \ + static __attribute__ ((unused,section(".text_head_prologue"))) \ + const u32 __entry_prologue[] = {(instr), ##__VA_ARGS__}; \ + barrier_data(__entry_prologue); \ +} while(0) + +#define __emit_entry_prologue(instr1, instr2, instr3, instr4, instr5) \ + ____emit_entry_prologue(instr1, instr2, instr3, instr4, instr5) + +#define __ARM_SETUP_STACK(stack_top) \ + __emit_entry_prologue(0x14000002 /* b pc+0x8 */, \ + stack_top /* 32-bit literal */, \ + 0x18ffffe9 /* ldr w9, top */, \ + 0xb4000049 /* cbz x9, pc+0x8 */, \ + 0x9100013f /* mov sp, x9 */) +#else +#define __ARM_SETUP_STACK(stack_top) if (stack_top) arm_setup_stack(stack_top) +#endif + +/* + * Unlike ENTRY_FUNCTION, this can be used to setup stack for a C entry + * point on both ARM32 and ARM64. ENTRY_FUNCTION on ARM64 can only be used + * if preceding boot stage has initialized the stack pointer. + * + * Stack top of 0 means stack is already set up. In that case, the follow-up + * code block will not be inlined and may spill to stack right away. + */ +#define ENTRY_FUNCTION_WITHSTACK(name, stack_top, 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 \ + (ulong r0, ulong r1, ulong r2) \ + { \ + __barebox_arm_head(); \ + __ARM_SETUP_STACK(stack_top); \ + __##name(r0, r1, r2); \ + } \ + static void noinline __##name \ + (ulong arg0, ulong arg1, ulong arg2) + + #define ENTRY_FUNCTION(name, arg0, arg1, arg2) \ void name(ulong r0, ulong r1, ulong r2); \ \ diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S index 0a0fb8b5ac13..e77b3220fcb0 100644 --- a/arch/arm/lib/pbl.lds.S +++ b/arch/arm/lib/pbl.lds.S @@ -31,6 +31,7 @@ SECTIONS .text : { _stext = .; + *(.text_head_prologue*) *(.text_head_entry*) __bare_init_start = .; *(.text_bare_init*) -- 2.30.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox
next reply other threads:[~2021-12-02 7:44 UTC|newest] Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-12-02 7:42 Ahmad Fatoum [this message] 2021-12-02 7:42 ` [PATCH 2/3] ARM: turn arm_mem_stack_top into a macro Ahmad Fatoum 2021-12-02 8:01 ` Ahmad Fatoum 2021-12-07 9:26 ` Sascha Hauer 2021-12-02 7:42 ` [PATCH 3/3] ARM: rpi: use ENTRY_FUNCTION_WITHSTACK to prepare for ARM64 support Ahmad Fatoum 2021-12-02 7:56 ` [PATCH] fixup! ARM: implement ENTRY_FUNCTION_WITHSTACK Ahmad Fatoum
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20211202074256.200325-1-a.fatoum@pengutronix.de \ --to=a.fatoum@pengutronix.de \ --cc=barebox@lists.infradead.org \ --cc=ukl@pengutronix.de \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
mail archive of the barebox mailing list This inbox may be cloned and mirrored by anyone: git clone --mirror https://lore.barebox.org/barebox/0 barebox/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 barebox barebox/ https://lore.barebox.org/barebox \ barebox@lists.infradead.org barebox@lists.infradead.org public-inbox-index barebox Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git