Re: [U-Boot] [PATCH v15 07/10] arm64: core support

-----Original Message----- From: FengHua [mailto:fenghua@phytium.com.cn] Sent: Sunday, December 01, 2013 7:48 PM To: Sharma Bhupesh-B45370 Cc: 'Bhupesh SHARMA'; 'u-boot@lists.denx.de'; 'trini@ti.com'; Wood Scott- B07421 Subject: Re: RE: Re: [U-Boot] [PATCH v15 07/10] arm64: core support
-----Original Message----- From: FengHua [mailto:fenghua@phytium.com.cn] Sent: Friday, November 29, 2013 7:05 PM To: Bhupesh SHARMA Cc: u-boot@lists.denx.de; Sharma Bhupesh-B45370; trini@ti.com; Wood Scott-B07421 Subject: Re: Re: [U-Boot] [PATCH v15 07/10] arm64: core support
hi Bhupesh, Thank you for reviewing of the patch.
+/*
- Generic timer implementation of timer_read_counter() */
+unsigned long timer_read_counter(void) {
- unsigned long cntpct;
- isb();
- asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct));
- return cntpct;
+} diff --git a/arch/arm/cpu/armv8/gic.S b/arch/arm/cpu/armv8/gic.S
The ARMv8 foundation model has support for GICv2 while GICv3 is actually compatible to ARMv8. So although you mention in the cover letter that this is currently GICv2 support, now while trying to add GICv3 support it will be difficult to envision GICv2 code in
'arch/arm/cpu/armv8/'
directory.
Infact GICv2 is compatible with ARMv7 and as secure and non-secure copies of GIC registers are equally applicable to ARMv7, would it make sense to keep the GICv2 code at a place where both ARMv7 and ARMv8 can use it?
Can we reuse something from [1] for GICv2:
[1] http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/cpu/armv7/nonse c_vi rt.S;h=24b4c18bd452fa155bcd5ed94c755aa05a33efe7;hb=HEAD#l88
Gicv2 only support maximum 8 cores, but still could be used with armv8 processors if the processor contains less than 8 cores. AMCC's armv8 processor use Gicv2. Yes, as you said it would be better to abstract a few common routines of Gicv2 and Gicv3 code and place them at a common place (such as arm/lib) so that both ARMv7 and ARMv8 could use it.
- /* Cache/BPB/TLB Invalidate */
- bl __asm_flush_dcache_all /* dCache
clean&invalidate */
- bl __asm_invalidate_icache_all /* iCache invalidate */
- bl __asm_invalidate_tlb_all /* invalidate TLBs */
- /* Processor specific initialization */
- bl lowlevel_init
Shouldn't this call be protected inside a '#ifndef CONFIG_SKIP_LOWLEVEL_INIT'?
We could do so when it is actually needed.
+WEAK(lowlevel_init)
Ok, so this means that a specific SoC lowlevel_init implementation can override this generic implementation. Because I sure other secure/non-secure settings need to be put into place for ARM IPs like SMMU-500.
+ENTRY(armv8_switch_to_el2)
Do we need a switch to Secure Monitor here? I am not able to relate how this with the present ARMv7 code (see [2]):
[2] http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/cpu/armv7/nonse c_vi rt.S;h=24b4c18bd452fa155bcd5ed94c755aa05a33efe7;hb=HEAD#l29
Armv8 processor reset at el3(if it support security extension). So we need to switch the processor to el2 or el1 before u-boot jump to linux kernel due to linux-aarch64 only run at el2 or el1.
Hi David,
As per ARMv8 Arch Reference Manual (ARM), Monitor mode is provided to support switching between Secure and Non-secure states. For switching from secure to non secure state the usual mechanism is an exception return. To return to Non-secure state (EL1/EL2), software executing in
Monitor mode(EL3) sets SCR.NS to 1 and then performs the exception return.
The implementation already in place for ARMv7 (see: http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/cpu/armv7/nonsec_vi rt.S;h=24b4c18bd452fa155bcd5ed94c755aa05a33efe7;hb=HEAD#l29), does this (sets up SMC handler and start.S calls smc #0 to switch to
non-secure state).
Something similar must be put into place for ARMv8 as well.
Sorry,I did not get your initially. In my opinion, u-boot runs at monitor mode(EL3), it coulde set SCR.NS to 1 directly. Why we need to setup SMC handler and call SMC #0 to switch to non-secure state? I don't understand why armv7 did so. Did you have any understanding about this?
Well, all ARM cores which support security extensions must support a SMC exception handler (ARMv7/v8). The monitor mode (which is entered by executing a SMC instruction) allows ARM core to switch from secure to non-secure state and vice-versa.
Note that for supporting ARM TrustZone, ARM specifies a SMC calling convention spec: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0028a/index.h...
Regards, Bhupesh

