Пример #1
0
fapi2::ReturnCode ppe_pollHaltState(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
    const uint64_t i_base_address)
{
    fapi2::buffer<uint64_t> l_data64;

    // Halt state entry should be very fast on PPEs (eg nanoseconds)
    // Try only using the SCOM access time to delay.
    static const uint32_t HALT_TRIES = 10;

    uint32_t l_timeout_count = HALT_TRIES;

    do
    {
        FAPI_TRY(getScom(i_target, i_base_address + PPE_XIRAMDBG, l_data64), "Error in GETSCOM");
    }
    while (! l_data64.getBit<0>() &&
           --l_timeout_count != 0);


    FAPI_ASSERT(l_data64.getBit<0>(), fapi2::P9_PPE_STATE_HALT_TIMEOUT_ERR(),
                "PPE Halt Timeout");


fapi_try_exit:
    return fapi2::current_err;
}
Пример #2
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;
}
Пример #3
0
errlHndl_t MemOps::resolve(
        TargetHandle_t i_proc,
        AttentionList & o_attentions)
{
    errlHndl_t err = 0;

    uint64_t gp1ScomData = 0;

    do {

        // get the nest gp1 register content and decode
        // (get a list of membufs reporting attentions)

        err = getScom(i_proc, GP1::address, gp1ScomData);

        if(err)
        {
            break;
        }

        ResolveMcsArgs args;

        args.proc = i_proc;
        args.list = &o_attentions;
        args.ops = this;

        GP1::forEach(gp1ScomData, &args, &resolveMcs);

    } while(0);

    return err;
}
Пример #4
0
void resolveMcs(uint64_t i_mcs, void * i_data)
{
    ResolveMcsArgs * args = static_cast<ResolveMcsArgs *>(i_data);

    uint64_t mciFirScomData;

    TargetHandle_t mcs = getTargetService().getMcs(args->proc, i_mcs);

    // read the MCI fir to determine what type of attention
    // centaur reporting

    errlHndl_t err = getScom(mcs, MCI::address, mciFirScomData);

    if(err)
    {
        errlCommit(err, ATTN_COMP_ID);
    }
    else
    {
        // pick the highest priority attention

        for(uint64_t type = INVALID_ATTENTION_TYPE;
                type != END_ATTENTION_TYPE;
                ++type)
        {
            uint64_t mask;

            if(!MCI::getCheckbits(type, mask))
            {
                // this object doesn't support
                // this attention type

                continue;
            }

            if(mask & mciFirScomData)
            {
                AttnData d;
                d.targetHndl = getTargetService().getMembuf(mcs);

                if(!d.targetHndl)
                {
                    // this membuf not functional
                    // or nothing is attached to this MCS

                    break;
                }

                d.attnType = static_cast<ATTENTION_VALUE_TYPE>(type);

                args->list->add(Attention(d, args->ops));
                break;
            }
        }
    }
}
Пример #5
0
fapi2::ReturnCode ppe_isHalted(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
    const uint64_t i_base_address,
    bool* o_halted)
{
    fapi2::buffer<uint64_t> l_data64;

    FAPI_TRY(getScom ( i_target,
                       i_base_address + PPE_XIRAMDBG,
                       l_data64 ),
             "Failed reading XIRAMDBG register!" );

    *o_halted = l_data64.getBit<0>();

fapi_try_exit:
    return fapi2::current_err;
}
Пример #6
0
errlHndl_t MemOps::resolve(
        TargetHandle_t i_proc,
        AttentionList & o_attentions)
{
    errlHndl_t err = 0;

    //@TODO: RTC:150944
    // Don't need this for now as this is Centaur Chip related
    ATTN_TRACE("MemOps::resolve - P9 Noop");

#if 0
    uint64_t gp1ScomData = 0;

    do {

        // get the nest gp1 register content and decode
        // (get a list of membufs reporting attentions)

        err = getScom(i_proc, GP1::address, gp1ScomData);

        if(err)
        {
            break;
        }

        ResolveMcsArgs args;

        args.proc = i_proc;
        args.list = &o_attentions;
        args.ops = this;

        GP1::forEach(gp1ScomData, &args, &resolveMcs);

    } while(0);
#endif

    return err;
}
Пример #7
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);
        }
    }
}
Пример #8
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;
}
Пример #9
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;
}
Пример #10
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;
    }
