diff --git a/src/include/usr/isteps/tod_init_reasoncodes.H b/src/include/usr/isteps/tod_init_reasoncodes.H index abe3a9e0c29..9dc996a5195 100644 --- a/src/include/usr/isteps/tod_init_reasoncodes.H +++ b/src/include/usr/isteps/tod_init_reasoncodes.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -51,6 +51,18 @@ namespace TOD TOD_WIRE_PROCS = 0x10, TOD_WIRE_DRAWERS = 0x11, TOD_INIT_HWP = 0x12, + TOD_INIT_ALREADY_RUNNING = 0x13, + TOD_RESET_BACKUP = 0x14, + TOD_MDMT_TOPOLOGY = 0x15, + TOD_BUILD_BLACKLIST = 0x16, + TOD_ENDPOINT_CALLOUT = 0x17, + TOD_STEP_CHECK_RESET_HWP = 0x18, + TOD_FUNCTIONAL_TARGET = 0x19, + TOD_UTIL_HNDL_ECMD_BUF_RC = 0x1A, + TOD_CONTROLS_GET_TARGET = 0x1B, + TOD_UTIL_MOD_GET_PARENT = 0x1C, + TOD_MOD_LOG_UNSUPPORTED_BUSTYPE = 0x1D, + TOD_IS_MPIPL = 0x1E, }; enum TODReasonCode @@ -70,6 +82,23 @@ namespace TOD TOD_CREATION_ERR = TOD_COMP_ID | 0x0D, TOD_CREATION_ERR_NO_DRAWER = TOD_COMP_ID | 0x0E, TOD_CANNOT_WIRE_DRAWER = TOD_COMP_ID | 0x0F, + TOD_INVALID_PARAM = TOD_COMP_ID | 0x11, + TOD_MASTER_TARGET_NOT_FOUND = TOD_COMP_ID | 0x12, + TOD_NO_VALID_MDMT_FOUND = TOD_COMP_ID | 0x13, + TOD_NO_MDMT_ON_ACTIVE_CONFIG = TOD_COMP_ID | 0x14, + TOD_MASTER_PATH_ERROR = TOD_COMP_ID | 0x15, + TOD_HWP_EXECUTION_FAILED = TOD_COMP_ID | 0x16, + TOD_PARENT_NOT_FOUND = TOD_COMP_ID | 0x17, + TOD_DRAWER_SET_MDMT = TOD_COMP_ID | 0x18, + TOD_TOP_LEVEL_TARGET_NOT_FOUND = TOD_COMP_ID | 0x19, + }; + + enum TODUserDetailDataSubSection + { + EMOD_TOD_SET_ACTIVE_MDMT = 0x01, + EMOD_TOD_INIT_HWP = 0x02, + EMOD_TOD_INIT = 0x03, + EMOD_CALLOUT_TOD_ENDPOINT = 0x04, }; }; diff --git a/src/usr/isteps/istep18/TodAssert.H b/src/usr/isteps/istep18/TodAssert.H index a3609f5a10d..36f0ce74438 100644 --- a/src/usr/isteps/istep18/TodAssert.H +++ b/src/usr/isteps/istep18/TodAssert.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -52,9 +52,8 @@ namespace TOD * @param[in] expr,... * Printf-like expression to act as the assert message */ -#define TOD_ASSERT(expr,...) \ +#define TOD_ERR_ASSERT(expr,...) \ assert(expr,__VA_ARGS__) - } #endif diff --git a/src/usr/isteps/istep18/TodControls.C b/src/usr/isteps/istep18/TodControls.C index 8c3c678aae9..c22f6498460 100755 --- a/src/usr/isteps/istep18/TodControls.C +++ b/src/usr/isteps/istep18/TodControls.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -23,31 +23,34 @@ /* */ /* IBM_PROLOG_END_TAG */ -/** - * @file TodControls.C - * - * @brief This file implements the methods declared in TodControls class - * - * HWP_IGNORE_VERSION_CHECK - * - */ +//------------------------------------------------------------------------------ +//Includes +//------------------------------------------------------------------------------ +//Standard library +#include -#include #include + +//Targeting support #include -#include -#include -#include -#include "TodAssert.H" -#include "TodTrace.H" -#include "TodDrawer.H" +#include #include "TodProc.H" -#include "TodTypes.H" -#include "TodControls.H" +#include "TodDrawer.H" #include "TodSvcUtil.H" -#include "proc_tod_setup/proc_tod_setup.H" -#include -#include +#include "TodControls.H" +#include "TodTypes.H" +#include "TodTrace.H" +#include "TodUtils.H" +#include +#include + +//HWPF +#include +#include +#include +#include +#include +#include using namespace TARGETING; @@ -57,10 +60,6 @@ namespace TOD //------------------------------------------------------------------------------ //Static globals //------------------------------------------------------------------------------ -//const static char DIR_PATH_SERERATOR = '/'; -//const static mode_t DIR_CREATION_MODE = 0777; -//const static char * FILE_WRITE_MODE = "w+"; -//const static char * FILE_READ_MODE = "r"; TodControls & TodControls::getTheInstance() { @@ -70,7 +69,7 @@ TodControls & TodControls::getTheInstance() //****************************************************************************** //TodControls::TodControls //****************************************************************************** -TodControls::TodControls() +TodControls::TodControls () { TOD_ENTER("TodControls constructor"); TOD_EXIT("TodControls constructor"); @@ -79,7 +78,7 @@ TodControls::TodControls() //****************************************************************************** //TodControls::~TodControls //****************************************************************************** -TodControls::~TodControls() +TodControls ::~TodControls () { TOD_ENTER("TodControls destructor"); @@ -90,284 +89,175 @@ TodControls::~TodControls() } //****************************************************************************** -//TodControls::pickMDMT +//TodControls::pickMdmt //****************************************************************************** -errlHndl_t TodControls::pickMdmt(const proc_tod_setup_tod_sel i_config) +errlHndl_t TodControls ::pickMdmt(const p9_tod_setup_tod_sel i_config) { - TOD_ENTER("pickMdmt"); - errlHndl_t l_errHdl=NULL; + + TOD_ENTER("Input config is 0x%.2X", i_config); + + errlHndl_t l_errHdl = NULL; //MDMT is the master processor that drives TOD signals to all the remaining - //processors on the system, as such wherever possible algoritm will try to + //processors on the system, as such wherever possible algorithm will try to //ensure that primary and secondary topology provides redundancy of MDMT. - //Whenever there is an existing MDMT for the opposite configuration following - //considerations will go in deciding the MDMT for configuration passed - //through i_config - //1. MDMT will be chosen from a node other that the node on which other MDMDT - // belongs in multinode system - //2. In single node system MDMT will be chosen from a different fabric node - // (tod drawer ) - //3. Last a processor different from MDMT on the same fabric node will be - // chosen, if other options are not feasible - - do - { - proc_tod_setup_tod_sel l_oppConfig = (i_config == TOD_PRIMARY ) ? - TOD_SECONDARY : TOD_PRIMARY; + do{ - TodProc * l_pTodProc = NULL; - TodProc * l_oppMdmt = iv_todConfig[l_oppConfig].iv_mdmt; - TodDrawerContainer l_todDrawerList; - l_todDrawerList = iv_todConfig[i_config].iv_todDrawerList; - TodProc * l_lastProcWithMaxCores = NULL; - TodDrawer * l_lastMasterTodDrawer = NULL; - uint32_t l_lastMaxCoreCount = 0; - uint32_t l_coreCount=0; - uint32_t l_maxPossibleCoresPerProc = getMaxPossibleCoresPerProc(); + p9_tod_setup_tod_sel l_oppConfig = + (i_config == TOD_PRIMARY) ? TOD_SECONDARY : TOD_PRIMARY; + TodProc* l_otherConfigMdmt = iv_todConfig[l_oppConfig].iv_mdmt; + TodDrawerContainer l_todDrawerList = + iv_todConfig[i_config].iv_todDrawerList; + TodProcContainer l_procList; - if ( l_oppMdmt ) + if(l_otherConfigMdmt) { - //1.Try to find MDMT on a TOD drawer that is not on the same - // physical node as opposite MDMT - - //Iterate the list of TOD drawers - for (TodDrawerContainer::iterator l_todDrawerIter = - l_todDrawerList.begin(); - l_todDrawerIter != l_todDrawerList.end() ; - ++l_todDrawerIter) + TOD_INF("MDMT(0x%.8X) is configured for the " + "opposite config(0x%.2X)", + GETHUID(l_otherConfigMdmt->getTarget()), + l_oppConfig); + if(NULL == pickMdmt(l_otherConfigMdmt, i_config)) { - //TodProc --> TodDrawer --> Node - if ( l_oppMdmt->getParentDrawer()->getParentNodeTarget()-> - getAttr() - != - (*l_todDrawerIter)->getParentNodeTarget()-> - getAttr()) + TOD_INF("For config 0x%.2X, the only option for the MDMT " + "is the MDMT(0x%.8X) chosen for " + "the opposite config 0x%.2X", + i_config, + GETHUID(l_otherConfigMdmt->getTarget()), + l_oppConfig); + + //Get the TodProc pointer to l_otherConfigMdmt from this + //config's data structures. + for (const auto & l_drwItr: l_todDrawerList) { - l_pTodProc = NULL; - l_coreCount = 0; - (*l_todDrawerIter)-> - getProcWithMaxCores(NULL,l_pTodProc,l_coreCount); - if ( l_pTodProc ) + //This call will filter out GARDed/blacklisted chips + l_drwItr-> + getPotentialMdmts(l_procList); + //Now we check if l_otherConfigMdmt is still good. + for (const auto & l_procItr: l_procList) { - TOD_INF("returned core count = %d ",l_coreCount); - if ( l_coreCount > l_lastMaxCoreCount) + if(l_procItr->getTarget() == + (iv_todConfig[l_oppConfig].iv_mdmt)->getTarget()) { - l_lastProcWithMaxCores = l_pTodProc; - l_lastMaxCoreCount = l_coreCount; - l_lastMasterTodDrawer = (*l_todDrawerIter); - if (l_lastMaxCoreCount == l_maxPossibleCoresPerProc) + //Found l_otherConfigMdmt pointer + l_errHdl = setMdmt(i_config, + l_procItr, + l_drwItr); + if(l_errHdl) { - break; - } - } - } - - } - } - - if ( l_lastProcWithMaxCores ) - { - l_lastMasterTodDrawer->setMasterDrawer(true); - iv_todConfig[i_config].iv_mdmt = l_lastProcWithMaxCores; - l_lastProcWithMaxCores->setMasterType(TodProc::TOD_MASTER); - break; - } - - //2.Try to find MDMT on a TOD drawer that is on the same physical - // node as the possible opposite MDMT but on different TOD drawer - for (TodDrawerContainer::iterator l_todDrawerIter = - l_todDrawerList.begin(); - l_todDrawerIter != l_todDrawerList.end() ; - ++l_todDrawerIter) - { - if ( (l_oppMdmt->getParentDrawer()->getParentNodeTarget()-> - getAttr() - == - (*l_todDrawerIter)->getParentNodeTarget()-> - getAttr()) - //Same node as opposite MDMT - && - (l_oppMdmt->getParentDrawer()->getId() - != - (*l_todDrawerIter)->getId()))//Different Drawer - { - l_pTodProc = NULL; - l_coreCount = 0; - (*l_todDrawerIter)-> - getProcWithMaxCores(NULL,l_pTodProc,l_coreCount); - if ( l_pTodProc ) - { - if ( l_coreCount > l_lastMaxCoreCount) - { - l_lastProcWithMaxCores = l_pTodProc; - l_lastMaxCoreCount = l_coreCount; - l_lastMasterTodDrawer = (*l_todDrawerIter); - if (l_lastMaxCoreCount == l_maxPossibleCoresPerProc) - { - break; + TOD_ERR("Error setting proc 0x%.8X on " + "TOD drawer 0x%.2X as MDMT " + "for config 0x%.2X", + GETHUID(l_procItr->getTarget()), + l_drwItr->getId(), + i_config); } + break; } - } - - } - } - - if ( l_lastProcWithMaxCores ) - { - l_lastMasterTodDrawer->setMasterDrawer(true); - iv_todConfig[i_config].iv_mdmt = l_lastProcWithMaxCores; - l_lastProcWithMaxCores->setMasterType(TodProc::TOD_MASTER); - break; - } - - //3.Try to find MDMT on the same TOD drawer as the TOD Drawer of - // opposite MDMT - for (TodDrawerContainer::iterator l_todDrawerIter = - l_todDrawerList.begin(); - l_todDrawerIter != l_todDrawerList.end() ; - ++l_todDrawerIter) - { - l_coreCount = 0; - if ( l_oppMdmt->getParentDrawer()->getId() == - (*l_todDrawerIter)->getId() ) - { - //This is the TOD drawer on which opposite MDMT exists, - //try to avoid processor chip of opposite MDMT while - //getting the proc with max cores - (*l_todDrawerIter)->getProcWithMaxCores( - iv_todConfig[l_oppConfig].iv_mdmt,l_pTodProc - ,l_coreCount); - if ( l_pTodProc ) + if(iv_todConfig[i_config].iv_mdmt) { - iv_todConfig[i_config].iv_mdmt = l_pTodProc; - (*l_todDrawerIter)->setMasterDrawer(true); - l_pTodProc->setMasterType(TodProc::TOD_MASTER); break; } } } + } + else + { + TOD_INF("No MDMT configured for other config(0x%.2X) yet", + l_oppConfig); - if ( iv_todConfig[i_config].iv_mdmt ) - { - break; - } + uint32_t l_coreCount = 0; + uint32_t l_maxCoreCount = 0; + TodProc* l_newMdmt = NULL; + TodProc* l_pTodProc = NULL; + TodDrawer* l_pTodDrw = NULL; - //If we reach here only option left is MDMT on the other config so - //select it. So we look for a proc in this config's set of TOD - //drawers, find the one which is same as the MDMT on the other - //config (based on the HUID). - bool l_mdmtFound = false; - for(TodDrawerContainer::iterator l_drwItr = - iv_todConfig[i_config].iv_todDrawerList.begin(); - l_drwItr != iv_todConfig[i_config].iv_todDrawerList.end(); - ++l_drwItr) - { - const TodProcContainer& l_procs = (*l_drwItr)->getProcs(); - for(TodProcContainer::const_iterator - l_procItr = l_procs.begin(); - l_procItr != l_procs.end(); - ++l_procItr) - { - if( (*l_procItr)->getTarget()->getAttr() - == - (iv_todConfig[l_oppConfig].iv_mdmt)-> - getTarget()->getAttr() ) - { - iv_todConfig[i_config].iv_mdmt = (*l_procItr); - (*l_procItr)->setMasterType(TodProc::TOD_MASTER); - (*l_drwItr)->setMasterDrawer(true); - l_mdmtFound = true; - break; - } - } + //No MDMT configured yet. Our criteria to pick one is to + //look at TOD drawers and pick the one with max no of cores - if(l_mdmtFound) - { - break; - } - } - - if(l_mdmtFound) - { - break; - } - } - else - { //There is no MDMT configured for the other topology hence select - //the MDMT from any TOD drawer - for (TodDrawerContainer::iterator l_todDrawerIter = - l_todDrawerList.begin(); - l_todDrawerIter != l_todDrawerList.end() ; - ++l_todDrawerIter) + for (const auto & l_drwItr: l_todDrawerList) { l_pTodProc = NULL; l_coreCount = 0; - (*l_todDrawerIter)->getProcWithMaxCores( - NULL,l_pTodProc,l_coreCount); - if ( l_pTodProc ) + //Get the list of procs on this TOD drawer that have oscillator + //input. Each of them is a potential MDMT, choose the one with + //max no. of cores + l_drwItr-> + getPotentialMdmts(l_procList); + l_drwItr-> + getProcWithMaxCores(NULL, + l_pTodProc, + l_coreCount, + &l_procList); + if(l_coreCount > l_maxCoreCount) { - if ( l_coreCount > l_lastMaxCoreCount) - { - l_lastProcWithMaxCores = l_pTodProc; - l_lastMaxCoreCount = l_coreCount; - l_lastMasterTodDrawer = (*l_todDrawerIter); - if (l_lastMaxCoreCount == l_maxPossibleCoresPerProc) - { - break; - } - } + l_maxCoreCount = l_coreCount; + l_pTodDrw = l_drwItr; + l_newMdmt = l_pTodProc; } } - if ( l_lastProcWithMaxCores ) + if(l_newMdmt) { - l_lastMasterTodDrawer->setMasterDrawer(true); - iv_todConfig[i_config].iv_mdmt = l_lastProcWithMaxCores; - l_lastProcWithMaxCores->setMasterType(TodProc::TOD_MASTER); - break; + // If new MDMT, we set the todConfig + l_errHdl = setMdmt(i_config, + l_newMdmt, + l_pTodDrw); + if(l_errHdl) + { + TOD_ERR("Error setting proc 0x%.8X on " + "TOD drawer 0x%.2X as MDMT " + "for config 0x%.2X", + l_newMdmt->getTarget()-> + getAttr(), + l_pTodDrw->getId(), + i_config); + } } } - - if ( !iv_todConfig[i_config].iv_mdmt ) - { - TOD_ERR("MDMT NOT FOUND for configuration 0x%02X",i_config); - - /*@ - * @errortype - * @reasoncode TOD_NO_MASTER_PROC - * @moduleid TOD_PICK_MDMT - * @userdata1 TOD configuration type - * @devdesc MDMT could not be found for the supplied topology - * type - */ - l_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_INFORMATIONAL, - TOD_PICK_MDMT, - TOD_NO_MASTER_PROC, - i_config); - } - }while(0); - if ( iv_todConfig[i_config].iv_mdmt ) + if(!iv_todConfig[i_config].iv_mdmt) { - TOD_INF("MDMT for configuration %d , is proc " - "0%08X", i_config, iv_todConfig[i_config].iv_mdmt-> - getTarget()->getAttr()); + TOD_ERR("MDMT couldn't be chosen for configuration 0x%.2X", + i_config); + + /*@ + * @errortype + * @moduleid TOD_PICK_MDMT + * @reasoncode TOD_MASTER_TARGET_NOT_FOUND + * @userdata1 TOD topology type + * @devdesc MDMT could not be chosen for the supplied + * topology type + * @custdesc Host Processor Firmware couldn't detect any + * functional master processor required to boot the host + */ + l_errHdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_PICK_MDMT, + TOD_MASTER_TARGET_NOT_FOUND, + i_config); } - TOD_EXIT("pickMdmt. errHdl = %p", l_errHdl); - return l_errHdl; + else + { + TOD_INF("MDMT for configuration 0x%.2X, is proc 0x%.8X", + i_config, + iv_todConfig[i_config].iv_mdmt-> + getTarget()->getAttr()); + } + + TOD_EXIT(); + return l_errHdl; } //****************************************************************************** //TodControls::buildTodDrawers //****************************************************************************** errlHndl_t TodControls::buildTodDrawers( - const proc_tod_setup_tod_sel i_config) + const p9_tod_setup_tod_sel i_config) { TOD_ENTER("buildTodDrawers"); errlHndl_t l_errHdl = NULL; @@ -380,31 +270,36 @@ errlHndl_t TodControls::buildTodDrawers( TARGETING::Target* l_pSysTarget = NULL; (void)TARGETING::targetService().getTopLevelTarget(l_pSysTarget); - //We should not be reaching here without a valid system target - TOD_ASSERT(l_pSysTarget,"NULL system target "); + if (NULL == l_pSysTarget) + { + //We should not be reaching here without a valid system target + TOD_ERR_ASSERT("buildTodDrawers: NULL system target "); + break; + } //Build the list of functional nodes - l_errHdl = getFuncNodeTargetsOnSystem( l_pSysTarget, - l_funcNodeTargetList); + l_errHdl = TOD::TodSvcUtil::getFuncNodeTargetsOnSystem( l_pSysTarget, + l_funcNodeTargetList, true); if ( l_errHdl ) { TOD_ERR("For System target 0x%08X getFuncNodeTargetsOnSystem " - "returned error ",l_pSysTarget->getAttr()); + "returned error ",l_pSysTarget-> + getAttr()); break; } - //If there was no functional node found then we must return + //If there was no functional node found then we must return if ( l_funcNodeTargetList.empty() ) { TOD_ERR("For System target 0x%08X no functional node found ", l_pSysTarget->getAttr()); - /*@ - * @errortype - * @reasoncode TOD_NO_FUNC_NODE_AVAILABLE - * @moduleid TOD_BUILD_TOD_DRAWERS - * @userdata1 system target's HUID - * @devdesc MDMT could not find a functional node - */ + /*@ + * @errortype + * @moduleid TOD_BUILD_TOD_DRAWERS + * @reasoncode TOD_NO_FUNC_NODE_AVAILABLE + * @userdata1 system target's HUID + * @devdesc MDMT could not find a functional node + */ l_errHdl = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_INFORMATIONAL, TOD_BUILD_TOD_DRAWERS, @@ -442,25 +337,25 @@ errlHndl_t TodControls::buildTodDrawers( TARGETING::TargetService::ALL, &l_funcProcPostfixExpr); - //Go over the list of procs and insert them in respective fabric - //node list ( TOD drawer ) + //Go over the list of procs and insert them in respective TOD drawer for ( uint32_t l_procIndex =0 ; l_procIndex < l_funcProcTargetList.size(); ++l_procIndex ) { b_foundDrawer = false; - //Traverse over the fabric node list (TOD drawer) and find if - //there is an existing fabric node for this proc + //Get the ordinal id of the parent node and find if there is an + //existing TOD drawer whose id matches with the ordinal id of + //this node for ( l_todDrawerIter = l_todDrawerList.begin() ; l_todDrawerIter != l_todDrawerList.end() ; ++l_todDrawerIter) { if ( (*l_todDrawerIter)->getId() == - l_funcProcTargetList[l_procIndex]-> - getAttr()) + l_funcNodeTargetList[l_nodeIndex]-> + getAttr()) { - //Add the proc to this fabric node, such that + //Add the proc to this TOD drawer, such that //TodProc has the target pointer and the pointer to //the TOD drawer to which it belongs TodProc *l_procPtr = @@ -480,11 +375,12 @@ errlHndl_t TodControls::buildTodDrawers( if (!b_foundDrawer ) { //Create a new TOD drawer and add it to the TOD drawer list - //Create a TOD drawer with the fabric node id and the - //pointer to the node to which this fabric node belongs + //Create a TOD drawer with the drawer id same as parent + //node's id , and the pointer to the node target to which + //the TOD drawer belongs TodDrawer *l_pTodDrawer = new - TodDrawer(l_funcProcTargetList[l_procIndex]-> - getAttr(), + TodDrawer(l_funcNodeTargetList[l_nodeIndex]-> + getAttr(), l_funcNodeTargetList[l_nodeIndex]); //Create a TodProc passing the target pointer and the @@ -499,7 +395,7 @@ errlHndl_t TodControls::buildTodDrawers( //push the Tod drawer ( TodDrawer ) , into the //TodControls l_todDrawerList.push_back(l_pTodDrawer); - //Nullify the pointers after transfering the ownership + //Delete the pointers after transfering the ownership l_pTodDrawer = NULL; l_pTodProc = NULL; @@ -509,22 +405,23 @@ errlHndl_t TodControls::buildTodDrawers( } // end node list loop - //Validate that we had atlease one TOD drawer at the end of this process + //Validate that we had at least one TOD drawer at the end of this process //else generate an error if (iv_todConfig[i_config].iv_todDrawerList.empty()) { TOD_ERR("No TOD drawer could be built for the configuration " - " %s ", (i_config == TOD_PRIMARY ? "Primary " : - "Secondary") ); + " %s ", (i_config == TOD_PRIMARY) ? "Primary": "Secondary"); /*@ * @errortype - * @reasoncode TOD_NO_DRAWERS * @moduleid TOD_BUILD_TOD_DRAWERS + * @reasoncode TOD_NO_DRAWERS * @userdata1 TOD configuration * @devdesc No TOD drawer could be configured for this topology * type + * @custdesc Host failed to boot because there was a problem + * configuring Time Of Day on the Host processors */ - l_errHdl = new ERRORLOG::ErrlEntry( + l_errHdl = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, TOD_BUILD_TOD_DRAWERS, TOD_NO_DRAWERS, @@ -532,14 +429,14 @@ errlHndl_t TodControls::buildTodDrawers( } }while(0); - TOD_EXIT("buildTodDrawers. errHdl = %p", l_errHdl); + TOD_EXIT("buildTodDrawers"); return l_errHdl; } //****************************************************************************** //TodControls::isTodRunning //****************************************************************************** -errlHndl_t TodControls::isTodRunning(bool& o_isTodRunning)const +errlHndl_t TodControls ::isTodRunning(bool& o_isTodRunning)const { TOD_ENTER("isTodRunning"); errlHndl_t l_errHdl = NULL; @@ -547,8 +444,7 @@ errlHndl_t TodControls::isTodRunning(bool& o_isTodRunning)const TARGETING::Target* l_secondaryMdmt=NULL; o_isTodRunning = false; - do - { + do{ //Read the TOD HW to get the configured MDMT l_errHdl = getConfiguredMdmt(l_primaryMdmt,l_secondaryMdmt); if ( l_errHdl ) @@ -557,87 +453,154 @@ errlHndl_t TodControls::isTodRunning(bool& o_isTodRunning)const break; } - if ( l_primaryMdmt || l_secondaryMdmt ) //If there is atleast one MDMT - //configured , check the chipTOD HW status by reading the TOD - //status register TOD_PSS_MSS_STATUS_REG_00040008 - { - ecmdDataBufferBase l_primaryMdmtBuf(64); - ecmdDataBufferBase l_secondaryMdmtBuf(64); + //PHYP starts TOD logic. TOD logic can be started using either primary + //or secondary TOD configuration, if both configuration exist primary + //topology is considered for starting TOD logic. After the TOD logic is + //started successfully, TOD FSM ( finite state machine ) register will + //report the TOD status as running. - if ( l_primaryMdmt ) - { - l_errHdl = todGetScom(l_primaryMdmt, - TOD_PSS_MSS_STATUS_REG_00040008, - l_primaryMdmtBuf); - if ( l_errHdl ) - { - TOD_ERR("Scom failed for status register " - "TOD_PSS_MSS_STATUS_REG_00040008 on primary MDMT"); - break; - } - } + //If there is atleast one MDMT + //configured , check the chipTOD HW status by reading the TOD + //register PERV_TOD_FSM_REG - if ( l_secondaryMdmt ) + fapi2::variable_buffer l_primaryMdmtBuf(64); + l_primaryMdmtBuf.flush<0>(); + fapi2::variable_buffer l_secondaryMdmtBuf(64); + l_secondaryMdmtBuf.flush<0>(); + + if ( l_primaryMdmt ) + { + l_errHdl = todGetScom(l_primaryMdmt, + PERV_TOD_FSM_REG, + l_primaryMdmtBuf); + if ( l_errHdl ) { - l_errHdl = todGetScom(l_secondaryMdmt, - TOD_PSS_MSS_STATUS_REG_00040008, - l_secondaryMdmtBuf); - if ( l_errHdl ) - { - TOD_ERR("Scom failed for status register " - "TOD_PSS_MSS_STATUS_REG_00040008 on secondary MDMT"); - break; - } + TOD_ERR("Scom failed for TOD FSM register " + "PERV_TOD_FSM_REG on primary MDMT"); + break; } - //If all the bits of TOD_PSS_MSS_STATUS_REG_00040008 are off then - //ChipTOD HW is not running - if ((l_primaryMdmtBuf.getWord(0) == 0 ) && - (l_secondaryMdmtBuf.getWord(0)== 0)) + } + + if ( l_secondaryMdmt ) + { + l_errHdl = todGetScom(l_secondaryMdmt, + PERV_TOD_FSM_REG, + l_secondaryMdmtBuf); + if ( l_errHdl ) { + TOD_ERR("Scom failed for TOD FSM register " + "PERV_TOD_FSM_REG on secondary MDMT"); break; } + } + //If the bit 4 of the TOD_FSM_REG related to primary or + //secondary topology is set then the chip TOD logic is considered to + //be in the running state. + if(l_primaryMdmtBuf.isBitSet(TOD_FSM_REG_TOD_IS_RUNNING)) + { o_isTodRunning = true; + TOD_INF("TOD logic is in the running state considering primary" + "topology as active topology"); + } + else if( l_secondaryMdmtBuf.isBitSet(TOD_FSM_REG_TOD_IS_RUNNING) ) + { + o_isTodRunning = true; + TOD_INF("TOD logic is in the running state considering" + "secondary topology as active topology"); } - }while(0); - TOD_EXIT("TOD HW State = %d errHdl = %p",o_isTodRunning, l_errHdl); + TOD_EXIT("TOD HW State = %d",o_isTodRunning); return l_errHdl; } //****************************************************************************** //TodControls::queryActiveConfig //****************************************************************************** -errlHndl_t TodControls::queryActiveConfig( - proc_tod_setup_tod_sel& o_activeConfig, - bool& o_isTodRunning)const +errlHndl_t TodControls ::queryActiveConfig( + p9_tod_setup_tod_sel& o_activeConfig, + bool& o_isTodRunning, + TARGETING::Target*& o_mdmtOnActiveTopology, + bool i_determineTodRunningState)const { - TOD_ENTER("queryActiveConfig"); + TOD_ENTER(); errlHndl_t l_errHdl = NULL; TARGETING::Target* l_primaryMdmt=NULL; TARGETING::Target* l_secondaryMdmt=NULL; - o_isTodRunning = false; - o_activeConfig = TOD_PRIMARY; do { - //Read the configured Mdmt from TOD HW + + if ( i_determineTodRunningState ) + { + l_errHdl = isTodRunning(o_isTodRunning); + if ( l_errHdl ) + { + TOD_INF("Call to isTodRunning() failed,cannot query active " + "config state"); + break; + } + } + + //Read the TOD HW to get the configured MDMT l_errHdl = getConfiguredMdmt(l_primaryMdmt,l_secondaryMdmt); if ( l_errHdl ) { - TOD_ERR("Failed to get configured MDMTs" ); + TOD_ERR("Failed getting configured MDMTs" ); + break; + } + + //Check for case where no MDMT could be found.. this can happen only + //when the method is called before topology was configured + if ( ! ( l_primaryMdmt || l_secondaryMdmt )) + { + TOD_ERR(" Neither primary not Secondary MDMT is configured "); + //Return an error + /*@ + * @errortype + * @moduleid TOD_QUERY_ACTIVE_CONFIG + * @reasoncode TOD_NO_VALID_MDMT_FOUND + * @devdesc No valid MDMT found on either topology + * @custdesc Host failed to boot because there was a problem + * configuring Time Of Day on the Host processors + */ + l_errHdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_QUERY_ACTIVE_CONFIG, + TOD_NO_VALID_MDMT_FOUND); break; + } - if ( l_primaryMdmt || l_secondaryMdmt ) //If there is atleast one MDMT - //configured,` check the ChipTOD HW status by reading the TOD - //status register TOD_PSS_MSS_STATUS_REG_00040008 + //Initialize the output variables, in case TOD is not running then + //these values will be returned. + o_activeConfig = TOD_PRIMARY; + + if ( l_primaryMdmt ) + { + o_mdmtOnActiveTopology = l_primaryMdmt; + } + else { - ecmdDataBufferBase l_primaryMdmtBuf(64); - ecmdDataBufferBase l_secondaryMdmtBuf(64); + o_mdmtOnActiveTopology = l_secondaryMdmt; + } + + //If TOD is running then query the configured MDMT to get the active + //configuration data else return Primary as default active + //configuration. + if (o_isTodRunning) + { + o_mdmtOnActiveTopology = NULL; + //Make it NULL again, since TOD is running we cannot return + //l_primaryMdmt as the MDMT on the active topology + + fapi2::variable_buffer l_primaryMdmtBuf(64); + l_primaryMdmtBuf.flush<0>(); + fapi2::variable_buffer l_secondaryMdmtBuf(64); + l_secondaryMdmtBuf.flush<0>(); if ( l_primaryMdmt ) { @@ -647,112 +610,126 @@ errlHndl_t TodControls::queryActiveConfig( if ( l_errHdl ) { TOD_ERR("Scom failed for status register " - "TOD_PSS_MSS_STATUS_REG_00040008 on primary MDMT"); + "TOD_PSS_MSS_STATUS_REG_00040008 on primary " + " MDMT"); break; } - } - if ( l_secondaryMdmt ) + //Check First 3 bits of TOD_PSS_MSS_STATUS_REG_00040008 + //indicates active TOD topology + //[0:2] == '111' secondary, '000' is primary + //just check bit 0 + if( l_primaryMdmtBuf.isBitSet + (TOD_PSS_MSS_STATUS_REG_00040008_ACTIVE_BIT)) + { + TOD_INF("Primary MDMT 0x%08X is indicating active " + " configuration as TOD_PRIMARY ", + GETHUID(l_secondaryMdmt)); + o_activeConfig = TOD_SECONDARY; + o_mdmtOnActiveTopology = l_secondaryMdmt; + } + else + { + o_mdmtOnActiveTopology = l_primaryMdmt; + } + //else Primary Topology is considered active + } + //If Primary Mdmt is not present then querying the secondaryMdmt. + else if ( l_secondaryMdmt ) { l_errHdl = todGetScom(l_secondaryMdmt, - TOD_PSS_MSS_STATUS_REG_00040008, + PERV_TOD_PSS_MSS_STATUS_REG, l_secondaryMdmtBuf); if ( l_errHdl ) { TOD_ERR("Scom failed for status register " - "TOD_PSS_MSS_STATUS_REG_00040008 secondary MDMT "); + "TOD_PSS_MSS_STATUS_REG_00040008 on secondary " + " MDMT"); break; } + + //Check First 3 bits of TOD_PSS_MSS_STATUS_REG_00040008 + //indicates active TOD topology + // [0:2] == '111' secondary, '000' is primary - + //just check bit 0 + if ( l_secondaryMdmtBuf.isBitSet + (TOD_PSS_MSS_STATUS_REG_00040008_ACTIVE_BIT)) + { + TOD_INF("Secondary MDMT 0x%08X is indicating active " + " configuration as TOD_SECONDARY ", + GETHUID(l_secondaryMdmt)); + o_activeConfig = TOD_SECONDARY; + o_mdmtOnActiveTopology = l_secondaryMdmt; + } + else + { + o_mdmtOnActiveTopology = l_primaryMdmt; + } } - //If all the bits of TOD_PSS_MSS_STATUS_REG_00040008 are off then - //ChipTOD HW is not running - if ((l_primaryMdmtBuf.getWord(0) == 0 ) && - (l_secondaryMdmtBuf.getWord(0)== 0)) + //It is highly unlikely that PRIMARY topology says SECONDARY is + //active however we don't have MDMT on the secondary topology. + if ( !o_mdmtOnActiveTopology ) { + TOD_ERR("Active topology found but could not get the MDMT " + " on active TOPOLOGY "); + + /*@ + * @errortype + * @moduleid TOD_QUERY_ACTIVE_CONFIG + * @reasoncode TOD_NO_MDMT_ON_ACTIVE_CONFIG + * @userdata1 Active configuration + * @devdesc MDMT not found on active toplology + * @custdesc Service Processor Firmware encountered an + * internal error + */ + l_errHdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_QUERY_ACTIVE_CONFIG, + TOD_NO_MDMT_ON_ACTIVE_CONFIG, + o_activeConfig); break; } + }//isTodRunning check - o_isTodRunning = true; + }while(0); - //First 3 bits of TOD_PSS_MSS_STATUS_REG_00040008 indicates - //active TOD topology - // [0:2] == '111' secondary, '000' is primary - just check bit 0 - - //Putting the below check because of past TOD HW error. - //Both primary and secondary MDMT would claim that it is the active - //one,this happened during CHARM operation after failover from - //primary to econdary - //May be that error does not exists in P8 HW but in case it still - //exists we will be able to catch it - if ( l_primaryMdmt && l_secondaryMdmt ) + //If TOD logic is running and no failure is hit in the code above. + if( l_errHdl == NULL ) + { + if (o_isTodRunning) + { + if ( o_activeConfig == TOD_PRIMARY ) { - if ( - l_primaryMdmtBuf.isBitSet - (TOD_PSS_MSS_STATUS_REG_00040008_ACTIVE_BIT) - != - l_secondaryMdmtBuf.isBitSet - (TOD_PSS_MSS_STATUS_REG_00040008_ACTIVE_BIT) - ) - { - TOD_ERR("TOD HW error, primary and secondary MDMT do not" - "agree on bits 0 of TOD status register 0x40008"); - /*@ - * @errortype - * @reasoncode TOD_HW_ERROR - * @moduleid TOD_QUERY_ACTIVE_CONFIG - * @userdata1 Status register bits of primary MDMT - * @userdata2 Status register bits of secondary MDMT - * @devdesc Error: primary and secondary MDMT do not - * agree on bits 0 of TOD status register - * 0x40008 - */ - l_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - TOD_QUERY_ACTIVE_CONFIG, - TOD_HW_ERROR, - l_primaryMdmtBuf.getWord(0), - l_secondaryMdmtBuf.getWord(0) ); - break; - } + TOD_INF("Primary topology is considered as active "); } - - if(l_primaryMdmtBuf.isBitSet - (TOD_PSS_MSS_STATUS_REG_00040008_ACTIVE_BIT)) + else if( o_activeConfig == TOD_SECONDARY) { - TOD_INF("Primary MDMT says secondary is configured "); - o_activeConfig = TOD_SECONDARY; - // If the primary says the secondary is active then what the - // secondary MDMT says is not important - no more checking - // required. - break; + TOD_INF("Secondary topology is considered as active"); } - - //The secondaryMDMT only needs to be checked if the primaryMDMT - //said it is active ( i.e. bit 0 is clear ) - - //If the secondary says the secondary is active then primary was - //not found - if ( l_secondaryMdmtBuf.isBitSet - (TOD_PSS_MSS_STATUS_REG_00040008_ACTIVE_BIT)) + } + else + { + if ( i_determineTodRunningState ) { - TOD_INF("Secondary MDMT says secondary is configured "); - o_activeConfig = TOD_SECONDARY; - break; + TOD_INF("TOD logic is not in the running state!!"); } } - //Else not yet initialized, just return primary - - }while(0); + } + else + { + TOD_ERR("Failed to get TOD running state and active configuration" + "details!!"); + } - TOD_EXIT("queryActiveConfig. errHdl = %p", l_errHdl); + TOD_EXIT(); return l_errHdl; } //****************************************************************************** //TodControls::getConfiguredMdmt //****************************************************************************** -errlHndl_t TodControls::getConfiguredMdmt( +errlHndl_t TodControls ::getConfiguredMdmt( TARGETING::Target*& o_primaryMdmt, TARGETING::Target*& o_secondaryMdmt) const { @@ -778,49 +755,66 @@ errlHndl_t TodControls::getConfiguredMdmt( push(&l_funcPred).And(); TARGETING::TargetHandleList l_procTargetList; - - ecmdDataBufferBase l_todCtrlReg(64); - - //TOD_PSS_MSS_CTRL_REG_00040007 + //fapi2 data buffer for TOD register + fapi2::variable_buffer l_todStatusReg(64); + + /* TOD_PSS_MSS_STATUS_REG_00040008 has the following interpretation + * Primary configuration + * TOD_STATUS[13] TOD_STATUS[14] Inference + * 1 1 Master TOD Master Drawer + * 0 1 Slave TOD Master Drawer + * 0 0 Slave TOD Slave Drawer + * 1 0 Master TOD Slave Drawer + * + * Secondary configuration + * TOD_STATUS[17] TOD_STATUS[18] Inference + * Same as for primary + */ TARGETING::TargetRangeFilter l_filter( TARGETING::targetService().begin(), TARGETING::targetService().end(), &l_stateAndProcChipFilter); - //Read the TOD control register TOD_PSS_MSS_CTRL_REG_00040007 for each - //processor and check for bits 1 and 9 + //Read the TOD status register TOD_PSS_MSS_STATUS_REG_00040008 for each + //processor and check the TOD and Drawer bits for ( ; l_filter; ++l_filter ) { l_errHdl = todGetScom(*l_filter, - TOD_PSS_MSS_CTRL_REG_00040007, - l_todCtrlReg); + PERV_TOD_PSS_MSS_STATUS_REG, + l_todStatusReg); if ( l_errHdl ) { TOD_ERR("Scom failed for target 0x%08X on register" - "TOD_PSS_MSS_CTRL_REG_00040007 ", - (*l_filter)->getAttr()); + " TOD_PSS_MSS_STATUS_REG_00040008 ", + (*l_filter)->getAttr()); break; } if ( - l_todCtrlReg.isBitSet - (TOD_PSS_MSS_CTRL_REG_00040007_PRIMARY_MDMT_BIT) )//primary MDMT + l_todStatusReg.isBitSet( + TOD_PSS_MSS_STATUS_REG_00040008_PRI_M_S_TOD_SEL) + && + l_todStatusReg.isBitSet( + TOD_PSS_MSS_STATUS_REG_00040008_PRI_M_S_DRAWER_SEL ) ) { o_primaryMdmt = *l_filter; TOD_INF("found primary MDMT HUID = 0x%08X", - o_primaryMdmt->getAttr()); + o_primaryMdmt->getAttr()); } if ( - l_todCtrlReg.isBitSet - (TOD_PSS_MSS_CTRL_REG_00040007_SECONDARY_MDMT_BIT) ) - //secondary MDMT + l_todStatusReg.isBitSet( + TOD_PSS_MSS_STATUS_REG_00040008_SEC_M_S_TOD_SEL ) + && + l_todStatusReg.isBitSet( + TOD_PSS_MSS_STATUS_REG_00040008_SEC_M_S_DRAWER_SEL ) ) { o_secondaryMdmt = *l_filter; TOD_INF("found secondary MDMT HUID = 0x%08X", - o_secondaryMdmt->getAttr()); + o_secondaryMdmt->getAttr()); + } if ( o_primaryMdmt && o_secondaryMdmt ) @@ -831,16 +825,16 @@ errlHndl_t TodControls::getConfiguredMdmt( }while(0); - TOD_EXIT("getConfiguredMdmt. errHdl = %p", l_errHdl); + TOD_EXIT(); return l_errHdl; } //****************************************************************************** //TodControls::destroy //****************************************************************************** -void TodControls::destroy(const proc_tod_setup_tod_sel i_config) +void TodControls ::destroy(const p9_tod_setup_tod_sel i_config) { - TOD_ENTER("destroy"); + TOD_ENTER("TodControls::destroy"); for(TodDrawerContainer::iterator l_itr = iv_todConfig[i_config].iv_todDrawerList.begin(); @@ -855,22 +849,25 @@ void TodControls::destroy(const proc_tod_setup_tod_sel i_config) iv_todConfig[i_config].iv_todDrawerList.clear(); iv_todConfig[i_config].iv_mdmt = NULL; iv_todConfig[i_config].iv_isConfigured = false; + iv_todChipDataVector.clear(); + iv_BlackListedProcs.clear(); + iv_gardedTargets.clear(); - TOD_EXIT("destroy"); + TOD_EXIT(); } //****************************************************************************** //TodControls::writeTodProcData //****************************************************************************** -errlHndl_t TodControls::writeTodProcData( - const proc_tod_setup_tod_sel i_config) +errlHndl_t TodControls :: writeTodProcData( + const p9_tod_setup_tod_sel i_config) { - TOD_ENTER("writeTodProcData"); + TOD_ENTER("TodControls::writeTodProcData"); errlHndl_t l_errHdl = NULL; - do - { - //As per the requirement specified by PHYP/HDAT, HB needs to fill + do{ + + //As per the requirement specified by PHYP/HDAT, TOD needs to fill //data for every chip that can be installed on the system. //It is also required that chip ID match the index of the entry in the //array so we can possibly have valid chip data at different indexes in @@ -879,19 +876,15 @@ errlHndl_t TodControls::writeTodProcData( //non-significant values TodChipData blank; - uint32_t l_maxProcCount = getMaxProcsOnSystem(); + uint32_t l_maxProcCount = TOD::TodSvcUtil::getMaxProcsOnSystem(); Target* l_target = NULL; - //the size of the attribute needs to accomodate the size of the struct - TOD_ASSERT(sizeof(TodChipData) == sizeof(ATTR_TOD_CPU_DATA_type), - "sizeof TodChipData and attribute are different"); - TOD_INF("Max possible processor chips for this system when configured " "completely is %d",l_maxProcCount); iv_todChipDataVector.assign(l_maxProcCount,blank); - TARGETING::ATTR_POSITION_type l_ordId = 0x0; + TARGETING::ATTR_ORDINAL_ID_type l_ordId = 0x0; //Ordinal Id of the processors that form the topology //Fill the TodChipData structures with the actual value in the @@ -910,7 +903,8 @@ errlHndl_t TodControls::writeTodProcData( ++l_procItr) { l_ordId = - (*l_procItr)->getTarget()->getAttr(); + (*l_procItr)->getTarget()-> + getAttr(); //Clear the default flag for this chip, defaults to //NON_FUNCTIONAL however this is a functional chip @@ -931,10 +925,10 @@ errlHndl_t TodControls::writeTodProcData( { if ( (getMDMT(TOD_PRIMARY)->getTarget()-> - getAttr()) + getAttr()) == ((*l_procItr)->getTarget()-> - getAttr()) + getAttr()) ) { @@ -953,10 +947,10 @@ errlHndl_t TodControls::writeTodProcData( { if ( (getMDMT(TOD_SECONDARY)->getTarget()-> - getAttr()) + getAttr()) == ((*l_procItr)->getTarget()-> - getAttr()) + getAttr()) ) { @@ -982,13 +976,14 @@ errlHndl_t TodControls::writeTodProcData( }//end of writeTodProcData + //****************************************************************************** -//HwsvTodControls::hasNoValidData() +//TodControls::hasNoValidData() //****************************************************************************** -bool TodControls::hasNoValidData(const std::vector& +bool TodControls ::hasNoValidData(const std::vector& i_todChipDataVector)const { - TOD_ENTER("hasNoValidData"); + TOD_ENTER("TodControls::hasNoValidData"); bool result = true; for(std::vector::const_iterator l_iter = i_todChipDataVector.begin(); @@ -1004,54 +999,824 @@ bool TodControls::hasNoValidData(const std::vector& return result; } +//****************************************************************************** +//TodControls::pickMdmt +//****************************************************************************** +TodProc* TodControls ::pickMdmt( + const TodProc* i_otherConfigMdmt, + const p9_tod_setup_tod_sel& i_config, + const bool i_setMdmt) +{ + TOD_ENTER("Other MDMT : 0x%.8X, " + "Input config : 0x%.2X", + GETHUID(i_otherConfigMdmt->getTarget()), + i_config); + + TodProc* l_newMdmt = NULL; + TodProc *l_pTodProc = NULL; + TodDrawer* l_pMasterDrw = NULL; + TodDrawerContainer l_todDrawerList = + iv_todConfig[i_config].iv_todDrawerList; + TodProcContainer l_procList; + uint32_t l_coreCount = 0; + uint32_t l_maxCoreCount = 0; + errlHndl_t l_errHdl = NULL; + + do + { + //1.MDMT will be chosen from a node other than the node on which + //this MDMT exists, in case of multinode systems + //Iterate the list of TOD drawers + l_maxCoreCount = 0; + for (TodDrawerContainer::iterator l_todDrawerIter = + l_todDrawerList.begin(); + l_todDrawerIter != l_todDrawerList.end(); + ++l_todDrawerIter) + { + + //TodProc --> TodDrawer --> Node + if(i_otherConfigMdmt->getParentDrawer()->getParentNodeTarget()-> + getAttr() + != + (*l_todDrawerIter)->getParentNodeTarget()-> + getAttr()) + { + l_pTodProc = NULL; + l_coreCount = 0; + l_procList.clear(); + //Get the list of procs on this TOD drawer that have oscillator + //input. Each of them is a potential MDMT, choose the one with + //max no. of cores + (*l_todDrawerIter)-> + getPotentialMdmts(l_procList); + (*l_todDrawerIter)-> + getProcWithMaxCores(NULL, + l_pTodProc, + l_coreCount, + &l_procList); + if(l_coreCount > l_maxCoreCount) + { + l_newMdmt = l_pTodProc; + l_maxCoreCount = l_coreCount; + l_pMasterDrw = *l_todDrawerIter; + } + } + } + if(l_newMdmt && i_setMdmt ) + { + l_errHdl = setMdmt(i_config, + l_newMdmt, + l_pMasterDrw); + if(l_errHdl) + { + TOD_ERR("Error setting proc 0x%.8X on " + "TOD drawer 0x%.2X as MDMT " + "for config 0x%.2X", + l_newMdmt->getTarget()-> + getAttr(), + l_pMasterDrw->getId(), + i_config); + errlCommit(l_errHdl, TOD_COMP_ID); + l_newMdmt = NULL; + } + else + { + TOD_INF("Found MDMT 0x%.8X on different node 0x%.8X", + l_newMdmt->getTarget()->getAttr(), + l_pMasterDrw->getParentNodeTarget()-> + getAttr()); + l_pMasterDrw = NULL; + break; + } + } + + //2.Try to find MDMT on a TOD drawer that is on the same physical + //node as the possible opposite MDMT but on different TOD drawer + l_maxCoreCount = 0; + for(const auto & l_todDrawerIter : l_todDrawerList) + { + if((i_otherConfigMdmt->getParentDrawer()->getParentNodeTarget()-> + getAttr() == + l_todDrawerIter->getParentNodeTarget()-> + getAttr())//Same node + && + (i_otherConfigMdmt->getParentDrawer()->getId() != + l_todDrawerIter->getId()))//Different TOD Drawer + { + l_pTodProc = NULL; + l_coreCount = 0; + l_procList.clear(); + //Get the list of procs on this TOD drawer that have oscillator + //input. Each of them is a potential MDMT, choose the one with + //max no. of cores + l_todDrawerIter-> + getPotentialMdmts(l_procList); + l_todDrawerIter-> + getProcWithMaxCores(NULL, + l_pTodProc, + l_coreCount, + &l_procList); + if(l_coreCount > l_maxCoreCount) + { + l_newMdmt = l_pTodProc; + l_maxCoreCount = l_coreCount; + l_pMasterDrw = l_todDrawerIter; + } + } + } + if(l_newMdmt && i_setMdmt) + { + l_errHdl = setMdmt(i_config, + l_newMdmt, + l_pMasterDrw); + if(l_errHdl) + { + TOD_ERR("Error setting proc 0x%.8X on " + "TOD drawer 0x%.2X as MDMT " + "for config 0x%.2X", + l_newMdmt->getTarget()-> + getAttr(), + l_pMasterDrw->getId(), + i_config); + errlCommit(l_errHdl, TOD_COMP_ID); + l_newMdmt = NULL; + } + else + { + TOD_INF("Found MDMT 0x%.8X on different TOD drawer 0x%.2X", + l_newMdmt->getTarget()->getAttr(), + l_pMasterDrw->getId()); + l_pMasterDrw = NULL; + break; + } + } + + //3.Try to find MDMT on the same TOD drawer as the TOD Drawer of + //opposite MDMT + l_maxCoreCount = 0; + for (const auto l_todDrawerIter : l_todDrawerList) + { + l_pTodProc = NULL; + l_coreCount = 0; + l_procList.clear(); + if(i_otherConfigMdmt->getParentDrawer()->getId() == + l_todDrawerIter->getId()) + { + //This is the TOD drawer on which opposite MDMT exists, + //try to avoid processor chip of opposite MDMT while + //getting the proc with max cores + //Get the list of procs on this TOD drawer that have oscillator + //input. Each of them is a potential MDMT, choose the one with + //max no. of cores + l_todDrawerIter-> + getPotentialMdmts(l_procList); + l_todDrawerIter->getProcWithMaxCores( + i_otherConfigMdmt, + l_pTodProc, + l_coreCount, + &l_procList); + l_newMdmt = l_pTodProc; + l_pMasterDrw = l_todDrawerIter; + break; + } + } + if(l_newMdmt && i_setMdmt) + { + l_errHdl = setMdmt(i_config, + l_newMdmt, + l_pMasterDrw); + if(l_errHdl) + { + TOD_ERR("Error setting proc 0x%.8X on " + "TOD drawer 0x%.2X as MDMT " + "for config 0x%.2X", + l_newMdmt->getTarget()-> + getAttr(), + l_pMasterDrw->getId(), + i_config); + errlCommit(l_errHdl, TOD_COMP_ID); + l_newMdmt = NULL; + } + else + { + TOD_INF( + "Found another MDMT 0x%.8X on the same TOD drawer 0x%.2X " + "on which i_otherConfigMdmt(0x%.8X) resides", + GETHUID(l_newMdmt->getTarget()), + l_pMasterDrw->getId(), + GETHUID(i_otherConfigMdmt->getTarget())); + l_pMasterDrw = NULL; + break; + } + } + }while(0); + + TOD_EXIT(); + + return l_newMdmt; +} -//***************************************************************************** -//TodControls::getTodProcDataFromAttribute() //****************************************************************************** -errlHndl_t TodControls::getTodProcDataFromAttribute( - std::vector& o_todChipDataVector )const +//TodControls::setMdmtOfActiveConfig +//****************************************************************************** +void TodControls ::setMdmtOfActiveConfig( + const p9_tod_setup_tod_sel i_config, + TodProc* i_mdmt, + TodDrawer* i_masterDrawer) { - TOD_ENTER("getTodProcDataFromAttribute()"); + TOD_ENTER("setMdmtOfActiveConfig"); + + do + { + if ( !i_mdmt ) + { + TOD_ERR_ASSERT("Software error input MDMT must not be NULL"); + break; + } + + if ( !i_masterDrawer ) + { + TOD_ERR_ASSERT("Software error input master drawer must not be " + " NULL"); + break; + } + + iv_todConfig[i_config].iv_mdmt = i_mdmt; + i_mdmt->setMasterType(TodProc::TOD_MASTER); + i_masterDrawer->setMasterDrawer(true); + + TOD_INF("MDMT for configuration 0x%.2X is proc 0x%.8X", + i_config, + GETHUID(iv_todConfig[i_config].iv_mdmt->getTarget())); + } while (0); + TOD_EXIT(); +} + +//****************************************************************************** +//TodControls::setMdmt +//****************************************************************************** +errlHndl_t TodControls ::setMdmt(const p9_tod_setup_tod_sel i_config, + TodProc* i_mdmt, + TodDrawer* i_masterDrawer) +{ + TOD_ENTER("setMdmt"); + errlHndl_t l_errHdl = NULL; do { - TodChipData l_todData; - memset(&l_todData,0,sizeof(TodChipData)); - ATTR_TOD_CPU_DATA_type l_arrayVal; + if ( !i_mdmt ) + { + TOD_ERR_ASSERT("Software error input MDMT must not be NULL"); + break; + } + + if ( !i_masterDrawer ) + { + TOD_ERR_ASSERT("Software error input master drawer must not be " + " NULL"); + break; + } + + iv_todConfig[i_config].iv_mdmt = i_mdmt; + i_mdmt->setMasterType(TodProc::TOD_MASTER); + i_masterDrawer->setMasterDrawer(true); + + TOD_INF("MDMT for configuration 0x%.2X is proc 0x%.8X, ", + i_config, + iv_todConfig[i_config].iv_mdmt-> + getTarget()->getAttr()); + + } while (0); + TOD_EXIT(); + + return l_errHdl; +} - //the size of the attribute needs to accommodate the size of the struct - TOD_ASSERT(sizeof(TodChipData) == sizeof(ATTR_TOD_CPU_DATA_type), - "sizeof TodChipData and attribute different"); +//****************************************************************************** +//isProcBlackListed +//****************************************************************************** +bool TodControls::isProcBlackListed ( + TARGETING::ConstTargetHandle_t i_procTarget + )const +{ + TOD_ENTER(); - //The amount of data stored on TodSystemFile always depend on the - //maximum processor possible for the given system type - uint32_t l_maxProcCount = getMaxProcsOnSystem(); + bool l_blackListed = false; + + do + { + if(!i_procTarget) + { + TOD_ERR_ASSERT("Input target cannot be NULL for " + "isProcBlackListed"); + break; + } + + if ( + ( GETCLASS(i_procTarget) != TARGETING::CLASS_CHIP ) + || + ( GETTYPE(i_procTarget) != TARGETING::TYPE_PROC)) + { + TOD_ERR_ASSERT("Only processor target allowed as input for " + " isProcBlackListed "); + break; + } + + if(iv_BlackListedProcs.end() != std::find( + iv_BlackListedProcs.begin(), + iv_BlackListedProcs.end(), + i_procTarget)) + { + TOD_INF("Proc 0x%.8X is blacklisted!", GETHUID(i_procTarget)); + l_blackListed = true; + } + } while (0); + TOD_EXIT(); + + return l_blackListed; +} + +//****************************************************************************** +//buildGardedTargetsList +//****************************************************************************** +errlHndl_t TodControls::buildGardedTargetsList() +{ + TOD_ENTER("buildGardedTargetsList"); + errlHndl_t l_errHdl = NULL; + iv_gardListInitialized = false; + clearGardedTargetsList(); + + do + { + TARGETING::Target* l_pSystemTarget = NULL; + TARGETING::targetService().getTopLevelTarget(l_pSystemTarget); + if ( !l_pSystemTarget ) + { + TOD_ERR_ASSERT("System target could not be found"); + break; + } + + GardedUnitList_t l_gardedUnitList; + l_errHdl = gardGetGardedUnits(l_pSystemTarget,l_gardedUnitList); + if ( l_errHdl ) + { + TOD_ERR("Error getting garded units."); + break; + } + else + { + for(const auto & l_iter : l_gardedUnitList) + { + //Push the HUID to the set of garded targets + iv_gardedTargets.push_back(l_iter.iv_huid); + TOD_INF("Adding 0x%08X to the garded list of targets", + l_iter.iv_huid); + } - TodChipData blank; - //Allocate memory - o_todChipDataVector.assign(l_maxProcCount,blank); + } + + }while(0); + + if ( !l_errHdl ) + { + iv_gardListInitialized = true; + } + TOD_EXIT(); + return l_errHdl; + +} + + +//****************************************************************************** +//checkGardStatusOfTarget +//****************************************************************************** +errlHndl_t TodControls::checkGardStatusOfTarget( + TARGETING::ConstTargetHandle_t i_target, + bool& o_isTargetGarded ) +{ + TOD_ENTER("checkGardStatusOfTarget"); + errlHndl_t l_errHdl = NULL; + o_isTargetGarded = false; - TARGETING::TargetHandleList l_procListA; - getAllChips(l_procListA, TYPE_PROC); + do{ - bool l_read=0; - for(TargetHandleList::const_iterator proc = l_procListA.begin(); - proc != l_procListA.end(); ++proc) + if ( !iv_gardListInitialized ) + { + TOD_INF("Local cache of garded targets is not initialized " + " the gard status will be retrieved from system model"); + } + else { - l_read = - (*proc)->tryGetAttr(l_arrayVal); - TOD_ASSERT(l_read==true, "ATTR_TOD_CPU_DATA not found"); - memcpy(&l_todData, l_arrayVal, sizeof(TodChipData)); - o_todChipDataVector - [(*proc)->getAttr()]= l_todData; + if (iv_gardedTargets.end() != std::find( + iv_gardedTargets.begin(), + iv_gardedTargets.end(), + (GETHUID(i_target)))) + { + o_isTargetGarded = true; + } + } }while(0); - TOD_EXIT("getTodProcDataFromAttribute(). errHdl = %p", l_errHdl); + TOD_EXIT("Target 0x%08X is %s", + GETHUID(i_target),o_isTargetGarded?"garded":"not garded"); return l_errHdl; } +const char *TodControls::getPhysicalPathString( + const TARGETING::ATTR_PHYS_PATH_type &i_path) +{ + const char *l_str = i_path.toString(); + return l_str; +} + +/******************************************************************************/ +// gardGetGardedUnits +/******************************************************************************/ +errlHndl_t TodControls::gardGetGardedUnits( + const TARGETING::Target* const i_pTarget, + GardedUnitList_t &o_gardedUnitList) +{ + TOD_ENTER("gardGetGardedUnits"); + errlHndl_t l_err = NULL; + o_gardedUnitList.clear(); + do + { + HWAS::DeconfigGard::GardRecords_t l_gardRecords; + l_err = HWAS::theDeconfigGard().getGardRecords(i_pTarget, + l_gardRecords); + if(l_err != NULL) + { + TOD_ERR("Error getting gard records for HUID :[0x%08X]", + GETHUID(i_pTarget)); + + break; + } + + for(const auto & l_iter : l_gardRecords) + { + TARGETING::Target * l_pTarget = NULL; + + l_err = getTargetFromPhysicalPath(l_iter.iv_targetId, + l_pTarget); + if(l_err != NULL) + { + TOD_ERR("Error finding target"); + break; + } + GardedUnit_t l_gardedUnit; + memset(&l_gardedUnit,0,sizeof(GardedUnit_t)); + l_gardedUnit.iv_huid = + l_pTarget->getAttr(); + TARGETING::Target *l_pNodeTarget = NULL; + if((l_pTarget->getAttr() == + TARGETING::CLASS_ENC)&& + (l_pTarget->getAttr() == + TARGETING::TYPE_NODE)) + { + l_pNodeTarget = l_pTarget; + } + else + { + l_err = getParent(l_pTarget, + TARGETING::CLASS_ENC, + l_pNodeTarget); + if(l_err != NULL) + { + TOD_ERR("Error getting parent node, HUID:[0x%08X]", + l_pTarget->getAttr()); + + break; + } + } + l_gardedUnit.iv_nodeHuid = + l_pNodeTarget->getAttr(); + l_gardedUnit.iv_errlogId = + l_iter.iv_errlogEid; + l_gardedUnit.iv_errType = + static_cast(l_iter.iv_errorType); + l_gardedUnit.iv_domain = + l_pTarget->getAttr(); + l_gardedUnit.iv_type = + l_pTarget->getAttr(); + + l_gardedUnit.iv_class = + l_pTarget->getAttr(); + + o_gardedUnitList.push_back(l_gardedUnit); + } + if(l_err != NULL) + { + break; + } + } + while(0); + if(l_err != NULL) + { + o_gardedUnitList.clear(); + } + TOD_EXIT(); + return l_err; +} + +//****************************************************************************** +// getTargetFromPhysicalPath +//****************************************************************************** + +errlHndl_t TodControls::getTargetFromPhysicalPath( + const TARGETING::ATTR_PHYS_PATH_type &i_path, + TARGETING::Target*& o_pTarget) + +{ + TOD_ENTER("getTargetFromPhysicalPath"); + errlHndl_t l_err = NULL; + do + { + o_pTarget = + TARGETING::targetService().toTarget(i_path); + if(o_pTarget == NULL) + { + TOD_ERR("Error in getting target from entity path[%s]", + getPhysicalPathString(i_path)); + /*@ + * @errortype + * @moduleid TOD_CONTROLS_GET_TARGET + * @reasoncode TOD_NULL_INPUT_TARGET + * @devdesc Target ID is invalid + * @custdesc Service Processor Firmware encountered an internal + * error + */ + l_err = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_CONTROLS_GET_TARGET, + TOD_NULL_INPUT_TARGET); + break; + } + } + while(0); + TOD_EXIT(); + return l_err; +} + +//****************************************************************************** +// getParent +//****************************************************************************** + +errlHndl_t TodControls::getParent(const TARGETING::Target *i_pTarget, + const TARGETING::CLASS i_class, + TARGETING::Target *& o_parent_target) +{ + + //-------------------------------------------------------------------------- + // Local Variables + //-------------------------------------------------------------------------- + bool l_parent_found = false; + errlHndl_t l_errl = NULL; + TARGETING::TargetHandleList l_list; + // Initializing l_parentTarget here in-order to eliminate goto compilation + // error below + const TARGETING::Target * l_parentTarget = i_pTarget; + TARGETING::ATTR_TYPE_type l_type = TARGETING::TYPE_NA; + TARGETING::ATTR_CLASS_type l_class = TARGETING::CLASS_NA; + + //-------------------------------------------------------------------------- + // Code + //-------------------------------------------------------------------------- + TOD_ENTER("getParent"); + + do + { + // If i_pTarget is NULL then create an error log + if(!i_pTarget) + { + TOD_ERR("Input Target handle is null"); + + //Create error + /*@ + * @errortype + * @moduleid TOD_UTIL_MOD_GET_PARENT + * @reasoncode TOD_NULL_INPUT_TARGET + * @devdesc NULL Target is supplied as input + * @custdesc Service Processor Firmware encountered an internal + * error + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_UTIL_MOD_GET_PARENT, + TOD_NULL_INPUT_TARGET); + break; + } + + // If we have a valid target, check if it is system + l_type = i_pTarget->getAttr(); + + l_class = i_pTarget->getAttr(); + + if((TARGETING::CLASS_SYS == l_class) && + (TARGETING::TYPE_SYS == l_type)) + { + TOD_ERR("Input target is SYSTEM which cannot have a parent target." + "Class [0x%08X], Type [0x%08X]", + static_cast(l_class), + static_cast(l_type)); + + //Create error + /*@ + * @errortype + * @moduleid TOD_UTIL_MOD_GET_PARENT + * @reasoncode TOD_INVALID_TARGET + * @userdata1 HUID of the input target + * @devdesc Invalid target is supplied as input, + * SYSTEM target has no parent + * @custdesc Service Processor Firmware encountered an internal + * error + */ + + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_UTIL_MOD_GET_PARENT, + TOD_INVALID_TARGET, + GETHUID(i_pTarget)); + + break; + } + + + // Clear existing elements of l_list, just to make sure, though + // getAssociated() clears l_list below when it gets called + l_list.clear(); + + // Get the immediate parent + TARGETING::targetService().getAssociated(l_list, l_parentTarget, + TARGETING::TargetService::PARENT, + TARGETING::TargetService::IMMEDIATE); + + if (l_list.size() != 1) + { + // Parent not found + break; + } + else + { + // Copy parent from list + l_parentTarget = l_list[0]; + + // Check input CLASS with parent CLASS + if ((i_class == TARGETING::CLASS_NA) || + (i_class == l_parentTarget->getAttr())) + { + // Remove const-ness of l_parentTarget in-order to copy it to + // o_parent_target, which is not a const + o_parent_target = + const_cast(l_parentTarget); + l_parent_found = true; + break; + } + } + }while(0); + + // Create an error log if parent is not found + if(!l_parent_found) + { + + //Create error + /*@ + * @errortype + * @moduleid TOD_UTIL_MOD_GET_PARENT + * @reasoncode TOD_PARENT_NOT_FOUND + * @userdata1 HUID of supplied Target + * @userdata2[0:31] Size of the list + * @userdata2[32:63] Input CLASS + * @devdesc Parent of input CLASS for supplied Target is not found + * @custdesc Service Processor Firmware encountered an internal + * error + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_UTIL_MOD_GET_PARENT, + TOD_PARENT_NOT_FOUND, + GETHUID(i_pTarget), + TWO_UINT32_TO_UINT64(l_list.size(), i_class)); + + // Assert will R/R the FSP, set the R/R bit in this error + // to indicate that this error is responsible for the R/R + //l_errl->setRsrlBit(true); + + TOD_ERR_ASSERT(0, "ERROR - Parent not found for the supplied target." + "Supplied target's HUID: 0x%08X", + GETHUID(i_pTarget)); + + } + + TOD_EXIT(); + return l_errl; + +} + +// Wrapper function for TodControls::getDrawers instance +void getDrawers(const p9_tod_setup_tod_sel i_config, + TodDrawerContainer& o_drawerList) +{ + Singleton::instance().getDrawers(i_config, o_drawerList); +} + +// Wrapper function for TodControls::isProcBlackListed instance +bool isProcBlackListed (TARGETING::ConstTargetHandle_t i_procTarget) +{ + return Singleton::instance().isProcBlackListed( + i_procTarget); +} + +// Wrapper function for TodControls::getMDMT instance +TodProc* getMDMT(const p9_tod_setup_tod_sel i_config) +{ + return Singleton::instance().getMDMT(i_config); +} + +// Wrapper function for TodControls::pickMdmt instance +errlHndl_t pickMdmt(const p9_tod_setup_tod_sel i_config) +{ + return Singleton::instance().pickMdmt(i_config); +} + +// Wrapper function for TodControls::isTodRunning instance +errlHndl_t isTodRunning ( bool& o_isTodRunning) +{ + return Singleton::instance().isTodRunning(o_isTodRunning); +} + +// Wrapper function for TodControls::checkGardStatusOfTarget instance +errlHndl_t checkGardStatusOfTarget(TARGETING::ConstTargetHandle_t i_target, + bool& o_isTargetGarded) +{ + return Singleton::instance().checkGardStatusOfTarget( + i_target, o_isTargetGarded); +} + +// Wrapper function for TodControls::destroy instance +void destroy(const p9_tod_setup_tod_sel i_config) +{ + Singleton::instance().destroy(i_config); +} + +// Wrapper function for TodControls::buildTodDrawers instance +errlHndl_t buildTodDrawers(const p9_tod_setup_tod_sel i_config) +{ + return Singleton::instance().buildTodDrawers(i_config); +} + +// Wrapper function for TodControls::buildGardedTargetsList instance +errlHndl_t buildGardedTargetsList() +{ + return Singleton::instance().buildGardedTargetsList(); +} + +// Wrapper function for TodControls::setConfigStatus instance +void setConfigStatus(const p9_tod_setup_tod_sel i_config, + const bool i_isConfigured ) +{ + Singleton::instance().setConfigStatus(i_config, i_isConfigured); +} + +// Wrapper function for TodControls::getConfiguredMdmt instance +errlHndl_t getConfiguredMdmt(TARGETING::Target*& o_primaryMdmt, + TARGETING::Target*& o_secondaryMdmt) +{ + return Singleton::instance().getConfiguredMdmt(o_primaryMdmt, + o_secondaryMdmt); +} + +// Wrapper function for TodControls::writeTodProcData instance +errlHndl_t writeTodProcData(const p9_tod_setup_tod_sel i_config) +{ + return Singleton::instance().writeTodProcData(i_config); +} + +void clearGardedTargetsList() +{ + Singleton::instance().clearGardedTargetsList(); +} + +// Wrapper function for TodControls::queryActiveConfig instance +errlHndl_t queryActiveConfig(p9_tod_setup_tod_sel& o_activeConfig, + bool& o_isTodRunning, + TARGETING::Target*& o_mdmtOnActiveTopology, + bool i_determineTodRunningState) +{ + return Singleton::instance().queryActiveConfig(o_activeConfig, + o_isTodRunning, o_mdmtOnActiveTopology, i_determineTodRunningState); +} + +// Wrapper function for TodControls::setMdmtOfActiveConfig instance +void setMdmtOfActiveConfig(const p9_tod_setup_tod_sel i_config, + TodProc* i_proc, + TodDrawer* i_drawer) +{ + return Singleton::instance().setMdmtOfActiveConfig(i_config, + i_proc, i_drawer); +} + }//end of namespace diff --git a/src/usr/isteps/istep18/TodControls.H b/src/usr/isteps/istep18/TodControls.H index 339bfb9a699..96ad14f6d17 100755 --- a/src/usr/isteps/istep18/TodControls.H +++ b/src/usr/isteps/istep18/TodControls.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -22,25 +22,28 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ - +#ifndef TODCONTROLS_H +#define TODCONTROLS_H /** * @file TodControls.H * - * @brief This file declares the methods and members of TodControls class - * - * HWP_IGNORE_VERSION_CHECK - * + * @brief Contains TodControls class declaration + * TodControls class will maintain the data structures required for + * creating/modifying TOD topologies */ -#ifndef TODCONTROLS_H -#define TODCONTROLS_H - //------------------------------------------------------------------------------ //Includes //------------------------------------------------------------------------------ -#include -#include "proc_tod_utils.H" +//System Include + +#include +#include #include "TodDrawer.H" +#include "TodProc.H" +#include "TodSvcUtil.H" +#include "TodAssert.H" +#include "TodTrace.H" namespace TOD { @@ -56,7 +59,15 @@ struct TodChipData; //------------------------------------------------------------------------------ //Typedefs //------------------------------------------------------------------------------ +//Use "thesTodControls_t::Instance()" to access the singleton via reference +typedef Singleton theTodControls_t; typedef std::vector TodChipDataContainer; +typedef std::vector + BlacListedProcContainer; +typedef std::vector + GardedProcContainer; +typedef std::vector + GardedTargetsContainer; //------------------------------------------------------------------------------ //Static globals @@ -66,8 +77,13 @@ const static uint8_t TOD_NUM_CONFIGS = 2; const static uint8_t TOD_PSS_MSS_STATUS_REG_00040008_ACTIVE_BIT = 0; const static uint8_t TOD_PSS_MSS_CTRL_REG_00040007_PRIMARY_MDMT_BIT = 1; const static uint8_t TOD_PSS_MSS_CTRL_REG_00040007_SECONDARY_MDMT_BIT = 9; - -const static uint32_t TOD_INVALID_UNITID = 0xFFFFFFEF; +const static uint8_t TOD_PSS_MSS_STATUS_REG_00040008_PRI_M_S_TOD_SEL = 13; +const static uint8_t TOD_PSS_MSS_STATUS_REG_00040008_PRI_M_S_DRAWER_SEL = 14; +const static uint8_t TOD_PSS_MSS_STATUS_REG_00040008_SEC_M_S_TOD_SEL = 17; +const static uint8_t TOD_PSS_MSS_STATUS_REG_00040008_SEC_M_S_DRAWER_SEL = 18; +const static uint8_t TOD_FSM_REG_TOD_IS_RUNNING = 4; +const uint32_t TOD_HUID_INVALID = 0xFFFFFFFF; +const uint32_t FSP_INVALID_RID = 0x0; /** * @class TodControls @@ -111,8 +127,8 @@ public: * available in the system * * @par Detailed Description: - * TOD drawers are represented by HwsvTodDrawer class, that - * basically provides a grouping of the HwsvTodProc objects such + * TOD drawers are represented by TodDrawer class, that + * basically provides a grouping of the TodProc objects such * that processor chips beloning to a specific drawer connect * over X bus and inter drawer connection is over A bus. TOD drawer * is analogous to fabic node on the system. @@ -128,7 +144,7 @@ public: * At the end of operation TOD topology infrastructure will either * have iv_primTodDrawer or iv_secTodDrawerList completed with each * drawer having a list of functional proc chips represented as - * HwsvTodProc pointers. + * TodProc pointers. * * @param[in] i_config * Indicates the primary/secondary topology @@ -147,7 +163,7 @@ public: * any returned error created by this function will be a non-reported * tracing event error log. */ - errlHndl_t buildTodDrawers(const proc_tod_setup_tod_sel i_config); + errlHndl_t buildTodDrawers(const p9_tod_setup_tod_sel i_config); /** * @brief This method will pick MDMT chip for the configuration @@ -191,7 +207,7 @@ public: * any returned error created by this function will be a non-reported * tracing event error log. */ - errlHndl_t pickMdmt(const proc_tod_setup_tod_sel i_config); + errlHndl_t pickMdmt(const p9_tod_setup_tod_sel i_config); /** * @brief Destroy information pertaining to topology type @@ -202,7 +218,7 @@ public: * * @return N/A */ - void destroy(const proc_tod_setup_tod_sel i_config); + void destroy(const p9_tod_setup_tod_sel i_config); /** * @brief Gets a list of TOD drawers for a specific @@ -212,11 +228,11 @@ public: * Indicates the primary/secondary topology * * @param[out] o_drawerList - * list of HwsvTodDrawer pointers, empty in case of error + * list of TodDrawer pointers, empty in case of error * * @return N/A */ - void getDrawers(const proc_tod_setup_tod_sel i_config, + void getDrawers(const p9_tod_setup_tod_sel i_config, TodDrawerContainer& o_drawerList) const { o_drawerList = iv_todConfig[i_config].iv_todDrawerList; @@ -229,11 +245,11 @@ public: * Indicates the primary/secondary topology * * @param[out] o_pMDMT - * The HwsvTodProc pointer corresponding to the MDMT. NULL if error. + * The TodProc pointer corresponding to the MDMT. NULL if error. * * @return Pointer to the data member iv_todConfig[i_config].iv_mdmt */ - TodProc* getMDMT(const proc_tod_setup_tod_sel i_config) const + TodProc* getMDMT(const p9_tod_setup_tod_sel i_config) const { return iv_todConfig[i_config].iv_mdmt; } @@ -251,7 +267,7 @@ public: * * @return NA */ - void setConfigStatus(const proc_tod_setup_tod_sel i_config, + void setConfigStatus(const p9_tod_setup_tod_sel i_config, const bool i_isConfigured ) { iv_todConfig[i_config].iv_isConfigured = i_isConfigured; @@ -267,7 +283,7 @@ public: * * @return bool, indicating iv_isConfigured's value */ - bool getConfigStatus(const proc_tod_setup_tod_sel i_config) const + bool getConfigStatus(const p9_tod_setup_tod_sel i_config) const { return iv_todConfig[i_config].iv_isConfigured; } @@ -305,17 +321,15 @@ public: */ errlHndl_t isTodRunning ( bool& o_isTodRunning)const; - - /** - * @brief This method will save TOD topology register data for HDAT + * @brief This method will provide TOD topology register data to HDAT * * @par Detailed Description: * HWSV needs to share TOD topology data with HDAT. * HWSV also needs to persist with TOD topology data across non-memory * preserving IPL's. * Both the above requirements will be fulfilled by writing data - * to an attribute per proc. + * to a file. * This method will take the TOD register data and put it in the format * required by HDAT, and then call helper method to write the same to a * file @@ -328,30 +342,32 @@ public: * building one of the topologies i.e. primary could be built but not * the secondary then primary should be passed as i_config. * - * @return NULL if successful - * !NULL otherwise + * @return Error log handle indicating the status of the request. + * @retval NULL if successful + * @retval !NULL if failed to write TOD configuration data + * + * Error log handle points to a valid error log object whose primary + * SRC reason code (pError->getSRC()->reasonCode()) indicates the type + * of error. + * + * @note It is up to the caller to change the severity of the returned + * error based on what it decides to do with it. By default any + * returned error created by this function will be a non-reported + * tracing event error log. */ - errlHndl_t writeTodProcData(const proc_tod_setup_tod_sel i_config); - + errlHndl_t writeTodProcData(const p9_tod_setup_tod_sel i_config); - /** - * @brief This method will be used to return Tod Data for all procs - * by reading the TOD data from chip attribute - * - * @param[in]: o_todChipDataVector - * is populated with TOD data - * - * @return if it cannot read from attribute TOD_ASSERT() will be invoked - */ - errlHndl_t getTodProcDataFromAttribute( - std::vector& o_todChipDataVector )const; + //Temporary method for bringup + //Issue 132460 -- This method is temporarily provided for bringup + //errlHndl_t writeTodProcDataFromBuffer(std::vector& + // i_todChipDataVector ); /** * * @brief Getter method for iv_todChipDataVector * - * @return Constant reference to vector that will carry + * @return Constant reference to vector that will carry * back iv_todChipDataVector * */ @@ -360,132 +376,563 @@ public: return iv_todChipDataVector; } + /** + * + * @brief This method will determine if the input processor target is + * available in the precessor blacklist or not. + * + * @param[in] i_procTarget + * The input processor target. + * The input target must not be NULL, and it must be of the processor + * type only. + * + * @return bool + * True if input processor target is blacklisted false otherwise + * + */ + bool isProcBlackListed ( + TARGETING::ConstTargetHandle_t i_procTarget + )const; + /** + * + * @brief queryActiveConfig method will help to find the active TOD + * topology when ChipTOD HW is running, it will also report ChipTOD HW + * status (i.e. wheather it is currently running)and the MDMT belonging + * to active configuration. + * Calling code should ensure that it does not modifies active + * configuration when TOD HW is running. + * + * @par Detailed Description: + * This method ports logic from P7. + * Bits 00:02 of the TOD status register ( 0x40008 ), indicates the + * topology that is currently active in HW. + * + * @param[out] o_activeConfig, active configuration [primary | secondary] + * In case the TOD HW is not running then primary will be returned. + * + * @param[out] o_isTodRunning, It will indicate if TOD HW logic is running + * or not? + * + * @param[out] o_mdmtOnActiveTopology, target pointer of MDMT on active + * topology. In case of error or TOD HW logic is not running then this + * parameter will be NULL. + * + * @param[in] i_determineTodRunningState, This is a boolean variable that + * will determine if this method determines the TOD running state or + * not, this is done to reduce the number of SCOM operations in those + * flows where knowledge of running state is not required. Defaults to + * true i.e. determine the running state. + * + * @return Error log handle that will indicate if method was successfully + * able to determine various parameters or not + * + * @retval NULL , Indicates success + * @retval !NULL , Failed getting all the output parameters,in this case + * values of o_configAction,o_isTodRunning should not be considered + * for any further action. + * + * This API may return one of the following "special" reason codes: + * NA + * + * @note It is up to the caller to change the severity of the + * returned error based on what it decides to do with it. By default + * any returned error created by this function will be a non-reported + * tracing event error log. + */ + + errlHndl_t queryActiveConfig( p9_tod_setup_tod_sel& o_activeConfig, + bool& o_isTodRunning, + TARGETING::Target*& o_mdmtOnActiveTopology, + bool i_determineTodRunningState=true) const; + + /** + * + * @brief getConfiguredMdmt method will determine primary and secondary + * MDMT, if they are configured, using TOD register data. + * + * @par Detailed Description: + * TOD control register (0x40007) has bits that + * will be set for the processor when it is designated as primary + * MDMT or secondary MDMT. In case TOD HW indicates that MDMT is not + * set, output variables will be NULL. + * + * @param[out] o_primaryMdmt, Parameter in which target pointer of primary + * MDMT will be returned, it will be set to NULL if TOD HW does not + * shows that primary MDMT is configured. + * + * @param[out] o_secondaryMdmt, Parameter in which target pointer of + * secondary MDMT will be returned, it will be set to NULL if TOD HW + * does not show that secondary MDMT is configured. + * + * @return Error log handle indicating the status of request. + * @retval NULL , Indicates that method successfully executed its + * algorithm for determining MDMTs, however the individual output + * parameters must be checked to determine if the respective MDMT + * were found or not. + * @retval !NULL , Indicates a problem condition where method was not able + * to complete all the steps for determining MDMTs successfully. In + * the error condition output parameters should be ignored. + * + * This API may return one of the following "special" reason codes: + * NA + * @note It is up to the caller to change the severity of the + * returned error based on what it decides to do with it. By default + * any returned error created by this function will be a non-reported + * tracing event error log. + */ + errlHndl_t getConfiguredMdmt(TARGETING::Target*& o_primaryMdmt, + TARGETING::Target*& o_secondaryMdmt)const; + + /** + * @brief For the input config fills up iv_todConfig with MDMT and OSC + * info. Input proc is set as the master and the input drawer as the + * master drawer. Will also ask the proc to pick an OSC from which it + * can receive signals. Caller can provide an i_avoidOscHUID, this + * will help choose a redundant OSC for the redundant topology. + * + * @param[in] i_config + * Indicates the primary/secondary topology + * + * @param[in] i_proc + * TodProc pointer, must not be NULL. + * + * @param[in] i_drawer + * TodDrawer pointer, must not be NULL. + * + * @return Error log handle indicating the status of the request. + * @retval NULL if the MDMT was set + * @retval !NULL if MDMT couldn't be set + * + * This API may return one of the following "special" reason codes: + * NA + * + * @note It is up to the caller to change the severity of the + * returned error based on what it decides to do with it. By default + * any returned error created by this function will be a non-reported + * tracing event error log. + */ + errlHndl_t setMdmt(const p9_tod_setup_tod_sel i_config, + TodProc* i_proc, + TodDrawer* i_drawer); + + /** + * @brief This method is has similar functionality as setMdmt except that + * it will presume that OSC has already been configured for the + * processor chip that is going to be designated as MDMT. + * + * @par Detailed Description: + * The use case for this method is when we need to use the already + * configured values of MDMT and the OSC source for it. This may + * happen when TOD service gets a request for re-configuring the + * backup topology after RR because of which the in memory copy of + * active topology no longer exists. + * + * @param[in] i_config + * Indicates the primary/secondary topology + * + * @param[in] i_proc + * TodProc pointer, must not be NULL. + * + * @param[in] i_drawer + * TodDrawer pointer + * + * @return NA + * + */ + void setMdmtOfActiveConfig( const p9_tod_setup_tod_sel i_config, + TodProc* i_proc, + TodDrawer* i_drawer); + + /** + * @brief This method will collect gard records from system model and keep + * the HUIDs of garded targets on the system in local cache. + * It is done with the aim of avoiding repeated requests to the + * system model DB for checking the garded state of processors and + * OSCs, which can be time taking. + * + * @return Error log handle indicating the status of the request. + * @retval NULL if gard records could be retrieved successfully from + * system model. + * @retval !NULL if this method failed to build the local data structure + * of the garded targets on the system. + * + */ + errlHndl_t buildGardedTargetsList(); + + /** + * @brief Given a target this method will tell whether it is garded or + * not. This method will look into local cache it that was already + * initialized else it will go and look into the system model. + * + * @param[in] i_target Input target whose gard status needs to be + * determined. + * @param[out] o_isTargetGarded Boolean parameter to return the gard + * status of the input target to the caller. + * + * @return Error log handle indicating the status of the request. + * @retval NULL if gard gard status of the input target could be + * successfully determined. + * @retval !NULL if this method failed to build the local data structure + * of the garded targets on the system. + * + */ + errlHndl_t checkGardStatusOfTarget( + TARGETING::ConstTargetHandle_t i_target, + bool& o_isTargetGarded); + + /** + * + * @brief Interface to clear the local list of garded targets on the + * system. + * + * @return NA + */ + void clearGardedTargetsList() + { + TOD_INF("Clearing the list of garded targets"); + iv_gardedTargets.clear(); + iv_gardListInitialized = false; + } + protected: - /** - * @brief Constructor for the TodControls object. - */ - TodControls(); + /** + * @brief Constructor for the TodControls object. + */ + TodControls(); - /** - * @brief Destructor for the TodControls object. - */ - ~TodControls(); + /** + * @brief Destructor for the TodControls object. + */ + ~TodControls(); -private: - /** - * - * @brief queryActiveConfig method will help to find the active TOD topology - * when ChipTOD HW is running,It will also report ChipTOD HW status. - * i.e. wheather it is currently running. In case ChipTOD HW is running - * active configuration should never be modified. - * - * @par Detailed Description: - * This method ports logic from P7. - * Bits 00:02 of the TOD status register ( 0x40008 ), indicates the - * topology that is currently active in HW. - * - * @param[out] o_activeConfig, active configuration [primary | secondary] - * In case the TOD HW is not running then primary will be returned. - * - * @param[out] o_isTodRunning, It will indicate if HW is running or not - * - * @return Error log handle that will indicate if method was successfully - * able to determine various parameters or not - * @retval NULL , Indicates success - * @retval !NULL , Failed getting all the output parameters,in this case - * values of o_configAction,o_isTodRunning should not be considered for - * any further action. - * - * This API may return one of the following "special" reason codes: - * NA - * - * @note It is up to the caller to change the severity of the - * returned error based on what it decides to do with it. By default - * any returned error created by this function will be a non-reported - * tracing event error log. - */ +private: - errlHndl_t queryActiveConfig( proc_tod_setup_tod_sel& o_activeConfig, - bool& o_isTodRunning) const; + /** + * + * @brief Add new target to the processor blacklist + * + * @param[in] i_ProcTarget + * Processor target that needs to be added to blacklist of + * processors. + * Caller must ensure that the input target is neither + * NULL nor of non-processor type. + * + * @return NA + * + */ + void addProcToBlackList(TARGETING::ConstTargetHandle_t i_procTarget) + { + if ( !i_procTarget ) + { + TOD_ERR_ASSERT("Input target cannot be NULL for " + "addProcToBlackList"); + } + + if ( + ( GETCLASS(i_procTarget) != TARGETING::CLASS_CHIP ) + || + ( GETTYPE(i_procTarget) != TARGETING::TYPE_PROC)) + { + TOD_ERR_ASSERT(" Only processor target allowed as input for " + " addProcToBlackList"); + } + + iv_BlackListedProcs.push_back(i_procTarget); + } + + /** + * @brief This method will be used to determine if the data read from + * TodSystemData file indicates at least one functional processor + * + * @retval boolean value indicating presence or absence of valid data + * @retval false , There is useful data + * @retval true, No useful data found + */ + bool hasNoValidData(const std::vector& + i_todChipDataVector)const; - /** - * - * @brief getConfiguredMdmt method will determine primary and secondary MDMT - * ,if they are configured, using TOD register data. - * - * @par Detailed Description: - * TOD control register (0x40007) has bits that - * will be set for the processor when it is designated as primary MDMT - * or secondary MDMT. In case TOD HW indicates that MDMT is not set, - * output variables will be NULL. - * - * @param[out] o_primaryMdmt, Parameter in which target pointer of primary - * MDMT will be returned, it will be set to NULL if TOD HW does not - * shows that primary MDMT is configured. - * - * @param[out] o_secondaryMdmt, Parameter in which target pointer of - * secondary MDMT will be returned, it will be set to NULL if TOD HW - * does not show that secondary MDMT is configured. - * - * @return Error log handle indicating the status of request. - * @retval NULL , Indicates that method successfully executed its - * algorithm for determining MDMTs, however the individual output - * parameters must be checked to determine if the respective MDMT were - * found or not. - * @retval !NULL , Indicates a problem condition where method was not able - * to complete all the steps for determining MDMTs successfully. In the - * error condition output parameters should be ignored. - * - * This API may return one of the following "special" reason codes: - * NA - * @note It is up to the caller to change the severity of the - * returned error based on what it decides to do with it. By default - * any returned error created by this function will be a non-reported - * tracing event error log. - */ - errlHndl_t getConfiguredMdmt(TARGETING::Target*& o_primaryMdmt, - TARGETING::Target*& o_secondaryMdmt)const; +public: + /** + * @brief Given the MDMT for TOD config alternate to i_config, + * picks the MDMT for i_config based on the following criteria + * + * @par Detailed Description: + * Whenever there is an existing MDMT for the opposite configuration + * following criteria will decide the MDMT for this configuration + * + * First of all we'll look only at TOD drawers having at least one + * proc with OSC input. Of all such procs across TOD drawers, we'll + * pick the one with max no of cores + * + * We'll run the below algorithm twice, first time we'll try to pick + * an MDMT with redundant OSC. + * If we don't find one, we'll run it again witout the redundant OSC + * constraint. + * That way we'll maximise reliability : best case we'll find the + * MDMT connected to a redundant OSC on some other node. + * + * 1.MDMT will be chosen from a node other that the node on which + * this MDMT exists, in case of multinode systems. + * 2.In single node system MDMT will be chosen from a different + * fabric node (tod drawer). + * 3.Last a processor different from MDMT on the same fabric node + * will be chosen, if other options are not feasible + * + * @param[in] i_otherConfigMdmt + * TodProc pointer to the MDMT of the config alternate to i_config + * + * @param[in] i_config + * Indicates the primary/secondary topology, alternate to the one in + * which i_otherConfigMdmt is the MDMT + * + * @param[in] i_setMdmt + * Represents an special case where the method will find the MDMT but + * not set it, this case will be used when some part of code just + * wants to validate if MDMT can be found under given constraints or + * not. + * + * @return TodProc pointer to new MDMT, NULL if couldn't be chosen + */ + + TodProc* pickMdmt(const TodProc* i_otherConfigMdmt, + const p9_tod_setup_tod_sel& i_config, + const bool i_setMdmt = true); - /** - * @brief This method will be used to determine if the data read from - * TodSystemData file indicates at least one functional processor - * - * @retval boolean value indicating presence or absence of valid data - * @retval false , There is useful data - * @retval true, No useful data found - */ - bool hasNoValidData(const std::vector& - i_todChipDataVector)const; - - //Datastructure for a TOD topology : - //A list of TOD drawers (which will contain a list of HWSVTodProc's) - //The MDMT for this topology - struct TodConfig{ - TodDrawerContainer iv_todDrawerList; - TodProc* iv_mdmt; - bool iv_isConfigured; - TodConfig() : - iv_mdmt(NULL), - iv_isConfigured(false) - { - } - }; +private: - //Disabled copy constructor and assignment operator - TodControls(const TodControls& rhs); - TodControls& operator=(const TodControls& rhs); + //Datastructure for a TOD topology : + //A list of TOD drawers (which will contain a list of TodProc's) + //The MDMT for this topology + struct TodConfig{ + TodDrawerContainer iv_todDrawerList; + TodProc* iv_mdmt; + bool iv_isConfigured; + TodConfig() : + iv_mdmt(NULL), + iv_isConfigured(false) + { + } + }; + + //Disabled copy constructor and assignment operator + TodControls(const TodControls& rhs); + TodControls& operator=(const TodControls& rhs); + + //Array of TOD configs + //The fact that TOD_PRIMARY and TOD_SECONDARY are defined as 0 and 1 + //make then as appropriate indices to the array + //iv_todConfig[0] -> primary + //iv_todConfig[1] -> secondary + TodConfig iv_todConfig[TOD_NUM_CONFIGS]; + + //TodChipData for the whole system (in ordinal order) + TodChipDataContainer iv_todChipDataVector; + + //Black listed processors that should not be considered as MDMT + BlacListedProcContainer iv_BlackListedProcs; + + + //List of garded targets on the system + GardedTargetsContainer iv_gardedTargets; + + //Boolean value to indicate whether container iv_gardedTargets is + //initialized or not + bool iv_gardListInitialized; + + /* @brief enum for disable or Enable of Nag */ + enum NagUpdateAction{ + ENABLE_NAG = 0x0, + DISABLE_NAG = 0x1, + NAG_INVALID = 0x2, + }; + + + //NOTE:Extended mod ids have PLACEHOLDER MODID which needs to be used + //first when one is required. + enum ExtendedModId + { + EMOD_TOD_BUILD_BLACKLIST = 0x132, + EMOD_TOD_INIT = 0x10E, + EMOD_TOD_INIT_HWP = 0x10F, + }; + + /** + * @brief struct for returning gard records + * + */ + struct GardedUnit_t{ + TARGETING::ATTR_HUID_type iv_huid; //HUID of garded unit + TARGETING::ATTR_HUID_type iv_nodeHuid; //Node containing the unit + uint32_t iv_errlogId; //Garded Error log + HWAS::GARD_ErrorType iv_errType; //Type of gard error + TARGETING::CDM_DOMAIN iv_domain; //CDM Domain of the unit + TARGETING::ATTR_TYPE_type iv_type; //Type of the unit + TARGETING::ATTR_CLASS_type iv_class; //Class of the unit + uint32_t iv_rid; //RID of the unit + NagUpdateAction iv_nagDisabled; // Default to NAG enable + GardedUnit_t() : iv_huid(TOD_HUID_INVALID), + iv_nodeHuid(TOD_HUID_INVALID), + iv_errlogId(0), + iv_errType(HWAS::GARD_NULL), + iv_domain(TARGETING::CDM_DOMAIN_NONE), + iv_type(TARGETING::TYPE_NA), + iv_class(TARGETING::CLASS_NA), + iv_rid(FSP_INVALID_RID), + iv_nagDisabled(ENABLE_NAG) + { + } + + }; + typedef std::list GardedUnitList_t; + + /** + * @brief - This function returns all gard records in a system + * or node based on input huid + * + * @param[in] i_pTarget Target pointer to node or system, cannot be NULL + * @param[out] o_gardedUnitList List of garded records + * + * @return Error log handle indicating the status of the request + * @retval NULL on success + * @retval !NULL Error log handle, on failure + * + * @note It is up to the caller to change the severity of the returned + * error based on what it decides to do with it. By default any + * returned error created by this function will be a non-reported + * tracing event error log. + */ + errlHndl_t gardGetGardedUnits( + const TARGETING::Target* const i_pTarget, + GardedUnitList_t &o_gardedUnitList); + + /** + * @brief Return the physical path as string + * + * @param[in] i_path + * The physical path of a target + * + * + * @return string contains the string format of the path + */ + + const char * getPhysicalPathString( + const TARGETING::ATTR_PHYS_PATH_type &i_path); + + /** + * @brief Get Target based on the PHYSICAL Path + * + * @param[in] i_path + * Supplied PHYSICAL PATH + * + * @param[out] o_Target + * Pointer to Target + * + * @return errlHndl_t + * Returns error handle if supplied physical path + * is not valid + * else NULL + */ + + errlHndl_t getTargetFromPhysicalPath( + const TARGETING::ATTR_PHYS_PATH_type &i_path, + TARGETING::Target*& o_pTarget); + + /** + * @brief Get parent of input CLASS for a Target + * + * @par Description: + * Given a target, gets first target higher in the containment hierarchy + * whose class matches the specified class. + * + * @param[in] i_pTarget + * Input target pointer. Must not be NULL (otherwise call will return an + * error log). Must be a valid target from the system blueprint. + * + * @param[in] i_class + * Class which constrains the search result. CLASS_NA is not enforced, + * but it will never find a matching parent. Also note that if search + * is for a chip parent of a chip, or other illogical searches, it will + * not find a matching parent. See attributeenums.H for class values. + * + * @param[out] o_parent_target + * Parent Target; ignore on error. Note: points to a blueprint target + * which may or may not actually be present (source target must be + * present to have assurances about presence of parent) + * + * @return errlHndl_t Error log handle indicating the status of the + * operation + * @retval NULL Success, returned target is valid + * @retval !NULL Failure; returned target is invalid. Primary SRC + * reason codes + * may be set to the following (others may be possible): + * TOD_UTIL_REASON_NULL_TG: Supplied target is NULL + * TOD_UTIL_REASON_PARENT_NOT_FOUND: Parent target of specified class + * was not found + */ + + errlHndl_t getParent(const TARGETING::Target *i_pTarget, + const TARGETING::CLASS i_class, + TARGETING::Target *& o_parent_target); - //Array of TOD configs - //The fact that TOD_PRIMARY and TOD_SECONDARY are defined as 0 and 1 - //make then as appropriate indices to the array - //iv_todConfig[0] -> primary - //iv_todConfig[1] -> secondary - TodConfig iv_todConfig[TOD_NUM_CONFIGS]; - //hwsvTodChipData for the whole system (in ordinal order) - TodChipDataContainer iv_todChipDataVector; }; +// Wrapper function for TodControls::getDrawers instance +void getDrawers(const p9_tod_setup_tod_sel i_config, + TodDrawerContainer& o_drawerList); + +// Wrapper function for TodControls::isProcBlackListed instance +bool isProcBlackListed(TARGETING::ConstTargetHandle_t i_procTarget); + +// Wrapper function for TodControls::getMDMT instance +TodProc* getMDMT(const p9_tod_setup_tod_sel i_config); + +// Wrapper function for TodControls::pickMdmt instance +errlHndl_t pickMdmt(const p9_tod_setup_tod_sel i_config); + +// Wrapper function for TodControls::isTodRunning instance +errlHndl_t isTodRunning(bool& o_isTodRunning); + +// Wrapper function for TodControls::checkGardStatusOfTarget instance +errlHndl_t checkGardStatusOfTarget( + TARGETING::ConstTargetHandle_t i_target, + bool& o_isTargetGarded); + +// Wrapper function for TodControls::destroy instance +void destroy(const p9_tod_setup_tod_sel i_config); + +// Wrapper function for TodControls::buildTodDrawers instance +errlHndl_t buildTodDrawers(const p9_tod_setup_tod_sel i_config); + +// Wrapper function for TodControls::buildGardedTargetsList instance +errlHndl_t buildGardedTargetsList(); + +// Wrapper function for TodControls::setConfigStatus instance +void setConfigStatus(const p9_tod_setup_tod_sel i_config, + const bool i_isConfigured ); + +// Wrapper function for TodControls::getConfiguredMdmt instance +errlHndl_t getConfiguredMdmt(TARGETING::Target*& o_primaryMdmt, + TARGETING::Target*& o_secondaryMdmt); + +// Wrapper function for TodControls::writeTodProcData instance +errlHndl_t writeTodProcData(const p9_tod_setup_tod_sel i_config); + +// Wrapper function for TodControls::clearGardedTargetsList instance +void clearGardedTargetsList(); + +// Wrapper function for TodControls::queryActiveConfig instance +errlHndl_t queryActiveConfig(p9_tod_setup_tod_sel& o_activeConfig, + bool& o_isTodRunning, + TARGETING::Target*& o_mdmtOnActiveTopology, + bool i_determineTodRunningState); + +// Wrapper function for TodControls::setMdmtOfActiveConfig instance +void setMdmtOfActiveConfig(const p9_tod_setup_tod_sel i_config, + TodProc* i_proc, + TodDrawer* i_drawer); + } //end of namespace + #endif //TODCONTROLS_H diff --git a/src/usr/isteps/istep18/TodDrawer.C b/src/usr/isteps/istep18/TodDrawer.C index caaac1e5ba6..c8c078e3e5b 100755 --- a/src/usr/isteps/istep18/TodDrawer.C +++ b/src/usr/isteps/istep18/TodDrawer.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -22,25 +22,29 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ - /** * @file TodDrawer.C * * @brief The file implements methods of TodDrawer class - * - * HWP_IGNORE_VERSION_CHECK - * */ //------------------------------------------------------------------------------ //Includes //------------------------------------------------------------------------------ -#include "TodSvcUtil.H" -#include "TodDrawer.H" -#include "TodAssert.H" -#include "TodTrace.H" -#include +//Targeting support +#include +#include +#include +#include "TodControls.H" +#include "TodProc.H" +#include "TodDrawer.H" +#include "TodUtils.H" +#include +//Standard library +#include +#include "TodUtils.H" +#include namespace TOD { @@ -49,19 +53,25 @@ namespace TOD // TodDrawer::TodDrawer //****************************************************************************** TodDrawer::TodDrawer(const uint8_t i_drawerId, - const TARGETING::Target* i_parentNode): + const TARGETING::Target* i_parentNode): iv_todDrawerId(i_drawerId), iv_isTodMaster(false), iv_parentNodeTarget(i_parentNode) { - TOD_ASSERT(iv_parentNodeTarget, - "Error creating TOD drawer with id 0x%.2X, parent node" - "pointer passed as NULL", i_drawerId); - - TOD_ENTER("Created TOD drawer with id 0x%.2X, parent node 0x%.8X", - i_drawerId, - i_parentNode->getAttr()); - TOD_EXIT("TodDrawer constructor"); + do + { + if (!iv_parentNodeTarget) + { + TOD_ERR_ASSERT(0, "Error creating TOD drawer with id 0x%.2X," + "parent node pointer passed as NULL", + i_drawerId); + break; + } + TOD_ENTER("Created TOD drawer with id 0x%.2X, parent node 0x%.8X", + i_drawerId, + i_parentNode->getAttr()); + } while (0); + TOD_EXIT(); } //****************************************************************************** @@ -69,7 +79,7 @@ TodDrawer::TodDrawer(const uint8_t i_drawerId, //****************************************************************************** TodDrawer::~TodDrawer() { - TOD_ENTER("TodDrawer destructor"); + TOD_ENTER(); for(TodProcContainer::iterator l_itr = iv_todProcList.begin(); l_itr != iv_todProcList.end(); @@ -78,7 +88,7 @@ TodDrawer::~TodDrawer() delete (*l_itr); } iv_todProcList.clear(); - TOD_EXIT("TodDrawer destructor"); + TOD_EXIT(); } //****************************************************************************** @@ -87,7 +97,8 @@ TodDrawer::~TodDrawer() void TodDrawer::getProcWithMaxCores( const TodProc* i_procToIgnore, TodProc*& o_pTodProc, - uint32_t& o_coreCount) const + uint32_t& o_coreCount, + TodProcContainer* i_pProcList) const { TOD_ENTER("getProcWithMaxCores"); o_pTodProc = NULL; @@ -107,9 +118,11 @@ void TodDrawer::getProcWithMaxCores( TodProc* l_pSelectedTarget = NULL; uint32_t l_maxCores = 0; + const TodProcContainer &l_procList = + i_pProcList ? *i_pProcList : iv_todProcList; for(TodProcContainer::const_iterator l_procIter = - iv_todProcList.begin(); - l_procIter != iv_todProcList.end(); + l_procList.begin(); + l_procIter != l_procList.end(); ++l_procIter) { if((NULL != i_procToIgnore) && @@ -136,7 +149,7 @@ void TodDrawer::getProcWithMaxCores( { o_pTodProc = l_pSelectedTarget; o_coreCount = l_maxCores; - TOD_INF("getProcWithMaxCores,On drawer %d, processor 0x%08X " + TOD_INF("getProcWithMaxCores,On drawer 0x%2X, processor 0x%08X " "has maximum cores count = %d ", iv_todDrawerId, l_pSelectedTarget->getTarget()->getAttr(), @@ -145,7 +158,7 @@ void TodDrawer::getProcWithMaxCores( }while(0); - TOD_EXIT("getProcWithMaxCores"); + TOD_EXIT(); } @@ -154,7 +167,7 @@ void TodDrawer::getProcWithMaxCores( //****************************************************************************** errlHndl_t TodDrawer::findMasterProc(TodProc*& o_drawerMaster) const { - TOD_ENTER("findMasterProc"); + TOD_ENTER(); errlHndl_t l_errHdl = NULL; @@ -177,24 +190,104 @@ errlHndl_t TodDrawer::findMasterProc(TodProc*& o_drawerMaster) const TOD_ERR("No master proc for drawer 0x%.2X",iv_todDrawerId); /*@ * @errortype - * @reasoncode TOD_NO_MASTER_PROC * @moduleid TOD_FIND_MASTER_PROC + * @reasoncode TOD_NO_MASTER_PROC * @userdata1 TOD drawer id * @devdesc No master proc set for this drawer + * @custdesc Service Processor Firmware couldn't detect any + * functional master processor required to boot the + * host */ - l_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_INFORMATIONAL, - TOD_LOG_INVALID_CONFIG, - TOD_INVALID_CONFIG, - iv_todDrawerId, 0); + + l_errHdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_FIND_MASTER_PROC, + TOD_NO_MASTER_PROC, + iv_todDrawerId); } }while(0); o_drawerMaster = l_pMasterProc; - TOD_EXIT("findMasterProc, errHdl = %p", l_errHdl); + TOD_EXIT(); return l_errHdl; } +//****************************************************************************** +// TodDrawer::addProc +//****************************************************************************** +void TodDrawer::addProc(TodProc* i_proc) +{ + if(i_proc) + { + iv_todProcList.push_back(i_proc); + } + else + { + TOD_ERR_ASSERT("Code bug! Null Proc Target passed!"); + } +} + +//****************************************************************************** +// TodDrawer::getPotentialMdmts +//****************************************************************************** +void TodDrawer::getPotentialMdmts( + TodProcContainer& o_procList) const +{ + TOD_ENTER("TodDrawer::getPotentialMdmts"); + bool l_isGARDed = false; + errlHndl_t l_errHndl = NULL; + + const TARGETING::Target* l_procTarget = NULL; + + for(const auto & l_procItr : iv_todProcList) + { + + l_procTarget = l_procItr->getTarget(); + + //Check if the target is not black listed + if ( !(TOD::isProcBlackListed(l_procTarget)) ) + { + //Check if the target is not garded + l_errHndl = TOD::checkGardStatusOfTarget(l_procTarget, + l_isGARDed); + + if(l_errHndl) + { + TOD_ERR("Failed in checkGardStatusOfTarget() to get the " + " GARD state for the target 0x%.8x", + GETHUID(l_procTarget)); + + //Ignore this target as the gard status for this target + //could not be obtained. + continue; + } + + TARGETING::ATTR_HWAS_STATE_type l_state = + l_procTarget->getAttr(); + + if ( (!l_isGARDed) || + (l_state.deconfiguredByEid == + HWAS::DeconfigGard::CONFIGURED_BY_RESOURCE_RECOVERY) ) + { + o_procList.push_back(l_procItr); + } + else + { + TOD_INF("PROC target 0x%.8x cannot be choosen as MDMT as" + "its garded",GETHUID(l_procTarget)); + } + } + else + { + TOD_INF("PROC target 0x%.8x cannot be choosen as MDMT as it" + "is backlisted",GETHUID(l_procTarget)); + } + l_isGARDed = false; + + }//End of for loop + TOD_EXIT(); +} + }//end of namespace diff --git a/src/usr/isteps/istep18/TodDrawer.H b/src/usr/isteps/istep18/TodDrawer.H index 80257d836c8..2fbef648745 100755 --- a/src/usr/isteps/istep18/TodDrawer.H +++ b/src/usr/isteps/istep18/TodDrawer.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -24,24 +24,34 @@ /* IBM_PROLOG_END_TAG */ #ifndef TODDRAWER_H #define TODDRAWER_H - /** * @file TodDrawer.H * * @brief Contains TodDrawer class declaration * - * HWP_IGNORE_VERSION_CHECK - * */ -#include -#include +//------------------------------------------------------------------------------ +//Includes +//------------------------------------------------------------------------------ +//Targeting support +#include +#include "TodSvcUtil.H" #include "TodProc.H" namespace TOD { -class TodDrawer; // forward declaration +//------------------------------------------------------------------------------ +//Forward declarations +//------------------------------------------------------------------------------ +class TodDrawer; +class TodControls; +class TodProc; + +//------------------------------------------------------------------------------ +//Typedefs +//------------------------------------------------------------------------------ typedef std::list TodDrawerContainer; /** @@ -83,7 +93,7 @@ public: * @brief Destructor for the TodDrawer object. * * @par Detailed Description: - * Will destroy all HwsvTodProc objects that were added to this TOD + * Will destroy all TodProc objects that were added to this TOD * drawer. */ ~TodDrawer(); @@ -98,7 +108,8 @@ public: * TodTopologyManager will use this method to determine which * processor is the master for that drawer. * The method will go over the iv_todProcList and return the processor - * that is marked as TodProc::TOD_MASTER or TodProc::DRAWER_MASTER + * that is marked as TodProc::TOD_MASTER or + * TodProc::DRAWER_MASTER * * @param[out] o_drawerMaster * It will be set to master processor's address if master processor is @@ -108,9 +119,9 @@ public: * * @return Error log handle, indicates status of request * @retval NULL indicates that master processor was successfully found - * @retval !NULL indicates that the master processor could not be found + * @retval NULL indicates that the master processor could not be found * successfully. The only possible reason for returning NULL can be - * that this method was called out of sequence i.e even before + * that this method method was called out of sequence i.e even before * TodTopologyManager designated a processor on a given TOD drawer as * master for that drawer. * @@ -143,7 +154,7 @@ public: * for primar/secondary topology and MDMT has to be chosen for the * other topology, peviously chosen MDMT should be avoided. * - * @param[out] o_pTodProc, It will carry back pointer to the HwsvTodProc + * @param[out] o_pTodProc, It will carry back pointer to the TodProc * object that has the maximum number of cores. * In the unlikely case of TOD drawer not having any processor with * functional cores, this parameter will be set to NULL @@ -152,12 +163,18 @@ public: * found on processor with max functional core count. In case o_pTodProc * is set to NULL this will be zero. * + * @param[in] i_pProcList If non NULL, this will be our input set instead of + * the set of all procs on this drawer. Useful if caller has already + * identified the set of procs on this drawer for which the one with max + * no. of cores is to be determined. + * * @return N/A */ void getProcWithMaxCores( const TodProc * i_procToIgnore, TodProc *& o_pTodProc, - uint32_t& o_coreCount)const; + uint32_t& o_coreCount, + TodProcContainer* i_pProcList = NULL) const; /** * @brief Getter method for iv_todProcList @@ -186,17 +203,14 @@ public: } /** - * @brief Adds a processor to this TOD drawer + * @brief Adds a processor to this TOD drawer. * * @param[in] i_proc - * A VTodProc pointer correspnding to the proc to be added + * A TodProc pointer correspnding to the proc to be added. * * @return N/A */ - void addProc(TodProc* i_proc) - { - iv_todProcList.push_back(i_proc); - } + void addProc(TodProc* i_proc); /** * @brief Get this TOD drawer's id (this will be @@ -205,7 +219,7 @@ public: * @return TOD drawer's id * @retval corresponding fabric node's id */ - TARGETING::ATTR_FABRIC_NODE_ID_type getId() const + TARGETING::ATTR_FABRIC_GROUP_ID_type getId() const { return iv_todDrawerId; } @@ -232,23 +246,45 @@ public: return iv_parentNodeTarget; } + /** + * @brief Returns a list of procs on this drawer that can potentially be + * MDMT + * + * @par Detailed Description: + * For a processor to be a potential MDMT it has to fulfill the + * following criteria. + * 1) Processor should not be garded and it should not be on the + * blacklist. + * 2) Processor should be connected to OSC that is neither garded not + * present on the blacklist. + * 3) Processor should not be connected to the oscillator that is acting + * as MDMT source on an existing alternate toplogy. The + * Such oscillator target will be provided as input to this method. + * + * @param[out] o_procList list of procs + * + * @return N/A + */ + void getPotentialMdmts(TodProcContainer& o_procList)const; + private: //List of TodProc objects that belongs to TodDrawer instance TodProcContainer iv_todProcList; //TOD drawer id, the value of this attribute will be derived from - //ATTR_FABRIC_NODE_ID attribute of the processors that belong to this + //ATTR_FABRIC_GROUP_ID attribute of the processors that belong to this //TOD drawer, all the processors belonging to this TOD drawer will share - //the same value for ATTR_FABRIC_NODE_ID - TARGETING::ATTR_FABRIC_NODE_ID_type iv_todDrawerId; + //the same value for ATTR_FABRIC_GROUP_ID + TARGETING::ATTR_FABRIC_GROUP_ID_type iv_todDrawerId; //This data member will identify if the current drawer is a Tod master bool iv_isTodMaster; //Target pointer of the node to which TodDrawer belongs const TARGETING::Target * iv_parentNodeTarget; -}; -} //end of namespace +}; +}//end of namespace #endif //TODDRAWER_H + diff --git a/src/usr/isteps/istep18/TodHwpIntf.C b/src/usr/isteps/istep18/TodHwpIntf.C index b66f379ade4..9495c3ab4e8 100755 --- a/src/usr/isteps/istep18/TodHwpIntf.C +++ b/src/usr/isteps/istep18/TodHwpIntf.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -22,34 +22,38 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ - /** * @file TodHwpIntf.C * * @brief Implementation of TOD Hardware Procedure interfaces - * - * HWP_IGNORE_VERSION_CHECK - * */ //------------------------------------------------------------------------------ //Includes //------------------------------------------------------------------------------ -#include -#include +#include #include "TodTrace.H" -#include "TodHwpIntf.H" #include "TodControls.H" -#include "proc_tod_setup.H" -#include "proc_tod_save_config.H" -#include "proc_tod_init.H" +#include "TodUtils.H" +#include "TodProc.H" +#include "TodHwpIntf.H" +#include "TodSvcUtil.H" +#include + +//HWPF +#include +#include +#include +#include +#include namespace TOD + { -errlHndl_t todSetupHwp(const proc_tod_setup_tod_sel i_topologyType) +errlHndl_t todSetupHwp(const p9_tod_setup_tod_sel i_topologyType) { - TOD_ENTER("todSetupHwp"); + TOD_ENTER(); errlHndl_t l_errHdl = NULL; @@ -57,164 +61,215 @@ errlHndl_t todSetupHwp(const proc_tod_setup_tod_sel i_topologyType) { //Get the MDMT TodProc* l_pMDMT = - TodControls::getTheInstance().getMDMT(i_topologyType); - if(NULL == l_pMDMT) + TOD::getMDMT(i_topologyType); + + p9_tod_setup_osc_sel l_selectedOsc = TOD_OSC_0; + TOD_INF("For topology 0x%08X Passing OSC 0x%08X to " + " p9_tod_setup ",i_topologyType,l_selectedOsc); + + //Invoke the HWP by passing the topology tree (rooted at MDMT) + FAPI_INVOKE_HWP(l_errHdl, + p9_tod_setup, + l_pMDMT->getTopologyNode(), + i_topologyType, + l_selectedOsc); + if(l_errHdl) { - TOD_ERR("MDMT not found"); + TOD_ERR("Error in call to p9_tod_setup. " + "Topology type 0x%.8X. " + "MDMT's HUID is 0x%.8X. " + "MDMT Master type : 0x%.8X. " + "MDMT Bus RX 0x%.8X, Bus TX 0x%.8X.", + i_topologyType, + l_pMDMT->getTarget()->getAttr(), + l_pMDMT->getMasterType(), + l_pMDMT->getBusIn(), l_pMDMT->getBusOut()); + /*@ * @errortype - * @reasoncode TOD_NO_MASTER_PROC * @moduleid TOD_SETUP_HWP - * @devdesc MDMT could not be found + * @reasoncode TOD_HWP_EXECUTION_FAILED + * @userdata1 MDMT HUID + * @userdata2 Topology Type + * @devdesc Failed to configure TOD toplogy, due to + * error returned by p9_tod_setup. + * @custdesc Service Processor Firmware encountered an + * internal error */ l_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - TOD_SETUP_HWP, - TOD_NO_MASTER_PROC,0,0); + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_SETUP_HWP, + TOD_HWP_EXECUTION_FAILED, + GETHUID(l_pMDMT->getTarget()), + i_topologyType); break; } - - FAPI_INVOKE_HWP(l_errHdl, - proc_tod_setup, - l_pMDMT->getTopologyNode(), - i_topologyType, - TOD_OSC_0); - if(l_errHdl) - { - TOD_ERR("Error in call to proc_tod_setup. " - "Topology type 0x%.8X. " - "MDMT's HUID is 0x%.8X. " - "MDMT Master type : 0x%.8X. ", - i_topologyType, - l_pMDMT->getTarget()->getAttr(), - l_pMDMT->getMasterType()); - TOD_ERR("MDMT Bus RX 0x%.8X, Bus TX 0x%.8X.", - l_pMDMT->getBusIn(), l_pMDMT->getBusOut()); - break; - } - - //Mark the MDMT role in ATTR. Note the same chip - //can be both primary/secondary. Attr is volatile - //init'ed to zero - TARGETING::Target * l_proc = - const_cast(l_pMDMT->getTarget()); - uint8_t l_role = l_proc->getAttr(); - if (TOD_PRIMARY == i_topologyType) - { - l_role |= TARGETING::TOD_ROLE_PRIMARY; - } - else //Secondary - { - l_role |= TARGETING::TOD_ROLE_SECONDARY; - } - l_proc->setAttr(l_role); - }while(0); - TOD_EXIT("todSetupHwp. errHdl = %p", l_errHdl); + TOD_EXIT(); return l_errHdl; } -errlHndl_t todSaveRegsHwp(const proc_tod_setup_tod_sel i_topologyType) + +errlHndl_t todSaveRegsHwp(const p9_tod_setup_tod_sel i_topologyType) { - TOD_ENTER("todSaveRegsHwp"); + TOD_ENTER(); errlHndl_t l_errHdl = NULL; - do { //Get the MDMT TodProc* l_pMDMT = - TodControls::getTheInstance().getMDMT(i_topologyType); + TOD::getMDMT(i_topologyType); if(NULL == l_pMDMT) { - TOD_ERR("MDMT not found"); + TOD_ERR("MDMT not found for topology type 0x%.8X", + i_topologyType); /*@ * @errortype - * @reasoncode TOD_NO_MASTER_PROC * @moduleid TOD_SAVEREGS_HWP + * @reasoncode TOD_NO_VALID_MDMT_FOUND + * @userdata1 Topology type (primary/secondary) * @devdesc MDMT could not be found + * @custdesc Host failed to boot because there was a problem + * configuring Time Of Day on the Host processors */ l_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - TOD_SAVEREGS_HWP, - TOD_NO_MASTER_PROC,0,0); + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_SAVEREGS_HWP, + TOD_NO_VALID_MDMT_FOUND, + i_topologyType); break; } + //Invoke the HWP by passing the topology tree (rooted at MDMT) FAPI_INVOKE_HWP(l_errHdl, - proc_tod_save_config, - l_pMDMT->getTopologyNode()); + p9_tod_save_config, + l_pMDMT->getTopologyNode()); if(l_errHdl) { - TOD_ERR("Error in call to proc_tod_save_config. " - "Topology type 0x%.8X. " - "MDMT's HUID is 0x%.8X. " - "MDMT Master type : 0x%.8X. ", - i_topologyType, - l_pMDMT->getTarget()->getAttr(), - l_pMDMT->getMasterType()); - TOD_ERR("MDMT Bus RX 0x%.8X, Bus TX 0x%.8X.", - l_pMDMT->getBusIn(), l_pMDMT->getBusOut()); - break; + TOD_ERR("Error in call to p9_tod_save_config. " + "Topology type 0x%.8X. " + "MDMT's HUID is 0x%.8X. " + "MDMT Master type : 0x%.8X. " + "MDMT Bus RX 0x%.8X, Bus TX 0x%.8X.", + i_topologyType, + l_pMDMT->getTarget()->getAttr(), + l_pMDMT->getMasterType(), + l_pMDMT->getBusIn(), l_pMDMT->getBusOut()); + + /*@ + * @errortype + * @moduleid TOD_SAVEREGS_HWP + * @reasoncode TOD_HWP_EXECUTION_FAILED + * @userdata1 Topology Type + * @devdesc Failed to save TOD configuration registers, + * due to error returned by p9_tod_save_config. + * @custdesc Service Processor Firmware encountered an + * internal error + */ + l_errHdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_SAVEREGS_HWP, + TOD_HWP_EXECUTION_FAILED, + i_topologyType); + break; } }while(0); - TOD_EXIT("todSaveRegsHwp. errHdl = %p", l_errHdl); - + TOD_EXIT(); return l_errHdl; } -errlHndl_t todInitHwp(const proc_tod_setup_tod_sel i_topologyType) +//***************************************************************************** +//todInitHwp +//***************************************************************************** +errlHndl_t todInitHwp() { - TOD_ENTER("todInitHwp"); - + TOD_ENTER(); errlHndl_t l_errHdl = NULL; - do { + //Get the MDMT TodProc* l_pMDMT = - TodControls::getTheInstance().getMDMT(i_topologyType); - if(NULL == l_pMDMT) + TOD::getMDMT(TOD_PRIMARY); + + if( NULL == l_pMDMT ) { - TOD_ERR("MDMT not found"); + TOD_ERR("Valid MDMT not found in the primary TOD topology"); /*@ * @errortype - * @reasoncode TOD_NO_MASTER_PROC * @moduleid TOD_INIT_HWP - * @devdesc MDMT could not be found + * @reasoncode TOD_NO_VALID_MDMT_FOUND + * @userdata1 EMOD_TOD_INIT_HWP + * @userdata2 PRIMARY topology type + * @devdesc No MDMT present on the system + * @custdesc Host failed to boot because there was a problem + * configuring Time Of Day on the Host processors */ l_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - TOD_INIT_HWP, - TOD_NO_MASTER_PROC,0,0); + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_INIT_HWP, + TOD_NO_VALID_MDMT_FOUND, + EMOD_TOD_INIT_HWP, + TOD_PRIMARY); break; } + TARGETING::Target* l_failingTodProc = NULL; + fapi2::Target + l_fapiFailingProcTarget(l_failingTodProc); + + //Invoke the HWP by passing the reference to the topology FAPI_INVOKE_HWP(l_errHdl, - proc_tod_init, - l_pMDMT->getTopologyNode()); + p9_tod_init, + l_pMDMT->getTopologyNode(), + &l_fapiFailingProcTarget); if(l_errHdl) { - TOD_ERR("Error in call to proc_tod_init. " - "Topology type 0x%.8X. " - "MDMT's HUID is 0x%.8X. " - "MDMT Master type : 0x%.8X. ", - i_topologyType, - l_pMDMT->getTarget()->getAttr(), - l_pMDMT->getMasterType()); - TOD_ERR("MDMT Bus RX 0x%.8X, Bus TX 0x%.8X.", - l_pMDMT->getBusIn(), l_pMDMT->getBusOut()); - break; + TOD_ERR("Error in call to p9_tod_init. " + "MDMT's HUID is 0x%.8X. " + "MDMT Master type : 0x%.8X. ", + GETHUID(l_pMDMT->getTarget()), + l_pMDMT->getMasterType()); + + /*@ + * @errortype + * @moduleid TOD_INIT_HWP + * @reasoncode TOD_HWP_EXECUTION_FAILED + * @userdata1 MDMT HUID + * @devdesc Failed to initialize TOD, due to + * error returned by p9_tod_init. + * @custdesc Service Processor Firmware encountered an + * internal error + */ + l_errHdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_INIT_HWP, + TOD_HWP_EXECUTION_FAILED, + GETHUID(l_pMDMT->getTarget())); + + l_failingTodProc = reinterpret_cast( + l_fapiFailingProcTarget.get()); + + break; + } + else + { + TOD_INF("Successfully completed p9_tod_init. " + "MDMT's HUID is 0x%.8X. " + "MDMT Master type : 0x%.8X. ", + GETHUID(l_pMDMT->getTarget()), + l_pMDMT->getMasterType()); } - }while(0); - TOD_EXIT("todInitHwp. errHdl = %p", l_errHdl); + }while(0); + TOD_EXIT(); return l_errHdl; -} +}//todInitHwp -} //namespace TOD +} diff --git a/src/usr/isteps/istep18/TodHwpIntf.H b/src/usr/isteps/istep18/TodHwpIntf.H index 94f15cb8004..88dbbe4da8c 100755 --- a/src/usr/isteps/istep18/TodHwpIntf.H +++ b/src/usr/isteps/istep18/TodHwpIntf.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -24,7 +24,6 @@ /* IBM_PROLOG_END_TAG */ #ifndef TODHWPINTF_H #define TODHWPINTF_H - /** * @file TodHwpIntf.H * @@ -34,12 +33,19 @@ * */ -#include -#include "proc_tod_utils.H" +//------------------------------------------------------------------------------ +//Includes +//------------------------------------------------------------------------------ +#include "TodProc.H" +#include +#include namespace TOD { +class TodProc; +class TodControls; + /** * @brief Invokes the TOD setup hardware procedure * @@ -64,7 +70,7 @@ namespace TOD * any returned error created by this function will be a non-reported * tracing event error log. */ -errlHndl_t todSetupHwp(const proc_tod_setup_tod_sel i_topologyType); +errlHndl_t todSetupHwp(const p9_tod_setup_tod_sel i_topologyType); /** * @brief Invokes the TOD registry read HWP. @@ -74,7 +80,7 @@ errlHndl_t todSetupHwp(const proc_tod_setup_tod_sel i_topologyType); * topology and fills up, for each TOD proc datastructure, an output * field which corresponds to the TOD registers for that proc. The HWP * gets the register content by scomming the register. - * Check proc_tod_utils.H : proc_tod_setup_conf_regs for the list of regs. + * Check p9_tod_utils.H : proc_tod_setup_conf_regs for the list of regs. * * @param[in] i_topologyType * Topology type : primary/secondary @@ -92,13 +98,15 @@ errlHndl_t todSetupHwp(const proc_tod_setup_tod_sel i_topologyType); * any returned error created by this function will be a non-reported * tracing event error log. */ -errlHndl_t todSaveRegsHwp(const proc_tod_setup_tod_sel i_topologyType); +errlHndl_t todSaveRegsHwp(const p9_tod_setup_tod_sel i_topologyType); /** - * @brief Invokes the TOD init HWP. + * @brief Invokes the TOD Initialization hardware procedure * - * @param[in] i_topologyType - * Topology type : primary/secondary + * @note Detailed Description: + * This interface invokes the procedure which initializes the + * time of day logic on the functional P8 processors to running + * state. * * @return Error log handle indicating the status of the request * @retval NULL HWP executed succesfully @@ -113,8 +121,7 @@ errlHndl_t todSaveRegsHwp(const proc_tod_setup_tod_sel i_topologyType); * any returned error created by this function will be a non-reported * tracing event error log. */ -errlHndl_t todInitHwp(const proc_tod_setup_tod_sel i_topologyType); - -} //namespace TOD +errlHndl_t todInitHwp(); +} #endif //TODHWPINTF_H diff --git a/src/usr/isteps/istep18/TodProc.C b/src/usr/isteps/istep18/TodProc.C index 656b19fb605..93246762f2e 100755 --- a/src/usr/isteps/istep18/TodProc.C +++ b/src/usr/isteps/istep18/TodProc.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -22,7 +22,6 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ - /** * @file TodProc.C * @@ -35,15 +34,27 @@ //------------------------------------------------------------------------------ //Includes //------------------------------------------------------------------------------ -#include +//Standard library +#include +//Targeting support #include #include -#include +#include #include "TodDrawer.H" #include "TodProc.H" #include "TodTypes.H" +#include "TodControls.H" +#include #include "TodAssert.H" #include "TodTrace.H" +//HWPF +#include +#include +#include "TodUtils.H" + +extern "C" { + +using namespace fapi2; namespace TOD { @@ -59,13 +70,26 @@ TodProc::TodProc( iv_tod_node_data(NULL), iv_masterType(NOT_MASTER) { - TOD_ASSERT(iv_procTarget, "Target input i_procTarget is NULL "); - TOD_ASSERT(iv_parentDrawer, "TOD drawer input iv_parentDrawer is NULL "); + TOD_ENTER(); + + do + { + if(!iv_procTarget) + { + TOD_ERR_ASSERT("Target input i_procTarget is NULL "); + break; + } + if(!iv_parentDrawer) + { + TOD_ERR_ASSERT("TOD drawer input iv_parentDrawer is NULL "); + break; + } TOD_ENTER("Created proc 0x%.8X on drawer 0x%.2X", - iv_procTarget->getAttr(), - iv_parentDrawer->getId()); + iv_procTarget->getAttr(), + iv_parentDrawer->getId()); init(); + } while (0); TOD_EXIT("TodProc constructor"); } @@ -84,6 +108,7 @@ TodProc::~TodProc() delete iv_tod_node_data; iv_tod_node_data = NULL; } + iv_xbusTargetList.clear(); iv_abusTargetList.clear(); @@ -108,8 +133,12 @@ void TodProc::setMasterType(const ProcMasterType i_masterType) iv_masterType = i_masterType; iv_tod_node_data->i_drawer_master = true; + TOD_IMP("Proc 0X%.8X is the drawer master for TOD drawer 0x%.2X", + GETHUID(iv_procTarget), iv_parentDrawer->getId()); if(TOD_MASTER == i_masterType) { + TOD_IMP("Proc 0X%.8X is a TOD master", + GETHUID(iv_procTarget)); iv_tod_node_data->i_tod_master = true; } @@ -133,10 +162,9 @@ void TodProc::init() } iv_tod_node_data = new tod_topology_node(); //Initialize the iv_tod_node_data structure - iv_tod_node_data->i_target = new fapi::Target; - iv_tod_node_data->i_target->setType(fapi::TARGET_TYPE_PROC_CHIP); - iv_tod_node_data->i_target->set - (reinterpret_cast(const_cast(iv_procTarget))); + iv_tod_node_data->i_target = new + fapi2::Target + (const_cast(iv_procTarget)); iv_tod_node_data->i_tod_master = false; iv_tod_node_data->i_drawer_master = false; iv_tod_node_data->i_bus_rx = NONE; @@ -257,93 +285,116 @@ errlHndl_t TodProc::connect( //Step 3: If a match is found then fill the i_bus_tx and i_bus_rx //attributes for the destination proc and return - const TARGETING::Target * l_proc = NULL; + //Predicates tp look for a functional proc who's HUID is same as + //that of i_destination. This predicate will be applied as a result + //filter to getPeerTargets to determine the connected proc. + TARGETING::PredicateCTM + l_procFilter(TARGETING::CLASS_CHIP,TARGETING::TYPE_PROC); + TARGETING::PredicateIsFunctional l_funcFilter; + TARGETING::PredicateAttrVal + l_huidFilter( + i_destination->getTarget()->getAttr()); + TARGETING::PredicatePostfixExpr l_resFilter; + l_resFilter. + push(&l_procFilter). + push(&l_funcFilter). + And(). + push(&l_huidFilter). + And(); + + TARGETING::TargetHandleList l_procList; TARGETING::TargetHandleList l_busList; TARGETING::TargetHandleList::iterator l_busIter = (*l_pBusList).begin(); for(;l_busIter != (*l_pBusList).end() ; ++l_busIter) { + l_procList.clear(); l_busList.clear(); - //Get the peer target for this bus connection - //I need to know the peer's (bus endpoint) attributes such as - //HUID, chip unit. Applying a result filter will get me the proc - //on the other end, but will abstract away the bus, which is not - //what I want. - getPeerTargets( + //Need this call without result filter to get a handle to the + //peer (bus). I need to access its HUID and chip unit. + TARGETING::getPeerTargets( l_busList, - *l_busIter, + *l_busIter, NULL, NULL); - //There should be only 1 peer - if(1 == l_busList.size()) - { - l_proc = getParentChip(l_busList[0]); + //The call below is to determine the connected proc + TARGETING::getPeerTargets( + l_procList, + *l_busIter, + NULL, + //result filter to get the connected proc + &l_resFilter); - if((l_proc) && - l_proc->getAttr().functional && - (l_proc->getAttr() == - i_destination->iv_procTarget-> - getAttr())) + if(l_procList.size()) + { + if(l_busList.empty()) { - //We found a connection : - //iv_procTarget --- i_busChipUnitType --- i_destination - TOD_INF("Source processor 0x%.8X connects with the " - "destination processor 0x%.8X over " - "source bus 0x%.8X and destination bus 0x%.8X " - "via bus type 0x%.8X", - iv_procTarget->getAttr(), - i_destination->iv_procTarget-> - getAttr(), + //This is unlikely, since the proc list is not empty, + //we should have also found a bus, but just a safety check. + TOD_ERR_ASSERT(0, + "Couldn't find a peer for bus 0x%.8X on proc 0x%.8X", (*l_busIter)->getAttr(), - l_busList[0]->getAttr(), - i_busChipUnitType); - - //Determine the bus type as per our format, for eg XBUS0 - //ATTR_CHIP_UNIT gives the instance number of - //the bus and it has direct correspondance to - //the port no. - //For instance a processor has two A buses - //then the one with ATTR_CHIP_UNIT 0 will be A0 - //and the one with ATTR_CHIP_UNIT 1 will be A1 - proc_tod_setup_bus l_busOut = NONE; - proc_tod_setup_bus l_busIn = NONE; + iv_procTarget->getAttr()); + break; + } + //We found a connection : + //iv_procTarget --- i_busChipUnitType --- i_destination + TOD_INF("Source processor 0x%.8X connects with the " + "destination processor 0x%.8X over " + "source bus 0x%.8X and destination bus 0x%.8X " + "via bus type 0x%.8X", + iv_procTarget->getAttr(), + i_destination->iv_procTarget-> + getAttr(), + (*l_busIter)->getAttr(), + l_busList[0]->getAttr(), + i_busChipUnitType); + + //Determine the bus type as per our format, for eg XBUS0 + //ATTR_CHIP_UNIT gives the instance number of + //the bus and it has direct correspondance to + //the port no. + //For instance a processor has two A buses + //then the one with ATTR_CHIP_UNIT 0 will be A0 + //and the one with ATTR_CHIP_UNIT 1 will be A1 + p9_tod_setup_bus l_busOut = NONE; + p9_tod_setup_bus l_busIn = NONE; + l_errHndl = getBusPort(i_busChipUnitType, + (*l_busIter)-> + getAttr(), + l_busOut); + if(NULL == l_errHndl) + { l_errHndl = getBusPort(i_busChipUnitType, - (*l_busIter)-> - getAttr(), - l_busOut); - if(NULL == l_errHndl) - { - l_errHndl = getBusPort(i_busChipUnitType, - l_busList[0]-> - getAttr(), - l_busIn); - } - if(l_errHndl) - { - //Should not be hitting this path if HW procedure is - //correctly defining all the bus types and ports - TOD_ERR("proc_tod_setup_bus type not found for " - "port 0x%.2X of bus type 0x%.8X. Source processor " - "0x%.8X, destination processor 0x%.8X", - (*l_busIter)-> - getAttr(), - i_busChipUnitType, - iv_procTarget-> - getAttr(), - i_destination->iv_procTarget-> - getAttr()); - break; - } - - //Set the bus connections for i_destination : - //Bus out from this proc = l_busOut; - //Bus in to destination = l_busIn; - i_destination->setConnections(l_busOut, l_busIn); - o_isConnected = true; + l_busList[0]-> + getAttr(), + l_busIn); + } + else + { + //Should not be hitting this path if HW procedure is + //correctly defining all the bus types and ports + TOD_ERR("p9_tod_setup_bus type not found for " + "port 0x%.2X of bus type 0x%.8X. Source processor " + "0x%.8X, destination processor 0x%.8X", + (*l_busIter)-> + getAttr(), + i_busChipUnitType, + iv_procTarget-> + getAttr(), + i_destination->iv_procTarget-> + getAttr()); break; } + + //Set the bus connections for i_destination : + //Bus out from this proc = l_busOut; + //Bus in to destination = l_busIn; + i_destination->setConnections(l_busOut, l_busIn); + o_isConnected = true; + break; } } if(l_errHndl) @@ -363,7 +414,7 @@ errlHndl_t TodProc::connect( errlHndl_t TodProc::getBusPort( const TARGETING::TYPE i_busChipUnitType, const uint32_t i_busPort, - proc_tod_setup_bus& o_busPort) const + p9_tod_setup_bus& o_busPort) const { TOD_ENTER("getBusPort"); @@ -382,8 +433,8 @@ errlHndl_t TodProc::getBusPort( case 2: o_busPort = XBUS2; break; - case 3: - o_busPort = XBUS3; + case 7: + o_busPort = XBUS7; break; default: TOD_ERR("Port 0x%.8X not supported for X bus", @@ -398,15 +449,6 @@ errlHndl_t TodProc::getBusPort( { switch(i_busPort) { - case 0: - o_busPort = ABUS0; - break; - case 1: - o_busPort = ABUS1; - break; - case 2: - o_busPort = ABUS2; - break; default: TOD_ERR("Port 0x%.8X not supported for A bus", i_busPort); @@ -427,7 +469,6 @@ errlHndl_t TodProc::getBusPort( return l_errHndl; } - //****************************************************************************** //TodProc::logUnsupportedBusType //****************************************************************************** @@ -444,12 +485,13 @@ void TodProc::logUnsupportedBusType(const int32_t i_busChipUnitType, * getBusPort method has not been updated to support all the * bus type on a given system. * Resolution:Development team should be contacted. + * @custdesc Service Processor Firmware encountered an internal error */ - io_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - TOD_LOG_UNSUPPORTED_BUSTYPE, - TOD_UNSUPPORTED_BUSTYPE, - i_busChipUnitType, 0); + io_errHdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_MOD_LOG_UNSUPPORTED_BUSTYPE, + TOD_UNSUPPORTED_BUSTYPE, + i_busChipUnitType); } //****************************************************************************** @@ -462,8 +504,8 @@ void TodProc::logUnsupportedBusPort( { /*@ * @errortype - * @reasoncode TOD_UNSUPPORTED_BUSPORT * @moduleid TOD_LOG_UNSUPPORTED_BUSPORT + * @reasoncode TOD_UNSUPPORTED_BUSPORT * @userdata1 Bus port that is not currently supported * @userdata2 Bus Type for which the unsupported port has been reported * @devdesc Error: Unsupported bus port was detected for the specified @@ -472,12 +514,14 @@ void TodProc::logUnsupportedBusPort( * getBusPort method has not been updated to support all the * possible port for a bus on a given system type. * Resolution:Development team should be contacted. + * @custdescoff Service Processor Firmware encountered an internal error */ - io_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - TOD_LOG_UNSUPPORTED_BUSPORT, - TOD_UNSUPPORTED_BUSPORT, - i_busPort, i_busChipUnitType); + io_errHdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_MOD_LOG_UNSUPPORTED_BUSTYPE, + TOD_UNSUPPORTED_BUSPORT, + i_busPort, + i_busChipUnitType); } //****************************************************************************** @@ -500,7 +544,7 @@ void TodProc::addChild(TodProc* i_child) //****************************************************************************** // TodProc::getTodRegs //****************************************************************************** -void TodProc::getTodRegs(proc_tod_setup_conf_regs& o_todRegs) const +void TodProc::getTodRegs(p9_tod_setup_conf_regs& o_todRegs) const { o_todRegs.tod_m_path_ctrl_reg = iv_tod_node_data->o_todRegs.tod_m_path_ctrl_reg; @@ -527,22 +571,43 @@ void TodProc::getTodRegs(proc_tod_setup_conf_regs& o_todRegs) const //****************************************************************************** void TodProc::setTodChipData(TodChipData& o_todChipData) const { - proc_tod_setup_conf_regs& l_todRegs = iv_tod_node_data->o_todRegs; + p9_tod_setup_conf_regs& l_todRegs = iv_tod_node_data->o_todRegs; o_todChipData.header.chipID = iv_procTarget-> - getAttr(); + getAttr(); o_todChipData.header.flags |= TOD_FUNC; - o_todChipData.regs.mpcr = l_todRegs.tod_m_path_ctrl_reg.getWord(0); - o_todChipData.regs.pcrp0 = l_todRegs.tod_pri_port_0_ctrl_reg.getWord(0); - o_todChipData.regs.pcrp1 = l_todRegs.tod_pri_port_1_ctrl_reg.getWord(0); - o_todChipData.regs.scrp0 = l_todRegs.tod_sec_port_0_ctrl_reg.getWord(0); - o_todChipData.regs.scrp1 = l_todRegs.tod_sec_port_1_ctrl_reg.getWord(0); - o_todChipData.regs.spcr = l_todRegs.tod_s_path_ctrl_reg.getWord(0); - o_todChipData.regs.ipcr = l_todRegs.tod_i_path_ctrl_reg.getWord(0); - o_todChipData.regs.psmscr = l_todRegs.tod_pss_mss_ctrl_reg.getWord(0); - o_todChipData.regs.ccr = l_todRegs.tod_chip_ctrl_reg.getWord(0); + fapi2::variable_buffer l_regData((uint32_t)64); + + l_regData.set(l_todRegs.tod_m_path_ctrl_reg(), 0); + o_todChipData.regs.mpcr = l_regData.get(0); + + l_regData.set(l_todRegs.tod_pri_port_0_ctrl_reg(), 0); + o_todChipData.regs.pcrp0 = l_regData.get(0); + + l_regData.set(l_todRegs.tod_pri_port_1_ctrl_reg(), 0); + o_todChipData.regs.pcrp1 = l_regData.get(0); + + l_regData.set(l_todRegs.tod_sec_port_0_ctrl_reg(), 0); + o_todChipData.regs.scrp0 = l_regData.get(0); + + l_regData.set(l_todRegs.tod_sec_port_1_ctrl_reg(), 0); + o_todChipData.regs.scrp1 = l_regData.get(0); + + l_regData.set(l_todRegs.tod_s_path_ctrl_reg(), 0); + o_todChipData.regs.spcr = l_regData.get(0); + + l_regData.set(l_todRegs.tod_i_path_ctrl_reg(), 0); + o_todChipData.regs.ipcr = l_regData.get(0); + + l_regData.set(l_todRegs.tod_pss_mss_ctrl_reg(), 0); + o_todChipData.regs.psmscr = l_regData.get(0); + + l_regData.set(l_todRegs.tod_chip_ctrl_reg(), 0); + o_todChipData.regs.ccr = l_regData.get(0); } -} //end of namespace +}//end of namespace + +} diff --git a/src/usr/isteps/istep18/TodProc.H b/src/usr/isteps/istep18/TodProc.H index b020378f2df..39af8601b38 100755 --- a/src/usr/isteps/istep18/TodProc.H +++ b/src/usr/isteps/istep18/TodProc.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -29,382 +29,387 @@ * @file TodProc.H * * @brief Contains TodProc class declaration - * TodProc class encapsulates a proc chip target with other attributes - * that are necessary to define the proc chip in a TOD topology - * - * HWP_IGNORE_VERSION_CHECK - * + * TodProc class encapsulates a proc chip target with other attributes + * that are necessary to define the proc chip in a TOD topology */ -#include "proc_tod_utils.H" +//------------------------------------------------------------------------------ +//Includes +//------------------------------------------------------------------------------ +//HWPF - For TOD constants +#include #include "TodTypes.H" #include "TodSvcUtil.H" +#include "TodAssert.H" namespace TOD { -//------------------------------------------------------------------------------ +//-------------------------------------------------------------------------- //Forward declarations -//------------------------------------------------------------------------------ +//-------------------------------------------------------------------------- struct TodChipData; class TodDrawer; class TodProc; -//------------------------------------------------------------------------------ +//-------------------------------------------------------------------------- //Typedefs -//------------------------------------------------------------------------------ +//-------------------------------------------------------------------------- typedef std::list TodProcContainer; typedef std::list TodTopologyNodeContainer; - /** * @class TodProc * - * @brief TodProc class encapsulates a proc chip target with other - * attributes that helps to identify the position of proc chip in a - * TOD netwok and also define its connection with other proc chips + * @brief TodProc class encapsulates a proc chip target with other + * attributes that helps to identify the position of proc chip in a + * TOD netwok and also define its connection with other proc chips */ class TodProc { -public: - //Specify proc master type : - //TOD master/drawer master - enum ProcMasterType - { - NOT_MASTER = 0x00, - TOD_MASTER = 0x01, - DRAWER_MASTER = 0x02 - }; - - /** - * @brief Constructor - * - * @param[in] i_procTarget - * Pointer to proc target - * - * @param[in] i_parentDrawer - * Pointer to TOD drawer in which this proc is contained - */ - TodProc(const TARGETING::Target* i_procTarget, - const TodDrawer* i_parentDrawer); - - /** - * @brief Destructor - */ - ~TodProc(); - - /** - * @brief The method will try to connect TodProc object, for which the - * method has been called to the TodProc object specificed in - * destination argument. - * - * @par Detailed Description: - * While creating the TOD topology TodTopologyManager will connect - * TodProc objects to the topology if they - * physically connect over A/X bus, to a TodProc object - * that is already part of the topology and also valid candidate for - * connecting the TodProc object under consideration. - * - * The process of connecting processors starts with MDMT and will - * continue till all the processors are connected. - * At each step TodTopologyManager will make call to connect - * method. This method will check if processor chip owned by - * TodProc object (for which the method is called ) is physically - * connected to the destination (passed as argument), over the bus type - * specified in argument to the method. - * - * If they connect then the i_bus_rx and i_bus_tx members of - * iv_tod_node_data will be filled up for the destination object - * such that - * i_bus_rx == The bus on destination object that connects to the - * this proc - * i_bus_tx == The bus on this proc that connects to the - * destination - * - * @param[in] i_destination, Pointer to destination TodProc object - * that has to be connected. - * - * @param[in] i_busChipUnitType, Type of the bus (A/X) for which connection - * has to be determined - * - * @param[out] o_isConnected, this parameter will be set to true if - * source and destination connect over the specified bus type. Before - * looking for o_isConnected the caller should check for returned error - * log handle and only if it is NULL o_isConnected should be considered. - * - * @return Error log handle, indicates status of request - * @retval NULL indicates that connect method's algorithm executed - * successfully, however in order to know if two processor objects - * connect over the specified bus or not o_isConnected has to be - * examined. - * @retval !NULL indicates that method connect could not be completed - * successfully. In this case o_isConnected should be ignored. - * - * Error log handle points to a valid error log object whose primary - * SRC reason code (pError->getSRC()->reasonCode()) indicates the type - * of error. - * - * @note It is up to the caller to change the severity of the - * returned error based on what it decides to do with it. By default - * any returned error created by this function will be a non-reported - * tracing event error log. - */ - errlHndl_t connect( - TodProc* i_destination, - const TARGETING::TYPE i_busChipUnitType, - bool& o_isConnected); - - /** - * @brief This is a helper method for connect, that will pick a value - * from proc_tod_setup_bus enum corresponding to the bus type and - * the port specified as argument - * - * @param[in] i_busChipUnitType , This will indicate A/X bus type - * - * @param[in] i_busPort , The port of the bus - * - * @param[out] o_busId , proc_tod_setup_bus enum member corresponding to - * the bus type and bus port specified as parameter. Before looking for - * o_busId caller should look for returned error handle and only if it - * is NULL, o_busId should be considered. - * - * @return Error log handle, indicates status of request - * @retval NULL, indicates o_busId was successfully found - * @retval !NULL, indicates that o_busId could not be found possibly - * because specified bus type and port combination is not supported - * - * Error log handle points to a valid error log object whose primary - * SRC reason code (pError->getSRC()->reasonCode()) indicates the type - * of error. - * - * @note It is up to the caller to change the severity of the - * returned error based on what it decides to do with it. By default - * any returned error created by this function will be a non-reported - * tracing event error log. - */ - errlHndl_t getBusPort( - const TARGETING::TYPE i_busChipUnitType, - const uint32_t i_busPort, - proc_tod_setup_bus& o_busId) const; - - /** - * @brief Method to create an errlHndl_t object for - * TOD_UNSUPPORTED_BUSTYPE - * - * @par Detailed Description: - * This error will be logged by a method if it finds that a particular - * bus type is not supported on TOD topology. - * - * @param[in] i_busChipUnitType, Type of bus that is not supported - * - * @param[out] io_errHdl - * On input this parameter will be either NULL or pointing to - * an existing error handle. - * On output this parameter will either have a newly created handle - * assigned to it ( If input parameter was NULL ) or a new SRC will be - * appened to existing error handle ( If the input was not NULL ) - * - * @return N/A - */ - void logUnsupportedBusType(const int32_t i_busChipUnitType, - errlHndl_t& io_errHdl) const; - - /** - * @brief Method to create an errlHndl_t object for - * TOD_UNSUPPORTED_BUSPORT - * - * @par Detailed Description: - * This error will be logged by getBusPort if it finds that the input - * bus port is not supported for a specified bus type, from - * TOD topology point of view. - * - * @param[in] i_busPort , Type of bus that is not currently supported. - * - * @param[out] io_errHdl - * On input this parameter will be either NULL or pointing to - * an existing error handle. - * On output this parameter will either have a newly created handle - * assigned to it ( If input parameter was NULL ) or a new SRC will be - * appened to existing error handle ( If the input was not NULL ) - * - * @return N/A - */ - void logUnsupportedBusPort( + public: + + //Specify proc master type : + //TOD master/drawer master + enum ProcMasterType + { + NOT_MASTER = 0x00, + TOD_MASTER = 0x01, + DRAWER_MASTER = 0x02 + }; + + /** + * @brief Constructor + * + * @param[in] i_procTarget + * Pointer to proc target + * + * @param[in] i_parentDrawer + * Pointer to TOD drawer in which this proc is contained + */ + TodProc(const TARGETING::Target* i_procTarget, + const TodDrawer* i_parentDrawer); + + /** + * @brief Destructor + */ + ~TodProc(); + + /** + * @brief The method will try to connect TodProc object, for which + * the method has been called to the TodProc object specified + * in destination argument. + * + * @par Detailed Description: + * While creating the TOD topology TodTopologyManager will connect + * TodProc objects to the topology if they + * physically connect over A/X bus, to a TodProc object + * that is already part of the topology and also valid candidate for + * connecting the TodProc object under consideration. + * + * The process of connecting processors starts with MDMT and will + * continue till all the processors are connected. + * At each step TodTopologyManager will make call to connect + * method. This method will check if processor chip owned by + * TodProc object (for which the method is called ) is physically + * connected to the destination (passed as argument), over the bus type + * specified in argument to the method. + * + * If they connect then the i_bus_rx and i_bus_tx members of + * iv_tod_node_data will be filled up for the destination object + * such that + * i_bus_rx == The bus on destination object that connects to the + * this proc + * i_bus_tx == The bus on this proc that connects to the + * destination + * + * @param[in] i_destination, Pointer to destination TodProc object + * that has to be connected. + * + * @param[in] i_busChipUnitType, Type of the bus (A/X) for which connection + * has to be determined + * + * @param[out] o_isConnected, this parameter will be set to true if + * source and destination connect over the specified bus type. Before + * looking for o_isConnected the caller should check for returned error + * log handle and only if it is NULL o_isConnected should be considered. + * + * @return Error log handle, indicates status of request + * @retval NULL indicates that connect method's algorithm executed + * successfully, however in order to know if two processor objects + * connect over the specified bus or not o_isConnected has to be + * examined. + * @retval !NULL indicates that method connect could not be completed + * successfully. In this case o_isConnected should be ignored. + * + * Error log handle points to a valid error log object whose primary + * SRC reason code (pError->getSRC()->reasonCode()) indicates the type + * of error. + * + * @note It is up to the caller to change the severity of the + * returned error based on what it decides to do with it. By default + * any returned error created by this function will be a non-reported + * tracing event error log. + */ + errlHndl_t connect( + TodProc* i_destination, + const TARGETING::TYPE i_busChipUnitType, + bool& o_isConnected); + + /** + * @brief This is a helper method for connect, that will pick a value + * from p9_tod_setup_bus enum corresponding to the bus type and + * the port specified as argument + * + * @param[in] i_busChipUnitType , This will indicate A/X bus type + * + * @param[in] i_busPort , The port of the bus + * + * @param[out] o_busId , p9_tod_setup_bus enum member corresponding to + * the bus type and bus port specified as parameter. Before looking for + * o_busId caller should look for returned error handle and only if it + * is NULL, o_busId should be considered. + * + * @return Error log handle, indicates status of request + * @retval NULL, indicates o_busId was successfully found + * @retval !NULL, indicates that o_busId could not be found possibly + * because specified bus type and port combination is not supported + * + * Error log handle points to a valid error log object whose primary + * SRC reason code (pError->getSRC()->reasonCode()) indicates the type + * of error. + * + * @note It is up to the caller to change the severity of the + * returned error based on what it decides to do with it. By default + * any returned error created by this function will be a non-reported + * tracing event error log. + */ + errlHndl_t getBusPort( + const TARGETING::TYPE i_busChipUnitType, + const uint32_t i_busPort, + p9_tod_setup_bus& o_busId) const; + + /** + * @brief Method to create an errlHndl_t object for + * UNSUPPORTED_BUSTYPE + * + * @par Detailed Description: + * This error will be logged by a method if it finds that a particular + * bus type is not supported on TOD topology. + * + * @param[in] i_busChipUnitType, Type of bus that is not supported + * + * @param[out] io_errHdl + * On input this parameter will be either NULL or pointing to + * an existing error handle. + * On output this parameter will either have a newly created handle + * assigned to it ( If input parameter was NULL ) or a new SRC will be + * appened to existing error handle ( If the input was not NULL ) + * + * @return N/A + */ + void logUnsupportedBusType(const int32_t i_busChipUnitType, + errlHndl_t& io_errHdl) const; + + /** + * @brief Method to create an errlHndl_t object for + * UNSUPPORTED_BUSPORT + * + * @par Detailed Description: + * This error will be logged by getBusPort if it finds that the input + * bus port is not supported for a specified bus type, from + * TOD topology point of view. + * + * @param[in] i_busPort , Type of bus that is not currently supported. + * + * @param[out] io_errHdl + * On input this parameter will be either NULL or pointing to + * an existing error handle. + * On output this parameter will either have a newly created handle + * assigned to it ( If input parameter was NULL ) or a new SRC will be + * appened to existing error handle ( If the input was not NULL ) + * + * @return N/A + */ + void logUnsupportedBusPort( const int32_t i_busPort, const int32_t i_busChipUnitType, errlHndl_t& io_errHdl) const; - /** - * @brief Add a child TodProc to this (adds to iv_childrenList). - * Added child will receive TOD signal from the processor - * represented by this TodProc object. - * - * @param[in] i_child - * Pointer to child TodProc - * - * @return N/A - */ - void addChild(TodProc* i_child); - - /** - * @brief Setter method for iv_masterType - * - * @param[in] i_masterType - * Parameter to indicate the master type - * - * @return N/A - */ - void setMasterType(const ProcMasterType i_masterType); - - /** - * @brief Getter method for iv_masterType - * - * @return ProcMasterType, value of iv_masterType - */ - ProcMasterType getMasterType() const ; - - /** - * @brief Getter for TOD registers for this proc - * Check proc_tod_utils.H : proc_tod_setup_conf_regs for the list of - * registers. The registers are updated by the TOD HWP. - * - * @param[out] o_todRegs - * container of TOD registers - * - * @return N/A - */ - void getTodRegs(proc_tod_setup_conf_regs& o_todRegs) const; - - /** - * @brief This method will populate the TodChipData object passed as - * input with the TOD register values of the this proc. - * - * @param[out] o_todChipData - * The TodChipData object in which data has to be output - * - * @return NA - * - */ - void setTodChipData(TodChipData& o_todChipData) const; - - /** - * @brief Getter method for iv_tod_node_data - * - * @return tod_topology_node*, pointer to this proc's topology - * node structure - */ - tod_topology_node* getTopologyNode() - { - return iv_tod_node_data; - } - - /** - * @brief Getter method for iv_parentDrawer - * - * @return TodDrawer*, pointer to this proc's containing TOD drawer - */ - const TodDrawer* getParentDrawer() const - { - return iv_parentDrawer; - } - - /** - * @brief Getter method for tod_topology_node::i_bus_rx data member , - * i_bus_rx is the fabric bus over which current processor receives - * signals from its parent - * - * @return proc_tod_setup_bus bus type and port - */ - proc_tod_setup_bus getBusIn() const - { - return iv_tod_node_data->i_bus_rx; - } - - /** - * @brief Getter method for tod_topology_node::i_bus_tx data member , - * i_bus_tx is the bus over which signal is transmitted by the - * parent of this processor - * - * @return proc_tod_setup_bus bus type and port - */ - proc_tod_setup_bus getBusOut() const - { - return iv_tod_node_data->i_bus_tx; - } - - /** - * @brief Getter method for iv_procTarget - * - * @return Target pointer for this proc - */ - const TARGETING::Target* getTarget() const - { - return iv_procTarget; - } - - /** - * @brief Getter method for iv_childrenList. - * see also addChild - * - * @param[out] o_childrenList - * List of pointers to children TodProc - * - * @return N/A - */ - void getChildren(TodProcContainer& o_childrenList) const - { - o_childrenList = iv_childrenList; - } - - /** - * @brief Sets bus in and bus out - * - * @return N/A - */ - void setConnections(const proc_tod_setup_bus i_parentBusOut, - const proc_tod_setup_bus i_thisBusIn) - { - iv_tod_node_data->i_bus_tx = i_parentBusOut; - iv_tod_node_data->i_bus_rx = i_thisBusIn; - } - -private: - /* - * @brief Helper method to initialize the bus parameters - * (iv_xbusTargetList and iv_abusTargetList) and iv_tod_node_data, for - * this object. - * It will be called from the constructor. - * - * @return N/A - */ - void init(); - - //Target pointer to the processor chip, that is been encapsulated in - //the TodProc object - const TARGETING::Target* iv_procTarget; - - //Pointer to the parent TodDrawer object to which this processor - //belong - const TodDrawer * iv_parentDrawer; - - //List of X bus targets for this processor - TARGETING::TargetHandleList iv_xbusTargetList; - - //List of A bus targets for this processor - TARGETING::TargetHandleList iv_abusTargetList; - - //List of children that will receive TOD signal from this processor belongs - TodProcContainer iv_childrenList; - - //Pointer to the tod_topology_node object that defines TOD specific - //attributes for this processor chip, the reason this has been kept - //seperate is this data structure is shared across HB and HW procedure - tod_topology_node* iv_tod_node_data; - - //Data member to indicate if this processor is either a TOD_MASTER or - //DRAWER_MASTER - ProcMasterType iv_masterType; + /** + * @brief Add a child TodProc to this (adds to iv_childrenList). + * Added child will receive TOD signal from the processor + * represented by this TodProc object. + * + * @param[in] i_child + * Pointer to child TodProc + * + * @return N/A + */ + void addChild(TodProc* i_child); + + /** + * @brief Setter method for iv_masterType + * + * @param[in] i_masterType + * Parameter to indicate the master type + * + * @return N/A + */ + void setMasterType(const ProcMasterType i_masterType); + + /** + * @brief Getter method for iv_masterType + * + * @return ProcMasterType, value of iv_masterType + */ + ProcMasterType getMasterType() const ; + + /** + * @brief Getter for TOD registers for this proc + * Check proc_tod_utils.H : p9_tod_setup_conf_regs for the list of + * registers. The registers are updated by the TOD HWP. + * + * @param[out] o_todRegs + * container of TOD registers + * + * @return N/A + */ + void getTodRegs(p9_tod_setup_conf_regs& o_todRegs) const; + + /** + * @brief This method will populate the TodChipData object passed as + * input with the TOD register values of the this proc. + * + * @param[out] o_todChipData + * The TodChipData object in which data has to be output + * + * @return NA + * + */ + void setTodChipData(TodChipData& o_todChipData) const; + + + /** + * @brief Getter method for iv_tod_node_data + * + * @return tod_topology_node*, pointer to this proc's topology + * node structure + */ + tod_topology_node* getTopologyNode() + { + return iv_tod_node_data; + } + + /** + * @brief Getter method for iv_parentDrawer + * + * @return TodDrawer*, pointer to this proc's containing TOD drawer + */ + const TodDrawer* getParentDrawer() const + { + return iv_parentDrawer; + } + + /** + * @brief Getter method for tod_topology_node::i_bus_rx data member , + * i_bus_rx is the fabric bus over which current processor receives + * signals from its parent + * + * @return p9_tod_setup_bus bus type and port + */ + p9_tod_setup_bus getBusIn() const + { + return iv_tod_node_data->i_bus_rx; + } + + /** + * @brief Getter method for tod_topology_node::i_bus_tx data member , + * i_bus_tx is the bus over which signal is transmitted by the + * parent of this processor + * + * @return p9_tod_setup_bus bus type and port + */ + p9_tod_setup_bus getBusOut() const + { + return iv_tod_node_data->i_bus_tx; + } + + /** + * @brief Getter method for iv_procTarget + * + * @return Target pointer for this proc + */ + const TARGETING::Target* getTarget() const + { + return iv_procTarget; + } + + /** + * @brief Getter method for iv_childrenList. + * see also addChild + * + * @param[out] o_childrenList + * List of pointers to children TodProc + * + * @return N/A + */ + void getChildren(TodProcContainer& o_childrenList) const + { + o_childrenList = iv_childrenList; + } + + /** + * @brief Sets bus in and bus out + * + * @return N/A + */ + void setConnections(const p9_tod_setup_bus i_parentBusOut, + const p9_tod_setup_bus i_thisBusIn) + { + iv_tod_node_data->i_bus_tx = i_parentBusOut; + iv_tod_node_data->i_bus_rx = i_thisBusIn; + } + + private: + /* + * @brief Helper method to initialize the bus parameters + * iv_xbusTargetList and iv_abusTargetList) and iv_tod_node_data, + * for this object. + * It will be called from the constructor. + * + * @return N/A + */ + void init(); + + //Target pointer to the processor chip, that is been encapsulated in + //the TodProc object + const TARGETING::Target* iv_procTarget; + + //Pointer to the parent TodDrawer object to which this processor + //belong + const TodDrawer * iv_parentDrawer; + + //List of X bus targets for this processor + TARGETING::TargetHandleList iv_xbusTargetList; + + //List of A bus targets for this processor + TARGETING::TargetHandleList iv_abusTargetList; + + //List of children that will receive TOD signal from this processor + //belongs + TodProcContainer iv_childrenList; + + //Pointer to the tod_topology_node object that defines TOD specific + //attributes for this processor chip, the reason this has been kept + //seperate is this data structure is shared across HW procedure + tod_topology_node* iv_tod_node_data; + + //Data member to indicate if this processor is either a TOD_MASTER or + //DRAWER_MASTER + ProcMasterType iv_masterType; + }; }//end of namespace -#endif // TODPROC_H +#endif //TODPROC_H diff --git a/src/usr/isteps/istep18/TodSvc.C b/src/usr/isteps/istep18/TodSvc.C index f52cc99ddff..dcd8a5eb28d 100755 --- a/src/usr/isteps/istep18/TodSvc.C +++ b/src/usr/isteps/istep18/TodSvc.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -22,27 +22,35 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ - /** * @file TodSvc.C * * @brief Implements the TodSvc class that provides the Time Of Day service - * - * HWP_IGNORE_VERSION_CHECK - * */ -#include + +//------------------------------------------------------------------------------ +//Includes +//------------------------------------------------------------------------------ +//Service Processor components outside +//#include #include #include -#include +#include "TodSvc.H" +#include "TodControls.H" +#include "TodProc.H" #include "TodTopologyManager.H" #include "TodTrace.H" -#include "TodSvcUtil.H" + #include "TodHwpIntf.H" -#include "TodControls.H" -#include "TodSvc.H" -#include "proc_tod_utils.H" +#include "TodSvcUtil.H" + +#include +#include +#include "TodUtils.H" + +//HWP +#include namespace TOD { @@ -57,53 +65,78 @@ TodSvc & TodSvc::getTheInstance() //****************************************************************************** errlHndl_t TodSvc::todSetup() { - TOD_ENTER("todSetup"); + TOD_ENTER("TodSvc::todSetup"); errlHndl_t l_errHdl = NULL; bool l_isTodRunning = false; TodTopologyManager l_primary(TOD_PRIMARY); - TodControls & l_Tod = TodControls::getTheInstance(); do { - l_errHdl = l_Tod.isTodRunning(l_isTodRunning); - if ( l_errHdl ) + bool l_inMPIPLPath = false; + l_errHdl = isMPIPL(l_inMPIPLPath); + if (l_errHdl) { - TOD_INF("Call to isTodRunning failed , cannot create topology"); + TOD_ERR("Failed to check if in MPIPL path or not"); break; } - - if ( l_isTodRunning ) + if (false == l_inMPIPLPath) { - TOD_ERR("Cannot create TOD topology while the Chip TOD logic" - "is running "); - /*@ - * @errortype - * @reasoncode TOD_INVALID_ACTION - * @moduleid TOD_SETUP - * @userdata1 ChipTOD logic HW state , 1=running , zero otherwise - * @devdesc Error: can not create TOD topology when TOD - * HW is running - */ - l_errHdl = new ERRORLOG::ErrlEntry( + l_errHdl = + TOD::isTodRunning(l_isTodRunning); + if ( l_errHdl ) + { + TOD_INF("Call to isTodRunning failed, cannot create topology"); + break; + } + + if ( l_isTodRunning ) + { + TOD_ERR("Cannot create TOD topology while the Chip TOD logic" + "is running "); + /*@ + * @errortype + * @moduleid TOD_SETUP + * @reasoncode TOD_INVALID_ACTION + * @userdata1 ChipTOD logic HW state, 1=running, + * zero otherwise + * @devdesc Error: Creation of TOD topology required when + * TOD HW is running + * @custdesc Host failed to boot because there was a problem + * configuring Time Of Day on the Host processors + */ + l_errHdl = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_INFORMATIONAL, TOD_SETUP, TOD_INVALID_ACTION, - l_isTodRunning ? 1 : 0, 0); + l_isTodRunning); + + break; + + } + } + + TOD::destroy(TOD_PRIMARY); + TOD::destroy(TOD_SECONDARY); + + //Build the list of garded TOD targets + l_errHdl = TOD::buildGardedTargetsList(); + if ( l_errHdl ) + { + TOD_ERR("Call to buildGardedTargetsList failed"); break; } - l_Tod.destroy(TOD_PRIMARY); - l_Tod.destroy(TOD_SECONDARY); + //Build a set of datastructures to setup creation of the TOD topology //We're going to setup TOD for this IPL //1) Build a set of datastructures to setup creation of the TOD //topologies. - l_errHdl = l_Tod.buildTodDrawers(TOD_PRIMARY); + l_errHdl = TOD::buildTodDrawers(TOD_PRIMARY); if(l_errHdl) { TOD_ERR("TOD setup failure: failed to build TOD drawers " - "for primary topology."); + "for primary topology."); break; } @@ -118,12 +151,14 @@ errlHndl_t TodSvc::todSetup() //3) Call hardware procedures to configure the TOD hardware logic for //the primary topology and to fill up the TOD regs. + l_errHdl = todSetupHwp(TOD_PRIMARY); if(l_errHdl) { TOD_ERR("TOD setup failure: primary topology setup HWP."); break; } + l_errHdl = todSaveRegsHwp(TOD_PRIMARY); if(l_errHdl) { @@ -132,17 +167,16 @@ errlHndl_t TodSvc::todSetup() } //Primary successfully configured - l_Tod.setConfigStatus(TOD_PRIMARY,true); + TOD::setConfigStatus(TOD_PRIMARY,true); //Build datastructures for secondary topology - l_errHdl = l_Tod.buildTodDrawers(TOD_SECONDARY); + l_errHdl = TOD::buildTodDrawers(TOD_SECONDARY); if(l_errHdl) { TOD_ERR("TOD setup failure: failed to build TOD drawers " "for secondary topology."); //Report the error as informational - loss of redundancy, //but no loss of TOD function. - errlCommit( l_errHdl, TOD_COMP_ID ); break; } @@ -154,25 +188,26 @@ errlHndl_t TodSvc::todSetup() TOD_ERR("TOD setup failure: failed to create secondary topology."); //Report the error as informational - loss of redundancy, //but no loss of TOD function. - errlCommit( l_errHdl, TOD_COMP_ID ); + break; } l_secondary.dumpTopology(); //5) Call hardware procedures to configure the TOD hardware logic for //the secondary topology and to fill up the TOD regs. + l_errHdl = todSetupHwp(TOD_SECONDARY); if(l_errHdl) { TOD_ERR("TOD setup failure: secondary topology setup HWP."); //Report the error as informational - loss of redundancy, //but no loss of TOD function. - errlCommit( l_errHdl, TOD_COMP_ID ); + break; } //Secondary successfully configured - l_Tod.setConfigStatus(TOD_SECONDARY,true); + TOD::setConfigStatus(TOD_SECONDARY,true); //Need to call this again if the secondary topology got set up, //that would have updated more regs. @@ -191,30 +226,25 @@ errlHndl_t TodSvc::todSetup() { l_primary.dumpTodRegs(); - //If we are then atleast Primary or both configurations were + //If we are here then atleast Primary or both configurations were //successfully setup. If both were successfuly setup then we can use //writeTodProcData for either of them else we should call //writeTodProcData for only primary. //Ultimately it should be good enough to call the method for Primary - l_errHdl = l_Tod.writeTodProcData(TOD_PRIMARY); + l_errHdl = TOD::writeTodProcData(TOD_PRIMARY); if(l_errHdl) { - TOD_ERR("TOD setup: Failed to write topology register data"); + TOD_ERR("TOD setup failure:Failed to write topology register data" + " to the file."); } } - TOD_EXIT("todSetup. errHdl = %p", l_errHdl); + TOD::clearGardedTargetsList(); + TOD_EXIT(); return l_errHdl; } -//****************************************************************************** -//TodSvc::todInit -//****************************************************************************** -errlHndl_t TodSvc::todInit() -{ - return todInitHwp(TOD_PRIMARY); -} //****************************************************************************** //TodSvc::readTod @@ -224,48 +254,49 @@ errlHndl_t TodSvc::readTod(uint64_t& o_todValue) const TOD_ENTER("readTod"); errlHndl_t l_errHdl = NULL; - do { - //Get the MDMT - TodProc* l_pMDMT = - TodControls::getTheInstance().getMDMT(TOD_PRIMARY); - if(NULL == l_pMDMT) + TARGETING::Target* l_mdmtOnActiveTopology = NULL; + bool l_isTodRunning = false; + bool l_getTodRunningStatus = false; + p9_tod_setup_tod_sel l_activeConfig = TOD_PRIMARY; + + //Get the currently active TOD configuration + //Don't bother about the TOD runing state, caller should have asked for + //readTOD in correct state. + l_errHdl = TOD::queryActiveConfig( + l_activeConfig,l_isTodRunning, + l_mdmtOnActiveTopology, + l_getTodRunningStatus); + if ( l_errHdl ) { - TOD_ERR("MDMT not found"); - /*@ - * @errortype - * @reasoncode TOD_NO_MASTER_PROC - * @moduleid TOD_READ - * @devdesc MDMT could not be found - */ - l_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_INFORMATIONAL, - TOD_READ, - TOD_NO_MASTER_PROC); + TOD_ERR("Call to queryActiveConfig failed "); break; } + TOD_INF(" Active topology %d, HUID of MDMT 0x%08X ", + l_activeConfig, + GETHUID(l_mdmtOnActiveTopology)); + + //SCOM the TOD value reg - ecmdDataBufferBase o_todValueBuf(64); - l_errHdl = todGetScom(l_pMDMT->getTarget(), - TOD_VALUE_REG_00040020, - o_todValueBuf); + fapi2::variable_buffer o_todValueBuf(64); + l_errHdl = todGetScom(l_mdmtOnActiveTopology, + PERV_TOD_VALUE_REG, + o_todValueBuf); + if(l_errHdl) { TOD_ERR("TOD read error: failed to SCOM TOD value register " - "address 0x%.16llX on MDMT 0x%.8X.", - TOD_VALUE_REG_00040020, - l_pMDMT->getTarget()->getAttr()); + "address 0x%.16llX on MDMT 0x%.8X.", + PERV_TOD_VALUE_REG, + GETHUID(l_mdmtOnActiveTopology)); break; } - o_todValue = o_todValueBuf.getDoubleWord(0); - - TOD_INF("TOD value : 0x%.16llx", o_todValue ); - + o_todValue = o_todValueBuf.get(0); }while(0); - TOD_EXIT("readTod. errHdl = %p", l_errHdl); + TOD_EXIT(); return l_errHdl; } @@ -275,9 +306,9 @@ errlHndl_t TodSvc::readTod(uint64_t& o_todValue) const //****************************************************************************** TodSvc::TodSvc() { - TOD_ENTER("TodSvc constructor"); + TOD_ENTER(); - TOD_EXIT("TodSvc constructor"); + TOD_EXIT(); } //****************************************************************************** @@ -285,13 +316,295 @@ TodSvc::TodSvc() //****************************************************************************** TodSvc::~TodSvc() { - TOD_ENTER("TodSvc destructor"); + TOD_ENTER(); //Free up held memory - TodControls::getTheInstance().destroy(TOD_PRIMARY); - TodControls::getTheInstance().destroy(TOD_SECONDARY); + TOD::destroy(TOD_PRIMARY); + TOD::destroy(TOD_SECONDARY); + + TOD_EXIT(); +} - TOD_EXIT("TodSvc destructor"); +//****************************************************************************** +//TodSvc::todInit +//****************************************************************************** +errlHndl_t TodSvc::todInit() +{ + TOD_ENTER(); + errlHndl_t l_errHdl = NULL; + bool l_isTodRunning = false; + do + { + //Check if the Chip TOD logic is already Running + l_errHdl = TOD::isTodRunning(l_isTodRunning); + if ( l_errHdl ) + { + TOD_INF("Call to isTodRunning() failed , cannot initialize the" + "Chip TOD logic "); + break; + } + + if ( l_isTodRunning ) + { + TOD_ERR("Cannot initialize the TOD logic while the Chip TOD logic" + "is already running"); + /*@ + * @errortype + * @moduleid TOD_INIT_ALREADY_RUNNING + * @reasoncode TOD_INVALID_ACTION + * @userdata1 EMOD_TOD_INIT + * @userdata2 ChipTOD logic HW state, 1=running, + * zero otherwise + * @devdesc Error: Initialization of chip TOD logic cannot be + * done when its already in the running state + * @custdesc Host failed to boot because there was a problem + * configuring Time Of Day on the Host processors + */ + l_errHdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_INIT_ALREADY_RUNNING, + TOD_INVALID_ACTION, + EMOD_TOD_INIT, + l_isTodRunning); + + break; + + } + + //Call the hardware procedure to initialize the Chip TOD logic to the + //running state using the PRIMARY TOD topology. + l_errHdl = todInitHwp(); + if( l_errHdl ) + { + TOD_ERR("TOD initialization failed for primary topology : HWP"); + break; + } + + }while(0); + TOD_EXIT(); + return l_errHdl; +} + +//****************************************************************************** +//TodSvc::setActiveMdmtForResetBackup +//****************************************************************************** +errlHndl_t TodSvc::setActiveMdmtForResetBackup( + const p9_tod_setup_tod_sel i_activeConfig) +{ + TOD_ENTER("setActiveMdmtForResetBackup"); + errlHndl_t l_errHdl = NULL; + + //While doing a resetBackup it was found that in memory copy of active + //topology is not present, (system has done a RR ) + //In order to ensure redundancy of processor and oscillator source on the + //backup topology we needed to have the copy of active topology in memory. + + //However we may not need to recreate the complete active topology from + //the persistant topology information file. + //It would be just sufficient if we have the todControls built and MDMT set + + do{ + + l_errHdl = TOD::buildTodDrawers(i_activeConfig); + if ( l_errHdl ) + { + TOD_ERR("Failed to build TOD drawers for %s", + (TOD::TodSvcUtil:: + topologyTypeToString(i_activeConfig))); + break; + } + + TARGETING::Target* l_primaryMdmt = NULL; + TARGETING::Target* l_secondaryMdmt = NULL; + + //Read the HW to get the configured MDMT's + l_errHdl = TOD::getConfiguredMdmt(l_primaryMdmt, + l_secondaryMdmt); + if ( l_errHdl ) + { + TOD_ERR("Failed to get the configured MDMTs "); + break; + } + + TARGETING::Target* l_mdmtOnActiveTopology = NULL; + l_mdmtOnActiveTopology = ( i_activeConfig == TOD_PRIMARY )? + l_primaryMdmt : l_secondaryMdmt; + + if ( !l_mdmtOnActiveTopology ) //Big problem--This should not happen + + { + TOD_ERR("TOD HW logic is already running but we cannot locate" + "MDMT for the %s , that is active", + (TOD::TodSvcUtil:: + topologyTypeToString(i_activeConfig))); + /*@ + * @errortype + * @moduleid TOD_MDMT_TOPOLOGY + * @reasoncode TOD_NO_VALID_MDMT_FOUND + * @userdata1 EMOD_TOD_SET_ACTIVE_MDMT + * @userdata2 Topology type on which MDMT was searched + * @devdesc Error: Could not find MDMT on active topology + * even though TOD HW logic is running + * @custdesc Host failed to boot because there was a problem + * configuring Time Of Day on the Host processors + */ + + l_errHdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_MDMT_TOPOLOGY, + TOD_NO_VALID_MDMT_FOUND, + EMOD_TOD_SET_ACTIVE_MDMT, + i_activeConfig); + break; + + } + + //We have the valid MDMT target now, find the TodProc object + //corresponding to it and also figure out the TodDrawer object to + //which this processor belongs + + //To do so get the TodProc object whose HUID matches with the HUID + //of the active topology's MDMT, and also get the TOD drawer to which + //this TodProc object belongs + TodDrawer* l_masterDrawer = NULL; + TodProc* l_masterProc = NULL; + std::list l_drawerList; + TOD::getDrawers(i_activeConfig, l_drawerList); + + bool l_drawerFound = false; + + for(std::list::iterator l_drawerItr = + l_drawerList.begin(); + ((l_drawerItr != l_drawerList.end()) && !l_drawerFound); + ++l_drawerItr) + { + const std::list& l_procsList = + (*l_drawerItr)->getProcs(); + for(std::list::const_iterator l_procItr = + l_procsList.begin(); + ((l_procItr != l_procsList.end()) && !l_drawerFound); + ++l_procItr) + { + if ( + (*l_procItr)->getTarget() + == + l_mdmtOnActiveTopology) + { + l_masterProc = *l_procItr; + l_masterDrawer = *l_drawerItr; + l_drawerFound = true; + } + + } + + } + + if ( !l_masterProc || !l_masterDrawer ) + { + + //This should never happen unless we have goofed up big time + + TOD_ERR("Could not find TOD objects for the configured " + "MDMT 0x%08X on %s", + GETHUID(l_mdmtOnActiveTopology), + (TOD::TodSvcUtil:: + topologyTypeToString(i_activeConfig))); + + //FIX_ME_BEFORE_PRODUCTION_Q1 + bool l_masterProcNotFound = ( !l_masterProc )? true : false; + bool l_masterDrawerNotFound = ( !l_masterDrawer )? true : false; + + /*@ + * @errortype + * @moduleid TOD_FIND_MASTER_PROC + * @reasoncode TOD_MASTER_TARGET_NOT_FOUND + * @userdata1[32:64] 1 = Master proc was not found , zero otherwise + * @userdata1[32:63] 1 = Master drawer was not found, zero otherwise + * @userdata2[0:31] EMOD_TOD_SET_ACTIVE_MDMT + * @userdata2[32:64] Active topology + * @devdesc Either processor or drawer object was not found for + * the MDMT found by reading the processor registers. + * @custdesc Service Processor Firmware encountered an internal + * error + */ + + l_errHdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_FIND_MASTER_PROC, + TOD_MASTER_TARGET_NOT_FOUND, + TWO_UINT32_TO_UINT64( + l_masterProcNotFound, + l_masterDrawerNotFound), + TWO_UINT32_TO_UINT64( + EMOD_TOD_SET_ACTIVE_MDMT, + i_activeConfig)); + break; + + } + + //Now we have the all the objects required to set the MDMT + (void) TOD::setMdmtOfActiveConfig( + i_activeConfig, + l_masterProc, + l_masterDrawer); + + }while(0); + + TOD_EXIT(); + return l_errHdl; +} + +errlHndl_t TodSvc::isMPIPL( bool& o_mpIPL ) +{ + TOD_ENTER("isMPIPL"); + + errlHndl_t l_errHdl = NULL; + o_mpIPL = false; + + do{ + // Get the top level (system) target handle to check if MPIPL + TARGETING::Target* l_pTopLevelTarget = NULL; + (void)TARGETING::targetService().getTopLevelTarget(l_pTopLevelTarget); + if(NULL == l_pTopLevelTarget) + { + /*@ + * @errortype + * @moduleid TOD_IS_MPIPL + * @reasoncode TOD_TOP_LEVEL_TARGET_NOT_FOUND + * @devdesc Top level Target not found + * @custdesc Service Processor Firmware encountered an internal + * error + */ + l_errHdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_IS_MPIPL, + TOD_TOP_LEVEL_TARGET_NOT_FOUND); + + TOD_ERR_ASSERT("Error getting top level target"); + break; + } + if(true == l_pTopLevelTarget->getAttr()) + { + TOD_INF("In MPIPL path"); + o_mpIPL = true; + } + }while(0); + + TOD_EXIT( "Output Params - o_mpIPL: %d", o_mpIPL ); + + return l_errHdl; +} + +// Wrapper function for TodSvc::todInit instance +errlHndl_t todInit() +{ + return Singleton::instance().todInit(); +} + +// Wrapper function for TodSvc::todInit instance +errlHndl_t todSetup() +{ + return Singleton::instance().todSetup(); } } //namespace TOD diff --git a/src/usr/isteps/istep18/TodSvc.H b/src/usr/isteps/istep18/TodSvc.H index 11b0528575e..26366ba15c9 100755 --- a/src/usr/isteps/istep18/TodSvc.H +++ b/src/usr/isteps/istep18/TodSvc.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -24,7 +24,6 @@ /* IBM_PROLOG_END_TAG */ #ifndef TODSVC_H #define TODSVC_H - /** * @file TodSvc.H * @@ -35,11 +34,25 @@ * */ + +//------------------------------------------------------------------------------ +//Includes +//------------------------------------------------------------------------------ + #include +#include + +#include +#include namespace TOD { +class TodControls; +//Use "theTodSvc_t::Instance()" to access the singleton via reference +class TodSvc; +typedef Singleton theTodSvc_t; + /** * @class TodSvc * @@ -58,7 +71,7 @@ public: /** * @brief This interface should be called during IPL to setup the - * time of day logic on the P8 processors sitting on the system. + * time of day logic on the P9 processors sitting on the system. * * @par Detailed Description: * All processors of a symmetric multiprocessor model must appear to @@ -72,7 +85,7 @@ public: * Since the procs are connected by fabric buses, a signal sent out by * the oscillator will reach the procs at different times. Besides, * there are multiple bus paths to propagate TOD signals. To solve these - * issues, we (FSP HWSV) need to create a TOD topology. A TOD topology + * issues, we (FSP) need to create a TOD topology. A TOD topology * has a single Master Drawer Master TOD processor chip (MDMT), which * receives input directly from the oscillator. The MDMT will propagate * signals to other procs, MDSTs (Master Drawer Slave TOD Chips), @@ -125,7 +138,7 @@ public: * * @return Error log handle indicating the status of the request. * @retval NULL if successful - * @retval !NULL if failed to setup TOD + * @retval !NULL if failed to read TOD value * * Error log handle points to a valid error log object whose primary * SRC reason code (pError->getSRC()->reasonCode()) indicates the type @@ -136,25 +149,23 @@ public: * any returned error created by this function will be a non-reported * tracing event error log. */ - errlHndl_t todInit(); - /** - * @brief Reads the Time Of Day (TOD) value from the TOD register on - * the processor chip and returns the same. + errlHndl_t readTod(uint64_t& o_todValue) const; + + /** + * @brief This interface should be called during IPL to initialize the + * time of day logic on the P9 processors to running state. * * @par Detailed Description: - * This interface will read the TOD value from the TOD value register. - * We could read this from any of the processor that's part of the - * TOD topology, since the TOD value should be in sync across procs, - * so we'll read this from the MDMT's register. - * - * @param[out] o_todValue - * 64-bit contents of the TOD value register will be copied here - * in a big-endian format. Will be 0 on error. + * Once the TOD topology is setup on the system , the todinit is called + * to initialize the time of day logic on the P9 processors to running + * state. FSPFW needs to do this initialization explicitly for the + * Manufacturing AVP tests to pass. Once the FSP reaches runtime PHYP + * re-initializes it to the running state. * * @return Error log handle indicating the status of the request. * @retval NULL if successful - * @retval !NULL if failed to read TOD value + * @retval !NULL if failed to setup TOD * * Error log handle points to a valid error log object whose primary * SRC reason code (pError->getSRC()->reasonCode()) indicates the type @@ -164,8 +175,12 @@ public: * returned error based on what it decides to do with it. By default * any returned error created by this function will be a non-reported * tracing event error log. + * + * @note This initialization should be called only by the istep after the + * tod is setup. + * */ - errlHndl_t readTod(uint64_t& o_todValue) const; + errlHndl_t todInit(); protected: /** @@ -183,14 +198,64 @@ protected: ~TodSvc(); private: + + /** + * @brief This is a helper method to resetBackup and will be called to find + * out from HW the MDMT on active topology, and set it in TOD controls. + * + * @par Detailed Description: + * During resetBackup it may happen that FSP has done a RR before + * resetBackup was called in such circumstance the in memory copy of + * topology would have been lost. In order to re-configure the backup + * with adequate redundancy we want to have MDMT of active topology + * configured in TOD controls. + * + * @param[in] i_activeConfig + * Indicates the TOD configuration ( primary/secondary ) for which the + * MDMT is to be set + * + * @return Error log handle indicating the status of the request + * @retval NULL Indicates success + * !NULL means failed to set the MDMT for the active topology + * + */ + errlHndl_t setActiveMdmtForResetBackup( + const p9_tod_setup_tod_sel i_activeConfig); + //Disabled copy constructor and assignment operator TodSvc(const TodSvc& rhs); TodSvc& operator=(const TodSvc& rhs); - //Indicates if we've already setup TOD - bool iv_todSetup; + /** + * @brief This method checks if in MPIPL path using attribue ATTR_IS_MPIPL + * + * @param[out] o_mpIPL + * Boolean which indicates if in MPIPL path + * TRUE if MPIPL. FALSE if not. + * + * @return Error log handle indicating the status of the request + * @retval NULL Successfully checked if system in MPIPL path or not + * @retval !NULL Error checking if system in MPIPL path or not + * Error log handle points to a valid error log object whose primary + * SRC reason code (pError->getSRC()->reasonCode()) indicates the type + * of error + * + * @note It is up to the caller to change the severity of the + * returned error based on what it decides to do with it. By default + * any returned error created by this function will be a non-reported + * tracing event error log. + */ + + errlHndl_t isMPIPL( bool& o_mpIPL ); + }; +// Wrapper function for TodSvc::todInit instance +errlHndl_t todInit(); + +// Wrapper function for TodSvc::todSetup instance +errlHndl_t todSetup(); + } //namespace TOD #endif //TODSVC_H diff --git a/src/usr/isteps/istep18/TodSvcUtil.C b/src/usr/isteps/istep18/TodSvcUtil.C index ea00ca90ed0..91312081586 100755 --- a/src/usr/isteps/istep18/TodSvcUtil.C +++ b/src/usr/isteps/istep18/TodSvcUtil.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -22,28 +22,97 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ - /** * @file TodSvcUtil.C * - * @brief This file implements the various utility methods - * - * HWP_IGNORE_VERSION_CHECK + * @brief The file implements methods of common utility across TOD service * */ -#include -#include -#include -#include -#include "TodTrace.H" + +//targeting support +#include +#include +#include + #include "TodSvcUtil.H" +#include "TodUtils.H" +#include "TodDrawer.H" +#include "TodTrace.H" +#include "TodAssert.H" +#include + +namespace TOD + +{ + +//Namespace for containing the utility methods +namespace TodSvcUtil{ + +//****************************************************************************** +//calloutTodEndPoint +//****************************************************************************** +void calloutTodEndPoint( const TARGETING::Target* const i_pTodEndPoint, + errlHndl_t& io_errHdl ) +{ + + /*@ + * @errortype + * @moduleid TOD_ENDPOINT_CALLOUT + * @reasoncode TOD_MASTER_PATH_ERROR + * @userdata1 TOD_ENDPOINT_CALLOUT + * @userdata2 HUID of the TOD end point that is not receiving signal + * @devdesc This TOD end point target on processor is not receiving + * signal from the OSC. + * @custdesc There was a problem in configuring Time Of Day on the Host + * processor. + * + */ + + io_errHdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_ENDPOINT_CALLOUT, + TOD_MASTER_PATH_ERROR, + EMOD_CALLOUT_TOD_ENDPOINT, + GETHUID(i_pTodEndPoint)); + + //Get the PEER TOD end point on the OSC and callout as low + TARGETING::PredicateCTM l_todEndPointPred( + TARGETING::CLASS_UNIT,TARGETING::TYPE_TODCLK); + + TARGETING::PredicatePostfixExpr l_funcTodEndPointPred; + TARGETING::PredicateHwas l_hwasFunc; + l_hwasFunc.functional(true); -using namespace TARGETING; + l_funcTodEndPointPred.push(&l_todEndPointPred). + push(&l_hwasFunc).And(); -namespace TOD { + TARGETING::TargetHandleList l_todEndPointList; + TARGETING::getPeerTargets(l_todEndPointList,//output list + i_pTodEndPoint, //Peer for this TOD end point + NULL, + &l_funcTodEndPointPred);//Destination predicate + + + if ( l_todEndPointList.size() > 1 ) + { + TOD_ERR_ASSERT(0, "More than one PEER TOD end point returned" + " for the target 0x%08X ", + GETHUID(i_pTodEndPoint)); + } + + if ( !l_todEndPointList.empty()) + { + io_errHdl->addHwCallout((*l_todEndPointList.begin()), + HWAS::SRCI_PRIORITY_LOW, + HWAS::DECONFIG, + HWAS::GARD_Fatal); + + } + +} //****************************************************************************** //logInvalidTodConfig //****************************************************************************** @@ -53,18 +122,20 @@ void logInvalidTodConfig( { /*@ * @errortype - * @reasoncode TOD_INVALID_CONFIG * @moduleid TOD_LOG_INVALID_CONFIG - * @userdata1 The problematic configuration (Primary/Secondary) + * @reasoncode TOD_INVALID_CONFIG + * @userdata1 The problematic configuration ( Primary/Secondary) * @devdesc Error: Erroneous TOD configuration * Possible Causes: Programming issue * Resolution: Development team should be contacted. + * @custdesc Host failed to boot because there was a problem + * configuring Time Of Day on the Host processors */ io_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - TOD_LOG_INVALID_CONFIG, - TOD_INVALID_CONFIG, - i_config, 0); + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_LOG_INVALID_CONFIG, + TOD_INVALID_CONFIG, + i_config); } //****************************************************************************** @@ -76,8 +147,8 @@ void logUnsupportedOrdinalId( { /*@ * @errortype - * @reasoncode TOD_UNSUPORTED_ORDINALID * @moduleid TOD_LOG_UNSUPORTED_ORDINALID + * @reasoncode TOD_UNSUPORTED_ORDINALID * @userdata1 Ordinal Id for which the error is logged * @devdesc Error: The ordinal Id of one of the TOD procs did not fall * in the range 0 <= Ordinal Id < getMaxProcsOnSystem @@ -85,12 +156,14 @@ void logUnsupportedOrdinalId( * the latest system type where the no. of processor chips is * either equal to or more than getMaxProcsOnSystem * Resolution: Development team should be contacted. + * @custdesc Service Processor Firmware encountered an internal error */ io_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - TOD_LOG_UNSUPORTED_ORDINALID, - TOD_UNSUPORTED_ORDINALID, - i_ordinalId, 0 ); + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_LOG_UNSUPORTED_ORDINALID, + TOD_UNSUPORTED_ORDINALID, + i_ordinalId); + } //****************************************************************************** @@ -98,173 +171,130 @@ void logUnsupportedOrdinalId( //****************************************************************************** uint32_t getMaxProcsOnSystem() { - Target* sys = NULL; - targetService().getTopLevelTarget(sys); + TOD_ENTER("getMaxProcsOnSystem"); + errlHndl_t l_errHdl = NULL; + // Get the max attribute values in this structure; + maxConfigParamsContainer l_maxCfgParams; + + l_errHdl = getMaxConfigParams(l_maxCfgParams); - uint8_t l_maxProcs = 0; - sys->tryGetAttr(l_maxProcs); + uint32_t l_maxProcCount = 0; + if (!l_errHdl ) + { + //FIX_ME: need to find out how to populate this variable + //l_maxProcCount = l_maxCfgParams.max_compute_nodes_per_sys * + l_maxProcCount = + l_maxCfgParams.max_procchips_per_node; + TOD_INF("Maximum procs on system = 0x%08X", l_maxProcCount); + } + else + { + TOD_ERR("getMaxConfigParams() Failed"); + } - return ( (uint32_t)l_maxProcs ); + return (l_maxProcCount); } //****************************************************************************** -//getMaxPossibleCoresPerProc() +//topologyTypeToString //****************************************************************************** -uint32_t getMaxPossibleCoresPerProc() -{ - Target* sys = NULL; - targetService().getTopLevelTarget(sys); - - uint8_t l_maxCores = 0; - sys->tryGetAttr(l_maxCores); - return ( (uint32_t)l_maxCores ); +char const * topologyTypeToString ( const p9_tod_setup_tod_sel i_topologyType ) +{ + switch ( i_topologyType ) + { + case TOD_PRIMARY: + return "Primary Topology"; + case TOD_SECONDARY: + return "Secondary Topology"; + default: + TOD_ERR_ASSERT("Unknown Topology Type"); + return ""; + } } -//****************************************************************************** -//todGetScom() -//****************************************************************************** -errlHndl_t todGetScom(const TARGETING::Target * i_target, - const uint64_t i_address, - ecmdDataBufferBase & o_data) -{ - uint32_t l_ecmdRc; - errlHndl_t l_err = NULL; +/****************************************************************************** + * getFuncNodeTargetsOnSystem + *****************************************************************************/ - // Perform SCOM read - uint64_t l_data = 0; - size_t l_size = sizeof(uint64_t); +errlHndl_t getFuncNodeTargetsOnSystem( + TARGETING::ConstTargetHandle_t i_nodeOrSysTarget, + TARGETING::TargetHandleList& o_nodeList, + const bool i_skipFuncCheck){ - l_err = deviceRead((TARGETING::Target *)i_target, - &l_data, - l_size, - DEVICE_SCOM_ADDRESS(i_address)); + TOD_ENTER("Function Node Target On System"); - if (!l_err) - { - l_ecmdRc = o_data.setBitLength(64); - l_ecmdRc |= o_data.setDoubleWord(0, l_data); - if (l_ecmdRc) - { - /*@ - * @errortype - * @reasoncode TOD_ECMD_ERROR - * @moduleid TOD_GETSCOM - * @userdata1 return code from ecmdDataBufferBase operation(s) - * @devdesc Scom access error - */ - l_err = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_INFORMATIONAL, - TOD_LOG_UNSUPORTED_ORDINALID, - TOD_UNSUPORTED_ORDINALID, - l_ecmdRc, 0 ); - } - } + errlHndl_t l_errHdl = NULL; - return l_err; -} + o_nodeList.clear(); -//****************************************************************************** -//getFuncNodeTargetsOnSystem -//****************************************************************************** -errlHndl_t getFuncNodeTargetsOnSystem(const TARGETING::Target* - i_pInputTarget, TARGETING::TargetHandleList& - o_functionalNodeTargetList) -{ - TOD_ENTER("getFuncNodeTargetsOnSystem"); - errlHndl_t l_errHdl = NULL; - o_functionalNodeTargetList.clear(); + TARGETING::ATTR_CLASS_type l_class = GETCLASS(i_nodeOrSysTarget); + TARGETING::ATTR_TYPE_type l_type = GETTYPE(i_nodeOrSysTarget); do{ - if (i_pInputTarget == NULL ) + if(NULL == i_nodeOrSysTarget) { - TOD_ERR("NULL target passed in the call to method " - "getFuncNodeTargetsOnSystem "); - /*@ - * @errortype - * @reasoncode TOD_NULL_INPUT_TARGET - * @moduleid TOD_GETFUNCNODETARGETSONSYSTEM - * @userdata1 HUID of the target that was validated - * @devdesc Scom access error - */ - l_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_INFORMATIONAL, - TOD_GETFUNCNODETARGETSONSYSTEM, - TOD_NULL_INPUT_TARGET ); + TOD_ERR("NULL target node passed in"); + l_errHdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + TOD_BUILD_TOD_DRAWERS, + TOD_NULL_INPUT_TARGET, + 0); break; } - CLASS l_class = i_pInputTarget->getAttr(); - TYPE l_type = i_pInputTarget->getAttr(); - - if((TARGETING::CLASS_SYS == l_class) && - (TARGETING::TYPE_SYS == l_type))//System target + //Check if the target is node or system + TARGETING::PredicateCTM l_isNode(TARGETING::CLASS_ENC, + TARGETING::TYPE_NODE); + TARGETING::PredicateCTM l_isSys(TARGETING::CLASS_SYS, + TARGETING::TYPE_SYS); + if((false == l_isNode(i_nodeOrSysTarget)) && + (false == l_isSys(i_nodeOrSysTarget))) { - //create the predicate with CLASS_ENC and TYPE_NODE - TARGETING::PredicateCTM - l_nodeFilter(TARGETING::CLASS_ENC,TARGETING::TYPE_NODE); + TOD_ERR("Target 0x%.8X with class %s, type %s isn't node or sys", + GETHUID(i_nodeOrSysTarget), + TARGETING::attrToString(l_class), + TARGETING::attrToString(l_type)); + l_errHdl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + TOD_BUILD_TOD_DRAWERS, + TOD_INVALID_TARGET, + GETHUID(i_nodeOrSysTarget)); + break; + } + if(TARGETING::TYPE_SYS == l_type) //sys target + { //Use PredicateIsFunctional to filter only functional nodes - TARGETING::PredicateIsFunctional l_isFunctional; - TARGETING::PredicatePostfixExpr l_functionalAndNodeFilter; - - l_functionalAndNodeFilter.push(&l_nodeFilter). - push(&l_isFunctional).And(); - - //Create an iterator to loop over the selected targets - TARGETING::TargetRangeFilter l_pFuncNode( - TARGETING::targetService().begin(), - TARGETING::targetService().end(), - &l_functionalAndNodeFilter ); + TARGETING::PredicateIsFunctional l_isFunctional; + TARGETING::PredicatePostfixExpr l_funcNodeFilter; + l_funcNodeFilter. + push(&l_isNode).push(&l_isFunctional).And(); - for ( ; l_pFuncNode ; ++l_pFuncNode) - { - o_functionalNodeTargetList.push_back(*l_pFuncNode); - } + TARGETING::targetService().getAssociated( + o_nodeList, + i_nodeOrSysTarget , + TARGETING::TargetService::CHILD, + TARGETING::TargetService::IMMEDIATE, + i_skipFuncCheck ? + static_cast(&l_isNode) : + static_cast(&l_funcNodeFilter)); } - else if ((TARGETING::CLASS_ENC == l_class ) && - (TARGETING::TYPE_NODE == l_type )) //Node target + else //node target { - if (i_pInputTarget->getAttr().functional) + if(i_skipFuncCheck || + (isFunctional(i_nodeOrSysTarget))) { - o_functionalNodeTargetList.push_back( - const_cast(i_pInputTarget)); + o_nodeList.push_back( + const_cast(i_nodeOrSysTarget)); } - else - { - TOD_ERR("Failed to get the functional state for target 0x%08X", - i_pInputTarget->getAttr()); - break; - } - } - else - { - TOD_ERR("Invalid target 0x%08X passed in the call to method " - "getFuncNodeTargetsOnSystem ", - i_pInputTarget->getAttr()); - /*@ - * @errortype - * @reasoncode TOD_INVALID_TARGET - * @moduleid TOD_GETFUNCNODETARGETSONSYSTEM - * @userdata1 HUID of the target that was validated - * @devdesc Scom access error - */ - l_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_INFORMATIONAL, - TOD_GETFUNCNODETARGETSONSYSTEM, - TOD_INVALID_TARGET, - i_pInputTarget->getAttr()); - break; } }while(0); - if ( l_errHdl ) - { - o_functionalNodeTargetList.clear(); - } - - TOD_EXIT("getFuncNodeTargetsOnSystem. errHdl = %p", l_errHdl); return l_errHdl; } -} //End of namespace TOD + +}//End of namespace TodSvcUtil + +}//End of namespace TOD diff --git a/src/usr/isteps/istep18/TodSvcUtil.H b/src/usr/isteps/istep18/TodSvcUtil.H index aca27ae5225..302d62d8ced 100755 --- a/src/usr/isteps/istep18/TodSvcUtil.H +++ b/src/usr/isteps/istep18/TodSvcUtil.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -22,24 +22,62 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ +#ifndef TODSVCUTIL_H +#define TODSVCUTIL_H /** * @file TodSvcUtil.H * - * @brief This file declares the various utility methods - * - * HWP_IGNORE_VERSION_CHECK - * + * @brief Provides definition of functions that are of common use across TOD + * todService */ -#ifndef TODSVCUTIL_H -#define TODSVCUTIL_H - -#include -#include +//Targeting includes +#include +#include +#include +#include "TodUtils.H" namespace TOD { + +typedef std::vector + TodEndPointContainer; + +namespace TodSvcUtil{ + + /** + * @brief This method should be called to do a callout on input TOD end + * point target on processor. + * + * @par Detailed Description: + * The method will do the followin + * + * HW callout + * Target | Priority | Deconfig | Gard + * TOD end point on + * Processor High Yes Yes + * + * Tod end point on + * OSC Low Yes Yes + * + * Procedure callout + * EPUB_PRC_TOD_CLOCK_ERR Low + * + * @param[in] i_pTodEndPoint, Input TOD end point target for calling out. + * point target connects. + * + * @param[inout] io_errHdl + * On input this parameter will be either NULL or pointing to + * an existing error handle. + * On output this parameter will either have a newly created handle + * assigned to it ( If input parameter was NULL ) or a new SRC will be + * appened to existing error handle ( If the input was not NULL ) + * @return NA + */ + void calloutTodEndPoint( const TARGETING::Target* i_pTodEndPoint, + errlHndl_t& io_errHdl); + /** * @brief Method to create an errlHndl_t object for * TOD_INVALID_CONFIG error @@ -71,9 +109,9 @@ namespace TOD * The ordinal Id's of TOD procs should fall within the range of 0 * <= Ordinal Id < getMaxProcsOnSystem. * getMaxProcsOnSystem defines static count of the array of - * hwsvTodChipData structures that will be written in the file - * shared between HWSV and HDAT. - * Each hwsvTodChipData structure contains TOD chip register data + * TodChipData structures that will be written in the file + * shared between TOD and HDAT. + * Each TodChipData structure contains TOD chip register data * for a specific chip. * This error will be logged if at any point of time because of * changes in system configuration the no. of proc chips becomes @@ -103,61 +141,28 @@ namespace TOD * @return Count of procs * The method should succeed always */ - uint32_t getMaxProcsOnSystem(); - + uint32_t getMaxProcsOnSystem(); /** + * @brief Return the topology type as string * - * @brief This method finds out the maximum number of cores that is - * possible per proc for fully configured system of this type + * @param[in] i_topoloyType, The topology type for which its string + * equivalent needs to be returned. * - * @return Count of cores - * The method should succeed always + * @return String equivalent of the topology type passed as input. + * Method will assert if unsupported topology type is passed as input. */ - uint32_t getMaxPossibleCoresPerProc(); - /** - * @brief This method read the scom register - * - * @param[in] i_target : target object - * @param[in] i_address : SCOM register address - * - * @param[out] o_data : content of the register if no error - * - * @return errlHndl_t : NULL if ok. Otherwise, there is an error - */ - errlHndl_t todGetScom(const TARGETING::Target * i_target, - const uint64_t i_address, - ecmdDataBufferBase & o_data); + char const * topologyTypeToString ( + const p9_tod_setup_tod_sel i_topologyType); - /** - * - * @brief This method will get the list of functional node target - * pointers for the supplied target that can be a node or system - * type. - * - * @par Detailed Description: - * If the input target is a system level target then target - * pointers for all the functional nodes in system will be - * collected. - * If the target sent is of node type then the method will simply - * push back the target that has been passed as argument, provided - * it is functional - * - * @param[in] i_pInputTarget - * Target sent as input to this method - * - * @param[out] o_functionalNodeTargetList - * List of functional node targets collected by the method - * @return Error log handle to carry back status of request - * @retval !NULL Indicates an error in collecting the node target.This - * can happen if input target is neither of system/node - * type. In error case o_functionalNodeTargetList will be empty. - * @retval NULL Indicates that there was no error in getting the targets. - */ - errlHndl_t getFuncNodeTargetsOnSystem(const TARGETING::Target * i_target, - TARGETING::TargetHandleList& o_functionalNodeTargetList); + errlHndl_t getFuncNodeTargetsOnSystem( + TARGETING::ConstTargetHandle_t i_nodeOrSysTarget, + TARGETING::TargetHandleList& o_nodeList, + const bool i_skipFuncCheck); + +}//End of namespace TodSvcUtil -} //End of namespace TOD +}//End of namespace TOD #endif diff --git a/src/usr/isteps/istep18/TodTopologyManager.C b/src/usr/isteps/istep18/TodTopologyManager.C index 4a7d0943572..63e2e290af1 100755 --- a/src/usr/isteps/istep18/TodTopologyManager.C +++ b/src/usr/isteps/istep18/TodTopologyManager.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -22,27 +22,34 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ - /** * @file TodTopologyManager.C * * @brief TOD Topology Manager class implementation. Responsible for * creating/modifying the primary and secondary topologies. - * - * HWP_IGNORE_VERSION_CHECK - * */ + +//------------------------------------------------------------------------------ +//Includes +//------------------------------------------------------------------------------ +//#include + +//TARGETING #include #include -#include +#include "TodUtils.H" #include "TodTopologyManager.H" #include "TodControls.H" #include "TodDrawer.H" #include "TodProc.H" #include "TodTrace.H" +#include +#include + +extern "C" { -using namespace TARGETING; +using namespace fapi2; namespace TOD { @@ -57,31 +64,26 @@ static const char* NO_BUS = "NONE"; static const char* X_BUS_0 = "XBUS0"; static const char* X_BUS_1 = "XBUS1"; static const char* X_BUS_2 = "XBUS2"; -static const char* X_BUS_3 = "XBUS3"; -static const char* A_BUS_0 = "ABUS0"; -static const char* A_BUS_1 = "ABUS1"; -static const char* A_BUS_2 = "ABUS2"; //****************************************************************************** //TodTopologyManager::TodTopologyManager //****************************************************************************** TodTopologyManager::TodTopologyManager( - const proc_tod_setup_tod_sel i_topologyType) : + const p9_tod_setup_tod_sel i_topologyType) : iv_topologyType(i_topologyType) { TOD_ENTER("Topology type 0X%.8X", i_topologyType); - TOD_EXIT("TodTopologyManager constructor"); + TOD_EXIT(); } - //****************************************************************************** //TodTopologyManager::~TodTopologyManager //****************************************************************************** TodTopologyManager::~TodTopologyManager() { - TOD_ENTER("TodTopologyManager destructor"); + TOD_ENTER(); - TOD_EXIT("TodTopologyManager destructor"); + TOD_EXIT(); } //****************************************************************************** @@ -89,7 +91,7 @@ TodTopologyManager::~TodTopologyManager() //****************************************************************************** errlHndl_t TodTopologyManager::create() { - TOD_ENTER("create"); + TOD_ENTER("TodTopologyManager::create"); errlHndl_t l_errHdl = NULL; @@ -103,7 +105,8 @@ errlHndl_t TodTopologyManager::create() do { //1) Pick the MDMT. - l_errHdl = TodControls::getTheInstance().pickMdmt(iv_topologyType); + l_errHdl = + TOD::pickMdmt(iv_topologyType); if(l_errHdl) { TOD_ERR("Couldn't pick MDMT."); @@ -112,8 +115,7 @@ errlHndl_t TodTopologyManager::create() //Get the TOD drawers TodDrawerContainer l_todDrwList; - TodControls::getTheInstance().getDrawers(iv_topologyType, - l_todDrwList); + TOD::getDrawers(iv_topologyType, l_todDrwList); //Find the TOD system master drawer (the one in which the MDMT lies) TodDrawer* l_pMasterDrawer = NULL; for(TodDrawerContainer::const_iterator l_itr = l_todDrwList.begin(); @@ -124,7 +126,7 @@ errlHndl_t TodTopologyManager::create() { l_pMasterDrawer = *l_itr; TOD_INF("TOD drawer(0x%.2X) is the master drawer", - l_pMasterDrawer->getId()); + l_pMasterDrawer->getId()); break; } } @@ -133,16 +135,18 @@ errlHndl_t TodTopologyManager::create() TOD_ERR("TOD master drawer not found"); /*@ * @errortype - * @reasoncode TOD_CREATION_ERR * @moduleid TOD_TOPOLOGY_CREATE + * @reasoncode TOD_CREATION_ERR * @userdata1 Topology type : primary/secondary * @devdesc TOD master drawer not found + * @custdesc Host failed to boot because there was a problem + * configuring Time Of Day on the Host processors */ l_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_INFORMATIONAL, - TOD_TOPOLOGY_CREATE, - TOD_CREATION_ERR, - iv_topologyType ); + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_TOPOLOGY_CREATE, + TOD_CREATION_ERR, + iv_topologyType); break; } @@ -153,6 +157,7 @@ errlHndl_t TodTopologyManager::create() TOD_ERR("Couldn't wire one or more processors for " "the master TOD drawer(0x%.2X)", l_pMasterDrawer->getId()); + break; } @@ -207,7 +212,7 @@ errlHndl_t TodTopologyManager::create() } }while(0); - TOD_EXIT("create. errHdl = %p", l_errHdl); + TOD_EXIT(); return l_errHdl; } @@ -217,7 +222,7 @@ errlHndl_t TodTopologyManager::create() //****************************************************************************** errlHndl_t TodTopologyManager::wireProcs(const TodDrawer* i_pTodDrawer) { - TOD_ENTER("wireProcs"); + TOD_ENTER(); errlHndl_t l_errHdl = NULL; @@ -228,20 +233,22 @@ errlHndl_t TodTopologyManager::wireProcs(const TodDrawer* i_pTodDrawer) TOD_ERR("TOD drawer not specified"); /*@ * @errortype - * @reasoncode TOD_CREATION_ERR_NO_DRAWER * @moduleid TOD_WIRE_PROCS + * @reasoncode TOD_INVALID_PARAM * @userdata1 Topology type : primary/secondary * @devdesc TOD drawer not specified + * @custdesc Service Processor Firmware encountered an internal + * error */ l_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_INFORMATIONAL, - TOD_WIRE_PROCS, - TOD_CREATION_ERR_NO_DRAWER, - iv_topologyType ); + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_WIRE_PROCS, + TOD_INVALID_PARAM, + iv_topologyType); break; } - TOD_INF("TOD drawer id %d", i_pTodDrawer->getId()); + TOD_INF("TOD drawer id 0x%.2X", i_pTodDrawer->getId()); //The algorithm to wire procs in a TOD drawer goes as follows : /* @@ -294,8 +301,10 @@ errlHndl_t TodTopologyManager::wireProcs(const TodDrawer* i_pTodDrawer) { TOD_ERR("Error tying to connect target 0x%.8X " "to source 0x%.8X.", - (*l_targetItr)->getTarget()->getAttr(), - (*l_sourceItr)->getTarget()->getAttr()); + (*l_targetItr)->getTarget()-> + getAttr(), + (*l_sourceItr)->getTarget()-> + getAttr()); break; } if(l_connected) @@ -320,34 +329,39 @@ errlHndl_t TodTopologyManager::wireProcs(const TodDrawer* i_pTodDrawer) } if(false == l_targetsList.empty()) { + //We couldn't connect one or more procs in this drawer TOD_ERR("TOD drawer(0x%.2X) has one or more procs not connected. " "0x%.8X is the first such proc.", i_pTodDrawer->getId(), - (*(l_targetsList.begin()))->getTarget()->getAttr()); + (*(l_targetsList.begin()))->getTarget()-> + getAttr()); + /*@ * @errortype - * @reasoncode TOD_CREATION_ERR * @moduleid TOD_WIRE_PROCS - * @userdata1 DrawerId = bit[0:31], Topology type = bit[32:63] + * @reasoncode TOD_CREATION_ERR + * @userdata1[0:31] Topology type : primary/secondary + * @userdata1[32:63] TOD drawer id * @userdata2 HUID of first disconnected proc * @devdesc TOD drawer has one or more disconnected procs + * @custdesc Host failed to boot because there was a problem + * configuring Time Of Day on the Host processors */ - uint64_t l_data = i_pTodDrawer->getId(); - l_data <<= 32; - l_data |= iv_topologyType; l_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_INFORMATIONAL, - TOD_WIRE_PROCS, - TOD_CREATION_ERR, - l_data, - (*(l_targetsList.begin()))->getTarget()-> - getAttr()); + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_WIRE_PROCS, + TOD_CREATION_ERR, + TWO_UINT32_TO_UINT64( + iv_topologyType, + i_pTodDrawer->getId()), + (*(l_targetsList.begin()))->getTarget()-> + getAttr()); break; } }while(0); - TOD_EXIT("wireProcs. errHdl = %p", l_errHdl); + TOD_EXIT(); return l_errHdl; } @@ -357,7 +371,7 @@ errlHndl_t TodTopologyManager::wireProcs(const TodDrawer* i_pTodDrawer) //****************************************************************************** errlHndl_t TodTopologyManager::wireTodDrawer(TodDrawer* i_pTodDrawer) { - TOD_ENTER("wireTodDrawer"); + TOD_ENTER("wireTodDawer"); errlHndl_t l_errHdl = NULL; @@ -368,20 +382,22 @@ errlHndl_t TodTopologyManager::wireTodDrawer(TodDrawer* i_pTodDrawer) TOD_ERR("TOD drawer not specified"); /*@ * @errortype - * @reasoncode TOD_CREATION_ERR * @moduleid TOD_WIRE_DRAWERS + * @reasoncode TOD_INVALID_PARAM * @userdata1 Topology type : primary/secondary * @devdesc TOD drawer not specified + * @custdesc Service Processor Firmware encountered an internal + * error */ l_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_INFORMATIONAL, - TOD_WIRE_DRAWERS, - TOD_CREATION_ERR, - iv_topologyType); + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_WIRE_DRAWERS, + TOD_INVALID_PARAM, + iv_topologyType); break; } - TOD_INF("TOD drawer id %d", i_pTodDrawer->getId()); + TOD_INF("TOD drawer id 0x%.2X", i_pTodDrawer->getId()); //The algorithm to wire the slave TOD drawers to the mater TOD //drawer (to the MDMT to be specific) goes as follows : @@ -393,24 +409,26 @@ errlHndl_t TodTopologyManager::wireTodDrawer(TodDrawer* i_pTodDrawer) */ //Get the MDMT - TodProc* l_pMDMT = - TodControls::getTheInstance().getMDMT(iv_topologyType); + TodProc* l_pMDMT = TOD::getMDMT(iv_topologyType); if(NULL == l_pMDMT) { TOD_ERR("MDMT not found for topology type 0X%.8X", iv_topologyType); /*@ * @errortype - * @reasoncode TOD_NO_MASTER_PROC * @moduleid TOD_WIRE_DRAWERS + * @reasoncode TOD_MASTER_TARGET_NOT_FOUND * @userdata1 Topology type : primary/secondary * @devdesc MDMT could not be found + * @custdesc Service Processor Firmware couldn't detect any + * functional master processor required to boot the + * host */ l_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_INFORMATIONAL, - TOD_WIRE_DRAWERS, - TOD_NO_MASTER_PROC, - iv_topologyType); + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_WIRE_DRAWERS, + TOD_MASTER_TARGET_NOT_FOUND, + iv_topologyType); break; } @@ -439,8 +457,8 @@ errlHndl_t TodTopologyManager::wireTodDrawer(TodDrawer* i_pTodDrawer) { TOD_ERR("Error tying to connect target 0x%.4X " "to MDMT 0x%.8X.", - (*l_itr)->getTarget()->getAttr(), - l_pMDMT->getTarget()->getAttr()); + (*l_itr)->getTarget()->getAttr(), + l_pMDMT->getTarget()->getAttr()); break; } if(l_connected) @@ -461,23 +479,25 @@ errlHndl_t TodTopologyManager::wireTodDrawer(TodDrawer* i_pTodDrawer) i_pTodDrawer->getId()); /*@ * @errortype - * @reasoncode TOD_CANNOT_WIRE_DRAWER * @moduleid TOD_WIRE_DRAWERS + * @reasoncode TOD_CREATION_ERR * @userdata1 Topology type : primary/secondary * @userdata2 TOD drawer id * @devdesc TOD drawer couldn't be wired + * @custdesc Host failed to boot because there was a problem + * configuring Time Of Day on the Host processors */ l_errHdl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_INFORMATIONAL, - TOD_WIRE_DRAWERS, - TOD_CANNOT_WIRE_DRAWER, - iv_topologyType, - i_pTodDrawer->getId()); + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_WIRE_DRAWERS, + TOD_CREATION_ERR, + iv_topologyType, + i_pTodDrawer->getId()); break; } }while(0); - TOD_EXIT("wireTodDrawer. errHdl = %p", l_errHdl); + TOD_EXIT(); return l_errHdl; } @@ -489,15 +509,11 @@ void TodTopologyManager::dumpTopology() const { TOD_ENTER("dumpTopology"); - static const char* busnames[8] = {0}; + static const char* busnames[BUS_MAX+1] = {0}; busnames[NONE] = NO_BUS; busnames[XBUS0] = X_BUS_0; busnames[XBUS1] = X_BUS_1; busnames[XBUS2] = X_BUS_2; - busnames[XBUS3] = X_BUS_3; - busnames[ABUS0] = A_BUS_0; - busnames[ABUS1] = A_BUS_1; - busnames[ABUS2] = A_BUS_2; static const char* topologynames[2] = {0}; topologynames[TOD_PRIMARY] = TOD_PRIMARY_TOPOLOGY; @@ -510,20 +526,28 @@ void TodTopologyManager::dumpTopology() const topologynames[iv_topologyType]); //Get the TOD drawers TodDrawerContainer l_todDrwList; - TodControls::getTheInstance().getDrawers(iv_topologyType, l_todDrwList); - TodDrawerContainer::const_iterator l_drwItr = l_todDrwList.begin(); + TOD::getDrawers(iv_topologyType, l_todDrwList); + TodDrawerContainer::const_iterator l_drwItr = + l_todDrwList.begin(); while(l_todDrwList.end() != l_drwItr) { TOD_INF("TOPOLOGY DUMP> TOD Drawer(0x%.2X)",(*l_drwItr)->getId()); //Get the procs on this drawer TodProcContainer l_procList = (*l_drwItr)->getProcs(); - TOD_INF("TOPOLOGY DUMP> " - "parent_huid---bus out---bus in---child_huid"); - TodProcContainer::const_iterator l_procItr = l_procList.begin(); + TOD_INF("TOPOLOGY DUMP> parent---bus out---bus in---child"); + TodProcContainer::const_iterator l_procItr = + l_procList.begin(); + //FIX_ME_BEFORE_PRODUCTION_TASK32 + //bool l_ecmdTargetFound = false; while(l_procList.end() != l_procItr) { - //Get the children for this TOD proc + if(TodProc::TOD_MASTER == (*l_procItr)->getMasterType()) + { + TOD_INF("Proc 0x%.8X is the MDMT", + (*l_procItr)->getTarget()->getAttr()); + } + TodProcContainer l_childList; (*l_procItr)->getChildren(l_childList); TodProcContainer::const_iterator l_childItr = @@ -531,11 +555,11 @@ void TodTopologyManager::dumpTopology() const while(l_childList.end() != l_childItr) { TOD_INF("TOPOLOGY DUMP> 0x%08X---%s---%s---0x%08X", - (*l_procItr)->getTarget()->getAttr(), - busnames[(*l_childItr)->getBusIn()], - busnames[(*l_childItr)->getBusOut()], - (*l_childItr)->getTarget()->getAttr()); - ++l_childItr; + (*l_procItr)->getTarget()->getAttr(), + busnames[(*l_childItr)->getBusIn()], + busnames[(*l_childItr)->getBusOut()], + (*l_childItr)->getTarget()->getAttr()); + ++l_childItr; } ++l_procItr; } @@ -552,7 +576,7 @@ void TodTopologyManager::dumpTopology() const //****************************************************************************** void TodTopologyManager::dumpTodRegs() const { - TOD_ENTER("dumpTodRegs"); + TOD_ENTER(); static const char* topologynames[2] = {0}; topologynames[TOD_PRIMARY] = TOD_PRIMARY_TOPOLOGY; @@ -562,50 +586,63 @@ void TodTopologyManager::dumpTodRegs() const { TOD_INF("TOD REGDUMP> Start, topology type %s", topologynames[iv_topologyType]); + + fapi2::variable_buffer l_regData(64); //Get the TOD drawers TodDrawerContainer l_todDrwList; - TodControls::getTheInstance().getDrawers(iv_topologyType, l_todDrwList); + TOD::getDrawers(iv_topologyType, l_todDrwList); TodDrawerContainer::const_iterator l_drwItr = l_todDrwList.begin(); while(l_todDrwList.end() != l_drwItr) { TOD_INF("TOD REGDUMP> TOD Drawer(0x%.2X)",(*l_drwItr)->getId()); //Get the procs on this drawer TodProcContainer l_procList = (*l_drwItr)->getProcs(); - TodProcContainer::const_iterator l_procItr = l_procList.begin(); + TodProcContainer::const_iterator l_procItr = + l_procList.begin(); while(l_procList.end() != l_procItr) { TOD_INF("TOD REGDUMP> Proc HUID 0x%.8X", - (*l_procItr)->getTarget()->getAttr()); + (*l_procItr)->getTarget()->getAttr()); if(TodProc::TOD_MASTER == (*l_procItr)->getMasterType()) { - TOD_INF("TOD REGDUMP> This proc is the MDMT"); + TOD_INF("TOD REGDUMP> This proc is the MDMT"); } - else if(TodProc::DRAWER_MASTER == (*l_procItr)->getMasterType()) + else if(TodProc::DRAWER_MASTER == + (*l_procItr)->getMasterType()) { TOD_INF("TOD REGDUMP> This proc is the SDMT " " for this drawer"); } - proc_tod_setup_conf_regs l_todRegs; + p9_tod_setup_conf_regs l_todRegs; (*l_procItr)->getTodRegs(l_todRegs); + l_regData.set(l_todRegs.tod_m_path_ctrl_reg(), 0); TOD_INF("TOD REGDUMP> MASTER PATH CONTROL REG 0x%.16llX", - l_todRegs.tod_m_path_ctrl_reg.getDoubleWord(0)); + l_regData.get(0)); + l_regData.set(l_todRegs.tod_pri_port_0_ctrl_reg(), 0); TOD_INF("TOD REGDUMP> PORT 0 PRIMARY CONFIG REG 0x%.16llX", - l_todRegs.tod_pri_port_0_ctrl_reg.getDoubleWord(0)); + l_regData.get(0)); + l_regData.set(l_todRegs.tod_pri_port_1_ctrl_reg(), 0); TOD_INF("TOD REGDUMP> PORT 1 PRIMARY CONFIG REG 0x%.16llX", - l_todRegs.tod_pri_port_1_ctrl_reg.getDoubleWord(0)); + l_regData.get(0)); + l_regData.set(l_todRegs.tod_sec_port_0_ctrl_reg(), 0); TOD_INF("TOD REGDUMP> PORT 0 SECONDARY CONFIG REG 0x%.16llX", - l_todRegs.tod_sec_port_0_ctrl_reg.getDoubleWord(0)); + l_regData.get(0)); + l_regData.set(l_todRegs.tod_sec_port_1_ctrl_reg(), 0); TOD_INF("TOD REGDUMP> PORT 1 SECONDARY CONFIG REG 0x%.16llX", - l_todRegs.tod_sec_port_1_ctrl_reg.getDoubleWord(0)); + l_regData.get(0)); + l_regData.set(l_todRegs.tod_s_path_ctrl_reg(), 0); TOD_INF("TOD REGDUMP> SLAVE PATH CONTROL REG 0x%.16llX", - l_todRegs.tod_s_path_ctrl_reg.getDoubleWord(0)); + l_regData.get(0)); + l_regData.set(l_todRegs.tod_i_path_ctrl_reg(), 0); TOD_INF("TOD REGDUMP> INTERNAL PATH CONTROL REG 0x%.16llX", - l_todRegs.tod_i_path_ctrl_reg.getDoubleWord(0)); + l_regData.get(0)); + l_regData.set(l_todRegs.tod_pss_mss_ctrl_reg(), 0); TOD_INF("TOD REGDUMP> PRIMARY/SECONDARY MASTER/SLAVE CONTROL" " REG 0x%.16llX", - l_todRegs.tod_pss_mss_ctrl_reg.getDoubleWord(0)); + l_regData.get(0)); + l_regData.set(l_todRegs.tod_chip_ctrl_reg(), 0); TOD_INF("TOD REGDUMP> CHIP CONTROL REG 0x%.16llX", - l_todRegs.tod_chip_ctrl_reg.getDoubleWord(0)); + l_regData.get(0)); ++l_procItr; } ++l_drwItr; @@ -613,7 +650,63 @@ void TodTopologyManager::dumpTodRegs() const TOD_INF("TOD REGDUMP> End"); }while(0); - TOD_EXIT("dumpTodRegs"); + TOD_EXIT(); +} + +//****************************************************************************** +//TodTopologyManager::wireProcsInSmpWrapMode +//****************************************************************************** +errlHndl_t TodTopologyManager::wireProcsInSmpWrapMode( + TodProcContainer& io_sourcesList, + TodProcContainer& io_targetsList) +{ + TOD_ENTER(); + + errlHndl_t l_errHdl = NULL; + + do + { + TodProcContainer::iterator l_sourceItr = io_sourcesList.begin(); + TodProcContainer::iterator l_targetItr; + bool l_connected = false; + while((NULL == l_errHdl) && (io_sourcesList.end() != l_sourceItr)) + { + for(l_targetItr = io_targetsList.begin(); + l_targetItr != io_targetsList.end();) + { + l_errHdl = (*l_sourceItr)->connect(*l_targetItr, + TARGETING::TYPE_ABUS, + l_connected); + if(l_errHdl) + { + TOD_ERR("Error tying to connect target 0x%.8X " + "to source 0x%.8X.", + (*l_targetItr)->getTarget()-> + getAttr(), + (*l_sourceItr)->getTarget()-> + getAttr()); + break; + } + if(l_connected) + { + io_sourcesList.push_back(*l_targetItr); + (*l_sourceItr)->addChild(*l_targetItr); + l_targetItr = io_targetsList.erase(l_targetItr); + } + else + { + ++l_targetItr; + } + } + ++l_sourceItr; + } + }while(0); + + TOD_EXIT(); + + return l_errHdl; } } //namespace TOD + +} diff --git a/src/usr/isteps/istep18/TodTopologyManager.H b/src/usr/isteps/istep18/TodTopologyManager.H index 447fe44322f..7c992775a21 100755 --- a/src/usr/isteps/istep18/TodTopologyManager.H +++ b/src/usr/isteps/istep18/TodTopologyManager.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -24,19 +24,22 @@ /* IBM_PROLOG_END_TAG */ #ifndef TODTOPOLOGYMANAGER_H #define TODTOPOLOGYMANAGER_H - /** * @file TodTopologyManager.H * * @brief TOD Topology Manager class definition. Responsible for * creating/modifying the primary and secondary topologies - * - * HWP_IGNORE_VERSION_CHECK - * */ -#include -#include "proc_tod_utils/proc_tod_utils.H" + +//------------------------------------------------------------------------------ +//Includes +//------------------------------------------------------------------------------ + +#include "TodProc.H" + +//HWPF - For TOD constants +#include namespace TOD { @@ -45,7 +48,13 @@ namespace TOD //Forward declarations //------------------------------------------------------------------------------ class TodDrawer; +class TodControls; +/** + * @class TodSvc + * + * @brief Creates TOD topologies + */ class TodTopologyManager { public: @@ -62,7 +71,7 @@ public: * @param[in] i_type * Primary(TOD_PRIMARY) or Secondary(TOD_SECONDARY) */ - TodTopologyManager(const proc_tod_setup_tod_sel i_type); + TodTopologyManager(const p9_tod_setup_tod_sel i_type); /** * @brief Destructor. @@ -120,7 +129,7 @@ private: * processors in the input TOD drawer * * @param[in] i_pTodDrawer - * Pointer to a HwsvTodDrawer + * Pointer to a TodDrawer * * @return Error log handle indicating the status of the request. * @retval NULL if successful @@ -161,11 +170,42 @@ private: */ errlHndl_t wireTodDrawer(TodDrawer* i_pTodDrawer); + /** + * @brief Wires, or sets the A bus connection paths between + * intra-drawer processors. Such connections exist in the + * wrap test mode. + * + * @param[in/out] io_sourcesList + * List of procs that may be connected to. List grows as we + * connect procs, each newly connected proc is a potential + * source. + * + * @param[in/out] io_targetsList + * List of procs that need to be connected. Once a proc is + * connected, it is removed from this list. + * + * @return Error log handle indicating the status of the request. + * @retval NULL if successful + * @retval !NULL if failed to wire one or more procs in the TOD drawer + * + * Error log handle points to a valid error log object whose primary + * SRC reason code (pError->getSRC()->reasonCode()) indicates the type + * of error. + * + * @note It is up to the caller to change the severity of the + * returned error based on what it decides to do with it. By default + * any returned error created by this function will be a non-reported + * tracing event error log. + */ + errlHndl_t wireProcsInSmpWrapMode( + TodProcContainer& io_sourcesList, + TodProcContainer& io_targetsList); + //Holds the type of the topology this manager is working on : //primary/secondary - proc_tod_setup_tod_sel iv_topologyType; + p9_tod_setup_tod_sel iv_topologyType; + }; } //namespace TOD - #endif //#define TODTOPOLOGYMANAGER_H diff --git a/src/usr/isteps/istep18/TodTrace.H b/src/usr/isteps/istep18/TodTrace.H index 70246d89613..7aaa85ed90b 100644 --- a/src/usr/isteps/istep18/TodTrace.H +++ b/src/usr/isteps/istep18/TodTrace.H @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2016 */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -43,6 +43,8 @@ namespace TOD ERR_MRK" TOD:: " args) #define TOD_INF(args...) TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,\ INFO_MRK" TOD:: " args) +#define TOD_IMP(args...) TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,\ + INFO_MRK" TOD:: " args) // debug traces ------------------- diff --git a/src/usr/isteps/istep18/TodUtils.C b/src/usr/isteps/istep18/TodUtils.C new file mode 100644 index 00000000000..df1709f7d63 --- /dev/null +++ b/src/usr/isteps/istep18/TodUtils.C @@ -0,0 +1,172 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/isteps/istep18/TodUtils.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +// Includes +// /***********************************************************************/ + +#include "TodAssert.H" +#include "TodUtils.H" +#include +#include +#include +#include + +namespace TOD + +{ + +//****************************************************************************** +// isFunctional +//****************************************************************************** + +bool isFunctional(const TARGETING::Target* i_pTarget) +{ + //-------------------------------------------------------------------------- + // Local Variables + //-------------------------------------------------------------------------- + + errlHndl_t l_errl = NULL; + bool l_isFunctional = false; + + //-------------------------------------------------------------------------- + // Code + //-------------------------------------------------------------------------- + + if(i_pTarget) + { + // For now return true if state is FUNCTIONAL else false. + // There are total 4 HWAS functional states can exist: + // NON FUNCTIONAL,FUNCTIONAL,CM FUNCTIONAL and DUMP FUNCTIONAL. + // In-order to consider CM & DUMP FUNCTIONAL states we need to check + // whether system is in CM/DUMP mode. Since the CM/DUMP mode support + // is not available, we'll continue using FUNCTIONAL state only. + // Later we need to check for appropriate mode and state. + // @TODO via RTC: 69925 + l_isFunctional = + i_pTarget->getAttr().functional; + } + else + { + // If i_pTarget is NULL then create an error log + TOD_ERR("Input Target handle is null"); + + //Create error + /*@ + * @errortype + * @moduleid TOD_FUNCTIONAL_TARGET + * @reasoncode TOD_INVALID_TARGET + * @devdesc NULL Target is supplied as an input + * @custdesc Service Processor Firmware encountered an internal + * error + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_INFORMATIONAL, + TOD_FUNCTIONAL_TARGET, + TOD_INVALID_TARGET); + + errlCommit(l_errl, TOD_COMP_ID); + } + + return l_isFunctional; +} + + + +//****************************************************************************** +//todGetScom() +//****************************************************************************** +errlHndl_t todGetScom(const TARGETING::Target * i_target, + const uint64_t i_address, + fapi2::variable_buffer & o_data) +{ + errlHndl_t l_err = NULL; + + // Perform SCOM read + uint64_t l_data = 0; + size_t l_size = sizeof(uint64_t); + + l_err = deviceRead((TARGETING::Target *)i_target, + &l_data, + l_size, + DEVICE_SCOM_ADDRESS(i_address)); + + return l_err; +} + + +/*****************************************************************************/ +// getMaxConfigParams +/*****************************************************************************/ +errlHndl_t getMaxConfigParams( + maxConfigParamsContainer& o_maxConfigParams) +{ + TOD_ENTER("getMaxConfigParams"); + errlHndl_t l_err = NULL; + + do + { + //Get the top level (system) target handle + TARGETING::Target* l_pTopLevel = NULL; + (void)TARGETING::targetService().getTopLevelTarget(l_pTopLevel); + + // Assert on failure getting system target + if(NULL == l_pTopLevel) + { + TOD_ERR_ASSERT("NULL top level target found"); + break; + + } + // Top level target successfully retrieved. Now get attributes + + o_maxConfigParams.max_procchips_per_node = l_pTopLevel->getAttr + < TARGETING::ATTR_MAX_PROC_CHIPS_PER_NODE > (); + + o_maxConfigParams.max_exs_per_procchip = l_pTopLevel->getAttr + < TARGETING::ATTR_MAX_EXS_PER_PROC_CHIP > (); + + o_maxConfigParams.max_dimms_per_mbaport = l_pTopLevel->getAttr + < TARGETING::ATTR_MAX_DIMMS_PER_MBA_PORT > (); + + o_maxConfigParams.max_mbaports_per_mba = l_pTopLevel->getAttr + < TARGETING::ATTR_MAX_MBA_PORTS_PER_MBA > (); + + o_maxConfigParams.max_mbas_per_membuf = l_pTopLevel->getAttr + < TARGETING::ATTR_MAX_MBAS_PER_MEMBUF_CHIP > (); + + o_maxConfigParams.max_chiplets_per_proc = l_pTopLevel->getAttr + < TARGETING::ATTR_MAX_CHIPLETS_PER_PROC > (); + + o_maxConfigParams.max_mcs_per_sys = l_pTopLevel->getAttr + < TARGETING::ATTR_MAX_MCS_PER_SYSTEM > (); + + } while(0); + + TOD_EXIT(); + + return l_err; +} + +}//end of TOD namespace + diff --git a/src/usr/isteps/istep18/TodUtils.H b/src/usr/isteps/istep18/TodUtils.H new file mode 100644 index 00000000000..83d942617b1 --- /dev/null +++ b/src/usr/isteps/istep18/TodUtils.H @@ -0,0 +1,212 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/isteps/istep18/TodUtils.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2010,2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __TOD_HOSTBOOT_H +#define __TOD_HOSTBOOT_H + + +#include +#include +#include +#include "TodTrace.H" +#include + +//FIX_ME_BEFORE_PRODUCTION_Q12 Update these + +//moved from mboxclientlib.H +/** @enum mboxTodTopologyAction + * Values used to determine whether to enable, disable or switch TOD + * topologies. + */ +enum mboxTodTopologyAction +{ + MBOX_DISABLE_TOPOLOGY = 0, + MBOX_ENABLE_TOPOLOGY = 1, + MBOX_SWITCH_TOPOLOGY = 99 +}; // end mboxTodTopologyAction + +/** @enum mboxTopologyValue + * Values used to determine whether to enable, disable or switch TOD + * topologies. + */ +enum mboxTopologyValue +{ + MBOX_PRIMARY_TOPOLOGY = 0, + MBOX_SECONDARY_TOPOLOGY = 1 +}; // end mboxTopologyValue + +/** + * Retrieve the CLASS of the target, or return NA if the target is NULL + */ +#define GETCLASS(pTarget) (((pTarget) == NULL) ? (TARGETING::CLASS_NA) : \ + ((pTarget)->getAttr())) + +/** + * * Retrieve the TYPE of the target, or return NA if the target is NULL + * */ +#define GETTYPE(pTarget) (((pTarget) == NULL) ? (TARGETING::TYPE_NA) : \ + ((pTarget)->getAttr())) + + +namespace TOD +{ + +struct maxConfigParams +{ + uint8_t max_procchips_per_node; // This will contain the maximum proc + // chips per Node available on the system + uint8_t max_exs_per_procchip; // This will contain the maximum cores per + // proc chip on the system + uint8_t max_dimms_per_mbaport; // This will contain the maximum dimms per + // MBA Port available on the system + uint8_t max_mbaports_per_mba; // This will contain the maximum MBA Ports + // per MBA available on the system + uint8_t max_mbas_per_membuf; // This will contain the maximum MBA per + // Memory Buffer available on the system + uint8_t max_psilinks_per_fsp; // This will contain the maximum psi links + // per fsp which is same on all Systems + uint8_t min_psilinks_per_fsp; // This will contain minimum number of psi + // links per fsp present in the system + uint8_t max_chiplets_per_proc; // This will contain the maximum chiplets + // per proc available on the System + uint8_t max_mcs_per_sys; // This will contain max mcs + // present in the system + uint8_t max_compute_nodes_per_sys; // This will contain max compute + // nodes present in the system + uint8_t max_exs_per_procchip_archlimit; // This will contain max + // Architecture limit of max exs + // per proc chip + + /** + * @brief Copies the data from maxConfigParams structure into the buffer + * @par Detailed Description + * Copies the data from maxConfigParams structure into the buffer + * + * @param[out] o_utilBuf + * Output buffer in which the data from the structure will be copied + * This buffer will be cleared and data will be written from beginning of + * the stream. After the data is updated ,the buffer pointer will be + * pointing to the end of the inserted data + * + * @return Error log handle indicating the status of the request + * + * @retval NULL Successfully copied the data from maxConfigParams structure + * into the buffer + * @retval !NULL Failed to copy the data from maxConfigParams structure + * into the buffer + * + * Error log handle points to a valid error log object whose + * primary SRC reason code (pError->getSRC()->reasonCode()) indicates + * the type of error. + * + * @note It is up to the caller to change the severity of the + * returned error based on what it decides to do with it. By + * default any returned error created by this function will be a + * non-reported tracing event error log. + * + */ + + errlHndl_t flatten(UtilMem& o_utilBuf )const ; + + + /** + * @brief Copies the data from the input buffer to the maxConfigParams + * structure + * @par Detailed Description + * Copies the data from the input buffer to the maxConfigParams + * structure + * + * @param[in] i_utilBuf + * Input buffer from which the data will be copied to the structure + * @note Input buffer must contain only the maxConfigParams info and + * the buffer pointer must be pointing to index 0 of the buffer. + * The call will not alter any error in the existing input stream + * + * @return Error log handle indicating the status of the request + * + * @retval NULL Successfully copied the data from buffer into the + * maxConfigParams structure + * @retval !NULL Failed to copy the data from buffer into the + * maxConfigParams structure + * + * Error log handle points to a valid error log object whose + * primary SRC reason code (pError->getSRC()->reasonCode()) indicates + * the type of error. + * + * @note It is up to the caller to change the severity of the + * returned error based on what it decides to do with it. By + * default any returned error created by this function will be a + * non-reported tracing event error log. + * + * + */ + + errlHndl_t unflatten(const UtilMem& i_utilBuf); + + + /** + * @brief Returns the Size of data which is held in the maxConfigParams + * structure + * @par Detailed Description + * Returns the size of data which is held in the maxConfigParams structure + * + * + * @return + * Returns the size of data which is held in the maxConfigParams structure + */ + + uint32_t flattenSize(void) const; +}; + +typedef maxConfigParams maxConfigParamsContainer; + + +errlHndl_t getMaxConfigParams(maxConfigParamsContainer& o_maxConfigParams); + +#define GETHUID(pTarget) (((pTarget) == NULL) ? (0) : \ + ((pTarget)->getAttr())) + +//moved from fapi_sbe_common.H +#define CONST_UINT64_T(name, expr) const uint64_t name = (expr); +#define ULL(x) x##ull +//moved from p8_scom_addresses.H +CONST_UINT64_T( TOD_PSS_MSS_STATUS_REG_00040008 , ULL(0x00040008) ); + +//****************************************************************************** +// isFunctional +//****************************************************************************** + +bool isFunctional(const TARGETING::Target* i_pTarget); + + +//moved from TodSvcUtil.C from open powervm p8 +//****************************************************************************** +// todGetScom +//****************************************************************************** +errlHndl_t todGetScom(const TARGETING::Target * i_target, + const uint64_t i_address, + fapi2::variable_buffer & o_data); +}// end of namespace + +#endif //end of .H file diff --git a/src/usr/isteps/istep18/tod_init.H b/src/usr/isteps/istep18/call_tod_init.C similarity index 62% rename from src/usr/isteps/istep18/tod_init.H rename to src/usr/isteps/istep18/call_tod_init.C index 79e0de560ad..7b8391a923b 100644 --- a/src/usr/isteps/istep18/tod_init.H +++ b/src/usr/isteps/istep18/call_tod_init.C @@ -1,7 +1,7 @@ /* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ -/* $Source: src/usr/isteps/istep18/tod_init.H $ */ +/* $Source: src/usr/isteps/istep18/call_tod_init.C $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ @@ -22,15 +22,51 @@ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ -#ifndef TOD_INIT_H -#define TOD_INIT_H + +/** + * @file call_tod_init.C + * + * HWP_IGNORE_VERSION_CHECK + * + */ + +/******************************************************************************/ +// Includes +/******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "TodTrace.H" +#include "TodSvc.H" + +using namespace ISTEP_ERROR; namespace ISTEP_18 { - void build_proc_topology(tod_topology_node &i_tod_node); - void delete_proc_topology(tod_topology_node &i_tod_node); +void * call_tod_init(void *dummy) +{ + IStepError l_stepError; + errlHndl_t l_errl = NULL; + TOD_ENTER("call_tod_init"); + + if (!INITSERVICE::spBaseServicesEnabled()) + { + l_errl = TOD::todInit(); -}; + if (l_errl) + { + l_stepError.addErrorDetails( l_errl ); + TOD_ERR("todInit() return errl handle %p", l_errl); + errlCommit( l_errl, TOD_COMP_ID ); + } + } + return l_stepError.getErrorHandle(); +} -#endif +} // end namespace diff --git a/src/usr/isteps/istep18/call_tod_setup.C b/src/usr/isteps/istep18/call_tod_setup.C new file mode 100644 index 00000000000..4624d14c573 --- /dev/null +++ b/src/usr/isteps/istep18/call_tod_setup.C @@ -0,0 +1,73 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/isteps/istep18/call_tod_setup.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/** + * @file call_tod_setup.C + * + * HWP_IGNORE_VERSION_CHECK + * + */ + +/******************************************************************************/ +// Includes +/******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#include "TodTrace.H" +#include "TodSvc.H" + +using namespace ISTEP_ERROR; + +namespace ISTEP_18 +{ + +void * call_tod_setup(void *dummy) +{ + IStepError l_stepError; + errlHndl_t l_errl = NULL; + + TOD_ENTER("call_tod_setup"); + + if (!INITSERVICE::spBaseServicesEnabled()) + { + l_errl = TOD::todSetup(); + + if (l_errl) + { + l_stepError.addErrorDetails( l_errl ); + TOD_ERR("todSetup() return errl handle %p", l_errl); + errlCommit( l_errl, TOD_COMP_ID ); + } + } + return l_stepError.getErrorHandle(); +} + +} // end namespace diff --git a/src/usr/isteps/istep18/makefile b/src/usr/isteps/istep18/makefile index 005e6764090..39ed9f43927 100644 --- a/src/usr/isteps/istep18/makefile +++ b/src/usr/isteps/istep18/makefile @@ -25,36 +25,32 @@ ROOTPATH = ../../../.. MODULE = istep18 -PROCEDURES_PATH = ${ROOTPATH}/src/import/chips/p9/procedures - -NEST_HWP_PATH += ${PROCEDURES_PATH}/hwp/nest - - -VPATH += ${NEST_HWP_PATH} - -#Add all the objs for istep 18 -OBJS += tod_init.o - -#Add all the extra include paths -EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2 -EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/common/include -EXTRAINCDIR += ${NEST_HWP_PATH} -EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include -EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils/imageProcs/ -EXTRAINCDIR += ${ROOTPATH}/src/include/usr/isteps +PROCEDURES_PATH = ${ROOTPATH}/src/import/chips/p9/procedures/hwp/nest ## support for Targeting and fapi -EXTRAINCDIR += ${ROOTPATH}/src/include/usr/ecmddatabuffer -EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/tod_init EXTRAINCDIR += ${PROCEDURES_PATH} +EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include +EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2 +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils/imageProcs +## pointer to common HWP files -#Required include before all the procedure.mk are included -include ${ROOTPATH}/procedure.rules.mk - -#Include all the procedure makefiles -include $(NEST_HWP_PATH)/p9_tod_utils.mk -include $(NEST_HWP_PATH)/p9_tod_setup.mk -include $(NEST_HWP_PATH)/p9_tod_init.mk +OBJS += call_tod_init.o +OBJS += call_tod_setup.o +OBJS += TodControls.o +OBJS += TodDrawer.o +OBJS += TodProc.o +OBJS += TodSvc.o +OBJS += TodUtils.o +OBJS += TodSvcUtil.o +OBJS += TodHwpIntf.o +OBJS += TodTopologyManager.o +include ${ROOTPATH}/procedure.rules.mk +include ${PROCEDURES_PATH}/p9_tod_init.mk +include ${PROCEDURES_PATH}/p9_tod_setup.mk +include ${PROCEDURES_PATH}/p9_tod_utils.mk +include ${PROCEDURES_PATH}/p9_tod_save_config.mk include ${ROOTPATH}/config.mk + +VPATH += ${PROCEDURES_PATH} diff --git a/src/usr/isteps/istep18/tod_init.C b/src/usr/isteps/istep18/tod_init.C deleted file mode 100644 index 7a63c961fb0..00000000000 --- a/src/usr/isteps/istep18/tod_init.C +++ /dev/null @@ -1,248 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/usr/isteps/istep18/tod_init.C $ */ -/* */ -/* OpenPOWER HostBoot Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2016,2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -/** - * @file tod_init.C - * - * HWP_IGNORE_VERSION_CHECK - * - */ - -/******************************************************************************/ -// Includes -/******************************************************************************/ - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include - - -#include -#include - -#include "TodTrace.H" -#include "tod_init.H" - - -namespace ISTEP_18 -{ - -void * call_tod_setup(void *dummy) -{ - errlHndl_t l_errl = NULL; - - TOD_ENTER("call_tod_setup"); - - //Hack job to get things going while waiting for true - //TOD support - //@TODO RTC:149253 replace with full content - if (!INITSERVICE::spBaseServicesEnabled()) - { - //Initialize the iv_tod_node_data structure - tod_topology_node l_tod_node; - build_proc_topology(l_tod_node); - - FAPI_INVOKE_HWP( l_errl, p9_tod_setup, - &l_tod_node, - TOD_PRIMARY, - TOD_OSC_0 ); - - if (l_errl) - { - TOD_ERR("todSetup() return errl handle %p", l_errl); - errlCommit( l_errl, TOD_COMP_ID ); - } - delete_proc_topology(l_tod_node); - } - - return l_errl; // //@TODO RTC:149253 update later -} - -void * call_tod_init(void *dummy) -{ - errlHndl_t l_errl = NULL; - TOD_ENTER("call_init"); - - - // @TODO RTC:149253 - Replace below with full functionality - if (!INITSERVICE::spBaseServicesEnabled()) - { - TARGETING::Target* l_masterproc = nullptr; - TARGETING::targetService().masterProcChipTargetHandle(l_masterproc); - fapi2::Target - l_fapi2_proc_target (l_masterproc); - - //Initialize the iv_tod_node_data structure - tod_topology_node l_tod_node; - build_proc_topology(l_tod_node); - - FAPI_INVOKE_HWP( l_errl, p9_tod_init, - &l_tod_node, - NULL); - - if (l_errl) - { - TOD_ERR("todInit() return errl handle %p", l_errl); - errlCommit( l_errl, TOD_COMP_ID ); - } - - //Clear up TOD data - delete_proc_topology(l_tod_node); - } - - return l_errl; //@TODO RTC:149253 update later -} - - -void build_proc_topology(tod_topology_node &i_tod_node) -{ - - // @TODO RTC:149253 - if (!INITSERVICE::spBaseServicesEnabled()) - { - //Get top level target - TARGETING::Target* pSys; - TARGETING::targetService().getTopLevelTarget(pSys); - - //Create predicate to find Functional Procs - TARGETING::PredicateCTM l_procFilter(TARGETING::CLASS_CHIP, - TARGETING::TYPE_PROC); - TARGETING::PredicateHwas l_funcPred; - l_funcPred.functional(true); - TARGETING::PredicatePostfixExpr l_funcProcPostfixExpr; - l_funcProcPostfixExpr.push(&l_procFilter).push(&l_funcPred).And(); - - //Get the procs in a list - TARGETING::TargetHandleList l_procs; - TARGETING::targetService().getAssociated(l_procs, - pSys, - TARGETING::TargetService::CHILD, - TARGETING::TargetService::ALL, - &l_funcProcPostfixExpr); - - TARGETING::Target* l_masterproc = nullptr; - TARGETING::targetService().masterProcChipTargetHandle(l_masterproc); - fapi2::Target* l_fapi2_proc_target = - new fapi2::Target(l_masterproc); - - i_tod_node.i_target = l_fapi2_proc_target; - i_tod_node.i_tod_master = true; - i_tod_node.i_drawer_master = true; - i_tod_node.i_bus_rx = NONE; - i_tod_node.i_bus_tx = NONE; - i_tod_node.i_children.clear(); - - //Iterate through functional procs setting base TOD information - for (auto l_proc : l_procs) - { - //Add children to TOD Structure of master proc - if (l_proc != l_masterproc) - { - TOD_INF("Found non-master proc, adding to TOD topology"); - - tod_topology_node * l_tod_proc = new tod_topology_node; - - fapi2::Target* - l_fapi2_proc_target= - new fapi2::Target(l_proc); - - l_tod_proc->i_target = l_fapi2_proc_target; - l_tod_proc->i_tod_master = false; - l_tod_proc->i_drawer_master = true; - - auto l_xbus_targets = - l_fapi2_proc_target->getChildren(); - - for (auto l_xbus : l_xbus_targets) - { - if (l_xbus.isFunctional()) - { - const TARGETING::Target * l_xTarget = - static_cast(l_xbus); - switch (l_xTarget->getAttr()) - { - case 0 : l_tod_proc->i_bus_rx = XBUS0; - l_tod_proc->i_bus_tx = XBUS0; - TOD_DTRAC("XBUS 0 Functional"); - break; - case 1 : l_tod_proc->i_bus_rx = XBUS1; - l_tod_proc->i_bus_tx = XBUS1; - TOD_DTRAC("XBUS 1 Functional"); - break; - case 2 : l_tod_proc->i_bus_rx = XBUS2; - l_tod_proc->i_bus_tx = XBUS2; - TOD_DTRAC("XBUS 2 Functional"); - break; - } - } - } - - //Child proc should have no children - l_tod_proc->i_children.clear(); - - //Add non-master proc as child of master proc in the - // TOD topology - i_tod_node.i_children.push_back(l_tod_proc); - } - } - } - - return; -} - -void delete_proc_topology(tod_topology_node &i_tod_node) -{ - if (i_tod_node.i_target != NULL) - { - delete i_tod_node.i_target; - i_tod_node.i_target = NULL; - } - - for (auto l_child_node : i_tod_node.i_children) - { - if (l_child_node->i_target != NULL) - { - delete l_child_node->i_target; - l_child_node->i_target = NULL; - } - - delete l_child_node; - } -} - -}; // end namespace diff --git a/src/usr/targeting/common/xmltohb/simics_NIMBUS.system.xml b/src/usr/targeting/common/xmltohb/simics_NIMBUS.system.xml index 811ca2c14ce..211b82a55f1 100644 --- a/src/usr/targeting/common/xmltohb/simics_NIMBUS.system.xml +++ b/src/usr/targeting/common/xmltohb/simics_NIMBUS.system.xml @@ -179,6 +179,10 @@ MSS_MRW_THERMAL_MEMORY_POWER_LIMIT 0xFFFFF800000006AE + + MAX_PROC_CHIPS_PER_NODE + 2 +