aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSandrine Bailleux <sandrine.bailleux@arm.com>2019-01-07 15:56:12 +0000
committerTrustedFirmware Code Review <review@review.trustedfirmware.org>2019-01-07 15:56:12 +0000
commit9e7d37e7d4de365e56c4a6e1a38950378ae0c841 (patch)
treeeab764b40f2ba4413f967b14d3c9bac6565ebbbe
parent48ea56b221c113834a02334a71661dbeea26a091 (diff)
parentc5d315e6eecedfec609870f0cce6e31d927850cf (diff)
downloadtf-a-tests-9e7d37e7d4de365e56c4a6e1a38950378ae0c841.tar.gz
Merge changes from topic "sb/smc-tests-tos"
* changes: Relax SMC tests when Trusted OS is present Make UUID buffer optional for is_trusted_os_present()
-rw-r--r--include/runtime_services/trusted_os.h6
-rw-r--r--lib/trusted_os/trusted_os.c13
-rw-r--r--tftf/tests/runtime_services/generic/generic_smc.c79
3 files changed, 82 insertions, 16 deletions
diff --git a/include/runtime_services/trusted_os.h b/include/runtime_services/trusted_os.h
index f480c6bc..29478827 100644
--- a/include/runtime_services/trusted_os.h
+++ b/include/runtime_services/trusted_os.h
@@ -24,10 +24,8 @@
* Detect whether a Trusted OS is present in the software stack.
* This is implemented using the Trusted OS UID SMC call.
*
- * If a Trusted OS is detected then this function returns 1
- * and populates 'tos_uuid' with the UUID of the detected Trusted OS.
- * Otherwise, this function returns 0 and the value pointed by 'tos_uuid'
- * should be ignored.
+ * Return 1 if a Trusted OS is detected, else 0. Additionally, the caller may
+ * get the UUID of the Trusted OS if he passes a non-null 'tos_uuid' pointer.
*/
unsigned int is_trusted_os_present(uuid_t *tos_uuid);
diff --git a/lib/trusted_os/trusted_os.c b/lib/trusted_os/trusted_os.c
index b24c3d39..ac6a6810 100644
--- a/lib/trusted_os/trusted_os.c
+++ b/lib/trusted_os/trusted_os.c
@@ -14,7 +14,6 @@ unsigned int is_trusted_os_present(uuid_t *tos_uuid)
{
smc_args tos_uid_args = { SMC_TOS_UID };
smc_ret_values ret;
- uint32_t *tos_uuid32;
ret = tftf_smc(&tos_uid_args);
@@ -23,11 +22,13 @@ unsigned int is_trusted_os_present(uuid_t *tos_uuid)
(ret.ret3 == 0)))
return 0;
- tos_uuid32 = (uint32_t *) tos_uuid;
- tos_uuid32[0] = ret.ret0;
- tos_uuid32[1] = ret.ret1;
- tos_uuid32[2] = ret.ret2;
- tos_uuid32[3] = ret.ret3;
+ if (tos_uuid != NULL) {
+ uint32_t *tos_uuid32 = (uint32_t *) tos_uuid;
+ tos_uuid32[0] = ret.ret0;
+ tos_uuid32[1] = ret.ret1;
+ tos_uuid32[2] = ret.ret2;
+ tos_uuid32[3] = ret.ret3;
+ }
return 1;
}
diff --git a/tftf/tests/runtime_services/generic/generic_smc.c b/tftf/tests/runtime_services/generic/generic_smc.c
index 901b4481..366509bb 100644
--- a/tftf/tests/runtime_services/generic/generic_smc.c
+++ b/tftf/tests/runtime_services/generic/generic_smc.c
@@ -7,8 +7,10 @@
#include <psci.h>
#include <smccc.h>
#include <std_svc.h>
+#include <stdio.h>
#include <string.h>
#include <tftf_lib.h>
+#include <trusted_os.h>
#include <tsp.h>
#include <utils_def.h>
@@ -63,6 +65,49 @@ static bool smc_check_eq(const smc_args *args, const smc_ret_values *expect)
}
}
+/*
+ * Send an SMC with the specified arguments.
+ * Check that the values it returns match the expected ones. The do_check[]
+ * array indicates which ones should be checked and provides some flexibility
+ * to ignore some of them.
+ * If the values do not match, write an error message in the test report.
+ */
+static bool smc_check_match(const smc_args *args, const smc_ret_values *expect,
+ const bool do_check[4])
+{
+ smc_ret_values ret = tftf_smc(args);
+
+ if ((do_check[0] && (ret.ret0 != expect->ret0)) ||
+ (do_check[1] && (ret.ret1 != expect->ret1)) ||
+ (do_check[2] && (ret.ret2 != expect->ret2)) ||
+ (do_check[3] && (ret.ret3 != expect->ret3))) {
+ /*
+ * Build an error message where unchecked SMC return values are
+ * displayed as '*'.
+ */
+ char expect_str[4][20];
+#define BUILD_STR(_buf, _do_check, _expect) \
+ if (_do_check) { \
+ snprintf(_buf, 20, "0x%lx", _expect); \
+ } else { \
+ strncpy(_buf, "*", 2); \
+ }
+ BUILD_STR(expect_str[0], do_check[0], expect->ret0);
+ BUILD_STR(expect_str[1], do_check[1], expect->ret1);
+ BUILD_STR(expect_str[2], do_check[2], expect->ret2);
+ BUILD_STR(expect_str[3], do_check[3], expect->ret3);
+#undef BUILD_STR
+ tftf_testcase_printf(
+ "Got {0x%lx,0x%lx,0x%lx,0x%lx}, expected {%s,%s,%s,%s}.\n",
+ ret.ret0, ret.ret1, ret.ret2, ret.ret3,
+ expect_str[0], expect_str[1], expect_str[2], expect_str[3]);
+
+ return false;
+ } else {
+ return true;
+ }
+}
+
/* Exercise SMC32 calling convention with fast SMC calls. */
test_result_t smc32_fast(void)
{
@@ -118,9 +163,20 @@ test_result_t smc64_yielding(void)
const smc_args args3 = {
make_smc_fid(SMC_TYPE_STD, SMC_64, OEN_TOS_START, INVALID_FN),
0x44444444, 0x55555555, 0x66666666 };
- const smc_ret_values ret3
- = { SMC_UNKNOWN, 0x44444444, 0x55555555, 0x66666666 };
- FAIL_IF(!smc_check_eq(&args3, &ret3));
+
+ if (is_trusted_os_present(NULL)) {
+ /*
+ * The Trusted OS is free to return any error code in x0 but it
+ * should at least preserve the values of x1-x3.
+ */
+ const smc_ret_values ret3 = { 0, 0x44444444, 0x55555555, 0x66666666 };
+ const bool check[4] = { false, true, true, true };
+ FAIL_IF(!smc_check_match(&args3, &ret3, check));
+ } else {
+ const smc_ret_values ret3
+ = { SMC_UNKNOWN, 0x44444444, 0x55555555, 0x66666666 };
+ FAIL_IF(!smc_check_eq(&args3, &ret3));
+ }
return TEST_RESULT_SUCCESS;
}
@@ -218,9 +274,20 @@ test_result_t smc32_yielding(void)
const smc_args args3 = {
make_smc_fid(SMC_TYPE_STD, SMC_32, OEN_TOS_START, INVALID_FN),
0x44444444, 0x55555555, 0x66666666 };
- const smc_ret_values ret3
- = { SMC_UNKNOWN, 0x44444444, 0x55555555, 0x66666666 };
- FAIL_IF(!smc_check_eq(&args3, &ret3));
+
+ if (is_trusted_os_present(NULL)) {
+ /*
+ * The Trusted OS is free to return any error code in x0 but it
+ * should at least preserve the values of x1-x3.
+ */
+ const smc_ret_values ret3 = { 0, 0x44444444, 0x55555555, 0x66666666 };
+ const bool check[4] = { false, true, true, true };
+ FAIL_IF(!smc_check_match(&args3, &ret3, check));
+ } else {
+ const smc_ret_values ret3
+ = { SMC_UNKNOWN, 0x44444444, 0x55555555, 0x66666666 };
+ FAIL_IF(!smc_check_eq(&args3, &ret3));
+ }
return TEST_RESULT_SUCCESS;
}