Hi David,
-----Original Message----- From: u-boot-bounces@lists.denx.de [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Bhupesh Sharma Sent: Tuesday, December 03, 2013 3:33 PM To: 'FengHua' Cc: 'trini@ti.com'; 'u-boot@lists.denx.de'; Wood Scott-B07421 Subject: Re: [U-Boot] [PATCH v15 07/10] arm64: core support
-----Original Message----- From: FengHua [mailto:fenghua@phytium.com.cn] Sent: Sunday, December 01, 2013 7:48 PM To: Sharma Bhupesh-B45370 Cc: 'Bhupesh SHARMA'; 'u-boot@lists.denx.de'; 'trini@ti.com'; Wood Scott- B07421 Subject: Re: RE: Re: [U-Boot] [PATCH v15 07/10] arm64: core support
-----Original Message----- From: FengHua [mailto:fenghua@phytium.com.cn] Sent: Friday, November 29, 2013 7:05 PM To: Bhupesh SHARMA Cc: u-boot@lists.denx.de; Sharma Bhupesh-B45370; trini@ti.com; Wood Scott-B07421 Subject: Re: Re: [U-Boot] [PATCH v15 07/10] arm64: core support
hi Bhupesh, Thank you for reviewing of the patch.
+/*
- Generic timer implementation of timer_read_counter() */
+unsigned long timer_read_counter(void) {
- unsigned long cntpct;
- isb();
- asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct));
- return cntpct;
+} diff --git a/arch/arm/cpu/armv8/gic.S b/arch/arm/cpu/armv8/gic.S
The ARMv8 foundation model has support for GICv2 while GICv3 is actually compatible to ARMv8. So although you mention in the cover letter that this is currently GICv2 support, now while trying to add GICv3 support it will be difficult to envision GICv2 code in
'arch/arm/cpu/armv8/'
directory.
Infact GICv2 is compatible with ARMv7 and as secure and non-secure copies of GIC registers are equally applicable to ARMv7, would it make sense to keep the GICv2 code at a place where both ARMv7 and ARMv8 can use it?
Can we reuse something from [1] for GICv2:
[1] http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/cpu/armv7/non se c_vi rt.S;h=24b4c18bd452fa155bcd5ed94c755aa05a33efe7;hb=HEAD#l88
Gicv2 only support maximum 8 cores, but still could be used with armv8 processors if the processor contains less than 8 cores. AMCC's armv8 processor use Gicv2. Yes, as you said it would be better to abstract a few common routines of Gicv2 and Gicv3 code and place them at a common place (such as arm/lib) so that both ARMv7 and ARMv8 could use it.
- /* Cache/BPB/TLB Invalidate */
- bl __asm_flush_dcache_all /* dCache
clean&invalidate */
- bl __asm_invalidate_icache_all /* iCache invalidate */
- bl __asm_invalidate_tlb_all /* invalidate TLBs */
- /* Processor specific initialization */
- bl lowlevel_init
Shouldn't this call be protected inside a '#ifndef CONFIG_SKIP_LOWLEVEL_INIT'?
We could do so when it is actually needed.
+WEAK(lowlevel_init)
Ok, so this means that a specific SoC lowlevel_init implementation can override this generic implementation. Because I sure other secure/non-secure settings need to be put into place for ARM IPs like SMMU-500.
+ENTRY(armv8_switch_to_el2)
Do we need a switch to Secure Monitor here? I am not able to relate how this with the present ARMv7 code (see [2]):
[2] http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/cpu/armv7/non se c_vi rt.S;h=24b4c18bd452fa155bcd5ed94c755aa05a33efe7;hb=HEAD#l29
Armv8 processor reset at el3(if it support security extension). So we need to switch the processor to el2 or el1 before u-boot jump to linux kernel due to linux-aarch64 only run at el2 or el1.
Hi David,
As per ARMv8 Arch Reference Manual (ARM), Monitor mode is provided to support switching between Secure and Non-secure states. For switching from secure to non secure state the usual mechanism is an exception return. To return to Non-secure state (EL1/EL2), software executing in
Monitor mode(EL3) sets SCR.NS to 1 and then performs the exception return.
The implementation already in place for ARMv7 (see: http://git.denx.de/?p=u-boot.git;a=blob;f=arch/arm/cpu/armv7/nonsec_ vi rt.S;h=24b4c18bd452fa155bcd5ed94c755aa05a33efe7;hb=HEAD#l29), does this (sets up SMC handler and start.S calls smc #0 to switch to
non-secure state).
Something similar must be put into place for ARMv8 as well.
Sorry,I did not get your initially. In my opinion, u-boot runs at monitor mode(EL3), it coulde set SCR.NS to 1 directly. Why we need to setup SMC handler and call SMC #0 to switch to non-secure state? I don't understand why armv7 did so. Did you have any understanding about this?
Well, all ARM cores which support security extensions must support a SMC exception handler (ARMv7/v8). The monitor mode (which is entered by executing a SMC instruction) allows ARM core to switch from secure to non-secure state and vice-versa.
Note that for supporting ARM TrustZone, ARM specifies a SMC calling convention spec: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0028a/inde x.html
In reference to my mail above, I see that the transition to EL2 (from EL3) which occurs very early in start.S needs to be changed on lines of the ARMv7 code, i.e. the EL2 transition should happen just before Linux is booted up by the u-boot.
The reason for the same is that a no of ARM IPs like GIC, SMMU and TZPC/TZASC need to be configured to allow non-secure accesses from Linux world (which runs in EL1 mode). Adding the assembly code for all such IPs in 'setup_el3' function in start.S, will bloat the start.S and also increase the chances of a bug in the assembly code.
Hence, I would like to propose a strategy to shift from EL3 to EL2 to some point in u-boot code after the C Run Time has been initialized (similar to present ARMv7 u-boot code).
If you are ok with the same, I can try to send out some RFC patches rebased against your latest v16 code-base.
Please let me know. Regards, Bhupesh

