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> 15*b0c97dafSAditya Angadi #include <plat/arm/common/arm_def.h> 1609d40e0eSAntonio Nino Diaz #include <plat/common/platform.h> 17234bc7f8SAntonio Nino Diaz #include <platform_def.h> 1809d40e0eSAntonio Nino Diaz 1907570d59SYatharth Kochar void juno_reset_to_aarch32_state(void); 2007570d59SYatharth Kochar 214da6f6cdSSathees Balya static int is_watchdog_reset(void) 224da6f6cdSSathees Balya { 234da6f6cdSSathees Balya #if !CSS_USE_SCMI_SDS_DRIVER 244da6f6cdSSathees Balya #define RESET_REASON_WDOG_RESET (0x2) 254da6f6cdSSathees Balya const uint32_t *reset_flags_ptr = (const uint32_t *)SSC_GPRETN; 264da6f6cdSSathees Balya 274da6f6cdSSathees Balya if ((*reset_flags_ptr & RESET_REASON_WDOG_RESET) != 0) 284da6f6cdSSathees Balya return 1; 294da6f6cdSSathees Balya 304da6f6cdSSathees Balya return 0; 314da6f6cdSSathees Balya #else 324da6f6cdSSathees Balya int ret; 334da6f6cdSSathees Balya uint32_t scp_reset_synd_flags; 344da6f6cdSSathees Balya 354da6f6cdSSathees Balya ret = sds_init(); 364da6f6cdSSathees Balya if (ret != SDS_OK) { 374da6f6cdSSathees Balya ERROR("SCP SDS initialization failed\n"); 384da6f6cdSSathees Balya panic(); 394da6f6cdSSathees Balya } 404da6f6cdSSathees Balya 414da6f6cdSSathees Balya ret = sds_struct_read(SDS_RESET_SYNDROME_STRUCT_ID, 424da6f6cdSSathees Balya SDS_RESET_SYNDROME_OFFSET, 434da6f6cdSSathees Balya &scp_reset_synd_flags, 444da6f6cdSSathees Balya SDS_RESET_SYNDROME_SIZE, 454da6f6cdSSathees Balya SDS_ACCESS_MODE_NON_CACHED); 464da6f6cdSSathees Balya if (ret != SDS_OK) { 474da6f6cdSSathees Balya ERROR("Getting reset reason from SDS failed\n"); 484da6f6cdSSathees Balya panic(); 494da6f6cdSSathees Balya } 504da6f6cdSSathees Balya 514da6f6cdSSathees Balya /* Check if the WATCHDOG_RESET_BIT is set in the reset syndrome */ 524da6f6cdSSathees Balya if (scp_reset_synd_flags & SDS_RESET_SYNDROME_AP_WD_RESET_BIT) 534da6f6cdSSathees Balya return 1; 544da6f6cdSSathees Balya 554da6f6cdSSathees Balya return 0; 564da6f6cdSSathees Balya #endif 574da6f6cdSSathees Balya } 584da6f6cdSSathees Balya 594da6f6cdSSathees Balya /******************************************************************************* 604da6f6cdSSathees Balya * The following function checks if Firmware update is needed, 614da6f6cdSSathees Balya * by checking if TOC in FIP image is valid or watchdog reset happened. 624da6f6cdSSathees Balya ******************************************************************************/ 634da6f6cdSSathees Balya int plat_arm_bl1_fwu_needed(void) 644da6f6cdSSathees Balya { 65bde2836fSAmbroise Vincent const int32_t *nv_flags_ptr = (const int32_t *)V2M_SYS_NVFLAGS_ADDR; 664da6f6cdSSathees Balya 674da6f6cdSSathees Balya /* Check if TOC is invalid or watchdog reset happened. */ 684da6f6cdSSathees Balya if ((arm_io_is_toc_valid() != 1) || 694da6f6cdSSathees Balya (((*nv_flags_ptr == -EAUTH) || (*nv_flags_ptr == -ENOENT)) 704da6f6cdSSathees Balya && is_watchdog_reset())) 714da6f6cdSSathees Balya return 1; 724da6f6cdSSathees Balya 734da6f6cdSSathees Balya return 0; 744da6f6cdSSathees Balya } 754da6f6cdSSathees Balya 76436223deSYatharth Kochar /******************************************************************************* 77436223deSYatharth Kochar * On JUNO update the arg2 with address of SCP_BL2U image info. 78436223deSYatharth Kochar ******************************************************************************/ 79436223deSYatharth Kochar void bl1_plat_set_ep_info(unsigned int image_id, 80436223deSYatharth Kochar entry_point_info_t *ep_info) 81436223deSYatharth Kochar { 82436223deSYatharth Kochar if (image_id == BL2U_IMAGE_ID) { 83436223deSYatharth Kochar image_desc_t *image_desc = bl1_plat_get_image_desc(SCP_BL2U_IMAGE_ID); 84436223deSYatharth Kochar ep_info->args.arg2 = (unsigned long)&image_desc->image_info; 85436223deSYatharth Kochar } 86436223deSYatharth Kochar } 87436223deSYatharth Kochar 88436223deSYatharth Kochar /******************************************************************************* 89436223deSYatharth Kochar * On Juno clear SYS_NVFLAGS and wait for watchdog reset. 90436223deSYatharth Kochar ******************************************************************************/ 911f37b944SDan Handley __dead2 void bl1_plat_fwu_done(void *client_cookie, void *reserved) 92436223deSYatharth Kochar { 93436223deSYatharth Kochar unsigned int *nv_flags_clr = (unsigned int *) 94436223deSYatharth Kochar (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGSCLR); 95436223deSYatharth Kochar unsigned int *nv_flags_ptr = (unsigned int *) 96436223deSYatharth Kochar (V2M_SYSREGS_BASE + V2M_SYS_NVFLAGS); 97436223deSYatharth Kochar 98436223deSYatharth Kochar /* Clear the NV flags register. */ 99436223deSYatharth Kochar *nv_flags_clr = *nv_flags_ptr; 100436223deSYatharth Kochar 101436223deSYatharth Kochar while (1) 102436223deSYatharth Kochar wfi(); 103436223deSYatharth Kochar } 10407570d59SYatharth Kochar 10507570d59SYatharth Kochar #if JUNO_AARCH32_EL3_RUNTIME 10607570d59SYatharth Kochar void bl1_plat_prepare_exit(entry_point_info_t *ep_info) 10707570d59SYatharth Kochar { 10807570d59SYatharth Kochar #if !ARM_DISABLE_TRUSTED_WDOG 10907570d59SYatharth Kochar /* Disable watchdog before leaving BL1 */ 11007570d59SYatharth Kochar sp805_stop(ARM_SP805_TWDG_BASE); 11107570d59SYatharth Kochar #endif 11207570d59SYatharth Kochar 11307570d59SYatharth Kochar juno_reset_to_aarch32_state(); 11407570d59SYatharth Kochar } 11507570d59SYatharth Kochar #endif /* JUNO_AARCH32_EL3_RUNTIME */ 116*b0c97dafSAditya Angadi 117*b0c97dafSAditya Angadi void plat_arm_secure_wdt_start(void) 118*b0c97dafSAditya Angadi { 119*b0c97dafSAditya Angadi sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL); 120*b0c97dafSAditya Angadi } 121*b0c97dafSAditya Angadi 122*b0c97dafSAditya Angadi void plat_arm_secure_wdt_stop(void) 123*b0c97dafSAditya Angadi { 124*b0c97dafSAditya Angadi sp805_stop(ARM_SP805_TWDG_BASE); 125*b0c97dafSAditya Angadi } 126