aboutsummaryrefslogtreecommitdiff
path: root/tftf/tests/runtime_services/standard_service/psci/api_tests/mem_protect/test_mem_protect.c
diff options
context:
space:
mode:
Diffstat (limited to 'tftf/tests/runtime_services/standard_service/psci/api_tests/mem_protect/test_mem_protect.c')
-rw-r--r--tftf/tests/runtime_services/standard_service/psci/api_tests/mem_protect/test_mem_protect.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/tftf/tests/runtime_services/standard_service/psci/api_tests/mem_protect/test_mem_protect.c b/tftf/tests/runtime_services/standard_service/psci/api_tests/mem_protect/test_mem_protect.c
new file mode 100644
index 000000000..35c26e8ac
--- /dev/null
+++ b/tftf/tests/runtime_services/standard_service/psci/api_tests/mem_protect/test_mem_protect.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <psci.h>
+#include <stdlib.h>
+#include <test_helpers.h>
+#include <tftf_lib.h>
+#include <xlat_tables_v2.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.
+ */
+static test_result_t test_mem_protect_helper(void *arg)
+{
+ int ret;
+ unsigned char value;
+ unsigned char *sentinel = arg;
+
+ assert(sentinel != NULL);
+
+ if (tftf_is_rebooted()) {
+ value = *sentinel;
+ 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;
+ }
+
+ *sentinel = SENTINEL;
+
+ /* Notify that we are rebooting now. */
+ tftf_notify_reboot();
+
+ psci_system_reset();
+ /*
+ * psci_reset shouldn't return
+ */
+ return TEST_RESULT_FAIL;
+}
+
+test_result_t test_mem_protect(void)
+{
+ map_args_unmap_t args;
+ unsigned char *sentinel;
+ int ret;
+
+ ret = tftf_get_psci_feature_info(SMC_PSCI_MEM_PROTECT);
+ if (ret == PSCI_E_NOT_SUPPORTED) {
+ tftf_testcase_printf("Mem_protect is not supported %d\n", ret);
+ return TEST_RESULT_SKIPPED;
+ }
+
+ sentinel = psci_mem_prot_get_sentinel();
+ if (sentinel == NULL) {
+ tftf_testcase_printf("Could not find a suitable address for the sentinel.\n");
+ return TEST_RESULT_SKIPPED;
+ }
+
+ args.addr = (uintptr_t) sentinel & ~PAGE_SIZE_MASK;
+ args.size = PAGE_SIZE;
+ args.attr = MT_RW_DATA;
+ args.arg = sentinel;
+
+ return map_test_unmap(&args, test_mem_protect_helper);
+}