hi bhupesh,
Hi David,
In reference to my mail above, I see that the transition to EL2 (from EL3) which occurs very early in start.S needs to be changed on lines of the ARMv7 code, i.e. the EL2 transition should happen just before Linux is booted up by the u-boot.
The reason for the same is that a no of ARM IPs like GIC, SMMU and TZPC/TZASC need to be configured to allow non-secure accesses from Linux world (which runs in EL1 mode). Adding the assembly code for all such IPs in 'setup_el3' function in start.S, will bloat the start.S and also increase the chances of a bug in the assembly code.
Hence, I would like to propose a strategy to shift from EL3 to EL2 to some point in u-boot code after the C Run Time has been initialized (similar to present ARMv7 u-boot code).
If you are ok with the same, I can try to send out some RFC patches rebased against your latest v16 code-base.
Please let me know. Regards, Bhupesh
Actually, patch v16 did exception level switch in the way as you said. please review the code. Both master and slaves switch to el2(el1) just before jumping to linux kernel. BTW,if any good conception please feel free to patch it.
Best wishes, David

On Tue, 2014-01-14 at 09:52 +0800, FengHua wrote:
hi bhupesh,
Hi David,
In reference to my mail above, I see that the transition to EL2 (from EL3) which occurs very early in start.S needs to be changed on lines of the ARMv7 code, i.e. the EL2 transition should happen just before Linux is booted up by the u-boot.
The reason for the same is that a no of ARM IPs like GIC, SMMU and TZPC/TZASC need to be configured to allow non-secure accesses from Linux world (which runs in EL1 mode). Adding the assembly code for all such IPs in 'setup_el3' function in start.S, will bloat the start.S and also increase the chances of a bug in the assembly code.
Hence, I would like to propose a strategy to shift from EL3 to EL2 to some point in u-boot code after the C Run Time has been initialized (similar to present ARMv7 u-boot code).
If you are ok with the same, I can try to send out some RFC patches rebased against your latest v16 code-base.
Please let me know. Regards, Bhupesh
Actually, patch v16 did exception level switch in the way as you said. please review the code. Both master and slaves switch to el2(el1) just before jumping to linux kernel. BTW,if any good conception please feel free to patch it.
How would you handle running U-Boot under a secure firmware, or under a hypervisor? Why not take the Linux approach of running most code in EL1, with exception handlers pointing at code to handle special situations (such as returning to EL2 before OS entry)?
As for bloating start.S, could leaving EL3 be done in early C code rather than in early asm or late C code? Or, bundle U-Boot with a tiny "insecure firmware" that provides the minimum functionality needed with similar APIs that would be used with real secure firmware.
-Scott

