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/css/sds.h> 13 #include <drivers/arm/sp805.h> 14 #include <plat/arm/common/plat_arm.h> 15 #include <plat/common/platform.h> 16 #include <platform_def.h> 17 18 void juno_reset_to_aarch32_state(void); 19 20 static int is_watchdog_reset(void) 21 { 22 #if !CSS_USE_SCMI_SDS_DRIVER 23 #define RESET_REASON_WDOG_RESET (0x2) 24 const uint32_t *reset_flags_ptr = (const uint32_t *)SSC_GPRETN; 25 26 if ((*reset_flags_ptr & RESET_REASON_WDOG_RESET) != 0) 27 return 1; 28 29 return 0; 30 #else 31 int ret; 32 uint32_t scp_reset_synd_flags; 33 34 ret = sds_init(); 35 if (ret != SDS_OK) { 36 ERROR("SCP SDS initialization failed\n"); 37 panic(); 38 } 39 40 ret = sds_struct_read(SDS_RESET_SYNDROME_STRUCT_ID, 41 SDS_RESET_SYNDROME_OFFSET, 42 &scp_reset_synd_flags, 43 SDS_RESET_SYNDROME_SIZE, 44 SDS_ACCESS_MODE_NON_CACHED); 45 if (ret != SDS_OK) { 46 ERROR("Getting reset reason from SDS failed\n"); 47 panic(); 48 } 49 50 /* Check if the WATCHDOG_RESET_BIT is set in the reset syndrome */ 51 if (scp_reset_synd_flags & SDS_RESET_SYNDROME_AP_WD_RESET_BIT) 52 return 1; 53 54 return 0; 55 #endif 56 } 57 58 /******************************************************************************* 59 * The following function checks if Firmware update is needed, 60 * by checking if TOC in FIP image is valid or watchdog reset happened. 61 ******************************************************************************/ 62 int plat_arm_bl1_fwu_needed(void) 63 { 64 const uint32_t *nv_flags_ptr = (const uint32_t *)V2M_SYS_NVFLAGS_ADDR; 65 66 /* Check if TOC is invalid or watchdog reset happened. */ 67 if ((arm_io_is_toc_valid() != 1) || 68 (((*nv_flags_ptr == -EAUTH) || (*nv_flags_ptr == -ENOENT)) 69 && is_watchdog_reset())) 70 return 1; 71 72 return 0; 73 } 74 75 /******************************************************************************* 76 * On JUNO update the arg2 with address of SCP_BL2U image info. 77 ******************************************************************************/ 78 void bl1_plat_set_ep_info(unsigned int image_id, 79 entry_point_info_t *ep_info) 80 { 81 if (image_id == BL2U_IMAGE_ID) { 82 image_desc_t *image_desc = bl1_plat_get_image_desc(SCP_BL2U_IMAGE_ID); 83 ep_info->args.arg2 = (unsigned long)&image_desc->image_info; 84 } 85 } 86 87 /******************************************************************************* 88 * On Juno clear SYS_NVFLAGS and wait for watchdog reset. 89 ******************************************************************************/ 90 __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) 91 { 92 unsigned int *nv_flags_clr = (unsigned int *) 93 (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGSCLR); 94 unsigned int *nv_flags_ptr = (unsigned int *) 95 (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGS); 96 97 /* Clear the NV flags register. */ 98 *nv_flags_clr = *nv_flags_ptr; 99 100 while (1) 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