blob: e502e7b9dba638c76d8d8afbff4baeeb62d0b290 [file] [log] [blame]
Jens Wiklander52c798e2015-12-07 14:37:10 +01001/*
Jean-Philippe Brucker721b83d2023-09-07 18:13:07 +01002 * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
Jens Wiklander52c798e2015-12-07 14:37:10 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Jens Wiklander52c798e2015-12-07 14:37:10 +01005 */
6
7#include <assert.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00008
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00009#include <common/bl_common.h>
Maxim Uvarova0b85c22020-12-14 10:17:44 +000010#include <drivers/arm/pl061_gpio.h>
Jean-Philippe Brucker4453ba92023-09-07 18:47:48 +010011#include <lib/gpt_rme/gpt_rme.h>
Raymond Maobb653862023-10-04 09:58:29 -070012#include <lib/transfer_list.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000013#include <plat/common/platform.h>
Jean-Philippe Brucker997dda02024-08-16 09:49:38 +010014#if ENABLE_RME
Mathieu Poirier63a48ca2024-08-16 09:44:09 -060015#ifdef PLAT_qemu
Jean-Philippe Brucker997dda02024-08-16 09:49:38 +010016#include <qemu_pas_def.h>
Mathieu Poirier63a48ca2024-08-16 09:44:09 -060017#elif PLAT_qemu_sbsa
18#include <qemu_sbsa_pas_def.h>
19#endif /* PLAT_qemu */
20#endif /* ENABLE_RME */
Mathieu Poirier61c3ade2024-09-27 15:27:25 -060021#ifdef PLAT_qemu_sbsa
22#include <sbsa_platform.h>
23#endif
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000024
Jens Wiklander52c798e2015-12-07 14:37:10 +010025#include "qemu_private.h"
26
Chen Baozif7d9aa82023-02-20 10:50:15 +000027#define MAP_BL31_TOTAL MAP_REGION_FLAT( \
28 BL31_BASE, \
29 BL31_END - BL31_BASE, \
30 MT_MEMORY | MT_RW | EL3_PAS)
31#define MAP_BL31_RO MAP_REGION_FLAT( \
32 BL_CODE_BASE, \
33 BL_CODE_END - BL_CODE_BASE, \
34 MT_CODE | EL3_PAS), \
35 MAP_REGION_FLAT( \
36 BL_RO_DATA_BASE, \
37 BL_RO_DATA_END \
38 - BL_RO_DATA_BASE, \
39 MT_RO_DATA | EL3_PAS)
40
Chen Baozi097a43a2023-03-12 20:58:04 +080041#if USE_COHERENT_MEM
Chen Baozif7d9aa82023-02-20 10:50:15 +000042#define MAP_BL_COHERENT_RAM MAP_REGION_FLAT( \
43 BL_COHERENT_RAM_BASE, \
44 BL_COHERENT_RAM_END \
45 - BL_COHERENT_RAM_BASE, \
46 MT_DEVICE | MT_RW | EL3_PAS)
Chen Baozi097a43a2023-03-12 20:58:04 +080047#endif
Chen Baozif7d9aa82023-02-20 10:50:15 +000048
Jens Wiklander52c798e2015-12-07 14:37:10 +010049/*
Jens Wiklander52c798e2015-12-07 14:37:10 +010050 * Placeholder variables for copying the arguments that have been passed to
51 * BL3-1 from BL2.
52 */
53static entry_point_info_t bl32_image_ep_info;
54static entry_point_info_t bl33_image_ep_info;
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +010055#if ENABLE_RME
56static entry_point_info_t rmm_image_ep_info;
57#endif
Raymond Maobb653862023-10-04 09:58:29 -070058static struct transfer_list_header *bl31_tl;
Jens Wiklander52c798e2015-12-07 14:37:10 +010059
60/*******************************************************************************
61 * Perform any BL3-1 early platform setup. Here is an opportunity to copy
John Tsichritzisd653d332018-09-14 10:34:57 +010062 * parameters passed by the calling EL (S-EL1 in BL2 & EL3 in BL1) before
Jens Wiklander52c798e2015-12-07 14:37:10 +010063 * they are lost (potentially). This needs to be done before the MMU is
64 * initialized so that the memory layout can be used while creating page
65 * tables. BL2 has flushed this information to memory, so we are guaranteed
66 * to pick up good data.
67 ******************************************************************************/
Jens Wiklandere22b91e2018-09-04 14:07:19 +020068void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
69 u_register_t arg2, u_register_t arg3)
Jens Wiklander52c798e2015-12-07 14:37:10 +010070{
71 /* Initialize the console to provide early debug support */
Michalis Pappascca6cb72018-03-04 15:43:38 +080072 qemu_console_init();
Jens Wiklander52c798e2015-12-07 14:37:10 +010073
Marcin Juszkiewiczb6839fb2023-05-10 10:03:01 +020074/* Platform names have to be lowercase. */
75#ifdef PLAT_qemu_sbsa
Mathieu Poirier61c3ade2024-09-27 15:27:25 -060076 sbsa_platform_init();
Marcin Juszkiewiczb6839fb2023-05-10 10:03:01 +020077#endif
78
Fu Weic2f78442017-05-27 21:21:42 +080079 /*
80 * Check params passed from BL2
81 */
Jens Wiklandere22b91e2018-09-04 14:07:19 +020082 bl_params_t *params_from_bl2 = (bl_params_t *)arg0;
Fu Weic2f78442017-05-27 21:21:42 +080083
84 assert(params_from_bl2);
85 assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
86 assert(params_from_bl2->h.version >= VERSION_2);
87
88 bl_params_node_t *bl_params = params_from_bl2->head;
89
90 /*
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +010091 * Copy BL33, BL32 and RMM (if present), entry point information.
Fu Weic2f78442017-05-27 21:21:42 +080092 * They are stored in Secure RAM, in BL2's address space.
93 */
94 while (bl_params) {
95 if (bl_params->image_id == BL32_IMAGE_ID)
96 bl32_image_ep_info = *bl_params->ep_info;
97
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +010098#if ENABLE_RME
99 if (bl_params->image_id == RMM_IMAGE_ID)
100 rmm_image_ep_info = *bl_params->ep_info;
101#endif
102
Fu Weic2f78442017-05-27 21:21:42 +0800103 if (bl_params->image_id == BL33_IMAGE_ID)
104 bl33_image_ep_info = *bl_params->ep_info;
105
106 bl_params = bl_params->next_params_info;
107 }
108
109 if (!bl33_image_ep_info.pc)
110 panic();
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +0100111#if ENABLE_RME
112 if (!rmm_image_ep_info.pc)
113 panic();
114#endif
Raymond Maobb653862023-10-04 09:58:29 -0700115
116 if (TRANSFER_LIST && arg1 == (TRANSFER_LIST_SIGNATURE |
117 REGISTER_CONVENTION_VERSION_MASK) &&
118 transfer_list_check_header((void *)arg3) != TL_OPS_NON) {
119 bl31_tl = (void *)arg3; /* saved TL address from BL2 */
120 }
Jens Wiklander52c798e2015-12-07 14:37:10 +0100121}
Jean-Philippe Brucker997dda02024-08-16 09:49:38 +0100122
123#if ENABLE_RME
Mathieu Poirier63a48ca2024-08-16 09:44:09 -0600124#if PLAT_qemu
125/*
126 * The GPT library might modify the gpt regions structure to optimize
127 * the layout, so the array cannot be constant.
128 */
129static pas_region_t pas_regions[] = {
130 QEMU_PAS_ROOT,
131 QEMU_PAS_SECURE,
132 QEMU_PAS_GPTS,
133 QEMU_PAS_NS0,
134 QEMU_PAS_REALM,
135 QEMU_PAS_NS1,
136};
137
138static inline void bl31_adjust_pas_regions(void) {}
139#elif PLAT_qemu_sbsa
140/*
141 * The GPT library might modify the gpt regions structure to optimize
142 * the layout, so the array cannot be constant.
143 */
144static pas_region_t pas_regions[] = {
145 QEMU_PAS_ROOT,
146 QEMU_PAS_SECURE,
147 QEMU_PAS_GPTS,
148 QEMU_PAS_REALM,
149 QEMU_PAS_NS0,
150};
151
152static void bl31_adjust_pas_regions(void)
Jean-Philippe Brucker997dda02024-08-16 09:49:38 +0100153{
Mathieu Poirier63a48ca2024-08-16 09:44:09 -0600154 uint64_t base_addr = 0, total_size = 0;
155 struct platform_memory_data data;
156 uint32_t node;
157
Jean-Philippe Brucker997dda02024-08-16 09:49:38 +0100158 /*
Mathieu Poirier63a48ca2024-08-16 09:44:09 -0600159 * The amount of memory supported by the SBSA platform is dynamic
160 * and dependent on user input. Since the configuration of the GPT
161 * needs to reflect the system memory, QEMU_PAS_NS0 needs to be set
162 * based on the information found in the device tree.
Jean-Philippe Brucker997dda02024-08-16 09:49:38 +0100163 */
Jean-Philippe Brucker997dda02024-08-16 09:49:38 +0100164
Mathieu Poirier63a48ca2024-08-16 09:44:09 -0600165 for (node = 0; node < sbsa_platform_num_memnodes(); node++) {
166 data = sbsa_platform_memory_node(node);
167
168 if (data.nodeid == 0) {
169 base_addr = data.addr_base;
170 }
171
172 total_size += data.addr_size;
173 }
174
175 /* Index '4' correspond to QEMU_PAS_NS0, see pas_regions[] above */
176 pas_regions[4].base_pa = base_addr;
177 pas_regions[4].size = total_size;
178}
179#endif /* PLAT_qemu */
180
181static void bl31_plat_gpt_setup(void)
182{
Jean-Philippe Brucker997dda02024-08-16 09:49:38 +0100183 /*
184 * Initialize entire protected space to GPT_GPI_ANY. With each L0 entry
185 * covering 1GB (currently the only supported option), then covering
186 * 256TB of RAM (48-bit PA) would require a 2MB L0 region. At the
187 * moment we use a 8KB table, which covers 1TB of RAM (40-bit PA).
188 */
Mathieu Poirier154aee92024-06-03 10:38:42 -0600189 if (gpt_init_l0_tables(PLATFORM_GPCCR_PPS, PLAT_QEMU_L0_GPT_BASE,
Jean-Philippe Brucker997dda02024-08-16 09:49:38 +0100190 PLAT_QEMU_L0_GPT_SIZE +
191 PLAT_QEMU_GPT_BITLOCK_SIZE) < 0) {
192 ERROR("gpt_init_l0_tables() failed!\n");
193 panic();
194 }
195
Mathieu Poirier63a48ca2024-08-16 09:44:09 -0600196 bl31_adjust_pas_regions();
197
Jean-Philippe Brucker997dda02024-08-16 09:49:38 +0100198 /* Carve out defined PAS ranges. */
199 if (gpt_init_pas_l1_tables(GPCCR_PGS_4K,
200 PLAT_QEMU_L1_GPT_BASE,
201 PLAT_QEMU_L1_GPT_SIZE,
202 pas_regions,
203 (unsigned int)(sizeof(pas_regions) /
204 sizeof(pas_region_t))) < 0) {
205 ERROR("gpt_init_pas_l1_tables() failed!\n");
206 panic();
207 }
208
209 INFO("Enabling Granule Protection Checks\n");
210 if (gpt_enable() < 0) {
211 ERROR("gpt_enable() failed!\n");
212 panic();
213 }
214}
215#endif
Jens Wiklander52c798e2015-12-07 14:37:10 +0100216
217void bl31_plat_arch_setup(void)
218{
Chen Baozif7d9aa82023-02-20 10:50:15 +0000219 const mmap_region_t bl_regions[] = {
220 MAP_BL31_TOTAL,
221 MAP_BL31_RO,
Chen Baozi097a43a2023-03-12 20:58:04 +0800222#if USE_COHERENT_MEM
Chen Baozif7d9aa82023-02-20 10:50:15 +0000223 MAP_BL_COHERENT_RAM,
Chen Baozi097a43a2023-03-12 20:58:04 +0800224#endif
Jean-Philippe Brucker721b83d2023-09-07 18:13:07 +0100225#if ENABLE_RME
226 MAP_GPT_L0_REGION,
227 MAP_GPT_L1_REGION,
228 MAP_RMM_SHARED_MEM,
229#endif
Chen Baozif7d9aa82023-02-20 10:50:15 +0000230 {0}
231 };
232
233 setup_page_tables(bl_regions, plat_qemu_get_mmap());
234
235 enable_mmu_el3(0);
Jean-Philippe Brucker4453ba92023-09-07 18:47:48 +0100236
237#if ENABLE_RME
Jean-Philippe Brucker997dda02024-08-16 09:49:38 +0100238 /* Initialise and enable granule protection after MMU. */
239 bl31_plat_gpt_setup();
240
Jean-Philippe Brucker4453ba92023-09-07 18:47:48 +0100241 /*
242 * Initialise Granule Protection library and enable GPC for the primary
243 * processor. The tables have already been initialized by a previous BL
244 * stage, so there is no need to provide any PAS here. This function
245 * sets up pointers to those tables.
246 */
247 if (gpt_runtime_init() < 0) {
248 ERROR("gpt_runtime_init() failed!\n");
249 panic();
250 }
251#endif /* ENABLE_RME */
252
Jens Wiklander52c798e2015-12-07 14:37:10 +0100253}
254
Maxim Uvarova0b85c22020-12-14 10:17:44 +0000255static void qemu_gpio_init(void)
256{
257#ifdef SECURE_GPIO_BASE
258 pl061_gpio_init();
259 pl061_gpio_register(SECURE_GPIO_BASE, 0);
260#endif
261}
262
Jens Wiklander52c798e2015-12-07 14:37:10 +0100263void bl31_platform_setup(void)
264{
Hongbo Zhang32338ec2018-04-19 13:06:07 +0800265 plat_qemu_gic_init();
Maxim Uvarova0b85c22020-12-14 10:17:44 +0000266 qemu_gpio_init();
Jens Wiklander52c798e2015-12-07 14:37:10 +0100267}
268
269unsigned int plat_get_syscnt_freq2(void)
270{
Marcin Juszkiewiczb9a35532024-04-22 17:27:56 +0200271 return read_cntfrq_el0();
Jens Wiklander52c798e2015-12-07 14:37:10 +0100272}
273
274/*******************************************************************************
275 * Return a pointer to the 'entry_point_info' structure of the next image
276 * for the security state specified. BL3-3 corresponds to the non-secure
277 * image type while BL3-2 corresponds to the secure image type. A NULL
278 * pointer is returned if the image does not exist.
279 ******************************************************************************/
280entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
281{
282 entry_point_info_t *next_image_info;
283
284 assert(sec_state_is_valid(type));
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +0100285 if (type == NON_SECURE) {
286 next_image_info = &bl33_image_ep_info;
287 }
288#if ENABLE_RME
289 else if (type == REALM) {
290 next_image_info = &rmm_image_ep_info;
291 }
292#endif
293 else {
294 next_image_info = &bl32_image_ep_info;
295 }
296
Jens Wiklander52c798e2015-12-07 14:37:10 +0100297 /*
298 * None of the images on the ARM development platforms can have 0x0
299 * as the entrypoint
300 */
301 if (next_image_info->pc)
302 return next_image_info;
303 else
304 return NULL;
305}
Raymond Maobb653862023-10-04 09:58:29 -0700306
307void bl31_plat_runtime_setup(void)
308{
Raymond Maobb653862023-10-04 09:58:29 -0700309#if TRANSFER_LIST
310 if (bl31_tl) {
311 /*
312 * update the TL from S to NS memory before jump to BL33
313 * to reflect all changes in TL done by BL32
314 */
315 memcpy((void *)FW_NS_HANDOFF_BASE, bl31_tl, bl31_tl->max_size);
316 }
317#endif
Jens Wiklander7ad51de2024-03-01 09:07:19 +0100318
319 console_flush();
320 console_switch_state(CONSOLE_FLAG_RUNTIME);
Raymond Maobb653862023-10-04 09:58:29 -0700321}