On 14-01-22 04:29 PM, Scott Wood-2 [via U-Boot] wrote:
On Tue, 2014-01-14 at 09:52 +0800, FengHua wrote:
hi bhupesh,
Hi David,
In reference to my mail above, I see that the transition to EL2 (from EL3) which occurs very early in start.S needs to be changed on lines of the ARMv7 code, i.e. the EL2 transition should happen just before Linux is booted up by the u-boot.
The reason for the same is that a no of ARM IPs like GIC, SMMU and TZPC/TZASC need to be configured to allow non-secure accesses from Linux world (which runs in EL1 mode). Adding the assembly code for all such IPs in 'setup_el3' function in start.S, will bloat the start.S and also increase the chances of a bug in the assembly code.
Hence, I would like to propose a strategy to shift from EL3 to EL2 to some point in u-boot code after the C Run Time has been initialized (similar to present ARMv7 u-boot code).
If you are ok with the same, I can try to send out some RFC patches rebased against your latest v16 code-base.
Please let me know. Regards, Bhupesh
Actually, patch v16 did exception level switch in the way as you said. please review the code. Both master and slaves switch to el2(el1) just before jumping to linux kernel. BTW,if any good conception please feel free to patch it.
How would you handle running U-Boot under a secure firmware, or under a hypervisor? Why not take the Linux approach of running most code in EL1, with exception handlers pointing at code to handle special situations (such as returning to EL2 before OS entry)?
As for bloating start.S, could leaving EL3 be done in early C code rather than in early asm or late C code? Or, bundle U-Boot with a tiny "insecure firmware" that provides the minimum functionality needed with similar APIs that would be used with real secure firmware.
Hi Scott, Why is any EL3 code in u-boot at all? That's not the ARM ATF approach I believe but I'm not an expert in this. Please see http://lists.denx.de/pipermail/u-boot/2014-January/171581.html and (https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/user-g...
See section "Normal World Software Execution")
Thanks. Darwin
-Scott
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
If you reply to this email, your message will be added to the discussion below: http://u-boot.10912.n7.nabble.com/PATCH-v15-00-10-arm64-patch-tp167751p17210...
To unsubscribe from [PATCH v15 00/10] arm64 patch, visit http://u-boot.10912.n7.nabble.com/template/NamlServlet.jtp?macro=unsubscribe...
-- View this message in context: http://u-boot.10912.n7.nabble.com/PATCH-v15-00-10-arm64-patch-tp167751p17210... Sent from the U-Boot mailing list archive at Nabble.com.

Hi Scott,
-----Original Messages----- From: "Scott Wood" scottwood@freescale.com Sent Time: 2014-01-23 08:28:06 (Thursday) To: FengHua fenghua@phytium.com.cn Cc: "bhupesh.sharma@freescale.com" bhupesh.sharma@freescale.com, "'trini@ti.com'" trini@ti.com, "'u-boot@lists.denx.de'" u-boot@lists.denx.de, rod.dorris@freescale.com Subject: Re: [U-Boot] [PATCH v15 07/10] arm64: core support
On Tue, 2014-01-14 at 09:52 +0800, FengHua wrote:
hi bhupesh,
Hi David,
In reference to my mail above, I see that the transition to EL2 (from EL3) which occurs very early in start.S needs to be changed on lines of the ARMv7 code, i.e. the EL2 transition should happen just before Linux is booted up by the u-boot.
The reason for the same is that a no of ARM IPs like GIC, SMMU and TZPC/TZASC need to be configured to allow non-secure accesses from Linux world (which runs in EL1 mode). Adding the assembly code for all such IPs in 'setup_el3' function in start.S, will bloat the start.S and also increase the chances of a bug in the assembly code.
Hence, I would like to propose a strategy to shift from EL3 to EL2 to some point in u-boot code after the C Run Time has been initialized (similar to present ARMv7 u-boot code).
If you are ok with the same, I can try to send out some RFC patches rebased against your latest v16 code-base.
Please let me know. Regards, Bhupesh
Actually, patch v16 did exception level switch in the way as you said. please review the code. Both master and slaves switch to el2(el1) just before jumping to linux kernel. BTW,if any good conception please feel free to patch it.
How would you handle running U-Boot under a secure firmware, or under a hypervisor? Why not take the Linux approach of running most code in EL1, with exception handlers pointing at code to handle special situations (such as returning to EL2 before OS entry)?
As for bloating start.S, could leaving EL3 be done in early C code rather than in early asm or late C code? Or, bundle U-Boot with a tiny "insecure firmware" that provides the minimum functionality needed with similar APIs that would be used with real secure firmware.
-Scott
The u-boot for aarch64 are designed to support running at EL3/EL2/EL1. The macro 'switch_el' is used to separate different exception level code. If no secure firmware exist it runs at highest exception level processor implemented that could be EL3 or EL2 or EL1. Besides, theoretically it could be loaded by a secure firmware or a hypervisor and runs at EL2 or EL1 (This is not tested).
Best Regards, David
participants (5)
-
Bhupesh Sharma
-
bhupesh.sharma@freescale.com
-
drambo
-
FengHua
-
Scott Wood