diff mbox series

[v1,04/20] arm: socfpga: agilex5: Add low level initialization

Message ID 20240920070242.20884-5-tien.fong.chee@intel.com
State New
Delegated to: TIEN FONG CHEE
Headers show
Series SoCFPGA: Add Boot Support for Agilex 5 in U-Boot | expand

Commit Message

Chee, Tien Fong Sept. 20, 2024, 7:02 a.m. UTC
From: Tien Fong Chee <tien.fong.chee@intel.com>

Create new low level initialization for Agile5 due to the new ARM core
composition and warm reset behavior.

Signed-off-by: Tien Fong Chee <tien.fong.chee@intel.com>
---
 arch/arm/mach-socfpga/Makefile                |  1 +
 .../include/mach/reset_manager_soc64.h        | 12 +++-
 arch/arm/mach-socfpga/lowlevel_init_agilex5.S | 57 +++++++++++++++++++
 3 files changed, 68 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/mach-socfpga/lowlevel_init_agilex5.S

Comments

Marek Vasut Sept. 21, 2024, 1:49 p.m. UTC | #1
On 9/20/24 9:02 AM, tien.fong.chee@intel.com wrote:
> From: Tien Fong Chee <tien.fong.chee@intel.com>
> 
> Create new low level initialization for Agile5 due to the new ARM core
> composition and warm reset behavior.
> 
> Signed-off-by: Tien Fong Chee <tien.fong.chee@intel.com>
> ---
>   arch/arm/mach-socfpga/Makefile                |  1 +
>   .../include/mach/reset_manager_soc64.h        | 12 +++-
>   arch/arm/mach-socfpga/lowlevel_init_agilex5.S | 57 +++++++++++++++++++
>   3 files changed, 68 insertions(+), 2 deletions(-)
>   create mode 100644 arch/arm/mach-socfpga/lowlevel_init_agilex5.S
> 
> diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
> index 67c6a8dfec5..53c91d1d2a5 100644
> --- a/arch/arm/mach-socfpga/Makefile
> +++ b/arch/arm/mach-socfpga/Makefile
> @@ -58,6 +58,7 @@ endif
>   
>   ifdef CONFIG_TARGET_SOCFPGA_AGILEX5
>   obj-y	+= clock_manager_agilex5.o
> +obj-y	+= lowlevel_init_agilex5.o
>   obj-y	+= mailbox_s10.o
>   obj-y	+= misc_soc64.o
>   obj-y	+= mmu-arm64_s10.o
Can this be wired into existing early hook function, like s_init or so ?
Chee, Tien Fong Sept. 24, 2024, 3:14 a.m. UTC | #2
Hi,

> -----Original Message-----
> From: Marek Vasut <marex@denx.de>
> Sent: Saturday, September 21, 2024 9:49 PM
> To: Chee, Tien Fong <tien.fong.chee@intel.com>; u-boot@lists.denx.de
> Cc: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>; Meng, Tingting
> <tingting.meng@intel.com>; Yuslaimi, Alif Zakuan
> <alif.zakuan.yuslaimi@intel.com>; Hea, Kok Kiang
> <kok.kiang.hea@intel.com>
> Subject: Re: [PATCH v1 04/20] arm: socfpga: agilex5: Add low level
> initialization
> 
> On 9/20/24 9:02 AM, tien.fong.chee@intel.com wrote:
> > From: Tien Fong Chee <tien.fong.chee@intel.com>
> >
> > Create new low level initialization for Agile5 due to the new ARM core
> > composition and warm reset behavior.
> >
> > Signed-off-by: Tien Fong Chee <tien.fong.chee@intel.com>
> > ---
> >   arch/arm/mach-socfpga/Makefile                |  1 +
> >   .../include/mach/reset_manager_soc64.h        | 12 +++-
> >   arch/arm/mach-socfpga/lowlevel_init_agilex5.S | 57
> +++++++++++++++++++
> >   3 files changed, 68 insertions(+), 2 deletions(-)
> >   create mode 100644 arch/arm/mach-socfpga/lowlevel_init_agilex5.S
> >
> > diff --git a/arch/arm/mach-socfpga/Makefile
> > b/arch/arm/mach-socfpga/Makefile index 67c6a8dfec5..53c91d1d2a5
> 100644
> > --- a/arch/arm/mach-socfpga/Makefile
> > +++ b/arch/arm/mach-socfpga/Makefile
> > @@ -58,6 +58,7 @@ endif
> >
> >   ifdef CONFIG_TARGET_SOCFPGA_AGILEX5
> >   obj-y	+= clock_manager_agilex5.o
> > +obj-y	+= lowlevel_init_agilex5.o
> >   obj-y	+= mailbox_s10.o
> >   obj-y	+= misc_soc64.o
> >   obj-y	+= mmu-arm64_s10.o
> Can this be wired into existing early hook function, like s_init or so ?

