Merge changes from topic "spectre_bhb" into integration
* changes:
fix(security): apply SMCCC_ARCH_WORKAROUND_3 to A73/A75/A72/A57
fix(security): workaround for CVE-2022-23960 for Cortex-A57, Cortex-A72
fix(fvp): disable reclaiming init code by default
diff --git a/include/lib/cpus/aarch64/cortex_a76.h b/include/lib/cpus/aarch64/cortex_a76.h
index a61825f..74fb6e9 100644
--- a/include/lib/cpus/aarch64/cortex_a76.h
+++ b/include/lib/cpus/aarch64/cortex_a76.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,38 +10,41 @@
#include <lib/utils_def.h>
/* Cortex-A76 MIDR for revision 0 */
-#define CORTEX_A76_MIDR U(0x410fd0b0)
+#define CORTEX_A76_MIDR U(0x410fd0b0)
+
+/* Cortex-A76 loop count for CVE-2022-23960 mitigation */
+#define CORTEX_A76_BHB_LOOP_COUNT U(24)
/*******************************************************************************
* CPU Extended Control register specific definitions.
******************************************************************************/
-#define CORTEX_A76_CPUPWRCTLR_EL1 S3_0_C15_C2_7
-#define CORTEX_A76_CPUECTLR_EL1 S3_0_C15_C1_4
+#define CORTEX_A76_CPUPWRCTLR_EL1 S3_0_C15_C2_7
+#define CORTEX_A76_CPUECTLR_EL1 S3_0_C15_C1_4
-#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_WS_THR_L2 (ULL(3) << 24)
+#define CORTEX_A76_CPUECTLR_EL1_BIT_51 (ULL(1) << 51)
/*******************************************************************************
* CPU Auxiliary Control register specific definitions.
******************************************************************************/
-#define CORTEX_A76_CPUACTLR_EL1 S3_0_C15_C1_0
+#define CORTEX_A76_CPUACTLR_EL1 S3_0_C15_C1_0
#define CORTEX_A76_CPUACTLR_EL1_DISABLE_STATIC_PREDICTION (ULL(1) << 6)
-#define CORTEX_A76_CPUACTLR_EL1_BIT_13 (ULL(1) << 13)
+#define CORTEX_A76_CPUACTLR_EL1_BIT_13 (ULL(1) << 13)
-#define CORTEX_A76_CPUACTLR2_EL1 S3_0_C15_C1_1
+#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_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
+#define CORTEX_A76_CPUACTLR3_EL1 S3_0_C15_C1_2
-#define CORTEX_A76_CPUACTLR3_EL1_BIT_10 (ULL(1) << 10)
+#define CORTEX_A76_CPUACTLR3_EL1_BIT_10 (ULL(1) << 10)
/* Definitions of register field mask in CORTEX_A76_CPUPWRCTLR_EL1 */
-#define CORTEX_A76_CORE_PWRDN_EN_MASK U(0x1)
+#define CORTEX_A76_CORE_PWRDN_EN_MASK U(0x1)
#endif /* CORTEX_A76_H */
diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S
index 4d0e9f9..50bd8cd 100644
--- a/lib/cpus/aarch64/cortex_a76.S
+++ b/lib/cpus/aarch64/cortex_a76.S
@@ -7,11 +7,11 @@
#include <arch.h>
#include <asm_macros.S>
#include <common/bl_common.h>
-#include <context.h>
#include <cortex_a76.h>
#include <cpu_macros.S>
#include <plat_macros.S>
#include <services/arm_arch_svc.h>
+#include "wa_cve_2022_23960_bhb.S"
/* Hardware handled coherency */
#if HW_ASSISTED_COHERENCY == 0
@@ -35,59 +35,17 @@
*
* The macro saves x2-x3 to the context. In the fast path
* x0-x3 registers do not need to be restored as the calling
- * context will have saved them.
+ * context will have saved them. The macro also saves
+ * x29-x30 to the context in the sync_exception path.
*/
.macro apply_cve_2018_3639_wa _is_sync_exception _esr_el3_val
stp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
-
.if \_is_sync_exception
- /*
- * Ensure SMC is coming from A64/A32 state on #0
- * with W0 = SMCCC_ARCH_WORKAROUND_2
- *
- * This sequence evaluates as:
- * (W0==SMCCC_ARCH_WORKAROUND_2) ? (ESR_EL3==SMC#0) : (NE)
- * allowing use of a single branch operation
- */
- orr w2, wzr, #SMCCC_ARCH_WORKAROUND_2
- cmp x0, x2
- mrs x3, esr_el3
- mov_imm w2, \_esr_el3_val
- ccmp w2, w3, #0, eq
- /*
- * Static predictor will predict a fall-through, optimizing
- * the `SMCCC_ARCH_WORKAROUND_2` fast path.
- */
- bne 1f
-
- /*
- * The sequence below implements the `SMCCC_ARCH_WORKAROUND_2`
- * fast path.
- */
- cmp x1, xzr /* enable/disable check */
-
- /*
- * When the calling context wants mitigation disabled,
- * we program the mitigation disable function in the
- * CPU context, which gets invoked on subsequent exits from
- * EL3 via the `el3_exit` function. Otherwise NULL is
- * programmed in the CPU context, which results in caller's
- * inheriting the EL3 mitigation state (enabled) on subsequent
- * `el3_exit`.
- */
- mov x0, xzr
- adr x1, cortex_a76_disable_wa_cve_2018_3639
- csel x1, x1, x0, eq
- str x1, [sp, #CTX_CVE_2018_3639_OFFSET + CTX_CVE_2018_3639_DISABLE]
-
- mrs x2, CORTEX_A76_CPUACTLR2_EL1
- orr x1, x2, #CORTEX_A76_CPUACTLR2_EL1_DISABLE_LOAD_PASS_STORE
- bic x3, x2, #CORTEX_A76_CPUACTLR2_EL1_DISABLE_LOAD_PASS_STORE
- csel x3, x3, x1, eq
- msr CORTEX_A76_CPUACTLR2_EL1, x3
- exception_return /* exception_return contains ISB */
+ stp x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
+ mov_imm w2, \_esr_el3_val
+ bl apply_cve_2018_3639_sync_wa
+ ldp x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
.endif
-1:
/*
* Always enable v4 mitigation during EL3 execution. This is not
* required for the fast path above because it does not perform any
@@ -105,8 +63,10 @@
*/
ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
.endm
+#endif /* DYNAMIC_WORKAROUND_CVE_2018_3639 */
-vector_base cortex_a76_wa_cve_2018_3639_a76_vbar
+#if DYNAMIC_WORKAROUND_CVE_2018_3639 || WORKAROUND_CVE_2022_23960
+vector_base cortex_a76_wa_cve_vbar
/* ---------------------------------------------------------------------
* Current EL with SP_EL0 : 0x0 - 0x200
@@ -153,22 +113,54 @@
* ---------------------------------------------------------------------
*/
vector_entry cortex_a76_sync_exception_aarch64
+
+#if WORKAROUND_CVE_2022_23960
+ apply_cve_2022_23960_bhb_wa CORTEX_A76_BHB_LOOP_COUNT
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+#if DYNAMIC_WORKAROUND_CVE_2018_3639
apply_cve_2018_3639_wa _is_sync_exception=1 _esr_el3_val=ESR_EL3_A64_SMC0
+#endif /* DYNAMIC_WORKAROUND_CVE_2018_3639*/
+
b sync_exception_aarch64
end_vector_entry cortex_a76_sync_exception_aarch64
vector_entry cortex_a76_irq_aarch64
+
+#if WORKAROUND_CVE_2022_23960
+ apply_cve_2022_23960_bhb_wa CORTEX_A76_BHB_LOOP_COUNT
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+#if DYNAMIC_WORKAROUND_CVE_2018_3639
apply_cve_2018_3639_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A64_SMC0
+#endif /* DYNAMIC_WORKAROUND_CVE_2018_3639*/
+
b irq_aarch64
end_vector_entry cortex_a76_irq_aarch64
vector_entry cortex_a76_fiq_aarch64
+
+#if WORKAROUND_CVE_2022_23960
+ apply_cve_2022_23960_bhb_wa CORTEX_A76_BHB_LOOP_COUNT
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+#if DYNAMIC_WORKAROUND_CVE_2018_3639
apply_cve_2018_3639_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A64_SMC0
+#endif /* DYNAMIC_WORKAROUND_CVE_2018_3639*/
+
b fiq_aarch64
end_vector_entry cortex_a76_fiq_aarch64
vector_entry cortex_a76_serror_aarch64
+
+#if WORKAROUND_CVE_2022_23960
+ apply_cve_2022_23960_bhb_wa CORTEX_A76_BHB_LOOP_COUNT
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+#if DYNAMIC_WORKAROUND_CVE_2018_3639
apply_cve_2018_3639_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A64_SMC0
+#endif /* DYNAMIC_WORKAROUND_CVE_2018_3639*/
+
b serror_aarch64
end_vector_entry cortex_a76_serror_aarch64
@@ -177,24 +169,130 @@
* ---------------------------------------------------------------------
*/
vector_entry cortex_a76_sync_exception_aarch32
+
+#if WORKAROUND_CVE_2022_23960
+ apply_cve_2022_23960_bhb_wa CORTEX_A76_BHB_LOOP_COUNT
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+#if DYNAMIC_WORKAROUND_CVE_2018_3639
apply_cve_2018_3639_wa _is_sync_exception=1 _esr_el3_val=ESR_EL3_A32_SMC0
+#endif /* DYNAMIC_WORKAROUND_CVE_2018_3639*/
+
b sync_exception_aarch32
end_vector_entry cortex_a76_sync_exception_aarch32
vector_entry cortex_a76_irq_aarch32
+
+#if WORKAROUND_CVE_2022_23960
+ apply_cve_2022_23960_bhb_wa CORTEX_A76_BHB_LOOP_COUNT
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+#if DYNAMIC_WORKAROUND_CVE_2018_3639
apply_cve_2018_3639_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A32_SMC0
+#endif /* DYNAMIC_WORKAROUND_CVE_2018_3639*/
+
b irq_aarch32
end_vector_entry cortex_a76_irq_aarch32
vector_entry cortex_a76_fiq_aarch32
+
+#if WORKAROUND_CVE_2022_23960
+ apply_cve_2022_23960_bhb_wa CORTEX_A76_BHB_LOOP_COUNT
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+#if DYNAMIC_WORKAROUND_CVE_2018_3639
apply_cve_2018_3639_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A32_SMC0
+#endif /* DYNAMIC_WORKAROUND_CVE_2018_3639*/
+
b fiq_aarch32
end_vector_entry cortex_a76_fiq_aarch32
vector_entry cortex_a76_serror_aarch32
+
+#if WORKAROUND_CVE_2022_23960
+ apply_cve_2022_23960_bhb_wa CORTEX_A76_BHB_LOOP_COUNT
+#endif /* WORKAROUND_CVE_2022_23960 */
+
+#if DYNAMIC_WORKAROUND_CVE_2018_3639
apply_cve_2018_3639_wa _is_sync_exception=0 _esr_el3_val=ESR_EL3_A32_SMC0
+#endif /* DYNAMIC_WORKAROUND_CVE_2018_3639*/
+
b serror_aarch32
end_vector_entry cortex_a76_serror_aarch32
+#endif /* DYNAMIC_WORKAROUND_CVE_2018_3639 || WORKAROUND_CVE_2022_23960 */
+
+#if DYNAMIC_WORKAROUND_CVE_2018_3639
+ /*
+ * -----------------------------------------------------------------
+ * This function applies the mitigation for CVE-2018-3639
+ * specifically for sync exceptions. It implements a fast path
+ * where `SMCCC_ARCH_WORKAROUND_2` SMC calls from a lower EL
+ * running in AArch64 will go through the fast and return early.
+ *
+ * In the fast path x0-x3 registers do not need to be restored as the
+ * calling context will have saved them.
+ *
+ * Caller must pass value of esr_el3 to compare via x2.
+ * Save and restore these registers outside of this function from the
+ * context before jumping to the main runtime vector table entry.
+ *
+ * Shall clobber: x0-x3, x30
+ * -----------------------------------------------------------------
+ */
+func apply_cve_2018_3639_sync_wa
+ /*
+ * Ensure SMC is coming from A64/A32 state on #0
+ * with W0 = SMCCC_ARCH_WORKAROUND_2
+ *
+ * This sequence evaluates as:
+ * (W0==SMCCC_ARCH_WORKAROUND_2) ? (ESR_EL3==SMC#0) : (NE)
+ * allowing use of a single branch operation
+ * X2 populated outside this function with the SMC FID.
+ */
+ orr w3, wzr, #SMCCC_ARCH_WORKAROUND_2
+ cmp x0, x3
+ mrs x3, esr_el3
+
+ ccmp w2, w3, #0, eq
+ /*
+ * Static predictor will predict a fall-through, optimizing
+ * the `SMCCC_ARCH_WORKAROUND_2` fast path.
+ */
+ bne 1f
+
+ /*
+ * The sequence below implements the `SMCCC_ARCH_WORKAROUND_2`
+ * fast path.
+ */
+ cmp x1, xzr /* enable/disable check */
+
+ /*
+ * When the calling context wants mitigation disabled,
+ * we program the mitigation disable function in the
+ * CPU context, which gets invoked on subsequent exits from
+ * EL3 via the `el3_exit` function. Otherwise NULL is
+ * programmed in the CPU context, which results in caller's
+ * inheriting the EL3 mitigation state (enabled) on subsequent
+ * `el3_exit`.
+ */
+ mov x0, xzr
+ adr x1, cortex_a76_disable_wa_cve_2018_3639
+ csel x1, x1, x0, eq
+ str x1, [sp, #CTX_CVE_2018_3639_OFFSET + CTX_CVE_2018_3639_DISABLE]
+
+ mrs x2, CORTEX_A76_CPUACTLR2_EL1
+ orr x1, x2, #CORTEX_A76_CPUACTLR2_EL1_DISABLE_LOAD_PASS_STORE
+ bic x3, x2, #CORTEX_A76_CPUACTLR2_EL1_DISABLE_LOAD_PASS_STORE
+ csel x3, x3, x1, eq
+ msr CORTEX_A76_CPUACTLR2_EL1, x3
+ ldp x29, x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X29]
+ /*
+ * `SMCCC_ARCH_WORKAROUND_2`fast path return to lower EL.
+ */
+ exception_return /* exception_return contains ISB */
+1:
+ ret
+endfunc apply_cve_2018_3639_sync_wa
#endif /* DYNAMIC_WORKAROUND_CVE_2018_3639 */
/* --------------------------------------------------
@@ -519,6 +617,15 @@
#endif
endfunc check_errata_1165522
+func check_errata_cve_2022_23960
+#if WORKAROUND_CVE_2022_23960
+ mov x0, #ERRATA_APPLIES
+#else
+ mov x0, #ERRATA_MISSING
+#endif /* WORKAROUND_CVE_2022_23960 */
+ ret
+endfunc check_errata_cve_2022_23960
+
/* -------------------------------------------------
* The CPU Ops reset function for Cortex-A76.
* Shall clobber: x0-x19
@@ -590,16 +697,31 @@
* The Cortex-A76 generic vectors are overwritten to use the vectors
* defined above. This is required in order to apply mitigation
* against CVE-2018-3639 on exception entry from lower ELs.
+ * If the below vector table is used, skip overriding it again for
+ * CVE_2022_23960 as both use the same vbar.
*/
- adr x0, cortex_a76_wa_cve_2018_3639_a76_vbar
+ adr x0, cortex_a76_wa_cve_vbar
msr vbar_el3, x0
isb
+ b 2f
#endif /* IMAGE_BL31 */
1:
#endif /* DYNAMIC_WORKAROUND_CVE_2018_3639 */
#endif /* WORKAROUND_CVE_2018_3639 */
+#if IMAGE_BL31 && WORKAROUND_CVE_2022_23960
+ /*
+ * The Cortex-A76 generic vectors are overridden to apply errata
+ * mitigation on exception entry from lower ELs. This will be bypassed
+ * if DYNAMIC_WORKAROUND_CVE_2018_3639 has overridden the vectors.
+ */
+ adr x0, cortex_a76_wa_cve_vbar
+ msr vbar_el3, x0
+ isb
+#endif /* IMAGE_BL31 && WORKAROUND_CVE_2022_23960 */
+2:
+
#if ERRATA_DSU_798953
bl errata_dsu_798953_wa
#endif
@@ -656,6 +778,7 @@
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
+ report_errata WORKAROUND_CVE_2022_23960, cortex_a76, cve_2022_23960
ldp x8, x30, [sp], #16
ret
diff --git a/plat/marvell/armada/a3k/common/cm3_system_reset.c b/plat/marvell/armada/a3k/common/cm3_system_reset.c
index 548ff51..f105d59 100644
--- a/plat/marvell/armada/a3k/common/cm3_system_reset.c
+++ b/plat/marvell/armada/a3k/common/cm3_system_reset.c
@@ -58,5 +58,5 @@
}
/* If we reach here, the command is not implemented. */
- ERROR("System reset command not implemented in WTMI firmware!\n");
+ WARN("System reset command not implemented in WTMI firmware!\n");
}
diff --git a/plat/mediatek/mt8186/drivers/dfd/plat_dfd.c b/plat/mediatek/mt8186/drivers/dfd/plat_dfd.c
new file mode 100644
index 0000000..ade0837
--- /dev/null
+++ b/plat/mediatek/mt8186/drivers/dfd/plat_dfd.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <mtk_sip_svc.h>
+#include <plat_dfd.h>
+
+static bool dfd_enabled;
+static uint64_t dfd_base_addr;
+static uint64_t dfd_chain_length;
+static uint64_t dfd_cache_dump;
+
+static void dfd_setup(uint64_t base_addr, uint64_t chain_length,
+ uint64_t cache_dump)
+{
+ mmio_write_32(MCUSYS_DFD_MAP, base_addr >> 24);
+ mmio_write_32(WDT_DEBUG_CTL, WDT_DEBUG_CTL_VAL_0);
+
+ sync_writel(DFD_INTERNAL_CTL, (BIT(0) | BIT(2)));
+
+ mmio_setbits_32(DFD_INTERNAL_CTL, BIT(13));
+ mmio_setbits_32(DFD_INTERNAL_CTL, BIT(3));
+ mmio_setbits_32(DFD_INTERNAL_CTL, (BIT(19) | BIT(20)));
+ mmio_write_32(DFD_INTERNAL_PWR_ON, (BIT(0) | BIT(1) | BIT(3)));
+ mmio_write_32(DFD_CHAIN_LENGTH0, chain_length);
+ mmio_write_32(DFD_INTERNAL_SHIFT_CLK_RATIO, 0);
+ mmio_write_32(DFD_INTERNAL_TEST_SO_0, DFD_INTERNAL_TEST_SO_0_VAL);
+ mmio_write_32(DFD_INTERNAL_NUM_OF_TEST_SO_GROUP, 1);
+
+ mmio_write_32(DFD_TEST_SI_0, DFD_TEST_SI_0_VAL);
+ mmio_write_32(DFD_TEST_SI_1, DFD_TEST_SI_1_VAL);
+
+ sync_writel(DFD_V30_CTL, 1);
+
+ mmio_write_32(DFD_V30_BASE_ADDR, (base_addr & 0xFFF00000));
+
+ /* setup global variables for suspend and resume */
+ dfd_enabled = true;
+ dfd_base_addr = base_addr;
+ dfd_chain_length = chain_length;
+ dfd_cache_dump = cache_dump;
+
+ if ((cache_dump & DFD_CACHE_DUMP_ENABLE) != 0UL) {
+ mmio_write_32(WDT_DEBUG_CTL, WDT_DEBUG_CTL_VAL_1);
+ sync_writel(DFD_V35_ENALBE, 1);
+ sync_writel(DFD_V35_TAP_NUMBER, DFD_V35_TAP_NUMBER_VAL);
+ sync_writel(DFD_V35_TAP_EN, DFD_V35_TAP_EN_VAL);
+ sync_writel(DFD_V35_SEQ0_0, DFD_V35_SEQ0_0_VAL);
+
+ if (cache_dump & DFD_PARITY_ERR_TRIGGER) {
+ sync_writel(DFD_HW_TRIGGER_MASK, DFD_HW_TRIGGER_MASK_VAL);
+ mmio_setbits_32(DFD_INTERNAL_CTL, BIT(4));
+ }
+ }
+ dsbsy();
+}
+
+void dfd_resume(void)
+{
+ if (dfd_enabled == true) {
+ dfd_setup(dfd_base_addr, dfd_chain_length, dfd_cache_dump);
+ }
+}
+
+uint64_t dfd_smc_dispatcher(uint64_t arg0, uint64_t arg1,
+ uint64_t arg2, uint64_t arg3)
+{
+ uint64_t ret = 0L;
+
+ switch (arg0) {
+ case PLAT_MTK_DFD_SETUP_MAGIC:
+ INFO("[%s] DFD setup call from kernel\n", __func__);
+ dfd_setup(arg1, arg2, arg3);
+ break;
+ case PLAT_MTK_DFD_READ_MAGIC:
+ /* only allow to access DFD register base + 0x200 */
+ if (arg1 <= 0x200) {
+ ret = mmio_read_32(MISC1_CFG_BASE + arg1);
+ }
+ break;
+ case PLAT_MTK_DFD_WRITE_MAGIC:
+ /* only allow to access DFD register base + 0x200 */
+ if (arg1 <= 0x200) {
+ sync_writel(MISC1_CFG_BASE + arg1, arg2);
+ }
+ break;
+ default:
+ ret = MTK_SIP_E_INVALID_PARAM;
+ break;
+ }
+
+ return ret;
+}
diff --git a/plat/mediatek/mt8186/drivers/dfd/plat_dfd.h b/plat/mediatek/mt8186/drivers/dfd/plat_dfd.h
new file mode 100644
index 0000000..1901ec9
--- /dev/null
+++ b/plat/mediatek/mt8186/drivers/dfd/plat_dfd.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2022, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_DFD_H
+#define PLAT_DFD_H
+
+#include <arch_helpers.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#define sync_writel(addr, val) do { mmio_write_32((addr), (val)); \
+ dsbsy(); \
+ } while (0)
+
+#define PLAT_MTK_DFD_SETUP_MAGIC (0x99716150)
+#define PLAT_MTK_DFD_READ_MAGIC (0x99716151)
+#define PLAT_MTK_DFD_WRITE_MAGIC (0x99716152)
+
+#define MCU_BIU_BASE (MCUCFG_BASE)
+#define MISC1_CFG_BASE (MCU_BIU_BASE + 0xA040)
+
+#define DFD_INTERNAL_CTL (MISC1_CFG_BASE + 0x00)
+#define DFD_INTERNAL_PWR_ON (MISC1_CFG_BASE + 0x08)
+#define DFD_CHAIN_LENGTH0 (MISC1_CFG_BASE + 0x0C)
+#define DFD_INTERNAL_SHIFT_CLK_RATIO (MISC1_CFG_BASE + 0x10)
+#define DFD_INTERNAL_TEST_SO_0 (MISC1_CFG_BASE + 0x28)
+#define DFD_INTERNAL_NUM_OF_TEST_SO_GROUP (MISC1_CFG_BASE + 0x30)
+#define DFD_V30_CTL (MISC1_CFG_BASE + 0x48)
+#define DFD_V30_BASE_ADDR (MISC1_CFG_BASE + 0x4C)
+#define DFD_TEST_SI_0 (MISC1_CFG_BASE + 0x58)
+#define DFD_TEST_SI_1 (MISC1_CFG_BASE + 0x5C)
+#define DFD_HW_TRIGGER_MASK (MISC1_CFG_BASE + 0xBC)
+
+#define DFD_V35_ENALBE (MCU_BIU_BASE + 0xA0A8)
+#define DFD_V35_TAP_NUMBER (MCU_BIU_BASE + 0xA0AC)
+#define DFD_V35_TAP_EN (MCU_BIU_BASE + 0xA0B0)
+#define DFD_V35_SEQ0_0 (MCU_BIU_BASE + 0xA0C0)
+#define DFD_V35_SEQ0_1 (MCU_BIU_BASE + 0xA0C4)
+
+#define DFD_CACHE_DUMP_ENABLE (1U)
+#define DFD_PARITY_ERR_TRIGGER (2U)
+
+#define MCUSYS_DFD_MAP (0x10001390)
+#define WDT_DEBUG_CTL (0x10007048)
+
+#define WDT_DEBUG_CTL_VAL_0 (0x950603A0)
+#define DFD_INTERNAL_TEST_SO_0_VAL (0x3B)
+#define DFD_TEST_SI_0_VAL (0x108)
+#define DFD_TEST_SI_1_VAL (0x20200000)
+
+#define WDT_DEBUG_CTL_VAL_1 (0x95063E80)
+#define DFD_V35_TAP_NUMBER_VAL (0xA)
+#define DFD_V35_TAP_EN_VAL (0x3FF)
+#define DFD_V35_SEQ0_0_VAL (0x63668820)
+#define DFD_HW_TRIGGER_MASK_VAL (0xC)
+
+void dfd_resume(void);
+uint64_t dfd_smc_dispatcher(uint64_t arg0, uint64_t arg1,
+ uint64_t arg2, uint64_t arg3);
+
+#endif /* PLAT_DFD_H */
diff --git a/plat/mediatek/mt8186/include/plat_sip_calls.h b/plat/mediatek/mt8186/include/plat_sip_calls.h
index 598a5b8..9e3726b 100644
--- a/plat/mediatek/mt8186/include/plat_sip_calls.h
+++ b/plat/mediatek/mt8186/include/plat_sip_calls.h
@@ -10,6 +10,10 @@
/*******************************************************************************
* Plat SiP function constants
******************************************************************************/
-#define MTK_PLAT_SIP_NUM_CALLS 0
+#define MTK_PLAT_SIP_NUM_CALLS (2)
+
+/* DFD */
+#define MTK_SIP_KERNEL_DFD_AARCH32 (0x82000205)
+#define MTK_SIP_KERNEL_DFD_AARCH64 (0xC2000205)
#endif /* PLAT_SIP_CALLS_H */
diff --git a/plat/mediatek/mt8186/plat_pm.c b/plat/mediatek/mt8186/plat_pm.c
index 6bc6b9d..e125c99 100644
--- a/plat/mediatek/mt8186/plat_pm.c
+++ b/plat/mediatek/mt8186/plat_pm.c
@@ -13,6 +13,7 @@
#include <mt_gic_v3.h>
#include <mtspmc.h>
#include <plat/common/platform.h>
+#include <plat_dfd.h>
#include <plat_mtk_lpm.h>
#include <plat_params.h>
#include <plat_pm.h>
@@ -164,6 +165,8 @@
mt_gic_distif_restore();
gic_sgi_restore_all();
+ dfd_resume();
+
(void)plat_mt_pm_invoke(plat_mt_pm->pwr_mcusys_on_finished, cpu, state);
}
diff --git a/plat/mediatek/mt8186/plat_sip_calls.c b/plat/mediatek/mt8186/plat_sip_calls.c
index 87ba786..cb66218 100644
--- a/plat/mediatek/mt8186/plat_sip_calls.c
+++ b/plat/mediatek/mt8186/plat_sip_calls.c
@@ -8,6 +8,7 @@
#include <common/runtime_svc.h>
#include <mt_spm_vcorefs.h>
#include <mtk_sip_svc.h>
+#include <plat_dfd.h>
#include "plat_sip_calls.h"
uintptr_t mediatek_plat_sip_handler(uint32_t smc_fid,
@@ -27,6 +28,11 @@
ret = spm_vcorefs_args(x1, x2, x3, (uint64_t *)&x4);
SMC_RET2(handle, ret, x4);
break;
+ case MTK_SIP_KERNEL_DFD_AARCH32:
+ case MTK_SIP_KERNEL_DFD_AARCH64:
+ ret = dfd_smc_dispatcher(x1, x2, x3, x4);
+ SMC_RET1(handle, ret);
+ break;
default:
ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
break;
diff --git a/plat/mediatek/mt8186/platform.mk b/plat/mediatek/mt8186/platform.mk
index 6108a05..b6d9ca8 100644
--- a/plat/mediatek/mt8186/platform.mk
+++ b/plat/mediatek/mt8186/platform.mk
@@ -15,6 +15,7 @@
-I${MTK_PLAT}/common/lpm/ \
-I${MTK_PLAT_SOC}/drivers/spm/ \
-I${MTK_PLAT_SOC}/drivers/dcm/ \
+ -I${MTK_PLAT_SOC}/drivers/dfd/ \
-I${MTK_PLAT_SOC}/drivers/emi_mpu/ \
-I${MTK_PLAT_SOC}/drivers/gpio/ \
-I${MTK_PLAT_SOC}/drivers/mcdi/ \
@@ -58,6 +59,7 @@
${MTK_PLAT_SOC}/bl31_plat_setup.c \
${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm.c \
${MTK_PLAT_SOC}/drivers/dcm/mtk_dcm_utils.c \
+ ${MTK_PLAT_SOC}/drivers/dfd/plat_dfd.c \
${MTK_PLAT_SOC}/drivers/emi_mpu/emi_mpu.c \
${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c \
${MTK_PLAT_SOC}/drivers/mcdi/mt_cpu_pm.c \
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 7b2c8ec..03a7278 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -6,10 +6,8 @@
#include <arch_helpers.h>
-
#include <lib/bakery_lock.h>
#include <lib/mmio.h>
-
#include <ipi.h>
#include <plat_ipi.h>
#include <plat_private.h>
@@ -17,7 +15,6 @@
#include "pm_ipi.h"
-
#define ERROR_CODE_MASK 0xFFFFU
DEFINE_BAKERY_LOCK(pm_secure_lock);
diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c
index 77ec20e..4c1d340 100644
--- a/plat/xilinx/versal/pm_service/pm_client.c
+++ b/plat/xilinx/versal/pm_service/pm_client.c
@@ -136,6 +136,7 @@
enum pm_device_node_idx node_idx;
uint32_t idx, irq, lowest_set = reg & (-reg);
enum pm_ret_status ret;
+
idx = __builtin_ctz(lowest_set);
irq = base_irq + idx;
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 3d98584..620bf6c 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -45,11 +45,11 @@
ifdef ZYNQMP_WDT_RESTART
-$(eval $(call add_define,ZYNQMP_WDT_RESTART))
+ $(eval $(call add_define,ZYNQMP_WDT_RESTART))
endif
ifdef ZYNQMP_IPI_CRC_CHECK
- $(warning "ZYNQMP_IPI_CRC_CHECK macro is deprecated...instead please use IPI_CRC_CHECK.")
+ $(warning "ZYNQMP_IPI_CRC_CHECK macro is deprecated...instead please use IPI_CRC_CHECK.")
endif
ifdef IPI_CRC_CHECK
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index 4e38c42..48b3877 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
@@ -175,7 +175,6 @@
uint32_t key_lo,
uint32_t key_hi,
uint32_t *value);
-
enum pm_ret_status pm_fpga_read(uint32_t reg_numframes,
uint32_t address_low,
uint32_t address_high,
@@ -189,15 +188,12 @@
unsigned int mask,
unsigned int value,
unsigned int *out);
-
enum pm_ret_status pm_pll_set_parameter(enum pm_node_id nid,
- enum pm_pll_param param_id,
- unsigned int value);
-
+ enum pm_pll_param param_id,
+ unsigned int value);
enum pm_ret_status pm_pll_get_parameter(enum pm_node_id nid,
- enum pm_pll_param param_id,
- unsigned int *value);
-
+ enum pm_pll_param param_id,
+ unsigned int *value);
enum pm_ret_status pm_pll_set_mode(enum pm_node_id nid, enum pm_pll_mode mode);
enum pm_ret_status pm_pll_get_mode(enum pm_node_id nid, enum pm_pll_mode *mode);
enum pm_ret_status pm_efuse_access(uint32_t address_high,
@@ -205,7 +201,6 @@
enum pm_ret_status em_set_action(unsigned int *value);
enum pm_ret_status em_remove_action(unsigned int *value);
enum pm_ret_status em_send_errors(unsigned int *value);
-
enum pm_ret_status pm_feature_config(unsigned int ioctl_id,
unsigned int config_id,
unsigned int value,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_defs.h b/plat/xilinx/zynqmp/pm_service/pm_defs.h
index 2baf960..8eb197a 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_defs.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_defs.h
@@ -303,16 +303,16 @@
};
/**
- * @PM_PLL_PARAM_DIV2: Enable for divide by 2 function inside the PLL
- * @PM_PLL_PARAM_FBDIV: Feedback divisor integer portion for the PLL
- * @PM_PLL_PARAM_DATA: Feedback divisor fractional portion for the PLL
- * @PM_PLL_PARAM_PRE_SRC: Clock source for PLL input
- * @PM_PLL_PARAM_POST_SRC: Clock source for PLL Bypass mode
- * @PM_PLL_PARAM_LOCK_DLY: Lock circuit config settings for lock windowsize
- * @PM_PLL_PARAM_LOCK_CNT: Lock circuit counter setting
- * @PM_PLL_PARAM_LFHF: PLL loop filter high frequency capacitor control
- * @PM_PLL_PARAM_CP: PLL charge pump control
- * @PM_PLL_PARAM_RES: PLL loop filter resistor control
+ * @PM_PLL_PARAM_DIV2: Enable for divide by 2 function inside the PLL
+ * @PM_PLL_PARAM_FBDIV: Feedback divisor integer portion for the PLL
+ * @PM_PLL_PARAM_DATA: Feedback divisor fractional portion for the PLL
+ * @PM_PLL_PARAM_PRE_SRC: Clock source for PLL input
+ * @PM_PLL_PARAM_POST_SRC: Clock source for PLL Bypass mode
+ * @PM_PLL_PARAM_LOCK_DLY: Lock circuit config settings for lock windowsize
+ * @PM_PLL_PARAM_LOCK_CNT: Lock circuit counter setting
+ * @PM_PLL_PARAM_LFHF: PLL loop filter high frequency capacitor control
+ * @PM_PLL_PARAM_CP: PLL charge pump control
+ * @PM_PLL_PARAM_RES: PLL loop filter resistor control
*/
enum pm_pll_param {
PM_PLL_PARAM_DIV2,
@@ -329,9 +329,9 @@
};
/**
- * @PM_PLL_MODE_RESET: PLL is in reset (not locked)
- * @PM_PLL_MODE_INTEGER: PLL is locked in integer mode
- * @PM_PLL_MODE_FRACTIONAL: PLL is locked in fractional mode
+ * @PM_PLL_MODE_RESET: PLL is in reset (not locked)
+ * @PM_PLL_MODE_INTEGER: PLL is locked in integer mode
+ * @PM_PLL_MODE_FRACTIONAL: PLL is locked in fractional mode
*/
enum pm_pll_mode {
PM_PLL_MODE_RESET,
@@ -341,8 +341,8 @@
};
/**
- * @PM_CLOCK_DIV0_ID: Clock divider 0
- * @PM_CLOCK_DIV1_ID: Clock divider 1
+ * @PM_CLOCK_DIV0_ID: Clock divider 0
+ * @PM_CLOCK_DIV1_ID: Clock divider 1
*/
enum pm_clock_div_id {
PM_CLOCK_DIV0_ID,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index b789da1..d88e5fa 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -34,7 +34,6 @@
static int active_cores = 0;
#endif
-
/**
* pm_context - Structure which contains data for power management
* @api_version version of PM API, must match with one on PMU side
@@ -103,7 +102,7 @@
* action.
*/
static uint64_t ttc_fiq_handler(uint32_t id, uint32_t flags, void *handle,
- void *cookie)
+ void *cookie)
{
INFO("BL31: Got TTC FIQ\n");
@@ -136,7 +135,7 @@
* running CPU calls system restart.
*/
static uint64_t __unused __dead2 zynqmp_sgi7_irq(uint32_t id, uint32_t flags,
- void *handle, void *cookie)
+ void *handle, void *cookie)
{
int i;
uint32_t value;
diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
index 5e770f7..352ba82 100644
--- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
+++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
@@ -8,7 +8,6 @@
#include <common/debug.h>
#include <drivers/console.h>
#include <plat/arm/common/plat_arm.h>
-
#include <plat_private.h>
#include <platform_tsp.h>