Beispiel #1
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 #2
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 #3
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;
}
/**
 *  @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 #6
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;
}