Add support for Neoverse-N2 CPUs.

Enable basic support for Neoverse-N2 CPUs.

Signed-off-by: Javier Almansa Sobrino <javier.almansasobrino@arm.com>
Change-Id: I498adc2d9fc61ac6e1af8ece131039410872e8ad
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index c0fda78..e901e0c 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -363,10 +363,11 @@
    Cortex-A57 based platform must make its own decision on whether to use
    the optimization. This flag is disabled by default.
 
--  ``NEOVERSE_N1_EXTERNAL_LLC``: This flag indicates that an external last
+-  ``NEOVERSE_Nx_EXTERNAL_LLC``: This flag indicates that an external last
    level cache(LLC) is present in the system, and that the DataSource field
    on the master CHI interface indicates when data is returned from the LLC.
    This is used to control how the LL_CACHE* PMU events count.
+   Default value is 0 (Disabled).
 
 --------------
 
diff --git a/include/lib/cpus/aarch64/neoverse_n1.h b/include/lib/cpus/aarch64/neoverse_n1.h
index 9998b93..b50befa 100644
--- a/include/lib/cpus/aarch64/neoverse_n1.h
+++ b/include/lib/cpus/aarch64/neoverse_n1.h
@@ -64,12 +64,4 @@
 #define CPUPOR_EL3	S3_6_C15_C8_2
 #define CPUPMR_EL3	S3_6_C15_C8_3
 
-/******************************************************************************
- * CPU Configuration register definitions.
- *****************************************************************************/
-#define CPUCFR_EL1	S3_0_C15_C0_0
-
-/* SCU bit of CPU Configuration Register, EL1 */
-#define SCU_SHIFT	U(2)
-
 #endif /* NEOVERSE_N1_H */
diff --git a/include/lib/cpus/aarch64/neoverse_n2.h b/include/lib/cpus/aarch64/neoverse_n2.h
new file mode 100644
index 0000000..7cbd8c1
--- /dev/null
+++ b/include/lib/cpus/aarch64/neoverse_n2.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NEOVERSE_N2_H
+#define NEOVERSE_N2_H
+
+/* Neoverse N2 ID register for revision r0p0 */
+#define NEOVERSE_N2_MIDR			U(0x410FD490)
+
+/*******************************************************************************
+ * CPU Power control register
+ ******************************************************************************/
+#define NEOVERSE_N2_CPUPWRCTLR_EL1		S3_0_C15_C2_7
+#define NEOVERSE_N2_CORE_PWRDN_EN_BIT		(ULL(1) << 0)
+
+/*******************************************************************************
+ * CPU Extended Control register specific definitions.
+ ******************************************************************************/
+#define NEOVERSE_N2_CPUECTLR_EL1		S3_0_C15_C1_4
+#define NEOVERSE_N2_CPUECTLR_EL1_EXTLLC_BIT	(ULL(1) << 0)
+
+/*******************************************************************************
+ * CPU Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define NEOVERSE_N2_CPUACTLR2_EL1		S3_0_C15_C1_1
+#define NEOVERSE_N2_CPUACTLR2_EL1_BIT_2		(ULL(1) << 2)
+
+#endif /* NEOVERSE_N2_H */
diff --git a/include/lib/cpus/aarch64/neoverse_n_common.h b/include/lib/cpus/aarch64/neoverse_n_common.h
new file mode 100644
index 0000000..7cb91cd
--- /dev/null
+++ b/include/lib/cpus/aarch64/neoverse_n_common.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef NEOVERSE_N_COMMON_H
+#define NEOVERSE_N_COMMON_H
+
+/******************************************************************************
+ * Neoverse Nx CPU Configuration register definitions
+ *****************************************************************************/
+#define CPUCFR_EL1		S3_0_C15_C0_0
+
+/* SCU bit of CPU Configuration Register, EL1 */
+#define SCU_SHIFT		U(2)
+
+#endif /* NEOVERSE_N_COMMON_H */
diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S
index 03ee472..96891be 100644
--- a/lib/cpus/aarch64/neoverse_n1.S
+++ b/lib/cpus/aarch64/neoverse_n1.S
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <arch.h>
 #include <asm_macros.S>
-#include <neoverse_n1.h>
 #include <cpuamu.h>
 #include <cpu_macros.S>
 #include <context.h>
+#include <neoverse_n1.h>
 
 /* Hardware handled coherency */
 #if HW_ASSISTED_COHERENCY == 0
@@ -22,19 +22,6 @@
 #endif
 
 	.global neoverse_n1_errata_ic_trap_handler
