Merge "Neoverse N1: Forces cacheable atomic to near" into integration
diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst
index bfae9cc..75dfa3f 100644
--- a/docs/plat/stm32mp1.rst
+++ b/docs/plat/stm32mp1.rst
@@ -69,11 +69,15 @@
ROM code -> BL2 (compiled with BL2_AT_EL3) -> BL32 (SP_min) -> BL33 (U-Boot)
+or if Op-TEE is used:
+
+ROM code -> BL2 (compiled with BL2_AT_EL3) -> OP-TEE -> BL33 (U-Boot)
+
Build Instructions
------------------
-To build:
+To build with SP_min:
.. code:: bash
@@ -83,6 +87,12 @@
make DEVICE_TREE=stm32mp157c-ev1 all
./tools/mkimage -T stm32image -a 0xC0100000 -e 0xC0100000 -d u-boot.bin u-boot.stm32
+To build TF-A with with Op-TEE support:
+
+.. code:: bash
+
+ make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=optee
+
The following build options are supported:
- ``ENABLE_STACK_PROTECTOR``: To enable the stack protection.
diff --git a/drivers/arm/sbsa/sbsa.c b/drivers/arm/sbsa/sbsa.c
new file mode 100644
index 0000000..6f00a60
--- /dev/null
+++ b/drivers/arm/sbsa/sbsa.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+#include <drivers/arm/sbsa.h>
+#include <lib/mmio.h>
+#include <stdint_.h>
+#include <assert.h>
+
+void sbsa_watchdog_offset_reg_write(uintptr_t base, uint64_t value)
+{
+ assert((value >> SBSA_WDOG_WOR_WIDTH) == 0);
+ mmio_write_32(base + SBSA_WDOG_WOR_LOW_OFFSET,
+ ((uint32_t)value & UINT32_MAX));
+ mmio_write_32(base + SBSA_WDOG_WOR_HIGH_OFFSET, (uint32_t)(value >> 32));
+}
+
+/*
+ * Start the watchdog timer at base address "base" for a
+ * period of "ms" milliseconds.The watchdog has to be
+ * refreshed within this time period.
+ */
+void sbsa_wdog_start(uintptr_t base, uint64_t ms)
+{
+ uint64_t counter_freq;
+ uint64_t offset_reg_value;
+
+ counter_freq = (uint64_t)plat_get_syscnt_freq2();
+ offset_reg_value = ms * counter_freq / 1000;
+
+ sbsa_watchdog_offset_reg_write(base, offset_reg_value);
+ mmio_write_32(base + SBSA_WDOG_WCS_OFFSET, SBSA_WDOG_WCS_EN);
+}
+
+/* Stop the watchdog */
+void sbsa_wdog_stop(uintptr_t base)
+{
+ mmio_write_32(base + SBSA_WDOG_WCS_OFFSET, (0x0));
+}
diff --git a/include/drivers/arm/sbsa.h b/include/drivers/arm/sbsa.h
new file mode 100644
index 0000000..9403634
--- /dev/null
+++ b/include/drivers/arm/sbsa.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2019, ARM Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SBSA_H
+#define SBSA_H
+
+#include <stdint.h>
+
+/* Register Offsets */
+#define SBSA_WDOG_WCS_OFFSET UL(0x000)
+#define SBSA_WDOG_WOR_LOW_OFFSET UL(0x008)
+#define SBSA_WDOG_WOR_HIGH_OFFSET UL(0x00C)
+
+#define SBSA_WDOG_WCS_EN U(0x1)
+
+#define SBSA_WDOG_WOR_WIDTH UL(48)
+
+void sbsa_wdog_start(uintptr_t base, uint64_t ms);
+void sbsa_wdog_stop(uintptr_t base);
+
+#endif /* SBSA_H */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 527375f..97e6722 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -295,4 +295,8 @@
extern const mmap_region_t plat_arm_mmap[];
extern const unsigned int arm_pm_idle_states[];
+/* secure watchdog */
+void plat_arm_secure_wdt_start(void);
+void plat_arm_secure_wdt_stop(void);
+
#endif /* PLAT_ARM_H */
diff --git a/plat/arm/board/fvp/fvp_bl1_setup.c b/plat/arm/board/fvp/fvp_bl1_setup.c
index 75090e8..aa56716 100644
--- a/plat/arm/board/fvp/fvp_bl1_setup.c
+++ b/plat/arm/board/fvp/fvp_bl1_setup.c
@@ -5,9 +5,10 @@
*/
#include <common/tbbr/tbbr_img_def.h>
+#include <drivers/arm/sp805.h>
#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/common/arm_def.h>
#include <plat/common/platform.h>
-
#include "fvp_private.h"
/*******************************************************************************
@@ -30,3 +31,13 @@
*/
fvp_interconnect_enable();
}
+
+void plat_arm_secure_wdt_start(void)
+{
+ sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+ sp805_stop(ARM_SP805_TWDG_BASE);
+}
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 1a63e87..c11d848 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -112,7 +112,8 @@
FVP_CPU_LIBS += lib/cpus/aarch32/cortex_a32.S
endif
-BL1_SOURCES += drivers/io/io_semihosting.c \
+BL1_SOURCES += drivers/arm/sp805/sp805.c \
+ drivers/io/io_semihosting.c \
lib/semihosting/semihosting.c \
lib/semihosting/${ARCH}/semihosting_call.S \
plat/arm/board/fvp/${ARCH}/fvp_helpers.S \
diff --git a/plat/arm/board/fvp_ve/fvp_ve_bl1_setup.c b/plat/arm/board/fvp_ve/fvp_ve_bl1_setup.c
index 47cd876..4338f6f 100644
--- a/plat/arm/board/fvp_ve/fvp_ve_bl1_setup.c
+++ b/plat/arm/board/fvp_ve/fvp_ve_bl1_setup.c
@@ -4,8 +4,10 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <drivers/arm/sp805.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
+#include <platform_def.h>
/*******************************************************************************
* Perform any BL1 specific platform actions.
@@ -14,3 +16,13 @@
{
arm_bl1_early_platform_setup();
}
+
+void plat_arm_secure_wdt_start(void)
+{
+ sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+ sp805_stop(ARM_SP805_TWDG_BASE);
+}
diff --git a/plat/arm/board/juno/juno_bl1_setup.c b/plat/arm/board/juno/juno_bl1_setup.c
index 33f5c47..7a3d22d 100644
--- a/plat/arm/board/juno/juno_bl1_setup.c
+++ b/plat/arm/board/juno/juno_bl1_setup.c
@@ -12,6 +12,7 @@
#include <drivers/arm/css/sds.h>
#include <drivers/arm/sp805.h>
#include <plat/arm/common/plat_arm.h>
+#include <plat/arm/common/arm_def.h>
#include <plat/common/platform.h>
#include <platform_def.h>
@@ -112,3 +113,13 @@
juno_reset_to_aarch32_state();
}
#endif /* JUNO_AARCH32_EL3_RUNTIME */
+
+void plat_arm_secure_wdt_start(void)
+{
+ sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+ sp805_stop(ARM_SP805_TWDG_BASE);
+}
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index e44791b..40e6264 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -62,6 +62,7 @@
lib/cpus/aarch64/cortex_a72.S \
plat/arm/board/juno/juno_err.c \
plat/arm/board/juno/juno_bl1_setup.c \
+ drivers/arm/sp805/sp805.c \
${JUNO_INTERCONNECT_SOURCES} \
${JUNO_SECURITY_SOURCES}
diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h
index 03bd380..adb957e 100644
--- a/plat/arm/board/n1sdp/include/platform_def.h
+++ b/plat/arm/board/n1sdp/include/platform_def.h
@@ -87,4 +87,8 @@
/* Platform ID address */
#define SSC_VERSION (SSC_REG_BASE + SSC_VERSION_OFFSET)
+/* Secure Watchdog Constants */
+#define SBSA_SECURE_WDOG_BASE UL(0x2A480000)
+#define SBSA_SECURE_WDOG_TIMEOUT UL(100)
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/n1sdp/n1sdp_plat.c b/plat/arm/board/n1sdp/n1sdp_plat.c
index 6905896..f36f9e2 100644
--- a/plat/arm/board/n1sdp/n1sdp_plat.c
+++ b/plat/arm/board/n1sdp/n1sdp_plat.c
@@ -10,6 +10,7 @@
#include <common/debug.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
+#include <drivers/arm/sbsa.h>
/*
* Table of regions to map using the MMU.
@@ -22,3 +23,12 @@
{0}
};
+void plat_arm_secure_wdt_start(void)
+{
+ sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+ sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
+}
diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk
index 653d081..d0c34c8 100644
--- a/plat/arm/board/n1sdp/platform.mk
+++ b/plat/arm/board/n1sdp/platform.mk
@@ -25,6 +25,7 @@
PLAT_BL_COMMON_SOURCES := ${N1SDP_BASE}/n1sdp_plat.c \
${N1SDP_BASE}/aarch64/n1sdp_helper.S
+BL1_SOURCES += drivers/arm/sbsa/sbsa.c
BL31_SOURCES := ${N1SDP_CPU_SOURCES} \
${INTERCONNECT_SOURCES} \
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index 1e9edef..8e0c046 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -11,7 +11,6 @@
#include <arch.h>
#include <bl1/bl1.h>
#include <common/bl_common.h>
-#include <drivers/arm/sp805.h>
#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat/arm/common/plat_arm.h>
@@ -67,7 +66,7 @@
#if !ARM_DISABLE_TRUSTED_WDOG
/* Enable watchdog */
- sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
+ plat_arm_secure_wdt_start();
#endif
/* Initialize the console to provide early debug support */
@@ -172,7 +171,7 @@
{
#if !ARM_DISABLE_TRUSTED_WDOG
/* Disable watchdog before leaving BL1 */
- sp805_stop(ARM_SP805_TWDG_BASE);
+ plat_arm_secure_wdt_stop();
#endif
#ifdef EL3_PAYLOAD_BASE
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 5e890ed..c3d9e03 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -158,8 +158,7 @@
PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
endif
-BL1_SOURCES += drivers/arm/sp805/sp805.c \
- drivers/io/io_fip.c \
+BL1_SOURCES += drivers/io/io_fip.c \
drivers/io/io_memmap.c \
drivers/io/io_storage.c \
plat/arm/common/arm_bl1_setup.c \
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 c0e6555..032a1f4 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -208,5 +208,8 @@
#define PLAT_ARM_MEM_PROT_ADDR (V2M_FLASH0_BASE + \
V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+/*Secure Watchdog Constants */
+#define SBSA_SECURE_WDOG_BASE UL(0x2A480000)
+#define SBSA_SECURE_WDOG_TIMEOUT UL(100)
#endif /* SGI_BASE_PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index 613d3d5..b736b0b 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -33,7 +33,8 @@
PLAT_BL_COMMON_SOURCES += ${CSS_ENT_BASE}/sgi_plat.c \
${CSS_ENT_BASE}/aarch64/sgi_helper.S
-BL1_SOURCES += ${INTERCONNECT_SOURCES}
+BL1_SOURCES += ${INTERCONNECT_SOURCES} \
+ drivers/arm/sbsa/sbsa.c
BL2_SOURCES += ${CSS_ENT_BASE}/sgi_image_load.c
diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c
index 42eff86..3e207ec 100644
--- a/plat/arm/css/sgi/sgi_plat.c
+++ b/plat/arm/css/sgi/sgi_plat.c
@@ -13,6 +13,8 @@
#include <drivers/arm/ccn.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
+#include <drivers/arm/sbsa.h>
+#include <sgi_base_platform_def.h>
#include <services/secure_partition.h>
#define SGI_MAP_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\
@@ -139,3 +141,13 @@
return arm_get_mbedtls_heap(heap_addr, heap_size);
}
#endif
+
+void plat_arm_secure_wdt_start(void)
+{
+ sbsa_wdog_start(SBSA_SECURE_WDOG_BASE, SBSA_SECURE_WDOG_TIMEOUT);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+ sbsa_wdog_stop(SBSA_SECURE_WDOG_BASE);
+}
diff --git a/plat/arm/css/sgm/sgm-common.mk b/plat/arm/css/sgm/sgm-common.mk
index 0a136e6..34e78b2 100644
--- a/plat/arm/css/sgm/sgm-common.mk
+++ b/plat/arm/css/sgm/sgm-common.mk
@@ -31,7 +31,8 @@
BL1_SOURCES += $(SGM_CPU_SOURCES) \
${INTERCONNECT_SOURCES} \
${CSS_SGM_BASE}/sgm_bl1_setup.c \
- ${CSS_SGM_BASE}/sgm_plat_config.c
+ ${CSS_SGM_BASE}/sgm_plat_config.c \
+ drivers/arm/sp805/sp805.c
BL2_SOURCES += ${SECURITY_SOURCES} \
${CSS_SGM_BASE}/sgm_plat_config.c
diff --git a/plat/arm/css/sgm/sgm_bl1_setup.c b/plat/arm/css/sgm/sgm_bl1_setup.c
index 2036515..5fd9655 100644
--- a/plat/arm/css/sgm/sgm_bl1_setup.c
+++ b/plat/arm/css/sgm/sgm_bl1_setup.c
@@ -8,7 +8,8 @@
#include <common/debug.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/arm/soc/common/soc_css.h>
-
+#include <plat/arm/common/arm_def.h>
+#include <drivers/arm/sp805.h>
#include <sgm_plat_config.h>
void bl1_early_platform_setup(void)
@@ -32,3 +33,13 @@
plat_arm_interconnect_enter_coherency();
#endif
}
+
+void plat_arm_secure_wdt_start(void)
+{
+ sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
+}
+
+void plat_arm_secure_wdt_stop(void)
+{
+ sp805_stop(ARM_SP805_TWDG_BASE);
+}
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index f172160..38b2a0b 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -54,10 +54,27 @@
static uintptr_t storage_dev_handle;
static const io_dev_connector_t *mmc_dev_con;
+#ifdef AARCH32_SP_OPTEE
+static const struct stm32image_part_info optee_header_partition_spec = {
+ .name = OPTEE_HEADER_IMAGE_NAME,
+ .binary_type = OPTEE_HEADER_BINARY_TYPE,
+};
+
+static const struct stm32image_part_info optee_pager_partition_spec = {
+ .name = OPTEE_PAGER_IMAGE_NAME,
+ .binary_type = OPTEE_PAGER_BINARY_TYPE,
+};
+
+static const struct stm32image_part_info optee_paged_partition_spec = {
+ .name = OPTEE_PAGED_IMAGE_NAME,
+ .binary_type = OPTEE_PAGED_BINARY_TYPE,
+};
+#else
static const io_block_spec_t bl32_block_spec = {
.offset = BL32_BASE,
.length = STM32MP_BL32_SIZE
};
+#endif
static const io_block_spec_t bl2_block_spec = {
.offset = BL2_BASE,
@@ -71,6 +88,11 @@
enum {
IMG_IDX_BL33,
+#ifdef AARCH32_SP_OPTEE
+ IMG_IDX_OPTEE_HEADER,
+ IMG_IDX_OPTEE_PAGER,
+ IMG_IDX_OPTEE_PAGED,
+#endif
IMG_IDX_NUM
};
@@ -80,6 +102,20 @@
.name = BL33_IMAGE_NAME,
.binary_type = BL33_BINARY_TYPE,
},
+#ifdef AARCH32_SP_OPTEE
+ .part_info[IMG_IDX_OPTEE_HEADER] = {
+ .name = OPTEE_HEADER_IMAGE_NAME,
+ .binary_type = OPTEE_HEADER_BINARY_TYPE,
+ },
+ .part_info[IMG_IDX_OPTEE_PAGER] = {
+ .name = OPTEE_PAGER_IMAGE_NAME,
+ .binary_type = OPTEE_PAGER_BINARY_TYPE,
+ },
+ .part_info[IMG_IDX_OPTEE_PAGED] = {
+ .name = OPTEE_PAGED_IMAGE_NAME,
+ .binary_type = OPTEE_PAGED_BINARY_TYPE,
+ },
+#endif
};
static io_block_spec_t stm32image_block_spec = {
@@ -105,11 +141,29 @@
.image_spec = (uintptr_t)&bl2_block_spec,
.check = open_dummy
},
+#ifdef AARCH32_SP_OPTEE
+ [BL32_IMAGE_ID] = {
+ .dev_handle = &image_dev_handle,
+ .image_spec = (uintptr_t)&optee_header_partition_spec,
+ .check = open_image
+ },
+ [BL32_EXTRA1_IMAGE_ID] = {
+ .dev_handle = &image_dev_handle,
+ .image_spec = (uintptr_t)&optee_pager_partition_spec,
+ .check = open_image
+ },
+ [BL32_EXTRA2_IMAGE_ID] = {
+ .dev_handle = &image_dev_handle,
+ .image_spec = (uintptr_t)&optee_paged_partition_spec,
+ .check = open_image
+ },
+#else
[BL32_IMAGE_ID] = {
.dev_handle = &dummy_dev_handle,
.image_spec = (uintptr_t)&bl32_block_spec,
.check = open_dummy
},
+#endif
[BL33_IMAGE_ID] = {
.dev_handle = &image_dev_handle,
.image_spec = (uintptr_t)&bl33_partition_spec,
@@ -162,15 +216,99 @@
}
}
-void stm32mp_io_setup(void)
+static void boot_mmc(enum mmc_device_type mmc_dev_type,
+ uint16_t boot_interface_instance)
{
int io_result __unused;
uint8_t idx;
struct stm32image_part_info *part;
struct stm32_sdmmc2_params params;
struct mmc_device_info device_info;
- uintptr_t mmc_default_instance;
const partition_entry_t *entry;
+
+ zeromem(&device_info, sizeof(struct mmc_device_info));
+ zeromem(¶ms, sizeof(struct stm32_sdmmc2_params));
+
+ device_info.mmc_dev_type = mmc_dev_type;
+
+ switch (boot_interface_instance) {
+ case 1:
+ params.reg_base = STM32MP_SDMMC1_BASE;
+ break;
+ case 2:
+ params.reg_base = STM32MP_SDMMC2_BASE;
+ break;
+ case 3:
+ params.reg_base = STM32MP_SDMMC3_BASE;
+ break;
+ default:
+ WARN("SDMMC instance not found, using default\n");
+ if (mmc_dev_type == MMC_IS_SD) {
+ params.reg_base = STM32MP_SDMMC1_BASE;
+ } else {
+ params.reg_base = STM32MP_SDMMC2_BASE;
+ }
+ break;
+ }
+
+ params.device_info = &device_info;
+ if (stm32_sdmmc2_mmc_init(¶ms) != 0) {
+ ERROR("SDMMC%u init failed\n", boot_interface_instance);
+ panic();
+ }
+
+ /* Open MMC as a block device to read GPT table */
+ io_result = register_io_dev_block(&mmc_dev_con);
+ if (io_result != 0) {
+ panic();
+ }
+
+ io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec,
+ &storage_dev_handle);
+ assert(io_result == 0);
+
+ partition_init(GPT_IMAGE_ID);
+
+ io_result = io_dev_close(storage_dev_handle);
+ assert(io_result == 0);
+
+ stm32image_dev_info_spec.device_size =
+ stm32_sdmmc2_mmc_get_device_size();
+
+ for (idx = 0U; idx < IMG_IDX_NUM; idx++) {
+ part = &stm32image_dev_info_spec.part_info[idx];
+ entry = get_partition_entry(part->name);
+ if (entry == NULL) {
+ ERROR("Partition %s not found\n", part->name);
+ panic();
+ }
+
+ part->part_offset = entry->start;
+ part->bkp_offset = 0U;
+ }
+
+ /*
+ * Re-open MMC with io_mmc, for better perfs compared to
+ * io_block.
+ */
+ io_result = register_io_dev_mmc(&mmc_dev_con);
+ assert(io_result == 0);
+
+ io_result = io_dev_open(mmc_dev_con, 0, &storage_dev_handle);
+ assert(io_result == 0);
+
+ io_result = register_io_dev_stm32image(&stm32image_dev_con);
+ assert(io_result == 0);
+
+ io_result = io_dev_open(stm32image_dev_con,
+ (uintptr_t)&stm32image_dev_info_spec,
+ &image_dev_handle);
+ assert(io_result == 0);
+}
+
+void stm32mp_io_setup(void)
+{
+ int io_result __unused;
boot_api_context_t *boot_context =
(boot_api_context_t *)stm32mp_get_boot_ctx_address();
@@ -191,93 +329,12 @@
switch (boot_context->boot_interface_selected) {
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
+ dmbsy();
+ boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance);
+ break;
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
dmbsy();
-
- zeromem(&device_info, sizeof(struct mmc_device_info));
- zeromem(¶ms, sizeof(struct stm32_sdmmc2_params));
-
- if (boot_context->boot_interface_selected ==
- BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC) {
- device_info.mmc_dev_type = MMC_IS_EMMC;
- mmc_default_instance = STM32MP_SDMMC2_BASE;
- } else {
- device_info.mmc_dev_type = MMC_IS_SD;
- mmc_default_instance = STM32MP_SDMMC1_BASE;
- }
-
- switch (boot_context->boot_interface_instance) {
- case 1:
- params.reg_base = STM32MP_SDMMC1_BASE;
- break;
- case 2:
- params.reg_base = STM32MP_SDMMC2_BASE;
- break;
- case 3:
- params.reg_base = STM32MP_SDMMC3_BASE;
- break;
- default:
- WARN("SDMMC instance not found, using default\n");
- params.reg_base = mmc_default_instance;
- break;
- }
-
- params.device_info = &device_info;
- if (stm32_sdmmc2_mmc_init(¶ms) != 0) {
- ERROR("SDMMC%u init failed\n",
- boot_context->boot_interface_instance);
- panic();
- }
-
- /* Open MMC as a block device to read GPT table */
- io_result = register_io_dev_block(&mmc_dev_con);
- if (io_result != 0) {
- panic();
- }
-
- io_result = io_dev_open(mmc_dev_con,
- (uintptr_t)&mmc_block_dev_spec,
- &storage_dev_handle);
- assert(io_result == 0);
-
- partition_init(GPT_IMAGE_ID);
-
- io_result = io_dev_close(storage_dev_handle);
- assert(io_result == 0);
-
- stm32image_dev_info_spec.device_size =
- stm32_sdmmc2_mmc_get_device_size();
-
- for (idx = 0U; idx < IMG_IDX_NUM; idx++) {
- part = &stm32image_dev_info_spec.part_info[idx];
- entry = get_partition_entry(part->name);
- if (entry == NULL) {
- ERROR("Partition %s not found\n",
- part->name);
- panic();
- }
-
- part->part_offset = entry->start;
- part->bkp_offset = 0U;
- }
-
- /*
- * Re-open MMC with io_mmc, for better perfs compared to
- * io_block.
- */
- io_result = register_io_dev_mmc(&mmc_dev_con);
- assert(io_result == 0);
-
- io_result = io_dev_open(mmc_dev_con, 0, &storage_dev_handle);
- assert(io_result == 0);
-
- io_result = register_io_dev_stm32image(&stm32image_dev_con);
- assert(io_result == 0);
-
- io_result = io_dev_open(stm32image_dev_con,
- (uintptr_t)&stm32image_dev_info_spec,
- &image_dev_handle);
- assert(io_result == 0);
+ boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance);
break;
default:
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
index 2477954..b54486e 100644
--- a/plat/st/stm32mp1/bl2_plat_setup.c
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -22,6 +22,7 @@
#include <drivers/st/stm32mp1_pwr.h>
#include <drivers/st/stm32mp1_ram.h>
#include <lib/mmio.h>
+#include <lib/optee_utils.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
@@ -136,7 +137,13 @@
panic();
}
+#ifdef AARCH32_SP_OPTEE
+ INFO("BL2 runs OP-TEE setup\n");
+ /* Initialize tzc400 after DDR initialization */
+ stm32mp1_security_setup();
+#else
INFO("BL2 runs SP_MIN setup\n");
+#endif
}
void bl2_el3_plat_arch_setup(void)
@@ -154,11 +161,25 @@
BL_CODE_END - BL_CODE_BASE,
MT_CODE | MT_SECURE);
+#ifdef AARCH32_SP_OPTEE
+ /* OP-TEE image needs post load processing: keep RAM read/write */
+ mmap_add_region(STM32MP_DDR_BASE + dt_get_ddr_size() -
+ STM32MP_DDR_S_SIZE - STM32MP_DDR_SHMEM_SIZE,
+ STM32MP_DDR_BASE + dt_get_ddr_size() -
+ STM32MP_DDR_S_SIZE - STM32MP_DDR_SHMEM_SIZE,
+ STM32MP_DDR_S_SIZE,
+ MT_MEMORY | MT_RW | MT_SECURE);
+
+ mmap_add_region(STM32MP_OPTEE_BASE, STM32MP_OPTEE_BASE,
+ STM32MP_OPTEE_SIZE,
+ MT_MEMORY | MT_RW | MT_SECURE);
+#else
/* Prevent corruption of preloaded BL32 */
mmap_add_region(BL32_BASE, BL32_BASE,
BL32_LIMIT - BL32_BASE,
MT_MEMORY | MT_RO | MT_SECURE);
+#endif
/* Map non secure DDR for BL33 load and DDR training area restore */
mmap_add_region(STM32MP_DDR_BASE,
STM32MP_DDR_BASE,
@@ -261,3 +282,69 @@
stm32mp_io_setup();
}
+
+#if defined(AARCH32_SP_OPTEE)
+/*******************************************************************************
+ * This function can be used by the platforms to update/use image
+ * information for given `image_id`.
+ ******************************************************************************/
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+ int err = 0;
+ bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+ bl_mem_params_node_t *bl32_mem_params;
+ bl_mem_params_node_t *pager_mem_params;
+ bl_mem_params_node_t *paged_mem_params;
+
+ assert(bl_mem_params != NULL);
+
+ switch (image_id) {
+ case BL32_IMAGE_ID:
+ bl_mem_params->ep_info.pc =
+ bl_mem_params->image_info.image_base;
+
+ pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+ assert(pager_mem_params != NULL);
+ pager_mem_params->image_info.image_base = STM32MP_OPTEE_BASE;
+ pager_mem_params->image_info.image_max_size =
+ STM32MP_OPTEE_SIZE;
+
+ paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
+ assert(paged_mem_params != NULL);
+ paged_mem_params->image_info.image_base = STM32MP_DDR_BASE +
+ (dt_get_ddr_size() - STM32MP_DDR_S_SIZE -
+ STM32MP_DDR_SHMEM_SIZE);
+ paged_mem_params->image_info.image_max_size =
+ STM32MP_DDR_S_SIZE;
+
+ err = parse_optee_header(&bl_mem_params->ep_info,
+ &pager_mem_params->image_info,
+ &paged_mem_params->image_info);
+ if (err) {
+ ERROR("OPTEE header parse error.\n");
+ panic();
+ }
+
+ /* Set optee boot info from parsed header data */
+ bl_mem_params->ep_info.pc =
+ pager_mem_params->image_info.image_base;
+ bl_mem_params->ep_info.args.arg0 =
+ paged_mem_params->image_info.image_base;
+ bl_mem_params->ep_info.args.arg1 = 0; /* Unused */
+ bl_mem_params->ep_info.args.arg2 = 0; /* No DT supported */
+ break;
+
+ case BL33_IMAGE_ID:
+ bl32_mem_params = get_bl_mem_params_node(BL32_IMAGE_ID);
+ assert(bl32_mem_params != NULL);
+ bl32_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc;
+ break;
+
+ default:
+ /* Do nothing in default case */
+ break;
+ }
+
+ return err;
+}
+#endif
diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h
index 5019b1a..263e6d6 100644
--- a/plat/st/stm32mp1/include/platform_def.h
+++ b/plat/st/stm32mp1/include/platform_def.h
@@ -25,6 +25,15 @@
#define PLATFORM_STACK_SIZE 0xC00
#endif
+#ifdef AARCH32_SP_OPTEE
+#define OPTEE_HEADER_IMAGE_NAME "teeh"
+#define OPTEE_PAGED_IMAGE_NAME "teed"
+#define OPTEE_PAGER_IMAGE_NAME "teex"
+#define OPTEE_HEADER_BINARY_TYPE U(0x20)
+#define OPTEE_PAGER_BINARY_TYPE U(0x21)
+#define OPTEE_PAGED_BINARY_TYPE U(0x22)
+#endif
+
/* SSBL = second stage boot loader */
#define BL33_IMAGE_NAME "ssbl"
#define BL33_BINARY_TYPE U(0x0)
@@ -57,9 +66,11 @@
/*******************************************************************************
* BL32 specific defines.
******************************************************************************/
+#ifndef AARCH32_SP_OPTEE
#define BL32_BASE STM32MP_BL32_BASE
#define BL32_LIMIT (STM32MP_BL32_BASE + \
STM32MP_BL32_SIZE)
+#endif
/*******************************************************************************
* BL33 specific defines.
diff --git a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
index 0da93e4..1d407bb 100644
--- a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
+++ b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
@@ -27,7 +27,9 @@
VERSION_2, entry_point_info_t,
SECURE | EXECUTABLE | EP_FIRST_EXE),
+#if !defined(AARCH32_SP_OPTEE)
.ep_info.pc = BL32_BASE,
+#endif
.ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
SPSR_E_LITTLE,
DISABLE_ALL_EXCEPTIONS),
@@ -35,13 +37,48 @@
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
VERSION_2, image_info_t,
IMAGE_ATTRIB_PLAT_SETUP),
-
+#if defined(AARCH32_SP_OPTEE)
+ /* optee header is loaded in SYSRAM above BL2 */
+ .image_info.image_base = STM32MP_OPTEE_BASE,
+ .image_info.image_max_size = STM32MP_OPTEE_SIZE,
+#else
.image_info.image_base = BL32_BASE,
.image_info.image_max_size = BL32_LIMIT - BL32_BASE,
-
+#endif
.next_handoff_image_id = BL33_IMAGE_ID,
},
+#if defined(AARCH32_SP_OPTEE)
+ /* Fill BL32 external 1 image related information */
+ {
+ .image_id = BL32_EXTRA1_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | NON_EXECUTABLE),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_SKIP_LOADING),
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+ /* Fill BL32 external 2 image related information */
+ {
+ .image_id = BL32_EXTRA2_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | NON_EXECUTABLE),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_SKIP_LOADING),
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ },
+#endif /* AARCH32_SP_OPTEE */
+
/* Fill BL33 related information */
{
.image_id = BL33_IMAGE_ID,
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 3e34601..4796e91 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -18,7 +18,11 @@
# Number of TF-A copies in the device
STM32_TF_A_COPIES := 2
$(eval $(call add_define,STM32_TF_A_COPIES))
+ifeq ($(AARCH32_SP),optee)
+PLAT_PARTITION_MAX_ENTRIES := $(shell echo $$(($(STM32_TF_A_COPIES) + 4)))
+else
PLAT_PARTITION_MAX_ENTRIES := $(shell echo $$(($(STM32_TF_A_COPIES) + 1)))
+endif
$(eval $(call add_define,PLAT_PARTITION_MAX_ENTRIES))
PLAT_INCLUDES := -Iplat/st/common/include/
@@ -84,6 +88,10 @@
plat/st/stm32mp1/plat_bl2_mem_params_desc.c \
plat/st/stm32mp1/plat_image_load.c
+ifeq ($(AARCH32_SP),optee)
+BL2_SOURCES += lib/optee/optee_utils.c
+endif
+
# Macros and rules to build TF binary
STM32_TF_ELF_LDFLAGS := --hash-style=gnu --as-needed
STM32_DT_BASENAME := $(DTB_FILE_NAME:.dtb=)
diff --git a/plat/st/stm32mp1/stm32mp1.ld.S b/plat/st/stm32mp1/stm32mp1.ld.S
index c041fb6..b347bad 100644
--- a/plat/st/stm32mp1/stm32mp1.ld.S
+++ b/plat/st/stm32mp1/stm32mp1.ld.S
@@ -58,6 +58,7 @@
*(.bl2_image*)
__BL2_IMAGE_END__ = .;
+#ifndef AARCH32_SP_OPTEE
/*
* bl32 will be settled by bl2.
* The strongest and only alignment constraint is 8 words to simplify
@@ -67,6 +68,7 @@
__BL32_IMAGE_START__ = .;
*(.bl32_image*)
__BL32_IMAGE_END__ = .;
+#endif
__DATA_END__ = .;
} >RAM
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index 1c897bd..cff7ddb 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -34,7 +34,10 @@
/* DDR configuration */
#define STM32MP_DDR_BASE U(0xC0000000)
#define STM32MP_DDR_MAX_SIZE U(0x40000000) /* Max 1GB */
-#define STM32MP_DDR_SPEED_DFLT 528
+#ifdef AARCH32_SP_OPTEE
+#define STM32MP_DDR_S_SIZE U(0x01E00000) /* 30 MB */
+#define STM32MP_DDR_SHMEM_SIZE U(0x00200000) /* 2 MB */
+#endif
/* DDR power initializations */
#ifndef __ASSEMBLY__
@@ -57,21 +60,38 @@
(STM32MP_PARAM_LOAD_SIZE + \
STM32MP_HEADER_SIZE))
+#ifdef AARCH32_SP_OPTEE
+#define STM32MP_BL32_SIZE U(0)
+
+#define STM32MP_OPTEE_BASE STM32MP_SYSRAM_BASE
+
+#define STM32MP_OPTEE_SIZE (STM32MP_DTB_BASE - \
+ STM32MP_OPTEE_BASE)
+#else
#if STACK_PROTECTOR_ENABLED
#define STM32MP_BL32_SIZE U(0x00012000) /* 72 Ko for BL32 */
#else
#define STM32MP_BL32_SIZE U(0x00011000) /* 68 Ko for BL32 */
#endif
+#endif
#define STM32MP_BL32_BASE (STM32MP_SYSRAM_BASE + \
STM32MP_SYSRAM_SIZE - \
STM32MP_BL32_SIZE)
+#ifdef AARCH32_SP_OPTEE
+#if STACK_PROTECTOR_ENABLED
+#define STM32MP_BL2_SIZE U(0x00019000) /* 100 Ko for BL2 */
+#else
+#define STM32MP_BL2_SIZE U(0x00017000) /* 92 Ko for BL2 */
+#endif
+#else
#if STACK_PROTECTOR_ENABLED
#define STM32MP_BL2_SIZE U(0x00015000) /* 84 Ko for BL2 */
#else
#define STM32MP_BL2_SIZE U(0x00013000) /* 76 Ko for BL2 */
#endif
+#endif
#define STM32MP_BL2_BASE (STM32MP_BL32_BASE - \
STM32MP_BL2_SIZE)
diff --git a/plat/st/stm32mp1/stm32mp1_security.c b/plat/st/stm32mp1/stm32mp1_security.c
index 0ad43e4..61db2e7 100644
--- a/plat/st/stm32mp1/stm32mp1_security.c
+++ b/plat/st/stm32mp1/stm32mp1_security.c
@@ -14,6 +14,19 @@
#include <dt-bindings/clock/stm32mp1-clks.h>
#include <lib/mmio.h>
+#define TZC_REGION_NSEC_ALL_ACCESS_RDWR \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_GPU_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_MDMA_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_M4_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DMA_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_ETH_ID) | \
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DAP_ID)
+
/*******************************************************************************
* Initialize the TrustZone Controller. Configure Region 0 with Secure RW access
* and allow Non-Secure masters full access.
@@ -23,31 +36,55 @@
unsigned long long region_base, region_top;
unsigned long long ddr_base = STM32MP_DDR_BASE;
unsigned long long ddr_size = (unsigned long long)dt_get_ddr_size();
+ unsigned long long ddr_top = ddr_base + (ddr_size - 1U);
tzc400_init(STM32MP1_TZC_BASE);
tzc400_disable_filters();
- /* Region 1 set to cover all DRAM at 0xC000_0000. Apply the
+#ifdef AARCH32_SP_OPTEE
+ /*
+ * Region 1 set to cover all non-secure DRAM at 0xC000_0000. Apply the
* same configuration to all filters in the TZC.
*/
region_base = ddr_base;
- region_top = ddr_base + (ddr_size - 1U);
+ region_top = ddr_top - STM32MP_DDR_S_SIZE - STM32MP_DDR_SHMEM_SIZE;
tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 1,
- region_base,
- region_top,
- TZC_REGION_S_RDWR,
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) |
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_GPU_ID) |
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) |
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_MDMA_ID) |
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_M4_ID) |
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DMA_ID) |
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) |
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) |
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID) |
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_ETH_ID) |
- TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DAP_ID));
+ region_base,
+ region_top,
+ TZC_REGION_S_NONE,
+ TZC_REGION_NSEC_ALL_ACCESS_RDWR);
+
+ /* Region 2 set to cover all secure DRAM. */
+ region_base = region_top + 1U;
+ region_top = ddr_top - STM32MP_DDR_SHMEM_SIZE;
+ tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 2,
+ region_base,
+ region_top,
+ TZC_REGION_S_RDWR,
+ 0);
+
+ /* Region 3 set to cover non-secure shared memory DRAM. */
+ region_base = region_top + 1U;
+ region_top = ddr_top;
+ tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 3,
+ region_base,
+ region_top,
+ TZC_REGION_S_NONE,
+ TZC_REGION_NSEC_ALL_ACCESS_RDWR);
+#else
+ /*
+ * Region 1 set to cover all DRAM at 0xC000_0000. Apply the
+ * same configuration to all filters in the TZC.
+ */
+ region_base = ddr_base;
+ region_top = ddr_top;
+ tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 1,
+ region_base,
+ region_top,
+ TZC_REGION_S_NONE,
+ TZC_REGION_NSEC_ALL_ACCESS_RDWR);
+#endif
/* Raise an exception if a NS device tries to access secure memory */
tzc400_set_action(TZC_ACTION_ERR);
@@ -69,15 +106,12 @@
tzc400_disable_filters();
- /*
- * Region 1 set to cover Non-Secure DRAM at 0x8000_0000. Apply the
- * same configuration to all filters in the TZC.
- */
+ /* Region 1 set to cover Non-Secure DRAM at 0xC000_0000 */
tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 1,
STM32MP_DDR_BASE,
STM32MP_DDR_BASE +
(STM32MP_DDR_MAX_SIZE - 1U),
- TZC_REGION_S_RDWR,
+ TZC_REGION_S_NONE,
TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) |
TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID));