1 /* 2 * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <errno.h> 8 9 #include <common/bl_common.h> 10 #include <common/debug.h> 11 #include <common/tbbr/tbbr_img_def.h> 12 #include <drivers/arm/css/sds.h> 13 #include <drivers/arm/sp805.h> 14 #include <plat/arm/common/plat_arm.h> 15 #include <plat/arm/common/arm_def.h> 16 #include <plat/common/platform.h> 17 #include <platform_def.h> 18 19 void juno_reset_to_aarch32_state(void); 20 21 static int is_watchdog_reset(void) 22 { 23 #if !CSS_USE_SCMI_SDS_DRIVER 24 #define RESET_REASON_WDOG_RESET (0x2) 25 const uint32_t *reset_flags_ptr = (const uint32_t *)SSC_GPRETN; 26 27 if ((*reset_flags_ptr & RESET_REASON_WDOG_RESET) != 0) 28 return 1; 29 30 return 0; 31 #else 32 int ret; 33 uint32_t scp_reset_synd_flags; 34 35 ret = sds_init(); 36 if (ret != SDS_OK) { 37 ERROR("SCP SDS initialization failed\n"); 38 panic(); 39 } 40 41 ret = sds_struct_read(SDS_RESET_SYNDROME_STRUCT_ID, 42 SDS_RESET_SYNDROME_OFFSET, 43 &scp_reset_synd_flags, 44 SDS_RESET_SYNDROME_SIZE, 45 SDS_ACCESS_MODE_NON_CACHED); 46 if (ret != SDS_OK) { 47 ERROR("Getting reset reason from SDS failed\n"); 48 panic(); 49 } 50 51 /* Check if the WATCHDOG_RESET_BIT is set in the reset syndrome */ 52 if (scp_reset_synd_flags & SDS_RESET_SYNDROME_AP_WD_RESET_BIT) 53 return 1; 54 55 return 0; 56 #endif 57 } 58 59 /******************************************************************************* 60 * The following function checks if Firmware update is needed, 61 * by checking if TOC in FIP image is valid or watchdog reset happened. 62 ******************************************************************************/ 63 bool plat_arm_bl1_fwu_needed(void) 64 { 65 const int32_t *nv_flags_ptr = (const int32_t *)V2M_SYS_NVFLAGS_ADDR; 66 67 /* Check if TOC is invalid or watchdog reset happened. */ 68 return (!arm_io_is_toc_valid() || (((*nv_flags_ptr == -EAUTH) || 69 (*nv_flags_ptr == -ENOENT)) && is_watchdog_reset())); 70 } 71 72 /******************************************************************************* 73 * On JUNO update the arg2 with address of SCP_BL2U image info. 74 ******************************************************************************/ 75 void bl1_plat_set_ep_info(unsigned int image_id, 76 entry_point_info_t *ep_info) 77 { 78 if (image_id == BL2U_IMAGE_ID) { 79 image_desc_t *image_desc = bl1_plat_get_image_desc(SCP_BL2U_IMAGE_ID); 80 ep_info->args.arg2 = (unsigned long)&image_desc->image_info; 81 } 82 } 83 84 /******************************************************************************* 85 * On Juno clear SYS_NVFLAGS and wait for watchdog reset. 86 ******************************************************************************/ 87 __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) 88 { 89 unsigned int *nv_flags_clr = (unsigned int *) 90 (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGSCLR); 91 unsigned int *nv_flags_ptr = (unsigned int *) 92 (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGS); 93 94 /* Clear the NV flags register. */ 95 *nv_flags_clr = *nv_flags_ptr; 96 97 /* Setup the watchdog to reset the system as soon as possible */ 98 sp805_refresh(ARM_SP805_TWDG_BASE, 1U); 99 100 while (true) 101 wfi(); 102 } 103 104 #if JUNO_AARCH32_EL3_RUNTIME 105 void bl1_plat_prepare_exit(entry_point_info_t *ep_info) 106 { 107 #if !ARM_DISABLE_TRUSTED_WDOG 108 /* Disable watchdog before leaving BL1 */ 109 sp805_stop(ARM_SP805_TWDG_BASE); 110 #endif 111 112 juno_reset_to_aarch32_state(); 113 } 114 #endif /* JUNO_AARCH32_EL3_RUNTIME */ 115 116 void plat_arm_secure_wdt_start(void) 117 { 118 sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL); 119 } 120 121 void plat_arm_secure_wdt_stop(void) 122 { 123 sp805_stop(ARM_SP805_TWDG_BASE); 124 } 125