Skip to contentSkip to conversation

armv8: Support loading 32-bit OS in AArch32 execution state

PATCH Superseded Alison Wang 4 participants 10 messages May 26, 2016 – Jun 3, 2016

Subsystems (2)

v3 of 8 Superseded Latest is v8 →

lore
Share & tools
lore
#0 lore raw

v3 cover armv8: Support loading 32-bit OS in AArch32 execution state

This series is to support loading a 32-bit OS, the execution state will change from AArch64 to AArch32 when jumping to kernel. The architecture information will be got through checking FIT image, then U-Boot will load 32-bit OS or 64-bit OS automatically.

Spin-table method is used for secondary cores to load 32-bit OS. The architecture information will be got through checking FIT image and saved in the os_arch element of spin-table, then the secondary cores will check os_arch and jump to 32-bit OS or 64-bit OS automatically.

---------------------------------------------------------------
Changes in v3:
- Comments the functions and the arguments.
- Rename the real parameters.
- Use the macros instead of the magic values.
- Remove the redundant codes.
- Clean up all of the mess in boot_jump_linux().
- Add CONFIG_ARM64_SUPPORT_AARCH32 to detect for some ARM64 system doesn't support AArch32 state.
- Adjust the arguments for armv8_switch_to_el2_m and armv8_switch_to_el1_m.

Changes in v2:
- armv8_switch_to_el2_aarch32() is removed. armv8_switch_to_el2_m is used to switch to AArch64 EL2 or AArch32 Hyp.
- armv8_switch_to_el1_aarch32() is removed. armv8_switch_to_el1_m is used to switch to AArch64 EL1 or AArch32 SVC.
- Support to call armv8_switch_to_el2_m and armv8_switch_to_el1_m.

----------------------------------------------------------------
Alison Wang (2):
armv8: Support loading 32-bit OS in AArch32 execution state
armv8: fsl-layerscape: SMP support for loading 32-bit OS

 arch/arm/Kconfig                              |   6 ++
 arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S  |  35 ++++++++--
 arch/arm/cpu/armv8/fsl-layerscape/mp.c        |  10 +++
 arch/arm/cpu/armv8/transition.S               |   8 +--
 arch/arm/include/asm/arch-fsl-layerscape/mp.h |   6 ++
 arch/arm/include/asm/macro.h                  | 174 ++++++++++++++++++++++++++++++++++++-----------
 arch/arm/include/asm/system.h                 | 118 +++++++++++++++++++++++++++++++-
 arch/arm/lib/bootm.c                          |  24 +++++--
 common/image-fit.c                            |  14 +++-
 9 files changed, 339 insertions(+), 56 deletions(-)
#1 lore raw

PATCH v3 1/2 armv8: Support loading 32-bit OS in AArch32 execution state

To support loading a 32-bit OS, the execution state will change from AArch64 to AArch32 when jumping to kernel.

The architecture information will be got through checking FIT image, then U-Boot will load 32-bit OS or 64-bit OS automatically.

---
Changes in v3:
- Comments the functions and the arguments.
- Rename the real parameters.
- Use the macros instead of the magic values.
- Remove the redundant codes.
- Clean up all of the mess in boot_jump_linux().
- Add CONFIG_ARM64_SUPPORT_AARCH32 to detect for some ARM64 system doesn't support AArch32 state.

Changes in v2:
- armv8_switch_to_el2_aarch32() is removed. armv8_switch_to_el2_m is used to switch to AArch64 EL2 or AArch32 Hyp.
- armv8_switch_to_el1_aarch32() is removed. armv8_switch_to_el1_m is used to switch to AArch64 EL1 or AArch32 SVC.

 arch/arm/Kconfig                |   6 ++
 arch/arm/cpu/armv8/transition.S |   8 +-
 arch/arm/include/asm/macro.h    | 174 ++++++++++++++++++++++++++++++----------
 arch/arm/include/asm/system.h   | 118 ++++++++++++++++++++++++++-
 arch/arm/lib/bootm.c            |  19 ++++-
 common/image-fit.c              |  14 +++-
 6 files changed, 287 insertions(+), 52 deletions(-)
arch/arm/Kconfig +6 -0
index 729b181..794cb4f 100644
@@ -77,6 +77,12 @@ config SYS_L2CACHE_OFF
 	  If SoC does not support L2CACHE or one do not want to enable
 	  L2CACHE, choose this option.
 
+config ARM64_SUPPORT_AARCH32
+	bool "ARM64 system support AArch32 execution state"
+	default y if ARM64 && !CONFIG_THUNDERX
+	help
+	  This ARM64 system supports AArch32 execution state.
+
 choice
 	prompt "Target select"
 	default TARGET_HIKEY
arch/arm/cpu/armv8/transition.S +4 -4
index 253a39b..417e8b4 100644
@@ -11,13 +11,13 @@
 #include <asm/macro.h>
 
 ENTRY(armv8_switch_to_el2)
-	switch_el x0, 1f, 0f, 0f
+	switch_el x4, 1f, 0f, 0f
 0:	ret
-1:	armv8_switch_to_el2_m x0
+1:	armv8_switch_to_el2_m x0, x1, x2, x3, x4
 ENDPROC(armv8_switch_to_el2)
 
 ENTRY(armv8_switch_to_el1)
-	switch_el x0, 0f, 1f, 0f
+	switch_el x4, 0f, 1f, 0f
 0:	ret
-1:	armv8_switch_to_el1_m x0, x1
+1:	armv8_switch_to_el1_m x0, x1, x2, x3, x4
 ENDPROC(armv8_switch_to_el1)
arch/arm/include/asm/macro.h +133 -41

216 lines not on this page · raw message

arch/arm/include/asm/system.h +116 -2

130 lines not on this page · raw message

arch/arm/lib/bootm.c +15 -4
index 0838d89..1bbf85c 100644
@@ -189,13 +189,19 @@ static void setup_end_tag(bd_t *bd)
 __weak void setup_board_tags(struct tag **in_params) {}
 
 #ifdef CONFIG_ARM64
-static void do_nonsec_virt_switch(void)
+static void do_nonsec_virt_switch(bootm_headers_t *images, int flag)
 {
 	smp_kick_all_cpus();
 	dcache_disable();	/* flush cache before swtiching to EL2 */
-	armv8_switch_to_el2();
+
 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
-	armv8_switch_to_el1();
+	armv8_switch_to_el2((u64)images->ep, (u64)gd->bd->bi_arch_number,
+			    (u64)images->ft_addr, ES_TO_AARCH64);
+	armv8_switch_to_el1((u64)images->ep, (u64)gd->bd->bi_arch_number,
+			    (u64)images->ft_addr, flag);
+#else
+	armv8_switch_to_el2((u64)images->ep, (u64)gd->bd->bi_arch_number,
+			    (u64)images->ft_addr, flag);
 #endif
 }
 #endif
@@ -275,6 +281,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
 	void (*kernel_entry)(void *fdt_addr, void *res0, void *res1,
 			void *res2);
 	int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
+	int es_flag = ES_TO_AARCH64;
 
 	kernel_entry = (void (*)(void *fdt_addr, void *res0, void *res1,
 				void *res2))images->ep;
@@ -286,7 +293,11 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
 	announce_and_cleanup(fake);
 
 	if (!fake) {
-		do_nonsec_virt_switch();
+		if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
+		    (images->os.arch == IH_ARCH_ARM))
+			es_flag = ES_TO_AARCH32;
+
+		do_nonsec_virt_switch(images, es_flag);
 		kernel_entry(images->ft_addr, NULL, NULL, NULL);
 	}
 #else
common/image-fit.c +13 -1
index 9873957..982021b 100644
@@ -26,6 +26,7 @@ DECLARE_GLOBAL_DATA_PTR;
 #include <u-boot/md5.h>
 #include <u-boot/sha1.h>
 #include <u-boot/sha256.h>
+#include <generated/autoconf.h>
 
 /*****************************************************************************/
 /* New uImage format routines */
@@ -1164,7 +1165,9 @@ int fit_image_check_arch(const void *fit, int noffset, uint8_t arch)
 	if (fit_image_get_arch(fit, noffset, &image_arch))
 		return 0;
 	return (arch == image_arch) ||
-		(arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64);
+		(arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64) ||
+		(arch == IH_ARCH_ARM64 && image_arch == IH_ARCH_ARM &&
+		 CONFIG_ARM64_SUPPORT_AARCH32);
 }
 
 /**
@@ -1593,6 +1596,9 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
 	int type_ok, os_ok;
 	ulong load, data, len;
 	uint8_t os;
+#ifndef USE_HOSTCC
+	uint8_t os_arch;
+#endif
 	const char *prop_name;
 	int ret;
 
@@ -1676,6 +1682,12 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
 		return -ENOEXEC;
 	}
 #endif
+
+#ifndef USE_HOSTCC
+	fit_image_get_arch(fit, noffset, &os_arch);
+	images->os.arch = os_arch;
+#endif
+
 	if (image_type == IH_TYPE_FLATDT &&
 	    !fit_image_check_comp(fit, noffset, IH_COMP_NONE)) {
 		puts("FDT image is compressed");
Signature · 1 line
2.1.0.27.g96db324
#2 lore raw

PATCH v3 1/2 armv8: Support loading 32-bit OS in AArch32 execution state

Quoted 54 lines · Alison Wang

To support loading a 32-bit OS, the execution state will change from AArch64 to AArch32 when jumping to kernel.

The architecture information will be got through checking FIT image, then U-Boot will load 32-bit OS or 64-bit OS automatically.

---
Changes in v3:
- Comments the functions and the arguments.
- Rename the real parameters.
- Use the macros instead of the magic values.
- Remove the redundant codes.
- Clean up all of the mess in boot_jump_linux().
- Add CONFIG_ARM64_SUPPORT_AARCH32 to detect for some ARM64 system doesn't support AArch32 state.

Changes in v2:
- armv8_switch_to_el2_aarch32() is removed. armv8_switch_to_el2_m is used to switch to AArch64 EL2 or AArch32 Hyp.
- armv8_switch_to_el1_aarch32() is removed. armv8_switch_to_el1_m is used to switch to AArch64 EL1 or AArch32 SVC.

 arch/arm/Kconfig                |   6 ++
 arch/arm/cpu/armv8/transition.S |   8 +-
 arch/arm/include/asm/macro.h    | 174 ++++++++++++++++++++++++++++++----------
 arch/arm/include/asm/system.h   | 118 ++++++++++++++++++++++++++-
 arch/arm/lib/bootm.c            |  19 ++++-
 common/image-fit.c              |  14 +++-
 6 files changed, 287 insertions(+), 52 deletions(-)
arch/arm/Kconfig +6 -0
index 729b181..794cb4f 100644
@@ -77,6 +77,12 @@ config SYS_L2CACHE_OFF
 	  If SoC does not support L2CACHE or one do not want to enable
 	  L2CACHE, choose this option.
 
+config ARM64_SUPPORT_AARCH32
+	bool "ARM64 system support AArch32 execution state"
+	default y if ARM64 && !CONFIG_THUNDERX
+	help
+	  This ARM64 system supports AArch32 execution state.
+
 choice
 	prompt "Target select"
 	default TARGET_HIKEY
arch/arm/cpu/armv8/transition.S +0 -0
index 253a39b..417e8b4 100644

arch/arm/cpu/armv8/transition.S line 17

Quoted 9 lines
arch/arm/cpu/armv8/transition.S +2 -2
@@ -11,13 +11,13 @@
 #include <asm/macro.h>
 
 ENTRY(armv8_switch_to_el2)
-	switch_el x0, 1f, 0f, 0f
+	switch_el x4, 1f, 0f, 0f
 0:	ret
-1:	armv8_switch_to_el2_m x0
+1:	armv8_switch_to_el2_m x0, x1, x2, x3, x4
 ENDPROC(armv8_switch_to_el2)

Alison,

I see you are chaning macro armv8_switch_to_el2. You may have missed one in start.S. This is the code you can't test with our ARMv8 chip.

York

#3 lore raw

PATCH v3 1/2 armv8: Support loading 32-bit OS in AArch32 execution state

Hi, York,

Quoted 71 lines · Alison Wang
Quoted 9 lines

To support loading a 32-bit OS, the execution state will change from AArch64 to AArch32 when jumping to kernel.

The architecture information will be got through checking FIT image, then U-Boot will load 32-bit OS or 64-bit OS automatically.

Quoted 8 lines

---
Changes in v3:
- Comments the functions and the arguments.
- Rename the real parameters.
- Use the macros instead of the magic values.
- Remove the redundant codes.
- Clean up all of the mess in boot_jump_linux().
- Add CONFIG_ARM64_SUPPORT_AARCH32 to detect for some ARM64 system

doesn't support AArch32 state.

Quoted 3 lines

Changes in v2:
- armv8_switch_to_el2_aarch32() is removed. armv8_switch_to_el2_m is

used

Quoted 2 lines

to switch to AArch64 EL2 or AArch32 Hyp.
- armv8_switch_to_el1_aarch32() is removed. armv8_switch_to_el1_m is

used

Quoted 5 lines

to switch to AArch64 EL1 or AArch32 SVC.

 arch/arm/Kconfig                |   6 ++
 arch/arm/cpu/armv8/transition.S |   8 +-
 arch/arm/include/asm/macro.h    | 174 ++++++++++++++++++++++++++++++-

---------

Quoted 27 lines
 arch/arm/include/asm/system.h   | 118 ++++++++++++++++++++++++++-
 arch/arm/lib/bootm.c            |  19 ++++-
 common/image-fit.c              |  14 +++-
 6 files changed, 287 insertions(+), 52 deletions(-)
arch/arm/Kconfig index renamed from arch/arm/Kconfig +0 -0

729b181..794cb4f 100644

arch/arm/Kconfig +6 -0
@@ -77,6 +77,12 @@ config SYS_L2CACHE_OFF
 	  If SoC does not support L2CACHE or one do not want to enable
 	  L2CACHE, choose this option.
 
+config ARM64_SUPPORT_AARCH32
+	bool "ARM64 system support AArch32 execution state"
+	default y if ARM64 && !CONFIG_THUNDERX
+	help
+	  This ARM64 system supports AArch32 execution state.
+
 choice
 	prompt "Target select"
 	default TARGET_HIKEY
(quoted diff) +0 -0

b/arch/arm/cpu/armv8/transition.S index 253a39b..417e8b4 100644

arch/arm/cpu/armv8/transition.S line 17

Quoted 9 lines
arch/arm/cpu/armv8/transition.S +2 -2
@@ -11,13 +11,13 @@
 #include <asm/macro.h>
 
 ENTRY(armv8_switch_to_el2)
-	switch_el x0, 1f, 0f, 0f
+	switch_el x4, 1f, 0f, 0f
 0:	ret
-1:	armv8_switch_to_el2_m x0
+1:	armv8_switch_to_el2_m x0, x1, x2, x3, x4
 ENDPROC(armv8_switch_to_el2)

Alison,

Quoted 3 lines

I see you are chaning macro armv8_switch_to_el2. You may have missed one in start.S. This is the code you can't test with our ARMv8 chip.

[Alison Wang] Yes, I missed that one. In start.S, armv8_switch_to_el2 will be called for secondary cores. I will set argument x3 as ES_TO_AARCH64 for it. As the way to notice secondary cores about the architecture of OS may be different for other ARMv8 chips, I will not add ES_TO_AARCH32 in start.S. Do you agree?

Thanks for your reminder.

Best Regards,
Alison Wang

#4 lore raw

PATCH v3 1/2 armv8: Support loading 32-bit OS in AArch32 execution state

In reply to Alison Wang
Quoted 37 lines · Alison Wang

To support loading a 32-bit OS, the execution state will change from AArch64 to AArch32 when jumping to kernel.

The architecture information will be got through checking FIT image, then U-Boot will load 32-bit OS or 64-bit OS automatically.

---
Changes in v3:
- Comments the functions and the arguments.
- Rename the real parameters.
- Use the macros instead of the magic values.
- Remove the redundant codes.
- Clean up all of the mess in boot_jump_linux().
- Add CONFIG_ARM64_SUPPORT_AARCH32 to detect for some ARM64 system doesn't support AArch32 state.

Changes in v2:
- armv8_switch_to_el2_aarch32() is removed. armv8_switch_to_el2_m is used to switch to AArch64 EL2 or AArch32 Hyp.
- armv8_switch_to_el1_aarch32() is removed. armv8_switch_to_el1_m is used to switch to AArch64 EL1 or AArch32 SVC.

 arch/arm/Kconfig                |   6 ++
 arch/arm/cpu/armv8/transition.S |   8 +-
 arch/arm/include/asm/macro.h    | 174 ++++++++++++++++++++++++++++++----------
 arch/arm/include/asm/system.h   | 118 ++++++++++++++++++++++++++-
 arch/arm/lib/bootm.c            |  19 ++++-
 common/image-fit.c              |  14 +++-
 6 files changed, 287 insertions(+), 52 deletions(-)
arch/arm/Kconfig +0 -0
index 729b181..794cb4f 100644

arch/arm/Kconfig config SYS_L2CACHE_OFF · line 82

Quoted 6 lines
arch/arm/Kconfig +3 -0
@@ -77,6 +77,12 @@ config SYS_L2CACHE_OFF
 	  If SoC does not support L2CACHE or one do not want to enable
 	  L2CACHE, choose this option.
 
+config ARM64_SUPPORT_AARCH32
+	bool "ARM64 system support AArch32 execution state"
+	default y if ARM64 && !CONFIG_THUNDERX

I don't think that works. In Kconfig you need to omit the CONFIG_ parts. It's "ARM64" also, not "CONFIG_ARM64".

Please just try to run a local make defconfig on the thunderx reference system and see whether it includes the option or not.

Quoted 49 lines
arch/arm/Kconfig +3 -0
+	help
+	  This ARM64 system supports AArch32 execution state.
+
 choice
 	prompt "Target select"
 	default TARGET_HIKEY
arch/arm/cpu/armv8/transition.S +4 -4
index 253a39b..417e8b4 100644
@@ -11,13 +11,13 @@
 #include <asm/macro.h>
 
 ENTRY(armv8_switch_to_el2)
-	switch_el x0, 1f, 0f, 0f
+	switch_el x4, 1f, 0f, 0f
 0:	ret
-1:	armv8_switch_to_el2_m x0
+1:	armv8_switch_to_el2_m x0, x1, x2, x3, x4
 ENDPROC(armv8_switch_to_el2)
 
 ENTRY(armv8_switch_to_el1)
-	switch_el x0, 0f, 1f, 0f
+	switch_el x4, 0f, 1f, 0f
 0:	ret
-1:	armv8_switch_to_el1_m x0, x1
+1:	armv8_switch_to_el1_m x0, x1, x2, x3, x4
 ENDPROC(armv8_switch_to_el1)
arch/arm/include/asm/macro.h +3 -3
index 9bb0efa..dd2c510 100644
@@ -8,6 +8,9 @@
 
 #ifndef __ASM_ARM_MACRO_H__
 #define __ASM_ARM_MACRO_H__
+
+#include <asm/system.h>
+
 #ifdef __ASSEMBLY__
 
 /*
@@ -135,13 +138,18 @@ lr	.req	x30
 #endif
 .endm
 
-.macro armv8_switch_to_el2_m, xreg1
-	/* 64bit EL2 | HCE | SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1 */
-	mov	\xreg1, #0x5b1

arch/arm/include/asm/macro.h lr .req x30 · line 149