I cannot find the caller for s_init, wonder where is the s_init is called?
What's concern with lowlevel_init()? It's also wired into existing early hook function which's located inside start.S

Regards,
Tien Fong.
Marek Vasut Sept. 24, 2024, 6:32 p.m. UTC | #3
On 9/24/24 5:14 AM, Chee, Tien Fong wrote:

Hi,

>>> diff --git a/arch/arm/mach-socfpga/Makefile
>>> b/arch/arm/mach-socfpga/Makefile index 67c6a8dfec5..53c91d1d2a5
>> 100644
>>> --- a/arch/arm/mach-socfpga/Makefile
>>> +++ b/arch/arm/mach-socfpga/Makefile
>>> @@ -58,6 +58,7 @@ endif
>>>
>>>    ifdef CONFIG_TARGET_SOCFPGA_AGILEX5
>>>    obj-y	+= clock_manager_agilex5.o
>>> +obj-y	+= lowlevel_init_agilex5.o
>>>    obj-y	+= mailbox_s10.o
>>>    obj-y	+= misc_soc64.o
>>>    obj-y	+= mmu-arm64_s10.o
>> Can this be wired into existing early hook function, like s_init or so ?
> 
> I cannot find the caller for s_init, wonder where is the s_init is called?

arch/arm/cpu/armv7/lowlevel_init.S:.pushsection .text.s_init, "ax"
arch/arm/cpu/armv7/lowlevel_init.S:WEAK(s_init)
arch/arm/cpu/armv7/lowlevel_init.S:ENDPROC(s_init)
arch/arm/cpu/armv7/lowlevel_init.S:     bl      s_init

Maybe such a default lowlevel_init for armv8 could also have an s_init ?

> What's concern with lowlevel_init()? It's also wired into existing early hook function which's located inside start.S
I would like to avoid duplicating lowlevel_init functionality as much as 
possible , common lowlevel_init would be very welcome .
Chee, Tien Fong Sept. 25, 2024, 5:40 a.m. UTC | #4
Hi,

> -----Original Message-----
> From: Marek Vasut <marex@denx.de>
> Sent: Wednesday, September 25, 2024 2:32 AM
> To: Chee, Tien Fong <tien.fong.chee@intel.com>; u-boot@lists.denx.de
> Cc: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>; Meng, Tingting
> <tingting.meng@intel.com>; Yuslaimi, Alif Zakuan
> <alif.zakuan.yuslaimi@intel.com>; Hea, Kok Kiang
> <kok.kiang.hea@intel.com>
> Subject: Re: [PATCH v1 04/20] arm: socfpga: agilex5: Add low level
> initialization
> 
> On 9/24/24 5:14 AM, Chee, Tien Fong wrote:
> 
> Hi,
> 
> >>> diff --git a/arch/arm/mach-socfpga/Makefile
> >>> b/arch/arm/mach-socfpga/Makefile index 67c6a8dfec5..53c91d1d2a5
> >> 100644
> >>> --- a/arch/arm/mach-socfpga/Makefile
> >>> +++ b/arch/arm/mach-socfpga/Makefile
> >>> @@ -58,6 +58,7 @@ endif
> >>>
> >>>    ifdef CONFIG_TARGET_SOCFPGA_AGILEX5
> >>>    obj-y	+= clock_manager_agilex5.o
> >>> +obj-y	+= lowlevel_init_agilex5.o
> >>>    obj-y	+= mailbox_s10.o
> >>>    obj-y	+= misc_soc64.o
> >>>    obj-y	+= mmu-arm64_s10.o
> >> Can this be wired into existing early hook function, like s_init or so ?
> >
> > I cannot find the caller for s_init, wonder where is the s_init is called?
> 
> arch/arm/cpu/armv7/lowlevel_init.S:.pushsection .text.s_init, "ax"
> arch/arm/cpu/armv7/lowlevel_init.S:WEAK(s_init)
> arch/arm/cpu/armv7/lowlevel_init.S:ENDPROC(s_init)
> arch/arm/cpu/armv7/lowlevel_init.S:     bl      s_init
> 
> Maybe such a default lowlevel_init for armv8 could also have an s_init ?
> 
> > What's concern with lowlevel_init()? It's also wired into existing
> > early hook function which's located inside start.S
> I would like to avoid duplicating lowlevel_init functionality as much as
> possible , common lowlevel_init would be very welcome .

