#include <utils_def.h>
#include <xlat_tables_defs.h>
+/*
+ * Reserve 4 MiB for binaries of Secure Partitions and Resource Description
+ * blobs.
+ */
+#define PLAT_SP_PACKAGE_BASE BL32_BASE
+#define PLAT_SP_PACKAGE_SIZE ULL(0x400000)
+
+#define PLAT_MAP_SP_PACKAGE_MEM_RO MAP_REGION_FLAT( \
+ PLAT_SP_PACKAGE_BASE, \
+ PLAT_SP_PACKAGE_SIZE, \
+ MT_MEMORY | MT_RO | MT_SECURE)
+#define PLAT_MAP_SP_PACKAGE_MEM_RW MAP_REGION_FLAT( \
+ PLAT_SP_PACKAGE_BASE, \
+ PLAT_SP_PACKAGE_SIZE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
+/*
+ * The rest of the memory reserved for BL32 is free for SPM to use it as memory
+ * pool to allocate memory regions requested in the resource description.
+ */
+#define PLAT_SPM_HEAP_BASE (PLAT_SP_PACKAGE_BASE + PLAT_SP_PACKAGE_SIZE)
+#define PLAT_SPM_HEAP_SIZE (BL32_LIMIT - BL32_BASE - PLAT_SP_PACKAGE_SIZE)
+
+#if SPM_DEPRECATED
+
/*
* If BL31 is placed in DRAM, place the Secure Partition in DRAM right after the
* region used by BL31. If BL31 it is placed in SRAM, put the Secure Partition
MT_MEMORY | MT_RW | MT_SECURE)
#endif
-#if SPM_DEPRECATED
-
#ifdef IMAGE_BL31
/* SPM Payload memory. Mapped as code in S-EL1 */
#define ARM_SP_IMAGE_MMAP MAP_REGION2( \
const struct secure_partition_boot_info *plat_get_secure_partition_boot_info(
void *cookie);
int plat_spm_sp_rd_load(struct sp_res_desc *rd, const void *ptr, size_t size);
+int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size,
+ void **rd_base, size_t *rd_size);
/*******************************************************************************
* Mandatory BL image load functions(may be overridden).
ARM_MAP_BL1_RW,
#endif
#endif /* TRUSTED_BOARD_BOOT */
-#if ENABLE_SPM
+#if ENABLE_SPM && SPM_DEPRECATED
ARM_SP_IMAGE_MMAP,
#endif
+#if ENABLE_SPM && !SPM_DEPRECATED
+ PLAT_MAP_SP_PACKAGE_MEM_RW,
+#endif
#if ARM_BL31_IN_DRAM
ARM_MAP_BL31_SEC_DRAM,
#endif
ARM_V2M_MAP_MEM_PROTECT,
#if ENABLE_SPM && SPM_DEPRECATED
ARM_SPM_BUF_EL3_MMAP,
+#endif
+#if ENABLE_SPM && !SPM_DEPRECATED
+ PLAT_MAP_SP_PACKAGE_MEM_RO,
#endif
{0}
};
#if defined(IMAGE_BL31)
# if ENABLE_SPM
# define PLAT_ARM_MMAP_ENTRIES 9
-# define MAX_XLAT_TABLES 7
-# define PLAT_SP_IMAGE_MMAP_REGIONS 7
+# define MAX_XLAT_TABLES 9
+# define PLAT_SP_IMAGE_MMAP_REGIONS 30
# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
# else
# define PLAT_ARM_MMAP_ENTRIES 8
ifeq (${ENABLE_SPM},1)
BL31_SOURCES += common/fdt_wrappers.c \
plat/common/plat_spm_rd.c \
+ plat/common/plat_spm_sp.c \
${LIBFDT_SRCS}
endif
endif
--- /dev/null
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <platform_def.h>
+#include <sptool.h>
+
+static unsigned int sp_next;
+
+/*******************************************************************************
+ * Platform handler get the address of a Secure Partition and its resource
+ * description blob. It iterates through all SPs detected by the platform. If
+ * there is information for another SP, it returns 0. If there are no more SPs,
+ * it returns -1.
+ ******************************************************************************/
+int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size,
+ void **rd_base, size_t *rd_size)
+{
+ assert((sp_base != NULL) && (sp_size != NULL));
+ assert((rd_base != NULL) && (rd_base != NULL));
+
+ const uint64_t *pkg_base = (uint64_t *)PLAT_SP_PACKAGE_BASE;
+
+ struct sp_pkg_header *pkg_header = (struct sp_pkg_header *)pkg_base;
+
+ if (sp_next == 0) {
+ if (pkg_header->version != 0x1) {
+ ERROR("SP package has an unsupported version 0x%llx\n",
+ pkg_header->version);
+ panic();
+ }
+ }
+
+ if (sp_next >= pkg_header->number_of_sp) {
+ /* No more partitions in the package */
+ return -1;
+ }
+
+ const struct sp_pkg_entry *entry_list =
+ (const struct sp_pkg_entry *)((uintptr_t)pkg_base
+ + sizeof(struct sp_pkg_header));
+
+ const struct sp_pkg_entry *entry = &(entry_list[sp_next]);
+
+ uint64_t sp_offset = entry->sp_offset;
+ uint64_t rd_offset = entry->rd_offset;
+
+ uintptr_t pkg_sp_base = ((uintptr_t)PLAT_SP_PACKAGE_BASE + sp_offset);
+ uintptr_t pkg_rd_base = ((uintptr_t)PLAT_SP_PACKAGE_BASE + rd_offset);
+
+ uint64_t pkg_sp_size = entry->sp_size;
+ uint64_t pkg_rd_size = entry->rd_size;
+
+ uintptr_t pkg_end = (uintptr_t)PLAT_SP_PACKAGE_BASE
+ + (uintptr_t)PLAT_SP_PACKAGE_SIZE - 1U;
+
+ /*
+ * Check for overflows. The package header isn't trusted, so assert()
+ * can't be used here.
+ */
+
+ uintptr_t pkg_sp_end = pkg_sp_base + pkg_sp_size - 1U;
+ uintptr_t pkg_rd_end = pkg_rd_base + pkg_rd_size - 1U;
+
+ if ((pkg_sp_end > pkg_end) || (pkg_sp_end < pkg_sp_base)) {
+ ERROR("Invalid Secure Partition size (0x%llx)\n", pkg_sp_size);
+ panic();
+ }
+
+ if ((pkg_rd_end > pkg_end) || (pkg_rd_end < pkg_rd_base)) {
+ ERROR("Invalid Resource Description blob size (0x%llx)\n",
+ pkg_rd_size);
+ panic();
+ }
+
+ /* Return location of the binaries. */
+
+ *sp_base = (void *)pkg_sp_base;
+ *sp_size = pkg_sp_size;
+ *rd_base = (void *)pkg_rd_base;
+ *rd_size = pkg_rd_size;
+
+ sp_next++;
+
+ return 0;
+}
******************************************************************************/
int32_t spm_setup(void)
{
+ int rc;
sp_context_t *ctx;
+ void *sp_base, *rd_base;
+ size_t sp_size, rd_size;
/* Disable MMU at EL1 (initialized by BL2) */
disable_mmu_icache_el1();
ctx = &sp_ctx;
+ rc = plat_spm_sp_get_next_address(&sp_base, &sp_size,
+ &rd_base, &rd_size);
+ if (rc != 0) {
+ ERROR("No Secure Partition found.\n");
+ panic();
+ }
+
/* Assign translation tables context. */
ctx->xlat_ctx_handle = spm_get_sp_xlat_context();
+ /* Save location of the image in physical memory */
+ ctx->image_base = (uintptr_t)sp_base;
+ ctx->image_size = sp_size;
+
+ rc = plat_spm_sp_rd_load(&ctx->rd, rd_base, rd_size);
+ if (rc < 0) {
+ ERROR("Error while loading RD blob.\n");
+ panic();
+ }
+
spm_sp_setup(ctx);
/* Register init function for deferred init. */
#ifndef __ASSEMBLY__
#include <spinlock.h>
+#include <sp_res_desc.h>
#include <stdint.h>
#include <xlat_tables_v2.h>
} sp_state_t;
typedef struct sp_context {
+ /* Location of the image in physical memory */
+ unsigned long long image_base;
+ size_t image_size;
+
uint64_t c_rt_ctx;
cpu_context_t cpu_ctx;
xlat_ctx_t *xlat_ctx_handle;
+ struct sp_res_desc rd;
sp_state_t state;
spinlock_t state_lock;