plat/synquacer: enable SPM support
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Sat, 29 Dec 2018 18:44:35 +0000 (19:44 +0100)
committerArd Biesheuvel <ard.biesheuvel@linaro.org>
Tue, 15 Jan 2019 16:51:23 +0000 (17:51 +0100)
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 <ard.biesheuvel@linaro.org>
plat/socionext/synquacer/include/plat.ld.S [new file with mode: 0644]
plat/socionext/synquacer/include/platform_def.h
plat/socionext/synquacer/platform.mk
plat/socionext/synquacer/sq_bl31_setup.c
plat/socionext/synquacer/sq_spm.c [new file with mode: 0644]

diff --git a/plat/socionext/synquacer/include/plat.ld.S b/plat/socionext/synquacer/include/plat.ld.S
new file mode 100644 (file)
index 0000000..1b7f699
--- /dev/null
@@ -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 <xlat_tables_defs.h>
+
+#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__ */
index c5bf7d5a8fd05dd715ec1a45eb032d131fec2c6a..0cec81b8d0dce67aec7191422cb15bd98424b740 100644 (file)
@@ -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                                  \
 
 #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 */
index ff46056580b4162c2534ff7f4c45469d1e17adf2..53c39a0fc9c87ffac15710ed126bd3498d450fb5 100644 (file)
@@ -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
index cb711862e51b1f9a036d66e54f9d13f7f026e808..2fac80ff00ea761547b92093736bcb1160272ed3 100644 (file)
@@ -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 (file)
index 0000000..01cce17
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <bl31/ehf.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <services/secure_partition.h>
+
+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);