xref: /rk3399_ARM-atf/plat/arm/common/arm_bl1_setup.c (revision 5fb061e761ee98d6ba1938d87efcc26a29ef0a87)
1 /*
2  * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 
9 #include <platform_def.h>
10 
11 #include <arch.h>
12 #include <bl1/bl1.h>
13 #include <common/bl_common.h>
14 #include <lib/fconf/fconf.h>
15 #include <lib/fconf/fconf_dyn_cfg_getter.h>
16 #include <lib/utils.h>
17 #include <lib/xlat_tables/xlat_tables_compat.h>
18 #include <plat/arm/common/plat_arm.h>
19 #include <plat/common/platform.h>
20 
21 /* Weak definitions may be overridden in specific ARM standard platform */
22 #pragma weak bl1_early_platform_setup
23 #pragma weak bl1_plat_arch_setup
24 #pragma weak bl1_plat_sec_mem_layout
25 #pragma weak arm_bl1_early_platform_setup
26 #pragma weak bl1_plat_prepare_exit
27 #pragma weak bl1_plat_get_next_image_id
28 #pragma weak plat_arm_bl1_fwu_needed
29 #pragma weak arm_bl1_plat_arch_setup
30 
31 #define MAP_BL1_TOTAL		MAP_REGION_FLAT(			\
32 					bl1_tzram_layout.total_base,	\
33 					bl1_tzram_layout.total_size,	\
34 					MT_MEMORY | MT_RW | MT_SECURE)
35 /*
36  * If SEPARATE_CODE_AND_RODATA=1 we define a region for each section
37  * otherwise one region is defined containing both
38  */
39 #if SEPARATE_CODE_AND_RODATA
40 #define MAP_BL1_RO		MAP_REGION_FLAT(			\
41 					BL_CODE_BASE,			\
42 					BL1_CODE_END - BL_CODE_BASE,	\
43 					MT_CODE | MT_SECURE),		\
44 				MAP_REGION_FLAT(			\
45 					BL1_RO_DATA_BASE,		\
46 					BL1_RO_DATA_END			\
47 						- BL_RO_DATA_BASE,	\
48 					MT_RO_DATA | MT_SECURE)
49 #else
50 #define MAP_BL1_RO		MAP_REGION_FLAT(			\
51 					BL_CODE_BASE,			\
52 					BL1_CODE_END - BL_CODE_BASE,	\
53 					MT_CODE | MT_SECURE)
54 #endif
55 
56 /* Data structure which holds the extents of the trusted SRAM for BL1*/
57 static meminfo_t bl1_tzram_layout;
58 
59 /* Boolean variable to hold condition whether firmware update needed or not */
60 static bool is_fwu_needed;
61 
62 struct meminfo *bl1_plat_sec_mem_layout(void)
63 {
64 	return &bl1_tzram_layout;
65 }
66 
67 /*******************************************************************************
68  * BL1 specific platform actions shared between ARM standard platforms.
69  ******************************************************************************/
70 void arm_bl1_early_platform_setup(void)
71 {
72 
73 #if !ARM_DISABLE_TRUSTED_WDOG
74 	/* Enable watchdog */
75 	plat_arm_secure_wdt_start();
76 #endif
77 
78 	/* Initialize the console to provide early debug support */
79 	arm_console_boot_init();
80 
81 	/* Allow BL1 to see the whole Trusted RAM */
82 	bl1_tzram_layout.total_base = ARM_BL_RAM_BASE;
83 	bl1_tzram_layout.total_size = ARM_BL_RAM_SIZE;
84 }
85 
86 void bl1_early_platform_setup(void)
87 {
88 	arm_bl1_early_platform_setup();
89 
90 	/*
91 	 * Initialize Interconnect for this cluster during cold boot.
92 	 * No need for locks as no other CPU is active.
93 	 */
94 	plat_arm_interconnect_init();
95 	/*
96 	 * Enable Interconnect coherency for the primary CPU's cluster.
97 	 */
98 	plat_arm_interconnect_enter_coherency();
99 }
100 
101 /******************************************************************************
102  * Perform the very early platform specific architecture setup shared between
103  * ARM standard platforms. This only does basic initialization. Later
104  * architectural setup (bl1_arch_setup()) does not do anything platform
105  * specific.
106  *****************************************************************************/
107 void arm_bl1_plat_arch_setup(void)
108 {
109 #if USE_COHERENT_MEM && !ARM_CRYPTOCELL_INTEG
110 	/*
111 	 * Ensure ARM platforms don't use coherent memory in BL1 unless
112 	 * cryptocell integration is enabled.
113 	 */
114 	assert((BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE) == 0U);
115 #endif
116 
117 	const mmap_region_t bl_regions[] = {
118 		MAP_BL1_TOTAL,
119 		MAP_BL1_RO,
120 #if USE_ROMLIB
121 		ARM_MAP_ROMLIB_CODE,
122 		ARM_MAP_ROMLIB_DATA,
123 #endif
124 #if ARM_CRYPTOCELL_INTEG
125 		ARM_MAP_BL_COHERENT_RAM,
126 #endif
127 		{0}
128 	};
129 
130 	setup_page_tables(bl_regions, plat_arm_get_mmap());
131 #ifdef __aarch64__
132 	enable_mmu_el3(0);
133 #else
134 	enable_mmu_svc_mon(0);
135 #endif /* __aarch64__ */
136 
137 	arm_setup_romlib();
138 }
139 
140 void bl1_plat_arch_setup(void)
141 {
142 	arm_bl1_plat_arch_setup();
143 }
144 
145 /*
146  * Perform the platform specific architecture setup shared between
147  * ARM standard platforms.
148  */
149 void arm_bl1_platform_setup(void)
150 {
151 	const struct dyn_cfg_dtb_info_t *fw_config_info;
152 	image_desc_t *desc;
153 	uint32_t fw_config_max_size;
154 	int err = -1;
155 
156 	/* Initialise the IO layer and register platform IO devices */
157 	plat_arm_io_setup();
158 
159 	/* Check if we need FWU before further processing */
160 	is_fwu_needed = plat_arm_bl1_fwu_needed();
161 	if (is_fwu_needed) {
162 		ERROR("Skip platform setup as FWU detected\n");
163 		return;
164 	}
165 
166 	/* Set global DTB info for fixed fw_config information */
167 	fw_config_max_size = ARM_FW_CONFIG_LIMIT - ARM_FW_CONFIG_BASE;
168 	set_config_info(ARM_FW_CONFIG_BASE, fw_config_max_size, FW_CONFIG_ID);
169 
170 	/* Fill the device tree information struct with the info from the config dtb */
171 	err = fconf_load_config(FW_CONFIG_ID);
172 	if (err < 0) {
173 		ERROR("Loading of FW_CONFIG failed %d\n", err);
174 		plat_error_handler(err);
175 	}
176 
177 	/*
178 	 * FW_CONFIG loaded successfully. If FW_CONFIG device tree parsing
179 	 * is successful then load TB_FW_CONFIG device tree.
180 	 */
181 	fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
182 	if (fw_config_info != NULL) {
183 		err = fconf_populate_dtb_registry(fw_config_info->config_addr);
184 		if (err < 0) {
185 			ERROR("Parsing of FW_CONFIG failed %d\n", err);
186 			plat_error_handler(err);
187 		}
188 		/* load TB_FW_CONFIG */
189 		err = fconf_load_config(TB_FW_CONFIG_ID);
190 		if (err < 0) {
191 			ERROR("Loading of TB_FW_CONFIG failed %d\n", err);
192 			plat_error_handler(err);
193 		}
194 	} else {
195 		ERROR("Invalid FW_CONFIG address\n");
196 		plat_error_handler(err);
197 	}
198 
199 	/* The BL2 ep_info arg0 is modified to point to FW_CONFIG */
200 	desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
201 	assert(desc != NULL);
202 	desc->ep_info.args.arg0 = fw_config_info->config_addr;
203 
204 #if TRUSTED_BOARD_BOOT
205 	/* Share the Mbed TLS heap info with other images */
206 	arm_bl1_set_mbedtls_heap();
207 #endif /* TRUSTED_BOARD_BOOT */
208 
209 	/*
210 	 * Allow access to the System counter timer module and program
211 	 * counter frequency for non secure images during FWU
212 	 */
213 #ifdef ARM_SYS_TIMCTL_BASE
214 	arm_configure_sys_timer();
215 #endif
216 #if (ARM_ARCH_MAJOR > 7) || defined(ARMV7_SUPPORTS_GENERIC_TIMER)
217 	write_cntfrq_el0(plat_get_syscnt_freq2());
218 #endif
219 }
220 
221 void bl1_plat_prepare_exit(entry_point_info_t *ep_info)
222 {
223 #if !ARM_DISABLE_TRUSTED_WDOG
224 	/* Disable watchdog before leaving BL1 */
225 	plat_arm_secure_wdt_stop();
226 #endif
227 
228 #ifdef EL3_PAYLOAD_BASE
229 	/*
230 	 * Program the EL3 payload's entry point address into the CPUs mailbox
231 	 * in order to release secondary CPUs from their holding pen and make
232 	 * them jump there.
233 	 */
234 	plat_arm_program_trusted_mailbox(ep_info->pc);
235 	dsbsy();
236 	sev();
237 #endif
238 }
239 
240 /*
241  * On Arm platforms, the FWU process is triggered when the FIP image has
242  * been tampered with.
243  */
244 bool plat_arm_bl1_fwu_needed(void)
245 {
246 	return !arm_io_is_toc_valid();
247 }
248 
249 /*******************************************************************************
250  * The following function checks if Firmware update is needed,
251  * by checking if TOC in FIP image is valid or not.
252  ******************************************************************************/
253 unsigned int bl1_plat_get_next_image_id(void)
254 {
255 	return  is_fwu_needed ? NS_BL1U_IMAGE_ID : BL2_IMAGE_ID;
256 }
257