123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406 |
- /*
- * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #include <string.h>
- #include <platform_def.h>
- #include <arch_helpers.h>
- #include <common/bl_common.h>
- #include <lib/xlat_tables/xlat_tables_v2.h>
- #include <services/el3_spmc_ffa_memory.h>
- #if ENABLE_RME
- #include <services/rmm_core_manifest.h>
- #endif
- #ifdef PLAT_qemu_sbsa
- #include <sbsa_platform.h>
- #endif
- #include <plat/common/platform.h>
- #include "qemu_private.h"
- #define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \
- DEVICE0_SIZE, \
- MT_DEVICE | MT_RW | EL3_PAS)
- #ifdef DEVICE1_BASE
- #define MAP_DEVICE1 MAP_REGION_FLAT(DEVICE1_BASE, \
- DEVICE1_SIZE, \
- MT_DEVICE | MT_RW | EL3_PAS)
- #endif
- #ifdef DEVICE2_BASE
- #define MAP_DEVICE2 MAP_REGION_FLAT(DEVICE2_BASE, \
- DEVICE2_SIZE, \
- MT_DEVICE | MT_RW | EL3_PAS)
- #endif
- #define MAP_SHARED_RAM MAP_REGION_FLAT(SHARED_RAM_BASE, \
- SHARED_RAM_SIZE, \
- MT_DEVICE | MT_RW | EL3_PAS)
- #define MAP_BL32_MEM MAP_REGION_FLAT(BL32_MEM_BASE, BL32_MEM_SIZE, \
- MT_MEMORY | MT_RW | EL3_PAS)
- #define MAP_NS_DRAM0 MAP_REGION_FLAT(NS_DRAM0_BASE, NS_DRAM0_SIZE, \
- MT_MEMORY | MT_RW | MT_NS)
- #define MAP_FLASH0 MAP_REGION_FLAT(QEMU_FLASH0_BASE, QEMU_FLASH0_SIZE, \
- MT_MEMORY | MT_RO | EL3_PAS)
- #define MAP_FLASH1 MAP_REGION_FLAT(QEMU_FLASH1_BASE, QEMU_FLASH1_SIZE, \
- MT_MEMORY | MT_RO | EL3_PAS)
- #ifdef FW_HANDOFF_BASE
- #define MAP_FW_HANDOFF MAP_REGION_FLAT(FW_HANDOFF_BASE, FW_HANDOFF_SIZE, \
- MT_MEMORY | MT_RW | EL3_PAS)
- #endif
- #ifdef FW_NS_HANDOFF_BASE
- #define MAP_FW_NS_HANDOFF MAP_REGION_FLAT(FW_NS_HANDOFF_BASE, FW_HANDOFF_SIZE, \
- MT_MEMORY | MT_RW | MT_NS)
- #endif
- /*
- * Table of regions for various BL stages to map using the MMU.
- * This doesn't include TZRAM as the 'mem_layout' argument passed to
- * arm_configure_mmu_elx() will give the available subset of that,
- */
- #ifdef IMAGE_BL1
- static const mmap_region_t plat_qemu_mmap[] = {
- MAP_FLASH0,
- MAP_FLASH1,
- MAP_SHARED_RAM,
- MAP_DEVICE0,
- #ifdef MAP_DEVICE1
- MAP_DEVICE1,
- #endif
- #ifdef MAP_DEVICE2
- MAP_DEVICE2,
- #endif
- {0}
- };
- #endif
- #ifdef IMAGE_BL2
- static const mmap_region_t plat_qemu_mmap[] = {
- MAP_FLASH0,
- MAP_FLASH1,
- MAP_SHARED_RAM,
- MAP_DEVICE0,
- #ifdef MAP_DEVICE1
- MAP_DEVICE1,
- #endif
- #ifdef MAP_DEVICE2
- MAP_DEVICE2,
- #endif
- MAP_NS_DRAM0,
- #if SPM_MM
- QEMU_SP_IMAGE_MMAP,
- #else
- MAP_BL32_MEM,
- #endif
- #ifdef MAP_FW_HANDOFF
- MAP_FW_HANDOFF,
- #endif
- {0}
- };
- #endif
- #ifdef IMAGE_BL31
- static const mmap_region_t plat_qemu_mmap[] = {
- MAP_SHARED_RAM,
- MAP_DEVICE0,
- #ifdef MAP_DEVICE1
- MAP_DEVICE1,
- #endif
- #ifdef MAP_DEVICE2
- MAP_DEVICE2,
- #endif
- #ifdef MAP_FW_HANDOFF
- MAP_FW_HANDOFF,
- #endif
- #ifdef MAP_FW_NS_HANDOFF
- MAP_FW_NS_HANDOFF,
- #endif
- #if SPM_MM
- MAP_NS_DRAM0,
- QEMU_SPM_BUF_EL3_MMAP,
- #elif !SPMC_AT_EL3
- MAP_BL32_MEM,
- #endif
- {0}
- };
- #endif
- #ifdef IMAGE_BL32
- static const mmap_region_t plat_qemu_mmap[] = {
- MAP_SHARED_RAM,
- MAP_DEVICE0,
- #ifdef MAP_DEVICE1
- MAP_DEVICE1,
- #endif
- #ifdef MAP_DEVICE2
- MAP_DEVICE2,
- #endif
- {0}
- };
- #endif
- #ifdef IMAGE_RMM
- const mmap_region_t plat_qemu_mmap[] = {
- MAP_DEVICE0,
- #ifdef MAP_DEVICE1
- MAP_DEVICE1,
- #endif
- #ifdef MAP_DEVICE2
- MAP_DEVICE2,
- #endif
- {0}
- };
- #endif
- /*******************************************************************************
- * Returns QEMU platform specific memory map regions.
- ******************************************************************************/
- const mmap_region_t *plat_qemu_get_mmap(void)
- {
- return plat_qemu_mmap;
- }
- #if MEASURED_BOOT || TRUSTED_BOARD_BOOT
- int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
- {
- return get_mbedtls_heap_helper(heap_addr, heap_size);
- }
- #endif
- #if SPMC_AT_EL3
- /*
- * When using the EL3 SPMC implementation allocate the datastore
- * for tracking shared memory descriptors in normal memory.
- */
- #define PLAT_SPMC_SHMEM_DATASTORE_SIZE 64 * 1024
- uint8_t plat_spmc_shmem_datastore[PLAT_SPMC_SHMEM_DATASTORE_SIZE] __aligned(2 * sizeof(long));
- int plat_spmc_shmem_datastore_get(uint8_t **datastore, size_t *size)
- {
- *datastore = plat_spmc_shmem_datastore;
- *size = PLAT_SPMC_SHMEM_DATASTORE_SIZE;
- return 0;
- }
- int plat_spmc_shmem_begin(struct ffa_mtd *desc)
- {
- return 0;
- }
- int plat_spmc_shmem_reclaim(struct ffa_mtd *desc)
- {
- return 0;
- }
- #endif
- #if defined(SPD_spmd)
- int plat_spmd_handle_group0_interrupt(uint32_t intid)
- {
- /*
- * Currently, there are no sources of Group0 secure interrupt
- * enabled for QEMU.
- */
- (void)intid;
- return -1;
- }
- #endif /*defined(SPD_spmd)*/
- #if ENABLE_RME
- /*
- * Get a pointer to the RMM-EL3 Shared buffer and return it
- * through the pointer passed as parameter.
- *
- * This function returns the size of the shared buffer.
- */
- size_t plat_rmmd_get_el3_rmm_shared_mem(uintptr_t *shared)
- {
- *shared = (uintptr_t)RMM_SHARED_BASE;
- return (size_t)RMM_SHARED_SIZE;
- }
- #ifdef PLAT_qemu
- static uint32_t plat_get_num_memnodes(void)
- {
- return 1;
- }
- static void plat_get_memory_node(int index, struct ns_dram_bank *bank_ptr)
- {
- (void) index;
- bank_ptr->base = NS_DRAM0_BASE;
- bank_ptr->size = NS_DRAM0_SIZE;
- }
- #elif PLAT_qemu_sbsa
- static uint32_t plat_get_num_memnodes(void)
- {
- return sbsa_platform_num_memnodes();
- }
- static void plat_get_memory_node(int index, struct ns_dram_bank *bank_ptr)
- {
- struct platform_memory_data data = {0, 0, 0};
- if (index < sbsa_platform_num_memnodes()) {
- data = sbsa_platform_memory_node(index);
- }
- bank_ptr->base = data.addr_base;
- bank_ptr->size = data.addr_size;
- }
- #endif /* PLAT_qemu */
- int plat_rmmd_load_manifest(struct rmm_manifest *manifest)
- {
- int i, last;
- uint64_t checksum;
- size_t num_banks = plat_get_num_memnodes();
- size_t num_consoles = 1;
- struct ns_dram_bank *bank_ptr;
- struct console_info *console_ptr;
- assert(manifest != NULL);
- manifest->version = RMMD_MANIFEST_VERSION;
- manifest->padding = 0U; /* RES0 */
- manifest->plat_data = (uintptr_t)NULL;
- manifest->plat_dram.num_banks = num_banks;
- manifest->plat_console.num_consoles = num_consoles;
- /*
- * Boot manifest structure illustration:
- *
- * +----------------------------------------+
- * | offset | field | comment |
- * +----------+--------------+--------------+
- * | 0 | version | 0x00000003 |
- * +----------+--------------+--------------+
- * | 4 | padding | 0x00000000 |
- * +----------+--------------+--------------+
- * | 8 | plat_data | NULL |
- * +----------+--------------+--------------+
- * | 16 | num_banks | |
- * +----------+--------------+ |
- * | 24 | banks | plat_dram |
- * +----------+--------------+ |
- * | 32 | checksum | |
- * +----------+--------------+--------------+
- * | 40 | num_consoles | |
- * +----------+--------------+ |
- * | 48 | consoles | plat_console |
- * +----------+--------------+ |
- * | 56 | checksum | |
- * +----------+--------------+--------------+
- * | 64 | base 0 | |
- * +----------+--------------+ bank[0] |
- * | 72 | size 0 | |
- * +----------+--------------+--------------+
- * | 80 | base | |
- * +----------+--------------+ |
- * | 88 | map_pages | |
- * +----------+--------------+ |
- * | 96 | name | |
- * +----------+--------------+ consoles[0] |
- * | 104 | clk_in_hz | |
- * +----------+--------------+ |
- * | 112 | baud_rate | |
- * +----------+--------------+ |
- * | 120 | flags | |
- * +----------+--------------+--------------+
- */
- bank_ptr = (struct ns_dram_bank *)
- (((uintptr_t)manifest) + sizeof(*manifest));
- console_ptr = (struct console_info *)
- ((uintptr_t)bank_ptr + (num_banks * sizeof(*bank_ptr)));
- manifest->plat_dram.banks = bank_ptr;
- manifest->plat_console.consoles = console_ptr;
- /* Ensure the manifest is not larger than the shared buffer */
- assert((sizeof(struct rmm_manifest) +
- (sizeof(struct console_info) * num_consoles) +
- (sizeof(struct ns_dram_bank) * num_banks)) <= RMM_SHARED_SIZE);
- /* Calculate checksum of plat_dram structure */
- checksum = num_banks + (uint64_t)bank_ptr;
- /*
- * In the TF-A, NUMA nodes (if present) are stored in descending
- * order, i.e:
- *
- * INFO: RAM 0: node-id: 1, address: 0x10080000000 - 0x101ffffffff
- * INFO: RAM 1: node-id: 0, address: 0x10043000000 - 0x1007fffffff
- *
- * The RMM expects the memory banks to be presented in ascending order:
- *
- * INFO: RAM 1: node-id: 0, address: 0x10043000000 - 0x1007fffffff
- * INFO: RAM 0: node-id: 1, address: 0x10080000000 - 0x101ffffffff
- *
- * As such, go through the NUMA nodes one by one and fill out
- * @bank_ptr[] starting from the end. When NUMA nodes are not present
- * there is only one memory bank and none of the above matters.
- */
- last = num_banks - 1;
- for (i = 0; i < num_banks; i++) {
- plat_get_memory_node(i, &bank_ptr[last]);
- checksum += bank_ptr[last].base + bank_ptr[last].size;
- last--;
- }
- /* Checksum must be 0 */
- manifest->plat_dram.checksum = ~checksum + 1UL;
- /* Calculate the checksum of the plat_consoles structure */
- checksum = num_consoles + (uint64_t)console_ptr;
- /* Zero out the console info struct */
- memset((void *)console_ptr, 0, sizeof(struct console_info) * num_consoles);
- console_ptr[0].map_pages = 1;
- console_ptr[0].base = PLAT_QEMU_BOOT_UART_BASE;
- console_ptr[0].clk_in_hz = PLAT_QEMU_BOOT_UART_CLK_IN_HZ;
- console_ptr[0].baud_rate = PLAT_QEMU_CONSOLE_BAUDRATE;
- strlcpy(console_ptr[0].name, "pl011", sizeof(console_ptr[0].name));
- /* Update checksum */
- checksum += console_ptr[0].base + console_ptr[0].map_pages +
- console_ptr[0].clk_in_hz + console_ptr[0].baud_rate;
- /* Checksum must be 0 */
- manifest->plat_console.checksum = ~checksum + 1UL;
- return 0;
- }
- #endif /* ENABLE_RME */
- /**
- * plat_qemu_dt_runtime_address() - Get the final DT location in RAM
- *
- * When support is enabled on SBSA, the device tree is relocated from its
- * original place at the beginning of the NS RAM to after the RMM. This
- * function returns the address of the final location in RAM of the device
- * tree. See function update_dt() in qemu_bl2_setup.c
- *
- * Return: The address of the final location in RAM of the device tree
- */
- #if (ENABLE_RME && PLAT_qemu_sbsa)
- void *plat_qemu_dt_runtime_address(void)
- {
- return (void *)(uintptr_t)PLAT_QEMU_DT_BASE;
- }
- #else
- void *plat_qemu_dt_runtime_address(void)
- {
- return (void *)(uintptr_t)ARM_PRELOADED_DTB_BASE;
- }
- #endif /* (ENABLE_RME && PLAT_qemu_sbsa) */
|