diff --git a/include/plat/arm/common/fconf_nv_cntr_getter.h b/include/plat/arm/common/fconf_nv_cntr_getter.h new file mode 100644 index 000000000..80a600049 --- /dev/null +++ b/include/plat/arm/common/fconf_nv_cntr_getter.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_NV_CNTR_GETTER_H +#define FCONF_NV_CNTR_GETTER_H + +#include +#include + +#define cot__nv_cntr_addr_getter(id) nv_cntr_base_addr[id] + +extern uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS]; + +#endif /* FCONF_NV_CNTR_GETTER_H */ diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c index 38cbba9e9..8239e0d1a 100644 --- a/plat/arm/board/common/board_arm_trusted_boot.c +++ b/plat/arm/board/common/board_arm_trusted_boot.c @@ -12,7 +12,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -29,6 +31,16 @@ #endif #endif +#if COT_DESC_IN_DTB && defined(IMAGE_BL2) +uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS]; +#else +uintptr_t nv_cntr_base_addr[MAX_NV_CTR_IDS] = { + TFW_NVCTR_BASE, + NTFW_CTR_BASE +}; +#endif + + /* Weak definition may be overridden in specific platform */ #pragma weak plat_get_nv_ctr #pragma weak plat_set_nv_ctr @@ -183,9 +195,11 @@ int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr) oid = (const char *)cookie; if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) { - nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE; + nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr, + TRUSTED_NV_CTR_ID); } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) { - nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE; + nv_ctr_addr = (uint32_t *)FCONF_GET_PROPERTY(cot, nv_cntr_addr, + NON_TRUSTED_NV_CTR_ID); } else { return 1; } diff --git a/plat/arm/board/fvp/fvp_trusted_boot.c b/plat/arm/board/fvp/fvp_trusted_boot.c index 8825198a1..1ea37f7a3 100644 --- a/plat/arm/board/fvp/fvp_trusted_boot.c +++ b/plat/arm/board/fvp/fvp_trusted_boot.c @@ -9,7 +9,9 @@ #include #include +#include #include +#include #include #include #include @@ -50,9 +52,11 @@ int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) oid = (const char *)cookie; if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) { - nv_ctr_addr = TFW_NVCTR_BASE; + nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr, + TRUSTED_NV_CTR_ID); } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) { - nv_ctr_addr = NTFW_CTR_BASE; + nv_ctr_addr = FCONF_GET_PROPERTY(cot, nv_cntr_addr, + NON_TRUSTED_NV_CTR_ID); } else { return 1; } diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index a7d18252d..b6a9dae19 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -168,6 +168,9 @@ BL2_SOURCES += drivers/arm/sp805/sp805.c \ ${FVP_SECURITY_SOURCES} +ifeq (${COT_DESC_IN_DTB},1) +BL2_SOURCES += plat/arm/common/fconf/fconf_nv_cntr_getter.c +endif ifeq (${BL2_AT_EL3},1) BL2_SOURCES += plat/arm/board/fvp/${ARCH}/fvp_helpers.S \ diff --git a/plat/arm/common/fconf/fconf_nv_cntr_getter.c b/plat/arm/common/fconf/fconf_nv_cntr_getter.c new file mode 100644 index 000000000..8d645ef3d --- /dev/null +++ b/plat/arm/common/fconf/fconf_nv_cntr_getter.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include + +#include + +/******************************************************************************* + * fconf_populate_cot_descs() - Populate available nv-counters and update global + * structure. + * @config[in]: Pointer to the device tree blob in memory + * + * Return 0 on success or an error value otherwise. + ******************************************************************************/ +static int fconf_populate_nv_cntrs(uintptr_t config) +{ + int rc, node, child; + uint32_t id; + uintptr_t reg; + + /* As libfdt uses void *, we can't avoid this cast */ + const void *dtb = (void *)config; + const char *compatible_str = "arm, non-volatile-counter"; + + node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); + if (node < 0) { + ERROR("FCONF: Can't find %s compatible in node\n", + compatible_str); + return node; + } + + fdt_for_each_subnode(child, dtb, node) { + + rc = fdt_read_uint32(dtb, child, "id", &id); + if (rc < 0) { + ERROR("FCONF: Can't find %s property in node\n", "id"); + return rc; + } + + assert(id < MAX_NV_CTR_IDS); + + rc = fdt_get_reg_props_by_index(dtb, child, 0, ®, NULL); + if (rc < 0) { + ERROR("FCONF: Can't find %s property in node\n", "reg"); + return rc; + } + + nv_cntr_base_addr[id] = reg; + } + + return 0; +} + +FCONF_REGISTER_POPULATOR(TB_FW, nv_cntrs, fconf_populate_nv_cntrs);