Quoted 10 lines
arch/arm/include/asm/macro.h +9 -1
-	msr	scr_el3, \xreg1
+/*
+ * Switch from EL3 to EL2 for ARMv8
+ * @ep:     kernel entry point
+ * @arch:   machine nr
+ * @ftaddr: fdt address
+ * @flag:   The execution state flag for lower exception
+ *          level, ES_TO_AARCH64 or ES_TO_AARCH32
+ */
+.macro armv8_switch_to_el2_m, ep, arch, ftaddr, flag, xreg5

You're never really using the arch and ftaddr arguments. Just describe in the macro header that they need to be in x1 and x2 respectively and leave them out of the argument list for the macro.

Also please rename "xreg5" to something like "scratchreg" or "tmp" or "tmpreg". Then it's more obvious what this argument is about.

Quoted 11 lines
arch/arm/include/asm/macro.h +2 -2
 	msr	cptr_el3, xzr		/* Disable coprocessor traps to EL3 */
-	mov	\xreg1, #0x33ff
-	msr	cptr_el2, \xreg1	/* Disable coprocessor traps to EL2 */
+	mov	\xreg5, #(CPTR_EL2_BIT13_12_RES1 | CPTR_EL2_BIT9_0_RES1)
+	msr	cptr_el2, \xreg5	/* Disable coprocessor traps to EL2 */
 
 	/* Initialize Generic Timers */
 	msr	cntvoff_el2, xzr
@@ -152,45 +160,92 @@ lr	.req	x30
 	 * and RES0 bits (31,30,27,26,24,21,20,17,15-13,10-6) +
 	 * EE,WXN,I,SA,C,A,M to 0

arch/arm/include/asm/macro.h lr .req x30 · line 168

Quoted 10 lines
arch/arm/include/asm/macro.h +6 -3
 	 */
-	mov	\xreg1, #0x0830
-	movk	\xreg1, #0x30C5, lsl #16
-	msr	sctlr_el2, \xreg1
+	ldr	\xreg5, =(SCTLR_EL2_BIT29_28_RES1 | SCTLR_EL2_EE_LE |\
+			  SCTLR_EL2_BIT23_22_RES1 | SCTLR_EL2_WXN_DIS |\
+			  SCTLR_EL2_BIT18_RES1 | SCTLR_EL2_BIT16_RES1 |\
+			  SCTLR_EL2_BIT11_RES1 | SCTLR_EL2_BIT5_4_RES1 |\
+			  SCTLR_EL2_SA_DIS | SCTLR_EL2_DCACHE_DIS |\
+			  SCTLR_EL2_ALIGN_DIS | SCTLR_EL2_MMU_DIS)

Do you think you could just define something like SCTLR_EL2_RES1 in the header file that combines all RES1 fields already?

arch/arm/include/asm/macro.h lr .req x30 · line 178

Quoted 10 lines
arch/arm/include/asm/macro.h +10 -0
+	msr	sctlr_el2, \xreg5
+
+	mov	\xreg5, sp
+	msr	sp_el2, \xreg5		/* Migrate SP */
+	mrs	\xreg5, vbar_el3
+	msr	vbar_el2, \xreg5	/* Migrate VBAR */
+
+	/* Check switch to AArch64 EL2 or AArch32 Hypervisor mode */
+	ldr	\xreg5, =ES_TO_AARCH32
+	cmp	\flag, \xreg5

This can be an immediate cmp, no?

cmp \flag, #ES_TO_AARCH32

arch/arm/include/asm/macro.h lr .req x30 · line 187

Quoted 9 lines
arch/arm/include/asm/macro.h +9 -0
+	b.eq	1f
+
+	/*
+	 * The next lower exception level is AArch64, 64bit EL2 | HCE |
+	 * SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1.
+	 */
+	ldr	\xreg5, =(SCR_EL3_RW_AARCH64 | SCR_EL3_HCE_EN |\
+			  SCR_EL3_SMD_DIS | SCR_EL3_BIT5_4_RES1 |\
+			  SCR_EL3_NS_EN)

Same here - just define a single mask for SCR_EL3_RES1.

Quoted 38 lines
arch/arm/include/asm/macro.h +26 -6
+	msr	scr_el3, \xreg5
 
 	/* Return to the EL2_SP2 mode from EL3 */
-	mov	\xreg1, sp
-	msr	sp_el2, \xreg1		/* Migrate SP */
-	mrs	\xreg1, vbar_el3
-	msr	vbar_el2, \xreg1	/* Migrate VBAR */
-	mov	\xreg1, #0x3c9
-	msr	spsr_el3, \xreg1	/* EL2_SP2 | D | A | I | F */
+	ldr	\xreg5, =(SPSR_EL_DEBUG_MASK | SPSR_EL_SERR_MASK |\
+			  SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\
+			  SPSR_EL_M_AARCH64 | SPSR_EL_M_EL2H)
+	msr	spsr_el3, \xreg5
 	msr	elr_el3, lr
 	eret
+
+1:
+	/*
+	 * The next lower exception level is AArch32, 32bit EL2 | HCE |
+	 * SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1.
+	 */
+	ldr	\xreg5, =(SCR_EL3_RW_AARCH32 | SCR_EL3_HCE_EN |\
+			  SCR_EL3_SMD_DIS | SCR_EL3_BIT5_4_RES1 |\
+			  SCR_EL3_NS_EN)
+	msr	scr_el3, \xreg5
+
+	/* Return to AArch32 Hypervisor mode */
+	ldr     \xreg5, =(SPSR_EL_END_LE | SPSR_EL_ASYN_MASK |\
+			  SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\
+			  SPSR_EL_T_A32 | SPSR_EL_M_AARCH32 |\
+			  SPSR_EL_M_HYP)
+	msr	spsr_el3, \xreg5
+	msr     elr_el3, \ep
+
+	mov	\ep, #0
+	eret
 .endm
 

arch/arm/include/asm/macro.h lr .req x30 · line 228

Quoted 10 lines
arch/arm/include/asm/macro.h +9 -1
-.macro armv8_switch_to_el1_m, xreg1, xreg2
+/*
+ * Switch from EL2 to EL1 for ARMv8
+ * @ep:     kernel entry point
+ * @arch:   machine nr
+ * @ftaddr: fdt address
+ * @flag:   The execution state flag for lower exception
+ *          level, ES_TO_AARCH64 or ES_TO_AARCH32
+ */
+.macro armv8_switch_to_el1_m, ep, arch, ftaddr, flag, xreg5

All the comments to the function above apply here too :).

Quoted 47 lines
arch/arm/include/asm/macro.h +14 -19
 	/* Initialize Generic Timers */
-	mrs	\xreg1, cnthctl_el2
-	orr	\xreg1, \xreg1, #0x3	/* Enable EL1 access to timers */
-	msr	cnthctl_el2, \xreg1
+	mrs	\xreg5, cnthctl_el2
+	/* Enable EL1 access to timers */
+	orr	\xreg5, \xreg5, #(CNTHCTL_EL2_EL1PCEN_EN |\
+		CNTHCTL_EL2_EL1PCTEN_EN)
+	msr	cnthctl_el2, \xreg5
 	msr	cntvoff_el2, xzr
 
 	/* Initilize MPID/MPIDR registers */
-	mrs	\xreg1, midr_el1
-	mrs	\xreg2, mpidr_el1
-	msr	vpidr_el2, \xreg1
-	msr	vmpidr_el2, \xreg2
+	mrs	\xreg5, midr_el1
+	msr	vpidr_el2, \xreg5
+	mrs	\xreg5, mpidr_el1
+	msr	vmpidr_el2, \xreg5
 
 	/* Disable coprocessor traps */
-	mov	\xreg1, #0x33ff
-	msr	cptr_el2, \xreg1	/* Disable coprocessor traps to EL2 */
+	mov	\xreg5, #(CPTR_EL2_BIT13_12_RES1 | CPTR_EL2_BIT9_0_RES1)
+	msr	cptr_el2, \xreg5	/* Disable coprocessor traps to EL2 */
 	msr	hstr_el2, xzr		/* Disable coprocessor traps to EL2 */
-	mov	\xreg1, #3 << 20
-	msr	cpacr_el1, \xreg1	/* Enable FP/SIMD at EL1 */
-
-	/* Initialize HCR_EL2 */
-	mov	\xreg1, #(1 << 31)		/* 64bit EL1 */
-	orr	\xreg1, \xreg1, #(1 << 29)	/* Disable HVC */
-	msr	hcr_el2, \xreg1
+	mov	\xreg5, #(CPACR_EL1_FPEN_EN)
+	msr	cpacr_el1, \xreg5	/* Enable FP/SIMD at EL1 */
 
 	/* SCTLR_EL1 initialization
 	 *
@@ -199,19 +254,56 @@ lr	.req	x30
 	 * UCI,EE,EOE,WXN,nTWE,nTWI,UCT,DZE,I,UMA,SED,ITD,
 	 * CP15BEN,SA0,SA,C,A,M to 0
 	 */
-	mov	\xreg1, #0x0800
-	movk	\xreg1, #0x30d0, lsl #16
-	msr	sctlr_el1, \xreg1
+	ldr	\xreg5, =(SCTLR_EL1_BIT29_28_RES1 | SCTLR_EL1_UCI_DIS |\

arch/arm/include/asm/macro.h lr .req x30 · line 267

Quoted 10 lines
arch/arm/include/asm/macro.h +10 -0
+			  SCTLR_EL1_EE_LE | SCTLR_EL1_BIT23_22_RES1 |\
+			  SCTLR_EL1_BIT20_RES1 | SCTLR_EL1_WXN_DIS |\
+			  SCTLR_EL1_NTWE_DIS | SCTLR_EL1_NTWI_DIS |\
+			  SCTLR_EL1_UCT_DIS | SCTLR_EL1_DZE_DIS |\
+			  SCTLR_EL1_ICACHE_DIS | SCTLR_EL1_BIT11_RES1 |\
+			  SCTLR_EL1_UMA_DIS | SCTLR_EL1_SED_EN |\
+			  SCTLR_EL1_ITD_EN | SCTLR_EL1_CP15BEN_DIS |\
+			  SCTLR_EL1_SA0_DIS | SCTLR_EL1_SA_DIS |\
+			  SCTLR_EL1_DCACHE_DIS | SCTLR_EL1_ALIGN_DIS |\
+			  SCTLR_EL1_MMU_DIS)

Why are the caches getting disabled? Or did you just convert the old value to the define list?

Quoted 245 lines
arch/arm/include/asm/macro.h +35 -6
+	msr	sctlr_el1, \xreg5
+
+	mov	\xreg5, sp
+	msr	sp_el1, \xreg5		/* Migrate SP */
+	mrs	\xreg5, vbar_el2
+	msr	vbar_el1, \xreg5	/* Migrate VBAR */
+
+	/* Check switch to AArch64 EL1 or AArch32 Supervisor mode */
+	ldr	\xreg5, =ES_TO_AARCH32
+	cmp	\flag, \xreg5
+	b.eq	1f
+
+	/* Initialize HCR_EL2 */
+	ldr	\xreg5, =(HCR_EL2_RW_AARCH64 | HCR_EL2_HCD_DIS)
+	msr	hcr_el2, \xreg5
 
 	/* Return to the EL1_SP1 mode from EL2 */
-	mov	\xreg1, sp
-	msr	sp_el1, \xreg1		/* Migrate SP */
-	mrs	\xreg1, vbar_el2
-	msr	vbar_el1, \xreg1	/* Migrate VBAR */
-	mov	\xreg1, #0x3c5
-	msr	spsr_el2, \xreg1	/* EL1_SP1 | D | A | I | F */
+	ldr	\xreg5, =(SPSR_EL_DEBUG_MASK | SPSR_EL_SERR_MASK |\
+			  SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\
+			  SPSR_EL_M_AARCH64 | SPSR_EL_M_EL1H)
+	msr	spsr_el2, \xreg5
 	msr	elr_el2, lr
 	eret
+
+1:
+	/* Initialize HCR_EL2 */
+	ldr	\xreg5, =(HCR_EL2_RW_AARCH32 | HCR_EL2_HCD_DIS)
+	msr	hcr_el2, \xreg5
+
+	/* Return to AArch32 Supervisor mode from EL2 */
+	ldr	\xreg5, =(SPSR_EL_END_LE | SPSR_EL_ASYN_MASK |\
+			  SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\
+			  SPSR_EL_T_A32 | SPSR_EL_M_AARCH32 |\
+			  SPSR_EL_M_SVC)
+	msr     spsr_el2, \xreg5
+	msr     elr_el2, \ep
+
+	mov	\ep, #0
+	eret
 .endm
 
 #if defined(CONFIG_GICV3)
arch/arm/include/asm/system.h +116 -2
index 9ae890a..0271ddb 100644
@@ -17,6 +17,102 @@
 #define CR_WXN		(1 << 19)	/* Write Permision Imply XN	*/
 #define CR_EE		(1 << 25)	/* Exception (Big) Endian	*/
 
+#define ES_TO_AARCH64		1
+#define ES_TO_AARCH32		0
+
+/*
+ * SCR_EL3 bits definitions
+ */
+#define SCR_EL3_RW_AARCH64	(1 << 10) /* Next lower level is AArch64     */
+#define SCR_EL3_RW_AARCH32	(0 << 10) /* Lower lowers level are AArch32  */
+#define SCR_EL3_HCE_EN		(1 << 8)  /* Hypervisor Call enable          */
+#define SCR_EL3_SMD_DIS		(1 << 7)  /* Secure Monitor Call disable     */
+#define SCR_EL3_BIT5_4_RES1	(3 << 4)  /* Reserved, RES1                  */
+#define SCR_EL3_NS_EN		(1 << 0)  /* EL0 and EL1 in Non-scure state  */
+
+/*
+ * SPSR_EL3/SPSR_EL2 bits definitions
+ */
+#define SPSR_EL_END_LE		(0 << 9)  /* Exception Little-endian          */
+#define SPSR_EL_DEBUG_MASK	(1 << 9)  /* Debug exception masked           */
+#define SPSR_EL_ASYN_MASK	(1 << 8)  /* Asynchronous data abort masked   */
+#define SPSR_EL_SERR_MASK	(1 << 8)  /* System Error exception masked    */
+#define SPSR_EL_IRQ_MASK	(1 << 7)  /* IRQ exception masked             */
+#define SPSR_EL_FIQ_MASK	(1 << 6)  /* FIQ exception masked             */
+#define SPSR_EL_T_A32		(0 << 5)  /* AArch32 instruction set A32      */
+#define SPSR_EL_M_AARCH64	(0 << 4)  /* Exception taken from AArch64     */
+#define SPSR_EL_M_AARCH32	(1 << 4)  /* Exception taken from AArch32     */
+#define SPSR_EL_M_SVC		(0x3)     /* Exception taken from SVC mode    */
+#define SPSR_EL_M_HYP		(0xa)     /* Exception taken from HYP mode    */
+#define SPSR_EL_M_EL1H		(5)       /* Exception taken from EL1h mode   */
+#define SPSR_EL_M_EL2H		(9)       /* Exception taken from EL2h mode   */
+
+/*
+ * CPTR_EL2 bits definitions
+ */
+#define CPTR_EL2_BIT13_12_RES1	(3 << 12) /* Reserved, RES1                   */
+#define CPTR_EL2_BIT9_0_RES1	(0x3ff)   /* Reserved, RES1                   */
+
+/*
+ * SCTLR_EL2 bits definitions
+ */
+#define SCTLR_EL2_BIT29_28_RES1	(3 << 28) /* Reserved, RES1                   */
+#define SCTLR_EL2_EE_LE		(0 << 25) /* Exception Little-endian          */
+#define SCTLR_EL2_BIT23_22_RES1	(3 << 22) /* Reserved, RES1                   */
+#define SCTLR_EL2_WXN_DIS	(0 << 19) /* Write permission is not XN       */
+#define SCTLR_EL2_BIT18_RES1	(1 << 18) /* Reserved, RES1                   */
+#define SCTLR_EL2_BIT16_RES1	(1 << 16) /* Reserved, RES1                   */
+#define SCTLR_EL2_ICACHE_DIS	(0 << 12) /* Instruction cache disabled       */
+#define SCTLR_EL2_BIT11_RES1	(1 << 11) /* Reserved, RES1                   */
+#define SCTLR_EL2_BIT5_4_RES1	(3 << 4)  /* Reserved, RES1                   */
+#define SCTLR_EL2_SA_DIS	(0 << 3)  /* Stack Alignment Check disabled   */
+#define SCTLR_EL2_DCACHE_DIS	(0 << 2)  /* Data cache disabled              */
+#define SCTLR_EL2_ALIGN_DIS	(0 << 1)  /* Alignment check disabled         */
+#define SCTLR_EL2_MMU_DIS	(0)       /* MMU disabled                     */
+
+/*
+ * CNTHCTL_EL2 bits definitions
+ */
+#define CNTHCTL_EL2_EL1PCEN_EN	(1 << 1)  /* Physical timer regs accessible   */
+#define CNTHCTL_EL2_EL1PCTEN_EN	(1 << 0)  /* Physical counter accessible      */
+
+/*
+ * HCR_EL2 bits definitions
+ */
+#define HCR_EL2_RW_AARCH64	(1 << 31) /* EL1 is AArch64                   */
+#define HCR_EL2_RW_AARCH32	(0 << 31) /* Lower levels are AArch32         */
+#define HCR_EL2_HCD_DIS		(1 << 29) /* Hypervisor Call disabled         */
+
+/*
+ * CPACR_EL1 bits definitions
+ */
+#define CPACR_EL1_FPEN_EN	(3 << 20) /* SIMD and FP instruction enabled  */
+
+/*
+ * SCTLR_EL1 bits definitions
+ */
+#define SCTLR_EL1_BIT29_28_RES1	(3 << 28) /* Reserved, RES1                   */
+#define SCTLR_EL1_UCI_DIS	(0 << 26) /* Cache instruction disabled       */
+#define SCTLR_EL1_EE_LE		(0 << 25) /* Exception Little-endian          */
+#define SCTLR_EL1_BIT23_22_RES1	(3 << 22) /* Reserved, RES1                   */
+#define SCTLR_EL1_BIT20_RES1	(1 << 20) /* Reserved, RES1                   */
+#define SCTLR_EL1_WXN_DIS	(0 << 19) /* Write permission is not XN       */
+#define SCTLR_EL1_NTWE_DIS	(0 << 18) /* WFE instruction disabled         */
+#define SCTLR_EL1_NTWI_DIS	(0 << 16) /* WFI instruction disabled         */
+#define SCTLR_EL1_UCT_DIS	(0 << 15) /* CTR_EL0 access disabled          */
+#define SCTLR_EL1_DZE_DIS	(0 << 14) /* DC ZVA instruction disabled      */
+#define SCTLR_EL1_ICACHE_DIS	(0 << 12) /* Instruction cache disabled       */
+#define SCTLR_EL1_BIT11_RES1	(1 << 11) /* Reserved, RES1                   */
+#define SCTLR_EL1_UMA_DIS	(0 << 9)  /* User Mask Access disabled        */
+#define SCTLR_EL1_SED_EN	(0 << 8)  /* SETEND instruction enabled       */
+#define SCTLR_EL1_ITD_EN	(0 << 7)  /* IT instruction enabled           */
+#define SCTLR_EL1_CP15BEN_DIS	(0 << 5)  /* CP15 barrier operation disabled  */
+#define SCTLR_EL1_SA0_DIS	(0 << 4)  /* Stack Alignment EL0 disabled     */
+#define SCTLR_EL1_SA_DIS	(0 << 3)  /* Stack Alignment EL1 disabled     */
+#define SCTLR_EL1_DCACHE_DIS	(0 << 2)  /* Data cache disabled              */
+#define SCTLR_EL1_ALIGN_DIS	(0 << 1)  /* Alignment check disabled         */
+#define SCTLR_EL1_MMU_DIS	(0)       /* MMU disabled                     */
+
 #ifndef __ASSEMBLY__
 
 u64 get_page_table_size(void);
