Merge "doc: Add a binding document for COT descriptors" into integration
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 591f2f8..6b6c639 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -227,6 +227,17 @@
- ``ERRATA_A76_1275112``: This applies errata 1275112 workaround to Cortex-A76
CPU. This needs to be enabled only for revision <= r3p0 of the CPU.
+- ``ERRATA_A76_1791580``: This applies errata 1791580 workaround to Cortex-A76
+ CPU. This needs to be enabled only for revision <= r4p0 of the CPU.
+
+- ``ERRATA_A76_1800710``: This applies errata 1800710 workaround to Cortex-A76
+ CPU. This needs to be enabled only for revision <= r4p0 of the CPU.
+
+For Cortex-A77, the following errata build flags are defined :
+
+- ``ERRATA_A77_1800714``: This applies errata 1800714 workaround to Cortex-A77
+ CPU. This needs to be enabled only for revision <= r1p1 of the CPU.
+
For Cortex-A78, the following errata build flags are defined :
- ``ERRATA_A78_1688305``: This applies errata 1688305 workaround to Cortex-A78
diff --git a/include/lib/cpus/aarch64/cortex_a76.h b/include/lib/cpus/aarch64/cortex_a76.h
index 7dc7e06..b522e8e 100644
--- a/include/lib/cpus/aarch64/cortex_a76.h
+++ b/include/lib/cpus/aarch64/cortex_a76.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,6 +20,7 @@
#define CORTEX_A76_CPUECTLR_EL1_WS_THR_L2 (ULL(3) << 24)
#define CORTEX_A76_CPUECTLR_EL1_BIT_51 (ULL(1) << 51)
+#define CORTEX_A76_CPUECTLR_EL1_BIT_53 (ULL(1) << 53)
/*******************************************************************************
* CPU Auxiliary Control register specific definitions.
@@ -32,6 +33,8 @@
#define CORTEX_A76_CPUACTLR2_EL1 S3_0_C15_C1_1
+#define CORTEX_A76_CPUACTLR2_EL1_BIT_2 (ULL(1) << 2)
+
#define CORTEX_A76_CPUACTLR2_EL1_DISABLE_LOAD_PASS_STORE (ULL(1) << 16)
#define CORTEX_A76_CPUACTLR3_EL1 S3_0_C15_C1_2
diff --git a/include/lib/cpus/aarch64/cortex_a77.h b/include/lib/cpus/aarch64/cortex_a77.h
index 0467ef3..bbd647c 100644
--- a/include/lib/cpus/aarch64/cortex_a77.h
+++ b/include/lib/cpus/aarch64/cortex_a77.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,6 +16,7 @@
* CPU Extended Control register specific definitions.
******************************************************************************/
#define CORTEX_A77_CPUECTLR_EL1 S3_0_C15_C1_4
+#define CORTEX_A77_CPUECTLR_EL1_BIT_53 (ULL(1) << 53)
/*******************************************************************************
* CPU Power Control register specific definitions.
diff --git a/include/services/ffa_svc.h b/include/services/ffa_svc.h
index fe32175..7285077 100644
--- a/include/services/ffa_svc.h
+++ b/include/services/ffa_svc.h
@@ -12,13 +12,13 @@
#include <tools_share/uuid.h>
/* FFA error codes. */
-#define FFA_ERROR_NOT_SUPPORTED -1
+#define FFA_ERROR_NOT_SUPPORTED -1
#define FFA_ERROR_INVALID_PARAMETER -2
#define FFA_ERROR_NO_MEMORY -3
#define FFA_ERROR_BUSY -4
#define FFA_ERROR_INTERRUPTED -5
#define FFA_ERROR_DENIED -6
-#define FFA_ERROR_RETRY -7
+#define FFA_ERROR_RETRY -7
/* The macros below are used to identify FFA calls from the SMC function ID */
#define FFA_FNUM_MIN_VALUE U(0x60)
@@ -30,13 +30,15 @@
/* FFA_VERSION helpers */
#define FFA_VERSION_MAJOR U(1)
-#define FFA_VERSION_MAJOR_SHIFT 16
+#define FFA_VERSION_MAJOR_SHIFT 16
#define FFA_VERSION_MAJOR_MASK U(0x7FFF)
#define FFA_VERSION_MINOR U(0)
-#define FFA_VERSION_MINOR_SHIFT 0
+#define FFA_VERSION_MINOR_SHIFT 0
#define FFA_VERSION_MINOR_MASK U(0xFFFF)
+#define FFA_VERSION_BIT31_MASK U(0x1u << 31)
+
-#define MAKE_FFA_VERSION(major, minor) \
+#define MAKE_FFA_VERSION(major, minor) \
((((major) & FFA_VERSION_MAJOR_MASK) << FFA_VERSION_MAJOR_SHIFT) | \
(((minor) & FFA_VERSION_MINOR_MASK) << FFA_VERSION_MINOR_SHIFT))
#define FFA_VERSION_COMPILED MAKE_FFA_VERSION(FFA_VERSION_MAJOR, \
diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S
index baefa46..10011f7 100644
--- a/lib/cpus/aarch64/cortex_a76.S
+++ b/lib/cpus/aarch64/cortex_a76.S
@@ -392,6 +392,62 @@
#endif
endfunc check_errata_1286807
+ /* --------------------------------------------------
+ * Errata workaround for Cortex A76 Errata #1791580.
+ * This applies to revisions <= r4p0 of Cortex A76.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a76_1791580_wa
+ /* Compare x0 against revision r4p0 */
+ mov x17, x30
+ bl check_errata_1791580
+ cbz x0, 1f
+ mrs x1, CORTEX_A76_CPUACTLR2_EL1
+ orr x1, x1, CORTEX_A76_CPUACTLR2_EL1_BIT_2
+ msr CORTEX_A76_CPUACTLR2_EL1, x1
+ isb
+1:
+ ret x17
+endfunc errata_a76_1791580_wa
+
+func check_errata_1791580
+ /* Applies to everything <=r4p0. */
+ mov x1, #0x40
+ b cpu_rev_var_ls
+endfunc check_errata_1791580
+
+ /* --------------------------------------------------
+ * Errata Workaround for Cortex A76 Errata #1800710.
+ * This applies to revision <= r4p0 of Cortex A76.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a76_1800710_wa
+ /* Compare x0 against revision <= r4p0 */
+ mov x17, x30
+ bl check_errata_1800710
+ cbz x0, 1f
+
+ /* Disable allocation of splintered pages in the L2 TLB */
+ mrs x1, CORTEX_A76_CPUECTLR_EL1
+ orr x1, x1, CORTEX_A76_CPUECTLR_EL1_BIT_53
+ msr CORTEX_A76_CPUECTLR_EL1, x1
+ isb
+1:
+ ret x17
+endfunc errata_a76_1800710_wa
+
+func check_errata_1800710
+ /* Applies to everything <= r4p0 */
+ mov x1, #0x40
+ b cpu_rev_var_ls
+endfunc check_errata_1800710
+
func check_errata_cve_2018_3639
#if WORKAROUND_CVE_2018_3639
mov x0, #ERRATA_APPLIES
@@ -449,6 +505,16 @@
bl errata_a76_1262888_wa
#endif
+#if ERRATA_A76_1791580
+ mov x0, x18
+ bl errata_a76_1791580_wa
+#endif
+
+#if ERRATA_A76_1800710
+ mov x0, x18
+ bl errata_a76_1800710_wa
+#endif
+
#if WORKAROUND_CVE_2018_3639
/* If the PE implements SSBS, we don't need the dynamic workaround */
mrs x0, id_aa64pfr1_el1
@@ -529,6 +595,8 @@
report_errata ERRATA_A76_1262888, cortex_a76, 1262888
report_errata ERRATA_A76_1275112, cortex_a76, 1275112
report_errata ERRATA_A76_1286807, cortex_a76, 1286807
+ report_errata ERRATA_A76_1791580, cortex_a76, 1791580
+ report_errata ERRATA_A76_1800710, cortex_a76, 1800710
report_errata WORKAROUND_CVE_2018_3639, cortex_a76, cve_2018_3639
report_errata ERRATA_DSU_798953, cortex_a76, dsu_798953
report_errata ERRATA_DSU_936184, cortex_a76, dsu_936184
diff --git a/lib/cpus/aarch64/cortex_a77.S b/lib/cpus/aarch64/cortex_a77.S
index f3fd5e1..0c30460 100644
--- a/lib/cpus/aarch64/cortex_a77.S
+++ b/lib/cpus/aarch64/cortex_a77.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,6 +21,53 @@
#error "Cortex-A77 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
#endif
+ /* --------------------------------------------------
+ * Errata Workaround for Cortex A77 Errata #1800714.
+ * This applies to revision <= r1p1 of Cortex A77.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_a77_1800714_wa
+ /* Compare x0 against revision <= r1p1 */
+ mov x17, x30
+ bl check_errata_1800714
+ cbz x0, 1f
+
+ /* Disable allocation of splintered pages in the L2 TLB */
+ mrs x1, CORTEX_A77_CPUECTLR_EL1
+ orr x1, x1, CORTEX_A77_CPUECTLR_EL1_BIT_53
+ msr CORTEX_A77_CPUECTLR_EL1, x1
+ isb
+1:
+ ret x17
+endfunc errata_a77_1800714_wa
+
+func check_errata_1800714
+ /* Applies to everything <= r1p1 */
+ mov x1, #0x11
+ b cpu_rev_var_ls
+endfunc check_errata_1800714
+
+ /* -------------------------------------------------
+ * The CPU Ops reset function for Cortex-A77.
+ * Shall clobber: x0-x19
+ * -------------------------------------------------
+ */
+func cortex_a77_reset_func
+ mov x19, x30
+ bl cpu_get_rev_var
+ mov x18, x0
+
+#if ERRATA_A77_1800714
+ mov x0, x18
+ bl errata_a77_1800714_wa
+#endif
+
+ ret x19
+endfunc cortex_a77_reset_func
+
/* ---------------------------------------------
* HW will do the cache maintenance while powering down
* ---------------------------------------------
@@ -42,6 +89,18 @@
* Errata printing function for Cortex-A77. Must follow AAPCS.
*/
func cortex_a77_errata_report
+ stp x8, x30, [sp, #-16]!
+
+ bl cpu_get_rev_var
+ mov x8, x0
+
+ /*
+ * Report all errata. The revision-variant information is passed to
+ * checking functions of each errata.
+ */
+ report_errata ERRATA_A77_1800714, cortex_a77, 1800714
+
+ ldp x8, x30, [sp], #16
ret
endfunc cortex_a77_errata_report
#endif
@@ -67,5 +126,5 @@
endfunc cortex_a77_cpu_reg_dump
declare_cpu_ops cortex_a77, CORTEX_A77_MIDR, \
- CPU_NO_RESET_FUNC, \
+ cortex_a77_reset_func, \
cortex_a77_core_pwr_dwn
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 1bc082d..e494375 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -250,6 +250,18 @@
# only to revision <= r3p0 of the Cortex A76 cpu.
ERRATA_A76_1286807 ?=0
+# Flag to apply erratum 1791580 workaround during reset. This erratum applies
+# only to revision <= r4p0 of the Cortex A76 cpu.
+ERRATA_A76_1791580 ?=0
+
+# Flag to apply erratum 1800710 workaround during reset. This erratum applies
+# only to revision <= r4p0 of the Cortex A76 cpu.
+ERRATA_A76_1800710 ?=0
+
+# Flag to apply erratum 1800714 workaround during reset. This erratum applies
+# only to revision <= r1p1 of the Cortex A77 cpu.
+ERRATA_A77_1800714 ?=0
+
# Flag to apply erratum 1688305 workaround during reset. This erratum applies
# to revisions r0p0 - r1p0 of the A78 cpu.
ERRATA_A78_1688305 ?=0
@@ -487,6 +499,18 @@
$(eval $(call assert_boolean,ERRATA_A76_1286807))
$(eval $(call add_define,ERRATA_A76_1286807))
+# Process ERRATA_A76_1791580 flag
+$(eval $(call assert_boolean,ERRATA_A76_1791580))
+$(eval $(call add_define,ERRATA_A76_1791580))
+
+# Process ERRATA_A76_1800710 flag
+$(eval $(call assert_boolean,ERRATA_A76_1800710))
+$(eval $(call add_define,ERRATA_A76_1800710))
+
+# Process ERRATA_A77_1800714 flag
+$(eval $(call assert_boolean,ERRATA_A77_1800714))
+$(eval $(call add_define,ERRATA_A77_1800714))
+
# Process ERRATA_A78_1688305 flag
$(eval $(call assert_boolean,ERRATA_A78_1688305))
$(eval $(call add_define,ERRATA_A78_1688305))
diff --git a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
index 8172a6e..35a777b 100644
--- a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
+++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c
@@ -14,6 +14,7 @@
struct gicv3_config_t gicv3_config;
struct hw_topology_t soc_topology;
struct uart_serial_config_t uart_serial_config;
+struct cpu_timer_t cpu_timer;
#define ILLEGAL_ADDR ULL(~0)
@@ -260,9 +261,36 @@
VERBOSE("FCONF: UART serial device clk frequency: %x\n",
uart_serial_config.uart_clk);
+
+ return 0;
+}
+
+int fconf_populate_cpu_timer(uintptr_t config)
+{
+ int err, node;
+
+ /* Necessary to work with libfdt APIs */
+ const void *hw_config_dtb = (const void *)config;
+
+ /* Find the node offset point to "arm,armv8-timer" compatible property,
+ * a per-core architected timer attached to a GIC to deliver its per-processor
+ * interrupts via PPIs */
+ node = fdt_node_offset_by_compatible(hw_config_dtb, -1, "arm,armv8-timer");
+ if (node < 0) {
+ ERROR("FCONF: Unrecognized hardware configuration dtb (%d)\n", node);
+ return node;
+ }
+
+ /* Locate the cell holding the clock-frequency, an optional field */
+ err = fdt_read_uint32(hw_config_dtb, node, "clock-frequency", &cpu_timer.clock_freq);
+ if (err < 0) {
+ WARN("FCONF failed to read clock-frequency property\n");
+ }
+
return 0;
}
FCONF_REGISTER_POPULATOR(HW_CONFIG, gicv3_config, fconf_populate_gicv3_config);
FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology);
FCONF_REGISTER_POPULATOR(HW_CONFIG, uart_config, fconf_populate_uart_config);
+FCONF_REGISTER_POPULATOR(HW_CONFIG, cpu_timer, fconf_populate_cpu_timer);
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index dc7bfa2..4cc1c1b 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -7,7 +7,9 @@
#include <assert.h>
#include <common/debug.h>
#include <drivers/arm/smmu_v3.h>
+#include <fconf_hw_config_getter.h>
#include <lib/fconf/fconf.h>
+#include <lib/mmio.h>
#include <plat/arm/common/arm_config.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
@@ -65,3 +67,26 @@
fconf_populate("HW_CONFIG", hw_config_dtb);
#endif
}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+ unsigned int counter_base_frequency;
+
+#if !RESET_TO_BL31 && !BL2_AT_EL3
+ /* Get the frequency through FCONF API for HW_CONFIG */
+ counter_base_frequency = FCONF_GET_PROPERTY(hw_config, cpu_timer, clock_freq);
+ if (counter_base_frequency > 0U) {
+ return counter_base_frequency;
+ }
+#endif
+
+ /* Read the frequency from Frequency modes table */
+ counter_base_frequency = mmio_read_32(ARM_SYS_CNTCTL_BASE + CNTFID_OFF);
+
+ /* The first entry of the frequency modes table must not be 0 */
+ if (counter_base_frequency == 0U) {
+ panic();
+ }
+
+ return counter_base_frequency;
+}
diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h
index b53e00a..ca85f7a 100644
--- a/plat/arm/board/fvp/include/fconf_hw_config_getter.h
+++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h
@@ -11,10 +11,9 @@
/* Hardware Config related getter */
#define hw_config__gicv3_config_getter(prop) gicv3_config.prop
-
#define hw_config__topology_getter(prop) soc_topology.prop
-
#define hw_config__uart_serial_config_getter(prop) uart_serial_config.prop
+#define hw_config__cpu_timer_getter(prop) cpu_timer.prop
struct gicv3_config_t {
uint64_t gicd_base;
@@ -33,12 +32,17 @@
uint32_t uart_clk;
};
+struct cpu_timer_t {
+ uint32_t clock_freq;
+};
+
int fconf_populate_gicv3_config(uintptr_t config);
int fconf_populate_topology(uintptr_t config);
int fconf_populate_uart_config(uintptr_t config);
+int fconf_populate_cpu_timer(uintptr_t config);
extern struct gicv3_config_t gicv3_config;
extern struct hw_topology_t soc_topology;
extern struct uart_serial_config_t uart_serial_config;
-
+extern struct cpu_timer_t cpu_timer;
#endif /* FCONF_HW_CONFIG_GETTER_H */
diff --git a/plat/brcm/board/stingray/src/bl31_setup.c b/plat/brcm/board/stingray/src/bl31_setup.c
index d947551..a2a274d 100644
--- a/plat/brcm/board/stingray/src/bl31_setup.c
+++ b/plat/brcm/board/stingray/src/bl31_setup.c
@@ -923,7 +923,7 @@
scp_image_info.image_base = PRELOADED_SCP_BASE;
scp_image_info.image_size = PRELOADED_SCP_SIZE;
- bcm_bl2_plat_handle_scp_bl2(&scp_image_info);
+ plat_bcm_bl2_plat_handle_scp_bl2(&scp_image_info);
#endif
/*
* In BL31, logs are saved to DDR and we have much larger space to
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index a818037..4c2b58d 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -350,6 +350,7 @@
spmd_spm_core_context_t *ctx = spmd_get_context();
bool secure_origin;
int32_t ret;
+ uint32_t input_version;
/* Determine which security state this SMC originated from */
secure_origin = is_caller_secure(flags);
@@ -375,15 +376,24 @@
break; /* not reached */
case FFA_VERSION:
+ input_version = (uint32_t)(0xFFFFFFFF & x1);
/*
- * TODO: This is an optimization that the version information
- * provided by the SPM Core manifest is returned by the SPM
- * dispatcher. It might be a better idea to simply forward this
- * call to the SPM Core and wash our hands completely.
+ * If caller is secure and SPMC was initialized,
+ * return FFA_VERSION of SPMD.
+ * If caller is non secure and SPMC was initialized,
+ * return SPMC's version.
+ * Sanity check to "input_version".
*/
- ret = MAKE_FFA_VERSION(spmc_attrs.major_version,
- spmc_attrs.minor_version);
- SMC_RET8(handle, FFA_SUCCESS_SMC32, FFA_TARGET_INFO_MBZ, ret,
+ if ((input_version & FFA_VERSION_BIT31_MASK) ||
+ (ctx->state == SPMC_STATE_RESET)) {
+ ret = FFA_ERROR_NOT_SUPPORTED;
+ } else if (!secure_origin) {
+ ret = MAKE_FFA_VERSION(spmc_attrs.major_version, spmc_attrs.minor_version);
+ } else {
+ ret = MAKE_FFA_VERSION(FFA_VERSION_MAJOR, FFA_VERSION_MINOR);
+ }
+
+ SMC_RET8(handle, ret, FFA_TARGET_INFO_MBZ, FFA_TARGET_INFO_MBZ,
FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
FFA_PARAM_MBZ, FFA_PARAM_MBZ);
break; /* not reached */