SPM: Load image and RD from SP package
authorAntonio Nino Diaz <antonio.ninodiaz@arm.com>
Tue, 27 Nov 2018 08:36:02 +0000 (08:36 +0000)
committerAntonio Nino Diaz <antonio.ninodiaz@arm.com>
Tue, 11 Dec 2018 13:45:41 +0000 (13:45 +0000)
Load SP and RD from package instead of relying on RD being already
loaded in memory and the SP being loaded as a BL32 image.

Change-Id: I18d4fbf4597656c6a7e878e1d7c01a8a324f3f8a
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
include/plat/arm/common/arm_spm_def.h
include/plat/common/platform.h
plat/arm/board/fvp/fvp_common.c
plat/arm/board/fvp/include/platform_def.h
plat/arm/common/arm_common.mk
plat/common/plat_spm_sp.c [new file with mode: 0644]
services/std_svc/spm/spm_main.c
services/std_svc/spm/spm_private.h

index 6fa5615ea09d6d7833b722f81985ef5b25a65c34..8d17b90d93760e6ebda042beab988d50a6eaa3cc 100644 (file)
 #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
@@ -28,8 +53,6 @@
                                                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(                            \
index 79d069ad8d6d3470afb617d43185da7533b0ad98..04272b1b58f5627cd27d8cf5479dec49911a2cd5 100644 (file)
@@ -268,6 +268,8 @@ const struct mmap_region *plat_get_secure_partition_mmap(void *cookie);
 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).
index 66650eecd8d255bf530d793f2ba156a12433ad0e..f36b637ef1eb20b8009991e86b2910d9e7d432ef 100644 (file)
@@ -96,9 +96,12 @@ const mmap_region_t plat_arm_mmap[] = {
        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
@@ -126,6 +129,9 @@ const mmap_region_t plat_arm_mmap[] = {
        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}
 };
index 31c5fdfbf9a5c903c27a7efc4175db27a0a6c257..70e51fd95ae547ecb85d277192406067849e475a 100644 (file)
@@ -72,8 +72,8 @@
 #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
index 9f39d71ad4f6ea4ac661a01e256a47f8b82fabd5..24b61e8163211df153424c174c6dab956aa3e238 100644 (file)
@@ -249,6 +249,7 @@ ifeq (${SPM_DEPRECATED},0)
 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
diff --git a/plat/common/plat_spm_sp.c b/plat/common/plat_spm_sp.c
new file mode 100644 (file)
index 0000000..7b7fbd9
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * 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;
+}
index ad1262cbe61588b1372eec3b9e874d6d6eabb4c2..6de4858b0508630d8b4c832dc536e5cfd37ec4fb 100644 (file)
@@ -157,7 +157,10 @@ static int32_t spm_init(void)
  ******************************************************************************/
 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();
@@ -167,9 +170,26 @@ int32_t spm_setup(void)
 
        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.  */
index ec3f48ea28f55098212cf537ff3096a86239c1ed..ee13e94e73d4f522ad5a5ee20c9faa3cacd737a0 100644 (file)
@@ -32,6 +32,7 @@
 #ifndef __ASSEMBLY__
 
 #include <spinlock.h>
+#include <sp_res_desc.h>
 #include <stdint.h>
 #include <xlat_tables_v2.h>
 
@@ -42,9 +43,14 @@ typedef enum sp_state {
 } 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;