Esempio n. 1
0
fapi2::ReturnCode ppe_resume(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
    const uint64_t i_base_address)
{
    fapi2::buffer<uint64_t> l_data64;

    static const uint32_t RESUME_TRIES = 10;
    uint32_t l_timeout_count = RESUME_TRIES;
    //Before reume always clear debug status (Michael's comment)
    FAPI_INF("   Clear debug status via XCR...");
    l_data64.flush<0>();
    FAPI_TRY(putScom(i_target, i_base_address + PPE_XIXCR, l_data64), "Error in PUTSCOM in XCR to clear dbg status");

    FAPI_INF("   Send RESUME command via XCR...");
    l_data64.flush<0>().insertFromRight(p9hcd::RESUME, 1, 3);

    FAPI_TRY(putScom(i_target, i_base_address + PPE_XIXCR, l_data64), "Error in PUTSCOM in XCR to resume condition");

    do
    {
        FAPI_TRY(getScom(i_target, i_base_address + PPE_XIRAMEDR, l_data64));
        FAPI_DBG("   Poll content:  XSR: 0x%16llX", l_data64);
    }
    while((l_data64.getBit<p9hcd::HALTED_STATE>() != 0) && (--l_timeout_count != 0));

fapi_try_exit:
    return fapi2::current_err;
}
Esempio n. 2
0
errlHndl_t FakeRegSvc::modifyScom(
                TargetHandle_t i_target,
                uint64_t i_address,
                uint64_t i_data,
                uint64_t & o_data,
                ScomOp i_op)
{
    errlHndl_t err = 0;

    uint64_t data = iv_regs[i_target][i_address];


    uint64_t changedData = i_op == SCOM_OR
        ? (data | i_data)
        : (data & i_data);

    bool changed = changedData != data;

    if(changed)
    {
        putScom(
                i_target,
                i_address,
                changedData);

    }

    return err;
}
Esempio n. 3
0
errlHndl_t MemInjectSink::putAttention(const AttnData & i_attn)
{
    return putScom(
            getTargetService().getMcs(i_attn.targetHndl),
            MCI::address,
            ~0);
}
Esempio n. 4
0
fapi2::ReturnCode ppe_hard_reset(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
    const uint64_t i_base_address)
{
    fapi2::buffer<uint64_t> l_data64;

    FAPI_INF("   Hard reset via XCR...");
    l_data64.flush<0>().insertFromRight(6, 1, 3);
    FAPI_TRY(putScom(i_target, i_base_address + PPE_XIXCR, l_data64), "Error in PUTSCOM in XCR to do hard reset");


fapi_try_exit:
    return fapi2::current_err;
}
Esempio n. 5
0
fapi2::ReturnCode ppe_resume_only(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
    const uint64_t i_base_address)
{
    fapi2::buffer<uint64_t> l_data64;

    FAPI_INF("   Resume only through XCR...");
    l_data64.flush<0>().insertFromRight(p9hcd::RESUME, 1, 3);
    FAPI_TRY(putScom(i_target, i_base_address + PPE_XIXCR, l_data64), "Error in PUTSCOM in XCR only resume");


fapi_try_exit:
    return fapi2::current_err;
}
Esempio n. 6
0
fapi2::ReturnCode ppe_clear_dbg(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
    const uint64_t i_base_address)
{
    fapi2::buffer<uint64_t> l_data64;

    FAPI_INF("   Clear debug status via XCR...");
    l_data64.flush<0>();
    FAPI_TRY(putScom(i_target, i_base_address + PPE_XIXCR, l_data64), "Error in PUTSCOM in XCR to clear dbg status");



fapi_try_exit:
    return fapi2::current_err;
}
Esempio n. 7
0
fapi2::ReturnCode ppe_halt(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
    const uint64_t i_base_address)
{
    fapi2::buffer<uint64_t> l_data64;

    FAPI_INF("   Send HALT command via XCR...");
    l_data64.flush<0>().insertFromRight(p9hcd::HALT, 1, 3);

    FAPI_TRY(putScom(i_target, i_base_address + PPE_XIXCR, l_data64), "Error in PUTSCOM in XCR to generate Halt condition");

    FAPI_TRY(ppe_pollHaltState(i_target, i_base_address));

fapi_try_exit:
    return fapi2::current_err;
}
Esempio n. 8
0
fapi2::ReturnCode ppe_ss_only(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
    const uint64_t i_base_address,
    uint64_t i_step_count)
{
    fapi2::buffer<uint64_t> l_data64;

    FAPI_TRY(ppe_pollHaltState(i_target, i_base_address));


    while(i_step_count != 0)
    {
        FAPI_DBG("   Send Single step command via XCR...step count = 0x%16llx", i_step_count);
        l_data64.flush<0>().insertFromRight(p9hcd::SINGLE_STEP, 1, 3);
        FAPI_TRY(putScom(i_target, i_base_address + PPE_XIXCR, l_data64),
                 "Error in PUTSCOM in XCR to generate Single Step condition");
        --i_step_count;  //Decrement step count
        FAPI_TRY(ppe_pollHaltState(i_target, i_base_address));
    }


fapi_try_exit:
    return fapi2::current_err;
}
Esempio n. 9
0
errlHndl_t FakePrd::callPrd(const AttentionList & i_attentions)
{
    errlHndl_t  l_elog = i_attentions.forEach(Clear(*iv_injectSink)).err;

    AttnList    l_attnList;
    i_attentions.getAttnList(l_attnList);


    ATTN_TRACE("fakeCallPrd with Attn Count of %d", l_attnList.size());

    // -----------------------------------------------------
    // This is FAKE code only.
    // If you do the EC/MODEL check, it crashes in CXX testcase.
    // Kind of thinking some library missing that is needed when
    // adding these calls, For now, I will just leave them out
    // and we could probably scrap this test now that it runs
    // successfully  (see attntestproc.H)
    // (Maybe add to 'fake target service' for these ATTRs)
    // -----------------------------------------------------
    // For the initial NIMBUS chip, there is a HW issue
    // which requires us to clear the "Combined Global
    // interrupt register" on recoverable errors.
    // This also affects Checkstop/Special Attns, but
    // the FSP handles those and already clears the reg.
    // The issue does not apply to host/unit cs attns.
//    uint8_t l_ecLevel = 0;
    AttnList::iterator  l_attnIter = l_attnList.begin();

    // Shouldn't be mixing NIMBUS with CUMULUS,etc...
    // so probably don't need to repeat this call per chip.
//    bool l_isNimbus = ( (*l_attnIter).targetHndl->
//                        getAttr<ATTR_MODEL>() == MODEL_NIMBUS );

    // Iterate thru all chips in case PRD handled
    // a chip other than the first one.
    while(l_attnIter != l_attnList.end())
    {
//        l_ecLevel = (*l_attnIter).targetHndl->getAttr<ATTR_EC>();


        if ( (RECOVERABLE == (*l_attnIter).attnType)
//             && (true == l_isNimbus) && (l_ecLevel < 0x11)
           )
        {
            errlHndl_t l_scomErr = NULL;
            uint64_t   l_clrAllBits = 0;

            l_scomErr = putScom( (*l_attnIter).targetHndl,
                                  PIB_INTR_TYPE_REG,
                                  l_clrAllBits
                                );

            if (NULL != l_scomErr)
            {
                 ATTN_ERR("Clear PibIntrReg failed, HUID:0X%08X",
                          get_huid( (*l_attnIter).targetHndl) );
                 errlCommit(l_scomErr, ATTN_COMP_ID);
            } // failed to clear PIB intr reg

        } // if recoverable attn

        ++l_attnIter;

    } // end while looping thru attn list


    return l_elog;
}
Esempio n. 10
0
void ServiceCommon::processAttnPreAck(const TargetHandle_t i_proc)
{
    uint64_t hostMask = HostMask::host();
    uint64_t nonHostMask = HostMask::nonHost();
    uint64_t data = 0;

    // do the minimum that is required
    // for sending EOI without getting
    // another interrupt.  for host attentions
    // this is clearing the gpio interrupt
    // type status register
    // and for xstp,rec,spcl this is
    // masking the appropriate bit in
    // ipoll mask

    // read the ipoll status register
    // to determine the interrupt was
    // caused by host attn or something
    // else (xstp,rec,spcl)

    errlHndl_t err = getScom(i_proc, IPOLL_STATUS_REG, data);

    if(err)
    {
        errlCommit(err, ATTN_COMP_ID);

        // assume everything is on

        data = hostMask | nonHostMask;
    }

    if(data & hostMask)
    {
        // if host attention, clear the ITR macro gpio interrupt
        // type status register.

        err = putScom(i_proc, INTR_TYPE_LCL_ERR_STATUS_AND_REG, 0);

        if(err)
        {
            errlCommit(err, ATTN_COMP_ID);
        }
    }

    if(data & nonHostMask)
    {
        // mask local proc xstp,rec and/or special attns if on.

        // the other thread might be trying to unmask
        // on the same target.  The mutex ensures
        // neither thread corrupts the register.

        mutex_lock(&iv_mutex);

        err = modifyScom(i_proc, IPOLL::address, data & nonHostMask, SCOM_OR);

        mutex_unlock(&iv_mutex);

        if(err)
        {
            errlCommit(err, ATTN_COMP_ID);
        }
    }
}
Esempio n. 11
0
fapi2::ReturnCode p9a_omi_setup_bars(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    FAPI_DBG("Start");
    std::vector<uint64_t> l_base_addr_nm0;
    std::vector<uint64_t> l_base_addr_nm1;
    std::vector<uint64_t> l_base_addr_m;
    fapi2::buffer<uint64_t> l_mmio_bar;
    fapi2::buffer<uint64_t> l_cfg_bar;
    uint64_t l_base_addr_mmio;
    uint8_t l_pos;
    uint8_t l_mcc_pos;
    uint64_t l_ext_mask;

    // determine base address of chip MMIO range
    FAPI_TRY(p9_fbc_utils_get_chip_base_address(i_target,
             EFF_FBC_GRP_CHIP_IDS,
             l_base_addr_nm0,
             l_base_addr_nm1,
             l_base_addr_m,
             l_base_addr_mmio),
             "Error from p9_fbc_utils_get_chip_base_address");

    FAPI_TRY(p9a_get_ext_mask(l_ext_mask));

    FAPI_DBG("l_ext_mask: %x", l_ext_mask);
    FAPI_DBG("l_base_addr_mmio: 0x%llx", l_base_addr_mmio);

    for (auto l_mcc : i_target.getChildren<fapi2::TARGET_TYPE_MCC>())
    {
        fapi2::ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET_Type l_bar_offset;
        uint64_t l_omi_inband_addr = 0;
        fapi2::buffer<uint64_t> l_scom_data;

        auto l_omi_targets = l_mcc.getChildren<fapi2::TARGET_TYPE_OMI>();

        if (l_omi_targets.size() > 0)
        {

            // Set the sizes for the MMIO/Config bars
            FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, l_mcc, l_pos),
                     "Error getting ATTR_CHIP_UNIT_POS, l_rc 0x%.8X",
                     (uint64_t)fapi2::current_err);

            l_scom_data.flush<0>();
            // 2GB cfg and MMIO
            l_scom_data.insertFromRight<P9A_MI_MCFGP0_MCFGPR0_CONFIGURATION_GROUP_SIZE,
                                        P9A_MI_MCFGP0_MCFGPR0_CONFIGURATION_GROUP_SIZE_LEN>(mss::exp::ib::EXPLR_IB_BAR_SIZE);
            l_scom_data.insertFromRight<P9A_MI_MCFGP0_MCFGPR0_MMIO_GROUP_SIZE,
                                        P9A_MI_MCFGP0_MCFGPR0_MMIO_GROUP_SIZE_LEN>(mss::exp::ib::EXPLR_IB_BAR_SIZE);

            // Write to reg
            if (l_pos % 2 == 0)
            {
                FAPI_INF("Write MCFGP0 reg 0x%.16llX, Value 0x%.16llX",
                         P9A_MI_MCFGP0, l_scom_data);
                FAPI_TRY(fapi2::putScom(l_mcc.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGP0, l_scom_data),
                         "Error writing to MCS_MCFGP reg");
            }
            else
            {
                FAPI_INF("Write MCFGP1 reg 0x%.16llX, Value 0x%.16llX",
                         P9A_MI_MCFGP1, l_scom_data);
                FAPI_TRY(fapi2::putScom(l_mcc.getParent<fapi2::TARGET_TYPE_MI>(), P9A_MI_MCFGP1, l_scom_data),
                         "Error writing to MCS_MCFGP reg");
            }

            for (auto l_omi : l_omi_targets)
            {
                // retrieve OMI pos
                FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
                                       l_omi,
                                       l_pos),
                         "Error from FAPI_ATTR_GET (ATTR_CHIP_UNIT_POS)");

                // retrieve inband BAR offset
                FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET,
                                       l_omi,
                                       l_bar_offset),
                         "Error from FAPI_ATTR_GET (ATTR_OMI_INBAND_BAR_BASE_ADDR_OFFSET)");

                FAPI_DBG("l_bar_offset: 0x%llx", l_bar_offset);

                // If this is channel B, then the B bit must be set.  If it is not, then the B bit must not be set.
                FAPI_ASSERT( ((l_pos % 2) == 1) ==  // Is this B channel?
                             ((l_bar_offset & mss::exp::ib::EXPLR_IB_BAR_B_BIT) == mss::exp::ib::EXPLR_IB_BAR_B_BIT),

                             fapi2::PROC_OMI_SETUP_BARS_INVALID_BAR()
                             .set_TARGET(l_omi)
                             .set_BAR_VALUE(l_bar_offset),
                             "B Channel requires BAR size bit set");

                FAPI_ASSERT(((l_bar_offset & mss::exp::ib::EXPLR_IB_BAR_MASK_ZERO) == 0),
                            fapi2::PROC_OMI_SETUP_BARS_INVALID_BAR()
                            .set_TARGET(l_omi)
                            .set_BAR_VALUE(l_bar_offset),
                            "Bar size not honored");

                FAPI_ASSERT(((l_bar_offset & mss::exp::ib::EXPLR_IB_MMIO_OFFSET) == 0),
                            fapi2::PROC_OMI_SETUP_BARS_INVALID_BAR()
                            .set_TARGET(l_omi)
                            .set_BAR_VALUE(l_bar_offset),
                            "MMIO bit must not be set");

                l_omi_inband_addr = l_bar_offset;
            }

            FAPI_DBG("l_omi_inband_addr: 0x%llx", l_omi_inband_addr);

            // Force A Bar value
            l_omi_inband_addr = l_omi_inband_addr & (~mss::exp::ib::EXPLR_IB_BAR_B_BIT);

            FAPI_DBG("l_omi_inband_addr: 0x%llx", l_omi_inband_addr);

            // Add MMIO address for the chip
            l_omi_inband_addr = l_omi_inband_addr | l_base_addr_mmio;

            FAPI_DBG("l_omi_inband_addr: 0x%llx", l_omi_inband_addr);

            // Get cfg bar value
            fapi2::buffer<uint64_t> l_omi_inband_buf = l_omi_inband_addr;
            FAPI_DBG("l_omi_inband_buf: 0x%llx", l_omi_inband_buf);
            FAPI_TRY(extendBarAddress(l_ext_mask, l_omi_inband_buf, l_cfg_bar));

            FAPI_DBG("l_cfg_bar: 0x%llx", l_cfg_bar);

            // Get MMIO bar value
            l_omi_inband_addr = l_omi_inband_addr | mss::exp::ib::EXPLR_IB_MMIO_OFFSET;
            l_omi_inband_buf = l_omi_inband_addr;
            FAPI_DBG("l_omi_inband_buf: 0x%llx", l_omi_inband_buf);
            FAPI_TRY(extendBarAddress(l_ext_mask, l_omi_inband_buf, l_mmio_bar));

            FAPI_DBG("l_mmio_bar: 0x%llx", l_mmio_bar);

            // Write the channel cfg reg
            l_scom_data.flush<0>();
            l_scom_data.setBit<P9A_MI_MCFGPR0_CONFIGURATION_VALID>(); //Enable CFG
            l_scom_data.setBit<P9A_MI_MCFGPR0_MMIO_VALID>(); //Enable MMIO
            l_scom_data.insert<P9A_MI_MCFGPR0_CONFIGURATION_GROUP_BASE_ADDRESS,
                               P9A_MI_MCFGPR0_CONFIGURATION_GROUP_BASE_ADDRESS_LEN>(l_cfg_bar);
            l_scom_data.insert<P9A_MI_MCFGPR0_MMIO_GROUP_BASE_ADDRESS,
                               P9A_MI_MCFGPR0_MMIO_GROUP_BASE_ADDRESS_LEN>(l_mmio_bar);

            // get MI target to configure MCFGPR
            fapi2::Target<fapi2::TARGET_TYPE_MI> l_mi =
                l_mcc.getParent<fapi2::TARGET_TYPE_MI>();
            // retrieve DMI pos
            FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
                                   l_mcc,
                                   l_mcc_pos),
                     "Error from FAPI_ATTR_GET (ATTR_CHIP_UNIT_POS)");

            // configure inband channel 0 MCFGPR0
            if(l_mcc_pos % 2 == 0)
            {
                FAPI_TRY(putScom(l_mi, P9A_MI_MCFGPR0, l_scom_data));
            }
            // configure inband channel 1 MCFGPR1
            else
            {
                FAPI_TRY(putScom(l_mi, P9A_MI_MCFGPR1, l_scom_data));
            }
        }
    }

