Initial commit
This commit is contained in:
+135
@@ -0,0 +1,135 @@
|
||||
From 545f6950ae4dc55b4974986aa9629adb16eaf4e1 Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Tue, 25 May 2021 07:25:00 +0100
|
||||
Subject: [PATCH] aarch64: Rename labels and prepare for lower EL booting
|
||||
|
||||
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.
|
||||
|
||||
Upstream-Status: Pending
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
---
|
||||
arch/aarch64/boot.S | 28 ++++++++++++++++++++--------
|
||||
arch/aarch64/psci.S | 9 +++++----
|
||||
arch/aarch64/spin.S | 4 ++--
|
||||
3 files changed, 27 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
|
||||
index d682ba5..fab694e 100644
|
||||
--- a/arch/aarch64/boot.S
|
||||
+++ b/arch/aarch64/boot.S
|
||||
@@ -34,18 +34,30 @@ ASM_FUNC(_start)
|
||||
|
||||
/*
|
||||
* 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
|
||||
+ b.eq 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]
|
||||
|
||||
- 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
|
||||
|
||||
@@ -145,7 +157,7 @@ ASM_FUNC(_start)
|
||||
|
||||
bl gic_secure_init
|
||||
|
||||
- b start_el3
|
||||
+ b start_el_max
|
||||
|
||||
err_invalid_id:
|
||||
b .
|
||||
@@ -172,7 +184,7 @@ ASM_FUNC(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
|
||||
@@ -181,7 +193,7 @@ ASM_FUNC(jump_kernel)
|
||||
mov x3, x23
|
||||
|
||||
b.eq 1f
|
||||
- br x19 // No EL3
|
||||
+ br x19 // Keep current EL
|
||||
|
||||
1: mov x4, #SPSR_KERNEL
|
||||
|
||||
@@ -199,5 +211,5 @@ ASM_FUNC(jump_kernel)
|
||||
|
||||
.data
|
||||
.align 3
|
||||
-flag_no_el3:
|
||||
+flag_keep_el:
|
||||
.long 0
|
||||
diff --git a/arch/aarch64/psci.S b/arch/aarch64/psci.S
|
||||
index 8bd224b..7b8919a 100644
|
||||
--- a/arch/aarch64/psci.S
|
||||
+++ b/arch/aarch64/psci.S
|
||||
@@ -79,7 +79,7 @@ smc_exit:
|
||||
ldp x18, x19, [sp], #16
|
||||
eret
|
||||
|
||||
-ASM_FUNC(start_el3)
|
||||
+ASM_FUNC(start_el_max)
|
||||
ldr x0, =vector
|
||||
bl setup_vector
|
||||
|
||||
@@ -89,10 +89,11 @@ ASM_FUNC(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 othersr
|
||||
+ * will be trapped in an infinite loop.
|
||||
*/
|
||||
-ASM_FUNC(start_no_el3)
|
||||
+ASM_FUNC(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 1ea1c0b..bfb1d47 100644
|
||||
--- a/arch/aarch64/spin.S
|
||||
+++ b/arch/aarch64/spin.S
|
||||
@@ -12,8 +12,8 @@
|
||||
|
||||
.text
|
||||
|
||||
-ASM_FUNC(start_el3)
|
||||
-ASM_FUNC(start_no_el3)
|
||||
+ASM_FUNC(start_el_max)
|
||||
+ASM_FUNC(start_keep_el)
|
||||
cpuid x0, x1
|
||||
bl find_logical_id
|
||||
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
From bad32d3fc127a421be416b17e4f7d6d514f06abb Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Tue, 25 May 2021 07:25:00 +0100
|
||||
Subject: [PATCH] aarch64: Prepare for EL1 booting
|
||||
|
||||
When booting from EL1, add a check and skip the init of
|
||||
sctlr_el2 in jump_kernel
|
||||
|
||||
Upstream-Status: Pending
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
||||
---
|
||||
arch/aarch64/boot.S | 6 +++++-
|
||||
arch/aarch64/include/asm/cpu.h | 1 +
|
||||
2 files changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
|
||||
index fab694e..5105b41 100644
|
||||
--- a/arch/aarch64/boot.S
|
||||
+++ b/arch/aarch64/boot.S
|
||||
@@ -177,10 +177,14 @@ ASM_FUNC(jump_kernel)
|
||||
ldr x0, =SCTLR_EL1_KERNEL
|
||||
msr sctlr_el1, x0
|
||||
|
||||
+ mrs x0, CurrentEL
|
||||
+ cmp x0, #CURRENTEL_EL2
|
||||
+ b.lt 1f
|
||||
+
|
||||
ldr x0, =SCTLR_EL2_KERNEL
|
||||
msr sctlr_el2, x0
|
||||
|
||||
- cpuid x0, x1
|
||||
+1: cpuid x0, x1
|
||||
bl find_logical_id
|
||||
bl setup_stack // Reset stack pointer
|
||||
|
||||
diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
|
||||
index 49d3f86..3767da3 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)
|
||||
|
||||
/*
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
From 252cbd36e51414b60ab68306f9c38e358709494d Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Tue, 25 May 2021 07:25:00 +0100
|
||||
Subject: [PATCH] aarch64: Prepare for lower EL booting
|
||||
|
||||
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.
|
||||
|
||||
Upstream-Status: Pending
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
Reviewed-by: Andre Przywara <andre.przywara@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 5105b41..243198d 100644
|
||||
--- a/arch/aarch64/boot.S
|
||||
+++ b/arch/aarch64/boot.S
|
||||
@@ -151,7 +151,16 @@ el3_init:
|
||||
mov x0, #ZCR_EL3_LEN_MAX // 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, =COUNTER_FREQ
|
||||
msr cntfrq_el0, x0
|
||||
|
||||
@@ -199,7 +208,7 @@ ASM_FUNC(jump_kernel)
|
||||
b.eq 1f
|
||||
br x19 // Keep current EL
|
||||
|
||||
-1: mov x4, #SPSR_KERNEL
|
||||
+1: ldr w4, spsr_to_elx
|
||||
|
||||
/*
|
||||
* If bit 0 of the kernel address is set, we're entering in AArch32
|
||||
@@ -217,3 +226,5 @@ ASM_FUNC(jump_kernel)
|
||||
.align 3
|
||||
flag_keep_el:
|
||||
.long 0
|
||||
+spsr_to_elx:
|
||||
+ .long 0
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
From bff110a95a5e4c9db2d61e629b4aa4b84530201e Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Tue, 25 May 2021 07:25:00 +0100
|
||||
Subject: [PATCH] gic-v3: Prepare for gicv3 with EL2
|
||||
|
||||
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.
|
||||
|
||||
Upstream-Status: Pending
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
||||
---
|
||||
arch/aarch32/include/asm/gic-v3.h | 7 +++++++
|
||||
arch/aarch64/include/asm/gic-v3.h | 23 ++++++++++++++++++++---
|
||||
common/gic-v3.c | 2 +-
|
||||
3 files changed, 28 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/arch/aarch32/include/asm/gic-v3.h b/arch/aarch32/include/asm/gic-v3.h
|
||||
index 65f38de..11e7bc7 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 void gic_write_icc_sre(uint32_t val)
|
||||
{
|
||||
asm volatile ("mcr p15, 6, %0, c12, c12, 5" : : "r" (val));
|
||||
@@ -19,4 +21,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 5b32380..090ab0b 100644
|
||||
--- a/arch/aarch64/include/asm/gic-v3.h
|
||||
+++ b/arch/aarch64/include/asm/gic-v3.h
|
||||
@@ -15,14 +15,31 @@
|
||||
#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 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_init_icc_ctlr()
|
||||
{
|
||||
- asm volatile ("msr " ICC_CTLR_EL3 ", %0" : : "r" (val));
|
||||
+ if (current_el() == CURRENTEL_EL3)
|
||||
+ asm volatile ("msr " ICC_CTLR_EL3 ", %0" : : "r" (ICC_CTLR_EL3_RESET));
|
||||
+ else
|
||||
+ asm volatile ("msr " ICC_CTLR_EL1 ", %0" : : "r" (ICC_CTLR_EL1_RESET));
|
||||
}
|
||||
|
||||
#endif
|
||||
diff --git a/common/gic-v3.c b/common/gic-v3.c
|
||||
index 6207007..a0fe564 100644
|
||||
--- a/common/gic-v3.c
|
||||
+++ b/common/gic-v3.c
|
||||
@@ -117,6 +117,6 @@ void gic_secure_init(void)
|
||||
gic_write_icc_sre(ICC_SRE_Enable | ICC_SRE_DIB | ICC_SRE_DFB | ICC_SRE_SRE);
|
||||
isb();
|
||||
|
||||
- gic_write_icc_ctlr(0);
|
||||
+ gic_init_icc_ctlr();
|
||||
isb();
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
From ba955efb35ce1d41b562190d7c2fbcbcf8ef97ff Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Tue, 25 May 2021 07:25:00 +0100
|
||||
Subject: [PATCH] aarch64: Prepare for booting with EL2
|
||||
|
||||
Prepare for allowing boot-wrapper to be entered in EL2.
|
||||
Detect current EL and set the corresponding EL registers.
|
||||
|
||||
Upstream-Status: Pending
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
Reviewed-by: Andre Przywara <andre.przywara@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 243198d..3593ca5 100644
|
||||
--- a/arch/aarch64/boot.S
|
||||
+++ b/arch/aarch64/boot.S
|
||||
@@ -216,10 +216,18 @@ ASM_FUNC(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 85c7f8a..f02a249 100644
|
||||
--- a/arch/aarch64/utils.S
|
||||
+++ b/arch/aarch64/utils.S
|
||||
@@ -34,10 +34,18 @@ ASM_FUNC(find_logical_id)
|
||||
ret
|
||||
|
||||
/*
|
||||
- * Setup EL3 vectors
|
||||
+ * Setup EL3/EL2 vectors
|
||||
* x0: vector address
|
||||
*/
|
||||
ASM_FUNC(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
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
From 8e44fac113d935affed1550480631f3fe7f30584 Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Tue, 25 May 2021 07:25:00 +0100
|
||||
Subject: [PATCH] aarch64: Introduce EL2 boot code for Armv8-R AArch64
|
||||
|
||||
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.
|
||||
|
||||
Upstream-Status: Pending
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
---
|
||||
arch/aarch64/boot.S | 92 +++++++++++++++++++++++++++++++++-
|
||||
arch/aarch64/include/asm/cpu.h | 2 +
|
||||
2 files changed, 92 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
|
||||
index 3593ca5..a219ea7 100644
|
||||
--- a/arch/aarch64/boot.S
|
||||
+++ b/arch/aarch64/boot.S
|
||||
@@ -37,16 +37,24 @@ ASM_FUNC(_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
|
||||
- b.eq 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]
|
||||
@@ -160,6 +168,85 @@ 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, 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.
|
||||
+ * Also, since the architecture guarantees that those CPUID
|
||||
+ * fields never lose features when the value in a field
|
||||
+ * increases, we use blt to cover it.
|
||||
+ */
|
||||
+ blt 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: Armv8-R aarch64 only
|
||||
+
|
||||
+ mrs x1, id_aa64pfr0_el1
|
||||
+ ubfx x2, x1, #56, 4 // ID_AA64PFR0_EL1.CSV2
|
||||
+ cmp x2, 0x2
|
||||
+ b.lt 1f
|
||||
+ /*
|
||||
+ * Disable trap when accessing SCTXNUM_EL0 or SCTXNUM_EL1
|
||||
+ * if FEAT_CSV2.
|
||||
+ */
|
||||
+ orr x0, x0, #(1 << 53) // HCR_EL2.EnSCXT
|
||||
+
|
||||
+1: ubfx x2, x1, #28, 4 // ID_AA64PFR0_EL1.RAS
|
||||
+ cmp x2, 0x2
|
||||
+ b.lt 1f
|
||||
+ /* Disable trap when accessing ERXPFGCDN_EL1 if FEAT_RASv1p1. */
|
||||
+ orr x0, x0, #(1 << 47) // HCR_EL2.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) // HCR_EL2.APK
|
||||
+ orr x0, x0, #(1 << 41) // HCR_EL2.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, =COUNTER_FREQ
|
||||
msr cntfrq_el0, x0
|
||||
@@ -169,6 +256,7 @@ el_max_init:
|
||||
b start_el_max
|
||||
|
||||
err_invalid_id:
|
||||
+err_invalid_arch:
|
||||
b .
|
||||
|
||||
/*
|
||||
diff --git a/arch/aarch64/include/asm/cpu.h b/arch/aarch64/include/asm/cpu.h
|
||||
index 3767da3..3c0e00d 100644
|
||||
--- a/arch/aarch64/include/asm/cpu.h
|
||||
+++ b/arch/aarch64/include/asm/cpu.h
|
||||
@@ -25,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 */
|
||||
|
||||
@@ -50,6 +51,7 @@
|
||||
#else
|
||||
#define SCTLR_EL1_KERNEL 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__
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
From 0b9a966b8a28961b078215ee7169e32a976d5e7d Mon Sep 17 00:00:00 2001
|
||||
From: Qi Feng <qi.feng@arm.com>
|
||||
Date: Wed, 26 May 2021 17:52:01 +0800
|
||||
Subject: [PATCH] Allow --enable-psci to choose between smc and hvc
|
||||
|
||||
According to Armv8-R AArch64 manual [1], Armv8-R AArch64 does not
|
||||
support smc:
|
||||
|
||||
- Pseudocode for AArch64.CheckForSMCUndefOrTrap has this snippet:
|
||||
|
||||
if !HaveEL(EL3) || PSTATE.EL == EL0 then
|
||||
UNDEFINED;
|
||||
|
||||
And Armv8-R AArch64 does not have EL3.
|
||||
|
||||
- In the document of HCR_EL2 TSC bit:
|
||||
If EL3 is not implemented and HCR_EL2.NV is 0, it is IMPLEMENTATION
|
||||
DEFINED whether this bit is:
|
||||
- RES0.
|
||||
- Implemented with the functionality as described in HCR_EL2.TSC.
|
||||
|
||||
So hvc is needed in this situation. And due to the lack of libfdt, the
|
||||
psci method cannot be modified at runtime.
|
||||
|
||||
To use smc, use --enable-psci or --enable-psci=smc.
|
||||
To use hvc, use --enable-psci=hvc.
|
||||
|
||||
[1]: https://developer.arm.com/documentation/ddi0600/latest/
|
||||
|
||||
Issue-Id: SCM-2654
|
||||
Upstream-Status: Pending
|
||||
Signed-off-by: Qi Feng <qi.feng@arm.com>
|
||||
Change-Id: Ib8afabdad2d98bc37371d165bbb6f1f9b88bfc87
|
||||
|
||||
Upstream-Status: Pending
|
||||
Signed-off-by: Huifeng Zhang <Huifeng.Zhang@arm.com>
|
||||
---
|
||||
Makefile.am | 10 +++++-----
|
||||
configure.ac | 14 +++++++++-----
|
||||
2 files changed, 14 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 5731a19..fc66662 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -50,11 +50,11 @@ endif
|
||||
if PSCI
|
||||
ARCH_OBJ += psci.o
|
||||
COMMON_OBJ += psci.o
|
||||
-PSCI_NODE := psci { \
|
||||
- compatible = \"arm,psci\"; \
|
||||
- method = \"smc\"; \
|
||||
- cpu_on = <$(PSCI_CPU_ON)>; \
|
||||
- cpu_off = <$(PSCI_CPU_OFF)>; \
|
||||
+PSCI_NODE := psci { \
|
||||
+ compatible = \"arm,psci\"; \
|
||||
+ method = \"$(PSCI_METHOD)\"; \
|
||||
+ cpu_on = <$(PSCI_CPU_ON)>; \
|
||||
+ cpu_off = <$(PSCI_CPU_OFF)>; \
|
||||
};
|
||||
CPU_NODES := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/addpsci.pl $(KERNEL_DTB))
|
||||
else
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 9e3b722..53e51be 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -83,13 +83,17 @@ AS_IF([test "x$X_IMAGE" != "x"],
|
||||
# Allow a user to pass --enable-psci
|
||||
AC_ARG_ENABLE([psci],
|
||||
AS_HELP_STRING([--disable-psci], [disable the psci boot method]),
|
||||
- [USE_PSCI=$enableval], [USE_PSCI="yes"])
|
||||
-AM_CONDITIONAL([PSCI], [test "x$USE_PSCI" = "xyes"])
|
||||
-AS_IF([test "x$USE_PSCI" = "xyes"], [], [USE_PSCI=no])
|
||||
-
|
||||
-AS_IF([test "x$USE_PSCI" != "xyes" -a "x$KERNEL_ES" = "x32"],
|
||||
+ [case "${enableval}" in
|
||||
+ yes|smc) USE_PSCI=smc ;;
|
||||
+ hvc) USE_PSCI=hvc ;;
|
||||
+ *) AC_MSG_ERROR([Bad value "${enableval}" for --enable-psci. Use "smc" or "hvc"]) ;;
|
||||
+ esac], [USE_PSCI="yes"])
|
||||
+AM_CONDITIONAL([PSCI], [test "x$USE_PSCI" = "xyes" -o "x$USE_PSCI" = "xsmc" -o "x$USE_PSCI" = "xhvc"])
|
||||
+
|
||||
+AS_IF([test "x$USE_PSCI" = "xno" -a "x$KERNEL_ES" = "x32"],
|
||||
[AC_MSG_ERROR([With an AArch32 kernel, boot method must be PSCI.])]
|
||||
)
|
||||
+AC_SUBST([PSCI_METHOD], [$USE_PSCI])
|
||||
|
||||
# Allow a user to pass --with-initrd
|
||||
AC_ARG_WITH([initrd],
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
From 521c121eccb386aca7c75d92528e495546adccec Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Mon, 25 Oct 2021 17:09:13 +0800
|
||||
Subject: [PATCH] aarch64: Disable CNTPCT_EL0 trap for v8-R64
|
||||
|
||||
To allow EL1 to access CNTPCT_EL0 without traping into EL2, we need to
|
||||
set CNTHCTL_EL2.EL1PCTEN to 1.
|
||||
|
||||
For v8-R64, the CNTHCTL_EL2 register follows the v8-A architecture.
|
||||
However, as described in the v8-A architecture profile, the
|
||||
CNTHCTL_EL2's bit assignments are different according to whether the
|
||||
FEAT_VHE is implemented.
|
||||
|
||||
Since v8-R64 does not support FEAT_VHE, we do not need to detect
|
||||
FEAT_VHE. We can simply set CNTHCTL_EL2.EL1PCTEN to 1.
|
||||
|
||||
Issue-ID: SCM-3508
|
||||
Upstream-Status: Inappropriate [other]
|
||||
Implementation pending further discussion
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
Change-Id: I4147e66341c8153312021e6f2ab67d0037246da1
|
||||
---
|
||||
arch/aarch64/boot.S | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
|
||||
index a219ea7..27b1139 100644
|
||||
--- a/arch/aarch64/boot.S
|
||||
+++ b/arch/aarch64/boot.S
|
||||
@@ -240,6 +240,18 @@ el2_init:
|
||||
orr x0, x0, #(1 << 41) // HCR_EL2.API
|
||||
|
||||
1: msr hcr_el2, x0
|
||||
+
|
||||
+ /*
|
||||
+ * To disable trap when accessing CNTPCT_EL0, we need to set
|
||||
+ * CNTHCTL_EL2.EL1PCTEN to 1. However, the CNTHCTL_EL2 bit assignments
|
||||
+ * are different according to whether the FEAT_VHE is implemented.
|
||||
+ *
|
||||
+ * For Armv8-R AArch64, FEAT_VHE is not supported, so we do not need to
|
||||
+ * detect FEAT_VHE(ID_AA64MMFR1_EL1.VH) and simply set
|
||||
+ * CNTHCTL_EL2.EL1PCTEN to 1.
|
||||
+ */
|
||||
+ mov x0, #1 // CNTHCTL_EL2.EL1PCTEN
|
||||
+ msr cnthctl_el2, x0
|
||||
isb
|
||||
|
||||
mov w0, #SPSR_KERNEL_EL1
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
From 780df234d98db81485b1f351f902a68def35c9d4 Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Tue, 2 Nov 2021 15:10:28 +0800
|
||||
Subject: [PATCH] lds: Mark the mem range
|
||||
|
||||
Add firmware_start and firmware_end, so that we can use them to
|
||||
calculate the mem range of boot-wrapper and then set the range to
|
||||
/memreserve/ of dtb.
|
||||
|
||||
Issue-ID: SCM-3815
|
||||
Upstream-Status: Inappropriate [other]
|
||||
Implementation pending further discussion
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
Change-Id: Idc5a2894e193c75381049a0f359b4b2a51c567ee
|
||||
---
|
||||
model.lds.S | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/model.lds.S b/model.lds.S
|
||||
index d4e7e13..ab98ddf 100644
|
||||
--- a/model.lds.S
|
||||
+++ b/model.lds.S
|
||||
@@ -64,6 +64,7 @@ SECTIONS
|
||||
#endif
|
||||
|
||||
.boot PHYS_OFFSET: {
|
||||
+ PROVIDE(firmware_start = .);
|
||||
*(.init)
|
||||
*(.text*)
|
||||
*(.data* .rodata* .bss* COMMON)
|
||||
@@ -76,6 +77,7 @@ SECTIONS
|
||||
mbox = .;
|
||||
QUAD(0x0)
|
||||
}
|
||||
+ PROVIDE(firmware_end = .);
|
||||
|
||||
ASSERT(etext <= (PHYS_OFFSET + TEXT_LIMIT), ".text overflow!")
|
||||
}
|
||||
+6044
File diff suppressed because it is too large
Load Diff
+101
@@ -0,0 +1,101 @@
|
||||
From e2eff4f80e65cb3fcbe6345b5376a6bf7de7e2cc Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Tue, 28 Dec 2021 17:28:25 +0800
|
||||
Subject: [PATCH] common: Add essential libc functions
|
||||
|
||||
The libfdt uses some of the libc functions, e.g. memcmp, memmove,
|
||||
strlen .etc. Add them in lib.c.
|
||||
|
||||
The code is copied from TF-A (v2.5) [1] project, which is under the
|
||||
terms of BSD license. It is the same with boot-wrapper.
|
||||
|
||||
[1]: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git
|
||||
|
||||
Issue-Id: SCM-3814
|
||||
Upstream-Status: Inappropriate [other]
|
||||
Implementation pending further discussion
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
Change-Id: If3b55b00afa8694c7522df989a41e0b38eda1d38
|
||||
---
|
||||
common/lib.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 70 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/common/lib.c b/common/lib.c
|
||||
index fcf5f69..0be1c4a 100644
|
||||
--- a/common/lib.c
|
||||
+++ b/common/lib.c
|
||||
@@ -32,4 +32,73 @@ void *memset(void *s, int c, size_t n)
|
||||
return s;
|
||||
}
|
||||
|
||||
-/* TODO: memmove and memcmp could also be called */
|
||||
+int memcmp(const void *s1, const void *s2, size_t len)
|
||||
+{
|
||||
+ const unsigned char *s = s1;
|
||||
+ const unsigned char *d = s2;
|
||||
+ unsigned char sc;
|
||||
+ unsigned char dc;
|
||||
+
|
||||
+ while (len--) {
|
||||
+ sc = *s++;
|
||||
+ dc = *d++;
|
||||
+ if (sc - dc)
|
||||
+ return (sc - dc);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void *memmove(void *dst, const void *src, size_t len)
|
||||
+{
|
||||
+ if ((size_t)dst - (size_t)src >= len) {
|
||||
+ /* destination not in source data, so can safely use memcpy */
|
||||
+ return memcpy(dst, src, len);
|
||||
+ } else {
|
||||
+ /* copy backwards... */
|
||||
+ const char *end = dst;
|
||||
+ const char *s = (const char *)src + len;
|
||||
+ char *d = (char *)dst + len;
|
||||
+ while (d != end)
|
||||
+ *--d = *--s;
|
||||
+ }
|
||||
+ return dst;
|
||||
+}
|
||||
+
|
||||
+void *memchr(const void *src, int c, size_t len)
|
||||
+{
|
||||
+ const unsigned char *s = src;
|
||||
+
|
||||
+ while (len--) {
|
||||
+ if (*s == (unsigned char)c)
|
||||
+ return (void *) s;
|
||||
+ s++;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+char *strrchr(const char *p, int ch)
|
||||
+{
|
||||
+ char *save;
|
||||
+ char c;
|
||||
+
|
||||
+ c = ch;
|
||||
+ for (save = NULL;; ++p) {
|
||||
+ if (*p == c)
|
||||
+ save = (char *)p;
|
||||
+ if (*p == '\0')
|
||||
+ return (save);
|
||||
+ }
|
||||
+ /* NOTREACHED */
|
||||
+}
|
||||
+
|
||||
+size_t strlen(const char *s)
|
||||
+{
|
||||
+ const char *cursor = s;
|
||||
+
|
||||
+ while (*cursor)
|
||||
+ cursor++;
|
||||
+
|
||||
+ return cursor - s;
|
||||
+}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
From f4d5cf4c3424598a2b3bb391717313b70c79ea28 Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Tue, 28 Dec 2021 17:42:48 +0800
|
||||
Subject: [PATCH] Makefile: Add the libfdt to the Makefile system
|
||||
|
||||
Add the libfdt into Makefile system. The libfdt uses const value and
|
||||
thus gcc will enable the stack guard. The stack guard will fail the
|
||||
compile. Add -fno-stack-protector to fix it.
|
||||
|
||||
Issue-Id: SCM-3814
|
||||
Upstream-Status: Inappropriate [other]
|
||||
Implementation pending further discussion
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
Change-Id: I472bc28cdc5cde3b22461a4b7d7a3752ae382b4b
|
||||
---
|
||||
Makefile.am | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index fc66662..ab2c3a9 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -36,6 +36,9 @@ PSCI_CPU_OFF := 0x84000002
|
||||
COMMON_SRC := common/
|
||||
COMMON_OBJ := boot.o bakery_lock.o platform.o lib.o
|
||||
|
||||
+LIBFDT_SRC := common/libfdt/
|
||||
+LIBFDT_OBJS := fdt.o fdt_ro.o fdt_rw.o
|
||||
+
|
||||
ARCH_OBJ := boot.o stack.o utils.o
|
||||
|
||||
if BOOTWRAPPER_32
|
||||
@@ -127,11 +130,12 @@ CFLAGS += -I$(top_srcdir)/include/ -I$(top_srcdir)/$(ARCH_SRC)/include/
|
||||
CFLAGS += -Wall -fomit-frame-pointer
|
||||
CFLAGS += -ffreestanding -nostdlib
|
||||
CFLAGS += -fno-stack-protector
|
||||
+CFLAGS += -fno-stack-protector
|
||||
CFLAGS += -ffunction-sections -fdata-sections
|
||||
CFLAGS += -fno-pic -fno-pie
|
||||
LDFLAGS += --gc-sections
|
||||
|
||||
-OBJ := $(addprefix $(ARCH_SRC),$(ARCH_OBJ)) $(addprefix $(COMMON_SRC),$(COMMON_OBJ))
|
||||
+OBJ := $(addprefix $(ARCH_SRC),$(ARCH_OBJ)) $(addprefix $(COMMON_SRC),$(COMMON_OBJ)) $(addprefix $(LIBFDT_SRC),$(LIBFDT_OBJS))
|
||||
|
||||
# Don't lookup all prerequisites in $(top_srcdir), only the source files. When
|
||||
# building outside the source tree $(ARCH_SRC) needs to be created.
|
||||
@@ -152,10 +156,13 @@ $(ARCH_SRC):
|
||||
$(COMMON_SRC):
|
||||
$(MKDIR_P) $@
|
||||
|
||||
+$(LIBFDT_SRC):
|
||||
+ $(MKDIR_P) $@
|
||||
+
|
||||
%.o: %.S Makefile | $(ARCH_SRC)
|
||||
$(CC) $(CPPFLAGS) -D__ASSEMBLY__ $(CFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
-%.o: %.c Makefile | $(COMMON_SRC)
|
||||
+%.o: %.c Makefile | $(COMMON_SRC) $(LIBFDT_SRC)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c -o $@ $<
|
||||
|
||||
model.lds: $(LD_SCRIPT) Makefile
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
From f0ece5e8cac761a76a86df7204bae7c6ef09215f Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Wed, 29 Dec 2021 10:50:21 +0800
|
||||
Subject: [PATCH] platform: Add print_hex func
|
||||
|
||||
Refine the print functions, and add a new print_hex func to print hex
|
||||
numbers.
|
||||
|
||||
Issue-Id: SCM-3814
|
||||
Upstream-Status: Inappropriate [other]
|
||||
Implementation pending further discussion
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
Change-Id: Ic960345d9ef0b41d81d30c4a4dbd9c31139907c4
|
||||
---
|
||||
common/platform.c | 33 +++++++++++++++++++++++++--------
|
||||
1 file changed, 25 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/common/platform.c b/common/platform.c
|
||||
index d11f568..8269392 100644
|
||||
--- a/common/platform.c
|
||||
+++ b/common/platform.c
|
||||
@@ -30,20 +30,37 @@
|
||||
#define V2M_SYS(reg) ((void *)SYSREGS_BASE + V2M_SYS_##reg)
|
||||
#endif
|
||||
|
||||
-static void print_string(const char *str)
|
||||
+static void print_char(const char c)
|
||||
{
|
||||
uint32_t flags;
|
||||
+ do {
|
||||
+ flags = raw_readl(PL011(UARTFR));
|
||||
+ } while (flags & PL011_UARTFR_FIFO_FULL);
|
||||
|
||||
+ raw_writel(c, PL011(UARTDR));
|
||||
+
|
||||
+ do {
|
||||
+ flags = raw_readl(PL011(UARTFR));
|
||||
+ } while (flags & PL011_UARTFR_BUSY);
|
||||
+}
|
||||
+
|
||||
+void print_string(const char *str)
|
||||
+{
|
||||
while (*str) {
|
||||
- do
|
||||
- flags = raw_readl(PL011(UARTFR));
|
||||
- while (flags & PL011_UARTFR_FIFO_FULL);
|
||||
+ print_char(*str++);
|
||||
+ }
|
||||
+}
|
||||
|
||||
- raw_writel(*str++, PL011(UARTDR));
|
||||
+#define HEX_CHARS_PER_INT (2 * sizeof(int))
|
||||
+
|
||||
+void print_hex(unsigned int val)
|
||||
+{
|
||||
|
||||
- do
|
||||
- flags = raw_readl(PL011(UARTFR));
|
||||
- while (flags & PL011_UARTFR_BUSY);
|
||||
+ const char hex_chars[16] = "0123456789abcdef";
|
||||
+ int i;
|
||||
+ for (i = HEX_CHARS_PER_INT - 1; i >= 0; i--) {
|
||||
+ int v = (val >> (4 * i)) & 0xf;
|
||||
+ print_char(hex_chars[v]);
|
||||
}
|
||||
}
|
||||
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
From f4704146e1af9f6e0a2220db6b39a328c813fac1 Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Wed, 19 Jan 2022 16:19:02 +0800
|
||||
Subject: [PATCH] common: Add mem usage to /memreserve/
|
||||
|
||||
Set /memreserve/ to prevent next boot stages from overrding PSCI
|
||||
services with libfdt.
|
||||
|
||||
Issue-Id: SCM-3815
|
||||
Upstream-Status: Inappropriate [other]
|
||||
Implementation pending further discussion
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
Change-Id: I2ea80cdf736a910fa2c3deb622e21d50f04be960
|
||||
---
|
||||
Makefile.am | 2 +-
|
||||
common/boot.c | 1 +
|
||||
common/device_tree.c | 34 ++++++++++++++++++++++++++++++++++
|
||||
include/boot.h | 1 +
|
||||
4 files changed, 37 insertions(+), 1 deletion(-)
|
||||
create mode 100644 common/device_tree.c
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index ab2c3a9..e905602 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -34,7 +34,7 @@ endif
|
||||
PSCI_CPU_OFF := 0x84000002
|
||||
|
||||
COMMON_SRC := common/
|
||||
-COMMON_OBJ := boot.o bakery_lock.o platform.o lib.o
|
||||
+COMMON_OBJ := boot.o bakery_lock.o platform.o lib.o device_tree.o
|
||||
|
||||
LIBFDT_SRC := common/libfdt/
|
||||
LIBFDT_OBJS := fdt.o fdt_ro.o fdt_rw.o
|
||||
diff --git a/common/boot.c b/common/boot.c
|
||||
index c74d34c..ee2bea0 100644
|
||||
--- a/common/boot.c
|
||||
+++ b/common/boot.c
|
||||
@@ -63,6 +63,7 @@ void __noreturn first_spin(unsigned int cpu, unsigned long *mbox,
|
||||
{
|
||||
if (cpu == 0) {
|
||||
init_platform();
|
||||
+ dt_add_memreserve();
|
||||
|
||||
*mbox = (unsigned long)&entrypoint;
|
||||
sevl();
|
||||
diff --git a/common/device_tree.c b/common/device_tree.c
|
||||
new file mode 100644
|
||||
index 0000000..4d0876c
|
||||
--- /dev/null
|
||||
+++ b/common/device_tree.c
|
||||
@@ -0,0 +1,34 @@
|
||||
+/*
|
||||
+ * device_tree.c - Basic device tree node handler
|
||||
+ *
|
||||
+ * Copyright (C) 2021 ARM Limited. All rights reserved.
|
||||
+ *
|
||||
+ * Use of this source code is governed by a BSD-style license that can be
|
||||
+ * found in the LICENSE.txt file.
|
||||
+ */
|
||||
+#include <libfdt.h>
|
||||
+
|
||||
+extern unsigned long dtb;
|
||||
+extern char firmware_start[], firmware_end[];
|
||||
+
|
||||
+extern void print_string(const char *str);
|
||||
+
|
||||
+static void *blob;
|
||||
+
|
||||
+
|
||||
+void dt_add_memreserve(void)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ blob = (void*)&dtb;
|
||||
+ print_string("Add /memreserve/\n\r");
|
||||
+
|
||||
+ fdt_open_into(blob, blob, fdt_totalsize(blob) +
|
||||
+ sizeof(struct fdt_reserve_entry));
|
||||
+ ret = fdt_add_mem_rsv(blob, (uint64_t)firmware_start,
|
||||
+ (uint64_t)(firmware_end - firmware_start));
|
||||
+
|
||||
+ if(ret < 0) {
|
||||
+ print_string("reserve mem add err\n\r");
|
||||
+ }
|
||||
+}
|
||||
diff --git a/include/boot.h b/include/boot.h
|
||||
index d75e013..c3e2ec1 100644
|
||||
--- a/include/boot.h
|
||||
+++ b/include/boot.h
|
||||
@@ -16,4 +16,5 @@ void __noreturn spin(unsigned long *mbox, unsigned long invalid, int is_entry);
|
||||
void __noreturn first_spin(unsigned int cpu, unsigned long *mbox,
|
||||
unsigned long invalid_addr);
|
||||
|
||||
+void dt_add_memreserve(void);
|
||||
#endif
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
From 5995f83592aea874f5b423538e36675e2204582b Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Tue, 4 Jan 2022 17:01:55 +0800
|
||||
Subject: [PATCH] boot: Add the --enable-keep-el compile option
|
||||
|
||||
Add --enable-keep-el compile option to enable boot-wrapper booting next
|
||||
stage at EL2.
|
||||
The Armv8R AArch64 boots at EL2. If the next stage requires EL2 booting,
|
||||
the boot-wrapper should not drop to EL1.
|
||||
Currently, this option only works for Armv8R AArch64. Also, to work with
|
||||
Linux PSCI, this option will cause secondary cores booting at EL1.
|
||||
|
||||
Issue-Id: SCM-3813
|
||||
Upstream-Status: Inappropriate [other]
|
||||
Implementation pending further discussion
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
Change-Id: I3ba9c87cf0b59d163ca433f74c9e3a46e5ca2c63
|
||||
---
|
||||
Makefile.am | 4 ++++
|
||||
arch/aarch64/boot.S | 6 +++++-
|
||||
common/psci.c | 6 ++++++
|
||||
configure.ac | 5 +++++
|
||||
4 files changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index e905602..6604baa 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -33,6 +33,10 @@ PSCI_CPU_ON := 0xc4000003
|
||||
endif
|
||||
PSCI_CPU_OFF := 0x84000002
|
||||
|
||||
+if KEEP_EL
|
||||
+DEFINES += -DKEEP_EL
|
||||
+endif
|
||||
+
|
||||
COMMON_SRC := common/
|
||||
COMMON_OBJ := boot.o bakery_lock.o platform.o lib.o device_tree.o
|
||||
|
||||
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
|
||||
index 27b1139..c079d22 100644
|
||||
--- a/arch/aarch64/boot.S
|
||||
+++ b/arch/aarch64/boot.S
|
||||
@@ -254,7 +254,11 @@ el2_init:
|
||||
msr cnthctl_el2, x0
|
||||
isb
|
||||
|
||||
+#ifdef KEEP_EL
|
||||
+ mov w0, #SPSR_KERNEL
|
||||
+#else
|
||||
mov w0, #SPSR_KERNEL_EL1
|
||||
+#endif
|
||||
ldr x1, =spsr_to_elx
|
||||
str w0, [x1]
|
||||
// fall through
|
||||
@@ -334,5 +338,5 @@ ASM_FUNC(jump_kernel)
|
||||
.align 3
|
||||
flag_keep_el:
|
||||
.long 0
|
||||
-spsr_to_elx:
|
||||
+ASM_DATA(spsr_to_elx)
|
||||
.long 0
|
||||
diff --git a/common/psci.c b/common/psci.c
|
||||
index a0e8700..945780b 100644
|
||||
--- a/common/psci.c
|
||||
+++ b/common/psci.c
|
||||
@@ -18,6 +18,8 @@
|
||||
#error "No MPIDRs provided"
|
||||
#endif
|
||||
|
||||
+extern unsigned int spsr_to_elx;
|
||||
+
|
||||
static unsigned long branch_table[NR_CPUS];
|
||||
|
||||
bakery_ticket_t branch_table_lock[NR_CPUS];
|
||||
@@ -44,6 +46,10 @@ static int psci_cpu_on(unsigned long target_mpidr, unsigned long address)
|
||||
ret = psci_store_address(cpu, address);
|
||||
bakery_unlock(branch_table_lock, this_cpu);
|
||||
|
||||
+#ifdef KEEP_EL
|
||||
+ spsr_to_elx = SPSR_KERNEL_EL1;
|
||||
+#endif
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 53e51be..0e07db3 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -25,6 +25,11 @@ AS_IF([test "x$BOOTWRAPPER_ES" = x32 -a "x$KERNEL_ES" != x32],
|
||||
[AC_MSG_ERROR([a 32-bit boot-wrapper cannot launch a 64-bit kernel])]
|
||||
)
|
||||
|
||||
+AC_ARG_ENABLE([keep-el],
|
||||
+ AC_HELP_STRING([--enable-keep-el], [keep exception level when start kernel]),
|
||||
+ [KEEP_EL=yes], [KEEP_EL=no])
|
||||
+AM_CONDITIONAL([KEEP_EL], [test "x$KEEP_EL" = xyes])
|
||||
+
|
||||
# Allow a user to pass --with-kernel-dir
|
||||
AC_ARG_WITH([kernel-dir],
|
||||
AS_HELP_STRING([--with-kernel-dir], [specify the root Linux kernel build directory (required)]),
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
From 0c0695cd3160ccdb95bae29b7668918015c0b6aa Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hoyes <Peter.Hoyes@arm.com>
|
||||
Date: Tue, 1 Feb 2022 11:28:46 +0000
|
||||
Subject: [PATCH] Makefile: Change COUNTER_FREQ to 100 MHz
|
||||
|
||||
Older Arm Fast Models (AEM < RevC) had a base frequency of 24 MHz. but
|
||||
the RevC base models use 100 MHz. There is not a robust method of
|
||||
determining the configured base frequency at runtime, so update
|
||||
COUNTER_FREQ to be 100 MHz.
|
||||
|
||||
Issue-Id: SCM-3871
|
||||
Upstream-Status: Pending
|
||||
Signed-off-by: Peter Hoyes <Peter.Hoyes@arm.com>
|
||||
Change-Id: Ia9ad0f8ee488d1a887791f1fa1d8f3bf9c5887fd
|
||||
---
|
||||
Makefile.am | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 6604baa..cc6504e 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -13,7 +13,7 @@ SCRIPT_DIR := $(top_srcdir)/scripts
|
||||
PHYS_OFFSET := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findmem.pl $(KERNEL_DTB))
|
||||
UART_BASE := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,pl011')
|
||||
SYSREGS_BASE := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findbase.pl $(KERNEL_DTB) 0 'arm,vexpress-sysreg' 2> /dev/null)
|
||||
-COUNTER_FREQ := 24000000
|
||||
+COUNTER_FREQ := 100000000
|
||||
|
||||
CPU_IDS := $(shell perl -I $(SCRIPT_DIR) $(SCRIPT_DIR)/findcpuids.pl $(KERNEL_DTB))
|
||||
NR_CPUS := $(shell echo $(CPU_IDS) | tr ',' ' ' | wc -w)
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
From fa73d885be85eee4369b292ec601e7b024a68807 Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Tue, 2 Nov 2021 10:48:39 +0800
|
||||
Subject: [PATCH] PSCI: Apply flush cache after setting branch_data
|
||||
|
||||
For v8-R64, Hypervisor calls boot-wrapper's PSCI service using simple
|
||||
function call (instead of hvc).
|
||||
|
||||
In this case, hypervisor's main core has enabled MPU and cache, but
|
||||
the secondary cores which are spinning have not enabled cache.
|
||||
That means if the main core set the branch_data to 1 to boot other
|
||||
cores, the secondary cores cannot see the change of branch_data and
|
||||
also cannot break the spin.
|
||||
|
||||
Thus, the PSCI service in boot-wrapper needs a cache flush after
|
||||
setting branch_data in order to let other cores see the change.
|
||||
|
||||
Issue-ID: SCM-3816
|
||||
Upstream-Status: Inappropriate [other]
|
||||
Implementation pending further discussion
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
Change-Id: Ifc282091c54d8fb2ffdb8cfa7fd3ffc1f4be717e
|
||||
---
|
||||
common/psci.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/common/psci.c b/common/psci.c
|
||||
index 945780b..6efc695 100644
|
||||
--- a/common/psci.c
|
||||
+++ b/common/psci.c
|
||||
@@ -24,12 +24,18 @@ static unsigned long branch_table[NR_CPUS];
|
||||
|
||||
bakery_ticket_t branch_table_lock[NR_CPUS];
|
||||
|
||||
+static inline void flush_per_cpu_data(void *data)
|
||||
+{
|
||||
+ asm volatile ("dc cvac, %0" : : "r" (data));
|
||||
+}
|
||||
+
|
||||
static int psci_store_address(unsigned int cpu, unsigned long address)
|
||||
{
|
||||
if (branch_table[cpu] != PSCI_ADDR_INVALID)
|
||||
return PSCI_RET_ALREADY_ON;
|
||||
|
||||
branch_table[cpu] = address;
|
||||
+ flush_per_cpu_data((void*)&(branch_table[cpu]));
|
||||
return PSCI_RET_SUCCESS;
|
||||
}
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
From 9da48e3433b919868650cd60e28827273a42c63b Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Tue, 25 Jan 2022 14:56:36 +0800
|
||||
Subject: [PATCH] PSCI: Add function call entry point
|
||||
|
||||
The max exception level of Armv8R AArch64 is EL2, which means it has no
|
||||
exclusive EL for firmware. That is, firmware and hypervisors have to share
|
||||
the EL2. Also, hypervisors cannot call firmware services via a 'smc'
|
||||
instruction. Thus, boot-wrapper has to provide a function entry point
|
||||
for Armv8R AArch64.
|
||||
|
||||
Issue-Id: SCM-3816
|
||||
Upstream-Status: Inappropriate [other]
|
||||
Implementation pending further discussion
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
Change-Id: I06ec8e50298603155c6d8ae2330e71db2f111182
|
||||
---
|
||||
common/psci.c | 24 ++++++++++++++++++++----
|
||||
1 file changed, 20 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/common/psci.c b/common/psci.c
|
||||
index 6efc695..8fdefb5 100644
|
||||
--- a/common/psci.c
|
||||
+++ b/common/psci.c
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
extern unsigned int spsr_to_elx;
|
||||
|
||||
+unsigned long flag_from_smc_fn[NR_CPUS];
|
||||
+
|
||||
static unsigned long branch_table[NR_CPUS];
|
||||
|
||||
bakery_ticket_t branch_table_lock[NR_CPUS];
|
||||
@@ -49,12 +51,14 @@ static int psci_cpu_on(unsigned long target_mpidr, unsigned long address)
|
||||
return PSCI_RET_INVALID_PARAMETERS;
|
||||
|
||||
bakery_lock(branch_table_lock, this_cpu);
|
||||
- ret = psci_store_address(cpu, address);
|
||||
- bakery_unlock(branch_table_lock, this_cpu);
|
||||
-
|
||||
#ifdef KEEP_EL
|
||||
- spsr_to_elx = SPSR_KERNEL_EL1;
|
||||
+ if (!flag_from_smc_fn[this_cpu]) {
|
||||
+ spsr_to_elx = SPSR_KERNEL_EL1;
|
||||
+ flush_per_cpu_data((void*)&(spsr_to_elx));
|
||||
+ }
|
||||
#endif
|
||||
+ ret = psci_store_address(cpu, address);
|
||||
+ bakery_unlock(branch_table_lock, this_cpu);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -90,6 +94,18 @@ long psci_call(unsigned long fid, unsigned long arg1, unsigned long arg2)
|
||||
}
|
||||
}
|
||||
|
||||
+long smc_fn_entry(unsigned long fid, unsigned long arg1, unsigned long arg2)
|
||||
+{
|
||||
+ long ret;
|
||||
+ unsigned int this_cpu = this_cpu_logical_id();
|
||||
+
|
||||
+ flag_from_smc_fn[this_cpu] = 1;
|
||||
+ ret = psci_call(fid, arg1, arg2);
|
||||
+ flag_from_smc_fn[this_cpu] = 0;
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
void __noreturn psci_first_spin(unsigned int cpu)
|
||||
{
|
||||
if (cpu == MPIDR_INVALID)
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
From 7c5e40d9f8699a55ac2187c035429c643e6d0ef0 Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Tue, 2 Nov 2021 15:10:28 +0800
|
||||
Subject: [PATCH] lds: Rearrange and mark the sections
|
||||
|
||||
To make it possible for the next stage to protect sections with MPU,
|
||||
boot-wrapper needs to provide the text and data section information.
|
||||
By rearranging the .data .rodata and .vector sections, all sections
|
||||
can be split into 2 big sections:
|
||||
- RO and Executable
|
||||
- RW and Non-Executable
|
||||
Add firmware_data to mark the boundry, thus:
|
||||
firmware_start to firmware_data - 1 indicates RO and Executable section,
|
||||
firmware_data to firmware_end - 1 indicates RW and Non-Executable
|
||||
section.
|
||||
|
||||
Also, the firmware_data and firmware_end should align with 64 bytes,
|
||||
since Armv8R AArch64 MPU requires it.
|
||||
|
||||
Issue-ID: SCM-3816
|
||||
Upstream-Status: Inappropriate [other]
|
||||
Implementation pending further discussion
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
Change-Id: I55342aa7492f2c7b5c16ab9a6472c8cb45cff8fd
|
||||
---
|
||||
model.lds.S | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/model.lds.S b/model.lds.S
|
||||
index ab98ddf..85451f9 100644
|
||||
--- a/model.lds.S
|
||||
+++ b/model.lds.S
|
||||
@@ -63,12 +63,16 @@ SECTIONS
|
||||
}
|
||||
#endif
|
||||
|
||||
+#define FIRMWARE_ALIGN . = ALIGN(1 << 6)
|
||||
.boot PHYS_OFFSET: {
|
||||
PROVIDE(firmware_start = .);
|
||||
*(.init)
|
||||
*(.text*)
|
||||
- *(.data* .rodata* .bss* COMMON)
|
||||
*(.vectors)
|
||||
+ *(.rodata*)
|
||||
+ FIRMWARE_ALIGN;
|
||||
+ PROVIDE(firmware_data = .);
|
||||
+ *(.data* .bss* COMMON)
|
||||
*(.stack)
|
||||
PROVIDE(etext = .);
|
||||
}
|
||||
@@ -77,6 +81,7 @@ SECTIONS
|
||||
mbox = .;
|
||||
QUAD(0x0)
|
||||
}
|
||||
+ FIRMWARE_ALIGN;
|
||||
PROVIDE(firmware_end = .);
|
||||
|
||||
ASSERT(etext <= (PHYS_OFFSET + TEXT_LIMIT), ".text overflow!")
|
||||
+342
@@ -0,0 +1,342 @@
|
||||
From 3c1140c29c39561848056fb4b9a03042b00279f3 Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Wed, 29 Dec 2021 15:17:38 +0800
|
||||
Subject: [PATCH] common: Provide firmware info using libfdt
|
||||
|
||||
Boot-wrapper uses libfdt to provide more info in device tree.
|
||||
We add a new node to include those new firmware relevant infomation.
|
||||
The new node defined as follows:
|
||||
fw-shared-info {
|
||||
compatible = "firmware,shared_info";
|
||||
|
||||
#address-cells = <0x02>;
|
||||
#size-cells = <0x02>;
|
||||
|
||||
version = "1.0";
|
||||
regions = <START_ADDR_HIGH START_ADDR_LOW SIZE_HIGH SIZE_LOW
|
||||
0x0 0x80000000 0x0 0x400000
|
||||
0x0 0x90000000 0x0 0x400000
|
||||
0x0 0xA0000000 0x0 0x400000>;
|
||||
regions-permission = "RX", "R", "RWX", "RW";
|
||||
regions-cache = "Cache", "NCache", "Cache", "Device"
|
||||
|
||||
function_entry = <ENTRY_ADDR_HIGH ENRTY_ADDR_LOW>;
|
||||
};
|
||||
The node path is /fw-shared-info.
|
||||
For boot-wrapper, in real case, it will be:
|
||||
fw-shared-info {
|
||||
compatible = "firmware,shared_info";
|
||||
|
||||
#address-cells = <0x02>;
|
||||
#size-cells = <0x02>;
|
||||
|
||||
version = "1.0";
|
||||
regions = <0x0 firmware_start 0x0 firmware_code_size
|
||||
0x0 firmware_data 0x0 firmware_data_size>;
|
||||
regions-permission = "RX", "RW";
|
||||
regions-cache = "Cache", "Cache";
|
||||
|
||||
function_entry = <0x0 smc_fn_entry>;
|
||||
};
|
||||
|
||||
Issue-Id: SCM-3816
|
||||
Upstream-Status: Inappropriate [other]
|
||||
Implementation pending further discussion
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
Change-Id: I6ebc59ce2bd3939b0fe066720d57821eaa1bed27
|
||||
---
|
||||
common/device_tree.c | 271 ++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 270 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/common/device_tree.c b/common/device_tree.c
|
||||
index 4d0876c..7f7befc 100644
|
||||
--- a/common/device_tree.c
|
||||
+++ b/common/device_tree.c
|
||||
@@ -8,13 +8,225 @@
|
||||
*/
|
||||
#include <libfdt.h>
|
||||
|
||||
+#define DEVICE_TREE_DEBUG 1
|
||||
+
|
||||
+#define FW_NODE_NAME "/fw-shared-info"
|
||||
+#define FW_COMPAT "firmware,shared_info"
|
||||
+#define FW_INFO_VER "1.0"
|
||||
+
|
||||
+#ifdef BOOTWRAPPER_32
|
||||
+#define CELL_NUM 1
|
||||
+#define VAL_TYPE uint32_t
|
||||
+#else
|
||||
+#define CELL_NUM 2
|
||||
+#define VAL_TYPE uint64_t
|
||||
+#endif
|
||||
+
|
||||
+#define ALIGN(x) (((x) + (FDT_TAGSIZE) - 1) & ~((FDT_TAGSIZE) - 1))
|
||||
+
|
||||
extern unsigned long dtb;
|
||||
-extern char firmware_start[], firmware_end[];
|
||||
+extern char firmware_start[], firmware_data[], firmware_end[];
|
||||
+
|
||||
+extern long smc_fn_entry(unsigned long, unsigned long, unsigned long);
|
||||
|
||||
extern void print_string(const char *str);
|
||||
+extern void print_hex(unsigned int val);
|
||||
|
||||
static void *blob;
|
||||
|
||||
+static char *realloc_node(char *fdt, const char *name)
|
||||
+{
|
||||
+ int delta;
|
||||
+ int new_sz;
|
||||
+ /* FDT_BEGIN_NODE, node name in off_struct and FDT_END_NODE */
|
||||
+ delta = sizeof(struct fdt_node_header) + ALIGN(strlen(name) + 1)
|
||||
+ + FDT_TAGSIZE;
|
||||
+ new_sz = fdt_totalsize(fdt) + delta;
|
||||
+ fdt_open_into(fdt, fdt, new_sz);
|
||||
+ return fdt;
|
||||
+}
|
||||
+
|
||||
+static int create_node(const char *node_name)
|
||||
+{
|
||||
+ int node = 0;
|
||||
+ char *p;
|
||||
+
|
||||
+ p = strrchr(node_name, '/');
|
||||
+ if (!p) {
|
||||
+ print_string("node name without '/'\r\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ *p = '\0';
|
||||
+
|
||||
+ blob = realloc_node(blob, p + 1);
|
||||
+
|
||||
+ if (p > node_name) {
|
||||
+ node = fdt_path_offset(blob, node_name);
|
||||
+ if (node < 0) {
|
||||
+ print_string("no node name\r\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ node = fdt_add_subnode(blob, node, p + 1);
|
||||
+ if (node < 0) {
|
||||
+ print_string("add subnode err\r\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return node;
|
||||
+}
|
||||
+
|
||||
+static int dt_create_fw_node(void) {
|
||||
+ int fw_node;
|
||||
+
|
||||
+ fw_node = fdt_path_offset(blob, FW_NODE_NAME);
|
||||
+
|
||||
+ if(fw_node < 0) {
|
||||
+ fw_node = create_node(FW_NODE_NAME);
|
||||
+ }
|
||||
+
|
||||
+ return fw_node;
|
||||
+}
|
||||
+
|
||||
+static char *realloc_property(char *fdt, int nodeoffset, const char *name,
|
||||
+ int newlen)
|
||||
+{
|
||||
+ int delta = 0;
|
||||
+ int oldlen = 0;
|
||||
+ int new_sz;
|
||||
+
|
||||
+ if (!fdt_get_property(fdt, nodeoffset, name, &oldlen))
|
||||
+ delta = sizeof(struct fdt_property) + strlen(name) + 1;
|
||||
+
|
||||
+ if (newlen > oldlen)
|
||||
+ delta += ALIGN(newlen) - ALIGN(oldlen);
|
||||
+
|
||||
+ new_sz = fdt_totalsize(fdt) + delta;
|
||||
+ fdt_open_into(fdt, fdt, new_sz);
|
||||
+ return fdt;
|
||||
+}
|
||||
+
|
||||
+static void dt_set_prop(int node, char *property, void *buf, int len)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ err = fdt_setprop(blob, node, property, buf, len);
|
||||
+ if (err == -FDT_ERR_NOSPACE) {
|
||||
+ blob = realloc_property(blob, node, property, len);
|
||||
+ err = fdt_setprop(blob, node, property, buf, len);
|
||||
+ }
|
||||
+ if (err) {
|
||||
+ print_string("fdt error\n\r");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void dt_set_prop_u32(int node, char *property, uint32_t val)
|
||||
+{
|
||||
+ fdt32_t fdt_val = cpu_to_fdt32(val);
|
||||
+ int len = sizeof(fdt32_t);
|
||||
+
|
||||
+ dt_set_prop(node, property, (void*)&fdt_val, len);
|
||||
+}
|
||||
+
|
||||
+static void dt_set_prop_u64(int node, char *property, uint64_t val)
|
||||
+{
|
||||
+ fdt64_t fdt_val = cpu_to_fdt64(val);
|
||||
+ int len = sizeof(fdt64_t);
|
||||
+
|
||||
+ dt_set_prop(node, property, (void*)&fdt_val, len);
|
||||
+}
|
||||
+
|
||||
+/* This dt_set_prop_u32_array maybe unused according to the BOOTWRAPPER_32 */
|
||||
+__attribute__((unused))
|
||||
+static void dt_set_prop_u32_array(int node, char *property, uint32_t *vals,
|
||||
+ int size)
|
||||
+{
|
||||
+ fdt32_t *fdt_vals = (fdt32_t*)vals;
|
||||
+ int len = sizeof(fdt32_t) * size;
|
||||
+
|
||||
+ for (int i = 0; i < size; i++) {
|
||||
+ fdt_vals[i] = cpu_to_fdt32(vals[i]);
|
||||
+ }
|
||||
+
|
||||
+ dt_set_prop(node, property, (void*)fdt_vals, len);
|
||||
+}
|
||||
+
|
||||
+static void dt_set_prop_u64_array(int node, char *property, uint64_t *vals,
|
||||
+ int size)
|
||||
+{
|
||||
+ fdt64_t *fdt_vals = (fdt64_t*)vals;
|
||||
+ int len = sizeof(fdt64_t) * size;
|
||||
+
|
||||
+ for (int i = 0; i < size; i++) {
|
||||
+ fdt_vals[i] = cpu_to_fdt64(vals[i]);
|
||||
+ }
|
||||
+
|
||||
+ dt_set_prop(node, property, (void*)fdt_vals, len);
|
||||
+}
|
||||
+
|
||||
+#if DEVICE_TREE_DEBUG
|
||||
+static void dt_dump_string(const void *s, int len)
|
||||
+{
|
||||
+ char *sub = (char*)s;
|
||||
+ int sublen;
|
||||
+ while(*sub && ((uint64_t)sub - (uint64_t)s) < len) {
|
||||
+ sublen = strlen(sub) + 1;
|
||||
+ print_string(sub);
|
||||
+ print_string(" ");
|
||||
+ sub += sublen;
|
||||
+ }
|
||||
+ print_string("\n\r");
|
||||
+}
|
||||
+
|
||||
+static void dt_dump_fdt32_array(const void *vals, int len)
|
||||
+{
|
||||
+ fdt32_t *fdt_vals = (fdt32_t*)vals;
|
||||
+ len = len / sizeof(fdt32_t);
|
||||
+ for (int i = 0; i < len; i++) {
|
||||
+ print_hex(fdt32_to_cpu(fdt_vals[i]));
|
||||
+ print_string(" ");
|
||||
+ }
|
||||
+ print_string("\n\r");
|
||||
+}
|
||||
+
|
||||
+static void dt_dump(int node, char *property, char type)
|
||||
+{
|
||||
+ const void *val;
|
||||
+ int len;
|
||||
+
|
||||
+ val = fdt_getprop(blob, node, property, &len);
|
||||
+ print_string(property);
|
||||
+ print_string(": ");
|
||||
+
|
||||
+ if (type == 's') {
|
||||
+ /* string type */
|
||||
+ dt_dump_string(val, len);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* uint type */
|
||||
+ dt_dump_fdt32_array(val, len);
|
||||
+}
|
||||
+
|
||||
+void dt_dump_all(int node)
|
||||
+{
|
||||
+ if (node >= 0) {
|
||||
+ print_string(FW_NODE_NAME" info:\r\n");
|
||||
+ dt_dump(node, "compatible", 's');
|
||||
+ dt_dump(node, "version", 's');
|
||||
+ dt_dump(node, "function_entry", 'i');
|
||||
+ dt_dump(node, "address-cells", 'i');
|
||||
+ dt_dump(node, "size-cells", 'i');
|
||||
+ dt_dump(node, "regions", 'i');
|
||||
+ dt_dump(node, "regions-permission", 's');
|
||||
+ dt_dump(node, "regions-cache", 's');
|
||||
+ print_string("\r\n");
|
||||
+ }
|
||||
+}
|
||||
+#else
|
||||
+void dt_dump_all(int node) { (void*)node; return; }
|
||||
+#endif
|
||||
|
||||
void dt_add_memreserve(void)
|
||||
{
|
||||
@@ -32,3 +244,60 @@ void dt_add_memreserve(void)
|
||||
print_string("reserve mem add err\n\r");
|
||||
}
|
||||
}
|
||||
+
|
||||
+void dt_fw_node_init(int enable)
|
||||
+{
|
||||
+ int fw_node;
|
||||
+
|
||||
+ VAL_TYPE regions[] = {
|
||||
+ /* code region: start, end, ro, x, cachable */
|
||||
+ (VAL_TYPE)firmware_start,
|
||||
+ (VAL_TYPE)(firmware_data - firmware_start),
|
||||
+ /* data region: start, end, rw, xn, cachable */
|
||||
+ (VAL_TYPE)firmware_data,
|
||||
+ (VAL_TYPE)(firmware_end - firmware_data),
|
||||
+ };
|
||||
+ int regions_num = sizeof(regions) / sizeof(VAL_TYPE);
|
||||
+ char regions_permission[] = "RX\0RW";
|
||||
+ char regions_cache[] = "Cache\0Cache";
|
||||
+
|
||||
+ if (!enable)
|
||||
+ return;
|
||||
+
|
||||
+ print_string("Prepare "FW_NODE_NAME" node\n\r");
|
||||
+
|
||||
+ blob = (void*)&dtb;
|
||||
+
|
||||
+ if(fdt_path_offset(blob, "/psci") < 0) {
|
||||
+ print_string("/psci node not found\n\r");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ fw_node = dt_create_fw_node();
|
||||
+
|
||||
+ if(fw_node < 0) {
|
||||
+ print_string(FW_NODE_NAME" node create err\n\r");
|
||||
+ }
|
||||
+
|
||||
+ dt_set_prop(fw_node, "compatible", FW_COMPAT, sizeof(FW_COMPAT));
|
||||
+ dt_set_prop(fw_node, "version", FW_INFO_VER, sizeof(FW_INFO_VER));
|
||||
+
|
||||
+ dt_set_prop_u32(fw_node, "address-cells", CELL_NUM);
|
||||
+ dt_set_prop_u32(fw_node, "size-cells", CELL_NUM);
|
||||
+ dt_set_prop(fw_node, "regions-permission", regions_permission,
|
||||
+ sizeof(regions_permission));
|
||||
+ dt_set_prop(fw_node, "regions-cache", regions_cache,
|
||||
+ sizeof(regions_cache));
|
||||
+
|
||||
+#ifdef BOOTWRAPPER_32
|
||||
+ dt_set_prop_u32_array(fw_node, "regions", regions, regions_num);
|
||||
+ dt_set_prop_u32(fw_node, "function_entry", (VAL_TYPE)smc_fn_entry);
|
||||
+#else
|
||||
+ dt_set_prop_u64_array(fw_node, "regions", regions, regions_num);
|
||||
+ dt_set_prop_u64(fw_node, "function_entry", (VAL_TYPE)smc_fn_entry);
|
||||
+#endif
|
||||
+
|
||||
+ fdt_pack(blob);
|
||||
+
|
||||
+ dt_dump_all(fw_node);
|
||||
+}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
From b1105e862e8f770fc195bc20e9c64d231dd32f66 Mon Sep 17 00:00:00 2001
|
||||
From: Jaxson Han <jaxson.han@arm.com>
|
||||
Date: Wed, 29 Dec 2021 15:33:17 +0800
|
||||
Subject: [PATCH] boot: Enable firmware node initialization
|
||||
|
||||
Enable the firmware node initialization, so that the next stage
|
||||
(hypervisor) could share the EL2 with firmware (boot-wrapper). The next
|
||||
stage (hypervisor) get the smccc entry point, code/data sections, the
|
||||
sections attrs and firmware node version and so on.
|
||||
It is worth noting that this EL2 sharing mechanism is only for Armv8R
|
||||
AArch64, thus add flag_v8r to record if the arch is Armv8R AArch64.
|
||||
Enable the firmware node initialization only if it is Armv8R AArch64.
|
||||
Also, we increase the stack size to 1024 to fix the stack overflow issue
|
||||
when using the libfdt.
|
||||
|
||||
Add -fno-builtin options to CFLAGS to avoid the issue that the 'memset'
|
||||
in common/lib.c conflicts with builtin 'memset' function. GCC version
|
||||
>= 10 will have an incorrect compilation without -fno-builtin;
|
||||
|
||||
Issue-Id: SCM-3816
|
||||
Upstream-Status: Inappropriate [other]
|
||||
Implementation pending further discussion
|
||||
Signed-off-by: Jaxson Han <jaxson.han@arm.com>
|
||||
Change-Id: Ib274485a34d26215595fd0cd737be86610289817
|
||||
---
|
||||
Makefile.am | 4 ++--
|
||||
arch/aarch64/boot.S | 6 ++++++
|
||||
common/boot.c | 4 ++++
|
||||
3 files changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index cc6504e..fbe6b81 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -23,7 +23,7 @@ DEFINES += -DCPU_IDS=$(CPU_IDS)
|
||||
DEFINES += -DNR_CPUS=$(NR_CPUS)
|
||||
DEFINES += $(if $(SYSREGS_BASE), -DSYSREGS_BASE=$(SYSREGS_BASE), )
|
||||
DEFINES += -DUART_BASE=$(UART_BASE)
|
||||
-DEFINES += -DSTACK_SIZE=256
|
||||
+DEFINES += -DSTACK_SIZE=1024
|
||||
|
||||
if KERNEL_32
|
||||
DEFINES += -DKERNEL_32
|
||||
@@ -134,7 +134,7 @@ CFLAGS += -I$(top_srcdir)/include/ -I$(top_srcdir)/$(ARCH_SRC)/include/
|
||||
CFLAGS += -Wall -fomit-frame-pointer
|
||||
CFLAGS += -ffreestanding -nostdlib
|
||||
CFLAGS += -fno-stack-protector
|
||||
-CFLAGS += -fno-stack-protector
|
||||
+CFLAGS += -fno-stack-protector -fno-builtin
|
||||
CFLAGS += -ffunction-sections -fdata-sections
|
||||
CFLAGS += -fno-pic -fno-pie
|
||||
LDFLAGS += --gc-sections
|
||||
diff --git a/arch/aarch64/boot.S b/arch/aarch64/boot.S
|
||||
index c079d22..daaa674 100644
|
||||
--- a/arch/aarch64/boot.S
|
||||
+++ b/arch/aarch64/boot.S
|
||||
@@ -261,6 +261,10 @@ el2_init:
|
||||
#endif
|
||||
ldr x1, =spsr_to_elx
|
||||
str w0, [x1]
|
||||
+
|
||||
+ mov w0, #1
|
||||
+ ldr x1, =flag_v8r
|
||||
+ str w0, [x1]
|
||||
// fall through
|
||||
|
||||
el_max_init:
|
||||
@@ -340,3 +344,5 @@ flag_keep_el:
|
||||
.long 0
|
||||
ASM_DATA(spsr_to_elx)
|
||||
.long 0
|
||||
+ASM_DATA(flag_v8r)
|
||||
+ .long 0
|
||||
diff --git a/common/boot.c b/common/boot.c
|
||||
index ee2bea0..38b2dca 100644
|
||||
--- a/common/boot.c
|
||||
+++ b/common/boot.c
|
||||
@@ -11,6 +11,9 @@
|
||||
|
||||
extern unsigned long entrypoint;
|
||||
extern unsigned long dtb;
|
||||
+extern unsigned int flag_v8r;
|
||||
+
|
||||
+extern void dt_fw_node_init(int enable);
|
||||
|
||||
void init_platform(void);
|
||||
|
||||
@@ -64,6 +67,7 @@ void __noreturn first_spin(unsigned int cpu, unsigned long *mbox,
|
||||
if (cpu == 0) {
|
||||
init_platform();
|
||||
dt_add_memreserve();
|
||||
+ dt_fw_node_init(flag_v8r == 1);
|
||||
|
||||
*mbox = (unsigned long)&entrypoint;
|
||||
sevl();
|
||||
Reference in New Issue
Block a user