* [boot-wrapper PATCH v2 0/8] Add Armv8-R AArch64 support
@ 2021-05-21 10:47 Jaxson Han
2021-05-21 10:48 ` [boot-wrapper PATCH v2 1/8] Decouple V2M_SYS config by auto-detect dtb node Jaxson Han
` (7 more replies)
0 siblings, 8 replies; 18+ messages in thread
From: Jaxson Han @ 2021-05-21 10:47 UTC (permalink / raw)
To: mark.rutland, andre.przywara; +Cc: linux-arm-kernel, wei.chen, jaxson.han
Currently, we cannot boot Linux with boot-wrapper on Armv8-R AArch64:
1. The Armv8-R AArch64 profile does not support the EL3.
2. The Armv8-R AArch64 EL2 only supports a PMSA, which Linux does not
support. So it's necessary to drop into EL1 before entering the kernel.
3. There is no EL2 booting code for Armv8-R AArch64 and no
configuration for dropping to EL1 in boot-wrapper.
These patches enable boot-wrapper booting Linux with Armv8-R AArch64:
Patch 1 allows boot-wrapper to boot on more platforms.
Patch 2 renames some labels as preparations for booting from lower EL.
Patch 3 remove the redundant setup_stack.
Patch 4-5 does some preparations for lower EL booting.
Patch 6 prepares for GICv3 initialization with EL2.
Patch 7 adds necessary EL2 registers.
Patch 8 adds auto-detection for Armv8-R AArch64 to drop into EL1
before entering the kernel.
Refs: Arm Architecture Reference Manual Supplement - Armv8, for
Armv8-R AArch64 architecture profile.
[https://developer.arm.com/documentation/ddi0600/latest/]
---------
v1 -> v2:
1. Split Patch 2 to Patch 2,3,4.
2. Slightly refine some comments.
3. More checks on Armv8-R AArch64.
4. Force setting HCR_EL2 instead of modifying.
Jaxson Han (8):
Decouple V2M_SYS config by auto-detect dtb node
aarch64: Rename labels and prepare for lower EL booting
aarch64: Remove the redundant setup_stack
aarch64: Prepare for EL1 booting
aarch64: Prepare for lower EL booting
gic-v3: Prepare for gicv3 with EL2
aarch64: Prepare for booting with EL2
aarch64: Introduce EL2 boot code for Armv8-R AArch64
Makefile.am | 4 +-
arch/aarch32/include/asm/gic-v3.h | 7 ++
arch/aarch64/boot.S | 146 +++++++++++++++++++++++++++---
arch/aarch64/include/asm/cpu.h | 3 +
arch/aarch64/include/asm/gic-v3.h | 38 +++++++-
arch/aarch64/psci.S | 13 +--
arch/aarch64/spin.S | 8 +-
arch/aarch64/utils.S | 10 +-
gic-v3.c | 2 +-
platform.c | 4 +
10 files changed, 203 insertions(+), 32 deletions(-)
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 18+ messages in thread
* [boot-wrapper PATCH v2 1/8] Decouple V2M_SYS config by auto-detect dtb node
2021-05-21 10:47 [boot-wrapper PATCH v2 0/8] Add Armv8-R AArch64 support Jaxson Han
@ 2021-05-21 10:48 ` Jaxson Han
2021-05-21 10:48 ` [boot-wrapper PATCH v2 2/8] aarch64: Rename labels and prepare for lower EL booting Jaxson Han
` (6 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Jaxson Han @ 2021-05-21 10:48 UTC (permalink / raw)
To: mark.rutland, andre.przywara; +Cc: linux-arm-kernel, wei.chen, jaxson.han
An auto-detect switch is added to make it an option to enable/disable
'arm,vexpress-sysreg', because not all platforms support this feature.
But the auto-detection generates the side-effect of printing a warning
message about the missing node:
No matching devices found at ./findbase.pl line 37.
In this case, to drop the warning message, add "2> /dev/null" at the
end of the findbase.pl call.
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
---
Makefile.am | 4 ++--
platform.c | 4 ++++
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index af694b7..ef6b793 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -10,7 +10,7 @@
# VE
PHYS_OFFSET := $(shell perl -I $(top_srcdir) $(top_srcdir)/findmem.pl $(KERNEL_DTB))
UART_BASE := $(shell perl -I $(top_srcdir) $(top_srcdir)/findbase.pl $(KERNEL_DTB) 0 'arm,pl011')
-SYSREGS_BASE := $(shell perl -I $(top_srcdir) $(top_srcdir)/findbase.pl $(KERNEL_DTB) 0 'arm,vexpress-sysreg')
+SYSREGS_BASE := $(shell perl -I $(top_srcdir) $(top_srcdir)/findbase.pl $(KERNEL_DTB) 0 'arm,vexpress-sysreg' 2> /dev/null)
CNTFRQ := 0x01800000 # 24Mhz
CPU_IDS := $(shell perl -I $(top_srcdir) $(top_srcdir)/findcpuids.pl $(KERNEL_DTB))
@@ -19,7 +19,7 @@ NR_CPUS := $(shell echo $(CPU_IDS) | tr ',' ' ' | wc -w)
DEFINES = -DCNTFRQ=$(CNTFRQ)
DEFINES += -DCPU_IDS=$(CPU_IDS)
DEFINES += -DNR_CPUS=$(NR_CPUS)
-DEFINES += -DSYSREGS_BASE=$(SYSREGS_BASE)
+DEFINES += $(if $(SYSREGS_BASE), -DSYSREGS_BASE=$(SYSREGS_BASE), )
DEFINES += -DUART_BASE=$(UART_BASE)
DEFINES += -DSTACK_SIZE=256
diff --git a/platform.c b/platform.c
index a528a55..d11f568 100644
--- a/platform.c
+++ b/platform.c
@@ -23,10 +23,12 @@
#define PL011(reg) ((void *)UART_BASE + PL011_##reg)
+#ifdef SYSREGS_BASE
#define V2M_SYS_CFGDATA 0xa0
#define V2M_SYS_CFGCTRL 0xa4
#define V2M_SYS(reg) ((void *)SYSREGS_BASE + V2M_SYS_##reg)
+#endif
static void print_string(const char *str)
{
@@ -59,6 +61,7 @@ void init_platform(void)
print_string("Boot-wrapper v0.2\r\n\r\n");
+#ifdef SYSREGS_BASE
/*
* CLCD output site MB
*/
@@ -66,4 +69,5 @@ void init_platform(void)
/* START | WRITE | MUXFPGA | SITE_MB */
raw_writel((1 << 31) | (1 << 30) | (7 << 20) | (0 << 16),
V2M_SYS(CFGCTRL));
+#endif
}
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [boot-wrapper PATCH v2 2/8] aarch64: Rename labels and prepare for lower EL booting
2021-05-21 10:47 [boot-wrapper PATCH v2 0/8] Add Armv8-R AArch64 support Jaxson Han
2021-05-21 10:48 ` [boot-wrapper PATCH v2 1/8] Decouple V2M_SYS config by auto-detect dtb node Jaxson Han
@ 2021-05-21 10:48 ` Jaxson Han
2021-05-24 9:32 ` Andre Przywara
2021-05-21 10:48 ` [boot-wrapper PATCH v2 3/8] aarch64: Remove the redundant setup_stack Jaxson Han
` (5 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Jaxson Han @ 2021-05-21 10:48 UTC (permalink / raw)
To: mark.rutland, andre.przywara; +Cc: linux-arm-kernel, wei.chen, jaxson.han
Prepare for booting from lower EL. Rename *_el3 relavant labels with
*_el_max and *_no_el3 with *_keep_el. Since the original _no_el3 means
"We neither do init sequence at this highest EL nor drop to lower EL
when entering to kernel", we rename it with _keep_el to make it more
clear for lower EL initialisation.
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
---
arch/aarch64/boot.S | 33 ++++++++++++++++++++++-----------
arch/aarch64/include/asm/cpu.h | 3 +++
arch/aarch64/psci.S | 13 +++++++------
arch/aarch64/spin.S | 8 ++++----
4 files changed, 36 insertions(+), 21 deletions(-)
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index a9264de..e4f5f3d 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -12,7 +12,7 @@
.section .init
.globl _start
- .globl jump_kernel
+ .globl jump_kernel
_start:
cpuid x0, x1
@@ -22,20 +22,31 @@ _start:
bl setup_stack
/*
- * EL3 initialisation
+ * Boot sequence
+ * If CurrentEL == EL3, then goto EL3 initialisation and drop to
+ * lower EL before entering the kernel.
+ * Else, no initialisation and keep the current EL before
+ * entering the kernel.
*/
mrs x0, CurrentEL
cmp x0, #CURRENTEL_EL3
- b.eq 1f
+ beq el3_init
+ /*
+ * We stay in the current EL for entering the kernel
+ */
mov w0, #1
- ldr x1, =flag_no_el3
+ ldr x1, =flag_keep_el
str w0, [x1]
bl setup_stack
- b start_no_el3
+ b start_keep_el
-1: mov x0, #0x30 // RES1
+ /*
+ * EL3 initialisation
+ */
+el3_init:
+ mov x0, #0x30 // RES1
orr x0, x0, #(1 << 0) // Non-secure EL1
orr x0, x0, #(1 << 8) // HVC enable
@@ -114,7 +125,7 @@ _start:
bl gic_secure_init
- b start_el3
+ b start_el_max
err_invalid_id:
b .
@@ -141,7 +152,7 @@ jump_kernel:
bl find_logical_id
bl setup_stack // Reset stack pointer
- ldr w0, flag_no_el3
+ ldr w0, flag_keep_el
cmp w0, #0 // Prepare Z flag
mov x0, x20
@@ -150,9 +161,9 @@ jump_kernel:
mov x3, x23
b.eq 1f
- br x19 // No EL3
+ br x19 // Keep current EL
-1: mov x4, #SPSR_KERNEL
+1: ldr w4, #SPSR_KERNEL
/*
* If bit 0 of the kernel address is set, we're entering in AArch32
@@ -168,5 +179,5 @@ jump_kernel:
.data
.align 3
-flag_no_el3:
+flag_keep_el:
.long 0
diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
index ccb5397..2b3a0a4 100644
--- a/arch/aarch64/include/asm/cpu.h
+++ b/arch/aarch64/include/asm/cpu.h
@@ -11,6 +11,7 @@
#define MPIDR_ID_BITS 0xff00ffffff
+#define CURRENTEL_EL2 (2 << 2)
#define CURRENTEL_EL3 (3 << 2)
/*
@@ -24,6 +25,7 @@
#define SPSR_I (1 << 7) /* IRQ masked */
#define SPSR_F (1 << 6) /* FIQ masked */
#define SPSR_T (1 << 5) /* Thumb */
+#define SPSR_EL1H (5 << 0) /* EL1 Handler mode */
#define SPSR_EL2H (9 << 0) /* EL2 Handler mode */
#define SPSR_HYP (0x1a << 0) /* M[3:0] = hyp, M[4] = AArch32 */
@@ -42,6 +44,7 @@
#else
#define SCTLR_EL1_RESET SCTLR_EL1_RES1
#define SPSR_KERNEL (SPSR_A | SPSR_D | SPSR_I | SPSR_F | SPSR_EL2H)
+#define SPSR_KERNEL_EL1 (SPSR_A | SPSR_D | SPSR_I | SPSR_F | SPSR_EL1H)
#endif
#ifndef __ASSEMBLY__
diff --git a/arch/aarch64/psci.S b/arch/aarch64/psci.S
index 01ebe7d..ae02fd6 100644
--- a/arch/aarch64/psci.S
+++ b/arch/aarch64/psci.S
@@ -45,8 +45,8 @@ vector:
.text
- .globl start_no_el3
- .globl start_el3
+ .globl start_keep_el
+ .globl start_el_max
err_exception:
b err_exception
@@ -101,7 +101,7 @@ smc_exit:
eret
-start_el3:
+start_el_max:
ldr x0, =vector
bl setup_vector
@@ -111,10 +111,11 @@ start_el3:
b psci_first_spin
/*
- * This PSCI implementation requires EL3. Without EL3 we'll only boot the
- * primary cpu, all others will be trapped in an infinite loop.
+ * This PSCI implementation requires the highest EL(EL3 or Armv8-R EL2).
+ * Without the highest EL, we'll only boot the primary cpu, all others
+ * will be trapped in an infinite loop.
*/
-start_no_el3:
+start_keep_el:
cpuid x0, x1
bl find_logical_id
cbz x0, psci_first_spin
diff --git a/arch/aarch64/spin.S b/arch/aarch64/spin.S
index 72603cf..533177c 100644
--- a/arch/aarch64/spin.S
+++ b/arch/aarch64/spin.S
@@ -11,11 +11,11 @@
.text
- .globl start_no_el3
- .globl start_el3
+ .globl start_keep_el
+ .globl start_el_max
-start_el3:
-start_no_el3:
+start_el_max:
+start_keep_el:
cpuid x0, x1
bl find_logical_id
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [boot-wrapper PATCH v2 3/8] aarch64: Remove the redundant setup_stack
2021-05-21 10:47 [boot-wrapper PATCH v2 0/8] Add Armv8-R AArch64 support Jaxson Han
2021-05-21 10:48 ` [boot-wrapper PATCH v2 1/8] Decouple V2M_SYS config by auto-detect dtb node Jaxson Han
2021-05-21 10:48 ` [boot-wrapper PATCH v2 2/8] aarch64: Rename labels and prepare for lower EL booting Jaxson Han
@ 2021-05-21 10:48 ` Jaxson Han
2021-05-24 9:32 ` Andre Przywara
2021-05-21 10:48 ` [boot-wrapper PATCH v2 4/8] aarch64: Prepare for EL1 booting Jaxson Han
` (4 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Jaxson Han @ 2021-05-21 10:48 UTC (permalink / raw)
To: mark.rutland, andre.przywara; +Cc: linux-arm-kernel, wei.chen, jaxson.han
Since we already have set up a stack above, there is no need to do it
again.
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
---
arch/aarch64/boot.S | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index e4f5f3d..ee9886b 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -39,7 +39,6 @@ _start:
ldr x1, =flag_keep_el
str w0, [x1]
- bl setup_stack
b start_keep_el
/*
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [boot-wrapper PATCH v2 4/8] aarch64: Prepare for EL1 booting
2021-05-21 10:47 [boot-wrapper PATCH v2 0/8] Add Armv8-R AArch64 support Jaxson Han
` (2 preceding siblings ...)
2021-05-21 10:48 ` [boot-wrapper PATCH v2 3/8] aarch64: Remove the redundant setup_stack Jaxson Han
@ 2021-05-21 10:48 ` Jaxson Han
2021-05-24 9:32 ` Andre Przywara
2021-05-21 10:48 ` [boot-wrapper PATCH v2 5/8] aarch64: Prepare for lower EL booting Jaxson Han
` (3 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Jaxson Han @ 2021-05-21 10:48 UTC (permalink / raw)
To: mark.rutland, andre.przywara; +Cc: linux-arm-kernel, wei.chen, jaxson.han
When booting from EL1, add a check and skip the init of
sctlr_el2 in jump_kernel
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
---
arch/aarch64/boot.S | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index ee9886b..b8f9e4e 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -144,10 +144,14 @@ jump_kernel:
ldr x0, =SCTLR_EL1_RESET
msr sctlr_el1, x0
+ mrs x0, CurrentEL
+ cmp x0, #CURRENTEL_EL2
+ b.lt 1f
+
ldr x0, =SCTLR_EL2_RESET
msr sctlr_el2, x0
- cpuid x0, x1
+1: cpuid x0, x1
bl find_logical_id
bl setup_stack // Reset stack pointer
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [boot-wrapper PATCH v2 5/8] aarch64: Prepare for lower EL booting
2021-05-21 10:47 [boot-wrapper PATCH v2 0/8] Add Armv8-R AArch64 support Jaxson Han
` (3 preceding siblings ...)
2021-05-21 10:48 ` [boot-wrapper PATCH v2 4/8] aarch64: Prepare for EL1 booting Jaxson Han
@ 2021-05-21 10:48 ` Jaxson Han
2021-05-24 9:33 ` Andre Przywara
2021-05-21 10:48 ` [boot-wrapper PATCH v2 6/8] gic-v3: Prepare for gicv3 with EL2 Jaxson Han
` (2 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Jaxson Han @ 2021-05-21 10:48 UTC (permalink / raw)
To: mark.rutland, andre.przywara; +Cc: linux-arm-kernel, wei.chen, jaxson.han
Save SPSR_KERNEL into spsr_to_elx during el3_init.
The jump_kernel will load spsr_to_elx into spsr_el3.
This change will make it easier to control whether drop to lower EL
before jumping to the kernel.
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
---
arch/aarch64/boot.S | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index b8f9e4e..5600859 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -118,7 +118,16 @@ el3_init:
mov x0, #ZCR_EL3_LEN_MASK // SVE: Enable full vector len
msr ZCR_EL3, x0 // for EL2.
-1:
+ /*
+ * Save SPSR_KERNEL into spsr_to_elx.
+ * The jump_kernel will load spsr_to_elx into spsr_el3
+ */
+1: mov w0, #SPSR_KERNEL
+ ldr x1, =spsr_to_elx
+ str w0, [x1]
+ b el_max_init
+
+el_max_init:
ldr x0, =CNTFRQ
msr cntfrq_el0, x0
@@ -166,7 +175,7 @@ jump_kernel:
b.eq 1f
br x19 // Keep current EL
-1: ldr w4, #SPSR_KERNEL
+1: ldr w4, spsr_to_elx
/*
* If bit 0 of the kernel address is set, we're entering in AArch32
@@ -184,3 +193,5 @@ jump_kernel:
.align 3
flag_keep_el:
.long 0
+spsr_to_elx:
+ .long 0
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [boot-wrapper PATCH v2 6/8] gic-v3: Prepare for gicv3 with EL2
2021-05-21 10:47 [boot-wrapper PATCH v2 0/8] Add Armv8-R AArch64 support Jaxson Han
` (4 preceding siblings ...)
2021-05-21 10:48 ` [boot-wrapper PATCH v2 5/8] aarch64: Prepare for lower EL booting Jaxson Han
@ 2021-05-21 10:48 ` Jaxson Han
2021-05-24 9:33 ` Andre Przywara
2021-05-21 10:48 ` [boot-wrapper PATCH v2 7/8] aarch64: Prepare for booting " Jaxson Han
2021-05-21 10:48 ` [boot-wrapper PATCH v2 8/8] aarch64: Introduce EL2 boot code for Armv8-R AArch64 Jaxson Han
7 siblings, 1 reply; 18+ messages in thread
From: Jaxson Han @ 2021-05-21 10:48 UTC (permalink / raw)
To: mark.rutland, andre.przywara; +Cc: linux-arm-kernel, wei.chen, jaxson.han
This is a preparation for allowing boot-wrapper configuring the gicv3
with EL2.
When confiuring with EL2, since there is no ICC_CTLR_EL2, the
ICC_CTLR_EL3 cannot be replaced with ICC_CTLR_EL2 simply.
See [https://developer.arm.com/documentation/ihi0069/latest/].
As the caller, gic_secure_init expects the ICC_CTLR to be written,
we change the function into gic_init_icc_ctlr(). In the GIC spec,
the r/w bits in this register ([6:0]) either affect EL3 IRQ routing
(not applicable since no EL3), non-secure IRQ handling (not applicable
since only secure state in Armv8-R aarch64), or are aliased to
ICC_CTLR_EL1 bits.
So, based on this, the new gic_init_icc_ctlr() would be:
When currentEL is EL3, init ICC_CTLR_EL3 as before.
When currentEL is not EL3, init ICC_CTLR_EL1 with ICC_CTLR_EL1_RESET.
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
---
arch/aarch32/include/asm/gic-v3.h | 7 ++++++
arch/aarch64/include/asm/gic-v3.h | 38 ++++++++++++++++++++++++++++---
gic-v3.c | 2 +-
3 files changed, 43 insertions(+), 4 deletions(-)
diff --git a/arch/aarch32/include/asm/gic-v3.h b/arch/aarch32/include/asm/gic-v3.h
index ec9a327..86abe09 100644
--- a/arch/aarch32/include/asm/gic-v3.h
+++ b/arch/aarch32/include/asm/gic-v3.h
@@ -9,6 +9,8 @@
#ifndef __ASM_AARCH32_GICV3_H
#define __ASM_AARCH32_GICV3_H
+#define ICC_CTLR_RESET (0UL)
+
static inline uint32_t gic_read_icc_sre(void)
{
uint32_t val;
@@ -26,4 +28,9 @@ static inline void gic_write_icc_ctlr(uint32_t val)
asm volatile ("mcr p15, 6, %0, c12, c12, 4" : : "r" (val));
}
+static inline void gic_init_icc_ctlr()
+{
+ gic_write_icc_ctlr(ICC_CTLR_RESET);
+}
+
#endif
diff --git a/arch/aarch64/include/asm/gic-v3.h b/arch/aarch64/include/asm/gic-v3.h
index e743c02..b3dfbd3 100644
--- a/arch/aarch64/include/asm/gic-v3.h
+++ b/arch/aarch64/include/asm/gic-v3.h
@@ -15,21 +15,53 @@
#define ICC_CTLR_EL3 "S3_6_C12_C12_4"
#define ICC_PMR_EL1 "S3_0_C4_C6_0"
+#define ICC_CTLR_EL3_RESET (0UL)
+#define ICC_CTLR_EL1_RESET (0UL)
+
+static inline uint32_t current_el(void)
+{
+ uint32_t val;
+
+ asm volatile ("mrs %0, CurrentEL" : "=r" (val));
+ return val;
+}
+
static inline uint32_t gic_read_icc_sre(void)
{
uint32_t val;
- asm volatile ("mrs %0, " ICC_SRE_EL3 : "=r" (val));
+
+ if(current_el() == CURRENTEL_EL3)
+ asm volatile ("mrs %0, " ICC_SRE_EL3 : "=r" (val));
+ else
+ asm volatile ("mrs %0, " ICC_SRE_EL2 : "=r" (val));
+
return val;
}
static inline void gic_write_icc_sre(uint32_t val)
{
- asm volatile ("msr " ICC_SRE_EL3 ", %0" : : "r" (val));
+ if(current_el() == CURRENTEL_EL3)
+ asm volatile ("msr " ICC_SRE_EL3 ", %0" : : "r" (val));
+ else
+ asm volatile ("msr " ICC_SRE_EL2 ", %0" : : "r" (val));
}
-static inline void gic_write_icc_ctlr(uint32_t val)
+static inline void gic_write_icc_ctlr_el3(uint32_t val)
{
asm volatile ("msr " ICC_CTLR_EL3 ", %0" : : "r" (val));
}
+static inline void gic_write_icc_ctlr_el1(uint32_t val)
+{
+ asm volatile ("msr " ICC_CTLR_EL1 ", %0" : : "r" (val));
+}
+
+static inline void gic_init_icc_ctlr()
+{
+ if(current_el() == CURRENTEL_EL3)
+ gic_write_icc_ctlr_el3(ICC_CTLR_EL3_RESET);
+ else
+ gic_write_icc_ctlr_el1(ICC_CTLR_EL1_RESET);
+}
+
#endif
diff --git a/gic-v3.c b/gic-v3.c
index ae2d2bc..4850572 100644
--- a/gic-v3.c
+++ b/gic-v3.c
@@ -121,6 +121,6 @@ void gic_secure_init(void)
gic_write_icc_sre(sre);
isb();
- gic_write_icc_ctlr(0);
+ gic_init_icc_ctlr();
isb();
}
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [boot-wrapper PATCH v2 7/8] aarch64: Prepare for booting with EL2
2021-05-21 10:47 [boot-wrapper PATCH v2 0/8] Add Armv8-R AArch64 support Jaxson Han
` (5 preceding siblings ...)
2021-05-21 10:48 ` [boot-wrapper PATCH v2 6/8] gic-v3: Prepare for gicv3 with EL2 Jaxson Han
@ 2021-05-21 10:48 ` Jaxson Han
2021-05-24 9:33 ` Andre Przywara
2021-05-21 10:48 ` [boot-wrapper PATCH v2 8/8] aarch64: Introduce EL2 boot code for Armv8-R AArch64 Jaxson Han
7 siblings, 1 reply; 18+ messages in thread
From: Jaxson Han @ 2021-05-21 10:48 UTC (permalink / raw)
To: mark.rutland, andre.przywara; +Cc: linux-arm-kernel, wei.chen, jaxson.han
Prepare for allowing boot-wrapper to be entered in EL2.
Detect current EL and set the corresponding EL registers.
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
---
arch/aarch64/boot.S | 8 ++++++++
arch/aarch64/utils.S | 10 +++++++++-
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 5600859..14fd9cf 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -183,10 +183,18 @@ jump_kernel:
*/
bfi x4, x19, #5, #1
+ mrs x5, CurrentEL
+ cmp x5, #CURRENTEL_EL2
+ b.eq 1f
+
msr elr_el3, x19
msr spsr_el3, x4
eret
+1: msr elr_el2, x19
+ msr spsr_el2, x4
+ eret
+
.ltorg
.data
diff --git a/arch/aarch64/utils.S b/arch/aarch64/utils.S
index ae22ea7..94e9931 100644
--- a/arch/aarch64/utils.S
+++ b/arch/aarch64/utils.S
@@ -37,10 +37,18 @@ find_logical_id:
ret
/*
- * Setup EL3 vectors
+ * Setup EL3/EL2 vectors
* x0: vector address
*/
setup_vector:
+ mrs x1, CurrentEL
+ cmp x1, #CURRENTEL_EL2
+ b.eq 1f
+
msr VBAR_EL3, x0
isb
ret
+
+1: msr VBAR_EL2, x0
+ isb
+ ret
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [boot-wrapper PATCH v2 8/8] aarch64: Introduce EL2 boot code for Armv8-R AArch64
2021-05-21 10:47 [boot-wrapper PATCH v2 0/8] Add Armv8-R AArch64 support Jaxson Han
` (6 preceding siblings ...)
2021-05-21 10:48 ` [boot-wrapper PATCH v2 7/8] aarch64: Prepare for booting " Jaxson Han
@ 2021-05-21 10:48 ` Jaxson Han
2021-05-24 10:19 ` Andre Przywara
7 siblings, 1 reply; 18+ messages in thread
From: Jaxson Han @ 2021-05-21 10:48 UTC (permalink / raw)
To: mark.rutland, andre.przywara; +Cc: linux-arm-kernel, wei.chen, jaxson.han
The Armv8-R AArch64 profile does not support the EL3 exception level.
The Armv8-R AArch64 profile allows for an (optional) VMSAv8-64 MMU
at EL1, which allows to run off-the-shelf Linux. However EL2 only
supports a PMSA, which is not supported by Linux, so we need to drop
into EL1 before entering the kernel.
We add a new err_invalid_arch symbol as a dead loop. If we detect the
current Armv8-R aarch64 only supports with PMSA, meaning we cannot boot
Linux anymore, then we jump to err_invalid_arch.
During Armv8-R aarch64 init, to make sure nothing unexpected traps into
EL2, we auto-detect and config FIEN and EnSCXT in HCR_EL2.
The boot sequence is:
If CurrentEL == EL3, then goto EL3 initialisation and drop to lower EL
before entering the kernel.
If CurrentEL == EL2 && id_aa64mmfr0_el1.MSA == 0xf (Armv8-R aarch64),
if id_aa64mmfr0_el1.MSA_frac == 0x2,
then goto Armv8-R AArch64 initialisation and drop to EL1 before
entering the kernel.
else, which means VMSA unsupported and cannot boot Linux,
goto err_invalid_arch (dead loop).
Else, no initialisation and keep the current EL before entering the
kernel.
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
---
arch/aarch64/boot.S | 87 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 85 insertions(+), 2 deletions(-)
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
index 14fd9cf..0339e19 100644
--- a/arch/aarch64/boot.S
+++ b/arch/aarch64/boot.S
@@ -25,16 +25,24 @@ _start:
* Boot sequence
* If CurrentEL == EL3, then goto EL3 initialisation and drop to
* lower EL before entering the kernel.
+ * If CurrentEL == EL2 && id_aa64mmfr0_el1.MSA == 0xf, then
+ * If id_aa64mmfr0_el1.MSA_frac == 0x2, then goto
+ * Armv8-R AArch64 initialisation and drop to EL1 before
+ * entering the kernel.
+ * Else, which means VMSA unsupported and cannot boot Linux,
+ * goto err_invalid_arch (dead loop).
* Else, no initialisation and keep the current EL before
* entering the kernel.
*/
mrs x0, CurrentEL
- cmp x0, #CURRENTEL_EL3
- beq el3_init
+ cmp x0, #CURRENTEL_EL2
+ bgt el3_init
+ beq el2_init
/*
* We stay in the current EL for entering the kernel
*/
+keep_el:
mov w0, #1
ldr x1, =flag_keep_el
str w0, [x1]
@@ -127,6 +135,80 @@ el3_init:
str w0, [x1]
b el_max_init
+ /*
+ * EL2 Armv8-R AArch64 initialisation
+ */
+el2_init:
+ /* Detect Armv8-R AArch64 */
+ mrs x1, id_aa64mmfr0_el1
+ /*
+ * Check MSA, bits [51:48]:
+ * 0xf means Armv8-R AArch64.
+ * If not 0xf, goto keep_el.
+ */
+ ubfx x0, x1, #48, #4 // MSA
+ cmp x0, 0xf
+ bne keep_el
+ /*
+ * Check MSA_frac, bits [55:52]:
+ * 0x2 means EL1&0 translation regime also supports VMSAv8-64.
+ */
+ ubfx x0, x1, #52, #4 // MSA_frac
+ cmp x0, 0x2
+ /* If not 0x2, no VMSA, so cannot boot Linux and dead loop. */
+ bne err_invalid_arch
+
+ mrs x0, midr_el1
+ msr vpidr_el2, x0
+
+ mrs x0, mpidr_el1
+ msr vmpidr_el2, x0
+
+ mov x0, #(1 << 31) // VTCR_MSA: VMSAv8-64 support
+ msr vtcr_el2, x0
+
+ /* Init HCR_EL2 */
+ mov x0, #(1 << 31) // RES1
+
+ mrs x1, id_aa64pfr0_el1
+ ubfx x2, x1, #56, 4
+ cmp x2, 0x2
+ bne 1f
+ /*
+ * Disable trap when accessing SCTXNUM_EL0 or SCTXNUM_EL1
+ * if FEAT_CSV2.
+ */
+ orr x0, x0, #(1 << 53) // EnSCXT
+
+1: ubfx x2, x1, #28, 4
+ cmp x2, 0x2
+ bne 1f
+ /* Disable trap when accessing ERXPFGCDN_EL1 if FEAT_RASv1p1. */
+ orr x0, x0, #(1 << 47) // FIEN
+
+ /* Enable pointer authentication if present */
+1: mrs x1, id_aa64isar1_el1
+ /*
+ * If ID_AA64ISAR1_EL1.{GPI, GPA, API, APA} == {0000, 0000, 0000, 0000}
+ * then HCR_EL2.APK and HCR_EL2.API are RES 0.
+ * Else
+ * set HCR_EL2.APK and HCR_EL2.API.
+ */
+ ldr x2, =(((0xff) << 24) | (0xff << 4))
+ and x1, x1, x2
+ cbz x1, 1f
+
+ orr x0, x0, #(1 << 40) // APK
+ orr x0, x0, #(1 << 41) // API
+
+1: msr hcr_el2, x0
+ isb
+
+ mov w0, #SPSR_KERNEL_EL1
+ ldr x1, =spsr_to_elx
+ str w0, [x1]
+ // fall through
+
el_max_init:
ldr x0, =CNTFRQ
msr cntfrq_el0, x0
@@ -136,6 +218,7 @@ el_max_init:
b start_el_max
err_invalid_id:
+err_invalid_arch:
b .
/*
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [boot-wrapper PATCH v2 2/8] aarch64: Rename labels and prepare for lower EL booting
2021-05-21 10:48 ` [boot-wrapper PATCH v2 2/8] aarch64: Rename labels and prepare for lower EL booting Jaxson Han
@ 2021-05-24 9:32 ` Andre Przywara
2021-05-25 1:54 ` Jaxson Han
0 siblings, 1 reply; 18+ messages in thread
From: Andre Przywara @ 2021-05-24 9:32 UTC (permalink / raw)
To: Jaxson Han; +Cc: mark.rutland, linux-arm-kernel, wei.chen
On Fri, 21 May 2021 18:48:01 +0800
Jaxson Han <jaxson.han@arm.com> wrote:
> Prepare for booting from lower EL. Rename *_el3 relavant labels with
> *_el_max and *_no_el3 with *_keep_el. Since the original _no_el3 means
> "We neither do init sequence at this highest EL nor drop to lower EL
> when entering to kernel", we rename it with _keep_el to make it more
> clear for lower EL initialisation.
Thanks for splitting out this patch, I verified that most of it is
indeed just renames, apart from the things below:
>
> Signed-off-by: Jaxson Han <jaxson.han@arm.com>
> ---
> arch/aarch64/boot.S | 33 ++++++++++++++++++++++-----------
> arch/aarch64/include/asm/cpu.h | 3 +++
> arch/aarch64/psci.S | 13 +++++++------
> arch/aarch64/spin.S | 8 ++++----
> 4 files changed, 36 insertions(+), 21 deletions(-)
>
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index a9264de..e4f5f3d 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -12,7 +12,7 @@
> .section .init
>
> .globl _start
> - .globl jump_kernel
> + .globl jump_kernel
>
> _start:
> cpuid x0, x1
> @@ -22,20 +22,31 @@ _start:
> bl setup_stack
>
> /*
> - * EL3 initialisation
> + * Boot sequence
> + * If CurrentEL == EL3, then goto EL3 initialisation and drop to
> + * lower EL before entering the kernel.
> + * Else, no initialisation and keep the current EL before
> + * entering the kernel.
> */
> mrs x0, CurrentEL
> cmp x0, #CURRENTEL_EL3
> - b.eq 1f
> + beq el3_init
>
> + /*
> + * We stay in the current EL for entering the kernel
> + */
> mov w0, #1
> - ldr x1, =flag_no_el3
> + ldr x1, =flag_keep_el
> str w0, [x1]
>
> bl setup_stack
> - b start_no_el3
> + b start_keep_el
>
> -1: mov x0, #0x30 // RES1
> + /*
> + * EL3 initialisation
> + */
> +el3_init:
> + mov x0, #0x30 // RES1
> orr x0, x0, #(1 << 0) // Non-secure EL1
> orr x0, x0, #(1 << 8) // HVC enable
>
> @@ -114,7 +125,7 @@ _start:
>
> bl gic_secure_init
>
> - b start_el3
> + b start_el_max
>
> err_invalid_id:
> b .
> @@ -141,7 +152,7 @@ jump_kernel:
> bl find_logical_id
> bl setup_stack // Reset stack pointer
>
> - ldr w0, flag_no_el3
> + ldr w0, flag_keep_el
> cmp w0, #0 // Prepare Z flag
>
> mov x0, x20
> @@ -150,9 +161,9 @@ jump_kernel:
> mov x3, x23
>
> b.eq 1f
> - br x19 // No EL3
> + br x19 // Keep current EL
>
> -1: mov x4, #SPSR_KERNEL
> +1: ldr w4, #SPSR_KERNEL
This looks both premature and wrong: The value of SPSR_KERNEL doesn't
change here, so doesn't need any change in this instruction. Plus: ldr
without '=' requires an address, not a value, and this in fact already
breaks compilation:
arch/aarch64/boot.S:166: Error: immediate value must be a multiple of 4 at operand 2 -- `ldr w4,#((1<<8)|(1<<9)|(1<<7)|(1<<6)|(9<<0))'
So please remove this change, and also the changes in cpu.h below, and
introduce them only when they are actually needed.
Apart from the rest is then really just renames.
Cheers,
Andre
>
> /*
> * If bit 0 of the kernel address is set, we're entering in AArch32
> @@ -168,5 +179,5 @@ jump_kernel:
>
> .data
> .align 3
> -flag_no_el3:
> +flag_keep_el:
> .long 0
> diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
> index ccb5397..2b3a0a4 100644
> --- a/arch/aarch64/include/asm/cpu.h
> +++ b/arch/aarch64/include/asm/cpu.h
> @@ -11,6 +11,7 @@
>
> #define MPIDR_ID_BITS 0xff00ffffff
>
> +#define CURRENTEL_EL2 (2 << 2)
> #define CURRENTEL_EL3 (3 << 2)
>
> /*
> @@ -24,6 +25,7 @@
> #define SPSR_I (1 << 7) /* IRQ masked */
> #define SPSR_F (1 << 6) /* FIQ masked */
> #define SPSR_T (1 << 5) /* Thumb */
> +#define SPSR_EL1H (5 << 0) /* EL1 Handler mode */
> #define SPSR_EL2H (9 << 0) /* EL2 Handler mode */
> #define SPSR_HYP (0x1a << 0) /* M[3:0] = hyp, M[4] = AArch32 */
>
> @@ -42,6 +44,7 @@
> #else
> #define SCTLR_EL1_RESET SCTLR_EL1_RES1
> #define SPSR_KERNEL (SPSR_A | SPSR_D | SPSR_I | SPSR_F | SPSR_EL2H)
> +#define SPSR_KERNEL_EL1 (SPSR_A | SPSR_D | SPSR_I | SPSR_F | SPSR_EL1H)
> #endif
>
> #ifndef __ASSEMBLY__
> diff --git a/arch/aarch64/psci.S b/arch/aarch64/psci.S
> index 01ebe7d..ae02fd6 100644
> --- a/arch/aarch64/psci.S
> +++ b/arch/aarch64/psci.S
> @@ -45,8 +45,8 @@ vector:
>
> .text
>
> - .globl start_no_el3
> - .globl start_el3
> + .globl start_keep_el
> + .globl start_el_max
>
> err_exception:
> b err_exception
> @@ -101,7 +101,7 @@ smc_exit:
> eret
>
>
> -start_el3:
> +start_el_max:
> ldr x0, =vector
> bl setup_vector
>
> @@ -111,10 +111,11 @@ start_el3:
> b psci_first_spin
>
> /*
> - * This PSCI implementation requires EL3. Without EL3 we'll only boot the
> - * primary cpu, all others will be trapped in an infinite loop.
> + * This PSCI implementation requires the highest EL(EL3 or Armv8-R EL2).
> + * Without the highest EL, we'll only boot the primary cpu, all others
> + * will be trapped in an infinite loop.
> */
> -start_no_el3:
> +start_keep_el:
> cpuid x0, x1
> bl find_logical_id
> cbz x0, psci_first_spin
> diff --git a/arch/aarch64/spin.S b/arch/aarch64/spin.S
> index 72603cf..533177c 100644
> --- a/arch/aarch64/spin.S
> +++ b/arch/aarch64/spin.S
> @@ -11,11 +11,11 @@
>
> .text
>
> - .globl start_no_el3
> - .globl start_el3
> + .globl start_keep_el
> + .globl start_el_max
>
> -start_el3:
> -start_no_el3:
> +start_el_max:
> +start_keep_el:
> cpuid x0, x1
> bl find_logical_id
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [boot-wrapper PATCH v2 3/8] aarch64: Remove the redundant setup_stack
2021-05-21 10:48 ` [boot-wrapper PATCH v2 3/8] aarch64: Remove the redundant setup_stack Jaxson Han
@ 2021-05-24 9:32 ` Andre Przywara
0 siblings, 0 replies; 18+ messages in thread
From: Andre Przywara @ 2021-05-24 9:32 UTC (permalink / raw)
To: Jaxson Han; +Cc: mark.rutland, linux-arm-kernel, wei.chen
On Fri, 21 May 2021 18:48:02 +0800
Jaxson Han <jaxson.han@arm.com> wrote:
> Since we already have set up a stack above, there is no need to do it
> again.
Indeed, in fact it's a bug: setup_stack expects the logical CPU ID in
w0, and here we always call it with w0 being 1.
> Signed-off-by: Jaxson Han <jaxson.han@arm.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Thanks!
Andre
> ---
> arch/aarch64/boot.S | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index e4f5f3d..ee9886b 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -39,7 +39,6 @@ _start:
> ldr x1, =flag_keep_el
> str w0, [x1]
>
> - bl setup_stack
> b start_keep_el
>
> /*
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [boot-wrapper PATCH v2 4/8] aarch64: Prepare for EL1 booting
2021-05-21 10:48 ` [boot-wrapper PATCH v2 4/8] aarch64: Prepare for EL1 booting Jaxson Han
@ 2021-05-24 9:32 ` Andre Przywara
0 siblings, 0 replies; 18+ messages in thread
From: Andre Przywara @ 2021-05-24 9:32 UTC (permalink / raw)
To: Jaxson Han; +Cc: mark.rutland, linux-arm-kernel, wei.chen
On Fri, 21 May 2021 18:48:03 +0800
Jaxson Han <jaxson.han@arm.com> wrote:
> When booting from EL1, add a check and skip the init of
> sctlr_el2 in jump_kernel
>
> Signed-off-by: Jaxson Han <jaxson.han@arm.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Cheers,
Andre
> ---
> arch/aarch64/boot.S | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index ee9886b..b8f9e4e 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -144,10 +144,14 @@ jump_kernel:
> ldr x0, =SCTLR_EL1_RESET
> msr sctlr_el1, x0
>
> + mrs x0, CurrentEL
> + cmp x0, #CURRENTEL_EL2
> + b.lt 1f
> +
> ldr x0, =SCTLR_EL2_RESET
> msr sctlr_el2, x0
>
> - cpuid x0, x1
> +1: cpuid x0, x1
> bl find_logical_id
> bl setup_stack // Reset stack pointer
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [boot-wrapper PATCH v2 5/8] aarch64: Prepare for lower EL booting
2021-05-21 10:48 ` [boot-wrapper PATCH v2 5/8] aarch64: Prepare for lower EL booting Jaxson Han
@ 2021-05-24 9:33 ` Andre Przywara
0 siblings, 0 replies; 18+ messages in thread
From: Andre Przywara @ 2021-05-24 9:33 UTC (permalink / raw)
To: Jaxson Han; +Cc: mark.rutland, linux-arm-kernel, wei.chen
On Fri, 21 May 2021 18:48:04 +0800
Jaxson Han <jaxson.han@arm.com> wrote:
Hi,
> Save SPSR_KERNEL into spsr_to_elx during el3_init.
> The jump_kernel will load spsr_to_elx into spsr_el3.
>
> This change will make it easier to control whether drop to lower EL
> before jumping to the kernel.
Looks good, but this needs some adaption after fixing patch 2/8:
>
> Signed-off-by: Jaxson Han <jaxson.han@arm.com>
> ---
> arch/aarch64/boot.S | 15 +++++++++++++--
> 1 file changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index b8f9e4e..5600859 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -118,7 +118,16 @@ el3_init:
> mov x0, #ZCR_EL3_LEN_MASK // SVE: Enable full vector len
> msr ZCR_EL3, x0 // for EL2.
>
> -1:
> + /*
> + * Save SPSR_KERNEL into spsr_to_elx.
> + * The jump_kernel will load spsr_to_elx into spsr_el3
> + */
> +1: mov w0, #SPSR_KERNEL
> + ldr x1, =spsr_to_elx
> + str w0, [x1]
> + b el_max_init
> +
> +el_max_init:
> ldr x0, =CNTFRQ
> msr cntfrq_el0, x0
>
> @@ -166,7 +175,7 @@ jump_kernel:
> b.eq 1f
> br x19 // Keep current EL
>
> -1: ldr w4, #SPSR_KERNEL
> +1: ldr w4, spsr_to_elx
This would be the place where you change the original "mov x4,
#SPSR_KERNEL" line into this one here (and not in patch 2).
With that fixed:
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Cheers,
Andre
>
> /*
> * If bit 0 of the kernel address is set, we're entering in AArch32
> @@ -184,3 +193,5 @@ jump_kernel:
> .align 3
> flag_keep_el:
> .long 0
> +spsr_to_elx:
> + .long 0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [boot-wrapper PATCH v2 6/8] gic-v3: Prepare for gicv3 with EL2
2021-05-21 10:48 ` [boot-wrapper PATCH v2 6/8] gic-v3: Prepare for gicv3 with EL2 Jaxson Han
@ 2021-05-24 9:33 ` Andre Przywara
0 siblings, 0 replies; 18+ messages in thread
From: Andre Przywara @ 2021-05-24 9:33 UTC (permalink / raw)
To: Jaxson Han; +Cc: mark.rutland, linux-arm-kernel, wei.chen
On Fri, 21 May 2021 18:48:05 +0800
Jaxson Han <jaxson.han@arm.com> wrote:
Hi,
> This is a preparation for allowing boot-wrapper configuring the gicv3
> with EL2.
>
> When confiuring with EL2, since there is no ICC_CTLR_EL2, the
> ICC_CTLR_EL3 cannot be replaced with ICC_CTLR_EL2 simply.
> See [https://developer.arm.com/documentation/ihi0069/latest/].
>
> As the caller, gic_secure_init expects the ICC_CTLR to be written,
> we change the function into gic_init_icc_ctlr(). In the GIC spec,
> the r/w bits in this register ([6:0]) either affect EL3 IRQ routing
> (not applicable since no EL3), non-secure IRQ handling (not applicable
> since only secure state in Armv8-R aarch64), or are aliased to
> ICC_CTLR_EL1 bits.
> So, based on this, the new gic_init_icc_ctlr() would be:
> When currentEL is EL3, init ICC_CTLR_EL3 as before.
> When currentEL is not EL3, init ICC_CTLR_EL1 with ICC_CTLR_EL1_RESET.
Looks good, thanks!
>
> Signed-off-by: Jaxson Han <jaxson.han@arm.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Cheers,
Andre
> ---
> arch/aarch32/include/asm/gic-v3.h | 7 ++++++
> arch/aarch64/include/asm/gic-v3.h | 38 ++++++++++++++++++++++++++++---
> gic-v3.c | 2 +-
> 3 files changed, 43 insertions(+), 4 deletions(-)
>
> diff --git a/arch/aarch32/include/asm/gic-v3.h b/arch/aarch32/include/asm/gic-v3.h
> index ec9a327..86abe09 100644
> --- a/arch/aarch32/include/asm/gic-v3.h
> +++ b/arch/aarch32/include/asm/gic-v3.h
> @@ -9,6 +9,8 @@
> #ifndef __ASM_AARCH32_GICV3_H
> #define __ASM_AARCH32_GICV3_H
>
> +#define ICC_CTLR_RESET (0UL)
> +
> static inline uint32_t gic_read_icc_sre(void)
> {
> uint32_t val;
> @@ -26,4 +28,9 @@ static inline void gic_write_icc_ctlr(uint32_t val)
> asm volatile ("mcr p15, 6, %0, c12, c12, 4" : : "r" (val));
> }
>
> +static inline void gic_init_icc_ctlr()
> +{
> + gic_write_icc_ctlr(ICC_CTLR_RESET);
> +}
> +
> #endif
> diff --git a/arch/aarch64/include/asm/gic-v3.h b/arch/aarch64/include/asm/gic-v3.h
> index e743c02..b3dfbd3 100644
> --- a/arch/aarch64/include/asm/gic-v3.h
> +++ b/arch/aarch64/include/asm/gic-v3.h
> @@ -15,21 +15,53 @@
> #define ICC_CTLR_EL3 "S3_6_C12_C12_4"
> #define ICC_PMR_EL1 "S3_0_C4_C6_0"
>
> +#define ICC_CTLR_EL3_RESET (0UL)
> +#define ICC_CTLR_EL1_RESET (0UL)
> +
> +static inline uint32_t current_el(void)
> +{
> + uint32_t val;
> +
> + asm volatile ("mrs %0, CurrentEL" : "=r" (val));
> + return val;
> +}
> +
> static inline uint32_t gic_read_icc_sre(void)
> {
> uint32_t val;
> - asm volatile ("mrs %0, " ICC_SRE_EL3 : "=r" (val));
> +
> + if(current_el() == CURRENTEL_EL3)
> + asm volatile ("mrs %0, " ICC_SRE_EL3 : "=r" (val));
> + else
> + asm volatile ("mrs %0, " ICC_SRE_EL2 : "=r" (val));
> +
> return val;
> }
>
> static inline void gic_write_icc_sre(uint32_t val)
> {
> - asm volatile ("msr " ICC_SRE_EL3 ", %0" : : "r" (val));
> + if(current_el() == CURRENTEL_EL3)
> + asm volatile ("msr " ICC_SRE_EL3 ", %0" : : "r" (val));
> + else
> + asm volatile ("msr " ICC_SRE_EL2 ", %0" : : "r" (val));
> }
>
> -static inline void gic_write_icc_ctlr(uint32_t val)
> +static inline void gic_write_icc_ctlr_el3(uint32_t val)
> {
> asm volatile ("msr " ICC_CTLR_EL3 ", %0" : : "r" (val));
> }
>
> +static inline void gic_write_icc_ctlr_el1(uint32_t val)
> +{
> + asm volatile ("msr " ICC_CTLR_EL1 ", %0" : : "r" (val));
> +}
> +
> +static inline void gic_init_icc_ctlr()
> +{
> + if(current_el() == CURRENTEL_EL3)
> + gic_write_icc_ctlr_el3(ICC_CTLR_EL3_RESET);
> + else
> + gic_write_icc_ctlr_el1(ICC_CTLR_EL1_RESET);
> +}
> +
> #endif
> diff --git a/gic-v3.c b/gic-v3.c
> index ae2d2bc..4850572 100644
> --- a/gic-v3.c
> +++ b/gic-v3.c
> @@ -121,6 +121,6 @@ void gic_secure_init(void)
> gic_write_icc_sre(sre);
> isb();
>
> - gic_write_icc_ctlr(0);
> + gic_init_icc_ctlr();
> isb();
> }
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [boot-wrapper PATCH v2 7/8] aarch64: Prepare for booting with EL2
2021-05-21 10:48 ` [boot-wrapper PATCH v2 7/8] aarch64: Prepare for booting " Jaxson Han
@ 2021-05-24 9:33 ` Andre Przywara
0 siblings, 0 replies; 18+ messages in thread
From: Andre Przywara @ 2021-05-24 9:33 UTC (permalink / raw)
To: Jaxson Han; +Cc: mark.rutland, linux-arm-kernel, wei.chen
On Fri, 21 May 2021 18:48:06 +0800
Jaxson Han <jaxson.han@arm.com> wrote:
> Prepare for allowing boot-wrapper to be entered in EL2.
> Detect current EL and set the corresponding EL registers.
>
> Signed-off-by: Jaxson Han <jaxson.han@arm.com>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Cheers,
Andre
> ---
> arch/aarch64/boot.S | 8 ++++++++
> arch/aarch64/utils.S | 10 +++++++++-
> 2 files changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index 5600859..14fd9cf 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -183,10 +183,18 @@ jump_kernel:
> */
> bfi x4, x19, #5, #1
>
> + mrs x5, CurrentEL
> + cmp x5, #CURRENTEL_EL2
> + b.eq 1f
> +
> msr elr_el3, x19
> msr spsr_el3, x4
> eret
>
> +1: msr elr_el2, x19
> + msr spsr_el2, x4
> + eret
> +
> .ltorg
>
> .data
> diff --git a/arch/aarch64/utils.S b/arch/aarch64/utils.S
> index ae22ea7..94e9931 100644
> --- a/arch/aarch64/utils.S
> +++ b/arch/aarch64/utils.S
> @@ -37,10 +37,18 @@ find_logical_id:
> ret
>
> /*
> - * Setup EL3 vectors
> + * Setup EL3/EL2 vectors
> * x0: vector address
> */
> setup_vector:
> + mrs x1, CurrentEL
> + cmp x1, #CURRENTEL_EL2
> + b.eq 1f
> +
> msr VBAR_EL3, x0
> isb
> ret
> +
> +1: msr VBAR_EL2, x0
> + isb
> + ret
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [boot-wrapper PATCH v2 8/8] aarch64: Introduce EL2 boot code for Armv8-R AArch64
2021-05-21 10:48 ` [boot-wrapper PATCH v2 8/8] aarch64: Introduce EL2 boot code for Armv8-R AArch64 Jaxson Han
@ 2021-05-24 10:19 ` Andre Przywara
2021-05-25 1:59 ` Jaxson Han
0 siblings, 1 reply; 18+ messages in thread
From: Andre Przywara @ 2021-05-24 10:19 UTC (permalink / raw)
To: Jaxson Han; +Cc: mark.rutland, linux-arm-kernel, wei.chen
On Fri, 21 May 2021 18:48:07 +0800
Jaxson Han <jaxson.han@arm.com> wrote:
Hi,
> The Armv8-R AArch64 profile does not support the EL3 exception level.
> The Armv8-R AArch64 profile allows for an (optional) VMSAv8-64 MMU
> at EL1, which allows to run off-the-shelf Linux. However EL2 only
> supports a PMSA, which is not supported by Linux, so we need to drop
> into EL1 before entering the kernel.
>
> We add a new err_invalid_arch symbol as a dead loop. If we detect the
> current Armv8-R aarch64 only supports with PMSA, meaning we cannot boot
> Linux anymore, then we jump to err_invalid_arch.
>
> During Armv8-R aarch64 init, to make sure nothing unexpected traps into
> EL2, we auto-detect and config FIEN and EnSCXT in HCR_EL2.
>
> The boot sequence is:
> If CurrentEL == EL3, then goto EL3 initialisation and drop to lower EL
> before entering the kernel.
> If CurrentEL == EL2 && id_aa64mmfr0_el1.MSA == 0xf (Armv8-R aarch64),
> if id_aa64mmfr0_el1.MSA_frac == 0x2,
> then goto Armv8-R AArch64 initialisation and drop to EL1 before
> entering the kernel.
> else, which means VMSA unsupported and cannot boot Linux,
> goto err_invalid_arch (dead loop).
> Else, no initialisation and keep the current EL before entering the
> kernel.
This looks good in general, thanks for the commit message and the
comments inline. Some smaller things below:
>
> Signed-off-by: Jaxson Han <jaxson.han@arm.com>
> ---
> arch/aarch64/boot.S | 87 +++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 85 insertions(+), 2 deletions(-)
>
> diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
> index 14fd9cf..0339e19 100644
> --- a/arch/aarch64/boot.S
> +++ b/arch/aarch64/boot.S
> @@ -25,16 +25,24 @@ _start:
> * Boot sequence
> * If CurrentEL == EL3, then goto EL3 initialisation and drop to
> * lower EL before entering the kernel.
> + * If CurrentEL == EL2 && id_aa64mmfr0_el1.MSA == 0xf, then
> + * If id_aa64mmfr0_el1.MSA_frac == 0x2, then goto
> + * Armv8-R AArch64 initialisation and drop to EL1 before
> + * entering the kernel.
> + * Else, which means VMSA unsupported and cannot boot Linux,
> + * goto err_invalid_arch (dead loop).
> * Else, no initialisation and keep the current EL before
> * entering the kernel.
> */
> mrs x0, CurrentEL
> - cmp x0, #CURRENTEL_EL3
> - beq el3_init
> + cmp x0, #CURRENTEL_EL2
> + bgt el3_init
> + beq el2_init
>
> /*
> * We stay in the current EL for entering the kernel
> */
> +keep_el:
> mov w0, #1
> ldr x1, =flag_keep_el
> str w0, [x1]
> @@ -127,6 +135,80 @@ el3_init:
> str w0, [x1]
> b el_max_init
>
> + /*
> + * EL2 Armv8-R AArch64 initialisation
> + */
> +el2_init:
> + /* Detect Armv8-R AArch64 */
> + mrs x1, id_aa64mmfr0_el1
> + /*
> + * Check MSA, bits [51:48]:
> + * 0xf means Armv8-R AArch64.
> + * If not 0xf, goto keep_el.
Can you please change this last line to:
"If not 0xf, proceed in ARMv8-A EL2."
> + */
> + ubfx x0, x1, #48, #4 // MSA
> + cmp x0, 0xf
> + bne keep_el
> + /*
> + * Check MSA_frac, bits [55:52]:
> + * 0x2 means EL1&0 translation regime also supports VMSAv8-64.
> + */
> + ubfx x0, x1, #52, #4 // MSA_frac
> + cmp x0, 0x2
> + /* If not 0x2, no VMSA, so cannot boot Linux and dead loop. */
> + bne err_invalid_arch
The architecture guarantees that those CPUID fields never lose features
when the value in a field increases. So there might be some 0x3 feature
addition in the future, which wouldn't be covered right now.
So can you please change this branch to "b.lt" instead?
> +
> + mrs x0, midr_el1
> + msr vpidr_el2, x0
> +
> + mrs x0, mpidr_el1
> + msr vmpidr_el2, x0
> +
> + mov x0, #(1 << 31) // VTCR_MSA: VMSAv8-64 support
> + msr vtcr_el2, x0
> +
> + /* Init HCR_EL2 */
> + mov x0, #(1 << 31) // RES1
Please add to the comment that it's RES1 in ARMv8-R64 only.
> +
> + mrs x1, id_aa64pfr0_el1
> + ubfx x2, x1, #56, 4
Can you please add the CSV2 name of the field as a comment here?
> + cmp x2, 0x2
> + bne 1f
To stay compatible with future additions to the CSV2 field, please use
b.lt here.
> + /*
> + * Disable trap when accessing SCTXNUM_EL0 or SCTXNUM_EL1
> + * if FEAT_CSV2.
> + */
> + orr x0, x0, #(1 << 53) // EnSCXT
> +
> +1: ubfx x2, x1, #28, 4
> + cmp x2, 0x2
> + bne 1f
As above: b.lt.
Rest looks fine to me, compared the bits and values to the manuals.
Thanks,
Andre
> + /* Disable trap when accessing ERXPFGCDN_EL1 if FEAT_RASv1p1. */
> + orr x0, x0, #(1 << 47) // FIEN
> +
> + /* Enable pointer authentication if present */
> +1: mrs x1, id_aa64isar1_el1
> + /*
> + * If ID_AA64ISAR1_EL1.{GPI, GPA, API, APA} == {0000, 0000, 0000, 0000}
> + * then HCR_EL2.APK and HCR_EL2.API are RES 0.
> + * Else
> + * set HCR_EL2.APK and HCR_EL2.API.
> + */
> + ldr x2, =(((0xff) << 24) | (0xff << 4))
> + and x1, x1, x2
> + cbz x1, 1f
> +
> + orr x0, x0, #(1 << 40) // APK
> + orr x0, x0, #(1 << 41) // API
> +
> +1: msr hcr_el2, x0
> + isb
> +
> + mov w0, #SPSR_KERNEL_EL1
> + ldr x1, =spsr_to_elx
> + str w0, [x1]
> + // fall through
> +
> el_max_init:
> ldr x0, =CNTFRQ
> msr cntfrq_el0, x0
> @@ -136,6 +218,7 @@ el_max_init:
> b start_el_max
>
> err_invalid_id:
> +err_invalid_arch:
> b .
>
> /*
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 18+ messages in thread
* RE: [boot-wrapper PATCH v2 2/8] aarch64: Rename labels and prepare for lower EL booting
2021-05-24 9:32 ` Andre Przywara
@ 2021-05-25 1:54 ` Jaxson Han
0 siblings, 0 replies; 18+ messages in thread
From: Jaxson Han @ 2021-05-25 1:54 UTC (permalink / raw)
To: Andre Przywara; +Cc: Mark Rutland, linux-arm-kernel, Wei Chen
Hi Andre,
> -----Original Message-----
> From: Andre Przywara <andre.przywara@arm.com>
> Sent: Monday, May 24, 2021 5:32 PM
> To: Jaxson Han <Jaxson.Han@arm.com>
> Cc: Mark Rutland <Mark.Rutland@arm.com>; linux-arm-
> kernel@lists.infradead.org; Wei Chen <Wei.Chen@arm.com>
> Subject: Re: [boot-wrapper PATCH v2 2/8] aarch64: Rename labels and
> prepare for lower EL booting
>
> On Fri, 21 May 2021 18:48:01 +0800
> Jaxson Han <jaxson.han@arm.com> wrote:
>
> > Prepare for booting from lower EL. Rename *_el3 relavant labels with
> > *_el_max and *_no_el3 with *_keep_el. Since the original _no_el3 means
> > "We neither do init sequence at this highest EL nor drop to lower EL
> > when entering to kernel", we rename it with _keep_el to make it more
> > clear for lower EL initialisation.
>
> Thanks for splitting out this patch, I verified that most of it is indeed just
> renames, apart from the things below:
>
> >
> > Signed-off-by: Jaxson Han <jaxson.han@arm.com>
> > ---
> > arch/aarch64/boot.S | 33 ++++++++++++++++++++++-----------
> > arch/aarch64/include/asm/cpu.h | 3 +++
> > arch/aarch64/psci.S | 13 +++++++------
> > arch/aarch64/spin.S | 8 ++++----
> > 4 files changed, 36 insertions(+), 21 deletions(-)
> >
> > diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S index
> > a9264de..e4f5f3d 100644
> > --- a/arch/aarch64/boot.S
> > +++ b/arch/aarch64/boot.S
> > @@ -12,7 +12,7 @@
> > .section .init
> >
> > .globl _start
> > - .globl jump_kernel
> > + .globl jump_kernel
> >
> > _start:
> > cpuid x0, x1
> > @@ -22,20 +22,31 @@ _start:
> > bl setup_stack
> >
> > /*
> > - * EL3 initialisation
> > + * Boot sequence
> > + * If CurrentEL == EL3, then goto EL3 initialisation and drop to
> > + * lower EL before entering the kernel.
> > + * Else, no initialisation and keep the current EL before
> > + * entering the kernel.
> > */
> > mrs x0, CurrentEL
> > cmp x0, #CURRENTEL_EL3
> > - b.eq 1f
> > + beq el3_init
> >
> > + /*
> > + * We stay in the current EL for entering the kernel
> > + */
> > mov w0, #1
> > - ldr x1, =flag_no_el3
> > + ldr x1, =flag_keep_el
> > str w0, [x1]
> >
> > bl setup_stack
> > - b start_no_el3
> > + b start_keep_el
> >
> > -1: mov x0, #0x30 // RES1
> > + /*
> > + * EL3 initialisation
> > + */
> > +el3_init:
> > + mov x0, #0x30 // RES1
> > orr x0, x0, #(1 << 0) // Non-secure EL1
> > orr x0, x0, #(1 << 8) // HVC enable
> >
> > @@ -114,7 +125,7 @@ _start:
> >
> > bl gic_secure_init
> >
> > - b start_el3
> > + b start_el_max
> >
> > err_invalid_id:
> > b .
> > @@ -141,7 +152,7 @@ jump_kernel:
> > bl find_logical_id
> > bl setup_stack // Reset stack pointer
> >
> > - ldr w0, flag_no_el3
> > + ldr w0, flag_keep_el
> > cmp w0, #0 // Prepare Z flag
> >
> > mov x0, x20
> > @@ -150,9 +161,9 @@ jump_kernel:
> > mov x3, x23
> >
> > b.eq 1f
> > - br x19 // No EL3
> > + br x19 // Keep current EL
> >
> > -1: mov x4, #SPSR_KERNEL
> > +1: ldr w4, #SPSR_KERNEL
>
> This looks both premature and wrong: The value of SPSR_KERNEL doesn't
> change here, so doesn't need any change in this instruction. Plus: ldr without
> '=' requires an address, not a value, and this in fact already breaks
> compilation:
> arch/aarch64/boot.S:166: Error: immediate value must be a multiple of 4 at
> operand 2 -- `ldr w4,#((1<<8)|(1<<9)|(1<<7)|(1<<6)|(9<<0))'
>
> So please remove this change, and also the changes in cpu.h below, and
> introduce them only when they are actually needed.
>
> Apart from the rest is then really just renames.
Right, I made a mistake. I will fix this and move them into patch 5.
Thanks,
Jaxson
>
> Cheers,
> Andre
>
>
> >
> > /*
> > * If bit 0 of the kernel address is set, we're entering in AArch32
> > @@ -168,5 +179,5 @@ jump_kernel:
> >
> > .data
> > .align 3
> > -flag_no_el3:
> > +flag_keep_el:
> > .long 0
> > diff --git a/arch/aarch64/include/asm/cpu.h
> > b/arch/aarch64/include/asm/cpu.h index ccb5397..2b3a0a4 100644
> > --- a/arch/aarch64/include/asm/cpu.h
> > +++ b/arch/aarch64/include/asm/cpu.h
> > @@ -11,6 +11,7 @@
> >
> > #define MPIDR_ID_BITS 0xff00ffffff
> >
> > +#define CURRENTEL_EL2 (2 << 2)
> > #define CURRENTEL_EL3 (3 << 2)
> >
> > /*
> > @@ -24,6 +25,7 @@
> > #define SPSR_I (1 << 7) /* IRQ masked */
> > #define SPSR_F (1 << 6) /* FIQ masked */
> > #define SPSR_T (1 << 5) /* Thumb */
> > +#define SPSR_EL1H (5 << 0) /* EL1 Handler mode */
> > #define SPSR_EL2H (9 << 0) /* EL2 Handler mode */
> > #define SPSR_HYP (0x1a << 0) /* M[3:0] = hyp, M[4] =
> AArch32 */
> >
> > @@ -42,6 +44,7 @@
> > #else
> > #define SCTLR_EL1_RESET SCTLR_EL1_RES1
> > #define SPSR_KERNEL (SPSR_A | SPSR_D | SPSR_I | SPSR_F |
> SPSR_EL2H)
> > +#define SPSR_KERNEL_EL1 (SPSR_A | SPSR_D | SPSR_I | SPSR_F |
> SPSR_EL1H)
> > #endif
> >
> > #ifndef __ASSEMBLY__
> > diff --git a/arch/aarch64/psci.S b/arch/aarch64/psci.S index
> > 01ebe7d..ae02fd6 100644
> > --- a/arch/aarch64/psci.S
> > +++ b/arch/aarch64/psci.S
> > @@ -45,8 +45,8 @@ vector:
> >
> > .text
> >
> > - .globl start_no_el3
> > - .globl start_el3
> > + .globl start_keep_el
> > + .globl start_el_max
> >
> > err_exception:
> > b err_exception
> > @@ -101,7 +101,7 @@ smc_exit:
> > eret
> >
> >
> > -start_el3:
> > +start_el_max:
> > ldr x0, =vector
> > bl setup_vector
> >
> > @@ -111,10 +111,11 @@ start_el3:
> > b psci_first_spin
> >
> > /*
> > - * This PSCI implementation requires EL3. Without EL3 we'll only boot
> > the
> > - * primary cpu, all others will be trapped in an infinite loop.
> > + * This PSCI implementation requires the highest EL(EL3 or Armv8-R EL2).
> > + * Without the highest EL, we'll only boot the primary cpu, all
> > + others
> > + * will be trapped in an infinite loop.
> > */
> > -start_no_el3:
> > +start_keep_el:
> > cpuid x0, x1
> > bl find_logical_id
> > cbz x0, psci_first_spin
> > diff --git a/arch/aarch64/spin.S b/arch/aarch64/spin.S index
> > 72603cf..533177c 100644
> > --- a/arch/aarch64/spin.S
> > +++ b/arch/aarch64/spin.S
> > @@ -11,11 +11,11 @@
> >
> > .text
> >
> > - .globl start_no_el3
> > - .globl start_el3
> > + .globl start_keep_el
> > + .globl start_el_max
> >
> > -start_el3:
> > -start_no_el3:
> > +start_el_max:
> > +start_keep_el:
> > cpuid x0, x1
> > bl find_logical_id
> >
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 18+ messages in thread
* RE: [boot-wrapper PATCH v2 8/8] aarch64: Introduce EL2 boot code for Armv8-R AArch64
2021-05-24 10:19 ` Andre Przywara
@ 2021-05-25 1:59 ` Jaxson Han
0 siblings, 0 replies; 18+ messages in thread
From: Jaxson Han @ 2021-05-25 1:59 UTC (permalink / raw)
To: Andre Przywara; +Cc: Mark Rutland, linux-arm-kernel, Wei Chen
Hi Andre,
> -----Original Message-----
> From: Andre Przywara <andre.przywara@arm.com>
> Sent: Monday, May 24, 2021 6:20 PM
> To: Jaxson Han <Jaxson.Han@arm.com>
> Cc: Mark Rutland <Mark.Rutland@arm.com>; linux-arm-
> kernel@lists.infradead.org; Wei Chen <Wei.Chen@arm.com>
> Subject: Re: [boot-wrapper PATCH v2 8/8] aarch64: Introduce EL2 boot code
> for Armv8-R AArch64
>
> On Fri, 21 May 2021 18:48:07 +0800
> Jaxson Han <jaxson.han@arm.com> wrote:
>
> Hi,
>
> > The Armv8-R AArch64 profile does not support the EL3 exception level.
> > The Armv8-R AArch64 profile allows for an (optional) VMSAv8-64 MMU at
> > EL1, which allows to run off-the-shelf Linux. However EL2 only
> > supports a PMSA, which is not supported by Linux, so we need to drop
> > into EL1 before entering the kernel.
> >
> > We add a new err_invalid_arch symbol as a dead loop. If we detect the
> > current Armv8-R aarch64 only supports with PMSA, meaning we cannot
> > boot Linux anymore, then we jump to err_invalid_arch.
> >
> > During Armv8-R aarch64 init, to make sure nothing unexpected traps
> > into EL2, we auto-detect and config FIEN and EnSCXT in HCR_EL2.
> >
> > The boot sequence is:
> > If CurrentEL == EL3, then goto EL3 initialisation and drop to lower EL
> > before entering the kernel.
> > If CurrentEL == EL2 && id_aa64mmfr0_el1.MSA == 0xf (Armv8-R aarch64),
> > if id_aa64mmfr0_el1.MSA_frac == 0x2,
> > then goto Armv8-R AArch64 initialisation and drop to EL1 before
> > entering the kernel.
> > else, which means VMSA unsupported and cannot boot Linux,
> > goto err_invalid_arch (dead loop).
> > Else, no initialisation and keep the current EL before entering the
> > kernel.
>
> This looks good in general, thanks for the commit message and the
> comments inline. Some smaller things below:
>
> >
> > Signed-off-by: Jaxson Han <jaxson.han@arm.com>
> > ---
> > arch/aarch64/boot.S | 87
> > +++++++++++++++++++++++++++++++++++++++++++--
> > 1 file changed, 85 insertions(+), 2 deletions(-)
> >
> > diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S index
> > 14fd9cf..0339e19 100644
> > --- a/arch/aarch64/boot.S
> > +++ b/arch/aarch64/boot.S
> > @@ -25,16 +25,24 @@ _start:
> > * Boot sequence
> > * If CurrentEL == EL3, then goto EL3 initialisation and drop to
> > * lower EL before entering the kernel.
> > + * If CurrentEL == EL2 && id_aa64mmfr0_el1.MSA == 0xf, then
> > + * If id_aa64mmfr0_el1.MSA_frac == 0x2, then goto
> > + * Armv8-R AArch64 initialisation and drop to EL1 before
> > + * entering the kernel.
> > + * Else, which means VMSA unsupported and cannot boot Linux,
> > + * goto err_invalid_arch (dead loop).
> > * Else, no initialisation and keep the current EL before
> > * entering the kernel.
> > */
> > mrs x0, CurrentEL
> > - cmp x0, #CURRENTEL_EL3
> > - beq el3_init
> > + cmp x0, #CURRENTEL_EL2
> > + bgt el3_init
> > + beq el2_init
> >
> > /*
> > * We stay in the current EL for entering the kernel
> > */
> > +keep_el:
> > mov w0, #1
> > ldr x1, =flag_keep_el
> > str w0, [x1]
> > @@ -127,6 +135,80 @@ el3_init:
> > str w0, [x1]
> > b el_max_init
> >
> > + /*
> > + * EL2 Armv8-R AArch64 initialisation
> > + */
> > +el2_init:
> > + /* Detect Armv8-R AArch64 */
> > + mrs x1, id_aa64mmfr0_el1
> > + /*
> > + * Check MSA, bits [51:48]:
> > + * 0xf means Armv8-R AArch64.
> > + * If not 0xf, goto keep_el.
>
> Can you please change this last line to:
> "If not 0xf, proceed in ARMv8-A EL2."
>
> > + */
> > + ubfx x0, x1, #48, #4 // MSA
> > + cmp x0, 0xf
> > + bne keep_el
> > + /*
> > + * Check MSA_frac, bits [55:52]:
> > + * 0x2 means EL1&0 translation regime also supports VMSAv8-64.
> > + */
> > + ubfx x0, x1, #52, #4 // MSA_frac
> > + cmp x0, 0x2
> > + /* If not 0x2, no VMSA, so cannot boot Linux and dead loop. */
> > + bne err_invalid_arch
>
> The architecture guarantees that those CPUID fields never lose features
> when the value in a field increases. So there might be some 0x3 feature
> addition in the future, which wouldn't be covered right now.
> So can you please change this branch to "b.lt" instead?
Yes, I will change it.
>
> > +
> > + mrs x0, midr_el1
> > + msr vpidr_el2, x0
> > +
> > + mrs x0, mpidr_el1
> > + msr vmpidr_el2, x0
> > +
> > + mov x0, #(1 << 31) // VTCR_MSA: VMSAv8-64
> support
> > + msr vtcr_el2, x0
> > +
> > + /* Init HCR_EL2 */
> > + mov x0, #(1 << 31) // RES1
>
> Please add to the comment that it's RES1 in ARMv8-R64 only.
Yes, no problem.
>
> > +
> > + mrs x1, id_aa64pfr0_el1
> > + ubfx x2, x1, #56, 4
>
> Can you please add the CSV2 name of the field as a comment here?
Yes I will
>
> > + cmp x2, 0x2
> > + bne 1f
>
> To stay compatible with future additions to the CSV2 field, please use b.lt
> here.
No problem
>
> > + /*
> > + * Disable trap when accessing SCTXNUM_EL0 or SCTXNUM_EL1
> > + * if FEAT_CSV2.
> > + */
> > + orr x0, x0, #(1 << 53) // EnSCXT
> > +
> > +1: ubfx x2, x1, #28, 4
> > + cmp x2, 0x2
> > + bne 1f
>
> As above: b.lt.
Yes I will
Thanks,
Jaxson
>
> Rest looks fine to me, compared the bits and values to the manuals.
>
> Thanks,
> Andre
>
> > + /* Disable trap when accessing ERXPFGCDN_EL1 if FEAT_RASv1p1. */
> > + orr x0, x0, #(1 << 47) // FIEN
> > +
> > + /* Enable pointer authentication if present */
> > +1: mrs x1, id_aa64isar1_el1
> > + /*
> > + * If ID_AA64ISAR1_EL1.{GPI, GPA, API, APA} == {0000, 0000, 0000,
> 0000}
> > + * then HCR_EL2.APK and HCR_EL2.API are RES 0.
> > + * Else
> > + * set HCR_EL2.APK and HCR_EL2.API.
> > + */
> > + ldr x2, =(((0xff) << 24) | (0xff << 4))
> > + and x1, x1, x2
> > + cbz x1, 1f
> > +
> > + orr x0, x0, #(1 << 40) // APK
> > + orr x0, x0, #(1 << 41) // API
> > +
> > +1: msr hcr_el2, x0
> > + isb
> > +
> > + mov w0, #SPSR_KERNEL_EL1
> > + ldr x1, =spsr_to_elx
> > + str w0, [x1]
> > + // fall through
> > +
> > el_max_init:
> > ldr x0, =CNTFRQ
> > msr cntfrq_el0, x0
> > @@ -136,6 +218,7 @@ el_max_init:
> > b start_el_max
> >
> > err_invalid_id:
> > +err_invalid_arch:
> > b .
> >
> > /*
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2021-05-25 3:32 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-21 10:47 [boot-wrapper PATCH v2 0/8] Add Armv8-R AArch64 support Jaxson Han
2021-05-21 10:48 ` [boot-wrapper PATCH v2 1/8] Decouple V2M_SYS config by auto-detect dtb node Jaxson Han
2021-05-21 10:48 ` [boot-wrapper PATCH v2 2/8] aarch64: Rename labels and prepare for lower EL booting Jaxson Han
2021-05-24 9:32 ` Andre Przywara
2021-05-25 1:54 ` Jaxson Han
2021-05-21 10:48 ` [boot-wrapper PATCH v2 3/8] aarch64: Remove the redundant setup_stack Jaxson Han
2021-05-24 9:32 ` Andre Przywara
2021-05-21 10:48 ` [boot-wrapper PATCH v2 4/8] aarch64: Prepare for EL1 booting Jaxson Han
2021-05-24 9:32 ` Andre Przywara
2021-05-21 10:48 ` [boot-wrapper PATCH v2 5/8] aarch64: Prepare for lower EL booting Jaxson Han
2021-05-24 9:33 ` Andre Przywara
2021-05-21 10:48 ` [boot-wrapper PATCH v2 6/8] gic-v3: Prepare for gicv3 with EL2 Jaxson Han
2021-05-24 9:33 ` Andre Przywara
2021-05-21 10:48 ` [boot-wrapper PATCH v2 7/8] aarch64: Prepare for booting " Jaxson Han
2021-05-24 9:33 ` Andre Przywara
2021-05-21 10:48 ` [boot-wrapper PATCH v2 8/8] aarch64: Introduce EL2 boot code for Armv8-R AArch64 Jaxson Han
2021-05-24 10:19 ` Andre Przywara
2021-05-25 1:59 ` Jaxson Han
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.