fapi_try_exit:
    FAPI_DBG("End");
    return fapi2::current_err;
}
Esempio n. 12
0
void Service::processIntrQMsgPreAck(const msg_t & i_msg)
{
    // this function should do as little as possible
    // since the hw can't generate additional interrupts
    // until the msg is acknowledged

    TargetHandle_t proc = NULL;

    INTR::XISR_t xisr;

    xisr.u32 = i_msg.data[0];

    TargetHandleList procs;
    getTargetService().getAllChips(procs, TYPE_PROC);

    TargetHandleList::iterator it = procs.begin();

    // resolve the xisr to a proc target

    while(it != procs.end())
    {
        uint64_t node = 0, chip = 0;

        getTargetService().getAttribute(ATTR_FABRIC_NODE_ID, *it, node);
        getTargetService().getAttribute(ATTR_FABRIC_CHIP_ID, *it, chip);

        if(node == xisr.node
                && chip == xisr.chip)
        {
            proc = *it;
            break;
        }

        ++it;
    }

    uint64_t hostMask = HostMask::host();
    uint64_t nonHostMask = HostMask::nonHost();
    uint64_t data = 0;

    // do the minimum that is required
    // for sending EOI without getting
    // another interrupt.  for host attentions
    // this is clearing the gpio interrupt
    // type status register
    // and for xstp,rec,spcl this is
    // masking the appropriate bit in
    // ipoll mask

    // read the ipoll status register
    // to determine the interrupt was
    // caused by host attn or something
    // else (xstp,rec,spcl)

    errlHndl_t err = getScom(proc, IPOLL_STATUS_REG, data);

    if(err)
    {
        errlCommit(err, ATTN_COMP_ID);

        // assume everything is on

        data = hostMask | nonHostMask;
    }

    if(data & hostMask)
    {
        // if host attention, clear the ITR macro gpio interrupt
        // type status register.

        err = putScom(proc, INTR_TYPE_LCL_ERR_STATUS_AND_REG, 0);

        if(err)
        {
            errlCommit(err, ATTN_COMP_ID);
        }
    }

    if(data & nonHostMask)
    {
        // mask local proc xstp,rec and/or special attns if on.

        // the other thread might be trying to unmask
        // on the same target.  The mutex ensures
        // neither thread corrupts the register.

        mutex_lock(&iv_mutex);

        err = modifyScom(proc, IPOLL::address, data & nonHostMask, SCOM_OR);

        mutex_unlock(&iv_mutex);

        if(err)
        {
            errlCommit(err, ATTN_COMP_ID);
        }
    }
}
Esempio n. 13
0
errlHndl_t Service::configureInterrupts(
        msg_q_t i_q,
        ConfigureMode i_mode)
{
    errlHndl_t err = NULL;

    // First register for Q
    // This will set up the psi host bridge logic for
    // lcl_err interrupt on all chips

    if(i_mode == UP)
    {
        err = INTR::registerMsgQ(i_q,
                                 ATTENTION,
                                 INTR::ISN_LCL_ERR);
    }

    // setup the ITR macro for GPIO type host attentions,
    // on all procs

    if(!err)
    {
        TargetHandleList procs;
        getTargetService().getAllChips(procs, TYPE_PROC);
        TargetHandleList::iterator it = procs.begin();

        while(it != procs.end())
        {
            uint64_t mask = 0;

            // clear GPIO interrupt type status register

            if(i_mode == UP)
            {
                err = putScom(*it, INTR_TYPE_LCL_ERR_STATUS_AND_REG,
                              0);
            }

            if(err)
            {
                break;
            }

            // unmask GPIO interrupt type

            mask = 0x8000000000000000ull;

            err = putScom(
                    *it,
                    (i_mode == UP
                     ? INTR_TYPE_MASK_AND_REG
                     : INTR_TYPE_MASK_OR_REG),
                    i_mode == UP ? ~mask : mask);

            if(err)
            {
                break;
            }

            // set GPIO interrupt type mode - or

            if(i_mode == UP)
            {
                err = putScom(*it, INTR_TYPE_CONFIG_AND_REG,
                                 ~mask);
            }

            if(err)
            {
                break;
            }

            // enable/disable MCSes

            mask = 0;

            GP1::forEach(~0, &mask, &getPbGp2Mask);

            err = modifyScom(
                             *it,
                             GP2_REG,
                             i_mode == UP ? mask : ~mask,
                             i_mode == UP ? SCOM_OR : SCOM_AND);

            if(err)
            {
                break;
            }

            // enable attentions in ipoll mask

            mask = HostMask::nonHost();
            mask |= HostMask::host();

            // this doesn't have an and/or reg for some reason...

            err = modifyScom(
                    *it,
                    IPOLL::address,
                    i_mode == UP ? ~mask : mask,
                    i_mode == UP ? SCOM_AND : SCOM_OR);

            if(err)
            {
                break;
            }

            ++it;
        }

        if(!err && i_mode == DOWN)
        {
            if(NULL == INTR::unRegisterMsgQ(INTR::ISN_LCL_ERR))
            {
                ATTN_ERR("INTR did not find isn: 0x%07x",
                        INTR::ISN_LCL_ERR);
            }
        }
    }
    return err;
}
Esempio n. 14
0
    /** brief handle chip attentions
     *
     *  @param[in] i_proc - processor chip id at attention
     *                      XSCOM chip id based on devtree defn
     *  @param[in] i_ipollStatus - processor chip Ipoll status
     *  @param[in] i_ipollMask   - processor chip Ipoll mask
     *  @return 0 on success else return code
     */
    int handleAttns(uint64_t i_proc,
                    uint64_t i_ipollStatus,
                    uint64_t i_ipollMask)
    {
        ATTN_SLOW(ENTER_MRK"ATTN_RT::handleAttns RtProc: %llx"
                  ", ipollMask: %llx, ipollStatus: %llx",
                  i_proc, i_ipollMask, i_ipollStatus);

        int rc = 0;
        errlHndl_t err = NULL;
        AttentionList attentions;
        MemOps & memOps = getMemOps();
        uint64_t l_iprScomData = 0;


        do
        {
            // Convert chipIds to HB targets
            TargetHandle_t proc = NULL;
            err = RT_TARG::getHbTarget(i_proc, proc);
            if(err)
            {
                ATTN_ERR("ATTN_RT::handleAttns getHbTarget "
                   "returned error for RtProc: %llx", i_proc);
                rc = EINVAL;
                break;
            }

            err = Singleton<Service>::instance().handleAttentions(proc);
            if(err)
            {
                ATTN_ERR("ATTN_RT::handleAttns service::handleAttentions "
                   "returned error for RtProc: %llx", i_proc);
                break;
            }

            // For host attentions, clear gpio interrupt type register.
            // If we do not clear gpio register, ipoll status will again
            // get set and we will end up in infinite loop.

            uint64_t hostMask = 0;
            IPOLL::getCheckbits(HOST, hostMask);

            if( i_ipollMask & hostMask)
            {
                // After handling attn, check GP1 for more attns
                // as there could be additional memory units with attns.
                attentions.clear();

                err = memOps.resolve(proc, attentions);

                if(err)
                {
                    ATTN_ERR("RT GP1 Chk:memOps  returned error.HUID:0X%08X ",
                              get_huid( proc ));
                    break;
                }


                // Save the IPR if any attns still active on Centaurs
                if (!attentions.empty())
                {
                    err = getScom(proc, INTR_TYPE_LCL_ERR_STATUS_REG,
                                  l_iprScomData);

                    if(err)
                    {
                        ATTN_ERR("RT SaveIPR returned error.HUID:0X%08X ",
                                  get_huid( proc ));
                        break;
                    }

                } // end if any attentions


                // Clear the IPR (interrupt presentation register)
                err = putScom(proc, INTR_TYPE_LCL_ERR_STATUS_AND_REG, 0);

                if(err)
                {
                    ATTN_ERR("ATTN_RT::handleAttns putscom failed for "
                             "RtProc: %llx address:0x%08X", i_proc,
                              INTR_TYPE_LCL_ERR_STATUS_AND_REG);
                    break;
                }


                // Restore the IPR if any attns still active in Centaurs
                if (!attentions.empty())
                {
                    err = putScom(proc, INTR_TYPE_LCL_ERR_STATUS_OR_REG,
                                  l_iprScomData);

                    if(err)
                    {
                        ATTN_ERR("RT RestoreIPR returned error.HUID:0X%08X ",
                                  get_huid( proc ));
                        break;
                    }

                } // end if any attentions

            } // end if i_ipollMask & hostMask)

        } while(0);

        if(err)
        {
            errlCommit( err, ATTN_COMP_ID );
            if(0 == rc)
            {
                rc = -1;
            }
        }


        attentions.clear();
        ATTN_SLOW(EXIT_MRK"ATTN_RT::handleAttns rc: %d", rc);

        return rc;
    }