-	.global is_scu_present_in_dsu
-
-/*
- * Check DSU is configured with SCU and L3 unit
- * 1-> SCU present
- * 0-> SCU not present
- */
-func is_scu_present_in_dsu
-	mrs	x0, CPUCFR_EL1
-	ubfx	x0, x0, #SCU_SHIFT, #1
-	eor	x0, x0, #1
-	ret
-endfunc is_scu_present_in_dsu
 
 /* --------------------------------------------------
  * Errata Workaround for Neoverse N1 Erratum 1043202.
@@ -515,7 +502,7 @@
 	msr	CPUAMCNTENSET_EL0, x0
 #endif
 
-#if NEOVERSE_N1_EXTERNAL_LLC
+#if NEOVERSE_Nx_EXTERNAL_LLC
 	/* Some system may have External LLC, core needs to be made aware */
 	mrs     x0, NEOVERSE_N1_CPUECTLR_EL1
 	orr     x0, x0, NEOVERSE_N1_CPUECTLR_EL1_EXTLLC_BIT
diff --git a/lib/cpus/aarch64/neoverse_n2.S b/lib/cpus/aarch64/neoverse_n2.S
new file mode 100644
index 0000000..8d646cb
--- /dev/null
+++ b/lib/cpus/aarch64/neoverse_n2.S
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <cpu_macros.S>
+#include <neoverse_n2.h>
+
+/* Hardware handled coherency */
+#if HW_ASSISTED_COHERENCY == 0
+#error "Neoverse N2 must be compiled with HW_ASSISTED_COHERENCY enabled"
+#endif
+
+/* 64-bit only core */
+#if CTX_INCLUDE_AARCH32_REGS == 1
+#error "Neoverse-N2 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
+#endif
+
+	/* -------------------------------------------------
+	 * The CPU Ops reset function for Neoverse N2.
+	 * -------------------------------------------------
+	 */
+func neoverse_n2_reset_func
+	/* Check if the PE implements SSBS */
+	mrs	x0, id_aa64pfr1_el1
+	tst	x0, #(ID_AA64PFR1_EL1_SSBS_MASK << ID_AA64PFR1_EL1_SSBS_SHIFT)
+	b.eq	1f
+
+	/* Disable speculative loads */
+	msr	SSBS, xzr
+1:
+	/* Force all cacheable atomic instructions to be near */
+	mrs	x0, NEOVERSE_N2_CPUACTLR2_EL1
+	orr	x0, x0, #NEOVERSE_N2_CPUACTLR2_EL1_BIT_2
+	msr	NEOVERSE_N2_CPUACTLR2_EL1, x0
+
+#if ENABLE_AMU
+	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
+	mrs	x0, cptr_el3
+	orr	x0, x0, #TAM_BIT
+	msr	cptr_el3, x0
+
+	/* Make sure accesses from EL0/EL1 are not trapped to EL2 */
+	mrs	x0, cptr_el2
+	orr	x0, x0, #TAM_BIT
+	msr	cptr_el2, x0
+
+	/* No need to enable the counters as this would be done at el3 exit */
+#endif
+
+#if NEOVERSE_Nx_EXTERNAL_LLC
+	/* Some systems may have External LLC, core needs to be made aware */
+	mrs     x0, NEOVERSE_N2_CPUECTLR_EL1
+	orr     x0, x0, NEOVERSE_N2_CPUECTLR_EL1_EXTLLC_BIT
+	msr     NEOVERSE_N2_CPUECTLR_EL1, x0
+#endif
+
+	isb
+	ret
+endfunc neoverse_n2_reset_func
+
+func neoverse_n2_core_pwr_dwn
+	/* ---------------------------------------------
+	 * Enable CPU power down bit in power control register
+	 * No need to do cache maintenance here.
+	 * ---------------------------------------------
+	 */
+	mrs	x0, NEOVERSE_N2_CPUPWRCTLR_EL1
+	orr	x0, x0, #NEOVERSE_N2_CORE_PWRDN_EN_BIT
+	msr	NEOVERSE_N2_CPUPWRCTLR_EL1, x0
+	isb
+	ret
+endfunc neoverse_n2_core_pwr_dwn
+
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Neoverse N2 cores. Must follow AAPCS.
+ */
+func neoverse_n2_errata_report
+	/* No errata reported for Neoverse N2 cores */
+	ret
+endfunc neoverse_n2_errata_report
+#endif
+
+	/* ---------------------------------------------
+	 * This function provides Neoverse N2 specific
+	 * register information for crash reporting.
+	 * It needs to return with x6 pointing to
+	 * a list of register names in ASCII and
+	 * x8 - x15 having values of registers to be
+	 * reported.
+	 * ---------------------------------------------
+	 */
+.section .rodata.neoverse_n2_regs, "aS"
+neoverse_n2_regs:  /* The ASCII list of register names to be reported */
+	.asciz	"cpupwrctlr_el1", ""
+
+func neoverse_n2_cpu_reg_dump
+	adr	x6, neoverse_n2_regs
+	mrs	x8, NEOVERSE_N2_CPUPWRCTLR_EL1
+	ret
+endfunc neoverse_n2_cpu_reg_dump
+
+declare_cpu_ops neoverse_n2, NEOVERSE_N2_MIDR, \
+	neoverse_n2_reset_func, \
+	neoverse_n2_core_pwr_dwn
diff --git a/lib/cpus/aarch64/neoverse_n_common.S b/lib/cpus/aarch64/neoverse_n_common.S
new file mode 100644
index 0000000..b816342
--- /dev/null
+++ b/lib/cpus/aarch64/neoverse_n_common.S
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <neoverse_n_common.h>
+
+	.global is_scu_present_in_dsu
+
+/*
+ * Check if the SCU L3 Unit is present on the DSU
+ * 1-> SCU present
+ * 0-> SCU not present
+ *
+ * This function is implemented as weak on dsu_helpers.S and must be
+ * overwritten for Neoverse Nx cores.
+ */
+
+func is_scu_present_in_dsu
+	mrs	x0, CPUCFR_EL1
+	ubfx	x0, x0, #SCU_SHIFT, #1
+	eor	x0, x0, #1
+	ret
+endfunc is_scu_present_in_dsu
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 4126105..084e6e7 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -25,9 +25,9 @@
 WORKAROUND_CVE_2018_3639	?=1
 DYNAMIC_WORKAROUND_CVE_2018_3639	?=0
 
