1436223deSYatharth Kochar /* 207570d59SYatharth Kochar * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. 3436223deSYatharth Kochar * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5436223deSYatharth Kochar */ 6436223deSYatharth Kochar 7436223deSYatharth Kochar #include <errno.h> 809d40e0eSAntonio Nino Diaz 909d40e0eSAntonio Nino Diaz #include <common/bl_common.h> 1009d40e0eSAntonio Nino Diaz #include <common/debug.h> 1109d40e0eSAntonio Nino Diaz #include <common/tbbr/tbbr_img_def.h> 125932d194SAntonio Nino Diaz #include <drivers/arm/css/sds.h> 1309d40e0eSAntonio Nino Diaz #include <drivers/arm/sp805.h> 14bd9344f6SAntonio Nino Diaz #include <plat/arm/common/plat_arm.h> 1509d40e0eSAntonio Nino Diaz #include <plat/common/platform.h> 16234bc7f8SAntonio Nino Diaz #include <platform_def.h> 1709d40e0eSAntonio Nino Diaz 1807570d59SYatharth Kochar void juno_reset_to_aarch32_state(void); 1907570d59SYatharth Kochar 204da6f6cdSSathees Balya static int is_watchdog_reset(void) 214da6f6cdSSathees Balya { 224da6f6cdSSathees Balya #if !CSS_USE_SCMI_SDS_DRIVER 234da6f6cdSSathees Balya #define RESET_REASON_WDOG_RESET (0x2) 244da6f6cdSSathees Balya const uint32_t *reset_flags_ptr = (const uint32_t *)SSC_GPRETN; 254da6f6cdSSathees Balya 264da6f6cdSSathees Balya if ((*reset_flags_ptr & RESET_REASON_WDOG_RESET) != 0) 274da6f6cdSSathees Balya return 1; 284da6f6cdSSathees Balya 294da6f6cdSSathees Balya return 0; 304da6f6cdSSathees Balya #else 314da6f6cdSSathees Balya int ret; 324da6f6cdSSathees Balya uint32_t scp_reset_synd_flags; 334da6f6cdSSathees Balya 344da6f6cdSSathees Balya ret = sds_init(); 354da6f6cdSSathees Balya if (ret != SDS_OK) { 364da6f6cdSSathees Balya ERROR("SCP SDS initialization failed\n"); 374da6f6cdSSathees Balya panic(); 384da6f6cdSSathees Balya } 394da6f6cdSSathees Balya 404da6f6cdSSathees Balya ret = sds_struct_read(SDS_RESET_SYNDROME_STRUCT_ID, 414da6f6cdSSathees Balya SDS_RESET_SYNDROME_OFFSET, 424da6f6cdSSathees Balya &scp_reset_synd_flags, 434da6f6cdSSathees Balya SDS_RESET_SYNDROME_SIZE, 444da6f6cdSSathees Balya SDS_ACCESS_MODE_NON_CACHED); 454da6f6cdSSathees Balya if (ret != SDS_OK) { 464da6f6cdSSathees Balya ERROR("Getting reset reason from SDS failed\n"); 474da6f6cdSSathees Balya panic(); 484da6f6cdSSathees Balya } 494da6f6cdSSathees Balya 504da6f6cdSSathees Balya /* Check if the WATCHDOG_RESET_BIT is set in the reset syndrome */ 514da6f6cdSSathees Balya if (scp_reset_synd_flags & SDS_RESET_SYNDROME_AP_WD_RESET_BIT) 524da6f6cdSSathees Balya return 1; 534da6f6cdSSathees Balya 544da6f6cdSSathees Balya return 0; 554da6f6cdSSathees Balya #endif 564da6f6cdSSathees Balya } 574da6f6cdSSathees Balya 584da6f6cdSSathees Balya /******************************************************************************* 594da6f6cdSSathees Balya * The following function checks if Firmware update is needed, 604da6f6cdSSathees Balya * by checking if TOC in FIP image is valid or watchdog reset happened. 614da6f6cdSSathees Balya ******************************************************************************/ 624da6f6cdSSathees Balya int plat_arm_bl1_fwu_needed(void) 634da6f6cdSSathees Balya { 64*bde2836fSAmbroise Vincent const int32_t *nv_flags_ptr = (const int32_t *)V2M_SYS_NVFLAGS_ADDR; 654da6f6cdSSathees Balya 664da6f6cdSSathees Balya /* Check if TOC is invalid or watchdog reset happened. */ 674da6f6cdSSathees Balya if ((arm_io_is_toc_valid() != 1) || 684da6f6cdSSathees Balya (((*nv_flags_ptr == -EAUTH) || (*nv_flags_ptr == -ENOENT)) 694da6f6cdSSathees Balya && is_watchdog_reset())) 704da6f6cdSSathees Balya return 1; 714da6f6cdSSathees Balya 724da6f6cdSSathees Balya return 0; 734da6f6cdSSathees Balya } 744da6f6cdSSathees Balya 75436223deSYatharth Kochar /******************************************************************************* 76436223deSYatharth Kochar * On JUNO update the arg2 with address of SCP_BL2U image info. 77436223deSYatharth Kochar ******************************************************************************/ 78436223deSYatharth Kochar void bl1_plat_set_ep_info(unsigned int image_id, 79436223deSYatharth Kochar entry_point_info_t *ep_info) 80436223deSYatharth Kochar { 81436223deSYatharth Kochar if (image_id == BL2U_IMAGE_ID) { 82436223deSYatharth Kochar image_desc_t *image_desc = bl1_plat_get_image_desc(SCP_BL2U_IMAGE_ID); 83436223deSYatharth Kochar ep_info->args.arg2 = (unsigned long)&image_desc->image_info; 84436223deSYatharth Kochar } 85436223deSYatharth Kochar } 86436223deSYatharth Kochar 87436223deSYatharth Kochar /******************************************************************************* 88436223deSYatharth Kochar * On Juno clear SYS_NVFLAGS and wait for watchdog reset. 89436223deSYatharth Kochar ******************************************************************************/ 901f37b944SDan Handley __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) 91436223deSYatharth Kochar { 92436223deSYatharth Kochar unsigned int *nv_flags_clr = (unsigned int *) 93436223deSYatharth Kochar (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGSCLR); 94436223deSYatharth Kochar unsigned int *nv_flags_ptr = (unsigned int *) 95436223deSYatharth Kochar (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGS); 96436223deSYatharth Kochar 97436223deSYatharth Kochar /* Clear the NV flags register. */ 98436223deSYatharth Kochar *nv_flags_clr = *nv_flags_ptr; 99436223deSYatharth Kochar 100436223deSYatharth Kochar while (1) 101436223deSYatharth Kochar wfi(); 102436223deSYatharth Kochar } 10307570d59SYatharth Kochar 10407570d59SYatharth Kochar #if JUNO_AARCH32_EL3_RUNTIME 10507570d59SYatharth Kochar void bl1_plat_prepare_exit(entry_point_info_t *ep_info) 10607570d59SYatharth Kochar { 10707570d59SYatharth Kochar #if !ARM_DISABLE_TRUSTED_WDOG 10807570d59SYatharth Kochar /* Disable watchdog before leaving BL1 */ 10907570d59SYatharth Kochar sp805_stop(ARM_SP805_TWDG_BASE); 11007570d59SYatharth Kochar #endif 11107570d59SYatharth Kochar 11207570d59SYatharth Kochar juno_reset_to_aarch32_state(); 11307570d59SYatharth Kochar } 11407570d59SYatharth Kochar #endif /* JUNO_AARCH32_EL3_RUNTIME */ 115