1 
2 /*
3  * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include <string.h>
9 
10 #include <platform_def.h>
11 
12 #include <arch_helpers.h>
13 #include <common/bl_common.h>
14 #include <lib/xlat_tables/xlat_tables_v2.h>
15 #include <services/el3_spmc_ffa_memory.h>
16 #include <services/ffa_svc.h>
17 #if ENABLE_RME
18 #include <services/rmm_core_manifest.h>
19 #endif
20 
21 #include <plat/common/platform.h>
22 #include "qemu_private.h"
23 
24 #define MAP_DEVICE0	MAP_REGION_FLAT(DEVICE0_BASE,			\
25 					DEVICE0_SIZE,			\
26 					MT_DEVICE | MT_RW | EL3_PAS)
27 
28 #ifdef DEVICE1_BASE
29 #define MAP_DEVICE1	MAP_REGION_FLAT(DEVICE1_BASE,			\
30 					DEVICE1_SIZE,			\
31 					MT_DEVICE | MT_RW | EL3_PAS)
32 #endif
33 
34 #ifdef DEVICE2_BASE
35 #define MAP_DEVICE2	MAP_REGION_FLAT(DEVICE2_BASE,			\
36 					DEVICE2_SIZE,			\
37 					MT_DEVICE | MT_RW | EL3_PAS)
38 #endif
39 
40 #define MAP_SHARED_RAM	MAP_REGION_FLAT(SHARED_RAM_BASE,		\
41 					SHARED_RAM_SIZE,		\
42 					MT_DEVICE  | MT_RW | EL3_PAS)
43 
44 #define MAP_BL32_MEM	MAP_REGION_FLAT(BL32_MEM_BASE, BL32_MEM_SIZE,	\
45 					MT_MEMORY | MT_RW | EL3_PAS)
46 
47 #define MAP_NS_DRAM0	MAP_REGION_FLAT(NS_DRAM0_BASE, NS_DRAM0_SIZE,	\
48 					MT_MEMORY | MT_RW | MT_NS)
49 
50 #define MAP_FLASH0	MAP_REGION_FLAT(QEMU_FLASH0_BASE, QEMU_FLASH0_SIZE, \
51 					MT_MEMORY | MT_RO | EL3_PAS)
52 
53 #define MAP_FLASH1	MAP_REGION_FLAT(QEMU_FLASH1_BASE, QEMU_FLASH1_SIZE, \
54 					MT_MEMORY | MT_RO | EL3_PAS)
55 
56 #ifdef FW_HANDOFF_BASE
57 #define MAP_FW_HANDOFF MAP_REGION_FLAT(FW_HANDOFF_BASE, FW_HANDOFF_SIZE, \
58 				       MT_MEMORY | MT_RW | EL3_PAS)
59 #endif
60 #ifdef FW_NS_HANDOFF_BASE
61 #define MAP_FW_NS_HANDOFF MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, FW_HANDOFF_SIZE, \
62 					  MT_MEMORY | MT_RW | MT_NS)
63 #endif
64 /*
65  * Table of regions for various BL stages to map using the MMU.
66  * This doesn't include TZRAM as the 'mem_layout' argument passed to
67  * arm_configure_mmu_elx() will give the available subset of that,
68  */
69 #ifdef IMAGE_BL1
70 static const mmap_region_t plat_qemu_mmap[] = {
71 	MAP_FLASH0,
72 	MAP_FLASH1,
73 	MAP_SHARED_RAM,
74 	MAP_DEVICE0,
75 #ifdef MAP_DEVICE1
76 	MAP_DEVICE1,
77 #endif
78 #ifdef MAP_DEVICE2
79 	MAP_DEVICE2,
80 #endif
81 	{0}
82 };
83 #endif
84 #ifdef IMAGE_BL2
85 static const mmap_region_t plat_qemu_mmap[] = {
86 	MAP_FLASH0,
87 	MAP_FLASH1,
88 	MAP_SHARED_RAM,
89 	MAP_DEVICE0,
90 #ifdef MAP_DEVICE1
91 	MAP_DEVICE1,
92 #endif
93 #ifdef MAP_DEVICE2
94 	MAP_DEVICE2,
95 #endif
96 	MAP_NS_DRAM0,
97 #if SPM_MM
98 	QEMU_SP_IMAGE_MMAP,
99 #else
100 	MAP_BL32_MEM,
101 #endif
102 #ifdef MAP_FW_HANDOFF
103 	MAP_FW_HANDOFF,
104 #endif
105 	{0}
106 };
107 #endif
108 #ifdef IMAGE_BL31
109 static const mmap_region_t plat_qemu_mmap[] = {
110 	MAP_SHARED_RAM,
111 	MAP_DEVICE0,
112 #ifdef MAP_DEVICE1
113 	MAP_DEVICE1,
114 #endif
115 #ifdef MAP_DEVICE2
116 	MAP_DEVICE2,
117 #endif
118 #ifdef MAP_FW_HANDOFF
119 	MAP_FW_HANDOFF,
120 #endif
121 #ifdef MAP_FW_NS_HANDOFF
122 	MAP_FW_NS_HANDOFF,
123 #endif
124 #if SPM_MM
125 	MAP_NS_DRAM0,
126 	QEMU_SPM_BUF_EL3_MMAP,
127 #elif !SPMC_AT_EL3
128 	MAP_BL32_MEM,
129 #endif
130 	{0}
131 };
132 #endif
133 #ifdef IMAGE_BL32
134 static const mmap_region_t plat_qemu_mmap[] = {
135 	MAP_SHARED_RAM,
136 	MAP_DEVICE0,
137 #ifdef MAP_DEVICE1
138 	MAP_DEVICE1,
139 #endif
140 #ifdef MAP_DEVICE2
141 	MAP_DEVICE2,
142 #endif
143 	{0}
144 };
145 #endif
146 
147 #ifdef IMAGE_RMM
148 const mmap_region_t plat_qemu_mmap[] = {
149 	MAP_DEVICE0,
150 #ifdef MAP_DEVICE1
151 	MAP_DEVICE1,
152 #endif
153 #ifdef MAP_DEVICE2
154 	MAP_DEVICE2,
155 #endif
156 	{0}
157 };
158 #endif
159 
160 /*******************************************************************************
161  * Returns QEMU platform specific memory map regions.
162  ******************************************************************************/
plat_qemu_get_mmap(void)163 const mmap_region_t *plat_qemu_get_mmap(void)
164 {
165 	return plat_qemu_mmap;
166 }
167 
168 #if MEASURED_BOOT || TRUSTED_BOARD_BOOT
plat_get_mbedtls_heap(void ** heap_addr,size_t * heap_size)169 int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
170 {
171 	return get_mbedtls_heap_helper(heap_addr, heap_size);
172 }
173 #endif
174 
175 #if SPMC_AT_EL3
176 /*
177  * When using the EL3 SPMC implementation allocate the datastore
178  * for tracking shared memory descriptors in normal memory.
179  */
180 #define PLAT_SPMC_SHMEM_DATASTORE_SIZE 384 * 1024
181 
182 uint8_t plat_spmc_shmem_datastore[PLAT_SPMC_SHMEM_DATASTORE_SIZE] __aligned(8);
183 
plat_spmc_shmem_datastore_get(uint8_t ** datastore,size_t * size)184 int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size)
185 {
186 	*datastore = plat_spmc_shmem_datastore;
187 	*size = PLAT_SPMC_SHMEM_DATASTORE_SIZE;
188 	return 0;
189 }
190 
qemu_spmc_mem_set_shared(struct ffa_mtd * desc,bool shared)191 static int qemu_spmc_mem_set_shared(struct ffa_mtd *desc, bool shared)
192 {
193 	struct ffa_emad_v1_0 *emad0;
194 	struct ffa_comp_mrd *comp;
195 	bool secure;
196 	int ret;
197 
198 #if MAKE_FFA_VERSION(1, 1) > FFA_VERSION_COMPILED
199 #error "TF-A was compiled for FF-A v1.0"
200 #endif
201 	assert(is_aligned(desc->emad_offset, 16));
202 	emad0 = (struct ffa_emad_v1_0 *)((uint8_t *)desc + desc->emad_offset);
203 	comp = (struct ffa_comp_mrd *)((uint8_t *)desc + emad0->comp_mrd_offset);
204 	secure = (desc->flags & FFA_MTD_FLAG_TYPE_MASK) == FFA_MTD_FLAG_TYPE_LEND_MEMORY;
205 
206 	ret = qemu_ffa_comp_set_shared(comp, shared, secure);
207 	if (!ret && secure) {
208 		desc->memory_region_attributes &= ~FFA_MEM_ATTR_NS_BIT;
209 	}
210 	return ret;
211 }
212 
plat_spmc_shmem_begin(struct ffa_mtd * desc)213 int plat_spmc_shmem_begin(struct ffa_mtd *desc)
214 {
215 	return qemu_spmc_mem_set_shared(desc, true);
216 }
217 
plat_spmc_shmem_reclaim(struct ffa_mtd * desc)218 int plat_spmc_shmem_reclaim(struct ffa_mtd *desc)
219 {
220 	return qemu_spmc_mem_set_shared(desc, false);
221 }
222 #endif
223 
224 #if defined(SPD_spmd)
225 /*
226  * A dummy implementation of the platform handler for Group0 secure interrupt.
227  */
plat_spmd_handle_group0_interrupt(uint32_t intid)228 int plat_spmd_handle_group0_interrupt(uint32_t intid)
229 {
230 	(void)intid;
231 	return -1;
232 }
233 #endif /*defined(SPD_spmd)*/
234 
235 #if ENABLE_RME
236 /*
237  * Get a pointer to the RMM-EL3 Shared buffer and return it
238  * through the pointer passed as parameter.
239  *
240  * This function returns the size of the shared buffer.
241  */
plat_rmmd_get_el3_rmm_shared_mem(uintptr_t * shared)242 size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared)
243 {
244 	*shared = (uintptr_t)RMM_SHARED_BASE;
245 
246 	return (size_t)RMM_SHARED_SIZE;
247 }
248 
plat_rmmd_load_manifest(struct rmm_manifest * manifest)249 int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
250 {
251 	uint64_t checksum;
252 	uintptr_t base;
253 	uint64_t size;
254 	size_t num_banks = 1;
255 	size_t num_consoles = 1;
256 	struct ns_dram_bank *bank_ptr;
257 	struct console_info *console_ptr;
258 
259 	assert(manifest != NULL);
260 
261 	manifest->version = RMMD_MANIFEST_VERSION;
262 	manifest->padding = 0U; /* RES0 */
263 	manifest->plat_data = (uintptr_t)NULL;
264 	manifest->plat_dram.num_banks = num_banks;
265 	manifest->plat_console.num_consoles = num_consoles;
266 
267 	/*
268 	 * Boot manifest structure illustration:
269 	 *
270 	 * +----------------------------------------+
271 	 * |  offset  |   field      |  comment     |
272 	 * +----------+--------------+--------------+
273 	 * |    0     |  version     | 0x00000003   |
274 	 * +----------+--------------+--------------+
275 	 * |    4     |  padding     | 0x00000000   |
276 	 * +----------+--------------+--------------+
277 	 * |    8     | plat_data    |    NULL      |
278 	 * +----------+--------------+--------------+
279 	 * |    16    | num_banks    |              |
280 	 * +----------+--------------+              |
281 	 * |    24    |   banks      | plat_dram    |
282 	 * +----------+--------------+              |
283 	 * |    32    | checksum     |              |
284 	 * +----------+--------------+--------------+
285 	 * |    40    | num_consoles |              |
286 	 * +----------+--------------+              |
287 	 * |    48    | consoles     | plat_console |
288 	 * +----------+--------------+              |
289 	 * |    56    | checksum     |              |
290 	 * +----------+--------------+--------------+
291 	 * |    64    |  base 0      |              |
292 	 * +----------+--------------+   bank[0]    |
293 	 * |    72    |  size 0      |              |
294 	 * +----------+--------------+--------------+
295 	 * |    80    |  base        |              |
296 	 * +----------+--------------+              |
297 	 * |    88    |  map_pages   |              |
298 	 * +----------+--------------+              |
299 	 * |    96    |  name        |              |
300 	 * +----------+--------------+  consoles[0] |
301 	 * |   104    |  clk_in_hz   |              |
302 	 * +----------+--------------+              |
303 	 * |   112    |  baud_rate   |              |
304 	 * +----------+--------------+              |
305 	 * |   120    |  flags       |              |
306 	 * +----------+--------------+--------------+
307 	 */
308 	bank_ptr = (struct ns_dram_bank *)
309 		(((uintptr_t)manifest) + sizeof(*manifest));
310 
311 	console_ptr = (struct console_info *)
312 		((uintptr_t)bank_ptr + (num_banks * sizeof(*bank_ptr)));
313 
314 	manifest->plat_dram.banks = bank_ptr;
315 	manifest->plat_console.consoles = console_ptr;
316 
317 	/* Ensure the manifest is not larger than the shared buffer */
318 	assert((sizeof(struct rmm_manifest) +
319 		(sizeof(struct console_info) * num_consoles) +
320 		(sizeof(struct ns_dram_bank) * num_banks)) <= RMM_SHARED_SIZE);
321 
322 	/* Calculate checksum of plat_dram structure */
323 	checksum = num_banks + (uint64_t)bank_ptr;
324 
325 	base = NS_DRAM0_BASE;
326 	size = NS_DRAM0_SIZE;
327 	bank_ptr[0].base = base;
328 	bank_ptr[0].size = size;
329 	checksum += base + size;
330 
331 	/* Checksum must be 0 */
332 	manifest->plat_dram.checksum = ~checksum + 1UL;
333 
334 	/* Calculate the checksum of the plat_consoles structure */
335 	checksum = num_consoles + (uint64_t)console_ptr;
336 
337 	/* Zero out the console info struct */
338 	memset((void *)console_ptr, 0, sizeof(struct console_info) * num_consoles);
339 
340 	console_ptr[0].map_pages = 1;
341 	console_ptr[0].base = PLAT_QEMU_BOOT_UART_BASE;
342 	console_ptr[0].clk_in_hz = PLAT_QEMU_BOOT_UART_CLK_IN_HZ;
343 	console_ptr[0].baud_rate = PLAT_QEMU_CONSOLE_BAUDRATE;
344 
345 	strlcpy(console_ptr[0].name, "pl011", sizeof(console_ptr[0].name));
346 
347 	/* Update checksum */
348 	checksum += console_ptr[0].base + console_ptr[0].map_pages +
349 		console_ptr[0].clk_in_hz + console_ptr[0].baud_rate;
350 
351 	/* Checksum must be 0 */
352 	manifest->plat_console.checksum = ~checksum + 1UL;
353 
354 	return 0;
355 }
356 #endif  /* ENABLE_RME */
357