You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/03/01 05:23:55 UTC
[nuttx] branch master updated (b576a26d51 -> fa359e355c)
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
from b576a26d51 arch: cxd56xx: Fix emmc pin control on initialization error
new e5564a9872 arm64: PSCI config support
new 4240723b78 arm64: add ARCH_EARLY_PRINT support
new 0841f4dbaa arm64: ARMv8-r(Cortex-R82) support
new 4cb5ff3353 arm64: ARMv8-r(Cortex-R82) support(add ARCH_SET_VMPIDR_EL2 option)
new d5c6b8a94b arm64: add 64-bit time for all arm64 platform
new 518eb4076e arm64: ARMv8-r(Cortex-R82) support(mpid fix)
new fa359e355c Update arm64_head.S
The 7 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
arch/arm64/Kconfig | 60 ++++
arch/arm64/include/qemu/chip.h | 2 +-
arch/arm64/src/Toolchain.defs | 6 +
arch/arm64/src/a64/a64_boot.c | 20 +-
arch/arm64/src/common/Make.defs | 30 +-
arch/arm64/src/common/arm64_arch.h | 40 ++-
arch/arm64/src/common/arm64_arch_timer.c | 6 +-
arch/arm64/src/common/arm64_boot.c | 13 +
arch/arm64/src/common/arm64_cpu_psci.c | 6 +-
arch/arm64/src/common/arm64_cpu_psci.h | 6 +-
arch/arm64/src/common/arm64_cpuindex.c | 68 -----
arch/arm64/src/common/arm64_cpustart.c | 71 +++--
arch/arm64/src/common/arm64_fatal.c | 2 +
arch/arm64/src/common/arm64_gic.h | 29 +-
arch/arm64/src/common/arm64_gicv3.c | 80 ++++--
arch/arm64/src/common/arm64_head.S | 79 ++++--
arch/arm64/src/common/arm64_mpu.c | 241 +++++++++++++++++
arch/arm64/src/common/arm64_mpu.h | 301 +++++++++++++++++++++
arch/arm64/src/common/arm64_systemreset.c | 2 +-
arch/arm64/src/qemu/Kconfig | 3 +
arch/arm64/src/qemu/qemu_boot.c | 74 ++++-
arch/arm64/src/qemu/qemu_boot.h | 6 +
arch/arm64/src/qemu/qemu_serial.c | 1 -
boards/arm64/a64/pinephone/configs/lcd/defconfig | 1 +
boards/arm64/a64/pinephone/configs/lvgl/defconfig | 1 +
boards/arm64/a64/pinephone/configs/nsh/defconfig | 1 +
.../arm64/a64/pinephone/configs/sensor/defconfig | 1 +
.../qemu/qemu-armv8a/configs/netnsh/defconfig | 1 +
.../qemu/qemu-armv8a/configs/netnsh_smp/defconfig | 1 +
.../arm64/qemu/qemu-armv8a/configs/nsh/defconfig | 2 +
.../qemu/qemu-armv8a/configs/nsh_gicv2/defconfig | 1 +
.../qemu/qemu-armv8a/configs/nsh_smp/defconfig | 2 +
32 files changed, 992 insertions(+), 165 deletions(-)
delete mode 100644 arch/arm64/src/common/arm64_cpuindex.c
create mode 100644 arch/arm64/src/common/arm64_mpu.c
create mode 100644 arch/arm64/src/common/arm64_mpu.h
[nuttx] 05/07: arm64: add 64-bit time for all arm64 platform
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit d5c6b8a94b61873e427805d99af9d1bb1604000c
Author: qinwei1 <qi...@xiaomi.com>
AuthorDate: Tue Feb 28 17:30:13 2023 +0800
arm64: add 64-bit time for all arm64 platform
Summary
For ARM64 architecture, the arch timer is 64-bit,
the CONFIG_SYSTEM_TIME64 need to be enabled just like
x86_64 and risc-v 64
Signed-off-by: qinwei1 <qi...@xiaomi.com>
---
arch/arm64/src/common/arm64_arch_timer.c | 4 ++--
boards/arm64/a64/pinephone/configs/lcd/defconfig | 1 +
boards/arm64/a64/pinephone/configs/lvgl/defconfig | 1 +
boards/arm64/a64/pinephone/configs/nsh/defconfig | 1 +
boards/arm64/a64/pinephone/configs/sensor/defconfig | 1 +
boards/arm64/qemu/qemu-armv8a/configs/netnsh/defconfig | 1 +
boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp/defconfig | 1 +
boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig | 1 +
boards/arm64/qemu/qemu-armv8a/configs/nsh_gicv2/defconfig | 1 +
boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig | 1 +
10 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/src/common/arm64_arch_timer.c b/arch/arm64/src/common/arm64_arch_timer.c
index 51518a2fee..c2e860aa41 100644
--- a/arch/arm64/src/common/arm64_arch_timer.c
+++ b/arch/arm64/src/common/arm64_arch_timer.c
@@ -134,7 +134,7 @@ static int arm64_arch_timer_compare_isr(int irq, void *regs, void *arg)
static int arm64_arch_timer_compare_isr(int irq, void *regs, void *arg)
{
uint64_t curr_cycle;
- uint32_t delta_ticks;
+ uint64_t delta_ticks;
uint64_t next_cycle;
UNUSED(irq);
@@ -142,7 +142,7 @@ static int arm64_arch_timer_compare_isr(int irq, void *regs, void *arg)
UNUSED(arg);
curr_cycle = arm64_arch_timer_count();
- delta_ticks = (uint32_t)((curr_cycle - last_cycle) / cycle_per_tick);
+ delta_ticks = (curr_cycle - last_cycle) / cycle_per_tick;
last_cycle += delta_ticks * cycle_per_tick;
diff --git a/boards/arm64/a64/pinephone/configs/lcd/defconfig b/boards/arm64/a64/pinephone/configs/lcd/defconfig
index f9e0313b6c..31a73b5089 100644
--- a/boards/arm64/a64/pinephone/configs/lcd/defconfig
+++ b/boards/arm64/a64/pinephone/configs/lcd/defconfig
@@ -61,6 +61,7 @@ CONFIG_START_YEAR=2022
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_SYSTEM=y
+CONFIG_SYSTEM_TIME64=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_UART1_SERIAL_CONSOLE=y
diff --git a/boards/arm64/a64/pinephone/configs/lvgl/defconfig b/boards/arm64/a64/pinephone/configs/lvgl/defconfig
index 925489f8ca..9dfd1147ec 100644
--- a/boards/arm64/a64/pinephone/configs/lvgl/defconfig
+++ b/boards/arm64/a64/pinephone/configs/lvgl/defconfig
@@ -79,6 +79,7 @@ CONFIG_START_YEAR=2022
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_SYSTEM=y
+CONFIG_SYSTEM_TIME64=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_UART1_SERIAL_CONSOLE=y
diff --git a/boards/arm64/a64/pinephone/configs/nsh/defconfig b/boards/arm64/a64/pinephone/configs/nsh/defconfig
index a858488067..c6813b13b8 100644
--- a/boards/arm64/a64/pinephone/configs/nsh/defconfig
+++ b/boards/arm64/a64/pinephone/configs/nsh/defconfig
@@ -60,6 +60,7 @@ CONFIG_START_YEAR=2022
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_SYSTEM=y
+CONFIG_SYSTEM_TIME64=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_UART1_SERIAL_CONSOLE=y
diff --git a/boards/arm64/a64/pinephone/configs/sensor/defconfig b/boards/arm64/a64/pinephone/configs/sensor/defconfig
index a416f9f029..351b871866 100644
--- a/boards/arm64/a64/pinephone/configs/sensor/defconfig
+++ b/boards/arm64/a64/pinephone/configs/sensor/defconfig
@@ -65,6 +65,7 @@ CONFIG_START_YEAR=2022
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_SYSTEM=y
+CONFIG_SYSTEM_TIME64=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_UART1_SERIAL_CONSOLE=y
diff --git a/boards/arm64/qemu/qemu-armv8a/configs/netnsh/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/netnsh/defconfig
index 343013cb74..05d91bbc78 100644
--- a/boards/arm64/qemu/qemu-armv8a/configs/netnsh/defconfig
+++ b/boards/arm64/qemu/qemu-armv8a/configs/netnsh/defconfig
@@ -80,6 +80,7 @@ CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_PING=y
CONFIG_SYSTEM_SYSTEM=y
CONFIG_SYSTEM_TELNETD_SESSION_STACKSIZE=8192
+CONFIG_SYSTEM_TIME64=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_UART1_SERIAL_CONSOLE=y
diff --git a/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp/defconfig
index dbab634430..88733f9011 100644
--- a/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp/defconfig
+++ b/boards/arm64/qemu/qemu-armv8a/configs/netnsh_smp/defconfig
@@ -84,6 +84,7 @@ CONFIG_SYSTEM_PING=y
CONFIG_SYSTEM_SYSTEM=y
CONFIG_SYSTEM_TASKSET=y
CONFIG_SYSTEM_TELNETD_SESSION_STACKSIZE=8192
+CONFIG_SYSTEM_TIME64=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_TESTING_SMP=y
diff --git a/boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig
index 821eb9c6c6..5b8ef369e2 100644
--- a/boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig
+++ b/boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig
@@ -60,6 +60,7 @@ CONFIG_START_YEAR=2022
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_SYSTEM=y
+CONFIG_SYSTEM_TIME64=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_UART1_SERIAL_CONSOLE=y
diff --git a/boards/arm64/qemu/qemu-armv8a/configs/nsh_gicv2/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/nsh_gicv2/defconfig
index f6056bb21d..bf88943447 100644
--- a/boards/arm64/qemu/qemu-armv8a/configs/nsh_gicv2/defconfig
+++ b/boards/arm64/qemu/qemu-armv8a/configs/nsh_gicv2/defconfig
@@ -60,6 +60,7 @@ CONFIG_START_YEAR=2022
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_SYSTEM=y
+CONFIG_SYSTEM_TIME64=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_UART1_SERIAL_CONSOLE=y
diff --git a/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig
index c7fdd37a93..bcd9830668 100644
--- a/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig
+++ b/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig
@@ -60,6 +60,7 @@ CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_SYSTEM=y
CONFIG_SYSTEM_TASKSET=y
+CONFIG_SYSTEM_TIME64=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
CONFIG_TESTING_OSTEST_STACKSIZE=16384
[nuttx] 02/07: arm64: add ARCH_EARLY_PRINT support
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 4240723b7850f5274a9629383b2c71d510d6db7b
Author: qinwei1 <qi...@xiaomi.com>
AuthorDate: Tue Feb 28 15:07:42 2023 +0800
arm64: add ARCH_EARLY_PRINT support
Summary:
The aarch64 have EL0~El3 execute level and NS/S (security state),
the NuttX should be execute at EL1 in NS(ARmv8-A) or S(ARmv8-R)
state. but booting NuttX have different ELs and state while with
different platform, if NuttX runing at wrong ELs or state it will
be not normal anymore. So we need to print something in arm64_head.S
to debug this situation.
Enabling this option will need to implement up_earlyserialinit and
up_lowputc functions just you see in qemu, if you not sure,
keeping the option disable.
Signed-off-by: qinwei1 <qi...@xiaomi.com>
---
arch/arm64/Kconfig | 13 +++++++++++++
arch/arm64/src/common/arm64_head.S | 15 ++++++++-------
boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig | 1 +
boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig | 1 +
4 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c50519b064..cb9c7fcc58 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -64,6 +64,19 @@ config ARCH_HAVE_PSCI
maybe not applicable for arm core without PCSI firmware
interface implement
+config ARCH_EARLY_PRINT
+ bool "arch early print support"
+ default n
+ ---help---
+ The aarch64 have EL0~El3 execute level and NS/S (security state),
+ the NuttX should be execute at EL1 in NS(ARmv8-A) or S(ARmv8-R)
+ state. but booting NuttX have different ELs and state while with
+ different platform, if NuttX runing at wrong ELs or state it will
+ be not normal anymore. So we need to print something in arm64_head.S
+ to debug this situation.
+ Enabling this option will need to implement up_earlyserialinit and
+ up_lowputc functions just you see in qemu, if you not sure,
+ keeping the option disable.
config ARCH_CORTEX_A53
bool
diff --git a/arch/arm64/src/common/arm64_head.S b/arch/arm64/src/common/arm64_head.S
index ec6cc41f40..82104b7d57 100644
--- a/arch/arm64/src/common/arm64_head.S
+++ b/arch/arm64/src/common/arm64_head.S
@@ -48,7 +48,7 @@
#define __HEAD_FLAGS ((__HEAD_FLAG_PAGE_SIZE << 1) | \
(__HEAD_FLAG_PHYS_BASE << 3))
-#ifdef CONFIG_DEBUG_FEATURES
+#ifdef CONFIG_ARCH_EARLY_PRINT
#define RODATA_STR(label, msg) \
.pushsection .rodata.str, "aMS", %progbits, 1 ; \
@@ -66,7 +66,7 @@ label: .asciz msg; \
RODATA_STR(boot_string_##sym, _s)
#else
#define PRINT(sym, s)
-#endif /* CONFIG_DEBUG_FEATURES */
+#endif /* CONFIG_ARCH_EARLY_PRINT */
/****************************************************************************
* Private Functions
@@ -166,7 +166,7 @@ primary_core:
bl __reset_prep_c
-#ifdef CONFIG_DEBUG_FEATURES
+#ifdef CONFIG_ARCH_EARLY_PRINT
/* Initialize the UART for early print.
* Should only be called on the boot CPU
*/
@@ -228,8 +228,9 @@ jump_to_c_entry:
/* Fail-stop */
fail:
- PRINT(fail, "- Boot failed -\r\n")
-1: wfe
+ /* Boot failed */
+
+1: wfe
b 1b
/* Set the minimum necessary to safely call C code */
@@ -283,7 +284,7 @@ out:
ret x23
-#ifdef CONFIG_DEBUG_FEATURES
+#ifdef CONFIG_ARCH_EARLY_PRINT
/* Print early debug messages.
* x0: Nul-terminated string to print.
@@ -303,4 +304,4 @@ boot_stage_puts:
.type boot_low_puts, %function;
-#endif /* !CONFIG_DEBUG_FEATURES */
+#endif /* !CONFIG_ARCH_EARLY_PRINT */
diff --git a/boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig
index 06af9b7ea3..821eb9c6c6 100644
--- a/boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig
+++ b/boards/arm64/qemu/qemu-armv8a/configs/nsh/defconfig
@@ -12,6 +12,7 @@ CONFIG_ARCH_BOARD_QEMU_ARMV8A=y
CONFIG_ARCH_CHIP="qemu"
CONFIG_ARCH_CHIP_QEMU=y
CONFIG_ARCH_CHIP_QEMU_A53=y
+CONFIG_ARCH_EARLY_PRINT=y
CONFIG_ARCH_INTERRUPTSTACK=4096
CONFIG_BUILTIN=y
CONFIG_DEBUG_ASSERTIONS=y
diff --git a/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig b/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig
index 3540638a72..c7fdd37a93 100644
--- a/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig
+++ b/boards/arm64/qemu/qemu-armv8a/configs/nsh_smp/defconfig
@@ -13,6 +13,7 @@ CONFIG_ARCH_BOARD_QEMU_ARMV8A=y
CONFIG_ARCH_CHIP="qemu"
CONFIG_ARCH_CHIP_QEMU=y
CONFIG_ARCH_CHIP_QEMU_A53=y
+CONFIG_ARCH_EARLY_PRINT=y
CONFIG_ARCH_INTERRUPTSTACK=8192
CONFIG_BUILTIN=y
CONFIG_DEBUG_ASSERTIONS=y
[nuttx] 04/07: arm64: ARMv8-r(Cortex-R82) support(add ARCH_SET_VMPIDR_EL2 option)
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 4cb5ff3353af37a50603f6c5a2b4fd9aceae107f
Author: qinwei1 <qi...@xiaomi.com>
AuthorDate: Tue Feb 28 17:02:37 2023 +0800
arm64: ARMv8-r(Cortex-R82) support(add ARCH_SET_VMPIDR_EL2 option)
Summary
VMPIDR_EL2 holds the value of the Virtualization Multiprocessor ID.
From architecture manual of AArch64, the behave is:
-reading register MPIDR_EL1 in EL2, it's return real MPIDR_EL1
-reading register MPIDR_EL1 in EL1, it's return VMPIDR_EL2
So since NuttX for SMP is running at EL1 to read MPIDR_EL1 for
identify CPU id, it's need to set VMPIDR_EL2 to MPIDR_EL1 for
every CPU at boot EL2 stage.
For some platform, the bootloader or hypervisor will do that at
the EL2 stage, but not all.
Signed-off-by: qinwei1 <qi...@xiaomi.com>
---
arch/arm64/Kconfig | 15 +++++++++++++++
arch/arm64/src/common/arm64_boot.c | 5 +++++
arch/arm64/src/common/arm64_cpustart.c | 1 -
3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index e0b187f002..c44ebec8cf 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -84,6 +84,21 @@ config ARCH_HAVE_EL3
runing at EL3 is not necessary and system register for EL3
is not accessible
+config ARCH_SET_VMPIDR_EL2
+ bool "Set VMPIDR_EL2 at EL2 stage"
+ help
+ VMPIDR_EL2 holds the value of the Virtualization Multiprocessor ID.
+ From architecture manual of AArch64, the behave is:
+ -reading register MPIDR_EL1 in EL2, it's return real MPIDR_EL1
+ -reading register MPIDR_EL1 in EL1, it's return VMPIDR_EL2
+ So since NuttX for SMP is running at EL1 to read MPIDR_EL1 for
+ identify CPU id, it's need to set VMPIDR_EL2 to MPIDR_EL1 for
+ every CPU at boot EL2 stage.
+ For some platform, the bootloader or hypervisor will do that at
+ the EL2 stage, but not all.
+ ARM FVP and VDK should set it since these platform will boot
+ without BootLoader.
+
config ARCH_EARLY_PRINT
bool "arch early print support"
default n
diff --git a/arch/arm64/src/common/arm64_boot.c b/arch/arm64/src/common/arm64_boot.c
index 1d4013733a..74ba8632ed 100644
--- a/arch/arm64/src/common/arm64_boot.c
+++ b/arch/arm64/src/common/arm64_boot.c
@@ -130,6 +130,11 @@ void arm64_boot_el2_init(void)
zero_sysreg(cnthp_ctl_el2);
#endif
+#ifdef CONFIG_ARCH_SET_VMPIDR_EL2
+ reg = read_sysreg(mpidr_el1);
+ write_sysreg(reg, vmpidr_el2);
+#endif
+
/* Enable this if/when we use the hypervisor timer.
* write_cnthp_cval_el2(~(uint64_t)0);
*/
diff --git a/arch/arm64/src/common/arm64_cpustart.c b/arch/arm64/src/common/arm64_cpustart.c
index 1eac831cf0..808799c8b2 100644
--- a/arch/arm64/src/common/arm64_cpustart.c
+++ b/arch/arm64/src/common/arm64_cpustart.c
@@ -149,7 +149,6 @@ static void arm64_start_cpu(int cpu_num, char *stack, int stack_sz,
{
uint64_t cpu_mpid = cpu_num;
-
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Notify of the start event */
[nuttx] 06/07: arm64: ARMv8-r(Cortex-R82) support(mpid fix)
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 518eb4076ed4ccf46eaf7f79a38b862b30eae74b
Author: qinwei1 <qi...@xiaomi.com>
AuthorDate: Tue Feb 28 21:31:23 2023 +0800
arm64: ARMv8-r(Cortex-R82) support(mpid fix)
Summary
Different ARM64 Core will use different Affn define, the mpidr_el1
value is not CPU number, So we need to change CPU number to mpid
and vice versa, the patch change the mpid define into platform
Signed-off-by: qinwei1 <qi...@xiaomi.com>
---
arch/arm64/include/qemu/chip.h | 2 +-
arch/arm64/src/common/Make.defs | 2 +-
arch/arm64/src/common/arm64_arch.h | 40 ++++++++++++++++++--
arch/arm64/src/common/arm64_cpuindex.c | 68 ----------------------------------
arch/arm64/src/common/arm64_cpustart.c | 6 ++-
arch/arm64/src/common/arm64_gicv3.c | 12 ++++--
arch/arm64/src/common/arm64_head.S | 60 ++++++++++++++++++++++--------
arch/arm64/src/qemu/qemu_boot.c | 52 ++++++++++++++++++++++++++
8 files changed, 148 insertions(+), 94 deletions(-)
diff --git a/arch/arm64/include/qemu/chip.h b/arch/arm64/include/qemu/chip.h
index 6b6cae7521..f854f888bc 100644
--- a/arch/arm64/include/qemu/chip.h
+++ b/arch/arm64/include/qemu/chip.h
@@ -44,7 +44,7 @@
#define CONFIG_GICD_BASE 0x8000000
#define CONFIG_GICR_BASE 0x80a0000
-
+#define CONFIG_GICR_OFFSET 0x20000
#else
#error CONFIG_ARM_GIC_VERSION should be 2, 3 or 4
diff --git a/arch/arm64/src/common/Make.defs b/arch/arm64/src/common/Make.defs
index eea3c1d3de..afae287cf6 100644
--- a/arch/arm64/src/common/Make.defs
+++ b/arch/arm64/src/common/Make.defs
@@ -78,7 +78,7 @@ CMN_CSRCS += arm64_cpu_psci.c arm64_systemreset.c
endif
ifeq ($(CONFIG_SMP),y)
-CMN_CSRCS += arm64_cpuidlestack.c arm64_cpustart.c arm64_cpuindex.c
+CMN_CSRCS += arm64_cpuidlestack.c arm64_cpustart.c
CMN_CSRCS += arm64_cpupause.c
endif
diff --git a/arch/arm64/src/common/arm64_arch.h b/arch/arm64/src/common/arm64_arch.h
index 61a61e6e78..dd30b3f185 100644
--- a/arch/arm64/src/common/arm64_arch.h
+++ b/arch/arm64/src/common/arm64_arch.h
@@ -156,12 +156,31 @@
#define MPIDR_AFF2_SHIFT (16)
#define MPIDR_AFF3_SHIFT (32)
+/* mpidr_el1 register, the register is define:
+ * - bit 0~7: Aff0
+ * - bit 8~15: Aff1
+ * - bit 16~23: Aff2
+ * - bit 24: MT, multithreading
+ * - bit 25~29: RES0
+ * - bit 30: U, multiprocessor/Uniprocessor
+ * - bit 31: RES1
+ * - bit 32~39: Aff3
+ * - bit 40~63: RES0
+ * Different ARM64 Core will use different Affn define, the mpidr_el1
+ * value is not CPU number, So we need to change CPU number to mpid
+ * and vice versa
+ */
+
+#define GET_MPIDR() read_sysreg(mpidr_el1)
+
#define MPIDR_AFFLVL(mpidr, aff_level) \
(((mpidr) >> MPIDR_AFF ## aff_level ## _SHIFT) & MPIDR_AFFLVL_MASK)
-#define GET_MPIDR() read_sysreg(mpidr_el1)
-#define MPIDR_TO_CORE(mpidr) MPIDR_AFFLVL((mpidr), 0)
-#define IS_PRIMARY_CORE() (!MPIDR_TO_CORE(GET_MPIDR()))
+#define MPID_TO_CORE(mpid, aff_level) \
+ (((mpid) >> MPIDR_AFF ## aff_level ## _SHIFT) & MPIDR_AFFLVL_MASK)
+
+#define CORE_TO_MPID(core, aff_level) \
+ (((core) << MPIDR_AFF ## aff_level ## _SHIFT))
/* System register interface to GICv3 */
@@ -529,6 +548,21 @@ void arm64_cpu_enable(void);
# define arm64_cpu_enable()
#endif
+/****************************************************************************
+ * Name: arm64_get_mpid
+ *
+ * Description:
+ * The function from cpu index to get cpu mpid which is reading
+ * from mpidr_el1 register. Different ARM64 Core will use different
+ * Affn define, the mpidr_el1 value is not CPU number, So we need
+ * to change CPU number to mpid and vice versa
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SMP
+uint64_t arm64_get_mpid(int cpu);
+#endif /* CONFIG_SMP */
+
#endif /* __ASSEMBLY__ */
#endif /* ___ARCH_ARM64_SRC_COMMON_ARM64_ARCH_H */
diff --git a/arch/arm64/src/common/arm64_cpuindex.c b/arch/arm64/src/common/arm64_cpuindex.c
deleted file mode 100644
index a0249d8273..0000000000
--- a/arch/arm64/src/common/arm64_cpuindex.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/****************************************************************************
- * arch/arm64/src/common/arm64_cpuindex.c
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership. The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <stdint.h>
-
-#include <nuttx/arch.h>
-
-#include "arm64_arch.h"
-
-#ifdef CONFIG_SMP
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: up_cpu_index
- *
- * Description:
- * Return an index in the range of 0 through (CONFIG_SMP_NCPUS-1) that
- * corresponds to the currently executing CPU.
- *
- * If TLS is enabled, then the RTOS can get this information from the TLS
- * info structure. Otherwise, the MCU-specific logic must provide some
- * mechanism to provide the CPU index.
- *
- * Input Parameters:
- * None
- *
- * Returned Value:
- * An integer index in the range of 0 through (CONFIG_SMP_NCPUS-1) that
- * corresponds to the currently executing CPU.
- *
- ****************************************************************************/
-
-int up_cpu_index(void)
-{
- /* Read the Multiprocessor Affinity Register (MPIDR)
- * And return the CPU ID field
- */
-
- return MPIDR_TO_CORE(GET_MPIDR());
-}
-
-#endif /* CONFIG_SMP */
diff --git a/arch/arm64/src/common/arm64_cpustart.c b/arch/arm64/src/common/arm64_cpustart.c
index 808799c8b2..926854a7f0 100644
--- a/arch/arm64/src/common/arm64_cpustart.c
+++ b/arch/arm64/src/common/arm64_cpustart.c
@@ -147,7 +147,9 @@ static void arm64_smp_init_top(void *arg)
static void arm64_start_cpu(int cpu_num, char *stack, int stack_sz,
arm64_cpustart_t fn)
{
- uint64_t cpu_mpid = cpu_num;
+ uint64_t cpu_mpid;
+
+ cpu_mpid = arm64_get_mpid(cpu_num);
#ifdef CONFIG_SCHED_INSTRUMENTATION
@@ -167,7 +169,7 @@ static void arm64_start_cpu(int cpu_num, char *stack, int stack_sz,
/* store mpid last as this is our synchronization point */
- cpu_boot_params.mpid = cpu_num;
+ cpu_boot_params.mpid = cpu_mpid;
flush_boot_params();
diff --git a/arch/arm64/src/common/arm64_gicv3.c b/arch/arm64/src/common/arm64_gicv3.c
index 3c23d0aa53..7b714b2383 100644
--- a/arch/arm64/src/common/arm64_gicv3.c
+++ b/arch/arm64/src/common/arm64_gicv3.c
@@ -145,6 +145,13 @@ static int gic_wait_rwp(uint32_t intid)
return 0;
}
+static inline void arm64_gic_write_irouter(uint64_t val, unsigned int intid)
+{
+ unsigned long addr = IROUTER(GET_DIST_BASE(intid), intid);
+
+ putreg64(val, addr);
+}
+
void arm64_gic_irq_set_priority(unsigned int intid, unsigned int prio,
uint32_t flags)
{
@@ -195,8 +202,7 @@ void arm64_gic_irq_enable(unsigned int intid)
if (GIC_IS_SPI(intid))
{
- putreg64(MPIDR_TO_CORE(GET_MPIDR()),
- IROUTER(GET_DIST_BASE(intid), intid));
+ arm64_gic_write_irouter(up_cpu_index(), intid);
}
}
@@ -608,7 +614,7 @@ static void arm64_gic_init(void)
cpu = this_cpu();
gic_rdists[cpu] = CONFIG_GICR_BASE +
- MPIDR_TO_CORE(GET_MPIDR()) * 0x20000;
+ up_cpu_index() * CONFIG_GICR_OFFSET;
err = gic_validate_redist_version();
if (err)
diff --git a/arch/arm64/src/common/arm64_head.S b/arch/arm64/src/common/arm64_head.S
index 40ded82937..47f052e3e2 100644
--- a/arch/arm64/src/common/arm64_head.S
+++ b/arch/arm64/src/common/arm64_head.S
@@ -122,43 +122,65 @@ real_start:
ldr x0, =cpu_boot_params
get_cpu_id x1
- /* If the cores start up at the same time, we should atomically load and
- * store the mpid into arm64_cpu_boot_params.
+ /* The global variable cpu_boot_params is not safety to
+ * access in some case. eg. Some debugger will reboot
+ * the NuttX but not reload the whole image, so it will
+ * be not predicable for the initial value of the global
+ * value in that case
+ *
+ * get_cpu_id is safety because the CPU identification is
+ * not change in any case, so the code will judge in a
+ * very simple method:
+ * -- Primary core will go on until it want to boot the
+ * other core. For NuttX OS usage case, we can consider
+ * the CPU id (the affinity of mpidr_el1) of primary
+ * core is always 0.
+ * -- The other cores will waiting until the primary
+ * core write mpid and notify it to go on
*/
- ldaxr x2, [x0, #BOOT_PARAM_MPID]
- cmp x2, #-1
- bne 1f
-
- /* try to store x1 (mpid) */
-
- stlxr w3, x1, [x0]
-
- /* If succeed, go to primary_core */
-
- cbz w3, primary_core
+ cmp x1, #0
+ beq primary_core
/* loop until our turn comes */
1: dmb ld
- ldr x2, [x0, #BOOT_PARAM_MPID]
+ wfe
+ ldr x2, [x0, #BOOT_PARAM_MPID]
cmp x1, x2
bne 1b
/* we can now load our stack pointer value and move on */
+
ldr x24, [x0, #BOOT_PARAM_SP]
add x24, x24, #(CONFIG_IDLETHREAD_STACKSIZE)
ldr x25, =arm64_boot_secondary_c_routine
bl __reset_prep_c
+
+ PRINT(second_boot, "- Ready to Boot Second CPU\r\n")
+
b cpu_boot
primary_core:
+ /* set primary core id */
+
+ str x1, [x0, #BOOT_PARAM_MPID]
+
ldr x24, [x0, #BOOT_PARAM_SP]
add x24, x24, #(CONFIG_IDLETHREAD_STACKSIZE)
#else
+ /* In some case, we need to boot one core in a SMP system,
+ * To avoid the primary core disturbed by the other cores,
+ * we need keep the other cores into WFE loop
+ */
+ get_cpu_id x1
+ cmp x1, #0
+ bne fail
+
/* load stack and entry point */
+
ldr x24, =(g_idle_stack + CONFIG_IDLETHREAD_STACKSIZE)
-#endif
+#endif /* CONFIG_SMP */
ldr x25, =arm64_boot_primary_c_routine
@@ -174,8 +196,14 @@ primary_core:
bl up_earlyserialinit
#endif
-cpu_boot:
+#ifdef CONFIG_SMP
+ PRINT(primary_boot, "- Ready to Boot Primary CPU\r\n")
+#else
PRINT(cpu_boot, "- Ready to Boot CPU\r\n")
+#endif
+
+cpu_boot:
+
/* Platform hook for highest EL */
bl arm64_el_init
diff --git a/arch/arm64/src/qemu/qemu_boot.c b/arch/arm64/src/qemu/qemu_boot.c
index aff6461b2f..f2b0873988 100644
--- a/arch/arm64/src/qemu/qemu_boot.c
+++ b/arch/arm64/src/qemu/qemu_boot.c
@@ -70,6 +70,58 @@ const struct arm_mmu_config mmu_config =
* Public Functions
****************************************************************************/
+#ifdef CONFIG_SMP
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_cpu_index
+ *
+ * Description:
+ * Return an index in the range of 0 through (CONFIG_SMP_NCPUS-1) that
+ * corresponds to the currently executing CPU.
+ *
+ * If TLS is enabled, then the RTOS can get this information from the TLS
+ * info structure. Otherwise, the MCU-specific logic must provide some
+ * mechanism to provide the CPU index.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * An integer index in the range of 0 through (CONFIG_SMP_NCPUS-1) that
+ * corresponds to the currently executing CPU.
+ *
+ ****************************************************************************/
+
+int up_cpu_index(void)
+{
+ /* Read the Multiprocessor Affinity Register (MPIDR)
+ * And return the CPU ID field
+ */
+
+ return MPID_TO_CORE(GET_MPIDR(), 0);
+}
+
+/****************************************************************************
+ * Name: arm64_get_mpid
+ *
+ * Description:
+ * The function from cpu index to get cpu mpid which is reading
+ * from mpidr_el1 register. Different ARM64 Core will use different
+ * Affn define, the mpidr_el1 value is not CPU number, So we need
+ * to change CPU number to mpid and vice versa
+ *
+ ****************************************************************************/
+
+uint64_t arm64_get_mpid(int cpu)
+{
+ return CORE_TO_MPID(cpu, 0);
+}
+
+#endif /* CONFIG_SMP */
/****************************************************************************
* Name: arm64_el_init
*
[nuttx] 03/07: arm64: ARMv8-r(Cortex-R82) support
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 0841f4dbaa700ef61b7c476f31cda8ef31bd0a95
Author: qinwei1 <qi...@xiaomi.com>
AuthorDate: Tue Feb 28 17:01:24 2023 +0800
arm64: ARMv8-r(Cortex-R82) support
Summary:
Adding armv8-r(Cortex-R82) support and modify some common code to
fit the change, the change including:
1. ARM Single Security State Support, ARMv8-R support only single
security state, and some GIC configure need to change and fit
2. For ARMv8-R, only have EL0 ~ EL2, the code at EL3 is not necessary
and system register for EL3 is not accessible(gcc will failed when
access these registers)
3. add base MPU configure for the platform.
Signed-off-by: qinwei1 <qi...@xiaomi.com>
---
arch/arm64/Kconfig | 20 ++
arch/arm64/src/Toolchain.defs | 6 +
arch/arm64/src/a64/a64_boot.c | 18 ++
arch/arm64/src/common/Make.defs | 20 +-
arch/arm64/src/common/arm64_arch_timer.c | 2 -
arch/arm64/src/common/arm64_boot.c | 8 +
arch/arm64/src/common/arm64_cpustart.c | 51 ++++--
arch/arm64/src/common/arm64_fatal.c | 2 +
arch/arm64/src/common/arm64_gic.h | 29 ++-
arch/arm64/src/common/arm64_gicv3.c | 70 +++++--
arch/arm64/src/common/arm64_head.S | 8 +-
arch/arm64/src/common/arm64_mpu.c | 241 +++++++++++++++++++++++++
arch/arm64/src/common/arm64_mpu.h | 301 +++++++++++++++++++++++++++++++
arch/arm64/src/qemu/qemu_boot.c | 20 ++
arch/arm64/src/qemu/qemu_boot.h | 6 +
arch/arm64/src/qemu/qemu_serial.c | 1 -
16 files changed, 761 insertions(+), 42 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index cb9c7fcc58..e0b187f002 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -49,10 +49,12 @@ endchoice
config ARCH_ARMV8A
bool
default n
+ select ARCH_HAVE_EL3
config ARCH_ARMV8R
bool
default n
+ select ARCH_SINGLE_SECURITY_STATE
config ARCH_HAVE_PSCI
bool "ARM PCSI (Power State Coordination Interface) Support"
@@ -64,6 +66,24 @@ config ARCH_HAVE_PSCI
maybe not applicable for arm core without PCSI firmware
interface implement
+config ARCH_SINGLE_SECURITY_STATE
+ bool "ARM Single Security State Support"
+ default n
+ ---help---
+ Some ARM aarch64 Cortex-family processors only supports single
+ security state(eg. Cortex-R82). For these Processors,
+ GIC or other ARM architecture feature will with different
+ configure
+
+config ARCH_HAVE_EL3
+ bool
+ default n
+ ---help---
+ Some ARM aarch64 Cortex-family processors only supports
+ EL0~El2(eg. Cortex-R82). For these Processors, the code
+ runing at EL3 is not necessary and system register for EL3
+ is not accessible
+
config ARCH_EARLY_PRINT
bool "arch early print support"
default n
diff --git a/arch/arm64/src/Toolchain.defs b/arch/arm64/src/Toolchain.defs
index 7b2c9cb0d0..a62d87c14e 100644
--- a/arch/arm64/src/Toolchain.defs
+++ b/arch/arm64/src/Toolchain.defs
@@ -34,12 +34,18 @@ ifeq ($(CONFIG_ARCH_ARMV8A),y)
ARCHCPUFLAGS += -march=armv8-a
endif
+ifeq ($(CONFIG_ARCH_ARMV8R),y)
+ ARCHCPUFLAGS += -march=armv8-r
+endif
+
ifeq ($(CONFIG_ARCH_CORTEX_A53),y)
ARCHCPUFLAGS += -mtune=cortex-a53
else ifeq ($(CONFIG_ARCH_CORTEX_A57),y)
ARCHCPUFLAGS += -mtune=cortex-a57
else ifeq ($(CONFIG_ARCH_CORTEX_A72),y)
ARCHCPUFLAGS += -mtune=cortex-a72
+else ifeq ($(CONFIG_ARCH_CORTEX_R82),y)
+ ARCHCPUFLAGS += -mtune=cortex-r82
endif
ifeq ($(CONFIG_DEBUG_CUSTOMOPT),y)
diff --git a/arch/arm64/src/a64/a64_boot.c b/arch/arm64/src/a64/a64_boot.c
index 02777e120e..65a5c8ce99 100644
--- a/arch/arm64/src/a64/a64_boot.c
+++ b/arch/arm64/src/a64/a64_boot.c
@@ -70,6 +70,24 @@ const struct arm_mmu_config mmu_config =
* Public Functions
****************************************************************************/
+/****************************************************************************
+ * Name: arm64_el_init
+ *
+ * Description:
+ * The function called from arm64_head.S at very early stage for these
+ * platform, it's use to:
+ * - Handling special hardware initialize routine which is need to
+ * run at high ELs
+ * - Initialize system software such as hypervisor or security firmware
+ * which is need to run at high ELs
+ *
+ ****************************************************************************/
+
+void arm64_el_init(void)
+{
+ /* TODO: A64 set init sys clock */
+}
+
/****************************************************************************
* Name: arm64_chip_boot
*
diff --git a/arch/arm64/src/common/Make.defs b/arch/arm64/src/common/Make.defs
index cc4aecdfc6..eea3c1d3de 100644
--- a/arch/arm64/src/common/Make.defs
+++ b/arch/arm64/src/common/Make.defs
@@ -50,13 +50,29 @@ CMN_CSRCS += arm64_schedulesigaction.c arm64_sigdeliver.c
CMN_CSRCS += arm64_backtrace.c arm64_getintstack.c arm64_registerdump.c
# Common C source files ( hardware BSP )
-CMN_CSRCS += arm64_mmu.c arm64_arch_timer.c arm64_cache.c
-CMN_CSRCS += arm64_doirq.c arm64_gicv2.c arm64_gicv3.c arm64_fatal.c
+CMN_CSRCS += arm64_arch_timer.c arm64_cache.c
+CMN_CSRCS += arm64_doirq.c arm64_fatal.c
CMN_CSRCS += arm64_syscall.c
# Use common heap allocation for now (may need to be customized later)
CMN_CSRCS += arm64_allocateheap.c
+ifeq ($(CONFIG_ARM_GIC_VERSION),3)
+CMN_CSRCS += arm64_gicv3.c
+endif
+
+ifeq ($(CONFIG_ARM_GIC_VERSION),2)
+CMN_CSRCS += arm64_gicv2.c
+endif
+
+ifeq ($(CONFIG_ARCH_HAVE_MMU),y)
+CMN_CSRCS += arm64_mmu.c
+endif
+
+ifeq ($(CONFIG_ARCH_HAVE_MPU),y)
+CMN_CSRCS += arm64_mpu.c
+endif
+
ifeq ($(CONFIG_ARCH_HAVE_PSCI),y)
CMN_CSRCS += arm64_cpu_psci.c arm64_systemreset.c
endif
diff --git a/arch/arm64/src/common/arm64_arch_timer.c b/arch/arm64/src/common/arm64_arch_timer.c
index 4500a1fad5..51518a2fee 100644
--- a/arch/arm64/src/common/arm64_arch_timer.c
+++ b/arch/arm64/src/common/arm64_arch_timer.c
@@ -221,8 +221,6 @@ void up_timer_initialize(void)
(unsigned long)(arch_timer_rate / 10000) % 100, cycle_per_tick);
irq_attach(ARM_ARCH_TIMER_IRQ, arm64_arch_timer_compare_isr, 0);
- arm64_gic_irq_set_priority(ARM_ARCH_TIMER_IRQ, ARM_ARCH_TIMER_PRIO,
- ARM_ARCH_TIMER_FLAGS);
curr_cycle = arm64_arch_timer_count();
arm64_arch_timer_set_compare(curr_cycle + cycle_per_tick);
diff --git a/arch/arm64/src/common/arm64_boot.c b/arch/arm64/src/common/arm64_boot.c
index 4b1492c01e..1d4013733a 100644
--- a/arch/arm64/src/common/arm64_boot.c
+++ b/arch/arm64/src/common/arm64_boot.c
@@ -36,6 +36,13 @@ extern void *_vector_table[];
* Public Functions
****************************************************************************/
+#ifdef CONFIG_ARCH_HAVE_EL3
+
+/* Some ARM aarch64 Cortex-family processors have not EL3
+ * these two function should never called
+ * defined to available compile error when with gcc option
+ */
+
void arm64_boot_el3_init(void)
{
uint64_t reg;
@@ -87,6 +94,7 @@ void arm64_boot_el3_get_next_el(uint64_t switch_addr)
write_sysreg(spsr, spsr_el3);
}
+#endif
void arm64_boot_el2_init(void)
{
diff --git a/arch/arm64/src/common/arm64_cpustart.c b/arch/arm64/src/common/arm64_cpustart.c
index 53262c7b39..1eac831cf0 100644
--- a/arch/arm64/src/common/arm64_cpustart.c
+++ b/arch/arm64/src/common/arm64_cpustart.c
@@ -43,7 +43,12 @@
#include "arm64_arch_timer.h"
#include "arm64_smp.h"
#include "arm64_cpu_psci.h"
+
+#ifdef CONFIG_ARCH_HAVE_MPU
+#include "arm64_mpu.h"
+#else
#include "arm64_mmu.h"
+#endif
/****************************************************************************
* Public data
@@ -58,6 +63,7 @@ struct arm64_boot_params
arm64_cpustart_t func;
void *arg;
int cpu_num;
+ volatile long cpu_ready_flag;
};
volatile struct arm64_boot_params aligned_data(L1_CACHE_BYTES)
@@ -76,8 +82,6 @@ volatile uint64_t *g_cpu_int_stacktop[CONFIG_SMP_NCPUS] =
* Private data
****************************************************************************/
-static volatile long cpu_ready_flag;
-
/****************************************************************************
* Private Functions
****************************************************************************/
@@ -89,12 +93,28 @@ static inline void local_delay(void)
}
}
+#ifdef CONFIG_ARCH_HAVE_MMU
+static void flush_boot_params(void)
+{
+ uintptr_t flush_start;
+ uintptr_t flush_end;
+
+ flush_start = (uintptr_t)&cpu_boot_params;
+ flush_end = flush_start + sizeof(cpu_boot_params);
+
+ up_flush_dcache(flush_start, flush_end);
+}
+#else
+static void flush_boot_params(void)
+{
+ /* TODO: Flush at MPU platform */
+}
+#endif
+
static void arm64_smp_init_top(void *arg)
{
struct tcb_s *tcb = this_task();
- cpu_ready_flag = 1;
-
#ifndef CONFIG_SUPPRESS_INTERRUPTS
/* And finally, enable interrupts */
@@ -118,6 +138,9 @@ static void arm64_smp_init_top(void *arg)
write_sysreg(tcb, tpidr_el1);
write_sysreg(tcb, tpidr_el0);
+ cpu_boot_params.cpu_ready_flag = 1;
+ SP_SEV();
+
nx_idle_trampoline();
}
@@ -126,8 +149,6 @@ static void arm64_start_cpu(int cpu_num, char *stack, int stack_sz,
{
uint64_t cpu_mpid = cpu_num;
- uintptr_t flush_start;
- uintptr_t flush_end;
#ifdef CONFIG_SCHED_INSTRUMENTATION
@@ -149,9 +170,7 @@ static void arm64_start_cpu(int cpu_num, char *stack, int stack_sz,
cpu_boot_params.mpid = cpu_num;
- flush_start = (uintptr_t)&cpu_boot_params;
- flush_end = flush_start + sizeof(cpu_boot_params);
- up_flush_dcache(flush_start, flush_end);
+ flush_boot_params();
#ifdef CONFIG_ARCH_HAVE_PSCI
if (psci_cpu_on(cpu_mpid, (uint64_t)__start))
@@ -216,15 +235,16 @@ int up_cpu_start(int cpu)
arm64_stack_color(g_cpu_idlestackalloc[cpu], SMP_STACK_SIZE);
#endif
- cpu_ready_flag = 0;
+ cpu_boot_params.cpu_ready_flag = 0;
arm64_start_cpu(cpu, (char *)g_cpu_idlestackalloc[cpu], SMP_STACK_SIZE,
arm64_smp_init_top);
/* Waiting for this CPU to be boot complete */
- while (!cpu_ready_flag)
+ while (!cpu_boot_params.cpu_ready_flag)
{
- local_delay();
+ SP_WFE();
+ flush_boot_params();
}
return 0;
@@ -237,7 +257,13 @@ void arm64_boot_secondary_c_routine(void)
arm64_cpustart_t func;
void *arg;
+#ifdef CONFIG_ARCH_HAVE_MPU
+ arm64_mpu_init(false);
+#endif
+
+#ifdef CONFIG_ARCH_HAVE_MMU
arm64_mmu_init(false);
+#endif
arm64_gic_secondary_init();
@@ -263,7 +289,6 @@ void arm64_boot_secondary_c_routine(void)
int arm64_smp_sgi_init(void)
{
irq_attach(SGI_CPU_PAUSE, arm64_pause_handler, 0);
- arm64_gic_irq_set_priority(SGI_CPU_PAUSE, IRQ_DEFAULT_PRIORITY, 0);
up_enable_irq(SGI_CPU_PAUSE);
return 0;
diff --git a/arch/arm64/src/common/arm64_fatal.c b/arch/arm64/src/common/arm64_fatal.c
index 36321ec828..0bb4b3b552 100644
--- a/arch/arm64/src/common/arm64_fatal.c
+++ b/arch/arm64/src/common/arm64_fatal.c
@@ -359,6 +359,7 @@ void arm64_fatal_error(unsigned int reason, struct regs_context * reg)
break;
}
+#ifdef CONFIG_ARCH_HAVE_EL3
case MODE_EL3:
{
sinfo("CurrentEL: MODE_EL3\n");
@@ -367,6 +368,7 @@ void arm64_fatal_error(unsigned int reason, struct regs_context * reg)
__asm__ volatile ("mrs %0, elr_el3" : "=r" (elr));
break;
}
+#endif
default:
{
diff --git a/arch/arm64/src/common/arm64_gic.h b/arch/arm64/src/common/arm64_gic.h
index 4cc1b01e2f..aa5ca27031 100644
--- a/arch/arm64/src/common/arm64_gic.h
+++ b/arch/arm64/src/common/arm64_gic.h
@@ -145,15 +145,38 @@
#define GIC_INT_DEF_PRI_X4 0xa0a0a0a0
-/* Register bit definitions */
+/* GICD_CTLR : Distributor Control Register
+ *
+ * [31](RO) RWP Register Write Pending:
+ * -- 0 No register write in progress
+ * -- 1 Register write in progress
+ * [30:8] - Reserved -
+ * [7](RW) E1NWF Enable 1 of N Wakeup Functionality 0
+ * [6](RO) DS Disable Security status:
+ * -- 0 The gicd_ctlr_ds signal was LOW when the GIC
+ * exited reset. Therefore, the Distributor supports
+ * two Security states and Non-secure accesses cannot
+ * access and modify registers that control Group 0
+ * interrupts.
+ * -- 1 The gicd_ctlr_ds signal was HIGH when the GIC
+ * exited reset. Therefore, the Distributor only supports
+ * a single Security state and Non-secure accesses
+ * can access and modify registers that control
+ * Group 0 interrupts.
+ * [5](RO) ARE_NS Affinity Routing Enable, Non-secure state
+ * [4](RO) ARE_S Affinity Routing Enable, Secure state
+ * [3] - Reserved -
+ * [2](RW) EnableGrp1S Enable Secure Group 1 interrupts
+ * [1](RW) EnableGrp1NS Enable Non-secure Group 1 interrupts
+ * [0](RW) EnableGrp0 Enable Group 0 interrupts
+ */
-/* GICD_CTLR Interrupt group definitions */
#define GICD_CTLR_ENABLE_G0 0
#define GICD_CTLR_ENABLE_G1NS 1
#define GICD_CTLR_ENABLE_G1S 2
#define GICD_CTRL_ARE_S 4
#define GICD_CTRL_ARE_NS 5
-#define GICD_CTRL_NS 6
+#define GICD_CTRL_DS 6
#define GICD_CGRL_E1NWF 7
/* GICD_CTLR Register write progress bit */
diff --git a/arch/arm64/src/common/arm64_gicv3.c b/arch/arm64/src/common/arm64_gicv3.c
index 5df8b9c9cc..3c23d0aa53 100644
--- a/arch/arm64/src/common/arm64_gicv3.c
+++ b/arch/arm64/src/common/arm64_gicv3.c
@@ -73,6 +73,32 @@ static unsigned long gic_rdists[CONFIG_SMP_NCPUS];
* Private Functions
***************************************************************************/
+static inline void sys_set_bit(unsigned long addr, unsigned int bit)
+{
+ uint32_t temp;
+
+ temp = getreg32(addr);
+ temp = temp | (BIT(bit));
+ putreg32(temp, addr);
+}
+
+static inline void sys_clear_bit(unsigned long addr, unsigned int bit)
+{
+ uint32_t temp;
+
+ temp = getreg32(addr);
+ temp = temp & ~(BIT(bit));
+ putreg32(temp, addr);
+}
+
+static inline int sys_test_bit(unsigned long addr, unsigned int bit)
+{
+ uint32_t temp;
+
+ temp = getreg32(addr);
+ return (temp & BIT(bit));
+}
+
static inline unsigned long gic_get_rdist(void)
{
return gic_rdists[this_cpu()];
@@ -170,7 +196,7 @@ void arm64_gic_irq_enable(unsigned int intid)
if (GIC_IS_SPI(intid))
{
putreg64(MPIDR_TO_CORE(GET_MPIDR()),
- IROUTER(GET_DIST_BASE(intid), intid));
+ IROUTER(GET_DIST_BASE(intid), intid));
}
}
@@ -262,16 +288,12 @@ int arm64_gic_raise_sgi(unsigned int sgi_id, uint64_t target_aff,
static void gicv3_rdist_enable(unsigned long rdist)
{
- uint32_t temp;
-
if (!(getreg32(rdist + GICR_WAKER) & BIT(GICR_WAKER_CA)))
{
return;
}
- temp = getreg32(rdist + GICR_WAKER);
- temp = temp & ~(BIT(GICR_WAKER_PS));
- putreg32(temp, rdist + GICR_WAKER);
+ sys_clear_bit(rdist + GICR_WAKER, GICR_WAKER_PS);
while (getreg32(rdist + GICR_WAKER) & BIT(GICR_WAKER_CA))
{
@@ -361,17 +383,19 @@ static void gicv3_dist_init(void)
putreg32(0, GICD_CTLR);
gic_wait_rwp(GIC_SPI_INT_BASE);
-#if 0
+#ifdef CONFIG_ARCH_SINGLE_SECURITY_STATE
/* Before configuration, we need to check whether
* the GIC single security state mode is supported.
* Make sure GICD_CTRL_NS is 1.
*/
- sys_set_bit(GICD_CTLR, GICD_CTRL_NS);
- __ASSERT(sys_test_bit(GICD_CTLR,
- GICD_CTRL_NS),
- "Current GIC does not support single security state");
+ sys_set_bit(GICD_CTLR, GICD_CTRL_DS);
+ if (!sys_test_bit(GICD_CTLR, GICD_CTRL_DS))
+ {
+ sinfo("Current GIC does not support single security state\n");
+ PANIC();
+ }
#endif
/* Default configuration of all SPIs */
@@ -416,15 +440,12 @@ static void gicv3_dist_init(void)
putreg32(0, ICFGR(base, idx));
}
- /* Enable distributor with ARE */
-
- putreg32(BIT(GICD_CTRL_ARE_NS) | BIT(GICD_CTLR_ENABLE_G1NS),
- GICD_CTLR);
-#if 0
+ /* TODO: Some arrch64 Cortex-A core maybe without security state
+ * it has different GIC configure with standard arrch64 A or R core
+ */
- /* TODO: ARMv8-R support
- *
- * For GIC single security state(ARMv8-R), the config means
+#ifdef CONFIG_ARCH_SINGLE_SECURITY_STATE
+ /* For GIC single security state(ARMv8-R), the config means
* the GIC is under single security state which has
* only two groups:
* group 0 and group 1.
@@ -437,11 +458,20 @@ static void gicv3_dist_init(void)
putreg32(BIT(GICD_CTRL_ARE_S) | BIT(GICD_CTLR_ENABLE_G1NS),
GICD_CTLR);
+
+#else
+ /* Enable distributor with ARE */
+
+ putreg32(BIT(GICD_CTRL_ARE_NS) | BIT(GICD_CTLR_ENABLE_G1NS),
+ GICD_CTLR);
#endif
}
void up_enable_irq(int irq)
{
+ /* TODO: add common interface to set IRQ type for NuttX */
+
+ arm64_gic_irq_set_priority(irq, IRQ_DEFAULT_PRIORITY, IRQ_TYPE_LEVEL);
arm64_gic_irq_enable(irq);
}
@@ -563,7 +593,7 @@ static int gic_validate_redist_version(void)
ppi_nr = 0;
}
- sinfo("GICD_TYPER = 0x%"PRIx64"\n", typer);
+ sinfo("GICR_TYPER = 0x%"PRIx64"\n", typer);
sinfo("%d PPIs implemented\n", ppi_nr);
sinfo("%sVLPI support, %sdirect LPI support\n", !has_vlpis ? "no " : "",
!has_direct_lpi ? "no " : "");
diff --git a/arch/arm64/src/common/arm64_head.S b/arch/arm64/src/common/arm64_head.S
index 82104b7d57..40ded82937 100644
--- a/arch/arm64/src/common/arm64_head.S
+++ b/arch/arm64/src/common/arm64_head.S
@@ -176,10 +176,14 @@ primary_core:
cpu_boot:
PRINT(cpu_boot, "- Ready to Boot CPU\r\n")
+ /* Platform hook for highest EL */
+
+ bl arm64_el_init
switch_el:
switch_el x0, 3f, 2f, 1f
3:
+#ifdef CONFIG_ARCH_HAVE_EL3
PRINT(switch_el3, "- Boot from EL3\r\n")
/* EL3 init */
@@ -191,7 +195,7 @@ switch_el:
adr x0, switch_el
bl arm64_boot_el3_get_next_el
eret
-
+#endif
2:
PRINT(switch_el2, "- Boot from EL2\r\n")
@@ -243,10 +247,12 @@ __reset_prep_c:
switch_el x0, 3f, 2f, 1f
3:
+#ifdef CONFIG_ARCH_HAVE_EL3
/* Reinitialize SCTLR from scratch in EL3 */
ldr w0, =(SCTLR_EL3_RES1 | SCTLR_I_BIT | SCTLR_SA_BIT)
msr sctlr_el3, x0
+#endif
/* Set SP_EL1 */
diff --git a/arch/arm64/src/common/arm64_mpu.c b/arch/arm64/src/common/arm64_mpu.c
new file mode 100644
index 0000000000..3344d5f544
--- /dev/null
+++ b/arch/arm64/src/common/arm64_mpu.c
@@ -0,0 +1,241 @@
+/***************************************************************************
+ * arch/arm64/src/common/arm64_mpu.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ***************************************************************************/
+
+/***************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include <nuttx/config.h>
+#include <stdint.h>
+#include <debug.h>
+#include <assert.h>
+
+#include <nuttx/arch.h>
+#include <arch/irq.h>
+#include <arch/chip/chip.h>
+
+#include "arm64_arch.h"
+#include "arm64_internal.h"
+#include "arm64_fatal.h"
+#include "arm64_mpu.h"
+
+/***************************************************************************
+ * Pre-processor Definitions
+ ***************************************************************************/
+
+#define __MPU_ASSERT(__cond, fmt, ...) \
+ do \
+ { \
+ if (!(__cond)) \
+ { \
+ sinfo(fmt, ## __VA_ARGS__); \
+ PANIC(); \
+ } \
+ } \
+ while (false)
+
+/* AArch64 Memory Model Feature Register 0
+ * Provides information about the implemented memory model and memory
+ * management support in AArch64 state.
+ * See Arm Architecture Reference Manual Supplement
+ * Armv8, for Armv8-R AArch64 architecture profile, G1.3.7
+ *
+ * ID_AA64MMFR0_MSA_FRAC, bits[55:52]
+ * ID_AA64MMFR0_MSA, bits [51:48]
+ */
+
+#define ID_AA64MMFR0_MSA_MSK (0xFFUL << 48U)
+#define ID_AA64MMFR0_PMSA_EN (0x1FUL << 48U)
+#define ID_AA64MMFR0_PMSA_VMSA_EN (0x2FUL << 48U)
+
+/* Global status variable holding the number of HW MPU region indices, which
+ * have been reserved by the MPU driver to program the static (fixed) memory
+ * regions.
+ */
+
+static uint8_t static_regions_num;
+
+/***************************************************************************
+ * Private Functions
+ ***************************************************************************/
+
+/* Get the number of supported MPU regions. */
+
+static inline uint8_t get_num_regions(void)
+{
+ uint64_t type;
+
+ type = read_sysreg(mpuir_el1);
+ type = type & MPU_IR_REGION_MSK;
+
+ return (uint8_t)type;
+}
+
+/* ARM Core MPU Driver API Implementation for ARM MPU */
+
+/**
+ * @brief enable the MPU
+ */
+
+void arm64_core_mpu_enable(void)
+{
+ uint64_t val;
+
+ val = read_sysreg(sctlr_el1);
+ val |= SCTLR_M_BIT;
+ write_sysreg(val, sctlr_el1);
+ ARM64_DSB();
+ ARM64_ISB();
+}
+
+/**
+ * @brief disable the MPU
+ */
+
+void arm64_core_mpu_disable(void)
+{
+ uint64_t val;
+
+ /* Force any outstanding transfers to complete before disabling MPU */
+
+ ARM64_DMB();
+
+ val = read_sysreg(sctlr_el1);
+ val &= ~SCTLR_M_BIT;
+ write_sysreg(val, sctlr_el1);
+ ARM64_DSB();
+ ARM64_ISB();
+}
+
+/* ARM MPU Driver Initial Setup
+ *
+ * Configure the cache-ability attributes for all the
+ * different types of memory regions.
+ */
+
+static void mpu_init(void)
+{
+ /* Device region(s): Attribute-0
+ * Flash region(s): Attribute-1
+ * SRAM region(s): Attribute-2
+ * SRAM no cache-able regions(s): Attribute-3
+ */
+
+ uint64_t mair = MPU_MAIR_ATTRS;
+
+ write_sysreg(mair, mair_el1);
+ ARM64_DSB();
+ ARM64_ISB();
+}
+
+static inline void mpu_set_region(uint32_t rnr, uint64_t rbar,
+ uint64_t rlar)
+{
+ write_sysreg(rnr, prselr_el1);
+ ARM64_DSB();
+ write_sysreg(rbar, prbar_el1);
+ write_sysreg(rlar, prlar_el1);
+ ARM64_DSB();
+ ARM64_ISB();
+}
+
+/* This internal functions performs MPU region initialization. */
+
+static void region_init(const uint32_t index,
+ const struct arm64_mpu_region *region_conf)
+{
+ uint64_t rbar = region_conf->base & MPU_RBAR_BASE_MSK;
+ uint64_t rlar = (region_conf->limit - 1) & MPU_RLAR_LIMIT_MSK;
+
+ rbar |= region_conf->attr.rbar &
+ (MPU_RBAR_XN_MSK | MPU_RBAR_AP_MSK | MPU_RBAR_SH_MSK);
+ rlar |=
+ (region_conf->attr.mair_idx <<
+ MPU_RLAR_ATTRINDX_POS) & MPU_RLAR_ATTRINDX_MSK;
+ rlar |= MPU_RLAR_EN_MSK;
+
+ mpu_set_region(index, rbar, rlar);
+}
+
+/***************************************************************************
+ * Public Functions
+ ***************************************************************************/
+
+/* @brief MPU default configuration
+ *
+ * This function here provides the default configuration mechanism
+ * for the Memory Protection Unit (MPU).
+ */
+
+void arm64_mpu_init(bool is_primary_core)
+{
+ uint64_t val;
+ uint32_t r_index;
+
+ /* Current MPU code supports only EL1 */
+
+ __asm__ volatile ("mrs %0, CurrentEL" : "=r" (val));
+
+ __MPU_ASSERT(GET_EL(
+ val) == MODE_EL1,
+ "Exception level not EL1, MPU not enabled!\n");
+
+ /* Check whether the processor supports MPU */
+
+ val = read_sysreg(id_aa64mmfr0_el1) & ID_AA64MMFR0_MSA_MSK;
+ if ((val != ID_AA64MMFR0_PMSA_EN) && (val != ID_AA64MMFR0_PMSA_VMSA_EN))
+ {
+ __MPU_ASSERT(0, "MPU not supported!\n");
+ return;
+ }
+
+ if (mpu_config.num_regions > get_num_regions())
+ {
+ /* Attempt to configure more MPU regions than
+ * what is supported by hardware. As this operation
+ * is executed during system (pre-kernel) initialization,
+ * we want to ensure we can detect an attempt to
+ * perform invalid configuration.
+ */
+
+ __MPU_ASSERT(0, "Request to configure: %u regions (supported: %u)\n",
+ mpu_config.num_regions, get_num_regions());
+ return;
+ }
+
+ arm64_core_mpu_disable();
+
+ /* Architecture-specific configuration */
+
+ mpu_init();
+
+ /* Program fixed regions configured at SOC definition. */
+
+ for (r_index = 0U; r_index < mpu_config.num_regions; r_index++)
+ {
+ region_init(r_index, &mpu_config.mpu_regions[r_index]);
+ }
+
+ /* Update the number of programmed MPU regions. */
+
+ static_regions_num = mpu_config.num_regions;
+
+ arm64_core_mpu_enable();
+}
diff --git a/arch/arm64/src/common/arm64_mpu.h b/arch/arm64/src/common/arm64_mpu.h
new file mode 100644
index 0000000000..fe19fdaf43
--- /dev/null
+++ b/arch/arm64/src/common/arm64_mpu.h
@@ -0,0 +1,301 @@
+/****************************************************************************
+ * arch/arm64/src/common/arm64_mpu.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM64_SRC_COMMON_ARM64_MPU_H
+#define __ARCH_ARM64_SRC_COMMON_ARM64_MPU_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include "arm64_arch.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Convenience macros to represent the ARMv8-R64-specific configuration
+ * for memory access permission and cache-ability attribution.
+ */
+
+/* MPU MPUIR Register Definitions */
+
+#define MPU_IR_REGION_MSK (0xFFU)
+
+/* MPU RBAR Register attribute msk Definitions */
+
+#define MPU_RBAR_BASE_POS 6U
+#define MPU_RBAR_BASE_MSK (0x3FFFFFFFFFFFFFFUL << MPU_RBAR_BASE_POS)
+#define MPU_RBAR_SH_POS 4U
+#define MPU_RBAR_SH_MSK (0x3UL << MPU_RBAR_SH_POS)
+#define MPU_RBAR_AP_POS 2U
+#define MPU_RBAR_AP_MSK (0x3UL << MPU_RBAR_AP_POS)
+
+/* RBAR_EL1 XN */
+
+#define MPU_RBAR_XN_POS 1U
+#define MPU_RBAR_XN_MSK (0x1UL << MPU_RBAR_XN_POS)
+
+/* MPU PLBAR_ELx Register Definitions */
+
+#define MPU_RLAR_LIMIT_POS 6U
+#define MPU_RLAR_LIMIT_MSK (0x3FFFFFFFFFFFFFFUL << MPU_RLAR_LIMIT_POS)
+#define MPU_RLAR_ATTRINDX_POS 1U
+#define MPU_RLAR_ATTRINDX_MSK (0x7UL << MPU_RLAR_ATTRINDX_POS)
+#define MPU_RLAR_EN_MSK (0x1UL)
+
+/* PRBAR_ELx: Attribute flag for not-allowing
+ * execution (eXecute Never)
+ */
+
+#define NOT_EXEC MPU_RBAR_XN_MSK /* PRBAR_EL1 */
+
+/* PRBAR_ELx: Attribute flag for access permissions
+ * Privileged Read Write, Unprivileged No Access
+ */
+
+#define P_RW_U_NA 0x0U
+#define P_RW_U_NA_MSK ((P_RW_U_NA << \
+ MPU_RBAR_AP_POS) & MPU_RBAR_AP_MSK)
+
+/* Privileged Read Write, Unprivileged Read Write */
+
+#define P_RW_U_RW 0x1U
+#define P_RW_U_RW_MSK ((P_RW_U_RW << \
+ MPU_RBAR_AP_POS) & MPU_RBAR_AP_MSK)
+
+/* Privileged Read Only, Unprivileged No Access */
+
+#define P_RO_U_NA 0x2U
+#define P_RO_U_NA_MSK ((P_RO_U_NA << \
+ MPU_RBAR_AP_POS) & MPU_RBAR_AP_MSK)
+
+/* Privileged Read Only, Unprivileged Read Only */
+
+#define P_RO_U_RO 0x3U
+#define P_RO_U_RO_MSK ((P_RO_U_RO << \
+ MPU_RBAR_AP_POS) & MPU_RBAR_AP_MSK)
+
+/* PRBAR_ELx: Attribute flags for share-ability */
+
+#define NON_SHAREABLE 0x0U
+#define NON_SHAREABLE_MSK \
+ ((NON_SHAREABLE << MPU_RBAR_SH_POS) & MPU_RBAR_SH_MSK)
+#define OUTER_SHAREABLE 0x2U
+#define OUTER_SHAREABLE_MSK \
+ ((OUTER_SHAREABLE << MPU_RBAR_SH_POS) & MPU_RBAR_SH_MSK)
+#define INNER_SHAREABLE 0x3U
+#define INNER_SHAREABLE_MSK \
+ ((INNER_SHAREABLE << MPU_RBAR_SH_POS) & MPU_RBAR_SH_MSK)
+
+/* MPIR_ELx Attribute flags for cache-ability */
+
+/* Memory Attributes for Device Memory
+ * 1.Gathering (G/nG)
+ * Determines whether multiple accesses can be merged into a single
+ * bus transaction.
+ * nG: Number/size of accesses on the bus = number/size of accesses
+ * in code.
+ *
+ * 2.Reordering (R/nR)
+ * Determines whether accesses to the same device can be reordered.
+ * nR: Accesses to the same IMPLEMENTATION DEFINED block size will
+ * appear on the bus in program order.
+ *
+ * 3 Early Write Acknowledgment (E/nE)
+ * Indicates to the memory system whether a buffer can send
+ * acknowledgements.
+ * nE: The response should come from the end slave, not buffering in
+ * the interconnect.
+ */
+
+#define DEVICE_nGnRnE 0x0U
+#define DEVICE_nGnRE 0x4U
+#define DEVICE_nGRE 0x8U
+#define DEVICE_GRE 0xCU
+
+/* Read/Write Allocation Configurations for Cacheable Memory
+ * R_NON_W_NON: Do not allocate Read/Write
+ * R_NON_W_ALLOC: Do not allocate Read, Allocate Write
+ * R_ALLOC_W_NON: Allocate Read, Do not allocate Write
+ * R_ALLOC_W_ALLOC: Allocate Read/Write
+ */
+
+#define R_NON_W_NON 0x0U
+#define R_NON_W_ALLOC 0x1U
+#define R_ALLOC_W_NON 0x2U
+#define R_ALLOC_W_ALLOC 0x3U
+
+/* Memory Attributes for Normal Memory
+ * NORMAL_O_WT_NT: Normal, Outer Write-through on-transient
+ * NORMAL_O_WB_NT: Normal, Outer Write-back non-transient
+ * NORMAL_O_NON_C: Normal, Outer Non-Cacheable
+ * NORMAL_I_WT_NT: Normal, Inner Write-through non-transient
+ * NORMAL_I_WB_NT: Normal, Inner Write-back non-transient
+ * NORMAL_I_NON_C: Normal, Inner Non-Cacheable
+ */
+#define NORMAL_O_WT_NT 0x80U
+#define NORMAL_O_WB_NT 0xC0U
+#define NORMAL_O_NON_C 0x40U
+#define NORMAL_I_WT_NT 0x08U
+#define NORMAL_I_WB_NT 0x0CU
+#define NORMAL_I_NON_C 0x04U
+
+/* Global MAIR configurations */
+
+#define MPU_MAIR_INDEX_DEVICE 0U
+#define MPU_MAIR_ATTR_DEVICE (DEVICE_nGnRnE)
+
+#define MPU_MAIR_INDEX_FLASH 1U
+#define MPU_MAIR_ATTR_FLASH \
+ ((NORMAL_O_WT_NT | (R_ALLOC_W_NON << 4)) | \
+ (NORMAL_I_WT_NT | R_ALLOC_W_NON))
+
+#define MPU_MAIR_INDEX_SRAM 2U
+#define MPU_MAIR_ATTR_SRAM \
+ ((NORMAL_O_WB_NT | (R_ALLOC_W_ALLOC << 4)) | \
+ (NORMAL_I_WB_NT | R_ALLOC_W_ALLOC))
+
+#define MPU_MAIR_INDEX_SRAM_NOCACHE 3U
+#define MPU_MAIR_ATTR_SRAM_NOCACHE \
+ ((NORMAL_O_NON_C | (R_NON_W_NON << 4)) | \
+ (NORMAL_I_NON_C | R_NON_W_NON))
+
+#define MPU_MAIR_ATTRS \
+ ((MPU_MAIR_ATTR_DEVICE << (MPU_MAIR_INDEX_DEVICE * 8)) | \
+ (MPU_MAIR_ATTR_FLASH << (MPU_MAIR_INDEX_FLASH * 8)) | \
+ (MPU_MAIR_ATTR_SRAM << (MPU_MAIR_INDEX_SRAM * 8)) | \
+ (MPU_MAIR_ATTR_SRAM_NOCACHE << (MPU_MAIR_INDEX_SRAM_NOCACHE * 8)))
+
+/* Some helper defines for common regions.
+ *
+ * Note that the ARMv8-R MPU architecture requires that the
+ * enabled MPU regions are non-overlapping. Therefore, it is
+ * recommended to use these helper defines only for configuring
+ * fixed MPU regions at build-time.
+ */
+
+#define REGION_DEVICE_ATTR \
+ { \
+ /* AP, XN, SH */ \
+ .rbar = NOT_EXEC | P_RW_U_NA_MSK | NON_SHAREABLE_MSK, \
+ /* Cache-ability */ \
+ .mair_idx = MPU_MAIR_INDEX_DEVICE, \
+ }
+
+#define REGION_RAM_ATTR \
+ { \
+ /* AP, XN, SH */ \
+ .rbar = NOT_EXEC | P_RW_U_NA_MSK | NON_SHAREABLE_MSK, \
+ /* Cache-ability */ \
+ .mair_idx = MPU_MAIR_INDEX_SRAM, \
+ }
+
+#define REGION_RAM_TEXT_ATTR \
+ { \
+ /* AP, XN, SH */ \
+ .rbar = P_RO_U_RO_MSK | NON_SHAREABLE_MSK, \
+ /* Cache-ability */ \
+ .mair_idx = MPU_MAIR_INDEX_SRAM, \
+ }
+
+#define REGION_RAM_RO_ATTR \
+ { \
+ /* AP, XN, SH */ \
+ .rbar = NOT_EXEC | P_RO_U_RO_MSK | NON_SHAREABLE_MSK, \
+ /* Cache-ability */ \
+ .mair_idx = MPU_MAIR_INDEX_SRAM, \
+ }
+
+#ifndef __ASSEMBLY__
+
+struct arm64_mpu_region_attr
+{
+ /* Attributes belonging to PRBAR */
+
+ uint8_t rbar : 5;
+
+ /* MAIR index for attribute indirection */
+
+ uint8_t mair_idx : 3;
+};
+
+/* Region definition data structure */
+
+struct arm64_mpu_region
+{
+ /* Region Base Address */
+
+ uint64_t base;
+
+ /* Region limit Address */
+
+ uint64_t limit;
+
+ /* Region Name */
+
+ const char *name;
+
+ /* Region Attributes */
+
+ struct arm64_mpu_region_attr attr;
+};
+
+/* MPU configuration data structure */
+
+struct arm64_mpu_config
+{
+ /* Number of regions */
+
+ uint32_t num_regions;
+
+ /* Regions */
+
+ const struct arm64_mpu_region *mpu_regions;
+};
+
+#define MPU_REGION_ENTRY(_name, _base, _limit, _attr) \
+ { \
+ .name = _name, \
+ .base = _base, \
+ .limit = _limit, \
+ .attr = _attr, \
+ }
+
+/* Reference to the MPU configuration.
+ *
+ * This struct is defined and populated for each SoC (in the SoC definition),
+ * and holds the build-time configuration information for the fixed MPU
+ * regions enabled during kernel initialization.
+ */
+
+extern const struct arm64_mpu_config mpu_config;
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+void arm64_mpu_init(bool is_primary_core);
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ARCH_ARM64_SRC_COMMON_ARM64_MPU_H */
diff --git a/arch/arm64/src/qemu/qemu_boot.c b/arch/arm64/src/qemu/qemu_boot.c
index 3859e37f55..aff6461b2f 100644
--- a/arch/arm64/src/qemu/qemu_boot.c
+++ b/arch/arm64/src/qemu/qemu_boot.c
@@ -70,6 +70,26 @@ const struct arm_mmu_config mmu_config =
* Public Functions
****************************************************************************/
+/****************************************************************************
+ * Name: arm64_el_init
+ *
+ * Description:
+ * The function called from arm64_head.S at very early stage for these
+ * platform, it's use to:
+ * - Handling special hardware initialize routine which is need to
+ * run at high ELs
+ * - Initialize system software such as hypervisor or security firmware
+ * which is need to run at high ELs
+ *
+ ****************************************************************************/
+
+void arm64_el_init(void)
+{
+ write_sysreg(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, cntfrq_el0);
+
+ ARM64_ISB();
+}
+
/****************************************************************************
* Name: arm64_chip_boot
*
diff --git a/arch/arm64/src/qemu/qemu_boot.h b/arch/arm64/src/qemu/qemu_boot.h
index 3bee81edb1..b61c89a336 100644
--- a/arch/arm64/src/qemu/qemu_boot.h
+++ b/arch/arm64/src/qemu/qemu_boot.h
@@ -34,6 +34,12 @@
#include "arm64_internal.h"
#include "arm64_arch.h"
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC 62500000
+
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
diff --git a/arch/arm64/src/qemu/qemu_serial.c b/arch/arm64/src/qemu/qemu_serial.c
index 4af6611e24..6f5d295a6b 100644
--- a/arch/arm64/src/qemu/qemu_serial.c
+++ b/arch/arm64/src/qemu/qemu_serial.c
@@ -612,7 +612,6 @@ static int qemu_pl011_attach(struct uart_dev_s *dev)
data = &sport->data;
ret = irq_attach(sport->irq_num, qemu_pl011_irq_handler, dev);
- arm64_gic_irq_set_priority(sport->irq_num, IRQ_TYPE_LEVEL, 0);
if (ret == OK)
{
[nuttx] 01/07: arm64: PSCI config support
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit e5564a98723563f235508a255debeb725b3aed37
Author: qinwei1 <qi...@xiaomi.com>
AuthorDate: Tue Feb 28 14:23:02 2023 +0800
arm64: PSCI config support
Summory
This Power State Coordination Interface (PSCI) defines a standard
interface for power management. the PCSI need to implement handling
firmware at EL2 or EL3 for ARM64. the PSCI maybe not applicable
for arm core without PCSI firmware interface implement.
Add configure option for it.
Note:
1. ostest is PASSED at qemu and fvp ( single core and SMP)
Signed-off-by: qinwei1 <qi...@xiaomi.com>
---
arch/arm64/Kconfig | 12 ++++++++++++
arch/arm64/src/a64/a64_boot.c | 2 +-
arch/arm64/src/common/Make.defs | 8 ++++++--
arch/arm64/src/common/arm64_cpu_psci.c | 6 +++---
arch/arm64/src/common/arm64_cpu_psci.h | 6 +++---
arch/arm64/src/common/arm64_cpustart.c | 15 +++++----------
arch/arm64/src/common/arm64_systemreset.c | 2 +-
arch/arm64/src/qemu/Kconfig | 3 +++
arch/arm64/src/qemu/qemu_boot.c | 2 +-
9 files changed, 35 insertions(+), 21 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 4136e5a09d..c50519b064 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -31,6 +31,7 @@ config ARCH_CHIP_A64
select ARCH_CORTEX_A53
select ARCH_HAVE_ADDRENV
select ARCH_HAVE_RESET
+ select ARCH_HAVE_PSCI
select ARCH_NEED_ADDRENV_MAPPING
---help---
Allwinner A64 SoC
@@ -53,6 +54,17 @@ config ARCH_ARMV8R
bool
default n
+config ARCH_HAVE_PSCI
+ bool "ARM PCSI (Power State Coordination Interface) Support"
+ default n
+ ---help---
+ This Power State Coordination Interface (PSCI) defines
+ a standard interface for power management. the PCSI need
+ to implement handling firmware at EL2 or EL3. The option
+ maybe not applicable for arm core without PCSI firmware
+ interface implement
+
+
config ARCH_CORTEX_A53
bool
default n
diff --git a/arch/arm64/src/a64/a64_boot.c b/arch/arm64/src/a64/a64_boot.c
index ffb66fdf7a..02777e120e 100644
--- a/arch/arm64/src/a64/a64_boot.c
+++ b/arch/arm64/src/a64/a64_boot.c
@@ -84,7 +84,7 @@ void arm64_chip_boot(void)
arm64_mmu_init(true);
-#if defined(CONFIG_SMP) || defined(CONFIG_ARCH_HAVE_RESET)
+#if defined(CONFIG_SMP) || defined(CONFIG_ARCH_HAVE_PSCI)
arm64_psci_init("smc");
#endif
diff --git a/arch/arm64/src/common/Make.defs b/arch/arm64/src/common/Make.defs
index e076f888dd..cc4aecdfc6 100644
--- a/arch/arm64/src/common/Make.defs
+++ b/arch/arm64/src/common/Make.defs
@@ -46,17 +46,21 @@ CMN_CSRCS = arm64_initialize.c arm64_initialstate.c arm64_boot.c
CMN_CSRCS += arm64_nputs.c arm64_idle.c arm64_copystate.c arm64_createstack.c
CMN_CSRCS += arm64_releasestack.c arm64_stackframe.c arm64_usestack.c
CMN_CSRCS += arm64_task_sched.c arm64_exit.c arm64_vfork.c arm64_switchcontext.c
-CMN_CSRCS += arm64_schedulesigaction.c arm64_sigdeliver.c arm64_systemreset.c
+CMN_CSRCS += arm64_schedulesigaction.c arm64_sigdeliver.c
CMN_CSRCS += arm64_backtrace.c arm64_getintstack.c arm64_registerdump.c
# Common C source files ( hardware BSP )
CMN_CSRCS += arm64_mmu.c arm64_arch_timer.c arm64_cache.c
CMN_CSRCS += arm64_doirq.c arm64_gicv2.c arm64_gicv3.c arm64_fatal.c
-CMN_CSRCS += arm64_syscall.c arm64_cpu_psci.c
+CMN_CSRCS += arm64_syscall.c
# Use common heap allocation for now (may need to be customized later)
CMN_CSRCS += arm64_allocateheap.c
+ifeq ($(CONFIG_ARCH_HAVE_PSCI),y)
+CMN_CSRCS += arm64_cpu_psci.c arm64_systemreset.c
+endif
+
ifeq ($(CONFIG_SMP),y)
CMN_CSRCS += arm64_cpuidlestack.c arm64_cpustart.c arm64_cpuindex.c
CMN_CSRCS += arm64_cpupause.c
diff --git a/arch/arm64/src/common/arm64_cpu_psci.c b/arch/arm64/src/common/arm64_cpu_psci.c
index 25ff69746a..f8c066f465 100644
--- a/arch/arm64/src/common/arm64_cpu_psci.c
+++ b/arch/arm64/src/common/arm64_cpu_psci.c
@@ -150,7 +150,7 @@ uint32_t psci_version(void)
return psci_data.version;
}
-int pcsi_cpu_off(void)
+int psci_cpu_off(void)
{
int ret;
@@ -164,7 +164,7 @@ int pcsi_cpu_off(void)
return psci_to_dev_err(ret);
}
-int pcsi_cpu_reset(void)
+int psci_cpu_reset(void)
{
int ret;
@@ -178,7 +178,7 @@ int pcsi_cpu_reset(void)
return psci_to_dev_err(ret);
}
-int pcsi_cpu_on(unsigned long cpuid, uintptr_t entry_point)
+int psci_cpu_on(unsigned long cpuid, uintptr_t entry_point)
{
int ret;
diff --git a/arch/arm64/src/common/arm64_cpu_psci.h b/arch/arm64/src/common/arm64_cpu_psci.h
index eeb3801bd5..66e6e7445e 100644
--- a/arch/arm64/src/common/arm64_cpu_psci.h
+++ b/arch/arm64/src/common/arm64_cpu_psci.h
@@ -98,8 +98,8 @@ struct psci_interface
****************************************************************************/
uint32_t psci_version(void);
-int pcsi_cpu_off(void);
-int pcsi_cpu_reset(void);
-int pcsi_cpu_on(unsigned long cpuid, uintptr_t entry_point);
+int psci_cpu_off(void);
+int psci_cpu_reset(void);
+int psci_cpu_on(unsigned long cpuid, uintptr_t entry_point);
#endif /* __ARCH_ARM64_SRC_COMMON_ARM64_CPU_PSCI_H */
diff --git a/arch/arm64/src/common/arm64_cpustart.c b/arch/arm64/src/common/arm64_cpustart.c
index fcfcb209cc..53262c7b39 100644
--- a/arch/arm64/src/common/arm64_cpustart.c
+++ b/arch/arm64/src/common/arm64_cpustart.c
@@ -153,21 +153,16 @@ static void arm64_start_cpu(int cpu_num, char *stack, int stack_sz,
flush_end = flush_start + sizeof(cpu_boot_params);
up_flush_dcache(flush_start, flush_end);
- if (pcsi_cpu_on(cpu_mpid, (uint64_t)__start))
+#ifdef CONFIG_ARCH_HAVE_PSCI
+ if (psci_cpu_on(cpu_mpid, (uint64_t)__start))
{
sinfo("Failed to boot secondary CPU core %d (MPID:%#lx)\n", cpu_num,
cpu_mpid);
return;
}
-
- /* Wait secondary cores up, see z_arm64_secondary_start */
-
- while (cpu_boot_params.func)
- {
- SP_WFE();
- }
-
- sinfo("Secondary CPU core %d (MPID:%#lx) is up\n", cpu_num, cpu_mpid);
+#else
+ SP_SEV();
+#endif
}
/****************************************************************************
diff --git a/arch/arm64/src/common/arm64_systemreset.c b/arch/arm64/src/common/arm64_systemreset.c
index 1076d99c18..86c97ca198 100644
--- a/arch/arm64/src/common/arm64_systemreset.c
+++ b/arch/arm64/src/common/arm64_systemreset.c
@@ -51,7 +51,7 @@ void up_systemreset(void)
/* Set up for the system reset */
- ret = pcsi_cpu_reset();
+ ret = psci_cpu_reset();
if (ret)
{
sinfo("Failed to reset CPU, error code: %d\n", ret);
diff --git a/arch/arm64/src/qemu/Kconfig b/arch/arm64/src/qemu/Kconfig
index f5d4720ebb..32e6b6959d 100644
--- a/arch/arm64/src/qemu/Kconfig
+++ b/arch/arm64/src/qemu/Kconfig
@@ -15,16 +15,19 @@ config ARCH_CHIP_QEMU_A53
bool "Qemu virtual Processor (cortex-a53)"
select ARCH_HAVE_MULTICPU
select ARMV8A_HAVE_GICv3
+ select ARCH_HAVE_PSCI
config ARCH_CHIP_QEMU_A57
bool "Qemu virtual Processor (cortex-a57)"
select ARCH_HAVE_MULTICPU
select ARMV8A_HAVE_GICv3
+ select ARCH_HAVE_PCSI
config ARCH_CHIP_QEMU_A72
bool "Qemu virtual Processor (cortex-a72)"
select ARCH_HAVE_MULTICPU
select ARMV8A_HAVE_GICv3
+ select ARCH_HAVE_PCSI
endchoice # Qemu Chip Selection
diff --git a/arch/arm64/src/qemu/qemu_boot.c b/arch/arm64/src/qemu/qemu_boot.c
index b8f7caec4e..3859e37f55 100644
--- a/arch/arm64/src/qemu/qemu_boot.c
+++ b/arch/arm64/src/qemu/qemu_boot.c
@@ -84,7 +84,7 @@ void arm64_chip_boot(void)
arm64_mmu_init(true);
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) || defined(CONFIG_ARCH_HAVE_PSCI)
arm64_psci_init("smc");
#endif
[nuttx] 07/07: Update arm64_head.S
Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit fa359e355c231984a7401bc3e0a3b100133b0ba4
Author: qinwei2004 <10...@users.noreply.github.com>
AuthorDate: Wed Mar 1 10:17:39 2023 +0800
Update arm64_head.S
---
arch/arm64/src/common/arm64_head.S | 4 ----
1 file changed, 4 deletions(-)
diff --git a/arch/arm64/src/common/arm64_head.S b/arch/arm64/src/common/arm64_head.S
index 47f052e3e2..fba688f782 100644
--- a/arch/arm64/src/common/arm64_head.S
+++ b/arch/arm64/src/common/arm64_head.S
@@ -196,11 +196,7 @@ primary_core:
bl up_earlyserialinit
#endif
-#ifdef CONFIG_SMP
PRINT(primary_boot, "- Ready to Boot Primary CPU\r\n")
-#else
- PRINT(cpu_boot, "- Ready to Boot CPU\r\n")
-#endif
cpu_boot: