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