diff mbox

[U-Boot,v2,03/23] armv8: add lowlevel_init.S

Message ID 1480902750-839-4-git-send-email-andre.przywara@arm.com
State Superseded
Delegated to: Jagannadha Sutradharudu Teki
Headers show

Commit Message

Andre Przywara Dec. 5, 2016, 1:52 a.m. UTC
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 on with a
64-bit SPL.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
 arch/arm/cpu/armv8/Makefile        |  1 +
 arch/arm/cpu/armv8/lowlevel_init.S | 44 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+)
 create mode 100644 arch/arm/cpu/armv8/lowlevel_init.S

Comments

Simon Glass Dec. 5, 2016, 6:26 a.m. UTC | #1
Hi Andre,

On 4 December 2016 at 18:52, Andre Przywara <andre.przywara@arm.com> wrote:
> 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 on with a
> 64-bit SPL.
>
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> ---
>  arch/arm/cpu/armv8/Makefile        |  1 +
>  arch/arm/cpu/armv8/lowlevel_init.S | 44 ++++++++++++++++++++++++++++++++++++++
>  2 files changed, 45 insertions(+)
>  create mode 100644 arch/arm/cpu/armv8/lowlevel_init.S

Is this actually needed / used for anything?

Regards,
Simon
Tom Rini Dec. 5, 2016, 9:56 p.m. UTC | #2
On Mon, Dec 05, 2016 at 01:52:10AM +0000, Andre Przywara wrote:

> 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 on with a
> 64-bit SPL.
> 
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>

This is going to override lowlevel_init from arch/arm/cpu/armv8/start.S
and is that really desired?  Thanks!
Andre Przywara Dec. 6, 2016, 8:04 a.m. UTC | #3
On 05/12/16 21:56, Tom Rini wrote:
> On Mon, Dec 05, 2016 at 01:52:10AM +0000, Andre Przywara wrote:
> 
>> 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 on with a
>> 64-bit SPL.
>>
>> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> 
> This is going to override lowlevel_init from arch/arm/cpu/armv8/start.S
> and is that really desired?  Thanks!

Not sure if it is desired, but it's needed. The weak function in start.S
just initialises the GIC (if configured), that looks like a NOP for
sunxi to me (we do this already much better in ARM Trusted Firmware).
For 32-bit sunxi we call s_init() through lowlevel_init(), which is what
I copy here for armv8.
Now there is this comment which discourages doing so and Alex already
complained about it as well, so I might take a look at how we would skip
this step. I was a bit wary going there as this would mean to rework the
32-bit code as well, which affects a lot of boards, which I can barely
test here.

Cheers,
Andre.
Tom Rini Dec. 6, 2016, 12:18 p.m. UTC | #4
On Tue, Dec 06, 2016 at 08:04:24AM +0000, André Przywara wrote:
> On 05/12/16 21:56, Tom Rini wrote:
> > On Mon, Dec 05, 2016 at 01:52:10AM +0000, Andre Przywara wrote:
> > 
> >> 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 on with a
> >> 64-bit SPL.
> >>
> >> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> > 
> > This is going to override lowlevel_init from arch/arm/cpu/armv8/start.S
> > and is that really desired?  Thanks!
> 
> Not sure if it is desired, but it's needed. The weak function in start.S
> just initialises the GIC (if configured), that looks like a NOP for
> sunxi to me (we do this already much better in ARM Trusted Firmware).
> For 32-bit sunxi we call s_init() through lowlevel_init(), which is what
> I copy here for armv8.
> Now there is this comment which discourages doing so and Alex already
> complained about it as well, so I might take a look at how we would skip
> this step. I was a bit wary going there as this would mean to rework the
> 32-bit code as well, which affects a lot of boards, which I can barely
> test here.

The path flow here on 32bit, both with and without SPL is what makes
this area a good bit of a pain to make changes in.
Andre Przywara Dec. 17, 2016, 2:55 a.m. UTC | #5
On 05/12/16 06:26, Simon Glass wrote:
> Hi Andre,
> 
> On 4 December 2016 at 18:52, Andre Przywara <andre.przywara@arm.com> wrote:
>> 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 on with a
>> 64-bit SPL.
>>
>> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
>> ---
>>  arch/arm/cpu/armv8/Makefile        |  1 +
>>  arch/arm/cpu/armv8/lowlevel_init.S | 44 ++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 45 insertions(+)
>>  create mode 100644 arch/arm/cpu/armv8/lowlevel_init.S
> 
> Is this actually needed / used for anything?

All sunxi boards need to call s_init() in mach-sunxi/board.c.
But I gave this a closer look:
Indeed I believe we don't need lowlevel_init.S and the early call to
s_init(). We can just follow the recommendation in lowlevel_init.S and
move that code to board_init_f().
I have a small series that reworks this, but this would affect all sunxi
boards so should be considered separately.

Are you OK if we go ahead with this solution here for now, as it creates
the least churn?

Cheers,
Andre.
Simon Glass Dec. 17, 2016, 10:46 p.m. UTC | #6
Hi Andre,

On 16 December 2016 at 19:55, André Przywara <andre.przywara@arm.com> wrote:
>
> On 05/12/16 06:26, Simon Glass wrote:
> > Hi Andre,
> >
> > On 4 December 2016 at 18:52, Andre Przywara <andre.przywara@arm.com> wrote:
> >> 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 on with a
> >> 64-bit SPL.
> >>
> >> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> >> ---
> >>  arch/arm/cpu/armv8/Makefile        |  1 +
> >>  arch/arm/cpu/armv8/lowlevel_init.S | 44 ++++++++++++++++++++++++++++++++++++++
> >>  2 files changed, 45 insertions(+)
> >>  create mode 100644 arch/arm/cpu/armv8/lowlevel_init.S
> >
> > Is this actually needed / used for anything?
>
> All sunxi boards need to call s_init() in mach-sunxi/board.c.
> But I gave this a closer look:
> Indeed I believe we don't need lowlevel_init.S and the early call to
> s_init(). We can just follow the recommendation in lowlevel_init.S and
> move that code to board_init_f().
> I have a small series that reworks this, but this would affect all sunxi
> boards so should be considered separately.
>
> Are you OK if we go ahead with this solution here for now, as it creates
> the least churn?

Sounds good to me.

Regards,
Simon
diff mbox

Patch

diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
index dea1465..799a752 100644
--- a/arch/arm/cpu/armv8/Makefile
+++ b/arch/arm/cpu/armv8/Makefile
@@ -25,3 +25,4 @@  obj-$(CONFIG_FSL_LAYERSCAPE) += fsl-layerscape/
 obj-$(CONFIG_S32V234) += s32v234/
 obj-$(CONFIG_ARCH_ZYNQMP) += zynqmp/
 obj-$(CONFIG_TARGET_HIKEY) += hisilicon/
+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
index 0000000..189e35f
--- /dev/null
+++ b/arch/arm/cpu/armv8/lowlevel_init.S
@@ -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)