16a2426a9SMasahisa Kojima /* SPDX-License-Identifier: BSD-3-Clause
26a2426a9SMasahisa Kojima *
36a2426a9SMasahisa Kojima * Copyright (c) 2020, Linaro Limited and Contributors. All rights reserved.
46a2426a9SMasahisa Kojima */
56a2426a9SMasahisa Kojima
674c87a4bSMasahisa Kojima #include <libfdt.h>
774c87a4bSMasahisa Kojima
86a2426a9SMasahisa Kojima #include <bl31/ehf.h>
974c87a4bSMasahisa Kojima #include <common/debug.h>
1074c87a4bSMasahisa Kojima #include <common/fdt_fixup.h>
1174c87a4bSMasahisa Kojima #include <common/fdt_wrappers.h>
1270524d3dSMarcin Juszkiewicz #include <lib/xlat_tables/xlat_tables_v2.h>
136a2426a9SMasahisa Kojima #include <services/spm_mm_partition.h>
146a2426a9SMasahisa Kojima
156a2426a9SMasahisa Kojima #include <platform_def.h>
166a2426a9SMasahisa Kojima
176a2426a9SMasahisa Kojima /* Region equivalent to MAP_DEVICE1 suitable for mapping at EL0 */
186a2426a9SMasahisa Kojima #define MAP_DEVICE1_EL0 MAP_REGION_FLAT(DEVICE1_BASE, \
196a2426a9SMasahisa Kojima DEVICE1_SIZE, \
206a2426a9SMasahisa Kojima MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
216a2426a9SMasahisa Kojima
2274c87a4bSMasahisa Kojima mmap_region_t plat_qemu_secure_partition_mmap[] = {
2374c87a4bSMasahisa Kojima QEMU_SP_IMAGE_NS_BUF_MMAP, /* must be placed at first entry */
246a2426a9SMasahisa Kojima MAP_DEVICE1_EL0, /* for the UART */
256a2426a9SMasahisa Kojima QEMU_SP_IMAGE_MMAP,
266a2426a9SMasahisa Kojima QEMU_SPM_BUF_EL0_MMAP,
276a2426a9SMasahisa Kojima QEMU_SP_IMAGE_RW_MMAP,
2874c87a4bSMasahisa Kojima MAP_SECURE_VARSTORE,
296a2426a9SMasahisa Kojima {0}
306a2426a9SMasahisa Kojima };
316a2426a9SMasahisa Kojima
32cf952b0fSMasahisa Kojima /* Boot information passed to a secure partition during initialisation. */
33cf952b0fSMasahisa Kojima static spm_mm_mp_info_t sp_mp_info[PLATFORM_CORE_COUNT];
346a2426a9SMasahisa Kojima
3574c87a4bSMasahisa Kojima spm_mm_boot_info_t plat_qemu_secure_partition_boot_info = {
366a2426a9SMasahisa Kojima .h.type = PARAM_SP_IMAGE_BOOT_INFO,
376a2426a9SMasahisa Kojima .h.version = VERSION_1,
386a2426a9SMasahisa Kojima .h.size = sizeof(spm_mm_boot_info_t),
396a2426a9SMasahisa Kojima .h.attr = 0,
406a2426a9SMasahisa Kojima .sp_mem_base = PLAT_QEMU_SP_IMAGE_BASE,
416a2426a9SMasahisa Kojima .sp_mem_limit = BL32_LIMIT,
426a2426a9SMasahisa Kojima .sp_image_base = PLAT_QEMU_SP_IMAGE_BASE,
436a2426a9SMasahisa Kojima .sp_stack_base = PLAT_SP_IMAGE_STACK_BASE,
446a2426a9SMasahisa Kojima .sp_heap_base = PLAT_QEMU_SP_IMAGE_HEAP_BASE,
456a2426a9SMasahisa Kojima .sp_ns_comm_buf_base = PLAT_QEMU_SP_IMAGE_NS_BUF_BASE,
466a2426a9SMasahisa Kojima .sp_shared_buf_base = PLAT_SPM_BUF_BASE,
476a2426a9SMasahisa Kojima .sp_image_size = PLAT_QEMU_SP_IMAGE_SIZE,
486a2426a9SMasahisa Kojima .sp_pcpu_stack_size = PLAT_SP_IMAGE_STACK_PCPU_SIZE,
496a2426a9SMasahisa Kojima .sp_heap_size = PLAT_QEMU_SP_IMAGE_HEAP_SIZE,
506a2426a9SMasahisa Kojima .sp_ns_comm_buf_size = PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE,
516a2426a9SMasahisa Kojima .sp_shared_buf_size = PLAT_SPM_BUF_SIZE,
526a2426a9SMasahisa Kojima .num_sp_mem_regions = PLAT_QEMU_SP_IMAGE_NUM_MEM_REGIONS,
536a2426a9SMasahisa Kojima .num_cpus = PLATFORM_CORE_COUNT,
546a2426a9SMasahisa Kojima .mp_info = sp_mp_info
556a2426a9SMasahisa Kojima };
566a2426a9SMasahisa Kojima
576a2426a9SMasahisa Kojima /* Enumeration of priority levels on QEMU platforms. */
586a2426a9SMasahisa Kojima ehf_pri_desc_t qemu_exceptions[] = {
596a2426a9SMasahisa Kojima EHF_PRI_DESC(QEMU_PRI_BITS, PLAT_SP_PRI)
606a2426a9SMasahisa Kojima };
616a2426a9SMasahisa Kojima
qemu_initialize_mp_info(spm_mm_mp_info_t * mp_info)62cf952b0fSMasahisa Kojima static void qemu_initialize_mp_info(spm_mm_mp_info_t *mp_info)
63cf952b0fSMasahisa Kojima {
64cf952b0fSMasahisa Kojima unsigned int i, j;
65cf952b0fSMasahisa Kojima spm_mm_mp_info_t *tmp = mp_info;
66cf952b0fSMasahisa Kojima
67cf952b0fSMasahisa Kojima for (i = 0; i < PLATFORM_CLUSTER_COUNT; i++) {
68cf952b0fSMasahisa Kojima for (j = 0; j < PLATFORM_MAX_CPUS_PER_CLUSTER; j++) {
69cf952b0fSMasahisa Kojima tmp->mpidr = (0x80000000 | (i << MPIDR_AFF1_SHIFT)) + j;
70cf952b0fSMasahisa Kojima /*
71cf952b0fSMasahisa Kojima * Linear indices and flags will be filled
72cf952b0fSMasahisa Kojima * in the spm_mm service.
73cf952b0fSMasahisa Kojima */
74cf952b0fSMasahisa Kojima tmp->linear_id = 0;
75cf952b0fSMasahisa Kojima tmp->flags = 0;
76cf952b0fSMasahisa Kojima tmp++;
77cf952b0fSMasahisa Kojima }
78cf952b0fSMasahisa Kojima }
79cf952b0fSMasahisa Kojima }
80cf952b0fSMasahisa Kojima
dt_add_ns_buf_node(uintptr_t * base)8174c87a4bSMasahisa Kojima int dt_add_ns_buf_node(uintptr_t *base)
8274c87a4bSMasahisa Kojima {
8374c87a4bSMasahisa Kojima uintptr_t addr;
8474c87a4bSMasahisa Kojima size_t size;
8574c87a4bSMasahisa Kojima uintptr_t ns_buf_addr;
8674c87a4bSMasahisa Kojima int node;
8774c87a4bSMasahisa Kojima int err;
8874c87a4bSMasahisa Kojima void *fdt = (void *)ARM_PRELOADED_DTB_BASE;
8974c87a4bSMasahisa Kojima
9074c87a4bSMasahisa Kojima err = fdt_open_into(fdt, fdt, PLAT_QEMU_DT_MAX_SIZE);
9174c87a4bSMasahisa Kojima if (err < 0) {
9274c87a4bSMasahisa Kojima ERROR("Invalid Device Tree at %p: error %d\n", fdt, err);
9374c87a4bSMasahisa Kojima return err;
9474c87a4bSMasahisa Kojima }
9574c87a4bSMasahisa Kojima
9674c87a4bSMasahisa Kojima /*
9774c87a4bSMasahisa Kojima * reserved-memory for standaloneMM non-secure buffer
9874c87a4bSMasahisa Kojima * is allocated at the top of the first system memory region.
9974c87a4bSMasahisa Kojima */
10074c87a4bSMasahisa Kojima node = fdt_path_offset(fdt, "/memory");
10174c87a4bSMasahisa Kojima
10274c87a4bSMasahisa Kojima err = fdt_get_reg_props_by_index(fdt, node, 0, &addr, &size);
10374c87a4bSMasahisa Kojima if (err < 0) {
10474c87a4bSMasahisa Kojima ERROR("Failed to get the memory node information\n");
10574c87a4bSMasahisa Kojima return err;
10674c87a4bSMasahisa Kojima }
10774c87a4bSMasahisa Kojima INFO("System RAM @ 0x%lx - 0x%lx\n", addr, addr + size - 1);
10874c87a4bSMasahisa Kojima
10974c87a4bSMasahisa Kojima ns_buf_addr = addr + (size - PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE);
11074c87a4bSMasahisa Kojima INFO("reserved-memory for spm-mm @ 0x%lx - 0x%llx\n", ns_buf_addr,
11174c87a4bSMasahisa Kojima ns_buf_addr + PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE - 1);
11274c87a4bSMasahisa Kojima
11374c87a4bSMasahisa Kojima err = fdt_add_reserved_memory(fdt, "ns-buf-spm-mm", ns_buf_addr,
11474c87a4bSMasahisa Kojima PLAT_QEMU_SP_IMAGE_NS_BUF_SIZE);
11574c87a4bSMasahisa Kojima if (err < 0) {
11674c87a4bSMasahisa Kojima ERROR("Failed to add the reserved-memory node\n");
11774c87a4bSMasahisa Kojima return err;
11874c87a4bSMasahisa Kojima }
11974c87a4bSMasahisa Kojima
12074c87a4bSMasahisa Kojima *base = ns_buf_addr;
12174c87a4bSMasahisa Kojima return 0;
12274c87a4bSMasahisa Kojima }
12374c87a4bSMasahisa Kojima
1246a2426a9SMasahisa Kojima /* Plug in QEMU exceptions to Exception Handling Framework. */
1256a2426a9SMasahisa Kojima EHF_REGISTER_PRIORITIES(qemu_exceptions, ARRAY_SIZE(qemu_exceptions),
1266a2426a9SMasahisa Kojima QEMU_PRI_BITS);
1276a2426a9SMasahisa Kojima
plat_get_secure_partition_mmap(void * cookie)1286a2426a9SMasahisa Kojima const mmap_region_t *plat_get_secure_partition_mmap(void *cookie)
1296a2426a9SMasahisa Kojima {
13074c87a4bSMasahisa Kojima uintptr_t ns_buf_base;
13174c87a4bSMasahisa Kojima
132*db0d5350SBoyan Karatotev if (dt_add_ns_buf_node(&ns_buf_base) != 0) {
133*db0d5350SBoyan Karatotev panic();
134*db0d5350SBoyan Karatotev }
13574c87a4bSMasahisa Kojima
13674c87a4bSMasahisa Kojima plat_qemu_secure_partition_mmap[0].base_pa = ns_buf_base;
13774c87a4bSMasahisa Kojima plat_qemu_secure_partition_mmap[0].base_va = ns_buf_base;
13874c87a4bSMasahisa Kojima plat_qemu_secure_partition_boot_info.sp_ns_comm_buf_base = ns_buf_base;
13974c87a4bSMasahisa Kojima
1406a2426a9SMasahisa Kojima return plat_qemu_secure_partition_mmap;
1416a2426a9SMasahisa Kojima }
1426a2426a9SMasahisa Kojima
1436a2426a9SMasahisa Kojima const spm_mm_boot_info_t *
plat_get_secure_partition_boot_info(void * cookie)1446a2426a9SMasahisa Kojima plat_get_secure_partition_boot_info(void *cookie)
1456a2426a9SMasahisa Kojima {
146cf952b0fSMasahisa Kojima qemu_initialize_mp_info(sp_mp_info);
147cf952b0fSMasahisa Kojima
1486a2426a9SMasahisa Kojima return &plat_qemu_secure_partition_boot_info;
1496a2426a9SMasahisa Kojima }
150