mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-17 01:54:22 +00:00
SPM: FVP: Introduce port of SPM
This initial port of the Secure Partitions Manager to FVP supports BL31 in both SRAM and Trusted DRAM. A document with instructions to build the SPM has been added. Change-Id: I4ea83ff0a659be77f2cd72eaf2302cdf8ba98b32 Co-authored-by: Douglas Raillard <douglas.raillard@arm.com> Co-authored-by: Sandrine Bailleux <sandrine.bailleux@arm.com> Co-authored-by: Achin Gupta <achin.gupta@arm.com> Co-authored-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com> Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
This commit is contained in:
parent
2fccb22804
commit
e29efeb1b4
8 changed files with 297 additions and 8 deletions
59
docs/spm-user-guide.rst
Normal file
59
docs/spm-user-guide.rst
Normal file
|
@ -0,0 +1,59 @@
|
|||
ARM Trusted Firmware - SPM User Guide
|
||||
=====================================
|
||||
|
||||
.. section-numbering::
|
||||
:suffix: .
|
||||
|
||||
.. contents::
|
||||
|
||||
|
||||
This document briefly presents the Secure Partition Management (SPM) support in
|
||||
the Arm Trusted Firmware (TF), specifically focusing on how to build Arm TF with
|
||||
SPM support.
|
||||
|
||||
Overview of the SPM software stack
|
||||
----------------------------------
|
||||
|
||||
SPM is supported on the Arm FVP exclusively at the moment.
|
||||
|
||||
It is not currently possible for BL31 to integrate SPM support and a Secure
|
||||
Payload Dispatcher (SPD) at the same time; they are mutually exclusive. In the
|
||||
SPM bootflow, a Secure Partition (SP) image executing at Secure-EL0 replaces the
|
||||
Secure Payload image executing at Secure-EL1 (e.g. a Trusted OS). Both are
|
||||
referred to as BL32.
|
||||
|
||||
A working prototype of a SP has been implemented by repurposing the EDK2 code
|
||||
and tools, leveraging the concept of the *Standalone Management Mode (MM)* in
|
||||
the UEFI specification (see the PI v1.6 Volume 4: Management Mode Core
|
||||
Interface). This will be referred to as the *Standalone MM Secure Partition* in
|
||||
the rest of this document.
|
||||
|
||||
|
||||
Building TF with SPM support
|
||||
----------------------------
|
||||
|
||||
To enable SPM support in the TF, the source code must be compiled with the build
|
||||
flag ``ENABLE_SPM=1``. On Arm platforms the build option ``ARM_BL31_IN_DRAM``
|
||||
can be used to select the location of BL31, both SRAM and DRAM are supported.
|
||||
|
||||
|
||||
Using the Standalone MM SP
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
First, build the Standalone MM Secure Partition. To build it, refer to the
|
||||
`instructions in the EDK2 repository`_.
|
||||
|
||||
Then build TF with SPM support and include the Standalone MM Secure Partition
|
||||
image in the FIP:
|
||||
|
||||
::
|
||||
|
||||
BL32=path/to/standalone/mm/sp BL33=path/to/bl33.bin \
|
||||
make PLAT=fvp ENABLE_SPM=1 fip all
|
||||
|
||||
|
||||
--------------
|
||||
|
||||
*Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.*
|
||||
|
||||
.. _instructions in the EDK2 repository: https://github.com/tianocore/edk2-staging/blob/AArch64StandaloneMm/HowtoBuild.MD
|
|
@ -52,7 +52,17 @@
|
|||
* They are also used for the dynamically mapped regions in the images that
|
||||
* enable dynamic memory mapping.
|
||||
*/
|
||||
#if defined(IMAGE_BL31) || defined(IMAGE_BL32)
|
||||
#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 PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
|
||||
# else
|
||||
# define PLAT_ARM_MMAP_ENTRIES 7
|
||||
# define MAX_XLAT_TABLES 5
|
||||
# endif
|
||||
#elif defined(IMAGE_BL32)
|
||||
# define PLAT_ARM_MMAP_ENTRIES 7
|
||||
# define MAX_XLAT_TABLES 5
|
||||
#else
|
||||
|
@ -80,7 +90,11 @@
|
|||
* PLAT_ARM_MAX_BL31_SIZE is calculated using the current BL31 debug size plus a
|
||||
* little space for growth.
|
||||
*/
|
||||
#if ENABLE_SPM
|
||||
#define PLAT_ARM_MAX_BL31_SIZE 0x28000
|
||||
#else
|
||||
#define PLAT_ARM_MAX_BL31_SIZE 0x1D000
|
||||
#endif
|
||||
|
||||
#endif /* ARM_BOARD_OPTIMISE_MEM */
|
||||
|
||||
|
|
|
@ -121,6 +121,11 @@
|
|||
V2M_IOFPGA_SIZE, \
|
||||
MT_DEVICE | MT_RW | MT_SECURE)
|
||||
|
||||
/* Region equivalent to V2M_MAP_IOFPGA suitable for mapping at EL0 */
|
||||
#define V2M_MAP_IOFPGA_EL0 MAP_REGION_FLAT( \
|
||||
V2M_IOFPGA_BASE, \
|
||||
V2M_IOFPGA_SIZE, \
|
||||
MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
|
||||
|
||||
|
||||
#endif /* __V2M_DEF_H__ */
|
||||
|
|
|
@ -378,7 +378,13 @@
|
|||
* Trusted DRAM (if available) or the DRAM region secured by the TrustZone
|
||||
* controller.
|
||||
*/
|
||||
#if ARM_BL31_IN_DRAM
|
||||
#if ENABLE_SPM
|
||||
# define TSP_SEC_MEM_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
|
||||
# define TSP_SEC_MEM_SIZE (ARM_AP_TZC_DRAM1_SIZE - ULL(0x200000))
|
||||
# define BL32_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
|
||||
# define BL32_LIMIT (ARM_AP_TZC_DRAM1_BASE + \
|
||||
ARM_AP_TZC_DRAM1_SIZE)
|
||||
#elif ARM_BL31_IN_DRAM
|
||||
# define TSP_SEC_MEM_BASE (ARM_AP_TZC_DRAM1_BASE + \
|
||||
PLAT_ARM_MAX_BL31_SIZE)
|
||||
# define TSP_SEC_MEM_SIZE (ARM_AP_TZC_DRAM1_SIZE - \
|
||||
|
@ -409,11 +415,14 @@
|
|||
# error "Unsupported ARM_TSP_RAM_LOCATION_ID value"
|
||||
#endif
|
||||
|
||||
/* BL32 is mandatory in AArch32 */
|
||||
/*
|
||||
* BL32 is mandatory in AArch32. In AArch64, undefine BL32_BASE if there is no
|
||||
* SPD and no SPM, as they are the only ones that can be used as BL32.
|
||||
*/
|
||||
#ifndef AARCH32
|
||||
#ifdef SPD_none
|
||||
#undef BL32_BASE
|
||||
#endif /* SPD_none */
|
||||
# if defined(SPD_none) && !ENABLE_SPM
|
||||
# undef BL32_BASE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
105
include/plat/arm/common/arm_spm_def.h
Normal file
105
include/plat/arm/common/arm_spm_def.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#ifndef __ARM_SPM_DEF_H__
|
||||
#define __ARM_SPM_DEF_H__
|
||||
|
||||
#include <arm_def.h>
|
||||
#include <platform_def.h>
|
||||
#include <utils_def.h>
|
||||
#include <xlat_tables_defs.h>
|
||||
|
||||
/*
|
||||
* 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
|
||||
* at the base of DRAM.
|
||||
*/
|
||||
#define ARM_SP_IMAGE_BASE BL32_BASE
|
||||
#define ARM_SP_IMAGE_LIMIT BL32_LIMIT
|
||||
/* The maximum size of the S-EL0 payload can be 3MB */
|
||||
#define ARM_SP_IMAGE_SIZE ULL(0x300000)
|
||||
|
||||
#ifdef IMAGE_BL2
|
||||
/* SPM Payload memory. Mapped as RW in BL2. */
|
||||
#define ARM_SP_IMAGE_MMAP MAP_REGION_FLAT( \
|
||||
ARM_SP_IMAGE_BASE, \
|
||||
ARM_SP_IMAGE_SIZE, \
|
||||
MT_MEMORY | MT_RW | MT_SECURE)
|
||||
#endif
|
||||
#ifdef IMAGE_BL31
|
||||
/* SPM Payload memory. Mapped as code in S-EL1 */
|
||||
#define ARM_SP_IMAGE_MMAP MAP_REGION2( \
|
||||
ARM_SP_IMAGE_BASE, \
|
||||
ARM_SP_IMAGE_BASE, \
|
||||
ARM_SP_IMAGE_SIZE, \
|
||||
MT_CODE | MT_SECURE | MT_USER, \
|
||||
PAGE_SIZE)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Memory shared between EL3 and S-EL0. It is used by EL3 to push data into
|
||||
* S-EL0, so it is mapped with RW permission from EL3 and with RO permission
|
||||
* from S-EL0. Placed after SPM Payload memory.
|
||||
*/
|
||||
#define PLAT_SPM_BUF_BASE (ARM_SP_IMAGE_BASE + ARM_SP_IMAGE_SIZE)
|
||||
#define PLAT_SPM_BUF_SIZE ULL(0x100000)
|
||||
|
||||
#define ARM_SPM_BUF_EL3_MMAP MAP_REGION_FLAT( \
|
||||
PLAT_SPM_BUF_BASE, \
|
||||
PLAT_SPM_BUF_SIZE, \
|
||||
MT_RW_DATA | MT_SECURE)
|
||||
#define ARM_SPM_BUF_EL0_MMAP MAP_REGION2( \
|
||||
PLAT_SPM_BUF_BASE, \
|
||||
PLAT_SPM_BUF_BASE, \
|
||||
PLAT_SPM_BUF_SIZE, \
|
||||
MT_RO_DATA | MT_SECURE | MT_USER,\
|
||||
PAGE_SIZE)
|
||||
|
||||
/*
|
||||
* Memory shared between Normal world and S-EL0 for passing data during service
|
||||
* requests. Mapped as RW and NS. Placed after the shared memory between EL3 and
|
||||
* S-EL0.
|
||||
*/
|
||||
#define ARM_SP_IMAGE_NS_BUF_BASE (PLAT_SPM_BUF_BASE + PLAT_SPM_BUF_SIZE)
|
||||
#define ARM_SP_IMAGE_NS_BUF_SIZE ULL(0x10000)
|
||||
#define ARM_SP_IMAGE_NS_BUF_MMAP MAP_REGION2( \
|
||||
ARM_SP_IMAGE_NS_BUF_BASE, \
|
||||
ARM_SP_IMAGE_NS_BUF_BASE, \
|
||||
ARM_SP_IMAGE_NS_BUF_SIZE, \
|
||||
MT_RW_DATA | MT_NS | MT_USER, \
|
||||
PAGE_SIZE)
|
||||
|
||||
/*
|
||||
* RW memory, which uses the remaining Trusted DRAM. Placed after the memory
|
||||
* shared between Secure and Non-secure worlds. First there is the stack memory
|
||||
* for all CPUs and then there is the common heap memory. Both are mapped with
|
||||
* RW permissions.
|
||||
*/
|
||||
#define PLAT_SP_IMAGE_STACK_BASE (ARM_SP_IMAGE_NS_BUF_BASE + \
|
||||
ARM_SP_IMAGE_NS_BUF_SIZE)
|
||||
#define PLAT_SP_IMAGE_STACK_PCPU_SIZE ULL(0x2000)
|
||||
#define ARM_SP_IMAGE_STACK_TOTAL_SIZE (PLATFORM_CORE_COUNT * \
|
||||
PLAT_SP_IMAGE_STACK_PCPU_SIZE)
|
||||
|
||||
#define ARM_SP_IMAGE_HEAP_BASE (PLAT_SP_IMAGE_STACK_BASE + \
|
||||
ARM_SP_IMAGE_STACK_TOTAL_SIZE)
|
||||
#define ARM_SP_IMAGE_HEAP_SIZE (ARM_SP_IMAGE_LIMIT - ARM_SP_IMAGE_HEAP_BASE)
|
||||
|
||||
#define ARM_SP_IMAGE_RW_MMAP MAP_REGION2( \
|
||||
PLAT_SP_IMAGE_STACK_BASE, \
|
||||
PLAT_SP_IMAGE_STACK_BASE, \
|
||||
(ARM_SP_IMAGE_LIMIT - \
|
||||
PLAT_SP_IMAGE_STACK_BASE), \
|
||||
MT_RW_DATA | MT_SECURE | MT_USER,\
|
||||
PAGE_SIZE)
|
||||
|
||||
/* Total number of memory regions with distinct properties */
|
||||
#define ARM_SP_IMAGE_NUM_MEM_REGIONS 6
|
||||
|
||||
/* Cookies passed to the Secure Partition at boot. Not used by ARM platforms. */
|
||||
#define PLAT_SPM_COOKIE_0 ULL(0)
|
||||
#define PLAT_SPM_COOKIE_1 ULL(0)
|
||||
|
||||
#endif /* __ARM_SPM_DEF_H__ */
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <arm_config.h>
|
||||
#include <arm_def.h>
|
||||
#include <arm_spm_def.h>
|
||||
#include <assert.h>
|
||||
#include <cci.h>
|
||||
#include <ccn.h>
|
||||
|
@ -13,6 +14,7 @@
|
|||
#include <gicv2.h>
|
||||
#include <mmio.h>
|
||||
#include <plat_arm.h>
|
||||
#include <secure_partition.h>
|
||||
#include <v2m_def.h>
|
||||
#include "../fvp_def.h"
|
||||
|
||||
|
@ -89,6 +91,9 @@ const mmap_region_t plat_arm_mmap[] = {
|
|||
/* To access the Root of Trust Public Key registers. */
|
||||
MAP_DEVICE2,
|
||||
#endif
|
||||
#if ENABLE_SPM
|
||||
ARM_SP_IMAGE_MMAP,
|
||||
#endif
|
||||
#if ARM_BL31_IN_DRAM
|
||||
ARM_MAP_BL31_SEC_DRAM,
|
||||
#endif
|
||||
|
@ -114,8 +119,22 @@ const mmap_region_t plat_arm_mmap[] = {
|
|||
MAP_DEVICE0,
|
||||
MAP_DEVICE1,
|
||||
ARM_V2M_MAP_MEM_PROTECT,
|
||||
#if ENABLE_SPM
|
||||
ARM_SPM_BUF_EL3_MMAP,
|
||||
#endif
|
||||
{0}
|
||||
};
|
||||
|
||||
#if ENABLE_SPM && defined(IMAGE_BL31)
|
||||
const mmap_region_t plat_arm_secure_partition_mmap[] = {
|
||||
V2M_MAP_IOFPGA_EL0, /* for the UART */
|
||||
ARM_SP_IMAGE_MMAP,
|
||||
ARM_SP_IMAGE_NS_BUF_MMAP,
|
||||
ARM_SP_IMAGE_RW_MMAP,
|
||||
ARM_SPM_BUF_EL0_MMAP,
|
||||
{0}
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
#ifdef IMAGE_BL32
|
||||
const mmap_region_t plat_arm_mmap[] = {
|
||||
|
@ -156,6 +175,57 @@ static unsigned int get_interconnect_master(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if ENABLE_SPM && defined(IMAGE_BL31)
|
||||
/*
|
||||
* Boot information passed to a secure partition during initialisation. Linear
|
||||
* indices in MP information will be filled at runtime.
|
||||
*/
|
||||
static secure_partition_mp_info_t sp_mp_info[] = {
|
||||
[0] = {0x80000000, 0},
|
||||
[1] = {0x80000001, 0},
|
||||
[2] = {0x80000002, 0},
|
||||
[3] = {0x80000003, 0},
|
||||
[4] = {0x80000100, 0},
|
||||
[5] = {0x80000101, 0},
|
||||
[6] = {0x80000102, 0},
|
||||
[7] = {0x80000103, 0},
|
||||
};
|
||||
|
||||
const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = {
|
||||
.h.type = PARAM_SP_IMAGE_BOOT_INFO,
|
||||
.h.version = VERSION_1,
|
||||
.h.size = sizeof(secure_partition_boot_info_t),
|
||||
.h.attr = 0,
|
||||
.sp_mem_base = ARM_SP_IMAGE_BASE,
|
||||
.sp_mem_limit = ARM_SP_IMAGE_LIMIT,
|
||||
.sp_image_base = ARM_SP_IMAGE_BASE,
|
||||
.sp_stack_base = PLAT_SP_IMAGE_STACK_BASE,
|
||||
.sp_heap_base = ARM_SP_IMAGE_HEAP_BASE,
|
||||
.sp_ns_comm_buf_base = ARM_SP_IMAGE_NS_BUF_BASE,
|
||||
.sp_shared_buf_base = PLAT_SPM_BUF_BASE,
|
||||
.sp_image_size = ARM_SP_IMAGE_SIZE,
|
||||
.sp_pcpu_stack_size = PLAT_SP_IMAGE_STACK_PCPU_SIZE,
|
||||
.sp_heap_size = ARM_SP_IMAGE_HEAP_SIZE,
|
||||
.sp_ns_comm_buf_size = ARM_SP_IMAGE_NS_BUF_SIZE,
|
||||
.sp_shared_buf_size = PLAT_SPM_BUF_SIZE,
|
||||
.num_sp_mem_regions = ARM_SP_IMAGE_NUM_MEM_REGIONS,
|
||||
.num_cpus = PLATFORM_CORE_COUNT,
|
||||
.mp_info = &sp_mp_info[0],
|
||||
};
|
||||
|
||||
const struct mmap_region *plat_get_secure_partition_mmap(void *cookie)
|
||||
{
|
||||
return plat_arm_secure_partition_mmap;
|
||||
}
|
||||
|
||||
const struct secure_partition_boot_info *plat_get_secure_partition_boot_info(
|
||||
void *cookie)
|
||||
{
|
||||
return &plat_arm_secure_partition_boot_info;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* A single boot loader stack is expected to work on both the Foundation FVP
|
||||
* models and the two flavours of the Base FVP models (AEMv8 & Cortex). The
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <mmio.h>
|
||||
#include <plat_arm.h>
|
||||
#include <platform_def.h>
|
||||
#include <secure_partition.h>
|
||||
|
||||
extern const mmap_region_t plat_arm_mmap[];
|
||||
|
||||
|
@ -79,6 +80,14 @@ void arm_setup_page_tables(uintptr_t total_base,
|
|||
MT_DEVICE | MT_RW | MT_SECURE);
|
||||
#endif
|
||||
|
||||
#if ENABLE_SPM && defined(IMAGE_BL31)
|
||||
/* The address of the following region is calculated by the linker. */
|
||||
mmap_add_region(SP_IMAGE_XLAT_TABLES_START,
|
||||
SP_IMAGE_XLAT_TABLES_START,
|
||||
SP_IMAGE_XLAT_TABLES_SIZE,
|
||||
MT_MEMORY | MT_RW | MT_SECURE);
|
||||
#endif
|
||||
|
||||
/* Now (re-)map the platform-specific memory regions */
|
||||
mmap_add(plat_arm_get_mmap());
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <arm_def.h>
|
||||
#include <arm_spm_def.h>
|
||||
#include <debug.h>
|
||||
#include <platform_def.h>
|
||||
#include <tzc400.h>
|
||||
|
@ -56,9 +57,26 @@ void arm_tzc400_setup(void)
|
|||
ARM_DRAM2_BASE, ARM_DRAM2_END,
|
||||
ARM_TZC_NS_DRAM_S_ACCESS,
|
||||
PLAT_ARM_TZC_NS_DEV_ACCESS);
|
||||
#else
|
||||
|
||||
#if ENABLE_SPM
|
||||
/*
|
||||
* Region 4 set to cover Non-Secure access to the communication buffer
|
||||
* shared with the Secure world.
|
||||
*/
|
||||
tzc400_configure_region(PLAT_ARM_TZC_FILTERS,
|
||||
4,
|
||||
ARM_SP_IMAGE_NS_BUF_BASE,
|
||||
(ARM_SP_IMAGE_NS_BUF_BASE +
|
||||
ARM_SP_IMAGE_NS_BUF_SIZE) - 1,
|
||||
TZC_REGION_S_NONE,
|
||||
PLAT_ARM_TZC_NS_DEV_ACCESS);
|
||||
#endif
|
||||
|
||||
#else /* if defined(EL3_PAYLOAD_BASE) */
|
||||
|
||||
/* Allow secure access only to DRAM for EL3 payloads. */
|
||||
tzc400_configure_region0(TZC_REGION_S_RDWR, 0);
|
||||
|
||||
#endif /* EL3_PAYLOAD_BASE */
|
||||
|
||||
/*
|
||||
|
|
Loading…
Add table
Reference in a new issue