summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/hwas/common/hwasCommon.H141
-rw-r--r--src/usr/hwas/common/hwas.C645
-rw-r--r--src/usr/hwas/test/hwas1test.H826
-rw-r--r--src/usr/hwas/test/hwasGardTest.H20
4 files changed, 1477 insertions, 155 deletions
diff --git a/src/include/usr/hwas/common/hwasCommon.H b/src/include/usr/hwas/common/hwasCommon.H
index f9ffc9752..64002cf75 100644
--- a/src/include/usr/hwas/common/hwasCommon.H
+++ b/src/include/usr/hwas/common/hwasCommon.H
@@ -116,41 +116,122 @@ errlHndl_t platReadPartialGood(const TARGETING::TargetHandle_t &i_target,
void *o_pgData);
// constants the platReadPartialGood will use for looking at the VPD data
-const uint32_t VPD_CP00_PG_DATA_LENGTH = 64;
+const uint32_t VPD_CP00_PG_DATA_LENGTH = 128;
const uint32_t VPD_CP00_PG_HDR_LENGTH = 1;
+const uint32_t VPD_CP00_PG_DATA_ENTRIES = VPD_CP00_PG_DATA_LENGTH / 2;
// components of the partial good vector
-const uint32_t VPD_CP00_PG_PIB_INDEX = 0;
-const uint32_t VPD_CP00_PG_PIB_GOOD = 0x0000;
+// * = region does not exist in Nimbus
+// + = partial good region
+// '0' = region is good (NOTE: opposite of P8 where '1' represented good)
+// '1' = region is bad or does not exist
+
+const uint32_t VPD_CP00_PG_FSI_INDEX = 0;
+// all good - 4:FSI0, 5:FSI1, 6:FSIa
+const uint32_t VPD_CP00_PG_FSI_GOOD = 0xF1FF;
const uint32_t VPD_CP00_PG_PERVASIVE_INDEX = 1;
-// all good - 0:PRV, 1:NET, 2:PIB, 3:OCC, 7:PLL, 8:OSCSW - 0xF180
-const uint32_t VPD_CP00_PG_PERVASIVE_GOOD = 0xF180;
-
-const uint32_t VPD_CP00_PG_POWERBUS_INDEX = 2;
-// all good - 0:PRV, 1:PB, 2:NX, 3:PCIS, 4:MCL, 5:MCR - 0xFC00
-// base - 0:PRV, 1:PB, 2:NX, 3:PCIS - 0xF000
-// MCL - mcs-[0..3] - 0x0800
-// MCR - mcs-[4..7] - 0x0400
-const uint32_t VPD_CP00_PG_POWERBUS_BASE = 0xF000;
-const uint32_t VPD_CP00_PG_POWERBUS_MCL = 0x0800;
-const uint32_t VPD_CP00_PG_POWERBUS_MCR = 0x0400;
-
-const uint32_t VPD_CP00_PG_XBUS_INDEX = 4;
-// all good - 0:PRV, 1:IOX, 2:IOPCI, 3:XH - 0xF000
-const uint32_t VPD_CP00_PG_XBUS_GOOD = 0xF000;
-
-const uint32_t VPD_CP00_PG_ABUS_INDEX = 8;
-// all good - 0:PRV, 1:AB, 2:IOA, 7:PLL - 0xE100
-const uint32_t VPD_CP00_PG_ABUS_GOOD = 0xE100;
-
-const uint32_t VPD_CP00_PG_PCIE_INDEX = 9;
-// all good - 0:PRV, 1:PCI0, 2:PCI1, 3:PCI2, 5:IOPCI, 6:PBF, 7:PLL - 0xF700
-const uint32_t VPD_CP00_PG_PCIE_GOOD = 0xF700;
-
-const uint32_t VPD_CP00_PG_EX0_INDEX = 16;
-// all good - 0:PRV, 1:rC, 2:L2, 3:L3NP, 6:REFR, 7:DPLL - 0xF300
-const uint32_t VPD_CP00_PG_EX0_GOOD = 0xF300;
+// all good - 3:VITAL, 4:PRV, 5:NET, 6:PIB, 7:OCC, 8:ANPERV, 14:PLLNEST
+const uint32_t VPD_CP00_PG_PERVASIVE_GOOD = 0xE07D;
+
+const uint32_t VPD_CP00_PG_N0_INDEX = 2;
+// all good - 3:VITAL, 4:PRV, 5:NX, 6:CXA0, 7:PBIOE0, 8:PBIOE1, 9:PBIOE2
+const uint32_t VPD_CP00_PG_N0_GOOD = 0xE03F;
+
+const uint32_t VPD_CP00_PG_N1_INDEX = 3;
+// all good - 3:VITAL, 4:PRV, 5:MCD, 6:VA, 7:PBIOO0+, 8:PBIOO1+, 9:MCS23+
+const uint32_t VPD_CP00_PG_N1_GOOD = 0xE03F;
+const uint32_t VPD_CP00_PG_N1_PG_MASK = 0x01C0;
+const uint32_t VPD_CP00_PG_N1_PBIOO0 = 0x0100;
+const uint32_t VPD_CP00_PG_N1_PBIOO1 = 0x0080;
+const uint32_t VPD_CP00_PG_N1_MCS23 = 0x0040;
+
+const uint32_t VPD_CP00_PG_N2_INDEX = 4;
+// all good - 3:VITAL, 4:PRV, 5:CXA1, 6:PCIS0, 7:PCIS1, 8:PCIS2, 9:IOPSI
+const uint32_t VPD_CP00_PG_N2_GOOD = 0xE03F;
+
+const uint32_t VPD_CP00_PG_N3_INDEX = 5;
+// all good - 3:VITAL, 4:PRV, 5:PB, 6:BR, 7:NPU+, 8:MM, 9:INT, 10:MCS01+
+const uint32_t VPD_CP00_PG_N3_GOOD = 0xE01F;
+const uint32_t VPD_CP00_PG_N3_PG_MASK = 0x0120;
+const uint32_t VPD_CP00_PG_N3_NPU = 0x0100;
+const uint32_t VPD_CP00_PG_N3_MCS01 = 0x0020;
+
+const uint32_t VPD_CP00_PG_XBUS_INDEX = 6;
+// all good - 3:VITAL, 4:PRV, 5:IOX0*+, 6:IOX1+, 7:IOX2+,
+// 8:PBIOX0*, 9:PBIOX1, 10:PBIOX2, 14:PLLIOX
+const uint32_t VPD_CP00_PG_XBUS_GOOD = 0xE01D;
+const uint32_t VPD_CP00_PG_XBUS_PG_MASK = 0x07E0;
+const uint32_t VPD_CP00_PG_XBUS_IOX_PAIR[3] = {0x0480, 0x0240, 0x0120};
+
+const uint32_t VPD_CP00_PG_MCxx_INDEX[4] = {7, 7, 8, 8}; // by MCS
+// all good - 3:VITAL, 4:PRV, 5:MCA01, 6:IOM01+, 7:IOM23+, 14:PLLMEM
+// all good - 3:VITAL, 4:PRV, 5:MCA23, 6:IOM45+, 7:IOM67+, 14:PLLMEM
+const uint32_t VPD_CP00_PG_MCxx_GOOD = 0xE0FD;
+const uint32_t VPD_CP00_PG_MCxx_PG_MASK = 0x0300;
+const uint32_t VPD_CP00_PG_MCxx_IOMyy[4] = {0x0200, 0x0100, 0x0200, 0x0100};
+
+const uint32_t VPD_CP00_PG_OB0_INDEX = 9;
+const uint32_t VPD_CP00_PG_OB3_INDEX = 12;
+// all good - 3:VITAL, 4:PRV, 5:PLIOOAx, 6:IOOx, 14:PLLIOO; x=0, 1*, 2*, 3
+const uint32_t VPD_CP00_PG_OBUS_GOOD = 0xE1FD;
+
+const uint32_t VPD_CP00_PG_PCI0_INDEX = 13;
+// all good - 3:VITAL, 4:PRV, 5:PCI00, 6:IOPCI0, 14:PLLPCI0
+// all good - 3:VITAL, 4:PRV, 5:PCI11, 6:PCI12, 7:IOPCI1, 14:PLLPCI1
+// all good - 3:VITAL, 4:PRV, 5:PCI23, 6:PCI24, 7:PCI25, 8:IOPCI2, 14:PLLPCI2
+const uint32_t VPD_CP00_PG_PCIx_GOOD[3] = {0xE1FD, 0xE0FD, 0xE07D};
+
+const uint32_t VPD_CP00_PG_EP0_INDEX = 16;
+const uint32_t VPD_CP00_PG_EP5_INDEX = 21;
+// all good - 3:VITAL, 4:PRV, 5:EQPB, 6:L30+, 7:L31+,
+// 8:L20+, 9:L21+, 10:AN, 11:PBLEQ, 12:REFR0, 13:REFR1, 14:DPLL
+const uint32_t VPD_CP00_PG_EPx_GOOD = 0xE001;
+const uint32_t VPD_CP00_PG_EPx_PG_MASK = 0x03CC;
+const uint32_t VPD_CP00_PG_EPx_L3L2REFR[2] = {0x0288, 0x0144};
+
+const uint32_t VPD_CP00_PG_EC00_INDEX = 32;
+// all good - 3:VITAL, 4:PRV, 5:C00, 6:C01
+const uint32_t VPD_CP00_PG_ECxx_GOOD = 0xE1FF;
+
+const uint32_t VPD_CP00_PG_MAX_USED_INDEX = 55;
+const uint32_t VPD_CP00_PG_xxx_PERV = 0x0800;
+const uint32_t VPD_CP00_PG_RESERVED_GOOD = 0xFFFF;
+
+
+/**
+ * @brief Checks the PG keyword data to determine if the target chip is
+ * functional. The caller is responsible for allocating and de-allocating the
+ * PG keyword space.
+ *
+ * @param[in] i_target pointer to target that we're looking at
+ * @param[in] i_pgData pointer to area holding the PG keyword read from
+ * VPD; must be malloc'ed by the caller, and must be
+ * VPD_CP00_PG_DATA_LENGTH in size.
+ *
+ * @return bool Return true if the chip is functional; false if not.
+ *
+ */
+bool isChipFunctional(const TARGETING::TargetHandle_t &i_target,
+ const uint16_t i_pgData[VPD_CP00_PG_DATA_LENGTH]);
+
+
+/**
+ * @brief Checks the PG keyword data to determine if the descendant chiplet is
+ * functional. The caller is responsible for allocating and de-allocating the
+ * PG keyword space.
+ *
+ * @param[in] i_desc pointer to descendant of target we're looking at
+ * @param[in] i_pgData pointer to area holding the PG keyword read from
+ * VPD; must be malloc'ed by the caller, and must be
+ * VPD_CP00_PG_DATA_LENGTH in size.
+ *
+ * @return bool Return true if the descendant is functional; false if not.
+ *
+ */
+bool isDescFunctional(const TARGETING::TargetHandle_t &i_desc,
+ const uint16_t i_pgData[VPD_CP00_PG_DATA_LENGTH]);
+
/**
* @brief platform specific code to determine the PR vector of the input
diff --git a/src/usr/hwas/common/hwas.C b/src/usr/hwas/common/hwas.C
index c4f63126c..2e6445415 100644
--- a/src/usr/hwas/common/hwas.C
+++ b/src/usr/hwas/common/hwas.C
@@ -52,6 +52,7 @@
#include <hwas/common/hwas_reasoncodes.H>
#include <targeting/common/utilFilter.H>
+
namespace HWAS
{
@@ -117,6 +118,82 @@ void enableHwasState(Target *i_target,
}
+/**
+ * @brief simple helper fn to check IOX/PBIOX pairs in PG XBUS data
+ *
+ * @param[in] i_pgData XBUS data from PG keyword VPD
+ *
+ * @return bool pairs are valid
+ *
+ */
+bool areIoxPairsValid(uint16_t i_pgData)
+{
+ bool l_valid = true;
+
+ // Check that pairs are valid, that is, both good or both bad
+ for (uint8_t l_pair = 0;
+ l_pair <= 2;
+ l_pair++)
+ {
+ // Check if both are good in the pair
+ if ((i_pgData & VPD_CP00_PG_XBUS_IOX_PAIR[l_pair]) == 0)
+ {
+ continue;
+ }
+
+ // Check if both are bad in the pair
+ if ((i_pgData & VPD_CP00_PG_XBUS_IOX_PAIR[l_pair]) ==
+ VPD_CP00_PG_XBUS_IOX_PAIR[l_pair])
+ {
+ continue;
+ }
+
+ l_valid = false;
+ break;
+ }
+
+ return l_valid;
+}
+
+
+/**
+ * @brief simple helper fn to check L3/L2/REFR triplets in PG EPx data
+ *
+ * @param[in] i_pgData EPx data from PG keyword VPD
+ *
+ * @return bool triplets are valid
+ *
+ */
+bool areL3L2REFRtripletsValid(uint16_t i_pgData)
+{
+ bool l_valid = true;
+
+ // Check that triplets are valid, that is, all good or all bad
+ for (uint8_t l_triplet = 0;
+ l_triplet <= 1;
+ l_triplet++)
+ {
+ // Check if all are good in the triplet
+ if ((i_pgData & VPD_CP00_PG_EPx_L3L2REFR[l_triplet]) == 0)
+ {
+ continue;
+ }
+
+ // Check if all are bad in the triplet
+ if ((i_pgData & VPD_CP00_PG_EPx_L3L2REFR[l_triplet]) ==
+ VPD_CP00_PG_EPx_L3L2REFR[l_triplet])
+ {
+ continue;
+ }
+
+ l_valid = false;
+ break;
+ }
+
+ return l_valid;
+}
+
+
errlHndl_t discoverTargets()
{
HWAS_DBG("discoverTargets entry");
@@ -251,40 +328,13 @@ errlHndl_t discoverTargets()
// errl is now NULL
}
else
- // look at the 'nest' logic to override the functionality
- // of this proc
- if (pgData[VPD_CP00_PG_PIB_INDEX] !=
- VPD_CP00_PG_PIB_GOOD)
- {
- HWAS_INF("pTarget %.8X - PIB pgPdata[%d]: expected 0x%04X - bad",
- pTarget->getAttr<ATTR_HUID>(),
- VPD_CP00_PG_PIB_INDEX,
- VPD_CP00_PG_PIB_GOOD);
- chipFunctional = false;
- }
- else
- if (pgData[VPD_CP00_PG_PERVASIVE_INDEX] !=
- VPD_CP00_PG_PERVASIVE_GOOD)
- {
- HWAS_INF("pTarget %.8X - Pervasive pgPdata[%d]: expected 0x%04X - bad",
- pTarget->getAttr<ATTR_HUID>(),
- VPD_CP00_PG_PERVASIVE_INDEX,
- VPD_CP00_PG_PERVASIVE_GOOD);
- chipFunctional = false;
- }
- else
- if ((pgData[VPD_CP00_PG_POWERBUS_INDEX] &
- VPD_CP00_PG_POWERBUS_BASE) !=
- VPD_CP00_PG_POWERBUS_BASE)
- {
- HWAS_INF("pTarget %.8X - PowerBus pgPdata[%d]: expected 0x%04X - bad",
- pTarget->getAttr<ATTR_HUID>(),
- VPD_CP00_PG_POWERBUS_INDEX,
- VPD_CP00_PG_POWERBUS_BASE);
- chipFunctional = false;
- }
- else
{
+ // look at the 'nest' logic to override the functionality
+ // of this proc
+ chipFunctional = isChipFunctional(pTarget, pgData);
+
+ if (chipFunctional)
+ {
// read the PR keywords that we need, so that if
// we have errors, we can handle them as approprite.
uint8_t prData[VPD_VINI_PR_DATA_LENGTH/sizeof(uint8_t)];
@@ -324,6 +374,7 @@ errlHndl_t discoverTargets()
pTarget->getAttr<ATTR_HUID>());
}
}
+ }
}
} // TYPE_PROC
} // CLASS_CHIP
@@ -346,87 +397,11 @@ errlHndl_t discoverTargets()
bool descFunctional = chipFunctional;
if (chipFunctional)
- { // if the chip is functional, the look through the
+ { // if the chip is functional, then look through the
// partialGood vector to see if its chiplets
// are functional
- if ((pDesc->getAttr<ATTR_TYPE>() == TYPE_XBUS) &&
- (pgData[VPD_CP00_PG_XBUS_INDEX] !=
- VPD_CP00_PG_XBUS_GOOD))
- {
- HWAS_INF("pDesc %.8X - XBUS pgPdata[%d]: expected 0x%04X - bad",
- pDesc->getAttr<ATTR_HUID>(),
- VPD_CP00_PG_XBUS_INDEX,
- VPD_CP00_PG_XBUS_GOOD);
- descFunctional = false;
- }
- else
- if ((pDesc->getAttr<ATTR_TYPE>() == TYPE_ABUS) &&
- (pgData[VPD_CP00_PG_ABUS_INDEX] !=
- VPD_CP00_PG_ABUS_GOOD))
- {
- HWAS_INF("pDesc %.8X - ABUS pgPdata[%d]: expected 0x%04X - bad",
- pDesc->getAttr<ATTR_HUID>(),
- VPD_CP00_PG_ABUS_INDEX,
- VPD_CP00_PG_ABUS_GOOD);
- descFunctional = false;
- }
- else
- if ((pDesc->getAttr<ATTR_TYPE>() == TYPE_PCI) &&
- (pgData[VPD_CP00_PG_PCIE_INDEX] !=
- VPD_CP00_PG_PCIE_GOOD))
- {
- HWAS_INF("pDesc %.8X - PCIe pgPdata[%d]: expected 0x%04X - bad",
- pDesc->getAttr<ATTR_HUID>(),
- VPD_CP00_PG_PCIE_INDEX,
- VPD_CP00_PG_PCIE_GOOD);
- descFunctional = false;
- }
- else
- if ((pDesc->getAttr<ATTR_TYPE>() == TYPE_EX) ||
- (pDesc->getAttr<ATTR_TYPE>() == TYPE_CORE)
- )
- {
- ATTR_CHIP_UNIT_type indexEX =
- pDesc->getAttr<ATTR_CHIP_UNIT>();
- if (pgData[VPD_CP00_PG_EX0_INDEX + indexEX] !=
- VPD_CP00_PG_EX0_GOOD)
- {
- HWAS_INF("pDesc %.8X - CORE/EX%d pgPdata[%d]: expected 0x%04X - bad",
- pDesc->getAttr<ATTR_HUID>(), indexEX,
- VPD_CP00_PG_EX0_INDEX + indexEX,
- VPD_CP00_PG_EX0_GOOD);
- descFunctional = false;
- }
- }
- else
- if (pDesc->getAttr<ATTR_TYPE>() == TYPE_MCS)
- {
- ATTR_CHIP_UNIT_type indexMCS =
- pDesc->getAttr<ATTR_CHIP_UNIT>();
- // check: MCS 0..3 in MCL, MCS 4..7 in MCR
- if (((indexMCS >=0) && (indexMCS <=3)) &&
- ((pgData[VPD_CP00_PG_POWERBUS_INDEX] &
- VPD_CP00_PG_POWERBUS_MCL) == 0))
- {
- HWAS_INF("pDesc %.8X - MCS%d pgPdata[%d]: MCL expected 0x%04X - bad",
- pDesc->getAttr<ATTR_HUID>(), indexMCS,
- VPD_CP00_PG_POWERBUS_INDEX,
- VPD_CP00_PG_POWERBUS_MCL);
- descFunctional = false;
- }
- else
- if (((indexMCS >=4) && (indexMCS <=7)) &&
- ((pgData[VPD_CP00_PG_POWERBUS_INDEX] &
- VPD_CP00_PG_POWERBUS_MCR) == 0))
- {
- HWAS_INF("pDesc %.8X - MCS%d pgPdata[%d]: MCR expected 0x%04X - bad",
- pDesc->getAttr<ATTR_HUID>(), indexMCS,
- VPD_CP00_PG_POWERBUS_INDEX,
- VPD_CP00_PG_POWERBUS_MCR);
- descFunctional = false;
- }
- }
- } // chipFunctional
+ descFunctional = isDescFunctional(pDesc, pgData);
+ }
// for sub-parts, if it's not functional, it's not present.
enableHwasState(pDesc, descFunctional, descFunctional,
@@ -500,6 +475,450 @@ errlHndl_t discoverTargets()
} // discoverTargets
+bool isChipFunctional(const TARGETING::TargetHandle_t &i_target,
+ const uint16_t i_pgData[])
+{
+ bool l_chipFunctional = true;
+
+ // Check all bits in FSI entry
+ if (i_pgData[VPD_CP00_PG_FSI_INDEX] !=
+ VPD_CP00_PG_FSI_GOOD)
+ {
+ HWAS_INF("pTarget %.8X - FSI pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_target->getAttr<ATTR_HUID>(),
+ VPD_CP00_PG_FSI_INDEX,
+ i_pgData[VPD_CP00_PG_FSI_INDEX],
+ VPD_CP00_PG_FSI_GOOD);
+ l_chipFunctional = false;
+ }
+ else
+ // Check all bits in PRV entry
+ if (i_pgData[VPD_CP00_PG_PERVASIVE_INDEX] !=
+ VPD_CP00_PG_PERVASIVE_GOOD)
+ {
+ HWAS_INF("pTarget %.8X - Pervasive pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_target->getAttr<ATTR_HUID>(),
+ VPD_CP00_PG_PERVASIVE_INDEX,
+ i_pgData[VPD_CP00_PG_PERVASIVE_INDEX],
+ VPD_CP00_PG_PERVASIVE_GOOD);
+ l_chipFunctional = false;
+ }
+ else
+ // Check all bits in N0 entry
+ if (i_pgData[VPD_CP00_PG_N0_INDEX] != VPD_CP00_PG_N0_GOOD)
+ {
+ HWAS_INF("pTarget %.8X - N0 pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_target->getAttr<ATTR_HUID>(),
+ VPD_CP00_PG_N0_INDEX,
+ i_pgData[VPD_CP00_PG_N0_INDEX],
+ VPD_CP00_PG_N0_GOOD);
+ l_chipFunctional = false;
+ }
+ else
+ // Check bits in N1 entry except those in partial good region
+ if ((i_pgData[VPD_CP00_PG_N1_INDEX] &
+ ~VPD_CP00_PG_N1_PG_MASK) != VPD_CP00_PG_N1_GOOD)
+ {
+ HWAS_INF("pTarget %.8X - N1 pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_target->getAttr<ATTR_HUID>(),
+ VPD_CP00_PG_N1_INDEX,
+ i_pgData[VPD_CP00_PG_N1_INDEX],
+ VPD_CP00_PG_N1_GOOD);
+ l_chipFunctional = false;
+ }
+ else
+ // Check all bits in N2 entry
+ if (i_pgData[VPD_CP00_PG_N2_INDEX] != VPD_CP00_PG_N2_GOOD)
+ {
+ HWAS_INF("pTarget %.8X - N2 pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_target->getAttr<ATTR_HUID>(),
+ VPD_CP00_PG_N2_INDEX,
+ i_pgData[VPD_CP00_PG_N2_INDEX],
+ VPD_CP00_PG_N2_GOOD);
+ l_chipFunctional = false;
+ }
+ else
+ // Check bits in N3 entry except those in partial good region
+ if ((i_pgData[VPD_CP00_PG_N3_INDEX] &
+ ~VPD_CP00_PG_N3_PG_MASK) != VPD_CP00_PG_N3_GOOD)
+ {
+ HWAS_INF("pTarget %.8X - N3 pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_target->getAttr<ATTR_HUID>(),
+ VPD_CP00_PG_N3_INDEX,
+ i_pgData[VPD_CP00_PG_N3_INDEX],
+ VPD_CP00_PG_N3_GOOD);
+ l_chipFunctional = false;
+ }
+ else
+ // Check bits in XBUS entry, validating pairs in partial good region
+ if (((i_pgData[VPD_CP00_PG_XBUS_INDEX] &
+ ~VPD_CP00_PG_XBUS_PG_MASK) != VPD_CP00_PG_XBUS_GOOD)
+ ||
+ (!areIoxPairsValid(i_pgData[VPD_CP00_PG_XBUS_INDEX])))
+ {
+ HWAS_INF("pTarget %.8X - XBUS pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_target->getAttr<ATTR_HUID>(),
+ VPD_CP00_PG_XBUS_INDEX,
+ i_pgData[VPD_CP00_PG_XBUS_INDEX],
+ VPD_CP00_PG_XBUS_GOOD);
+ l_chipFunctional = false;
+ }
+
+ return l_chipFunctional;
+} // isChipFunctional
+
+
+bool isDescFunctional(const TARGETING::TargetHandle_t &i_desc,
+ const uint16_t i_pgData[])
+{
+ bool l_descFunctional = true;
+
+ if (i_desc->getAttr<ATTR_TYPE>() == TYPE_XBUS)
+ {
+ ATTR_CHIP_UNIT_type indexXB =
+ i_desc->getAttr<ATTR_CHIP_UNIT>();
+ // Check pair of bits in XBUS entry
+ if ((i_pgData[VPD_CP00_PG_XBUS_INDEX] &
+ VPD_CP00_PG_XBUS_IOX_PAIR[indexXB]) != 0)
+ {
+ HWAS_INF("pDesc %.8X - XBUS%d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexXB,
+ VPD_CP00_PG_XBUS_INDEX,
+ i_pgData[VPD_CP00_PG_XBUS_INDEX],
+ (i_pgData[VPD_CP00_PG_XBUS_INDEX] &
+ ~VPD_CP00_PG_XBUS_IOX_PAIR[indexXB]));
+ l_descFunctional = false;
+ }
+ }
+ else
+ if (i_desc->getAttr<ATTR_TYPE>() == TYPE_OBUS)
+ {
+ ATTR_CHIP_UNIT_type indexOB =
+ i_desc->getAttr<ATTR_CHIP_UNIT>();
+ // Check all bits in OBUSx entry
+ if (i_pgData[VPD_CP00_PG_OB0_INDEX + indexOB] !=
+ VPD_CP00_PG_OBUS_GOOD)
+ {
+ HWAS_INF("pDesc %.8X - OB%d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexOB,
+ VPD_CP00_PG_OB0_INDEX + indexOB,
+ i_pgData[VPD_CP00_PG_OB0_INDEX + indexOB],
+ VPD_CP00_PG_OBUS_GOOD);
+ l_descFunctional = false;
+ }
+ else
+ // Check PBIOO0 bit in N1 entry
+ // @TODO RTC:134608 PBIOO0 seems to be good with Nimbus and Cumulus
+ // except Nimbus Sforza (without optics and NVLINK)
+ // so is it associated with all OBUS entries or just
+ // with OBUS0 and OBUS3 -- verify this
+ if ((i_pgData[VPD_CP00_PG_N1_INDEX] &
+ VPD_CP00_PG_N1_PBIOO0) != 0)
+ {
+ HWAS_INF("pDesc %.8X - OB%d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexOB,
+ VPD_CP00_PG_N1_INDEX,
+ i_pgData[VPD_CP00_PG_N1_INDEX],
+ (i_pgData[VPD_CP00_PG_N1_INDEX] &
+ ~VPD_CP00_PG_N1_PBIOO0));
+ l_descFunctional = false;
+ }
+ else
+ // Check PBIOO1 bit in N1 entry if second or third OBUS
+ // @TODO RTC:134608 PBIOO1 seems to be associated with OBUS1 and OBUS2
+ // which only are valid on a Cumulus -- verify this
+ if (((1 == indexOB) || (2 == indexOB)) &&
+ ((i_pgData[VPD_CP00_PG_N1_INDEX] &
+ VPD_CP00_PG_N1_PBIOO1) != 0))
+ {
+ HWAS_INF("pDesc %.8X - OB%d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexOB,
+ VPD_CP00_PG_N1_INDEX,
+ i_pgData[VPD_CP00_PG_N1_INDEX],
+ (i_pgData[VPD_CP00_PG_N1_INDEX] &
+ ~VPD_CP00_PG_N1_PBIOO1));
+ l_descFunctional = false;
+ }
+ }
+ else
+ if (i_desc->getAttr<ATTR_TYPE>() == TYPE_PEC)
+ {
+ ATTR_CHIP_UNIT_type indexPCI =
+ i_desc->getAttr<ATTR_CHIP_UNIT>();
+ // Check all bits in PCIx entry
+ if (i_pgData[VPD_CP00_PG_PCI0_INDEX + indexPCI] !=
+ VPD_CP00_PG_PCIx_GOOD[indexPCI])
+ {
+ HWAS_INF("pDesc %.8X - PCI%d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexPCI,
+ VPD_CP00_PG_PCI0_INDEX + indexPCI,
+ i_pgData[VPD_CP00_PG_PCI0_INDEX + indexPCI],
+ VPD_CP00_PG_PCIx_GOOD[indexPCI]);
+ l_descFunctional = false;
+ }
+ }
+ else
+ if (i_desc->getAttr<ATTR_TYPE>() == TYPE_EQ)
+ {
+ ATTR_CHIP_UNIT_type indexEP =
+ i_desc->getAttr<ATTR_CHIP_UNIT>();
+ // Check bits in EPx entry, validating triplets in partial good region
+ if (((i_pgData[VPD_CP00_PG_EP0_INDEX + indexEP]
+ & ~VPD_CP00_PG_EPx_PG_MASK) !=
+ VPD_CP00_PG_EPx_GOOD) ||
+ (!areL3L2REFRtripletsValid(i_pgData[VPD_CP00_PG_EP0_INDEX +
+ indexEP])))
+ {
+ HWAS_INF("pDesc %.8X - EQ%d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexEP,
+ VPD_CP00_PG_EP0_INDEX + indexEP,
+ i_pgData[VPD_CP00_PG_EP0_INDEX + indexEP],
+ VPD_CP00_PG_EPx_GOOD);
+ l_descFunctional = false;
+ }
+ }
+ else
+ if (i_desc->getAttr<ATTR_TYPE>() == TYPE_EX)
+ {
+ ATTR_CHIP_UNIT_type indexEX =
+ i_desc->getAttr<ATTR_CHIP_UNIT>();
+ // 2 EX chiplets per EP/EQ chiplet
+ size_t indexEP = indexEX / 2;
+ // 2 L3/L2/REFR triplets per EX chiplet
+ size_t indexL3L2REFR = indexEX % 2;
+ // Check triplet of bits in EPx entry
+ if ((i_pgData[VPD_CP00_PG_EP0_INDEX + indexEP] &
+ VPD_CP00_PG_EPx_L3L2REFR[indexL3L2REFR]) != 0)
+ {
+ HWAS_INF("pDesc %.8X - EX%d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexEX,
+ VPD_CP00_PG_EP0_INDEX + indexEP,
+ i_pgData[VPD_CP00_PG_EP0_INDEX + indexEP],
+ (i_pgData[VPD_CP00_PG_EP0_INDEX + indexEP] &
+ ~VPD_CP00_PG_EPx_L3L2REFR[indexL3L2REFR]));
+ l_descFunctional = false;
+ }
+ }
+ else
+ if (i_desc->getAttr<ATTR_TYPE>() == TYPE_CORE)
+ {
+ ATTR_CHIP_UNIT_type indexEC =
+ i_desc->getAttr<ATTR_CHIP_UNIT>();
+ // Check all bits in ECxx entry
+ if (i_pgData[VPD_CP00_PG_EC00_INDEX + indexEC] !=
+ VPD_CP00_PG_ECxx_GOOD)
+ {
+ HWAS_INF("pDesc %.8X - CORE/EC%2.2d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexEC,
+ VPD_CP00_PG_EC00_INDEX + indexEC,
+ i_pgData[VPD_CP00_PG_EC00_INDEX + indexEC],
+ VPD_CP00_PG_ECxx_GOOD);
+ l_descFunctional = false;
+ }
+ }
+ else
+ if (i_desc->getAttr<ATTR_TYPE>() == TYPE_MCBIST)
+ {
+ ATTR_CHIP_UNIT_type indexMCBIST =
+ i_desc->getAttr<ATTR_CHIP_UNIT>();
+ // 2 MCS chiplets per MCBIST / MCU
+ size_t indexMCS = indexMCBIST * 2;
+ // Check MCS01 bit in N3 entry if first MCBIST / MCU
+ if ((0 == indexMCBIST) &&
+ ((i_pgData[VPD_CP00_PG_N3_INDEX] &
+ VPD_CP00_PG_N3_MCS01) != 0))
+ {
+ HWAS_INF("pDesc %.8X - MCBIST%d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexMCBIST,
+ VPD_CP00_PG_N3_INDEX,
+ i_pgData[VPD_CP00_PG_N3_INDEX],
+ (i_pgData[VPD_CP00_PG_N3_INDEX] &
+ ~VPD_CP00_PG_N3_MCS01));
+ l_descFunctional = false;
+ }
+ else
+ // Check MCS23 bit in N1 entry if second MCBIST / MCU
+ if ((1 == indexMCBIST) &&
+ ((i_pgData[VPD_CP00_PG_N1_INDEX] &
+ VPD_CP00_PG_N1_MCS23) != 0))
+ {
+ HWAS_INF("pDesc %.8X - MCBIST%d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexMCBIST,
+ VPD_CP00_PG_N1_INDEX,
+ i_pgData[VPD_CP00_PG_N1_INDEX],
+ (i_pgData[VPD_CP00_PG_N1_INDEX] &
+ ~VPD_CP00_PG_N1_MCS23));
+ l_descFunctional = false;
+ }
+ else
+ // Check bits in MCxx entry except those in partial good region
+ if ((i_pgData[VPD_CP00_PG_MCxx_INDEX[indexMCS]]
+ & ~VPD_CP00_PG_MCxx_PG_MASK) !=
+ VPD_CP00_PG_MCxx_GOOD)
+ {
+ HWAS_INF("pDesc %.8X - MCBIST%d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexMCBIST,
+ VPD_CP00_PG_MCxx_INDEX[indexMCS],
+ i_pgData[VPD_CP00_PG_MCxx_INDEX[indexMCS]],
+ VPD_CP00_PG_MCxx_GOOD);
+ l_descFunctional = false;
+ }
+ }
+ else
+ if (i_desc->getAttr<ATTR_TYPE>() == TYPE_MCS)
+ {
+ ATTR_CHIP_UNIT_type indexMCS =
+ i_desc->getAttr<ATTR_CHIP_UNIT>();
+ // Check MCS01 bit in N3 entry if first or second MCS
+ if (((0 == indexMCS) || (1 == indexMCS)) &&
+ ((i_pgData[VPD_CP00_PG_N3_INDEX] &
+ VPD_CP00_PG_N3_MCS01) != 0))
+ {
+ HWAS_INF("pDesc %.8X - MCS%d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexMCS,
+ VPD_CP00_PG_N3_INDEX,
+ i_pgData[VPD_CP00_PG_N3_INDEX],
+ (i_pgData[VPD_CP00_PG_N3_INDEX] &
+ ~VPD_CP00_PG_N3_MCS01));
+ l_descFunctional = false;
+ }
+ else
+ // Check MCS23 bit in N1 entry if third or fourth MCS
+ if (((2 == indexMCS) || (3 == indexMCS)) &&
+ ((i_pgData[VPD_CP00_PG_N1_INDEX] &
+ VPD_CP00_PG_N1_MCS23) != 0))
+ {
+ HWAS_INF("pDesc %.8X - MCS%d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexMCS,
+ VPD_CP00_PG_N1_INDEX,
+ i_pgData[VPD_CP00_PG_N1_INDEX],
+ (i_pgData[VPD_CP00_PG_N1_INDEX] &
+ ~VPD_CP00_PG_N1_MCS23));
+ l_descFunctional = false;
+ }
+ else
+ // Check bits in MCxx entry including specific IOM bit,
+ // but not other bits in partial good region
+ if ((i_pgData[VPD_CP00_PG_MCxx_INDEX[indexMCS]]
+ & ~(VPD_CP00_PG_MCxx_PG_MASK
+ & ~VPD_CP00_PG_MCxx_IOMyy[indexMCS])) !=
+ VPD_CP00_PG_MCxx_GOOD)
+ {
+ HWAS_INF("pDesc %.8X - MCS%d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexMCS,
+ VPD_CP00_PG_MCxx_INDEX[indexMCS],
+ i_pgData[VPD_CP00_PG_MCxx_INDEX[indexMCS]],
+ (i_pgData[VPD_CP00_PG_MCxx_INDEX[indexMCS]] &
+ ~VPD_CP00_PG_MCxx_IOMyy[indexMCS]));
+ l_descFunctional = false;
+ }
+ }
+ else
+ if (i_desc->getAttr<ATTR_TYPE>() == TYPE_MCA)
+ {
+ ATTR_CHIP_UNIT_type indexMCA =
+ i_desc->getAttr<ATTR_CHIP_UNIT>();
+ // 2 MCA chiplets per MCS
+ size_t indexMCS = indexMCA / 2;
+ // Check IOM bit in MCxx entry
+ if ((i_pgData[VPD_CP00_PG_MCxx_INDEX[indexMCS]]
+ & VPD_CP00_PG_MCxx_IOMyy[indexMCS]) != 0)
+ {
+ HWAS_INF("pDesc %.8X - MCA%d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexMCA,
+ VPD_CP00_PG_MCxx_INDEX[indexMCS],
+ i_pgData[VPD_CP00_PG_MCxx_INDEX[indexMCS]],
+ (i_pgData[VPD_CP00_PG_MCxx_INDEX[indexMCS]] &
+ ~VPD_CP00_PG_MCxx_IOMyy[indexMCS]));
+ l_descFunctional = false;
+ }
+ }
+ else
+ if (i_desc->getAttr<ATTR_TYPE>() == TYPE_NVBUS)
+ {
+ // Check NPU bit in N3 entry
+ if ((i_pgData[VPD_CP00_PG_N3_INDEX] &
+ VPD_CP00_PG_N3_NPU) != 0)
+ {
+ HWAS_INF("pDesc %.8X - NVBUS pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(),
+ VPD_CP00_PG_N3_INDEX,
+ i_pgData[VPD_CP00_PG_N3_INDEX],
+ (i_pgData[VPD_CP00_PG_N3_INDEX] &
+ ~VPD_CP00_PG_N3_NPU));
+ l_descFunctional = false;
+ }
+ }
+ else
+ if (i_desc->getAttr<ATTR_TYPE>() == TYPE_PERV)
+ {
+ // Loop through PG entries from PRV entry to last used entry
+ for (uint8_t l_pgDataIndex =
+ VPD_CP00_PG_PERVASIVE_INDEX;
+ l_pgDataIndex <= VPD_CP00_PG_MAX_USED_INDEX;
+ ++l_pgDataIndex)
+ {
+ // Skip reserved entries between EP5 entry and EC00 entry
+ if ((l_pgDataIndex > VPD_CP00_PG_EP5_INDEX) &&
+ (l_pgDataIndex < VPD_CP00_PG_EC00_INDEX))
+ {
+ continue;
+ }
+
+ // Skip OB1 and OB2 entries on NIMBUS (region doesn't exist)
+ if ((i_desc->getAttr<ATTR_MODEL>() ==
+ MODEL_NIMBUS) &&
+ (l_pgDataIndex > VPD_CP00_PG_OB0_INDEX) &&
+ (l_pgDataIndex < VPD_CP00_PG_OB3_INDEX))
+ {
+ continue;
+ }
+
+ // Check PERV bit in the entry
+ if ((i_pgData[l_pgDataIndex]
+ & VPD_CP00_PG_xxx_PERV) != 0)
+ {
+ HWAS_INF("pDesc %.8X - PERV pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(),
+ l_pgDataIndex,
+ i_pgData[l_pgDataIndex],
+ (i_pgData[l_pgDataIndex] &
+ ~VPD_CP00_PG_xxx_PERV));
+ l_descFunctional = false;
+ break;
+ }
+ }
+ }
+
+ return l_descFunctional;
+} // isDescFunctional
+
+
+
errlHndl_t restrictEXunits(
std::vector <procRestrict_t> &i_procList,
const bool i_present,
@@ -998,7 +1417,7 @@ errlHndl_t checkMinimumHardware(const TARGETING::ConstTargetHandle_t i_nodeOrSys
if (l_dimms.empty())
{
HWAS_ERR( "Insufficient hardware to continue IPL (func DIMM)");
-
+
if(o_bootable)
{
*o_bootable = false;
diff --git a/src/usr/hwas/test/hwas1test.H b/src/usr/hwas/test/hwas1test.H
index f1d5cf2a2..cb102e3f3 100644
--- a/src/usr/hwas/test/hwas1test.H
+++ b/src/usr/hwas/test/hwas1test.H
@@ -5,7 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* COPYRIGHT International Business Machines Corp. 2011,2014 */
+/* Contributors Listed Below - COPYRIGHT 2011,2015 */
+/* [+] International Business Machines Corp. */
+/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
@@ -48,6 +50,75 @@
#include <hwas/common/hwas.H>
#include <hwas/common/hwasCommon.H>
#include <targeting/common/commontargeting.H>
+#include <targeting/common/utilFilter.H>
+
+
+// Buffer with all good data (CUMULUS chip)
+const uint16_t pgDataAllGood[HWAS::VPD_CP00_PG_DATA_ENTRIES] =
+ {(uint16_t)HWAS::VPD_CP00_PG_FSI_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_PERVASIVE_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_N0_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_N1_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_N2_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_N3_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_XBUS_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_MCxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_MCxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_OBUS_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_OBUS_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_OBUS_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_OBUS_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_PCIx_GOOD[0],
+ (uint16_t)HWAS::VPD_CP00_PG_PCIx_GOOD[1],
+ (uint16_t)HWAS::VPD_CP00_PG_PCIx_GOOD[2],
+ (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_EPx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_ECxx_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD,
+ (uint16_t)HWAS::VPD_CP00_PG_RESERVED_GOOD};
class HWAS1test: public CxxTest::TestSuite
{
@@ -189,7 +260,7 @@ public:
Target* pSys;
targetService().getTopLevelTarget(pSys);
- uint8_t pgData[64];
+ uint8_t pgData[HWAS::VPD_CP00_PG_DATA_LENGTH];
l_errl = HWAS::platReadPartialGood(pSys, pgData);
@@ -207,6 +278,757 @@ public:
TS_TRACE( "testHWASplatReadPartialGood exit" );
}
+ /**
+ * @brief test isChipFunctional
+ */
+ void testHWASisChipFunctional()
+ {
+ using namespace HWAS;
+ using namespace TARGETING;
+
+ TS_TRACE( "testHWASisChipFunctional entry" );
+
+ // Get list of all targets with type PROC
+ TargetHandleList allProcs;
+ getAllChips( allProcs, TYPE_PROC, false );
+
+ for (TargetHandleList::const_iterator pTarget_it = allProcs.begin();
+ pTarget_it != allProcs.end();
+ ++pTarget_it
+ )
+ {
+ TargetHandle_t pTarget = *pTarget_it;
+ ATTR_MODEL_type l_model = pTarget->getAttr<ATTR_MODEL>();
+ uint16_t l_xbus = (MODEL_NIMBUS == l_model)
+ ? (uint16_t)(VPD_CP00_PG_XBUS_GOOD |
+ VPD_CP00_PG_XBUS_IOX_PAIR[0])
+ : (uint16_t)VPD_CP00_PG_XBUS_GOOD;
+ uint16_t l_obus12 = (MODEL_NIMBUS == l_model)
+ ? (uint16_t)VPD_CP00_PG_RESERVED_GOOD
+ : (uint16_t)VPD_CP00_PG_OBUS_GOOD;
+ uint16_t pgData[VPD_CP00_PG_DATA_ENTRIES];
+ memcpy(pgData,
+ pgDataAllGood,
+ VPD_CP00_PG_DATA_LENGTH);
+ pgData[VPD_CP00_PG_XBUS_INDEX] = l_xbus;
+ pgData[VPD_CP00_PG_OB0_INDEX + 1] = l_obus12;
+ pgData[VPD_CP00_PG_OB0_INDEX + 2] = l_obus12;
+ uint16_t l_mask = 0x8000;
+
+ TS_TRACE( "testHWASisChipFunctional: chip is functional");
+ if (!isChipFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisChipFunctional>"
+ "functional = 0x%x, should be true.",
+ isChipFunctional(pTarget, pgData));
+ }
+
+ TS_TRACE( "testHWASisChipFunctional: partial good all bad");
+ pgData[VPD_CP00_PG_N1_INDEX] |= VPD_CP00_PG_N1_PG_MASK;
+ pgData[VPD_CP00_PG_N3_INDEX] |= VPD_CP00_PG_N3_PG_MASK;
+ pgData[VPD_CP00_PG_XBUS_INDEX] |= VPD_CP00_PG_XBUS_PG_MASK;
+
+ if (!isChipFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisChipFunctional>"
+ "functional = 0x%x, should be true.",
+ isChipFunctional(pTarget, pgData));
+ }
+
+ pgData[VPD_CP00_PG_N1_INDEX] &= ~VPD_CP00_PG_N1_PG_MASK;
+ pgData[VPD_CP00_PG_N3_INDEX] &= ~VPD_CP00_PG_N3_PG_MASK;
+ pgData[VPD_CP00_PG_XBUS_INDEX] = l_xbus;
+
+ TS_TRACE( "testHWASisChipFunctional: FSI is not functional");
+ for (l_mask = 0x8000;
+ l_mask > 0;
+ l_mask >>= 1)
+ {
+ if (pgData[VPD_CP00_PG_FSI_INDEX] & l_mask)
+ {
+ // Turn off a bit that should be on
+ pgData[VPD_CP00_PG_FSI_INDEX] &= ~l_mask;
+ }
+ else
+ {
+ // Turn on a bit that should be off
+ pgData[VPD_CP00_PG_FSI_INDEX] |= l_mask;
+ }
+
+ if (isChipFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisChipFunctional>"
+ "functional = 0x%x, should be false.",
+ isChipFunctional(pTarget, pgData));
+ }
+
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_FSI_INDEX] =
+ (uint16_t)VPD_CP00_PG_FSI_GOOD;
+ }
+
+ TS_TRACE( "testHWASisChipFunctional: PRV is not functional");
+ for (l_mask = 0x8000;
+ l_mask > 0;
+ l_mask >>= 1)
+ {
+ if (pgData[VPD_CP00_PG_PERVASIVE_INDEX] & l_mask)
+ {
+ // Turn off a bit that should be on
+ pgData[VPD_CP00_PG_PERVASIVE_INDEX] &= ~l_mask;
+ }
+ else
+ {
+ // Turn on a bit that should be off
+ pgData[VPD_CP00_PG_PERVASIVE_INDEX] |= l_mask;
+ }
+
+ if (isChipFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisChipFunctional>"
+ "functional = 0x%x, should be false.",
+ isChipFunctional(pTarget, pgData));
+ }
+
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_PERVASIVE_INDEX] =
+ (uint16_t)VPD_CP00_PG_PERVASIVE_GOOD;
+ }
+
+ TS_TRACE( "testHWASisChipFunctional: N0 is not functional");
+ for (l_mask = 0x8000;
+ l_mask > 0;
+ l_mask >>= 1)
+ {
+ if (pgData[VPD_CP00_PG_N0_INDEX] & l_mask)
+ {
+ // Turn off a bit that should be on
+ pgData[VPD_CP00_PG_N0_INDEX] &= ~l_mask;
+ }
+ else
+ {
+ // Turn on a bit that should be off
+ pgData[VPD_CP00_PG_N0_INDEX] |= l_mask;
+ }
+
+ if (isChipFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisChipFunctional>"
+ "functional = 0x%x, should be false.",
+ isChipFunctional(pTarget, pgData));
+ }
+
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_N0_INDEX] =
+ (uint16_t)VPD_CP00_PG_N0_GOOD;
+ }
+
+ TS_TRACE( "testHWASisChipFunctional: N1 is not functional");
+ for (l_mask = 0x8000;
+ l_mask > 0;
+ l_mask >>= 1)
+ {
+ if ((uint16_t)VPD_CP00_PG_N1_PG_MASK & l_mask)
+ {
+ // Ignore partial good region
+ continue;
+ }
+ else
+ if (pgData[VPD_CP00_PG_N1_INDEX] & l_mask)
+ {
+ // Turn off a bit that should be on
+ pgData[VPD_CP00_PG_N1_INDEX] &= ~l_mask;
+ }
+ else
+ {
+ // Turn on a bit that should be off
+ pgData[VPD_CP00_PG_N1_INDEX] |= l_mask;
+ }
+
+ if (isChipFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisChipFunctional>"
+ "functional = 0x%x, should be false.",
+ isChipFunctional(pTarget, pgData));
+ }
+
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_N1_INDEX] =
+ (uint16_t)VPD_CP00_PG_N1_GOOD;
+ }
+
+ TS_TRACE( "testHWASisChipFunctional: N2 is not functional");
+ for (l_mask = 0x8000;
+ l_mask > 0;
+ l_mask >>= 1)
+ {
+ if (pgData[VPD_CP00_PG_N2_INDEX] & l_mask)
+ {
+ // Turn off a bit that should be on
+ pgData[VPD_CP00_PG_N2_INDEX] &= ~l_mask;
+ }
+ else
+ {
+ // Turn on a bit that should be off
+ pgData[VPD_CP00_PG_N2_INDEX] |= l_mask;
+ }
+
+ if (isChipFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisChipFunctional>"
+ "functional = 0x%x, should be false.",
+ isChipFunctional(pTarget, pgData));
+ }
+
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_N2_INDEX] =
+ (uint16_t)VPD_CP00_PG_N2_GOOD;
+ }
+
+ TS_TRACE( "testHWASisChipFunctional: N3 is not functional");
+ for (l_mask = 0x8000;
+ l_mask > 0;
+ l_mask >>= 1)
+ {
+ if ((uint16_t)VPD_CP00_PG_N3_PG_MASK & l_mask)
+ {
+ // Ignore partial good region
+ continue;
+ }
+ else
+ if (pgData[VPD_CP00_PG_N3_INDEX] & l_mask)
+ {
+ // Turn off a bit that should be on
+ pgData[VPD_CP00_PG_N3_INDEX] &= ~l_mask;
+ }
+ else
+ {
+ // Turn on a bit that should be off
+ pgData[VPD_CP00_PG_N3_INDEX] |= l_mask;
+ }
+
+ if (isChipFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisChipFunctional>"
+ "functional = 0x%x, should be false.",
+ isChipFunctional(pTarget, pgData));
+ }
+
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_N3_INDEX] =
+ (uint16_t)VPD_CP00_PG_N3_GOOD;
+ }
+
+ TS_TRACE( "testHWASisChipFunctional: XBUS is not functional");
+ for (l_mask = 0x8000;
+ l_mask > 0;
+ l_mask >>= 1)
+ {
+ // NOTE: Single bits of XBUS matched pairs will be turned
+ // on or off individually while going through loop,
+ // thus creating and testing mismatched pairs.
+ if (pgData[VPD_CP00_PG_XBUS_INDEX] & l_mask)
+ {
+ // Turn off a bit that should be on
+ pgData[VPD_CP00_PG_XBUS_INDEX] &= ~l_mask;
+ }
+ else
+ {
+ // Turn on a bit that should be off
+ pgData[VPD_CP00_PG_XBUS_INDEX] |= l_mask;
+ }
+
+ if (isChipFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisChipFunctional>"
+ "functional = 0x%x, should be false.",
+ isChipFunctional(pTarget, pgData));
+ }
+
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_XBUS_INDEX] = l_xbus;
+ }
+ }
+
+ TS_TRACE( "testHWASisChipFunctional exit" );
+ }
+
+ /**
+ * @brief test isDescFunctional
+ */
+ void testHWASisDescFunctional()
+ {
+ using namespace HWAS;
+ using namespace TARGETING;
+
+ // Get list of present targets with type PROC
+ TargetHandleList pCheckPres;
+ getAllChips( pCheckPres, TYPE_PROC, true );
+
+ for (TargetHandleList::const_iterator pTarget_it = pCheckPres.begin();
+ pTarget_it != pCheckPres.end();
+ ++pTarget_it
+ )
+ {
+ TargetHandle_t pTarget = *pTarget_it;
+ ATTR_MODEL_type l_model = pTarget->getAttr<ATTR_MODEL>();
+ uint16_t l_xbus = (MODEL_NIMBUS == l_model)
+ ? (uint16_t)(VPD_CP00_PG_XBUS_GOOD |
+ VPD_CP00_PG_XBUS_IOX_PAIR[0])
+ : (uint16_t)VPD_CP00_PG_XBUS_GOOD;
+ uint16_t l_obus12 = (MODEL_NIMBUS == l_model)
+ ? (uint16_t)VPD_CP00_PG_RESERVED_GOOD
+ : (uint16_t)VPD_CP00_PG_OBUS_GOOD;
+ uint16_t pgData[VPD_CP00_PG_DATA_ENTRIES];
+ memcpy(pgData,
+ pgDataAllGood,
+ VPD_CP00_PG_DATA_LENGTH);
+ uint16_t l_mask = 0x8000;
+ uint32_t l_index = VPD_CP00_PG_PERVASIVE_INDEX;
+
+ TargetHandleList pDescList;
+ targetService().getAssociated( pDescList, pTarget,
+ TargetService::CHILD, TargetService::ALL);
+ for (TargetHandleList::const_iterator pDesc_it = pDescList.begin();
+ pDesc_it != pDescList.end();
+ ++pDesc_it)
+ {
+ TargetHandle_t pDesc = *pDesc_it;
+ ATTR_TYPE_type l_type = pDesc->getAttr<ATTR_TYPE>();
+ ATTR_CHIP_UNIT_type l_chipUnit =
+ pDesc->getAttr<ATTR_CHIP_UNIT>();
+
+ TS_TRACE( "testHWASisDescFunctional: descendant functional");
+ if (!isDescFunctional(pDesc, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be true.",
+ isDescFunctional(pTarget, pgData));
+ }
+
+ if ((TYPE_XBUS == l_type) && (0 == l_chipUnit))
+ {
+ pgData[VPD_CP00_PG_XBUS_INDEX] = l_xbus;
+ }
+
+ if ((TYPE_OBUS == l_type) &&
+ ((1 == l_chipUnit) || (2 == l_chipUnit)))
+ {
+ pgData[VPD_CP00_PG_OB0_INDEX + l_chipUnit] = l_obus12;
+ }
+
+ switch(l_type)
+ {
+ case TYPE_XBUS:
+ TS_TRACE( "testHWASisDescFunctional: "
+ "XBUS%d is not functional", l_chipUnit);
+ pgData[VPD_CP00_PG_XBUS_INDEX] |=
+ (uint16_t)VPD_CP00_PG_XBUS_IOX_PAIR[l_chipUnit];
+
+ if (isDescFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false.",
+ isDescFunctional(pTarget, pgData));
+ }
+
+ pgData[VPD_CP00_PG_XBUS_INDEX] = l_xbus;
+ break;
+
+ case TYPE_OBUS:
+ TS_TRACE( "testHWASisDescFunctional: "
+ "OBUS%d is not functional", l_chipUnit);
+ if ((1 == l_chipUnit) || (2 == l_chipUnit))
+ {
+ pgData[VPD_CP00_PG_N1_INDEX] |=
+ (uint16_t)VPD_CP00_PG_N1_PBIOO0;
+ }
+ else
+ {
+ pgData[VPD_CP00_PG_N1_INDEX] |=
+ (uint16_t)VPD_CP00_PG_N1_PBIOO1;
+ }
+
+ if (isDescFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false.",
+ isDescFunctional(pTarget, pgData));
+ }
+
+ pgData[VPD_CP00_PG_N1_INDEX] =
+ (uint16_t)VPD_CP00_PG_N1_GOOD;
+
+ for (l_mask = 0x8000;
+ l_mask > 0;
+ l_mask >>= 1)
+ {
+ if (pgData[VPD_CP00_PG_OB0_INDEX + l_chipUnit] &
+ l_mask)
+ {
+ // Turn off a bit that should be on
+ pgData[VPD_CP00_PG_OB0_INDEX + l_chipUnit] &=
+ ~l_mask;
+ }
+ else
+ {
+ // Turn on a bit that should be off
+ pgData[VPD_CP00_PG_OB0_INDEX + l_chipUnit] |=
+ l_mask;
+ }
+
+ if (isDescFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false.",
+ isDescFunctional(pTarget, pgData));
+ }
+
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_OB0_INDEX + l_chipUnit]
+ = ((1 == l_chipUnit) || (2 == l_chipUnit))
+ ? l_obus12
+ : (uint16_t)VPD_CP00_PG_OBUS_GOOD;
+ }
+ break;
+
+ case TYPE_PEC:
+ TS_TRACE( "testHWASisDescFunctional: "
+ "PCI%d is not functional", l_chipUnit);
+ for (l_mask = 0x8000;
+ l_mask > 0;
+ l_mask >>= 1)
+ {
+ if (pgData[VPD_CP00_PG_PCI0_INDEX + l_chipUnit] &
+ l_mask)
+ {
+ // Turn off a bit that should be on
+ pgData[VPD_CP00_PG_PCI0_INDEX + l_chipUnit] &=
+ ~l_mask;
+ }
+ else
+ {
+ // Turn on a bit that should be off
+ pgData[VPD_CP00_PG_PCI0_INDEX + l_chipUnit] |=
+ l_mask;
+ }
+
+ if (isDescFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false.",
+ isDescFunctional(pTarget, pgData));
+ }
+
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_PCI0_INDEX + l_chipUnit] =
+ (uint16_t)VPD_CP00_PG_PCIx_GOOD[l_chipUnit];
+ }
+ break;
+
+ case TYPE_EQ:
+ TS_TRACE( "testHWASisDescFunctional: "
+ "EQ%d is not functional", l_chipUnit);
+ for (l_mask = 0x8000;
+ l_mask > 0;
+ l_mask >>= 1)
+ {
+ // NOTE: Single bits of L2 / L3 matched pairs will
+ // be turned on or off individually while
+ // going through loop, thus creating and
+ // testing mismatched pairs.
+ if (pgData[VPD_CP00_PG_EP0_INDEX + l_chipUnit] &
+ l_mask)
+ {
+ // Turn off a bit that should be on
+ pgData[VPD_CP00_PG_EP0_INDEX + l_chipUnit] &=
+ ~l_mask;
+ }
+ else
+ {
+ // Turn on a bit that should be off
+ pgData[VPD_CP00_PG_EP0_INDEX + l_chipUnit] |=
+ l_mask;
+ }
+
+ if (isDescFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false.",
+ isDescFunctional(pTarget, pgData));
+ }
+
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_EP0_INDEX + l_chipUnit] =
+ (uint16_t)VPD_CP00_PG_EPx_GOOD;
+ }
+ break;
+
+ case TYPE_EX:
+ TS_TRACE( "testHWASisDescFunctional: "
+ "EX%d is not functional", l_chipUnit);
+ pgData[VPD_CP00_PG_EP0_INDEX + (l_chipUnit / 2)] |=
+ (uint16_t)VPD_CP00_PG_EPx_L3L2REFR[l_chipUnit % 2];
+
+ if (isDescFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false.",
+ isDescFunctional(pTarget, pgData));
+ }
+
+ pgData[VPD_CP00_PG_EP0_INDEX + (l_chipUnit / 2)] =
+ (uint16_t)VPD_CP00_PG_EPx_GOOD;
+ break;
+
+ case TYPE_CORE:
+ TS_TRACE( "testHWASisDescFunctional: "
+ "CORE%d is not functional", l_chipUnit);
+ for (l_mask = 0x8000;
+ l_mask > 0;
+ l_mask >>= 1)
+ {
+ if (pgData[VPD_CP00_PG_EC00_INDEX + l_chipUnit] &
+ l_mask)
+ {
+ // Turn off a bit that should be on
+ pgData[VPD_CP00_PG_EC00_INDEX + l_chipUnit] &=
+ ~l_mask;
+ }
+ else
+ {
+ // Turn on a bit that should be off
+ pgData[VPD_CP00_PG_EC00_INDEX + l_chipUnit] |=
+ l_mask;
+ }
+
+ if (isDescFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false.",
+ isDescFunctional(pTarget, pgData));
+ }
+
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_EC00_INDEX + l_chipUnit] =
+ VPD_CP00_PG_ECxx_GOOD;
+ }
+ break;
+
+ case TYPE_MCBIST:
+ TS_TRACE( "testHWASisDescFunctional: "
+ "MCBIST%d is not functional", l_chipUnit);
+ if (l_chipUnit)
+ {
+ pgData[VPD_CP00_PG_N1_INDEX] |=
+ (uint16_t)VPD_CP00_PG_N1_MCS23;
+ }
+ else
+ {
+ pgData[VPD_CP00_PG_N3_INDEX] |=
+ (uint16_t)VPD_CP00_PG_N3_MCS01;
+ }
+
+ if (isDescFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false.",
+ isDescFunctional(pTarget, pgData));
+ }
+
+ if (l_chipUnit)
+ {
+ pgData[VPD_CP00_PG_N1_INDEX] =
+ (uint16_t)VPD_CP00_PG_N1_GOOD;
+ }
+ else
+ {
+ pgData[VPD_CP00_PG_N3_INDEX] =
+ (uint16_t)VPD_CP00_PG_N3_GOOD;
+ }
+
+ for (l_mask = 0x8000;
+ l_mask > 0;
+ l_mask >>= 1)
+ {
+ if ((uint16_t)VPD_CP00_PG_MCxx_PG_MASK & l_mask)
+ {
+ // Ignore partial good region
+ continue;
+ }
+ else
+ if (pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit * 2]]
+ & l_mask)
+ {
+ // Turn off a bit that should be on
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit * 2]]
+ &= ~l_mask;
+ }
+ else
+ {
+ // Turn on a bit that should be off
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit * 2]]
+ |= l_mask;
+ }
+
+ if (isDescFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false.",
+ isDescFunctional(pTarget, pgData));
+ }
+
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit * 2]] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ }
+ break;
+
+ case TYPE_MCS:
+ TS_TRACE( "testHWASisDescFunctional: "
+ "MCS%d is not functional", l_chipUnit);
+ if (l_chipUnit >= 2)
+ {
+ pgData[VPD_CP00_PG_N1_INDEX] |=
+ (uint16_t)VPD_CP00_PG_N1_MCS23;
+ }
+ else
+ {
+ pgData[VPD_CP00_PG_N3_INDEX] |=
+ (uint16_t)VPD_CP00_PG_N3_MCS01;
+ }
+
+ if (isDescFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false.",
+ isDescFunctional(pTarget, pgData));
+ }
+
+ if (l_chipUnit >= 2)
+ {
+ pgData[VPD_CP00_PG_N1_INDEX] =
+ (uint16_t)VPD_CP00_PG_N1_GOOD;
+ }
+ else
+ {
+ pgData[VPD_CP00_PG_N3_INDEX] =
+ (uint16_t)VPD_CP00_PG_N3_GOOD;
+ }
+
+ for (l_mask = 0x8000;
+ l_mask > 0;
+ l_mask >>= 1)
+ {
+ if ((uint16_t)(VPD_CP00_PG_MCxx_PG_MASK &
+ ~VPD_CP00_PG_MCxx_IOMyy[l_chipUnit]) & l_mask)
+ {
+ // Ignore partial good region
+ continue;
+ }
+ else
+ if (pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit]] &
+ l_mask)
+ {
+ // Turn off a bit that should be on
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit]] &=
+ ~l_mask;
+ }
+ else
+ {
+ // Turn on a bit that should be off
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit]] |=
+ l_mask;
+ }
+
+ if (isDescFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false.",
+ isDescFunctional(pTarget, pgData));
+ }
+
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit]] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ }
+ break;
+
+ case TYPE_MCA:
+ TS_TRACE( "testHWASisDescFunctional: "
+ "MCA%d is not functional", l_chipUnit);
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit / 2]] |=
+ (uint16_t)VPD_CP00_PG_MCxx_IOMyy[l_chipUnit / 2];
+
+ if (isDescFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false.",
+ isDescFunctional(pTarget, pgData));
+ }
+
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit / 2]] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ break;
+
+ case TYPE_NVBUS:
+ TS_TRACE( "testHWASisDescFunctional: "
+ "NVBUS is not functional");
+ pgData[VPD_CP00_PG_N3_INDEX] |=
+ (uint16_t)VPD_CP00_PG_N3_NPU;
+
+ if (isDescFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false.",
+ isDescFunctional(pTarget, pgData));
+ }
+
+ pgData[VPD_CP00_PG_N3_INDEX] =
+ (uint16_t)VPD_CP00_PG_N3_GOOD;
+ break;
+
+ case TYPE_PERV:
+ TS_TRACE( "testHWASisDescFunctional: "
+ "PERV is not functional");
+ for (l_index = VPD_CP00_PG_PERVASIVE_INDEX;
+ l_index < VPD_CP00_PG_DATA_ENTRIES;
+ l_index++)
+ {
+ if (pgData[l_index] &
+ (uint16_t)VPD_CP00_PG_xxx_PERV)
+ {
+ // Ignore chiplet lines where PERV is "1"
+ continue;
+ }
+ else
+ {
+ // Turn on PERV bit that should be off / good
+ pgData[l_index] |=
+ (uint16_t)VPD_CP00_PG_xxx_PERV;
+ }
+
+ if (isDescFunctional(pTarget, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false.",
+ isDescFunctional(pTarget, pgData));
+ }
+
+ // Restore the "all good" data
+ pgData[l_index] &= ~VPD_CP00_PG_xxx_PERV;
+ }
+ break;
+
+ default:
+ break;
+ }
+ } // for pDesc_it
+ } // for pTarget_it
+
+ TS_TRACE( "testHWASisDescFunctional exit" );
+ }
+
};
#endif //
diff --git a/src/usr/hwas/test/hwasGardTest.H b/src/usr/hwas/test/hwasGardTest.H
index 5576a289b..f25a67ee3 100644
--- a/src/usr/hwas/test/hwasGardTest.H
+++ b/src/usr/hwas/test/hwasGardTest.H
@@ -46,7 +46,7 @@
using namespace HWAS;
using namespace TARGETING;
-bool compareAffinity(const TargetInfo t1, const TargetInfo t2)
+bool compareAffinityCXX(const TargetInfo t1, const TargetInfo t2)
{
return t1.affinityPath < t2.affinityPath;
}
@@ -3434,7 +3434,7 @@ public:
// Check result
std::sort(l_targToDeconfig.begin(), l_targToDeconfig.end(),
- compareAffinity);
+ compareAffinityCXX);
if ((l_targToDeconfig.size() == 4) &&
(l_targToDeconfig[0].affinityPath == l_ep[0]) &&
(l_targToDeconfig[1].affinityPath == l_ep[1]) &&
@@ -3517,7 +3517,7 @@ public:
// Check result
std::sort(l_targToDeconfig.begin(), l_targToDeconfig.end(),
- compareAffinity);
+ compareAffinityCXX);
if ((l_targToDeconfig.size() == 1) &&
(l_targToDeconfig[0].affinityPath == l_ep[0]) )
{
@@ -3615,7 +3615,7 @@ public:
// Check result
std::sort(l_targToDeconfig.begin(), l_targToDeconfig.end(),
- compareAffinity);
+ compareAffinityCXX);
if ((l_targToDeconfig.size() == 3) &&
(l_targToDeconfig[0].affinityPath == l_ep[4]) && // 10 MEMBUF
(l_targToDeconfig[1].affinityPath == l_ep[3]) && // 100 MBA
@@ -3673,7 +3673,7 @@ public:
// Check result
std::sort(l_targToDeconfig.begin(), l_targToDeconfig.end(),
- compareAffinity);
+ compareAffinityCXX);
if ((l_targToDeconfig.size() == 2) &&
(l_targToDeconfig[0].affinityPath == l_ep[0]) && // 0 MCS
(l_targToDeconfig[1].affinityPath == l_ep[1]) ) // 00 MEMBUF
@@ -3732,7 +3732,7 @@ public:
// Check result
std::sort(l_targToDeconfig.begin(), l_targToDeconfig.end(),
- compareAffinity);
+ compareAffinityCXX);
if ((l_targToDeconfig.size() == 2) &&
(l_targToDeconfig[0].affinityPath == l_ep[0]) && // 00 MEMBUF
(l_targToDeconfig[1].affinityPath == l_ep[1]) ) // 000 MBA
@@ -3793,7 +3793,7 @@ public:
// Check result
std::sort(l_targToDeconfig.begin(), l_targToDeconfig.end(),
- compareAffinity);
+ compareAffinityCXX);
if ((l_targToDeconfig.size() == 2) &&
(l_targToDeconfig[0].affinityPath == l_ep[0]) && // 000 MBA
(l_targToDeconfig[1].affinityPath == l_ep[1]) ) // 0000 DIMM
@@ -3874,7 +3874,7 @@ public:
// Check result
std::sort(l_targToDeconfig.begin(), l_targToDeconfig.end(),
- compareAffinity);
+ compareAffinityCXX);
if ((l_targToDeconfig.size() == 1) &&
(l_targToDeconfig[0].affinityPath == l_ep[4]) ) // 001 MBA
{
@@ -3991,7 +3991,7 @@ public:
// Check result
std::sort(l_targToDeconfig.begin(), l_targToDeconfig.end(),
- compareAffinity);
+ compareAffinityCXX);
if ((l_targToDeconfig.size() == 6) &&
(l_targToDeconfig[0].affinityPath == l_ep[0]) && // 0 MCS
(l_targToDeconfig[1].affinityPath == l_ep[1]) && // 00 MEMBUF
@@ -4089,7 +4089,7 @@ public:
// Check result
std::sort(l_targToDeconfig.begin(), l_targToDeconfig.end(),
- compareAffinity);
+ compareAffinityCXX);
if ((l_targToDeconfig.size() == 6) &&
(l_targToDeconfig[0].affinityPath == l_ep[0]) &&
(l_targToDeconfig[1].affinityPath == l_ep[1]) &&
OpenPOWER on IntegriCloud