[Pdbg] [PATCH 06/18] tests: Add fapi p10 address translation tests
Joel Stanley
joel at jms.id.au
Mon Sep 28 16:46:52 AEST 2020
On Mon, 28 Sep 2020 at 06:35, Amitay Isaacs <amitay at ozlabs.org> wrote:
>
> From: Alistair Popple <alistair at popple.id.au>
>
> Signed-off-by: Alistair Popple <alistair at popple.id.au>
> Signed-off-by: Amitay Isaacs <amitay at ozlabs.org>
This is pretty unreviewable. Perhaps have a patch that adds the ekb
sources, and one that adds the test infra around it follows?
We should fix the prologs before adding it to the pdbg tree.
> ---
> Makefile.am | 11 +-
> src/tests/libpdbg_p10_fapi_translation_test.C | 113 +++
> src/tests/p10_cu.H | 120 +++
> src/tests/p10_scom_addr.C | 934 ++++++++++++++++++
> src/tests/p10_scom_addr.H | 718 ++++++++++++++
> src/tests/p10_scominfo.C | 856 ++++++++++++++++
> src/tests/p10_scominfo.H | 107 ++
> tests/test_p10_fapi_translation.sh | 206 ++++
> 8 files changed, 3064 insertions(+), 1 deletion(-)
> create mode 100644 src/tests/libpdbg_p10_fapi_translation_test.C
> create mode 100644 src/tests/p10_cu.H
> create mode 100644 src/tests/p10_scom_addr.C
> create mode 100644 src/tests/p10_scom_addr.H
> create mode 100644 src/tests/p10_scominfo.C
> create mode 100644 src/tests/p10_scominfo.H
> create mode 100755 tests/test_p10_fapi_translation.sh
>
> diff --git a/Makefile.am b/Makefile.am
> index 779c52c..d902863 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -16,6 +16,7 @@ libpdbg_tests = libpdbg_target_test \
> bin_PROGRAMS = pdbg
> check_PROGRAMS = $(libpdbg_tests) libpdbg_dtree_test \
> libpdbg_p9_fapi_translation_test \
> + libpdbg_p10_fapi_translation_test \
> optcmd_test hexdump_test cronus_proxy \
> libpdbg_prop_test libpdbg_attr_test \
> libpdbg_traverse_test
> @@ -31,13 +32,15 @@ PDBG_TESTS = \
> tests/test_attr_array.sh \
> tests/test_attr_packed.sh \
> tests/test_traverse.sh \
> - tests/test_p9_fapi_translation.sh
> + tests/test_p9_fapi_translation.sh \
> + tests/test_p10_fapi_translation.sh
>
> TESTS = $(libpdbg_tests) optcmd_test $(PDBG_TESTS)
>
> tests/test_tree2.sh: fake2.dtb fake2-backend.dtb
> tests/test_prop.sh: fake.dtb fake-backend.dtb
> tests/test_p9_fapi_translation.sh: p9.dtb bmc-kernel.dtb
> +tests/test_p10_fapi_translation.sh: p10.dtb bmc-kernel.dtb
>
> test: $(libpdbg_tests)
>
> @@ -252,6 +255,12 @@ libpdbg_p9_fapi_translation_test_CXXFLAGS = $(libpdbg_test_cflags)
> libpdbg_p9_fapi_translation_test_LDFLAGS = $(libpdbg_test_ldflags)
> libpdbg_p9_fapi_translation_test_LDADD = $(libpdbg_test_ldadd)
>
> +libpdbg_p10_fapi_translation_test_SOURCES = src/tests/libpdbg_p10_fapi_translation_test.C \
> + src/tests/p10_scominfo.C src/tests/p10_scom_addr.C
> +libpdbg_p10_fapi_translation_test_CXXFLAGS = $(libpdbg_test_cflags)
> +libpdbg_p10_fapi_translation_test_LDFLAGS = $(libpdbg_test_ldflags)
> +libpdbg_p10_fapi_translation_test_LDADD = $(libpdbg_test_ldadd)
> +
> libpdbg_prop_test_SOURCES = src/tests/libpdbg_prop_test.c
> libpdbg_prop_test_CFLAGS = $(libpdbg_test_cflags)
> libpdbg_prop_test_LDFLAGS = $(libpdbg_test_ldflags)
> diff --git a/src/tests/libpdbg_p10_fapi_translation_test.C b/src/tests/libpdbg_p10_fapi_translation_test.C
> new file mode 100644
> index 0000000..eb6db73
> --- /dev/null
> +++ b/src/tests/libpdbg_p10_fapi_translation_test.C
> @@ -0,0 +1,113 @@
Copyright header
> +#include <stdio.h>
> +#include <inttypes.h>
> +
> +#define class klass
> +#include "libpdbg/libpdbg.h"
> +#include "libpdbg/hwunit.h"
> +#include "libpdbg/target.h"
> +#undef class
> +
> +#include "p10_scominfo.H"
> +
> +#define MAX_INDEX 30
> +
> +int test_unit_translation(struct pdbg_target *target, p10ChipUnits_t cu, int index, uint64_t addr)
> +{
> + uint64_t pdbg_addr, fapi_addr;
> +
> + target->index = index;
> +
> + /* TODO: Check standard chiplet translation */
> + if (!target->translate)
> + return 1;
> +
> + if (validateChipUnitNum(index, cu))
> + return 1;
> +
> + pdbg_addr = target->translate(target, addr);
> + fapi_addr = p10_scominfo_createChipUnitScomAddr(cu, 0x10, index, addr, 0);
> +
> + /* Ignore bad addresses. We should really test that we get an assert error
> + * from the translation code though. */
> + if (fapi_addr == FAILED_TRANSLATION)
> + return 1;
> +
> + if (pdbg_addr != fapi_addr)
> + fprintf(stderr,
> + "PDBG Address 0x%016" PRIx64 " does not match FAPI Address 0x%016" PRIx64
> + " for address 0x%016" PRIx64 " on target %s@%d\n",
> + pdbg_addr, fapi_addr, addr, pdbg_target_path(target), index);
> +
> + return pdbg_addr == fapi_addr;
> +}
> +
> +static struct chip_unit {
> + p10ChipUnits_t cu;
> + const char *classname;
> +} chip_unit[] = {
> + { PU_C_CHIPUNIT, "core" },
> + { PU_EQ_CHIPUNIT, "eq" },
> + { PU_PEC_CHIPUNIT, "pec" },
> + { PU_PHB_CHIPUNIT, "phb" },
> + { PU_MI_CHIPUNIT, "mi" },
> + { PU_MCC_CHIPUNIT, "mcc" },
> + { PU_OMIC_CHIPUNIT, "omic" },
> + { PU_OMI_CHIPUNIT, "omi" },
> + { PU_PERV_CHIPUNIT, "chiplet" },
> + { PU_MC_CHIPUNIT, "mc" },
> + { PU_NMMU_CHIPUNIT, "nmmu" },
> + { PU_IOHS_CHIPUNIT, "iohs" },
> + { PU_PAU_CHIPUNIT, "pau" },
> + { PU_PAUC_CHIPUNIT, "pauc" },
> + { NONE, NULL },
> +};
> +
> +int main(int argc, const char **argv)
> +{
> + struct pdbg_target *target;
> + p10ChipUnits_t cu = NONE;
> + int i, count=0;
> +
> + if (argc != 2) {
> + fprintf(stderr, "Usage: %s <class>\n", argv[0]);
> + return 1;
> + }
> +
> + // pdbg_set_loglevel(PDBG_DEBUG);
> +
> + pdbg_targets_init(NULL);
> +
> + for (i=0; chip_unit[i].classname; i++) {
> + if (!strcmp(argv[1], chip_unit[i].classname)) {
> + cu = chip_unit[i].cu;
> + }
> + }
> +
> + if (cu == NONE) {
> + fprintf(stderr, "Unknown class '%s'\n", argv[1]);
> + return 1;
> + }
> +
> + pdbg_for_each_class_target(argv[1], target) {
> + uint64_t addr;
> + int index = pdbg_target_index(target);
> +
> + /* We only need to test targets on proc0, translation won't change for
> + * other procs */
> + if (pdbg_target_index(pdbg_target_parent("proc", target)))
> + continue;
> +
> + printf("Testing %s %d\n", pdbg_target_path(target), index);
> + /* Test every sat offset */
> + for (addr = 0; addr < 0xffffffff; addr += 0x40)
> + assert(test_unit_translation(target, cu, index, addr));
> +
> + count++;
> + }
> +
> + if (count == 0) {
> + printf("Test skipped for class '%s'\n", argv[1]);
> + }
> +
> + return 0;
> +}
> diff --git a/src/tests/p10_cu.H b/src/tests/p10_cu.H
> new file mode 100644
> index 0000000..36e429c
> --- /dev/null
> +++ b/src/tests/p10_cu.H
> @@ -0,0 +1,120 @@
> +/* IBM_PROLOG_BEGIN_TAG */
> +/* This is an automatically generated prolog. */
> +/* */
> +/* $Source: chips/p10/common/scominfo/p10_cu.H $ */
> +/* */
> +/* IBM CONFIDENTIAL */
err... This notice should be dropped before putting it anywhere.
> +/* */
> +/* EKB Project */
> +/* */
> +/* COPYRIGHT 2018,2019 */
> +/* [+] International Business Machines Corp. */
> +/* */
> +/* */
> +/* The source code for this program is not published or otherwise */
> +/* divested of its trade secrets, irrespective of what has been */
> +/* deposited with the U.S. Copyright Office. */
> +/* */
> +/* IBM_PROLOG_END_TAG */
> +///
> +/// @file p10_cu.H
> +/// @brief P10 chip unit definitions
> +///
> +/// HWP Owner: thi at us.ibm.com
> +/// HWP Team: NEST
> +/// HWP Level: 1
> +/// HWP Consumed by: FSP/HB
> +///
> +
> +#ifndef P10_CU_H
> +#define P10_CU_H
> +
> +// includes
> +#include <stdint.h>
> +
> +extern "C"
> +{
> +
> + /// P10 chip unit type enumeration
> + typedef enum
> + {
> + P10_NO_CU = 0, ///< P10 chip
> + PU_PERV_CHIPUNIT = 1, ///< Pervasive
> + PU_EQ_CHIPUNIT = 2, ///< Quad
> + PU_C_CHIPUNIT = 3, ///< Core
> + PU_PEC_CHIPUNIT = 4, ///< PCIe (PEC)
> + PU_PHB_CHIPUNIT = 5, ///< PCIe (PHB)
> + PU_NMMU_CHIPUNIT = 6, ///< NMMU
> + PU_IOHS_CHIPUNIT = 7, ///< IOHS (High speed IO)
> + PU_MC_CHIPUNIT = 8, ///< MC
> + PU_MI_CHIPUNIT = 9, ///< MI
> + PU_MCC_CHIPUNIT = 10, ///< MCC
> + PU_OMI_CHIPUNIT = 11, ///< OMI
> + PU_OMIC_CHIPUNIT = 12, ///< OMIC
> + PU_PAU_CHIPUNIT = 13, ///< PAU
> + PU_PAUC_CHIPUNIT = 14, ///< PAUC
> + NONE = 0xFF, ///< None/Invalid
> + } p10ChipUnits_t;
> +
> + /// P10 chip unit pairing struct
> + struct p10_chipUnitPairing_t
> + {
> + /// @brief Default constructor
> + p10_chipUnitPairing_t()
> + : chipUnitType(NONE), chipUnitNum(0) {}
> + /// @brief Construct from type/instance number
> + p10_chipUnitPairing_t (p10ChipUnits_t type, uint32_t num)
> + : chipUnitType(type), chipUnitNum(num) {}
> +
> + p10ChipUnits_t chipUnitType; ///< chip unit type
> + uint32_t chipUnitNum; ///< chip unit instance number
> + };
> +
> + struct p10_chipUnitDescription_t
> + {
> + const char* strVal; // Chip unit string
> + const p10ChipUnits_t enumVal; // Chip unit enum value
> + const uint8_t maxChipUnitNum; // Max Chip unit num value
> + };
> +
> +
> + // Max chip unit positions
> + const uint8_t MAX_PU_CHIPUNIT_NUM = 0; // P10_NO_CU
> + const uint8_t MAX_PU_EQ_CHIPUNIT_NUM = 7;
> + const uint8_t MAX_PU_C_CHIPUNIT_NUM = 31;
> + const uint8_t MAX_PU_PEC_CHIPUNIT_NUM = 1;
> + const uint8_t MAX_PU_PHB_CHIPUNIT_NUM = 5;
> + const uint8_t MAX_PU_NMMU_CHIPUNIT_NUM = 1;
> + const uint8_t MAX_PU_PERV_CHIPUNIT_NUM = 39; // Special case, with gaps
> + const uint8_t MAX_PU_IOHS_CHIPUNIT_NUM = 7;
> + const uint8_t MAX_PU_PAU_CHIPUNIT_NUM = 7;
> + const uint8_t MAX_PU_MC_CHIPUNIT_NUM = 3;
> + const uint8_t MAX_PU_MI_CHIPUNIT_NUM = 3;
> + const uint8_t MAX_PU_MCC_CHIPUNIT_NUM = 7;
> + const uint8_t MAX_PU_OMIC_CHIPUNIT_NUM = 7;
> + const uint8_t MAX_PU_OMI_CHIPUNIT_NUM = 15;
> + const uint8_t MAX_PU_PAUC_CHIPUNIT_NUM = 3;
> +
> + // Chip unit string/enum/max targes table
> + const p10_chipUnitDescription_t ChipUnitDescriptionTable[] =
> + {
> + { "pu" , P10_NO_CU, MAX_PU_CHIPUNIT_NUM },
> + { "eq" , PU_EQ_CHIPUNIT, MAX_PU_EQ_CHIPUNIT_NUM },
> + { "c" , PU_C_CHIPUNIT, MAX_PU_C_CHIPUNIT_NUM },
> + { "pec" , PU_PEC_CHIPUNIT, MAX_PU_PEC_CHIPUNIT_NUM },
> + { "phb" , PU_PHB_CHIPUNIT, MAX_PU_PHB_CHIPUNIT_NUM },
> + { "nmmu" , PU_NMMU_CHIPUNIT, MAX_PU_NMMU_CHIPUNIT_NUM },
> + { "perv" , PU_PERV_CHIPUNIT, MAX_PU_PERV_CHIPUNIT_NUM }, // Special case, with gaps
> + { "iohs" , PU_IOHS_CHIPUNIT, MAX_PU_IOHS_CHIPUNIT_NUM },
> + { "mc" , PU_MC_CHIPUNIT, MAX_PU_MC_CHIPUNIT_NUM },
> + { "mi" , PU_MI_CHIPUNIT, MAX_PU_MI_CHIPUNIT_NUM },
> + { "mcc" , PU_MCC_CHIPUNIT, MAX_PU_MCC_CHIPUNIT_NUM },
> + { "omi" , PU_OMI_CHIPUNIT, MAX_PU_OMI_CHIPUNIT_NUM },
> + { "omic" , PU_OMIC_CHIPUNIT, MAX_PU_OMIC_CHIPUNIT_NUM },
> + { "pau" , PU_PAU_CHIPUNIT, MAX_PU_PAU_CHIPUNIT_NUM },
> + { "pauc" , PU_PAUC_CHIPUNIT, MAX_PU_PAUC_CHIPUNIT_NUM },
> + };
> +
> +} // extern "C"
> +
> +#endif /* P10_CU_H */
> diff --git a/src/tests/p10_scom_addr.C b/src/tests/p10_scom_addr.C
> new file mode 100644
> index 0000000..cd88ea0
> --- /dev/null
> +++ b/src/tests/p10_scom_addr.C
> @@ -0,0 +1,934 @@
> +/* IBM_PROLOG_BEGIN_TAG */
> +/* This is an automatically generated prolog. */
> +/* */
> +/* $Source: chips/p10/common/scominfo/p10_scom_addr.C $ */
> +/* */
> +/* IBM CONFIDENTIAL */
> +/* */
> +/* EKB Project */
> +/* */
> +/* COPYRIGHT 2018,2019 */
> +/* [+] International Business Machines Corp. */
> +/* */
> +/* */
> +/* The source code for this program is not published or otherwise */
> +/* divested of its trade secrets, irrespective of what has been */
> +/* deposited with the U.S. Copyright Office. */
> +/* */
> +/* IBM_PROLOG_END_TAG */
> +///
> +/// @file p10_scom_addr.C
> +/// @brief P10 chip unit SCOM address platform translation code
> +///
> +/// HWP HW Maintainer: Thi Tran <thi at us.ibm.com>
> +/// HWP FW Maintainer:
> +/// HWP Consumed by: Cronus, HB, HWSV
> +///
> +
> +// includes
> +#include "p10_scom_addr.H"
> +
> +#define P10_SCOM_ADDR_C
> +
> +extern "C"
> +{
> + /// See function description in header file
> +
> + // #####################################
> + bool p10_scom_addr::isEqTarget()
> + {
> + bool l_eqTarget = false;
> +
> + // Must have EQ chiplet ID
> + if ( (getChipletId() >= EQ0_CHIPLET_ID) &&
> + (getChipletId() <= EQ7_CHIPLET_ID) )
> + {
> + // If endpoint is QME (0xE):
> + // QME per core (bit 20) must be 0
> + // region select (bits 16:19) must be 0
> + if ( (getEndpoint() == QME_ENDPOINT) && (!getQMEPerCore()) &&
> + (getRegionSelect() == EQ_REGION_SEL) )
> + {
> + l_eqTarget = true;
> + }
> + // associate perv target resources with EQ
> + else if (isPervTarget())
> + {
> + l_eqTarget = true;
> + }
> + }
> +
> + return l_eqTarget;
> + }
> +
> + // ########################################
> + uint8_t p10_scom_addr::getEqTargetInstance()
> + {
> + uint8_t l_instance = 0;
> + l_instance = (getChipletId() - EQ0_CHIPLET_ID);
> + return l_instance;
> + }
> +
> + // #####################################
> + bool p10_scom_addr::isCoreTarget()
> + {
> + bool l_coreTarget = false;
> +
> + // Must have EQ chiplet ID
> + if ( (getChipletId() >= EQ0_CHIPLET_ID) &&
> + (getChipletId() <= EQ7_CHIPLET_ID) )
> + {
> + // Region select must be...
> + if ( (getRegionSelect() == MULTI_HOT_SELECT_C0) || // 0x8
> + (getRegionSelect() == MULTI_HOT_SELECT_C1) || // 0x4
> + (getRegionSelect() == MULTI_HOT_SELECT_C2) || // 0x2
> + (getRegionSelect() == MULTI_HOT_SELECT_C3) || // 0x1
> + (getRegionSelect() == EQ_REGION_SEL) ) // 0x0
> + {
> + // If QME endpoint (0xE), QME per core (bit 20) must be 1
> + if ( (getEndpoint() == QME_ENDPOINT) && getQMEPerCore() )
> + {
> + l_coreTarget = true;
> + }
> + // or must be PSCOM endpoints -- ensure that ring ID is
> + // associated with a core resource on the first PSCOM
> + // endpoint (0x1), all are core rings on the second
> + // PSCOM endpoint (0x2)
> + else if ( ((getEndpoint() == PSCOM_ENDPOINT) && // 0x1
> + ((getEQRingId() != PERV_RING_ID) && // 0x1
> + (getEQRingId() != QME_RING_ID))) || // 0x2
> + (getEndpoint() == PSCOM_2_ENDPOINT) ) // 0x2
> + {
> + l_coreTarget = true;
> + }
> + }
> + }
> +
> + return l_coreTarget;
> + }
> +
> + // #####################################
> + uint8_t p10_scom_addr::getCoreTargetInstance()
> + {
> + uint8_t l_instance = 0;
> +
> + // First core instance of the quad
> + l_instance = (getChipletId() - EQ0_CHIPLET_ID) * NUM_CORES_PER_EQ;
> +
> + // Get core instance based on region select
> + if (getRegionSelect() == MULTI_HOT_SELECT_C3)
> + {
> + l_instance += 3;
> + }
> + else if (getRegionSelect() == MULTI_HOT_SELECT_C2)
> + {
> + l_instance += 2;
> + }
> + else if (getRegionSelect() == MULTI_HOT_SELECT_C1)
> + {
> + l_instance += 1;
> + }
> +
> + return l_instance;
> + }
> +
> + // #####################################
> + bool p10_scom_addr::isPecTarget()
> + {
> + bool l_pecTarget = false;
> +
> + // associate perv target resources with PCIE
> + if ( (getChipletId() >= PCI0_CHIPLET_ID) && // 0x8
> + (getChipletId() <= PCI1_CHIPLET_ID) ) // 0x9
> + {
> + l_pecTarget = isPervTarget();
> + }
> +
> + // Endpoint must be PSCOM (0x1)
> + if (getEndpoint() == PSCOM_ENDPOINT) // 0x1
> + {
> + // For PEC addresses via NEST regions:
> + // Ring ID must be 0x6, sat ID must be 0
> + if ( (getChipletId() >= N0_CHIPLET_ID) && // 0x2
> + (getChipletId() <= N1_CHIPLET_ID) && // 0x3
> + (getRingId() == N0_PE1_RING_ID) && // 0x6
> + (getSatId() == PEC_SAT_ID) ) // 0x0
> +
> + {
> + l_pecTarget = true;
> + }
> + // For PEC addresses via PCIE:
> + else if ( (getChipletId() >= PCI0_CHIPLET_ID) && // 0x8
> + (getChipletId() <= PCI1_CHIPLET_ID) ) // 0x9
> + {
> + // Ring IDs must be 0x4-0x5 (iopci rings) or
> + // Ring ID is 0x2 (pci ring) and sat Id = 0x0
> + if ( (getRingId() == IO_PCI0_RING_ID) || // 0x4
> + (getRingId() == IO_PCI1_RING_ID) || // 0x5
> + ((getRingId() == PCI_RING_ID) && // 0x2
> + (getSatId() == PEC_SAT_ID)) ) // 0x0
> + {
> + l_pecTarget = true;
> + }
> + }
> + }
> +
> + return l_pecTarget;
> + }
> +
> + // #####################################
> + uint8_t p10_scom_addr::getPecTargetInstance()
> + {
> + uint8_t l_instance = 0;
> +
> + // PEC addresses via NEST regions
> + l_instance = N1_CHIPLET_ID - getChipletId();
> +
> + // PEC addresses via PCIE
> + if ( (getChipletId() == PCI0_CHIPLET_ID) ||
> + (getChipletId() == PCI1_CHIPLET_ID) )
> + {
> + l_instance = getChipletId() - PCI0_CHIPLET_ID;
> + }
> +
> + return l_instance;
> + }
> +
> + // #####################################
> + bool p10_scom_addr::isPhbTarget()
> + {
> + bool l_phbTarget = false;
> +
> + // Endpoint must be PSCOM (0x1)
> + if ( (getEndpoint() == PSCOM_ENDPOINT) ) // 0x1
> + {
> + // PCIE chiplet ID
> + if ( (getChipletId() >= PCI0_CHIPLET_ID) && // 0x8
> + (getChipletId() <= PCI1_CHIPLET_ID) ) // 0x9
> + {
> + // Ring ID of 0x2, Sat ID 1-6
> + if ( (getRingId() == PCI_RING_ID) && // 0x2
> + (getSatId() >= PHB0_AIB_SAT_ID) && // 0x1
> + (getSatId() <= PHB2_PHB_SAT_ID) ) // 0x6
> + {
> + l_phbTarget = true;
> + }
> + }
> +
> + // N0/N1 chiplet ID
> + if ( (getChipletId() >= N0_CHIPLET_ID) && // 0x2
> + (getChipletId() <= N1_CHIPLET_ID) && // 0x3
> + (getRingId() == N0_PE1_RING_ID) && // 0x6
> + (getSatId() >= PHB0_AIB_SAT_ID) && // 0x1
> + (getSatId() <= PHB2_AIB_SAT_ID) ) // 0x3
> + {
> + l_phbTarget = true;
> + }
> + }
> +
> + return l_phbTarget;
> + }
> +
> + // #####################################
> + uint8_t p10_scom_addr::getPhbTargetInstance()
> + {
> + uint8_t l_instance = 0;
> +
> + if ( (getChipletId() == N0_CHIPLET_ID) ||
> + (getChipletId() == PCI1_CHIPLET_ID) )
> + {
> + l_instance += 3;
> + }
> +
> + if ( (getRingId() == N0_PE1_RING_ID) )
> + {
> + l_instance += (getSatId() - 1);
> + }
> + else if ( (getRingId() == PCI_RING_ID ) )
> + {
> + l_instance += ((getSatId() - 1) % 3);
> + }
> + else
> + {
> + l_instance += (getRingId() - 3);
> + }
> +
> + return l_instance;
> + }
> +
> + // #####################################
> + bool p10_scom_addr::isNmmuTarget()
> + {
> + bool l_nmmuTarget = false;
> +
> + // Must have NEST chiplet ID
> + if ( (getChipletId() == N0_CHIPLET_ID) ||
> + (getChipletId() == N1_CHIPLET_ID) )
> + {
> + // Endpoint must be PSCOM, ring ID must be 0x3, Sat ID must be 0/1
> + if ( (getEndpoint() == PSCOM_ENDPOINT) && // 0x1
> + (getRingId() == N0_MM0_RING_ID) && // 0x3
> + (getSatId() >= NMMU_SAT_ID0) && // 0x0
> + (getSatId() <= NMMU_SAT_ID1) ) // 0x1
> + {
> + l_nmmuTarget = true;
> + }
> + }
> +
> + return l_nmmuTarget;
> + }
> +
> + // #####################################
> + uint8_t p10_scom_addr::getNmmuTargetInstance()
> + {
> + return (getChipletId() - N0_CHIPLET_ID);
> + }
> +
> + // #####################################
> + bool p10_scom_addr::isPervTarget()
> + {
> + bool l_pervTarget = false;
> + uint8_t l_index = 0;
> +
> + // Check chiplet ID by looping through PERV chiplet ID table
> + for (l_index = 0;
> + l_index < sizeof(PervTargetChipletIdTable) / sizeof(p10ChipletId_t);
> + l_index++)
> + {
> + // See if Chiplet ID is a perv chiplet ID from table
> + if (getChipletId() == PervTargetChipletIdTable[l_index])
> + {
> + if (getEndpoint() == PSCOM_ENDPOINT) // 0x1
> + {
> + // EQ specific PSCOM endpoint logic
> + // ensure ring being accessed is EQ scoped (non-core)
> + if ( (getChipletId() >= EQ0_CHIPLET_ID) &&
> + (getChipletId() <= EQ7_CHIPLET_ID) )
> + {
> + if ( (getEQRingId() == PERV_RING_ID) || // 0x1
> + (getEQRingId() == QME_RING_ID) ) // 0x2
> + {
> + l_pervTarget = true;
> + }
> + }
> +
> + // non-EQ chiplet, just match for ring ID = 0 / 1
> + else
> + {
> + if ( (getRingId() == PSCOM_RING_ID) || // 0x0
> + (getRingId() == PERV_RING_ID) ) // 0x1
> + {
> + l_pervTarget = true;
> + }
> + }
> + }
> + else if (getEndpoint() == CLOCK_CTRL_ENDPOINT) // 0x3
> + {
> + l_pervTarget = true;
> + }
> + // Check if Endpoint is a PERV endpoint
> + else if ( (getEndpoint() == CHIPLET_CTRL_ENDPOINT) || // 0x0
> + (getEndpoint() == FIR_ENDPOINT) || // 0x4
> + (getEndpoint() == THERMAL_ENDPOINT) || // 0x5
> + (getEndpoint() == PCBSLV_ENDPOINT) ) // 0xF
> + {
> + if ( getRingId() == PSCOM_RING_ID) // 0x0
> + {
> + l_pervTarget = true;
> + }
> + }
> +
> + break;
> + }
> + }
> +
> + return l_pervTarget;
> + }
> +
> + // #####################################
> + uint8_t p10_scom_addr::getPervTargetInstance()
> + {
> + return getChipletId();
> + }
> +
> + // #####################################
> + bool p10_scom_addr::isIoHsTarget()
> + {
> + bool l_iohsTarget = false;
> +
> + // IOHS can be targeted by AXON or PAU chiplets (indirect scom),
> +
> + // Associate perv target resources with AXON
> + if ( (getChipletId() >= AXON0_CHIPLET_ID) && // 0x18
> + (getChipletId() <= AXON7_CHIPLET_ID) ) // 0x1F
> + {
> + l_iohsTarget = isPervTarget();
> +
> + // If not a PERV target check for IOHS target that uses AXON chiplet
> + if (l_iohsTarget == false)
> + {
> + if ( (getEndpoint() == PSCOM_ENDPOINT) &&
> + (getRingId() == AXONE_PDL_RING_ID) && // 0x4
> + (getSatId() == DLP_SAT_ID) ) // 0x0
> + {
> + l_iohsTarget = true;
> + }
> + }
> + }
> +
> + // Target via PAU chiplets
> + else if ( isIndirect() &&
> + (getChipletId() >= PAU0_CHIPLET_ID) && // 0x10
> + (getChipletId() <= PAU3_CHIPLET_ID) ) // 0x13
> + {
> + // Endpoint must be PSCOM and RingID is IOPPE
> + if ( (getEndpoint() == PSCOM_ENDPOINT) &&
> + (getRingId() == PAU_IOPPE_RING_ID) ) // 0xB
> + {
> + // Group address (bits 22:26 of upper address) must be 0b00000 or 0b00001,
> + // and indirect register address should be per-group or per-lane
> + // Group 0: IOHS[0]
> + // Group 1: IOHS[1]
> + if ( ( (getIoGroupAddr() == 0x0) ||
> + (getIoGroupAddr() == 0x1) ) &&
> + ((getIoRegAddr() & 0x1E0) != 0x1E0) )
> + {
> + l_iohsTarget = true;
> + }
> + }
> + }
> +
> + return l_iohsTarget;
> + }
> +
> + // #####################################
> + uint8_t p10_scom_addr::getIoHsTargetInstance()
> + {
> + uint8_t l_instance = 0;
> +
> + // Chiplet ID is AXON
> + if ( (getChipletId() >= AXON0_CHIPLET_ID) &&
> + (getChipletId() <= AXON7_CHIPLET_ID) )
> + {
> + l_instance = getChipletId() - AXON0_CHIPLET_ID;
> + }
> + // Chiplet ID is PAU
> + else
> + {
> + // If chiplet ID is PAU then this is indirect address.
> + // Use PAU and Group address (bits 22:26) to calculate instance.
> + // PAU0 (lower right) -> IOHS0 + IOHS1
> + // PAU1 (upper right) -> IOHS2 + IOHS3
> + // PAU2 (lower left) -> IOHS4 + IOHS5
> + // PAU3 (upper left) -> IOHS6 + IOHS7
> + //
> + // Group address bits (22:26) of upper 32-bit
> + // Group 0: IOHS[0]
> + // Group 1: IOHS[1]
> + if ( (getChipletId() >= PAU0_CHIPLET_ID) && // 0x10
> + (getChipletId() <= PAU3_CHIPLET_ID) ) // 0x13
> + {
> + l_instance = (getChipletId() - PAU0_CHIPLET_ID) * 2;
> +
> + if (getIoGroupAddr() == 0x1)
> + {
> + l_instance += 1;
> + }
> + }
> + }
> +
> + return l_instance;
> + }
> +
> + // #####################################
> + bool p10_scom_addr::isPauTarget()
> + {
> + bool l_pauTarget = false;
> +
> + // Endpoint must be PSCOM
> + if ( getEndpoint() == PSCOM_ENDPOINT)
> + {
> + // Check chiplet ID
> + if ( (getChipletId() >= PAU0_CHIPLET_ID) &&
> + (getChipletId() <= PAU3_CHIPLET_ID) )
> + {
> + if ( (getRingId() == PAU0346_0_RING_ID) || // 0x02
> + (getRingId() == PAU0346_1_RING_ID) ) // 0x03
> +
> + {
> + l_pauTarget = true;
> + }
> + else if ( (getChipletId() == PAU2_CHIPLET_ID) ||
> + (getChipletId() == PAU3_CHIPLET_ID) )
> + {
> + if ( (getRingId() == PAU57_0_RING_ID) || // 0x04
> + (getRingId() == PAU57_1_RING_ID) ) // 0x05
> + {
> + l_pauTarget = true;
> + }
> + }
> + }
> + }
> +
> + return l_pauTarget;
> + }
> +
> + // #####################################
> + uint8_t p10_scom_addr::getPauTargetInstance()
> + {
> + uint8_t l_instance = 0;
> +
> + if ( (getRingId() == PAU0346_0_RING_ID) || // 0x02
> + (getRingId() == PAU0346_1_RING_ID) ) // 0x03
> + {
> + if (getChipletId() == PAU0_CHIPLET_ID)
> + {
> + l_instance = 0;
> + }
> + else if (getChipletId() == PAU1_CHIPLET_ID)
> + {
> + l_instance = 3;
> + }
> + else if (getChipletId() == PAU2_CHIPLET_ID)
> + {
> + l_instance = 4;
> + }
> + else if (getChipletId() == PAU3_CHIPLET_ID)
> + {
> + l_instance = 6;
> + }
> + }
> +
> + else if ( (getRingId() == PAU57_0_RING_ID) || // 0x04
> + (getRingId() == PAU57_1_RING_ID) ) // 0x05
> + {
> + if (getChipletId() == PAU2_CHIPLET_ID)
> + {
> + l_instance = 5;
> + }
> + else if (getChipletId() == PAU3_CHIPLET_ID)
> + {
> + l_instance = 7;
> + }
> + }
> +
> + return l_instance;
> + }
> +
> + // #####################################
> + bool p10_scom_addr::isMcTarget()
> + {
> + // Same as MI
> + return isMiTarget();
> + }
> +
> + // #####################################
> + uint8_t p10_scom_addr::getMcTargetInstance()
> + {
> + // Same as MI
> + return getMiTargetInstance();
> + }
> +
> + // #####################################
> + bool p10_scom_addr::isMiTarget()
> + {
> + bool l_miTarget = false;
> +
> + // Chiplet ID must belong to MCs
> + if ( (getChipletId() >= MC0_CHIPLET_ID) && // 0x0C
> + (getChipletId() <= MC3_CHIPLET_ID) ) // 0x0F
> + {
> + // allow access to perv endpoints on MC chiplets
> + if (isPervTarget())
> + {
> + l_miTarget = true;
> + }
> + // Endpoint = PSCOM_ENDPOINT, and ringID = MC_0_RING_ID
> + else if ( (getEndpoint() == PSCOM_ENDPOINT) && // 0x1
> + (getRingId() == MC_0_RING_ID) ) // 0x3
> + {
> + // PBI satellite
> + if (getSatId() == MC_SAT_ID0) // 0x0 (PBI)
> + {
> + // avoid match on MCC register space
> + if (!(((getSatOffset() >= 0x22) &&
> + (getSatOffset() <= 0x2B)) ||
> + ((getSatOffset() >= 0x32) &&
> + (getSatOffset() <= 0x3B))))
> + {
> + l_miTarget = true;
> + }
> + }
> +
> + // MCBIST satellite ID space
> + // avoid match on MCC register space in 0xD
> + if ( (getSatId() == MC_SAT_ID12) || // 0xC,0xE,0xF (MCBIST)
> + (getSatId() == MC_SAT_ID14) ||
> + (getSatId() == MC_SAT_ID15) )
> + {
> + l_miTarget = true;
> + }
> + }
> + }
> +
> + return l_miTarget;
> + }
> +
> + // #####################################
> + uint8_t p10_scom_addr::getMiTargetInstance()
> + {
> + return getChipletId() - MC0_CHIPLET_ID;
> + }
> +
> + // #####################################
> + bool p10_scom_addr::isMccTarget()
> + {
> + bool l_mccTarget = false;
> +
> + // Chiplet ID must belong to MCs, Endpoint = PSCOM_ENDPOINT,
> + // and ringID = MC_0_RING_ID
> + if ( (getChipletId() >= MC0_CHIPLET_ID) && // 0x0C
> + (getChipletId() <= MC3_CHIPLET_ID) && // 0x0F
> + (getEndpoint() == PSCOM_ENDPOINT) && // 0x1
> + (getRingId() == MC_0_RING_ID) ) // 0x3
> + {
> + // MCC Sat ID
> + if ( (getSatId() == MC_SAT_ID4) || // 0x4
> + (getSatId() == MC_SAT_ID8) || // 0x8
> + (getSatId() == MC_SAT_ID5) || // 0x5
> + (getSatId() == MC_SAT_ID9) ) // 0x9
> + {
> + l_mccTarget = true;
> + }
> +
> + // MCC register space in PBI
> + if (getSatId() == MC_SAT_ID0)
> + {
> + if (((getSatOffset() >= 0x22) &&
> + (getSatOffset() <= 0x2B)) ||
> + ((getSatOffset() >= 0x32) &&
> + (getSatOffset() <= 0x3B)))
> + {
> + l_mccTarget = true;
> + }
> + }
> +
> + // MCC register space in MCBIST
> + if (getSatId() == MC_SAT_ID13)
> + {
> + l_mccTarget = true;
> + }
> + }
> +
> + return l_mccTarget;
> + }
> +
> + // #####################################
> + uint8_t p10_scom_addr::getMccTargetInstance()
> + {
> + uint8_t l_instance = (getChipletId() - MC0_CHIPLET_ID) * 2;
> +
> + // MCC Sat ID
> + if ( (getSatId() == MC_SAT_ID5) || // 5
> + (getSatId() == MC_SAT_ID9) ) // 9
> + {
> + l_instance += 1;
> + }
> +
> + // MCC register space in PBI
> + if ( getSatId() == MC_SAT_ID0 ) // 0
> + {
> + if ((getSatOffset() >= 0x32) &&
> + (getSatOffset() <= 0x3B))
> + {
> + l_instance += 1;
> + }
> + }
> +
> + // MCC register space in MCBIST
> + if ( getSatId() == MC_SAT_ID13) // 13
> + {
> + // MSB of SatOffset denotes channel
> + if (getSatOffset() >= 0x20)
> + {
> + l_instance += 1;
> + }
> + }
> +
> + return l_instance;
> + }
> +
> + // #####################################
> + bool p10_scom_addr::isOmiTarget()
> + {
> + bool l_omiTarget = false;
> +
> + // PAU chiplet, IOPPE ringId (indirect scom)
> + if ( isIndirect() && // indirect
> + ( getChipletId() >= PAU0_CHIPLET_ID ) && // 0x10
> + ( getChipletId() <= PAU3_CHIPLET_ID ) && // 0x13
> + ( getEndpoint() == PSCOM_ENDPOINT ) && // 0x1
> + ( getRingId() == PAU_IOPPE_RING_ID) && // 0xB
> + ( getSatId() == PPE_SAT_ID0) ) // 0x0
> + {
> + // Group address (bits 22:26 of upper address)
> + // must be 0b00010 or 0b00011 (for OMI)
> + if ( (getIoGroupAddr() == 0x2 ) ||
> + (getIoGroupAddr() == 0x3 ) )
> + {
> + // Reg address must start with 0xxx (per lane)
> + uint32_t regAddr = getIoRegAddr();
> +
> + if ( ( regAddr & 0x100 ) == 0x000 )
> + {
> + l_omiTarget = true;
> + }
> + }
> + }
> +
> + // MC chiplet direct SCOM
> + if ( ( getChipletId() >= MC0_CHIPLET_ID ) && // 0x0C
> + ( getChipletId() <= MC3_CHIPLET_ID ) && // 0x0F
> + ( getEndpoint() == PSCOM_ENDPOINT ) && // 0x1
> + ( getRingId() >= OMI0_RING_ID ) && // 0x5
> + ( getRingId() <= OMI1_RING_ID ) && // 0x6
> + ( getSatId() == MC_SAT_ID0 ) ) // 0x0 (DL)
> + {
> + if (((getSatOffset() >= 16) && // 16:31 (subchannel 0)
> + (getSatOffset() <= 47)) || // 32:47 (subchannel 1)
> + ((getSatOffset() >= 48) && // 48:51 (subchannel 0, pm regs)
> + (getSatOffset() <= 51)) ||
> + ((getSatOffset() >= 56) && // 48:51 (subchannel 1, pm regs)
> + (getSatOffset() <= 59)))
> + {
> + l_omiTarget = true;
> + }
> + }
> +
> + return l_omiTarget;
> + }
> +
> + // #####################################
> + uint8_t p10_scom_addr::getOmiTargetInstance()
> + {
> + uint8_t l_instance = 0;
> +
> + // PAU chiplet indirect SCOM
> + if ( (getChipletId() >= PAU0_CHIPLET_ID) && // 0x10
> + (getChipletId() <= PAU3_CHIPLET_ID) ) // 0x13
> + {
> + // PAU0 --> OMI 0/1/2/3
> + // PAU1 --> OMI 8/9/10/11
> + // PAU2 --> OMI 4/5/6/7
> + // PAU3 --> OMI 12/13/14/15
> + // set basis based on direct chiplet ID
> + if (getChipletId() == PAU0_CHIPLET_ID)
> + {
> + l_instance = 0;
> + }
> + else if (getChipletId() == PAU1_CHIPLET_ID)
> + {
> + l_instance = 8;
> + }
> + else if (getChipletId() == PAU2_CHIPLET_ID)
> + {
> + l_instance = 4;
> + }
> + else
> + {
> + l_instance = 12;
> + }
> +
> + // account for IO group address
> + if (getIoGroupAddr() == 0x3)
> + {
> + l_instance += 2;
> + }
> +
> + // account for IO lane selection
> + if ( ( getIoLane() >= 8 ) &&
> + ( getIoLane() <= 15) )
> + {
> + l_instance += 1;
> + }
> + }
> +
> + // MC direct
> + if ( (getChipletId() >= MC0_CHIPLET_ID) &&
> + (getChipletId() <= MC3_CHIPLET_ID) )
> + {
> + // Instances 0, 4, 8, 12
> + l_instance = (getChipletId() - MC0_CHIPLET_ID) * 4;
> +
> + // Instances 2, 6, 10, 14
> + if ( getRingId() == OMI1_RING_ID ) // 0x6
> + {
> + l_instance += 2;
> + }
> +
> + // Instances 1, 3, 5, 7, 9, 11, 13, 15
> + if ( ((getSatOffset() >= 32) &&
> + (getSatOffset() <= 47)) ||
> + ((getSatOffset() >= 56) &&
> + (getSatOffset() <= 59)) )
> + {
> + l_instance += 1;
> + }
> + }
> +
> + return l_instance;
> + }
> +
> + // #####################################
> + bool p10_scom_addr::isOmicTarget()
> + {
> + bool l_omicTarget = false;
> +
> + // PAU chiplet, IOPPE ringId (indirect scom)
> + if ( isIndirect() && // indirect
> + ( getChipletId() >= PAU0_CHIPLET_ID ) && // 0x10
> + ( getChipletId() <= PAU3_CHIPLET_ID ) && // 0x13
> + ( getEndpoint() == PSCOM_ENDPOINT ) && // 0x1
> + ( getRingId() == PAU_IOPPE_RING_ID) && // 0xB
> + ( getSatId() == PPE_SAT_ID0) ) // 0x0
> + {
> + // Group address (bits 22:26 of upper address)
> + // must be 0b00010 or 0b00011 (for OMI)
> + if ( (getIoGroupAddr() == 0x2 ) ||
> + (getIoGroupAddr() == 0x3 ) )
> + {
> + // Reg address must start with 1xxx (per group),
> + // excluding 1111 (per bus)
> + uint32_t regAddr = getIoRegAddr();
> +
> + if ( ( ( regAddr & 0x1E0 ) != 0x1E0 ) &&
> + ( ( regAddr & 0x100 ) == 0x100 ) )
> + {
> + l_omicTarget = true;
> + }
> + }
> + }
> +
> + // MC chiplet direct SCOM
> + if ( ( getChipletId() >= MC0_CHIPLET_ID ) && // 0x0C
> + ( getChipletId() <= MC3_CHIPLET_ID ) && // 0x0F
> + ( getEndpoint() == PSCOM_ENDPOINT ) && // 0x1
> + ( getRingId() >= OMI0_RING_ID ) && // 0x5
> + ( getRingId() <= OMI1_RING_ID ) && // 0x6
> + ( getSatId() == MC_SAT_ID0 ) && // 0x0 (DL)
> + ( getSatOffset() >= 0 ) && // shared regs 0-15
> + ( getSatOffset() <= 15 ) )
> + {
> + l_omicTarget = true;
> + }
> +
> + return l_omicTarget;
> + }
> +
> + // #####################################
> + uint8_t p10_scom_addr::getOmicTargetInstance()
> + {
> + uint8_t l_instance = 0;
> +
> + // PAU indirect
> + if ( ( getChipletId() >= PAU0_CHIPLET_ID ) && // 0x10
> + ( getChipletId() <= PAU3_CHIPLET_ID ) ) // 0x13
> + {
> + // PAU0 --> OMIC 0/1
> + // PAU1 --> OMIC 4/5
> + // PAU2 --> OMIC 2/3
> + // PAU3 --> OMIC 6/7
> + if (getChipletId() == PAU0_CHIPLET_ID)
> + {
> + l_instance = 0;
> + }
> + else if (getChipletId() == PAU1_CHIPLET_ID)
> + {
> + l_instance = 4;
> + }
> + else if (getChipletId() == PAU2_CHIPLET_ID)
> + {
> + l_instance = 2;
> + }
> + else // PAU3_CHIPLET_ID
> + {
> + l_instance = 6;
> + }
> +
> + if (getIoGroupAddr() == 0x3)
> + {
> + l_instance += 1;
> + }
> + }
> +
> + // MC direct
> + if ( ( getChipletId() >= MC0_CHIPLET_ID ) && // 0x0C
> + ( getChipletId() <= MC3_CHIPLET_ID ) ) // 0x0F
> + {
> + l_instance = (getChipletId() - MC0_CHIPLET_ID) * 2;
> +
> + if (getRingId() == 0x6)
> + {
> + l_instance += 1;
> + }
> + }
> +
> + return l_instance;
> + }
> +
> + // #####################################
> + bool p10_scom_addr::isPaucTarget()
> + {
> + bool l_paucTarget = false;
> +
> + if ( (getChipletId() >= PAU0_CHIPLET_ID) && // 0x10
> + (getChipletId() <= PAU3_CHIPLET_ID) ) // 0x13
> + {
> + // allow access to perv endpoints on MC chiplets
> + if (isPervTarget())
> + {
> + l_paucTarget = true;
> + }
> + else if ( getEndpoint() == PSCOM_ENDPOINT ) // 0x1
> + {
> + // IO PPE access
> + if ( isDirect() && // direct
> + (getRingId() == PAU_IOPPE_RING_ID) && // 0xB
> + ( (getSatId() == PPE_SAT_ID0) || // 0x0
> + (getSatId() == PPE_SAT_ID1) ) ) // 0x1
> + {
> + l_paucTarget = true;
> + }
> +
> + // TL access
> + if ( (getRingId() == PAU_TL_RING_ID) && // 0x6
> + ( (getSatId() == TL_SAT_ID) ) ) // 0x0
> + {
> + l_paucTarget = true;
> + }
> +
> + // per-bus IO super wrapper registers
> + if ( isIndirect() && // indirect
> + ((getIoRegAddr() & 0x1E0) == 0x1E0) && // register(0:3) = 0b1111
> + (getRingId() == PAU_IOPPE_RING_ID) && // 0xB
> + (getSatId() == PPE_SAT_ID0) ) // 0x0
> + {
> + l_paucTarget = true;
> + }
> + }
> + }
> +
> + return l_paucTarget;
> + }
> +
> + // #####################################
> + uint8_t p10_scom_addr::getPaucTargetInstance()
> + {
> + uint8_t l_instance = (getChipletId() - PAU0_CHIPLET_ID);
> +
> + return l_instance;
> + }
> +
> +} // extern "C"
> +
> +#undef P10_SCOM_ADDR_C
> diff --git a/src/tests/p10_scom_addr.H b/src/tests/p10_scom_addr.H
> new file mode 100644
> index 0000000..a5d5efe
> --- /dev/null
> +++ b/src/tests/p10_scom_addr.H
> @@ -0,0 +1,718 @@
> +/* IBM_PROLOG_BEGIN_TAG */
> +/* This is an automatically generated prolog. */
> +/* */
> +/* $Source: chips/p10/common/scominfo/p10_scom_addr.H $ */
> +/* */
> +/* IBM CONFIDENTIAL */
> +/* */
> +/* EKB Project */
> +/* */
> +/* COPYRIGHT 2018,2019 */
> +/* [+] International Business Machines Corp. */
> +/* */
> +/* */
> +/* The source code for this program is not published or otherwise */
> +/* divested of its trade secrets, irrespective of what has been */
> +/* deposited with the U.S. Copyright Office. */
> +/* */
> +/* IBM_PROLOG_END_TAG */
> +///
> +/// @file p10_scom_addr.H
> +/// @brief P10 SCOM address class
> +///
> +/// HWP HW Maintainer: Thi Tran <thi at us.ibm.com>
> +/// HWP FW Maintainer:
> +/// HWP Consumed by: Cronus, HB, HWSV
> +///
> +
> +#ifndef P10_SCOM_ADDR_H
> +#define P10_SCOM_ADDR_H
> +
> +// includes
> +#include <stdint.h>
> +
> +extern "C"
> +{
> + /// Constants
> + const uint32_t NUM_CORES_PER_EQ = 4; // Num of cores in an EQ chiplet
> +
> + /// P10 Chiplet ID enumeration
> + typedef enum
> + {
> + PIB_CHIPLET_ID = 0x00, ///< PIB chiplet (FSI)
> + PERV_CHIPLET_ID = 0x01, ///< TP chiplet
> +
> + N0_CHIPLET_ID = 0x02, ///< Nest0 (North) chiplet
> + N1_CHIPLET_ID = 0x03, ///< Nest1 (South) chiplet
> +
> + PCI0_CHIPLET_ID = 0x08, ///< PCIe0 chiplet
> + PCI1_CHIPLET_ID = 0x09, ///< PCIe1 chiplet
> +
> + MC0_CHIPLET_ID = 0x0C, ///< MC0 chiplet
> + MC1_CHIPLET_ID = 0x0D, ///< MC1 chiplet
> + MC2_CHIPLET_ID = 0x0E, ///< MC2 chiplet
> + MC3_CHIPLET_ID = 0x0F, ///< MC3 chiplet
> +
> + PAU0_CHIPLET_ID = 0x10, ///< PAU0 chiplet
> + PAU1_CHIPLET_ID = 0x11, ///< PAU1 chiplet
> + PAU2_CHIPLET_ID = 0x12, ///< PAU2 chiplet
> + PAU3_CHIPLET_ID = 0x13, ///< PAU3 chiplet
> +
> + AXON0_CHIPLET_ID = 0x18, ///< AXON0 chiplet (high speed io)
> + AXON1_CHIPLET_ID = 0x19, ///< AXON1 chiplet (high speed io)
> + AXON2_CHIPLET_ID = 0x1A, ///< AXON2 chiplet (high speed io)
> + AXON3_CHIPLET_ID = 0x1B, ///< AXON3 chiplet (high speed io)
> + AXON4_CHIPLET_ID = 0x1C, ///< AXON4 chiplet (high speed io)
> + AXON5_CHIPLET_ID = 0x1D, ///< AXON5 chiplet (high speed io)
> + AXON6_CHIPLET_ID = 0x1E, ///< AXON6 chiplet (high speed io)
> + AXON7_CHIPLET_ID = 0x1F, ///< AXON7 chiplet (high speed io)
> +
> + EQ0_CHIPLET_ID = 0x20, ///< Quad0 chiplet (super chiplet)
> + EQ1_CHIPLET_ID = 0x21, ///< Quad1 chiplet (super chiplet)
> + EQ2_CHIPLET_ID = 0x22, ///< Quad2 chiplet (super chiplet)
> + EQ3_CHIPLET_ID = 0x23, ///< Quad3 chiplet (super chiplet)
> + EQ4_CHIPLET_ID = 0x24, ///< Quad4 chiplet (super chiplet)
> + EQ5_CHIPLET_ID = 0x25, ///< Quad5 chiplet (super chiplet)
> + EQ6_CHIPLET_ID = 0x26, ///< Quad6 chiplet (super chiplet)
> + EQ7_CHIPLET_ID = 0x27, ///< Quad7 chiplet (super chiplet)
> + } p10ChipletId_t;
> +
> + /// P10 SCOM Endpoint ID enumeration
> + typedef enum
> + {
> + CHIPLET_CTRL_ENDPOINT = 0x0, ///< Chiplet Control
> + PSCOM_ENDPOINT = 0x1, ///< EQ:PSCOM (L3), others: PSCOM
> + PSCOM_2_ENDPOINT = 0x2, ///< EQ:PSCOM (Core/L2), TP:ITR, Nest:TOD (Time Of Day)
> + CLOCK_CTRL_ENDPOINT = 0x3, ///< Clock controller
> + FIR_ENDPOINT = 0x4, ///< FIR
> + THERMAL_ENDPOINT = 0x5, ///< Thermal
> + DPLL_ENDPOINT = 0x6, ///< TP (only): DPLL
> + QME_ENDPOINT = 0xE, ///< EQ (only): QME
> + PCBSLV_ENDPOINT = 0xF, ///< PCB Slave registers
> + } p10EndpointID_t;
> +
> + /// P10 region select (CoreId/One-hot)
> + typedef enum
> + {
> + EQ_REGION_SEL = 0x0,
> + MULTI_HOT_SELECT_C0 = 0x8,
> + MULTI_HOT_SELECT_C1 = 0x4,
> + MULTI_HOT_SELECT_C2 = 0x2,
> + MULTI_HOT_SELECT_C3 = 0x1,
> + } p10RegionSelect_t;
> +
> + /// *************************************
> + /// Ring ID enums
> + /// *************************************
> +
> + /// P10 N0 chiplet ring ID enumeration
> + typedef enum
> + {
> + N0_MM0_RING_ID = 0x3,
> + N0_PE1_RING_ID = 0x6,
> + } p10_N0_RingId_t;
> +
> + /// P10 N1 chiplet ring ID enumeration
> + /// source: tpc_p10_n1_top.vhdl
> + typedef enum
> + {
> + N1_MM1_RING_ID = 0x3,
> + N1_PE0_RING_ID = 0x6,
> + } p10_N1_RingId_t;
> +
> + /// P10 PCIe chiplet SCOM ring ID enumeration
> + typedef enum
> + {
> + PCI_RING_ID = 0x2,
> + IO_PCI0_RING_ID = 0x4,
> + IO_PCI1_RING_ID = 0x5,
> + } p10_PCI_RingId_t;
> +
> + /// P10 PERV chiplet and PSCOM ring ID enumeration
> + typedef enum
> + {
> + PSCOM_RING_ID = 0x0,
> + PERV_RING_ID = 0x1,
> + } p10_PSCOM_PERV_RingId_t;
> +
> + /// P10 AXONE chiplet ring ID enumeration
> + typedef enum
> + {
> + AXONE_PDL_RING_ID = 0x4,
> + } p10_AXONE_RingId_t;
> +
> + /// P10 PAU chiplet ring ID enumeration
> + typedef enum
> + {
> + PAU0346_0_RING_ID = 0x2,
> + PAU0346_1_RING_ID = 0x3,
> + PAU57_0_RING_ID = 0x4,
> + PAU57_1_RING_ID = 0x5,
> + PAU_TL_RING_ID = 0x6,
> + PAU_IOPPE_RING_ID = 0xB,
> + } p10_PAU_RingId_t;
> +
> + /// P10 MC chiplet ring ID enumeration
> + typedef enum
> + {
> + MC_0_RING_ID = 0x3,
> + MC_1_RING_ID = 0x4,
> + OMI0_RING_ID = 0x5,
> + OMI1_RING_ID = 0x6,
> + } p10_MC_RingId_t;
> +
> + /// P10 EQ chiplet ring ID enumeration
> + typedef enum
> + {
> + QME_RING_ID = 0x2,
> + L3_RING_ID = 0x3,
> + } p10_EQ_PSCOM_RingId_t;
> +
> + typedef enum
> + {
> + L2_RING_ID = 0x0,
> + C_0_RING_ID = 0x2,
> + C_1_RING_ID = 0x3,
> + C_3_RING_ID = 0x5,
> + } p10_EQ_PSCOM2_RingId_t;
> +
> + /// -----------------------
> + /// Satellite ID defintions
> + /// -----------------------
> + typedef enum
> + {
> + NMMU_SAT_ID0 = 0x0,
> + NMMU_SAT_ID1 = 0x1,
> + } p10_NMMU_SatId_t;
> +
> + typedef enum
> + {
> + PEC_SAT_ID = 0x0,
> + PHB0_AIB_SAT_ID = 0x1,
> + PHB1_AIB_SAT_ID = 0x2,
> + PHB2_AIB_SAT_ID = 0x3,
> + PHB0_PHB_SAT_ID = 0x4,
> + PHB1_PHB_SAT_ID = 0x5,
> + PHB2_PHB_SAT_ID = 0x6,
> + } p10_PCI_SatId_t;
> +
> + typedef enum
> + {
> + MC_SAT_ID0 = 0x0,
> + MC_SAT_ID4 = 0x4,
> + MC_SAT_ID5 = 0x5,
> + MC_SAT_ID8 = 0x8,
> + MC_SAT_ID9 = 0x9,
> + MC_SAT_ID12 = 0xC,
> + MC_SAT_ID13 = 0xD,
> + MC_SAT_ID14 = 0xE,
> + MC_SAT_ID15 = 0xF,
> + } p10_MC_SatId_t;
> +
> + typedef enum
> + {
> + PPE_SAT_ID0 = 0x0,
> + TL_SAT_ID = 0x0,
> + PPE_SAT_ID1 = 0x1,
> + } p10_PAU_SatId_t;
> +
> + typedef enum
> + {
> + DLP_SAT_ID = 0x0,
> + } p10_AXONE_SatId_t;
> +
> + /// *************************************
> + /// Perv target table
> + /// *************************************
> + const p10ChipletId_t PervTargetChipletIdTable[] =
> + {
> + PIB_CHIPLET_ID,
> + PERV_CHIPLET_ID,
> + N0_CHIPLET_ID,
> + N1_CHIPLET_ID,
> + PCI0_CHIPLET_ID,
> + PCI1_CHIPLET_ID,
> + MC0_CHIPLET_ID,
> + MC1_CHIPLET_ID,
> + MC2_CHIPLET_ID,
> + MC3_CHIPLET_ID,
> + PAU0_CHIPLET_ID,
> + PAU1_CHIPLET_ID,
> + PAU2_CHIPLET_ID,
> + PAU3_CHIPLET_ID,
> + AXON0_CHIPLET_ID,
> + AXON1_CHIPLET_ID,
> + AXON2_CHIPLET_ID,
> + AXON3_CHIPLET_ID,
> + AXON4_CHIPLET_ID,
> + AXON5_CHIPLET_ID,
> + AXON6_CHIPLET_ID,
> + AXON7_CHIPLET_ID,
> + EQ0_CHIPLET_ID,
> + EQ1_CHIPLET_ID,
> + EQ2_CHIPLET_ID,
> + EQ3_CHIPLET_ID,
> + EQ4_CHIPLET_ID,
> + EQ5_CHIPLET_ID,
> + EQ6_CHIPLET_ID,
> + EQ7_CHIPLET_ID,
> + };
> +
> +// ----------------------
> +// For non-EQ chiplets
> +// ----------------------
> +// 8 7 6 5 4 3 2 1
> +//
> +// |0 1 2 3| |4 5 6 7| |8 9 10 11| |12 13 14 15| |16 17 18 19| |20 21 22 23| |24 25 26 27| |28 29 30 31|
> +// {A}{ B } { C } 0 0 { D } { E } { F }
> +//
> +// A - Is multiCast if bit 1 = 0x1
> +// B - Chiplet ID (6 bits) [2:7]
> +// C - Endpoint ID (4 bits) [12:15]
> +// D - Ring (4 bits) [18:21]
> +// E - Sat ID (4 bits) [22:25]
> +// F - Sat Offset (6 bits) [26:31]
> +
> +// ----------------------
> +// For EQ/Core chiplets
> +// ----------------------
> +// 8 7 6 5 4 3 2 1
> +//
> +// |0 1 2 3| |4 5 6 7| |8 9 10 11| |12 13 14 15| |16 17 18 19| |20 21 22 23| |24 25 26 27| |28 29 30 31|
> +// {A}{ B } { C } { D } E F { G } { H }
> +//
> +// A - Is multiCast if bit 1 = 0x1
> +// B - Chiplet ID (6 bits) [2:7]
> +// C - Endpoint ID (4 bits) [12:15]
> +// D - Region select (4 bits) [16:19]
> +// E - QME per core (1 bit) [20]
> +// F - QME Sat Enable (1 bit) [21]
> +// G - QME Sat sel (2 bits) [22:23]
> +// H - QME reg (8 bits) [24:31]
> +
> + /// P10 SCOM address class
> + class p10_scom_addr
> + {
> + public:
> +
> + /// @brief Construct a SCOM address object
> + /// @param[in] i_addr 64-bit raw SCOM address
> + p10_scom_addr(const uint64_t i_addr)
> + : iv_addr(i_addr)
> + {
> + }
> +
> + /// @brief Set full/raw SCOM address
> + /// @param[in] i_addr 64-bit SCOM address
> + /// @retval none
> + inline void setAddr(const uint64_t i_addr)
> + {
> + iv_addr = i_addr;
> + return;
> + }
> +
> + /// @brief Retrieve full/raw SCOM address
> + /// @retval uint64_t 64-bit SCOM address
> + inline uint64_t getAddr() const
> + {
> + return (iv_addr);
> + }
> +
> + /// @brief Determine if SCOM address is direct-form (bit 0)
> + /// @retval bool True if SCOM address is direct-form, false otherwise
> + inline bool isDirect() const
> + {
> + return (((iv_addr >> 63) & 0x1) == 0x0);
> + }
> +
> + /// @brief Determine if SCOM address is indirect-form
> + /// @retval bool True if SCOM address is indirect-form, false otherwise
> + inline bool isIndirect() const
> + {
> + return (!isDirect());
> + }
> +
> + /// @brief Determine if SCOM address is multicast (bit 1)
> + /// @retval bool True if SCOM address is multicast, false otherwise
> + inline bool isMulticast() const
> + {
> + return (((iv_addr >> 30) & 0x1) == 0x1);
> + }
> +
> + /// @brief Determine if SCOM address is unicast
> + /// @retval bool True if SCOM address is unicast, false otherwise
> + inline bool isUnicast() const
> + {
> + return (!(isMulticast()));
> + }
> +
> + /// @brief Extract pervasive chiplet ID from SCOM address (bits 2:7)
> + /// @retval uint8_t Pervasive chiplet ID value
> + inline uint8_t getChipletId() const
> + {
> + return ((iv_addr >> 24) & 0x3F);
> + }
> +
> + /// @brief Modify SCOM address, update pervasive chiplet ID
> + /// @param[in] i_chiplet_id Chiplet ID value to write
> + /// @retval none
> + inline void setChipletId(const uint8_t i_chiplet_id)
> + {
> + iv_addr &= 0xFFFFFFFFC0FFFFFFULL;
> + iv_addr |= ((i_chiplet_id & 0x3F) << 24);
> + return;
> + }
> +
> + /// @brief Extract Endpoint field from SCOM address (bits 12:15)
> + /// @retval uint8_t Endpoint field value
> + inline uint8_t getEndpoint() const
> + {
> + return ((iv_addr >> 16) & 0xF);
> + }
> +
> + /// @brief Modify the Endpoint field from SCOM address
> + /// @retval none
> + inline void setEndpoint(const uint8_t i_port)
> + {
> + iv_addr &= 0xFFFFFFFFFFF0FFFFULL;
> + iv_addr |= ((i_port & 0xF) << 16);
> + return;
> + }
> +
> + /// @brief Extract region select field (core id) from SCOM address (bits 16:19)
> + /// @retval uint8_t Region select value
> + inline uint8_t getRegionSelect() const
> + {
> + return ((iv_addr >> 12) & 0xF);
> + }
> +
> + /// @brief Modify the region select field (core id) from SCOM address
> + /// @retval none
> + inline void setRegionSelect(const uint8_t i_regionSelect)
> + {
> + iv_addr &= 0xFFFFFFFFFFFF0FFFULL;
> + iv_addr |= ((i_regionSelect & 0xF) << 12);
> + return;
> + }
> +
> + /// @brief Extract ring field from SCOM address (bits 18:21)
> + /// @retval uint8_t Ring id value
> + inline uint8_t getRingId() const
> + {
> + return ((iv_addr >> 10) & 0xF);
> + }
> +
> + /// @brief Extract EQ ring field from SCOM address (bits 20:22)
> + /// @retval uint8_t Ring id value
> + inline uint8_t getEQRingId() const
> + {
> + return ((iv_addr >> 9) & 0x7);
> + }
> +
> + /// @brief Modify SCOM address, update ring field value
> + /// @param[in] i_ring Ring field value to write
> + /// @retval none
> + inline void setRingId(const uint8_t i_ring)
> + {
> + iv_addr &= 0xFFFFFFFFFFFF03FFULL;
> + iv_addr |= ((i_ring & 0x3F) << 10);
> + return;
> + }
> +
> + /// @brief Extract satellite ID field from SCOM address (bits 22:25)
> + /// @retval uint8_t Satellite ID field value
> + inline uint8_t getSatId() const
> + {
> + return ((iv_addr >> 6) & 0xF);
> + }
> +
> + /// @brief Extract EQ satellite ID field from SCOM address (bits 23:25)
> + /// @retval uint8_t Ring id value
> + inline uint8_t getEQSatId() const
> + {
> + return ((iv_addr >> 6) & 0x7);
> + }
> +
> + /// @brief Modify SCOM address, update satellite ID field
> + /// @param[in] i_sat_id Satellite ID value to write
> + /// @retval none
> + inline void setSatId(const uint8_t i_satId)
> + {
> + iv_addr &= 0xFFFFFFFFFFFFFC3FULL;
> + iv_addr |= ((i_satId & 0xF) << 6);
> + return;
> + }
> +
> + /// @brief Extract satellite register offset field from SCOM address (bits 26:31)
> + /// @retval uint8_t Satellite register offset field value
> + inline uint8_t getSatOffset() const
> + {
> + return (iv_addr & 0x3F);
> + }
> +
> + /// @brief Modify SCOM address, update satellite offset field
> + /// @param[in] i_sat_offset Satellite offset value to write
> + /// @retval none
> + inline void setSatOffset(const uint8_t i_sat_offset)
> + {
> + iv_addr &= 0xFFFFFFFFFFFFFFC0ULL;
> + iv_addr |= (i_sat_offset & 0x3F);
> + return;
> + }
> +
> + /// @brief Get the OBUS Super Wrapper Group address (bits 22:26) of
> + /// an indirect scom address
> + /// @retval uint8_t Group address
> + inline uint8_t getIoGroupAddr() const
> + {
> + return ((iv_addr >> 37) & 0x1F);
> + }
> +
> + /// @brief Set the OBUS Super Wrapper Group address (bits 22:26) of
> + /// an indirect scom address
> + /// @param[in] i_group_addr Group address value to write
> + /// @retval none
> + inline void setIoGroupAddr(const uint8_t i_group_addr)
> + {
> + iv_addr &= 0xFFFFFC1FFFFFFFFFULL;
> + iv_addr |= ( ((uint64_t)i_group_addr & 0x1F) << 37 );
> + return;
> + }
> +
> + /// @brief Get Super Wrapper Register address (bits 12:20)
> + /// of an indirect scom address
> + /// @retval uint32_t Register address
> + inline uint32_t getIoRegAddr() const
> + {
> + return ((iv_addr >> 43) & 0x1FF);
> + }
> +
> + /// @brief Get the OBUS Super Wrapper TX/RX bit (bit 21)
> + /// of an indirect scom address
> + /// @retval uint8_t TX/RX bit
> + inline uint32_t getIoTxRxBit() const
> + {
> + return ((iv_addr >> 42) & 0x1);
> + }
> +
> + /// @brief Get the OBUS Super Wrapper Lane (bits 27:31)
> + /// of an indirect scom address
> + /// @retval uint8_t Lane
> + inline uint32_t getIoLane() const
> + {
> + return ((iv_addr >> 32) & 0x1F);
> + }
> +
> + /// @brief Set the OBUS Super Wrapper Lane (bits 27:31)
> + /// of an indirect scom address
> + /// @retval uint8_t Lane
> + inline void setIoLane(const uint8_t i_lane)
> + {
> + iv_addr &= 0xFFFFFFE0FFFFFFFFULL;
> + iv_addr |= ( ((uint64_t)i_lane & 0x1F) << 32);
> + }
> +
> + /// IOP indirect SCOMs
> + /// IOP0.top0.pma0 (PMA0) -> 0x8000xxxx0801113f
> + /// IOP0.top0.pma1 (PMA1) -> 0x8001xxxx0801113f
> + /// IOP0.top1.pma0 (PMA2) -> 0x8000xxxx0801153f
> + /// IOP0.top1.pma1 (PMA3) -> 0x8001xxxx0801153f
> + /// IOP1.top0.pma0 (PMA0) -> 0x8000xxxx0901113f
> + /// IOP1.top0.pma1 (PMA1) -> 0x8001xxxx0901113f
> + /// IOP1.top1.pma0 (PMA2) -> 0x8000xxxx0901153f
> + /// IOP1.top1.pma1 (PMA3) -> 0x8001xxxx0901153f
> +
> + /// @brief Get PEC IOP Control Register value (bits 12:31) from
> + /// an indirect scom address
> + /// @retval uint32_t CR register
> + inline uint32_t getIopIndCRreg() const
> + {
> + return ((iv_addr >> 32) & 0xFFFFF);
> + }
> +
> + /// @brief Get IOP TOP value (bit 53) from an indirect scom address
> + /// @retval uint8_t Top value (0 or 1)
> + inline uint8_t getIopTop() const
> + {
> + return ((iv_addr >> 10) & 0x1);
> + }
> +
> + /// @brief Get PMA value (bit 15) from an indirect scom address
> + /// @retval uint8_t Top value (0 or 1)
> + inline uint8_t getPMA() const
> + {
> + return ( ((iv_addr >> 48) & 0x1) + (getIopTop() * 2) );
> + }
> +
> + /// @brief Determine if SCOM address is valid/well-formed
> + /// @retval bool True if SCOM address is valid, false otherwise
> + inline bool isValid() const
> + {
> + return true;
> + }
> +
> + /// @brief Determine if this address belongs to EQ target type
> + /// @retval true or false.
> + bool isEqTarget();
> +
> + /// @brief Determine the EQ instance for this address
> + /// Function prereq: Address must belong to EQ target type
> + /// @retval uint8_t EQ target instance
> + uint8_t getEqTargetInstance();
> +
> + /// @brief Determine if this address belongs to core target type
> + /// @retval true or false.
> + bool isCoreTarget();
> +
> + /// @brief Determine the core instance for this address.
> + /// Function prereq: Address must belong to core target type
> + /// @retval uint8_t Core target instance
> + uint8_t getCoreTargetInstance();
> +
> + /// @brief Determine if this address belongs to PEC target type
> + /// @retval true or false.
> + bool isPecTarget();
> +
> + /// @brief Determine the pec instance for this address
> + /// Function prereq: Address must belong to PEC target type
> + /// @retval uint8_t PEC target instance
> + uint8_t getPecTargetInstance();
> +
> + /// @brief Determine if this address belongs to PHB target type
> + /// @retval true or false.
> + bool isPhbTarget();
> +
> + /// @brief Determine the PHB instance for this address
> + /// Function prereq: Address must belong to PHB target type
> + /// @retval uint8_t PHB target instance
> + uint8_t getPhbTargetInstance();
> +
> + /// @brief Determine if this address belongs to NMMU target type
> + /// @retval true or false.
> + bool isNmmuTarget();
> +
> + /// @brief Determine the NMMU instance for this address
> + /// Function prereq: Address must belong to NMMU target type
> + /// @retval uint8_t NMMU target instance
> + uint8_t getNmmuTargetInstance();
> +
> + /// @brief Get the QME Per Core value (bit 20, EQ/Core only)
> + /// Function prereq: Address must belong to EQ or Core target type
> + /// @retval uint8_t QME Per Core value
> + inline uint8_t getQMEPerCore()
> + {
> + return (iv_addr >> 11) & 0x1;
> + }
> +
> + /// @brief Get the QME Sat Enable value (bit 21, EQ/Core only)
> + /// Function prereq: Address must belong to EQ or Core target type
> + /// @retval uint8_t QME Sat Enable value
> + inline uint8_t getQMESatEn()
> + {
> + return (iv_addr >> 10) & 0x1;
> + }
> +
> + /// @brief Get the QME Sat Select value (bit 22:23, EQ/Core only)
> + /// Function prereq: Address must belong to EQ or Core target type
> + /// @retval uint8_t QME Sat Sel value
> + inline uint8_t getQMESatSel()
> + {
> + return (iv_addr >> 8) & 0x3;
> + }
> +
> + /// @brief Get the QME reg value (bit 24:31, EQ/Core only)
> + /// Function prereq: Address must belong to EQ or Core target type
> + /// @retval uint8_t QME reg value
> + inline uint8_t getQMEReg()
> + {
> + return (iv_addr & 0xFF);
> + }
> +
> + /// @brief Determine if this address belongs to PERV target type
> + /// @retval true or false.
> + bool isPervTarget();
> +
> + /// @brief Determine the PERV instance for this address
> + /// Function prereq: Address must belong to PERV target type
> + /// @retval uint8_t PERV target instance.
> + uint8_t getPervTargetInstance();
> +
> + /// @brief Determine if this address belongs to IOHS target type
> + /// @retval true or false.
> + bool isIoHsTarget();
> +
> + /// @brief Determine the IOHS instance for this address
> + /// Function prereq: Address must belong to IOHS target type
> + /// @retval uint8_t IOHS target instance.
> + uint8_t getIoHsTargetInstance();
> +
> + /// @brief Determine if this address belongs to PAU target type
> + /// @retval true or false.
> + bool isPauTarget();
> +
> + /// @brief Determine the PAU instance for this address
> + /// Function prereq: Address must belong to PAU target type
> + /// @retval uint8_t PAU target instance.
> + uint8_t getPauTargetInstance();
> +
> + /// @brief Determine if this address belongs to MC target type
> + /// @retval true or false.
> + bool isMcTarget();
> +
> + /// @brief Determine the MC instance for this address
> + /// Function prereq: Address must belong to MI target type
> + /// @retval uint8_t MC target instance.
> + uint8_t getMcTargetInstance();
> +
> + /// @brief Determine if this address belongs to MI target type
> + /// @retval true or false.
> + bool isMiTarget();
> +
> + /// @brief Determine the MI instance for this address
> + /// Function prereq: Address must belong to MI target type
> + /// @retval uint8_t MI target instance.
> + uint8_t getMiTargetInstance();
> +
> + /// @brief Determine if this address belongs to MCC target type
> + /// @retval true or false.
> + bool isMccTarget();
> +
> + /// @brief Determine the MCC instance for this address
> + /// Function prereq: Address must belong to MCC target type
> + /// @retval uint8_t MCC target instance.
> + uint8_t getMccTargetInstance();
> +
> + /// @brief Determine if this address belongs to OMI target type
> + /// @retval true or false.
> + bool isOmiTarget();
> +
> + /// @brief Determine the OMI instance for this address
> + /// Function prereq: Address must belong to OMI target type
> + /// @retval uint8_t OMI target instance.
> + uint8_t getOmiTargetInstance();
> +
> + /// @brief Determine if this address belongs to OMIC target type
> + /// @retval true or false.
> + bool isOmicTarget();
> +
> + /// @brief Determine the OMIC instance for this address
> + /// Function prereq: Address must belong to OMIC target type
> + /// @retval uint8_t OMIC target instance.
> + uint8_t getOmicTargetInstance();
> +
> + /// @brief Determine if this address belongs to PAUC target type
> + /// @retval true or false.
> + bool isPaucTarget();
> +
> + /// @brief Determine the PAUC instance for this address
> + /// Function prereq: Address must belong to PAUC target type
> + /// @retval uint8_t PAUC target instance.
> + uint8_t getPaucTargetInstance();
> +
> + private:
> + uint64_t iv_addr; ///< 64-bit raw SCOM address
> + };
> +
> +} // extern "C"
> +
> +#endif /* P10_SCOM_ADDR_H */
> diff --git a/src/tests/p10_scominfo.C b/src/tests/p10_scominfo.C
> new file mode 100644
> index 0000000..25c294a
> --- /dev/null
> +++ b/src/tests/p10_scominfo.C
> @@ -0,0 +1,856 @@
> +/* IBM_PROLOG_BEGIN_TAG */
> +/* This is an automatically generated prolog. */
> +/* */
> +/* $Source: chips/p10/common/scominfo/p10_scominfo.C $ */
> +/* */
> +/* IBM CONFIDENTIAL */
> +/* */
> +/* EKB Project */
> +/* */
> +/* COPYRIGHT 2018,2019 */
> +/* [+] International Business Machines Corp. */
> +/* */
> +/* */
> +/* The source code for this program is not published or otherwise */
> +/* divested of its trade secrets, irrespective of what has been */
> +/* deposited with the U.S. Copyright Office. */
> +/* */
> +/* IBM_PROLOG_END_TAG */
> +///
> +/// @file p10_scominfo.C
> +/// @brief P10 chip unit SCOM address platform translation code
> +///
> +/// HWP HW Maintainer: Thi Tran <thi at us.ibm.com>
> +/// HWP FW Maintainer:
> +/// HWP Consumed by: Cronus, HB, HWSV
> +///
> +
> +// includes
> +#include "p10_scominfo.H"
> +#include "p10_scom_addr.H"
> +
> +#define P10_SCOMINFO_C
> +
> +extern "C"
> +{
> +
> + // ---------------------------
> + // Internal functions
> + // ---------------------------
> +
> + //################################################################################
> + /// @brief Calculate the region select (core ID) value for given core
> + /// instance
> + /// @param[in] i_coreInstance Core instance number (0-31)
> + /// @retval uint8_t Region select value
> + uint8_t calcRegionSelect(uint8_t i_coreInstanceNum)
> + {
> + uint8_t l_regionSel = 0;
> +
> + if (i_coreInstanceNum % NUM_CORES_PER_EQ == 0)
> + {
> + l_regionSel = 8;
> + }
> + else if (i_coreInstanceNum % NUM_CORES_PER_EQ == 1)
> + {
> + l_regionSel = 4;
> + }
> + else if (i_coreInstanceNum % NUM_CORES_PER_EQ == 2)
> + {
> + l_regionSel = 2;
> + }
> + else
> + {
> + l_regionSel = 1;
> + }
> +
> + return l_regionSel;
> + }
> +
> + //################################################################################
> + /// @brief Get the chiplet ID for a chip unit instance based on given
> + /// address and chip unit type
> + /// @param[in] i_addr SCOM address
> + /// @param[in] i_chipUnitNum Instance number
> + /// @param[in] i_chipUnitType Chip unit type
> + /// @param[out] o_chipletId Output chiplet id
> + /// @retval Non-zero if error
> + uint8_t getChipletId(const uint64_t i_addr,
> + const uint8_t i_chipUnitNum,
> + const p10ChipUnits_t i_chipUnitType,
> + uint8_t& o_chipletId)
> + {
> + uint8_t l_rc = 0;
> +
> + do
> + {
> + p10_scom_addr l_scom(i_addr);
> +
> + switch (i_chipUnitType)
> + {
> + case PU_EQ_CHIPUNIT:
> + o_chipletId = EQ0_CHIPLET_ID + i_chipUnitNum;
> + break;
> +
> + case PU_C_CHIPUNIT:
> + o_chipletId = EQ0_CHIPLET_ID + (i_chipUnitNum / NUM_CORES_PER_EQ);
> + break;
> +
> + case PU_PEC_CHIPUNIT:
> +
> + // If input address is of Nest chiplets
> + if ( (l_scom.getChipletId() >= N0_CHIPLET_ID) &&
> + (l_scom.getChipletId() <= N1_CHIPLET_ID) )
> + {
> + o_chipletId = ((i_chipUnitNum) ? (N0_CHIPLET_ID) : (N1_CHIPLET_ID));
> + }
> + // If input address is of PCI chiplets
> + else
> + {
> + o_chipletId = PCI0_CHIPLET_ID + i_chipUnitNum;
> + }
> +
> + break;
> +
> + case PU_PHB_CHIPUNIT:
> +
> + // If input address is of Nest chiplets
> + if ( (l_scom.getChipletId() >= N0_CHIPLET_ID) &&
> + (l_scom.getChipletId() <= N1_CHIPLET_ID) )
> + {
> + o_chipletId = ((i_chipUnitNum / 3) ? (N0_CHIPLET_ID) : (N1_CHIPLET_ID));
> + }
> + // If input address is of PCI chiplets
> + else
> + {
> + o_chipletId = (i_chipUnitNum / 3) + PCI0_CHIPLET_ID;
> + }
> +
> + break;
> +
> + case PU_NMMU_CHIPUNIT:
> + o_chipletId = i_chipUnitNum + N0_CHIPLET_ID;
> + break;
> +
> + case PU_PERV_CHIPUNIT:
> + o_chipletId = i_chipUnitNum;
> + break;
> +
> + case PU_IOHS_CHIPUNIT:
> +
> + // If input address is of AXON chiplets
> + if ( (l_scom.getChipletId() >= AXON0_CHIPLET_ID) && // 0x18
> + (l_scom.getChipletId() <= AXON7_CHIPLET_ID) ) // 0x1F
> + {
> + o_chipletId = AXON0_CHIPLET_ID + i_chipUnitNum;
> + }
> + else if ( (l_scom.getChipletId() >= PAU0_CHIPLET_ID) &&
> + (l_scom.getChipletId() <= PAU3_CHIPLET_ID) )
> + {
> + // PAU0 --> IOHS0, IOHS1
> + // PAU1 --> IOHS2, IOHS3
> + // PAU2 --> IOHS4, IOHS5
> + // PAU3 --> IOHS6, IOHS7
> + o_chipletId = (i_chipUnitNum / 2) + PAU0_CHIPLET_ID;
> + }
> + else
> + {
> + l_rc = 1;
> + }
> +
> + break;
> +
> + case PU_MI_CHIPUNIT:
> + case PU_MC_CHIPUNIT:
> + o_chipletId = i_chipUnitNum + MC0_CHIPLET_ID;
> + break;
> +
> + case PU_MCC_CHIPUNIT:
> + o_chipletId = (i_chipUnitNum / 2) + MC0_CHIPLET_ID;
> + break;
> +
> + case PU_OMIC_CHIPUNIT:
> +
> + // PAU indirect
> + if ( (l_scom.getChipletId() >= PAU0_CHIPLET_ID) && // 0x10
> + (l_scom.getChipletId() <= PAU3_CHIPLET_ID) ) // 0x13
> + {
> + // PAU0 --> OMIC 0/1
> + // PAU1 --> OMIC 4/5
> + // PAU2 --> OMIC 2/3
> + // PAU3 --> OMIC 6/7
> + if (i_chipUnitNum >= 0 && i_chipUnitNum <= 1)
> + {
> + o_chipletId = PAU0_CHIPLET_ID;
> + }
> + else if (i_chipUnitNum >= 2 && i_chipUnitNum <= 3)
> + {
> + o_chipletId = PAU2_CHIPLET_ID;
> + }
> + else if (i_chipUnitNum >= 4 && i_chipUnitNum <= 5)
> + {
> + o_chipletId = PAU1_CHIPLET_ID;
> + }
> + else if (i_chipUnitNum >= 6 && i_chipUnitNum <= 7)
> + {
> + o_chipletId = PAU3_CHIPLET_ID;
> + }
> + else
> + {
> + l_rc = 1;
> + }
> + }
> + // MC direct
> + else
> + {
> + o_chipletId = (i_chipUnitNum / 2) + MC0_CHIPLET_ID;
> + }
> +
> + break;
> +
> + case PU_OMI_CHIPUNIT:
> +
> + // PAU indirect
> + if ( (l_scom.getChipletId() >= PAU0_CHIPLET_ID) && // 0x10
> + (l_scom.getChipletId() <= PAU3_CHIPLET_ID) ) // 0x13
> + {
> + // PAU0 --> OMI 0/1/2/3
> + // PAU1 --> OMI 8/9/10/11
> + // PAU2 --> OMI 4/5/6/7
> + // PAU3 --> OMI 12/13/14/15
> + if (i_chipUnitNum >= 0 && i_chipUnitNum <= 3)
> + {
> + o_chipletId = PAU0_CHIPLET_ID;
> + }
> + else if (i_chipUnitNum >= 4 && i_chipUnitNum <= 7)
> + {
> + o_chipletId = PAU2_CHIPLET_ID;
> + }
> + else if (i_chipUnitNum >= 8 && i_chipUnitNum <= 11)
> + {
> + o_chipletId = PAU1_CHIPLET_ID;
> + }
> + else if (i_chipUnitNum >= 12 && i_chipUnitNum <= 15)
> + {
> + o_chipletId = PAU3_CHIPLET_ID;
> + }
> + else
> + {
> + l_rc = 1;
> + }
> + }
> + // MC direct
> + else
> + {
> + o_chipletId = (i_chipUnitNum / 4) + MC0_CHIPLET_ID;
> + }
> +
> + break;
> +
> + case PU_PAUC_CHIPUNIT:
> + o_chipletId = i_chipUnitNum + PAU0_CHIPLET_ID;
> + break;
> +
> + case PU_PAU_CHIPUNIT:
> + o_chipletId = (i_chipUnitNum / 2) + PAU0_CHIPLET_ID;
> + break;
> +
> + default:
> + l_rc = 1;
> + break;
> + };
> +
> + }
> + while (0);
> +
> + return (l_rc);
> + }
> +
> + // See header file for function description
> + uint64_t p10_scominfo_createChipUnitScomAddr(
> + const p10ChipUnits_t i_p10CU,
> + const uint8_t i_ecLevel,
> + const uint8_t i_chipUnitNum,
> + const uint64_t i_scomAddr,
> + const uint32_t i_mode)
> + {
> + uint8_t l_rc = 0;
> + p10_scom_addr l_scom(i_scomAddr);
> + uint8_t l_chipletId = 0;
> +
> + do
> + {
> + // Make sure i_chipUnitNum is within range
> + l_rc = validateChipUnitNum(i_chipUnitNum, i_p10CU);
> +
> + if (l_rc)
> + {
> + break;
> + }
> +
> + // If chip unit type is a chip, return input address
> + if (i_p10CU == P10_NO_CU)
> + {
> + l_scom.setAddr(i_scomAddr);
> + break;
> + }
> +
> + // Set the chiplet ID
> + l_rc = getChipletId(i_scomAddr, i_chipUnitNum, i_p10CU, l_chipletId);
> +
> + if (l_rc)
> + {
> + break;
> + }
> +
> + l_scom.setChipletId(l_chipletId);
> +
> + // Set other address fields (ringId, satId, etc...)
> + // for Chip unit types that are needed.
> + switch (i_p10CU)
> + {
> + case PU_C_CHIPUNIT:
> + // Set the core's region select (core ID)
> + l_scom.setRegionSelect(calcRegionSelect(i_chipUnitNum));
> + break;
> +
> + case PU_PHB_CHIPUNIT:
> +
> + // If input address is of Nest chiplets
> + if ( (l_scom.getChipletId() >= N0_CHIPLET_ID) &&
> + (l_scom.getChipletId() <= N1_CHIPLET_ID) )
> + {
> + l_scom.setSatId(1 + (i_chipUnitNum % 3));
> + }
> + // If input address is of PCI chiplets
> + else
> + {
> + if (l_scom.getRingId() == 2)
> + {
> + if ((l_scom.getSatId() >= 1) &&
> + (l_scom.getSatId() <= 3))
> + {
> + l_scom.setSatId(1 + (i_chipUnitNum % 3));
> + }
> + else
> + {
> + l_scom.setSatId(4 + (i_chipUnitNum % 3));
> + }
> + }
> + }
> +
> + break;
> +
> + case PU_MCC_CHIPUNIT:
> +
> + // Set Sat ID
> + if (i_chipUnitNum % 2)
> + {
> + uint8_t l_offset = l_scom.getSatOffset();
> +
> + // MCC Sat ID
> + // For odd MCC instance, Sat Id is to be set to 5, or 9
> + // If input address is an even instance that has:
> + // SatId = 0x4 --> set translated SatId to 0x5
> + // = 0x8 --> set translated SatId to 0x9
> + // If input address is an odd instance, leave the SatId
> + // as input address.
> + if (l_scom.getSatId() == 0x4)
> + {
> + l_scom.setSatId(0x5);
> + }
> + else if (l_scom.getSatId() == 0x8)
> + {
> + l_scom.setSatId(0x9);
> + }
> + // PBI Sat ID
> + else if (l_scom.getSatId() == 0x0)
> + {
> + if ((l_offset >= 0x22) &&
> + (l_offset <= 0x2B))
> + {
> + l_scom.setSatOffset(l_offset + 0x10);
> + }
> + }
> + // MCBIST Sat ID
> + else if (l_scom.getSatId() == 0xD)
> + {
> + if ((l_offset >= 0x00) &&
> + (l_offset <= 0x1F))
> + {
> + l_scom.setSatOffset(l_offset + 0x20);
> + }
> + }
> + }
> + else
> + {
> + uint8_t l_offset = l_scom.getSatOffset();
> +
> + // For even MCC instance, Sat Id is to be set to 4, or 8
> + // If input address is an odd instance that has:
> + // SatId = 0x5 --> set translated SatId to 0x4
> + // = 0x9 --> set translated SatId to 0x8
> + // If input address is an even instance, leave the SatId
> + // as input address.
> + if (l_scom.getSatId() == 0x5)
> + {
> + l_scom.setSatId(0x4);
> + }
> + else if (l_scom.getSatId() == 0x9)
> + {
> + l_scom.setSatId(0x8);
> + }
> + // PBI Sat ID
> + else if (l_scom.getSatId() == 0x0)
> + {
> + if ((l_offset >= 0x32) &&
> + (l_offset <= 0x3B))
> + {
> + l_scom.setSatOffset(l_offset - 0x10);
> + }
> + }
> + // MCBIST Sat ID
> + else if (l_scom.getSatId() == 0xD)
> + {
> + if ((l_offset >= 0x20) &&
> + (l_offset <= 0x3F))
> + {
> + l_scom.setSatOffset(l_offset - 0x20);
> + }
> + }
> + }
> +
> + break;
> +
> +
> + case PU_IOHS_CHIPUNIT:
> +
> + // PAU indirect
> + if ( (l_scom.getChipletId() >= PAU0_CHIPLET_ID) && // 0x10
> + (l_scom.getChipletId() <= PAU3_CHIPLET_ID) ) // 0x13
> + {
> + // for odd IOHS instances, set IO group = 1
> + if ( i_chipUnitNum % 2 )
> + {
> + l_scom.setIoGroupAddr(0x1);
> + }
> + // for even IOHS instances, set IO group = 0
> + else
> + {
> + l_scom.setIoGroupAddr(0x0);
> + }
> + }
> +
> + break;
> +
> + case PU_OMI_CHIPUNIT:
> +
> + // PAU indirect
> + if ( (l_scom.getChipletId() >= PAU0_CHIPLET_ID) && // 0x10
> + (l_scom.getChipletId() <= PAU3_CHIPLET_ID) ) // 0x13
> + {
> + // for odd OMI instances, set IO lane between 8-15
> + if ( i_chipUnitNum % 2 )
> + {
> + l_scom.setIoLane(8 + (l_scom.getIoLane() % 8));
> + }
> + // for even OMI instances, set IO lane between 0-7
> + else
> + {
> + l_scom.setIoLane(0 + (l_scom.getIoLane() % 8));
> + }
> +
> + // for odd OMI instances after dividing by 2, set IO group = 3
> + if ( (i_chipUnitNum / 2) % 2 )
> + {
> + l_scom.setIoGroupAddr(0x3);
> + }
> + // for even OMI instances after dividing by 2, set IO group = 2
> + else
> + {
> + l_scom.setIoGroupAddr(0x2);
> + }
> + }
> + // MC direct
> + else
> + {
> + // non-PM regs
> + if ((l_scom.getSatOffset() >= 16) && (l_scom.getSatOffset() <= 47))
> + {
> + // for odd OMI instances, set sat reg ID between 32-47
> + if ( i_chipUnitNum % 2 )
> + {
> + l_scom.setSatOffset(32 + (l_scom.getSatOffset() % 16));
> + }
> + // for even OMI instances, set sat reg ID between 16-31
> + else
> + {
> + l_scom.setSatOffset(16 + (l_scom.getSatOffset() % 16));
> + }
> + }
> + // PM regs
> + else
> + {
> + // for odd OMI instances, set sat reg ID between 56-59
> + if ( i_chipUnitNum % 2 )
> + {
> + l_scom.setSatOffset(56 + (l_scom.getSatOffset() % 4));
> + }
> + // for even OMI instances, set sat reg ID between 48-51
> + else
> + {
> + l_scom.setSatOffset(48 + (l_scom.getSatOffset() % 4));
> + }
> +
> + }
> +
> + // for odd OMI instances after dividing by 2, set ring ID = 6
> + if ( (i_chipUnitNum / 2) % 2 )
> + {
> + l_scom.setRingId(0x6);
> + }
> + // for even OMI instances after dividing by 2, set ring ID = 5
> + else
> + {
> + l_scom.setRingId(0x5);
> + }
> + }
> +
> + break;
> +
> + case PU_OMIC_CHIPUNIT:
> +
> + // PAU indirect
> + if ( (l_scom.getChipletId() >= PAU0_CHIPLET_ID) && // 0x10
> + (l_scom.getChipletId() <= PAU3_CHIPLET_ID) ) // 0x13
> + {
> + if (i_chipUnitNum % 2)
> + {
> + // For odd OMIC instance, set IO group ID=3
> + l_scom.setIoGroupAddr(0x3);
> + }
> + else
> + {
> + // For even OMIC instance, set IO group ID=2
> + l_scom.setIoGroupAddr(0x2);
> + }
> + }
> + // MC direct
> + else
> + {
> + if (i_chipUnitNum % 2)
> + {
> + // For odd OMIC instance, set ring ID=6
> + l_scom.setRingId(0x6);
> + }
> + else
> + {
> + // For even OMIC instance, set ring ID=5
> + l_scom.setRingId(0x5);
> + }
> + }
> +
> + break;
> +
> + case PU_PAU_CHIPUNIT:
> +
> + // Setting RingId for instances 0, 3, 4, and 6
> + // If input address has:
> + // RingId = 0x4 --> set translated RingId to 0x2
> + // 0x5 --> set translated RingId to 0x3
> + // Leave RingId as is otherwise
> + if ( (i_chipUnitNum == 0) ||
> + (i_chipUnitNum == 3) ||
> + (i_chipUnitNum == 4) ||
> + (i_chipUnitNum == 6) )
> + {
> + if (l_scom.getRingId() == 0x4)
> + {
> + l_scom.setRingId(0x2);
> + }
> + else if (l_scom.getRingId() == 0x5)
> + {
> + l_scom.setRingId(0x3);
> + }
> + }
> +
> + // Setting RingId for instances 1, 2, 5, and 7
> + // If input address has:
> + // RingId = 0x2 --> set translated RingId to 0x4
> + // 0x3 --> set translated RingId to 0x5
> + // Leave RingId as is otherwise
> + else if ( (i_chipUnitNum == 1) ||
> + (i_chipUnitNum == 2) ||
> + (i_chipUnitNum == 5) ||
> + (i_chipUnitNum == 7) )
> + {
> + if (l_scom.getRingId() == 0x2)
> + {
> + l_scom.setRingId(0x4);
> + }
> + else if (l_scom.getRingId() == 0x3)
> + {
> + l_scom.setRingId(0x5);
> + }
> + }
> +
> + break;
> +
> + default:
> + break;
> + }
> +
> + // Break out if error
> + if (l_rc)
> + {
> + break;
> + }
> +
> + }
> + while(0);
> +
> + if (l_rc)
> + {
> + l_scom.setAddr(FAILED_TRANSLATION);
> + }
> +
> + return l_scom.getAddr();
> + }
> +
> + // See header file for function description
> + uint32_t p10_scominfo_isChipUnitScom(const p10ChipUnits_t i_p10CU,
> + const uint8_t i_ecLevel,
> + const uint64_t i_scomAddr,
> + bool& o_chipUnitRelated,
> + std::vector<p10_chipUnitPairing_t>& o_chipUnitPairing,
> + const p10TranslationMode_t i_mode)
> + {
> + p10_scom_addr l_scom(i_scomAddr);
> + o_chipUnitRelated = false;
> + o_chipUnitPairing.clear();
> +
> + // Quad registers which can be addressed by EQ target type
> + // eq: 0..7
> + if (l_scom.isEqTarget())
> + {
> + o_chipUnitRelated = true;
> + // PU_EQ_CHIPUNIT
> + o_chipUnitPairing.push_back(p10_chipUnitPairing_t(PU_EQ_CHIPUNIT,
> + l_scom.getEqTargetInstance()));
> + }
> +
> + // Core, L2, L3 registers which can be addressed by core target type
> + // c: 0..31
> + if (l_scom.isCoreTarget())
> + {
> + o_chipUnitRelated = true;
> + // PU_C_CHIPUNIT
> + o_chipUnitPairing.push_back(p10_chipUnitPairing_t(PU_C_CHIPUNIT,
> + l_scom.getCoreTargetInstance()));
> + }
> +
> + // PEC registers which can be addressed by pec target type
> + // pec: 0..1
> + if (l_scom.isPecTarget())
> + {
> + o_chipUnitRelated = true;
> + // PU_PEC_CHIPUNIT
> + o_chipUnitPairing.push_back(p10_chipUnitPairing_t(PU_PEC_CHIPUNIT,
> + l_scom.getPecTargetInstance()));
> + }
> +
> + // PHB registers
> + // phb: 0..5
> + if (l_scom.isPhbTarget())
> + {
> + o_chipUnitRelated = true;
> + // PU_PHB_CHIPUNIT
> + o_chipUnitPairing.push_back(p10_chipUnitPairing_t(PU_PHB_CHIPUNIT,
> + l_scom.getPhbTargetInstance()));
> + }
> +
> + // NMMU registers
> + // nmmu: 0..1
> + if (l_scom.isNmmuTarget())
> + {
> + o_chipUnitRelated = true;
> + // PU_NMMU_CHIPUNIT
> + o_chipUnitPairing.push_back(p10_chipUnitPairing_t(PU_NMMU_CHIPUNIT,
> + l_scom.getNmmuTargetInstance()));
> + }
> +
> + // IOHS registers
> + if (l_scom.isIoHsTarget() &&
> + // prevent matching on IOHS SCOMs in ENGD build mode
> + (i_mode != P10_ENGD_BUILD_MODE))
> + {
> + o_chipUnitRelated = true;
> + // PU_IOHS_CHIPUNIT
> + o_chipUnitPairing.push_back(p10_chipUnitPairing_t(PU_IOHS_CHIPUNIT,
> + l_scom.getIoHsTargetInstance()));
> + }
> +
> + // PAU registers
> + if (l_scom.isPauTarget())
> + {
> + o_chipUnitRelated = true;
> + // PU_PAU_CHIPUNIT
> + o_chipUnitPairing.push_back(p10_chipUnitPairing_t(PU_PAU_CHIPUNIT,
> + l_scom.getPauTargetInstance()));
> + }
> +
> + // MC registers
> + if (l_scom.isMcTarget())
> + {
> + o_chipUnitRelated = true;
> + // PU_MC_CHIPUNIT
> + o_chipUnitPairing.push_back(p10_chipUnitPairing_t(PU_MC_CHIPUNIT,
> + l_scom.getMcTargetInstance()));
> + }
> +
> + // MI registers
> + if (l_scom.isMiTarget())
> + {
> + o_chipUnitRelated = true;
> + // PU_MI_CHIPUNIT
> + o_chipUnitPairing.push_back(p10_chipUnitPairing_t(PU_MI_CHIPUNIT,
> + l_scom.getMiTargetInstance()));
> + }
> +
> + // MCC registers
> + if (l_scom.isMccTarget())
> + {
> + o_chipUnitRelated = true;
> + // PU_MCC_CHIPUNIT
> + o_chipUnitPairing.push_back(p10_chipUnitPairing_t(PU_MCC_CHIPUNIT,
> + l_scom.getMccTargetInstance()));
> + }
> +
> + // OMI registers
> + if (l_scom.isOmiTarget())
> + {
> + o_chipUnitRelated = true;
> + // PU_OMI_CHIPUNIT
> + o_chipUnitPairing.push_back(p10_chipUnitPairing_t(PU_OMI_CHIPUNIT,
> + l_scom.getOmiTargetInstance()));
> + }
> +
> + // OMIC registers
> + if (l_scom.isOmicTarget())
> + {
> + o_chipUnitRelated = true;
> + // PU_OMIC_CHIPUNIT
> + o_chipUnitPairing.push_back(p10_chipUnitPairing_t(PU_OMIC_CHIPUNIT,
> + l_scom.getOmicTargetInstance()));
> + }
> +
> + // PAUC registers
> + if (l_scom.isPaucTarget() &&
> + // prevent matching on indirect SCOMs (physically targeting IOHS
> + // scan latches) in ENGD build mode
> + ((i_mode != P10_ENGD_BUILD_MODE) ||
> + (l_scom.isDirect())))
> + {
> + o_chipUnitRelated = true;
> + // PU_PAUC_CHIPUNIT
> + o_chipUnitPairing.push_back(p10_chipUnitPairing_t(PU_PAUC_CHIPUNIT,
> + l_scom.getPaucTargetInstance()));
> + }
> +
> + // PERV registers
> + if (l_scom.isPervTarget())
> + {
> + // if running in engineering data build flow context, do not
> + // emit associations for registers which would have only
> + // a single association of type PERV
> + if (!((o_chipUnitPairing.size() == 0) &&
> + (i_mode == P10_ENGD_BUILD_MODE)))
> + {
> + o_chipUnitRelated = true;
> + // PU_PERV_CHIPUNIT
> + o_chipUnitPairing.push_back(p10_chipUnitPairing_t(PU_PERV_CHIPUNIT,
> + l_scom.getPervTargetInstance()));
> + }
> + }
> +
> + /// Address may be of a chip, let it pass through
> + return (!l_scom.isValid());
> + }
> +
> + uint32_t p10_scominfo_fixChipUnitScomAddrOrTarget(const p10ChipUnits_t i_p10CU,
> + const uint8_t i_ecLevel,
> + const uint32_t i_targetChipUnitNum,
> + const uint64_t i_scomaddr,
> + uint64_t& o_modifiedScomAddr,
> + p10ChipUnits_t& o_p10CU,
> + uint32_t& o_modifiedChipUnitNum,
> + const uint32_t i_mode)
> + {
> + uint32_t rc = 0;
> +
> + o_modifiedScomAddr = i_scomaddr;
> + o_p10CU = i_p10CU;
> + o_modifiedChipUnitNum = i_targetChipUnitNum;
> +
> + return rc;
> + }
> +
> + //################################################################################
> + uint8_t validateChipUnitNum(const uint8_t i_chipUnitNum,
> + const p10ChipUnits_t i_chipUnitType)
> + {
> + uint8_t l_rc = 0;
> + uint8_t l_index;
> +
> + for (l_index = 0;
> + l_index < (sizeof(ChipUnitDescriptionTable) / sizeof(p10_chipUnitDescription_t));
> + l_index++)
> + {
> + // Looking for input chip unit type in table
> + if (i_chipUnitType == ChipUnitDescriptionTable[l_index].enumVal)
> + {
> + // Found a match, check input i_chipUnitNum to be <= max chip unit num
> + // for this unit type
> + if (i_chipUnitNum > ChipUnitDescriptionTable[l_index].maxChipUnitNum)
> + {
> + l_rc = 1;
> + }
> +
> + // Additional check for PERV targets, where there are gaps between instances
> + else if (i_chipUnitType == PU_PERV_CHIPUNIT)
> + {
> + // Note: We allow content in chiplet ID = 0x00 to be referenced with a perv target instance,
> + // so do not check for instance = 0 here.
> + if ( ((i_chipUnitNum > 3) && (i_chipUnitNum < 8)) ||
> + ((i_chipUnitNum > 9) && (i_chipUnitNum < 12)) ||
> + ((i_chipUnitNum > 19) && (i_chipUnitNum < 24)) )
> + {
> + l_rc = 1;
> + }
> + }
> +
> + // Additional check for PAU targets, where instance 1 and 2 are not valid
> + else if (i_chipUnitType == PU_PAU_CHIPUNIT)
> + {
> + if ( (i_chipUnitNum == 1) || (i_chipUnitNum == 2) )
> + {
> + l_rc = 1;
> + }
> + }
> +
> + break;
> + }
> + }
> +
> + // Can't find i_chipUnitType in table
> + if ( l_index >= (sizeof(ChipUnitDescriptionTable) / sizeof(p10_chipUnitDescription_t)) )
> + {
> + l_rc = 1;
> + }
> +
> + return (l_rc);
> + }
> +
> +} // extern "C"
> +
> +#undef P10_SCOMINFO_C
> diff --git a/src/tests/p10_scominfo.H b/src/tests/p10_scominfo.H
> new file mode 100644
> index 0000000..f970c9d
> --- /dev/null
> +++ b/src/tests/p10_scominfo.H
> @@ -0,0 +1,107 @@
> +/* IBM_PROLOG_BEGIN_TAG */
> +/* This is an automatically generated prolog. */
> +/* */
> +/* $Source: chips/p10/common/scominfo/p10_scominfo.H $ */
> +/* */
> +/* IBM CONFIDENTIAL */
> +/* */
> +/* EKB Project */
> +/* */
> +/* COPYRIGHT 2018,2019 */
> +/* [+] International Business Machines Corp. */
> +/* */
> +/* */
> +/* The source code for this program is not published or otherwise */
> +/* divested of its trade secrets, irrespective of what has been */
> +/* deposited with the U.S. Copyright Office. */
> +/* */
> +/* IBM_PROLOG_END_TAG */
> +///
> +/// @file p10_scominfo.H
> +/// @brief P10 chip unit SCOM address platform translation code
> +///
> +/// HWP HW Maintainer: Thi Tran <thi at us.ibm.com>
> +/// HWP FW Maintainer:
> +/// HWP Consumed by: Cronus, HB, HWSV
> +///
> +
> +#ifndef P10_SCOMINFO_H
> +#define P10_SCOMINFO_H
> +
> +// includes
> +#include <stdint.h>
> +#include <vector>
> +#include "p10_cu.H"
> +
> +extern "C"
> +{
> + // Modes of translation
> + typedef enum
> + {
> + P10_DEFAULT_MODE = 0, // Default platform behavior
> + P10_ENGD_BUILD_MODE = 1, // Apply customization for ENGD build
> + } p10TranslationMode_t;
> +
> + typedef enum
> + {
> + FAILED_TRANSLATION = 0xFFFFFFFFFFFFFFF1ull
> + } p10TranslationResult_t;
> +
> + /// @brief Creates the actual SCOM address based on the chip unit type, instance, and the input SCOM address (relative to chip unit instance 0)
> + /// @param[in] i_p10CU Enumeration of the chip unit type
> + /// @param[in] i_ecLevel Chip EC level represented in HEX digit value. Example: i_ecLevel = 0x12 --> EC level 1.2
> + /// @param[in] i_chipUnitNum Instance number of the chip unit
> + /// @param[in] i_scomAddr The input SCOM address associated with the chip unit type
> + /// @param[in] i_mode Translation mode, specifying different addr translation methods.
> + /// @retval uint64_t Actual SCOM address for the chip unit instance passed in
> + uint64_t p10_scominfo_createChipUnitScomAddr(const p10ChipUnits_t i_p10CU,
> + const uint8_t i_ecLevel,
> + const uint8_t i_chipUnitNum,
> + const uint64_t i_scomAddr,
> + const uint32_t i_mode = 0);
> +
> + /// @brief Determine if the provided SCOM address correlates to any chip units (if so creates a list of chipUnitPairing structures which correspond)
> + /// @param[in] i_p10CU Enumeration of the chip unit type
> + /// @param[in] i_ecLevel Chip EC level represented in HEX digit value. Example: i_ecLevel = 0x12 --> EC level 1.2
> + /// @param[in] i_scomAddr SCOM address to be tested
> + /// @param[out] o_chipUnitRelated Returns true if SCOM address is associated with any chip units
> + /// @param[out] o_chipUnitPairing Collection of chipUnitPairing enums
> + /// @param[in] i_mode Translation mode, specifying different addr translation methods.
> + /// @retval uint32_t Return non-zero for error
> + uint32_t p10_scominfo_isChipUnitScom(const p10ChipUnits_t i_p10CU,
> + const uint8_t i_ecLevel,
> + const uint64_t i_scomAddr,
> + bool& o_chipUnitRelated,
> + std::vector<p10_chipUnitPairing_t>& o_chipUnitPairing,
> + const p10TranslationMode_t i_mode = P10_DEFAULT_MODE);
> +
> + /// @brief Alter the unit/unitnum of a target for spys where the clocks-on vs clocks-off targets are different.
> + /// @param[in] i_p10CU Target used for the spy request
> + /// @param[in] i_ecLevel Chip EC level represented in HEX digit value. Example: i_ecLevel = 0x12 --> EC level 1.2
> + /// @param[in] i_targetChipUnitNum The instance number of the target used for the spy request
> + /// @param[in] i_scomaddr The scom from the clocks-on portion of the spy
> + /// @param[out] o_modifiedScomAddr The translated scom address (none may be needed)
> + /// @param[out] o_p10CU The translated target type
> + /// @param[out] o_modifiedChipUnitNum The translated target instance number
> + /// @param[in] i_mode Translation mode, specifying different addr translation methods.
> + /// @retval uint32_t Return non-zero for error
> + uint32_t p10_scominfo_fixChipUnitScomAddrOrTarget(const p10ChipUnits_t i_p10CU,
> + const uint8_t i_ecLevel,
> + const uint32_t i_targetChipUnitNum,
> + const uint64_t i_scomaddr,
> + uint64_t& o_modifiedScomAddr,
> + p10ChipUnits_t& o_p10CU,
> + uint32_t& o_modifiedChipUnitNum,
> + const uint32_t i_mode = 0);
> +
> + /// @brief Validate the chip unit number to be within range
> + /// of a chip unit type.
> + /// @param[in] i_chipUnitNum Value of chip unit number (instance)
> + /// @param[in] i_chipUnitType Chip unit type
> + /// @retval Non-zero if error
> + uint8_t validateChipUnitNum(const uint8_t i_chipUnitNum,
> + const p10ChipUnits_t i_chipUnitType);
> +
> +} // extern "C"
> +
> +#endif /* P10_SCOMINFO_H */
> diff --git a/tests/test_p10_fapi_translation.sh b/tests/test_p10_fapi_translation.sh
> new file mode 100755
> index 0000000..5e58ccb
> --- /dev/null
> +++ b/tests/test_p10_fapi_translation.sh
> @@ -0,0 +1,206 @@
> +#!/bin/sh
> +
> +. $(dirname "$0")/driver.sh
> +
> +test_group "p10 fapi translation tests"
> +
> +export PDBG_BACKEND_DTB=bmc-kernel.dtb
> +export PDBG_DTB=p10.dtb
> +
> +test_result 0 <<EOF
> +Testing /proc0/pib/chiplet at 20000000/eq at 0/fc at 0/core at 0 0
> +Testing /proc0/pib/chiplet at 20000000/eq at 0/fc at 0/core at 1 1
> +Testing /proc0/pib/chiplet at 20000000/eq at 0/fc at 1/core at 0 2
> +Testing /proc0/pib/chiplet at 20000000/eq at 0/fc at 1/core at 1 3
> +Testing /proc0/pib/chiplet at 21000000/eq at 1/fc at 0/core at 0 4
> +Testing /proc0/pib/chiplet at 21000000/eq at 1/fc at 0/core at 1 5
> +Testing /proc0/pib/chiplet at 21000000/eq at 1/fc at 1/core at 0 6
> +Testing /proc0/pib/chiplet at 21000000/eq at 1/fc at 1/core at 1 7
> +Testing /proc0/pib/chiplet at 22000000/eq at 2/fc at 0/core at 0 8
> +Testing /proc0/pib/chiplet at 22000000/eq at 2/fc at 0/core at 1 9
> +Testing /proc0/pib/chiplet at 22000000/eq at 2/fc at 1/core at 0 10
> +Testing /proc0/pib/chiplet at 22000000/eq at 2/fc at 1/core at 1 11
> +Testing /proc0/pib/chiplet at 23000000/eq at 3/fc at 0/core at 0 12
> +Testing /proc0/pib/chiplet at 23000000/eq at 3/fc at 0/core at 1 13
> +Testing /proc0/pib/chiplet at 23000000/eq at 3/fc at 1/core at 0 14
> +Testing /proc0/pib/chiplet at 23000000/eq at 3/fc at 1/core at 1 15
> +Testing /proc0/pib/chiplet at 24000000/eq at 4/fc at 0/core at 0 16
> +Testing /proc0/pib/chiplet at 24000000/eq at 4/fc at 0/core at 1 17
> +Testing /proc0/pib/chiplet at 24000000/eq at 4/fc at 1/core at 0 18
> +Testing /proc0/pib/chiplet at 24000000/eq at 4/fc at 1/core at 1 19
> +Testing /proc0/pib/chiplet at 25000000/eq at 5/fc at 0/core at 0 20
> +Testing /proc0/pib/chiplet at 25000000/eq at 5/fc at 0/core at 1 21
> +Testing /proc0/pib/chiplet at 25000000/eq at 5/fc at 1/core at 0 22
> +Testing /proc0/pib/chiplet at 25000000/eq at 5/fc at 1/core at 1 23
> +Testing /proc0/pib/chiplet at 26000000/eq at 6/fc at 0/core at 0 24
> +Testing /proc0/pib/chiplet at 26000000/eq at 6/fc at 0/core at 1 25
> +Testing /proc0/pib/chiplet at 26000000/eq at 6/fc at 1/core at 0 26
> +Testing /proc0/pib/chiplet at 26000000/eq at 6/fc at 1/core at 1 27
> +Testing /proc0/pib/chiplet at 27000000/eq at 7/fc at 0/core at 0 28
> +Testing /proc0/pib/chiplet at 27000000/eq at 7/fc at 0/core at 1 29
> +Testing /proc0/pib/chiplet at 27000000/eq at 7/fc at 1/core at 0 30
> +Testing /proc0/pib/chiplet at 27000000/eq at 7/fc at 1/core at 1 31
> +EOF
> +
> +test_run libpdbg_p10_fapi_translation_test core
> +
> +
> +test_result 0 <<EOF
> +Testing /proc0/pib/chiplet at 20000000/eq at 0 0
> +Testing /proc0/pib/chiplet at 21000000/eq at 1 1
> +Testing /proc0/pib/chiplet at 22000000/eq at 2 2
> +Testing /proc0/pib/chiplet at 23000000/eq at 3 3
> +Testing /proc0/pib/chiplet at 24000000/eq at 4 4
> +Testing /proc0/pib/chiplet at 25000000/eq at 5 5
> +Testing /proc0/pib/chiplet at 26000000/eq at 6 6
> +Testing /proc0/pib/chiplet at 27000000/eq at 7 7
> +EOF
> +
> +test_run libpdbg_p10_fapi_translation_test eq
> +
> +
> +test_result 0 <<EOF
> +Testing /proc0/pib/chiplet at 8000000/pec at 0 0
> +Testing /proc0/pib/chiplet at 9000000/pec at 1 1
> +EOF
> +
> +test_run libpdbg_p10_fapi_translation_test pec
> +
> +
> +test_result 0 <<EOF
> +Testing /proc0/pib/chiplet at 8000000/pec at 0/phb at 0 0
> +Testing /proc0/pib/chiplet at 8000000/pec at 0/phb at 1 1
> +Testing /proc0/pib/chiplet at 8000000/pec at 0/phb at 2 2
> +Testing /proc0/pib/chiplet at 9000000/pec at 1/phb at 0 3
> +Testing /proc0/pib/chiplet at 9000000/pec at 1/phb at 1 4
> +Testing /proc0/pib/chiplet at 9000000/pec at 1/phb at 2 5
> +EOF
> +
> +test_run libpdbg_p10_fapi_translation_test phb
> +
> +
> +test_result 0 <<EOF
> +Testing /proc0/pib/chiplet at c000000/mc at 0/mi at 0 0
> +Testing /proc0/pib/chiplet at d000000/mc at 1/mi at 1 1
> +Testing /proc0/pib/chiplet at e000000/mc at 2/mi at 2 2
> +Testing /proc0/pib/chiplet at f000000/mc at 3/mi at 3 3
> +EOF
> +
> +test_run libpdbg_p10_fapi_translation_test mi
> +
> +
> +test_result 0 <<EOF
> +Testing /proc0/pib/chiplet at c000000/mc at 0/mi at 0/mcc at 0 0
> +Testing /proc0/pib/chiplet at c000000/mc at 0/mi at 0/mcc at 1 1
> +Testing /proc0/pib/chiplet at d000000/mc at 1/mi at 1/mcc at 0 2
> +Testing /proc0/pib/chiplet at d000000/mc at 1/mi at 1/mcc at 1 3
> +Testing /proc0/pib/chiplet at e000000/mc at 2/mi at 2/mcc at 0 4
> +Testing /proc0/pib/chiplet at e000000/mc at 2/mi at 2/mcc at 1 5
> +Testing /proc0/pib/chiplet at f000000/mc at 3/mi at 3/mcc at 0 6
> +Testing /proc0/pib/chiplet at f000000/mc at 3/mi at 3/mcc at 1 7
> +EOF
> +
> +test_run libpdbg_p10_fapi_translation_test mcc
> +
> +
> +test_result 0 <<EOF
> +Testing /proc0/pib/chiplet at c000000/mc at 0/omic at 0 0
> +Testing /proc0/pib/chiplet at c000000/mc at 0/omic at 1 1
> +Testing /proc0/pib/chiplet at d000000/mc at 1/omic at 2 2
> +Testing /proc0/pib/chiplet at d000000/mc at 1/omic at 3 3
> +Testing /proc0/pib/chiplet at e000000/mc at 2/omic at 4 4
> +Testing /proc0/pib/chiplet at e000000/mc at 2/omic at 5 5
> +Testing /proc0/pib/chiplet at f000000/mc at 3/omic at 6 6
> +Testing /proc0/pib/chiplet at f000000/mc at 3/omic at 7 7
> +EOF
> +
> +test_run libpdbg_p10_fapi_translation_test omic
> +
> +
> +test_result 0 <<EOF
> +Testing /proc0/pib/chiplet at 1000000 1
> +Testing /proc0/pib/chiplet at 2000000 2
> +Testing /proc0/pib/chiplet at 3000000 3
> +Testing /proc0/pib/chiplet at 8000000 8
> +Testing /proc0/pib/chiplet at 9000000 9
> +Testing /proc0/pib/chiplet at c000000 12
> +Testing /proc0/pib/chiplet at d000000 13
> +Testing /proc0/pib/chiplet at e000000 14
> +Testing /proc0/pib/chiplet at f000000 15
> +Testing /proc0/pib/chiplet at 10000000 16
> +Testing /proc0/pib/chiplet at 11000000 17
> +Testing /proc0/pib/chiplet at 12000000 18
> +Testing /proc0/pib/chiplet at 13000000 19
> +Testing /proc0/pib/chiplet at 18000000 24
> +Testing /proc0/pib/chiplet at 19000000 25
> +Testing /proc0/pib/chiplet at 1a000000 26
> +Testing /proc0/pib/chiplet at 1b000000 27
> +Testing /proc0/pib/chiplet at 1c000000 28
> +Testing /proc0/pib/chiplet at 1d000000 29
> +Testing /proc0/pib/chiplet at 1e000000 30
> +Testing /proc0/pib/chiplet at 1f000000 31
> +Testing /proc0/pib/chiplet at 20000000 32
> +Testing /proc0/pib/chiplet at 21000000 33
> +Testing /proc0/pib/chiplet at 22000000 34
> +Testing /proc0/pib/chiplet at 23000000 35
> +Testing /proc0/pib/chiplet at 24000000 36
> +Testing /proc0/pib/chiplet at 25000000 37
> +Testing /proc0/pib/chiplet at 26000000 38
> +Testing /proc0/pib/chiplet at 27000000 39
> +EOF
> +
> +test_run libpdbg_p10_fapi_translation_test chiplet
> +
> +
> +test_result 0 <<EOF
> +Testing /proc0/pib/chiplet at c000000/mc at 0 0
> +Testing /proc0/pib/chiplet at d000000/mc at 1 1
> +Testing /proc0/pib/chiplet at e000000/mc at 2 2
> +Testing /proc0/pib/chiplet at f000000/mc at 3 3
> +EOF
> +
> +test_run libpdbg_p10_fapi_translation_test mc
> +
> +
> +test_result 0 <<EOF
> +Testing /proc0/pib/chiplet at 2000000/nmmu at 0 0
> +Testing /proc0/pib/chiplet at 3000000/nmmu at 1 1
> +EOF
> +
> +test_run libpdbg_p10_fapi_translation_test nmmu
> +
> +
> +test_result 0 <<EOF
> +Testing /proc0/pib/chiplet at 18000000/iohs at 0 0
> +Testing /proc0/pib/chiplet at 19000000/iohs at 1 1
> +Testing /proc0/pib/chiplet at 1a000000/iohs at 2 2
> +Testing /proc0/pib/chiplet at 1b000000/iohs at 3 3
> +Testing /proc0/pib/chiplet at 1c000000/iohs at 4 4
> +Testing /proc0/pib/chiplet at 1d000000/iohs at 5 5
> +Testing /proc0/pib/chiplet at 1e000000/iohs at 6 6
> +Testing /proc0/pib/chiplet at 1f000000/iohs at 7 7
> +EOF
> +
> +test_run libpdbg_p10_fapi_translation_test iohs
> +
> +
> +test_result 0 <<EOF
> +Testing /proc0/pib/chiplet at 10000000/pauc at 0/pau at 0 0
> +Testing /proc0/pib/chiplet at 11000000/pauc at 1/pau at 3 3
> +Testing /proc0/pib/chiplet at 12000000/pauc at 2/pau at 4 4
> +Testing /proc0/pib/chiplet at 12000000/pauc at 2/pau at 5 5
> +Testing /proc0/pib/chiplet at 13000000/pauc at 3/pau at 6 6
> +Testing /proc0/pib/chiplet at 13000000/pauc at 3/pau at 7 7
> +EOF
> +
> +test_run libpdbg_p10_fapi_translation_test pau
> +
> +
> +test_result 0 <<EOF
> +Testing /proc0/pib/chiplet at 10000000/pauc at 0 0
> +Testing /proc0/pib/chiplet at 11000000/pauc at 1 1
> +Testing /proc0/pib/chiplet at 12000000/pauc at 2 2
> +Testing /proc0/pib/chiplet at 13000000/pauc at 3 3
> +EOF
> +
> +test_run libpdbg_p10_fapi_translation_test pauc
> --
> 2.26.2
>
> --
> Pdbg mailing list
> Pdbg at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/pdbg
More information about the Pdbg
mailing list