//****************************************************************************** //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"); l_errHdl->setSev(ERRORLOG::ERRL_SEV_UNRECOVERABLE); errlCommit(l_errHdl, TOD_COMP_ID); break; } }while(0); TOD_EXIT(); return l_errHdl; }
//****************************************************************************** //TodSvc::~TodSvc //****************************************************************************** TodSvc::~TodSvc() { TOD_ENTER(); //Free up held memory TOD::destroy(TOD_PRIMARY); TOD::destroy(TOD_SECONDARY); TOD_EXIT(); }
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 > (); o_maxConfigParams.max_compute_nodes_per_sys = l_pTopLevel->getAttr < TARGETING::ATTR_MAX_COMPUTE_NODES_PER_SYSTEM > (); } while(0); TOD_EXIT(); return l_err; }
//****************************************************************************** //TodSvc::readTod //****************************************************************************** errlHndl_t TodSvc::readTod(uint64_t& o_todValue) const { TOD_ENTER("readTod"); errlHndl_t l_errHdl = NULL; do { 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("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 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.", PERV_TOD_VALUE_REG, GETHUID(l_mdmtOnActiveTopology)); break; } o_todValue = o_todValueBuf.get<int32_t>(0); }while(0); TOD_EXIT(); return l_errHdl; }
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(); }
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<TARGETING::ATTR_IS_MPIPL_HB>()) { TOD_INF("In MPIPL path"); o_mpIPL = true; } }while(0); TOD_EXIT( "Output Params - o_mpIPL: %d", o_mpIPL ); return l_errHdl; }
//***************************************************************************** // resetBackupTopology //***************************************************************************** errlHndl_t resetBackupTopology( uint32_t i_oscPos, const TARGETING::TargetHandle_t& i_procOscTgt, const TARGETING::TargetHandleList& i_badChipList, bool i_informPhyp) { TOD_ENTER("resetBackupTopology"); errlHndl_t l_err = nullptr; // Put the handle to the firmware_request request struct // out here so it is easier to free later hostInterfaces::hbrt_fw_msg *l_req_fw_msg = nullptr; hostInterfaces::hbrt_fw_msg *l_resp_fw_msg = nullptr; do { if ((nullptr == g_hostInterfaces) || (nullptr == g_hostInterfaces->firmware_request)) { TOD_ERR("resetBackupTopology: " "Hypervisor firmware_request interface not linked"); /*@ * @errortype * @severity ERRL_SEV_UNRECOVERABLE * @moduleid TOD_RT_TOPOLOGY_RESET_BACKUP * @reasoncode TOD_RT_NULL_FIRMWARE_REQUEST_PTR * @userdata1 None * @userdata2 None * @devdesc Host interfaces are not initialized * @custdesc An internal error occurred. This will * force the Time of Day function to run * with complete redundancy. */ l_err = new ErrlEntry( ERRL_SEV_UNRECOVERABLE, TOD_RT_TOPOLOGY_RESET_BACKUP, TOD_RT_NULL_FIRMWARE_REQUEST_PTR, 0, 0, true); break; } // The format of the data to be sent, according to the document // "Handle PRD Request for resetting backup TOD topology" is as follows // All data members below are 4 bytes long (32 bits) // Ordinal ID - 0xFFFFFFFF means no OSC to be avoided // HUID of the node - This field should be considered only if Ordinal // ID is NOT set to 0xFFFFFFFF otherwise it is set // to 0 // HUID of the first processor // HUID of the second processor, etc // Check if we get conflicting data, if so send a Trace out if ((0xFFFFFFFF == i_oscPos) && (nullptr != i_procOscTgt)) { TOD_ERR("Conflicting input data, input oscillator position " "(i_oscPos) has value 0xFFFFFFFF, meaning no oscillator " "to be avoided but input oscillator target (i_procOscTgt) " "has a valid value" ); } else if ((0xFFFFFFFF != i_oscPos) && (nullptr == i_procOscTgt)) { TOD_ERR("Conflicting input data, input oscillator position " "(i_oscPos) has value 0x%X, meaning avoid oscillator " "but input oscillator target (i_procOscTgt) " "has a NULL value", i_oscPos); } // Flag to determine if the OSC data will be added to the data bool l_addOscData = (0xFFFFFFFF != i_oscPos) && (nullptr != i_procOscTgt); // Default the request data size to the size of the // GenericFspMboxMessage_t minus the size of the // GenericFspMboxMessage_t's data. The size of the // GenericFspMboxMessage_t's data will be added later uint32_t l_req_data_size = sizeof(GenericFspMboxMessage_t) - sizeof(GenericFspMboxMessage_t::data); // Add to the request data size iff there is data needing to be passed if (i_badChipList.size() > 0) { // if the bad chip list has any items then increase size to // accommodate for an ordinal ID and a HUID, regardless if // they have relevant data or not, because they are expected // before the HUID list. l_req_data_size += (MSG_OSC_SIZE_OF_DETAILS * sizeof(uint32_t)) + (i_badChipList.size() * sizeof(uint32_t)); } else if (l_addOscData) { // if there is a valid OSC then accommodate for an ordinal ID // and HUID of node, but don't need space for HUID list because, // if we are here, the list is empty l_req_data_size += (MSG_OSC_SIZE_OF_DETAILS * sizeof(uint32_t)); } // The request data size must be at a minimum the size of the // FSP generic message (sizeof(GenericFspMboxMessage_t)) if (l_req_data_size < sizeof(GenericFspMboxMessage_t)) { l_req_data_size = sizeof(GenericFspMboxMessage_t); } // Calculate the TOTAL size of hostInterfaces::hbrt_fw_msg which // means only adding hostInterfaces::HBRT_FW_MSG_BASE_SIZE to // the previous calculated request data size uint64_t l_req_fw_msg_size = hostInterfaces::HBRT_FW_MSG_BASE_SIZE + l_req_data_size; // Create the firmware_request request struct to send data l_req_fw_msg = (hostInterfaces::hbrt_fw_msg *)malloc(l_req_fw_msg_size); // Initialize the firmware_request request struct l_req_fw_msg->generic_msg.initialize(); // Populate the firmware_request request struct with given data l_req_fw_msg->io_type = hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ; l_req_fw_msg->generic_msg.dataSize = l_req_data_size; l_req_fw_msg->generic_msg.msgq = MBOX::FSP_TOD_MSGQ; l_req_fw_msg->generic_msg.msgType = (false == i_informPhyp ? GenericFspMboxMessage_t::MSG_TOD_BACKUP_RESET: GenericFspMboxMessage_t::MSG_TOD_BACKUP_RESET_INFORM_PHYP); l_req_fw_msg->generic_msg.__req = GenericFspMboxMessage_t::REQUEST; // A convenient way to populate the data uint32_t* l_dataPtr = reinterpret_cast<uint32_t*>(&(l_req_fw_msg->generic_msg.data)); if (i_badChipList.size() > 0) { // set the ordinal ID l_dataPtr[MSG_OSC_ORDINAL_ID_LOC] = i_oscPos; // attach the HUIDs from bad chip list to end of struct size_t i = MSG_OSC_HUIDS_LOC; for (auto l_target : i_badChipList) { l_dataPtr[i++] = GETHUID(l_target); } } // Set the HUID of the ordinal node if need be if (l_addOscData) { // set the ordinal ID l_dataPtr[MSG_OSC_ORDINAL_ID_LOC] = i_oscPos; // Get the parent node target TARGETING::TargetHandleList l_list; TARGETING::targetService().getAssociated(l_list, i_procOscTgt, TARGETING::TargetService::PARENT, TARGETING::TargetService::IMMEDIATE); if (l_list.size() == 1) { l_dataPtr[MSG_OSC_ORDINAL_NODE_HUID_LOC] = GETHUID(l_list[0]); } else { /*@ * @errortype * @severity ERRL_SEV_UNRECOVERABLE * @moduleid TOD_RT_TOPOLOGY_RESET_BACKUP * @reasoncode TOD_INVALID_TARGET * @userdata1 The number of parents found osc target * @userdata2 None * @devdesc No/Multiple parent(s) found for * processor osc target * @custdesc An internal error occurred. This will * force the Time of Day function to run * with complete redundancy. */ l_err = new ErrlEntry(ERRL_SEV_UNRECOVERABLE, TOD_RT_TOPOLOGY_RESET_BACKUP, TOD_INVALID_TARGET, l_list.size(), 0, true); break; } } // Create the firmware_request response struct to receive data // NOTE: For messages to the FSP the response size must match // the request size uint64_t l_resp_fw_msg_size = l_req_fw_msg_size; l_resp_fw_msg = (hostInterfaces::hbrt_fw_msg *)malloc(l_resp_fw_msg_size); memset(l_resp_fw_msg, 0, l_resp_fw_msg_size); // Trace out the request structure TRACFBIN(ISTEPS_TRACE::g_trac_isteps_trace, INFO_MRK"TOD::Sending firmware_request", l_req_fw_msg, l_req_fw_msg_size); // Make the firmware_request call l_err = firmware_request_helper(l_req_fw_msg_size, l_req_fw_msg, &l_resp_fw_msg_size, l_resp_fw_msg); if (l_err) { break; } } while (0); // Release the firmware messages free(l_req_fw_msg); free(l_resp_fw_msg); l_req_fw_msg = l_resp_fw_msg = nullptr; TOD_EXIT("resetBackupTopology"); return l_err; } // end resetBackupTopology
errlHndl_t resetBackupTopologyPortedCoded( const TARGETING::TargetHandleList& i_badChipList, bool i_informPhyp) { TOD_ENTER("resetBackupTopology"); errlHndl_t l_err = nullptr; bool l_deleteOnFailure = false; // l_backupConfig will be set again after determining the non-active // topology from register values p9_tod_setup_tod_sel l_backupConfig = TOD_SECONDARY; // NOTE: Not sure if this is needed - no direct port // util::ScopeLock l_lock(iv_mutexTodAccess); do { p9_tod_setup_tod_sel l_activeConfig = TOD_PRIMARY; bool l_isTodRunning = false; TARGETING::Target* l_mdmtOnActiveTopology = NULL; bool l_getTodRunningStatus = true; // Get the currently active TOD configuration l_err = TOD::queryActiveConfig(l_activeConfig, l_isTodRunning, l_mdmtOnActiveTopology, l_getTodRunningStatus); if ( l_err ) { TOD_ERR("Call to queryActiveConfig failed "); break; } if ( !l_isTodRunning ) { TOD_ERR("TOD HW logic is not running,only use case of " " resetBackup is when TOD is already running "); /*@ * @errortype * @moduleid TOD::TOD_RESET_BACKUP * @reasoncode TOD::TOD_INVALID_ACTION * @userdata1 ChipTOD logic HW state, 1 means running, zero * otherwise * @devdesc Error: TOD HW logic is not running, only use case * of resetBackup is when TOD is already running * @custdesc Host failed to boot because there was a problem * configuring Time Of Day on the Host processors */ l_err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_INFORMATIONAL, TOD_RESET_BACKUP, TOD_INVALID_ACTION, l_isTodRunning); break; } l_backupConfig = (( l_activeConfig == TOD_PRIMARY) ? TOD_SECONDARY : TOD_PRIMARY ); TOD_INF("Currently active topology ==> %s, and inactive ==> %s", TodSvcUtil::topologyTypeToString(l_activeConfig), TodSvcUtil::topologyTypeToString(l_backupConfig) ); // PHYP needs to be informed that it won't have a // backup available for failover while we are reconfiguring it. // Not all the cases will require HWSV to inform PHYP because in some // of the case PHYP would have already initiated a failover before // PRD asks HWSV to reconfigure backup. // This indication is sent by PRD after the analysis of TOD error // If this method is initiated by PHYP's message to MBOX to reset the // backup topology this parameter will be always false. if ( i_informPhyp ) { TOD_INF("Sending request to PHYP to disable the %s", TodSvcUtil::topologyTypeToString(l_backupConfig)); // NOTE: Not sure if this is needed - no direct port // l_err = mboxControlTodTopology(MBOX_DISABLE_TOPOLOGY, // (( l_backupConfig == TOD_PRIMARY)? // MBOX_PRIMARY_TOPOLOGY : MBOX_SECONDARY_TOPOLOGY)); if ( l_err ) { TOD_ERR("Request to PHYP for disabling the %s,that is " "currently inactive failed", TodSvcUtil::topologyTypeToString(l_backupConfig)); break; } TOD_INF("Got response from PHYP, for the request to disable" "inactive topology "); } // Mark configured state to false TOD::setConfigStatus(l_backupConfig,false); // Destroy the backup topology in case it exists, this is copy of // topology in volatile memory so it won't matter even if we fail // somewhere TOD::destroy(l_backupConfig); // Build blacklist information l_err = TOD::buildBlackList(i_badChipList); if ( l_err ) { TOD_ERR("Call to buildBlackList failed "); break; } //Build the list of garded TOD targets l_err = TOD::buildGardedTargetsList(); if ( l_err ) { TOD_ERR("Call to buildGardedTargetsList failed"); break; } // Build a set of datastructures to setup creation of the TOD topology l_err = TOD::buildTodDrawers(l_backupConfig); if ( l_err ) { TOD_ERR("TOD setup failure: failed to build TOD drawers " "for %s", TodSvcUtil::topologyTypeToString(l_backupConfig)); break; } // From here on if resetBackup failed, we will do the cleanup at the end l_deleteOnFailure = true; //Before we ask HwsvTodTopologyManager to create a new backup //topology let us make sure that we have MDMT set in TOD Controls for //the active topology, if there was RR then the copy of //topology in main memory would have got erased //MDMT of the active topology should be avoided while choosing MDMT for //backup if ( !(TOD::getConfigStatus(l_activeConfig)) && TOD::getMDMT(l_activeConfig) ) { l_err = Singleton<TodSvc>::instance(). setActiveMdmtForResetBackup(l_activeConfig); if ( l_err ) { TOD_ERR("setActiveMdmtForResetBackup failed for " " %s", TodSvcUtil::topologyTypeToString(l_activeConfig)); break; } } // Ask the topology manager to setup the backup topology TodTopologyManager l_backupTopology(l_backupConfig); l_err = l_backupTopology.create(); if ( l_err ) { TOD_ERR("TOD setup failure: failed to create %s", TodSvcUtil::topologyTypeToString(l_backupConfig)); break; } l_backupTopology.dumpTopology(); //Call hardware procedures to configure the TOD hardware logic for //the backup topology and to fill up the TOD regs. l_err = TOD::todSetupHwp(l_backupConfig); if ( l_err ) { TOD_ERR("TOD setup failure: secondary topology setup HWP."); break; } // Save the TOD registers into the local data structures l_err = todSaveRegsHwp(l_backupConfig); if ( l_err ) { TOD_ERR("todSaveRegsHwp failed for the %s", TodSvcUtil::topologyTypeToString(l_backupConfig)); break; } l_backupTopology.dumpTodRegs(); // Sending request to PHYP to enable the inactive TOD_INF("Sending request to PHYP to enable the inactive %s", TodSvcUtil::topologyTypeToString(l_backupConfig)); // Inform PHYP about the availability of backup topology // NOTE: Not sure if this is needed - no direct port // l_err = mboxControlTodTopology(MBOX_ENABLE_TOPOLOGY, // ( l_backupConfig == TOD_PRIMARY)? MBOX_PRIMARY_TOPOLOGY // : MBOX_SECONDARY_TOPOLOGY ); if ( l_err ) { TOD_ERR("Request to PHYP for disabling the %s,that is curently" "backup, failed ", TodSvcUtil::topologyTypeToString(l_backupConfig)); break; } TOD_INF("Got response from PHYP, for the request to enable" "inactive topology "); // Write this information to the persistant file l_err = TOD::writeTodProcData(l_backupConfig); if( l_err ) { TOD_ERR("TOD setup failure:Failed to write topology register data" " to the file."); break; } // Backup successfully configured TOD::setConfigStatus(l_backupConfig, true); } while (0); if ( l_err && l_deleteOnFailure ) { TOD::destroy(l_backupConfig); } TOD::clearGardedTargetsList(); TOD_EXIT("resetBackupTopology"); return l_err; } // end resetBackupTopologyPortedCoded
//***************************************************************************** // readTodProcDataFromFile //***************************************************************************** errlHndl_t readTodProcDataFromFile(TodChipDataContainer& o_todChipData) { TOD_ENTER("readTodProcDataFromFile"); errlHndl_t l_err = nullptr; // Put the handle to the firmware messages out here // so it is easier to free later hostInterfaces::hbrt_fw_msg *l_req_fw_msg = nullptr; hostInterfaces::hbrt_fw_msg *l_resp_fw_msg = nullptr; // clear the out data, regardless of the code to follow o_todChipData.clear(); do { if ((nullptr == g_hostInterfaces) || (nullptr == g_hostInterfaces->firmware_request)) { TOD_ERR("readTodProcDataFromFile: " "Hypervisor firmware_request interface not linked"); /*@ * @errortype * @severity ERRL_SEV_UNRECOVERABLE * @moduleid TOD_RT_TOPOLOGY_DATA * @reasoncode TOD_RT_NULL_FIRMWARE_REQUEST_PTR * @devdesc Host interfaces are not initialized * @custdesc An internal error occurred. This will * force the Time of Day function to run * with complete redundancy. */ l_err = new ErrlEntry( ERRL_SEV_UNRECOVERABLE, TOD_RT_TOPOLOGY_DATA, TOD_RT_NULL_FIRMWARE_REQUEST_PTR, 0, 0, true); break; } // Default the response data size to the size of the // GenericFspMboxMessage_t minus the size of the // GenericFspMboxMessage_t's data. The size of the // GenericFspMboxMessage_t's data will be added later uint32_t l_resp_data_size = sizeof(GenericFspMboxMessage_t) - sizeof(GenericFspMboxMessage_t::data); // Get the number of TodChipData items that will be returned. uint32_t l_nTodChips = TodSvcUtil::getMaxProcsOnSystem(); // Add to the response data size iff there is data needing to be passed l_resp_data_size += (l_nTodChips * sizeof(TodChipData)); // The response data size must be at a minimum the size of the // FSP generic message (sizeof(GenericFspMboxMessage_t)) if (l_resp_data_size < sizeof(GenericFspMboxMessage_t)) { l_resp_data_size = sizeof(GenericFspMboxMessage_t); } // Calculate the TOTAL size of hostInterfaces::hbrt_fw_msg which // means only adding hostInterfaces::HBRT_FW_MSG_BASE_SIZE to // the previous calculated response data size uint64_t l_resp_fw_msg_size = hostInterfaces::HBRT_FW_MSG_BASE_SIZE + l_resp_data_size; // Create the firmware_request response struct to receive data l_resp_fw_msg = (hostInterfaces::hbrt_fw_msg *)malloc(l_resp_fw_msg_size); memset(l_resp_fw_msg, 0, l_resp_fw_msg_size); // Create the firmware_request request struct to send data uint64_t l_req_fw_msg_size = l_resp_fw_msg_size; l_req_fw_msg = (hostInterfaces::hbrt_fw_msg *)malloc(l_req_fw_msg_size); // Initialize the firmware_request request struct l_req_fw_msg->generic_msg.initialize(); // Populate the firmware_request request struct with given data l_req_fw_msg->io_type = hostInterfaces::HBRT_FW_MSG_HBRT_FSP_REQ; l_req_fw_msg->generic_msg.msgq = MBOX::FSP_TOD_MSGQ; l_req_fw_msg->generic_msg.msgType = GenericFspMboxMessage_t::MSG_TOD_TOPOLOGY_DATA; l_req_fw_msg->generic_msg.__req = GenericFspMboxMessage_t::REQUEST; // Trace out the request structure TRACFBIN(ISTEPS_TRACE::g_trac_isteps_trace, INFO_MRK"TOD::Sending firmware_request", l_req_fw_msg, l_req_fw_msg_size); // Make the firmware_request call l_err = firmware_request_helper(l_req_fw_msg_size, l_req_fw_msg, &l_resp_fw_msg_size, l_resp_fw_msg); if (l_err) { break; } // If we are here, then this was no error retrieving the data. Now, // just get the data from the returned struct and pass back to caller // Get a pointer to the data TodChipData* l_todChipData = (TodChipData*)(&(l_resp_fw_msg->generic_msg.data)); // Gather the data into the container provided for (size_t i = 0; i < l_nTodChips; ++i) { o_todChipData.push_back(l_todChipData[i]); } } while (0); // Release the firmware messages free(l_req_fw_msg); free(l_resp_fw_msg); l_req_fw_msg = l_resp_fw_msg = nullptr; TOD_EXIT("readTodProcDataFromFile"); return l_err; } // end readTodProcDataFromFile
//****************************************************************************** //TodSvc::todSetup //****************************************************************************** errlHndl_t TodSvc::todSetup() { TOD_ENTER("TodSvc::todSetup"); errlHndl_t l_errHdl = NULL; bool l_isTodRunning = false; TodTopologyManager l_primary(TOD_PRIMARY); do { bool l_inMPIPLPath = false; l_errHdl = isMPIPL(l_inMPIPLPath); if (l_errHdl) { TOD_ERR("Failed to check if in MPIPL path or not"); break; } if (false == l_inMPIPLPath) { 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); 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; } //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 = TOD::buildTodDrawers(TOD_PRIMARY); if(l_errHdl) { TOD_ERR("TOD setup failure: failed to build TOD drawers " "for primary topology."); break; } //2) Ask the topology manager to setup the primary topology l_errHdl = l_primary.create(); if(l_errHdl) { TOD_ERR("TOD setup failure: failed to create primary topology."); break; } l_primary.dumpTopology(); //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) { TOD_ERR("TOD setup failure: primary topology register save HWP."); break; } //Primary successfully configured TOD::setConfigStatus(TOD_PRIMARY,true); //Build datastructures for secondary topology 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; } //4) Ask the topology manager to setup the secondary topology TodTopologyManager l_secondary(TOD_SECONDARY); l_errHdl = l_secondary.create(); if(l_errHdl) { 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 TOD::setConfigStatus(TOD_SECONDARY,true); //Need to call this again if the secondary topology got set up, //that would have updated more regs. l_errHdl = todSaveRegsHwp(TOD_PRIMARY); if(l_errHdl) { TOD_ERR("TOD setup failure: primary topology register save HWP."); break; } //Done with TOD setup }while(0); if((NULL == l_errHdl) && (false == l_isTodRunning )) { l_primary.dumpTodRegs(); //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 = TOD::writeTodProcData(TOD_PRIMARY); if(l_errHdl) { TOD_ERR("TOD setup failure:Failed to write topology register data" " to the file."); } } TOD::clearGardedTargetsList(); 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<TodDrawer*> l_drawerList; TOD::getDrawers(i_activeConfig, l_drawerList); bool l_drawerFound = false; for(std::list<TodDrawer*>::iterator l_drawerItr = l_drawerList.begin(); ((l_drawerItr != l_drawerList.end()) && !l_drawerFound); ++l_drawerItr) { const std::list<TodProc*>& l_procsList = (*l_drawerItr)->getProcs(); for(std::list<TodProc*>::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; }
//****************************************************************************** //TodSvc::TodSvc //****************************************************************************** TodSvc::TodSvc() { TOD_ENTER(); TOD_EXIT(); }