Esempio n. 1
0
//******************************************************************************
//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;
}
Esempio n. 2
0
//******************************************************************************
//TodSvc::~TodSvc
//******************************************************************************
TodSvc::~TodSvc()
{
    TOD_ENTER();

    //Free up held memory
    TOD::destroy(TOD_PRIMARY);
    TOD::destroy(TOD_SECONDARY);

    TOD_EXIT();
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
//******************************************************************************
//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;
}
Esempio n. 5
0
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();
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
//*****************************************************************************
// 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
Esempio n. 8
0
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
Esempio n. 9
0
//*****************************************************************************
// 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
Esempio n. 10
0
//******************************************************************************
//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;
}
Esempio n. 11
0
//******************************************************************************
//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;
}
Esempio n. 12
0
//******************************************************************************
//TodSvc::TodSvc
//******************************************************************************
TodSvc::TodSvc()
{
    TOD_ENTER();

    TOD_EXIT();
}