@@ -100,8 +196,26 @@ void __asm_invalidate_icache_all(void);
 int __asm_flush_l3_cache(void);
 void __asm_switch_ttbr(u64 new_ttbr);
 
-void armv8_switch_to_el2(void);
-void armv8_switch_to_el1(void);
+/*
+ * Switch from EL3 to EL2 for ARMv8
+ *
+ * @entry_point: kernel entry point
+ * @mach_nr:     machine nr
+ * @fdt_addr:    fdt address
+ * @es_flag:     execution state flag, ES_TO_AARCH64 or ES_TO_AARCH32
+ */
+void armv8_switch_to_el2(u64 entry_point, u64 mach_nr, u64 fdt_addr,
+			 u64 es_flag);
+/*
+ * Switch from EL2 to EL1 for ARMv8
+ *
+ * @entry_point: kernel entry point
+ * @mach_nr:     machine nr
+ * @fdt_addr:    fdt address
+ * @es_flag:     execution state flag, ES_TO_AARCH64 or ES_TO_AARCH32
+ */
+void armv8_switch_to_el1(u64 entry_point, u64 mach_nr, u64 fdt_addr,
+			 u64 es_flag);
 void gic_init(void);
 void gic_send_sgi(unsigned long sgino);
 void wait_for_wakeup(void);
arch/arm/lib/bootm.c +15 -4
index 0838d89..1bbf85c 100644
@@ -189,13 +189,19 @@ static void setup_end_tag(bd_t *bd)
 __weak void setup_board_tags(struct tag **in_params) {}
 
 #ifdef CONFIG_ARM64
-static void do_nonsec_virt_switch(void)
+static void do_nonsec_virt_switch(bootm_headers_t *images, int flag)
 {
 	smp_kick_all_cpus();
 	dcache_disable();	/* flush cache before swtiching to EL2 */
-	armv8_switch_to_el2();
+
 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
-	armv8_switch_to_el1();
+	armv8_switch_to_el2((u64)images->ep, (u64)gd->bd->bi_arch_number,
+			    (u64)images->ft_addr, ES_TO_AARCH64);
+	armv8_switch_to_el1((u64)images->ep, (u64)gd->bd->bi_arch_number,
+			    (u64)images->ft_addr, flag);
+#else
+	armv8_switch_to_el2((u64)images->ep, (u64)gd->bd->bi_arch_number,
+			    (u64)images->ft_addr, flag);
 #endif
 }
 #endif
@@ -275,6 +281,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
 	void (*kernel_entry)(void *fdt_addr, void *res0, void *res1,
 			void *res2);
 	int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
+	int es_flag = ES_TO_AARCH64;
 
 	kernel_entry = (void (*)(void *fdt_addr, void *res0, void *res1,
 				void *res2))images->ep;
@@ -286,7 +293,11 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
 	announce_and_cleanup(fake);
 
 	if (!fake) {
-		do_nonsec_virt_switch();
+		if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
+		    (images->os.arch == IH_ARCH_ARM))
+			es_flag = ES_TO_AARCH32;
+
+		do_nonsec_virt_switch(images, es_flag);
 		kernel_entry(images->ft_addr, NULL, NULL, NULL);
 	}
 #else
common/image-fit.c +1 -0
index 9873957..982021b 100644
@@ -26,6 +26,7 @@ DECLARE_GLOBAL_DATA_PTR;
 #include <u-boot/md5.h>
 #include <u-boot/sha1.h>
 #include <u-boot/sha256.h>
+#include <generated/autoconf.h>
 
 /*****************************************************************************/
 /* New uImage format routines */

common/image-fit.c int fit_image_check_arch(const void *fit, int noffset, uint8_t arch) · line 1170

Quoted 7 lines
common/image-fit.c +3 -1
@@ -1164,7 +1165,9 @@ int fit_image_check_arch(const void *fit, int noffset, uint8_t arch)
 	if (fit_image_get_arch(fit, noffset, &image_arch))
 		return 0;
 	return (arch == image_arch) ||
-		(arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64);
+		(arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64) ||
+		(arch == IH_ARCH_ARM64 && image_arch == IH_ARCH_ARM &&
+		 CONFIG_ARM64_SUPPORT_AARCH32);

Uh, I think this define is simply not defined for non-compatible systems (including non-arm64). This really needs to go into an #ifdef.

Thanks a lot for all the refactoring work :). This patch already reads much nicer than the original code. I guess with next round we'll get this into really good shape.

Alex

Quoted 27 lines
common/image-fit.c +9 -0
 }
 
 /**
@@ -1593,6 +1596,9 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
 	int type_ok, os_ok;
 	ulong load, data, len;
 	uint8_t os;
+#ifndef USE_HOSTCC
+	uint8_t os_arch;
+#endif
 	const char *prop_name;
 	int ret;
 
@@ -1676,6 +1682,12 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
 		return -ENOEXEC;
 	}
 #endif
+
+#ifndef USE_HOSTCC
+	fit_image_get_arch(fit, noffset, &os_arch);
+	images->os.arch = os_arch;
+#endif
+
 	if (image_type == IH_TYPE_FLATDT &&
 	    !fit_image_check_comp(fit, noffset, IH_COMP_NONE)) {
 		puts("FDT image is compressed");
#5 lore raw

PATCH v3 1/2 armv8: Support loading 32-bit OS in AArch32 execution state

Quoted 52 lines · Alison Wang
Quoted 9 lines

To support loading a 32-bit OS, the execution state will change from AArch64 to AArch32 when jumping to kernel.

The architecture information will be got through checking FIT image, then U-Boot will load 32-bit OS or 64-bit OS automatically.

Quoted 8 lines

---
Changes in v3:
- Comments the functions and the arguments.
- Rename the real parameters.
- Use the macros instead of the magic values.
- Remove the redundant codes.
- Clean up all of the mess in boot_jump_linux().
- Add CONFIG_ARM64_SUPPORT_AARCH32 to detect for some ARM64 system

doesn't support AArch32 state.

Quoted 3 lines

Changes in v2:
- armv8_switch_to_el2_aarch32() is removed. armv8_switch_to_el2_m is

used

Quoted 2 lines

to switch to AArch64 EL2 or AArch32 Hyp.
- armv8_switch_to_el1_aarch32() is removed. armv8_switch_to_el1_m is

used

Quoted 5 lines

to switch to AArch64 EL1 or AArch32 SVC.

 arch/arm/Kconfig                |   6 ++
 arch/arm/cpu/armv8/transition.S |   8 +-
 arch/arm/include/asm/macro.h    | 174 ++++++++++++++++++++++++++++++-

---------

Quoted 10 lines
 arch/arm/include/asm/system.h   | 118 ++++++++++++++++++++++++++-
 arch/arm/lib/bootm.c            |  19 ++++-
 common/image-fit.c              |  14 +++-
 6 files changed, 287 insertions(+), 52 deletions(-)
arch/arm/Kconfig index renamed from arch/arm/Kconfig +0 -0

729b181..794cb4f 100644

arch/arm/Kconfig config SYS_L2CACHE_OFF · line 82

Quoted 6 lines
arch/arm/Kconfig +3 -0
@@ -77,6 +77,12 @@ config SYS_L2CACHE_OFF
 	  If SoC does not support L2CACHE or one do not want to enable
 	  L2CACHE, choose this option.
 
+config ARM64_SUPPORT_AARCH32
+	bool "ARM64 system support AArch32 execution state"
+	default y if ARM64 && !CONFIG_THUNDERX

I don't think that works. In Kconfig you need to omit the CONFIG_ parts. It's "ARM64" also, not "CONFIG_ARM64".

Quoted 2 lines

Please just try to run a local make defconfig on the thunderx reference system and see whether it includes the option or not.

[Alison Wang] Yes, I missed it. Will change in the next version.

Quoted 50 lines
Quoted 44 lines
arch/arm/Kconfig +3 -0
+	help
+	  This ARM64 system supports AArch32 execution state.
+
 choice
 	prompt "Target select"
 	default TARGET_HIKEY
(quoted diff) +0 -0

b/arch/arm/cpu/armv8/transition.S index 253a39b..417e8b4 100644

arch/arm/cpu/armv8/transition.S +4 -4
@@ -11,13 +11,13 @@
 #include <asm/macro.h>
 
 ENTRY(armv8_switch_to_el2)
-	switch_el x0, 1f, 0f, 0f
+	switch_el x4, 1f, 0f, 0f
 0:	ret
-1:	armv8_switch_to_el2_m x0
+1:	armv8_switch_to_el2_m x0, x1, x2, x3, x4
 ENDPROC(armv8_switch_to_el2)
 
 ENTRY(armv8_switch_to_el1)
-	switch_el x0, 0f, 1f, 0f
+	switch_el x4, 0f, 1f, 0f
 0:	ret
-1:	armv8_switch_to_el1_m x0, x1
+1:	armv8_switch_to_el1_m x0, x1, x2, x3, x4
 ENDPROC(armv8_switch_to_el1)
(quoted diff) +0 -0

b/arch/arm/include/asm/macro.h index 9bb0efa..dd2c510 100644

arch/arm/include/asm/macro.h +3 -0
@@ -8,6 +8,9 @@
 
 #ifndef __ASM_ARM_MACRO_H__
 #define __ASM_ARM_MACRO_H__
+
+#include <asm/system.h>
+
 #ifdef __ASSEMBLY__
 
 /*

arch/arm/include/asm/macro.h lr .req x30 · line 139

Quoted 5 lines
arch/arm/include/asm/macro.h +0 -2
@@ -135,13 +138,18 @@ lr	.req	x30
 #endif
 .endm
 
-.macro armv8_switch_to_el2_m, xreg1
-	/* 64bit EL2 | HCE | SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1

*/

Quoted 15 lines

arch/arm/include/asm/macro.h lr .req x30 · line 149

Quoted 11 lines
arch/arm/include/asm/macro.h +9 -2
-	mov	\xreg1, #0x5b1
-	msr	scr_el3, \xreg1
+/*
+ * Switch from EL3 to EL2 for ARMv8
+ * @ep:     kernel entry point
+ * @arch:   machine nr
+ * @ftaddr: fdt address
+ * @flag:   The execution state flag for lower exception
+ *          level, ES_TO_AARCH64 or ES_TO_AARCH32
+ */
+.macro armv8_switch_to_el2_m, ep, arch, ftaddr, flag, xreg5

You're never really using the arch and ftaddr arguments. Just describe in the macro header that they need to be in x1 and x2 respectively and leave them out of the argument list for the macro.

[Alison Wang] Do you mean rename arch and ftaddr to x1 and x2 here?

Quoted 3 lines

Also please rename "xreg5" to something like "scratchreg" or "tmp" or "tmpreg". Then it's more obvious what this argument is about.

[Alison Wang] Ok.

Quoted 18 lines

arch/arm/include/asm/macro.h lr .req x30 · line 150

Quoted 2 lines
arch/arm/include/asm/macro.h +0 -0
 	msr	cptr_el3, xzr		/* Disable coprocessor traps to EL3

*/

Quoted 15 lines
arch/arm/include/asm/macro.h +3 -5
-	mov	\xreg1, #0x33ff
-	msr	cptr_el2, \xreg1	/* Disable coprocessor traps to EL2 */
+	mov	\xreg5, #(CPTR_EL2_BIT13_12_RES1 | CPTR_EL2_BIT9_0_RES1)
+	msr	cptr_el2, \xreg5	/* Disable coprocessor traps to EL2 */
 
 	/* Initialize Generic Timers */
 	msr	cntvoff_el2, xzr
@@ -152,45 +160,92 @@ lr	.req	x30
 	 * and RES0 bits (31,30,27,26,24,21,20,17,15-13,10-6) +
 	 * EE,WXN,I,SA,C,A,M to 0
 	 */
-	mov	\xreg1, #0x0830
-	movk	\xreg1, #0x30C5, lsl #16
-	msr	sctlr_el2, \xreg1
+	ldr	\xreg5, =(SCTLR_EL2_BIT29_28_RES1 | SCTLR_EL2_EE_LE |\
Quoted 8 lines

arch/arm/include/asm/macro.h lr .req x30 · line 168

Quoted 5 lines
arch/arm/include/asm/macro.h +5 -0
+			  SCTLR_EL2_BIT23_22_RES1 | SCTLR_EL2_WXN_DIS |\
+			  SCTLR_EL2_BIT18_RES1 | SCTLR_EL2_BIT16_RES1 |\
+			  SCTLR_EL2_BIT11_RES1 | SCTLR_EL2_BIT5_4_RES1 |\
+			  SCTLR_EL2_SA_DIS | SCTLR_EL2_DCACHE_DIS |\
+			  SCTLR_EL2_ALIGN_DIS | SCTLR_EL2_MMU_DIS)

Do you think you could just define something like SCTLR_EL2_RES1 in the header file that combines all RES1 fields already?

[Alison Wang] Ok, I think so.

Quoted 14 lines

arch/arm/include/asm/macro.h lr .req x30 · line 178

Quoted 11 lines
arch/arm/include/asm/macro.h +10 -0
+	msr	sctlr_el2, \xreg5
+
+	mov	\xreg5, sp
+	msr	sp_el2, \xreg5		/* Migrate SP */
+	mrs	\xreg5, vbar_el3
+	msr	vbar_el2, \xreg5	/* Migrate VBAR */
+
+	/* Check switch to AArch64 EL2 or AArch32 Hypervisor mode */
+	ldr	\xreg5, =ES_TO_AARCH32
+	cmp	\flag, \xreg5

This can be an immediate cmp, no?

Quoted 1 line

cmp \flag, #ES_TO_AARCH32

[Alison Wang] Yes, it can. Will change in the next version.

Quoted 12 lines

arch/arm/include/asm/macro.h lr .req x30 · line 187

Quoted 10 lines
arch/arm/include/asm/macro.h +9 -0
+	b.eq	1f
+
+	/*
+	 * The next lower exception level is AArch64, 64bit EL2 | HCE |
+	 * SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1.
+	 */
+	ldr	\xreg5, =(SCR_EL3_RW_AARCH64 | SCR_EL3_HCE_EN |\
+			  SCR_EL3_SMD_DIS | SCR_EL3_BIT5_4_RES1 |\
+			  SCR_EL3_NS_EN)

Same here - just define a single mask for SCR_EL3_RES1.

[Alison Wang] Ok.

Quoted 39 lines
Quoted 39 lines
arch/arm/include/asm/macro.h +26 -6
+	msr	scr_el3, \xreg5
 
 	/* Return to the EL2_SP2 mode from EL3 */
-	mov	\xreg1, sp
-	msr	sp_el2, \xreg1		/* Migrate SP */
-	mrs	\xreg1, vbar_el3
-	msr	vbar_el2, \xreg1	/* Migrate VBAR */
-	mov	\xreg1, #0x3c9
-	msr	spsr_el3, \xreg1	/* EL2_SP2 | D | A | I | F */
+	ldr	\xreg5, =(SPSR_EL_DEBUG_MASK | SPSR_EL_SERR_MASK |\
+			  SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\
+			  SPSR_EL_M_AARCH64 | SPSR_EL_M_EL2H)
+	msr	spsr_el3, \xreg5
 	msr	elr_el3, lr
 	eret
+
+1:
+	/*
+	 * The next lower exception level is AArch32, 32bit EL2 | HCE |
+	 * SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1.
+	 */
+	ldr	\xreg5, =(SCR_EL3_RW_AARCH32 | SCR_EL3_HCE_EN |\
+			  SCR_EL3_SMD_DIS | SCR_EL3_BIT5_4_RES1 |\
+			  SCR_EL3_NS_EN)
+	msr	scr_el3, \xreg5
+
+	/* Return to AArch32 Hypervisor mode */
+	ldr     \xreg5, =(SPSR_EL_END_LE | SPSR_EL_ASYN_MASK |\
+			  SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\
+			  SPSR_EL_T_A32 | SPSR_EL_M_AARCH32 |\
+			  SPSR_EL_M_HYP)
+	msr	spsr_el3, \xreg5
+	msr     elr_el3, \ep
+
+	mov	\ep, #0
+	eret
 .endm
 
Quoted 12 lines

arch/arm/include/asm/macro.h lr .req x30 · line 228

Quoted 10 lines
arch/arm/include/asm/macro.h +9 -1
-.macro armv8_switch_to_el1_m, xreg1, xreg2
+/*
+ * Switch from EL2 to EL1 for ARMv8
+ * @ep:     kernel entry point
+ * @arch:   machine nr
+ * @ftaddr: fdt address
+ * @flag:   The execution state flag for lower exception
+ *          level, ES_TO_AARCH64 or ES_TO_AARCH32
+ */
+.macro armv8_switch_to_el1_m, ep, arch, ftaddr, flag, xreg5

All the comments to the function above apply here too :).

[Alison Wang] Ok.

Quoted 54 lines
Quoted 18 lines
arch/arm/include/asm/macro.h +6 -7
 	/* Initialize Generic Timers */
-	mrs	\xreg1, cnthctl_el2
-	orr	\xreg1, \xreg1, #0x3	/* Enable EL1 access to timers */
-	msr	cnthctl_el2, \xreg1
+	mrs	\xreg5, cnthctl_el2
+	/* Enable EL1 access to timers */
+	orr	\xreg5, \xreg5, #(CNTHCTL_EL2_EL1PCEN_EN |\
+		CNTHCTL_EL2_EL1PCTEN_EN)
+	msr	cnthctl_el2, \xreg5
 	msr	cntvoff_el2, xzr
 
 	/* Initilize MPID/MPIDR registers */
-	mrs	\xreg1, midr_el1
-	mrs	\xreg2, mpidr_el1
-	msr	vpidr_el2, \xreg1
-	msr	vmpidr_el2, \xreg2
+	mrs	\xreg5, midr_el1

arch/arm/include/asm/macro.h lr .req x30

Quoted 10 lines
arch/arm/include/asm/macro.h +5 -2
+	msr	vpidr_el2, \xreg5
+	mrs	\xreg5, mpidr_el1
+	msr	vmpidr_el2, \xreg5
 
 	/* Disable coprocessor traps */
-	mov	\xreg1, #0x33ff
-	msr	cptr_el2, \xreg1	/* Disable coprocessor traps to EL2 */
+	mov	\xreg5, #(CPTR_EL2_BIT13_12_RES1 | CPTR_EL2_BIT9_0_RES1)
+	msr	cptr_el2, \xreg5	/* Disable coprocessor traps to EL2 */
 	msr	hstr_el2, xzr		/* Disable coprocessor traps to EL2

*/

Quoted 25 lines
arch/arm/include/asm/macro.h +8 -10
-	mov	\xreg1, #3 << 20
-	msr	cpacr_el1, \xreg1	/* Enable FP/SIMD at EL1 */
-
-	/* Initialize HCR_EL2 */
-	mov	\xreg1, #(1 << 31)		/* 64bit EL1 */
-	orr	\xreg1, \xreg1, #(1 << 29)	/* Disable HVC */
-	msr	hcr_el2, \xreg1
+	mov	\xreg5, #(CPACR_EL1_FPEN_EN)
+	msr	cpacr_el1, \xreg5	/* Enable FP/SIMD at EL1 */
 
 	/* SCTLR_EL1 initialization
 	 *
@@ -199,19 +254,56 @@ lr	.req	x30
 	 * UCI,EE,EOE,WXN,nTWE,nTWI,UCT,DZE,I,UMA,SED,ITD,
 	 * CP15BEN,SA0,SA,C,A,M to 0
 	 */
