summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBrian Horton <brianh@linux.ibm.com>2012-04-06 12:49:14 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-04-16 10:22:07 -0500
commite680dbb8a2fbc423665a274cf60f88d7550d37c0 (patch)
tree3f2bfe1acea74add810d85a4e03c2dac3c2ba7f2 /src
parent334a214dd6f311637c78cab7c021762617eca283 (diff)
downloadtalos-hostboot-e680dbb8a2fbc423665a274cf60f88d7550d37c0.tar.gz
talos-hostboot-e680dbb8a2fbc423665a274cf60f88d7550d37c0.zip
Improve presence detection in HWAS code
Change presence detection logic in HWAS code to be a bit more general, in case something in the layout and structure of CLASS and TYPE changes. Instead of relying on a CLASS_SYS -> CLASS_ENC -> (objects that need physical detect) hierarchy, rely on the fact that we know all PROC MEMBUF and DIMM targets are the ones that need the platform-specific physical detect. Also, list of present targets will be culled so that only CLASS_CHIP targets are in the list for the call to the platform-specific routine that does the Chip ID and EC Level fetching. And, use new HUID attribute instead of local function for debug/error msgs. This is RTC Task 39791. Change-Id: I3f3e14ebcc02da15ab08a2c8d9151dbff6648a34 RTC: 35007 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/836 Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com> Tested-by: Jenkins Server
Diffstat (limited to 'src')
-rw-r--r--src/usr/hwas/hwas.C208
-rw-r--r--src/usr/hwas/plat/hwasPlat.C89
2 files changed, 128 insertions, 169 deletions
diff --git a/src/usr/hwas/hwas.C b/src/usr/hwas/hwas.C
index b77c37dd1..ff57bcc9e 100644
--- a/src/usr/hwas/hwas.C
+++ b/src/usr/hwas/hwas.C
@@ -50,53 +50,6 @@ namespace HWAS
using namespace TARGETING;
-//@todo - This should come from the target/attribute code somewhere
-uint64_t target_to_uint64(const Target* i_target)
-{
- uint64_t id = 0;
- if (i_target == NULL)
- {
- id = 0x0;
- }
- else if (i_target == MASTER_PROCESSOR_CHIP_TARGET_SENTINEL)
- {
- id = 0xFFFFFFFFFFFFFFFF;
- }
- else
- {
- // physical path, 3 nibbles per type/instance pair
- // TIITIITII... etc.
- EntityPath epath;
- i_target->tryGetAttr<ATTR_PHYS_PATH>(epath);
- for (uint32_t x = 0; x < epath.size(); x++)
- {
- id = id << 12;
- id |= (uint64_t)((epath[x].type << 8) & 0xF00);
- id |= (uint64_t)(epath[x].instance & 0x0FF);
- }
- }
- return id;
-}
-
-
-/**
- * @brief simple helper function to get and set hwas to clear state
- *
- * @param[in] i_target pointer to target that we're looking at
- *
- * @return none
- */
-void clearHwasState(Target * i_target)
-{
- HwasState hwasState = i_target->getAttr<ATTR_HWAS_STATE>();
- hwasState.poweredOn = false;
- hwasState.present = false;
- hwasState.functional = false;
- hwasState.changedSinceLastIPL = false;
- hwasState.gardLevel = 0;
- i_target->setAttr<ATTR_HWAS_STATE>(hwasState);
-}
-
/**
* @brief simple helper fn to get and set hwas state to poweredOn,
* present, functional
@@ -115,6 +68,7 @@ void enableHwasState(Target *i_target)
i_target->setAttr<ATTR_HWAS_STATE>( hwasState );
}
+
errlHndl_t discoverTargets()
{
HWAS_DBG("discoverTargets entry");
@@ -125,32 +79,34 @@ errlHndl_t discoverTargets()
target != targetService().end();
++target)
{
- clearHwasState(*target);
+ HwasState hwasState = target->getAttr<ATTR_HWAS_STATE>();
+ hwasState.poweredOn = false;
+ hwasState.present = false;
+ hwasState.functional = false;
+ hwasState.changedSinceLastIPL = false;
+ hwasState.gardLevel = 0;
+ target->setAttr<ATTR_HWAS_STATE>(hwasState);
}
- // ASSUMPTIONS: Physical hierarchy is:
- // CLASS_SYS (exactly 1)
- // \->children: CLASS_ENC
- // \->children: CLASS_* where ALL require hardware query
- // \->children: CLASS_* where NONE require hardware query
-
- // find CLASS_SYS (the top level target)
- Target* pSys;
- targetService().getTopLevelTarget(pSys);
+ // ASSUMPTIONS:
+ // CLASS_SYS (exactly 1) - mark as present
+ // CLASS_ENC (>=1) - mark as present
+ // TYPE_PROC TYPE_MEMBUF TYPE_DIMM (ALL require hardware query)
+ // - call platPresenceDetect
+ // \->children: CLASS_* (NONE require hardware query) - mark as present
do
{
- if (pSys == NULL)
- {
- // shouldn't happen; if it does, then we're done - nothing present.
- HWAS_ERR("pSys NULL - nothing present");
- break; // break out of the do/while so that we can return
- }
+ // find CLASS_SYS (the top level target)
+ Target* pSys;
+ targetService().getTopLevelTarget(pSys);
+
+ assert(pSys, "HWAS discoverTargets: no CLASS_SYS TopLevelTarget found");
// mark this as present
enableHwasState(pSys);
HWAS_DBG("pSys %x (%p) %x/%x - marked present",
- target_to_uint64(pSys), pSys,
+ pSys->getAttr<ATTR_HUID>(), pSys,
pSys->getAttr<ATTR_CLASS>(), pSys->getAttr<ATTR_TYPE>());
// find CLASS_ENC
@@ -168,69 +124,89 @@ errlHndl_t discoverTargets()
// mark it as present
enableHwasState(pEnc);
HWAS_DBG("pEnc %x (%p) %x/%x - marked present",
- target_to_uint64(pEnc), pEnc,
+ pEnc->getAttr<ATTR_HUID>(), pEnc,
pEnc->getAttr<ATTR_CLASS>(), pEnc->getAttr<ATTR_TYPE>());
+ } // for pEnc_it
- // now find the physical children
- TargetHandleList pChildList;
- targetService().getAssociated(pChildList, pEnc,
- TargetService::CHILD, TargetService::IMMEDIATE);
+ // find TYPE_PROC, TYPE_MEMBUF and TYPE_DIMM
+ PredicateCTM predProc(CLASS_CHIP, TYPE_PROC);
+ PredicateCTM predMembuf(CLASS_CHIP, TYPE_MEMBUF);
+ PredicateCTM predDimm(CLASS_LOGICAL_CARD, TYPE_DIMM);
+ PredicatePostfixExpr checkExpr;
+ checkExpr.push(&predProc).push(&predMembuf).Or().push(&predDimm).Or();
- // pass this list of children to the hwas common api
- // pChildList will be modified to only have present targets
- HWAS_DBG("pChildList size before %d", pChildList.size());
- errl = platPresenceDetect(pChildList);
- HWAS_DBG("pChildList size after %d", pChildList.size());
+ TargetHandleList pCheckPres;
+ targetService().getAssociated( pCheckPres, pSys,
+ TargetService::CHILD, TargetService::ALL, &checkExpr );
+
+ // pass this list to the hwas platform-specific api where
+ // pCheckPres will be modified to only have present targets
+ HWAS_DBG("pCheckPres size: %d", pCheckPres.size());
+ errl = platPresenceDetect(pCheckPres);
+ HWAS_DBG("pCheckPres size: %d", pCheckPres.size());
+
+ if (errl != NULL)
+ {
+ break; // break out of the do/while so that we can return
+ }
- if (errl != NULL)
+ // no errors - keep going
+ // for each, mark them and their descendants as present
+ for (TargetHandleList::iterator pTarget_it = pCheckPres.begin();
+ pTarget_it != pCheckPres.end();
+ ) // increment will be done in the loop below
+ {
+ TargetHandle_t pTarget = *pTarget_it;
+
+ // set HWAS state to show it's present
+ enableHwasState(pTarget);
+ HWAS_DBG("pTarget %x (%p) %x/%x - detected present",
+ pTarget->getAttr<ATTR_HUID>(), pTarget,
+ pTarget->getAttr<ATTR_CLASS>(),
+ pTarget->getAttr<ATTR_TYPE>());
+
+ // now need to mark all of this target's
+ // physical descendants as present
+ TargetHandleList pDescList;
+ targetService().getAssociated( pDescList, pTarget,
+ TargetService::CHILD, TargetService::ALL);
+ for (TargetHandleList::iterator pDesc_it = pDescList.begin();
+ pDesc_it != pDescList.end();
+ pDesc_it++)
{
- break; // get out of the pEnc loop
+ TargetHandle_t pDesc = *pDesc_it;
+ enableHwasState(pDesc);
+ HWAS_DBG("pDesc %x (%p) %x/%x - marked present",
+ pDesc->getAttr<ATTR_HUID>(), pDesc,
+ pDesc->getAttr<ATTR_CLASS>(),
+ pDesc->getAttr<ATTR_TYPE>());
}
- // read Chip ID/EC data from these physical chips, since they
- // are present
- errl = platReadIDEC(pChildList);
-
- if (errl != NULL)
+ // if we're not a CHIP, remove us from the list, so that
+ // when we do the Chip ID/EC call after the loop, we have
+ // a list that is CHIPs only
+ if (pTarget->getAttr<ATTR_CLASS>() != CLASS_CHIP)
{
- break; // get out of the pEnc loop
+ // erase this target, and 'increment' to next
+ pTarget_it = pCheckPres.erase(pTarget_it);
}
+ else
+ {
+ // advance to next entry in the list
+ pTarget_it++;
+ }
+ } // for pTarget_it
- // no errors - keep going
+ // at this point, pCheckPres only has present CLASS_CHIP targets
+ // read Chip ID/EC data from these physical chips
+ HWAS_DBG("pCheckPres size: %d", pCheckPres.size());
+ errl = platReadIDEC(pCheckPres);
+
+ if (errl != NULL)
+ {
+ break; // break out of the do/while so that we can return
+ }
- // at this point, pChildList only has present targets
- // for each, mark them and their descendants as present
- for (TargetHandleList::iterator pChild_it = pChildList.begin();
- pChild_it != pChildList.end();
- pChild_it++)
- {
- TargetHandle_t pChild = *pChild_it;
-
- // set HWAS state to show it's present
- enableHwasState(pChild);
- HWAS_DBG("pChild %x (%p) %x/%x - detected present",
- target_to_uint64(pChild), pChild,
- pChild->getAttr<ATTR_CLASS>(),
- pChild->getAttr<ATTR_TYPE>());
-
- // now need to mark all of this target's
- // physical descendants as present
- TargetHandleList pDescList;
- targetService().getAssociated( pDescList, pChild,
- TargetService::CHILD, TargetService::ALL);
- for (TargetHandleList::iterator pDesc_it = pDescList.begin();
- pDesc_it != pDescList.end();
- pDesc_it++)
- {
- TargetHandle_t pDesc = *pDesc_it;
- enableHwasState(pDesc);
- HWAS_DBG("pDsnds %x (%p) %x/%x - marked present",
- target_to_uint64(pDesc), pDesc,
- pDesc->getAttr<ATTR_CLASS>(),
- pDesc->getAttr<ATTR_TYPE>());
- }
- } // for pChild_it
- } // for pEnc_it
} while (0);
if (errl != NULL)
diff --git a/src/usr/hwas/plat/hwasPlat.C b/src/usr/hwas/plat/hwasPlat.C
index 9bf5a5ed4..8611b6531 100644
--- a/src/usr/hwas/plat/hwasPlat.C
+++ b/src/usr/hwas/plat/hwasPlat.C
@@ -43,8 +43,6 @@ namespace HWAS
using namespace TARGETING;
-uint64_t target_to_uint64(const Target* i_target);
-
//******************************************************************************
// platReadIDEC function
//******************************************************************************
@@ -52,12 +50,7 @@ errlHndl_t platReadIDEC(const TargetHandleList &i_targets)
{
errlHndl_t errl = NULL;
- // we have to handle the master processor chip special, so figure
- // out what it is first
- Target* pMasterProc = NULL;
- targetService().masterProcChipTargetHandle(pMasterProc);
-
- // we got a list of targets - read the ID/EC for eacn
+ // we got a list of targets - read the ID/EC for each
// and update the appropriate ATTR_ fields.
for (TargetHandleList::const_iterator pTarget_it = i_targets.begin();
pTarget_it != i_targets.end();
@@ -65,48 +58,38 @@ errlHndl_t platReadIDEC(const TargetHandleList &i_targets)
{
TargetHandle_t pTarget = *pTarget_it;
- if (pTarget->getAttr<ATTR_CLASS>() == CLASS_CHIP)
- {
- uint64_t id_ec;
- size_t op_size = sizeof(id_ec);
- errl = DeviceFW::deviceRead(pTarget, &id_ec,
- op_size, DEVICE_SCOM_ADDRESS(0x000F000Full));
-
- if (errl == NULL)
- { // no error, so we got a valid ID/EC value back
- // EC - nibbles 0,2
- // 01234567
- uint8_t ec = (((id_ec & 0xF000000000000000ull) >> 56) |
- ((id_ec & 0x00F0000000000000ull) >> 52));
- pTarget->setAttr<ATTR_EC>(ec);
-
- // ID - nibbles 1,5,3,4
- // 01234567
- uint32_t id = (((id_ec & 0x0F00000000000000ull) >> 44) |
- ((id_ec & 0x00000F0000000000ull) >> 32) |
- ((id_ec & 0x000F000000000000ull) >> 44) |
- ((id_ec & 0x0000F00000000000ull) >> 44));
- pTarget->setAttr<ATTR_CHIP_ID>(id);
- HWAS_DBG( "pTarget %x (%p) id %x ec %x",
- target_to_uint64(pTarget), pTarget, id, ec);
- }
- else
- { // errl was set - this is an error condition.
- HWAS_ERR( "pTarget %x (%p) %x/%x - failed ID/EC read",
- target_to_uint64(pTarget), pTarget,
- pTarget->getAttr<ATTR_CLASS>(),
- pTarget->getAttr<ATTR_TYPE>());
+ uint64_t id_ec;
+ size_t op_size = sizeof(id_ec);
+ errl = DeviceFW::deviceRead(pTarget, &id_ec,
+ op_size, DEVICE_SCOM_ADDRESS(0x000F000Full));
- // break out so that we can return an error
- break;
- }
+ if (errl == NULL)
+ { // no error, so we got a valid ID/EC value back
+ // EC - nibbles 0,2
+ // 01234567
+ uint8_t ec = (((id_ec & 0xF000000000000000ull) >> 56) |
+ ((id_ec & 0x00F0000000000000ull) >> 52));
+ pTarget->setAttr<ATTR_EC>(ec);
+
+ // ID - nibbles 1,5,3,4
+ // 01234567
+ uint32_t id = (((id_ec & 0x0F00000000000000ull) >> 44) |
+ ((id_ec & 0x00000F0000000000ull) >> 32) |
+ ((id_ec & 0x000F000000000000ull) >> 44) |
+ ((id_ec & 0x0000F00000000000ull) >> 44));
+ pTarget->setAttr<ATTR_CHIP_ID>(id);
+ HWAS_DBG( "pTarget %x (%p) id %x ec %x",
+ pTarget->getAttr<ATTR_HUID>(), pTarget, id, ec);
}
else
- { // skipping - no ID/EC on this target
- HWAS_DBG( "pTarget %x (%p) %x/%x - skipping",
- target_to_uint64(pTarget), pTarget,
+ { // errl was set - this is an error condition.
+ HWAS_ERR( "pTarget %x (%p) %x/%x - failed ID/EC read",
+ pTarget->getAttr<ATTR_HUID>(), pTarget,
pTarget->getAttr<ATTR_CLASS>(),
pTarget->getAttr<ATTR_TYPE>());
+
+ // break out so that we can return an error
+ break;
}
} // for pTarget_it
@@ -138,8 +121,8 @@ errlHndl_t platPresenceDetect(TargetHandleList &io_targets)
{ // no error, so we got a valid present value back
if (present == true)
{
- HWAS_DBG( "io_targets %x (%p) %x/%x - detected present",
- target_to_uint64(pTarget), pTarget,
+ HWAS_DBG( "pTarget %x (%p) %x/%x - detected present",
+ pTarget->getAttr<ATTR_HUID>(), pTarget,
pTarget->getAttr<ATTR_CLASS>(),
pTarget->getAttr<ATTR_TYPE>());
@@ -148,19 +131,19 @@ errlHndl_t platPresenceDetect(TargetHandleList &io_targets)
}
else
{ // chip no present -- remove from list
- HWAS_DBG( "io_targets %x (%p) %x/%x - no presence",
- target_to_uint64(pTarget), pTarget,
+ HWAS_DBG( "pTarget %x (%p) %x/%x - no presence",
+ pTarget->getAttr<ATTR_HUID>(), pTarget,
pTarget->getAttr<ATTR_CLASS>(),
pTarget->getAttr<ATTR_TYPE>());
- // erase this target, and 'increment' to next
- pTarget_it = io_targets.erase(pTarget_it);
+ // erase this target, and 'increment' to next
+ pTarget_it = io_targets.erase(pTarget_it);
}
}
else
{ // errl was set - this is an error condition.
- HWAS_ERR( "io_targets %x (%p) %x/%x - failed presence detect",
- target_to_uint64(pTarget), pTarget,
+ HWAS_ERR( "pTarget %x (%p) %x/%x - failed presence detect",
+ pTarget->getAttr<ATTR_HUID>(), pTarget,
pTarget->getAttr<ATTR_CLASS>(),
pTarget->getAttr<ATTR_TYPE>());
OpenPOWER on IntegriCloud