blob: d89ad7b94b329f6e29d71e0252a446b4d808f2db [file] [log] [blame]
Varun Wadekarb316e242015-05-19 16:48:04 +05301/*
Varun Wadekar3fb854f2017-02-28 08:23:59 -08002 * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
Varun Wadekarb316e242015-05-19 16:48:04 +05303 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Varun Wadekarb316e242015-05-19 16:48:04 +05305 */
6
7#include <arch.h>
8#include <arch_helpers.h>
9#include <assert.h>
10#include <bl31.h>
11#include <bl_common.h>
12#include <console.h>
Varun Wadekarb316e242015-05-19 16:48:04 +053013#include <cortex_a53.h>
Isla Mitchelle3631462017-07-14 10:46:32 +010014#include <cortex_a57.h>
Varun Wadekarb316e242015-05-19 16:48:04 +053015#include <debug.h>
Varun Wadekarbaf903e2015-09-22 15:00:06 +053016#include <denver.h>
Varun Wadekar7a269e22015-06-10 14:04:32 +053017#include <errno.h>
Varun Wadekarb316e242015-05-19 16:48:04 +053018#include <memctrl.h>
19#include <mmio.h>
20#include <platform.h>
21#include <platform_def.h>
22#include <stddef.h>
Varun Wadekarb41a4142016-05-23 15:56:14 -070023#include <string.h>
Varun Wadekar0dc91812015-12-30 15:06:41 -080024#include <tegra_def.h>
Varun Wadekarb316e242015-05-19 16:48:04 +053025#include <tegra_private.h>
26
Arve Hjønnevåg8f539492018-02-21 17:36:44 -080027/* length of Trusty's input parameters (in bytes) */
28#define TRUSTY_PARAMS_LEN_BYTES (4096*2)
29
Varun Wadekarb41a4142016-05-23 15:56:14 -070030extern void zeromem16(void *mem, unsigned int length);
31
Varun Wadekarb316e242015-05-19 16:48:04 +053032/*******************************************************************************
33 * Declarations of linker defined symbols which will help us find the layout
34 * of trusted SRAM
35 ******************************************************************************/
Varun Wadekar3fb854f2017-02-28 08:23:59 -080036extern unsigned long __TEXT_START__;
37extern unsigned long __TEXT_END__;
38extern unsigned long __RW_START__;
39extern unsigned long __RW_END__;
40extern unsigned long __RODATA_START__;
41extern unsigned long __RODATA_END__;
Varun Wadekarb316e242015-05-19 16:48:04 +053042extern unsigned long __BL31_END__;
43
Varun Wadekarb316e242015-05-19 16:48:04 +053044extern uint64_t tegra_bl31_phys_base;
Varun Wadekard2014c62015-10-29 10:37:28 +053045extern uint64_t tegra_console_base;
Varun Wadekarb316e242015-05-19 16:48:04 +053046
47/*
48 * The next 3 constants identify the extents of the code, RO data region and the
49 * limit of the BL3-1 image. These addresses are used by the MMU setup code and
50 * therefore they must be page-aligned. It is the responsibility of the linker
51 * script to ensure that __RO_START__, __RO_END__ & __BL31_END__ linker symbols
52 * refer to page-aligned addresses.
53 */
Varun Wadekar3fb854f2017-02-28 08:23:59 -080054#define BL31_RW_START (unsigned long)(&__RW_START__)
55#define BL31_RW_END (unsigned long)(&__RW_END__)
56#define BL31_RODATA_BASE (unsigned long)(&__RODATA_START__)
57#define BL31_RODATA_END (unsigned long)(&__RODATA_END__)
Varun Wadekarb316e242015-05-19 16:48:04 +053058#define BL31_END (unsigned long)(&__BL31_END__)
59
Varun Wadekar52a15982015-06-05 12:57:27 +053060static entry_point_info_t bl33_image_ep_info, bl32_image_ep_info;
Varun Wadekarb316e242015-05-19 16:48:04 +053061static plat_params_from_bl2_t plat_bl31_params_from_bl2 = {
Varun Wadekarc8bfe2e2015-07-31 10:03:01 +053062 .tzdram_size = (uint64_t)TZDRAM_SIZE
Varun Wadekarb316e242015-05-19 16:48:04 +053063};
Arve Hjønnevåg8f539492018-02-21 17:36:44 -080064static unsigned long bl32_mem_size;
65static unsigned long bl32_boot_params;
Varun Wadekarb316e242015-05-19 16:48:04 +053066
67/*******************************************************************************
68 * This variable holds the non-secure image entry address
69 ******************************************************************************/
70extern uint64_t ns_image_entrypoint;
71
72/*******************************************************************************
Varun Wadekar3f0a8ad2016-03-28 15:56:47 -070073 * The following platform setup functions are weakly defined. They
74 * provide typical implementations that will be overridden by a SoC.
75 ******************************************************************************/
76#pragma weak plat_early_platform_setup
Varun Wadekard22d4ad2016-05-23 11:41:07 -070077#pragma weak plat_get_bl31_params
78#pragma weak plat_get_bl31_plat_params
Varun Wadekar3f0a8ad2016-03-28 15:56:47 -070079
80void plat_early_platform_setup(void)
81{
82 ; /* do nothing */
83}
84
Varun Wadekard22d4ad2016-05-23 11:41:07 -070085bl31_params_t *plat_get_bl31_params(void)
86{
87 return NULL;
88}
89
90plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
91{
92 return NULL;
93}
94
Varun Wadekar3f0a8ad2016-03-28 15:56:47 -070095/*******************************************************************************
Varun Wadekarb316e242015-05-19 16:48:04 +053096 * Return a pointer to the 'entry_point_info' structure of the next image for
97 * security state specified. BL33 corresponds to the non-secure image type
98 * while BL32 corresponds to the secure image type.
99 ******************************************************************************/
100entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
101{
102 if (type == NON_SECURE)
103 return &bl33_image_ep_info;
104
Varun Wadekar197a75f2016-06-06 10:46:28 -0700105 /* return BL32 entry point info if it is valid */
106 if (type == SECURE && bl32_image_ep_info.pc)
Varun Wadekar52a15982015-06-05 12:57:27 +0530107 return &bl32_image_ep_info;
108
Varun Wadekarb316e242015-05-19 16:48:04 +0530109 return NULL;
110}
111
112/*******************************************************************************
113 * Return a pointer to the 'plat_params_from_bl2_t' structure. The BL2 image
114 * passes this platform specific information.
115 ******************************************************************************/
116plat_params_from_bl2_t *bl31_get_plat_params(void)
117{
118 return &plat_bl31_params_from_bl2;
119}
120
121/*******************************************************************************
122 * Perform any BL31 specific platform actions. Populate the BL33 and BL32 image
123 * info.
124 ******************************************************************************/
125void bl31_early_platform_setup(bl31_params_t *from_bl2,
126 void *plat_params_from_bl2)
127{
128 plat_params_from_bl2_t *plat_params =
129 (plat_params_from_bl2_t *)plat_params_from_bl2;
Soren Brinkmannf9ce0f02017-06-07 09:51:26 -0700130#if LOG_LEVEL >= LOG_LEVEL_INFO
Varun Wadekarbaf903e2015-09-22 15:00:06 +0530131 int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
132#endif
Varun Wadekarb41a4142016-05-23 15:56:14 -0700133 image_info_t bl32_img_info = { {0} };
134 uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end;
Varun Wadekarbaf903e2015-09-22 15:00:06 +0530135
Varun Wadekarb316e242015-05-19 16:48:04 +0530136 /*
Varun Wadekard22d4ad2016-05-23 11:41:07 -0700137 * For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
138 * there's no argument to relay from a previous bootloader. Platforms
139 * might use custom ways to get arguments, so provide handlers which
140 * they can override.
141 */
142 if (from_bl2 == NULL)
143 from_bl2 = plat_get_bl31_params();
144 if (plat_params == NULL)
145 plat_params = plat_get_bl31_plat_params();
146
147 /*
Varun Wadekar52a15982015-06-05 12:57:27 +0530148 * Copy BL3-3, BL3-2 entry point information.
Varun Wadekarb316e242015-05-19 16:48:04 +0530149 * They are stored in Secure RAM, in BL2's address space.
150 */
Varun Wadekard22d4ad2016-05-23 11:41:07 -0700151 assert(from_bl2);
Varun Wadekar6bb62462015-10-06 12:49:31 +0530152 assert(from_bl2->bl33_ep_info);
153 bl33_image_ep_info = *from_bl2->bl33_ep_info;
Varun Wadekarbaf903e2015-09-22 15:00:06 +0530154
Arve Hjønnevåg8f539492018-02-21 17:36:44 -0800155 if (from_bl2->bl32_ep_info) {
Varun Wadekarbaf903e2015-09-22 15:00:06 +0530156 bl32_image_ep_info = *from_bl2->bl32_ep_info;
Arve Hjønnevåg8f539492018-02-21 17:36:44 -0800157 bl32_mem_size = from_bl2->bl32_ep_info->args.arg0;
158 bl32_boot_params = from_bl2->bl32_ep_info->args.arg2;
159 }
Varun Wadekarb316e242015-05-19 16:48:04 +0530160
161 /*
Varun Wadekar6bb62462015-10-06 12:49:31 +0530162 * Parse platform specific parameters - TZDRAM aperture base and size
Varun Wadekarb316e242015-05-19 16:48:04 +0530163 */
Varun Wadekar6bb62462015-10-06 12:49:31 +0530164 assert(plat_params);
165 plat_bl31_params_from_bl2.tzdram_base = plat_params->tzdram_base;
166 plat_bl31_params_from_bl2.tzdram_size = plat_params->tzdram_size;
Varun Wadekard2014c62015-10-29 10:37:28 +0530167 plat_bl31_params_from_bl2.uart_id = plat_params->uart_id;
168
169 /*
Varun Wadekar1ec441e2016-03-24 15:34:24 -0700170 * It is very important that we run either from TZDRAM or TZSRAM base.
171 * Add an explicit check here.
172 */
173 if ((plat_bl31_params_from_bl2.tzdram_base != BL31_BASE) &&
174 (TEGRA_TZRAM_BASE != BL31_BASE))
175 panic();
176
177 /*
Varun Wadekard2014c62015-10-29 10:37:28 +0530178 * Get the base address of the UART controller to be used for the
179 * console
180 */
Varun Wadekard2014c62015-10-29 10:37:28 +0530181 tegra_console_base = plat_get_console_from_id(plat_params->uart_id);
182
Damon Duan777baa52016-11-07 19:37:50 +0800183 if (tegra_console_base != (uint64_t)0) {
184 /*
185 * Configure the UART port to be used as the console
186 */
187 console_init(tegra_console_base, TEGRA_BOOT_UART_CLK_IN_HZ,
188 TEGRA_CONSOLE_BAUDRATE);
Damon Duan777baa52016-11-07 19:37:50 +0800189 }
Varun Wadekard2014c62015-10-29 10:37:28 +0530190
Varun Wadekar5118b532016-06-04 22:08:50 -0700191 /*
Steven Kao27e64312016-10-21 14:16:59 +0800192 * Initialize delay timer
193 */
194 tegra_delay_timer_init();
195
196 /*
Varun Wadekar5118b532016-06-04 22:08:50 -0700197 * Do initial security configuration to allow DRAM/device access.
198 */
199 tegra_memctrl_tzdram_setup(plat_bl31_params_from_bl2.tzdram_base,
200 plat_bl31_params_from_bl2.tzdram_size);
201
Varun Wadekarb41a4142016-05-23 15:56:14 -0700202 /*
203 * The previous bootloader might not have placed the BL32 image
204 * inside the TZDRAM. We check the BL32 image info to find out
205 * the base/PC values and relocate the image if necessary.
206 */
207 if (from_bl2->bl32_image_info) {
208
209 bl32_img_info = *from_bl2->bl32_image_info;
210
211 /* Relocate BL32 if it resides outside of the TZDRAM */
212 tzdram_start = plat_bl31_params_from_bl2.tzdram_base;
213 tzdram_end = plat_bl31_params_from_bl2.tzdram_base +
214 plat_bl31_params_from_bl2.tzdram_size;
215 bl32_start = bl32_img_info.image_base;
216 bl32_end = bl32_img_info.image_base + bl32_img_info.image_size;
217
218 assert(tzdram_end > tzdram_start);
219 assert(bl32_end > bl32_start);
220 assert(bl32_image_ep_info.pc > tzdram_start);
221 assert(bl32_image_ep_info.pc < tzdram_end);
222
223 /* relocate BL32 */
224 if (bl32_start >= tzdram_end || bl32_end <= tzdram_start) {
225
226 INFO("Relocate BL32 to TZDRAM\n");
227
228 memcpy16((void *)(uintptr_t)bl32_image_ep_info.pc,
229 (void *)(uintptr_t)bl32_start,
230 bl32_img_info.image_size);
231
232 /* clean up non-secure intermediate buffer */
233 zeromem16((void *)(uintptr_t)bl32_start,
234 bl32_img_info.image_size);
235 }
236 }
237
Varun Wadekar3f0a8ad2016-03-28 15:56:47 -0700238 /* Early platform setup for Tegra SoCs */
239 plat_early_platform_setup();
240
Varun Wadekard2014c62015-10-29 10:37:28 +0530241 INFO("BL3-1: Boot CPU: %s Processor [%lx]\n", (impl == DENVER_IMPL) ?
242 "Denver" : "ARM", read_mpidr());
Varun Wadekarb316e242015-05-19 16:48:04 +0530243}
Arve Hjønnevåg8f539492018-02-21 17:36:44 -0800244
245#ifdef SPD_trusty
246void plat_trusty_set_boot_args(aapcs64_params_t *args)
247{
248 args->arg0 = bl32_mem_size;
249 args->arg1 = bl32_boot_params;
250 args->arg2 = TRUSTY_PARAMS_LEN_BYTES;
251}
252#endif
Varun Wadekarb316e242015-05-19 16:48:04 +0530253
254/*******************************************************************************
255 * Initialize the gic, configure the SCR.
256 ******************************************************************************/
257void bl31_platform_setup(void)
258{
259 uint32_t tmp_reg;
260
Varun Wadekarb7b45752015-12-28 14:55:41 -0800261 /* Initialize the gic cpu and distributor interfaces */
262 plat_gic_setup();
263
Varun Wadekarb316e242015-05-19 16:48:04 +0530264 /*
265 * Setup secondary CPU POR infrastructure.
266 */
267 plat_secondary_setup();
268
269 /*
270 * Initial Memory Controller configuration.
271 */
272 tegra_memctrl_setup();
273
274 /*
Varun Wadekar0dc91812015-12-30 15:06:41 -0800275 * Set up the TZRAM memory aperture to allow only secure world
276 * access
277 */
278 tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE);
279
Varun Wadekarb316e242015-05-19 16:48:04 +0530280 /* Set the next EL to be AArch64 */
281 tmp_reg = SCR_RES1_BITS | SCR_RW_BIT;
282 write_scr(tmp_reg);
283
Varun Wadekarbaf903e2015-09-22 15:00:06 +0530284 INFO("BL3-1: Tegra platform setup complete\n");
Varun Wadekarb316e242015-05-19 16:48:04 +0530285}
286
287/*******************************************************************************
Varun Wadekar1dcffa92016-01-08 17:48:42 -0800288 * Perform any BL3-1 platform runtime setup prior to BL3-1 cold boot exit
289 ******************************************************************************/
290void bl31_plat_runtime_setup(void)
291{
Varun Wadekarc92050b2017-03-29 14:57:29 -0700292 /*
293 * During boot, USB3 and flash media (SDMMC/SATA) devices need
294 * access to IRAM. Because these clients connect to the MC and
295 * do not have a direct path to the IRAM, the MC implements AHB
296 * redirection during boot to allow path to IRAM. In this mode
297 * accesses to a programmed memory address aperture are directed
298 * to the AHB bus, allowing access to the IRAM. This mode must be
299 * disabled before we jump to the non-secure world.
300 */
301 tegra_memctrl_disable_ahb_redirection();
Varun Wadekar1dcffa92016-01-08 17:48:42 -0800302}
303
304/*******************************************************************************
Varun Wadekarb316e242015-05-19 16:48:04 +0530305 * Perform the very early platform specific architectural setup here. At the
306 * moment this only intializes the mmu in a quick and dirty way.
307 ******************************************************************************/
308void bl31_plat_arch_setup(void)
309{
Varun Wadekar3fb854f2017-02-28 08:23:59 -0800310 unsigned long rw_start = BL31_RW_START;
311 unsigned long rw_size = BL31_RW_END - BL31_RW_START;
312 unsigned long rodata_start = BL31_RODATA_BASE;
313 unsigned long rodata_size = BL31_RODATA_END - BL31_RODATA_BASE;
314 unsigned long code_base = (unsigned long)(&__TEXT_START__);
315 unsigned long code_size = (unsigned long)(&__TEXT_END__) - code_base;
Varun Wadekarb316e242015-05-19 16:48:04 +0530316 const mmap_region_t *plat_mmio_map = NULL;
Varun Wadekarb316e242015-05-19 16:48:04 +0530317#if USE_COHERENT_MEM
Varun Wadekar207cc732015-07-08 12:57:50 +0530318 unsigned long coh_start, coh_size;
Varun Wadekarb316e242015-05-19 16:48:04 +0530319#endif
Varun Wadekard1513632016-03-18 13:01:12 -0700320 plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
Varun Wadekarb316e242015-05-19 16:48:04 +0530321
322 /* add memory regions */
Varun Wadekar3fb854f2017-02-28 08:23:59 -0800323 mmap_add_region(rw_start, rw_start,
324 rw_size,
Varun Wadekarb316e242015-05-19 16:48:04 +0530325 MT_MEMORY | MT_RW | MT_SECURE);
Varun Wadekar3fb854f2017-02-28 08:23:59 -0800326 mmap_add_region(rodata_start, rodata_start,
327 rodata_size,
328 MT_RO_DATA | MT_SECURE);
329 mmap_add_region(code_base, code_base,
330 code_size,
331 MT_CODE | MT_SECURE);
Varun Wadekar207cc732015-07-08 12:57:50 +0530332
Varun Wadekard1513632016-03-18 13:01:12 -0700333 /* map TZDRAM used by BL31 as coherent memory */
334 if (TEGRA_TZRAM_BASE == tegra_bl31_phys_base) {
335 mmap_add_region(params_from_bl2->tzdram_base,
336 params_from_bl2->tzdram_base,
337 BL31_SIZE,
338 MT_DEVICE | MT_RW | MT_SECURE);
339 }
340
Varun Wadekarb316e242015-05-19 16:48:04 +0530341#if USE_COHERENT_MEM
Masahiro Yamada0fac5af2016-12-28 16:11:41 +0900342 coh_start = total_base + (BL_COHERENT_RAM_BASE - BL31_RO_BASE);
343 coh_size = BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE;
Varun Wadekar207cc732015-07-08 12:57:50 +0530344
Varun Wadekarb316e242015-05-19 16:48:04 +0530345 mmap_add_region(coh_start, coh_start,
346 coh_size,
347 MT_DEVICE | MT_RW | MT_SECURE);
348#endif
349
Steven Kao4d160ac2016-12-23 16:05:13 +0800350 /* map on-chip free running uS timer */
351 mmap_add_region(page_align((uint64_t)TEGRA_TMRUS_BASE, 0),
352 page_align((uint64_t)TEGRA_TMRUS_BASE, 0),
353 (uint64_t)TEGRA_TMRUS_SIZE,
354 MT_DEVICE | MT_RO | MT_SECURE);
355
Varun Wadekarb316e242015-05-19 16:48:04 +0530356 /* add MMIO space */
357 plat_mmio_map = plat_get_mmio_map();
358 if (plat_mmio_map)
359 mmap_add(plat_mmio_map);
360 else
361 WARN("MMIO map not available\n");
362
363 /* set up translation tables */
364 init_xlat_tables();
365
366 /* enable the MMU */
367 enable_mmu_el3(0);
Varun Wadekarbaf903e2015-09-22 15:00:06 +0530368
369 INFO("BL3-1: Tegra: MMU enabled\n");
Varun Wadekarb316e242015-05-19 16:48:04 +0530370}
Varun Wadekar7a269e22015-06-10 14:04:32 +0530371
372/*******************************************************************************
373 * Check if the given NS DRAM range is valid
374 ******************************************************************************/
375int bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes)
376{
Varun Wadekar55902982017-01-25 13:35:27 -0800377 uint64_t end = base + size_in_bytes;
Varun Wadekar7a269e22015-06-10 14:04:32 +0530378
379 /*
380 * Check if the NS DRAM address is valid
381 */
Varun Wadekar55902982017-01-25 13:35:27 -0800382 if ((base < TEGRA_DRAM_BASE) || (end > TEGRA_DRAM_END)) {
Varun Wadekar7a269e22015-06-10 14:04:32 +0530383 ERROR("NS address is out-of-bounds!\n");
384 return -EFAULT;
385 }
386
387 /*
388 * TZDRAM aperture contains the BL31 and BL32 images, so we need
389 * to check if the NS DRAM range overlaps the TZDRAM aperture.
390 */
391 if ((base < TZDRAM_END) && (end > tegra_bl31_phys_base)) {
392 ERROR("NS address overlaps TZDRAM!\n");
393 return -ENOTSUP;
394 }
395
396 /* valid NS address */
397 return 0;
398}