-# Flag to indicate internal or external Last level cache
+# Flags to indicate internal or external Last level cache
 # By default internal
-NEOVERSE_N1_EXTERNAL_LLC	?=0
+NEOVERSE_Nx_EXTERNAL_LLC	?=0
 
 # Process A57_ENABLE_NONCACHEABLE_LOAD_FWD flag
 $(eval $(call assert_boolean,A57_ENABLE_NONCACHEABLE_LOAD_FWD))
@@ -56,8 +56,8 @@
 $(eval $(call assert_boolean,DYNAMIC_WORKAROUND_CVE_2018_3639))
 $(eval $(call add_define,DYNAMIC_WORKAROUND_CVE_2018_3639))
 
-$(eval $(call assert_boolean,NEOVERSE_N1_EXTERNAL_LLC))
-$(eval $(call add_define,NEOVERSE_N1_EXTERNAL_LLC))
+$(eval $(call assert_boolean,NEOVERSE_Nx_EXTERNAL_LLC))
+$(eval $(call add_define,NEOVERSE_Nx_EXTERNAL_LLC))
 
 ifneq (${DYNAMIC_WORKAROUND_CVE_2018_3639},0)
     ifeq (${WORKAROUND_CVE_2018_3639},0)
diff --git a/plat/arm/board/arm_fpga/platform.mk b/plat/arm/board/arm_fpga/platform.mk
index 4b751fb..3ac1c01 100644
--- a/plat/arm/board/arm_fpga/platform.mk
+++ b/plat/arm/board/arm_fpga/platform.mk
@@ -59,7 +59,9 @@
 				lib/cpus/aarch64/cortex_a76ae.S		\
 				lib/cpus/aarch64/cortex_a77.S		\
 				lib/cpus/aarch64/cortex_a78.S		\
+				lib/cpus/aarch64/neoverse_n_common.S	\
 				lib/cpus/aarch64/neoverse_n1.S		\
+				lib/cpus/aarch64/neoverse_n2.S		\
 				lib/cpus/aarch64/neoverse_e1.S		\
 				lib/cpus/aarch64/neoverse_v1.S		\
 				lib/cpus/aarch64/cortex_a78_ae.S	\
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 4da0d76..0a6fa56 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -118,7 +118,9 @@
 					lib/cpus/aarch64/cortex_a76ae.S		\
 					lib/cpus/aarch64/cortex_a77.S		\
 					lib/cpus/aarch64/cortex_a78.S		\
+					lib/cpus/aarch64/neoverse_n_common.S	\
 					lib/cpus/aarch64/neoverse_n1.S		\
+					lib/cpus/aarch64/neoverse_n2.S		\
 					lib/cpus/aarch64/neoverse_e1.S		\
 					lib/cpus/aarch64/neoverse_v1.S		\
 					lib/cpus/aarch64/cortex_a78_ae.S	\
diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk
index 4b621e3..f20397a 100644
--- a/plat/arm/board/n1sdp/platform.mk
+++ b/plat/arm/board/n1sdp/platform.mk
@@ -69,7 +69,7 @@
 USE_COHERENT_MEM			:=	0
 
 # Enable the flag since N1SDP has a system level cache
-NEOVERSE_N1_EXTERNAL_LLC		:=	1
+NEOVERSE_Nx_EXTERNAL_LLC		:=	1
 include plat/arm/common/arm_common.mk
 include plat/arm/css/common/css_common.mk
 include plat/arm/board/common/board_common.mk