diff options
Diffstat (limited to 'tftf/tests/runtime_services/arm_arch_svc/smccc_arch_soc_id.c')
-rw-r--r-- | tftf/tests/runtime_services/arm_arch_svc/smccc_arch_soc_id.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_soc_id.c b/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_soc_id.c new file mode 100644 index 000000000..b866450de --- /dev/null +++ b/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_soc_id.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch_helpers.h> +#include <arm_arch_svc.h> +#include <debug.h> +#include <smccc.h> +#include <string.h> +#include <tftf_lib.h> + +/* + * Return SOC ID parameters(SOC revision/SOC version) according + * to argument passed + */ +static smc_ret_values get_soc_id_param(u_register_t arg) +{ + smc_args args; + smc_ret_values ret; + + memset(&args, 0, sizeof(args)); + args.fid = SMCCC_ARCH_SOC_ID; + args.arg1 = arg; + ret = tftf_smc(&args); + + return ret; +} + +/* Entry function to execute SMCCC_ARCH_SOC_ID test */ +test_result_t test_smccc_arch_soc_id(void) +{ + smc_args args; + smc_ret_values ret; + int32_t expected_ver; + int32_t skip_cnt = 0; + bool fail_soc_id_test = false; + + /* Check if SMCCC version is at least v1.2 */ + expected_ver = MAKE_SMCCC_VERSION(1, 2); + memset(&args, 0, sizeof(args)); + args.fid = SMCCC_VERSION; + ret = tftf_smc(&args); + if ((int32_t)ret.ret0 < expected_ver) { + tftf_testcase_printf("Unexpected SMCCC version: 0x%x\n", + (int)ret.ret0); + return TEST_RESULT_SKIPPED; + } + + /* Check if SMCCC_ARCH_SOC_ID is implemented or not */ + memset(&args, 0, sizeof(args)); + args.fid = SMCCC_ARCH_FEATURES; + args.arg1 = SMCCC_ARCH_SOC_ID; + ret = tftf_smc(&args); + if ((int)ret.ret0 == SMC_ARCH_CALL_NOT_SUPPORTED) { + tftf_testcase_printf("SMCCC_ARCH_SOC_ID is not implemented\n"); + return TEST_RESULT_FAIL; + } + + /* If the call returns SMC_OK then SMCCC_ARCH_SOC_ID is feature available */ + if ((int)ret.ret0 == SMC_OK) { + ret = get_soc_id_param(SMC_GET_SOC_REVISION); + + if ((int)ret.ret0 == SMC_ARCH_CALL_INVAL_PARAM) { + ERROR("Invalid param passed to SMCCC_ARCH_SOC_ID\n"); + fail_soc_id_test = true; + } else if ((int)ret.ret0 == SMC_ARCH_CALL_NOT_SUPPORTED) { + tftf_testcase_printf("SOC Rev is not implemented\n"); + skip_cnt++; + } else { + tftf_testcase_printf("SOC Rev = 0x%x\n", (int)ret.ret0); + } + + ret = get_soc_id_param(SMC_GET_SOC_VERSION); + + if ((int)ret.ret0 == SMC_ARCH_CALL_INVAL_PARAM) { + ERROR("Invalid param passed to SMCCC_ARCH_SOC_ID\n"); + fail_soc_id_test = true; + } else if ((int)ret.ret0 == SMC_ARCH_CALL_NOT_SUPPORTED) { + tftf_testcase_printf("SOC Ver is not implemented\n"); + skip_cnt++; + } else { + tftf_testcase_printf("SOC Ver = 0x%x\n", (int)ret.ret0); + } + + if (skip_cnt == 2) + return TEST_RESULT_SKIPPED; + else if (fail_soc_id_test) + return TEST_RESULT_FAIL; + } else { + ERROR("Invalid error during SMCCC_ARCH_FEATURES call = 0x%x\n", + (int)ret.ret0); + return TEST_RESULT_FAIL; + } + + return TEST_RESULT_SUCCESS; +} |