Esempio n. 15
0
fapi2::ReturnCode
p9_hcd_core_stopclocks(
    const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target,
    const bool i_sync_stop_quad_clk)
{
    FAPI_INF(">>p9_hcd_core_stopclocks");
    fapi2::ReturnCode                              l_rc;
    fapi2::buffer<uint64_t>                        l_ccsr;
    fapi2::buffer<uint64_t>                        l_data64;
    fapi2::buffer<uint64_t>                        l_temp64;
    uint32_t                                       l_loops1ms;
    uint8_t                                        l_attr_chip_unit_pos;
    uint8_t                                        l_attr_vdm_enabled;
    uint8_t                                        l_attr_sdisn_setup;
    const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> l_sys;
    auto  l_quad = i_target.getParent<fapi2::TARGET_TYPE_EQ>();
    auto  l_perv = i_target.getParent<fapi2::TARGET_TYPE_PERV>();
    auto  l_chip = i_target.getParent<fapi2::TARGET_TYPE_PROC_CHIP>();

    auto l_ex_vector = l_quad.getChildren<fapi2::TARGET_TYPE_EX>
                       (fapi2::TARGET_STATE_FUNCTIONAL);

    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_SDISN_SETUP, l_chip,
                           l_attr_sdisn_setup));

    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_VDM_ENABLED,      l_chip,
                           l_attr_vdm_enabled));
    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,    l_perv,
                           l_attr_chip_unit_pos));
    l_attr_chip_unit_pos = (l_attr_chip_unit_pos -
                            p9hcd::PERV_TO_CORE_POS_OFFSET) % 4;

    //Check if EQ is powered off; if so, return
    FAPI_TRY(fapi2::getScom(l_quad, EQ_PPM_PFSNS, l_data64),
             "Error reading data from EQ_PPM_PFSNS");

    if (l_data64.getBit<EQ_PPM_PFSNS_VDD_PFETS_DISABLED_SENSE>())
    {
        FAPI_DBG("Set core as stopped in STOP history register");
        FAPI_TRY(putScom(i_target, C_PPM_SSHSRC, BIT64(0)));
        return fapi2::current_err;
    }

    //Check if core is powered off; if so, return
    FAPI_TRY(fapi2::getScom(i_target, C_PPM_PFSNS, l_data64),
             "Error reading data from C_PPM_PFSNS");

    if (l_data64.getBit<C_PPM_PFSNS_VDD_PFETS_DISABLED_SENSE>())
    {
        FAPI_DBG("Set core as stopped in STOP history register");
        FAPI_TRY(putScom(i_target, C_PPM_SSHSRC, BIT64(0)));
        return fapi2::current_err;
    }


    // ----------------------------
    // Prepare to stop core clocks
    // ----------------------------

    FAPI_DBG("Check PM_RESET_STATE_INDICATOR via GPMMR[15]");
    FAPI_TRY(getScom(i_target, C_PPM_GPMMR_SCOM, l_data64));

    if (!l_data64.getBit<15>())
    {
        FAPI_DBG("Gracefully turn off power management, continue anyways if fail");
        /// @todo RTC158181 suspend_pm()
    }

    FAPI_DBG("Check core clock controller status");
    l_rc = p9_common_clk_ctrl_state<fapi2::TARGET_TYPE_CORE>(i_target);

    if (l_rc)
    {
        FAPI_INF("Clock controller of this core chiplet is inaccessible, return");
        goto fapi_try_exit;
    }

    FAPI_DBG("Check cache clock controller status");
    l_rc = p9_common_clk_ctrl_state<fapi2::TARGET_TYPE_EQ>(l_quad);

    if (l_rc)
    {
        FAPI_INF("WARNING: core is enabled while cache is not, continue anyways");
    }
    else
    {

        FAPI_DBG("Check PERV clock status for access to CME via CLOCK_STAT[4]");
        FAPI_TRY(getScom(l_quad, EQ_CLOCK_STAT_SL, l_data64));

        FAPI_DBG("Check PERV fence status for access to CME via CPLT_CTRL1[4]");
        FAPI_TRY(getScom(l_quad, EQ_CPLT_CTRL1, l_temp64));

        if (l_data64.getBit<4>() == 0 && l_temp64.getBit<4>() == 0)
        {

#ifdef DD2
            FAPI_DBG("Halting the PGPE ...");
            l_rc = ppe_halt(l_chip, PGPE_BASE_ADDRESS);
            FAPI_ASSERT_NOEXIT(!l_rc,
                               fapi2::CORE_STOPCLKS_PGPE_HALT_TIMEOUT()
                               .set_CHIP(l_chip),
                               "PSTATE GPE Halt timeout");

            FAPI_DBG("Halting the SGPE ...");
            l_rc = ppe_halt(l_chip, SGPE_BASE_ADDRESS);
            FAPI_ASSERT_NOEXIT(!l_rc,
                               fapi2::CORE_STOPCLKS_SGPE_HALT_TIMEOUT()
                               .set_CHIP(l_chip),
                               "STOP GPE Halt timeout");

            FAPI_DBG("Clear the atomic lock on EQ %d", l_attr_chip_unit_pos);
            l_rc = p9_clear_atomic_lock(l_quad);
            FAPI_ASSERT_NOEXIT(!l_rc,
                               fapi2::CORE_STOPCLKS_ATOMIC_LOCK_FAIL()
                               .set_EQ(l_quad),
                               "EQ Atomic Halt timeout");

            for ( auto& ex : l_ex_vector )
            {
                fapi2::ATTR_CHIP_UNIT_POS_Type  l_cme_id = 0;
                FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, ex, l_cme_id));

                FAPI_DBG("Halting CME %d", l_cme_id );
                uint64_t l_cme_base_address = getCmeBaseAddress (l_cme_id);
                l_rc = ppe_halt(l_chip, l_cme_base_address);
                FAPI_ASSERT_NOEXIT(!l_rc,
                                   fapi2::CACHE_STOPCLKS_CME_HALT_TIMEOUT()
                                   .set_EX(ex),
                                   "CME Halt timeout");
            }

