diff options
-rw-r--r-- | include/common/test_helpers.h | 13 | ||||
-rw-r--r-- | include/runtime_services/psci.h | 4 | ||||
-rw-r--r-- | lib/psci/psci.c | 3 | ||||
-rw-r--r-- | tests/common/test_helpers.c | 23 | ||||
-rw-r--r-- | tests/runtime_services/standard_service/psci/api_tests/mem_protect/test_mem_protect.c | 103 | ||||
-rw-r--r-- | tests/tests-manual.xml | 4 | ||||
-rw-r--r-- | tests/tests.mk | 1 |
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 \ |