/**
 * @brief This function updates the NVDIMM firmware code
 */
void call_nvdimm_update()
{
    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,ENTER_MRK"call_nvdimm_update()");

    TARGETING::TargetHandleList l_nvdimmTargetList;
    TARGETING::TargetHandleList l_procList;
    TARGETING::getAllChips(l_procList, TARGETING::TYPE_PROC, false);

    // grab the NVDIMMs under each processor and add to overall list
    for (auto l_proc : l_procList)
    {
        TARGETING::TargetHandleList tmpList =
            TARGETING::getProcNVDIMMs(l_proc);
        l_nvdimmTargetList.insert(l_nvdimmTargetList.end(),
                                  tmpList.begin(), tmpList.end());
    }

    // Run the nvdimm update function if the list is not empty
    if ( !l_nvdimmTargetList.empty() )
    {
        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
            "call_nvdimm_update(): found %d nvdimms to check for update",
            l_nvdimmTargetList.size());
        bool updateWorked = NVDIMM::nvdimm_update(l_nvdimmTargetList);
        if (!updateWorked)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "call_nvdimm_update(): nvdimm update failed");
        }
    }

    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,EXIT_MRK"call_nvdimm_update()");
}
Beispiel #2
0
//Swaps chip at location 0 with a chip at location i_chipToFront
void FabricDomain::MoveToFrontInTheseChips(uint32_t i_chipToFront, TARGETING::TargetHandleList & i_chips)
{
    using namespace TARGETING;

    for (TargetHandleList::iterator i = i_chips.begin()+i_chipToFront; i != i_chips.begin(); i--)
    {
        std::swap((*i), (*(i-1)));
    }
}
Beispiel #3
0
//Analyze a subset of chips in a Domain...
//This is a mini analysis of some of the chips in the Fabric Domain.
int32_t FabricDomain::AnalyzeTheseChips(STEP_CODE_DATA_STRUCT & serviceData,
                                        ATTENTION_TYPE attentionType,
                                        TARGETING::TargetHandleList & i_chips)
{
    using namespace TARGETING ;
    PRDF_DENTER( "FabricDomain::AnalyzeTheseChips" );
    int32_t l_rc = ~SUCCESS;

    PRDF_DTRAC( "FabricDomain::AnalyzeTheseChips:: Domain ID = 0x%X", GetId() );

    if(i_chips.size() != 0)
    {

        for (TargetHandleList::iterator i = i_chips.begin(); i != i_chips.end(); ++i)
        {
            PRDF_DTRAC( "FabricDomain::AnalyzeTheseChips::Before--chip=0x%X",
                        PlatServices::getHuid(*i));
        }

        OrderTheseChips(attentionType, i_chips);

        for (TargetHandleList::iterator i = i_chips.begin(); i != i_chips.end(); ++i)
        {
            PRDF_DTRAC( "FabricDomain::AnalyzeTheseChips::After--chip=0x%X",
                        PlatServices::getHuid(*i) );
        }
        //After the Order function is called the first chip should contain the chip to look at.
        //Look here for the correct LookUp function.  I don't think this is working.
        RuleChip * l_fabChip = FindChipInTheseChips(i_chips[0], i_chips);
        PRDF_DTRAC( "FabricDomain::AnalyzeTheseChips::Analyzing this one: 0x%X",
                    l_fabChip->GetId() );
        if(NULL != l_fabChip)
        {
            l_rc = l_fabChip->Analyze(serviceData, attentionType);
        }
        else
        {
            PRDF_DTRAC( "FabricDomain::AnalyzeTheseChips::l_fabChip is NULL" );
            l_rc = ~SUCCESS;
        }
    }
    else
    {
        PRDF_DTRAC( "FabricDomain::AnalyzeTheseChips::i_chips = %d",
                    i_chips.size() );
    }

    //Get P7 chip Global FIR data for FFDC
    for (TargetHandleList::iterator i = i_chips.begin(); i != i_chips.end(); ++i)
    {
        RuleChip * l_fabChip = FindChipInTheseChips(*i, i_chips);
        l_fabChip->CaptureErrorData(
                                    serviceData.service_data->GetCaptureData(),
                                    Util::hashString("GlobalFIRs"));
    }


    PRDF_DEXIT( "FabricDomain::AnalyzeTheseChips" );
    return l_rc;
}
Beispiel #4
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
Beispiel #5
0
int32_t FabricDomain::OrderTheseChips(ATTENTION_TYPE attentionType,
                                      TARGETING::TargetHandleList & i_chips)
{
    using namespace PluginDef;
    using namespace TARGETING;
    PRDF_DENTER( "FabricDomain::OrderTheseChips" );

    uint32_t l_internalOnlyCount = 0;
    uint64_t l_externalDrivers[i_chips.size()];
    uint64_t l_wofValues[i_chips.size()];
    bool l_internalCS[i_chips.size()];

    union { uint64_t * u; CPU_WORD * c; } ptr;

    uint32_t l_chip = 0;
    uint32_t l_chipToFront = 0;
    // Get internal setting and external driver list for each chip.
    for (TargetHandleList::iterator i = i_chips.begin(); i != i_chips.end(); ++i)
    {

        RuleChip * l_fabChip = FindChipInTheseChips(*i, i_chips);

        ptr.u = &l_externalDrivers[l_chip];
        BitString l_externalChips(i_chips.size(), ptr.c);
        TargetHandleList l_tmpList;

        if(l_fabChip != NULL)
        {
            // Call "GetCheckstopInfo" plugin.
            ExtensibleChipFunction * l_extFunc
                = l_fabChip->getExtensibleFunction("GetCheckstopInfo");

            (*l_extFunc)(l_fabChip,
                     bindParm<bool &, TargetHandleList &, uint64_t &>
                        (l_internalCS[l_chip],
                         l_tmpList,
                         l_wofValues[l_chip]
                     )
            );
        }
        else
        {
            l_internalCS[l_chip] = false;
            PRDF_DTRAC( "FabricDomain::OrderTheseChips: l_fabChip is NULL" );
        }

        //If we are just checking for internal errors then there is no need for
        //a list of what chips sent checkstops where.
        // Update bit buffer.
        for (TargetHandleList::iterator j = l_tmpList.begin();
             j != l_tmpList.end();
             ++j)
        {
            for (uint32_t k = 0; k < i_chips.size(); k++)
                if ((*j) == LookUp(k)->GetChipHandle())
                    l_externalChips.Set(k);
        };

        // Check if is internal.
        if (l_internalCS[l_chip])
        {
            l_internalOnlyCount++;
            l_chipToFront = l_chip;
        }
        l_chip++;  //Move to next chip in the list.
    }

    // Check if we are done... only one with an internal error.
    if (1 == l_internalOnlyCount)
    {
        MoveToFrontInTheseChips(l_chipToFront, i_chips);
        return(SUCCESS);
    }

    PRDF_DEXIT( "FabricDomain::OrderTheseChips" );
    return(SUCCESS);
}
Beispiel #6
0
    // Notify HTMGT that an OCC has failed and needs to be reset
    void processOccReset(TARGETING::Target * i_proc)
    {
        TMGT_INF(">>processOccReset(0x%p)", i_proc);
        errlHndl_t errl = NULL;
        TARGETING::Target * failedOccTarget = NULL;

        TARGETING::Target* sys = NULL;
        TARGETING::targetService().getTopLevelTarget(sys);
        uint8_t safeMode = 0;

        // If the system is in safemode then ignore request to reset OCCs
        if(sys &&
           sys->tryGetAttr<TARGETING::ATTR_HTMGT_SAFEMODE>(safeMode) &&
           safeMode)
        {
            return;
        }

        // Get functional OCC (one per proc)
        TARGETING::TargetHandleList pOccs;
        getChildChiplets(pOccs, i_proc, TARGETING::TYPE_OCC);
        if (pOccs.size() > 0)
        {
            failedOccTarget = pOccs[0];
        }

        if(NULL != failedOccTarget)
        {
            uint32_t huid = failedOccTarget->getAttr<TARGETING::ATTR_HUID>();
            TMGT_INF("processOccReset(HUID=0x%08X) called", huid);
        }
        else
        {
            uint32_t huid = i_proc->getAttr<TARGETING::ATTR_HUID>();
            TMGT_INF("processOccReset: Invalid OCC target (proc huid=0x08X)"
                     "resetting OCCs anyway",
                     huid);

            /*@
             * @errortype
             * @reasoncode      HTMGT_RC_INVALID_PARAMETER
             * @moduleid        HTMGT_MOD_PROCESS_OCC_RESET
             * @userdata1[0:7]  Processor HUID
             * @devdesc         No OCC target found for proc Target,
             */
            bldErrLog(errl,
                      HTMGT_MOD_PROCESS_OCC_RESET,
                      HTMGT_RC_INVALID_PARAMETER,
                      huid, 0, 0, 1,
                      ERRORLOG::ERRL_SEV_INFORMATIONAL);

            // Add HB firmware callout
            errl->addProcedureCallout(HWAS::EPUB_PRC_HB_CODE,
                                      HWAS::SRCI_PRIORITY_MED);
            ERRORLOG::errlCommit(errl, HTMGT_COMP_ID); // sets errl to NULL
        }

        errl = OccManager::resetOccs(failedOccTarget);
        if(errl)
        {
            ERRORLOG::errlCommit(errl, HTMGT_COMP_ID); // sets errl to NULL
        }
        TMGT_INF("<<processOccReset()");
    } // end processOccReset()
