From e8166d3e5937b8db43921b5049672b16af7f58e0 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Wed, 22 Mar 2023 15:27:22 -0500 Subject: [PATCH 1/2] feat(sbsa): helper api for refreshing watchdog timer This patch adds a helper API to explicitly refresh SBSA secure watchdog timer. Please refer section A.3 of the following spec: https://developer.arm.com/documentation/den0029/latest/ Change-Id: I2d0943792aea0092bee1e51d74b908348587e66b Signed-off-by: Madhukar Pappireddy --- changelog.yaml | 3 +++ drivers/arm/sbsa/sbsa.c | 8 +++++++- include/drivers/arm/sbsa.h | 10 ++++++++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/changelog.yaml b/changelog.yaml index 6dbb9b20d..c969b2c56 100644 --- a/changelog.yaml +++ b/changelog.yaml @@ -877,6 +877,9 @@ subsections: deprecated: - drivers/tzc380 + - title: SBSA + scope: sbsa + - title: Marvell scope: marvell-drivers diff --git a/drivers/arm/sbsa/sbsa.c b/drivers/arm/sbsa/sbsa.c index 79c6f2620..a88e20c04 100644 --- a/drivers/arm/sbsa/sbsa.c +++ b/drivers/arm/sbsa/sbsa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited. All rights reserved. + * Copyright (c) 2019-2023, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -40,3 +40,9 @@ void sbsa_wdog_stop(uintptr_t base) { mmio_write_32(base + SBSA_WDOG_WCS_OFFSET, (0x0)); } + +/* Refresh the secure watchdog timer explicitly */ +void sbsa_wdog_refresh(uintptr_t refresh_base) +{ + mmio_write_32(refresh_base + SBSA_WDOG_WRR_OFFSET, SBSA_WDOG_WRR_REFRESH); +} diff --git a/include/drivers/arm/sbsa.h b/include/drivers/arm/sbsa.h index 9403634f7..4ca71942e 100644 --- a/include/drivers/arm/sbsa.h +++ b/include/drivers/arm/sbsa.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited. All rights reserved. + * Copyright (c) 2019-2023, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,7 +9,12 @@ #include -/* Register Offsets */ +/* SBSA Secure Watchdog Register Offsets */ +/* Refresh frame */ +#define SBSA_WDOG_WRR_OFFSET UL(0x000) +#define SBSA_WDOG_WRR_REFRESH UL(0x1) + +/* Control and status frame */ #define SBSA_WDOG_WCS_OFFSET UL(0x000) #define SBSA_WDOG_WOR_LOW_OFFSET UL(0x008) #define SBSA_WDOG_WOR_HIGH_OFFSET UL(0x00C) @@ -20,5 +25,6 @@ void sbsa_wdog_start(uintptr_t base, uint64_t ms); void sbsa_wdog_stop(uintptr_t base); +void sbsa_wdog_refresh(uintptr_t refresh_base); #endif /* SBSA_H */ From 28b2d86cd28ffc54c6272defcd6f123a925012f1 Mon Sep 17 00:00:00 2001 From: Madhukar Pappireddy Date: Wed, 22 Mar 2023 15:40:40 -0500 Subject: [PATCH 2/2] feat(tc): allow secure watchdog timer to trigger periodically This patch does the following: 1. Configures SBSA secure watchdog timer as Group0 interrupt for TC platform while keeping it as Group1 secure interrupt for other CSS based SoCs. 2. Programs the watchdog timer to trigger periodically 3. Provides a Group0 interrupt handler for TC platform port to deactivate the EL3 interrupt due to expiry of secure watchdog timer and refresh it explicitly. Change-Id: I3847d6eb7347c6ea0e527b97b096119ca1e6701b Signed-off-by: Madhukar Pappireddy --- include/plat/arm/common/plat_arm.h | 1 + include/plat/arm/css/common/css_def.h | 11 +++++--- plat/arm/board/tc/include/platform_def.h | 13 ++++++--- plat/arm/board/tc/platform.mk | 3 +- plat/arm/board/tc/tc_bl31_setup.c | 35 ++++++++++++++++++++++++ plat/arm/board/tc/tc_plat.c | 11 ++++++-- plat/arm/common/arm_bl31_setup.c | 3 +- 7 files changed, 64 insertions(+), 13 deletions(-) diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index ffbd4ca13..e8461f5a2 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -364,6 +364,7 @@ extern const unsigned int arm_pm_idle_states[]; /* secure watchdog */ void plat_arm_secure_wdt_start(void); void plat_arm_secure_wdt_stop(void); +void plat_arm_secure_wdt_refresh(void); /* Get SOC-ID of ARM platform */ uint32_t plat_arm_get_soc_id(void); diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h index dde174c37..f87f857c5 100644 --- a/include/plat/arm/css/common/css_def.h +++ b/include/plat/arm/css/common/css_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -52,18 +52,21 @@ * terminology. On a GICv2 system or mode, the interrupts will be treated as * Group 0 interrupts. */ -#define CSS_G1S_IRQ_PROPS(grp) \ +#define CSS_G1S_INT_PROPS(grp) \ INTR_PROP_DESC(CSS_IRQ_MHU, GIC_HIGHEST_SEC_PRIORITY, grp, \ GIC_INTR_CFG_LEVEL), \ INTR_PROP_DESC(CSS_IRQ_GPU_SMMU_0, GIC_HIGHEST_SEC_PRIORITY, grp, \ GIC_INTR_CFG_LEVEL), \ INTR_PROP_DESC(CSS_IRQ_TZC, GIC_HIGHEST_SEC_PRIORITY, grp, \ GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(CSS_IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_LEVEL), \ INTR_PROP_DESC(CSS_IRQ_SEC_SYS_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \ GIC_INTR_CFG_LEVEL) +#define CSS_G1S_IRQ_PROPS(grp) \ + CSS_G1S_INT_PROPS(grp), \ + INTR_PROP_DESC(CSS_IRQ_TZ_WDOG, GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL) + #if CSS_USE_SCMI_SDS_DRIVER /* Memory region for shared data storage */ #define PLAT_ARM_SDS_MEM_BASE ARM_SHARED_RAM_BASE diff --git a/plat/arm/board/tc/include/platform_def.h b/plat/arm/board/tc/include/platform_def.h index eea1be6ba..59fff6e2a 100644 --- a/plat/arm/board/tc/include/platform_def.h +++ b/plat/arm/board/tc/include/platform_def.h @@ -212,8 +212,11 @@ #define PLAT_ARM_DRAM2_SIZE ULL(0x180000000) #define PLAT_ARM_DRAM2_END (PLAT_ARM_DRAM2_BASE + PLAT_ARM_DRAM2_SIZE - 1ULL) -#define PLAT_ARM_G1S_IRQ_PROPS(grp) CSS_G1S_IRQ_PROPS(grp) -#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) +#define PLAT_ARM_G1S_IRQ_PROPS(grp) CSS_G1S_INT_PROPS(grp) +#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp), \ + INTR_PROP_DESC(SBSA_SECURE_WDOG_INTID, \ + GIC_HIGHEST_SEC_PRIORITY, grp, \ + GIC_INTR_CFG_LEVEL) #define PLAT_ARM_SP_IMAGE_STACK_BASE (PLAT_SP_IMAGE_NS_BUF_BASE + \ PLAT_SP_IMAGE_NS_BUF_SIZE) @@ -229,9 +232,11 @@ #define PLAT_ARM_MEM_PROT_ADDR (V2M_FLASH0_BASE + \ V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE) -/*Secure Watchdog Constants */ -#define SBSA_SECURE_WDOG_BASE UL(0x2A480000) +/* Secure Watchdog Constants */ +#define SBSA_SECURE_WDOG_CONTROL_BASE UL(0x2A480000) +#define SBSA_SECURE_WDOG_REFRESH_BASE UL(0x2A490000) #define SBSA_SECURE_WDOG_TIMEOUT UL(100) +#define SBSA_SECURE_WDOG_INTID 86 #define PLAT_ARM_SCMI_CHANNEL_COUNT 1 diff --git a/plat/arm/board/tc/platform.mk b/plat/arm/board/tc/platform.mk index 63a923795..c75507a51 100644 --- a/plat/arm/board/tc/platform.mk +++ b/plat/arm/board/tc/platform.mk @@ -118,7 +118,8 @@ BL31_SOURCES += ${INTERCONNECT_SOURCES} \ lib/fconf/fconf_dyn_cfg_getter.c \ drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ - plat/arm/common/arm_nor_psci_mem_protect.c + plat/arm/common/arm_nor_psci_mem_protect.c \ + drivers/arm/sbsa/sbsa.c BL31_SOURCES += ${FDT_WRAPPERS_SOURCES} diff --git a/plat/arm/board/tc/tc_bl31_setup.c b/plat/arm/board/tc/tc_bl31_setup.c index 8ad1d3056..630324fb3 100644 --- a/plat/arm/board/tc/tc_bl31_setup.c +++ b/plat/arm/board/tc/tc_bl31_setup.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -81,3 +82,37 @@ void __init bl31_plat_arch_setup(void) fconf_populate("HW_CONFIG", hw_config_info->config_addr); } + +#if defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1) +void tc_bl31_plat_runtime_setup(void) +{ + arm_bl31_plat_runtime_setup(); + + /* Start secure watchdog timer. */ + plat_arm_secure_wdt_start(); +} + +void bl31_plat_runtime_setup(void) +{ + tc_bl31_plat_runtime_setup(); +} + +/* + * Platform handler for Group0 secure interrupt. + */ +int plat_spmd_handle_group0_interrupt(uint32_t intid) +{ + /* Trusted Watchdog timer is the only source of Group0 interrupt now. */ + if (intid == SBSA_SECURE_WDOG_INTID) { + INFO("Watchdog restarted\n"); + /* Refresh the timer. */ + plat_arm_secure_wdt_refresh(); + + /* Deactivate the corresponding interrupt. */ + plat_ic_end_of_interrupt(intid); + return 0; + } + + return -1; +} +#endif /*defined(SPD_spmd) && (SPMD_SPM_AT_SEL2 == 1)*/ diff --git a/plat/arm/board/tc/tc_plat.c b/plat/arm/board/tc/tc_plat.c index 228f2fab3..766bfb570 100644 --- a/plat/arm/board/tc/tc_plat.c +++ b/plat/arm/board/tc/tc_plat.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2023, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -147,10 +147,15 @@ int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) void plat_arm_secure_wdt_start(void) { - sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT); + sbsa_wdog_start(SBSA_SECURE_WDOG_CONTROL_BASE, SBSA_SECURE_WDOG_TIMEOUT); } void plat_arm_secure_wdt_stop(void) { - sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE); + sbsa_wdog_stop(SBSA_SECURE_WDOG_CONTROL_BASE); +} + +void plat_arm_secure_wdt_refresh(void) +{ + sbsa_wdog_refresh(SBSA_SECURE_WDOG_REFRESH_BASE); } diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 19efdd32e..8c62a9bb9 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -43,6 +43,7 @@ CASSERT(BL31_BASE >= ARM_FW_CONFIG_LIMIT, assert_bl31_base_overflows); #pragma weak bl31_platform_setup #pragma weak bl31_plat_arch_setup #pragma weak bl31_plat_get_next_image_ep_info +#pragma weak bl31_plat_runtime_setup #define MAP_BL31_TOTAL MAP_REGION_FLAT( \ BL31_START, \