-	mov	\xreg1, #0x0800
-	movk	\xreg1, #0x30d0, lsl #16
-	msr	sctlr_el1, \xreg1
+	ldr	\xreg5, =(SCTLR_EL1_BIT29_28_RES1 | SCTLR_EL1_UCI_DIS |\
+			  SCTLR_EL1_EE_LE | SCTLR_EL1_BIT23_22_RES1 |\
+			  SCTLR_EL1_BIT20_RES1 | SCTLR_EL1_WXN_DIS |\
+			  SCTLR_EL1_NTWE_DIS | SCTLR_EL1_NTWI_DIS |\
+			  SCTLR_EL1_UCT_DIS | SCTLR_EL1_DZE_DIS |\
+			  SCTLR_EL1_ICACHE_DIS | SCTLR_EL1_BIT11_RES1 |\
Quoted 8 lines

arch/arm/include/asm/macro.h lr .req x30 · line 267

Quoted 5 lines
arch/arm/include/asm/macro.h +5 -0
+			  SCTLR_EL1_UMA_DIS | SCTLR_EL1_SED_EN |\
+			  SCTLR_EL1_ITD_EN | SCTLR_EL1_CP15BEN_DIS |\
+			  SCTLR_EL1_SA0_DIS | SCTLR_EL1_SA_DIS |\
+			  SCTLR_EL1_DCACHE_DIS | SCTLR_EL1_ALIGN_DIS |\
+			  SCTLR_EL1_MMU_DIS)

Why are the caches getting disabled? Or did you just convert the old value to the define list?

[Alison Wang] Yes, I just convert the old value to the define list.

Quoted 308 lines
Quoted 54 lines
arch/arm/include/asm/macro.h +35 -6
+	msr	sctlr_el1, \xreg5
+
+	mov	\xreg5, sp
+	msr	sp_el1, \xreg5		/* Migrate SP */
+	mrs	\xreg5, vbar_el2
+	msr	vbar_el1, \xreg5	/* Migrate VBAR */
+
+	/* Check switch to AArch64 EL1 or AArch32 Supervisor mode */
+	ldr	\xreg5, =ES_TO_AARCH32
+	cmp	\flag, \xreg5
+	b.eq	1f
+
+	/* Initialize HCR_EL2 */
+	ldr	\xreg5, =(HCR_EL2_RW_AARCH64 | HCR_EL2_HCD_DIS)
+	msr	hcr_el2, \xreg5
 
 	/* Return to the EL1_SP1 mode from EL2 */
-	mov	\xreg1, sp
-	msr	sp_el1, \xreg1		/* Migrate SP */
-	mrs	\xreg1, vbar_el2
-	msr	vbar_el1, \xreg1	/* Migrate VBAR */
-	mov	\xreg1, #0x3c5
-	msr	spsr_el2, \xreg1	/* EL1_SP1 | D | A | I | F */
+	ldr	\xreg5, =(SPSR_EL_DEBUG_MASK | SPSR_EL_SERR_MASK |\
+			  SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\
+			  SPSR_EL_M_AARCH64 | SPSR_EL_M_EL1H)
+	msr	spsr_el2, \xreg5
 	msr	elr_el2, lr
 	eret
+
+1:
+	/* Initialize HCR_EL2 */
+	ldr	\xreg5, =(HCR_EL2_RW_AARCH32 | HCR_EL2_HCD_DIS)
+	msr	hcr_el2, \xreg5
+
+	/* Return to AArch32 Supervisor mode from EL2 */
+	ldr	\xreg5, =(SPSR_EL_END_LE | SPSR_EL_ASYN_MASK |\
+			  SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\
+			  SPSR_EL_T_A32 | SPSR_EL_M_AARCH32 |\
+			  SPSR_EL_M_SVC)
+	msr     spsr_el2, \xreg5
+	msr     elr_el2, \ep
+
+	mov	\ep, #0
+	eret
 .endm
 
 #if defined(CONFIG_GICV3)
(quoted diff) +0 -0

b/arch/arm/include/asm/system.h index 9ae890a..0271ddb 100644

arch/arm/include/asm/system.h line 26

Quoted 10 lines
arch/arm/include/asm/system.h +7 -0
@@ -17,6 +17,102 @@
 #define CR_WXN		(1 << 19)	/* Write Permision Imply XN	*/
 #define CR_EE		(1 << 25)	/* Exception (Big) Endian	*/
 
+#define ES_TO_AARCH64		1
+#define ES_TO_AARCH32		0
+
+/*
+ * SCR_EL3 bits definitions
+ */
+#define SCR_EL3_RW_AARCH64	(1 << 10) /* Next lower level is AArch64

*/

arch/arm/include/asm/system.h line 27

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCR_EL3_RW_AARCH32	(0 << 10) /* Lower lowers level are

AArch32 */

arch/arm/include/asm/system.h line 28

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCR_EL3_HCE_EN		(1 << 8)  /* Hypervisor Call enable

*/

arch/arm/include/asm/system.h line 29

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCR_EL3_SMD_DIS		(1 << 7)  /* Secure Monitor Call

disable */

arch/arm/include/asm/system.h line 30

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCR_EL3_BIT5_4_RES1	(3 << 4)  /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 31

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCR_EL3_NS_EN		(1 << 0)  /* EL0 and EL1 in Non-scure

state */

arch/arm/include/asm/system.h line 35

Quoted 4 lines
arch/arm/include/asm/system.h +4 -0
+
+/*
+ * SPSR_EL3/SPSR_EL2 bits definitions  */
+#define SPSR_EL_END_LE		(0 << 9)  /* Exception Little-endian

*/

arch/arm/include/asm/system.h line 36

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_DEBUG_MASK	(1 << 9)  /* Debug exception masked

*/

arch/arm/include/asm/system.h line 37

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_ASYN_MASK	(1 << 8)  /* Asynchronous data abort

masked */

arch/arm/include/asm/system.h line 38

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_SERR_MASK	(1 << 8)  /* System Error exception masked

*/

arch/arm/include/asm/system.h line 39

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_IRQ_MASK	(1 << 7)  /* IRQ exception masked

*/

arch/arm/include/asm/system.h line 40

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_FIQ_MASK	(1 << 6)  /* FIQ exception masked

*/

arch/arm/include/asm/system.h line 41

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_T_A32		(0 << 5)  /* AArch32 instruction set A32

*/

arch/arm/include/asm/system.h line 42

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_AARCH64	(0 << 4)  /* Exception taken from AArch64

*/

arch/arm/include/asm/system.h line 43

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_AARCH32	(1 << 4)  /* Exception taken from AArch32

*/

arch/arm/include/asm/system.h line 44

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_SVC		(0x3)     /* Exception taken from SVC mode

*/

arch/arm/include/asm/system.h line 45

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_HYP		(0xa)     /* Exception taken from HYP mode

*/

arch/arm/include/asm/system.h line 46

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_EL1H		(5)       /* Exception taken from

EL1h mode */

arch/arm/include/asm/system.h line 47

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_EL2H		(9)       /* Exception taken from

EL2h mode */

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * CPTR_EL2 bits definitions
+ */
+#define CPTR_EL2_BIT13_12_RES1	(3 << 12) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 53

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define CPTR_EL2_BIT9_0_RES1	(0x3ff)   /* Reserved, RES1

*/

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * SCTLR_EL2 bits definitions
+ */
+#define SCTLR_EL2_BIT29_28_RES1	(3 << 28) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 59

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_EE_LE		(0 << 25) /* Exception Little-endian

*/

arch/arm/include/asm/system.h line 60

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_BIT23_22_RES1	(3 << 22) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 61

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_WXN_DIS	(0 << 19) /* Write permission is not XN

*/

arch/arm/include/asm/system.h line 62

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_BIT18_RES1	(1 << 18) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 63

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_BIT16_RES1	(1 << 16) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 64

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_ICACHE_DIS	(0 << 12) /* Instruction cache

disabled */

arch/arm/include/asm/system.h line 65

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_BIT11_RES1	(1 << 11) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 66

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_BIT5_4_RES1	(3 << 4)  /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 67

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_SA_DIS	(0 << 3)  /* Stack Alignment Check

disabled */

arch/arm/include/asm/system.h line 68

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_DCACHE_DIS	(0 << 2)  /* Data cache disabled

*/

arch/arm/include/asm/system.h line 69

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_ALIGN_DIS	(0 << 1)  /* Alignment check disabled

*/

arch/arm/include/asm/system.h line 70

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_MMU_DIS	(0)       /* MMU disabled

*/

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * CNTHCTL_EL2 bits definitions
+ */
+#define CNTHCTL_EL2_EL1PCEN_EN	(1 << 1)  /* Physical timer regs

accessible */

arch/arm/include/asm/system.h line 76

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define CNTHCTL_EL2_EL1PCTEN_EN	(1 << 0)  /* Physical counter

accessible */

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * HCR_EL2 bits definitions
+ */
+#define HCR_EL2_RW_AARCH64	(1 << 31) /* EL1 is AArch64

*/

arch/arm/include/asm/system.h line 82

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define HCR_EL2_RW_AARCH32	(0 << 31) /* Lower levels are AArch32

*/

arch/arm/include/asm/system.h line 83

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define HCR_EL2_HCD_DIS		(1 << 29) /* Hypervisor Call

disabled */

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * CPACR_EL1 bits definitions
+ */
+#define CPACR_EL1_FPEN_EN	(3 << 20) /* SIMD and FP instruction

enabled */

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * SCTLR_EL1 bits definitions
+ */
+#define SCTLR_EL1_BIT29_28_RES1	(3 << 28) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 94

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_UCI_DIS	(0 << 26) /* Cache instruction disabled

*/

arch/arm/include/asm/system.h line 95

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_EE_LE		(0 << 25) /* Exception Little-endian

*/

arch/arm/include/asm/system.h line 96

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_BIT23_22_RES1	(3 << 22) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 97

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_BIT20_RES1	(1 << 20) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 98

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_WXN_DIS	(0 << 19) /* Write permission is not XN

*/

arch/arm/include/asm/system.h line 99

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_NTWE_DIS	(0 << 18) /* WFE instruction disabled

*/

arch/arm/include/asm/system.h line 100

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_NTWI_DIS	(0 << 16) /* WFI instruction disabled

*/

arch/arm/include/asm/system.h line 101

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_UCT_DIS	(0 << 15) /* CTR_EL0 access disabled

*/

arch/arm/include/asm/system.h line 102

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_DZE_DIS	(0 << 14) /* DC ZVA instruction disabled

*/

arch/arm/include/asm/system.h line 103

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_ICACHE_DIS	(0 << 12) /* Instruction cache

disabled */

arch/arm/include/asm/system.h line 104

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_BIT11_RES1	(1 << 11) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 105

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_UMA_DIS	(0 << 9)  /* User Mask Access disabled

*/

arch/arm/include/asm/system.h line 106

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_SED_EN	(0 << 8)  /* SETEND instruction enabled

*/

arch/arm/include/asm/system.h line 107

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_ITD_EN	(0 << 7)  /* IT instruction enabled

*/

arch/arm/include/asm/system.h line 108

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_CP15BEN_DIS	(0 << 5)  /* CP15 barrier operation

disabled */

arch/arm/include/asm/system.h line 109

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_SA0_DIS	(0 << 4)  /* Stack Alignment EL0 disabled

*/

arch/arm/include/asm/system.h line 110

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_SA_DIS	(0 << 3)  /* Stack Alignment EL1 disabled

*/

arch/arm/include/asm/system.h line 111

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_DCACHE_DIS	(0 << 2)  /* Data cache disabled

*/

arch/arm/include/asm/system.h line 112

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_ALIGN_DIS	(0 << 1)  /* Alignment check disabled

*/

arch/arm/include/asm/system.h line 113

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_MMU_DIS	(0)       /* MMU disabled

*/

arch/arm/lib/bootm.c static void boot_jump_linux(bootm_headers_t

Quoted 60 lines
arch/arm/include/asm/system.h +21 -2
+
 #ifndef __ASSEMBLY__
 
 u64 get_page_table_size(void);
@@ -100,8 +196,26 @@ void __asm_invalidate_icache_all(void);
 int __asm_flush_l3_cache(void);
 void __asm_switch_ttbr(u64 new_ttbr);
 
-void armv8_switch_to_el2(void);
-void armv8_switch_to_el1(void);
+/*
+ * Switch from EL3 to EL2 for ARMv8
+ *
+ * @entry_point: kernel entry point
+ * @mach_nr:     machine nr
+ * @fdt_addr:    fdt address
+ * @es_flag:     execution state flag, ES_TO_AARCH64 or ES_TO_AARCH32
+ */
+void armv8_switch_to_el2(u64 entry_point, u64 mach_nr, u64 fdt_addr,
+			 u64 es_flag);
+/*
+ * Switch from EL2 to EL1 for ARMv8
+ *
+ * @entry_point: kernel entry point
+ * @mach_nr:     machine nr
+ * @fdt_addr:    fdt address
+ * @es_flag:     execution state flag, ES_TO_AARCH64 or ES_TO_AARCH32
+ */
+void armv8_switch_to_el1(u64 entry_point, u64 mach_nr, u64 fdt_addr,
+			 u64 es_flag);
 void gic_init(void);
 void gic_send_sgi(unsigned long sgino);  void wait_for_wakeup(void);
arch/arm/lib/bootm.c index renamed from arch/arm/lib/bootm.c +0 -0

0838d89..1bbf85c 100644

arch/arm/lib/bootm.c +9 -3
@@ -189,13 +189,19 @@ static void setup_end_tag(bd_t *bd)  __weak void
 setup_board_tags(struct tag **in_params) {}
 
 #ifdef CONFIG_ARM64
-static void do_nonsec_virt_switch(void)
+static void do_nonsec_virt_switch(bootm_headers_t *images, int flag)
 {
 	smp_kick_all_cpus();
 	dcache_disable();	/* flush cache before swtiching to EL2 */
-	armv8_switch_to_el2();
+
 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
-	armv8_switch_to_el1();
+	armv8_switch_to_el2((u64)images->ep, (u64)gd->bd->bi_arch_number,
+			    (u64)images->ft_addr, ES_TO_AARCH64);
+	armv8_switch_to_el1((u64)images->ep, (u64)gd->bd->bi_arch_number,
+			    (u64)images->ft_addr, flag);
+#else
+	armv8_switch_to_el2((u64)images->ep, (u64)gd->bd->bi_arch_number,
+			    (u64)images->ft_addr, flag);
 #endif
 }
 #endif
@@ -275,6 +281,7 @@ static void boot_jump_linux(bootm_headers_t

*images, int flag)

arch/arm/lib/bootm.c static void boot_jump_linux(bootm_headers_t

Quoted 8 lines
arch/arm/lib/bootm.c +1 -0
 	void (*kernel_entry)(void *fdt_addr, void *res0, void *res1,
 			void *res2);
 	int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
+	int es_flag = ES_TO_AARCH64;
 
 	kernel_entry = (void (*)(void *fdt_addr, void *res0, void *res1,
 				void *res2))images->ep;
@@ -286,7 +293,11 @@ static void boot_jump_linux(bootm_headers_t

*images, int flag)

common/image-fit.c int fit_image_check_arch(const void *fit, int

Quoted 25 lines
arch/arm/lib/bootm.c +5 -1
 	announce_and_cleanup(fake);
 
 	if (!fake) {
-		do_nonsec_virt_switch();
+		if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
+		    (images->os.arch == IH_ARCH_ARM))
+			es_flag = ES_TO_AARCH32;
+
+		do_nonsec_virt_switch(images, es_flag);
 		kernel_entry(images->ft_addr, NULL, NULL, NULL);
 	}
 #else
common/image-fit.c index renamed from common/image-fit.c +0 -0

9873957..982021b 100644

common/image-fit.c +1 -0
@@ -26,6 +26,7 @@ DECLARE_GLOBAL_DATA_PTR;  #include <u-boot/md5.h>
 #include <u-boot/sha1.h>  #include <u-boot/sha256.h>
+#include <generated/autoconf.h>
 
 
 /*********************************************************************
 ********/
 /* New uImage format routines */
@@ -1164,7 +1165,9 @@ int fit_image_check_arch(const void *fit, int

noffset, uint8_t arch)

Quoted 10 lines

common/image-fit.c int fit_image_check_arch(const void *fit, int noffset, uint8_t arch) · line 1170

Quoted 7 lines
common/image-fit.c +3 -1
 	if (fit_image_get_arch(fit, noffset, &image_arch))
 		return 0;
 	return (arch == image_arch) ||
-		(arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64);
+		(arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64) ||
+		(arch == IH_ARCH_ARM64 && image_arch == IH_ARCH_ARM &&
+		 CONFIG_ARM64_SUPPORT_AARCH32);

Uh, I think this define is simply not defined for non-compatible systems (including non-arm64). This really needs to go into an #ifdef.

[Alison Wang] I think arch == IH_ARCH_ARM64 will check for non-arm64 system. I can't understand your concern. Please explain more.

Quoted 4 lines

Thanks a lot for all the refactoring work :). This patch already reads much nicer than the original code. I guess with next round we'll get this into really good shape.

[Alison Wang] I hope so. Thank you very much for your suggestions. :)

Quoted 33 lines

Alex

