diff options
-rw-r--r-- | include/plat/arm/board/common/board_arm_def.h | 19 | ||||
-rw-r--r-- | include/plat/arm/board/common/v2m_def.h | 1 | ||||
-rw-r--r-- | include/plat/arm/common/plat_arm.h | 4 | ||||
-rw-r--r-- | plat/arm/board/common/board_common.mk | 8 | ||||
-rw-r--r-- | plat/arm/board/common/board_css_common.c | 6 | ||||
-rw-r--r-- | plat/arm/board/fvp/fvp_common.c | 1 | ||||
-rw-r--r-- | plat/arm/board/fvp/fvp_pm.c | 13 | ||||
-rw-r--r-- | plat/arm/board/fvp/sp_min/sp_min-fvp.mk | 5 | ||||
-rw-r--r-- | plat/arm/board/juno/include/platform_def.h | 10 | ||||
-rw-r--r-- | plat/arm/board/juno/sp_min/sp_min-juno.mk | 3 | ||||
-rw-r--r-- | plat/arm/common/arm_bl2_setup.c | 4 | ||||
-rw-r--r-- | plat/arm/common/arm_nor_psci_mem_protect.c | 92 | ||||
-rw-r--r-- | plat/arm/css/common/css_pm.c | 11 |
13 files changed, 164 insertions, 13 deletions
diff --git a/include/plat/arm/board/common/board_arm_def.h b/include/plat/arm/board/common/board_arm_def.h index 751c3bb1..a065abf5 100644 --- a/include/plat/arm/board/common/board_arm_def.h +++ b/include/plat/arm/board/common/board_arm_def.h @@ -89,11 +89,26 @@ #define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00040000 /* 256 KB */ +/* Reserve the last block of flash for PSCI MEM PROTECT flag */ #define PLAT_ARM_FIP_BASE V2M_FLASH0_BASE -#define PLAT_ARM_FIP_MAX_SIZE V2M_FLASH0_SIZE +#define PLAT_ARM_FIP_MAX_SIZE (V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE) #define PLAT_ARM_NVM_BASE V2M_FLASH0_BASE -#define PLAT_ARM_NVM_SIZE V2M_FLASH0_SIZE +#define PLAT_ARM_NVM_SIZE (V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE) +/* PSCI memory protect definitions: + * This variable is stored in a non-secure flash because some ARM reference + * platforms do not have secure NVRAM. Real systems that provided MEM_PROTECT + * support must use a secure NVRAM to store the PSCI MEM_PROTECT definitions. + */ +#define PLAT_ARM_MEM_PROT_ADDR (V2M_FLASH0_BASE + \ + V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE) + +/* + * Map mem_protect flash region with read and write permissions + */ +#define ARM_V2M_MAP_MEM_PROTECT MAP_REGION_FLAT(PLAT_ARM_MEM_PROT_ADDR, \ + V2M_FLASH_BLOCK_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) #endif /* __BOARD_ARM_DEF_H__ */ diff --git a/include/plat/arm/board/common/v2m_def.h b/include/plat/arm/board/common/v2m_def.h index 2ad513ac..364b7803 100644 --- a/include/plat/arm/board/common/v2m_def.h +++ b/include/plat/arm/board/common/v2m_def.h @@ -69,6 +69,7 @@ /* NOR Flash */ #define V2M_FLASH0_BASE 0x08000000 #define V2M_FLASH0_SIZE 0x04000000 +#define V2M_FLASH_BLOCK_SIZE 0x00040000 /* 256 KB */ #define V2M_IOFPGA_BASE 0x1c000000 #define V2M_IOFPGA_SIZE 0x03000000 diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index f0e97678..4e589c0c 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -122,6 +122,10 @@ int arm_validate_power_state(unsigned int power_state, int arm_validate_ns_entrypoint(uintptr_t entrypoint); void arm_system_pwr_domain_resume(void); void arm_program_trusted_mailbox(uintptr_t address); +int arm_psci_read_mem_protect(int *val); +int arm_nor_psci_write_mem_protect(int val); +void arm_nor_psci_do_mem_protect(void); +int arm_psci_mem_protect_chk(uintptr_t base, u_register_t length); /* Topology utility function */ int arm_check_mpidr(u_register_t mpidr); diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk index 46672982..2023150c 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 159bf86f..4638af18 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 e869f5b2..bc033130 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 9a02089e..dad3a794 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 864df1ba..b370fd55 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 f1714e13..e8a4a40a 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 336c4e7c..cd1f4976 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 cab6113e..5d83118a 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 00000000..0f16e352 --- /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 e0e52004..93d51fe6 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 }; |