From 0560efb93eeba9cf16dc837893a07430e638dcc5 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sat, 29 Dec 2018 19:43:21 +0100 Subject: [PATCH 1/7] services/spm_deprecated: update ARM platform specific asserts Update some asserts that refer to #defines that only occur in ARM platforms, preventing this code to be used on other platforms. Instead, use a platform agnostic name, and update all the existing users. Signed-off-by: Ard Biesheuvel --- include/plat/arm/common/arm_spm_def.h | 10 +++++----- include/plat/arm/common/plat_arm.h | 4 ++-- plat/arm/board/fvp/fvp_common.c | 4 ++-- plat/arm/board/fvp/include/platform_def.h | 4 ++-- plat/arm/css/sgi/include/sgi_base_platform_def.h | 12 ++++++------ plat/arm/css/sgi/sgi_plat.c | 4 ++-- services/std_svc/spm_deprecated/spm_setup.c | 4 ++-- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/include/plat/arm/common/arm_spm_def.h b/include/plat/arm/common/arm_spm_def.h index bdcbc96af..c17b5652b 100644 --- a/include/plat/arm/common/arm_spm_def.h +++ b/include/plat/arm/common/arm_spm_def.h @@ -88,12 +88,12 @@ * 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 PLAT_SP_IMAGE_NS_BUF_BASE (PLAT_SPM_BUF_BASE + PLAT_SPM_BUF_SIZE) +#define PLAT_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, \ + PLAT_SP_IMAGE_NS_BUF_BASE, \ + PLAT_SP_IMAGE_NS_BUF_BASE, \ + PLAT_SP_IMAGE_NS_BUF_SIZE, \ MT_RW_DATA | MT_NS | MT_USER, \ PAGE_SIZE) diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 628160824..d1c03be68 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -46,8 +46,8 @@ typedef struct arm_tzc_regions_info { PLAT_ARM_TZC_NS_DEV_ACCESS}, \ {ARM_DRAM2_BASE, ARM_DRAM2_END, ARM_TZC_NS_DRAM_S_ACCESS, \ PLAT_ARM_TZC_NS_DEV_ACCESS}, \ - {ARM_SP_IMAGE_NS_BUF_BASE, (ARM_SP_IMAGE_NS_BUF_BASE + \ - ARM_SP_IMAGE_NS_BUF_SIZE) - 1, TZC_REGION_S_NONE, \ + {PLAT_SP_IMAGE_NS_BUF_BASE, (PLAT_SP_IMAGE_NS_BUF_BASE + \ + PLAT_SP_IMAGE_NS_BUF_SIZE) - 1, TZC_REGION_S_NONE, \ PLAT_ARM_TZC_NS_DEV_ACCESS} #else diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index 31a61de4e..fa5539dd0 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -218,12 +218,12 @@ const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = { .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_ns_comm_buf_base = PLAT_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_ns_comm_buf_size = PLAT_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, diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index ca4bd5399..31f06a988 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -271,8 +271,8 @@ #define PLAT_ARM_PRIVATE_SDEI_EVENTS ARM_SDEI_PRIVATE_EVENTS #define PLAT_ARM_SHARED_SDEI_EVENTS ARM_SDEI_SHARED_EVENTS -#define PLAT_ARM_SP_IMAGE_STACK_BASE (ARM_SP_IMAGE_NS_BUF_BASE + \ - ARM_SP_IMAGE_NS_BUF_SIZE) +#define PLAT_ARM_SP_IMAGE_STACK_BASE (PLAT_SP_IMAGE_NS_BUF_BASE + \ + PLAT_SP_IMAGE_NS_BUF_SIZE) #define PLAT_SP_PRI PLAT_RAS_PRI diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h index ad7ab81d9..4afaae1d9 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -147,8 +147,8 @@ /* Allocate 128KB for CPER buffers */ #define PLAT_SP_BUF_BASE ULL(0x20000) -#define PLAT_ARM_SP_IMAGE_STACK_BASE (ARM_SP_IMAGE_NS_BUF_BASE + \ - ARM_SP_IMAGE_NS_BUF_SIZE + \ +#define PLAT_ARM_SP_IMAGE_STACK_BASE (PLAT_SP_IMAGE_NS_BUF_BASE + \ + PLAT_SP_IMAGE_NS_BUF_SIZE + \ PLAT_SP_BUF_BASE) /* Platform specific SMC FID's used for RAS */ @@ -171,8 +171,8 @@ SDEI_EXPLICIT_EVENT(SGI_SDEI_DS_EVENT_1, SDEI_MAPF_CRITICAL), #define PLAT_ARM_SHARED_SDEI_EVENTS -#define ARM_SP_CPER_BUF_BASE (ARM_SP_IMAGE_NS_BUF_BASE + \ - ARM_SP_IMAGE_NS_BUF_SIZE) +#define ARM_SP_CPER_BUF_BASE (PLAT_SP_IMAGE_NS_BUF_BASE + \ + PLAT_SP_IMAGE_NS_BUF_SIZE) #define ARM_SP_CPER_BUF_SIZE ULL(0x20000) #define ARM_SP_CPER_BUF_MMAP MAP_REGION2( \ ARM_SP_CPER_BUF_BASE, \ @@ -182,8 +182,8 @@ PAGE_SIZE) #else -#define PLAT_ARM_SP_IMAGE_STACK_BASE (ARM_SP_IMAGE_NS_BUF_BASE + \ - ARM_SP_IMAGE_NS_BUF_SIZE) +#define PLAT_ARM_SP_IMAGE_STACK_BASE (PLAT_SP_IMAGE_NS_BUF_BASE + \ + PLAT_SP_IMAGE_NS_BUF_SIZE) #endif /* RAS_EXTENSION */ /* Platform ID address */ diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c index 79f3e5b55..835779437 100644 --- a/plat/arm/css/sgi/sgi_plat.c +++ b/plat/arm/css/sgi/sgi_plat.c @@ -127,12 +127,12 @@ const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = { .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_ns_comm_buf_base = PLAT_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_ns_comm_buf_size = PLAT_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, diff --git a/services/std_svc/spm_deprecated/spm_setup.c b/services/std_svc/spm_deprecated/spm_setup.c index d458f4a6a..e78a42c72 100644 --- a/services/std_svc/spm_deprecated/spm_setup.c +++ b/services/std_svc/spm_deprecated/spm_setup.c @@ -84,10 +84,10 @@ void spm_sp_setup(sp_context_t *sp_ctx) unsigned int max_granule_mask = max_granule - 1U; /* Base must be aligned to the max granularity */ - assert((ARM_SP_IMAGE_NS_BUF_BASE & max_granule_mask) == 0); + assert((PLAT_SP_IMAGE_NS_BUF_BASE & max_granule_mask) == 0); /* Size must be a multiple of the max granularity */ - assert((ARM_SP_IMAGE_NS_BUF_SIZE & max_granule_mask) == 0); + assert((PLAT_SP_IMAGE_NS_BUF_SIZE & max_granule_mask) == 0); #endif /* ENABLE_ASSERTIONS */ From c024ea6cd2b18487629dfc38707615bedd42901c Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 1 Jan 2019 11:01:41 +0100 Subject: [PATCH 2/7] services/spm_deprecated: permit timer sysreg access at S-EL0 Expose the timer registers that are accessible at EL0 per the architecture to the SPM payload running in secure EL0. Note that this requires NS_TIMER_SWITCH to be enable for all users of this code. Signed-off-by: Ard Biesheuvel --- services/std_svc/spm_deprecated/spm.mk | 3 +++ services/std_svc/spm_deprecated/spm_setup.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/services/std_svc/spm_deprecated/spm.mk b/services/std_svc/spm_deprecated/spm.mk index ed36812f9..35030206b 100644 --- a/services/std_svc/spm_deprecated/spm.mk +++ b/services/std_svc/spm_deprecated/spm.mk @@ -21,3 +21,6 @@ SPM_SOURCES := $(addprefix services/std_svc/spm_deprecated/, \ # Let the top-level Makefile know that we intend to include a BL32 image NEED_BL32 := yes + +# required so that SPM code executing at S-EL0 can access the timer registers +NS_TIMER_SWITCH := 1 diff --git a/services/std_svc/spm_deprecated/spm_setup.c b/services/std_svc/spm_deprecated/spm_setup.c index e78a42c72..beaff946c 100644 --- a/services/std_svc/spm_deprecated/spm_setup.c +++ b/services/std_svc/spm_deprecated/spm_setup.c @@ -168,6 +168,9 @@ void spm_sp_setup(sp_context_t *sp_ctx) write_ctx_reg(get_sysregs_ctx(ctx), CTX_VBAR_EL1, SPM_SHIM_EXCEPTIONS_PTR); + write_ctx_reg(get_sysregs_ctx(ctx), CTX_CNTKCTL_EL1, + EL0PTEN_BIT | EL0VTEN_BIT | EL0PCTEN_BIT | EL0VCTEN_BIT); + /* * FPEN: Allow the Secure Partition to access FP/SIMD registers. * Note that SPM will not do any saving/restoring of these registers on From 021318dffb551a0222c0eb5fc23f2d04b8e601ac Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 3 Jan 2019 12:03:49 +0100 Subject: [PATCH 3/7] services/spm_deprecated: disable alignment checking for S-EL0 Permit unaligned accesses while executing the secure partition payload, so that we don't have to modify existing code that we will host there. (The UEFI spec explicitly permits unaligned accesses) Signed-off-by: Ard Biesheuvel --- services/std_svc/spm_deprecated/spm_setup.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/services/std_svc/spm_deprecated/spm_setup.c b/services/std_svc/spm_deprecated/spm_setup.c index beaff946c..aae6cd5e2 100644 --- a/services/std_svc/spm_deprecated/spm_setup.c +++ b/services/std_svc/spm_deprecated/spm_setup.c @@ -144,8 +144,6 @@ void spm_sp_setup(sp_context_t *sp_ctx) SCTLR_SA0_BIT | /* Allow cacheable data and instr. accesses to normal memory. */ SCTLR_C_BIT | SCTLR_I_BIT | - /* Alignment fault checking enabled when at EL1 and EL0. */ - SCTLR_A_BIT | /* Enable MMU. */ SCTLR_M_BIT ; @@ -153,6 +151,11 @@ void spm_sp_setup(sp_context_t *sp_ctx) sctlr_el1 &= ~( /* Explicit data accesses at EL0 are little-endian. */ SCTLR_E0E_BIT | + /* + * Alignment fault checking disabled when at EL1 and EL0 as + * the UEFI spec permits unaligned accesses. + */ + SCTLR_A_BIT | /* Accesses to DAIF from EL0 are trapped to EL1. */ SCTLR_UMA_BIT ); From 0e4f761bc44346d0c08a8b272f148899198be825 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Tue, 1 Jan 2019 11:03:08 +0100 Subject: [PATCH 4/7] services/spm_deprecated: fix return code polarity of spm_init() Registered init handlers return a boolean int, not a return code, so convert the result from the SPM init call before returning it. Signed-off-by: Ard Biesheuvel --- services/std_svc/spm_deprecated/spm_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/std_svc/spm_deprecated/spm_main.c b/services/std_svc/spm_deprecated/spm_main.c index 540f257bd..7525763b1 100644 --- a/services/std_svc/spm_deprecated/spm_main.c +++ b/services/std_svc/spm_deprecated/spm_main.c @@ -151,7 +151,7 @@ static int32_t spm_init(void) INFO("Secure Partition initialized.\n"); - return rc; + return !rc; } /******************************************************************************* From 32e83537489267a8941f64caa58c0fa56d6b2c7e Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sun, 6 Jan 2019 10:07:24 +0100 Subject: [PATCH 5/7] spm: permit platform to override the VMA placement of the vector table On some systems, it may be preferred to place the secure EL1/0 vector table outside of the static placement of the BL31 image itself, for instance when the latter is located in non-shareable SRAM which does not tolerate inner shareable WBWA mappings (as is the case on SynQuacer) So permit the platform to #define SPM_SHIM_EXCEPTIONS_VMA in its supplementary linker script, in which case it will be used as the VMA region for the vector table. Note that the LMA does not change, and it is up to the platform to copy the contents to the right place at init time. Signed-off-by: Ard Biesheuvel --- bl31/bl31.ld.S | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index 5925e0ca0..c09b3517e 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -143,6 +143,10 @@ SECTIONS "cpu_ops not defined for this platform.") #if ENABLE_SPM +#ifndef SPM_SHIM_EXCEPTIONS_VMA +#define SPM_SHIM_EXCEPTIONS_VMA RAM +#endif + /* * Exception vectors of the SPM shim layer. They must be aligned to a 2K * address, but we need to place them in a separate page so that we can set @@ -156,7 +160,10 @@ SECTIONS *(.spm_shim_exceptions) . = ALIGN(PAGE_SIZE); __SPM_SHIM_EXCEPTIONS_END__ = .; - } >RAM + } >SPM_SHIM_EXCEPTIONS_VMA AT>RAM + + PROVIDE(__SPM_SHIM_EXCEPTIONS_LMA__ = LOADADDR(spm_shim_exceptions)); + . = LOADADDR(spm_shim_exceptions) + SIZEOF(spm_shim_exceptions); #endif /* From e373b6a28c34f81ac5681a7e03de5b95e269b192 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sat, 29 Dec 2018 19:40:31 +0100 Subject: [PATCH 6/7] plat/synquacer: enable OP-TEE logic only if SPD_opteed is set The logic that initializes the BL32 entry point data structure should only be executed if we are in fact loading OP-TEE, and not if BL32_BASE is set for other reasons (i.e., when enabling SPM) Signed-off-by: Ard Biesheuvel --- plat/socionext/synquacer/include/platform_def.h | 2 ++ plat/socionext/synquacer/platform.mk | 4 ---- plat/socionext/synquacer/sq_bl31_setup.c | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h index de6be7d23..c5bf7d5a8 100644 --- a/plat/socionext/synquacer/include/platform_def.h +++ b/plat/socionext/synquacer/include/platform_def.h @@ -38,6 +38,8 @@ #define BL31_SIZE 0x00080000 #define BL31_LIMIT (BL31_BASE + BL31_SIZE) +#define BL32_BASE 0xfc000000 + #define PLAT_SQ_CCN_BASE 0x32000000 #define PLAT_SQ_CLUSTER_TO_CCN_ID_MAP \ 0, /* Cluster 0 */ \ diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk index 1bee20abb..ff4605658 100644 --- a/plat/socionext/synquacer/platform.mk +++ b/plat/socionext/synquacer/platform.mk @@ -17,10 +17,6 @@ ERRATA_A53_855873 := 1 # Libraries include lib/xlat_tables_v2/xlat_tables.mk -ifeq (${SPD},opteed) -TF_CFLAGS_aarch64 += -DBL32_BASE=0xfc000000 -endif - PLAT_PATH := plat/socionext/synquacer PLAT_INCLUDES := -I$(PLAT_PATH)/include \ -I$(PLAT_PATH)/drivers/scpi \ diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c index f8d252622..cb711862e 100644 --- a/plat/socionext/synquacer/sq_bl31_setup.c +++ b/plat/socionext/synquacer/sq_bl31_setup.c @@ -76,7 +76,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, /* Initialize power controller before setting up topology */ plat_sq_pwrc_setup(); -#ifdef BL32_BASE +#ifdef SPD_opteed struct draminfo di = {0}; scpi_get_draminfo(&di); @@ -98,7 +98,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, } else { NOTICE("OP-TEE has not been loaded by SCP firmware\n"); } -#endif /* BL32_BASE */ +#endif /* SPD_opteed */ /* Populate entry point information for BL33 */ SET_PARAM_HEAD(&bl33_image_ep_info, From 434454a2710eea3f49ebfca951019d7b6c783fb5 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Sat, 29 Dec 2018 19:44:35 +0100 Subject: [PATCH 7/7] plat/synquacer: enable SPM support Enable the deprecated SPM framework for the SynQuacer platform. It involves creating a memory layout in secure DRAM, and wiring up the SPM infrastructure so that the secure partition payload that is loaded into this region by the SCP firmware is dispatched appropriately. Signed-off-by: Ard Biesheuvel --- plat/socionext/synquacer/include/plat.ld.S | 32 ++++++++ .../synquacer/include/platform_def.h | 79 ++++++++++++++++++- plat/socionext/synquacer/platform.mk | 6 ++ plat/socionext/synquacer/sq_bl31_setup.c | 25 +++++- plat/socionext/synquacer/sq_spm.c | 75 ++++++++++++++++++ 5 files changed, 214 insertions(+), 3 deletions(-) create mode 100644 plat/socionext/synquacer/include/plat.ld.S create mode 100644 plat/socionext/synquacer/sq_spm.c diff --git a/plat/socionext/synquacer/include/plat.ld.S b/plat/socionext/synquacer/include/plat.ld.S new file mode 100644 index 000000000..1b7f69989 --- /dev/null +++ b/plat/socionext/synquacer/include/plat.ld.S @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SYNQUACER_PLAT_LD_S__ +#define SYNQUACER_PLAT_LD_S__ + +#include + +#define SPM_SHIM_EXCEPTIONS_VMA SP_DRAM + +MEMORY { + SP_DRAM (rw): ORIGIN = PLAT_SQ_SP_PRIV_BASE, LENGTH = PLAT_SQ_SP_PRIV_SIZE +} + +SECTIONS +{ + /* + * Put the page tables in secure DRAM so that the PTW can make cacheable + * accesses, as the core SPM code expects. (The SRAM on SynQuacer does + * not support inner shareable WBWA mappings so it is mapped normal + * non-cacheable) + */ + sp_xlat_table (NOLOAD) : ALIGN(PAGE_SIZE) { + *(sp_xlat_table) + *(.bss.sp_base_xlat_table) + } >SP_DRAM +} + +#endif /* SYNQUACER_PLAT_LD_S__ */ diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h index c5bf7d5a8..0cec81b8d 100644 --- a/plat/socionext/synquacer/include/platform_def.h +++ b/plat/socionext/synquacer/include/platform_def.h @@ -29,8 +29,8 @@ #define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) -#define MAX_XLAT_TABLES 4 -#define MAX_MMAP_REGIONS 6 +#define MAX_XLAT_TABLES 8 +#define MAX_MMAP_REGIONS 8 #define PLATFORM_STACK_SIZE 0x400 @@ -39,6 +39,8 @@ #define BL31_LIMIT (BL31_BASE + BL31_SIZE) #define BL32_BASE 0xfc000000 +#define BL32_SIZE 0x03c00000 +#define BL32_LIMIT (BL32_BASE + BL32_SIZE) #define PLAT_SQ_CCN_BASE 0x32000000 #define PLAT_SQ_CLUSTER_TO_CCN_ID_MAP \ @@ -81,4 +83,77 @@ #define PLAT_SQ_GPIO_BASE 0x51000000 +#define PLAT_SPM_BUF_BASE (BL32_LIMIT - 32 * PLAT_SPM_BUF_SIZE) +#define PLAT_SPM_BUF_SIZE ULL(0x10000) +#define PLAT_SPM_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) + +#define PLAT_SP_IMAGE_NS_BUF_BASE BL32_LIMIT +#define PLAT_SP_IMAGE_NS_BUF_SIZE ULL(0x200000) +#define PLAT_SP_IMAGE_NS_BUF_MMAP MAP_REGION2(PLAT_SP_IMAGE_NS_BUF_BASE, \ + PLAT_SP_IMAGE_NS_BUF_BASE, \ + PLAT_SP_IMAGE_NS_BUF_SIZE, \ + MT_RW_DATA | MT_NS | \ + MT_USER, PAGE_SIZE) + +#define PLAT_SP_IMAGE_STACK_PCPU_SIZE ULL(0x10000) +#define PLAT_SP_IMAGE_STACK_SIZE (32 * PLAT_SP_IMAGE_STACK_PCPU_SIZE) +#define PLAT_SP_IMAGE_STACK_BASE (PLAT_SQ_SP_HEAP_BASE + PLAT_SQ_SP_HEAP_SIZE) + +#define PLAT_SQ_SP_IMAGE_SIZE ULL(0x200000) +#define PLAT_SQ_SP_IMAGE_MMAP MAP_REGION2(BL32_BASE, BL32_BASE, \ + PLAT_SQ_SP_IMAGE_SIZE, \ + MT_CODE | MT_SECURE | \ + MT_USER, PAGE_SIZE) + +#define PLAT_SQ_SP_HEAP_BASE (BL32_BASE + PLAT_SQ_SP_IMAGE_SIZE) +#define PLAT_SQ_SP_HEAP_SIZE ULL(0x800000) + +#define PLAT_SQ_SP_IMAGE_RW_MMAP MAP_REGION2(PLAT_SQ_SP_HEAP_BASE, \ + PLAT_SQ_SP_HEAP_BASE, \ + (PLAT_SQ_SP_HEAP_SIZE + \ + PLAT_SP_IMAGE_STACK_SIZE), \ + MT_RW_DATA | MT_SECURE | \ + MT_USER, PAGE_SIZE) + +#define PLAT_SQ_SP_PRIV_BASE (PLAT_SP_IMAGE_STACK_BASE + \ + PLAT_SP_IMAGE_STACK_SIZE) +#define PLAT_SQ_SP_PRIV_SIZE ULL(0x40000) + +#define PLAT_SP_PRI 0x20 +#define PLAT_PRI_BITS 2 +#define PLAT_SPM_COOKIE_0 ULL(0) +#define PLAT_SPM_COOKIE_1 ULL(0) + +/* Total number of memory regions with distinct properties */ +#define PLAT_SP_IMAGE_NUM_MEM_REGIONS 6 + +#define PLAT_SP_IMAGE_MMAP_REGIONS 30 +#define PLAT_SP_IMAGE_MAX_XLAT_TABLES 20 +#define PLAT_SP_IMAGE_XLAT_SECTION_NAME "sp_xlat_table" + +#define PLAT_SQ_UART1_BASE PLAT_SQ_BOOT_UART_BASE +#define PLAT_SQ_UART1_SIZE ULL(0x1000) +#define PLAT_SQ_UART1_MMAP MAP_REGION_FLAT(PLAT_SQ_UART1_BASE, \ + PLAT_SQ_UART1_SIZE, \ + MT_DEVICE | MT_RW | \ + MT_NS | MT_PRIVILEGED) + +#define PLAT_SQ_PERIPH_BASE 0x50000000 +#define PLAT_SQ_PERIPH_SIZE ULL(0x8000000) +#define PLAT_SQ_PERIPH_MMAP MAP_REGION_FLAT(PLAT_SQ_PERIPH_BASE, \ + PLAT_SQ_PERIPH_SIZE, \ + MT_DEVICE | MT_RW | \ + MT_NS | MT_USER) + +#define PLAT_SQ_FLASH_BASE 0x08000000 +#define PLAT_SQ_FLASH_SIZE ULL(0x8000000) +#define PLAT_SQ_FLASH_MMAP MAP_REGION_FLAT(PLAT_SQ_FLASH_BASE, \ + PLAT_SQ_FLASH_SIZE, \ + MT_DEVICE | MT_RW | \ + MT_NS | MT_USER) + #endif /* PLATFORM_DEF_H */ diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk index ff4605658..53c39a0fc 100644 --- a/plat/socionext/synquacer/platform.mk +++ b/plat/socionext/synquacer/platform.mk @@ -43,3 +43,9 @@ BL31_SOURCES += drivers/arm/ccn/ccn.c \ $(PLAT_PATH)/sq_xlat_setup.c \ $(PLAT_PATH)/drivers/scpi/sq_scpi.c \ $(PLAT_PATH)/drivers/mhu/sq_mhu.c + +ifeq (${ENABLE_SPM},1) +$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT)) + +BL31_SOURCES += $(PLAT_PATH)/sq_spm.c +endif diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c index cb711862e..2fac80ff0 100644 --- a/plat/socionext/synquacer/sq_bl31_setup.c +++ b/plat/socionext/synquacer/sq_bl31_setup.c @@ -21,6 +21,10 @@ static console_pl011_t console; static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; +IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_START__, SPM_SHIM_EXCEPTIONS_START); +IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_END__, SPM_SHIM_EXCEPTIONS_END); +IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_LMA__, SPM_SHIM_EXCEPTIONS_LMA); + entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) { assert(sec_state_is_valid(type)); @@ -155,8 +159,27 @@ void bl31_plat_runtime_setup(void) void bl31_plat_arch_setup(void) { - sq_mmap_setup(BL31_BASE, BL31_SIZE, NULL); + static const mmap_region_t secure_partition_mmap[] = { +#if ENABLE_SPM && SPM_DEPRECATED + MAP_REGION_FLAT(PLAT_SPM_BUF_BASE, + PLAT_SPM_BUF_SIZE, + MT_RW_DATA | MT_SECURE), + MAP_REGION_FLAT(PLAT_SQ_SP_PRIV_BASE, + PLAT_SQ_SP_PRIV_SIZE, + MT_RW_DATA | MT_SECURE), +#endif + {0}, + }; + + sq_mmap_setup(BL31_BASE, BL31_SIZE, secure_partition_mmap); enable_mmu_el3(XLAT_TABLE_NC); + +#if ENABLE_SPM && SPM_DEPRECATED + memcpy((void *)SPM_SHIM_EXCEPTIONS_START, + (void *)SPM_SHIM_EXCEPTIONS_LMA, + (uintptr_t)SPM_SHIM_EXCEPTIONS_END - + (uintptr_t)SPM_SHIM_EXCEPTIONS_START); +#endif } void bl31_plat_enable_mmu(uint32_t flags) diff --git a/plat/socionext/synquacer/sq_spm.c b/plat/socionext/synquacer/sq_spm.c new file mode 100644 index 000000000..01cce1739 --- /dev/null +++ b/plat/socionext/synquacer/sq_spm.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include + +#include +#include +#include + +static const mmap_region_t plat_arm_secure_partition_mmap[] = { + PLAT_SQ_FLASH_MMAP, + PLAT_SQ_UART1_MMAP, + PLAT_SQ_PERIPH_MMAP, + PLAT_SQ_SP_IMAGE_MMAP, + PLAT_SP_IMAGE_NS_BUF_MMAP, + PLAT_SQ_SP_IMAGE_RW_MMAP, + PLAT_SPM_SPM_BUF_EL0_MMAP, + {0} +}; + +/* + * 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[] = { + {0x80000000, 0}, {0x80000001, 0}, {0x80000100, 0}, {0x80000101, 0}, + {0x80000200, 0}, {0x80000201, 0}, {0x80000300, 0}, {0x80000301, 0}, + {0x80000400, 0}, {0x80000401, 0}, {0x80000500, 0}, {0x80000501, 0}, + {0x80000600, 0}, {0x80000601, 0}, {0x80000700, 0}, {0x80000701, 0}, + {0x80000800, 0}, {0x80000801, 0}, {0x80000900, 0}, {0x80000901, 0}, + {0x80000a00, 0}, {0x80000a01, 0}, {0x80000b00, 0}, {0x80000b01, 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 = BL32_BASE, + .sp_mem_limit = BL32_LIMIT, + .sp_image_base = BL32_BASE, + .sp_stack_base = PLAT_SP_IMAGE_STACK_BASE, + .sp_heap_base = PLAT_SQ_SP_HEAP_BASE, + .sp_ns_comm_buf_base = PLAT_SP_IMAGE_NS_BUF_BASE, + .sp_shared_buf_base = PLAT_SPM_BUF_BASE, + .sp_image_size = PLAT_SQ_SP_IMAGE_SIZE, + .sp_pcpu_stack_size = PLAT_SP_IMAGE_STACK_PCPU_SIZE, + .sp_heap_size = PLAT_SQ_SP_HEAP_SIZE, + .sp_ns_comm_buf_size = PLAT_SP_IMAGE_NS_BUF_SIZE, + .sp_shared_buf_size = PLAT_SPM_BUF_SIZE, + .num_sp_mem_regions = PLAT_SP_IMAGE_NUM_MEM_REGIONS, + .num_cpus = PLATFORM_CORE_COUNT, + .mp_info = sp_mp_info, +}; + +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; +} + +static ehf_pri_desc_t sq_exceptions[] = { + EHF_PRI_DESC(PLAT_PRI_BITS, PLAT_SP_PRI), +}; +EHF_REGISTER_PRIORITIES(sq_exceptions, ARRAY_SIZE(sq_exceptions), PLAT_PRI_BITS);