1 /* 2 * Copyright (c) 2015-2016, 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/sp805.h> 13 #include <plat/common/platform.h> 14 #include <platform_def.h> 15 16 #include <plat_arm.h> 17 #include <sds.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 int plat_arm_bl1_fwu_needed(void) 64 { 65 const uint32_t *nv_flags_ptr = (const uint32_t *)V2M_SYS_NVFLAGS_ADDR; 66 67 /* Check if TOC is invalid or watchdog reset happened. */ 68 if ((arm_io_is_toc_valid() != 1) || 69 (((*nv_flags_ptr == -EAUTH) || (*nv_flags_ptr == -ENOENT)) 70 && is_watchdog_reset())) 71 return 1; 72 73 return 0; 74 } 75 76 /******************************************************************************* 77 * On JUNO update the arg2 with address of SCP_BL2U image info. 78 ******************************************************************************/ 79 void bl1_plat_set_ep_info(unsigned int image_id, 80 entry_point_info_t *ep_info) 81 { 82 if (image_id == BL2U_IMAGE_ID) { 83 image_desc_t *image_desc = bl1_plat_get_image_desc(SCP_BL2U_IMAGE_ID); 84 ep_info->args.arg2 = (unsigned long)&image_desc->image_info; 85 } 86 } 87 88 /******************************************************************************* 89 * On Juno clear SYS_NVFLAGS and wait for watchdog reset. 90 ******************************************************************************/ 91 __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) 92 { 93 unsigned int *nv_flags_clr = (unsigned int *) 94 (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGSCLR); 95 unsigned int *nv_flags_ptr = (unsigned int *) 96 (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGS); 97 98 /* Clear the NV flags register. */ 99 *nv_flags_clr = *nv_flags_ptr; 100 101 while (1) 102 wfi(); 103 } 104 105 #if JUNO_AARCH32_EL3_RUNTIME 106 void bl1_plat_prepare_exit(entry_point_info_t *ep_info) 107 { 108 #if !ARM_DISABLE_TRUSTED_WDOG 109 /* Disable watchdog before leaving BL1 */ 110 sp805_stop(ARM_SP805_TWDG_BASE); 111 #endif 112 113 juno_reset_to_aarch32_state(); 114 } 115 #endif /* JUNO_AARCH32_EL3_RUNTIME */ 116