summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Horton <brianh@linux.ibm.com>2013-04-04 10:26:56 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-05-15 09:01:41 -0500
commitb3e5730d1fa5358cef38a3fe9064d21bfe5e06af (patch)
treeccf5a530b71cf123aebacccd2158f5603d46008a
parent6cbd7c560d3a9c4354128ebf8714cec8fa044453 (diff)
downloadtalos-hostboot-b3e5730d1fa5358cef38a3fe9064d21bfe5e06af.tar.gz
talos-hostboot-b3e5730d1fa5358cef38a3fe9064d21bfe5e06af.zip
Handle the PR keyword
Add support in the HWAS code to handle the PR keyword, to potentially force processors to run with less cores than are available. Move FRU_ID from fsp-only to common, so that the PR keyword code knows which procs are to be grouped. This work involves changes to HWAS Common code, as well as hostboot and FSP platform-specific code. Change-Id: I6d437a68c37f51edbd6d0d4741f2193892f80a6b RTC: 35077 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/4221 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
-rw-r--r--src/include/usr/hwas/common/hwasCommon.H38
-rw-r--r--src/include/usr/targeting/common/target.H9
-rw-r--r--src/usr/hwas/common/hwas.C246
-rw-r--r--src/usr/hwas/hwasPlat.C107
-rwxr-xr-xsrc/usr/targeting/common/genHwsvMrwXml.pl4
-rw-r--r--src/usr/targeting/common/xmltohb/attribute_types.xml8
-rw-r--r--src/usr/targeting/common/xmltohb/simics_MURANO.system.xml16
-rw-r--r--src/usr/targeting/common/xmltohb/simics_VENICE.system.xml32
-rw-r--r--src/usr/targeting/common/xmltohb/target_types.xml3
-rw-r--r--src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml16
-rw-r--r--src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml8
11 files changed, 428 insertions, 59 deletions
diff --git a/src/include/usr/hwas/common/hwasCommon.H b/src/include/usr/hwas/common/hwasCommon.H
index ae0c52ac6..edf87f129 100644
--- a/src/include/usr/hwas/common/hwasCommon.H
+++ b/src/include/usr/hwas/common/hwasCommon.H
@@ -87,7 +87,7 @@ errlHndl_t platReadIDEC(const TARGETING::TargetHandle_t &i_target);
* target. The platform specific code is responsible for returning the
* vector. The caller is reponsible for allocating and de-allocating the space.
*
- * @param[in] i_target target to check for chip ID/EC
+ * @param[in] i_target target to read the Partial Good keyword from
* @param[out] o_pgData pointer to area that will hold the partialGood vector
* read from VPD; must be malloc'ed by the caller,
* and must be VPD_CP00_PG_DATA_LENGTH in size.
@@ -136,6 +136,42 @@ const uint32_t VPD_CP00_PG_EX0_INDEX = 16;
const uint32_t VPD_CP00_PG_EX0_GOOD = 0xF300;
/**
+ * @brief platform specific code to determine the PR vector of the input
+ * target. The platform specific code is responsible for returning the
+ * vector. The caller is reponsible for allocating and de-allocating the space.
+ *
+ * @param[in] i_target target to read the PR keyword from
+ * @param[out] o_prData pointer to area that will hold the PR keyword
+ * read from VPD; must be malloc'ed by the caller,
+ * and must be VPD_CP00_PR_DATA_LENGTH in size.
+ *
+ * @return errlHndl_t valid errlHndl_t handle if there was an error
+ * NULL if no errors;
+ */
+errlHndl_t platReadPR(const TARGETING::TargetHandle_t &i_target,
+ void *o_prData);
+
+// constants the platReadPR will use for looking at the VPD data
+const uint32_t VPD_VINI_PR_DATA_LENGTH = 8;
+
+// Byte 2 Number of processors per module chip
+const uint32_t VPD_VINI_PR_B2_MASK = 0xF0; // bits 0-3
+const uint32_t VPD_VINI_PR_B2_SHIFT = 4;
+// Byte 7 Max VPD copies (aka replication factor)
+// Bits 2:7
+// Number of chips using this VPD minus 1, i.e., Used to
+// calculate the maximum number of duplicate copies of the B9
+// keyword allowed. Multiply PR byte 2 (number of processor
+// per module) times this value [(PR byte 7) + 1] to get the max
+// number of copies of any given B9 keyword data in the SPIRA
+// PACA structure.
+// If the number of functional processors is different on chips
+// within the same module. It will be firmwares responsibility
+// average them out as specified in byte 2 above.
+const uint32_t VPD_VINI_PR_B7_MASK = 0x3F; // bits 2-7
+
+
+/**
* @brief platform specific code to get the address in PNOR to read
* and write GARD data
*
diff --git a/src/include/usr/targeting/common/target.H b/src/include/usr/targeting/common/target.H
index 496636a57..866920010 100644
--- a/src/include/usr/targeting/common/target.H
+++ b/src/include/usr/targeting/common/target.H
@@ -253,8 +253,7 @@ class Target
bool l_wrote = trySetAttr<A>(i_attrValue);
//@TODO: Remove assert once release has stabilized
- TARG_ASSERT(l_wrote,"TARGETING::Target::setAttr<%d>: trySetAttr "
- "returned false",A);
+ TARG_ASSERT(l_wrote,"TARGETING::Target::setAttr<0x%7x>: trySetAttr returned false",A);
}
/**
@@ -504,8 +503,7 @@ typename AttributeTraits<A>::Type Target::getAttr() const
bool l_read = tryGetAttr<A>(l_attrValue);
//@TODO Remove assert once release has stablized
- TARG_ASSERT(l_read,"TARGETING::Target::getAttr<%d>: tryGetAttr "
- "returned false",A);
+ TARG_ASSERT(l_read,"TARGETING::Target::getAttr<0x%7x>: tryGetAttr returned false",A);
return l_attrValue;
}
@@ -539,8 +537,7 @@ const char* Target::getAttrAsString() const
bool l_read = tryGetAttr<A>(l_attrValue);
//@TODO Remove assert once release has stabilized
- TARG_ASSERT(l_read,"TARGETING::Target::getAttrAsString<%d>: tryGetAttr "
- "returned false",A);
+ TARG_ASSERT(l_read,"TARGETING::Target::getAttrAsString<0x%7x>: tryGetAttr returned false",A);
return attrToString<A>(l_attrValue);
}
diff --git a/src/usr/hwas/common/hwas.C b/src/usr/hwas/common/hwas.C
index 7be663b63..19b688acb 100644
--- a/src/usr/hwas/common/hwas.C
+++ b/src/usr/hwas/common/hwas.C
@@ -33,6 +33,7 @@
// Includes
/******************************************************************************/
#include <stdint.h>
+#include <algorithm>
#include <targeting/common/commontargeting.H>
@@ -58,6 +59,24 @@ TRAC_INIT(&g_trac_dbg_hwas, "HWAS", 1024 );
TRAC_INIT(&g_trac_imp_hwas, "HWAS_I", 1024 );
#endif
+// structure used to store proc information for PR keyword processing
+typedef struct {
+ TargetHandle_t target;
+ ATTR_FRU_ID_type fruid;
+ uint8_t avgNum;
+ uint8_t vpdCopies;
+} procPR_t;
+
+// SORT functions that we'll use for PR keyword processing
+bool compareTargetHUID(TargetHandle_t t1, TargetHandle_t t2)
+{
+ return (t1->getAttr<ATTR_HUID>() < t2->getAttr<ATTR_HUID>());
+}
+bool compareProcFRUID(procPR_t t1, procPR_t t2)
+{
+ return (t1.fruid < t2.fruid);
+}
+
/**
* @brief simple helper fn to get and set hwas state to poweredOn,
* present, functional
@@ -108,13 +127,10 @@ errlHndl_t discoverTargets()
target->setAttr<ATTR_HWAS_STATE>(hwasState);
}
- // ASSUMPTIONS:
+ // Assumptions and actions:
// CLASS_SYS (exactly 1) - mark as present
- // CLASS_ENC and
- // CLASS_CHIP - (TYPE_PROC TYPE_MEMBUF)
- // CLASS_LOGICAL_CARD - TYPE_DIMM
- // (ALL require hardware query)
- // - call platPresenceDetect
+ // CLASS_ENC, TYPE_PROC, TYPE_MEMBUF, TYPE_DIMM
+ // (ALL require hardware query) - call platPresenceDetect
// \->children: CLASS_* (NONE require hardware query) - mark as present
do
{
@@ -130,7 +146,7 @@ errlHndl_t discoverTargets()
HWAS_DBG("pSys %.8X - marked present",
pSys->getAttr<ATTR_HUID>());
- // find CLASS_ENC
+ // find list of all we need to call platPresenceDetect against
PredicateCTM predEnc(CLASS_ENC);
PredicateCTM predChip(CLASS_CHIP);
PredicateCTM predDimm(CLASS_LOGICAL_CARD, TYPE_DIMM);
@@ -152,14 +168,18 @@ errlHndl_t discoverTargets()
break; // break out of the do/while so that we can return
}
- // no errors - keep going
// for each, read their ID/EC level. if that works,
// mark them and their descendants as present
// read the partialGood vector to determine if any are not functional
+ // and read and store values from the PR keyword
+
+ // list of procs and data that we'll need to look at the PR keyword
+ procPR_t l_procEntry;
+ std::vector <procPR_t> l_procPRList;
for (TargetHandleList::iterator pTarget_it = pCheckPres.begin();
pTarget_it != pCheckPres.end();
- pTarget_it++
+ ++pTarget_it
)
{
TargetHandle_t pTarget = *pTarget_it;
@@ -180,6 +200,7 @@ errlHndl_t discoverTargets()
uint32_t errlPlid = 0;
uint16_t pgData[VPD_CP00_PG_DATA_LENGTH / sizeof(uint16_t)];
bzero(pgData, sizeof(pgData));
+
if (pTarget->getAttr<ATTR_CLASS>() == CLASS_CHIP)
{
// read Chip ID/EC data from these physical chips
@@ -196,7 +217,6 @@ errlHndl_t discoverTargets()
errlCommit(errl, HWAS_COMP_ID);
// errl is now NULL
}
-
if (pTarget->getAttr<ATTR_TYPE>() == TYPE_PROC)
{
// read partialGood vector from these as well.
@@ -219,8 +239,7 @@ errlHndl_t discoverTargets()
if (pgData[VPD_CP00_PG_PIB_INDEX] !=
VPD_CP00_PG_PIB_GOOD)
{
- HWAS_INF("pTarget %.8X - PIB "
- "pgPdata[%d]: expected 0x%04X - bad",
+ 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);
@@ -230,8 +249,7 @@ errlHndl_t discoverTargets()
if (pgData[VPD_CP00_PG_PERVASIVE_INDEX] !=
VPD_CP00_PG_PERVASIVE_GOOD)
{
- HWAS_INF("pTarget %.8X - Pervasive "
- "pgPdata[%d]: expected 0x%04X - bad",
+ 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);
@@ -242,25 +260,50 @@ errlHndl_t discoverTargets()
VPD_CP00_PG_POWERBUS_BASE) !=
VPD_CP00_PG_POWERBUS_BASE)
{
- HWAS_INF("pTarget %.8X - PowerBus "
- "pgPdata[%d]: expected 0x%04X - bad",
+ 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
+ {
+ // 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)];
+ bzero(prData, sizeof(prData));
+ errl = platReadPR(pTarget, prData);
+ if (errl != NULL)
+ { // read of PR keyword failed
+ HWAS_INF("pTarget %.8X - read PR failed - bad",
+ pTarget->getAttr<ATTR_HUID>());
+ chipFunctional = false;
+ errlPlid = errl->plid();
+
+ // commit the error but keep going
+ errlCommit(errl, HWAS_COMP_ID);
+ // errl is now NULL
+ }
+ else
+ {
+ // save info so that we can
+ // process the PR keyword after this loop
+ HWAS_INF("pTarget %.8X - pushing to procPRlist; FRU_ID %d",
+ pTarget->getAttr<ATTR_HUID>(),
+ pTarget->getAttr<ATTR_FRU_ID>());
+ l_procEntry.target = pTarget;
+ l_procEntry.fruid = pTarget->getAttr<ATTR_FRU_ID>();
+ l_procEntry.avgNum =
+ (prData[2] & VPD_VINI_PR_B2_MASK)
+ >> VPD_VINI_PR_B2_SHIFT;
+ l_procEntry.vpdCopies =
+ (prData[7] & VPD_VINI_PR_B7_MASK) + 1;
+ l_procPRList.push_back(l_procEntry);
+ }
+ }
} // TYPE_PROC
} // CLASS_CHIP
- // TODO: Story 35077 - add PR processing. roughly:
- // totalcores = readPR();
- // for each child ex in chip c
- // if goodcores < totalcores
- // if ex->functional==true
- // goodcores++
- // else
- // ex->functional = false
-
HWAS_DBG("pTarget %.8X - detected present, %sfunctional",
pTarget->getAttr<ATTR_HUID>(),
chipFunctional ? "" : "NOT ");
@@ -272,7 +315,7 @@ errlHndl_t discoverTargets()
TargetService::CHILD, TargetService::ALL);
for (TargetHandleList::iterator pDesc_it = pDescList.begin();
pDesc_it != pDescList.end();
- pDesc_it++)
+ ++pDesc_it)
{
TargetHandle_t pDesc = *pDesc_it;
// by default, the descendant's functionality is 'inherited'
@@ -286,8 +329,7 @@ errlHndl_t discoverTargets()
(pgData[VPD_CP00_PG_XBUS_INDEX] !=
VPD_CP00_PG_XBUS_GOOD))
{
- HWAS_INF("pDesc %.8X - XBUS "
- "pgPdata[%d]: expected 0x%04X - bad",
+ 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);
@@ -298,8 +340,7 @@ errlHndl_t discoverTargets()
(pgData[VPD_CP00_PG_ABUS_INDEX] !=
VPD_CP00_PG_ABUS_GOOD))
{
- HWAS_INF("pDesc %.8X - ABUS "
- "pgPdata[%d]: expected 0x%04X - bad",
+ 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);
@@ -310,8 +351,7 @@ errlHndl_t discoverTargets()
(pgData[VPD_CP00_PG_PCIE_INDEX] !=
VPD_CP00_PG_PCIE_GOOD))
{
- HWAS_INF("pDesc %.8X - PCIe "
- "pgPdata[%d]: expected 0x%04X - bad",
+ 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);
@@ -327,8 +367,7 @@ errlHndl_t discoverTargets()
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",
+ 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);
@@ -345,8 +384,7 @@ errlHndl_t discoverTargets()
((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",
+ 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);
@@ -357,8 +395,7 @@ errlHndl_t discoverTargets()
((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",
+ 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);
@@ -381,6 +418,139 @@ errlHndl_t discoverTargets()
} // for pTarget_it
+ // PR keyword processing - potentially reduce the number of ex/core
+ // units that are functional based on what's in the PR keyword.
+
+ // predicate to find present EX units
+ PredicateCTM predEX(CLASS_UNIT, TYPE_EX);
+ PredicateHwas predPresent;
+ predPresent.present(true);
+ PredicatePostfixExpr exCheckExpr;
+ exCheckExpr.push(&predEX).push(&predPresent).And();
+
+ // predicate to find CORE units
+ PredicateCTM predCore(CLASS_UNIT, TYPE_CORE);
+ PredicatePostfixExpr coreCheckExpr;
+ coreCheckExpr.push(&predCore);
+
+ // sort by ATTR_FRU_ID so PROC# are in the right groupings.
+ std::sort(l_procPRList.begin(), l_procPRList.end(),
+ compareProcFRUID);
+
+ // AFTER all targets have been tested, loop thru procs to handle PR
+ const uint32_t l_PRProcCount = l_procPRList.size();
+ for (uint32_t procIdx = 0;
+ procIdx < l_PRProcCount;
+ // the increment will happen in the loop to handle
+ // PR records covering more than 1 proc target
+ )
+ {
+ // determine the number of procs we should enable
+ uint8_t avgNum = l_procPRList[procIdx].avgNum;
+ uint8_t vpdCopies = l_procPRList[procIdx].vpdCopies;
+
+ // this procs FRU_ID, used to determine groupings
+ ATTR_FRU_ID_type thisFruId = l_procPRList[procIdx].fruid;
+
+ HWAS_INF("procPRList[%d] - PR avg units %d, VPDs %d, FRU_ID %d",
+ procIdx, avgNum, vpdCopies, thisFruId);
+
+ // exs and iters for each proc in this vpd set
+ TargetHandleList pEXList[vpdCopies];
+ TargetHandleList::iterator pEX_it[vpdCopies];
+
+ // find the proc's that we think are in this group
+ for (uint32_t i = 0; i < vpdCopies; i++)
+ {
+ TargetHandle_t pProc = l_procPRList[procIdx].target;
+
+ // if this proc is past the last of the proc count
+ // OR is NOT in the same FRU_ID
+ if ((procIdx >= l_PRProcCount) ||
+ (thisFruId != pProc->getAttr<ATTR_FRU_ID>()))
+ {
+ HWAS_DBG("procPRList[%d] - not in FRU_ID %d group",
+ i, thisFruId);
+
+ // change this to be how many we actually have here
+ vpdCopies = i;
+
+ // we're done - break so that we use procIdx as the
+ // start index next time
+ break;
+ }
+
+ // get this proc's (CHILD) present EX units
+ targetService().getAssociated( pEXList[i], pProc,
+ TargetService::CHILD, TargetService::ALL, &exCheckExpr);
+
+ // sort the list by ATTR_HUID to ensure that we
+ // start at the same place each time
+ std::sort(pEXList[i].begin(), pEXList[i].end(),
+ compareTargetHUID);
+
+ // keep a pointer into that list
+ pEX_it[i] = pEXList[i].begin();
+
+ // advance the outer loop as well since we're doing these
+ // procs together
+ ++procIdx;
+ } // for
+ HWAS_DBG("procIdx %d, vpdCopies %d", procIdx, vpdCopies);
+
+ // now need to find EX units that stay function, going
+ // across the list of units for each proc we have, until
+ // we get to the max or run out of EXs.
+ uint8_t procs_remaining = vpdCopies;
+ uint32_t maxEXs = avgNum * vpdCopies;
+ uint32_t goodEXs = 0;
+ do
+ {
+ // now cycle thru the procs
+ for (uint32_t i = 0;i < vpdCopies;i++)
+ {
+ // if we are done with this list of ex/core units
+ // from this processor
+ if (pEX_it[i] == pEXList[i].end())
+ {
+ procs_remaining--;
+ continue;
+ }
+
+ // got a present EX
+ HWAS_DBG("pEX %.8X - is good!",
+ (*(pEX_it[i]))->getAttr<ATTR_HUID>());
+ (pEX_it[i])++; // next ex/core in this proc's list
+ goodEXs++;
+ } // for
+ }
+ while ((goodEXs < maxEXs) && (procs_remaining != 0));
+
+ // now mark the rest of the EXs as non-present/non-functional
+ for (uint32_t i = 0;i < vpdCopies;i++)
+ {
+ // walk thru the rest of the EX list
+ while (pEX_it[i] != pEXList[i].end())
+ {
+ TargetHandle_t l_pEX = *(pEX_it[i]);
+ enableHwasState(l_pEX, false, false, 0);
+ HWAS_INF("pEX %.8X - marked NOT present, NOT functional (PR)",
+ l_pEX->getAttr<ATTR_HUID>());
+
+ // now need to mark the child CORE
+ TargetHandleList pCoreList;
+ targetService().getAssociated(
+ pCoreList, l_pEX,
+ TargetService::CHILD, TargetService::ALL,
+ &coreCheckExpr );
+ enableHwasState(pCoreList[0], false, false, 0);
+ HWAS_INF("pCore %.8X - marked NOT present, NOT functional (PR)",
+ pCoreList[0]->getAttr<ATTR_HUID>());
+ (pEX_it[i])++; // next ex/core in this proc's list
+ }
+ } // for making remaining non-present/non-functional
+ } // for procIdx < l_PRProcCount
+
} while (0);
HWAS_INF("discoverTargets returning errl %p", errl);
diff --git a/src/usr/hwas/hwasPlat.C b/src/usr/hwas/hwasPlat.C
index 864e01551..94d4b6385 100644
--- a/src/usr/hwas/hwasPlat.C
+++ b/src/usr/hwas/hwasPlat.C
@@ -48,7 +48,7 @@ class RegisterHWASFunctions
RegisterHWASFunctions()
{
// HWAS is awake
-
+
// register processCallout function for ErrlEntry::commit
HWAS_DBG("module load: calling errlog::setHwasProcessCalloutFn");
ERRORLOG::ErrlManager::setHwasProcessCalloutFn(
@@ -135,7 +135,6 @@ bool platSystemIsAtRuntime()
errlHndl_t platReadPartialGood(const TargetHandle_t &i_target,
void *o_pgData)
{
- errlHndl_t errl = NULL;
HWAS_DBG( "i_target %.8X",
i_target->getAttr<ATTR_HUID>());
@@ -143,7 +142,7 @@ errlHndl_t platReadPartialGood(const TargetHandle_t &i_target,
uint8_t pgRaw[VPD_CP00_PG_HDR_LENGTH + VPD_CP00_PG_DATA_LENGTH];
size_t pgSize = sizeof(pgRaw);
- errl = deviceRead(i_target, pgRaw, pgSize,
+ errlHndl_t errl = deviceRead(i_target, pgRaw, pgSize,
DEVICE_MVPD_ADDRESS(MVPD::CP00, MVPD::PG));
if (unlikely(errl != NULL))
@@ -165,20 +164,30 @@ errlHndl_t platReadPartialGood(const TargetHandle_t &i_target,
}
else
if (i_target->getAttr<ATTR_HUID>() == 0x50001)
- { // 2nd proc - mark Pervasive bad - entire chip
- // should be marked present and NOT functional
- pgData[VPD_CP00_PG_PERVASIVE_INDEX] = 0;
+ {
+ pgData[VPD_CP00_PG_EX0_INDEX+6] = 0xF300;
+ pgData[VPD_CP00_PG_EX0_INDEX+12] = 0xF300;
+ pgData[VPD_CP00_PG_EX0_INDEX+13] = 0xF300;
+ pgData[VPD_CP00_PG_EX0_INDEX+14] = 0xF300;
}
else
if (i_target->getAttr<ATTR_HUID>() == 0x50002)
- { // 3rd proc - part of XBUS is bad
- pgData[VPD_CP00_PG_XBUS_INDEX] = 0;
+ { // 3rd proc
+ //// mark Pervasive bad - entire chip
+ //// should be marked present and NOT functional
+ ////pgData[VPD_CP00_PG_PERVASIVE_INDEX] = 0;
+
+ //pgData[VPD_CP00_PG_EX0_INDEX+12] = 0xF300;
+ pgData[VPD_CP00_PG_EX0_INDEX+13] = 0xF300;
+ pgData[VPD_CP00_PG_EX0_INDEX+14] = 0xF300;
}
else
if (i_target->getAttr<ATTR_HUID>() == 0x50003)
- { // 4th proc - EX13 and EX14 are bad
- pgData[VPD_CP00_PG_EX0_INDEX+13] = 0;
- pgData[VPD_CP00_PG_EX0_INDEX+14] = 0;
+ { // 4th proc - EX13 and EX14 are good
+ pgData[VPD_CP00_PG_EX0_INDEX+6] = 0xF300;
+ pgData[VPD_CP00_PG_EX0_INDEX+12] = 0xF300;
+ pgData[VPD_CP00_PG_EX0_INDEX+13] = 0xF300;
+ pgData[VPD_CP00_PG_EX0_INDEX+14] = 0xF300;
}
}
#endif
@@ -194,6 +203,76 @@ errlHndl_t platReadPartialGood(const TargetHandle_t &i_target,
} // platReadPartialGood
//******************************************************************************
+// platReadPR function
+//******************************************************************************
+errlHndl_t platReadPR(const TargetHandle_t &i_target,
+ void *o_prData)
+{
+ HWAS_DBG( "i_target %.8X",
+ i_target->getAttr<ATTR_HUID>());
+
+ // call deviceRead() to find the PR record
+ uint8_t prData[VPD_VINI_PR_DATA_LENGTH];
+ size_t prSize = sizeof(prData);
+
+ errlHndl_t errl = deviceRead(i_target, prData, prSize,
+ DEVICE_MVPD_ADDRESS(MVPD::VINI, MVPD::PR));
+
+ if (unlikely(errl != NULL))
+ { // errl was set - this is an error condition.
+ HWAS_ERR( "i_target %.8X - failed PR read",
+ i_target->getAttr<ATTR_HUID>());
+ }
+ else
+ {
+#if 0
+// Unit test. set P8_MURANO.config to have 4 procs, and this code will
+// alter the VPD so that some of the procs and chiplets should get marked
+// as NOT functional.
+ {
+ if (i_target->getAttr<ATTR_HUID>() == 0x50000)
+ { // 1st proc - let it go thru ok.
+ prData[2] = 3 << VPD_VINI_PR_B2_SHIFT; // 3*2 = 6 cores
+ prData[7] = 0; // 2 procs
+ //prData[2] = 1 << VPD_VINI_PR_B2_SHIFT; // 1*4 = 4 cores
+ //prData[7] = 3; // 4 cores
+ }
+ else
+ if (i_target->getAttr<ATTR_HUID>() == 0x50001)
+ { // 2nd proc -
+ prData[2] = 3 << VPD_VINI_PR_B2_SHIFT; // 3*2 = 6 cores
+ prData[7] = 1; // 2 procs
+ //prData[2] = 1 << VPD_VINI_PR_B2_SHIFT; // 1*4 = 4 cores
+ //prData[7] = 3; // 4 cores
+ }
+ else
+ if (i_target->getAttr<ATTR_HUID>() == 0x50002)
+ { // 3rd proc -
+ prData[2] = 3 << VPD_VINI_PR_B2_SHIFT; // 3*2 = 6 cores
+ prData[7] = 0; // 2 procs
+ //prData[2] = 1 << VPD_VINI_PR_B2_SHIFT; // 1*4 = 4 cores
+ //prData[7] = 3; // 4 cores
+ }
+ else
+ if (i_target->getAttr<ATTR_HUID>() == 0x50003)
+ { // 4th proc -
+ prData[2] = 3 << VPD_VINI_PR_B2_SHIFT; // 3*2 = 6 cores
+ prData[7] = 0; // 2 procs
+ //prData[2] = 1 << VPD_VINI_PR_B2_SHIFT; // 1*4 = 4 cores
+ //prData[7] = 3; // 4 cores
+ }
+ }
+#endif
+
+ HWAS_DBG_BIN("PR record", prData, VPD_VINI_PR_DATA_LENGTH);
+ // copy the data back into the caller's buffer
+ memcpy(o_prData, prData, VPD_VINI_PR_DATA_LENGTH);
+ }
+
+ return errl;
+} // platReadPR
+
+//******************************************************************************
// platPresenceDetect function
//******************************************************************************
errlHndl_t platPresenceDetect(TargetHandleList &io_targets)
@@ -278,7 +357,7 @@ GardAddress::GardAddress(bool &o_gardEnabled)
if (errl)
{
HWAS_ERR("PNOR::getSectionInfo failed!!!");
- // no support for GARD in this configuration.
+ // no support for GARD in this configuration.
// Commit the log as unrecoverable and keep going.
errlCommit(errl, HWAS_COMP_ID);
// errl is now NULL
@@ -311,14 +390,14 @@ GardAddress::~GardAddress()
{
for (std::vector<void *>::iterator iter = iv_addr.begin();
iter != iv_addr.end();
- iter++)
+ ++iter)
{
HWAS_DBG("flushing GARD in PNOR: addr=%p", *iter);
int l_rc = mm_remove_pages(FLUSH, (void *) *iter,
sizeof(DeconfigGard::GardRecord));
if (l_rc)
{
- HWAS_ERR("mm_remove_pages(FLUSH,%p,%d) returned %d",
+ HWAS_ERR("mm_remove_pages(FLUSH,%p,%d) returned %d",
*iter, sizeof(DeconfigGard::GardRecord),l_rc);
}
}
diff --git a/src/usr/targeting/common/genHwsvMrwXml.pl b/src/usr/targeting/common/genHwsvMrwXml.pl
index 8fcecc846..47e810009 100755
--- a/src/usr/targeting/common/genHwsvMrwXml.pl
+++ b/src/usr/targeting/common/genHwsvMrwXml.pl
@@ -1746,6 +1746,10 @@ sub generate_proc
<id>FABRIC_CHIP_ID</id>
<default>$logid</default>
</attribute>
+ <attribute>
+ <id>FRU_ID</id>
+ <default>$fruid</default>
+ </attribute>
<attribute><id>VPD_REC_NUM</id><default>$vpdnum</default></attribute>
<!-- workaround for SW196865 - see RTC:69918 for additional details -->
diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml
index a62352f1a..3d27e1c55 100644
--- a/src/usr/targeting/common/xmltohb/attribute_types.xml
+++ b/src/usr/targeting/common/xmltohb/attribute_types.xml
@@ -11862,6 +11862,14 @@ firmware notes: Platforms should initialize this attribute to AUTO (0)</descript
</attribute>
<attribute>
+ <id>FRU_ID</id>
+ <description>FRU ID attribute for chip class</description>
+ <simpleType><uint32_t><default>0</default></uint32_t></simpleType>
+ <persistency>non-volatile</persistency>
+ <readable/>
+</attribute>
+
+<attribute>
<id>PLCK_IPL_ATTR_OVERRIDES_EXIST</id>
<description>
Set to 1 by HWSV to indicate that attribute overrides exist in a PLCK IPL
diff --git a/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml b/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml
index e7e5d2cc5..c937876db 100644
--- a/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml
+++ b/src/usr/targeting/common/xmltohb/simics_MURANO.system.xml
@@ -254,6 +254,10 @@
<default>affinity:sys-0/node-0/proc-0</default>
</attribute>
<attribute>
+ <id>FRU_ID</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
<id>FABRIC_NODE_ID</id>
<default>0</default>
</attribute>
@@ -916,6 +920,10 @@
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-1</default>
</attribute>
+ <attribute>
+ <id>FRU_ID</id>
+ <default>0</default>
+ </attribute>
<!-- FSI is connected via proc0:MFSI-0 -->
<attribute>
<id>FSI_MASTER_CHIP</id>
@@ -1607,6 +1615,10 @@
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-2</default>
</attribute>
+ <attribute>
+ <id>FRU_ID</id>
+ <default>1</default>
+ </attribute>
<!-- FSI is connected via proc0:MFSI-1 -->
<attribute>
<id>FSI_MASTER_CHIP</id>
@@ -2297,6 +2309,10 @@
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-3</default>
</attribute>
+ <attribute>
+ <id>FRU_ID</id>
+ <default>1</default>
+ </attribute>
<!-- FSI is connected via proc0:MFSI-2 -->
<attribute>
<id>FSI_MASTER_CHIP</id>
diff --git a/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml b/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml
index 746b3c8c2..b21e190d5 100644
--- a/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml
+++ b/src/usr/targeting/common/xmltohb/simics_VENICE.system.xml
@@ -226,6 +226,10 @@
<default>affinity:sys-0/node-0/proc-0</default>
</attribute>
<attribute>
+ <id>FRU_ID</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
<id>FABRIC_NODE_ID</id>
<default>0</default>
</attribute>
@@ -1245,6 +1249,10 @@
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-1</default>
</attribute>
+ <attribute>
+ <id>FRU_ID</id>
+ <default>1</default>
+ </attribute>
<!-- FSI is connected via proc0:MFSI-1 -->
<attribute>
<id>FSI_MASTER_CHIP</id>
@@ -2285,6 +2293,10 @@
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-2</default>
</attribute>
+ <attribute>
+ <id>FRU_ID</id>
+ <default>2</default>
+ </attribute>
<!-- FSI is connected via proc0:MFSI-2 -->
<attribute>
<id>FSI_MASTER_CHIP</id>
@@ -3327,6 +3339,10 @@
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-3</default>
</attribute>
+ <attribute>
+ <id>FRU_ID</id>
+ <default>3</default>
+ </attribute>
<!-- FSI is connected via proc0:MFSI-3 -->
<attribute>
<id>FSI_MASTER_CHIP</id>
@@ -4366,6 +4382,10 @@
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-4</default>
</attribute>
+ <attribute>
+ <id>FRU_ID</id>
+ <default>4</default>
+ </attribute>
<!-- FSI is connected via proc0:MFSI-4 -->
<attribute>
<id>FSI_MASTER_CHIP</id>
@@ -5407,6 +5427,10 @@
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-5</default>
</attribute>
+ <attribute>
+ <id>FRU_ID</id>
+ <default>5</default>
+ </attribute>
<!-- FSI is connected via proc0:MFSI-5 -->
<attribute>
<id>FSI_MASTER_CHIP</id>
@@ -6446,6 +6470,10 @@
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-6</default>
</attribute>
+ <attribute>
+ <id>FRU_ID</id>
+ <default>6</default>
+ </attribute>
<!-- FSI is connected via proc0:MFSI-6 -->
<attribute>
<id>FSI_MASTER_CHIP</id>
@@ -7486,6 +7514,10 @@
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-7</default>
</attribute>
+ <attribute>
+ <id>FRU_ID</id>
+ <default>7</default>
+ </attribute>
<!-- FSI is connected via proc0:MFSI-7 -->
<attribute>
<id>FSI_MASTER_CHIP</id>
diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml
index 91078c0e5..5799da941 100644
--- a/src/usr/targeting/common/xmltohb/target_types.xml
+++ b/src/usr/targeting/common/xmltohb/target_types.xml
@@ -219,6 +219,9 @@
<attribute>
<id>CHIP_ID</id>
</attribute>
+ <attribute>
+ <id>FRU_ID</id>
+ </attribute>
</targetType>
<targetType>
diff --git a/src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml b/src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml
index e1b406ea2..70cda5561 100644
--- a/src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml
+++ b/src/usr/targeting/common/xmltohb/vbu_MURANO.system.xml
@@ -198,6 +198,10 @@
<default>affinity:sys-0/node-0/proc-0</default>
</attribute>
<attribute>
+ <id>FRU_ID</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
<id>FABRIC_NODE_ID</id>
<default>0</default>
</attribute>
@@ -710,6 +714,10 @@
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-1</default>
</attribute>
+ <attribute>
+ <id>FRU_ID</id>
+ <default>0</default>
+ </attribute>
<!-- FSI is connected via proc0:MFSI-0 -->
<attribute>
<id>FSI_MASTER_CHIP</id>
@@ -1133,6 +1141,10 @@
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-2</default>
</attribute>
+ <attribute>
+ <id>FRU_ID</id>
+ <default>1</default>
+ </attribute>
<!-- FSI is connected via proc0:MFSI-2 -->
<attribute>
<id>FSI_MASTER_CHIP</id>
@@ -1557,6 +1569,10 @@
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-3</default>
</attribute>
+ <attribute>
+ <id>FRU_ID</id>
+ <default>1</default>
+ </attribute>
<!-- FSI is connected via proc0:MFSI-3 -->
<attribute>
<id>FSI_MASTER_CHIP</id>
diff --git a/src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml b/src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml
index 719d461ff..193aaabe2 100644
--- a/src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml
+++ b/src/usr/targeting/common/xmltohb/vbu_VENICE.system.xml
@@ -243,6 +243,10 @@
<default>affinity:sys-0/node-0/proc-0</default>
</attribute>
<attribute>
+ <id>FRU_ID</id>
+ <default>0</default>
+ </attribute>
+ <attribute>
<id>FABRIC_NODE_ID</id>
<default>0</default>
</attribute>
@@ -1344,6 +1348,10 @@
<id>AFFINITY_PATH</id>
<default>affinity:sys-0/node-0/proc-1</default>
</attribute>
+ <attribute>
+ <id>FRU_ID</id>
+ <default>1</default>
+ </attribute>
<!-- FSI is connected via proc0:MFSI-1 -->
<attribute>
<id>FSI_MASTER_CHIP</id>
OpenPOWER on IntegriCloud