Message ID | 20200924044236.130586-7-amitay@ozlabs.org |
---|---|
State | Superseded |
Headers | show |
Series | Add p10 support to libpdbg | expand |
On Mon, 28 Sep 2020 at 06:35, Amitay Isaacs <amitay@ozlabs.org> wrote: > > From: Alistair Popple <alistair@popple.id.au> > > Signed-off-by: Alistair Popple <alistair@popple.id.au> > Signed-off-by: Amitay Isaacs <amitay@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@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@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@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@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@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@20000000/eq@0/fc@0/core@0 0 > +Testing /proc0/pib/chiplet@20000000/eq@0/fc@0/core@1 1 > +Testing /proc0/pib/chiplet@20000000/eq@0/fc@1/core@0 2 > +Testing /proc0/pib/chiplet@20000000/eq@0/fc@1/core@1 3 > +Testing /proc0/pib/chiplet@21000000/eq@1/fc@0/core@0 4 > +Testing /proc0/pib/chiplet@21000000/eq@1/fc@0/core@1 5 > +Testing /proc0/pib/chiplet@21000000/eq@1/fc@1/core@0 6 > +Testing /proc0/pib/chiplet@21000000/eq@1/fc@1/core@1 7 > +Testing /proc0/pib/chiplet@22000000/eq@2/fc@0/core@0 8 > +Testing /proc0/pib/chiplet@22000000/eq@2/fc@0/core@1 9 > +Testing /proc0/pib/chiplet@22000000/eq@2/fc@1/core@0 10 > +Testing /proc0/pib/chiplet@22000000/eq@2/fc@1/core@1 11 > +Testing /proc0/pib/chiplet@23000000/eq@3/fc@0/core@0 12 > +Testing /proc0/pib/chiplet@23000000/eq@3/fc@0/core@1 13 > +Testing /proc0/pib/chiplet@23000000/eq@3/fc@1/core@0 14 > +Testing /proc0/pib/chiplet@23000000/eq@3/fc@1/core@1 15 > +Testing /proc0/pib/chiplet@24000000/eq@4/fc@0/core@0 16 > +Testing /proc0/pib/chiplet@24000000/eq@4/fc@0/core@1 17 > +Testing /proc0/pib/chiplet@24000000/eq@4/fc@1/core@0 18 > +Testing /proc0/pib/chiplet@24000000/eq@4/fc@1/core@1 19 > +Testing /proc0/pib/chiplet@25000000/eq@5/fc@0/core@0 20 > +Testing /proc0/pib/chiplet@25000000/eq@5/fc@0/core@1 21 > +Testing /proc0/pib/chiplet@25000000/eq@5/fc@1/core@0 22 > +Testing /proc0/pib/chiplet@25000000/eq@5/fc@1/core@1 23 > +Testing /proc0/pib/chiplet@26000000/eq@6/fc@0/core@0 24 > +Testing /proc0/pib/chiplet@26000000/eq@6/fc@0/core@1 25 > +Testing /proc0/pib/chiplet@26000000/eq@6/fc@1/core@0 26 > +Testing /proc0/pib/chiplet@26000000/eq@6/fc@1/core@1 27 > +Testing /proc0/pib/chiplet@27000000/eq@7/fc@0/core@0 28 > +Testing /proc0/pib/chiplet@27000000/eq@7/fc@0/core@1 29 > +Testing /proc0/pib/chiplet@27000000/eq@7/fc@1/core@0 30 > +Testing /proc0/pib/chiplet@27000000/eq@7/fc@1/core@1 31 > +EOF > + > +test_run libpdbg_p10_fapi_translation_test core > + > + > +test_result 0 <<EOF > +Testing /proc0/pib/chiplet@20000000/eq@0 0 > +Testing /proc0/pib/chiplet@21000000/eq@1 1 > +Testing /proc0/pib/chiplet@22000000/eq@2 2 > +Testing /proc0/pib/chiplet@23000000/eq@3 3 > +Testing /proc0/pib/chiplet@24000000/eq@4 4 > +Testing /proc0/pib/chiplet@25000000/eq@5 5 > +Testing /proc0/pib/chiplet@26000000/eq@6 6 > +Testing /proc0/pib/chiplet@27000000/eq@7 7 > +EOF > + > +test_run libpdbg_p10_fapi_translation_test eq > + > + > +test_result 0 <<EOF > +Testing /proc0/pib/chiplet@8000000/pec@0 0 > +Testing /proc0/pib/chiplet@9000000/pec@1 1 > +EOF > + > +test_run libpdbg_p10_fapi_translation_test pec > + > + > +test_result 0 <<EOF > +Testing /proc0/pib/chiplet@8000000/pec@0/phb@0 0 > +Testing /proc0/pib/chiplet@8000000/pec@0/phb@1 1 > +Testing /proc0/pib/chiplet@8000000/pec@0/phb@2 2 > +Testing /proc0/pib/chiplet@9000000/pec@1/phb@0 3 > +Testing /proc0/pib/chiplet@9000000/pec@1/phb@1 4 > +Testing /proc0/pib/chiplet@9000000/pec@1/phb@2 5 > +EOF > + > +test_run libpdbg_p10_fapi_translation_test phb > + > + > +test_result 0 <<EOF > +Testing /proc0/pib/chiplet@c000000/mc@0/mi@0 0 > +Testing /proc0/pib/chiplet@d000000/mc@1/mi@1 1 > +Testing /proc0/pib/chiplet@e000000/mc@2/mi@2 2 > +Testing /proc0/pib/chiplet@f000000/mc@3/mi@3 3 > +EOF > + > +test_run libpdbg_p10_fapi_translation_test mi > + > + > +test_result 0 <<EOF > +Testing /proc0/pib/chiplet@c000000/mc@0/mi@0/mcc@0 0 > +Testing /proc0/pib/chiplet@c000000/mc@0/mi@0/mcc@1 1 > +Testing /proc0/pib/chiplet@d000000/mc@1/mi@1/mcc@0 2 > +Testing /proc0/pib/chiplet@d000000/mc@1/mi@1/mcc@1 3 > +Testing /proc0/pib/chiplet@e000000/mc@2/mi@2/mcc@0 4 > +Testing /proc0/pib/chiplet@e000000/mc@2/mi@2/mcc@1 5 > +Testing /proc0/pib/chiplet@f000000/mc@3/mi@3/mcc@0 6 > +Testing /proc0/pib/chiplet@f000000/mc@3/mi@3/mcc@1 7 > +EOF > + > +test_run libpdbg_p10_fapi_translation_test mcc > + > + > +test_result 0 <<EOF > +Testing /proc0/pib/chiplet@c000000/mc@0/omic@0 0 > +Testing /proc0/pib/chiplet@c000000/mc@0/omic@1 1 > +Testing /proc0/pib/chiplet@d000000/mc@1/omic@2 2 > +Testing /proc0/pib/chiplet@d000000/mc@1/omic@3 3 > +Testing /proc0/pib/chiplet@e000000/mc@2/omic@4 4 > +Testing /proc0/pib/chiplet@e000000/mc@2/omic@5 5 > +Testing /proc0/pib/chiplet@f000000/mc@3/omic@6 6 > +Testing /proc0/pib/chiplet@f000000/mc@3/omic@7 7 > +EOF > + > +test_run libpdbg_p10_fapi_translation_test omic > + > + > +test_result 0 <<EOF > +Testing /proc0/pib/chiplet@1000000 1 > +Testing /proc0/pib/chiplet@2000000 2 > +Testing /proc0/pib/chiplet@3000000 3 > +Testing /proc0/pib/chiplet@8000000 8 > +Testing /proc0/pib/chiplet@9000000 9 > +Testing /proc0/pib/chiplet@c000000 12 > +Testing /proc0/pib/chiplet@d000000 13 > +Testing /proc0/pib/chiplet@e000000 14 > +Testing /proc0/pib/chiplet@f000000 15 > +Testing /proc0/pib/chiplet@10000000 16 > +Testing /proc0/pib/chiplet@11000000 17 > +Testing /proc0/pib/chiplet@12000000 18 > +Testing /proc0/pib/chiplet@13000000 19 > +Testing /proc0/pib/chiplet@18000000 24 > +Testing /proc0/pib/chiplet@19000000 25 > +Testing /proc0/pib/chiplet@1a000000 26 > +Testing /proc0/pib/chiplet@1b000000 27 > +Testing /proc0/pib/chiplet@1c000000 28 > +Testing /proc0/pib/chiplet@1d000000 29 > +Testing /proc0/pib/chiplet@1e000000 30 > +Testing /proc0/pib/chiplet@1f000000 31 > +Testing /proc0/pib/chiplet@20000000 32 > +Testing /proc0/pib/chiplet@21000000 33 > +Testing /proc0/pib/chiplet@22000000 34 > +Testing /proc0/pib/chiplet@23000000 35 > +Testing /proc0/pib/chiplet@24000000 36 > +Testing /proc0/pib/chiplet@25000000 37 > +Testing /proc0/pib/chiplet@26000000 38 > +Testing /proc0/pib/chiplet@27000000 39 > +EOF > + > +test_run libpdbg_p10_fapi_translation_test chiplet > + > + > +test_result 0 <<EOF > +Testing /proc0/pib/chiplet@c000000/mc@0 0 > +Testing /proc0/pib/chiplet@d000000/mc@1 1 > +Testing /proc0/pib/chiplet@e000000/mc@2 2 > +Testing /proc0/pib/chiplet@f000000/mc@3 3 > +EOF > + > +test_run libpdbg_p10_fapi_translation_test mc > + > + > +test_result 0 <<EOF > +Testing /proc0/pib/chiplet@2000000/nmmu@0 0 > +Testing /proc0/pib/chiplet@3000000/nmmu@1 1 > +EOF > + > +test_run libpdbg_p10_fapi_translation_test nmmu > + > + > +test_result 0 <<EOF > +Testing /proc0/pib/chiplet@18000000/iohs@0 0 > +Testing /proc0/pib/chiplet@19000000/iohs@1 1 > +Testing /proc0/pib/chiplet@1a000000/iohs@2 2 > +Testing /proc0/pib/chiplet@1b000000/iohs@3 3 > +Testing /proc0/pib/chiplet@1c000000/iohs@4 4 > +Testing /proc0/pib/chiplet@1d000000/iohs@5 5 > +Testing /proc0/pib/chiplet@1e000000/iohs@6 6 > +Testing /proc0/pib/chiplet@1f000000/iohs@7 7 > +EOF > + > +test_run libpdbg_p10_fapi_translation_test iohs > + > + > +test_result 0 <<EOF > +Testing /proc0/pib/chiplet@10000000/pauc@0/pau@0 0 > +Testing /proc0/pib/chiplet@11000000/pauc@1/pau@3 3 > +Testing /proc0/pib/chiplet@12000000/pauc@2/pau@4 4 > +Testing /proc0/pib/chiplet@12000000/pauc@2/pau@5 5 > +Testing /proc0/pib/chiplet@13000000/pauc@3/pau@6 6 > +Testing /proc0/pib/chiplet@13000000/pauc@3/pau@7 7 > +EOF > + > +test_run libpdbg_p10_fapi_translation_test pau > + > + > +test_result 0 <<EOF > +Testing /proc0/pib/chiplet@10000000/pauc@0 0 > +Testing /proc0/pib/chiplet@11000000/pauc@1 1 > +Testing /proc0/pib/chiplet@12000000/pauc@2 2 > +Testing /proc0/pib/chiplet@13000000/pauc@3 3 > +EOF > + > +test_run libpdbg_p10_fapi_translation_test pauc > -- > 2.26.2 > > -- > Pdbg mailing list > Pdbg@lists.ozlabs.org > https://lists.ozlabs.org/listinfo/pdbg
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 @@ +#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 */ +/* */ +/* 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@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@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@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@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@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@20000000/eq@0/fc@0/core@0 0 +Testing /proc0/pib/chiplet@20000000/eq@0/fc@0/core@1 1 +Testing /proc0/pib/chiplet@20000000/eq@0/fc@1/core@0 2 +Testing /proc0/pib/chiplet@20000000/eq@0/fc@1/core@1 3 +Testing /proc0/pib/chiplet@21000000/eq@1/fc@0/core@0 4 +Testing /proc0/pib/chiplet@21000000/eq@1/fc@0/core@1 5 +Testing /proc0/pib/chiplet@21000000/eq@1/fc@1/core@0 6 +Testing /proc0/pib/chiplet@21000000/eq@1/fc@1/core@1 7 +Testing /proc0/pib/chiplet@22000000/eq@2/fc@0/core@0 8 +Testing /proc0/pib/chiplet@22000000/eq@2/fc@0/core@1 9 +Testing /proc0/pib/chiplet@22000000/eq@2/fc@1/core@0 10 +Testing /proc0/pib/chiplet@22000000/eq@2/fc@1/core@1 11 +Testing /proc0/pib/chiplet@23000000/eq@3/fc@0/core@0 12 +Testing /proc0/pib/chiplet@23000000/eq@3/fc@0/core@1 13 +Testing /proc0/pib/chiplet@23000000/eq@3/fc@1/core@0 14 +Testing /proc0/pib/chiplet@23000000/eq@3/fc@1/core@1 15 +Testing /proc0/pib/chiplet@24000000/eq@4/fc@0/core@0 16 +Testing /proc0/pib/chiplet@24000000/eq@4/fc@0/core@1 17 +Testing /proc0/pib/chiplet@24000000/eq@4/fc@1/core@0 18 +Testing /proc0/pib/chiplet@24000000/eq@4/fc@1/core@1 19 +Testing /proc0/pib/chiplet@25000000/eq@5/fc@0/core@0 20 +Testing /proc0/pib/chiplet@25000000/eq@5/fc@0/core@1 21 +Testing /proc0/pib/chiplet@25000000/eq@5/fc@1/core@0 22 +Testing /proc0/pib/chiplet@25000000/eq@5/fc@1/core@1 23 +Testing /proc0/pib/chiplet@26000000/eq@6/fc@0/core@0 24 +Testing /proc0/pib/chiplet@26000000/eq@6/fc@0/core@1 25 +Testing /proc0/pib/chiplet@26000000/eq@6/fc@1/core@0 26 +Testing /proc0/pib/chiplet@26000000/eq@6/fc@1/core@1 27 +Testing /proc0/pib/chiplet@27000000/eq@7/fc@0/core@0 28 +Testing /proc0/pib/chiplet@27000000/eq@7/fc@0/core@1 29 +Testing /proc0/pib/chiplet@27000000/eq@7/fc@1/core@0 30 +Testing /proc0/pib/chiplet@27000000/eq@7/fc@1/core@1 31 +EOF + +test_run libpdbg_p10_fapi_translation_test core + + +test_result 0 <<EOF +Testing /proc0/pib/chiplet@20000000/eq@0 0 +Testing /proc0/pib/chiplet@21000000/eq@1 1 +Testing /proc0/pib/chiplet@22000000/eq@2 2 +Testing /proc0/pib/chiplet@23000000/eq@3 3 +Testing /proc0/pib/chiplet@24000000/eq@4 4 +Testing /proc0/pib/chiplet@25000000/eq@5 5 +Testing /proc0/pib/chiplet@26000000/eq@6 6 +Testing /proc0/pib/chiplet@27000000/eq@7 7 +EOF + +test_run libpdbg_p10_fapi_translation_test eq + + +test_result 0 <<EOF +Testing /proc0/pib/chiplet@8000000/pec@0 0 +Testing /proc0/pib/chiplet@9000000/pec@1 1 +EOF + +test_run libpdbg_p10_fapi_translation_test pec + + +test_result 0 <<EOF +Testing /proc0/pib/chiplet@8000000/pec@0/phb@0 0 +Testing /proc0/pib/chiplet@8000000/pec@0/phb@1 1 +Testing /proc0/pib/chiplet@8000000/pec@0/phb@2 2 +Testing /proc0/pib/chiplet@9000000/pec@1/phb@0 3 +Testing /proc0/pib/chiplet@9000000/pec@1/phb@1 4 +Testing /proc0/pib/chiplet@9000000/pec@1/phb@2 5 +EOF + +test_run libpdbg_p10_fapi_translation_test phb + + +test_result 0 <<EOF +Testing /proc0/pib/chiplet@c000000/mc@0/mi@0 0 +Testing /proc0/pib/chiplet@d000000/mc@1/mi@1 1 +Testing /proc0/pib/chiplet@e000000/mc@2/mi@2 2 +Testing /proc0/pib/chiplet@f000000/mc@3/mi@3 3 +EOF + +test_run libpdbg_p10_fapi_translation_test mi + + +test_result 0 <<EOF +Testing /proc0/pib/chiplet@c000000/mc@0/mi@0/mcc@0 0 +Testing /proc0/pib/chiplet@c000000/mc@0/mi@0/mcc@1 1 +Testing /proc0/pib/chiplet@d000000/mc@1/mi@1/mcc@0 2 +Testing /proc0/pib/chiplet@d000000/mc@1/mi@1/mcc@1 3 +Testing /proc0/pib/chiplet@e000000/mc@2/mi@2/mcc@0 4 +Testing /proc0/pib/chiplet@e000000/mc@2/mi@2/mcc@1 5 +Testing /proc0/pib/chiplet@f000000/mc@3/mi@3/mcc@0 6 +Testing /proc0/pib/chiplet@f000000/mc@3/mi@3/mcc@1 7 +EOF + +test_run libpdbg_p10_fapi_translation_test mcc + + +test_result 0 <<EOF +Testing /proc0/pib/chiplet@c000000/mc@0/omic@0 0 +Testing /proc0/pib/chiplet@c000000/mc@0/omic@1 1 +Testing /proc0/pib/chiplet@d000000/mc@1/omic@2 2 +Testing /proc0/pib/chiplet@d000000/mc@1/omic@3 3 +Testing /proc0/pib/chiplet@e000000/mc@2/omic@4 4 +Testing /proc0/pib/chiplet@e000000/mc@2/omic@5 5 +Testing /proc0/pib/chiplet@f000000/mc@3/omic@6 6 +Testing /proc0/pib/chiplet@f000000/mc@3/omic@7 7 +EOF + +test_run libpdbg_p10_fapi_translation_test omic + + +test_result 0 <<EOF +Testing /proc0/pib/chiplet@1000000 1 +Testing /proc0/pib/chiplet@2000000 2 +Testing /proc0/pib/chiplet@3000000 3 +Testing /proc0/pib/chiplet@8000000 8 +Testing /proc0/pib/chiplet@9000000 9 +Testing /proc0/pib/chiplet@c000000 12 +Testing /proc0/pib/chiplet@d000000 13 +Testing /proc0/pib/chiplet@e000000 14 +Testing /proc0/pib/chiplet@f000000 15 +Testing /proc0/pib/chiplet@10000000 16 +Testing /proc0/pib/chiplet@11000000 17 +Testing /proc0/pib/chiplet@12000000 18 +Testing /proc0/pib/chiplet@13000000 19 +Testing /proc0/pib/chiplet@18000000 24 +Testing /proc0/pib/chiplet@19000000 25 +Testing /proc0/pib/chiplet@1a000000 26 +Testing /proc0/pib/chiplet@1b000000 27 +Testing /proc0/pib/chiplet@1c000000 28 +Testing /proc0/pib/chiplet@1d000000 29 +Testing /proc0/pib/chiplet@1e000000 30 +Testing /proc0/pib/chiplet@1f000000 31 +Testing /proc0/pib/chiplet@20000000 32 +Testing /proc0/pib/chiplet@21000000 33 +Testing /proc0/pib/chiplet@22000000 34 +Testing /proc0/pib/chiplet@23000000 35 +Testing /proc0/pib/chiplet@24000000 36 +Testing /proc0/pib/chiplet@25000000 37 +Testing /proc0/pib/chiplet@26000000 38 +Testing /proc0/pib/chiplet@27000000 39 +EOF + +test_run libpdbg_p10_fapi_translation_test chiplet + + +test_result 0 <<EOF +Testing /proc0/pib/chiplet@c000000/mc@0 0 +Testing /proc0/pib/chiplet@d000000/mc@1 1 +Testing /proc0/pib/chiplet@e000000/mc@2 2 +Testing /proc0/pib/chiplet@f000000/mc@3 3 +EOF + +test_run libpdbg_p10_fapi_translation_test mc + + +test_result 0 <<EOF +Testing /proc0/pib/chiplet@2000000/nmmu@0 0 +Testing /proc0/pib/chiplet@3000000/nmmu@1 1 +EOF + +test_run libpdbg_p10_fapi_translation_test nmmu + + +test_result 0 <<EOF +Testing /proc0/pib/chiplet@18000000/iohs@0 0 +Testing /proc0/pib/chiplet@19000000/iohs@1 1 +Testing /proc0/pib/chiplet@1a000000/iohs@2 2 +Testing /proc0/pib/chiplet@1b000000/iohs@3 3 +Testing /proc0/pib/chiplet@1c000000/iohs@4 4 +Testing /proc0/pib/chiplet@1d000000/iohs@5 5 +Testing /proc0/pib/chiplet@1e000000/iohs@6 6 +Testing /proc0/pib/chiplet@1f000000/iohs@7 7 +EOF + +test_run libpdbg_p10_fapi_translation_test iohs + + +test_result 0 <<EOF +Testing /proc0/pib/chiplet@10000000/pauc@0/pau@0 0 +Testing /proc0/pib/chiplet@11000000/pauc@1/pau@3 3 +Testing /proc0/pib/chiplet@12000000/pauc@2/pau@4 4 +Testing /proc0/pib/chiplet@12000000/pauc@2/pau@5 5 +Testing /proc0/pib/chiplet@13000000/pauc@3/pau@6 6 +Testing /proc0/pib/chiplet@13000000/pauc@3/pau@7 7 +EOF + +test_run libpdbg_p10_fapi_translation_test pau + + +test_result 0 <<EOF +Testing /proc0/pib/chiplet@10000000/pauc@0 0 +Testing /proc0/pib/chiplet@11000000/pauc@1 1 +Testing /proc0/pib/chiplet@12000000/pauc@2 2 +Testing /proc0/pib/chiplet@13000000/pauc@3 3 +EOF + +test_run libpdbg_p10_fapi_translation_test pauc