From c3ab09d1c543bda64d543557556e8e03d2b26c32 Mon Sep 17 00:00:00 2001 From: Saivardhan Thatikonda Date: Wed, 5 Mar 2025 14:18:37 +0000 Subject: [PATCH] feat(versal2): is OCM configured as coherent Warn users about disabled OCM coherency which is not enabled by default in designs. If it is not enabled and TF-A is running out of OCM,TF-A won't work properly. This check is done only in Debug mode and isolation disabled. Change-Id: I7661e0183503b71085c57fa35014341d14522203 Signed-off-by: Saivardhan Thatikonda --- plat/amd/versal2/bl31_setup.c | 6 ++ plat/amd/versal2/include/plat_ocm_coherency.h | 20 +++++ plat/amd/versal2/plat_ocm_coherency.c | 82 +++++++++++++++++++ plat/amd/versal2/platform.mk | 5 ++ 4 files changed, 113 insertions(+) create mode 100644 plat/amd/versal2/include/plat_ocm_coherency.h create mode 100644 plat/amd/versal2/plat_ocm_coherency.c diff --git a/plat/amd/versal2/bl31_setup.c b/plat/amd/versal2/bl31_setup.c index 3a856cb05..cf95f5362 100644 --- a/plat/amd/versal2/bl31_setup.c +++ b/plat/amd/versal2/bl31_setup.c @@ -31,6 +31,8 @@ #include #include +#include + static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; @@ -143,6 +145,10 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, setup_console(); + if (IS_TFA_IN_OCM(BL31_BASE) && (check_ocm_coherency() < 0)) { + NOTICE("OCM coherency check not supported\n"); + } + NOTICE("TF-A running on %s v%d.%d, RTL v%d.%d, PS v%d.%d, PMC v%d.%d\n", board_name_decode(), (platform_version >> 1), platform_version % 10U, diff --git a/plat/amd/versal2/include/plat_ocm_coherency.h b/plat/amd/versal2/include/plat_ocm_coherency.h new file mode 100644 index 000000000..b88c2eb7d --- /dev/null +++ b/plat/amd/versal2/include/plat_ocm_coherency.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef PLAT_OCM_COHERENCY_H +#define PLAT_OCM_COHERENCY_H + +#define COHERENCY_CHECK_NOT_SUPPORTED -1 + +#if (DEBUG == 1) +int32_t check_ocm_coherency(void); +#else +static inline int32_t check_ocm_coherency(void) +{ + return COHERENCY_CHECK_NOT_SUPPORTED; +} +#endif + +#endif/*PLAT_OCM_COHERENCY_H*/ diff --git a/plat/amd/versal2/plat_ocm_coherency.c b/plat/amd/versal2/plat_ocm_coherency.c new file mode 100644 index 000000000..872ee23c5 --- /dev/null +++ b/plat/amd/versal2/plat_ocm_coherency.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2025, Advanced Micro Devices, Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include +#include + +#include +#include + +/* + * Register non hash mem regions addresses + */ +#define POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 U(0xF8168000) +#define NON_HASH_MEM_REGION_REG0 U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC08) +#define NON_HASH_MEM_REGION_REG1 U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC0C) +#define NON_HASH_MEM_REGION_REG2 U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC10) +#define NON_HASH_MEM_REGION_REG3 U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC14) +#define NON_HASH_MEM_REGION_REG4 U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC18) +#define NON_HASH_MEM_REGION_REG5 U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC1C) +#define NON_HASH_MEM_REGION_REG6 U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC20) +#define NON_HASH_MEM_REGION_REG7 U(POR_RNSAM_NODE_INFO_U_RNFBESAM_NID12 + 0xC24) + +#define REGION_BASE_ADDR_VALUE U(0x2E) +#define REGION_BASE_ADDR_SHIFT 9 + +#define REGION_BASE_ADDRESS_MASK GENMASK(30, REGION_BASE_ADDR_SHIFT) +#define REGION_VALID_BIT BIT(0) + +/* + * verify the register configured as non-hashed + */ +#define IS_NON_HASHED_REGION(reg) \ +((FIELD_GET(REGION_BASE_ADDRESS_MASK, mmio_read_32(reg)) == REGION_BASE_ADDR_VALUE) && \ + (mmio_read_32(reg) & REGION_VALID_BIT)) + +/* + * Splitter registers + */ +#define FPX_SPLITTER_0 U(0xECC20000) +#define FPX_SPLITTER_1 U(0xECD20000) +#define FPX_SPLITTER_2 U(0xECE20000) +#define FPX_SPLITTER_3 U(0xECF20000) +#define OCM_ADDR_DIST_MODE BIT(16) + +#define OCM_COHERENT 0 +#define OCM_NOT_COHERENT 1 +#define TFA_NOT_IN_OCM 2 + +/* + * Function that verifies the OCM is coherent or not with the following checks: + * verify that OCM is in non hashed region or not if not then verify + * OCM_ADDR_DIST_MODE bit in splitter registers is set. + */ +int32_t check_ocm_coherency(void) +{ + int32_t status = OCM_COHERENT; + /* isolation should be disabled in order to read these registers */ + if ((IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG0) || + IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG1) || + IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG2) || + IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG3) || + IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG4) || + IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG5) || + IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG6) || + IS_NON_HASHED_REGION(NON_HASH_MEM_REGION_REG7))) { + WARN("OCM is not configured as coherent\n"); + status = OCM_NOT_COHERENT; + } else { + /* verify OCM_ADDR_DIST_MODE bit in splitter registers is set */ + if (!((mmio_read_32(FPX_SPLITTER_0) & OCM_ADDR_DIST_MODE) && + (mmio_read_32(FPX_SPLITTER_1) & OCM_ADDR_DIST_MODE) && + (mmio_read_32(FPX_SPLITTER_2) & OCM_ADDR_DIST_MODE) && + (mmio_read_32(FPX_SPLITTER_3) & OCM_ADDR_DIST_MODE))) { + WARN("OCM is not configured as coherent\n"); + status = OCM_NOT_COHERENT; + } + } + return status; +} + diff --git a/plat/amd/versal2/platform.mk b/plat/amd/versal2/platform.mk index 7cd864ebf..283ad420d 100644 --- a/plat/amd/versal2/platform.mk +++ b/plat/amd/versal2/platform.mk @@ -160,6 +160,11 @@ BL31_SOURCES += common/fdt_wrappers.c \ ${PLAT_PATH}/sip_svc_setup.c \ ${PLAT_PATH}/gicv3.c + +ifeq ($(DEBUG),1) +BL31_SOURCES += ${PLAT_PATH}/plat_ocm_coherency.c +endif + ifeq (${ERRATA_ABI_SUPPORT}, 1) # enable the cpu macros for errata abi interface CORTEX_A78_AE_H_INC := 1