diff options
author | Roberto Vargas <roberto.vargas@arm.com> | 2017-08-03 08:16:16 +0100 |
---|---|---|
committer | Roberto Vargas <roberto.vargas@arm.com> | 2017-09-25 13:32:20 +0100 |
commit | d4c596be87e0b04404fc10ee49544eda33c0f625 (patch) | |
tree | 1824de0ccd55451b7afca6bd4399308f20380917 /lib/psci | |
parent | df312c5a2b152953f755df9d979cff20afb7ef4b (diff) | |
download | arm-trusted-firmware-d4c596be87e0b04404fc10ee49544eda33c0f625.tar.gz |
mem_protect: Add mem_protect API
This patch adds the generic code that links the psci smc handler
with the platform function that implements the mem_protect and
mem_check_range functionalities. These functions are optional
APIs added in PSCI v1.1 (ARM DEN022D).
Change-Id: I3bac1307a5ce2c7a196ace76db8317e8d8c8bb3f
Signed-off-by: Roberto Vargas <roberto.vargas@arm.com>
Diffstat (limited to 'lib/psci')
-rw-r--r-- | lib/psci/psci_lib.mk | 1 | ||||
-rw-r--r-- | lib/psci/psci_main.c | 9 | ||||
-rw-r--r-- | lib/psci/psci_mem_protect.c | 38 | ||||
-rw-r--r-- | lib/psci/psci_private.h | 4 | ||||
-rw-r--r-- | lib/psci/psci_setup.c | 5 |
5 files changed, 57 insertions, 0 deletions
diff --git a/lib/psci/psci_lib.mk b/lib/psci/psci_lib.mk index 29080dbb0..1d4aac4a3 100644 --- a/lib/psci/psci_lib.mk +++ b/lib/psci/psci_lib.mk @@ -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) diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c index 257479aa9..a5d707e01 100644 --- a/lib/psci/psci_main.c +++ b/lib/psci/psci_main.c @@ -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; } diff --git a/lib/psci/psci_mem_protect.c b/lib/psci/psci_mem_protect.c new file mode 100644 index 000000000..fca84e905 --- /dev/null +++ b/lib/psci/psci_mem_protect.c @@ -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; +} diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h index da6a20fa4..facfacb03 100644 --- a/lib/psci/psci_private.h +++ b/lib/psci/psci_private.h @@ -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__ */ diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c index f70e34da4..5ef49acbe 100644 --- a/lib/psci/psci_setup.c +++ b/lib/psci/psci_setup.c @@ -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); |