Sure, I can add the s_init to common lowlevel_init and moving the codes to s_init.

Thanks.

Regards,
Tien Fong
Marek Vasut Sept. 25, 2024, 12:50 p.m. UTC | #5
On 9/25/24 7:40 AM, Chee, Tien Fong wrote:

Hi,

>> arch/arm/cpu/armv7/lowlevel_init.S:.pushsection .text.s_init, "ax"
>> arch/arm/cpu/armv7/lowlevel_init.S:WEAK(s_init)
>> arch/arm/cpu/armv7/lowlevel_init.S:ENDPROC(s_init)
>> arch/arm/cpu/armv7/lowlevel_init.S:     bl      s_init
>>
>> Maybe such a default lowlevel_init for armv8 could also have an s_init ?
>>
>>> What's concern with lowlevel_init()? It's also wired into existing
>>> early hook function which's located inside start.S
>> I would like to avoid duplicating lowlevel_init functionality as much as
>> possible , common lowlevel_init would be very welcome .
> 
> Sure, I can add the s_init to common lowlevel_init and moving the codes to s_init.
Thanks. Then the question is, how much of this stuff can be removed 
because it is part of generic lowlevel_init, I hope a lot.
Chee, Tien Fong Sept. 26, 2024, 6:02 a.m. UTC | #6
Hi,

> >> arch/arm/cpu/armv7/lowlevel_init.S:.pushsection .text.s_init, "ax"
> >> arch/arm/cpu/armv7/lowlevel_init.S:WEAK(s_init)
> >> arch/arm/cpu/armv7/lowlevel_init.S:ENDPROC(s_init)
> >> arch/arm/cpu/armv7/lowlevel_init.S:     bl      s_init
> >>
> >> Maybe such a default lowlevel_init for armv8 could also have an s_init ?
> >>
> >>> What's concern with lowlevel_init()? It's also wired into existing
> >>> early hook function which's located inside start.S
> >> I would like to avoid duplicating lowlevel_init functionality as much
> >> as possible , common lowlevel_init would be very welcome .
> >
> > Sure, I can add the s_init to common lowlevel_init and moving the codes to
> s_init.
> Thanks. Then the question is, how much of this stuff can be removed
> because it is part of generic lowlevel_init, I hope a lot.

I'm not sure I completely understand your question, but I can share what we're going to do.
Declaring a weak s_init function at lowlevel_init.S

.pushsection .text.s_init, "ax"
WEAK(s_init)
	bx	lr
ENDPROC(s_init)
.popsection

Calling s_init before lowlevel_init returned to parent call
              [...]
	bl s_init
	move lr, x29
              ret

We will move the codes to s_init which is declared in our platform driver, arch/arm/mach-socfpga .

The codes is needed to backup the data section as earlier as possible to support
warm reset / watchdog due to warm reset use case, where reloading SPL would be skipped after reset.

Thanks.

Regards,
Tien Fong
Marek Vasut Sept. 26, 2024, 10:37 p.m. UTC | #7
On 9/26/24 8:02 AM, Chee, Tien Fong wrote:
> Hi,

Hi,

>>>> arch/arm/cpu/armv7/lowlevel_init.S:.pushsection .text.s_init, "ax"
>>>> arch/arm/cpu/armv7/lowlevel_init.S:WEAK(s_init)
>>>> arch/arm/cpu/armv7/lowlevel_init.S:ENDPROC(s_init)
>>>> arch/arm/cpu/armv7/lowlevel_init.S:     bl      s_init
>>>>
>>>> Maybe such a default lowlevel_init for armv8 could also have an s_init ?
>>>>
>>>>> What's concern with lowlevel_init()? It's also wired into existing
>>>>> early hook function which's located inside start.S
>>>> I would like to avoid duplicating lowlevel_init functionality as much
>>>> as possible , common lowlevel_init would be very welcome .
>>>
>>> Sure, I can add the s_init to common lowlevel_init and moving the codes to
>> s_init.
>> Thanks. Then the question is, how much of this stuff can be removed
>> because it is part of generic lowlevel_init, I hope a lot.
> 
> I'm not sure I completely understand your question, but I can share what we're going to do.