common/image-fit.c int fit_image_load(bootm_headers_t *images,

Quoted 4 lines
common/image-fit.c +0 -0
 }
 
 /**
@@ -1593,6 +1596,9 @@ int fit_image_load(bootm_headers_t *images,

ulong addr,

common/image-fit.c int fit_image_load(bootm_headers_t *images,

Quoted 10 lines
common/image-fit.c +3 -0
 	int type_ok, os_ok;
 	ulong load, data, len;
 	uint8_t os;
+#ifndef USE_HOSTCC
+	uint8_t os_arch;
+#endif
 	const char *prop_name;
 	int ret;
 
@@ -1676,6 +1682,12 @@ int fit_image_load(bootm_headers_t *images,

ulong addr,

Quoted 13 lines
common/image-fit.c +6 -0
 		return -ENOEXEC;
 	}
 #endif
+
+#ifndef USE_HOSTCC
+	fit_image_get_arch(fit, noffset, &os_arch);
+	images->os.arch = os_arch;
+#endif
+
 	if (image_type == IH_TYPE_FLATDT &&
 	    !fit_image_check_comp(fit, noffset, IH_COMP_NONE)) {
 		puts("FDT image is compressed");
#6 lore raw

PATCH v3 1/2 armv8: Support loading 32-bit OS in AArch32 execution state

Quoted 120 lines · Huan Wang
Quoted 52 lines · Alison Wang
Quoted 9 lines

To support loading a 32-bit OS, the execution state will change from AArch64 to AArch32 when jumping to kernel.

The architecture information will be got through checking FIT image, then U-Boot will load 32-bit OS or 64-bit OS automatically.

Quoted 8 lines

---
Changes in v3:
- Comments the functions and the arguments.
- Rename the real parameters.
- Use the macros instead of the magic values.
- Remove the redundant codes.
- Clean up all of the mess in boot_jump_linux().
- Add CONFIG_ARM64_SUPPORT_AARCH32 to detect for some ARM64 system

doesn't support AArch32 state.

Quoted 3 lines

Changes in v2:
- armv8_switch_to_el2_aarch32() is removed. armv8_switch_to_el2_m is

used

Quoted 2 lines

to switch to AArch64 EL2 or AArch32 Hyp.
- armv8_switch_to_el1_aarch32() is removed. armv8_switch_to_el1_m is

used

Quoted 5 lines

to switch to AArch64 EL1 or AArch32 SVC.

 arch/arm/Kconfig                |   6 ++
 arch/arm/cpu/armv8/transition.S |   8 +-
 arch/arm/include/asm/macro.h    | 174 ++++++++++++++++++++++++++++++-

---------

Quoted 10 lines
 arch/arm/include/asm/system.h   | 118 ++++++++++++++++++++++++++-
 arch/arm/lib/bootm.c            |  19 ++++-
 common/image-fit.c              |  14 +++-
 6 files changed, 287 insertions(+), 52 deletions(-)
arch/arm/Kconfig index renamed from arch/arm/Kconfig +0 -0

729b181..794cb4f 100644

arch/arm/Kconfig config SYS_L2CACHE_OFF · line 82

Quoted 6 lines
arch/arm/Kconfig +3 -0
@@ -77,6 +77,12 @@ config SYS_L2CACHE_OFF
 	  If SoC does not support L2CACHE or one do not want to enable
 	  L2CACHE, choose this option.
 
+config ARM64_SUPPORT_AARCH32
+	bool "ARM64 system support AArch32 execution state"
+	default y if ARM64 && !CONFIG_THUNDERX

I don't think that works. In Kconfig you need to omit the CONFIG_ parts. It's "ARM64" also, not "CONFIG_ARM64".

Quoted 2 lines

Please just try to run a local make defconfig on the thunderx reference system and see whether it includes the option or not.

[Alison Wang] Yes, I missed it. Will change in the next version.

Quoted 50 lines
Quoted 44 lines
arch/arm/Kconfig +3 -0
+	help
+	  This ARM64 system supports AArch32 execution state.
+
 choice
 	prompt "Target select"
 	default TARGET_HIKEY
(quoted diff) +0 -0

b/arch/arm/cpu/armv8/transition.S index 253a39b..417e8b4 100644

arch/arm/cpu/armv8/transition.S +4 -4
@@ -11,13 +11,13 @@
 #include <asm/macro.h>
 
 ENTRY(armv8_switch_to_el2)
-	switch_el x0, 1f, 0f, 0f
+	switch_el x4, 1f, 0f, 0f
 0:	ret
-1:	armv8_switch_to_el2_m x0
+1:	armv8_switch_to_el2_m x0, x1, x2, x3, x4
 ENDPROC(armv8_switch_to_el2)
 
 ENTRY(armv8_switch_to_el1)
-	switch_el x0, 0f, 1f, 0f
+	switch_el x4, 0f, 1f, 0f
 0:	ret
-1:	armv8_switch_to_el1_m x0, x1
+1:	armv8_switch_to_el1_m x0, x1, x2, x3, x4
 ENDPROC(armv8_switch_to_el1)
(quoted diff) +0 -0

b/arch/arm/include/asm/macro.h index 9bb0efa..dd2c510 100644

arch/arm/include/asm/macro.h +3 -0
@@ -8,6 +8,9 @@
 
 #ifndef __ASM_ARM_MACRO_H__
 #define __ASM_ARM_MACRO_H__
+
+#include <asm/system.h>
+
 #ifdef __ASSEMBLY__
 
 /*

arch/arm/include/asm/macro.h lr .req x30 · line 139

Quoted 5 lines
arch/arm/include/asm/macro.h +0 -2
@@ -135,13 +138,18 @@ lr	.req	x30
 #endif
 .endm
 
-.macro armv8_switch_to_el2_m, xreg1
-	/* 64bit EL2 | HCE | SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1

*/

Quoted 15 lines

arch/arm/include/asm/macro.h lr .req x30 · line 149

Quoted 11 lines
arch/arm/include/asm/macro.h +9 -2
-	mov	\xreg1, #0x5b1
-	msr	scr_el3, \xreg1
+/*
+ * Switch from EL3 to EL2 for ARMv8
+ * @ep:     kernel entry point
+ * @arch:   machine nr
+ * @ftaddr: fdt address
+ * @flag:   The execution state flag for lower exception
+ *          level, ES_TO_AARCH64 or ES_TO_AARCH32
+ */
+.macro armv8_switch_to_el2_m, ep, arch, ftaddr, flag, xreg5

You're never really using the arch and ftaddr arguments. Just describe in the macro header that they need to be in x1 and x2 respectively and leave them out of the argument list for the macro.

Quoted 1 line

[Alison Wang] Do you mean rename arch and ftaddr to x1 and x2 here?

I mean omit arch and ftaddr from the macro arguments and instead mention that x1 and x2 get passed as x1 and x2 to the guest and are usually "ftaddr" and "arch".

Also it would make the code more consistent to always use ep.

+/*
+ * Switch from EL3 to EL2 for ARMv8 and jump to @ep.
+ *
+ * @flag: The execution state flag for lower exception
+ * level, ES_TO_AARCH64 or ES_TO_AARCH32
+ *
+ * When flag == ES_TO_AARCH32:

+ * @ep:     location to jump to in AArch32 EL2 mode
+ * x1:      "Machine ID" for Linux payloads
+ * x2:      "DT Address" for Linux payloads

+ *
+ * When flag == ES_TO_AARCH64:
+ * @ep: location to jump to in AArch64 EL2 mode
+ * x1: "DT Address" for Linux payloads
+ */
+.macro armv8_switch_to_el2_m, ep, flag, tmpreg

Quoted 493 lines
Quoted 3 lines

Also please rename "xreg5" to something like "scratchreg" or "tmp" or "tmpreg". Then it's more obvious what this argument is about.

[Alison Wang] Ok.

Quoted 18 lines

arch/arm/include/asm/macro.h lr .req x30 · line 150

Quoted 2 lines
arch/arm/include/asm/macro.h +0 -0
 	msr	cptr_el3, xzr		/* Disable coprocessor traps to EL3

*/

Quoted 15 lines
arch/arm/include/asm/macro.h +3 -5
-	mov	\xreg1, #0x33ff
-	msr	cptr_el2, \xreg1	/* Disable coprocessor traps to EL2 */
+	mov	\xreg5, #(CPTR_EL2_BIT13_12_RES1 | CPTR_EL2_BIT9_0_RES1)
+	msr	cptr_el2, \xreg5	/* Disable coprocessor traps to EL2 */
 
 	/* Initialize Generic Timers */
 	msr	cntvoff_el2, xzr
@@ -152,45 +160,92 @@ lr	.req	x30
 	 * and RES0 bits (31,30,27,26,24,21,20,17,15-13,10-6) +
 	 * EE,WXN,I,SA,C,A,M to 0
 	 */
-	mov	\xreg1, #0x0830
-	movk	\xreg1, #0x30C5, lsl #16
-	msr	sctlr_el2, \xreg1
+	ldr	\xreg5, =(SCTLR_EL2_BIT29_28_RES1 | SCTLR_EL2_EE_LE |\
Quoted 8 lines

arch/arm/include/asm/macro.h lr .req x30 · line 168

Quoted 5 lines
arch/arm/include/asm/macro.h +5 -0
+			  SCTLR_EL2_BIT23_22_RES1 | SCTLR_EL2_WXN_DIS |\
+			  SCTLR_EL2_BIT18_RES1 | SCTLR_EL2_BIT16_RES1 |\
+			  SCTLR_EL2_BIT11_RES1 | SCTLR_EL2_BIT5_4_RES1 |\
+			  SCTLR_EL2_SA_DIS | SCTLR_EL2_DCACHE_DIS |\
+			  SCTLR_EL2_ALIGN_DIS | SCTLR_EL2_MMU_DIS)

Do you think you could just define something like SCTLR_EL2_RES1 in the header file that combines all RES1 fields already?

[Alison Wang] Ok, I think so.

Quoted 14 lines

arch/arm/include/asm/macro.h lr .req x30 · line 178

Quoted 11 lines
arch/arm/include/asm/macro.h +10 -0
+	msr	sctlr_el2, \xreg5
+
+	mov	\xreg5, sp
+	msr	sp_el2, \xreg5		/* Migrate SP */
+	mrs	\xreg5, vbar_el3
+	msr	vbar_el2, \xreg5	/* Migrate VBAR */
+
+	/* Check switch to AArch64 EL2 or AArch32 Hypervisor mode */
+	ldr	\xreg5, =ES_TO_AARCH32
+	cmp	\flag, \xreg5

This can be an immediate cmp, no?

Quoted 1 line

cmp \flag, #ES_TO_AARCH32

[Alison Wang] Yes, it can. Will change in the next version.

Quoted 12 lines

arch/arm/include/asm/macro.h lr .req x30 · line 187

Quoted 10 lines
arch/arm/include/asm/macro.h +9 -0
+	b.eq	1f
+
+	/*
+	 * The next lower exception level is AArch64, 64bit EL2 | HCE |
+	 * SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1.
+	 */
+	ldr	\xreg5, =(SCR_EL3_RW_AARCH64 | SCR_EL3_HCE_EN |\
+			  SCR_EL3_SMD_DIS | SCR_EL3_BIT5_4_RES1 |\
+			  SCR_EL3_NS_EN)

Same here - just define a single mask for SCR_EL3_RES1.

[Alison Wang] Ok.

Quoted 39 lines
Quoted 39 lines
arch/arm/include/asm/macro.h +26 -6
+	msr	scr_el3, \xreg5
 
 	/* Return to the EL2_SP2 mode from EL3 */
-	mov	\xreg1, sp
-	msr	sp_el2, \xreg1		/* Migrate SP */
-	mrs	\xreg1, vbar_el3
-	msr	vbar_el2, \xreg1	/* Migrate VBAR */
-	mov	\xreg1, #0x3c9
-	msr	spsr_el3, \xreg1	/* EL2_SP2 | D | A | I | F */
+	ldr	\xreg5, =(SPSR_EL_DEBUG_MASK | SPSR_EL_SERR_MASK |\
+			  SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\
+			  SPSR_EL_M_AARCH64 | SPSR_EL_M_EL2H)
+	msr	spsr_el3, \xreg5
 	msr	elr_el3, lr
 	eret
+
+1:
+	/*
+	 * The next lower exception level is AArch32, 32bit EL2 | HCE |
+	 * SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1.
+	 */
+	ldr	\xreg5, =(SCR_EL3_RW_AARCH32 | SCR_EL3_HCE_EN |\
+			  SCR_EL3_SMD_DIS | SCR_EL3_BIT5_4_RES1 |\
+			  SCR_EL3_NS_EN)
+	msr	scr_el3, \xreg5
+
+	/* Return to AArch32 Hypervisor mode */
+	ldr     \xreg5, =(SPSR_EL_END_LE | SPSR_EL_ASYN_MASK |\
+			  SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\
+			  SPSR_EL_T_A32 | SPSR_EL_M_AARCH32 |\
+			  SPSR_EL_M_HYP)
+	msr	spsr_el3, \xreg5
+	msr     elr_el3, \ep
+
+	mov	\ep, #0
+	eret
 .endm
 
Quoted 12 lines

arch/arm/include/asm/macro.h lr .req x30 · line 228

Quoted 10 lines
arch/arm/include/asm/macro.h +9 -1
-.macro armv8_switch_to_el1_m, xreg1, xreg2
+/*
+ * Switch from EL2 to EL1 for ARMv8
+ * @ep:     kernel entry point
+ * @arch:   machine nr
+ * @ftaddr: fdt address
+ * @flag:   The execution state flag for lower exception
+ *          level, ES_TO_AARCH64 or ES_TO_AARCH32
+ */
+.macro armv8_switch_to_el1_m, ep, arch, ftaddr, flag, xreg5

All the comments to the function above apply here too :).

[Alison Wang] Ok.

Quoted 54 lines
Quoted 18 lines
arch/arm/include/asm/macro.h +6 -7
 	/* Initialize Generic Timers */
-	mrs	\xreg1, cnthctl_el2
-	orr	\xreg1, \xreg1, #0x3	/* Enable EL1 access to timers */
-	msr	cnthctl_el2, \xreg1
+	mrs	\xreg5, cnthctl_el2
+	/* Enable EL1 access to timers */
+	orr	\xreg5, \xreg5, #(CNTHCTL_EL2_EL1PCEN_EN |\
+		CNTHCTL_EL2_EL1PCTEN_EN)
+	msr	cnthctl_el2, \xreg5
 	msr	cntvoff_el2, xzr
 
 	/* Initilize MPID/MPIDR registers */
-	mrs	\xreg1, midr_el1
-	mrs	\xreg2, mpidr_el1
-	msr	vpidr_el2, \xreg1
-	msr	vmpidr_el2, \xreg2
+	mrs	\xreg5, midr_el1

arch/arm/include/asm/macro.h lr .req x30

Quoted 10 lines
arch/arm/include/asm/macro.h +5 -2
+	msr	vpidr_el2, \xreg5
+	mrs	\xreg5, mpidr_el1
+	msr	vmpidr_el2, \xreg5
 
 	/* Disable coprocessor traps */
-	mov	\xreg1, #0x33ff
-	msr	cptr_el2, \xreg1	/* Disable coprocessor traps to EL2 */
+	mov	\xreg5, #(CPTR_EL2_BIT13_12_RES1 | CPTR_EL2_BIT9_0_RES1)
+	msr	cptr_el2, \xreg5	/* Disable coprocessor traps to EL2 */
 	msr	hstr_el2, xzr		/* Disable coprocessor traps to EL2

*/

Quoted 25 lines
arch/arm/include/asm/macro.h +8 -10
-	mov	\xreg1, #3 << 20
-	msr	cpacr_el1, \xreg1	/* Enable FP/SIMD at EL1 */
-
-	/* Initialize HCR_EL2 */
-	mov	\xreg1, #(1 << 31)		/* 64bit EL1 */
-	orr	\xreg1, \xreg1, #(1 << 29)	/* Disable HVC */
-	msr	hcr_el2, \xreg1
+	mov	\xreg5, #(CPACR_EL1_FPEN_EN)
+	msr	cpacr_el1, \xreg5	/* Enable FP/SIMD at EL1 */
 
 	/* SCTLR_EL1 initialization
 	 *
@@ -199,19 +254,56 @@ lr	.req	x30
 	 * UCI,EE,EOE,WXN,nTWE,nTWI,UCT,DZE,I,UMA,SED,ITD,
 	 * CP15BEN,SA0,SA,C,A,M to 0
 	 */
-	mov	\xreg1, #0x0800
-	movk	\xreg1, #0x30d0, lsl #16
-	msr	sctlr_el1, \xreg1
+	ldr	\xreg5, =(SCTLR_EL1_BIT29_28_RES1 | SCTLR_EL1_UCI_DIS |\
+			  SCTLR_EL1_EE_LE | SCTLR_EL1_BIT23_22_RES1 |\
+			  SCTLR_EL1_BIT20_RES1 | SCTLR_EL1_WXN_DIS |\
+			  SCTLR_EL1_NTWE_DIS | SCTLR_EL1_NTWI_DIS |\
+			  SCTLR_EL1_UCT_DIS | SCTLR_EL1_DZE_DIS |\
+			  SCTLR_EL1_ICACHE_DIS | SCTLR_EL1_BIT11_RES1 |\
Quoted 8 lines

arch/arm/include/asm/macro.h lr .req x30 · line 267

Quoted 5 lines
arch/arm/include/asm/macro.h +5 -0
+			  SCTLR_EL1_UMA_DIS | SCTLR_EL1_SED_EN |\
+			  SCTLR_EL1_ITD_EN | SCTLR_EL1_CP15BEN_DIS |\
+			  SCTLR_EL1_SA0_DIS | SCTLR_EL1_SA_DIS |\
+			  SCTLR_EL1_DCACHE_DIS | SCTLR_EL1_ALIGN_DIS |\
+			  SCTLR_EL1_MMU_DIS)

Why are the caches getting disabled? Or did you just convert the old value to the define list?

[Alison Wang] Yes, I just convert the old value to the define list.

Quoted 308 lines
Quoted 54 lines
arch/arm/include/asm/macro.h +35 -6
+	msr	sctlr_el1, \xreg5
+
+	mov	\xreg5, sp
+	msr	sp_el1, \xreg5		/* Migrate SP */
+	mrs	\xreg5, vbar_el2
+	msr	vbar_el1, \xreg5	/* Migrate VBAR */
+
+	/* Check switch to AArch64 EL1 or AArch32 Supervisor mode */
+	ldr	\xreg5, =ES_TO_AARCH32
+	cmp	\flag, \xreg5
+	b.eq	1f
+
+	/* Initialize HCR_EL2 */
+	ldr	\xreg5, =(HCR_EL2_RW_AARCH64 | HCR_EL2_HCD_DIS)
+	msr	hcr_el2, \xreg5
 
 	/* Return to the EL1_SP1 mode from EL2 */
-	mov	\xreg1, sp
-	msr	sp_el1, \xreg1		/* Migrate SP */
-	mrs	\xreg1, vbar_el2
-	msr	vbar_el1, \xreg1	/* Migrate VBAR */
-	mov	\xreg1, #0x3c5
-	msr	spsr_el2, \xreg1	/* EL1_SP1 | D | A | I | F */
+	ldr	\xreg5, =(SPSR_EL_DEBUG_MASK | SPSR_EL_SERR_MASK |\
+			  SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\
+			  SPSR_EL_M_AARCH64 | SPSR_EL_M_EL1H)
+	msr	spsr_el2, \xreg5
 	msr	elr_el2, lr
 	eret
+
+1:
+	/* Initialize HCR_EL2 */
+	ldr	\xreg5, =(HCR_EL2_RW_AARCH32 | HCR_EL2_HCD_DIS)
+	msr	hcr_el2, \xreg5
+
+	/* Return to AArch32 Supervisor mode from EL2 */
+	ldr	\xreg5, =(SPSR_EL_END_LE | SPSR_EL_ASYN_MASK |\
+			  SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\
+			  SPSR_EL_T_A32 | SPSR_EL_M_AARCH32 |\
+			  SPSR_EL_M_SVC)
+	msr     spsr_el2, \xreg5
+	msr     elr_el2, \ep
+
+	mov	\ep, #0
+	eret
 .endm
 
 #if defined(CONFIG_GICV3)
(quoted diff) +0 -0

b/arch/arm/include/asm/system.h index 9ae890a..0271ddb 100644

arch/arm/include/asm/system.h line 26

Quoted 10 lines
arch/arm/include/asm/system.h +7 -0
@@ -17,6 +17,102 @@
 #define CR_WXN		(1 << 19)	/* Write Permision Imply XN	*/
 #define CR_EE		(1 << 25)	/* Exception (Big) Endian	*/
 
+#define ES_TO_AARCH64		1
+#define ES_TO_AARCH32		0
+
+/*
+ * SCR_EL3 bits definitions
+ */
+#define SCR_EL3_RW_AARCH64	(1 << 10) /* Next lower level is AArch64

*/

arch/arm/include/asm/system.h line 27

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCR_EL3_RW_AARCH32	(0 << 10) /* Lower lowers level are

AArch32 */

arch/arm/include/asm/system.h line 28

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCR_EL3_HCE_EN		(1 << 8)  /* Hypervisor Call enable

*/

arch/arm/include/asm/system.h line 29

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCR_EL3_SMD_DIS		(1 << 7)  /* Secure Monitor Call

disable */

arch/arm/include/asm/system.h line 30

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCR_EL3_BIT5_4_RES1	(3 << 4)  /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 31

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCR_EL3_NS_EN		(1 << 0)  /* EL0 and EL1 in Non-scure

state */

arch/arm/include/asm/system.h line 35

Quoted 4 lines
arch/arm/include/asm/system.h +4 -0
+
+/*
+ * SPSR_EL3/SPSR_EL2 bits definitions  */
+#define SPSR_EL_END_LE		(0 << 9)  /* Exception Little-endian

*/

arch/arm/include/asm/system.h line 36

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_DEBUG_MASK	(1 << 9)  /* Debug exception masked

*/

arch/arm/include/asm/system.h line 37

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_ASYN_MASK	(1 << 8)  /* Asynchronous data abort

masked */

arch/arm/include/asm/system.h line 38

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_SERR_MASK	(1 << 8)  /* System Error exception masked

*/

