armv8: add lowlevel_init.S
authorAndre Przywara <andre.przywara@arm.com>
Mon, 2 Jan 2017 11:48:27 +0000 (11:48 +0000)
committerJagan Teki <jagan@openedev.com>
Wed, 4 Jan 2017 15:37:40 +0000 (16:37 +0100)
For boards that call s_init() when the SPL runs, we are expected to
setup an early stack before calling this C function.
Implement the proper AArch64 version of this based on the ARMv7 code.
This allows sunxi boards to setup the basic peripherals even with a
64-bit SPL.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Jagan Teki <jagan@openedev.com>
arch/arm/cpu/armv8/Makefile
arch/arm/cpu/armv8/lowlevel_init.S [new file with mode: 0644]

index 28ba7862072a2cc165c87bea0877e9422a76c520..e780afcde25ae918f9767952d96e500c092e9217 100644 (file)
@@ -26,3 +26,4 @@ obj-$(CONFIG_S32V234) += s32v234/
 obj-$(CONFIG_ARCH_ZYNQMP) += zynqmp/
 obj-$(CONFIG_TARGET_HIKEY) += hisilicon/
 obj-$(CONFIG_ARMV8_PSCI) += psci.o
+obj-$(CONFIG_ARCH_SUNXI) += lowlevel_init.o
diff --git a/arch/arm/cpu/armv8/lowlevel_init.S b/arch/arm/cpu/armv8/lowlevel_init.S
new file mode 100644 (file)
index 0000000..189e35f
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * A lowlevel_init function that sets up the stack to call a C function to
+ * perform further init.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+       /*
+        * Setup a temporary stack. Global data is not available yet.
+        */
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
+       ldr     w0, =CONFIG_SPL_STACK
+#else
+       ldr     w0, =CONFIG_SYS_INIT_SP_ADDR
+#endif
+       bic     sp, x0, #0xf    /* 16-byte alignment for ABI compliance */
+
+       /*
+        * Save the old LR(passed in x29) and the current LR to stack
+        */
+       stp     x29, x30, [sp, #-16]!
+
+       /*
+        * Call the very early init function. This should do only the
+        * absolute bare minimum to get started. It should not:
+        *
+        * - set up DRAM
+        * - use global_data
+        * - clear BSS
+        * - try to start a console
+        *
+        * For boards with SPL this should be empty since SPL can do all of
+        * this init in the SPL board_init_f() function which is called
+        * immediately after this.
+        */
+       bl      s_init
+       ldp     x29, x30, [sp]
+       ret
+ENDPROC(lowlevel_init)