I am wondering if some of the code here can be deduplicated by using the 
generic lowlevel_init.S , i.e. if some of the code in lowlevel_init.S is 
duplicate of the code in this custom lowlevel_init.S implementation.

> Declaring a weak s_init function at lowlevel_init.S
> 
> .pushsection .text.s_init, "ax"
> WEAK(s_init)
> 	bx	lr
> ENDPROC(s_init)
> .popsection
> 
> Calling s_init before lowlevel_init returned to parent call
>                [...]
> 	bl s_init
> 	move lr, x29
>                ret
> 
> We will move the codes to s_init which is declared in our platform driver, arch/arm/mach-socfpga .
> 
> The codes is needed to backup the data section as earlier as possible to support
> warm reset / watchdog due to warm reset use case, where reloading SPL would be skipped after reset.
If you need to run code very early and back up critical data, look at 
save_boot_params .
Chee, Tien Fong Sept. 27, 2024, 4:53 a.m. UTC | #8
Hi,
 
> >>>> arch/arm/cpu/armv7/lowlevel_init.S:.pushsection .text.s_init, "ax"
> >>>> arch/arm/cpu/armv7/lowlevel_init.S:WEAK(s_init)
> >>>> arch/arm/cpu/armv7/lowlevel_init.S:ENDPROC(s_init)
> >>>> arch/arm/cpu/armv7/lowlevel_init.S:     bl      s_init
> >>>>
> >>>> Maybe such a default lowlevel_init for armv8 could also have an s_init ?
> >>>>
> >>>>> What's concern with lowlevel_init()? It's also wired into existing
> >>>>> early hook function which's located inside start.S
> >>>> I would like to avoid duplicating lowlevel_init functionality as
> >>>> much as possible , common lowlevel_init would be very welcome .
> >>>
> >>> Sure, I can add the s_init to common lowlevel_init and moving the
> >>> codes to
> >> s_init.
> >> Thanks. Then the question is, how much of this stuff can be removed
> >> because it is part of generic lowlevel_init, I hope a lot.
> >
> > I'm not sure I completely understand your question, but I can share what
> we're going to do.
> 
> I am wondering if some of the code here can be deduplicated by using the
> generic lowlevel_init.S , i.e. if some of the code in lowlevel_init.S is duplicate
> of the code in this custom lowlevel_init.S implementation.

No duplicate codes in both common lowlevel_init.S and custom lowlevel_init.S.

> 
> > Declaring a weak s_init function at lowlevel_init.S
> >
> > .pushsection .text.s_init, "ax"
> > WEAK(s_init)
> > 	bx	lr
> > ENDPROC(s_init)
> > .popsection
> >
> > Calling s_init before lowlevel_init returned to parent call
> >                [...]
> > 	bl s_init
> > 	move lr, x29
> >                ret
> >
> > We will move the codes to s_init which is declared in our platform driver,
> arch/arm/mach-socfpga .
> >
> > The codes is needed to backup the data section as earlier as possible
> > to support warm reset / watchdog due to warm reset use case, where
> reloading SPL would be skipped after reset.
> If you need to run code very early and back up critical data, look at
> save_boot_params .

Thanks for suggesting this, we will try this out.

Regards,
Tien Fong
diff mbox series

Patch

diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
index 67c6a8dfec5..53c91d1d2a5 100644
--- a/arch/arm/mach-socfpga/Makefile
+++ b/arch/arm/mach-socfpga/Makefile
@@ -58,6 +58,7 @@  endif
 
 ifdef CONFIG_TARGET_SOCFPGA_AGILEX5
 obj-y	+= clock_manager_agilex5.o
+obj-y	+= lowlevel_init_agilex5.o
 obj-y	+= mailbox_s10.o
 obj-y	+= misc_soc64.o
 obj-y	+= mmu-arm64_s10.o
diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h b/arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h
index c8bb727aa2b..d373ec0dc70 100644
--- a/arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h
+++ b/arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h
@@ -1,15 +1,17 @@ 
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- *  Copyright (C) 2016-2019 Intel Corporation <www.intel.com>
+ *  Copyright (C) 2016-2024 Intel Corporation <www.intel.com>
  */
 
 #ifndef _RESET_MANAGER_SOC64_H_
 #define _RESET_MANAGER_SOC64_H_
 