arch/arm/include/asm/system.h line 39

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_IRQ_MASK	(1 << 7)  /* IRQ exception masked

*/

arch/arm/include/asm/system.h line 40

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_FIQ_MASK	(1 << 6)  /* FIQ exception masked

*/

arch/arm/include/asm/system.h line 41

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_T_A32		(0 << 5)  /* AArch32 instruction set A32

*/

arch/arm/include/asm/system.h line 42

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_AARCH64	(0 << 4)  /* Exception taken from AArch64

*/

arch/arm/include/asm/system.h line 43

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_AARCH32	(1 << 4)  /* Exception taken from AArch32

*/

arch/arm/include/asm/system.h line 44

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_SVC		(0x3)     /* Exception taken from SVC mode

*/

arch/arm/include/asm/system.h line 45

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_HYP		(0xa)     /* Exception taken from HYP mode

*/

arch/arm/include/asm/system.h line 46

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_EL1H		(5)       /* Exception taken from

EL1h mode */

arch/arm/include/asm/system.h line 47

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_EL2H		(9)       /* Exception taken from

EL2h mode */

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * CPTR_EL2 bits definitions
+ */
+#define CPTR_EL2_BIT13_12_RES1	(3 << 12) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 53

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define CPTR_EL2_BIT9_0_RES1	(0x3ff)   /* Reserved, RES1

*/

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * SCTLR_EL2 bits definitions
+ */
+#define SCTLR_EL2_BIT29_28_RES1	(3 << 28) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 59

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_EE_LE		(0 << 25) /* Exception Little-endian

*/

arch/arm/include/asm/system.h line 60

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_BIT23_22_RES1	(3 << 22) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 61

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_WXN_DIS	(0 << 19) /* Write permission is not XN

*/

arch/arm/include/asm/system.h line 62

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_BIT18_RES1	(1 << 18) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 63

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_BIT16_RES1	(1 << 16) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 64

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_ICACHE_DIS	(0 << 12) /* Instruction cache

disabled */

arch/arm/include/asm/system.h line 65

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_BIT11_RES1	(1 << 11) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 66

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_BIT5_4_RES1	(3 << 4)  /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 67

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_SA_DIS	(0 << 3)  /* Stack Alignment Check

disabled */

arch/arm/include/asm/system.h line 68

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_DCACHE_DIS	(0 << 2)  /* Data cache disabled

*/

arch/arm/include/asm/system.h line 69

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_ALIGN_DIS	(0 << 1)  /* Alignment check disabled

*/

arch/arm/include/asm/system.h line 70

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_MMU_DIS	(0)       /* MMU disabled

*/

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * CNTHCTL_EL2 bits definitions
+ */
+#define CNTHCTL_EL2_EL1PCEN_EN	(1 << 1)  /* Physical timer regs

accessible */

arch/arm/include/asm/system.h line 76

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define CNTHCTL_EL2_EL1PCTEN_EN	(1 << 0)  /* Physical counter

accessible */

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * HCR_EL2 bits definitions
+ */
+#define HCR_EL2_RW_AARCH64	(1 << 31) /* EL1 is AArch64

*/

arch/arm/include/asm/system.h line 82

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define HCR_EL2_RW_AARCH32	(0 << 31) /* Lower levels are AArch32

*/

arch/arm/include/asm/system.h line 83

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define HCR_EL2_HCD_DIS		(1 << 29) /* Hypervisor Call

disabled */

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * CPACR_EL1 bits definitions
+ */
+#define CPACR_EL1_FPEN_EN	(3 << 20) /* SIMD and FP instruction

enabled */

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * SCTLR_EL1 bits definitions
+ */
+#define SCTLR_EL1_BIT29_28_RES1	(3 << 28) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 94

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_UCI_DIS	(0 << 26) /* Cache instruction disabled

*/

arch/arm/include/asm/system.h line 95

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_EE_LE		(0 << 25) /* Exception Little-endian

*/

arch/arm/include/asm/system.h line 96

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_BIT23_22_RES1	(3 << 22) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 97

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_BIT20_RES1	(1 << 20) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 98

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_WXN_DIS	(0 << 19) /* Write permission is not XN

*/

arch/arm/include/asm/system.h line 99

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_NTWE_DIS	(0 << 18) /* WFE instruction disabled

*/

arch/arm/include/asm/system.h line 100

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_NTWI_DIS	(0 << 16) /* WFI instruction disabled

*/

arch/arm/include/asm/system.h line 101

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_UCT_DIS	(0 << 15) /* CTR_EL0 access disabled

*/

arch/arm/include/asm/system.h line 102

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_DZE_DIS	(0 << 14) /* DC ZVA instruction disabled

*/

arch/arm/include/asm/system.h line 103

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_ICACHE_DIS	(0 << 12) /* Instruction cache

disabled */

arch/arm/include/asm/system.h line 104

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_BIT11_RES1	(1 << 11) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 105

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_UMA_DIS	(0 << 9)  /* User Mask Access disabled

*/

arch/arm/include/asm/system.h line 106

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_SED_EN	(0 << 8)  /* SETEND instruction enabled

*/

arch/arm/include/asm/system.h line 107

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_ITD_EN	(0 << 7)  /* IT instruction enabled

*/

arch/arm/include/asm/system.h line 108

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_CP15BEN_DIS	(0 << 5)  /* CP15 barrier operation

disabled */

arch/arm/include/asm/system.h line 109

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_SA0_DIS	(0 << 4)  /* Stack Alignment EL0 disabled

*/

arch/arm/include/asm/system.h line 110

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_SA_DIS	(0 << 3)  /* Stack Alignment EL1 disabled

*/

arch/arm/include/asm/system.h line 111

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_DCACHE_DIS	(0 << 2)  /* Data cache disabled

*/

arch/arm/include/asm/system.h line 112

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_ALIGN_DIS	(0 << 1)  /* Alignment check disabled

*/

arch/arm/include/asm/system.h line 113

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_MMU_DIS	(0)       /* MMU disabled

*/

arch/arm/lib/bootm.c static void boot_jump_linux(bootm_headers_t

Quoted 60 lines
arch/arm/include/asm/system.h +21 -2
+
 #ifndef __ASSEMBLY__
 
 u64 get_page_table_size(void);
@@ -100,8 +196,26 @@ void __asm_invalidate_icache_all(void);
 int __asm_flush_l3_cache(void);
 void __asm_switch_ttbr(u64 new_ttbr);
 
-void armv8_switch_to_el2(void);
-void armv8_switch_to_el1(void);
+/*
+ * Switch from EL3 to EL2 for ARMv8
+ *
+ * @entry_point: kernel entry point
+ * @mach_nr:     machine nr
+ * @fdt_addr:    fdt address
+ * @es_flag:     execution state flag, ES_TO_AARCH64 or ES_TO_AARCH32
+ */
+void armv8_switch_to_el2(u64 entry_point, u64 mach_nr, u64 fdt_addr,
+			 u64 es_flag);
+/*
+ * Switch from EL2 to EL1 for ARMv8
+ *
+ * @entry_point: kernel entry point
+ * @mach_nr:     machine nr
+ * @fdt_addr:    fdt address
+ * @es_flag:     execution state flag, ES_TO_AARCH64 or ES_TO_AARCH32
+ */
+void armv8_switch_to_el1(u64 entry_point, u64 mach_nr, u64 fdt_addr,
+			 u64 es_flag);
 void gic_init(void);
 void gic_send_sgi(unsigned long sgino);  void wait_for_wakeup(void);
arch/arm/lib/bootm.c index renamed from arch/arm/lib/bootm.c +0 -0

0838d89..1bbf85c 100644

arch/arm/lib/bootm.c +9 -3
@@ -189,13 +189,19 @@ static void setup_end_tag(bd_t *bd)  __weak void
 setup_board_tags(struct tag **in_params) {}
 
 #ifdef CONFIG_ARM64
-static void do_nonsec_virt_switch(void)
+static void do_nonsec_virt_switch(bootm_headers_t *images, int flag)
 {
 	smp_kick_all_cpus();
 	dcache_disable();	/* flush cache before swtiching to EL2 */
-	armv8_switch_to_el2();
+
 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
-	armv8_switch_to_el1();
+	armv8_switch_to_el2((u64)images->ep, (u64)gd->bd->bi_arch_number,
+			    (u64)images->ft_addr, ES_TO_AARCH64);
+	armv8_switch_to_el1((u64)images->ep, (u64)gd->bd->bi_arch_number,
+			    (u64)images->ft_addr, flag);
+#else
+	armv8_switch_to_el2((u64)images->ep, (u64)gd->bd->bi_arch_number,
+			    (u64)images->ft_addr, flag);
 #endif
 }
 #endif
@@ -275,6 +281,7 @@ static void boot_jump_linux(bootm_headers_t

*images, int flag)

arch/arm/lib/bootm.c static void boot_jump_linux(bootm_headers_t

Quoted 8 lines
arch/arm/lib/bootm.c +1 -0
 	void (*kernel_entry)(void *fdt_addr, void *res0, void *res1,
 			void *res2);
 	int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
+	int es_flag = ES_TO_AARCH64;
 
 	kernel_entry = (void (*)(void *fdt_addr, void *res0, void *res1,
 				void *res2))images->ep;
@@ -286,7 +293,11 @@ static void boot_jump_linux(bootm_headers_t

*images, int flag)

common/image-fit.c int fit_image_check_arch(const void *fit, int

Quoted 25 lines
arch/arm/lib/bootm.c +5 -1
 	announce_and_cleanup(fake);
 
 	if (!fake) {
-		do_nonsec_virt_switch();
+		if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
+		    (images->os.arch == IH_ARCH_ARM))
+			es_flag = ES_TO_AARCH32;
+
+		do_nonsec_virt_switch(images, es_flag);
 		kernel_entry(images->ft_addr, NULL, NULL, NULL);
 	}
 #else
common/image-fit.c index renamed from common/image-fit.c +0 -0

9873957..982021b 100644

common/image-fit.c +1 -0
@@ -26,6 +26,7 @@ DECLARE_GLOBAL_DATA_PTR;  #include <u-boot/md5.h>
 #include <u-boot/sha1.h>  #include <u-boot/sha256.h>
+#include <generated/autoconf.h>
 
 
 /*********************************************************************
 ********/
 /* New uImage format routines */
@@ -1164,7 +1165,9 @@ int fit_image_check_arch(const void *fit, int

noffset, uint8_t arch)

Quoted 10 lines

common/image-fit.c int fit_image_check_arch(const void *fit, int noffset, uint8_t arch) · line 1170

Quoted 7 lines
common/image-fit.c +3 -1
 	if (fit_image_get_arch(fit, noffset, &image_arch))
 		return 0;
 	return (arch == image_arch) ||
-		(arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64);
+		(arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64) ||
+		(arch == IH_ARCH_ARM64 && image_arch == IH_ARCH_ARM &&
+		 CONFIG_ARM64_SUPPORT_AARCH32);

Uh, I think this define is simply not defined for non-compatible systems (including non-arm64). This really needs to go into an #ifdef.

Quoted 2 lines

[Alison Wang] I think arch == IH_ARCH_ARM64 will check for non-arm64 system. I can't understand your concern. Please explain more.

You either get a

#define CONFIG_ARM64_SUPPORT_AARCH32 1

in the config header if the option is set or simply nothing at all. If there's nothing, compiling this code will result in an unresolved symbol.

Alex

#7 lore raw

PATCH v3 1/2 armv8: Support loading 32-bit OS in AArch32 execution state

Quoted 123 lines · Huan Wang
Quoted 23 lines
Quoted 23 lines · Alison Wang
Quoted 9 lines

To support loading a 32-bit OS, the execution state will change from AArch64 to AArch32 when jumping to kernel.

The architecture information will be got through checking FIT image, then U-Boot will load 32-bit OS or 64-bit OS automatically.

Quoted 8 lines

---
Changes in v3:
- Comments the functions and the arguments.
- Rename the real parameters.
- Use the macros instead of the magic values.
- Remove the redundant codes.
- Clean up all of the mess in boot_jump_linux().
- Add CONFIG_ARM64_SUPPORT_AARCH32 to detect for some ARM64 system

doesn't support AArch32 state.

Quoted 3 lines

Changes in v2:
- armv8_switch_to_el2_aarch32() is removed. armv8_switch_to_el2_m is

used

Quoted 8 lines
Quoted 8 lines
Quoted 2 lines

to switch to AArch64 EL2 or AArch32 Hyp.
- armv8_switch_to_el1_aarch32() is removed. armv8_switch_to_el1_m is

used

Quoted 5 lines

to switch to AArch64 EL1 or AArch32 SVC.

 arch/arm/Kconfig                |   6 ++
 arch/arm/cpu/armv8/transition.S |   8 +-
 arch/arm/include/asm/macro.h    | 174

++++++++++++++++++++++++++++++-

Quoted 14 lines
Quoted 14 lines

---------

Quoted 13 lines
 arch/arm/include/asm/system.h   | 118 ++++++++++++++++++++++++++-
 arch/arm/lib/bootm.c            |  19 ++++-
 common/image-fit.c              |  14 +++-
 6 files changed, 287 insertions(+), 52 deletions(-)
arch/arm/Kconfig index renamed from arch/arm/Kconfig +0 -0

729b181..794cb4f 100644

arch/arm/Kconfig +0 -0
@@ -77,6 +77,12 @@ config SYS_L2CACHE_OFF
 	  If SoC does not support L2CACHE or one do not want to enable
 	  L2CACHE, choose this option.
 
Quoted 5 lines
Quoted 5 lines

arch/arm/Kconfig config SYS_L2CACHE_OFF · line 82

Quoted 3 lines
arch/arm/Kconfig +3 -0
+config ARM64_SUPPORT_AARCH32
+	bool "ARM64 system support AArch32 execution state"
+	default y if ARM64 && !CONFIG_THUNDERX

I don't think that works. In Kconfig you need to omit the CONFIG_

parts.

Quoted 70 lines
Quoted 4 lines

It's "ARM64" also, not "CONFIG_ARM64".

Please just try to run a local make defconfig on the thunderx reference system and see whether it includes the option or not.

[Alison Wang] Yes, I missed it. Will change in the next version.

Quoted 65 lines
Quoted 44 lines
arch/arm/Kconfig +3 -0
+	help
+	  This ARM64 system supports AArch32 execution state.
+
 choice
 	prompt "Target select"
 	default TARGET_HIKEY
(quoted diff) +0 -0

b/arch/arm/cpu/armv8/transition.S index 253a39b..417e8b4 100644

arch/arm/cpu/armv8/transition.S +4 -4
@@ -11,13 +11,13 @@
 #include <asm/macro.h>
 
 ENTRY(armv8_switch_to_el2)
-	switch_el x0, 1f, 0f, 0f
+	switch_el x4, 1f, 0f, 0f
 0:	ret
-1:	armv8_switch_to_el2_m x0
+1:	armv8_switch_to_el2_m x0, x1, x2, x3, x4
 ENDPROC(armv8_switch_to_el2)
 
 ENTRY(armv8_switch_to_el1)
-	switch_el x0, 0f, 1f, 0f
+	switch_el x4, 0f, 1f, 0f
 0:	ret
-1:	armv8_switch_to_el1_m x0, x1
+1:	armv8_switch_to_el1_m x0, x1, x2, x3, x4
 ENDPROC(armv8_switch_to_el1)
(quoted diff) +0 -0

b/arch/arm/include/asm/macro.h index 9bb0efa..dd2c510 100644

arch/arm/include/asm/macro.h +3 -0
@@ -8,6 +8,9 @@
 
 #ifndef __ASM_ARM_MACRO_H__
 #define __ASM_ARM_MACRO_H__
+
+#include <asm/system.h>
+
 #ifdef __ASSEMBLY__
 
 /*

arch/arm/include/asm/macro.h lr .req x30 · line 139

Quoted 5 lines
arch/arm/include/asm/macro.h +0 -2
@@ -135,13 +138,18 @@ lr	.req	x30
 #endif
 .endm
 
-.macro armv8_switch_to_el2_m, xreg1
-	/* 64bit EL2 | HCE | SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1

*/

arch/arm/include/asm/macro.h lr .req x30 · line 149

Quoted 11 lines
arch/arm/include/asm/macro.h +9 -2
-	mov	\xreg1, #0x5b1
-	msr	scr_el3, \xreg1
+/*
+ * Switch from EL3 to EL2 for ARMv8
+ * @ep:     kernel entry point
+ * @arch:   machine nr
+ * @ftaddr: fdt address
+ * @flag:   The execution state flag for lower exception
+ *          level, ES_TO_AARCH64 or ES_TO_AARCH32
+ */
+.macro armv8_switch_to_el2_m, ep, arch, ftaddr, flag, xreg5

You're never really using the arch and ftaddr arguments. Just describe in the macro header that they need to be in x1 and x2 respectively and leave them out of the argument list for the macro.

Quoted 7 lines
Quoted 1 line

[Alison Wang] Do you mean rename arch and ftaddr to x1 and x2 here?

I mean omit arch and ftaddr from the macro arguments and instead mention that x1 and x2 get passed as x1 and x2 to the guest and are usually "ftaddr" and "arch".

Also it would make the code more consistent to always use ep.

[Alison Wang] I don't think arch and ftaddr can be removed from the macro arguments in the current code. For 32-bit kernel startup entry point, the requirements are: r0 = 0, r1 = machine nr, r2 = atags or dtb pointer.

Quoted 529 lines

+/*
+ * Switch from EL3 to EL2 for ARMv8 and jump to @ep.
+ *
+ * @flag: The execution state flag for lower exception
+ * level, ES_TO_AARCH64 or ES_TO_AARCH32
+ *
+ * When flag == ES_TO_AARCH32:

+ * @ep:     location to jump to in AArch32 EL2 mode
+ * x1:      "Machine ID" for Linux payloads
+ * x2:      "DT Address" for Linux payloads

+ *
+ * When flag == ES_TO_AARCH64:
+ * @ep: location to jump to in AArch64 EL2 mode
+ * x1: "DT Address" for Linux payloads
+ */
+.macro armv8_switch_to_el2_m, ep, flag, tmpreg

Quoted 223 lines
Quoted 3 lines

Also please rename "xreg5" to something like "scratchreg" or "tmp" or "tmpreg". Then it's more obvious what this argument is about.

[Alison Wang] Ok.

Quoted 18 lines

arch/arm/include/asm/macro.h lr .req x30 · line 150

Quoted 2 lines
arch/arm/include/asm/macro.h +0 -0
 	msr	cptr_el3, xzr		/* Disable coprocessor traps to EL3

*/

Quoted 15 lines
arch/arm/include/asm/macro.h +3 -5
-	mov	\xreg1, #0x33ff
-	msr	cptr_el2, \xreg1	/* Disable coprocessor traps to EL2 */
+	mov	\xreg5, #(CPTR_EL2_BIT13_12_RES1 | CPTR_EL2_BIT9_0_RES1)
+	msr	cptr_el2, \xreg5	/* Disable coprocessor traps to EL2 */
 
 	/* Initialize Generic Timers */
 	msr	cntvoff_el2, xzr
@@ -152,45 +160,92 @@ lr	.req	x30
 	 * and RES0 bits (31,30,27,26,24,21,20,17,15-13,10-6) +
 	 * EE,WXN,I,SA,C,A,M to 0
 	 */
-	mov	\xreg1, #0x0830
-	movk	\xreg1, #0x30C5, lsl #16
-	msr	sctlr_el2, \xreg1
+	ldr	\xreg5, =(SCTLR_EL2_BIT29_28_RES1 | SCTLR_EL2_EE_LE |\
Quoted 8 lines

arch/arm/include/asm/macro.h lr .req x30 · line 168

Quoted 5 lines
arch/arm/include/asm/macro.h +5 -0
+			  SCTLR_EL2_BIT23_22_RES1 | SCTLR_EL2_WXN_DIS |\
+			  SCTLR_EL2_BIT18_RES1 | SCTLR_EL2_BIT16_RES1 |\
+			  SCTLR_EL2_BIT11_RES1 | SCTLR_EL2_BIT5_4_RES1 |\
+			  SCTLR_EL2_SA_DIS | SCTLR_EL2_DCACHE_DIS |\
+			  SCTLR_EL2_ALIGN_DIS | SCTLR_EL2_MMU_DIS)

Do you think you could just define something like SCTLR_EL2_RES1 in the header file that combines all RES1 fields already?

[Alison Wang] Ok, I think so.

Quoted 14 lines

arch/arm/include/asm/macro.h lr .req x30 · line 178

Quoted 11 lines
arch/arm/include/asm/macro.h +10 -0
+	msr	sctlr_el2, \xreg5
+
+	mov	\xreg5, sp
+	msr	sp_el2, \xreg5		/* Migrate SP */
+	mrs	\xreg5, vbar_el3
+	msr	vbar_el2, \xreg5	/* Migrate VBAR */
+
+	/* Check switch to AArch64 EL2 or AArch32 Hypervisor mode */
+	ldr	\xreg5, =ES_TO_AARCH32
+	cmp	\flag, \xreg5

This can be an immediate cmp, no?

Quoted 1 line

cmp \flag, #ES_TO_AARCH32

[Alison Wang] Yes, it can. Will change in the next version.

Quoted 12 lines

arch/arm/include/asm/macro.h lr .req x30 · line 187

Quoted 10 lines
arch/arm/include/asm/macro.h +9 -0
+	b.eq	1f
+
+	/*
+	 * The next lower exception level is AArch64, 64bit EL2 | HCE |
+	 * SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1.
+	 */
+	ldr	\xreg5, =(SCR_EL3_RW_AARCH64 | SCR_EL3_HCE_EN |\
+			  SCR_EL3_SMD_DIS | SCR_EL3_BIT5_4_RES1 |\
+			  SCR_EL3_NS_EN)

Same here - just define a single mask for SCR_EL3_RES1.

[Alison Wang] Ok.

Quoted 39 lines
Quoted 39 lines
arch/arm/include/asm/macro.h +26 -6
+	msr	scr_el3, \xreg5
 
 	/* Return to the EL2_SP2 mode from EL3 */
-	mov	\xreg1, sp
-	msr	sp_el2, \xreg1		/* Migrate SP */
-	mrs	\xreg1, vbar_el3
-	msr	vbar_el2, \xreg1	/* Migrate VBAR */
-	mov	\xreg1, #0x3c9
-	msr	spsr_el3, \xreg1	/* EL2_SP2 | D | A | I | F */
+	ldr	\xreg5, =(SPSR_EL_DEBUG_MASK | SPSR_EL_SERR_MASK |\
+			  SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\
+			  SPSR_EL_M_AARCH64 | SPSR_EL_M_EL2H)
+	msr	spsr_el3, \xreg5
 	msr	elr_el3, lr
 	eret
+
+1:
+	/*
+	 * The next lower exception level is AArch32, 32bit EL2 | HCE |
+	 * SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1.
+	 */
+	ldr	\xreg5, =(SCR_EL3_RW_AARCH32 | SCR_EL3_HCE_EN |\
+			  SCR_EL3_SMD_DIS | SCR_EL3_BIT5_4_RES1 |\
+			  SCR_EL3_NS_EN)
+	msr	scr_el3, \xreg5
+
+	/* Return to AArch32 Hypervisor mode */
+	ldr     \xreg5, =(SPSR_EL_END_LE | SPSR_EL_ASYN_MASK |\
+			  SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\
+			  SPSR_EL_T_A32 | SPSR_EL_M_AARCH32 |\
+			  SPSR_EL_M_HYP)
+	msr	spsr_el3, \xreg5
+	msr     elr_el3, \ep
+
+	mov	\ep, #0
+	eret
 .endm
 
Quoted 12 lines

arch/arm/include/asm/macro.h lr .req x30 · line 228

Quoted 10 lines
arch/arm/include/asm/macro.h +9 -1
-.macro armv8_switch_to_el1_m, xreg1, xreg2
+/*
+ * Switch from EL2 to EL1 for ARMv8
+ * @ep:     kernel entry point
+ * @arch:   machine nr
+ * @ftaddr: fdt address
+ * @flag:   The execution state flag for lower exception
+ *          level, ES_TO_AARCH64 or ES_TO_AARCH32
+ */
+.macro armv8_switch_to_el1_m, ep, arch, ftaddr, flag, xreg5

All the comments to the function above apply here too :).

[Alison Wang] Ok.

Quoted 54 lines
Quoted 18 lines
arch/arm/include/asm/macro.h +6 -7
 	/* Initialize Generic Timers */
-	mrs	\xreg1, cnthctl_el2
-	orr	\xreg1, \xreg1, #0x3	/* Enable EL1 access to timers */
-	msr	cnthctl_el2, \xreg1
+	mrs	\xreg5, cnthctl_el2
+	/* Enable EL1 access to timers */
+	orr	\xreg5, \xreg5, #(CNTHCTL_EL2_EL1PCEN_EN |\
+		CNTHCTL_EL2_EL1PCTEN_EN)
+	msr	cnthctl_el2, \xreg5
 	msr	cntvoff_el2, xzr
 
 	/* Initilize MPID/MPIDR registers */
