summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/common/test_helpers.h13
-rw-r--r--include/runtime_services/psci.h4
-rw-r--r--lib/psci/psci.c3
-rw-r--r--tests/common/test_helpers.c23
-rw-r--r--tests/runtime_services/standard_service/psci/api_tests/mem_protect/test_mem_protect.c103
-rw-r--r--tests/tests-manual.xml4
-rw-r--r--tests/tests.mk1
7 files changed, 149 insertions, 2 deletions
diff --git a/include/common/test_helpers.h b/include/common/test_helpers.h
index 735bce3..b216ae4 100644
--- a/include/common/test_helpers.h
+++ b/include/common/test_helpers.h
@@ -107,4 +107,17 @@
*/
int is_sys_suspend_state_ready(void);
+/*
+ * Helper function to reset the system. This function shouldn't return.
+ * It is not marked with __dead to help the test to catch some error in
+ * TF
+ */
+void psci_system_reset(void);
+
+/*
+ * Helper function that enables/disables the mem_protect mechanism
+ */
+int psci_mem_protect(int val);
+
+
#endif /* __TEST_HELPERS_H__ */
diff --git a/include/runtime_services/psci.h b/include/runtime_services/psci.h
index 73aebbd..30d0f23 100644
--- a/include/runtime_services/psci.h
+++ b/include/runtime_services/psci.h
@@ -82,6 +82,7 @@
#define SMC_PSCI_STAT_RESIDENCY64 0xc4000010
#define SMC_PSCI_STAT_COUNT32 0x84000011
#define SMC_PSCI_STAT_COUNT64 0xc4000011
+#define SMC_PSCI_MEM_PROTECT 0x84000013
/*
* Architecture-specific SMC function IDs
@@ -108,12 +109,13 @@
#define SMC_PSCI_SYSTEM_SUSPEND SMC_PSCI_SYSTEM_SUSPEND32
#define SMC_PSCI_STAT_RESIDENCY SMC_PSCI_STAT_RESIDENCY32
#define SMC_PSCI_STAT_COUNT SMC_PSCI_STAT_COUNT32
+#define SMC_PSCI_MEM_PROTECT_CHECK SMC_PSCI_MEM_PROTECT_CHECK_RANGE32
#endif
/*
* Number of PSCI calls defined in the PSCI specification.
*/
-#define PSCI_NUM_CALLS 28
+#define PSCI_NUM_CALLS 29
#ifndef __ASSEMBLY__
typedef struct {
diff --git a/lib/psci/psci.c b/lib/psci/psci.c
index 8117aa4..087475c 100644
--- a/lib/psci/psci.c
+++ b/lib/psci/psci.c
@@ -71,7 +71,8 @@ const psci_function_t psci_functions[PSCI_NUM_CALLS] = {
DEFINE_PSCI_FUNC(PSCI_STAT_RESIDENCY32, false),
DEFINE_PSCI_FUNC(PSCI_STAT_RESIDENCY64, false),
DEFINE_PSCI_FUNC(PSCI_STAT_COUNT32, false),
- DEFINE_PSCI_FUNC(PSCI_STAT_COUNT64, false)
+ DEFINE_PSCI_FUNC(PSCI_STAT_COUNT64, false),
+ DEFINE_PSCI_FUNC(PSCI_MEM_PROTECT, false),
};
int32_t tftf_psci_cpu_on(u_register_t target_cpu,
diff --git a/tests/common/test_helpers.c b/tests/common/test_helpers.c
index 955845c..1f75cb9 100644
--- a/tests/common/test_helpers.c
+++ b/tests/common/test_helpers.c
@@ -54,3 +54,26 @@ int is_sys_suspend_state_ready(void)
return 1;
}
+
+void psci_system_reset(void)
+{
+ smc_args args = { SMC_PSCI_SYSTEM_RESET };
+ smc_ret_values ret;
+
+ ret = tftf_smc(&args);
+
+ /* The PSCI SYSTEM_RESET call is not supposed to return */
+ tftf_testcase_printf("System didn't reboot properly (%d)\n",
+ (unsigned int)ret.ret0);
+}
+
+int psci_mem_protect(int val)
+{
+ smc_args args = { SMC_PSCI_MEM_PROTECT};
+ smc_ret_values ret;
+
+ args.arg1 = val;
+ ret = tftf_smc(&args);
+
+ return ret.ret0;
+}
diff --git a/tests/runtime_services/standard_service/psci/api_tests/mem_protect/test_mem_protect.c b/tests/runtime_services/standard_service/psci/api_tests/mem_protect/test_mem_protect.c
new file mode 100644
index 0000000..ffa1cf0
--- /dev/null
+++ b/tests/runtime_services/standard_service/psci/api_tests/mem_protect/test_mem_protect.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <debug.h>
+#include <stdlib.h>
+#include <psci.h>
+#include <test_helpers.h>
+#include <tftf_lib.h>
+
+#define SENTINEL 0x55
+#define MEM_PROT_ENABLED 1
+#define MEM_PROT_DISABLED 0
+/*
+ * Test to verify that mem_protect is executed in next boot after calling
+ * the PSCI mem_protect function
+ *
+ * Returns:
+ * TEST_RESULT_SUCCESS : when after rebooting mem_protect is activated
+ * and the sentinel is detected to have been reset.
+ * TEST_RESULT_FAIL : when some of the calls to mem_protect fails or
+ * sentinel is not cleared after resetting.
+ */
+test_result_t test_mem_protect(void)
+{
+ int ret;
+ unsigned char value;
+ extern unsigned char __TFTF_END__[];
+
+ ret = tftf_get_psci_feature_info(SMC_PSCI_MEM_PROTECT);
+ if (ret == PSCI_E_NOT_SUPPORTED)
+ return TEST_RESULT_SKIPPED;
+
+ if (tftf_is_rebooted()) {
+ value = *__TFTF_END__;
+ if (value != 0 && value != SENTINEL) {
+ tftf_testcase_printf("Sentinel address modified out of mem_protect:%d\n",
+ value);
+ return TEST_RESULT_FAIL;
+ }
+ if (value == SENTINEL) {
+ tftf_testcase_printf("Sentinel address not cleared by mem_protect\n");
+ return TEST_RESULT_FAIL;
+ }
+ return TEST_RESULT_SUCCESS;
+ }
+
+ ret = psci_mem_protect(MEM_PROT_DISABLED);
+ if (ret != MEM_PROT_ENABLED && ret != MEM_PROT_DISABLED) {
+ INFO("Mem_protect failed %d\n", ret);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* mem_protect mechanism should be disabled at this point */
+ ret = psci_mem_protect(MEM_PROT_ENABLED);
+ if (ret != MEM_PROT_DISABLED) {
+ tftf_testcase_printf("Mem_protect failed %d\n", ret);
+ return TEST_RESULT_FAIL;
+ }
+
+ /* mem_protect mechanism should be enabled at this point */
+ ret = psci_mem_protect(MEM_PROT_ENABLED);
+ if (ret != MEM_PROT_ENABLED) {
+ tftf_testcase_printf("Mem_protect failed %d\n", ret);
+ return TEST_RESULT_FAIL;
+ }
+
+ *__TFTF_END__ = SENTINEL;
+
+ /* Notify that we are rebooting now. */
+ tftf_notify_reboot();
+
+ psci_system_reset();
+ /*
+ * psci_reset shouldn't return
+ */
+ return TEST_RESULT_FAIL;
+}
diff --git a/tests/tests-manual.xml b/tests/tests-manual.xml
index ae31ddc..45e0f4f 100644
--- a/tests/tests-manual.xml
+++ b/tests/tests-manual.xml
@@ -24,4 +24,8 @@
<testcase name="System Off" function="test_system_off" />
</testsuite>
+ <testsuite name="PSCI mem_protect" description="Check the mem_protect feature">
+ <testcase name="PSCI mem_protect" function="test_mem_protect" />
+ </testsuite>
+
</testsuites>
diff --git a/tests/tests.mk b/tests/tests.mk
index 8f09673..c5b2816 100644
--- a/tests/tests.mk
+++ b/tests/tests.mk
@@ -52,6 +52,7 @@ TESTS_SOURCES := tests/framework_validation_tests/test_timer_framework.c \
tests/runtime_services/standard_service/psci/system_tests/test_psci_hotplug_stress.c \
tests/runtime_services/standard_service/psci/system_tests/test_psci_on_off_suspend_stress.c \
tests/runtime_services/standard_service/psci/system_tests/test_psci_system_suspend_stress.c \
+ tests/runtime_services/standard_service/psci/api_tests/mem_protect/test_mem_protect.c \
tests/runtime_services/standard_service/query_std_svc.c \
tests/runtime_services/standard_service/sdei/system_tests/sdei_entrypoint.S \
tests/runtime_services/standard_service/sdei/system_tests/test_sdei.c \