+#ifndef __ASSEMBLY__
 void reset_deassert_peripherals_handoff(void);
 int cpu_has_been_warmreset(void);
 void print_reset_info(void);
 void socfpga_bridges_reset(int enable);
+#endif
 
 #define RSTMGR_SOC64_STATUS	0x00
 #define RSTMGR_SOC64_MPUMODRST	0x20
@@ -23,14 +25,20 @@  void socfpga_bridges_reset(int enable);
 #define RSTMGR_BRGMODRST_FPGA2SOC_MASK	0x00000004
 
 /* SDM, Watchdogs and MPU warm reset mask */
-#define RSTMGR_STAT_SDMWARMRST		BIT(1)
+#define RSTMGR_STAT_SDMWARMRST		0x2
 #define RSTMGR_STAT_MPU0RST_BITPOS	8
 #define RSTMGR_STAT_L4WD0RST_BITPOS	16
+#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5)
+#define RSTMGR_STAT_L4WD0RST_BIT	0x1F0000
+#define RSTMGR_L4WD_MPU_WARMRESET_MASK	(RSTMGR_STAT_SDMWARMRST | \
+		RSTMGR_STAT_L4WD0RST_BIT)
+#else
 #define RSTMGR_L4WD_MPU_WARMRESET_MASK	(RSTMGR_STAT_SDMWARMRST | \
 		GENMASK(RSTMGR_STAT_MPU0RST_BITPOS + 3, \
 			RSTMGR_STAT_MPU0RST_BITPOS) | \
 		GENMASK(RSTMGR_STAT_L4WD0RST_BITPOS + 3, \
 			RSTMGR_STAT_L4WD0RST_BITPOS))
+#endif
 
 /*
  * SocFPGA Stratix10 reset IDs, bank mapping is as follows:
diff --git a/arch/arm/mach-socfpga/lowlevel_init_agilex5.S b/arch/arm/mach-socfpga/lowlevel_init_agilex5.S
new file mode 100644
index 00000000000..27430577719
--- /dev/null
+++ b/arch/arm/mach-socfpga/lowlevel_init_agilex5.S
@@ -0,0 +1,57 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2024 Intel Corporation. All rights reserved
+ */
+
+#include <asm-offsets.h>
+#include <config.h>
+#include <asm/arch/reset_manager_soc64.h>
+#include <asm/macro.h>
+#include <linux/linkage.h>
+
+ENTRY(lowlevel_init)
+	mov	x29, lr			/* Save LR */
+
+	/* Enable Async */
+	msr daifclr, #4
+
+#ifdef CONFIG_SPL_BUILD
+	branch_if_slave x0, 3f
+
+	/* Check rstmgr.stat for warm reset status */
+	ldr	w1, =SOCFPGA_RSTMGR_ADDRESS
+	ldr	w0, [x1]
+	/* Check whether any L4 watchdogs or SDM had triggered warm reset */
+	ldr	x2, =RSTMGR_L4WD_MPU_WARMRESET_MASK
+	ands	x0, x0, x2
+	/*
+	 * If current Reset Manager's status is warm reset just reload the
+	 * .data section by copying the data from data preserve section.
+	 * Otherwise, copy the .data section to the data preserve section to
+	 * keep an original copy of .data section. This ensure SPL is
+	 * reentrant after warm reset.
+	 */
+	b.ne	reload_data_section
+	/* Copy from .data to preserved .data to backup the SPL state */
+	ldr	x0, =__data_start
+	ldr	x1, =__preserve_data_start
+	ldr	x2, =__preserve_data_end
+	b	copy_loop
+reload_data_section:
+	/* Copy from preserved .data to .data to restore the SPL state */
+	ldr	x0, =__preserve_data_start
+	ldr	x1, =__data_start
+	ldr	x2, =__data_end
+copy_loop:
+	ldr	w3, [x0]
+	add	x0, x0, #4
+	str	w3, [x1]
+	add	x1, x1, #4
+	cmp	x1, x2
+	b.ne	copy_loop
+3:
+#endif
+
+	mov	lr, x29			/* Restore LR */
+	ret
+ENDPROC(lowlevel_init)