-	mrs	\xreg1, midr_el1
-	mrs	\xreg2, mpidr_el1
-	msr	vpidr_el2, \xreg1
-	msr	vmpidr_el2, \xreg2
+	mrs	\xreg5, midr_el1

arch/arm/include/asm/macro.h lr .req x30

Quoted 10 lines
arch/arm/include/asm/macro.h +5 -2
+	msr	vpidr_el2, \xreg5
+	mrs	\xreg5, mpidr_el1
+	msr	vmpidr_el2, \xreg5
 
 	/* Disable coprocessor traps */
-	mov	\xreg1, #0x33ff
-	msr	cptr_el2, \xreg1	/* Disable coprocessor traps to EL2 */
+	mov	\xreg5, #(CPTR_EL2_BIT13_12_RES1 | CPTR_EL2_BIT9_0_RES1)
+	msr	cptr_el2, \xreg5	/* Disable coprocessor traps to EL2 */
 	msr	hstr_el2, xzr		/* Disable coprocessor traps to EL2

*/

Quoted 25 lines
arch/arm/include/asm/macro.h +8 -10
-	mov	\xreg1, #3 << 20
-	msr	cpacr_el1, \xreg1	/* Enable FP/SIMD at EL1 */
-
-	/* Initialize HCR_EL2 */
-	mov	\xreg1, #(1 << 31)		/* 64bit EL1 */
-	orr	\xreg1, \xreg1, #(1 << 29)	/* Disable HVC */
-	msr	hcr_el2, \xreg1
+	mov	\xreg5, #(CPACR_EL1_FPEN_EN)
+	msr	cpacr_el1, \xreg5	/* Enable FP/SIMD at EL1 */
 
 	/* SCTLR_EL1 initialization
 	 *
@@ -199,19 +254,56 @@ lr	.req	x30
 	 * UCI,EE,EOE,WXN,nTWE,nTWI,UCT,DZE,I,UMA,SED,ITD,
 	 * CP15BEN,SA0,SA,C,A,M to 0
 	 */
-	mov	\xreg1, #0x0800
-	movk	\xreg1, #0x30d0, lsl #16
-	msr	sctlr_el1, \xreg1
+	ldr	\xreg5, =(SCTLR_EL1_BIT29_28_RES1 | SCTLR_EL1_UCI_DIS |\
+			  SCTLR_EL1_EE_LE | SCTLR_EL1_BIT23_22_RES1 |\
+			  SCTLR_EL1_BIT20_RES1 | SCTLR_EL1_WXN_DIS |\
+			  SCTLR_EL1_NTWE_DIS | SCTLR_EL1_NTWI_DIS |\
+			  SCTLR_EL1_UCT_DIS | SCTLR_EL1_DZE_DIS |\
+			  SCTLR_EL1_ICACHE_DIS | SCTLR_EL1_BIT11_RES1 |\
Quoted 8 lines

arch/arm/include/asm/macro.h lr .req x30 · line 267

Quoted 5 lines
arch/arm/include/asm/macro.h +5 -0
+			  SCTLR_EL1_UMA_DIS | SCTLR_EL1_SED_EN |\
+			  SCTLR_EL1_ITD_EN | SCTLR_EL1_CP15BEN_DIS |\
+			  SCTLR_EL1_SA0_DIS | SCTLR_EL1_SA_DIS |\
+			  SCTLR_EL1_DCACHE_DIS | SCTLR_EL1_ALIGN_DIS |\
+			  SCTLR_EL1_MMU_DIS)

Why are the caches getting disabled? Or did you just convert the old value to the define list?

[Alison Wang] Yes, I just convert the old value to the define list.

Quoted 48 lines
Quoted 48 lines
arch/arm/include/asm/macro.h +35 -6
+	msr	sctlr_el1, \xreg5
+
+	mov	\xreg5, sp
+	msr	sp_el1, \xreg5		/* Migrate SP */
+	mrs	\xreg5, vbar_el2
+	msr	vbar_el1, \xreg5	/* Migrate VBAR */
+
+	/* Check switch to AArch64 EL1 or AArch32 Supervisor mode */
+	ldr	\xreg5, =ES_TO_AARCH32
+	cmp	\flag, \xreg5
+	b.eq	1f
+
+	/* Initialize HCR_EL2 */
+	ldr	\xreg5, =(HCR_EL2_RW_AARCH64 | HCR_EL2_HCD_DIS)
+	msr	hcr_el2, \xreg5
 
 	/* Return to the EL1_SP1 mode from EL2 */
-	mov	\xreg1, sp
-	msr	sp_el1, \xreg1		/* Migrate SP */
-	mrs	\xreg1, vbar_el2
-	msr	vbar_el1, \xreg1	/* Migrate VBAR */
-	mov	\xreg1, #0x3c5
-	msr	spsr_el2, \xreg1	/* EL1_SP1 | D | A | I | F */
+	ldr	\xreg5, =(SPSR_EL_DEBUG_MASK | SPSR_EL_SERR_MASK |\
+			  SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\
+			  SPSR_EL_M_AARCH64 | SPSR_EL_M_EL1H)
+	msr	spsr_el2, \xreg5
 	msr	elr_el2, lr
 	eret
+
+1:
+	/* Initialize HCR_EL2 */
+	ldr	\xreg5, =(HCR_EL2_RW_AARCH32 | HCR_EL2_HCD_DIS)
+	msr	hcr_el2, \xreg5
+
+	/* Return to AArch32 Supervisor mode from EL2 */
+	ldr	\xreg5, =(SPSR_EL_END_LE | SPSR_EL_ASYN_MASK |\
+			  SPSR_EL_IRQ_MASK | SPSR_EL_FIQ_MASK |\
+			  SPSR_EL_T_A32 | SPSR_EL_M_AARCH32 |\
+			  SPSR_EL_M_SVC)
+	msr     spsr_el2, \xreg5
+	msr     elr_el2, \ep
+
+	mov	\ep, #0
+	eret
 .endm
 
Quoted 7 lines
Quoted 7 lines

arch/arm/include/asm/system.h line 17

Quoted 7 lines
arch/arm/include/asm/macro.h +0 -0
 #if defined(CONFIG_GICV3)
(quoted diff) +0 -0

b/arch/arm/include/asm/system.h index 9ae890a..0271ddb 100644

arch/arm/include/asm/system.h +0 -0
@@ -17,6 +17,102 @@
 #define CR_WXN		(1 << 19)	/* Write Permision Imply XN
	*/
Quoted 9 lines
Quoted 9 lines

arch/arm/include/asm/system.h

Quoted 9 lines
arch/arm/include/asm/system.h +7 -0
 #define CR_EE		(1 << 25)	/* Exception (Big) Endian	*/
 
+#define ES_TO_AARCH64		1
+#define ES_TO_AARCH32		0
+
+/*
+ * SCR_EL3 bits definitions
+ */
+#define SCR_EL3_RW_AARCH64	(1 << 10) /* Next lower level is

AArch64

Quoted 10 lines
Quoted 10 lines

*/

arch/arm/include/asm/system.h line 27

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCR_EL3_RW_AARCH32	(0 << 10) /* Lower lowers level are

AArch32 */

arch/arm/include/asm/system.h line 28

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCR_EL3_HCE_EN		(1 << 8)  /* Hypervisor Call enable

*/

arch/arm/include/asm/system.h line 29

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCR_EL3_SMD_DIS		(1 << 7)  /* Secure Monitor Call

disable */

arch/arm/include/asm/system.h line 30

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCR_EL3_BIT5_4_RES1	(3 << 4)  /* Reserved, RES1

*/

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCR_EL3_NS_EN		(1 << 0)  /* EL0 and EL1 in Non-

scure

Quoted 9 lines
Quoted 9 lines

state */

arch/arm/include/asm/system.h line 35

Quoted 4 lines
arch/arm/include/asm/system.h +4 -0
+
+/*
+ * SPSR_EL3/SPSR_EL2 bits definitions  */
+#define SPSR_EL_END_LE		(0 << 9)  /* Exception Little-endian

*/

arch/arm/include/asm/system.h line 36

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_DEBUG_MASK	(1 << 9)  /* Debug exception masked

*/

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_ASYN_MASK	(1 << 8)  /* Asynchronous data abort
Quoted 8 lines
Quoted 8 lines

masked */

arch/arm/include/asm/system.h line 38

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_SERR_MASK	(1 << 8)  /* System Error exception masked

*/

arch/arm/include/asm/system.h line 39

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_IRQ_MASK	(1 << 7)  /* IRQ exception masked

*/

arch/arm/include/asm/system.h line 40

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_FIQ_MASK	(1 << 6)  /* FIQ exception masked

*/

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_T_A32		(0 << 5)  /* AArch32 instruction set

A32

Quoted 6 lines
Quoted 6 lines

*/

arch/arm/include/asm/system.h line 42

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_AARCH64	(0 << 4)  /* Exception taken from AArch64

*/

arch/arm/include/asm/system.h line 43

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_AARCH32	(1 << 4)  /* Exception taken from AArch32

*/

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_SVC		(0x3)     /* Exception taken from

SVC mode

Quoted 2 lines
Quoted 2 lines

*/

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_HYP		(0xa)     /* Exception taken from

HYP mode

Quoted 32 lines
Quoted 32 lines

*/

arch/arm/include/asm/system.h line 46

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_EL1H		(5)       /* Exception taken from

EL1h mode */

arch/arm/include/asm/system.h line 47

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SPSR_EL_M_EL2H		(9)       /* Exception taken from

EL2h mode */

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * CPTR_EL2 bits definitions
+ */
+#define CPTR_EL2_BIT13_12_RES1	(3 << 12) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 53

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define CPTR_EL2_BIT9_0_RES1	(0x3ff)   /* Reserved, RES1

*/

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * SCTLR_EL2 bits definitions
+ */
+#define SCTLR_EL2_BIT29_28_RES1	(3 << 28) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 59

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_EE_LE		(0 << 25) /* Exception Little-endian

*/

arch/arm/include/asm/system.h line 60

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_BIT23_22_RES1	(3 << 22) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 61

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_WXN_DIS	(0 << 19) /* Write permission is not XN

*/

arch/arm/include/asm/system.h line 62

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_BIT18_RES1	(1 << 18) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 63

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_BIT16_RES1	(1 << 16) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 64

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_ICACHE_DIS	(0 << 12) /* Instruction cache

disabled */

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_BIT11_RES1	(1 << 11) /* Reserved, RES1
Quoted 8 lines
Quoted 8 lines

*/

arch/arm/include/asm/system.h line 66

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_BIT5_4_RES1	(3 << 4)  /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 67

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_SA_DIS	(0 << 3)  /* Stack Alignment Check

disabled */

arch/arm/include/asm/system.h line 68

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_DCACHE_DIS	(0 << 2)  /* Data cache disabled

*/

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_ALIGN_DIS	(0 << 1)  /* Alignment check

disabled

Quoted 10 lines
Quoted 10 lines

*/

arch/arm/include/asm/system.h line 70

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL2_MMU_DIS	(0)       /* MMU disabled

*/

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * CNTHCTL_EL2 bits definitions
+ */
+#define CNTHCTL_EL2_EL1PCEN_EN	(1 << 1)  /* Physical timer regs

accessible */

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define CNTHCTL_EL2_EL1PCTEN_EN	(1 << 0)  /* Physical counter
Quoted 8 lines
Quoted 8 lines

accessible */

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * HCR_EL2 bits definitions
+ */
+#define HCR_EL2_RW_AARCH64	(1 << 31) /* EL1 is AArch64

*/

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define HCR_EL2_RW_AARCH32	(0 << 31) /* Lower levels are

AArch32

Quoted 18 lines
Quoted 18 lines

*/

arch/arm/include/asm/system.h line 83

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define HCR_EL2_HCD_DIS		(1 << 29) /* Hypervisor Call

disabled */

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * CPACR_EL1 bits definitions
+ */
+#define CPACR_EL1_FPEN_EN	(3 << 20) /* SIMD and FP instruction

enabled */

arch/arm/include/asm/system.h

Quoted 5 lines
arch/arm/include/asm/system.h +5 -0
+
+/*
+ * SCTLR_EL1 bits definitions
+ */
+#define SCTLR_EL1_BIT29_28_RES1	(3 << 28) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 94

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_UCI_DIS	(0 << 26) /* Cache instruction disabled

*/

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_EE_LE		(0 << 25) /* Exception Little-endian
Quoted 8 lines
Quoted 8 lines

*/

arch/arm/include/asm/system.h line 96

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_BIT23_22_RES1	(3 << 22) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 97

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_BIT20_RES1	(1 << 20) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 98

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_WXN_DIS	(0 << 19) /* Write permission is not XN

*/

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_NTWE_DIS	(0 << 18) /* WFE instruction

disabled

Quoted 2 lines
Quoted 2 lines

*/

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_NTWI_DIS	(0 << 16) /* WFI instruction

disabled

Quoted 16 lines
Quoted 16 lines

*/

arch/arm/include/asm/system.h line 101

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_UCT_DIS	(0 << 15) /* CTR_EL0 access disabled

*/

arch/arm/include/asm/system.h line 102

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_DZE_DIS	(0 << 14) /* DC ZVA instruction disabled

*/

arch/arm/include/asm/system.h line 103

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_ICACHE_DIS	(0 << 12) /* Instruction cache

disabled */

arch/arm/include/asm/system.h line 104

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_BIT11_RES1	(1 << 11) /* Reserved, RES1

*/

arch/arm/include/asm/system.h line 105

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_UMA_DIS	(0 << 9)  /* User Mask Access disabled

*/

arch/arm/include/asm/system.h line 106

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_SED_EN	(0 << 8)  /* SETEND instruction enabled

*/

arch/arm/include/asm/system.h line 107

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_ITD_EN	(0 << 7)  /* IT instruction enabled

*/

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_CP15BEN_DIS	(0 << 5)  /* CP15 barrier operation
Quoted 8 lines
Quoted 8 lines

disabled */

arch/arm/include/asm/system.h line 109

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_SA0_DIS	(0 << 4)  /* Stack Alignment EL0 disabled

*/

arch/arm/include/asm/system.h line 110

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_SA_DIS	(0 << 3)  /* Stack Alignment EL1 disabled

*/

