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(2 * sizeof(long));
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)
plat_spmd_handle_group0_interrupt(uint32_t intid)225 int plat_spmd_handle_group0_interrupt(uint32_t intid)
226 {
227 /*
228 * Currently, there are no sources of Group0 secure interrupt
229 * enabled for QEMU.
230 */
231 (void)intid;
232 return -1;
233 }
234 #endif /*defined(SPD_spmd)*/
235
236 #if ENABLE_RME
237 /*
238 * Get a pointer to the RMM-EL3 Shared buffer and return it
239 * through the pointer passed as parameter.
240 *
241 * This function returns the size of the shared buffer.
242 */
plat_rmmd_get_el3_rmm_shared_mem(uintptr_t * shared)243 size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared)
244 {
245 *shared = (uintptr_t)RMM_SHARED_BASE;
246
247 return (size_t)RMM_SHARED_SIZE;
248 }
249
plat_rmmd_load_manifest(struct rmm_manifest * manifest)250 int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
251 {
252 uint64_t checksum;
253 uintptr_t base;
254 uint64_t size;
255 size_t num_banks = 1;
256 size_t num_consoles = 1;
257 struct ns_dram_bank *bank_ptr;
258 struct console_info *console_ptr;
259
260 assert(manifest != NULL);
261
262 manifest->version = RMMD_MANIFEST_VERSION;
263 manifest->padding = 0U; /* RES0 */
264 manifest->plat_data = (uintptr_t)NULL;
265 manifest->plat_dram.num_banks = num_banks;
266 manifest->plat_console.num_consoles = num_consoles;
267
268 /*
269 * Boot manifest structure illustration:
270 *
271 * +----------------------------------------+
272 * | offset | field | comment |
273 * +----------+--------------+--------------+
274 * | 0 | version | 0x00000003 |
275 * +----------+--------------+--------------+
276 * | 4 | padding | 0x00000000 |
277 * +----------+--------------+--------------+
278 * | 8 | plat_data | NULL |
279 * +----------+--------------+--------------+
280 * | 16 | num_banks | |
281 * +----------+--------------+ |
282 * | 24 | banks | plat_dram |
283 * +----------+--------------+ |
284 * | 32 | checksum | |
285 * +----------+--------------+--------------+
286 * | 40 | num_consoles | |
287 * +----------+--------------+ |
288 * | 48 | consoles | plat_console |
289 * +----------+--------------+ |
290 * | 56 | checksum | |
291 * +----------+--------------+--------------+
292 * | 64 | base 0 | |
293 * +----------+--------------+ bank[0] |
294 * | 72 | size 0 | |
295 * +----------+--------------+--------------+
296 * | 80 | base | |
297 * +----------+--------------+ |
298 * | 88 | map_pages | |
299 * +----------+--------------+ |
300 * | 96 | name | |
301 * +----------+--------------+ consoles[0] |
302 * | 104 | clk_in_hz | |
303 * +----------+--------------+ |
304 * | 112 | baud_rate | |
305 * +----------+--------------+ |
306 * | 120 | flags | |
307 * +----------+--------------+--------------+
308 */
309 bank_ptr = (struct ns_dram_bank *)
310 (((uintptr_t)manifest) + sizeof(*manifest));
311
312 console_ptr = (struct console_info *)
313 ((uintptr_t)bank_ptr + (num_banks * sizeof(*bank_ptr)));
314
315 manifest->plat_dram.banks = bank_ptr;
316 manifest->plat_console.consoles = console_ptr;
317
318 /* Ensure the manifest is not larger than the shared buffer */
319 assert((sizeof(struct rmm_manifest) +
320 (sizeof(struct console_info) * num_consoles) +
321 (sizeof(struct ns_dram_bank) * num_banks)) <= RMM_SHARED_SIZE);
322
323 /* Calculate checksum of plat_dram structure */
324 checksum = num_banks + (uint64_t)bank_ptr;
325
326 base = NS_DRAM0_BASE;
327 size = NS_DRAM0_SIZE;
328 bank_ptr[0].base = base;
329 bank_ptr[0].size = size;
330 checksum += base + size;
331
332 /* Checksum must be 0 */
333 manifest->plat_dram.checksum = ~checksum + 1UL;
334
335 /* Calculate the checksum of the plat_consoles structure */
336 checksum = num_consoles + (uint64_t)console_ptr;
337
338 /* Zero out the console info struct */
339 memset((void *)console_ptr, 0, sizeof(struct console_info) * num_consoles);
340
341 console_ptr[0].map_pages = 1;
342 console_ptr[0].base = PLAT_QEMU_BOOT_UART_BASE;
343 console_ptr[0].clk_in_hz = PLAT_QEMU_BOOT_UART_CLK_IN_HZ;
344 console_ptr[0].baud_rate = PLAT_QEMU_CONSOLE_BAUDRATE;
345
346 strlcpy(console_ptr[0].name, "pl011", sizeof(console_ptr[0].name));
347
348 /* Update checksum */
349 checksum += console_ptr[0].base + console_ptr[0].map_pages +
350 console_ptr[0].clk_in_hz + console_ptr[0].baud_rate;
351
352 /* Checksum must be 0 */
353 manifest->plat_console.checksum = ~checksum + 1UL;
354
355 return 0;
356 }
357 #endif /* ENABLE_RME */
358