Exemplo n.º 1
0
bool isNVDIMM( const TARGETING::Target * i_target )
{
    // Not the most elegant way of doing it but the hybrid attributes
    // are at the MCS level. Need to find my way up to MCS and check
    // if the dimm is hybrid
    TARGETING::TargetHandleList l_mcaList;
    getParentAffinityTargets(l_mcaList, i_target, TARGETING::CLASS_UNIT, TARGETING::TYPE_MCA);

    if (l_mcaList.size())
    {
        TARGETING::TargetHandleList l_mcsList;
        getParentAffinityTargets(l_mcsList, l_mcaList[0], TARGETING::CLASS_UNIT, TARGETING::TYPE_MCS);

        if(l_mcsList.size())
        {
            // 2-D array. [MCA][DIMM]
            TARGETING::ATTR_EFF_HYBRID_type l_hybrid;
            TARGETING::ATTR_EFF_HYBRID_MEMORY_TYPE_type l_hybrid_type;

            if( l_mcsList[0]->tryGetAttr<TARGETING::ATTR_EFF_HYBRID>(l_hybrid) &&
                l_mcsList[0]->tryGetAttr<TARGETING::ATTR_EFF_HYBRID_MEMORY_TYPE>(l_hybrid_type) )
            {
                //Using relative position to lookup the hybrid attribute for the current dimm
                TARGETING::ATTR_REL_POS_type l_dimm_rel_pos = i_target->getAttr<ATTR_REL_POS>();
                TARGETING::ATTR_REL_POS_type l_mca_rel_pos = l_mcaList[0]->getAttr<ATTR_REL_POS>();

                // Verify code is not accessing outside of the array boundaries
                // Check if l_dimm_rel_pos is outside of l_hybrid column boundary
                assert(l_dimm_rel_pos < sizeof(l_hybrid[0]));

                // Check if l_mca_rel_pos is outside of l_hybrid row boundary
                assert(l_mca_rel_pos < (sizeof(l_hybrid)/sizeof(l_hybrid[0])));

                return (l_hybrid[l_mca_rel_pos][l_dimm_rel_pos] == TARGETING::EFF_HYBRID_IS_HYBRID &&
                        l_hybrid_type[l_mca_rel_pos][l_dimm_rel_pos] == TARGETING::EFF_HYBRID_MEMORY_TYPE_NVDIMM);
            }
        }
    }

    return false;
}
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;
}
/**
 *  @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;
}