Merge changes from topic "rfa-related-fixes"
* changes:
fix: remove dependency on fixed PSCI version in smc32_fast
fix: ignore errors on optional General service queries
fix(psci): mask MBZ bits in PSCI target_cpu arguments
diff --git a/include/runtime_services/psci.h b/include/runtime_services/psci.h
index 0e56bdc..e76156b 100644
--- a/include/runtime_services/psci.h
+++ b/include/runtime_services/psci.h
@@ -110,6 +110,13 @@
#endif /* __ASSEMBLY__ */
/*******************************************************************************
+ * PSCI target CPU defines
+ ******************************************************************************/
+
+#define PSCI_TARGET_CPU_MASK ULL(0x000000FF00FFFFFF)
+#define psci_target_cpu_from_mpid(mpidr) ((mpidr) & PSCI_TARGET_CPU_MASK)
+
+/*******************************************************************************
* PSCI Migrate specific defines
******************************************************************************/
#define PSCI_TOS_UP_MIG_CAP 0
diff --git a/lib/psci/psci.c b/lib/psci/psci.c
index 42e53b9..720d319 100644
--- a/lib/psci/psci.c
+++ b/lib/psci/psci.c
@@ -60,7 +60,7 @@
{
smc_args args = {
SMC_PSCI_CPU_ON,
- target_cpu,
+ psci_target_cpu_from_mpid(target_cpu),
entry_point_address,
context_id
};
@@ -97,7 +97,7 @@
{
smc_args args = {
SMC_PSCI_STAT_RESIDENCY,
- target_cpu,
+ psci_target_cpu_from_mpid(target_cpu),
power_state,
};
smc_ret_values ret_vals;
@@ -111,7 +111,7 @@
{
smc_args args = {
SMC_PSCI_STAT_COUNT,
- target_cpu,
+ psci_target_cpu_from_mpid(target_cpu),
power_state,
};
smc_ret_values ret_vals;
@@ -127,7 +127,7 @@
smc_args args = {
SMC_PSCI_AFFINITY_INFO,
- target_affinity,
+ psci_target_cpu_from_mpid(target_affinity),
lowest_affinity_level
};
@@ -139,7 +139,7 @@
{
smc_args args = {
SMC_PSCI_CPU_HW_STATE,
- target_cpu,
+ psci_target_cpu_from_mpid(target_cpu),
power_level
};
smc_ret_values ret;
diff --git a/tftf/tests/runtime_services/el3/query_ven_el3_svc.c b/tftf/tests/runtime_services/el3/query_ven_el3_svc.c
index 0b3b6e3..50d918a 100644
--- a/tftf/tests/runtime_services/el3/query_ven_el3_svc.c
+++ b/tftf/tests/runtime_services/el3/query_ven_el3_svc.c
@@ -47,6 +47,10 @@
ven_el3_svc_args.fid = VEN_EL3_SVC_UID;
ret = tftf_smc(&ven_el3_svc_args);
+ /* These functions are optional, skip test when not supported. */
+ if (ret.ret0 == SMC_UNKNOWN)
+ return TEST_RESULT_SKIPPED;
+
make_uuid_from_4words(&ven_el3_svc_uuid,
ret.ret0, ret.ret1, ret.ret2, ret.ret3);
if (!uuid_equal(&ven_el3_svc_uuid, &armtf_ven_el3_svc_uuid)) {
diff --git a/tftf/tests/runtime_services/generic/generic_smc.c b/tftf/tests/runtime_services/generic/generic_smc.c
index 6d057a6..1d15dcf 100644
--- a/tftf/tests/runtime_services/generic/generic_smc.c
+++ b/tftf/tests/runtime_services/generic/generic_smc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2025, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,10 +17,6 @@
/* An invalid SMC function number. */
#define INVALID_FN 0x666
-/* PSCI version returned by TF-A. */
-static const uint32_t psci_version = PSCI_VERSION(PSCI_MAJOR_VER,
- PSCI_MINOR_VER);
-
/* UUID of the standard service in TF-A. */
static const smc_ret_values std_svc_uuid = {
0x108d905b, 0x47e8f863, 0xfbc02dae, 0xe2f64156
@@ -46,6 +42,26 @@
} while (0)
/*
+ * Check that the values it returns match the expected ones. If not, write an
+ * error message in the test report.
+ */
+static bool smc_check_eq_common(const smc_ret_values *ret,
+ const smc_ret_values *expect)
+{
+ if (memcmp(ret, expect, sizeof(smc_ret_values)) == 0)
+ return true;
+
+ tftf_testcase_printf(
+ "Got {0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx}, \
+ expected {0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx}.\n",
+ ret->ret0, ret->ret1, ret->ret2, ret->ret3,
+ ret->ret4, ret->ret5, ret->ret6, ret->ret7,
+ expect->ret0, expect->ret1, expect->ret2, expect->ret3,
+ expect->ret4, expect->ret5, expect->ret6, expect->ret7);
+ return false;
+}
+
+/*
* Send an SMC with the specified arguments.
* Check that the values it returns match the expected ones. If not, write an
* error message in the test report.
@@ -54,18 +70,27 @@
{
smc_ret_values ret = tftf_smc(args);
- if (memcmp(&ret, expect, sizeof(smc_ret_values)) == 0) {
- return true;
- } else {
- tftf_testcase_printf(
- "Got {0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx}, \
- expected {0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx,0x%lx}.\n",
- ret.ret0, ret.ret1, ret.ret2, ret.ret3,
- ret.ret4, ret.ret5, ret.ret6, ret.ret7,
- expect->ret0, expect->ret1, expect->ret2, expect->ret3,
- expect->ret4, expect->ret5, expect->ret6, expect->ret7);
- return false;
- }
+ return smc_check_eq_common(&ret, expect);
+}
+
+/*
+ * Send an optional SMC with the specified arguments. Treat it as skipped if the
+ * firmware does not support the call and skip further checks.
+ * Otherwise, check that the values it returns match the expected ones. If not,
+ * return a test fail result.
+ */
+static test_result_t smc_check_eq_optional(const smc_args *args, const smc_ret_values *expect)
+{
+ smc_ret_values ret = tftf_smc(args);
+
+ if (ret.ret0 == SMC_UNKNOWN)
+ return TEST_RESULT_SKIPPED;
+
+ if (smc_check_eq_common(&ret, expect))
+ return TEST_RESULT_SUCCESS;
+ else
+ return TEST_RESULT_FAIL;
+
}
/*
@@ -153,9 +178,14 @@
/* Exercise SMC32 calling convention with fast SMC calls. */
test_result_t smc32_fast(void)
{
+ test_result_t result;
+
/* Valid Fast SMC32 using all 4 return values. */
const smc_args args1 = { .fid = SMC_STD_SVC_UID };
- FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+ result = smc_check_eq_optional(&args1, &std_svc_uuid);
+ if (result != TEST_RESULT_SUCCESS) {
+ return result;
+ }
/* Invalid Fast SMC32. */
const smc_args args2 = {
@@ -171,10 +201,15 @@
const smc_args args3
= { SMC_PSCI_VERSION, 0x44444444, 0x55555555, 0x66666666,
0x77777777, 0x88888888, 0x99999999, 0xaaaaaaaa };
- const smc_ret_values ret3
- = { psci_version, 0x44444444, 0x55555555, 0x66666666,
+ smc_ret_values ret3
+ = { 0x00000000, 0x44444444, 0x55555555, 0x66666666,
0x77777777, 0x88888888, 0x99999999, 0xaaaaaaaa };
- FAIL_IF(!smc_check_eq(&args3, &ret3));
+
+ const bool check[8] = { false, true, true, true, true, true, true, true };
+ const bool allow_zeros[8] = { false, true, true, true,
+ true, true, true, true };
+
+ FAIL_IF(!smc_check_match(&args3, &ret3, check, allow_zeros));
return TEST_RESULT_SUCCESS;
}
@@ -182,9 +217,14 @@
/* Exercise SMC64 calling convention with yielding SMC calls. */
test_result_t smc64_yielding(void)
{
+ test_result_t result;
+
/* Valid Fast SMC32 using all 4 return values. */
const smc_args args1 = { .fid = SMC_STD_SVC_UID };
- FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+ result = smc_check_eq_optional(&args1, &std_svc_uuid);
+ if (result != TEST_RESULT_SUCCESS) {
+ return result;
+ }
/* Invalid function number, SMC64 Yielding. */
const smc_args args2 = {
@@ -239,9 +279,14 @@
#ifndef __aarch64__
static test_result_t smc64_fast_caller32(void)
{
+ test_result_t result;
+
/* Valid Fast SMC32 using all 4 return values. */
smc_args args1 = { .fid = SMC_STD_SVC_UID };
- FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+ result = smc_check_eq_optional(&args1, &std_svc_uuid);
+ if (result != TEST_RESULT_SUCCESS) {
+ return result;
+ }
/* Invalid SMC function number, Fast SMC64. */
const smc_args args2 = {
@@ -270,9 +315,14 @@
#else
static test_result_t smc64_fast_caller64(void)
{
+ test_result_t result;
+
/* Valid Fast SMC32 using all 4 return values. */
smc_args args1 = { .fid = SMC_STD_SVC_UID };
- FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+ result = smc_check_eq_optional(&args1, &std_svc_uuid);
+ if (result != TEST_RESULT_SUCCESS) {
+ return result;
+ }
/* Invalid function number, Fast SMC64. */
const smc_args args2 = {
@@ -310,9 +360,14 @@
/* Exercise SMC32 calling convention with yielding SMC calls. */
test_result_t smc32_yielding(void)
{
+ test_result_t result;
+
/* Valid Fast SMC32 using all 4 return values. */
const smc_args args1 = { .fid = SMC_STD_SVC_UID };
- FAIL_IF(!smc_check_eq(&args1, &std_svc_uuid));
+ result = smc_check_eq_optional(&args1, &std_svc_uuid);
+ if (result != TEST_RESULT_SUCCESS) {
+ return result;
+ }
/* Invalid function number, SMC32 Yielding. */
const smc_args args2 = {
diff --git a/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c b/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c
index 43685e4..259ed1d 100644
--- a/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c
+++ b/tftf/tests/runtime_services/standard_service/pmf/api_tests/runtime_instr/test_pmf_rt_instr.c
@@ -75,10 +75,11 @@
args.fid = PMF_SMC_GET_VERSION;
ret = tftf_smc(&args);
+ if (ret.ret0 == SMC_UNKNOWN)
+ return TEST_RESULT_SKIPPED;
+
if (ret.ret1 != PMF_SMC_VERSION)
- {
return TEST_RESULT_FAIL;
- }
return TEST_RESULT_SUCCESS;
}
diff --git a/tftf/tests/runtime_services/standard_service/psci/api_tests/migrate_info_type/test_migrate_info_type.c b/tftf/tests/runtime_services/standard_service/psci/api_tests/migrate_info_type/test_migrate_info_type.c
index 50462d7..a3141a5 100644
--- a/tftf/tests/runtime_services/standard_service/psci/api_tests/migrate_info_type/test_migrate_info_type.c
+++ b/tftf/tests/runtime_services/standard_service/psci/api_tests/migrate_info_type/test_migrate_info_type.c
@@ -89,7 +89,7 @@
* Pass a valid MPID so that the MIGRATE call doesn't fail because of
* invalid parameters
*/
- args.arg1 = read_mpidr_el1() & MPID_MASK;
+ args.arg1 = psci_target_cpu_from_mpid(read_mpidr_el1());
ret = tftf_smc(&args);
migrate_ret = (int32_t) ret.ret0;
diff --git a/tftf/tests/runtime_services/standard_service/query_std_svc.c b/tftf/tests/runtime_services/standard_service/query_std_svc.c
index c8ce6e9..6debe63 100644
--- a/tftf/tests/runtime_services/standard_service/query_std_svc.c
+++ b/tftf/tests/runtime_services/standard_service/query_std_svc.c
@@ -47,6 +47,10 @@
std_svc_args.fid = SMC_STD_SVC_UID;
ret = tftf_smc(&std_svc_args);
+ /* These functions are optional, skip test when not supported. */
+ if (ret.ret0 == SMC_UNKNOWN)
+ return TEST_RESULT_SKIPPED;
+
make_uuid_from_4words(&std_svc_uuid,
ret.ret0, ret.ret1, ret.ret2, ret.ret3);
if (!uuid_equal(&std_svc_uuid, &armtf_std_svc_uuid)) {