summaryrefslogtreecommitdiffstats
path: root/src/usr/hwas
diff options
context:
space:
mode:
authorMarty Gloff <mgloff@us.ibm.com>2017-07-31 16:26:42 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-09-29 13:26:29 -0400
commiteb2d9340dac4d1bf781bc44aa6e7d4718a3b90a9 (patch)
treeb689f0c71a0f0f41d71f10e8200acacca0051b0b /src/usr/hwas
parent7ca7ca7fc1aea76ef66ea9472a3e2e6bc6b605b4 (diff)
downloadtalos-hostboot-eb2d9340dac4d1bf781bc44aa6e7d4718a3b90a9.tar.gz
talos-hostboot-eb2d9340dac4d1bf781bc44aa6e7d4718a3b90a9.zip
Partial good updates for Cumulus
Handle differences in PG data for Cumulus that may not have been identified or finalized for the initial P9 development. Change-Id: Ibec5a31cca5e8cf62d3671698e09c01f24619d1e RTC: 134608 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/44020 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Prachi Gupta <pragupta@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Martin Gloff <mgloff@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/hwas')
-rw-r--r--src/usr/hwas/common/hwas.C104
-rw-r--r--src/usr/hwas/test/hwas1test.H229
2 files changed, 318 insertions, 15 deletions
diff --git a/src/usr/hwas/common/hwas.C b/src/usr/hwas/common/hwas.C
index 8951c9dfe..76a4c4916 100644
--- a/src/usr/hwas/common/hwas.C
+++ b/src/usr/hwas/common/hwas.C
@@ -350,7 +350,9 @@ errlHndl_t discoverTargets()
{
// look at the 'nest' logic to override the
// functionality of this proc
- chipFunctional = isChipFunctional(pTarget, pgData);
+ chipFunctional =
+ isChipFunctional(pTarget,
+ pgData);
// Fill in a dummy restrict list
l_procEntry.target = pTarget;
@@ -386,7 +388,8 @@ errlHndl_t discoverTargets()
{ // if the chip is functional, then look through the
// partialGood vector to see if its chiplets
// are functional
- descFunctional = isDescFunctional(pDesc, pgData);
+ descFunctional = isDescFunctional(pDesc,
+ pgData);
}
if (pDesc->getAttr<ATTR_TYPE>() == TYPE_PERV)
@@ -631,10 +634,9 @@ bool isDescFunctional(const TARGETING::TargetHandle_t &i_desc,
}
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
+ // Rule 3 / Rule 4 PBIOO0 to be good with Nimbus and Cumulus except
+ // Nimbus Sforza (without optics and NVLINK), so is
+ // associated with all OBUS entries
if ((i_pgData[VPD_CP00_PG_N1_INDEX] &
VPD_CP00_PG_N1_PBIOO0) != 0)
{
@@ -649,8 +651,8 @@ bool isDescFunctional(const TARGETING::TargetHandle_t &i_desc,
}
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
+ // Rule 4 PBIOO1 to be associated with OBUS1 and OBUS2 which only are
+ // valid on a Cumulus
if (((1 == indexOB) || (2 == indexOB)) &&
((i_pgData[VPD_CP00_PG_N1_INDEX] &
VPD_CP00_PG_N1_PBIOO1) != 0))
@@ -819,7 +821,7 @@ bool isDescFunctional(const TARGETING::TargetHandle_t &i_desc,
l_descFunctional = false;
}
}
- else
+ else // MCBIST is found on Nimbus chips
if (i_desc->getAttr<ATTR_TYPE>() == TYPE_MCBIST)
{
ATTR_CHIP_UNIT_type indexMCBIST =
@@ -886,7 +888,7 @@ bool isDescFunctional(const TARGETING::TargetHandle_t &i_desc,
}
}
- else
+ else // MCS is found on Nimbus chips
if (i_desc->getAttr<ATTR_TYPE>() == TYPE_MCS)
{
ATTR_CHIP_UNIT_type indexMCS =
@@ -952,7 +954,7 @@ bool isDescFunctional(const TARGETING::TargetHandle_t &i_desc,
l_descFunctional = false;
}
}
- else
+ else // MCA is found on Nimbus chips
if (i_desc->getAttr<ATTR_TYPE>() == TYPE_MCA)
{
ATTR_CHIP_UNIT_type indexMCA =
@@ -987,6 +989,80 @@ bool isDescFunctional(const TARGETING::TargetHandle_t &i_desc,
l_descFunctional = false;
}
}
+ else // MC/MI/DMI is found on Cumulus chips
+ if ((i_desc->getAttr<ATTR_TYPE>() == TYPE_MC) ||
+ (i_desc->getAttr<ATTR_TYPE>() == TYPE_MI) ||
+ (i_desc->getAttr<ATTR_TYPE>() == TYPE_DMI))
+ {
+ ATTR_CHIP_UNIT_type index =
+ i_desc->getAttr<ATTR_CHIP_UNIT>();
+
+ // 2 MCs/chip, 2 MIs/MC, 2 DMIs/MI
+ size_t indexMC = 0;
+ size_t indexMI = 0;
+
+ if (i_desc->getAttr<ATTR_TYPE>() == TYPE_MC)
+ {
+ indexMC = index;
+ indexMI = index * 2;
+ }
+ else
+ if (i_desc->getAttr<ATTR_TYPE>() == TYPE_MI)
+ {
+ indexMI = index;
+ indexMC = index / 2;
+ }
+ else
+ if (i_desc->getAttr<ATTR_TYPE>() == TYPE_DMI)
+ {
+ indexMI = index / 2;
+ indexMC = index / 4;
+ }
+
+ // Check MCS01 bit in N3 entry if first MC
+ if ((0 == indexMC) &&
+ ((i_pgData[VPD_CP00_PG_N3_INDEX] &
+ VPD_CP00_PG_N3_MCS01) != 0))
+ {
+ HWAS_INF("pDesc %.8X - MC%d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexMC,
+ 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 MC
+ if ((1 == indexMC) &&
+ ((i_pgData[VPD_CP00_PG_N1_INDEX] &
+ VPD_CP00_PG_N1_MCS23) != 0))
+ {
+ HWAS_INF("pDesc %.8X - MC%d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexMC,
+ 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[indexMI]] !=
+ VPD_CP00_PG_MCxx_GOOD)
+ {
+ HWAS_INF("pDesc %.8X - MC%d pgData[%d]: "
+ "actual 0x%04X, expected 0x%04X - bad",
+ i_desc->getAttr<ATTR_HUID>(), indexMC,
+ VPD_CP00_PG_MCxx_INDEX[indexMI],
+ i_pgData[VPD_CP00_PG_MCxx_INDEX[indexMI]],
+ VPD_CP00_PG_MCxx_GOOD);
+ l_descFunctional = false;
+ }
+
+ }
else
if (i_desc->getAttr<ATTR_TYPE>() == TYPE_OBUS_BRICK)
{
@@ -2134,7 +2210,7 @@ void invokePresentByAssoc()
#endif
// get the functional membufs
- // note: do not expect membufs for NIMBUS
+ // note: do not expect membufs for NIMBUS
TargetHandleList l_funcMembufTargetList;
getAllChips(l_funcMembufTargetList, TYPE_MEMBUF, true );
l_funcTargetList.insert(l_funcTargetList.begin(),
@@ -2265,7 +2341,7 @@ void presentByAssoc(TargetInfoVector& io_funcTargets,
size_t l_MIIndex = __INT_MAX__;
size_t l_DMIIndex = __INT_MAX__;
size_t l_MEMBUFIndex = __INT_MAX__;
- size_t l_MBAIndex = __INT_MAX__;
+ size_t l_MBAIndex = __INT_MAX__;
size_t i = 0;
// Perform presentByAssoc algorithm
@@ -2726,7 +2802,7 @@ void presentByAssoc(TargetInfoVector& io_funcTargets,
else if ( l_MEMBUFIndex != __INT_MAX__)
{
i = l_MEMBUFIndex;
- }
+ }
//Backtrack to last DMI (CUMULUS),if no MEMBUF has been seen yet
else if ( l_DMIIndex != __INT_MAX__ )
{
diff --git a/src/usr/hwas/test/hwas1test.H b/src/usr/hwas/test/hwas1test.H
index 0eca4045a..4b1e9ccd0 100644
--- a/src/usr/hwas/test/hwas1test.H
+++ b/src/usr/hwas/test/hwas1test.H
@@ -1422,7 +1422,234 @@ public:
break;
- case TYPE_OBUS_BRICK:
+ case TYPE_MC:
+ TS_INFO( "testHWASisDescFunctional: "
+ "MC%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(pDesc, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false, "
+ "N1/N3 for MC%d = 0x%04x.",
+ isDescFunctional(pDesc, pgData),
+ l_chipUnit,
+ l_chipUnit ? pgData[VPD_CP00_PG_N1_INDEX]
+ : pgData[VPD_CP00_PG_N3_INDEX]);
+ }
+
+ 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 (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(pDesc, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false, "
+ "MC%s for MC%d = 0x%04x, "
+ "mask = 0x%04x.",
+ isDescFunctional(pDesc, pgData),
+ l_chipUnit ? "01" : "23",
+ l_chipUnit,
+ pgData[VPD_CP00_PG_MCxx_INDEX
+ [l_chipUnit * 2]],
+ l_mask);
+ }
+
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit * 2]] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ }
+
+ break;
+
+ case TYPE_MI:
+ TS_INFO( "testHWASisDescFunctional: "
+ "MI%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(pDesc, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false, "
+ "N1/N3 for MI%d = 0x%04x.",
+ isDescFunctional(pDesc, pgData),
+ l_chipUnit,
+ (l_chipUnit / 2)
+ ? pgData[VPD_CP00_PG_N1_INDEX]
+ : pgData[VPD_CP00_PG_N3_INDEX]);
+ }
+
+ 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 (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(pDesc, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false, "
+ "MC%s for MI%d = 0x%04x, "
+ "mask = 0x%04x.",
+ isDescFunctional(pDesc, pgData),
+ (l_chipUnit / 2) ? "01" : "23",
+ l_chipUnit,
+ pgData[VPD_CP00_PG_MCxx_INDEX
+ [l_chipUnit]],
+ l_mask);
+ }
+
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit]] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ }
+
+ break;
+
+ case TYPE_DMI:
+ TS_INFO( "testHWASisDescFunctional: "
+ "DMI%d is not functional", l_chipUnit);
+ if (l_chipUnit / 4)
+ {
+ 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(pDesc, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false, "
+ "N1/N3 for DMI%d = 0x%04x.",
+ isDescFunctional(pDesc, pgData),
+ l_chipUnit,
+ (l_chipUnit / 4)
+ ? pgData[VPD_CP00_PG_N1_INDEX]
+ : pgData[VPD_CP00_PG_N3_INDEX]);
+ }
+
+ if (l_chipUnit / 4)
+ {
+ 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 (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(pDesc, pgData))
+ {
+ TS_FAIL("testHWASisDescFunctional>"
+ "functional = 0x%x, should be false, "
+ "MC%s for DMI%d = 0x%04x, "
+ "mask = 0x%04x.",
+ isDescFunctional(pDesc, pgData),
+ (l_chipUnit / 4) ? "01" : "23",
+ l_chipUnit,
+ pgData[VPD_CP00_PG_MCxx_INDEX
+ [l_chipUnit / 2]],
+ l_mask);
+ }
+
+ // Restore the "all good" data
+ pgData[VPD_CP00_PG_MCxx_INDEX[l_chipUnit / 2]] =
+ (uint16_t)VPD_CP00_PG_MCxx_GOOD;
+ }
+
+ break;
+
+ case TYPE_OBUS_BRICK:
{
//Two cases here:
//OBRICK==SMP --> Target should be present regardless of PG
OpenPOWER on IntegriCloud