diff --git a/plat/socionext/synquacer/include/plat.ld.S b/plat/socionext/synquacer/include/plat.ld.S new file mode 100644 index 0000000..1b7f699 --- /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 c5bf7d5..0cec81b 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 ff46056..53c39a0 100644 --- a/plat/socionext/synquacer/platform.mk +++ b/plat/socionext/synquacer/platform.mk @@ -43,3 +43,9 @@ $(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 cb71186..2fac80f 100644 --- a/plat/socionext/synquacer/sq_bl31_setup.c +++ b/plat/socionext/synquacer/sq_bl31_setup.c @@ -21,6 +21,10 @@ 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_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 0000000..01cce17 --- /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);