blob: 5d9600d72f9a42e4538deb54b4025aec51fff738 [file] [log] [blame]
/*
* Copyright (c) 2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <test_helpers.h>
#include <tftf_lib.h>
#include <tftf.h>
#include <string.h>
#include <arch_helpers.h>
#ifdef __aarch64__
static bool is_init_val_set(u_register_t reg, u_register_t init_val,
u_register_t feat_mask)
{
return (reg & feat_mask) == (init_val & feat_mask);
}
#define CHECK_FEAT_TRAP_INITIALIZED(_reg, _REG, _feat_check, _FEAT) \
do { \
if (_feat_check() != 0) { \
if (is_init_val_set(_reg, _REG ## _INIT_VAL, \
_REG ## _ ## FEAT_ ## _FEAT ## _MASK) == 0) { \
return TEST_RESULT_FAIL; \
} \
} \
} while (false);
#define CHECK_FEAT_TRAP_INITIALIZED2(_reg, _REG, _feat_check, _FEAT, \
_feat2_check, _FEAT2, _op) \
do { \
if ((_feat_check() != 0) _op (_feat2_check() != 0)) { \
if (is_init_val_set(_reg, _REG ## _INIT_VAL, _REG ## _ \
## FEAT_ ## _FEAT ## _ ## _FEAT2 ## _MASK) \
== 0) { \
return TEST_RESULT_FAIL; \
} \
} \
} while (false);
#endif
/*
* TF-A is expected to allow access to ARMv8.6-FGT system registers from EL2.
* Reading these registers causes a trap to EL3 and crash when TF-A has not
* allowed access.
*/
test_result_t test_fgt_enabled(void)
{
SKIP_TEST_IF_AARCH32();
#ifdef __aarch64__
SKIP_TEST_IF_FGT_NOT_SUPPORTED();
u_register_t hfgitr_el2 = read_hfgitr_el2();
u_register_t hfgrtr_el2 = read_hfgrtr_el2();
u_register_t hfgwtr_el2 = read_hfgwtr_el2();
/*
* The following registers are not supposed to be consumed, but
* are read to test their presence when FEAT_FGT is supported.
*/
read_hdfgrtr_el2();
read_hdfgwtr_el2();
CHECK_FEAT_TRAP_INITIALIZED(hfgitr_el2, HFGITR_EL2, \
get_feat_brbe_support, BRBE)
CHECK_FEAT_TRAP_INITIALIZED(hfgitr_el2, HFGITR_EL2, \
is_feat_specres_present, SPECRES)
CHECK_FEAT_TRAP_INITIALIZED(hfgitr_el2, HFGITR_EL2, \
is_feat_tlbirange_present, TLBIRANGE)
CHECK_FEAT_TRAP_INITIALIZED2(hfgitr_el2, HFGITR_EL2, \
is_feat_tlbirange_present, TLBIRANGE, \
is_feat_tlbios_present, TLBIOS, &&)
CHECK_FEAT_TRAP_INITIALIZED(hfgitr_el2, HFGITR_EL2, \
is_feat_tlbios_present, TLBIOS)
CHECK_FEAT_TRAP_INITIALIZED(hfgitr_el2, HFGITR_EL2, \
is_armv8_2_pan2_present, PAN2)
CHECK_FEAT_TRAP_INITIALIZED(hfgitr_el2, HFGITR_EL2, \
is_feat_dpb2_present, DPB2)
if (is_init_val_set(hfgitr_el2, HFGITR_EL2_INIT_VAL,
HFGITR_EL2_NON_FEAT_DEPENDENT_MASK) == 0) {
return TEST_RESULT_FAIL;
}
CHECK_FEAT_TRAP_INITIALIZED(hfgrtr_el2, HFGRTR_EL2, \
is_feat_sme_supported, SME)
CHECK_FEAT_TRAP_INITIALIZED(hfgrtr_el2, HFGRTR_EL2, \
is_feat_ls64_accdata_present, LS64_ACCDATA)
CHECK_FEAT_TRAP_INITIALIZED(hfgrtr_el2, HFGRTR_EL2, \
is_feat_ras_present, RAS)
CHECK_FEAT_TRAP_INITIALIZED(hfgrtr_el2, HFGRTR_EL2, \
is_feat_rasv1p1_present, RASV1P1)
CHECK_FEAT_TRAP_INITIALIZED(hfgrtr_el2, HFGRTR_EL2, \
is_feat_gicv3_gicv4_present, GICV3)
CHECK_FEAT_TRAP_INITIALIZED2(hfgrtr_el2, HFGRTR_EL2, \
is_feat_csv2_2_present, CSV2_2, \
is_feat_csv2_1p2_present, CSV2_1P2, ||)
CHECK_FEAT_TRAP_INITIALIZED(hfgrtr_el2, HFGRTR_EL2, \
is_feat_lor_present, LOR)
CHECK_FEAT_TRAP_INITIALIZED(hfgrtr_el2, HFGRTR_EL2, \
is_armv8_3_pauth_apa_api_apa3_present, PAUTH)
if (is_init_val_set(hfgrtr_el2, HFGRTR_EL2_INIT_VAL,
HFGRTR_EL2_NON_FEAT_DEPENDENT_MASK) == 0) {
return TEST_RESULT_FAIL;
}
CHECK_FEAT_TRAP_INITIALIZED(hfgwtr_el2, HFGWTR_EL2, \
is_feat_sme_supported, SME)
CHECK_FEAT_TRAP_INITIALIZED(hfgwtr_el2, HFGWTR_EL2, \
is_feat_ls64_accdata_present, LS64_ACCDATA);
CHECK_FEAT_TRAP_INITIALIZED(hfgwtr_el2, HFGWTR_EL2, \
is_feat_ras_present, RAS);
CHECK_FEAT_TRAP_INITIALIZED(hfgwtr_el2, HFGWTR_EL2, \
is_feat_rasv1p1_present, RASV1P1);
CHECK_FEAT_TRAP_INITIALIZED(hfgwtr_el2, HFGWTR_EL2, \
is_feat_gicv3_gicv4_present, GICV3);
CHECK_FEAT_TRAP_INITIALIZED2(hfgwtr_el2, HFGWTR_EL2, \
is_feat_csv2_2_present, CSV2_2, \
is_feat_csv2_1p2_present, CSV2_1P2, ||)
CHECK_FEAT_TRAP_INITIALIZED(hfgwtr_el2, HFGWTR_EL2, \
is_feat_lor_present, LOR)
CHECK_FEAT_TRAP_INITIALIZED(hfgwtr_el2, HFGWTR_EL2, \
is_armv8_3_pauth_apa_api_apa3_present, PAUTH)
if (is_init_val_set(hfgwtr_el2, HFGWTR_EL2_INIT_VAL, \
HFGWTR_EL2_NON_FEAT_DEPENDENT_MASK) == 0) {
return TEST_RESULT_FAIL;
}
return TEST_RESULT_SUCCESS;
#endif /* __aarch64__ */
}