Merge pull request #1109 from robertovargas-arm/mem_protect
Mem protect
This commit is contained in:
commit
c64d1345a8
|
@ -65,6 +65,9 @@
|
|||
#define PSCI_STAT_RESIDENCY_AARCH64 U(0xc4000010)
|
||||
#define PSCI_STAT_COUNT_AARCH32 U(0x84000011)
|
||||
#define PSCI_STAT_COUNT_AARCH64 U(0xc4000011)
|
||||
#define PSCI_MEM_PROTECT U(0x84000013)
|
||||
#define PSCI_MEM_CHK_RANGE_AARCH32 U(0x84000014)
|
||||
#define PSCI_MEM_CHK_RANGE_AARCH64 U(0xc4000014)
|
||||
|
||||
/* Macro to help build the psci capabilities bitfield */
|
||||
#define define_psci_cap(x) (U(1) << (x & U(0x1f)))
|
||||
|
@ -288,6 +291,9 @@ typedef struct plat_psci_ops {
|
|||
unsigned int power_state,
|
||||
psci_power_state_t *output_state);
|
||||
int (*get_node_hw_state)(u_register_t mpidr, unsigned int power_level);
|
||||
int (*mem_protect_chk)(uintptr_t base, u_register_t length);
|
||||
int (*read_mem_protect)(int *val);
|
||||
int (*write_mem_protect)(int val);
|
||||
} plat_psci_ops_t;
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
@ -19,6 +19,25 @@
|
|||
|
||||
#include <types.h>
|
||||
|
||||
typedef struct mem_region_t {
|
||||
uintptr_t base;
|
||||
size_t nbytes;
|
||||
} mem_region_t;
|
||||
|
||||
/*
|
||||
* zero_normalmem all the regions defined in tbl.
|
||||
*/
|
||||
void clear_mem_regions(mem_region_t *tbl, size_t nregions);
|
||||
|
||||
|
||||
/*
|
||||
* checks that a region (addr + nbytes-1) of memory is totally covered by
|
||||
* one of the regions defined in tbl. Caller must ensure that (addr+nbytes-1)
|
||||
* doesn't overflow.
|
||||
*/
|
||||
int mem_region_in_array_chk(mem_region_t *tbl, size_t nregions,
|
||||
uintptr_t addr, size_t nbytes);
|
||||
|
||||
/*
|
||||
* Fill a region of normal memory of size "length" in bytes with zero bytes.
|
||||
*
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -177,7 +177,12 @@
|
|||
ARM_NS_DRAM1_SIZE, \
|
||||
MT_MEMORY | MT_RW | MT_NS)
|
||||
|
||||
#define ARM_MAP_DRAM2 MAP_REGION_FLAT( \
|
||||
ARM_DRAM2_BASE, \
|
||||
ARM_DRAM2_SIZE, \
|
||||
MT_MEMORY | MT_RW | MT_NS)
|
||||
#ifdef SPD_tspd
|
||||
|
||||
#define ARM_MAP_TSP_SEC_MEM MAP_REGION_FLAT( \
|
||||
TSP_SEC_MEM_BASE, \
|
||||
TSP_SEC_MEM_SIZE, \
|
||||
|
@ -224,8 +229,18 @@
|
|||
* Required platform porting definitions common to all ARM standard platforms
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* We need to access DRAM2 from BL2 for PSCI_MEM_PROTECT for
|
||||
* AArch64 builds
|
||||
*/
|
||||
#ifdef AARCH64
|
||||
#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 36)
|
||||
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 36)
|
||||
#else
|
||||
#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 32)
|
||||
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 32)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* This macro defines the deepest retention state possible. A higher state
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -17,6 +17,7 @@ PSCI_LIB_SOURCES := lib/el3_runtime/cpu_data_array.c \
|
|||
lib/psci/psci_main.c \
|
||||
lib/psci/psci_setup.c \
|
||||
lib/psci/psci_system_off.c \
|
||||
lib/psci/psci_mem_protect.c \
|
||||
lib/psci/${ARCH}/psci_helpers.S
|
||||
|
||||
ifeq (${ARCH}, aarch64)
|
||||
|
|
|
@ -408,6 +408,11 @@ u_register_t psci_smc_handler(uint32_t smc_fid,
|
|||
case PSCI_STAT_COUNT_AARCH32:
|
||||
return psci_stat_count(x1, x2);
|
||||
#endif
|
||||
case PSCI_MEM_PROTECT:
|
||||
return psci_mem_protect(x1);
|
||||
|
||||
case PSCI_MEM_CHK_RANGE_AARCH32:
|
||||
return psci_mem_chk_range(x1, x2);
|
||||
|
||||
default:
|
||||
break;
|
||||
|
@ -445,6 +450,10 @@ u_register_t psci_smc_handler(uint32_t smc_fid,
|
|||
return psci_stat_count(x1, x2);
|
||||
#endif
|
||||
|
||||
case PSCI_MEM_CHK_RANGE_AARCH64:
|
||||
return psci_mem_chk_range(x1, x2);
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <utils.h>
|
||||
#include "psci_private.h"
|
||||
|
||||
int psci_mem_protect(unsigned int enable)
|
||||
{
|
||||
int val;
|
||||
|
||||
assert(psci_plat_pm_ops->read_mem_protect);
|
||||
assert(psci_plat_pm_ops->write_mem_protect);
|
||||
|
||||
if (psci_plat_pm_ops->read_mem_protect(&val) < 0)
|
||||
return PSCI_E_NOT_SUPPORTED;
|
||||
if (psci_plat_pm_ops->write_mem_protect(enable) < 0)
|
||||
return PSCI_E_NOT_SUPPORTED;
|
||||
|
||||
return val != 0;
|
||||
}
|
||||
|
||||
int psci_mem_chk_range(uintptr_t base, u_register_t length)
|
||||
{
|
||||
int ret;
|
||||
|
||||
assert(psci_plat_pm_ops->mem_protect_chk);
|
||||
|
||||
if (length == 0 || check_uptr_overflow(base, length-1))
|
||||
return PSCI_E_DENIED;
|
||||
|
||||
ret = psci_plat_pm_ops->mem_protect_chk(base, length);
|
||||
return (ret < 0) ? PSCI_E_DENIED : PSCI_E_SUCCESS;
|
||||
}
|
|
@ -269,4 +269,8 @@ u_register_t psci_stat_residency(u_register_t target_cpu,
|
|||
u_register_t psci_stat_count(u_register_t target_cpu,
|
||||
unsigned int power_state);
|
||||
|
||||
/* Private exported functions from psci_mem_protect.c */
|
||||
int psci_mem_protect(unsigned int enable);
|
||||
int psci_mem_chk_range(uintptr_t base, u_register_t length);
|
||||
|
||||
#endif /* __PSCI_PRIVATE_H__ */
|
||||
|
|
|
@ -243,6 +243,11 @@ int psci_setup(const psci_lib_args_t *lib_args)
|
|||
psci_caps |= define_psci_cap(PSCI_SYSTEM_RESET);
|
||||
if (psci_plat_pm_ops->get_node_hw_state)
|
||||
psci_caps |= define_psci_cap(PSCI_NODE_HW_STATE_AARCH64);
|
||||
if (psci_plat_pm_ops->read_mem_protect &&
|
||||
psci_plat_pm_ops->write_mem_protect)
|
||||
psci_caps |= define_psci_cap(PSCI_MEM_PROTECT);
|
||||
if (psci_plat_pm_ops->mem_protect_chk)
|
||||
psci_caps |= define_psci_cap(PSCI_MEM_CHK_RANGE_AARCH64);
|
||||
|
||||
#if ENABLE_PSCI_STAT
|
||||
psci_caps |= define_psci_cap(PSCI_STAT_RESIDENCY_AARCH64);
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <utils.h>
|
||||
|
||||
/*
|
||||
* All the regions defined in mem_region_t must have the following properties
|
||||
*
|
||||
* - Any contiguous regions must be merged into a single entry.
|
||||
* - The number of bytes of each region must be greater than zero.
|
||||
* - The calculation of the highest address within the region (base + nbytes-1)
|
||||
* doesn't produce an overflow.
|
||||
*
|
||||
* These conditions must be fulfilled by the caller and they aren't checked
|
||||
* at runtime.
|
||||
*/
|
||||
|
||||
/*
|
||||
* zero_normalmem all the regions defined in tbl.
|
||||
* It assumes that MMU is enabled and the memory is Normal memory.
|
||||
* tbl must be a valid pointer to a memory mem_region_t array,
|
||||
* nregions is the size of the array.
|
||||
*/
|
||||
void clear_mem_regions(mem_region_t *tbl, size_t nregions)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
assert(tbl);
|
||||
assert(nregions > 0);
|
||||
|
||||
for (i = 0; i < nregions; i++) {
|
||||
assert(tbl->nbytes > 0);
|
||||
assert(!check_uptr_overflow(tbl->base, tbl->nbytes-1));
|
||||
zero_normalmem((void *) (tbl->base), tbl->nbytes);
|
||||
tbl++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function checks that a region (addr + nbytes-1) of memory is totally
|
||||
* covered by one of the regions defined in tbl.
|
||||
* tbl must be a valid pointer to a memory mem_region_t array, nregions
|
||||
* is the size of the array and the region described by addr and nbytes must
|
||||
* not generate an overflow.
|
||||
* Returns:
|
||||
* -1 means that the region is not covered by any of the regions
|
||||
* described in tbl.
|
||||
* 0 the region (addr + nbytes-1) is covered by one of the regions described
|
||||
* in tbl
|
||||
*/
|
||||
int mem_region_in_array_chk(mem_region_t *tbl, size_t nregions,
|
||||
uintptr_t addr, size_t nbytes)
|
||||
{
|
||||
uintptr_t region_start, region_end, start, end;
|
||||
size_t i;
|
||||
|
||||
assert(tbl);
|
||||
assert(nbytes > 0);
|
||||
assert(!check_uptr_overflow(addr, nbytes-1));
|
||||
|
||||
region_start = addr;
|
||||
region_end = addr + (nbytes - 1);
|
||||
for (i = 0; i < nregions; i++) {
|
||||
assert(tbl->nbytes > 0);
|
||||
assert(!check_uptr_overflow(tbl->base, tbl->nbytes-1));
|
||||
start = tbl->base;
|
||||
end = start + (tbl->nbytes - 1);
|
||||
if (region_start >= start && region_end <= end)
|
||||
return 0;
|
||||
tbl++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -29,10 +29,16 @@ 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,
|
||||
ARM_MAP_NS_DRAM1,
|
||||
#ifdef AARCH64
|
||||
ARM_MAP_DRAM2,
|
||||
#endif
|
||||
#ifdef SPD_tspd
|
||||
ARM_MAP_TSP_SEC_MEM,
|
||||
#endif
|
||||
|
@ -56,6 +62,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}
|
||||
};
|
||||
|
|
|
@ -79,6 +79,9 @@ const mmap_region_t plat_arm_mmap[] = {
|
|||
MAP_DEVICE0,
|
||||
MAP_DEVICE1,
|
||||
ARM_MAP_NS_DRAM1,
|
||||
#ifdef AARCH64
|
||||
ARM_MAP_DRAM2,
|
||||
#endif
|
||||
#ifdef SPD_tspd
|
||||
ARM_MAP_TSP_SEC_MEM,
|
||||
#endif
|
||||
|
@ -109,6 +112,7 @@ const mmap_region_t plat_arm_mmap[] = {
|
|||
V2M_MAP_IOFPGA,
|
||||
MAP_DEVICE0,
|
||||
MAP_DEVICE1,
|
||||
ARM_V2M_MAP_MEM_PROTECT,
|
||||
{0}
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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} \
|
||||
|
|
|
@ -68,11 +68,11 @@
|
|||
|
||||
#ifdef IMAGE_BL2
|
||||
#ifdef SPD_opteed
|
||||
# define PLAT_ARM_MMAP_ENTRIES 9
|
||||
# define MAX_XLAT_TABLES 4
|
||||
# define PLAT_ARM_MMAP_ENTRIES 11
|
||||
# define MAX_XLAT_TABLES 5
|
||||
#else
|
||||
# define PLAT_ARM_MMAP_ENTRIES 8
|
||||
# define MAX_XLAT_TABLES 3
|
||||
# define PLAT_ARM_MMAP_ENTRIES 10
|
||||
# define MAX_XLAT_TABLES 4
|
||||
#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 7
|
||||
# define MAX_XLAT_TABLES 3
|
||||
#endif
|
||||
|
||||
#ifdef IMAGE_BL32
|
||||
|
|
|
@ -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} \
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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},
|
||||
#ifdef AARCH64
|
||||
{ARM_DRAM2_BASE, ARM_DRAM2_SIZE},
|
||||
#endif
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
* 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);
|
||||
}
|
|
@ -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
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue