barebox_riscv_entry() is a naked function that switches the stack with
inline assembly and then continues in C. GCC only supports basic asm in
naked functions and clang rejects anything else outright.

Let's move the stack switch into an assembly __barebox_riscv_entry() like
on ARM. barebox_riscv_entry() becomes an always inlined function, so the
naked ENTRY_FUNCTION()s, which may run without a stack, can still call it.

Assisted-by: Claude:opus-5.5
Signed-off-by: Ahmad Fatoum <[email protected]>
---
 arch/riscv/boot/Makefile               |  2 +-
 arch/riscv/boot/entry.c                | 31 --------------------------
 arch/riscv/boot/entry_ll.S             | 15 +++++++++++++
 arch/riscv/include/asm/barebox-riscv.h | 30 ++++++++++++++++++++++---
 4 files changed, 43 insertions(+), 35 deletions(-)
 delete mode 100644 arch/riscv/boot/entry.c
 create mode 100644 arch/riscv/boot/entry_ll.S

diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile
index 936f6e2e0391..2cd6f098d5ef 100644
--- a/arch/riscv/boot/Makefile
+++ b/arch/riscv/boot/Makefile
@@ -1,4 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
-pbl-y += entry.o uncompress.o
+pbl-y += entry_ll.o uncompress.o
 pbl-y += nmon_entry.o
 pbl-$(CONFIG_BOARD_GENERIC_DT) += board-dt-2nd.o
diff --git a/arch/riscv/boot/entry.c b/arch/riscv/boot/entry.c
deleted file mode 100644
index f5a536fc78a9..000000000000
--- a/arch/riscv/boot/entry.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <types.h>
-
-#include <asm/barebox-riscv.h>
-
-#include "entry.h"
-#include <debug_ll.h>
-
-/*
- * Main RISC-V entry point. Call this with the memory region you can
- * spare for barebox. This doesn't necessarily have to be the full
- * SDRAM. The currently running binary can be inside or outside of
- * this region. The PBL can be running inside or outside of this
- * region.
- *
- * -> membase + memsize
- *   STACK_SIZE              - stack
- *   128KiB                  - early memory space
- * -> maximum end of barebox binary
- */
-
-void __noreturn __naked barebox_riscv_entry(unsigned long membase,
-                                           unsigned long memsize, void 
*boarddata,
-                                           unsigned flags)
-{
-       unsigned long stack_top = riscv_mem_stack_top(membase, membase + 
memsize);
-       asm volatile ("move sp, %0" : : "r"(stack_top));
-       riscv_set_flags(flags);
-       barebox_pbl_start(membase, memsize, boarddata);
-}
-
diff --git a/arch/riscv/boot/entry_ll.S b/arch/riscv/boot/entry_ll.S
new file mode 100644
index 000000000000..3611d72a3a78
--- /dev/null
+++ b/arch/riscv/boot/entry_ll.S
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <linux/linkage.h>
+
+/*
+ * a0: memory base
+ * a1: memory size
+ * a2: board data
+ * a3: new value for SP
+ */
+.section .text.__barebox_riscv_entry
+ENTRY(__barebox_riscv_entry)
+       mv      sp, a3
+       tail    barebox_pbl_start
+ENDPROC(__barebox_riscv_entry)
diff --git a/arch/riscv/include/asm/barebox-riscv.h 
b/arch/riscv/include/asm/barebox-riscv.h
index 9fdffb213e8c..4a7726ddc508 100644
--- a/arch/riscv/include/asm/barebox-riscv.h
+++ b/arch/riscv/include/asm/barebox-riscv.h
@@ -25,9 +25,6 @@
 #include <asm/reloc.h>
 #include <pbl/handoff-data.h>
 
-void __noreturn __naked barebox_riscv_entry(unsigned long membase, unsigned 
long memsize,
-                                           void *boarddata, unsigned int 
flags);
-
 #define barebox_riscv_machine_entry(membase, memsize, boarddata) \
        barebox_riscv_entry(membase, memsize, boarddata, RISCV_M_MODE)
 
@@ -82,6 +79,33 @@ static inline unsigned long riscv_mem_barebox_image(unsigned 
long membase,
        return ALIGN_DOWN(endmem - size, SZ_1M);
 }
 
+void __noreturn __barebox_riscv_entry(unsigned long membase,
+                                     unsigned long memsize, void *boarddata,
+                                     unsigned long sp);
+
+/*
+ * Main RISC-V entry point. Call this with the memory region you can
+ * spare for barebox. This doesn't necessarily have to be the full
+ * SDRAM. The currently running binary can be inside or outside of
+ * this region. The PBL can be running inside or outside of this
+ * region.
+ *
+ * -> membase + memsize
+ *   STACK_SIZE              - stack
+ *   128KiB                  - early memory space
+ * -> maximum end of barebox binary
+ *
+ * Inline, so naked ENTRY_FUNCTION()s can call it without a stack.
+ */
+static __always_inline void __noreturn
+barebox_riscv_entry(unsigned long membase, unsigned long memsize,
+                   void *boarddata, unsigned int flags)
+{
+       riscv_set_flags(flags);
+       __barebox_riscv_entry(membase, memsize, boarddata,
+                             riscv_mem_stack_top(membase, membase + memsize));
+}
+
 #define ENTRY_FUNCTION(name, arg0, arg1, arg2)                          \
        void name (ulong r0, ulong r1, ulong r2);                       \
        static void __##name(ulong, ulong, ulong);                      \
-- 
2.47.3


Reply via email to