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 <antonio.ninodiaz@arm.com>
This commit is contained in:
parent
26010da116
commit
680389a65a
|
@ -10,6 +10,31 @@
|
||||||
#include <utils_def.h>
|
#include <utils_def.h>
|
||||||
#include <xlat_tables_defs.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
|
* 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
|
* 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)
|
MT_MEMORY | MT_RW | MT_SECURE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SPM_DEPRECATED
|
|
||||||
|
|
||||||
#ifdef IMAGE_BL31
|
#ifdef IMAGE_BL31
|
||||||
/* SPM Payload memory. Mapped as code in S-EL1 */
|
/* SPM Payload memory. Mapped as code in S-EL1 */
|
||||||
#define ARM_SP_IMAGE_MMAP MAP_REGION2( \
|
#define ARM_SP_IMAGE_MMAP MAP_REGION2( \
|
||||||
|
|
|
@ -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(
|
const struct secure_partition_boot_info *plat_get_secure_partition_boot_info(
|
||||||
void *cookie);
|
void *cookie);
|
||||||
int plat_spm_sp_rd_load(struct sp_res_desc *rd, const void *ptr, size_t size);
|
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).
|
* Mandatory BL image load functions(may be overridden).
|
||||||
|
|
|
@ -96,9 +96,12 @@ const mmap_region_t plat_arm_mmap[] = {
|
||||||
ARM_MAP_BL1_RW,
|
ARM_MAP_BL1_RW,
|
||||||
#endif
|
#endif
|
||||||
#endif /* TRUSTED_BOARD_BOOT */
|
#endif /* TRUSTED_BOARD_BOOT */
|
||||||
#if ENABLE_SPM
|
#if ENABLE_SPM && SPM_DEPRECATED
|
||||||
ARM_SP_IMAGE_MMAP,
|
ARM_SP_IMAGE_MMAP,
|
||||||
#endif
|
#endif
|
||||||
|
#if ENABLE_SPM && !SPM_DEPRECATED
|
||||||
|
PLAT_MAP_SP_PACKAGE_MEM_RW,
|
||||||
|
#endif
|
||||||
#if ARM_BL31_IN_DRAM
|
#if ARM_BL31_IN_DRAM
|
||||||
ARM_MAP_BL31_SEC_DRAM,
|
ARM_MAP_BL31_SEC_DRAM,
|
||||||
#endif
|
#endif
|
||||||
|
@ -126,6 +129,9 @@ const mmap_region_t plat_arm_mmap[] = {
|
||||||
ARM_V2M_MAP_MEM_PROTECT,
|
ARM_V2M_MAP_MEM_PROTECT,
|
||||||
#if ENABLE_SPM && SPM_DEPRECATED
|
#if ENABLE_SPM && SPM_DEPRECATED
|
||||||
ARM_SPM_BUF_EL3_MMAP,
|
ARM_SPM_BUF_EL3_MMAP,
|
||||||
|
#endif
|
||||||
|
#if ENABLE_SPM && !SPM_DEPRECATED
|
||||||
|
PLAT_MAP_SP_PACKAGE_MEM_RO,
|
||||||
#endif
|
#endif
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
|
@ -72,8 +72,8 @@
|
||||||
#if defined(IMAGE_BL31)
|
#if defined(IMAGE_BL31)
|
||||||
# if ENABLE_SPM
|
# if ENABLE_SPM
|
||||||
# define PLAT_ARM_MMAP_ENTRIES 9
|
# define PLAT_ARM_MMAP_ENTRIES 9
|
||||||
# define MAX_XLAT_TABLES 7
|
# define MAX_XLAT_TABLES 9
|
||||||
# define PLAT_SP_IMAGE_MMAP_REGIONS 7
|
# define PLAT_SP_IMAGE_MMAP_REGIONS 30
|
||||||
# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
|
# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
|
||||||
# else
|
# else
|
||||||
# define PLAT_ARM_MMAP_ENTRIES 8
|
# define PLAT_ARM_MMAP_ENTRIES 8
|
||||||
|
|
|
@ -249,6 +249,7 @@ ifeq (${SPM_DEPRECATED},0)
|
||||||
ifeq (${ENABLE_SPM},1)
|
ifeq (${ENABLE_SPM},1)
|
||||||
BL31_SOURCES += common/fdt_wrappers.c \
|
BL31_SOURCES += common/fdt_wrappers.c \
|
||||||
plat/common/plat_spm_rd.c \
|
plat/common/plat_spm_rd.c \
|
||||||
|
plat/common/plat_spm_sp.c \
|
||||||
${LIBFDT_SRCS}
|
${LIBFDT_SRCS}
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -157,7 +157,10 @@ static int32_t spm_init(void)
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
int32_t spm_setup(void)
|
int32_t spm_setup(void)
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
sp_context_t *ctx;
|
sp_context_t *ctx;
|
||||||
|
void *sp_base, *rd_base;
|
||||||
|
size_t sp_size, rd_size;
|
||||||
|
|
||||||
/* Disable MMU at EL1 (initialized by BL2) */
|
/* Disable MMU at EL1 (initialized by BL2) */
|
||||||
disable_mmu_icache_el1();
|
disable_mmu_icache_el1();
|
||||||
|
@ -167,9 +170,26 @@ int32_t spm_setup(void)
|
||||||
|
|
||||||
ctx = &sp_ctx;
|
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. */
|
/* Assign translation tables context. */
|
||||||
ctx->xlat_ctx_handle = spm_get_sp_xlat_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);
|
spm_sp_setup(ctx);
|
||||||
|
|
||||||
/* Register init function for deferred init. */
|
/* Register init function for deferred init. */
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
#include <spinlock.h>
|
#include <spinlock.h>
|
||||||
|
#include <sp_res_desc.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <xlat_tables_v2.h>
|
#include <xlat_tables_v2.h>
|
||||||
|
|
||||||
|
@ -42,9 +43,14 @@ typedef enum sp_state {
|
||||||
} sp_state_t;
|
} sp_state_t;
|
||||||
|
|
||||||
typedef struct sp_context {
|
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;
|
uint64_t c_rt_ctx;
|
||||||
cpu_context_t cpu_ctx;
|
cpu_context_t cpu_ctx;
|
||||||
xlat_ctx_t *xlat_ctx_handle;
|
xlat_ctx_t *xlat_ctx_handle;
|
||||||
|
struct sp_res_desc rd;
|
||||||
|
|
||||||
sp_state_t state;
|
sp_state_t state;
|
||||||
spinlock_t state_lock;
|
spinlock_t state_lock;
|
||||||
|
|
Loading…
Reference in New Issue