blob: db507c3279a1ec2c4d10f922f59e1843e8a48686 [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>
12#include <errno.h>
13#include <generic_delay_timer.h>
14#include <mmio.h>
15#include <partition/partition.h>
16#include <platform.h>
17#include <string.h>
18#include "hi3798cv200.h"
19#include "plat_private.h"
20
21/* Memory ranges for code and read only data sections */
22#define BL2_RO_BASE (unsigned long)(&__RO_START__)
23#define BL2_RO_LIMIT (unsigned long)(&__RO_END__)
24
25/* Memory ranges for coherent memory section */
26#define BL2_COHERENT_RAM_BASE (unsigned long)(&__COHERENT_RAM_START__)
27#define BL2_COHERENT_RAM_LIMIT (unsigned long)(&__COHERENT_RAM_END__)
28
29typedef struct bl2_to_bl31_params_mem {
30 bl31_params_t bl31_params;
31 image_info_t bl31_image_info;
Victor Chong662556a2017-10-28 01:59:41 +090032 image_info_t bl32_image_info;
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020033 image_info_t bl33_image_info;
34 entry_point_info_t bl33_ep_info;
Victor Chong662556a2017-10-28 01:59:41 +090035 entry_point_info_t bl32_ep_info;
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020036 entry_point_info_t bl31_ep_info;
37} bl2_to_bl31_params_mem_t;
38
39static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
40static bl2_to_bl31_params_mem_t bl31_params_mem;
41
42meminfo_t *bl2_plat_sec_mem_layout(void)
43{
44 return &bl2_tzram_layout;
45}
46
47bl31_params_t *bl2_plat_get_bl31_params(void)
48{
49 bl31_params_t *bl2_to_bl31_params = NULL;
50
51 /*
52 * Initialise the memory for all the arguments that needs to
53 * be passed to BL3-1
54 */
55 memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
56
57 /* Assign memory for TF related information */
58 bl2_to_bl31_params = &bl31_params_mem.bl31_params;
59 SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
60
61 /* Fill BL3-1 related information */
62 bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
63 SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info,
64 PARAM_IMAGE_BINARY, VERSION_1, 0);
65
Victor Chong662556a2017-10-28 01:59:41 +090066 /* Fill BL3-2 related information if it exists */
67#ifdef BL32_BASE
68 bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
69 SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
70 VERSION_1, 0);
71 bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
72 SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
73 VERSION_1, 0);
74#endif
75
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +020076 /* Fill BL3-3 related information */
77 bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
78 SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
79 PARAM_EP, VERSION_1, 0);
80
81 /* BL3-3 expects to receive the primary CPU MPID (through x0) */
82 bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
83
84 bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
85 SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info,
86 PARAM_IMAGE_BINARY, VERSION_1, 0);
87
88 return bl2_to_bl31_params;
89}
90
91struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
92{
93 return &bl31_params_mem.bl31_ep_info;
94}
95
96void bl2_plat_set_bl31_ep_info(image_info_t *image,
97 entry_point_info_t *bl31_ep_info)
98{
99 SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
100 bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
101 DISABLE_ALL_EXCEPTIONS);
102}
Victor Chong662556a2017-10-28 01:59:41 +0900103
104/*******************************************************************************
105 * Before calling this function BL32 is loaded in memory and its entrypoint
106 * is set by load_image. This is a placeholder for the platform to change
107 * the entrypoint of BL32 and set SPSR and security state.
108 * On Poplar we only set the security state of the entrypoint
109 ******************************************************************************/
110#ifdef BL32_BASE
111void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
112 entry_point_info_t *bl32_ep_info)
113{
114 SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
115 /*
116 * The Secure Payload Dispatcher service is responsible for
117 * setting the SPSR prior to entry into the BL32 image.
118 */
119 bl32_ep_info->spsr = 0;
120}
121
122/*******************************************************************************
123 * Populate the extents of memory available for loading BL32
124 ******************************************************************************/
125void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
126{
127 /*
128 * Populate the extents of memory available for loading BL32.
129 */
130 bl32_meminfo->total_base = BL32_BASE;
131 bl32_meminfo->free_base = BL32_BASE;
132 bl32_meminfo->total_size =
133 (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
134 bl32_meminfo->free_size =
135 (TSP_SEC_MEM_BASE + TSP_SEC_MEM_SIZE) - BL32_BASE;
136}
137#endif /* BL32_BASE */
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200138
139static uint32_t hisi_get_spsr_for_bl33_entry(void)
140{
141 unsigned long el_status;
142 unsigned int mode;
143 uint32_t spsr;
144
145 /* Figure out what mode we enter the non-secure world in */
146 el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
147 el_status &= ID_AA64PFR0_ELX_MASK;
148
149 mode = (el_status) ? MODE_EL2 : MODE_EL1;
150
151 /*
152 * TODO: Consider the possibility of specifying the SPSR in
153 * the FIP ToC and allowing the platform to have a say as
154 * well.
155 */
156 spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
157 return spsr;
158}
159
160void bl2_plat_set_bl33_ep_info(image_info_t *image,
161 entry_point_info_t *bl33_ep_info)
162{
163 SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
164 bl33_ep_info->spsr = hisi_get_spsr_for_bl33_entry();
165 bl33_ep_info->args.arg2 = image->image_size;
166}
167
168void bl2_plat_flush_bl31_params(void)
169{
170 flush_dcache_range((unsigned long)&bl31_params_mem,
171 sizeof(bl2_to_bl31_params_mem_t));
172}
173
174void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
175{
176 bl33_meminfo->total_base = DDR_BASE;
177 bl33_meminfo->total_size = DDR_SIZE;
178 bl33_meminfo->free_base = DDR_BASE;
179 bl33_meminfo->free_size = DDR_SIZE;
180}
181
182void bl2_early_platform_setup(meminfo_t *mem_layout)
183{
184 console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
185
186 /* Enable arch timer */
187 generic_delay_timer_init();
188
189 bl2_tzram_layout = *mem_layout;
190}
191
192void bl2_plat_arch_setup(void)
193{
194 plat_configure_mmu_el1(bl2_tzram_layout.total_base,
195 bl2_tzram_layout.total_size,
196 BL2_RO_BASE,
197 BL2_RO_LIMIT,
198 BL2_COHERENT_RAM_BASE,
199 BL2_COHERENT_RAM_LIMIT);
200}
201
202void bl2_platform_setup(void)
203{
204 plat_io_setup();
205}
206
207unsigned long plat_get_ns_image_entrypoint(void)
208{
Victor Chong6df271c2017-10-27 00:09:14 +0900209 return PLAT_POPLAR_NS_IMAGE_OFFSET;
Jorge Ramirez-Ortiza29d9a62017-06-28 10:11:31 +0200210}