From c703d752cce4fd101599378e72db66ccf53644fa Mon Sep 17 00:00:00 2001 From: Sieu Mun Tang Date: Mon, 7 Mar 2022 12:13:04 +0800 Subject: [PATCH] fix(intel): fix ECC Double Bit Error handling SError and Abort are handled in Linux (EL1) instead of EL3. This patch adds some functionality that complements the use cases by Linux as follows: - Provide SMC for ECC DBE notification to EL3 - Determine type of reset needed and service the request in place of Linux Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi Signed-off-by: Sieu Mun Tang Change-Id: I43d02c77f28004a31770be53599a5a42de412211 --- plat/intel/soc/agilex/platform.mk | 1 + .../common/include/socfpga_reset_manager.h | 2 +- .../soc/common/include/socfpga_sip_svc.h | 14 ++++++ .../common/include/socfpga_system_manager.h | 8 +++- plat/intel/soc/common/sip/socfpga_sip_ecc.c | 46 +++++++++++++++++++ plat/intel/soc/common/socfpga_psci.c | 7 ++- plat/intel/soc/common/socfpga_sip_svc.c | 4 ++ plat/intel/soc/n5x/platform.mk | 1 + plat/intel/soc/stratix10/platform.mk | 1 + 9 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 plat/intel/soc/common/sip/socfpga_sip_ecc.c diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk index 92b77545d..10a3eec42 100644 --- a/plat/intel/soc/agilex/platform.mk +++ b/plat/intel/soc/agilex/platform.mk @@ -65,6 +65,7 @@ BL31_SOURCES += \ plat/intel/soc/common/socfpga_psci.c \ plat/intel/soc/common/socfpga_sip_svc.c \ plat/intel/soc/common/socfpga_topology.c \ + plat/intel/soc/common/sip/socfpga_sip_ecc.c \ plat/intel/soc/common/sip/socfpga_sip_fcs.c \ plat/intel/soc/common/soc/socfpga_mailbox.c \ plat/intel/soc/common/soc/socfpga_reset_manager.c diff --git a/plat/intel/soc/common/include/socfpga_reset_manager.h b/plat/intel/soc/common/include/socfpga_reset_manager.h index 637f8dfe5..a976df75f 100644 --- a/plat/intel/soc/common/include/socfpga_reset_manager.h +++ b/plat/intel/soc/common/include/socfpga_reset_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Intel Corporation. All rights reserved. + * Copyright (c) 2019-2022, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h index 6eca19719..5770f11c9 100644 --- a/plat/intel/soc/common/include/socfpga_sip_svc.h +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -40,12 +40,22 @@ #define INTEL_SIP_SMC_RSU_DCMF_VERSION 0xC2000010 #define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION 0xC2000011 + +/* ECC */ +#define INTEL_SIP_SMC_ECC_DBE 0xC200000D + /* Send Mailbox Command */ #define INTEL_SIP_SMC_MBOX_SEND_CMD 0xC200001E /* SiP Definitions */ +/* ECC DBE */ +#define WARM_RESET_WFI_FLAG BIT(31) +#define SYSMGR_ECC_DBE_COLD_RST_MASK (SYSMGR_ECC_OCRAM_MASK |\ + SYSMGR_ECC_DDR0_MASK |\ + SYSMGR_ECC_DDR1_MASK) + /* FPGA config helpers */ #define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x400000 #define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 0x2000000 @@ -74,4 +84,8 @@ struct fpga_config_info { bool is_address_in_ddr_range(uint64_t addr, uint64_t size); +/* ECC DBE */ +bool cold_reset_for_ecc_dbe(void); +uint32_t intel_ecc_dbe_notification(uint64_t dbe_value); + #endif /* SOCFPGA_SIP_SVC_H */ diff --git a/plat/intel/soc/common/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h index 8b42d47af..2b13f1fd3 100644 --- a/plat/intel/soc/common/include/socfpga_system_manager.h +++ b/plat/intel/soc/common/include/socfpga_system_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, Intel Corporation. All rights reserved. + * Copyright (c) 2019-2022, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -30,6 +30,8 @@ #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_0 0x200 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_1 0x204 #define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_2 0x208 +#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_8 0x220 +#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_9 0x224 /* Field Masking */ @@ -47,6 +49,10 @@ | SCR_MPU_MASK) #define DISABLE_BRIDGE_FIREWALL 0x0ffe0101 +#define SYSMGR_ECC_OCRAM_MASK BIT(1) +#define SYSMGR_ECC_DDR0_MASK BIT(16) +#define SYSMGR_ECC_DDR1_MASK BIT(17) + /* Macros */ #define SOCFPGA_SYSMGR(_reg) (SOCFPGA_SYSMGR_REG_BASE \ diff --git a/plat/intel/soc/common/sip/socfpga_sip_ecc.c b/plat/intel/soc/common/sip/socfpga_sip_ecc.c new file mode 100644 index 000000000..c4e06a6dc --- /dev/null +++ b/plat/intel/soc/common/sip/socfpga_sip_ecc.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved. + */ + +#include +#include +#include +#include +#include + +#include "socfpga_fcs.h" +#include "socfpga_mailbox.h" +#include "socfpga_reset_manager.h" +#include "socfpga_sip_svc.h" +#include "socfpga_system_manager.h" + +uint32_t intel_ecc_dbe_notification(uint64_t dbe_value) +{ + dbe_value &= WARM_RESET_WFI_FLAG; + + /* Trap CPUs in WFI if warm reset flag is set */ + if (dbe_value > 0) { + while (1) { + wfi(); + } + } + + return INTEL_SIP_SMC_STATUS_OK; +} + +bool cold_reset_for_ecc_dbe(void) +{ + uint32_t dbe_int_status; + + dbe_int_status = mmio_read_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_8)); + + /* Trigger cold reset only for error in critical memory (DDR/OCRAM) */ + dbe_int_status &= SYSMGR_ECC_DBE_COLD_RST_MASK; + + if (dbe_int_status > 0) { + return true; + } + + return false; +} diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c index 4b57b8f31..5fd6559f2 100644 --- a/plat/intel/soc/common/socfpga_psci.c +++ b/plat/intel/soc/common/socfpga_psci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,7 +14,7 @@ #include "socfpga_mailbox.h" #include "socfpga_plat_def.h" #include "socfpga_reset_manager.h" - +#include "socfpga_sip_svc.h" /******************************************************************************* @@ -151,6 +151,9 @@ static void __dead2 socfpga_system_reset(void) static int socfpga_system_reset2(int is_vendor, int reset_type, u_register_t cookie) { + if (cold_reset_for_ecc_dbe()) { + mailbox_reset_cold(); + } /* disable cpuif */ gicv2_cpuif_disable(); diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 16f8145d5..14cd9e07b 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -530,6 +530,10 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, SMC_RET2(handle, status, retval); } + case INTEL_SIP_SMC_ECC_DBE: + status = intel_ecc_dbe_notification(x1); + SMC_RET1(handle, status); + case INTEL_SIP_SMC_MBOX_SEND_CMD: x5 = SMC_GET_GP(handle, CTX_GPREG_X5); x6 = SMC_GET_GP(handle, CTX_GPREG_X6); diff --git a/plat/intel/soc/n5x/platform.mk b/plat/intel/soc/n5x/platform.mk index 722694d43..8366d6d33 100644 --- a/plat/intel/soc/n5x/platform.mk +++ b/plat/intel/soc/n5x/platform.mk @@ -38,6 +38,7 @@ BL31_SOURCES += \ plat/intel/soc/common/socfpga_psci.c \ plat/intel/soc/common/socfpga_sip_svc.c \ plat/intel/soc/common/socfpga_topology.c \ + plat/intel/soc/common/sip/socfpga_sip_ecc.c \ plat/intel/soc/common/sip/socfpga_sip_fcs.c \ plat/intel/soc/common/soc/socfpga_mailbox.c \ plat/intel/soc/common/soc/socfpga_reset_manager.c diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk index b47ac9d72..d9d88d418 100644 --- a/plat/intel/soc/stratix10/platform.mk +++ b/plat/intel/soc/stratix10/platform.mk @@ -63,6 +63,7 @@ BL31_SOURCES += \ plat/intel/soc/common/socfpga_psci.c \ plat/intel/soc/common/socfpga_sip_svc.c \ plat/intel/soc/common/socfpga_topology.c \ + plat/intel/soc/common/sip/socfpga_sip_ecc.c \ plat/intel/soc/common/sip/socfpga_sip_fcs.c \ plat/intel/soc/common/soc/socfpga_mailbox.c \ plat/intel/soc/common/soc/socfpga_reset_manager.c