diff options
author | Brian Horton <brianh@linux.ibm.com> | 2012-04-06 12:49:14 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2012-04-16 10:22:07 -0500 |
commit | e680dbb8a2fbc423665a274cf60f88d7550d37c0 (patch) | |
tree | 3f2bfe1acea74add810d85a4e03c2dac3c2ba7f2 /src | |
parent | 334a214dd6f311637c78cab7c021762617eca283 (diff) | |
download | talos-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.C | 208 | ||||
-rw-r--r-- | src/usr/hwas/plat/hwasPlat.C | 89 |
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>()); |