Beispiel #7
0
    // Notify HTMGT that an OCC has an error to report
    void processOccError(TARGETING::Target * i_procTarget)
    {
        TMGT_INF(">>processOccError(0x%p)", i_procTarget);

        TARGETING::Target* sys = NULL;
        TARGETING::targetService().getTopLevelTarget(sys);
        uint8_t safeMode = 0;

        // If the system is in safemode then can't talk to OCCs -
        // ignore call to processOccError
        if(sys &&
           sys->tryGetAttr<TARGETING::ATTR_HTMGT_SAFEMODE>(safeMode) &&
           safeMode)
        {
            return;
        }

        bool polledOneOcc = false;
        errlHndl_t err = OccManager::buildOccs();
        if (NULL == err)
        {
            if (i_procTarget != NULL)
            {
                const uint32_t l_huid =
                    i_procTarget->getAttr<TARGETING::ATTR_HUID>();
                TMGT_INF("processOccError(HUID=0x%08X) called", l_huid);

                TARGETING::TargetHandleList pOccs;
                getChildChiplets(pOccs, i_procTarget, TARGETING::TYPE_OCC);
                if (pOccs.size() > 0)
                {
                    // Poll specified OCC flushing any errors
                    errlHndl_t err = OccManager::sendOccPoll(true, pOccs[0]);
                    if (err)
                    {
                        ERRORLOG::errlCommit(err, HTMGT_COMP_ID);
                    }
                    polledOneOcc = true;
                }
            }

            if ((OccManager::getNumOccs() > 1) || (false == polledOneOcc))
            {
                // Send POLL command to all OCCs to flush any other errors
                errlHndl_t err = OccManager::sendOccPoll(true);
                if (err)
                {
                    ERRORLOG::errlCommit(err, HTMGT_COMP_ID);
                }
            }

            if (OccManager::occNeedsReset())
            {
                TMGT_ERR("processOccError(): OCCs need to be reset");
                // Don't pass failed target as OCC should have already
                // been marked as failed during the poll.
                errlHndl_t err = OccManager::resetOccs(NULL);
                if(err)
                {
                    ERRORLOG::errlCommit(err, HTMGT_COMP_ID);
                }
            }
        }
        else
        {
            // OCC build failed...
            TMGT_ERR("processOccError() called, but unable to find OCCs");
            ERRORLOG::errlCommit(err, HTMGT_COMP_ID);
        }
        TMGT_INF("<<processOccError()");

    } // end processOccError()
/**
 *  @brief Returns the runtime target ID for a given targeting target for all
 *      hypervisors other than PHyp
 *  @param[in] i_pTarget Targeting target, must not be NULL (asserts
 *      otherwise)
 *  @param[out] o_rtTargetId Runtime target ID which maps to the given targeting
 *      target
 *  @return Error log handle
 *  @retval NULL Computed a valid runtime target ID for the given input
 *      targeting target and returned it in the output parameter.
 *  @retval !NULL Failed to compute a runtime target ID for the given input
 *      targeting target. Ignore output parameter.
 */
