blob: 2d925a213a850d1e593b1bb29a446e66e9e3a232 [file] [log] [blame]
/*
* Copyright (c) 2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <arch_helpers.h>
#include <arm_arch_svc.h>
#include <assert.h>
#include <debug.h>
#include <smccc.h>
#include <sync.h>
#include <tftf_lib.h>
#include <platform_def.h>
static volatile bool undef_injection_triggered;
static bool undef_injection_handler(void)
{
uint64_t esr_el2 = read_esr_el2();
if (EC_BITS(esr_el2) == EC_UNKNOWN) {
VERBOSE("UNDEF injection from EL3\n");
undef_injection_triggered = true;
return true;
}
return false;
}
/*
* Test to verify UNDEF injection support in TF-A
*
* This test tries to access FGT EL2 registers which traps to EL3 and then
* the error is injected back from EL3 to TFTF to ensure that injection
* logic in TF-A is working, it also ensures that EL3 is still functional
* after UNDEF injection.
*
* To trap FGT register access to EL3, we run this test on a model with
* FEAT_FGT present but the traps from EL3 are not disabled by setting
* ENABLE_FEAT_FGT = 0
*/
test_result_t test_undef_injection(void)
{
undef_injection_triggered = false;
register_custom_sync_exception_handler(undef_injection_handler);
/* Try to access a register which traps to EL3 */
read_hfgitr_el2();
unregister_custom_sync_exception_handler();
/* Ensure that EL3 still functional */
smc_args args;
smc_ret_values smc_ret;
memset(&args, 0, sizeof(args));
args.fid = SMCCC_VERSION;
smc_ret = tftf_smc(&args);
tftf_testcase_printf("SMCCC Version = %d.%d\n",
(int)((smc_ret.ret0 >> SMCCC_VERSION_MAJOR_SHIFT) & SMCCC_VERSION_MAJOR_MASK),
(int)((smc_ret.ret0 >> SMCCC_VERSION_MINOR_SHIFT) & SMCCC_VERSION_MINOR_MASK));
if (undef_injection_triggered == false) {
return TEST_RESULT_FAIL;
}
return TEST_RESULT_SUCCESS;
}