Пример #11
0
fapi2::ReturnCode p9_extract_sbe_rc(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target_chip,
                                    P9_EXTRACT_SBE_RC::RETURN_ACTION& o_return_action, bool i_set_sdb, bool i_unsecure_mode)
{

    fapi2::buffer<uint64_t> l_data64;
    fapi2::buffer<uint64_t> l_data64_dbgpro;
    fapi2::buffer<uint64_t> l_data64_fi2c_status;
    fapi2::buffer<uint64_t> l_data64_mib_mem_info;
    fapi2::buffer<uint64_t> l_data64_mib_sib_info;
    fapi2::buffer<uint32_t> l_data32;
    fapi2::buffer<uint32_t> l_data32_ir;
    fapi2::buffer<uint32_t> l_data32_edr;
    fapi2::buffer<uint32_t> l_data32_iar;
    bool l_ppe_halt_state = true;
    bool l_data_mchk = false;
    bool otprom_addr_range = false;
    bool pibmem_addr_range = false;
    bool seeprom_addr_range = false;
    bool otprom_data_range = false;
    bool pibmem_data_range = false;
    bool seeprom_data_range = false;
    uint32_t HC, MCS, otprom_addr, mem_error, sib_rsp_info;

    // FAPI_ASSERT condition constant
    const bool FAIL = false;
    // Address Range constants
    const uint32_t OTPROM_MIN_RANGE  = 0x000C0000;
    const uint32_t OTPROM_MAX_RANGE  = 0x000C0378;
    const uint32_t PIBMEM_MIN_RANGE  = 0xFFFE8000;
    const uint32_t PIBMEM_MAX_RANGE  = 0xFFFFFFFF;
    const uint32_t SEEPROM_MIN_RANGE = 0x80000000;
    const uint32_t SEEPROM_MAX_RANGE = 0x80038E18;

    // OTPROM Address constants as per the image on 28/Sep/2016
    // These values might change on every recomilation of OTPROM binary
    // Refs : /afs/apd/func/project/tools/cronus/p9/exe/dev/prcd_d/images/sbe_otprom.dis
    const uint32_t MAGIC_NUMBER_MISMATCH_LOCATION = 0xC0188;
    const uint32_t OTPROM_IMAGE_END_LOCATION      = 0xC016C;

    FAPI_INF("p9_extract_sbe_rc : Entering ...");

    if(i_set_sdb)
    {
        // Applying SDB setting
        FAPI_DBG("p9_extract_sbe_rc: Setting chip in SDB mode");
        FAPI_TRY(getCfamRegister(i_target_chip, PERV_SB_CS_FSI, l_data32));
        l_data32.setBit<PERV_SB_CS_SECURE_DEBUG_MODE>();
        FAPI_TRY(putCfamRegister(i_target_chip, PERV_SB_CS_FSI, l_data32));
    }

    // XSR and IAR
    FAPI_DBG("p9_extract_sbe_rc : Reading PPE_XIDBGPRO");
    FAPI_TRY(getScom(i_target_chip, PU_PPE_XIDBGPRO, l_data64_dbgpro));
    l_data64_dbgpro.extractToRight(l_data32_iar, PU_PPE_XIDBGPRO_IAR,
                                   (PU_PPE_XIDBGPRO_IAR_LEN + 2)); //To get 32 bits of address
    FAPI_DBG("p9_extract_sbe_rc : PPE_XIDBGPRO : %#018lX", l_data64_dbgpro);
    FAPI_DBG("p9_extract_sbe_rc : SBE IAR : %#08lX", l_data32_iar);

    if (l_data64_dbgpro.getBit<PU_PPE_XIDBGPRO_XSR_HS>())
    {
        FAPI_INF("p9_extract_sbe_rc : PPE is in HALT state");
        l_ppe_halt_state  = true;
    }
    else
    {
        FAPI_INF("p9_extract_sbe_rc : PPE is in RUNNING state, likely infinite loop, recommending restart");
        l_ppe_halt_state  = false;
        o_return_action = P9_EXTRACT_SBE_RC::RESTART_SBE;
        FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_RUNNING()
                    .set_TARGET_CHIP(i_target_chip), "SBE is in running state");
    }

    if(l_ppe_halt_state)
    {
        // ------- LEVEL 1 ------ //

        //Extract HC
        l_data32.flush<0>();
        l_data64_dbgpro.extractToRight(l_data32, PU_PPE_XIDBGPRO_XSR_HC, PU_PPE_XIDBGPRO_XSR_HC_LEN);
        HC = l_data32;

        switch(HC)
        {
            case 0x0 :
                o_return_action = P9_EXTRACT_SBE_RC::RESTART_SBE;
                FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_NEVER_STARTED()
                            .set_TARGET_CHIP(i_target_chip),
                            "ERROR:Halt Condition is all Zero, SBE engine was probably never started");
                break;

            case 0x1 :
                FAPI_ERR("p9_extract_sbe_rc : XCR[CMD] written 111 to force-halt the processor.");
                break;

            case 0x2 :
                FAPI_ERR("p9_extract_sbe_rc : A second watchdog timer (WDT) event occurred while TCR[WRC]=11");
                break;

            case 0x3 :
                FAPI_ERR("p9_extract_sbe_rc : Unmaskable interrupt halt");
                break;

            case 0x4 :
                FAPI_ERR("p9_extract_sbe_rc : Debug halt");
                break;

            case 0x5 :
                FAPI_ERR("p9_extract_sbe_rc : DBCR halt");
                break;

            case 0x6 :
                FAPI_ERR("p9_extract_sbe_rc : The external halt_req input was active.");
                break;

            case 0x7 :
                FAPI_ERR("p9_extract_sbe_rc : Hardware failure");
                break;

            default :
                FAPI_ERR("p9_extract_sbe_rc : INVALID HALT CONDITION HC=0x%x", HC);
                break;
        }

        //Extract TRAP
        if(l_data64_dbgpro.getBit<PU_PPE_XIDBGPRO_XSR_TRAP>())
        {
            FAPI_DBG("p9_extract_sbe_rc : TRAP Instruction Debug Event Occured");
        }

        //Extract IAC
        if(l_data64_dbgpro.getBit<PU_PPE_XIDBGPRO_XSR_IAC>())
        {
            FAPI_DBG("p9_extract_sbe_rc : Instruction Address Compare Debug Event Occured");
        }

        //Extract DACR
        if(l_data64_dbgpro.getBit<PU_PPE_XIDBGPRO_XSR_DACR>())
        {
            FAPI_DBG("p9_extract_sbe_rc : Data Address Compare (Read) Debug Event Occured");
        }

        //Extract DACW
        if(l_data64_dbgpro.getBit<PU_PPE_XIDBGPRO_XSR_DACW>())
        {
            FAPI_DBG("p9_extract_sbe_rc : Data Address Compare (Write) Debug Event Occured");
        }

        //Extract WS
        if(l_data64_dbgpro.getBit<PU_PPE_XIDBGPRO_NULL_MSR_WE>())
        {
            FAPI_DBG("p9_extract_sbe_rc : In WAIT STATE");
        }

        //Extract EP
        if(l_data64_dbgpro.getBit<PU_PPE_XIDBGPRO_XSR_EP>())
        {
            FAPI_DBG("p9_extract_sbe_rc : Maskable Event Pending");
        }

        //Extract MFE
        if(l_data64_dbgpro.getBit<PU_PPE_XIDBGPRO_XSR_MFE>())
        {
            FAPI_ERR("p9_extract_sbe_rc : Multiple Fault Error Occured");
        }

        //Extract MCS
        l_data32.flush<0>();
        l_data64_dbgpro.extractToRight(l_data32, PU_PPE_XIDBGPRO_XSR_MCS, PU_PPE_XIDBGPRO_XSR_MCS_LEN);
        MCS = l_data32;

        // IR and EDR
        FAPI_DBG("p9_extract_sbe_rc : Reading PPE_XIRAMEDR");
        FAPI_TRY(getScom(i_target_chip, PU_PPE_XIRAMEDR, l_data64));
        l_data64.extractToRight(l_data32_ir, PU_PPE_XIRAMEDR_XIRAMGA_IR, PU_PPE_XIRAMEDR_XIRAMGA_IR_LEN);
        l_data64.extractToRight(l_data32_edr, PU_PPE_XIRAMEDR_EDR, PU_PPE_XIRAMEDR_EDR_LEN);

        if(MCS == 0x4)
        {
            if((OTPROM_MIN_RANGE <= l_data32_iar) && (l_data32_iar <= OTPROM_MAX_RANGE))
            {
                FAPI_DBG("p9_extract_sbe_rc : Program Interrupt occured in OTPROM memory program");
            }
            else if((PIBMEM_MIN_RANGE <= l_data32_iar) && (l_data32_iar <= PIBMEM_MAX_RANGE))
            {
                FAPI_DBG("p9_extract_sbe_rc : Program Interrupt occured in PIBMEM memory program");
            }
            else if((SEEPROM_MIN_RANGE <= l_data32_iar) && (l_data32_iar <= SEEPROM_MAX_RANGE))
            {
                FAPI_DBG("p9_extract_sbe_rc : Program Interrupt occured in SEEPROM memory program");
            }
            else
            {
                FAPI_ERR("ERROR: IAR %08lX is out of range when MCS reported a Program Interrupt", l_data32_iar);
            }

            o_return_action = P9_EXTRACT_SBE_RC::RESTART_SBE;
            FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_PROGRAM_INTERRUPT()
                        .set_TARGET_CHIP(i_target_chip),
                        "ERROR:Program interrupt promoted for Address=%08lX", l_data32_edr);
        }
        else
        {
            FAPI_DBG("p9_extract_sbe_rc : Data/Alignment/Data Machine check interrupt for Data=%08lX", l_data32_edr);

            switch (MCS)
            {
                case 0x0 :
                    FAPI_DBG("p9_extract_sbe_rc : Instruction machine check");
                    break;

                case 0x1 :
                    FAPI_DBG("p9_extract_sbe_rc : Data machine check - load");
                    l_data_mchk = true;
                    break;

                case 0x2 :
                    FAPI_DBG("p9_extract_sbe_rc : Data machine check - precise store");
                    l_data_mchk = true;
                    break;

                case 0x3 :
                    FAPI_DBG("p9_extract_sbe_rc : Data machine check - imprecise store");
                    l_data_mchk = true;
                    break;

                case 0x5 :
                    FAPI_DBG("p9_extract_sbe_rc : Instruction storage interrupt, promoted");
                    break;

                case 0x6 :
                    FAPI_DBG("p9_extract_sbe_rc : Alignment interrupt, promoted");
                    break;

                case 0x7 :
                    FAPI_DBG("p9_extract_sbe_rc : Data storage interrupt, promoted");
                    break;

                default :
                    FAPI_ERR("p9_extract_sbe_rc : INVALID Machine Check Status MCS=0x%x", MCS);
                    break;
            }
        }

        // ------- LEVEL 2 ------ //

        if((OTPROM_MIN_RANGE <= l_data32_iar) && (l_data32_iar <= OTPROM_MAX_RANGE))
        {
            FAPI_DBG("p9_extract_sbe_rc : IAR contains OTPROM address");
            otprom_addr_range = true;
        }
        else if((PIBMEM_MIN_RANGE <= l_data32_iar) && (l_data32_iar <= PIBMEM_MAX_RANGE))
        {
            FAPI_DBG("p9_extract_sbe_rc : IAR contains PIBMEM address");
            pibmem_addr_range = true;
        }
        else if((SEEPROM_MIN_RANGE <= l_data32_iar) && (l_data32_iar <= SEEPROM_MAX_RANGE))
        {
            FAPI_DBG("p9_extract_sbe_rc : IAR contains SEEPROM address");
            seeprom_addr_range = true;
        }
        else
        {
            o_return_action = P9_EXTRACT_SBE_RC::RESTART_SBE;
            FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_ADDR_NOT_RECOGNIZED()
                        .set_TARGET_CHIP(i_target_chip),
                        "ERROR:Address %08lX is out of range", l_data32_iar);
        }

        // ------- LEVEL 3 ------ //

        if(otprom_addr_range)
        {
            if(i_unsecure_mode)
            {
                FAPI_DBG("p9_extract_sbe_rc : Reading OTPROM status register");
                FAPI_TRY(getScom(i_target_chip, PU_STATUS_REGISTER, l_data64));
                FAPI_DBG("p9_extract_sbe_rc : OTPROM status : %#018lX", l_data64);

                if(l_data64.getBit<PU_STATUS_REGISTER_ADDR_NVLD>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : OTPROM::Address invalid bit set");
                }

                if(l_data64.getBit<PU_STATUS_REGISTER_WRITE_NVLD>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : OTPROM::Write invalid bit set");
                }

                if(l_data64.getBit<PU_STATUS_REGISTER_READ_NVLD>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : OTPROM::Read invalid bit set");
                }

                if(l_data64.getBit<PU_STATUS_REGISTER_INVLD_CMD_ERR>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : OTPROM::Invalid command register fields programmed bit set");
                }

                if(l_data64.getBit<PU_STATUS_REGISTER_CORR_ERR>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : OTPROM::Correctable error bit set");
                }

                if(l_data64.getBit<PU_STATUS_REGISTER_UNCORR_ERROR>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : OTPROM::Uncorrectable error bit set");
                }

                if(l_data64.getBit<PU_STATUS_REGISTER_DCOMP_ERR>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : OTPROM::Decompression Engine Error bit set");
                }

                if(l_data64.getBit<PU_STATUS_REGISTER_INVLD_PRGM_ERR>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : OTPROM::Invalid Program Operation error bit set");
                }


                //--  FAPI Asserts section for OTPROM --//
                o_return_action = P9_EXTRACT_SBE_RC::NO_RECOVERY_ACTION;
                FAPI_ASSERT(l_data64.getBit<PU_STATUS_REGISTER_UNCORR_ERROR>() != 1,
                            fapi2::EXTRACT_SBE_RC_OTP_ECC_ERR_INSECURE_MODE()
                            .set_TARGET_CHIP(i_target_chip),
                            "ERROR:Uncorrectable error detected in OTPROM memory read");
            }

            // Map the OTPROM address to the known error at that location
            // the OTPROM is write-once at mfg test, so addresses should remain fixed in this code
            otprom_addr = l_data32_iar;

            if(otprom_addr == MAGIC_NUMBER_MISMATCH_LOCATION)
            {
                o_return_action = P9_EXTRACT_SBE_RC::REIPL_UPD_SEEPROM;
                FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_MAGIC_NUMBER_MISMATCH()
                            .set_TARGET_CHIP(i_target_chip),
                            "ERROR:SEEPROM magic number didn't match");
            }
            else if(otprom_addr == OTPROM_IMAGE_END_LOCATION)
            {
                o_return_action = P9_EXTRACT_SBE_RC::NO_RECOVERY_ACTION;
                FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_BRANCH_TO_SEEPROM_FAIL()
                            .set_TARGET_CHIP(i_target_chip),
                            "ERROR:Branch to SEEPROM didn't happen");
            }
            else
            {
                o_return_action = P9_EXTRACT_SBE_RC::NO_RECOVERY_ACTION;
                FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_UNEXPECTED_OTPROM_HALT()
                            .set_TARGET_CHIP(i_target_chip),
                            "ERROR:Halted in OTPROM at address %08lX, but not at an expected halt location", otprom_addr);
            }
        }

        if(pibmem_addr_range)
        {
            FAPI_DBG("p9_extract_sbe_rc : Reading PIBMEM status register");
            FAPI_TRY(getScom(i_target_chip, PU_PIBMEM_STATUS_REG, l_data64));
            FAPI_DBG("p9_extract_sbe_rc : PIBMEM status : %#018lX", l_data64);

            if(l_data64.getBit<PU_PIBMEM_STATUS_REG_ADDR_INVALID_PIB>())
            {
                FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Address which PIB is trying to access in PIBMEM is not valid one in PIBMEM");
            }

            if(l_data64.getBit<PU_PIBMEM_STATUS_REG_WRITE_INVALID_PIB>())
            {
                FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Address for which PIB is trying to write is not writable");
            }

            if(l_data64.getBit<PU_PIBMEM_STATUS_REG_READ_INVALID_PIB>())
            {
                FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Address for which PIB is trying to read is not readable");
            }

            if(l_data64.getBit<PU_PIBMEM_STATUS_REG_ECC_UNCORRECTED_ERROR_PIB>())
            {
                FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Uncorrectable error occurred while PIB memory read");
            }

            if(l_data64.getBit<PU_PIBMEM_STATUS_REG_ECC_CORRECTED_ERROR_PIB>())
            {
                FAPI_INF("p9_extract_sbe_rc : PIBMEM::Corrected error in PIB mem read");
            }

            if(l_data64.getBit<PU_PIBMEM_STATUS_REG_WRITE_RST_INTERRUPT_PIB>())
            {
                FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Reset occurred during write operation to PIBMEM from PIB side");
            }

            if(l_data64.getBit<PU_PIBMEM_STATUS_REG_READ_RST_INTERRUPT_PIB>())
            {
                FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Reset occurred during read operation to PIBMEM from PIB side");
            }

            if(l_data64.getBit<PU_PIBMEM_STATUS_REG_ADDR_INVALID_FACES>())
            {
                FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Address which is given by Fast acesss interface, to access in PIBMEM is not valid one in PIBMEM");
            }

            if(l_data64.getBit<PU_PIBMEM_STATUS_REG_WRITE_INVALID_FACES>())
            {
                FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Address which is given by Fast acesss interface, to access in PIBMEM is not valid one in PIBMEM or not writable");
            }

            if(l_data64.getBit<PU_PIBMEM_STATUS_REG_READ_INVALID_FACES>())
            {
                FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Address which is given by Fast acesss interface, to access is not readable");
            }

            if(l_data64.getBit<PU_PIBMEM_STATUS_REG_ECC_UNCORRECTED_ERROR_FACES>())
            {
                FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Uncorrectable error occurred while fast acess interface read");
            }

            if(l_data64.getBit<PU_PIBMEM_STATUS_REG_ECC_CORRECTED_ERROR_FACES>())
            {
                FAPI_INF("p9_extract_sbe_rc : PIBMEM::Corrected error in fast acess read operation");
            }

            if(l_data64.getBit<PU_PIBMEM_STATUS_REG_BAD_ARRAY_ADDRESS_FACES>())
            {
                FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Wrong address accessd in indirect mode of operation from fast acess interface");
            }

            if(l_data64.getBit<PU_PIBMEM_STATUS_REG_WRITE_RST_INTERRUPT_FACES>())
            {
                FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Reset occurred during write operation to PIBMEM from fast acess side");
            }

            if(l_data64.getBit<PU_PIBMEM_STATUS_REG_READ_RST_INTERRUPT_FACES>())
            {
                FAPI_ERR("p9_extract_sbe_rc : PIBMEM::Reset occurred during read operation to PIBMEM from fast acess side");
            }

            //--  FAPI Asserts section for PIBMEM --//
            o_return_action = P9_EXTRACT_SBE_RC::RESTART_SBE;
            FAPI_ASSERT(l_data64.getBit<PU_PIBMEM_STATUS_REG_ECC_UNCORRECTED_ERROR_PIB>() != 1,
                        fapi2::EXTRACT_SBE_RC_PIBMEM_ECC_ERR_INSECURE_MODE()
                        .set_TARGET_CHIP(i_target_chip),
                        "ERROR:Uncorrectable error occurred while PIB memory read");

            o_return_action = P9_EXTRACT_SBE_RC::RESTART_SBE;
            FAPI_ASSERT(l_data64.getBit<PU_PIBMEM_STATUS_REG_ECC_UNCORRECTED_ERROR_FACES>() != 1,
                        fapi2::EXTRACT_SBE_RC_PIBMEM_ECC_ERR_INSECURE_MODE()
                        .set_TARGET_CHIP(i_target_chip),
                        "ERROR:Uncorrectable error occurred while fast access interface read");
        }

        if(seeprom_addr_range)
        {
            if(i_unsecure_mode)
            {
                FAPI_DBG("p9_extract_sbe_rc : Reading FI2CM mode register");
                FAPI_TRY(getScom(i_target_chip, PU_MODE_REGISTER_B, l_data64));
                FAPI_DBG("p9_extract_sbe_rc : FI2CM mode : %#018lX", l_data64);

                l_data32.flush<0>();
                l_data64.extractToRight(l_data32, 0, 16);
                uint32_t i2c_speed = l_data32;

                if(i2c_speed < 0x0003)
                {
                    o_return_action = P9_EXTRACT_SBE_RC::RESTART_SBE;
                    FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_FI2CM_BIT_RATE_ERR()
                                .set_TARGET_CHIP(i_target_chip),
                                "ERROR:Speed on the I2C bit rate divisor is less than min speed value (0x0003), I2C Speed read is %04lX", i2c_speed);
                }
            }

            if(i_unsecure_mode)
            {
                FAPI_DBG("p9_extract_sbe_rc : Reading FI2CM status register");
                FAPI_TRY(getScom(i_target_chip, PU_STATUS_REGISTER_B, l_data64_fi2c_status));
                FAPI_DBG("p9_extract_sbe_rc : FI2CM status : %#018lX", l_data64_fi2c_status);

                if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_ADDR_NVLD_0>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : FI2CM::Address invalid bit set");
                }

                if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_WRITE_NVLD_0>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : FI2CM::Write invalid bit set");
                }

                if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_READ_NVLD_0>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : FI2CM::Read invalid bit set");
                }

                if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_ADDR_P_ERR_0>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : FI2CM::Address parity error bit set");
                }

                if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_PAR_ERR_0>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : FI2CM::Data parity error bit set");
                }

                if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_LB_PARITY_ERROR_0>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : FI2CM::Local bus parity error bit set");
                }

                if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_ECC_CORRECTED_ERROR_0>())
                {
                    FAPI_INF("p9_extract_sbe_rc : FI2CM::WARN:One bit flip was there in data and been corrected");
                }

                if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_ECC_UNCORRECTED_ERROR_0>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : FI2CM::There are 2 bit flips in read data which cannot be corrected");
                }

                if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_ECC_CONFIG_ERROR_0>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : FI2CM::Control register is ecc_enabled for data_length not equal to 8. OR ECC is enabled for the engine where ECC block is not instantiated");
                }

                if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_INVALID_COMMAND_0>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : FI2CM::Invalid command bit set");
                }

                if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_PARITY_ERROR_0>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : FI2CM::Parity error bit set");
                }

                if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_BACK_END_OVERRUN_ERROR_0>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : FI2CM::Back end overrun error bit set");
                }

                if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_BACK_END_ACCESS_ERROR_0>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : FI2CM::Back end access error bit set");
                }

                if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_ARBITRATION_LOST_ERROR_0>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : FI2CM::Arbitration lost error bit set");
                }

                if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_NACK_RECEIVED_ERROR_0>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : FI2CM::NACK receieved error bit set");
                }

                if(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_STOP_ERROR_0>())
                {
                    FAPI_ERR("p9_extract_sbe_rc : FI2CM::Stop error bit set");
                }

                //--  FAPI Asserts section for SEEPROM --//
                o_return_action = P9_EXTRACT_SBE_RC::REIPL_BKP_SEEPROM;
                FAPI_ASSERT((l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_ECC_CONFIG_ERROR_0>() != 1           ||
                             l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_INVALID_COMMAND_0>() != 1        ||
                             l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_PARITY_ERROR_0>() != 1           ||
                             l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_BACK_END_OVERRUN_ERROR_0>() != 1 ||
                             l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_BACK_END_ACCESS_ERROR_0>() != 1  ||
                             l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_ARBITRATION_LOST_ERROR_0>() != 1 ||
                             l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_NACK_RECEIVED_ERROR_0>() != 1    ||
                             l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_BUS_STOP_ERROR_0>() != 1),
                            fapi2::EXTRACT_SBE_RC_FI2C_ERROR()
                            .set_TARGET_CHIP(i_target_chip),
                            "FI2C I2C Error detected");

                o_return_action = P9_EXTRACT_SBE_RC::REIPL_UPD_SEEPROM;
                FAPI_ASSERT(l_data64_fi2c_status.getBit<PU_STATUS_REGISTER_B_ECC_UNCORRECTED_ERROR_0>() != 1,
                            fapi2::EXTRACT_SBE_RC_FI2C_ECC_ERR_INSECURE_MODE()
                            .set_TARGET_CHIP(i_target_chip),
                            "ERROR:There are 2 bit flips in read data which cannot be corrected");
            }
            else
            {
                // TODO - Read FI2CM status register by performing ramming of local register
            }
        }

        // ------- LEVEL 4 ------ //
        if(l_data_mchk)
        {
            if((OTPROM_MIN_RANGE <= l_data32_edr) && (l_data32_edr <= OTPROM_MAX_RANGE))
            {
                FAPI_DBG("p9_extract_sbe_rc : EDR contains OTPROM address");
                otprom_data_range = true;
            }
            else if((PIBMEM_MIN_RANGE <= l_data32_edr) && (l_data32_edr <= PIBMEM_MAX_RANGE))
            {
                FAPI_DBG("p9_extract_sbe_rc : EDR contains PIBMEM address");
                pibmem_data_range = true;
            }
            else if((SEEPROM_MIN_RANGE <= l_data32_edr) && (l_data32_edr <= SEEPROM_MAX_RANGE))
            {
                FAPI_DBG("p9_extract_sbe_rc : EDR contains SEEPROM address");
                seeprom_data_range = true;
            }
            else
            {
                FAPI_DBG("p9_extract_sbe_rc : EDR contains out of scope address = %08lX", l_data32_edr);
            }

            if(otprom_data_range || seeprom_data_range) // SIB Info is valid only for Otprom & Seeprom data
            {
                //-- MIB External Interface SIB Info
                FAPI_DBG("p9_extract_sbe_rc : Reading MIB SIB Info register");
                FAPI_TRY(getScom(i_target_chip, PU_MIB_XISIB, l_data64_mib_sib_info));
                FAPI_DBG("p9_extract_sbe_rc : MIB SIB Info : %#018lX", l_data64_mib_sib_info);

                l_data32.flush<0>();
                l_data64_mib_sib_info.extractToRight(l_data32, PU_MIB_XISIB_PIB_RSP_INFO, PU_MIB_XISIB_PIB_RSP_INFO_LEN);
                sib_rsp_info = l_data32;
            }

            if(otprom_data_range)
            {
                o_return_action = P9_EXTRACT_SBE_RC::NO_RECOVERY_ACTION;
                FAPI_ASSERT((!(sib_rsp_info == 0x6)), fapi2::EXTRACT_SBE_RC_OTP_ECC_ERR(),
                            "Parity/ECC error detected in OTPROM memory, Check if OTPROM programmed correctly by dumping content");

                o_return_action = P9_EXTRACT_SBE_RC::RESTART_CBS;
                FAPI_ASSERT((!(sib_rsp_info == 0x7)), fapi2::EXTRACT_SBE_RC_OTP_TIMEOUT()
                            .set_TARGET_CHIP(i_target_chip),
                            "PIB Timeout error detected during access to OTPROM");

                o_return_action = P9_EXTRACT_SBE_RC::RESTART_CBS;
                FAPI_ASSERT((!(sib_rsp_info != 0x0)), fapi2::EXTRACT_SBE_RC_OTP_PIB_ERR()
                            .set_TARGET_CHIP(i_target_chip),
                            "Scom error detected");
            }

            if(pibmem_data_range)
            {
                //-- MIB External Interface MEM Info
                FAPI_DBG("p9_extract_sbe_rc : Reading MIB MEM Info register");
                FAPI_TRY(getScom(i_target_chip, PU_MIB_XIMEM, l_data64_mib_mem_info));
                FAPI_DBG("p9_extract_sbe_rc : MIB MEM Info : %#018lX", l_data64_mib_mem_info);

                l_data32.flush<0>();
                l_data64_mib_mem_info.extractToRight(l_data32, PU_MIB_XIMEM_MEM_ERROR, PU_MIB_XIMEM_MEM_ERROR_LEN);
                mem_error = l_data32;

                o_return_action = P9_EXTRACT_SBE_RC::RESTART_SBE;
                FAPI_ASSERT((!(mem_error == 0x6)), fapi2::EXTRACT_SBE_RC_PIBMEM_ECC_ERR(),
                            "ECC error detected during pibmem access, Run PIBMEM REPAIR test..");

                o_return_action = P9_EXTRACT_SBE_RC::RESTART_CBS;
                FAPI_ASSERT((!(mem_error != 0x0)), fapi2::EXTRACT_SBE_RC_PIBMEM_PIB_ERR()
                            .set_TARGET_CHIP(i_target_chip),
                            "Error detected during pibmem access");
            }

            if(seeprom_data_range)
            {
                o_return_action = P9_EXTRACT_SBE_RC::REIPL_BKP_SEEPROM;
                FAPI_ASSERT((!(sib_rsp_info == 0x7)), fapi2::EXTRACT_SBE_RC_FI2C_TIMEOUT()
                            .set_TARGET_CHIP(i_target_chip),
                            "FI2C Timeout error detected");

                o_return_action = P9_EXTRACT_SBE_RC::REIPL_UPD_SEEPROM;
                FAPI_ASSERT((!(sib_rsp_info == 0x6)), fapi2::EXTRACT_SBE_RC_FI2C_ECC_ERR()
                            .set_TARGET_CHIP(i_target_chip),
                            "FI2C SEEPROM uncorrectable ECC error detected");

                o_return_action = P9_EXTRACT_SBE_RC::RESTART_CBS;
                FAPI_ASSERT((!(sib_rsp_info == 0x4)), fapi2::EXTRACT_SBE_RC_FI2C_SPRM_CFG_ERR()
                            .set_TARGET_CHIP(i_target_chip),
                            "FI2C SEEPROM config error detected");

                o_return_action = P9_EXTRACT_SBE_RC::RESTART_CBS;
                FAPI_ASSERT((!(sib_rsp_info != 0x0)), fapi2::EXTRACT_SBE_RC_FI2C_PIB_ERR()
                            .set_TARGET_CHIP(i_target_chip),
                            "FI2C PIB error detected");
            }
        }

        //Unknown
        FAPI_ERR("Halted due to unknown error at IAR location %08lX", l_data32_iar);
        o_return_action = P9_EXTRACT_SBE_RC::REIPL_BKP_SEEPROM;
        FAPI_ASSERT(FAIL, fapi2::EXTRACT_SBE_RC_UNKNOWN_ERROR()
                    .set_TARGET_CHIP(i_target_chip), "SBE halted due to unknown error");
    }

    FAPI_INF("p9_extract_sbe_rc : Exiting ...");

fapi_try_exit:
    return fapi2::current_err;

}
Пример #12
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);
        }
    }
}