errlHndl_t computeNonPhypRtTarget(
    const TARGETING::Target*   i_pTarget,
          RT_TARG::rtChipId_t& o_rtTargetId)
{
    assert(i_pTarget != NULL);

    errlHndl_t pError = NULL;

    do
    {
        if(i_pTarget == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL)
        {
            TARGETING::Target* masterProcChip = NULL;
            TARGETING::targetService().
                masterProcChipTargetHandle(masterProcChip);
            i_pTarget = masterProcChip;
        }

        auto targetingTargetType = i_pTarget->getAttr<TARGETING::ATTR_TYPE>();

        if(targetingTargetType == TARGETING::TYPE_PROC)
        {
            uint32_t fabId =
                i_pTarget->getAttr<TARGETING::ATTR_FABRIC_GROUP_ID>();

            uint32_t procPos =
                i_pTarget->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>();

            o_rtTargetId = PIR_t::createChipId( fabId, procPos );
        }
        else if( targetingTargetType == TARGETING::TYPE_MEMBUF)
        {
            //MEMBUF
            // 0b1000.0000.0000.0000.0000.0GGG.GCCC.MMMM
            // where GGGG is group, CCC is chip, MMMM is memory channel
            //
            TARGETING::TargetHandleList targetList;

            getParentAffinityTargets(targetList,
                                    i_pTarget,
                                    TARGETING::CLASS_UNIT,
                                    TARGETING::TYPE_DMI);

            if( targetList.empty() )
            {
                auto huid = get_huid(i_pTarget);
                TRACFCOMP(g_trac_runtime, ERR_MRK
                    "No associated DMI targeting target(s) found for MEMBUF "
                    "targeting target with HUID of 0x%08X",
                    huid);
                /*@
                 * @error
                 * @moduleid    RUNTIME::MOD_CUST_COMP_NON_PHYP_RT_TARGET
                 * @reasoncode  RUNTIME::RT_UNIT_TARGET_NOT_FOUND
                 * @userdata1   MEMBUF targeting target's HUID
                 * @devdesc     No associated DMI targeting target(s) found for
                 *              given MEMBUF targeting target
                 */
                pError = new ERRORLOG::ErrlEntry(
                    ERRORLOG::ERRL_SEV_INFORMATIONAL,
                    RUNTIME::MOD_CUST_COMP_NON_PHYP_RT_TARGET,
                    RUNTIME::RT_UNIT_TARGET_NOT_FOUND,
                    huid,
                    0,
                    true);

                ERRORLOG::ErrlUserDetailsTarget(i_pTarget,"Targeting Target").
                    addToLog(pError);

                break;
            }

            auto target = targetList[0];
            auto pos = target->getAttr<TARGETING::ATTR_CHIP_UNIT>();

            targetList.clear();
            getParentAffinityTargets(targetList,
                                     target,
                                     TARGETING::CLASS_CHIP,
                                     TARGETING::TYPE_PROC);

            if(targetList.empty())
            {
                pError = createProcNotFoundError(target);
                break;
            }

            auto procTarget = targetList[0];
            pError = computeNonPhypRtTarget(procTarget, o_rtTargetId);
            if(pError)
            {
                break;
            }

            o_rtTargetId = (o_rtTargetId << RT_TARG::MEMBUF_ID_SHIFT);
            o_rtTargetId += pos;
            o_rtTargetId |= HBRT_MEMBUF_TYPE;
        }
        else if(targetingTargetType == TARGETING::TYPE_CORE)
        {
            // CORE
            // 0b0100.0000.0000.0000.0000.GGGG.CCCP.PPPP
            // GGGG is group, CCC is chip, PPPPP is core
            auto pos = i_pTarget->getAttr<TARGETING::ATTR_CHIP_UNIT>();
            const TARGETING::Target* procTarget = getParentChip(i_pTarget);
            if(procTarget == NULL)
            {
                pError = createProcNotFoundError(i_pTarget);
                break;
            }

            pError = computeNonPhypRtTarget(procTarget, o_rtTargetId);
            if(pError)
            {
                break;
            }

            o_rtTargetId = PIR_t::createCoreId(o_rtTargetId,pos);
            o_rtTargetId |= HBRT_CORE_TYPE;
        }
        else
        {
            auto huid = get_huid(i_pTarget);
            TRACFCOMP(g_trac_runtime,ERR_MRK
                      "Targeting target type 0x%08X not supported.  Cannot "
                      "convert targeting target with HUID of 0x%08X into a "
                      "runtime target ID",
                      targetingTargetType,
                      huid);
            /*@
             * @errortype
             * @moduleid    RUNTIME::MOD_CUST_COMP_NON_PHYP_RT_TARGET
             * @reasoncode  RUNTIME::RT_TARGET_TYPE_NOT_SUPPORTED
             * @userdata1   Targeting target's HUID
             * @userdata2   Targeting target's type
             * @devdesc     The targeting type of the input targeting target is
             *              not supported by runtime code
             */
            pError = new ERRORLOG::ErrlEntry(
                ERRORLOG::ERRL_SEV_INFORMATIONAL,
                RUNTIME::MOD_CUST_COMP_NON_PHYP_RT_TARGET,
                RUNTIME::RT_TARGET_TYPE_NOT_SUPPORTED,
                huid,
                targetingTargetType,
                true);

            ERRORLOG::ErrlUserDetailsTarget(i_pTarget,"Targeting Target").
                addToLog(pError);
        }

    } while(0);

    return pError;
}
Beispiel #9
0
//******************************************************************************
// fenceAttachedMembufs - helper function for hwp proc_cen_ref_clk_enable
//******************************************************************************
void fenceAttachedMembufs( TARGETING::Target * i_procTarget  )
{
     errlHndl_t  l_errl = NULL;

    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
            "Fencing attached (present) membuf chips downstream from "
            "proc chip with HUID of 0x%08X",
            i_procTarget->getAttr<TARGETING::ATTR_HUID>());


    // Get list of membuf chips downstream from the given proc chip
    TARGETING::TargetHandleList MembufChipList;

    getChildAffinityTargetsByState( MembufChipList,
                      const_cast<TARGETING::Target*>(i_procTarget ),
                      TARGETING::CLASS_CHIP,
                      TARGETING::TYPE_MEMBUF,
                      TARGETING::UTIL_FILTER_PRESENT);

    // loop through the membufs
    for(TARGETING::TargetHandleList::const_iterator pTargetItr
                            = MembufChipList.begin();
                            pTargetItr != MembufChipList.end();
                            pTargetItr++)
    {
        //Get CFAM "1012" -- FSI GP3 and set bits 23-27 (various fence bits)
        //Note 1012 is ecmd addressing, real address is 0x1048 (byte)
        uint64_t l_addr = 0x1048;
        const uint32_t l_fence_bits= 0x000001F0;
        uint32_t l_data = 0;
        size_t l_size = sizeof(uint32_t);
        l_errl = deviceRead(*pTargetItr,
                         &l_data,
                         l_size,
                         DEVICE_FSI_ADDRESS(l_addr));
        if (l_errl)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
             "Failed getcfam 1012 to HUID 0x%08X, ignoring, skipping",
             (*pTargetItr)->getAttr<TARGETING::ATTR_HUID>());
            delete l_errl;
            l_errl = NULL;
            continue;
        }

        l_data |= l_fence_bits;

        l_errl = deviceWrite(*pTargetItr,
                         &l_data,
                         l_size,
                         DEVICE_FSI_ADDRESS(l_addr));
        if (l_errl)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                      "Failed putcfam 1012 to HUID 0x%08X, ignoring, skipping",
                      (*pTargetItr)->getAttr<TARGETING::ATTR_HUID>());
            delete l_errl;
            l_errl = NULL;
            continue;
        }
    }

}
Beispiel #10
0
//******************************************************************************
// call_proc_cen_ref_clock_enable
//******************************************************************************
void* call_proc_cen_ref_clk_enable(void *io_pArgs )
{
    errlHndl_t  l_errl = NULL;

    IStepError  l_stepError;

    TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
               "call_proc_cen_ref_clock_enable enter" );

    TARGETING::TargetHandleList functionalProcChipList;

    getAllChips(functionalProcChipList, TYPE_PROC, true);

    // loop thru the list of processors
    for (TargetHandleList::const_iterator
            l_proc_iter = functionalProcChipList.begin();
            l_proc_iter != functionalProcChipList.end();
            ++l_proc_iter)
    {
        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                "target HUID %.8X",
                TARGETING::get_huid( *l_proc_iter ));

        uint8_t l_membufsAttached = 0;
        // get a bit mask of present/functional dimms assocated with
        // this processor
        l_membufsAttached = getMembufsAttachedBitMask( *l_proc_iter );

        //Perform a workaround for GA1 to raise fences on centaurs
        //to prevent FSP from analyzing if HB TIs for recoverable
        //errors
        //RTC 106276
        fenceAttachedMembufs( *l_proc_iter );

        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                "passing target HUID %.8X and 0x%x mask",
                TARGETING::get_huid( *l_proc_iter ), l_membufsAttached );

        if( l_membufsAttached )
        {

            fapi::Target l_fapiProcTarget( fapi::TARGET_TYPE_PROC_CHIP,
                                       *l_proc_iter );

            // Invoke the HWP passing in the proc target and
            // a bit mask indicating connected centaurs
            FAPI_INVOKE_HWP(l_errl,
                    proc_cen_ref_clk_enable,
                    l_fapiProcTarget, l_membufsAttached );

            if (l_errl)
            {
                TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                        "ERROR : proc_cen_ref_clk_enable",
                        "failed, returning errorlog" );

                // capture the target data in the elog
                ErrlUserDetailsTarget( *l_proc_iter ).addToLog( l_errl );

                // Create IStep error log and cross ref error that occurred
                l_stepError.addErrorDetails( l_errl );

                // Commit error log
                errlCommit( l_errl, HWPF_COMP_ID );
            }
            else
            {
                TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                        "SUCCESS : proc_cen_ref_clk_enable",
                        "completed ok");
            }
        }
    }   // endfor

    TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
               "call_proc_cen_ref_clock_enable exit" );

    // end task, returning any errorlogs to IStepDisp
    return l_stepError.getErrorHandle();
}
Beispiel #11
0
//******************************************************************************
// getMembufsAttachedBitMask - helper function for hwp proc_cen_ref_clk_enable
//******************************************************************************
uint8_t getMembufsAttachedBitMask( TARGETING::Target * i_procTarget  )
{
    const uint8_t MCS_WITH_ATTACHED_CENTAUR_MASK = 0x80;

    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
            "Finding functional membuf chips downstream from "
            "proc chip with HUID of 0x%08X",
            i_procTarget->getAttr<TARGETING::ATTR_HUID>());

    uint8_t l_attachedMembufs = 0;

    // Get list of functional membuf chips downstream from the given
    // proc chip
    TARGETING::TargetHandleList functionalMembufChipList;

    getChildAffinityTargets( functionalMembufChipList,
                      const_cast<TARGETING::Target*>(i_procTarget ),
                      TARGETING::CLASS_CHIP,
                      TARGETING::TYPE_MEMBUF,
                      true);

    // loop through the functional membufs
    for(TARGETING::TargetHandleList::const_iterator pTargetItr
                            = functionalMembufChipList.begin();
                            pTargetItr != functionalMembufChipList.end();
                            pTargetItr++)
    {
        // Find each functional membuf chip's upstream functional MCS
        // unit, if any, and accumulate it into the attached membuf
        // chips mask
        TARGETING::TargetHandleList functionalMcsUnitList;

        getParentAffinityTargets( functionalMcsUnitList, *pTargetItr,
                                  TARGETING::CLASS_UNIT, TARGETING::TYPE_MCS,
                                  true );

        if(functionalMcsUnitList.empty())
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "Functional membuf chip with HUID of 0x%08X "
                    "is not attached to an upstream functional MCS",
                    (*pTargetItr)->getAttr<
                    TARGETING::ATTR_HUID>());
            continue;
        }

        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                "Found functional MCS unit with HUID of 0x%08X "
                "upstream from functional membuf chip with HUID of 0x%08X",
                ((*functionalMcsUnitList.begin())->getAttr<
                 TARGETING::ATTR_CHIP_UNIT>()),
                (*pTargetItr)->getAttr<
                TARGETING::ATTR_HUID>());
        l_attachedMembufs |=
            ((MCS_WITH_ATTACHED_CENTAUR_MASK) >>
             ((*functionalMcsUnitList.begin())->getAttr<
              TARGETING::ATTR_CHIP_UNIT>()));
    }

    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
            "Proc chip with HUID of 0x%08X has attached membuf "
            "mask (l_attachedMembufs) of 0x%02X",
            i_procTarget->getAttr<TARGETING::ATTR_HUID>(),
            l_attachedMembufs);

    // return the bitmask
    return l_attachedMembufs;

}
Beispiel #12
0
// ------------------------------------------------------------------
// dimmPresenceDetect
// ------------------------------------------------------------------
errlHndl_t dimmPresenceDetect( DeviceFW::OperationType i_opType,
                               TARGETING::Target * i_target,
                               void * io_buffer,
                               size_t & io_buflen,
                               int64_t i_accessType,
                               va_list i_args )
{
    errlHndl_t err = NULL;
    bool present = false;
    size_t presentSz = sizeof(present);

    TRACSSCOMP( g_trac_spd,
                ENTER_MRK"dimmPresenceDetect()" );

    do
    {
        // Check to be sure that the buffer is big enough.
        if( !(io_buflen >= sizeof(bool)) )
        {
            TRACFCOMP( g_trac_spd,
                       ERR_MRK"dimmPresenceDetect() - Invalid Data Length: %d",
                       io_buflen );

            /*@
             * @errortype
             * @reasoncode       VPD::VPD_INSUFFICIENT_BUFFER_SIZE
             * @severity         ERRORLOG::ERRL_SEV_UNRECOVERABLE
             * @moduleid         VPD::VPD_SPD_PRESENCE_DETECT
             * @userdata1        Buffer Length
             * @userdata2        <UNUSED>
             * @devdesc          Buffer for checking Presence Detect
             *                   was not the correct size.
             */
            err = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                           VPD::VPD_SPD_PRESENCE_DETECT,
                                           VPD::VPD_INSUFFICIENT_BUFFER_SIZE,
                                           TO_UINT64(io_buflen),
                                           0x0,
                                           true /*Add HB Software Callout*/);

            err->collectTrace( "SPD", 256);

            break;
        }

        // Is the target present
#ifdef CONFIG_DJVPD_READ_FROM_HW
        // Check if the parent MBA/MEMBUF is present.  If it is not then
        // no reason to check the DIMM which would otherwise generate
        // tons of FSI errors.  We can't just check if parent MBA
        // is functional because DIMM presence detect is called before
        // the parent MBA/MEMBUF is set as present/functional.
        TARGETING::TargetHandleList membufList;
        TARGETING::PredicateCTM membufPred( TARGETING::CLASS_CHIP,
                                            TARGETING::TYPE_MEMBUF );
        TARGETING::targetService().getAssociated(
            membufList,
            i_target,
            TARGETING::TargetService::PARENT_BY_AFFINITY,
            TARGETING::TargetService::ALL,
            &membufPred);

        bool parentPresent = false;
        const TARGETING::TargetHandle_t membufTarget = *(membufList.begin());

        err = deviceRead(membufTarget, &parentPresent, presentSz,
                                DEVICE_PRESENT_ADDRESS());
        if (err)
        {
            TRACFCOMP(
                g_trac_spd,
                "Error reading parent MEMBUF present: huid 0x%X DIMM huid 0x%X",
                TARGETING::get_huid(membufTarget),
                TARGETING::get_huid(i_target) );
            break;
        }
        if (!parentPresent)
        {
            present = false;
            // Invalidate the SPD in PNOR
            err = VPD::invalidatePnorCache(i_target);
            if (err)
            {
                TRACFCOMP( g_trac_spd, "Error invalidating SPD in PNOR" );
            }
            break;
        }
#endif

        present = spdPresent( i_target );

        if( present == false )
        {
            TRACUCOMP( g_trac_spd,
                       INFO_MRK"Dimm was found to be NOT present." );
        }
        else
        {
            TRACUCOMP( g_trac_spd,
                       INFO_MRK"Dimm was found to be present." );
        }

#if defined(CONFIG_DJVPD_READ_FROM_HW) && defined(CONFIG_DJVPD_READ_FROM_PNOR)
        if( present )
        {
            // Check if the VPD data in the PNOR matches the SEEPROM
            err = VPD::ensureCacheIsInSync( i_target );
            if( err )
            {
                present = false;

                TRACFCOMP(g_trac_spd,ERR_MRK "dimmPresenceDetectt> Error during ensureCacheIsInSync (SPD)" );
                break;
            }
        }
        else
        {
            // SPD is not present, invalidate the SPD in PNOR
            err = VPD::invalidatePnorCache(i_target);
            if (err)
            {
                TRACFCOMP( g_trac_spd, "Error invalidating SPD in PNOR" );
            }
        }
#endif

        if( present && !err )
        {
            //Fsp sets PN/SN so if there is none, do it here
            if(!INITSERVICE::spBaseServicesEnabled())
            {
                //populate serial and part number attributes
                SPD::setPartAndSerialNumberAttributes( i_target );
            }

            // Read ATTR_CLEAR_DIMM_SPD_ENABLE attribute
            TARGETING::Target* l_sys = NULL;
            TARGETING::targetService().getTopLevelTarget(l_sys);

            TARGETING::ATTR_CLEAR_DIMM_SPD_ENABLE_type l_clearSPD =
                l_sys->getAttr<TARGETING::ATTR_CLEAR_DIMM_SPD_ENABLE>();

            // If SPD clear is enabled then write 0's into magic word for 
            // DIMM_BAD_DQ_DATA keyword
            // Note: If there's an error from performing the clearing,
            // just log the error and continue.
            if (l_clearSPD)
            {
                size_t l_size = 0;

                // Do a read to get the DIMM_BAD_DQ_DATA keyword size
                err = deviceRead(i_target, NULL, l_size,
                                 DEVICE_SPD_ADDRESS( DIMM_BAD_DQ_DATA ));
                if (err)
                {
                    TRACFCOMP(g_trac_spd, "dimmPresenceDetect - "
                        "Error reading DIMM_BAD_DQ_DATA keyword size");
                    errlCommit( err, VPD_COMP_ID );
                }
                else
                {
                    // Clear the data
                    TRACFCOMP( g_trac_spd, "Clearing out BAD_DQ_DATA SPD on "
                               "DIMM HUID 0x%X",
                               TARGETING::get_huid(i_target));

                    uint8_t * l_data = static_cast<uint8_t*>(malloc( l_size ));
                    memset(l_data, 0, l_size);

                    err = deviceWrite(i_target, l_data, l_size,
                                     DEVICE_SPD_ADDRESS( DIMM_BAD_DQ_DATA ));
                    if (err)
                    {
                        TRACFCOMP( g_trac_spd, "Error trying to clear SPD on "
                                   "DIMM HUID 0x%X",
                                   TARGETING::get_huid(i_target));
                        errlCommit( err, VPD_COMP_ID );
                    }

                    // Free the memory
                    if (NULL != l_data)
                    {
                        free(l_data);
                    }
                }
            }
        }

        // copy present value into output buffer so caller can read it
        memcpy( io_buffer, &present, presentSz );
        io_buflen = presentSz;

    } while( 0 );

    TRACSSCOMP( g_trac_spd,
                EXIT_MRK"dimmPresenceDetect()" );

    return err;
} // end dimmPresenceDetect
Beispiel #13
0
errlHndl_t initiateDrtm()
{
    SB_ENTER("initiateDrtm");

    errlHndl_t pError = nullptr;

    // For DRTM, the thread has to be pinned to a core (and therefore pinned to
    // a chip)
    task_affinity_pin();

    void* drtmPayloadVirtAddr = nullptr;

    do
    {
        const std::vector<SECUREBOOT::ProcSecurity> LLP {
            SECUREBOOT::ProcSecurity::LLPBit,
        };

        const std::vector<SECUREBOOT::ProcSecurity> LLS {
            SECUREBOOT::ProcSecurity::LLSBit,
        };

        // Determine which fabric group and chip this task is executing on and
        // create a filter to find the matching chip target
        auto cpuId = task_getcpuid();
        auto groupId = PIR_t::groupFromPir(cpuId);
        auto chipId = PIR_t::chipFromPir(cpuId);
        TARGETING::PredicateAttrVal<TARGETING::ATTR_FABRIC_GROUP_ID>
            matchesGroup(groupId);
        TARGETING::PredicateAttrVal<TARGETING::ATTR_FABRIC_CHIP_ID>
            matchesChip(chipId);
        TARGETING::PredicatePostfixExpr matchesGroupAndChip;
        matchesGroupAndChip.push(&matchesGroup).push(&matchesChip).And();

        // Get all the functional proc chips and find the chip we're running on
        TARGETING::TargetHandleList funcProcChips;
        TARGETING::getAllChips(funcProcChips,
                               TARGETING::TYPE_PROC);
        if(funcProcChips.empty())
        {
            // TODO: RTC 167205: GA error handling
            assert(false,"initiateDrtm: BUG! Functional proc chips is empty, "
                "yet this code is running on a functional chip!");
            break;
        }

        // NOTE: std::find_if requires predicates to be copy constructable, but
        // predicates are not; hence use a wrapper lambda function to bypass
        // that limitation
        auto pMatch =
            std::find_if(funcProcChips.begin(),funcProcChips.end(),
                [&matchesGroupAndChip] ( TARGETING::Target* pTarget )
                {
                    return matchesGroupAndChip(pTarget);
                } );

        if(pMatch == funcProcChips.end())
        {
            // TODO: RTC 167205: GA error handling
            assert(false, "initiateDrtm: BUG! No functional chip found "
                "to be running this code");
            break;
        }

        // Move the matching target to the end of the list.
        // NOTE: If reverse iterators were supported, we could have verified the
        // last element of the container is not the match, and done a
        // std::iter_swap of the match and the last element
        TARGETING::Target* const pMatchTarget = *pMatch;
        funcProcChips.erase(pMatch);
        funcProcChips.push_back(pMatchTarget);

        // Map to the DRTM payload area in mainstore
        const uint32_t drtmPayloadPhysAddrMb = DRTM_RIT_PAYLOAD_PHYS_ADDR_MB;
        drtmPayloadVirtAddr = mm_block_map(
            reinterpret_cast<void*>(drtmPayloadPhysAddrMb*BYTES_PER_MEGABYTE),
            PAGESIZE);
        if(drtmPayloadVirtAddr == nullptr)
        {
            // TODO: RTC 167205: GA error handling
            assert(false, "initiateDrtm: BUG! Failed in call to mm_block_map "
                "to map the DRTM payload.");
            break;
        }

        // Copy the DRTM payload to the DRTM payload area
        memcpy(
            reinterpret_cast<uint32_t*>(drtmPayloadVirtAddr),
            DRTM_RIT_PAYLOAD,
            sizeof(DRTM_RIT_PAYLOAD));

        // The required generic sequencing to initiate DRTM is as follows:
        // 1) Initiating task must pin itself to a core (to ensure it
        //     will not be accidentally queisced by SBE)
        // 2) It must set the DRTM payload information in the master processor
        //     mailbox scratch registers (registers 7 and 8) before it goes
        //     offline
        // 3) It must determine the processor it's currently running on
        // 4) It must set the late launch bit (LL) on all other processors
        //     4a) If the given processor is an active master, it must set
        //         late launch primary (LLP) bit
        //     4b) Otherwise it must set late launch secondary (LLS) bit
        // 5) Finally, it must its own processor's LL bit last, according to the
        //     rules of step 4.
        for(auto &pFuncProc :funcProcChips)
        {
            const auto procMasterType = pFuncProc->getAttr<
                TARGETING::ATTR_PROC_MASTER_TYPE>();

            // If master chip, set the DRTM payload address and validity
            if(procMasterType == TARGETING::PROC_MASTER_TYPE_ACTING_MASTER)
            {
                (void)setDrtmPayloadPhysAddrMb(drtmPayloadPhysAddrMb);
            }

            pError = SECUREBOOT::setSecuritySwitchBits(procMasterType ==
                         TARGETING::PROC_MASTER_TYPE_ACTING_MASTER ?
                            LLP : LLS,
                         pFuncProc);
            if(pError)
            {
                SB_ERR("initiateDrtm: setSecuritySwitchBits() failed for proc "
                    "= 0x%08X. Tried to set LLP or LLS.",
                    get_huid(pFuncProc));
                break;
            }
        }

        if(pError)
        {
            break;
        }


        SB_INF("initiateDrtm: SBE should eventually quiesce all cores; until "
            "then, endlessly yield the task");
        while(1)
        {
            task_yield();
        }

    } while(0);

    // If we -do- come back from this function (on error path only), then we
    // should unpin
    task_affinity_unpin();

    if(drtmPayloadVirtAddr)
    {
        auto rc = mm_block_unmap(const_cast<void*>(drtmPayloadVirtAddr));
        if(rc != 0)
        {
            // TODO: RTC 167205: GA error handling
            assert(false,"initiateDrtm: BUG! mm_block_unmap failed for virtual "
                "address 0x%16llX.",
                drtmPayloadVirtAddr);
        }
    }

    if(pError)
    {
        SB_ERR("initiateDrtm: plid=0x%08X, eid=0x%08X, reason=0x%04X",
               ERRL_GETPLID_SAFE(pError),
               ERRL_GETEID_SAFE(pError),
               ERRL_GETRC_SAFE(pError));
    }

    SB_EXIT("initiateDrtm");

    return pError;
}
errlHndl_t configureHbrtHypIds(const bool i_configForPhyp)
{
    TRACDCOMP( g_trac_runtime, ENTER_MRK "configureHbrtHypIds" );

    errlHndl_t pError = NULL;

    TARGETING::PredicateCTM isaProc(
        TARGETING::CLASS_CHIP, TARGETING::TYPE_PROC);
    TARGETING::PredicateCTM isaMembuf(
        TARGETING::CLASS_CHIP, TARGETING::TYPE_MEMBUF);
    TARGETING::PredicateCTM isaCore(
        TARGETING::CLASS_UNIT, TARGETING::TYPE_CORE);
    TARGETING::PredicatePostfixExpr isaProcMembufOrCore;
    isaProcMembufOrCore.push(&isaProc).push(&isaMembuf).Or()
        .push(&isaCore).Or();
    TARGETING::TargetRangeFilter pIt(
        TARGETING::targetService().begin(),
        TARGETING::targetService().end(),
        &isaProcMembufOrCore);
    for (; pIt; ++pIt)
    {
        auto hbrtHypId = HBRT_HYP_ID_UNKNOWN;

        // Phyp is the only special case
        if(i_configForPhyp)
        {
            auto rtType = RT_TYPE_UNKNOWN;
            pError = getRtTypeForTarget(*pIt,rtType);
            if(pError)
            {
                break;
            }

            if(   (*pIt)->getAttr<TARGETING::ATTR_TYPE>()
               == TARGETING::TYPE_CORE)
            {
                if(TARGETING::is_fused_mode())
                {
                    // If we're in fused core mode, all core ID's must
                    // match that of the parent EX
                    auto type = TARGETING::TYPE_EX;
                    const TARGETING::Target* pEx =
                            TARGETING::getParent(*pIt,type);

                    // If this fails, everything is already hosed
                    assert(pEx != NULL);

                    hbrtHypId = (pEx)->getAttr<TARGETING::ATTR_ORDINAL_ID>();
                }else
                {
                    hbrtHypId = (*pIt)->getAttr<TARGETING::ATTR_ORDINAL_ID>();
                }
            }
            else if( (*pIt)->getAttr<TARGETING::ATTR_TYPE>()
                     == TARGETING::TYPE_MEMBUF )
            {
                //MEMBUF
                // 0b1000.0000.0000.0000.0000.0PPP.PPPP.MMMM
                // where PP is the parent proc's id, MMMM is memory channel
                //
                TARGETING::TargetHandleList targetList;

                getParentAffinityTargets(targetList,
                                         (*pIt),
                                         TARGETING::CLASS_UNIT,
                                         TARGETING::TYPE_MCS);
                assert( !targetList.empty() );

                auto mcs_target = targetList[0];
                auto pos = mcs_target->getAttr<TARGETING::ATTR_CHIP_UNIT>();

                targetList.clear();
                getParentAffinityTargets(targetList,
                                         mcs_target,
                                         TARGETING::CLASS_CHIP,
                                         TARGETING::TYPE_PROC);
                assert( !targetList.empty() );

                auto procTarget = targetList[0];
                hbrtHypId = procTarget->getAttr<TARGETING::ATTR_ORDINAL_ID>();
                hbrtHypId = (hbrtHypId << RT_TARG::MEMBUF_ID_SHIFT);
                hbrtHypId += pos;
            }
            else // just PROC
            {
                hbrtHypId = (*pIt)->getAttr<TARGETING::ATTR_ORDINAL_ID>();
            }

            hbrtHypId |= rtType;
        }
        else
        {
            pError = computeNonPhypRtTarget(*pIt,hbrtHypId);
            if(pError)
            {
                break;
            }
        }

        (*pIt)->setAttr<TARGETING::ATTR_HBRT_HYP_ID>(hbrtHypId);
        TRACDCOMP( g_trac_runtime, "configureHbrtHypIds> "
            "Set ATTR_HBRT_HYP_ID attribute to 0x%016llX on targeting target "
            "with HUID of 0x%08X",
            hbrtHypId,TARGETING::get_huid(*pIt));
    }

    TRACDCOMP( g_trac_runtime, EXIT_MRK "configureHbrtHypIds" );

    return pError;
}
Beispiel #15
0
//******************************************************************************
// wrapper function to call proc_build_smp
//******************************************************************************
void*    call_proc_build_smp( void    *io_pArgs )
{

    errlHndl_t  l_errl  =   NULL;
    IStepError l_StepError;

    TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
               "call_proc_build_smp entry" );

    do
    {
        // Get all functional proc chip targets
        TARGETING::TargetHandleList l_cpuTargetList;
        getAllChips(l_cpuTargetList, TYPE_PROC);

        // Collect all valid abus connections and xbus connections
        TargetPairs_t l_abusConnections;
        TargetPairs_t l_xbusConnections;
        l_errl = PbusLinkSvc::getTheInstance().getPbusConnections(
                                     l_abusConnections, TYPE_ABUS, false );
        if (l_errl)
        {
            // Create IStep error log and cross reference error that occurred
            l_StepError.addErrorDetails( l_errl);
            // Commit error
            errlCommit( l_errl, HWPF_COMP_ID );
        }

        // Get XBUS connections
        l_errl = PbusLinkSvc::getTheInstance().getPbusConnections(
                                 l_xbusConnections, TYPE_XBUS, false );

        if (l_errl)
        {
            // Create IStep error log and cross reference error that occurred
            l_StepError.addErrorDetails( l_errl);
            // Commit error
            errlCommit( l_errl, HWPF_COMP_ID );
        }

        // Populate l_proc_Chips vector for each good processor chip
        //   if a A/X-bus endpoint has a valid connection, then
        //   obtain the proc chip target of the other endpoint of the
        //   connection, build the fapi target to update the corresponding
        //   chip object of this A/X-bus endpoint for the procEntry
        std::vector<proc_build_smp_proc_chip> l_procChips;

        // Get the master proc
        TARGETING::Target * l_masterProc =   NULL;
        (void)TARGETING::targetService().
                   masterProcChipTargetHandle( l_masterProc );

        for (TARGETING::TargetHandleList::const_iterator
             l_cpuIter = l_cpuTargetList.begin();
             l_cpuIter != l_cpuTargetList.end();
             ++l_cpuIter)
        {
            const TARGETING::Target* l_pTarget = *l_cpuIter;
            fapi::Target l_fapiproc_target( TARGET_TYPE_PROC_CHIP,
                 (const_cast<TARGETING::Target*>(l_pTarget)));

            proc_build_smp_proc_chip l_procEntry;
            l_procEntry.this_chip = l_fapiproc_target;
            l_procEntry.enable_f0  = false;
            l_procEntry.enable_f1  = false;

            if (l_pTarget == l_masterProc)
            {
                l_procEntry.master_chip_sys_next = true;
            }
            else
            {
                l_procEntry.master_chip_sys_next = false;
            }

            // Get A-BUS
            //abus connections were found so can get the a-bus
            TARGETING::TargetHandleList l_abuses;
               getChildChiplets( l_abuses, l_pTarget, TYPE_ABUS );

            for (TARGETING::TargetHandleList::const_iterator
                    l_abusIter = l_abuses.begin();
                    l_abusIter != l_abuses.end();
                    ++l_abusIter)
            {
                const TARGETING::Target * l_target = *l_abusIter;
                uint8_t l_srcID = l_target->getAttr<ATTR_CHIP_UNIT>();
                TargetPairs_t::iterator l_itr =
                                        l_abusConnections.find(l_target);
                if ( l_itr == l_abusConnections.end() )
                {
                    continue;
                }

                fapi::Target l_fapiEndpointTarget(TARGET_TYPE_ABUS_ENDPOINT,
                          (const_cast<TARGETING::Target*>(l_itr->second)) );

                switch (l_srcID)
                {
                    case 0:
                        l_procEntry.a0_chip = l_fapiEndpointTarget;
                        break;
                    case 1:
                        l_procEntry.a1_chip = l_fapiEndpointTarget;
                        break;
                    case 2:
                        l_procEntry.a2_chip = l_fapiEndpointTarget;
                        break;
                    default:
                        break;
                }

                const TARGETING::Target *l_pParent =
                           getParentChip(
                             (const_cast<TARGETING::Target*>(l_itr->second)));

                l_procEntry.f0_node_id = static_cast<proc_fab_smp_node_id>(
                        l_pTarget->getAttr<TARGETING::ATTR_FABRIC_NODE_ID>());
                l_procEntry.f1_node_id = static_cast<proc_fab_smp_node_id>(
                        l_pParent->getAttr<TARGETING::ATTR_FABRIC_NODE_ID>());
            }

            // Get X-BUS
            TARGETING::TargetHandleList l_xbuses;
            getChildChiplets( l_xbuses, l_pTarget, TYPE_XBUS );

            for (TARGETING::TargetHandleList::const_iterator
                    l_xbusIter = l_xbuses.begin();
                    l_xbusIter != l_xbuses.end();
                    ++l_xbusIter)
            {
                const TARGETING::Target * l_target = *l_xbusIter;
                uint8_t l_srcID = l_target->getAttr<ATTR_CHIP_UNIT>();
                TargetPairs_t::iterator l_itr =
                                l_xbusConnections.find(l_target);
                if ( l_itr == l_xbusConnections.end() )
                {
                    continue;
                }

                fapi::Target l_fapiEndpointTarget(TARGET_TYPE_XBUS_ENDPOINT,
                            (const_cast<TARGETING::Target*>(l_itr->second)) );

                switch (l_srcID)
                {
                    case 0:
                        l_procEntry.x0_chip = l_fapiEndpointTarget;
                        break;
                    case 1:
                        l_procEntry.x1_chip = l_fapiEndpointTarget;
                        break;
                    case 2:
                        l_procEntry.x2_chip = l_fapiEndpointTarget;
                        break;
                    case 3:
                        l_procEntry.x3_chip = l_fapiEndpointTarget;
                        break;
                    default:
                        break;
                }
            }

            l_procChips.push_back( l_procEntry );
        }

        //  call the HWP with each fapi::Target
        FAPI_INVOKE_HWP( l_errl, proc_build_smp, l_procChips,
                         SMP_ACTIVATE_PHASE1 );

        if(l_errl)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                      "ERROR : proc_build_smp" );
            // Create IStep error log and cross reference error that occurred
            l_StepError.addErrorDetails(l_errl);
            // Commit error
            errlCommit( l_errl, HWPF_COMP_ID );
            break;
        }
        else
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                      "SUCCESS : proc_build_smp" );
        }

        // At the point where we can now change the proc chips to use
        // XSCOM rather than FSISCOM which is the default.

        TARGETING::TargetHandleList procChips;
        getAllChips(procChips, TYPE_PROC);

        TARGETING::TargetHandleList::iterator curproc = procChips.begin();

        // Loop through all proc chips
        while(curproc != procChips.end())
        {
            TARGETING::Target*  l_proc_target = *curproc;

            // If the proc chip supports xscom..
            if (l_proc_target->getAttr<ATTR_PRIMARY_CAPABILITIES>()
                .supportsXscom)
            {
                ScomSwitches l_switches =
                  l_proc_target->getAttr<ATTR_SCOM_SWITCHES>();

                // If Xscom is not already enabled.
                if ((l_switches.useXscom != 1) || (l_switches.useFsiScom != 0))
                {
                    l_switches.useFsiScom = 0;
                    l_switches.useXscom = 1;

                    // Turn off FSI scom and turn on Xscom.
                    l_proc_target->setAttr<ATTR_SCOM_SWITCHES>(l_switches);

                    // Reset the FSI2OPB logic on the new chips
                    l_errl = FSI::resetPib2Opb(l_proc_target);
                    if(l_errl)
                    {
                        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                                  "ERROR : resetPib2Opb on %.8X",
                                  TARGETING::get_huid(l_proc_target));
                        // Create IStep error log and cross reference error that occurred
                        l_StepError.addErrorDetails(l_errl);
                        // Commit error
                        errlCommit( l_errl, HWPF_COMP_ID );
                        break;
                    }
                }
            }

            // Enable PSI interrupts even if can't Xscom as
            // Pbus is up and interrupts can flow
            l_errl = INTR::enablePsiIntr(l_proc_target); 
            if(l_errl)
            {
                // capture the target data in the elog
                ErrlUserDetailsTarget(l_proc_target).addToLog( l_errl );

                break;
            }

            ++curproc;
        }


    } while (0);

    TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
            "call_proc_build_smp exit" );

    // end task, returning any errorlogs to IStepDisp
    return l_StepError.getErrorHandle();
}
Beispiel #16
0
void HBVddrMsg::createVddrData(
          VDDR_MSG_TYPE     i_requestType,
          RequestContainer& io_request) const
{
    TRACFCOMP( g_trac_volt, ENTER_MRK "HBVddrMsg::createVddrData" );

    // Go through all the memory buffers and gather their domains, domain
    // specific IDs, and domain specific voltages
    io_request.clear();

    do{

        TARGETING::TargetHandleList membufTargetList;
        //When request is a disable command, disable all present Centaurs
        // in case we go through a reconfigure loop
        if(i_requestType == HB_VDDR_DISABLE)
        {
            getChipResources( membufTargetList, TYPE_MEMBUF,
                              UTIL_FILTER_PRESENT );
        }
        //When the request is an enable command, enable only functional
        // centaurs.
        else
        {
            getAllChips(membufTargetList, TYPE_MEMBUF);
        }

        TARGETING::Target* pMembuf =NULL;
        for (TARGETING::TargetHandleList::const_iterator
                ppMembuf = membufTargetList.begin();
             ppMembuf != membufTargetList.end();
             ++ppMembuf)
        {
            pMembuf = *ppMembuf;

            if(i_requestType == HB_VDDR_ENABLE)
            {
                (void)addMemoryVoltageDomains<
                    TARGETING::ATTR_MSS_CENT_VDD_OFFSET_DISABLE,
                    TARGETING::ATTR_MEM_VDD_OFFSET_MILLIVOLTS,
                    TARGETING::ATTR_MEM_VDD_OFFSET_MILLIVOLTS,
                    TARGETING::ATTR_VDD_ID>(
                        pMembuf,
                        io_request);

                (void)addMemoryVoltageDomains<
                    TARGETING::ATTR_MSS_CENT_AVDD_OFFSET_DISABLE,
                    TARGETING::ATTR_MEM_AVDD_OFFSET_MILLIVOLTS,
                    TARGETING::ATTR_MEM_AVDD_OFFSET_MILLIVOLTS,
                    TARGETING::ATTR_AVDD_ID>(
                        pMembuf,
                        io_request);

                (void)addMemoryVoltageDomains<
                    TARGETING::ATTR_MSS_CENT_VCS_OFFSET_DISABLE,
                    TARGETING::ATTR_MEM_VCS_OFFSET_MILLIVOLTS,
                    TARGETING::ATTR_MEM_VCS_OFFSET_MILLIVOLTS,
                    TARGETING::ATTR_VCS_ID>(
                        pMembuf,
                        io_request);

                (void)addMemoryVoltageDomains<
                    TARGETING::ATTR_MSS_VOLT_VPP_OFFSET_DISABLE,
                    TARGETING::ATTR_MEM_VPP_OFFSET_MILLIVOLTS,
                    TARGETING::ATTR_VPP_BASE,
                    TARGETING::ATTR_VPP_ID>(
                        pMembuf,
                        io_request);
            }

            (void)addMemoryVoltageDomains<
                TARGETING::ATTR_MSS_VOLT_VDDR_OFFSET_DISABLE,
                TARGETING::ATTR_MEM_VDDR_OFFSET_MILLIVOLTS,
                TARGETING::ATTR_MSS_VOLT,
                TARGETING::ATTR_VMEM_ID>(
                    pMembuf,
                    io_request);
        }

        if (membufTargetList.size() > 1)
        {
            // Take out the duplicate records in io_request by first
            // sorting and then removing the duplicates
            std::sort(io_request.begin(), io_request.end(), compareVids);
            std::vector<hwsvPowrMemVoltDomainRequest_t>::iterator
                pInvalidEntries = std::unique(
                    io_request.begin(),
                    io_request.end(),
                    areVidsEqual);
            io_request.erase(pInvalidEntries,io_request.end());
        }

        if( ( (i_requestType == HB_VDDR_ENABLE) ||
              (i_requestType == HB_VDDR_POST_DRAM_INIT_ENABLE) )
           && (!membufTargetList.empty())      )
        {
            // Inhibit sending any request to turn on a domain with no voltage.
            // When disabling we don't need to do this because the voltage is
            // ignored.
            io_request.erase(
                std::remove_if(io_request.begin(), io_request.end(),
                    isUnusedVoltageDomain),io_request.end());
        }

    } while(0);

    TRACFCOMP( g_trac_volt, EXIT_MRK "HBVddrMsg::createVddrData" );
    return;
}
Beispiel #17
0
//******************************************************************************
// host_gard function
//******************************************************************************
void* host_gard( void *io_pArgs )
{
    TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_gard entry" );
    errlHndl_t errl;

    do {
        // Check whether we're in MPIPL mode
        TARGETING::Target* l_pTopLevel = NULL;
        targetService().getTopLevelTarget( l_pTopLevel );
        HWAS_ASSERT(l_pTopLevel, "HWAS host_gard: no TopLevelTarget");

        if (l_pTopLevel->getAttr<ATTR_IS_MPIPL_HB>())
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "MPIPL mode");

            // we only want EX units to be processed
            TARGETING::PredicateCTM l_exFilter(TARGETING::CLASS_UNIT,
                                           TARGETING::TYPE_EX);
            errl = collectGard(&l_exFilter);
            if (errl)
            {
               TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                               "collectGard returned error; breaking out");
                break;
            }
        }
        else
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace, "Normal IPL mode");

            errl = collectGard();
            if(errl)
            {
                TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                   "collectGard returned error; breaking out");
                break;
            }

            if (errl == NULL)
            {
                //  check and see if we still have enough hardware to continue
                errl = checkMinimumHardware();
                if(errl)
                {
                    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                      "check minimum hardware returned error; breaking out");
                    break;
                }
            }
            // If targets are deconfigured as a result of host_gard, they are
            // done so using the PLID as the reason for deconfiguration.  This
            // triggers the reconfigure loop attribute to be set, which causes
            // undesirable behavior, so we need to reset it here:

            // Read current value
            TARGETING::ATTR_RECONFIGURE_LOOP_type l_reconfigAttr =
                l_pTopLevel->getAttr<TARGETING::ATTR_RECONFIGURE_LOOP>();
            // Turn off deconfigure bit
            l_reconfigAttr &= ~TARGETING::RECONFIGURE_LOOP_DECONFIGURE;
            // Write back to attribute
            l_pTopLevel->setAttr<TARGETING::ATTR_RECONFIGURE_LOOP>
                    (l_reconfigAttr);
        }

        // Send message to FSP sending HUID of EX chip associated with
        // master core
        msg_t * core_msg = msg_allocate();
        core_msg->type = SBE::MSG_IPL_MASTER_CORE;
        const TARGETING::Target*  l_masterCore  = TARGETING::getMasterCore( );

         /*@    errorlog tag
          *  @errortype      ERRL_SEV_CRITICAL_SYS_TERM
          *  @moduleid       MOD_HOST_GARD
          *  @reasoncode     RC_MASTER_CORE_NULL
          *  @userdata1      0
          *  @userdata2      0
          *  @devdesc        HWAS host_gard: no masterCore found
          */
        if (l_masterCore == NULL)
        {
            TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                "No masterCore Found" );
            const bool hbSwError = true;
            errl = new ERRORLOG::ErrlEntry
                    (ERRORLOG::ERRL_SEV_CRITICAL_SYS_TERM,
                     HWAS::MOD_HOST_GARD,
                     HWAS::RC_MASTER_CORE_NULL,
                     0, 0, hbSwError);
            break;
        }
        // Get the EX chip associated with the master core as that is the
        // chip that
        //   has the IS_MASTER_EX attribute associated with it
        TARGETING::TargetHandleList targetList;
        getParentAffinityTargets(targetList,
                             l_masterCore,
                             TARGETING::CLASS_UNIT,
                             TARGETING::TYPE_EX);
        HWAS_ASSERT(targetList.size() == 1,
             "HWAS host_gard: Incorrect EX chip(s) associated with masterCore");
        core_msg->data[0] = 0;
        core_msg->data[1] = TARGETING::get_huid( targetList[0] );
        core_msg->extra_data = NULL;
        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
              "Sending MSG_MASTER_CORE message with HUID %08x",
              core_msg->data[1]);
        errl = MBOX::send(MBOX::IPL_SERVICE_QUEUE,core_msg);
        if (errl)
        {
            TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                      ERR_MRK"MBOX::send failed sending Master Core message");
            msg_free(core_msg);
            break;
        }
    } while (0);

    TRACDCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "host_gard exit" );
    return errl;
}
Beispiel #18
0
errlHndl_t getRtTarget(const TARGETING::Target* i_target,
                       rtChipId_t &o_chipId)
{
    errlHndl_t err = NULL;

    do
    {
        if(i_target == TARGETING::MASTER_PROCESSOR_CHIP_TARGET_SENTINEL)
        {
            TARGETING::Target* masterProcChip = NULL;
            TARGETING::targetService().
                masterProcChipTargetHandle(masterProcChip);

            i_target = masterProcChip;
        }

        TARGETING::TYPE target_type = i_target->getAttr<TARGETING::ATTR_TYPE>();

        if(target_type == TARGETING::TYPE_PROC)
        {
            // use 0b0000.0000.0000.0000.0000.0000.00NN.NCCC:
            uint32_t fabId =
                i_target->getAttr<TARGETING::ATTR_FABRIC_NODE_ID>();

            uint32_t procPos =
                i_target->getAttr<TARGETING::ATTR_FABRIC_CHIP_ID>();

            o_chipId = (fabId << CHIPID_NODE_SHIFT) + procPos;
        }
        else if( target_type == TARGETING::TYPE_MEMBUF)
        {
            //MEMBUF
            // 0b1000.0000.0000.0000.0000.00NN.NCCC.MMMM
            // where NNN id node, CCC is chip, MMMM is memory channel
            //
            TARGETING::TargetHandleList targetList;

            getParentAffinityTargets(targetList,
                                    i_target,
                                    TARGETING::CLASS_UNIT,
                                    TARGETING::TYPE_MCS);

            if( targetList.empty() )
            {
                uint32_t huid = get_huid(i_target);
                TRACFCOMP(g_trac_targeting,ERR_MRK
                          "getRtTarget: No target found for huid: %08x",
                          huid);
                /*@
                 * @errortype
                 * @moduleid     TARG_RT_GET_RT_TARGET
                 * @reasoncode   TARG_RT_UNIT_TARGET_NOT_FOUND
                 * @userdata1    HUID of given MEMBUF target
                 * @devdesc      No MCS target(s) found for the
                 *               given MEMBUF target
                 */
                err =
                    new ERRORLOG::ErrlEntry
                    (ERRORLOG::ERRL_SEV_INFORMATIONAL,
                     TARGETING::TARG_RT_GET_RT_TARGET,
                     TARGETING::TARG_RT_UNIT_TARGET_NOT_FOUND,
                     huid,
                     0,
                     true);

                ERRORLOG::ErrlUserDetailsTarget(i_target,"Runtime Target").
                    addToLog(err);

                break;
            }

            TARGETING::Target * target = targetList[0];
            uint32_t pos = target->getAttr<TARGETING::ATTR_CHIP_UNIT>();

            targetList.clear();
            getParentAffinityTargets(targetList,
                                     target,
                                     TARGETING::CLASS_CHIP,
                                     TARGETING::TYPE_PROC);

            if(targetList.empty())
            {
                err = procRtTargetError(target);
                break;
            }

            TARGETING::Target * proc_target = targetList[0];

            err = getRtTarget(proc_target, o_chipId);
            if(err)
            {
                break;
            }

            o_chipId = (o_chipId << UNIT_ID_SHIFT);
            o_chipId += pos;
            o_chipId |= MEMBUF_ID_TYPE;
        }
        else if(target_type == TARGETING::TYPE_EX ||
                target_type == TARGETING::TYPE_CORE)
        {
            // EX/CORE
            // 0b0100.0000.0000.0000.0000.00NN.NCCC.PPPP
            // NNN is node, CCC is chip, PPPP is core
            uint32_t pos = i_target->getAttr<TARGETING::ATTR_CHIP_UNIT>();

            const TARGETING::Target * proc_target = getParentChip(i_target);
            if(proc_target == NULL)
            {
                err =  procRtTargetError(i_target);
                break;
            }

            err = getRtTarget(proc_target, o_chipId);
            if(err)
            {
                break;
            }

            o_chipId = (o_chipId << UNIT_ID_SHIFT);
            o_chipId += pos;
            o_chipId |= CORE_ID_TYPE;
        }
        else
        {
            uint32_t huid = get_huid(i_target);
            TRACFCOMP(g_trac_targeting,ERR_MRK
                      "Runtime target type %d not supported."
                      " huid: %08x",
                      target_type,
                      huid);
            /*@
             * @errortype
             * @moduleid     TARG_RT_GET_RT_TARGET
             * @reasoncode   TARG_RT_TARGET_TYPE_NOT_SUPPORTED
             * @userdata1    HUID of the target
             * @userdata2    target_type
             * @devdesc      Target type not supported by HBRT.
             */
            err =
                new ERRORLOG::ErrlEntry
                (ERRORLOG::ERRL_SEV_INFORMATIONAL,
                 TARGETING::TARG_RT_GET_RT_TARGET,
                 TARGETING::TARG_RT_TARGET_TYPE_NOT_SUPPORTED,
                 huid,
                 target_type,
                 true);

            ERRORLOG::ErrlUserDetailsTarget(i_target,"Runtime Target").
                addToLog(err);
        }
    } while(0);

    return err;
}