blob: 4a79a908c6322d9f95178c8f5b2e64be5c0b759b [file] [log] [blame]
Masahisa Kojima099064b2020-06-11 21:46:44 +09001
Jens Wiklander52c798e2015-12-07 14:37:10 +01002/*
Jean-Philippe Bruckerb54f6c92023-09-07 17:46:12 +01003 * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
Jens Wiklander52c798e2015-12-07 14:37:10 +01004 *
dp-armfa3cf0b2017-05-03 09:38:09 +01005 * SPDX-License-Identifier: BSD-3-Clause
Jens Wiklander52c798e2015-12-07 14:37:10 +01006 */
7
Jean-Philippe Brucker2c7b22d2024-04-04 09:41:57 +01008#include <string.h>
9
Jens Wiklander52c798e2015-12-07 14:37:10 +010010#include <platform_def.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000011
12#include <arch_helpers.h>
13#include <common/bl_common.h>
14#include <lib/xlat_tables/xlat_tables_v2.h>
Jens Wiklanderf9198382022-01-17 09:48:28 +010015#include <services/el3_spmc_ffa_memory.h>
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +010016#if ENABLE_RME
17#include <services/rmm_core_manifest.h>
18#endif
Mathieu Poirieradfa7b32024-10-07 13:46:04 -060019#ifdef PLAT_qemu_sbsa
20#include <sbsa_platform.h>
21#endif
Antonio Nino Diaz61aff002018-10-19 16:52:22 +010022
Ruchika Gupta5c172532022-04-08 13:14:44 +053023#include <plat/common/platform.h>
Isla Mitchelle3631462017-07-14 10:46:32 +010024#include "qemu_private.h"
Jens Wiklander52c798e2015-12-07 14:37:10 +010025
26#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \
27 DEVICE0_SIZE, \
Jean-Philippe Bruckerb54f6c92023-09-07 17:46:12 +010028 MT_DEVICE | MT_RW | EL3_PAS)
Jens Wiklander52c798e2015-12-07 14:37:10 +010029
30#ifdef DEVICE1_BASE
31#define MAP_DEVICE1 MAP_REGION_FLAT(DEVICE1_BASE, \
32 DEVICE1_SIZE, \
Jean-Philippe Bruckerb54f6c92023-09-07 17:46:12 +010033 MT_DEVICE | MT_RW | EL3_PAS)
Jens Wiklander52c798e2015-12-07 14:37:10 +010034#endif
35
36#ifdef DEVICE2_BASE
37#define MAP_DEVICE2 MAP_REGION_FLAT(DEVICE2_BASE, \
38 DEVICE2_SIZE, \
Jean-Philippe Bruckerb54f6c92023-09-07 17:46:12 +010039 MT_DEVICE | MT_RW | EL3_PAS)
Jens Wiklander52c798e2015-12-07 14:37:10 +010040#endif
41
42#define MAP_SHARED_RAM MAP_REGION_FLAT(SHARED_RAM_BASE, \
43 SHARED_RAM_SIZE, \
Jean-Philippe Bruckerb54f6c92023-09-07 17:46:12 +010044 MT_DEVICE | MT_RW | EL3_PAS)
Jens Wiklander52c798e2015-12-07 14:37:10 +010045
46#define MAP_BL32_MEM MAP_REGION_FLAT(BL32_MEM_BASE, BL32_MEM_SIZE, \
Jean-Philippe Bruckerb54f6c92023-09-07 17:46:12 +010047 MT_MEMORY | MT_RW | EL3_PAS)
Jens Wiklander52c798e2015-12-07 14:37:10 +010048
49#define MAP_NS_DRAM0 MAP_REGION_FLAT(NS_DRAM0_BASE, NS_DRAM0_SIZE, \
50 MT_MEMORY | MT_RW | MT_NS)
51
52#define MAP_FLASH0 MAP_REGION_FLAT(QEMU_FLASH0_BASE, QEMU_FLASH0_SIZE, \
Jean-Philippe Bruckerb54f6c92023-09-07 17:46:12 +010053 MT_MEMORY | MT_RO | EL3_PAS)
Jens Wiklander52c798e2015-12-07 14:37:10 +010054
Radoslaw Biernacki7ed5e122018-06-07 20:14:36 +020055#define MAP_FLASH1 MAP_REGION_FLAT(QEMU_FLASH1_BASE, QEMU_FLASH1_SIZE, \
Jean-Philippe Bruckerb54f6c92023-09-07 17:46:12 +010056 MT_MEMORY | MT_RO | EL3_PAS)
Radoslaw Biernacki7ed5e122018-06-07 20:14:36 +020057
Raymond Mao032ba022023-06-28 15:07:15 -070058#ifdef FW_HANDOFF_BASE
59#define MAP_FW_HANDOFF MAP_REGION_FLAT(FW_HANDOFF_BASE, FW_HANDOFF_SIZE, \
Jean-Philippe Bruckerb54f6c92023-09-07 17:46:12 +010060 MT_MEMORY | MT_RW | EL3_PAS)
Raymond Mao032ba022023-06-28 15:07:15 -070061#endif
62#ifdef FW_NS_HANDOFF_BASE
63#define MAP_FW_NS_HANDOFF MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, FW_HANDOFF_SIZE, \
64 MT_MEMORY | MT_RW | MT_NS)
65#endif
Jens Wiklander52c798e2015-12-07 14:37:10 +010066/*
67 * Table of regions for various BL stages to map using the MMU.
68 * This doesn't include TZRAM as the 'mem_layout' argument passed to
69 * arm_configure_mmu_elx() will give the available subset of that,
70 */
Masahiro Yamada441bfdd2016-12-25 23:36:24 +090071#ifdef IMAGE_BL1
Jens Wiklander52c798e2015-12-07 14:37:10 +010072static const mmap_region_t plat_qemu_mmap[] = {
73 MAP_FLASH0,
Radoslaw Biernacki7ed5e122018-06-07 20:14:36 +020074 MAP_FLASH1,
Jens Wiklander52c798e2015-12-07 14:37:10 +010075 MAP_SHARED_RAM,
76 MAP_DEVICE0,
77#ifdef MAP_DEVICE1
78 MAP_DEVICE1,
79#endif
80#ifdef MAP_DEVICE2
81 MAP_DEVICE2,
82#endif
83 {0}
84};
85#endif
Masahiro Yamada441bfdd2016-12-25 23:36:24 +090086#ifdef IMAGE_BL2
Jens Wiklander52c798e2015-12-07 14:37:10 +010087static const mmap_region_t plat_qemu_mmap[] = {
88 MAP_FLASH0,
Radoslaw Biernacki7ed5e122018-06-07 20:14:36 +020089 MAP_FLASH1,
Jens Wiklander52c798e2015-12-07 14:37:10 +010090 MAP_SHARED_RAM,
91 MAP_DEVICE0,
92#ifdef MAP_DEVICE1
93 MAP_DEVICE1,
94#endif
95#ifdef MAP_DEVICE2
96 MAP_DEVICE2,
97#endif
98 MAP_NS_DRAM0,
Masahisa Kojima099064b2020-06-11 21:46:44 +090099#if SPM_MM
100 QEMU_SP_IMAGE_MMAP,
101#else
Jens Wiklander52c798e2015-12-07 14:37:10 +0100102 MAP_BL32_MEM,
Masahisa Kojima099064b2020-06-11 21:46:44 +0900103#endif
Raymond Mao032ba022023-06-28 15:07:15 -0700104#ifdef MAP_FW_HANDOFF
105 MAP_FW_HANDOFF,
106#endif
Jens Wiklander52c798e2015-12-07 14:37:10 +0100107 {0}
108};
109#endif
Masahiro Yamada441bfdd2016-12-25 23:36:24 +0900110#ifdef IMAGE_BL31
Jens Wiklander52c798e2015-12-07 14:37:10 +0100111static const mmap_region_t plat_qemu_mmap[] = {
112 MAP_SHARED_RAM,
113 MAP_DEVICE0,
114#ifdef MAP_DEVICE1
115 MAP_DEVICE1,
116#endif
Graeme Gregory6260ddd2020-12-16 12:11:06 +0000117#ifdef MAP_DEVICE2
118 MAP_DEVICE2,
119#endif
Raymond Mao032ba022023-06-28 15:07:15 -0700120#ifdef MAP_FW_HANDOFF
121 MAP_FW_HANDOFF,
122#endif
123#ifdef MAP_FW_NS_HANDOFF
124 MAP_FW_NS_HANDOFF,
125#endif
Masahisa Kojima099064b2020-06-11 21:46:44 +0900126#if SPM_MM
Masahisa Kojima7e917dc2020-09-23 16:52:59 +0900127 MAP_NS_DRAM0,
Masahisa Kojima099064b2020-06-11 21:46:44 +0900128 QEMU_SPM_BUF_EL3_MMAP,
Jens Wiklanderf9198382022-01-17 09:48:28 +0100129#elif !SPMC_AT_EL3
Jens Wiklander52c798e2015-12-07 14:37:10 +0100130 MAP_BL32_MEM,
Masahisa Kojima099064b2020-06-11 21:46:44 +0900131#endif
Jens Wiklander52c798e2015-12-07 14:37:10 +0100132 {0}
133};
134#endif
Etienne Carriere911de8c2018-02-02 13:23:22 +0100135#ifdef IMAGE_BL32
136static const mmap_region_t plat_qemu_mmap[] = {
137 MAP_SHARED_RAM,
138 MAP_DEVICE0,
139#ifdef MAP_DEVICE1
140 MAP_DEVICE1,
141#endif
Graeme Gregory6260ddd2020-12-16 12:11:06 +0000142#ifdef MAP_DEVICE2
143 MAP_DEVICE2,
144#endif
Etienne Carriere911de8c2018-02-02 13:23:22 +0100145 {0}
146};
147#endif
Jens Wiklander52c798e2015-12-07 14:37:10 +0100148
Jean-Philippe Brucker3e807552023-09-07 19:06:44 +0100149#ifdef IMAGE_RMM
150const mmap_region_t plat_qemu_mmap[] = {
151 MAP_DEVICE0,
152#ifdef MAP_DEVICE1
153 MAP_DEVICE1,
154#endif
155#ifdef MAP_DEVICE2
156 MAP_DEVICE2,
157#endif
158 {0}
159};
160#endif
161
Jens Wiklander52c798e2015-12-07 14:37:10 +0100162/*******************************************************************************
Chen Baozif7d9aa82023-02-20 10:50:15 +0000163 * Returns QEMU platform specific memory map regions.
Jens Wiklander52c798e2015-12-07 14:37:10 +0100164 ******************************************************************************/
Chen Baozif7d9aa82023-02-20 10:50:15 +0000165const mmap_region_t *plat_qemu_get_mmap(void)
166{
167 return plat_qemu_mmap;
168}
Jens Wiklander52c798e2015-12-07 14:37:10 +0100169
Ruchika Gupta5c172532022-04-08 13:14:44 +0530170#if MEASURED_BOOT || TRUSTED_BOARD_BOOT
171int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
172{
173 return get_mbedtls_heap_helper(heap_addr, heap_size);
174}
175#endif
Jens Wiklanderf9198382022-01-17 09:48:28 +0100176
177#if SPMC_AT_EL3
178/*
179 * When using the EL3 SPMC implementation allocate the datastore
180 * for tracking shared memory descriptors in normal memory.
181 */
182#define PLAT_SPMC_SHMEM_DATASTORE_SIZE 64 * 1024
183
Jens Wiklander0b425ef2024-11-01 15:58:28 +0100184uint8_t plat_spmc_shmem_datastore[PLAT_SPMC_SHMEM_DATASTORE_SIZE] __aligned(2 * sizeof(long));
Jens Wiklanderf9198382022-01-17 09:48:28 +0100185
186int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size)
187{
188 *datastore = plat_spmc_shmem_datastore;
189 *size = PLAT_SPMC_SHMEM_DATASTORE_SIZE;
190 return 0;
191}
192
193int plat_spmc_shmem_begin(struct ffa_mtd *desc)
194{
195 return 0;
196}
197
198int plat_spmc_shmem_reclaim(struct ffa_mtd *desc)
199{
200 return 0;
201}
202#endif
Madhukar Pappireddy042043b2023-03-02 16:33:25 -0600203
Jens Wiklander453fe322024-10-31 16:34:37 +0100204#if defined(SPD_spmd)
Madhukar Pappireddy042043b2023-03-02 16:33:25 -0600205int plat_spmd_handle_group0_interrupt(uint32_t intid)
206{
Jens Wiklander453fe322024-10-31 16:34:37 +0100207 /*
208 * Currently, there are no sources of Group0 secure interrupt
209 * enabled for QEMU.
210 */
Madhukar Pappireddy042043b2023-03-02 16:33:25 -0600211 (void)intid;
212 return -1;
213}
Jens Wiklander453fe322024-10-31 16:34:37 +0100214#endif /*defined(SPD_spmd)*/
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +0100215
216#if ENABLE_RME
217/*
218 * Get a pointer to the RMM-EL3 Shared buffer and return it
219 * through the pointer passed as parameter.
220 *
221 * This function returns the size of the shared buffer.
222 */
223size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared)
224{
225 *shared = (uintptr_t)RMM_SHARED_BASE;
226
227 return (size_t)RMM_SHARED_SIZE;
228}
Mathieu Poirieradfa7b32024-10-07 13:46:04 -0600229
230#ifdef PLAT_qemu
231static uint32_t plat_get_num_memnodes(void)
232{
233 return 1;
234}
235
Jens Wiklander9dc54512025-02-07 07:51:07 +0100236static void plat_get_memory_node(int index, struct memory_bank *bank_ptr)
Mathieu Poirieradfa7b32024-10-07 13:46:04 -0600237{
238 (void) index;
239 bank_ptr->base = NS_DRAM0_BASE;
240 bank_ptr->size = NS_DRAM0_SIZE;
241}
242#elif PLAT_qemu_sbsa
243static uint32_t plat_get_num_memnodes(void)
244{
245 return sbsa_platform_num_memnodes();
246}
247
Jens Wiklander9dc54512025-02-07 07:51:07 +0100248static void plat_get_memory_node(int index, struct memory_bank *bank_ptr)
Mathieu Poirieradfa7b32024-10-07 13:46:04 -0600249{
250 struct platform_memory_data data = {0, 0, 0};
251
252 if (index < sbsa_platform_num_memnodes()) {
253 data = sbsa_platform_memory_node(index);
254 }
255
256 bank_ptr->base = data.addr_base;
257 bank_ptr->size = data.addr_size;
258}
259#endif /* PLAT_qemu */
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +0100260
Jean-Philippe Bruckercaa32f12024-11-20 12:42:54 +0000261/*
262 * Calculate checksum of 64-bit words @buffer, of @size bytes
263 */
264static uint64_t checksum_calc(uint64_t *buffer, size_t size)
265{
266 uint64_t sum = 0UL;
267
268 assert(((uintptr_t)buffer & (sizeof(uint64_t) - 1UL)) == 0UL);
269 assert((size & (sizeof(uint64_t) - 1UL)) == 0UL);
270
271 for (unsigned long i = 0UL; i < (size / sizeof(uint64_t)); i++) {
272 sum += buffer[i];
273 }
274
275 return sum;
276}
277
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +0100278int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
279{
Mathieu Poirieradfa7b32024-10-07 13:46:04 -0600280 int i, last;
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +0100281 uint64_t checksum;
Mathieu Poirieradfa7b32024-10-07 13:46:04 -0600282 size_t num_banks = plat_get_num_memnodes();
Jean-Philippe Brucker2c7b22d2024-04-04 09:41:57 +0100283 size_t num_consoles = 1;
Jens Wiklander9dc54512025-02-07 07:51:07 +0100284 struct memory_bank *bank_ptr;
Jean-Philippe Brucker2c7b22d2024-04-04 09:41:57 +0100285 struct console_info *console_ptr;
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +0100286
287 assert(manifest != NULL);
288
289 manifest->version = RMMD_MANIFEST_VERSION;
290 manifest->padding = 0U; /* RES0 */
291 manifest->plat_data = (uintptr_t)NULL;
Jean-Philippe Brucker2c7b22d2024-04-04 09:41:57 +0100292 manifest->plat_dram.num_banks = num_banks;
293 manifest->plat_console.num_consoles = num_consoles;
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +0100294
295 /*
Jean-Philippe Brucker2c7b22d2024-04-04 09:41:57 +0100296 * Boot manifest structure illustration:
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +0100297 *
Jean-Philippe Brucker2c7b22d2024-04-04 09:41:57 +0100298 * +----------------------------------------+
299 * | offset | field | comment |
300 * +----------+--------------+--------------+
301 * | 0 | version | 0x00000003 |
302 * +----------+--------------+--------------+
303 * | 4 | padding | 0x00000000 |
304 * +----------+--------------+--------------+
305 * | 8 | plat_data | NULL |
306 * +----------+--------------+--------------+
307 * | 16 | num_banks | |
308 * +----------+--------------+ |
309 * | 24 | banks | plat_dram |
310 * +----------+--------------+ |
311 * | 32 | checksum | |
312 * +----------+--------------+--------------+
313 * | 40 | num_consoles | |
314 * +----------+--------------+ |
315 * | 48 | consoles | plat_console |
316 * +----------+--------------+ |
317 * | 56 | checksum | |
318 * +----------+--------------+--------------+
319 * | 64 | base 0 | |
320 * +----------+--------------+ bank[0] |
321 * | 72 | size 0 | |
322 * +----------+--------------+--------------+
323 * | 80 | base | |
324 * +----------+--------------+ |
325 * | 88 | map_pages | |
326 * +----------+--------------+ |
327 * | 96 | name | |
328 * +----------+--------------+ consoles[0] |
329 * | 104 | clk_in_hz | |
330 * +----------+--------------+ |
331 * | 112 | baud_rate | |
332 * +----------+--------------+ |
333 * | 120 | flags | |
334 * +----------+--------------+--------------+
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +0100335 */
Jens Wiklander9dc54512025-02-07 07:51:07 +0100336 bank_ptr = (struct memory_bank *)
Jean-Philippe Brucker2c7b22d2024-04-04 09:41:57 +0100337 (((uintptr_t)manifest) + sizeof(*manifest));
338
339 console_ptr = (struct console_info *)
340 ((uintptr_t)bank_ptr + (num_banks * sizeof(*bank_ptr)));
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +0100341
342 manifest->plat_dram.banks = bank_ptr;
Jean-Philippe Brucker2c7b22d2024-04-04 09:41:57 +0100343 manifest->plat_console.consoles = console_ptr;
344
345 /* Ensure the manifest is not larger than the shared buffer */
346 assert((sizeof(struct rmm_manifest) +
347 (sizeof(struct console_info) * num_consoles) +
Jens Wiklander9dc54512025-02-07 07:51:07 +0100348 (sizeof(struct memory_bank) * num_banks)) <= RMM_SHARED_SIZE);
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +0100349
350 /* Calculate checksum of plat_dram structure */
Jean-Philippe Brucker2c7b22d2024-04-04 09:41:57 +0100351 checksum = num_banks + (uint64_t)bank_ptr;
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +0100352
Mathieu Poirieradfa7b32024-10-07 13:46:04 -0600353 /*
354 * In the TF-A, NUMA nodes (if present) are stored in descending
355 * order, i.e:
356 *
357 * INFO: RAM 0: node-id: 1, address: 0x10080000000 - 0x101ffffffff
358 * INFO: RAM 1: node-id: 0, address: 0x10043000000 - 0x1007fffffff
359 *
360 * The RMM expects the memory banks to be presented in ascending order:
361 *
362 * INFO: RAM 1: node-id: 0, address: 0x10043000000 - 0x1007fffffff
363 * INFO: RAM 0: node-id: 1, address: 0x10080000000 - 0x101ffffffff
364 *
365 * As such, go through the NUMA nodes one by one and fill out
366 * @bank_ptr[] starting from the end. When NUMA nodes are not present
367 * there is only one memory bank and none of the above matters.
368 */
369 last = num_banks - 1;
370 for (i = 0; i < num_banks; i++) {
371 plat_get_memory_node(i, &bank_ptr[last]);
Mathieu Poirieradfa7b32024-10-07 13:46:04 -0600372 last--;
373 }
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +0100374
Jean-Philippe Bruckercaa32f12024-11-20 12:42:54 +0000375 checksum += checksum_calc((uint64_t *)bank_ptr,
376 num_banks * sizeof(*bank_ptr));
377
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +0100378 /* Checksum must be 0 */
379 manifest->plat_dram.checksum = ~checksum + 1UL;
380
Jean-Philippe Brucker2c7b22d2024-04-04 09:41:57 +0100381 /* Calculate the checksum of the plat_consoles structure */
382 checksum = num_consoles + (uint64_t)console_ptr;
383
384 /* Zero out the console info struct */
385 memset((void *)console_ptr, 0, sizeof(struct console_info) * num_consoles);
386
387 console_ptr[0].map_pages = 1;
388 console_ptr[0].base = PLAT_QEMU_BOOT_UART_BASE;
389 console_ptr[0].clk_in_hz = PLAT_QEMU_BOOT_UART_CLK_IN_HZ;
390 console_ptr[0].baud_rate = PLAT_QEMU_CONSOLE_BAUDRATE;
391
392 strlcpy(console_ptr[0].name, "pl011", sizeof(console_ptr[0].name));
393
394 /* Update checksum */
Jean-Philippe Bruckercaa32f12024-11-20 12:42:54 +0000395 checksum += checksum_calc((uint64_t *)console_ptr,
396 num_consoles * sizeof(*console_ptr));
Jean-Philippe Brucker2c7b22d2024-04-04 09:41:57 +0100397
398 /* Checksum must be 0 */
399 manifest->plat_console.checksum = ~checksum + 1UL;
400
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +0100401 return 0;
402}
Jean-Philippe Bruckerbafbaea2025-03-18 14:35:11 +0000403
404/*
405 * Update encryption key associated with @mecid.
406 */
407int plat_rmmd_mecid_key_update(uint16_t mecid)
408{
409 /*
410 * QEMU does not provide an interface to change the encryption key
411 * associated with MECID. Hence always return success.
412 */
413 return 0;
414}
Jean-Philippe Bruckerf304bd62023-09-07 17:33:22 +0100415#endif /* ENABLE_RME */
Mathieu Poirierdfbaf642024-10-10 15:07:49 -0600416
417/**
418 * plat_qemu_dt_runtime_address() - Get the final DT location in RAM
419 *
420 * When support is enabled on SBSA, the device tree is relocated from its
421 * original place at the beginning of the NS RAM to after the RMM. This
422 * function returns the address of the final location in RAM of the device
423 * tree. See function update_dt() in qemu_bl2_setup.c
424 *
425 * Return: The address of the final location in RAM of the device tree
426 */
427#if (ENABLE_RME && PLAT_qemu_sbsa)
428void *plat_qemu_dt_runtime_address(void)
429{
430 return (void *)(uintptr_t)PLAT_QEMU_DT_BASE;
431}
432#else
433void *plat_qemu_dt_runtime_address(void)
434{
435 return (void *)(uintptr_t)ARM_PRELOADED_DTB_BASE;
436}
437#endif /* (ENABLE_RME && PLAT_qemu_sbsa) */