arch/arm/include/asm/system.h line 111

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_DCACHE_DIS	(0 << 2)  /* Data cache disabled

*/

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_ALIGN_DIS	(0 << 1)  /* Alignment check

disabled

Quoted 11 lines
Quoted 11 lines

*/

arch/arm/include/asm/system.h line 113

Quoted 1 line
arch/arm/include/asm/system.h +1 -0
+#define SCTLR_EL1_MMU_DIS	(0)       /* MMU disabled

*/

Quoted 8 lines
arch/arm/include/asm/system.h +1 -0
+
 #ifndef __ASSEMBLY__
 
 u64 get_page_table_size(void);
@@ -100,8 +196,26 @@ void __asm_invalidate_icache_all(void);
 int __asm_flush_l3_cache(void);
 void __asm_switch_ttbr(u64 new_ttbr);
 
Quoted 9 lines
Quoted 9 lines

arch/arm/include/asm/system.h void __asm_invalidate_icache_all(void);

Quoted 9 lines
arch/arm/include/asm/system.h +7 -2
-void armv8_switch_to_el2(void);
-void armv8_switch_to_el1(void);
+/*
+ * Switch from EL3 to EL2 for ARMv8
+ *
+ * @entry_point: kernel entry point
+ * @mach_nr:     machine nr
+ * @fdt_addr:    fdt address
+ * @es_flag:     execution state flag, ES_TO_AARCH64 or

ES_TO_AARCH32

Quoted 10 lines
Quoted 10 lines

arch/arm/include/asm/system.h void __asm_invalidate_icache_all(void);

Quoted 10 lines
arch/arm/include/asm/system.h +10 -0
+ */
+void armv8_switch_to_el2(u64 entry_point, u64 mach_nr, u64 fdt_addr,
+			 u64 es_flag);
+/*
+ * Switch from EL2 to EL1 for ARMv8
+ *
+ * @entry_point: kernel entry point
+ * @mach_nr:     machine nr
+ * @fdt_addr:    fdt address
+ * @es_flag:     execution state flag, ES_TO_AARCH64 or

ES_TO_AARCH32

Quoted 80 lines
Quoted 70 lines

arch/arm/lib/bootm.c static void boot_jump_linux(bootm_headers_t

Quoted 33 lines
arch/arm/include/asm/system.h +3 -0
+ */
+void armv8_switch_to_el1(u64 entry_point, u64 mach_nr, u64 fdt_addr,
+			 u64 es_flag);
 void gic_init(void);
 void gic_send_sgi(unsigned long sgino);  void

wait_for_wakeup(void); diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 0838d89..1bbf85c 100644

arch/arm/lib/bootm.c +9 -3
@@ -189,13 +189,19 @@ static void setup_end_tag(bd_t *bd)  __weak
 void setup_board_tags(struct tag **in_params) {}
 
 #ifdef CONFIG_ARM64
-static void do_nonsec_virt_switch(void)
+static void do_nonsec_virt_switch(bootm_headers_t *images, int
+flag)
 {
 	smp_kick_all_cpus();
 	dcache_disable();	/* flush cache before swtiching to EL2 */
-	armv8_switch_to_el2();
+
 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
-	armv8_switch_to_el1();
+	armv8_switch_to_el2((u64)images->ep, (u64)gd->bd->bi_arch_number,
+			    (u64)images->ft_addr, ES_TO_AARCH64);
+	armv8_switch_to_el1((u64)images->ep, (u64)gd->bd->bi_arch_number,
+			    (u64)images->ft_addr, flag); #else
+	armv8_switch_to_el2((u64)images->ep, (u64)gd->bd->bi_arch_number,
+			    (u64)images->ft_addr, flag);
 #endif
 }
 #endif
@@ -275,6 +281,7 @@ static void boot_jump_linux(bootm_headers_t

*images, int flag)

arch/arm/lib/bootm.c static void boot_jump_linux(bootm_headers_t

Quoted 8 lines
arch/arm/lib/bootm.c +1 -0
 	void (*kernel_entry)(void *fdt_addr, void *res0, void *res1,
 			void *res2);
 	int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
+	int es_flag = ES_TO_AARCH64;
 
 	kernel_entry = (void (*)(void *fdt_addr, void *res0, void *res1,
 				void *res2))images->ep;
@@ -286,7 +293,11 @@ static void boot_jump_linux(bootm_headers_t

*images, int flag)

common/image-fit.c int fit_image_check_arch(const void *fit, int

Quoted 26 lines
arch/arm/lib/bootm.c +5 -1
 	announce_and_cleanup(fake);
 
 	if (!fake) {
-		do_nonsec_virt_switch();
+		if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
+		    (images->os.arch == IH_ARCH_ARM))
+			es_flag = ES_TO_AARCH32;
+
+		do_nonsec_virt_switch(images, es_flag);
 		kernel_entry(images->ft_addr, NULL, NULL, NULL);
 	}
 #else
common/image-fit.c index renamed from common/image-fit.c +0 -0

9873957..982021b 100644

common/image-fit.c +1 -0
@@ -26,6 +26,7 @@ DECLARE_GLOBAL_DATA_PTR;  #include <u-boot/md5.h>
 #include <u-boot/sha1.h>  #include <u-boot/sha256.h>
+#include <generated/autoconf.h>
 
 
 /*******************************************************************
 **
 ********/

/* New uImage format routines */

common/image-fit.c +0 -0
@@ -1164,7 +1165,9 @@ int fit_image_check_arch(const void *fit, int

noffset, uint8_t arch)

Quoted 10 lines

common/image-fit.c int fit_image_check_arch(const void *fit, int noffset, uint8_t arch) · line 1170

Quoted 7 lines
common/image-fit.c +3 -1
 	if (fit_image_get_arch(fit, noffset, &image_arch))
 		return 0;
 	return (arch == image_arch) ||
-		(arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64);
+		(arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64) ||
+		(arch == IH_ARCH_ARM64 && image_arch == IH_ARCH_ARM &&
+		 CONFIG_ARM64_SUPPORT_AARCH32);

Uh, I think this define is simply not defined for non-compatible systems (including non-arm64). This really needs to go into an #ifdef.

Quoted 1 line

[Alison Wang] I think arch == IH_ARCH_ARM64 will check for non-arm64

system.

Quoted 9 lines
Quoted 1 line

I can't understand your concern. Please explain more.

You either get a

#define CONFIG_ARM64_SUPPORT_AARCH32 1

in the config header if the option is set or simply nothing at all. If there's nothing, compiling this code will result in an unresolved symbol.

[Alison Wang] Yes, I will change as follows in the next version.

int fit_image_check_arch(const void *fit, int noffset, uint8_t arch)

 {
        uint8_t image_arch;

+ int aarch32_support = 0;
+
+#ifdef CONFIG_ARM64_SUPPORT_AARCH32
+ aarch32_support = 1;
+#endif

        if (fit_image_get_arch(fit, noffset, &image_arch))
                return 0;
        return (arch == image_arch) ||
                (arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64) ||
                (arch == IH_ARCH_ARM64 && image_arch == IH_ARCH_ARM &&

- CONFIG_ARM64_SUPPORT_AARCH32);
+ aarch32_support);
}

Best Regards,
Alison Wang

#8 lore raw

PATCH v3 1/2 armv8: Support loading 32-bit OS in AArch32 execution state

Am 03.06.2016 um 11:31 schrieb Huan Wang <[email protected]>:

Quoted 129 lines
Quoted 129 lines · Huan Wang
Quoted 23 lines
Quoted 23 lines · Alison Wang
Quoted 9 lines

To support loading a 32-bit OS, the execution state will change from AArch64 to AArch32 when jumping to kernel.

The architecture information will be got through checking FIT image, then U-Boot will load 32-bit OS or 64-bit OS automatically.

Quoted 8 lines

---
Changes in v3:
- Comments the functions and the arguments.
- Rename the real parameters.
- Use the macros instead of the magic values.
- Remove the redundant codes.
- Clean up all of the mess in boot_jump_linux().
- Add CONFIG_ARM64_SUPPORT_AARCH32 to detect for some ARM64 system

doesn't support AArch32 state.

Quoted 3 lines

Changes in v2:
- armv8_switch_to_el2_aarch32() is removed. armv8_switch_to_el2_m is

used

Quoted 8 lines
Quoted 8 lines
Quoted 2 lines

to switch to AArch64 EL2 or AArch32 Hyp.
- armv8_switch_to_el1_aarch32() is removed. armv8_switch_to_el1_m is

used

Quoted 5 lines

to switch to AArch64 EL1 or AArch32 SVC.

arch/arm/Kconfig                |   6 ++
arch/arm/cpu/armv8/transition.S |   8 +-
arch/arm/include/asm/macro.h    | 174

++++++++++++++++++++++++++++++-

Quoted 14 lines
Quoted 14 lines

---------

Quoted 13 lines
arch/arm/include/asm/system.h   | 118 ++++++++++++++++++++++++++-
arch/arm/lib/bootm.c            |  19 ++++-
common/image-fit.c              |  14 +++-
6 files changed, 287 insertions(+), 52 deletions(-)
arch/arm/Kconfig index renamed from arch/arm/Kconfig +0 -0

729b181..794cb4f 100644

arch/arm/Kconfig +0 -0
@@ -77,6 +77,12 @@ config SYS_L2CACHE_OFF
     If SoC does not support L2CACHE or one do not want to enable
     L2CACHE, choose this option.
 
Quoted 5 lines
Quoted 5 lines

arch/arm/Kconfig config SYS_L2CACHE_OFF · line 82

Quoted 3 lines
arch/arm/Kconfig +3 -0
+config ARM64_SUPPORT_AARCH32
+    bool "ARM64 system support AArch32 execution state"
+    default y if ARM64 && !CONFIG_THUNDERX

I don't think that works. In Kconfig you need to omit the CONFIG_

parts.

Quoted 67 lines
Quoted 4 lines

It's "ARM64" also, not "CONFIG_ARM64".

Please just try to run a local make defconfig on the thunderx reference system and see whether it includes the option or not.

[Alison Wang] Yes, I missed it. Will change in the next version.

Quoted 62 lines
Quoted 47 lines
arch/arm/Kconfig +3 -0
+    help
+      This ARM64 system supports AArch32 execution state.
+

choice
prompt "Target select"
default TARGET_HIKEY

(quoted diff) +0 -0

b/arch/arm/cpu/armv8/transition.S index 253a39b..417e8b4 100644

arch/arm/cpu/armv8/transition.S +1 -1
@@ -11,13 +11,13 @@
 #include <asm/macro.h>
 
 ENTRY(armv8_switch_to_el2)
-    switch_el x0, 1f, 0f, 0f
+    switch_el x4, 1f, 0f, 0f

0: ret
-1: armv8_switch_to_el2_m x0
+1: armv8_switch_to_el2_m x0, x1, x2, x3, x4
ENDPROC(armv8_switch_to_el2)

ENTRY(armv8_switch_to_el1)

arch/arm/cpu/armv8/transition.S +1 -1
-    switch_el x0, 0f, 1f, 0f
+    switch_el x4, 0f, 1f, 0f

0: ret
-1: armv8_switch_to_el1_m x0, x1
+1: armv8_switch_to_el1_m x0, x1, x2, x3, x4
ENDPROC(armv8_switch_to_el1)

(quoted diff) +0 -0

b/arch/arm/include/asm/macro.h index 9bb0efa..dd2c510 100644

arch/arm/include/asm/macro.h +3 -0
@@ -8,6 +8,9 @@
 
 #ifndef __ASM_ARM_MACRO_H__
 #define __ASM_ARM_MACRO_H__
+
+#include <asm/system.h>
+
 #ifdef __ASSEMBLY__
 
 /*
@@ -135,13 +138,18 @@ lr    .req    x30
 #endif

.endm

Quoted 2 lines

-.macro armv8_switch_to_el2_m, xreg1
- /* 64bit EL2 | HCE | SMD | RES1 (Bits[5:4]) | Non-secure EL0/EL1

*/

Quoted 11 lines
arch/arm/include/asm/macro.h +9 -2
-    mov    \xreg1, #0x5b1
-    msr    scr_el3, \xreg1
+/*
+ * Switch from EL3 to EL2 for ARMv8
+ * @ep:     kernel entry point
+ * @arch:   machine nr
+ * @ftaddr: fdt address
+ * @flag:   The execution state flag for lower exception
+ *          level, ES_TO_AARCH64 or ES_TO_AARCH32
+ */
+.macro armv8_switch_to_el2_m, ep, arch, ftaddr, flag, xreg5
Quoted 4 lines
Quoted 3 lines

You're never really using the arch and ftaddr arguments. Just describe in the macro header that they need to be in x1 and x2 respectively and leave them out of the argument list for the macro.

[Alison Wang] Do you mean rename arch and ftaddr to x1 and x2 here?

I mean omit arch and ftaddr from the macro arguments and instead mention that x1 and x2 get passed as x1 and x2 to the guest and are usually "ftaddr" and "arch".

Quoted 5 lines
Quoted 1 line

Also it would make the code more consistent to always use ep.

[Alison Wang] I don't think arch and ftaddr can be removed from the macro arguments in the current code. For 32-bit kernel startup entry point, the requirements are: r0 = 0, r1 = machine nr, r2 = atags or dtb pointer.

You don't refer to them, so they can be removed. Don't remove them from the function prototype - only from the macro.

Or if you find it too confusing to read then, pass a struct that contains ep, x0, x1, x2 and load the values from there.

Alex

#9 lore raw

PATCH v3 2/2 armv8: fsl-layerscape: SMP support for loading 32-bit OS

In reply to Alison Wang

Spin-table method is used for secondary cores to load 32-bit OS. The architecture information will be got through checking FIT image and saved in the os_arch element of spin-table, then the secondary cores will check os_arch and jump to 32-bit OS or 64-bit OS automatically.

---
Changes in v3:
- Adjust the arguments for armv8_switch_to_el2_m and armv8_switch_to_el1_m.

Changes in v2:
- Support to call armv8_switch_to_el2_m and armv8_switch_to_el1_m.

 arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S  | 35 ++++++++++++++++++++++++---
 arch/arm/cpu/armv8/fsl-layerscape/mp.c        | 10 ++++++++
 arch/arm/include/asm/arch-fsl-layerscape/mp.h |  6 +++++
 arch/arm/lib/bootm.c                          |  5 ++++
 4 files changed, 52 insertions(+), 4 deletions(-)
arch/arm/cpu/armv8/fsl-layerscape/lowlevel.S +31 -4
index 04831ca..7363595 100644
@@ -13,6 +13,8 @@
 #ifdef CONFIG_MP
 #include <asm/arch/mp.h>
 #endif
+#include <asm/u-boot.h>
+#include <asm/system.h>
 
 ENTRY(lowlevel_init)
 	mov	x29, lr			/* Save LR */
@@ -320,6 +322,12 @@ ENTRY(secondary_boot_func)
         gic_wait_for_interrupt_m x0, w1
 #endif
 
+	ldr	x5, [x11, #24]
+	ldr	x6, =IH_ARCH_DEFAULT
+	cmp	x6, x5
+	b.ne	slave_cpu
+
+	ldr	x3, =ES_TO_AARCH64
 	bl secondary_switch_to_el2
 #ifdef CONFIG_ARMV8_SWITCH_TO_EL1
 	bl secondary_switch_to_el1
@@ -337,19 +345,38 @@ slave_cpu:
 	tbz     x1, #25, cpu_is_le
 	rev     x0, x0                  /* BE to LE conversion */
 cpu_is_le:
+
+	ldr	x5, [x11, #24]
+	ldr	x6, =IH_ARCH_DEFAULT
+	cmp	x6, x5
+	b.eq	1f
+
+#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
+	ldr	x3, =ES_TO_AARCH64
+	bl	secondary_switch_to_el2
+	ldr	x0, [x11]
+	ldr	x3, =ES_TO_AARCH32
+	bl	secondary_switch_to_el1
+#else
+	ldr	x0, [x11]
+	ldr	x3, =ES_TO_AARCH32
+	bl	secondary_switch_to_el2
+#endif
+
+1:
 	br	x0			/* branch to the given address */
 ENDPROC(secondary_boot_func)
 
 ENTRY(secondary_switch_to_el2)
-	switch_el x0, 1f, 0f, 0f
+	switch_el x4, 1f, 0f, 0f
 0:	ret
-1:	armv8_switch_to_el2_m x0
+1:	armv8_switch_to_el2_m x0, x1, x2, x3, x4
 ENDPROC(secondary_switch_to_el2)
 
 ENTRY(secondary_switch_to_el1)
-	switch_el x0, 0f, 1f, 0f
+	switch_el x4, 0f, 1f, 0f
 0:	ret
-1:	armv8_switch_to_el1_m x0, x1
+1:	armv8_switch_to_el1_m x0, x1, x2, x3, x4
 ENDPROC(secondary_switch_to_el1)
 
 	/* Ensure that the literals used by the secondary boot code are
arch/arm/cpu/armv8/fsl-layerscape/mp.c +10 -0
index df7ffb8..dd91550 100644
@@ -22,6 +22,16 @@ phys_addr_t determine_mp_bootpg(void)
 	return (phys_addr_t)&secondary_boot_code;
 }
 
+void update_os_arch_secondary_cores(uint8_t os_arch)
+{
+	u64 *table = get_spin_tbl_addr();
+	int i;
+
+	for (i = 1; i < CONFIG_MAX_CPUS; i++)
+		table[i * WORDS_PER_SPIN_TABLE_ENTRY +
+			SPIN_TABLE_ELEM_OS_ARCH_IDX] = os_arch;
+}
+
 int fsl_layerscape_wake_seconday_cores(void)
 {
 	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
arch/arm/include/asm/arch-fsl-layerscape/mp.h +6 -0
index e46e076..55f0e0c 100644
@@ -13,6 +13,7 @@
 *      uint64_t entry_addr;
 *      uint64_t status;
 *      uint64_t lpid;
+*      uint64_t os_arch;
 * };
 * we pad this struct to 64 bytes so each entry is in its own cacheline
 * the actual spin table is an array of these structures
@@ -20,6 +21,7 @@
 #define SPIN_TABLE_ELEM_ENTRY_ADDR_IDX	0
 #define SPIN_TABLE_ELEM_STATUS_IDX	1
 #define SPIN_TABLE_ELEM_LPID_IDX	2
+#define SPIN_TABLE_ELEM_OS_ARCH_IDX	3
 #define WORDS_PER_SPIN_TABLE_ENTRY	8	/* pad to 64 bytes */
 #define SPIN_TABLE_ELEM_SIZE		64
 
@@ -35,4 +37,8 @@ phys_addr_t determine_mp_bootpg(void);
 void secondary_boot_func(void);
 int is_core_online(u64 cpu_id);
 #endif
+
+#define IH_ARCH_ARM		2	/* ARM */
+#define IH_ARCH_ARM64		22	/* ARM64 */
+
 #endif /* _FSL_LAYERSCAPE_MP_H */
arch/arm/lib/bootm.c +5 -0
index 1bbf85c..4dca065 100644
@@ -274,6 +274,10 @@ bool armv7_boot_nonsec(void)
 }
 #endif
 
+__weak void update_os_arch_secondary_cores(uint8_t os_arch)
+{
+}
+
 /* Subcommand: GO */
 static void boot_jump_linux(bootm_headers_t *images, int flag)
 {
@@ -293,6 +297,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
 	announce_and_cleanup(fake);
 
 	if (!fake) {
+		update_os_arch_secondary_cores(images->os.arch);
 		if ((IH_ARCH_DEFAULT == IH_ARCH_ARM64) &&
 		    (images->os.arch == IH_ARCH_ARM))
 			es_flag = ES_TO_AARCH32;
Signature · 1 line
2.1.0.27.g96db324