blob: 177630b0359fce4be4299934b348d9c0a39dfb41 [file] [log] [blame]
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +02001/*
2 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch_helpers.h>
8#include <assert.h>
9#include <bl_common.h>
10#include <console.h>
11#include <debug.h>
Victor Chong175dd8a2018-02-01 00:35:22 +090012#include <desc_image_load.h>
Victor Chong539408d2018-01-03 01:53:08 +090013#include <dw_mmc.h>
14#include <emmc.h>
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020015#include <errno.h>
16#include <generic_delay_timer.h>
17#include <mmio.h>
Victor Chongaa033472018-02-01 00:35:39 +090018#include <optee_utils.h>
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020019#include <partition/partition.h>
20#include <platform.h>
21#include <string.h>
22#include "hi3798cv200.h"
23#include "plat_private.h"
24
25/* Memory ranges for code and read only data sections */
26#define BL2_RO_BASE (unsigned long)(&__RO_START__)
27#define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
28
29/* Memory ranges for coherent memory section */
30#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
31#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
32
Victor Chong175dd8a2018-02-01 00:35:22 +090033static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
34
35#if !LOAD_IMAGE_V2
36
37/*******************************************************************************
38 * This structure represents the superset of information that is passed to
39 * BL31, e.g. while passing control to it from BL2, bl31_params
40 * and other platform specific params
41 ******************************************************************************/
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020042typedef struct bl2_to_bl31_params_mem {
43 bl31_params_t bl31_params;
44 image_info_t bl31_image_info;
Victor Chong662556a2017-10-28 01:59:41 +090045 image_info_t bl32_image_info;
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020046 image_info_t bl33_image_info;
47 entry_point_info_t bl33_ep_info;
Victor Chong662556a2017-10-28 01:59:41 +090048 entry_point_info_t bl32_ep_info;
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020049 entry_point_info_t bl31_ep_info;
50} bl2_to_bl31_params_mem_t;
51
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020052static bl2_to_bl31_params_mem_t bl31_params_mem;
53
54meminfo_t *bl2_plat_sec_mem_layout(void)
55{
56 return &bl2_tzram_layout;
57}
Victor Chong175dd8a2018-02-01 00:35:22 +090058
59#ifdef SCP_BL2_BASE
60void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo)
61{
62 /*
63 * This platform has no SCP_BL2 yet
64 */
65}
66#endif
67#endif /* LOAD_IMAGE_V2 */
68
69/*******************************************************************************
70 * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol.
71 * Return 0 on success, -1 otherwise.
72 ******************************************************************************/
73#if LOAD_IMAGE_V2
74int plat_poplar_bl2_handle_scp_bl2(image_info_t *scp_bl2_image_info)
75#else
76int bl2_plat_handle_scp_bl2(struct image_info *scp_bl2_image_info)
77#endif
78{
79 /*
80 * This platform has no SCP_BL2 yet
81 */
82 return 0;
83}
84
85/*******************************************************************************
86 * Gets SPSR for BL32 entry
87 ******************************************************************************/
88uint32_t poplar_get_spsr_for_bl32_entry(void)
89{
90 /*
91 * The Secure Payload Dispatcher service is responsible for
92 * setting the SPSR prior to entry into the BL3-2 image.
93 */
94 return 0;
95}
96
97/*******************************************************************************
98 * Gets SPSR for BL33 entry
99 ******************************************************************************/
100#ifndef AARCH32
101uint32_t poplar_get_spsr_for_bl33_entry(void)
102{
103 unsigned long el_status;
104 unsigned int mode;
105 uint32_t spsr;
106
107 /* Figure out what mode we enter the non-secure world in */
108 el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
109 el_status &= ID_AA64PFR0_ELX_MASK;
110
111 mode = (el_status) ? MODE_EL2 : MODE_EL1;
112
113 /*
114 * TODO: Consider the possibility of specifying the SPSR in
115 * the FIP ToC and allowing the platform to have a say as
116 * well.
117 */
118 spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
119 return spsr;
120}
121#else
122uint32_t poplar_get_spsr_for_bl33_entry(void)
123{
124 unsigned int hyp_status, mode, spsr;
125
126 hyp_status = GET_VIRT_EXT(read_id_pfr1());
127
128 mode = (hyp_status) ? MODE32_hyp : MODE32_svc;
129
130 /*
131 * TODO: Consider the possibility of specifying the SPSR in
132 * the FIP ToC and allowing the platform to have a say as
133 * well.
134 */
135 spsr = SPSR_MODE32(mode, plat_get_ns_image_entrypoint() & 0x1,
136 SPSR_E_LITTLE, DISABLE_ALL_EXCEPTIONS);
137 return spsr;
138}
139#endif /* AARCH32 */
140
141#if LOAD_IMAGE_V2
142int poplar_bl2_handle_post_image_load(unsigned int image_id)
143{
144 int err = 0;
145 bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
Victor Chongaa033472018-02-01 00:35:39 +0900146#ifdef SPD_opteed
147 bl_mem_params_node_t *pager_mem_params = NULL;
148 bl_mem_params_node_t *paged_mem_params = NULL;
149#endif
Victor Chong175dd8a2018-02-01 00:35:22 +0900150
151 assert(bl_mem_params);
152
153 switch (image_id) {
154#ifdef AARCH64
155 case BL32_IMAGE_ID:
Victor Chongaa033472018-02-01 00:35:39 +0900156#ifdef SPD_opteed
157 pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
158 assert(pager_mem_params);
159
160 paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
161 assert(paged_mem_params);
162
163 err = parse_optee_header(&bl_mem_params->ep_info,
164 &pager_mem_params->image_info,
165 &paged_mem_params->image_info);
166 if (err != 0) {
167 WARN("OPTEE header parse error.\n");
168 }
169
170 /*
171 * OP-TEE expect to receive DTB address in x2.
172 * This will be copied into x2 by dispatcher.
173 * Set this (arg3) if necessary
174 */
175 /* bl_mem_params->ep_info.args.arg3 = PLAT_HIKEY_DT_BASE; */
176#endif
Victor Chong175dd8a2018-02-01 00:35:22 +0900177 bl_mem_params->ep_info.spsr = poplar_get_spsr_for_bl32_entry();
178 break;
179#endif
180
181 case BL33_IMAGE_ID:
182 /* BL33 expects to receive the primary CPU MPID (through r0) */
183 bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr();
184 bl_mem_params->ep_info.spsr = poplar_get_spsr_for_bl33_entry();
185 break;
186
187#ifdef SCP_BL2_BASE
188 case SCP_BL2_IMAGE_ID:
189 /* The subsequent handling of SCP_BL2 is platform specific */
190 err = plat_poplar_bl2_handle_scp_bl2(&bl_mem_params->image_info);
191 if (err) {
192 WARN("Failure in platform-specific handling of SCP_BL2 image.\n");
193 }
194 break;
195#endif
196 }
197
198 return err;
199}
200
201/*******************************************************************************
202 * This function can be used by the platforms to update/use image
203 * information for given `image_id`.
204 ******************************************************************************/
205int bl2_plat_handle_post_image_load(unsigned int image_id)
206{
207 return poplar_bl2_handle_post_image_load(image_id);
208}
209
210#else /* LOAD_IMAGE_V2 */
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200211
212bl31_params_t *bl2_plat_get_bl31_params(void)
213{
214 bl31_params_t *bl2_to_bl31_params = NULL;
215
216 /*
217 * Initialise the memory for all the arguments that needs to
218 * be passed to BL3-1
219 */
220 memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
221
222 /* Assign memory for TF related information */
223 bl2_to_bl31_params = &bl31_params_mem.bl31_params;
224 SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
225
226 /* Fill BL3-1 related information */
227 bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
228 SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info,
229 PARAM_IMAGE_BINARY, VERSION_1, 0);
230
Victor Chong662556a2017-10-28 01:59:41 +0900231 /* Fill BL3-2 related information if it exists */
232#ifdef BL32_BASE
233 bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
234 SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
235 VERSION_1, 0);
236 bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
237 SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
238 VERSION_1, 0);
239#endif
240
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200241 /* Fill BL3-3 related information */
242 bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
243 SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
244 PARAM_EP, VERSION_1, 0);
245
246 /* BL3-3 expects to receive the primary CPU MPID (through x0) */
247 bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
248
249 bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
250 SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info,
251 PARAM_IMAGE_BINARY, VERSION_1, 0);
252
253 return bl2_to_bl31_params;
254}
255
256struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
257{
Victor Chong175dd8a2018-02-01 00:35:22 +0900258#if DEBUG
259 bl31_params_mem.bl31_ep_info.args.arg1 = POPLAR_BL31_PLAT_PARAM_VAL;
260#endif
261
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200262 return &bl31_params_mem.bl31_ep_info;
263}
264
265void bl2_plat_set_bl31_ep_info(image_info_t *image,
266 entry_point_info_t *bl31_ep_info)
267{
268 SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
269 bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
270 DISABLE_ALL_EXCEPTIONS);
271}
Victor Chong662556a2017-10-28 01:59:41 +0900272
273/*******************************************************************************
274 * Before calling this function BL32 is loaded in memory and its entrypoint
275 * is set by load_image. This is a placeholder for the platform to change
276 * the entrypoint of BL32 and set SPSR and security state.
277 * On Poplar we only set the security state of the entrypoint
278 ******************************************************************************/
279#ifdef BL32_BASE
280void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
281 entry_point_info_t *bl32_ep_info)
282{
283 SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
284 /*
285 * The Secure Payload Dispatcher service is responsible for
286 * setting the SPSR prior to entry into the BL32 image.
287 */
288 bl32_ep_info->spsr = 0;
289}
290
291/*******************************************************************************
292 * Populate the extents of memory available for loading BL32
293 ******************************************************************************/
294void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
295{
296 /*
297 * Populate the extents of memory available for loading BL32.
298 */
299 bl32_meminfo->total_base = BL32_BASE;
300 bl32_meminfo->free_base = BL32_BASE;
301 bl32_meminfo->total_size =
302 (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
303 bl32_meminfo->free_size =
304 (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
305}
306#endif /* BL32_BASE */
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200307
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200308void bl2_plat_set_bl33_ep_info(image_info_t *image,
309 entry_point_info_t *bl33_ep_info)
310{
311 SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
Victor Chong175dd8a2018-02-01 00:35:22 +0900312 bl33_ep_info->spsr = poplar_get_spsr_for_bl33_entry();
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200313 bl33_ep_info->args.arg2 = image->image_size;
314}
315
316void bl2_plat_flush_bl31_params(void)
317{
318 flush_dcache_range((unsigned long)&bl31_params_mem,
319 sizeof(bl2_to_bl31_params_mem_t));
320}
321
322void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
323{
324 bl33_meminfo->total_base = DDR_BASE;
325 bl33_meminfo->total_size = DDR_SIZE;
326 bl33_meminfo->free_base = DDR_BASE;
327 bl33_meminfo->free_size = DDR_SIZE;
328}
Victor Chong175dd8a2018-02-01 00:35:22 +0900329#endif /* LOAD_IMAGE_V2 */
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200330
331void bl2_early_platform_setup(meminfo_t *mem_layout)
332{
Victor Chongf0c7c612018-01-16 00:29:47 +0900333#if !POPLAR_RECOVERY
Victor Chong539408d2018-01-03 01:53:08 +0900334 dw_mmc_params_t params = EMMC_INIT_PARAMS(POPLAR_EMMC_DESC_BASE);
Victor Chongf0c7c612018-01-16 00:29:47 +0900335#endif
Victor Chong539408d2018-01-03 01:53:08 +0900336
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200337 console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
338
339 /* Enable arch timer */
340 generic_delay_timer_init();
341
342 bl2_tzram_layout = *mem_layout;
Victor Chong539408d2018-01-03 01:53:08 +0900343
Victor Chongf0c7c612018-01-16 00:29:47 +0900344#if !POPLAR_RECOVERY
Victor Chong539408d2018-01-03 01:53:08 +0900345 /* SoC-specific emmc register are initialized/configured by bootrom */
346 INFO("BL2: initializing emmc\n");
347 dw_mmc_init(&params);
Victor Chongf0c7c612018-01-16 00:29:47 +0900348#endif
Victor Chong539408d2018-01-03 01:53:08 +0900349
350 plat_io_setup();
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200351}
352
353void bl2_plat_arch_setup(void)
354{
355 plat_configure_mmu_el1(bl2_tzram_layout.total_base,
356 bl2_tzram_layout.total_size,
357 BL2_RO_BASE,
358 BL2_RO_LIMIT,
359 BL2_COHERENT_RAM_BASE,
360 BL2_COHERENT_RAM_LIMIT);
361}
362
363void bl2_platform_setup(void)
364{
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200365}
366
Victor Chong175dd8a2018-02-01 00:35:22 +0900367uintptr_t plat_get_ns_image_entrypoint(void)
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200368{
Victor Chong175dd8a2018-02-01 00:35:22 +0900369#ifdef PRELOADED_BL33_BASE
370 return PRELOADED_BL33_BASE;
371#else
Victor Chong6df271c2017-10-27 00:09:14 +0900372 return PLAT_POPLAR_NS_IMAGE_OFFSET;
Victor Chong175dd8a2018-02-01 00:35:22 +0900373#endif
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200374}