From 54f90468fb55fbb11fb6fdff819f55c27d396e6e Mon Sep 17 00:00:00 2001 From: Dan Crowell Date: Sun, 14 Dec 2014 11:16:24 -0600 Subject: 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 Reviewed-by: PRACHI GUPTA Reviewed-by: A. Patrick Williams III --- src/usr/hwpf/hwp/occ/occ.C | 189 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 186 insertions(+), 3 deletions(-) (limited to 'src/usr/hwpf/hwp/occ') 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()) + { + 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() ) + { + 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()); + + //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())); + + if((targ0->getAttr()) == + ((*(itr+1))->getAttr())) + { + //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() ) + { + 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 -- cgit v1.2.1