#endif

            //if a core is only in special wakeup and asserting pm_exit,
            //then setting 6,7 of SICR will cause pm_exit to drop and
            //the core will re-enter a power saving state
            FAPI_DBG("Prevent Core-L2 Quiesce from removing PM_EXIT CME_SCOM_LMCR[22]");
            FAPI_TRY(putScom(l_quad,
                             (l_attr_chip_unit_pos < 2) ?
                             EX_0_CME_SCOM_LMCR_OR : EX_1_CME_SCOM_LMCR_OR,
                             (BIT64(22))));

            FAPI_DBG("Assert Core-L2/CC Quiesces via CME_SCOM_SICR[6,8]/[7,9]");
            FAPI_TRY(putScom(l_quad,
                             (l_attr_chip_unit_pos < 2) ?
                             EX_0_CME_SCOM_SICR_OR : EX_1_CME_SCOM_SICR_OR,
                             (BIT64(6 + (l_attr_chip_unit_pos % 2)) |
                              BIT64(8 + (l_attr_chip_unit_pos % 2)))));
        }
    }

    FAPI_DBG("Assert pm_mux_disable to get PCB Mux from CME via SLAVE_CONFIG[7]");
    FAPI_TRY(getScom(i_target, C_SLAVE_CONFIG_REG, l_data64));
    FAPI_TRY(putScom(i_target, C_SLAVE_CONFIG_REG, DATA_SET(7)));

    FAPI_DBG("Override possible PPM write protection to CME via CPPM_CPMMR[1]");
    FAPI_TRY(putScom(i_target, C_CPPM_CPMMR_OR, MASK_SET(1)));

    FAPI_DBG("Assert chiplet fence via NET_CTRL0[18]");
    FAPI_TRY(putScom(i_target, C_NET_CTRL0_WOR, MASK_SET(18)));

    // -------------------------------
    // Stop core clocks
    // -------------------------------

    FAPI_DBG("Clear all SCAN_REGION_TYPE bits");
    FAPI_TRY(putScom(i_target, C_SCAN_REGION_TYPE, MASK_ZERO));

    if(i_sync_stop_quad_clk)
    {
        FAPI_DBG("Stop core clocks(all but pll) via CLK_REGION in SLAVE mode");
        l_data64 = (p9hcd::CLK_STOP_CMD_SLAVE     |
                    p9hcd::CLK_REGION_ALL_BUT_PLL |
                    p9hcd::CLK_THOLD_ALL);
        FAPI_TRY(putScom(i_target, C_CLK_REGION, l_data64));

    }
    else
    {
        FAPI_DBG("Stop core clocks(all but pll) via CLK_REGION");
        l_data64 = (p9hcd::CLK_STOP_CMD           |
                    p9hcd::CLK_REGION_ALL_BUT_PLL |
                    p9hcd::CLK_THOLD_ALL);
        FAPI_TRY(putScom(i_target, C_CLK_REGION, l_data64));

        FAPI_DBG("Poll for core clocks stopped via CPLT_STAT0[8]");
        l_loops1ms = 1E6 / CORE_CLK_STOP_POLLING_HW_NS_DELAY;

        do
        {
            fapi2::delay(CORE_CLK_STOP_POLLING_HW_NS_DELAY,
                         CORE_CLK_STOP_POLLING_SIM_CYCLE_DELAY);

            FAPI_TRY(getScom(i_target, C_CPLT_STAT0, l_data64));
        }
        while((l_data64.getBit<8>() != 1) && ((--l_loops1ms) != 0));

        FAPI_ASSERT((l_loops1ms != 0),
                    fapi2::PMPROC_CORECLKSTOP_TIMEOUT().set_CORECPLTSTAT(l_data64),
                    "Core Clock Stop Timeout");

        FAPI_DBG("Check core clocks stopped via CLOCK_STAT_SL[4-13]");
        FAPI_TRY(getScom(i_target, C_CLOCK_STAT_SL, l_data64));

        FAPI_ASSERT((((~l_data64) & p9hcd::CLK_REGION_ALL_BUT_PLL) == 0),
                    fapi2::PMPROC_CORECLKSTOP_FAILED().set_CORECLKSTAT(l_data64),
                    "Core Clock Stop Failed");
        FAPI_DBG("Core clocks stopped now");
    }

    // -------------------------------
    // Disable core clock sync
    // -------------------------------

    FAPI_DBG("Drop core clock sync enable via CPPM_CACCR[15]");
    FAPI_TRY(putScom(i_target, C_CPPM_CACCR_CLEAR, MASK_SET(15)));

    FAPI_DBG("Poll for core clock sync done to drop via CPPM_CACSR[13]");
    l_loops1ms = 1E6 / CORE_CLK_SYNC_POLLING_HW_NS_DELAY;

    do
    {
        fapi2::delay(CORE_CLK_SYNC_POLLING_HW_NS_DELAY,
                     CORE_CLK_SYNC_POLLING_SIM_CYCLE_DELAY);

        FAPI_TRY(getScom(i_target, C_CPPM_CACSR, l_data64));
    }
    while((l_data64.getBit<13>() == 1) && ((--l_loops1ms) != 0));

    FAPI_ASSERT((l_loops1ms != 0),
                fapi2::PMPROC_CORECLKSYNCDROP_TIMEOUT().set_COREPPMCACSR(l_data64),
                "Core Clock Sync Drop Timeout");
    FAPI_DBG("Core clock sync done dropped");

    // -------------------------------
    // Fence up
    // -------------------------------

    FAPI_DBG("Assert skew sense to skew adjust fence via NET_CTRL0[22]");
    FAPI_TRY(putScom(i_target, C_NET_CTRL0_WOR, MASK_SET(22)));

    FAPI_DBG("Drop ABIST_SRAM_MODE_DC to support ABIST Recovery via BIST[1]");
    FAPI_TRY(getScom(i_target, C_BIST, l_data64));
    FAPI_TRY(putScom(i_target, C_BIST, DATA_UNSET(1)));

    FAPI_DBG("Assert vital fence via CPLT_CTRL1[3]");
    FAPI_TRY(putScom(i_target, C_CPLT_CTRL1_OR, MASK_SET(3)));

    FAPI_DBG("Assert regional fences via CPLT_CTRL1[4-14]");
    FAPI_TRY(putScom(i_target, C_CPLT_CTRL1_OR, p9hcd::CLK_REGION_ALL));

    if (l_attr_sdisn_setup)
    {
        FAPI_DBG("DD1 Only: Drop sdis_n(flushing LCBES condition) vai CPLT_CONF0[34]");
        FAPI_TRY(putScom(i_target, C_CPLT_CONF0_CLEAR, MASK_SET(34)));
    }

    // -------------------------------
    // Disable VDM
    // -------------------------------

    if (l_attr_vdm_enabled == fapi2::ENUM_ATTR_VDM_ENABLED_TRUE)
    {
        FAPI_DBG("Set VDM Disable via CPPM_VDMCR[1]");
        FAPI_TRY(putScom(i_target, C_PPM_VDMCR_OR, MASK_SET(1)));
        FAPI_DBG("Drop VDM Poweron via CPPM_VDMCR[0]");
        FAPI_TRY(putScom(i_target, C_PPM_VDMCR_CLEAR, MASK_SET(0)));
    }

    // -------------------------------
    // Update stop history
    // -------------------------------

    FAPI_DBG("Set core as stopped in STOP history register");
    FAPI_TRY(putScom(i_target, C_PPM_SSHSRC, BIT64(0)));

    // -------------------------------
    // Clean up
    // -------------------------------

    FAPI_DBG("Return possible PPM write protection to CME via CPPM_CPMMR[1]");
    FAPI_TRY(putScom(i_target, C_CPPM_CPMMR_CLEAR, MASK_SET(1)));

    FAPI_DBG("Drop pm_mux_disable to release PCB Mux via SLAVE_CONFIG[7]");
    FAPI_TRY(getScom(i_target, C_SLAVE_CONFIG_REG, l_data64));
    FAPI_TRY(putScom(i_target, C_SLAVE_CONFIG_REG, DATA_UNSET(7)));

