From 680389a65a004d2af007abccf0a0352f2c0eb529 Mon Sep 17 00:00:00 2001 From: Antonio Nino Diaz Date: Tue, 27 Nov 2018 08:36:02 +0000 Subject: [PATCH] SPM: Load image and RD from SP package 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 --- include/plat/arm/common/arm_spm_def.h | 27 ++++++- include/plat/common/platform.h | 2 + plat/arm/board/fvp/fvp_common.c | 8 +- plat/arm/board/fvp/include/platform_def.h | 4 +- plat/arm/common/arm_common.mk | 1 + plat/common/plat_spm_sp.c | 90 +++++++++++++++++++++++ services/std_svc/spm/spm_main.c | 20 +++++ services/std_svc/spm/spm_private.h | 6 ++ 8 files changed, 153 insertions(+), 5 deletions(-) create mode 100644 plat/common/plat_spm_sp.c diff --git a/include/plat/arm/common/arm_spm_def.h b/include/plat/arm/common/arm_spm_def.h index 6fa5615ea..8d17b90d9 100644 --- a/include/plat/arm/common/arm_spm_def.h +++ b/include/plat/arm/common/arm_spm_def.h @@ -10,6 +10,31 @@ #include #include +/* + * 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( \ diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 79d069ad8..04272b1b5 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -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). diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index 66650eecd..f36b637ef 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -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} }; diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 31c5fdfbf..70e51fd95 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -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 diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 9f39d71ad..24b61e816 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -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 index 000000000..7b7fbd987 --- /dev/null +++ b/plat/common/plat_spm_sp.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2018, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include + +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; +} diff --git a/services/std_svc/spm/spm_main.c b/services/std_svc/spm/spm_main.c index ad1262cbe..6de4858b0 100644 --- a/services/std_svc/spm/spm_main.c +++ b/services/std_svc/spm/spm_main.c @@ -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. */ diff --git a/services/std_svc/spm/spm_private.h b/services/std_svc/spm/spm_private.h index ec3f48ea2..ee13e94e7 100644 --- a/services/std_svc/spm/spm_private.h +++ b/services/std_svc/spm/spm_private.h @@ -32,6 +32,7 @@ #ifndef __ASSEMBLY__ #include +#include #include #include @@ -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;