diff options
author | Dan Crowell <dcrowell@us.ibm.com> | 2014-12-14 11:16:24 -0600 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2015-01-16 11:39:12 -0600 |
commit | 54f90468fb55fbb11fb6fdff819f55c27d396e6e (patch) | |
tree | a088b759e63d4a0955097be970b49340e1108939 /src/usr/hwpf/hwp/occ | |
parent | a59dccb2db8eabad2b756b9207e28a0e72aa7cbc (diff) | |
download | talos-hostboot-54f90468fb55fbb11fb6fdff819f55c27d396e6e.tar.gz talos-hostboot-54f90468fb55fbb11fb6fdff819f55c27d396e6e.zip |
IPL-time interface to reset/stop OCCs
Change-Id: If95d6ca987ac586a0557e2456103bf6e5f65d890
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/14914
Tested-by: Jenkins Server
Reviewed-by: Christopher Cain <cjcain@us.ibm.com>
Reviewed-by: PRACHI GUPTA <pragupta@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/hwpf/hwp/occ')
-rw-r--r-- | src/usr/hwpf/hwp/occ/occ.C | 189 |
1 files changed, 186 insertions, 3 deletions
diff --git a/src/usr/hwpf/hwp/occ/occ.C b/src/usr/hwpf/hwp/occ/occ.C index 13fcbf949..b516ba87f 100644 --- a/src/usr/hwpf/hwp/occ/occ.C +++ b/src/usr/hwpf/hwp/occ/occ.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2013,2014 */ +/* Contributors Listed Below - COPYRIGHT 2013,2015 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -409,9 +409,9 @@ namespace HBOCC * * @return errlHndl_t Error log if OCC load failed */ - errlHndl_t activateOCC () + errlHndl_t activateOCCs() { - TRACUCOMP( g_fapiTd,ENTER_MRK"activateOCC" ); + TRACUCOMP( g_fapiTd,ENTER_MRK"activateOCCs" ); errlHndl_t l_errl = NULL; TARGETING::Target* l_failedOccTarget = NULL; #ifdef CONFIG_HTMGT @@ -440,4 +440,187 @@ namespace HBOCC TRACUCOMP( g_fapiTd,EXIT_MRK"activateOCC" ); return l_errl; } + + /** + * @brief Stops OCCs on all Processors in the node + */ + errlHndl_t stopOCCs() + { + TRACUCOMP( g_fapiTd,ENTER_MRK"stopOCCs" ); + errlHndl_t l_errl = NULL; + bool winkle_loaded = false; + + do { + //OCC requires the build_winkle_images library + if ( !VFS::module_is_loaded( "libbuild_winkle_images.so" ) ) + { + l_errl = VFS::module_load( "libbuild_winkle_images.so" ); + + if ( l_errl ) + { + // load module returned with errl set + TRACFCOMP( g_fapiTd,ERR_MRK"stopOCCs: Could not load build_winkle module" ); + // break from do loop if error occured + break; + } + winkle_loaded = true; + } + + TargetHandleList procChips; + getAllChips(procChips, TYPE_PROC, true); + + if(procChips.size() == 0) + { + TRACFCOMP( g_fapiTd,INFO_MRK"stopOCCs: No processors found" ); + //We'll never get this far in the IPL without any processors, + // so just exit. + break; + } + + TRACUCOMP( g_fapiTd, + INFO_MRK"stopOCCs: %d procs found", + procChips.size()); + + //The OCC Procedures require processors within a DCM be + //setup together. If DCM installed is set, we work under + //the assumption that each nodeID is a DCM. So sort the + //list by NodeID then call OCC Procedures on NodeID pairs. + std::sort(procChips.begin(), + procChips.end(), + orderByNodeAndPosition); + + //The OCC master for the node must be reset last. For all + //OP systems there is only a single OCC that can be the + //master so it is safe to look at the MASTER_CAPABLE flag. + Target* masterProc0 = NULL; + Target* masterProc1 = NULL; + + TargetHandleList::iterator itr1 = procChips.begin(); + + if(0 == (*itr1)->getAttr<ATTR_PROC_DCM_INSTALLED>()) + { + TRACUCOMP( g_fapiTd, + INFO_MRK"stopOCCs: non-dcm path entered"); + + for (TargetHandleList::iterator itr = procChips.begin(); + itr != procChips.end(); + ++itr) + { + TargetHandleList pOccs; + getChildChiplets(pOccs, *itr, TYPE_OCC); + if (pOccs.size() > 0) + { + if( pOccs[0]->getAttr<ATTR_OCC_MASTER_CAPABLE>() ) + { + masterProc0 = *itr; + continue; + } + } + + l_errl = HBOCC::stopOCC( *itr, NULL ); + if (l_errl) + { + TRACFCOMP( g_fapiImpTd, ERR_MRK"stopOCCs: stop failed"); + errlCommit (l_errl, HWPF_COMP_ID); + // just commit and try the next chip + } + } + if (l_errl) + { + break; + } + } + else + { + TRACUCOMP( g_fapiTd, + INFO_MRK"stopOCCs: Following DCM Path"); + + for (TargetHandleList::iterator itr = procChips.begin(); + itr != procChips.end(); + ++itr) + { + Target* targ0 = *itr; + Target* targ1 = NULL; + + TRACUCOMP( g_fapiImpTd, INFO_MRK"stopOCCs: Cur target nodeID=%d", + targ0->getAttr<ATTR_FABRIC_NODE_ID>()); + + //if the next target in the list is in the same node + // they are on the same DCM, so bump itr forward + // and update targ0 pointer + if((itr+1) != procChips.end()) + { + TRACUCOMP( g_fapiImpTd, INFO_MRK"stopOCCs: n+1 target nodeID=%d", ((*(itr+1))->getAttr<ATTR_FABRIC_NODE_ID>())); + + if((targ0->getAttr<ATTR_FABRIC_NODE_ID>()) == + ((*(itr+1))->getAttr<ATTR_FABRIC_NODE_ID>())) + { + //need to flip the numbers because we were reversed + targ1 = targ0; + itr++; + targ0 = *itr; + } + } + + TargetHandleList pOccs; + getChildChiplets(pOccs, targ0, TYPE_OCC); + if (pOccs.size() > 0) + { + if( pOccs[0]->getAttr<ATTR_OCC_MASTER_CAPABLE>() ) + { + masterProc0 = targ0; + masterProc1 = targ1; + continue; + } + } + + l_errl = HBOCC::stopOCC( targ0, targ1 ); + if (l_errl) + { + TRACFCOMP( g_fapiImpTd, ERR_MRK"stopOCCs: stop failed"); + errlCommit (l_errl, HWPF_COMP_ID); + // just commit and try the next module + } + } + if (l_errl) + { + break; + } + } + + //now do the master OCC + if( masterProc0 ) + { + l_errl = HBOCC::stopOCC( masterProc0, masterProc1 ); + if (l_errl) + { + TRACFCOMP( g_fapiImpTd, ERR_MRK"stopOCCs: stop failed on master"); + break; + } + } + } while(0); + + //make sure we always unload the module if we loaded it + if (winkle_loaded) + { + errlHndl_t l_tmpErrl = + VFS::module_unload( "libbuild_winkle_images.so" ); + if ( l_tmpErrl ) + { + TRACFCOMP( g_fapiTd,ERR_MRK"stopOCCs: Error unloading build_winkle module" ); + if(l_errl) + { + errlCommit( l_tmpErrl, HWPF_COMP_ID ); + } + else + { + l_errl = l_tmpErrl; + } + } + } + + TRACUCOMP( g_fapiTd,EXIT_MRK"stopOCCs" ); + return l_errl; + } + } //end OCC namespace |