fapi_try_exit:

    FAPI_INF("<<p9_hcd_core_stopclocks");
    return fapi2::current_err;
}
Esempio n. 16
0
errlHndl_t ServiceCommon::configureInterrupts(
        ConfigureMode i_mode)
{
    errlHndl_t err = NULL;

    TargetHandleList procs;
    getTargetService().getAllChips(procs, TYPE_PROC);
    TargetHandleList::iterator it = procs.begin();

    while(it != procs.end())
    {
        uint64_t mask = 0;

        // clear GPIO interrupt type status register

        if(i_mode == UP)
        {
            err = putScom(*it, INTR_TYPE_LCL_ERR_STATUS_AND_REG,
                          0);
        }

        if(err)
        {
            break;
        }

        // unmask GPIO interrupt type

        mask = 0x8000000000000000ull;

        err = putScom(*it,
                      (i_mode == UP
                       ? INTR_TYPE_MASK_AND_REG
                       : INTR_TYPE_MASK_OR_REG),
                      i_mode == UP ? ~mask : mask);

        if(err)
        {
            break;
        }

        // set GPIO interrupt type mode - or

        if(i_mode == UP)
        {
            err = putScom(*it, INTR_TYPE_CONFIG_AND_REG,
                          ~mask);
        }

        if(err)
        {
            break;
        }

        // enable/disable MCSes

        mask = 0;

        GP1::forEach(~0, &mask, &getPbGp2Mask);

        err = modifyScom(*it,
                         GP2_REG,
                         i_mode == UP ? mask : ~mask,
                         i_mode == UP ? SCOM_OR : SCOM_AND);

        if(err)
        {
            break;
        }

        // enable attentions in ipoll mask

        mask = HostMask::nonHost();
        mask |= HostMask::host();

        // this doesn't have an and/or reg for some reason...

        err = modifyScom(*it,
                         IPOLL::address,
                         i_mode == UP ? ~mask : mask,
                         i_mode == UP ? SCOM_AND : SCOM_OR);

        if(err)
        {
            break;
        }

        ++it;
    }

    return err;
}
Esempio n. 17
0
fapi2::ReturnCode ppe_single_step(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
    const uint64_t i_base_address,
    const uint16_t i_Rs,
    uint64_t i_step_count)
{
    fapi2::buffer<uint64_t> l_data64;
    fapi2::buffer<uint64_t> l_dbcr_save;
    fapi2::buffer<uint32_t> l_gpr31_save;
    fapi2::buffer<uint64_t> l_sprg0_save;

    FAPI_TRY(ppe_pollHaltState(i_target, i_base_address));
    // Save SPRG0 i_Rs before getting dbcr
    FAPI_DBG("Save SPRG0");
    FAPI_TRY(getScom(i_target, i_base_address + PPE_XIRAMDBG, l_data64), "Error in GETSCOM");
    l_data64.extractToRight(l_sprg0_save, 32, 32);
    FAPI_DBG("Saved SPRG0 value : 0x%08llX", l_sprg0_save );
    FAPI_DBG("Save i_Rs");
    l_data64.flush<0>().insertFromRight(ppe_getMtsprInstruction(i_Rs, SPRG0), 0, 32);
    FAPI_DBG("getMtsprInstruction(%d, SPRG0): 0x%16llX", R31, l_data64 );
    FAPI_TRY(ppe_RAMRead(i_target, i_base_address, l_data64, l_gpr31_save));
    FAPI_DBG("Saved GPR31 value : 0x%08llX", l_gpr31_save );

    FAPI_INF("   Read and Save DBCR");
    FAPI_DBG("Move DBCR to i_Rs");
    l_data64.flush<0>().insertFromRight(ppe_getMfsprInstruction(i_Rs, DBCR), 0, 32);
    FAPI_DBG("getMfsprInstruction(%d, DBCR): 0x%16llX", i_Rs, l_data64 );
    FAPI_TRY(fapi2::putScom(i_target, i_base_address + PPE_XIRAMEDR, l_data64));

    FAPI_DBG("Move i_Rs to SPRG0 : so now SPRG0 has DBCR value");
    l_data64.flush<0>().insertFromRight(ppe_getMtsprInstruction(i_Rs, SPRG0), 0, 32);
    FAPI_DBG("getMtsprInstruction(%d, SPRG0): 0x%16llX", i_Rs, l_data64 );
    FAPI_TRY(fapi2::putScom(i_target, i_base_address + PPE_XIRAMEDR, l_data64));

    FAPI_DBG("Save SPRG0 i.e. DBCR");
    FAPI_TRY(getScom(i_target, i_base_address + PPE_XIRAMDBG, l_data64), "Error in GETSCOM");
    l_data64.extractToRight(l_dbcr_save, 32, 32);
    FAPI_DBG("Saved DBCR value : 0x%08llX", l_dbcr_save );

    FAPI_DBG("clear DBCR[8] IACE and DBCR[12:13] DACE");
    FAPI_TRY(ppe_update_dbcr(i_target, i_base_address, ANDIS_CONST, 0x0F73, R31));

    //Restore i_Rs and SPRG0 before single step
    FAPI_DBG("Restore i_Rs");
    l_data64.flush<0>().insertFromRight(ppe_getMfsprInstruction(i_Rs, SPRG0), 0, 32);
    FAPI_DBG("getMfsprInstruction(R31, SPRG0): 0x%16llX",  l_data64 );
    l_data64.insertFromRight(l_gpr31_save, 32, 32);
    FAPI_DBG("Final Instr + SPRG0: 0x%16llX", l_data64 );
    //write sprg0 with address and ram mfsprg0 to i_Rs
    FAPI_TRY(fapi2::putScom(i_target, i_base_address + PPE_XIRAMGA, l_data64 ));
    FAPI_DBG("Restore SPRG0");
    FAPI_TRY(ppe_pollHaltState(i_target, i_base_address));
    FAPI_TRY(putScom(i_target, i_base_address + PPE_XIRAMDBG , l_sprg0_save), "Error in PUTSCOM");

    while(i_step_count != 0)
    {
        FAPI_DBG("   Send Single step command via XCR...step count = 0x%16llx", i_step_count);
        l_data64.flush<0>().insertFromRight(p9hcd::SINGLE_STEP, 1, 3);
        FAPI_TRY(putScom(i_target, i_base_address + PPE_XIXCR, l_data64),
                 "Error in PUTSCOM in XCR to generate Single Step condition");
        --i_step_count;  //Decrement step count
        FAPI_TRY(ppe_pollHaltState(i_target, i_base_address));
    }

    // Save SPRG0 i_Rs before getting dbcr
    FAPI_DBG("Save SPRG0");
    FAPI_TRY(getScom(i_target, i_base_address + PPE_XIRAMDBG, l_data64), "Error in GETSCOM");
    l_data64.extractToRight(l_sprg0_save, 32, 32);
    FAPI_DBG("Saved SPRG0 value : 0x%08llX", l_sprg0_save );
    FAPI_DBG("Save i_Rs");
    l_data64.flush<0>().insertFromRight(ppe_getMtsprInstruction(i_Rs, SPRG0), 0, 32);
    FAPI_DBG("getMtsprInstruction(%d, SPRG0): 0x%16llX", R31, l_data64 );
    FAPI_TRY(ppe_RAMRead(i_target, i_base_address, l_data64, l_gpr31_save));
    FAPI_DBG("Saved GPR31 value : 0x%08llX", l_gpr31_save );

    FAPI_INF("   Restore DBCR");
    FAPI_INF("   Write orig. DBCR into SPRG0");

    l_data64.flush<0>().insertFromRight(ppe_getMfsprInstruction(i_Rs, SPRG0), 0, 32);
    FAPI_DBG("getMfsprInstruction(%d, SPRG0): 0x%16llX", i_Rs, l_data64 );
    l_data64.insertFromRight(l_dbcr_save, 32, 32);
    FAPI_DBG("Final Instr + SPRG0: 0x%16llX", l_data64 );
    //write sprg0 with address and ram mfsprg0 to i_Rs
    FAPI_TRY(fapi2::putScom(i_target, i_base_address + PPE_XIRAMGA, l_data64 ));

    //then mtDBCR from i_Rs
    l_data64.flush<0>().insertFromRight(ppe_getMtsprInstruction(i_Rs, DBCR), 0, 32);
    FAPI_DBG("getMtsprInstruction(%d, DBCR): 0x%16llX", i_Rs, l_data64  );
    FAPI_TRY(fapi2::putScom(i_target, i_base_address + PPE_XIRAMEDR, l_data64));

    //Restore i_Rs and SPRG0 after dbcr updates
    FAPI_DBG("Restore i_Rs");
    l_data64.flush<0>().insertFromRight(ppe_getMfsprInstruction(i_Rs, SPRG0), 0, 32);
    FAPI_DBG("getMfsprInstruction(R31, SPRG0): 0x%16llX",  l_data64 );
    l_data64.insertFromRight(l_gpr31_save, 32, 32);
    FAPI_DBG("Final Instr + SPRG0: 0x%16llX", l_data64 );
    //write sprg0 with address and ram mfsprg0 to i_Rs
    FAPI_TRY(fapi2::putScom(i_target, i_base_address + PPE_XIRAMGA, l_data64 ));
    FAPI_DBG("Restore SPRG0");
    FAPI_TRY(ppe_pollHaltState(i_target, i_base_address));
    FAPI_TRY(putScom(i_target, i_base_address + PPE_XIRAMDBG , l_sprg0_save), "Error in GETSCOM");


fapi_try_exit:
    return fapi2::current_err;
}