diff options
| author | Brian Horton <brianh@linux.ibm.com> | 2013-06-19 18:52:17 -0500 |
|---|---|---|
| committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-07-10 16:23:50 -0500 |
| commit | 36da1243a5e1026fe10de3194c167cb1ceeb77c8 (patch) | |
| tree | d666ee803d606f530c39d043adc0bb038f528148 /src/usr | |
| parent | 3837a7143776c6ea55fcda737e3425860c75a28c (diff) | |
| download | blackbird-hostboot-36da1243a5e1026fe10de3194c167cb1ceeb77c8.tar.gz blackbird-hostboot-36da1243a5e1026fe10de3194c167cb1ceeb77c8.zip | |
HWAS support of Field Core Override (FCO)
. add FIELD_CORE_OVERRIDE attribute
. add HWAS support of FCO to restrict EX units, if needed
Change-Id: I93acc3453edf68ce7dceab03d11ee2a08d312b1d
RTC: 45870
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/5099
Tested-by: Jenkins Server
Reviewed-by: MIKE J. JONES <mjjones@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr')
| -rw-r--r-- | src/usr/hwas/common/deconfigGard.C | 157 | ||||
| -rw-r--r-- | src/usr/hwas/common/hwas.C | 321 | ||||
| -rw-r--r-- | src/usr/hwas/hwasPlat.C | 56 | ||||
| -rw-r--r-- | src/usr/targeting/common/xmltohb/attribute_types.xml | 21 | ||||
| -rw-r--r-- | src/usr/targeting/common/xmltohb/target_types.xml | 1 |
5 files changed, 386 insertions, 170 deletions
diff --git a/src/usr/hwas/common/deconfigGard.C b/src/usr/hwas/common/deconfigGard.C index 617a262f4..6a9313c1a 100644 --- a/src/usr/hwas/common/deconfigGard.C +++ b/src/usr/hwas/common/deconfigGard.C @@ -26,10 +26,13 @@ * @brief Implements the DeconfigGard class */ #include <stdint.h> +#include <algorithm> +#include <hwas/common/hwas.H> #include <hwas/common/hwasCommon.H> #include <hwas/common/deconfigGard.H> #include <hwas/common/hwas_reasoncodes.H> +#include <targeting/common/utilFilter.H> // Trace definition #define __COMP_TD__ g_trac_deconf @@ -65,27 +68,43 @@ bool processDeferredDeconfig() errlHndl_t collectGard(const TARGETING::PredicateBase *i_pPredicate) { HWAS_INF("collectGard entry" ); + errlHndl_t errl = NULL; - errlHndl_t errl = theDeconfigGard().clearGardRecordsForReplacedTargets(); - - if (errl) - { - HWAS_ERR("ERROR: collectGard failed to clear GARD Records for replaced Targets"); - } - else + do { + + errl = theDeconfigGard().clearGardRecordsForReplacedTargets(); + if (errl) + { + HWAS_ERR("ERROR: collectGard failed to clear GARD Records for replaced Targets"); + break; + } + errl = theDeconfigGard(). deconfigureTargetsFromGardRecordsForIpl(i_pPredicate); - if (errl) { HWAS_ERR("ERROR: collectGard failed to deconfigure Targets from GARD Records for IPL"); + break; } - else + + errl = theDeconfigGard().processFieldCoreOverride(); + if (errl) { - HWAS_INF("collectGard completed successfully"); + HWAS_ERR("ERROR: collectGard failed to process Field Core Override"); + break; } } + while(0); + + if (errl) + { + HWAS_INF("collectGard failed (plid 0x%X)", errl->plid()); + } + else + { + HWAS_INF("collectGard completed successfully"); + } return errl; } @@ -296,6 +315,118 @@ errlHndl_t DeconfigGard::deconfigureTargetsFromGardRecordsForIpl( return l_pErr; } +bool compareTargetHuid(TARGETING::TargetHandle_t t1, + TARGETING::TargetHandle_t t2) +{ + return (t1->getAttr<TARGETING::ATTR_HUID>() < + t2->getAttr<TARGETING::ATTR_HUID>()); +} + +//****************************************************************************** +errlHndl_t DeconfigGard::processFieldCoreOverride() +{ + HWAS_INF("Process Field Core Override FCO"); + errlHndl_t l_pErr = NULL; + + do + { + // otherwise, process and reduce cores. + // find all functional NODE targets + TARGETING::Target* pSys; + TARGETING::targetService().getTopLevelTarget(pSys); + TARGETING::PredicateCTM predNode(TARGETING::CLASS_ENC, + TARGETING::TYPE_NODE); + TARGETING::PredicateHwas predFunctional; + predFunctional.functional(true); + TARGETING::PredicatePostfixExpr nodeCheckExpr; + nodeCheckExpr.push(&predNode).push(&predFunctional).And(); + + TARGETING::TargetHandleList pNodeList; + TARGETING::targetService().getAssociated(pNodeList, pSys, + TARGETING::TargetService::CHILD, + TARGETING::TargetService::ALL, + &nodeCheckExpr); + + // sort the list by ATTR_HUID to ensure that we + // start at the same place each time + std::sort(pNodeList.begin(), pNodeList.end(), + compareTargetHuid); + + // for each of the nodes + for (TARGETING::TargetHandleList::const_iterator + pNode_it = pNodeList.begin(); + pNode_it != pNodeList.end(); + ++pNode_it + ) + { + const TARGETING::TargetHandle_t pNode = *pNode_it; + + // Get FCO value + uint32_t l_fco = 0; + l_pErr = platGetFCO(pNode, l_fco); + if (l_pErr) + { + HWAS_ERR("Error from platGetFCO"); + break; + } + + // FCO of 0 means no overrides for this node + if (l_fco == 0) + { + HWAS_INF("FCO: node %.8X: no overrides, done.", + TARGETING::get_huid(pNode)); + continue; // next node + } + + HWAS_INF("FCO: node %.8X: value %d", + TARGETING::get_huid(pNode), l_fco); + + // find all functional child PROC targets + TARGETING::TargetHandleList pProcList; + TARGETING::getChildAffinityTargets(pProcList, pNode, + TARGETING::CLASS_CHIP, TARGETING::TYPE_PROC, + true); + + // sort the list by ATTR_HUID to ensure that we + // start at the same place each time + std::sort(pProcList.begin(), pProcList.end(), + compareTargetHuid); + + // create list for restrictEXunits() function + procRestrict_t l_procEntry; + std::vector <procRestrict_t> l_procRestrictList; + for (TARGETING::TargetHandleList::const_iterator + pProc_it = pProcList.begin(); + pProc_it != pProcList.end(); + ++pProc_it + ) + { + const TARGETING::TargetHandle_t pProc = *pProc_it; + + // save info so that we can + // restrict the number of EX units + HWAS_INF("pProc %.8X - pushing to proclist", + TARGETING::get_huid(pProc)); + l_procEntry.target = pProc; + l_procEntry.group = 0; + l_procEntry.procs = pProcList.size(); + l_procEntry.maxEXs = l_fco; + l_procRestrictList.push_back(l_procEntry); + } // for pProc_it + + // restrict the EX units; units turned off are marked + // present=true, functional=false + HWAS_INF("FCO: calling restrictEXunits with %d entries", + l_procRestrictList.size()); + l_pErr = restrictEXunits(l_procRestrictList, true); + break; + } // for pNode_it + } + while (0); + + return l_pErr; +} + //****************************************************************************** errlHndl_t DeconfigGard::deconfigureTarget(TARGETING::Target & i_target, const uint32_t i_errlPlid, @@ -500,7 +631,8 @@ void DeconfigGard::_deconfigureByAssoc(TARGETING::Target & i_target, TARGETING::TargetService::CHILD, TARGETING::TargetService::ALL, &hwasPredicate); - for (TARGETING::TargetHandleList::iterator pChild_it = pChildList.begin(); + for (TARGETING::TargetHandleList::const_iterator + pChild_it = pChildList.begin(); pChild_it != pChildList.end(); ++pChild_it) { @@ -516,7 +648,8 @@ void DeconfigGard::_deconfigureByAssoc(TARGETING::Target & i_target, TARGETING::TargetService::CHILD_BY_AFFINITY, TARGETING::TargetService::ALL, &hwasPredicate); - for (TARGETING::TargetHandleList::iterator pChild_it = pChildList.begin(); + for (TARGETING::TargetHandleList::const_iterator + pChild_it = pChildList.begin(); pChild_it != pChildList.end(); ++pChild_it) { diff --git a/src/usr/hwas/common/hwas.C b/src/usr/hwas/common/hwas.C index 4e04ee86e..be642ca13 100644 --- a/src/usr/hwas/common/hwas.C +++ b/src/usr/hwas/common/hwas.C @@ -36,6 +36,7 @@ #include <algorithm> #include <targeting/common/commontargeting.H> +#include <targeting/common/utilFilter.H> #include <hwas/common/hwas.H> #include <hwas/common/hwasCommon.H> @@ -59,22 +60,19 @@ 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) +bool compareProcGroup(procRestrict_t t1, procRestrict_t t2) { - return (t1.fruid < t2.fruid); + if (t1.group == t2.group) + { + return (t1.target->getAttr<ATTR_HUID>() < + t2.target->getAttr<ATTR_HUID>()); + } + return (t1.group < t2.group); } /** @@ -173,10 +171,14 @@ errlHndl_t discoverTargets() // 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(); + procRestrict_t l_procEntry; + std::vector <procRestrict_t> l_procPRList; + + // sort the list by ATTR_HUID to ensure that we + // start at the same place each time + std::sort(pCheckPres.begin(), pCheckPres.end(), + compareTargetHUID); + for (TargetHandleList::const_iterator pTarget_it = pCheckPres.begin(); pTarget_it != pCheckPres.end(); ++pTarget_it ) @@ -291,12 +293,12 @@ errlHndl_t discoverTargets() pTarget->getAttr<ATTR_HUID>(), pTarget->getAttr<ATTR_FRU_ID>()); l_procEntry.target = pTarget; - l_procEntry.fruid = pTarget->getAttr<ATTR_FRU_ID>(); - l_procEntry.avgNum = + l_procEntry.group = pTarget->getAttr<ATTR_FRU_ID>(); + l_procEntry.procs = + (prData[7] & VPD_VINI_PR_B7_MASK) + 1; + l_procEntry.maxEXs = l_procEntry.procs * (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); } } @@ -312,7 +314,7 @@ errlHndl_t discoverTargets() TargetHandleList pDescList; targetService().getAssociated( pDescList, pTarget, TargetService::CHILD, TargetService::ALL); - for (TargetHandleList::iterator pDesc_it = pDescList.begin(); + for (TargetHandleList::const_iterator pDesc_it = pDescList.begin(); pDesc_it != pDescList.end(); ++pDesc_it) { @@ -419,156 +421,187 @@ errlHndl_t discoverTargets() // PR keyword processing - potentially reduce the number of ex/core // units that are functional based on what's in the PR keyword. + // call to restrict EX units, marking bad units as present=false; + errl = restrictEXunits(l_procPRList, false); - // 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; + } while (0); + + if (errl) + { + HWAS_INF("discoverTargets failed (plid 0x%X)", errl->plid()); + } + else + { + HWAS_INF("discoverTargets completed successfully"); + } + return errl; +} // discoverTargets - // 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); +errlHndl_t restrictEXunits( + std::vector <procRestrict_t> &i_procList, + bool i_present) +{ + HWAS_INF("restrictEXunits entry, %d elements", i_procList.size()); + errlHndl_t errl = NULL; - // exs and iters for each proc in this vpd set - TargetHandleList pEXList[vpdCopies]; - TargetHandleList::iterator pEX_it[vpdCopies]; + // sort by group so PROC# are in the right groupings. + std::sort(i_procList.begin(), i_procList.end(), + compareProcGroup); + + // loop thru procs to handle restrict + const uint32_t l_ProcCount = i_procList.size(); + for (uint32_t procIdx = 0; + procIdx < l_ProcCount; + // the increment will happen in the loop to handle + // groups covering more than 1 proc target + ) + { + // determine the number of procs we should enable + uint8_t procs = i_procList[procIdx].procs; + uint32_t maxEXs = i_procList[procIdx].maxEXs; - // 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; + // this procs number, used to determine groupings + uint32_t thisGroup = i_procList[procIdx].group; - // 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); + HWAS_INF("procRestrictList[%d] - maxEXs %d, procs %d, group %d", + procIdx, maxEXs, procs, thisGroup); - // change this to be how many we actually have here - vpdCopies = i; + // exs and iters for each proc in this vpd set + TargetHandleList pEXList[procs]; + TargetHandleList::const_iterator pEX_it[procs]; - // we're done - break so that we use procIdx as the - // start index next time - break; - } + // find the proc's that we think are in this group + uint32_t currentEXs = 0; + for (uint32_t i = 0; i < procs; ) // increment in loop + { + TargetHandle_t pProc = i_procList[procIdx].target; - // get this proc's (CHILD) present EX units - targetService().getAssociated( pEXList[i], pProc, - TargetService::CHILD, TargetService::ALL, &exCheckExpr); + // if this proc is past the last of the proc count + // OR is NOT in the same group + if ((procIdx >= l_ProcCount) || + (thisGroup != i_procList[procIdx].group)) + { + HWAS_DBG("procRestrictList[%d] - group %d not in group %d", + i, i_procList[procIdx].group, thisGroup); - if (!pEXList[i].empty()) - { - // 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); + // change this to be how many we actually have here + procs = i; - // keep a pointer into that list - pEX_it[i] = pEXList[i].begin(); - } - else - { - // this one is bad, so decrement the counters - vpdCopies--; - i--; - } + // we're done - break so that we use procIdx as the + // start index next time + break; + } - // advance the outer loop as well since we're doing these - // procs together - ++procIdx; - } // for + // get this proc's (CHILD) functional EX units + getChildChiplets(pEXList[i], pProc, TYPE_EX, true); - // 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; - HWAS_DBG("vpdCopies %d maxEXs %d", vpdCopies, maxEXs); - do + if (!pEXList[i].empty()) { - // now cycle thru the procs - for (uint32_t i = 0;i < vpdCopies;i++) - { - // if we have EX units still to process - // from this processor - if (pEX_it[i] != pEXList[i].end()) - { - // got a present EX - goodEXs++; - HWAS_DBG("pEX %.8X - is good %d!", - (*(pEX_it[i]))->getAttr<ATTR_HUID>(), goodEXs); + // 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); - (pEX_it[i])++; // next ex/core in this proc's list + // keep a pointer into that list + pEX_it[i] = pEXList[i].begin(); - // check to see if we just hit the end of the list - if (pEX_it[i] == pEXList[i].end()) - { - procs_remaining--; - continue; - } - } - } // for + // keep local count of current functional EX units + currentEXs += pEXList[i].size(); + + // go to next proc + i++; + } + else + { + // this one is bad, stay on this i but lower the end count + procs--; } - 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++) + // advance the outer loop as well since we're doing these + // procs together + ++procIdx; + } // for + + if (currentEXs <= maxEXs) + { + // we don't need to restrict - we're done with this group. + HWAS_DBG("currentEXs %d <= maxEXs %d -- done", + currentEXs, maxEXs); + continue; + } + + HWAS_DBG("currentEXs %d > maxEXs %d -- restricting!", + currentEXs, maxEXs); + + // 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 = procs; + uint32_t goodEXs = 0; + HWAS_DBG("procs %d maxEXs %d", procs, maxEXs); + do + { + // now cycle thru the procs, stopping when we either hit + // the end, or when we hit our maxEXs limit + for (uint32_t i = 0;(i < procs) && (goodEXs < maxEXs);i++) { - // walk thru the rest of the EX list - while (pEX_it[i] != pEXList[i].end()) + // if we have EX units still to process + // from this processor + if (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>()); + // got a functional EX + goodEXs++; + HWAS_DBG("pEX %.8X - is good %d!", + (*(pEX_it[i]))->getAttr<ATTR_HUID>(), goodEXs); + (pEX_it[i])++; // next ex/core in this proc's list + + // check to see if we just hit the end of the list + if (pEX_it[i] == pEXList[i].end()) + { + procs_remaining--; + continue; + } } - } // for making remaining non-present/non-functional - } // for procIdx < l_PRProcCount + } // for + } + while ((goodEXs < maxEXs) && (procs_remaining != 0)); - } while (0); + // now mark the rest of the EXs as non-functional + for (uint32_t i = 0;i < procs;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, i_present, false, 0); + HWAS_INF("pEX %.8X - marked %spresent, NOT functional", + l_pEX->getAttr<ATTR_HUID>(), + i_present ? "" : "NOT "); + + // now need to mark the child CORE + TargetHandleList pCoreList; + getChildChiplets(pCoreList, l_pEX, TYPE_CORE, true); + enableHwasState(pCoreList[0], i_present, false, 0); + HWAS_INF("pCore %.8X - marked %spresent, NOT functional", + l_pEX->getAttr<ATTR_HUID>(), + i_present ? "" : "NOT "); + (pEX_it[i])++; // next ex/core in this proc's list + } + } // for making remaining non-functional + } // for procIdx < l_ProcCount - HWAS_INF("discoverTargets returning errl %p", errl); + if (errl) + { + HWAS_INF("restrictEXunits failed (plid 0x%X)", errl->plid()); + } + else + { + HWAS_INF("restrictEXunits completed successfully"); + } return errl; -} // discoverTargets +} // restrictEXunits }; // end namespace diff --git a/src/usr/hwas/hwasPlat.C b/src/usr/hwas/hwasPlat.C index 2371fca68..d3b736a94 100644 --- a/src/usr/hwas/hwasPlat.C +++ b/src/usr/hwas/hwasPlat.C @@ -77,8 +77,8 @@ errlHndl_t platReadIDEC(const TargetHandle_t &i_target) // using SCOM path. We must use FSI path to read the IDEC values. // For master proc, use scom // For everything else, use FSI(0x1028) - TARGETING::Target* l_pMasterProcChip = NULL; - TARGETING::targetService(). masterProcChipTargetHandle(l_pMasterProcChip); + Target* l_pMasterProcChip = NULL; + targetService().masterProcChipTargetHandle(l_pMasterProcChip); if (i_target == l_pMasterProcChip) { @@ -161,11 +161,19 @@ errlHndl_t platReadPartialGood(const TargetHandle_t &i_target, // skip past the header uint16_t *pgData = reinterpret_cast <uint16_t *>(&pgRaw[VPD_CP00_PG_HDR_LENGTH]); if (i_target->getAttr<ATTR_HUID>() == 0x50000) - { // 1st proc - let it go thru ok. + { // 1st proc + pgData[VPD_CP00_PG_EX0_INDEX+4] = 0xF300; + pgData[VPD_CP00_PG_EX0_INDEX+5] = 0xF300; + pgData[VPD_CP00_PG_EX0_INDEX+6] = 0x9300; // off + pgData[VPD_CP00_PG_EX0_INDEX+12] = 0x9300; // off + pgData[VPD_CP00_PG_EX0_INDEX+13] = 0x9300; // off + pgData[VPD_CP00_PG_EX0_INDEX+14] = 0x9300; // off } else if (i_target->getAttr<ATTR_HUID>() == 0x50001) - { + { // 2nd proc + pgData[VPD_CP00_PG_EX0_INDEX+4] = 0xF300; + pgData[VPD_CP00_PG_EX0_INDEX+5] = 0xF300; pgData[VPD_CP00_PG_EX0_INDEX+6] = 0xF300; pgData[VPD_CP00_PG_EX0_INDEX+12] = 0xF300; pgData[VPD_CP00_PG_EX0_INDEX+13] = 0xF300; @@ -178,17 +186,22 @@ errlHndl_t platReadPartialGood(const TargetHandle_t &i_target, //// 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+4] = 0xF300; + pgData[VPD_CP00_PG_EX0_INDEX+5] = 0xF300; + pgData[VPD_CP00_PG_EX0_INDEX+6] = 0x9300; // off + pgData[VPD_CP00_PG_EX0_INDEX+12] = 0x9300; // off 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 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; + pgData[VPD_CP00_PG_EX0_INDEX+4] = 0xF300; + pgData[VPD_CP00_PG_EX0_INDEX+5] = 0xF300; + pgData[VPD_CP00_PG_EX0_INDEX+6] = 0x9300; // off + pgData[VPD_CP00_PG_EX0_INDEX+12] = 0x9300; // off + pgData[VPD_CP00_PG_EX0_INDEX+13] = 0x9300; // off + pgData[VPD_CP00_PG_EX0_INDEX+14] = 0x9300; // off } } #endif @@ -234,7 +247,7 @@ errlHndl_t platReadPR(const TargetHandle_t &i_target, 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[7] = 1; // 2 procs //prData[2] = 1 << VPD_VINI_PR_B2_SHIFT; // 1*4 = 4 cores //prData[7] = 3; // 4 cores } @@ -249,16 +262,16 @@ errlHndl_t platReadPR(const TargetHandle_t &i_target, 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] = 3 << VPD_VINI_PR_B2_SHIFT; // 3*1 = 3 cores + prData[7] = 0; // 1 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] = 4 << VPD_VINI_PR_B2_SHIFT; // 4*1 = 4 cores + prData[7] = 0; // 1 procs //prData[2] = 1 << VPD_VINI_PR_B2_SHIFT; // 1*4 = 4 cores //prData[7] = 3; // 4 cores } @@ -274,6 +287,21 @@ errlHndl_t platReadPR(const TargetHandle_t &i_target, } // platReadPR //****************************************************************************** +// platGetFCO function +//****************************************************************************** +errlHndl_t platGetFCO(const TargetHandle_t &i_node, + uint32_t &o_fco) +{ + errlHndl_t errl = NULL; + + o_fco = i_node->getAttr<ATTR_FIELD_CORE_OVERRIDE>(); + + HWAS_INF("FCO returned: %d", o_fco); + + return errl; +} // platGetFCO + +//****************************************************************************** // platPresenceDetect function //****************************************************************************** errlHndl_t platPresenceDetect(TargetHandleList &io_targets) diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml index 8a1ca787b..77afa1c8e 100644 --- a/src/usr/targeting/common/xmltohb/attribute_types.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types.xml @@ -12605,4 +12605,25 @@ firmware notes: Platforms should initialize this attribute to AUTO (0)</descript </enumerator> </enumerationType> +<attribute> + <id>FIELD_CORE_OVERRIDE</id> + <description>Field Core Override (FCO) is the override value for the + number of functional cores allowed on the system. + FCO is used when customers order a system with N cores but they only want + to enable less than N cores to lower software license costs. A field in the + anchor VPD is set by manufacturing to specify the maximum number of cores + to enable. The number is maintained, even if some cores are garded out due + to error. + A value of 0 means all cores allowed; + </description> + <simpleType> + <uint32_t> + <default>0</default> + </uint32_t> + </simpleType> + <persistency>non-volatile</persistency> + <readable/> + <writeable/> +</attribute> + </attributes> diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml index 46a4c4131..99553c49a 100644 --- a/src/usr/targeting/common/xmltohb/target_types.xml +++ b/src/usr/targeting/common/xmltohb/target_types.xml @@ -651,6 +651,7 @@ <id>MODEL</id> <default>POWER8</default> </attribute> + <attribute><id>FIELD_CORE_OVERRIDE</id></attribute> </targetType> <targetType> |

