aboutsummaryrefslogtreecommitdiffstats
path: root/plat
diff options
context:
space:
mode:
authorRoberto Vargas <roberto.vargas@arm.com>2017-08-03 09:16:43 +0100
committerRoberto Vargas <roberto.vargas@arm.com>2017-09-25 13:32:20 +0100
commitf145403c2a1a7064cb55670ac0674dc6586398ab (patch)
tree8da5287f959444b451329224dc57ff595fb82b05 /plat
parent43cbaf061587e7e8b3529e4b1d30de3ab1b52d3e (diff)
downloadplatform_external_arm-trusted-firmware-f145403c2a1a7064cb55670ac0674dc6586398ab.tar.gz
platform_external_arm-trusted-firmware-f145403c2a1a7064cb55670ac0674dc6586398ab.tar.bz2
platform_external_arm-trusted-firmware-f145403c2a1a7064cb55670ac0674dc6586398ab.zip
mem_protect: Add mem_protect support in Juno and FVP for DRAM1
mem_protect needs some kind of non-volatile memory because it has to remember its state across reset and power down events. The most suitable electronic part for this feature is a NVRAM which should be only accesible from the secure world. Juno and FVP lack such hardware and for this reason the MEM_PROTECT functionality is implemented with Flash EEPROM memory on both boards, even though this memory is accesible from the non-secure world. This is done only to show a full implementation of these PSCI features, but an actual system shouldn't use a non-secure NVRAM to implement it. The EL3 runtime software will write the mem_protect flag and BL2 will read and clear the memory ranges if enabled. It is done in BL2 because it reduces the time that TF needs access to the full non-secure memory. The memory layout of both boards is defined using macros which take different values in Juno and FVP platforms. Generic platform helpers are added that use the platform specific macros to generate a mem_region_t that is valid for the platform. Change-Id: I2c6818ac091a2966fa07a52c5ddf8f6fde4941e9 Signed-off-by: Roberto Vargas <roberto.vargas@arm.com>
Diffstat (limited to 'plat')
-rw-r--r--plat/arm/board/common/board_common.mk8
-rw-r--r--plat/arm/board/common/board_css_common.c6
-rw-r--r--plat/arm/board/fvp/fvp_common.c1
-rw-r--r--plat/arm/board/fvp/fvp_pm.c13
-rw-r--r--plat/arm/board/fvp/sp_min/sp_min-fvp.mk5
-rw-r--r--plat/arm/board/juno/include/platform_def.h10
-rw-r--r--plat/arm/board/juno/sp_min/sp_min-juno.mk3
-rw-r--r--plat/arm/common/arm_bl2_setup.c4
-rw-r--r--plat/arm/common/arm_nor_psci_mem_protect.c92
-rw-r--r--plat/arm/css/common/css_pm.c11
10 files changed, 142 insertions, 11 deletions
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index 46672982c..2023150cc 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -12,9 +12,13 @@ PLAT_BL_COMMON_SOURCES += drivers/arm/pl011/${ARCH}/pl011_console.S \
BL1_SOURCES += plat/arm/board/common/drivers/norflash/norflash.c
-BL2_SOURCES += plat/arm/board/common/drivers/norflash/norflash.c
+BL2_SOURCES += lib/utils/mem_region.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c \
+ plat/arm/board/common/drivers/norflash/norflash.c
-#BL31_SOURCES +=
+BL31_SOURCES += lib/utils/mem_region.c \
+ plat/arm/board/common/drivers/norflash/norflash.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
ifneq (${TRUSTED_BOARD_BOOT},0)
ifneq (${ARM_CRYPTOCELL_INTEG}, 1)
diff --git a/plat/arm/board/common/board_css_common.c b/plat/arm/board/common/board_css_common.c
index 159bf86f4..4638af183 100644
--- a/plat/arm/board/common/board_css_common.c
+++ b/plat/arm/board/common/board_css_common.c
@@ -29,6 +29,9 @@ const mmap_region_t plat_arm_mmap[] = {
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
V2M_MAP_FLASH0_RO,
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+ ARM_V2M_MAP_MEM_PROTECT,
+#endif
V2M_MAP_IOFPGA,
CSS_MAP_DEVICE,
SOC_CSS_MAP_DEVICE,
@@ -56,6 +59,9 @@ const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
V2M_MAP_IOFPGA,
CSS_MAP_DEVICE,
+#ifdef PLAT_ARM_MEM_PROT_ADDR
+ ARM_V2M_MAP_MEM_PROTECT,
+#endif
SOC_CSS_MAP_DEVICE,
{0}
};
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index e869f5b22..bc033130c 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -109,6 +109,7 @@ const mmap_region_t plat_arm_mmap[] = {
V2M_MAP_IOFPGA,
MAP_DEVICE0,
MAP_DEVICE1,
+ ARM_V2M_MAP_MEM_PROTECT,
{0}
};
#endif
diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c
index 9a02089e7..dad3a7949 100644
--- a/plat/arm/board/fvp/fvp_pm.c
+++ b/plat/arm/board/fvp/fvp_pm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -324,5 +324,14 @@ plat_psci_ops_t plat_arm_psci_pm_ops = {
.system_reset = fvp_system_reset,
.validate_power_state = arm_validate_power_state,
.validate_ns_entrypoint = arm_validate_ns_entrypoint,
- .get_node_hw_state = fvp_node_hw_state
+ .get_node_hw_state = fvp_node_hw_state,
+/*
+ * mem_protect is not supported in RESET_TO_BL31 and RESET_TO_SP_MIN,
+ * as that would require mapping in all of NS DRAM into BL31 or BL32.
+ */
+#if !RESET_TO_BL31 && !RESET_TO_SP_MIN
+ .mem_protect_chk = arm_psci_mem_protect_chk,
+ .read_mem_protect = arm_psci_read_mem_protect,
+ .write_mem_protect = arm_nor_psci_write_mem_protect,
+#endif
};
diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
index 864df1bad..b370fd55a 100644
--- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
+++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk
@@ -5,11 +5,14 @@
#
# SP_MIN source files specific to FVP platform
-BL32_SOURCES += plat/arm/board/fvp/aarch32/fvp_helpers.S \
+BL32_SOURCES += lib/utils/mem_region.c \
+ plat/arm/board/fvp/aarch32/fvp_helpers.S \
plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c \
plat/arm/board/fvp/fvp_pm.c \
plat/arm/board/fvp/fvp_topology.c \
plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c \
+ plat/arm/board/common/drivers/norflash/norflash.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c \
${FVP_CPU_LIBS} \
${FVP_GIC_SOURCES} \
${FVP_INTERCONNECT_SOURCES} \
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index f1714e137..e8a4a40a8 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -68,11 +68,11 @@
#ifdef IMAGE_BL2
#ifdef SPD_opteed
+# define PLAT_ARM_MMAP_ENTRIES 10
+# define MAX_XLAT_TABLES 5
+#else
# define PLAT_ARM_MMAP_ENTRIES 9
# define MAX_XLAT_TABLES 4
-#else
-# define PLAT_ARM_MMAP_ENTRIES 8
-# define MAX_XLAT_TABLES 3
#endif
#endif
@@ -82,8 +82,8 @@
#endif
#ifdef IMAGE_BL31
-# define PLAT_ARM_MMAP_ENTRIES 5
-# define MAX_XLAT_TABLES 2
+# define PLAT_ARM_MMAP_ENTRIES 6
+# define MAX_XLAT_TABLES 3
#endif
#ifdef IMAGE_BL32
diff --git a/plat/arm/board/juno/sp_min/sp_min-juno.mk b/plat/arm/board/juno/sp_min/sp_min-juno.mk
index 336c4e7ce..cd1f4976c 100644
--- a/plat/arm/board/juno/sp_min/sp_min-juno.mk
+++ b/plat/arm/board/juno/sp_min/sp_min-juno.mk
@@ -8,7 +8,10 @@
BL32_SOURCES += lib/cpus/aarch32/cortex_a53.S \
lib/cpus/aarch32/cortex_a57.S \
lib/cpus/aarch32/cortex_a72.S \
+ lib/utils/mem_region.c \
+ plat/arm/board/common/drivers/norflash/norflash.c \
plat/arm/board/juno/juno_topology.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c \
plat/arm/soc/common/soc_css_security.c \
${JUNO_GIC_SOURCES} \
${JUNO_INTERCONNECT_SOURCES} \
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index cab6113e9..5d83118a8 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -193,6 +193,10 @@ void arm_bl2_platform_setup(void)
{
/* Initialize the secure environment */
plat_arm_security_setup();
+
+#if defined(PLAT_ARM_MEM_PROT_ADDR)
+ arm_nor_psci_do_mem_protect();
+#endif
}
void bl2_platform_setup(void)
diff --git a/plat/arm/common/arm_nor_psci_mem_protect.c b/plat/arm/common/arm_nor_psci_mem_protect.c
new file mode 100644
index 000000000..0f16e3529
--- /dev/null
+++ b/plat/arm/common/arm_nor_psci_mem_protect.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <mmio.h>
+#include <norflash.h>
+#include <plat_arm.h>
+#include <platform_def.h>
+#include <psci.h>
+#include <utils.h>
+
+mem_region_t arm_ram_ranges[] = {
+ {ARM_NS_DRAM1_BASE, ARM_NS_DRAM1_SIZE},
+};
+
+/*******************************************************************************
+ * Function that reads the content of the memory protect variable that
+ * enables clearing of non secure memory when system boots. This variable
+ * should be stored in a secure NVRAM.
+ ******************************************************************************/
+int arm_psci_read_mem_protect(int *enabled)
+{
+ int tmp;
+
+ tmp = *(int *) PLAT_ARM_MEM_PROT_ADDR;
+ *enabled = (tmp == 1);
+ return 0;
+}
+
+/*******************************************************************************
+ * Function that writes the content of the memory protect variable that
+ * enables overwritten of non secure memory when system boots.
+ ******************************************************************************/
+int arm_nor_psci_write_mem_protect(int val)
+{
+ int enable = (val != 0);
+
+ if (nor_unlock(PLAT_ARM_MEM_PROT_ADDR) != 0) {
+ ERROR("unlocking memory protect variable\n");
+ return -1;
+ }
+
+ if (enable) {
+ /*
+ * If we want to write a value different than 0
+ * then we have to erase the full block because
+ * otherwise we cannot ensure that the value programmed
+ * into the flash is going to be the same than the value
+ * requested by the caller
+ */
+ if (nor_erase(PLAT_ARM_MEM_PROT_ADDR) != 0) {
+ ERROR("erasing block containing memory protect variable\n");
+ return -1;
+ }
+ }
+
+ if (nor_word_program(PLAT_ARM_MEM_PROT_ADDR, enable) != 0) {
+ ERROR("programming memory protection variable\n");
+ return -1;
+ }
+ return 0;
+}
+
+/*******************************************************************************
+ * Function used for required psci operations performed when
+ * system boots
+ ******************************************************************************/
+void arm_nor_psci_do_mem_protect(void)
+{
+ int enable;
+
+ arm_psci_read_mem_protect(&enable);
+ if (!enable)
+ return;
+ INFO("PSCI: Overwritting non secure memory\n");
+ clear_mem_regions(arm_ram_ranges, ARRAY_SIZE(arm_ram_ranges));
+ arm_nor_psci_write_mem_protect(0);
+}
+
+/*******************************************************************************
+ * Function that checks if a region is protected by the memory protect
+ * mechanism
+ ******************************************************************************/
+int arm_psci_mem_protect_chk(uintptr_t base, u_register_t length)
+{
+ return mem_region_in_array_chk(arm_ram_ranges,
+ ARRAY_SIZE(arm_ram_ranges),
+ base, length);
+}
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index e0e52004d..93d51fe66 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -290,5 +290,14 @@ plat_psci_ops_t plat_arm_psci_pm_ops = {
.validate_ns_entrypoint = arm_validate_ns_entrypoint,
.translate_power_state_by_mpidr = css_translate_power_state_by_mpidr,
.get_node_hw_state = css_node_hw_state,
- .get_sys_suspend_power_state = css_get_sys_suspend_power_state
+ .get_sys_suspend_power_state = css_get_sys_suspend_power_state,
+/*
+ * mem_protect is not supported in RESET_TO_BL31 and RESET_TO_SP_MIN,
+ * as that would require mapping in all of NS DRAM into BL31 or BL32.
+ */
+#if defined(PLAT_ARM_MEM_PROT_ADDR) && !RESET_TO_BL31 && !RESET_TO_SP_MIN
+ .mem_protect_chk = arm_psci_mem_protect_chk,
+ .read_mem_protect = arm_psci_read_mem_protect,
+ .write_mem_protect = arm_nor_psci_write_mem_protect,
+#endif
};