Example #1
0
// ----------------------------------------------------------------------
// Function definitions
// ----------------------------------------------------------------------
fapi2::ReturnCode p9_pm_firinit(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
    const p9pm::PM_FLOW_MODE i_mode)
{
    FAPI_IMP("p9_pm_firinit start");

    fapi2::ReturnCode l_rc;
    uint8_t l_pm_firinit_flag;
    fapi2::buffer<uint64_t> l_data64;

    // CHECKING FOR FIRS BEFORE RESET and INIT
    FAPI_DBG("Checking PBA FIRs");
    FAPI_TRY(fapi2::getScom(i_target, PU_PBAFIR , l_data64),
             "ERROR: Failed to fetch PBA FIR");

    if(l_data64)
    {
        FAPI_INF("WARNING: PBA has active error(s)");
    }

    // Handle PBA FIRs, Masks and actions
    FAPI_DBG("Calling PBA firinit ...");
    FAPI_EXEC_HWP(l_rc, p9_pm_pba_firinit, i_target, i_mode);
    FAPI_TRY(l_rc);

    // Handle Core and Quad errors
    FAPI_DBG("Calling PPM firinit ...");
    FAPI_EXEC_HWP(l_rc, p9_pm_ppm_firinit, i_target, i_mode);
    FAPI_TRY(l_rc);

    // Handle CME FIRs, Masks and actions
    FAPI_DBG("Calling CME firinit ...");
    FAPI_EXEC_HWP(l_rc, p9_pm_cme_firinit, i_target, i_mode);
    FAPI_TRY(l_rc);

    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PM_FIRINIT_DONE_ONCE_FLAG, i_target,
                           l_pm_firinit_flag),
             "ERROR: Failed to fetch the firinit call status flag");

    // Set the ATTR_PM_FIRINIT_DONE_ONCE_FLAG attribute
    if (i_mode == p9pm::PM_INIT)
    {
        if (l_pm_firinit_flag != 1)
        {
            l_pm_firinit_flag = 1;
            FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_PM_FIRINIT_DONE_ONCE_FLAG,
                                   i_target, l_pm_firinit_flag),
                     "ERROR: Failed to set firinit call status after init");
        }
    }

fapi_try_exit:
    FAPI_INF("p9_pm_firinit end");
    return fapi2::current_err;
} // END p9_pm_firinit
/**
 * @brief A HWP that runs Restore eRepair.  This procedure should update the
 * bad lane vector and power down the bad lanes.  The rx bad lanes will update
 * the bad lane vector of the passed target.  The lanes specified in the
 * i_rx_bad_lanes and in the i_tx_bad_lanes vectors will be powered down on the
 * target that is passed in.  Note: This procedure does not power down any
 * bad lanes on the connected target.
 * @param[in] i_target        FAPI2 Target
 * @param[in] i_rx_bad_lanes  Vector of Rx Bad Lanes
 * @param[in] i_tx_bad_lanes  Vector of Tx Bad Lanes
 * @retval    ReturnCode
 */
fapi2::ReturnCode
p9_io_dmi_restore_erepair(
    const fapi2::Target< fapi2::TARGET_TYPE_DMI >& i_target,
    const std::vector< uint8_t >&                  i_rx_bad_lanes,
    const std::vector< uint8_t >&                  i_tx_bad_lanes)
{
    FAPI_IMP("Entering...");

    FAPI_DBG("Rx Bad Lanes Size: %d", i_rx_bad_lanes.size());
    FAPI_DBG("Tx Bad Lanes Size: %d", i_tx_bad_lanes.size());

    if(!i_rx_bad_lanes.empty())
    {
        FAPI_TRY(set_rx_bad_lane_vectors(i_target, i_rx_bad_lanes),
                 "Setting Rx Bad Lane Vectors Failed");
    }

    // This function will power down the rx & tx lanes specified in the vectors
    //   on the target that is passed in.
    FAPI_EXEC_HWP(fapi2::current_err,
                  p9_io_dmi_pdwn_lanes,
                  i_target,
                  i_rx_bad_lanes,
                  i_tx_bad_lanes);

fapi_try_exit:
    FAPI_IMP("Exiting...");
    return fapi2::current_err;
}
Example #3
0
    ///
    /// @brief Scominit for Explorer
    /// @param[in] i_target the OCMB target to operate on
    /// @return FAPI2_RC_SUCCESS iff ok
    ///
    fapi2::ReturnCode exp_scominit( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target)
    {
        mss::display_git_commit_info("exp_scominit");

        if (mss::count_dimm(i_target) == 0)
        {
            FAPI_INF("... skipping mss_scominit %s - no DIMM ...", mss::c_str(i_target));
            return fapi2::FAPI2_RC_SUCCESS;
        }

        // We need to make sure we hit all ports
        const auto& l_port_targets = mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target);

        fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
        const auto& l_mc = i_target.getParent<fapi2::TARGET_TYPE_OMI>()
                           .getParent<fapi2::TARGET_TYPE_MCC>()
                           .getParent<fapi2::TARGET_TYPE_MI>()
                           .getParent<fapi2::TARGET_TYPE_MC>();

        for(const auto& l_port : l_port_targets)
        {
            fapi2::ReturnCode l_rc;
            FAPI_INF("phy scominit for %s", mss::c_str(l_port));
            FAPI_EXEC_HWP(l_rc, explorer_scom, i_target, l_port, FAPI_SYSTEM, l_mc);

            FAPI_TRY(l_rc, "Error from explorer.scom.initfile %s", mss::c_str(l_port));
        }

        return fapi2::FAPI2_RC_SUCCESS;

    fapi_try_exit:
        FAPI_INF("End MSS SCOM init");
        return fapi2::current_err;
    }
    ///
    /// @brief MBvpd accessor for the ATTR_VPD_POWER_CONTROL_CAPABLE attribute
    /// @param[in] i_mbTarget - Reference to mb Target
    /// @param[out] o_val     - retrieved MR value
    /// @return fapi::ReturnCode FAPI_RC_SUCCESS if success, else error code
    ///
    fapi2::ReturnCode getControlCapableData(
        const fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP>& i_mbTarget,
        uint8_t& o_val)
    {
        fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
        FAPI_DBG("getControlCapableData: start on %s", mss::c_str(i_mbTarget));
        // ATTR_VPD_POWER_CONTROL_CAPABLE is at the membuf level, but the
        //  getMBvpdAttr() function takes a mba, so need to do a
        //  conversion
        const auto l_mbas = i_mbTarget.getChildren<fapi2::TARGET_TYPE_MBA>();

        // If we don't have any functional MBAs then we will fail in
        //  the other function so just return a default value here
        if( l_mbas.empty() )
        {
            o_val = fapi2::ENUM_ATTR_CEN_VPD_POWER_CONTROL_CAPABLE_NONE;
            return l_rc;
        }

        // Call a VPD Accessor HWP to get the data
        FAPI_EXEC_HWP(l_rc, getMBvpdAttr,
                      l_mbas[0], fapi2::ATTR_CEN_VPD_POWER_CONTROL_CAPABLE,
                      &o_val, sizeof(fapi2::ATTR_CEN_VPD_POWER_CONTROL_CAPABLE_Type));
        FAPI_DBG("getControlCapableData: end on %s", mss::c_str(i_mbTarget));

        return l_rc;
    }
Example #5
0
//------------------------------------------------------------------------------
// function: apply PBCQ/AIB customization via SCOM initfile
// parameters: i_target => processor chip target
// returns: FAPI_RC_SUCCESS if initfile evaluation is successful,
//          else error
//------------------------------------------------------------------------------
fapi::ReturnCode proc_pcie_config_pbcq(
    const fapi::Target & i_target)
{
    fapi::ReturnCode rc;
    std::vector<fapi::Target> targets;

    // mark function entry
    FAPI_INF("proc_pcie_config_pbcq: Start");

    do
    {
        // execute Phase2 SCOM initfile
        targets.push_back(i_target);
        FAPI_INF("proc_pcie_config_pbcq: Executing %s on %s",
                 PROC_PCIE_CONFIG_PHASE2_IF, i_target.toEcmdString());
        FAPI_EXEC_HWP(
            rc,
            fapiHwpExecInitFile,
            targets,
            PROC_PCIE_CONFIG_PHASE2_IF);
        if (!rc.ok())
        {
            FAPI_ERR("proc_pcie_config_pbcq: Error from fapiHwpExecInitfile executing %s on %s",
                     PROC_PCIE_CONFIG_PHASE2_IF,
                     i_target.toEcmdString());
            break;
        }
    } while(0);

    // mark function exit
    FAPI_INF("proc_pcie_config_pbcq: End");
    return rc;
}
// HWP entry point, comments in header
fapi2::ReturnCode p9_io_obus_scominit( const fapi2::Target<fapi2::TARGET_TYPE_OBUS>& i_target )
{
    // mark HWP entry
    FAPI_INF("p9_io_obus_scominit: Entering...");
    const uint8_t GROUP_00 = 0;
    const uint8_t LANE_00  = 0;
    const uint8_t SET_RESET = 1;
    const uint8_t CLEAR_RESET = 0;
    fapi2::ReturnCode rc = fapi2::FAPI2_RC_SUCCESS;

    // get system target
    const fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> l_system_target;

    // get a proc target
    fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> l_proc_target = i_target.getParent<fapi2::TARGET_TYPE_PROC_CHIP>();

    // assert IO reset to power-up bus endpoint logic
    FAPI_TRY( io::rmw( OPT_IORESET_HARD_BUS0, i_target, GROUP_00, LANE_00, SET_RESET ) );

    // Bus Reset is relatively fast, only needing < a hundred cycles to allow the signal to propogate.
    FAPI_TRY( fapi2::delay( 10, 1000 ) );

    FAPI_TRY( io::rmw( OPT_IORESET_HARD_BUS0, i_target, GROUP_00, LANE_00, CLEAR_RESET ) );

    FAPI_INF("Invoke FAPI procedure core: input_target");
    FAPI_EXEC_HWP(rc, p9_obus_scom, i_target, l_system_target, l_proc_target);

    // configure FIR
    {
        FAPI_TRY(fapi2::putScom(i_target,
                                OBUS_FIR_ACTION0_REG,
                                OBUS_PHY_FIR_ACTION0),
                 "Error from putScom (OBUS_FIR_ACTION0_REG)");
        FAPI_TRY(fapi2::putScom(i_target,
                                OBUS_FIR_ACTION1_REG,
                                OBUS_PHY_FIR_ACTION1),
                 "Error from putScom (OBUS_FIR_ACTION1_REG)");
        FAPI_TRY(fapi2::putScom(i_target,
                                OBUS_FIR_MASK_REG,
                                OBUS_PHY_FIR_MASK),
                 "Error from putScom (OBUS_FIR_MASK_REG)");
    }

    // mark HWP exit
    FAPI_INF("p9_io_obus_scominit: ...Exiting");

fapi_try_exit:
    return fapi2::current_err;
}
fapi2::ReturnCode p9_pm_ocb_indir_setup_circular(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
    const p9ocb::PM_OCB_CHAN_NUM i_ocb_chan,
    const p9ocb::PM_OCB_CHAN_TYPE i_ocb_type,
    const uint32_t i_ocb_bar,
    const uint8_t i_ocb_q_len,
    const p9ocb::PM_OCB_CHAN_OUFLOW i_ocb_flow,
    const p9ocb::PM_OCB_ITPTYPE i_ocb_itp)
{
    FAPI_IMP("p9_pm_ocb_indir_setup_circular Enter");
    FAPI_DBG("Channel: %d; Mode: %d; OCB BAR: 0x%08X; Queue length: %d;",
             i_ocb_chan, i_ocb_type, i_ocb_bar, i_ocb_q_len);
    FAPI_DBG("Flow Notification Mode: %d; Interrupt Behaviour: %d", i_ocb_flow,
             i_ocb_itp);

    fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
    FAPI_EXEC_HWP(l_rc,
                  p9_pm_ocb_init,
                  i_target,
                  p9pm::PM_SETUP_ALL,
                  i_ocb_chan,
                  i_ocb_type,
                  i_ocb_bar,
                  i_ocb_q_len,
                  i_ocb_flow,
                  i_ocb_itp);

    if (l_rc == fapi2::FAPI2_RC_SUCCESS)
    {
        FAPI_INF("Circular setup of channel %d successful.", i_ocb_chan);
    }
    else
    {
        FAPI_ERR("ERROR: Failed to setup channel %d to circular mode.",
                 i_ocb_chan);
    }

    FAPI_IMP("p9_pm_ocb_indir_setup_circular Exit");
    return l_rc;
}
uint32_t rcTestCalloutNoneDeconfig()
{
    uint32_t l_result = 0;
    errlHndl_t l_errl = NULL;
    bool l_hw_callout_found = false;

    FAPI_INF("rcTestCalloutNoneDeconfig running");

    TARGETING::TargetHandleList l_dimmList;
    TARGETING::getAllLogicalCards(l_dimmList, TARGETING::TYPE_DIMM, false);
    TARGETING::Target * l_Dimm = NULL;

    //Take the first dimm
    if (l_dimmList.size() > 0)
    {
        l_Dimm = l_dimmList[0];
    }
    else
    {
        TS_FAIL("No dimms found");
    }

    //Convert to fapi2 target for the HWP below
    fapi2::Target<fapi2::TARGET_TYPE_DIMM> fapi2_dimmTarget(l_Dimm);

    FAPI_INVOKE_HWP(l_errl, p9_deconfigCalloutNone, fapi2_dimmTarget);

    if(l_errl != NULL)
    {
        FAPI_INF("rcTestCalloutNoneDeconfig: p9_deconfigCalloutNone "
                 "returned errl (expected)");

        //Get the User Data fields of the errl. They are returned as
        //vector<void*>, so iterate over them.
        for( auto l_callout_raw : l_errl->
                getUDSections( ERRL_COMP_ID, ERRORLOG::ERRL_UDT_CALLOUT ) )
        {
            HWAS::callout_ud_t* l_callout_entry =
                           reinterpret_cast<HWAS::callout_ud_t*>(l_callout_raw);

            if(l_callout_entry->type == HWAS::HW_CALLOUT)
            {
                l_hw_callout_found = true;
                FAPI_INF("rcTestCalloutNoneDeconfig: hw callout found");
                if(l_callout_entry->deconfigState == HWAS::DELAYED_DECONFIG)
                {
                   FAPI_INF("rcTestCalloutNoneDeconfig: Target is deconfigured");
                }
                else
                {
                    TS_FAIL("rcTestCalloutNoneDeconfig: Target is NOT deconfigured");
                    l_result = 1;
                    break;
                }
            }
        }
        if(!l_hw_callout_found)
        {
            TS_FAIL("rcTestCalloutNoneDeconfig: hw callout NOT found");
            l_result = 2;
        }
    }
    else
    {
        TS_FAIL("rcTestCalloutNoneDeconfig: No error was returned from"
                                                 " p9_deconfigCalloutNone !!");
        l_result = 3;
    }

    //l_errl->setSev(ERRORLOG::ERRL_SEV_RECOVERED);
    //errlCommit(l_errl,CXXTEST_COMP_ID);
    delete l_errl;
    l_errl = NULL;

    // Now try it the way HWP people do it
    ReturnCode l_rc;
    FAPI_EXEC_HWP(l_rc, p9_deconfigCalloutNone, fapi2_dimmTarget);
    if (l_rc != fapi2::FAPI2_RC_SUCCESS)
    {
        // log the error but don't fail the unit test
        FAPI_INF("rcTestCalloutNoneDeconfig: logError called");
        fapi2::logError(l_rc, fapi2::FAPI2_ERRL_SEV_RECOVERED, true);
    }
    else
    {
        TS_FAIL("rcTestCalloutNoneDeconfig: No error was returned from "
                                     "FAPI_EXEC_HWP p9_deconfigCalloutNone !!");
        l_result = 4;
    }

    FAPI_INF("rcTestCalloutNoneDeconfig finished");
    return l_result;
}
// HWP entry point, comments in header
fapi::ReturnCode proc_chiplet_scominit(const fapi::Target & i_target)
{
    fapi::ReturnCode rc;
    uint32_t rc_ecmd = 0;

    fapi::TargetType target_type;
    std::vector<fapi::Target> initfile_targets;
    std::vector<fapi::Target> ex_targets;
    std::vector<fapi::Target> mcs_targets;
    uint8_t nx_enabled;
    uint8_t mcs_pos;
    uint8_t ex_pos;
    uint8_t num_ex_targets;
    uint8_t master_mcs_pos = 0xFF;
    fapi::Target master_mcs;
    uint8_t enable_xbus_resonant_clocking = 0x0;
    uint8_t i2c_slave_address = 0x0;
    uint8_t dual_capp_present = 0x0;

    ecmdDataBufferBase data(64);
    ecmdDataBufferBase cfam_data(32);
    ecmdDataBufferBase mask(64);

    bool               is_master = false;

    // mark HWP entry
    FAPI_INF("proc_chiplet_scominit: Start");

    do
    {
        rc = proc_check_master_sbe_seeprom(i_target, is_master);
        if (!rc.ok())
        {
            FAPI_ERR("proc_cen_ref_clk_enable: Error from proc_check_master_sbe_seeprom");
            break;
        }

        // obtain target type to determine which initfile(s) to execute
        target_type = i_target.getType();

        // chip level target
        if (target_type == fapi::TARGET_TYPE_PROC_CHIP)
        {
            // execute FBC SCOM initfile
            initfile_targets.push_back(i_target);
            FAPI_INF("proc_chiplet_scominit: Executing %s on %s",
                     PROC_CHIPLET_SCOMINIT_FBC_IF, i_target.toEcmdString());
            FAPI_EXEC_HWP(
                rc,
                fapiHwpExecInitFile,
                initfile_targets,
                PROC_CHIPLET_SCOMINIT_FBC_IF);
            if (!rc.ok())
            {
                FAPI_ERR("proc_chiplet_scominit: Error from fapiHwpExecInitfile executing %s on %s",
                         PROC_CHIPLET_SCOMINIT_FBC_IF,
                         i_target.toEcmdString());
                break;
            }

            // execute PSI SCOM initfile
            FAPI_INF("proc_chiplet_scominit: Executing %s on %s",
                     PROC_CHIPLET_SCOMINIT_PSI_IF, i_target.toEcmdString());
            FAPI_EXEC_HWP(
                rc,
                fapiHwpExecInitFile,
                initfile_targets,
                PROC_CHIPLET_SCOMINIT_PSI_IF);
            if (!rc.ok())
            {
                FAPI_ERR("proc_chiplet_scominit: Error from fapiHwpExecInitfile executing %s on %s",
                         PROC_CHIPLET_SCOMINIT_PSI_IF,
                         i_target.toEcmdString());
                break;
            }

            // execute TP bridge SCOM initfile
            FAPI_INF("proc_chiplet_scominit: Executing %s on %s",
                     PROC_CHIPLET_SCOMINIT_TPBRIDGE_IF, i_target.toEcmdString());
            FAPI_EXEC_HWP(
                rc,
                fapiHwpExecInitFile,
                initfile_targets,
                PROC_CHIPLET_SCOMINIT_TPBRIDGE_IF);
            if (!rc.ok())
            {
                FAPI_ERR("proc_chiplet_scominit: Error from fapiHwpExecInitfile executing %s on %s",
                         PROC_CHIPLET_SCOMINIT_TPBRIDGE_IF,
                         i_target.toEcmdString());
                break;
            }

            // query NX partial good attribute
            rc = FAPI_ATTR_GET(ATTR_PROC_NX_ENABLE,
                               &i_target,
                               nx_enabled);
            if (!rc.ok())
            {
                FAPI_ERR("proc_chiplet_scominit: Error querying ATTR_PROC_NX_ENABLE");
                break;
            }

            // apply NX/AS SCOM initfiles only if partial good attribute is set
            if (nx_enabled == fapi::ENUM_ATTR_PROC_NX_ENABLE_ENABLE)
            {
                // execute NX SCOM initfile
                FAPI_INF("proc_chiplet_scominit: Executing %s on %s",
                         PROC_CHIPLET_SCOMINIT_NX_IF, i_target.toEcmdString());
                FAPI_EXEC_HWP(
                    rc,
                    fapiHwpExecInitFile,
                    initfile_targets,
                    PROC_CHIPLET_SCOMINIT_NX_IF);
                if (!rc.ok())
                {
                    FAPI_ERR("proc_chiplet_scominit: Error from fapiHwpExecInitfile executing %s on %s",
                             PROC_CHIPLET_SCOMINIT_NX_IF,
                             i_target.toEcmdString());
                    break;
                }

                // execute CXA SCOM initfile
                FAPI_INF("proc_chiplet_scominit: Executing %s on %s",
                         PROC_CHIPLET_SCOMINIT_CXA_IF, i_target.toEcmdString());
                FAPI_EXEC_HWP(
                    rc,
                    fapiHwpExecInitFile,
                    initfile_targets,
                    PROC_CHIPLET_SCOMINIT_CXA_IF);
                if (!rc.ok())
                {
                    FAPI_ERR("proc_chiplet_scominit: Error from fapiHwpExecInitfile executing %s on %s",
                             PROC_CHIPLET_SCOMINIT_CXA_IF,
                             i_target.toEcmdString());
                    break;
                }

                // configure CXA APC master LCO settings
                rc = fapiGetChildChiplets(i_target,
                                          fapi::TARGET_TYPE_EX_CHIPLET,
                                          ex_targets,
                                          fapi::TARGET_STATE_FUNCTIONAL);
                if (!rc.ok())
                {
                    FAPI_ERR("proc_chiplet_scominit: Error from fapiGetChildChiplets (EX) on %s",
                             i_target.toEcmdString());
                    break;
                }

                // form valid LCO target list
                for (std::vector<fapi::Target>::iterator i = ex_targets.begin();
                     i != ex_targets.end();
                     i++)
                {
                    // determine EX chiplet number
                    rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &(*i), ex_pos);

                    if (!rc.ok())
                    {
                        FAPI_ERR("proc_chiplet_scominit: Error from FAPI_ATTR_GET (ATTR_CHIP_UNIT_POS) on %s",
                                 i->toEcmdString());
                        break;
                    }

                    rc_ecmd |= data.setBit(ex_pos-((ex_pos < 8)?(1):(3)));
                }
                if (!rc.ok())
                {
                    break;
                }

                num_ex_targets = ex_targets.size();
                rc_ecmd |= data.insertFromRight(
                    num_ex_targets,
                    CAPP_APC_MASTER_LCO_TARGET_MIN_START_BIT,
                    (CAPP_APC_MASTER_LCO_TARGET_MIN_END_BIT-
                     CAPP_APC_MASTER_LCO_TARGET_MIN_START_BIT+1));

                if (rc_ecmd)
                {
                    FAPI_ERR("proc_chiplet_scominit: Error 0x%x setting APC Master LCO Target register data buffer",
                             rc_ecmd);
                    rc.setEcmdError(rc_ecmd);
                    break;
                }

                rc = fapiPutScom(i_target,
                                 CAPP_APC_MASTER_LCO_TARGET_0x02013021,
                                 data);
                if (!rc.ok())
                {
                    FAPI_ERR("proc_chiplet_scominit: fapiPutScom error (CAPP_APC_MASTER_LCO_TARGET_0x02013021) on %s",
                             i_target.toEcmdString());
                    break;
                }

                // get dual CAPP presence attribute
                FAPI_DBG("proc_chiplet_scominit: Querying dual CAPP feature attribute");
                rc = FAPI_ATTR_GET(ATTR_CHIP_EC_FEATURE_DUAL_CAPP_PRESENT,
                                   &i_target,
                                   dual_capp_present);
                if (!rc.ok())
                {
                    FAPI_ERR("proc_chiplet_scominit: Error querying ATTR_CHIP_EC_FEATURE_DUAL_CAPP_PRESENT");
                    break;
                }
                
                if (dual_capp_present != 0)
                {
                    rc = fapiPutScom(i_target,
                                     CAPP1_APC_MASTER_LCO_TARGET_0x020131A1,
                                     data);
                    if (!rc.ok())
                    {
                        FAPI_ERR("proc_chiplet_scominit: fapiPutScom error (CAPP1_APC_MASTER_LCO_TARGET_0x020131A1) on %s",
                                 i_target.toEcmdString());
                        break;
                    }
                }

                // execute AS SCOM initfile
                FAPI_INF("proc_chiplet_scominit: Executing %s on %s",
                         PROC_CHIPLET_SCOMINIT_AS_IF, i_target.toEcmdString());
                FAPI_EXEC_HWP(
                    rc,
                    fapiHwpExecInitFile,
                    initfile_targets,
                    PROC_CHIPLET_SCOMINIT_AS_IF);
                if (!rc.ok())
                {
                    FAPI_ERR("proc_chiplet_scominit: Error from fapiHwpExecInitfile executing %s on %s",
                             PROC_CHIPLET_SCOMINIT_AS_IF,
                             i_target.toEcmdString());
                    break;
                }
            }
            else
            {
                FAPI_DBG("proc_chiplet_scominit: Skipping execution of %s/%s/%s (partial good)",
                         PROC_CHIPLET_SCOMINIT_NX_IF, PROC_CHIPLET_SCOMINIT_CXA_IF, PROC_CHIPLET_SCOMINIT_AS_IF);
            }

            // conditionally enable I2C Slave
            rc = FAPI_ATTR_GET(ATTR_I2C_SLAVE_ADDRESS,
                               &i_target,
                               i2c_slave_address);
            if (!rc.ok())
            {
                FAPI_ERR("proc_chiplet_scominit: Error querying ATTR_I2C_SLAVE_ADDRESS on %s",
                         i_target.toEcmdString());
                break;
            }
            rc = fapiGetScom(i_target,
                             I2C_SLAVE_CONFIG_REG_0x000D0000,
                             data);
            if (!rc.ok())
            {
                FAPI_ERR("proc_chiplet_scominit: fapiGetScom error (I2C_SLAVE_CONFIG_REG_0x000D0000) on %s",
                         i_target.toEcmdString());
                break;
            }
            if (i2c_slave_address)
            {
                FAPI_DBG("proc_chiplet_scominit: I2C Slave enabled (%s) address = %d",
                     i_target.toEcmdString(),i2c_slave_address);

                //set I2C address
                rc_ecmd |= data.insert(i2c_slave_address,0,7);

                // disable error state.  when this is enabled and there
                // is an error from I2CS it locks up the I2CS and no
                // more operations are allowed unless cleared
                // through FSI.  Not good for a FSPless system.
                rc_ecmd |= data.clearBit(23);

                // enable I2C interface
                rc_ecmd |= data.setBit(21);

            }
            else
            {
                FAPI_DBG("proc_chiplet_scominit: I2C Slave disabled (%s)",
                     i_target.toEcmdString());

                // disable I2C interface when attribute = 0x0
                rc_ecmd |= data.clearBit(21);
            }

            if (rc_ecmd)
            {
                FAPI_ERR("proc_chiplet_scominit: Error 0x%x setting I2C Slave register data buffer",
                         rc_ecmd);
                rc.setEcmdError(rc_ecmd);
                break;
            }

            rc = fapiPutScom(i_target,
                             I2C_SLAVE_CONFIG_REG_0x000D0000,
                             data);
            if (!rc.ok())
            {
                FAPI_ERR("proc_chiplet_scominit: fapiPutScom error (I2C_SLAVE_CONFIG_REG_0x000D0000) on %s",
                         i_target.toEcmdString());
                break;
            }

            // conditionally enable resonant clocking for XBUS
            rc = FAPI_ATTR_GET(ATTR_CHIP_EC_FEATURE_XBUS_RESONANT_CLK_VALID,
                               &i_target,
                               enable_xbus_resonant_clocking);
            if (!rc.ok())
            {
                FAPI_ERR("proc_chiplet_scominit: Error querying ATTR_CHIP_EC_FEATURE_XBUS_RESONANT_CLK_VALID on %s",
                         i_target.toEcmdString());
                break;
            }

            if (enable_xbus_resonant_clocking)
            {
                FAPI_DBG("proc_chiplet_scominit: Enabling XBUS resonant clocking");
                rc = fapiGetScom(i_target,
                                 MBOX_FSIGP6_0x00050015,
                                 data);
                if (!rc.ok())
                {
                    FAPI_ERR("proc_chiplet_scominit: fapiGetScom error (MBOX_FSIGP6_0x00050015) on %s",
                             i_target.toEcmdString());
                    break;
                }

                rc_ecmd |= data.insertFromRight(
                    XBUS_RESONANT_CLOCK_CONFIG,
                    MBOX_FSIGP6_XBUS_RESONANT_CLOCK_CONFIG_START_BIT,
                    (MBOX_FSIGP6_XBUS_RESONANT_CLOCK_CONFIG_END_BIT-
                     MBOX_FSIGP6_XBUS_RESONANT_CLOCK_CONFIG_START_BIT+1));

                if (rc_ecmd)
                {
                    FAPI_ERR("proc_chiplet_scominit: Error 0x%x setting FSI GP6 register data buffer",
                             rc_ecmd);
                    rc.setEcmdError(rc_ecmd);
                    break;
                }

                if (is_master) 
                {
                    rc = fapiPutScom(i_target,
                                 MBOX_FSIGP6_0x00050015,
                                 data);
                    if (!rc.ok())
                    {
                        FAPI_ERR("proc_chiplet_scominit: fapiPutScom error (MBOX_FSIGP6_0x00050015) on %s",
                             i_target.toEcmdString());
                        break;
                    }
                }
                else 
                {
                    cfam_data.insert(data, 0, 32, 0);
                    rc = fapiPutCfamRegister(i_target, CFAM_FSI_GP6_0x00002815, cfam_data);
                    if (rc)
                    {
                        FAPI_ERR("proc_cen_ref_clk_enable: fapiPutCfamRegister error (CFAM_FSI_GP8_0x00001017)");
                        break;
                    }
                }
            }

            // execute A/X/PCI/DMI FIR init SCOM initfile
            FAPI_INF("proc_chiplet_scominit: Executing %s on %s",
                     PROC_CHIPLET_SCOMINIT_A_X_PCI_DMI_IF, i_target.toEcmdString());
            FAPI_EXEC_HWP(
                rc,
                fapiHwpExecInitFile,
                initfile_targets,
                PROC_CHIPLET_SCOMINIT_A_X_PCI_DMI_IF);
            if (!rc.ok())
            {
                FAPI_ERR("proc_chiplet_scominit: Error from fapiHwpExecInitfile executing %s on %s",
                         PROC_CHIPLET_SCOMINIT_A_X_PCI_DMI_IF,
                         i_target.toEcmdString());
                break;
            }

            // execute NV scominit file
            uint8_t exist_NV = 0x00;
            rc = FAPI_ATTR_GET(ATTR_CHIP_EC_FEATURE_NV_PRESENT, &i_target, exist_NV);
            if (!rc.ok())
            {
                FAPI_ERR("proc_chiplet_scominit: Error getting attribute value ATTR_CHIP_EC_FEATURE_NV_PRESENT");
                break;
            }
            if (exist_NV)
            {
                FAPI_INF("proc_chiplet_scominit: Executing  %s on %s",
                         PROC_CHIPLET_SCOMINIT_NPU_IF, i_target.toEcmdString());
                FAPI_EXEC_HWP(
                        rc,
                        fapiHwpExecInitFile,
                        initfile_targets,
                        PROC_CHIPLET_SCOMINIT_NPU_IF);
                if (!rc.ok())
                {
                    FAPI_ERR("proc_chiplet_scominit: Error from fapiHwpExecInitfile executing %s on %s",
                             PROC_CHIPLET_SCOMINIT_NPU_IF,
                             i_target.toEcmdString());
                    break;
                }

                // cleanup FIR bit (NPU FIR bit 27) caused by NDL/NTL parity error
                rc_ecmd = data.flushTo1();
                rc_ecmd = data.clearBit(NPU_FIR_NTL_DL2TL_PARITY_ERR_BIT);
                if (rc_ecmd)
                {
                    FAPI_ERR("proc_chiplet_scominit: Error 0x%Xforming NPU FIR cleanup data buffer",
                  	   rc_ecmd);
                    rc.setEcmdError(rc_ecmd);
                    break;
                }
                rc = fapiPutScom(i_target, NPU_FIR_AND_0x08013D81, data);
                if (!rc.ok())
                {
                    FAPI_ERR("proc_chiplet_scominit: fapiPutScom error (NPU_FIR_AND_0x08013D81) on %s",
                             i_target.toEcmdString());
                    break;
                }
                rc = fapiPutScom(i_target, NPU_FIR_MASK_AND_0x08013D84, data);
                if (!rc.ok())
                {
                    FAPI_ERR("proc_chiplet_scominit: fapiPutScom error (NPU_FIR_MASK_AND_0x08013D84) on %s",
                             i_target.toEcmdString());
                    break;
                }
            }
            else
            {
                FAPI_INF("proc_chiplet_scominit: NV link logic not present, scom initfile processing skipped");
            }

            // determine set of functional MCS chiplets
            rc = fapiGetChildChiplets(i_target,
                                      fapi::TARGET_TYPE_MCS_CHIPLET,
                                      mcs_targets,
                                      fapi::TARGET_STATE_FUNCTIONAL);
            if (!rc.ok())
            {
                FAPI_ERR("proc_chiplet_scominit: Error from fapiGetChildChiplets (MCS) on %s",
                         i_target.toEcmdString());
                break;
            }

            // apply MCS SCOM initfile only for functional chiplets
            for (std::vector<fapi::Target>::iterator i = mcs_targets.begin();
                 (i != mcs_targets.end()) && rc.ok();
                 i++)
            {
                // execute MCS SCOM initfile
                initfile_targets.clear();
                initfile_targets.push_back(*i);
                initfile_targets.push_back(i_target);
                FAPI_INF("proc_chiplet_scominit: Executing %s on %s",
                         PROC_CHIPLET_SCOMINIT_MCS_IF, i->toEcmdString());
                FAPI_EXEC_HWP(
                    rc,
                    fapiHwpExecInitFile,
                    initfile_targets,
                    PROC_CHIPLET_SCOMINIT_MCS_IF);
                if (!rc.ok())
                {
                    FAPI_ERR("proc_chiplet_scominit: Error from fapiHwpExecInitfile executing %s on %s",
                             PROC_CHIPLET_SCOMINIT_MCS_IF,
                             i->toEcmdString());
                    break;
                }

                // determine MCS position
                rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &(*i), mcs_pos);

                if (!rc.ok())
                {
                    FAPI_ERR("proc_chiplet_scominit: Error from FAPI_ATTR_GET (ATTR_CHIP_UNIT_POS) on %s",
                             i->toEcmdString());
                    break;
                }

                if (mcs_pos < master_mcs_pos)
                {
                    fapi::Target cen_target_unused;
                    rc = fapiGetOtherSideOfMemChannel(*i,
                                                      cen_target_unused,
                                                      fapi::TARGET_STATE_FUNCTIONAL);
                    // use return code only to indicate presence of connected Centaur,
                    // do not propogate/emit error if not connected
                    if (rc.ok())
                    {
                        FAPI_DBG("Updating master_mcs_pos to %d", mcs_pos);
                        FAPI_DBG("  Target: %s", cen_target_unused.toEcmdString());
                        master_mcs = *i;
                        master_mcs_pos = mcs_pos;
                    }
                    else
                    {
                        rc = fapi::FAPI_RC_SUCCESS;
                    }
                }

            }
            if (!rc.ok())
            {
                break;
            }

            if (master_mcs.getType() == fapi::TARGET_TYPE_MCS_CHIPLET)
            {
                // set MCMODE0Q_ENABLE_CENTAUR_SYNC on first target only
                // (this bit is required to be set on at most one MCS/chip)
                rc_ecmd |= data.flushTo0();
                rc_ecmd |= data.setBit(MCSMODE0_EN_CENTAUR_SYNC_BIT);
                rc_ecmd |= mask.setBit(MCSMODE0_EN_CENTAUR_SYNC_BIT);

                // check buffer manipulation return codes
                if (rc_ecmd)
                {
                    FAPI_ERR("proc_chiplet_scominit: Error 0x%X setting up MCSMODE0 data buffer",
                             rc_ecmd);
                    rc.setEcmdError(rc_ecmd);
                    break;
                }

                // write register with updated content
                rc = fapiPutScomUnderMask(master_mcs,
                                          MCS_MCSMODE0_0x02011807,
                                          data,
                                          mask);
                if (!rc.ok())
                {
                    FAPI_ERR("proc_chiplet_scominit: fapiPutScomUnderMask error (MCS_MCSMODE0_0x02011807) on %s",
                             master_mcs.toEcmdString());
                    break;
                }

            }
        }
        // unsupported target type
        else
        {
            FAPI_ERR("proc_chiplet_scominit: Unsupported target type");
            const fapi::Target & TARGET = i_target;
            FAPI_SET_HWP_ERROR(rc, RC_PROC_CHIPLET_SCOMINIT_INVALID_TARGET);
            break;
        }
    } while(0);

    // mark HWP exit
    FAPI_INF("proc_chiplet_scominit: End");
    return rc;
}
Example #10
0
fapi2::ReturnCode pm_cme_fir_reset(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    FAPI_IMP("pm_cme_fir_reset start");
    auto l_eqChiplets = i_target.getChildren<fapi2::TARGET_TYPE_EQ>
                        (fapi2::TARGET_STATE_FUNCTIONAL);
    uint8_t firinit_done_flag;

    FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PM_FIRINIT_DONE_ONCE_FLAG,
                           i_target, firinit_done_flag),
             "ERROR: Failed to fetch the entry status of FIRINIT");

    for (auto l_eq_chplt : l_eqChiplets)
    {
        //We cannot rely on the HWAS state because during an MPIPL
        //the cores get stopped and the SP doesnt know until an
        //attr sync occurs with the platform. We must use the
        //query_cache_state to safely determine if we can scom
        //the ex targets
        fapi2::ReturnCode l_rc;
        bool l_l2_is_scanable[MAX_L2_PER_QUAD];
        bool l_l2_is_scomable[MAX_L2_PER_QUAD];
        bool l_l3_is_scanable[MAX_L3_PER_QUAD];
        bool l_l3_is_scomable[MAX_L3_PER_QUAD];

        for (auto cnt = 0; cnt < MAX_L2_PER_QUAD; ++cnt)
        {
            l_l2_is_scomable[cnt] = false;
            l_l2_is_scanable[cnt] = false;
        }

        for (auto cnt = 0; cnt < MAX_L3_PER_QUAD; ++cnt)
        {
            l_l3_is_scanable[cnt] = false;
            l_l3_is_scomable[cnt] = false;
        }

        uint8_t l_chip_unit_pos;

        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
                               l_eq_chplt, l_chip_unit_pos),
                 "ERROR: Failed to get the chip unit pos attribute from the eq");

        FAPI_EXEC_HWP(l_rc, p9_query_cache_access_state, l_eq_chplt,
                      l_l2_is_scomable, l_l2_is_scanable,
                      l_l3_is_scomable, l_l3_is_scanable);
        FAPI_TRY(l_rc, "ERROR: failed to query cache access state for EQ %d",
                 l_chip_unit_pos);


        auto l_exChiplets = l_eq_chplt.getChildren<fapi2::TARGET_TYPE_EX>
                            (fapi2::TARGET_STATE_FUNCTIONAL);

        for(auto l_ex_chplt : l_exChiplets)
        {
            FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS,
                                   l_ex_chplt, l_chip_unit_pos),
                     "ERROR: Failed to get the chip unit pos attribute from the ex");

            //look ex is scommable
            l_chip_unit_pos = l_chip_unit_pos % 2;

            if ((!(l_l2_is_scomable[l_chip_unit_pos]) &&
                 !(l_l3_is_scomable[l_chip_unit_pos])))
            {
                continue;
            }

            p9pmFIR::PMFir <p9pmFIR::FIRTYPE_CME_LFIR> l_cmeFir(l_ex_chplt);

            /* Only save off the FIR masks if they have been initialized */
            if ( firinit_done_flag != fapi2::ENUM_ATTR_PM_FIRINIT_DONE_ONCE_FLAG_FIRS_RESET_IN_HB )
            {
                FAPI_TRY(l_cmeFir.get(p9pmFIR::REG_FIRMASK),
                         "ERROR: Failed to get the PBA FIR MASK value");

                /* Fetch the CME FIR MASK; Save it to HWP attribute; clear it */
                FAPI_TRY(l_cmeFir.saveMask(),
                         "ERROR: Failed to save CME FIR Mask to the attribute");

                FAPI_TRY(l_cmeFir.setAllRegBits(p9pmFIR::REG_FIRMASK),
                         "ERROR: Faled to set the CME FIR MASK");

                FAPI_TRY(l_cmeFir.put(),
                         "ERROR:Failed to write to the CME FIR MASK");
            }
        }
    }

    if (firinit_done_flag == fapi2::ENUM_ATTR_PM_FIRINIT_DONE_ONCE_FLAG_NO_INIT)
    {
        firinit_done_flag   =   fapi2::ENUM_ATTR_PM_FIRINIT_DONE_ONCE_FLAG_FIRS_RESET_IN_HB;
        FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_PM_FIRINIT_DONE_ONCE_FLAG, i_target, firinit_done_flag ),
                 "ERROR: Failed to set attribute PM_FIRINIT_DONE_ONCE_FLAG to RESET_IN_HB in pm_cme_fir_reset");
    }

fapi_try_exit:
    return fapi2::current_err;
}
//------------------------------------------------------------------------------
// function:
//      Check if the SBE is still running
//      Wait 1 sec, then check again if still running
//      When stopped, check if the SBE halt code, istep, and substep are correct
//
// parameters: i_target           => slave chip target
//             i_pSEEPROM         => pointer to the seeprom image (for errors)
//             i_wait_in_ms       => pointer to the seeprom image (for errors)
//
// returns: FAPI_RC_SUCCESS if the slave SBE stopped with success at the correct
//          location, else error
//------------------------------------------------------------------------------
    fapi::ReturnCode proc_check_slave_sbe_seeprom_complete(
        const fapi::Target & i_target,
        const void         * i_pSEEPROM,
        const size_t       i_wait_in_ms)
    {
        // data buffer to hold register values
        ecmdDataBufferBase data(64);

        // return codes
        uint32_t rc_ecmd = 0;
        fapi::ReturnCode rc;

        // track if procedure has cleared I2C master bus fence
        bool i2cm_bus_fence_cleared = false;

        // mark function entry
        FAPI_INF("Entry");

        do
        {
            //Check if the SBE is still running.  Loop until stopped
            //or loop time is exceeded.  
            bool still_running = true;
            size_t loop_time = 0;
            rc = proc_check_slave_sbe_seeprom_complete_check_running(
                   i_target,
                   still_running );
            if( rc )
            {
                break;
            }

            while (still_running && (loop_time < i_wait_in_ms))
            {
                //Not done -- sleep 10ms, then check again
                loop_time += MS_TO_FINISH;
                rc = fapiDelay(NS_TO_FINISH, SIM_CYCLES_TO_FINISH);
                if( rc )
                {
                    FAPI_ERR("Error with delay\n");
                    break;
                }

                rc = proc_check_slave_sbe_seeprom_complete_check_running(
                       i_target,
                       still_running );
                if( rc )
                {
                    break;
                }
            }

            //Break if took an error
            if( rc )
            {
                break;
            }

            FAPI_INF("SBE is running [%d], wait time in ms[%zd]",
                     still_running, loop_time);

            //Give up if we're still running
            if( still_running )
            {
                FAPI_ERR(
                        "SBE still running after waiting (%zdns, %lld cycles)",
                        loop_time,
                        loop_time/MS_TO_FINISH*SIM_CYCLES_TO_FINISH );

                const fapi::Target & CHIP_IN_ERROR = i_target;
                FAPI_SET_HWP_ERROR(rc,
                      RC_PROC_CHECK_SLAVE_SBE_SEEPROM_COMPLETE_STILL_RUNNING);
                break;
            } //end if(still_running)

            //SBE is stopped. Let's see where
            uint8_t  halt_code = 0;
            uint16_t istep_num = 0;
            uint8_t  substep_num = 0;

            // before analysis proceeds, make sure that I2C master bus fence is cleared
            FAPI_EXEC_HWP(rc, proc_reset_i2cm_bus_fence, i_target);
            if (!rc.ok())
            {
                FAPI_ERR("Error from proc_reset_i2cm_bus_fence");
                break;
            }
            // mark that fence has been cleared
            i2cm_bus_fence_cleared = true;

            //Get current location from SBE VITAL
            rc = proc_check_slave_sbe_seeprom_complete_get_location(
                i_target,
                halt_code,
                istep_num,
                substep_num );
            if( rc )
            {
                FAPI_ERR("Unable to get the current SBE location");
                break;
            }

            //Did it stop with success?
            if( halt_code != SBE_EXIT_SUCCESS_0xF )
            {
                FAPI_ERR(
                    "SBE halted with error %i (istep 0x%X, substep %i)", 
                    halt_code,
                    istep_num,
                    substep_num);
                //Get the error code from the SBE code
                FAPI_EXEC_HWP(rc, proc_extract_sbe_rc, i_target, NULL, i_pSEEPROM, SBE);
                break;
            }
            //Halt code was success

            //Did it stop in the correct istep?
            if(( istep_num != PROC_SBE_CHECK_MASTER_MAGIC_ISTEP_NUM ) &&
               ( istep_num != PROC_SBE_ENABLE_PNOR_MAGIC_ISTEP_NUM ) &&
               ( istep_num != PROC_SBE_EX_HOST_RUNTIME_SCOM_MAGIC_ISTEP_NUM ))
            {
                FAPI_ERR(
                    "SBE halted in wrong istep (istep 0x%X, substep %i)", 
                    istep_num,
                    substep_num);
                const fapi::Target & CHIP_IN_ERROR = i_target;
                uint16_t & ISTEP_NUM = istep_num;
                uint8_t & SUBSTEP_NUM = substep_num;
                FAPI_SET_HWP_ERROR(rc,
                        RC_PROC_CHECK_SLAVE_SBE_SEEPROM_COMPLETE_BAD_ISTEP_NUM);
                break;
            }
            //Istep is correct

            //Did it stop in the correct substep?
            if( (( istep_num == PROC_SBE_CHECK_MASTER_MAGIC_ISTEP_NUM ) &&
                 ( substep_num != SUBSTEP_CHECK_MASTER_SLAVE_CHIP )) ||
                (( istep_num == PROC_SBE_ENABLE_PNOR_MAGIC_ISTEP_NUM ) &&
                 ( substep_num != SUBSTEP_ENABLE_PNOR_SLAVE_CHIP )))
            {
                FAPI_ERR(
                    "SBE halted in wrong substep (istep 0x%X, substep %i)", 
                    istep_num,
                    substep_num);
                const fapi::Target & CHIP_IN_ERROR = i_target;
                uint16_t & ISTEP_NUM = istep_num;
                uint8_t & SUBSTEP_NUM = substep_num;
                FAPI_SET_HWP_ERROR(rc,
                      RC_PROC_CHECK_SLAVE_SBE_SEEPROM_COMPLETE_BAD_SUBSTEP_NUM);
                break;
            }
            //Substep is correct

            //Looks good!

            // Reset the SBE so it can be used for MPIPL if needed
            rc_ecmd |= data.flushTo0();
            rc_ecmd |= data.setBit(0);

            if(rc_ecmd)
            {
                FAPI_ERR("Error (0x%x) setting up ecmdDataBufferBase", rc_ecmd);
                rc.setEcmdError(rc_ecmd);
                break;
            }
            rc = fapiPutScom(i_target, PORE_SBE_RESET_0x000E0002, data);
            if(!rc.ok())
            {
                FAPI_ERR("Scom error resetting SBE\n");
                break;
            }
        } while (0);

        // if an error occurred prior to the I2C master bus fence
        // being cleared, attempt to clear it prior to exit
        if (!rc.ok() && !i2cm_bus_fence_cleared)
        {
            // discard rc, return that of original fail
            fapi::ReturnCode rc_unused;
            FAPI_EXEC_HWP(rc_unused, proc_reset_i2cm_bus_fence, i_target);
        }

        // mark function exit
        FAPI_INF("Exit");
        return rc;
    }
Example #12
0
///////////////////////////////////////////////////////////////////////////////
// See header for doxygen documentation
///////////////////////////////////////////////////////////////////////////////
errlHndl_t mmioScomPerformOp(DeviceFW::OperationType i_opType,
                          TARGETING::Target* i_target,
                          void* io_buffer,
                          size_t& io_buflen,
                          int64_t i_accessType,
                          va_list i_args)
{
    errlHndl_t l_err = nullptr;
    fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;
    // The only extra arg should be the scomAddress
    uint64_t l_expAddr = va_arg(i_args,uint64_t);

    // The fapi2 put/get mmioScom interfaces require a fapi2::buffer so convert
    // to a uint64_t buffer (for IBM scom) and uint32_t buffer (for Microchip scoms)
    fapi2::buffer<uint64_t> l_fapi2Buffer64(*reinterpret_cast<uint64_t *>(io_buffer));
    fapi2::buffer<uint32_t> l_fapi2Buffer32;
    l_fapi2Buffer64.extractToRight<32,32>(l_fapi2Buffer32);

    do
    {
        // First make sure the inputs are valid
        l_err = EXPSCOM::validateInputs ( i_opType, i_target, io_buflen, l_expAddr);

        if(l_err)
        {
            // Write a trace out to the buffer and then collect it on the log
            // this way we can know if the fail was in i2cScomPerformOp or mmioScomPerformOp
            TRACFCOMP( g_trac_expscom, ERR_MRK "mmioscomPerformOp> Validation of inputs failed see error logs for details ");
            l_err->collectTrace(EXPSCOM_COMP_NAME);
            break;
        }

        // Check if this is a IBM_SCOM address by &ing the address with IBM_SCOM_INDICATOR
        // If the indicator is not set, then we will assume this is a microChip address
        if( (l_expAddr & mss::exp::i2c::IBM_SCOM_INDICATOR) == mss::exp::i2c::IBM_SCOM_INDICATOR)
        {
            // READ and WRITE equates to mss::exp::ib::getScom and mss::exp::ib::putScom respectively.
            //  any other OP is invalid. i/o data is expected to be 8 bytes for IBM scoms
            if(i_opType == DeviceFW::READ)
            {
                FAPI_EXEC_HWP(l_rc , mss::exp::ib::getScom, i_target, l_expAddr, l_fapi2Buffer64);
                l_err = fapi2::rcToErrl(l_rc);
                if(l_err)
                {
                    l_err->collectTrace(FAPI_IMP_TRACE_NAME,256);
                    l_err->collectTrace(FAPI_TRACE_NAME,384);
                    TRACFCOMP( g_trac_expscom, ERR_MRK "mmioscomPerformOp> mss::exp::ib::getScom failed for HUID 0x%x Address 0x%lx ",
                               TARGETING::get_huid(i_target), l_expAddr );
                }
                else
                {
                    // Copy contents of what we read to io_buffer
                    memcpy(io_buffer, reinterpret_cast<uint8_t *>(l_fapi2Buffer64.pointer()), sizeof(uint64_t));
                }
            }
            else
            {
                FAPI_EXEC_HWP(l_rc , mss::exp::ib::putScom, i_target, l_expAddr, l_fapi2Buffer64);
                l_err = fapi2::rcToErrl(l_rc);
                if(l_err)
                {
                    l_err->collectTrace(FAPI_IMP_TRACE_NAME,256);
                    l_err->collectTrace(FAPI_TRACE_NAME,384);
                    TRACFCOMP( g_trac_expscom, ERR_MRK "mmioscomPerformOp> mss::exp::ib::putScom failed for HUID 0x%x Address 0x%lx ",
                               TARGETING::get_huid(i_target), l_expAddr );
                }
            }
        }
        else
        {
            // READ and WRITE equates to mss::exp::ib::gettMMIO32 and mss::exp::ib::putMMIO32 respectively.
            //  any other OP is invalid.
            if(i_opType == DeviceFW::READ)
            {
                FAPI_EXEC_HWP(l_rc , mss::exp::ib::getMMIO32, i_target, l_expAddr, l_fapi2Buffer32);
                l_err = fapi2::rcToErrl(l_rc);
                if(l_err)
                {
                    TRACFCOMP( g_trac_expscom, ERR_MRK "mmioscomPerformOp> getMMIO32 failed for HUID 0x%x Address 0x%lx ",
                              TARGETING::get_huid(i_target), l_expAddr );
                }
                else
                {
                    // Put the contexts of the 32 bit buffer right justified into the 64 bit buffer
                    l_fapi2Buffer64.flush<0>();
                    l_fapi2Buffer64.insertFromRight<32,32>(l_fapi2Buffer32);
                    // Copy contents of 64 bit buffer to io_buffer
                    memcpy(io_buffer, reinterpret_cast<uint8_t *>(l_fapi2Buffer64.pointer()), sizeof(uint64_t));
                }
            }
            else
            {
                FAPI_EXEC_HWP(l_rc , mss::exp::ib::putMMIO32, i_target, l_expAddr, l_fapi2Buffer32);
                l_err = fapi2::rcToErrl(l_rc);
                if(l_err)
                {
                    TRACFCOMP( g_trac_expscom, ERR_MRK "mmioscomPerformOp> putMMIO32 failed for HUID 0x%x Address 0x%lx ",
                              TARGETING::get_huid(i_target), l_expAddr );
                }
            }

        }

    } while (0);
    return l_err;
}
Example #13
0
///
/// @brief Creates and loads the OCC memory boot launcher
/// @param[in] i_target  Chip target
/// @param[in] i_data64  32 bit instruction representing the branch
///                    instruction to the SRAM boot loader
/// @return FAPI2_RC_SUCCESS on success, else error
///
fapi2::ReturnCode bootMemory(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target,
    fapi2::buffer<uint64_t>& i_data64)
{
    static const uint32_t SRAM_PROGRAM_SIZE = 2;  // in double words
    uint64_t l_sram_program[SRAM_PROGRAM_SIZE];
    fapi2::ReturnCode l_rc;
    uint32_t l_ocb_length_act = 0;

    // Setup use OCB channel 1 for placing instruction in SRAM
    // Channel will be returned to Linear Stream, Circular upon exit
    FAPI_EXEC_HWP(l_rc, p9_pm_ocb_indir_setup_linear, i_target,
                  p9ocb::OCB_CHAN1,
                  p9ocb::OCB_TYPE_LINSTR,
                  OCC_SRAM_BOOT_ADDR);   // Bar
    FAPI_TRY(l_rc);


    // lis r1, 0x8000
    l_sram_program[0] = ((uint64_t)ppc_lis(1, 0x8000) << 32);
    FAPI_DBG("ppc_lis: 0x%08X with data 0x%08X",
             ppc_lis(1, 0x8000), 0x8000);

    // ori r1, r1, OCC_BOOT_OFFSET
    l_sram_program[0] |= (ppc_ori(1, 1, OCC_BOOT_OFFSET));
    FAPI_DBG("ppc_ori: 0x%08X with data 0x%08X",
             ppc_ori(1, 1, OCC_BOOT_OFFSET), OCC_BOOT_OFFSET);

    // mtctr (mtspr r1, CTR )
    l_sram_program[1] = ((uint64_t)ppc_mtspr(1, CTR) << 32);
    FAPI_DBG("ppc_mtspr: 0x%08X with spr 0x%08X",
             ppc_mtspr(1, CTR), CTR);

    // bctr
    l_sram_program[1] |= ppc_bctr();
    FAPI_DBG("ppc_bctr: 0x%08X", ppc_bctr());

    FAPI_DBG("SRAM PGM[0]: 0x%016llX", l_sram_program[0]);
    FAPI_DBG("SRAM PGM[1]: 0x%016llX", l_sram_program[1]);

    // Write to SRAM
    FAPI_EXEC_HWP(l_rc, p9_pm_ocb_indir_access, i_target,
                  p9ocb::OCB_CHAN1,
                  p9ocb::OCB_PUT,
                  SRAM_PROGRAM_SIZE,
                  false,
                  0,
                  l_ocb_length_act,
                  l_sram_program);

    FAPI_ASSERT(l_ocb_length_act == SRAM_PROGRAM_SIZE,
                fapi2::OCC_CONTROL_MEM_BOOT_LENGTH_MISMATCH()
                .set_ACTLENGTH(l_ocb_length_act)
                .set_LENGTH(SRAM_PROGRAM_SIZE),
                "OCC memory boot launcher length mismatch");

    // b OCC_SRAM_BOOT_ADDR2
    i_data64.insertFromRight<0, 32>(ppc_b(OCC_SRAM_BOOT_ADDR2));

fapi_try_exit:
    // Channel 1 returned to Linear Stream, Circular upon exit
    FAPI_EXEC_HWP(l_rc, p9_pm_ocb_indir_setup_circular, i_target,
                  p9ocb::OCB_CHAN1,
                  p9ocb::OCB_TYPE_CIRC,
                  0,   // Bar
                  0,   // Length
                  p9ocb::OCB_Q_OUFLOW_NULL,
                  p9ocb::OCB_Q_ITPTYPE_NULL);
    fapi2::current_err = l_rc;

    return fapi2::current_err;
}
fapi2::ReturnCode p9_chiplet_fabric_scominit(const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target)
{
    fapi2::ReturnCode l_rc;
    char l_procTargetStr[fapi2::MAX_ECMD_STRING_LEN];
    char l_chipletTargetStr[fapi2::MAX_ECMD_STRING_LEN];
    fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM;
    std::vector<fapi2::Target<fapi2::TARGET_TYPE_XBUS>> l_xbus_chiplets;
    std::vector<fapi2::Target<fapi2::TARGET_TYPE_OBUS>> l_obus_chiplets;

    fapi2::ATTR_PROC_FABRIC_OPTICS_CONFIG_MODE_Type l_fbc_optics_cfg_mode = { fapi2::ENUM_ATTR_PROC_FABRIC_OPTICS_CONFIG_MODE_SMP };
    FAPI_DBG("Start");

    // Get proc target string
    fapi2::toString(i_target, l_procTargetStr, sizeof(l_procTargetStr));

    // apply FBC non-hotplug initfile
    FAPI_DBG("Invoking p9.fbc.no_hp.scom.initfile on target %s...", l_procTargetStr);
    FAPI_EXEC_HWP(l_rc, p9_fbc_no_hp_scom, i_target, FAPI_SYSTEM);

    if (l_rc)
    {
        FAPI_ERR("Error from p9_fbc_no_hp_scom");
        fapi2::current_err = l_rc;
        goto fapi_try_exit;
    }

    // setup IOE (XBUS FBC IO) TL SCOMs
    FAPI_DBG("Invoking p9.fbc.ioe_tl.scom.initfile on target %s...", l_procTargetStr);
    FAPI_EXEC_HWP(l_rc, p9_fbc_ioe_tl_scom, i_target, FAPI_SYSTEM);

    if (l_rc)
    {
        FAPI_ERR("Error from p9_fbc_ioe_tl_scom");
        fapi2::current_err = l_rc;
        goto fapi_try_exit;
    }

    l_xbus_chiplets = i_target.getChildren<fapi2::TARGET_TYPE_XBUS>();

    if (l_xbus_chiplets.size())
    {
        FAPI_TRY(fapi2::putScom(i_target, PU_PB_IOE_FIR_ACTION0_REG, FBC_IOE_TL_FIR_ACTION0),
                 "Error from putScom (PU_PB_IOE_FIR_ACTION0_REG)");
        FAPI_TRY(fapi2::putScom(i_target, PU_PB_IOE_FIR_ACTION1_REG, FBC_IOE_TL_FIR_ACTION1),
                 "Error from putScom (PU_PB_IOE_FIR_ACTION1_REG)");
        FAPI_TRY(fapi2::putScom(i_target, PU_PB_IOE_FIR_MASK_REG, FBC_IOE_TL_FIR_MASK),
                 "Error from putScom (PU_PB_IOE_FIR_MASK_REG)");
    }

    // setup IOE (XBUS FBC IO) DL SCOMs
    for (auto l_iter = l_xbus_chiplets.begin();
         l_iter != l_xbus_chiplets.end();
         l_iter++)
    {
        fapi2::toString(*l_iter, l_chipletTargetStr, sizeof(l_chipletTargetStr));
        FAPI_DBG("Invoking p9.fbc.ioe_dl.scom.initfile on target %s...", l_chipletTargetStr);
        FAPI_EXEC_HWP(l_rc, p9_fbc_ioe_dl_scom, *l_iter, i_target);

        if (l_rc)
        {
            FAPI_ERR("Error from p9_fbc_ioe_dl_scom");
            fapi2::current_err = l_rc;
            goto fapi_try_exit;
        }

        // configure action registers & unmask
        FAPI_TRY(fapi2::putScom(*l_iter, XBUS_LL0_IOEL_FIR_ACTION0_REG, FBC_IOE_DL_FIR_ACTION0),
                 "Error from putScom (XBUS_LL0_IOEL_FIR_ACTION0_REG)");
        FAPI_TRY(fapi2::putScom(*l_iter, XBUS_LL0_IOEL_FIR_ACTION1_REG, FBC_IOE_DL_FIR_ACTION1),
                 "Error from putScom (XBUS_LL0_IOEL_FIR_ACTION1_REG)");
        FAPI_TRY(fapi2::putScom(*l_iter, XBUS_LL0_LL0_LL0_IOEL_FIR_MASK_REG, FBC_IOE_DL_FIR_MASK),
                 "Error from putScom (XBUS_LL0_LL0_LL0_IOEL_FIR_MASK_REG)");
    }

    // set FBC optics config mode attribute
    l_obus_chiplets = i_target.getChildren<fapi2::TARGET_TYPE_OBUS>();

    for (auto l_iter = l_obus_chiplets.begin();
         l_iter != l_obus_chiplets.end();
         l_iter++)
    {
        uint8_t l_unit_pos;
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, *l_iter, l_unit_pos),
                 "Error from FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS)");
        FAPI_INF("Updating index: %d\n", l_unit_pos);
        FAPI_INF("  before: %d\n", l_fbc_optics_cfg_mode[l_unit_pos]);
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_OPTICS_CONFIG_MODE, *l_iter, l_fbc_optics_cfg_mode[l_unit_pos]),
                 "Error from FAPI_ATTR_GET(ATTR_OPTICS_CONFIG_MODE)");
        FAPI_INF("  after: %d\n", l_fbc_optics_cfg_mode[l_unit_pos]);
    }

    FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_PROC_FABRIC_OPTICS_CONFIG_MODE, i_target, l_fbc_optics_cfg_mode),
             "Error from FAPI_ATTR_SET(ATTR_PROC_FABRIC_OPTICS_CONFIG_MODE)");

fapi_try_exit:
    FAPI_DBG("End");
    return fapi2::current_err;
}
//------------------------------------------------------------------------------
// function:
//      Stop SBE runtime scan service
//
// parameters: i_target => chip target
// returns: FAPI_RC_SUCCESS if operation was successful, else error
//------------------------------------------------------------------------------
fapi::ReturnCode proc_stop_sbe_scan_service(
    const fapi::Target& i_target,
    const void* i_pSEEPROM)
{
    // return codes
    fapi::ReturnCode rc;
    uint32_t rc_ecmd = 0;

    // track if procedure has cleared I2C master bus fence
    bool i2cm_bus_fence_cleared = false;

    // mark function entry
    FAPI_DBG("Start");

    do
    {
        // check SBE progress
        bool sbe_running = true;
        size_t loop_time = 0;
        uint8_t halt_code = 0;
        uint16_t istep_num = 0;
        uint8_t substep_num = 0;
        bool scan_service_loop_reached = false;

        // retrieve status
        rc = proc_sbe_utils_check_status(
            i_target,
            sbe_running,
            halt_code,
            istep_num,
            substep_num);
        if (!rc.ok())
        {
            FAPI_ERR("Error from proc_check_sbe_state_check_status");
            break;
        }

        // get HB->SBE request mailbox, check that it is clear
        ecmdDataBufferBase mbox_data(64);
        bool sbe_ready = false;
        rc = fapiGetScom(i_target, MBOX_SCRATCH_REG0_0x00050038, mbox_data);
        if (!rc.ok())
        {
            FAPI_ERR("Scom error reading SBE MBOX0 Register");
            break;
        }
        sbe_ready = (mbox_data.getDoubleWord(0) == 0);

        scan_service_loop_reached =
            sbe_running &&
            sbe_ready &&
            !halt_code &&
            (istep_num == PROC_SBE_SCAN_SERVICE_ISTEP_NUM) &&
            (substep_num == SUBSTEP_SBE_READY);

        FAPI_INF("SBE is running [%d], loop time [%zd], scan service loop reached [%d]",
                 sbe_running, loop_time, scan_service_loop_reached);

        if (!sbe_running)
        {
            FAPI_INF("SBE is stopped, exiting!");
            break;
        }
        else if (scan_service_loop_reached)
        {
            // format stop request
            rc_ecmd |= mbox_data.setBit(MBOX0_REQUEST_VALID_BIT);
            rc_ecmd |= mbox_data.insertFromRight(MBOX0_HALT_PATTERN,
                                                 MBOX0_HALT_PATTERN_START_BIT,
                                                 (MBOX0_HALT_PATTERN_END_BIT-
                                                  MBOX0_HALT_PATTERN_START_BIT)+1);
            if (rc_ecmd)
            {
                FAPI_ERR("Error 0x%x setting up SBE MBOX0 data buffer.", rc_ecmd);
                rc.setEcmdError(rc_ecmd);
                break;
            }

            // submit stop request to SBE
            FAPI_DBG("Submitting stop request to SBE");
            rc = fapiPutScom(i_target, MBOX_SCRATCH_REG0_0x00050038, mbox_data);
            if (!rc.ok())
            {
                FAPI_ERR("Error writing SBE MBOX0 Register");
                break;
            }

            // pause to allow request to be processed
            uint32_t loop_num = 0;
            while (sbe_running && (loop_num < SBE_HALT_POLL_MAX_LOOPS))
            {
                loop_num++;
                rc = fapiDelay(SBE_HALT_POLL_DELAY_HW, SBE_HALT_POLL_DELAY_SIM);
                if (!rc.ok())
                {
                    FAPI_ERR("Error from fapiDelay");
                    break;
                }

                // retrieve status
                rc = proc_sbe_utils_check_status(
                    i_target,
                    sbe_running,
                    halt_code,
                    istep_num,
                    substep_num);
                if (!rc.ok())
                {
                    FAPI_ERR("Error from proc_check_sbe_state_check_status");
                    break;
                }
            }
            if (rc)
            {
                break;
            }
            if (sbe_running)
            {
                FAPI_ERR("SBE is STILL running!");
                const fapi::Target & TARGET = i_target;
                FAPI_SET_HWP_ERROR(rc, RC_PROC_STOP_SBE_SCAN_SERVICE_SBE_NOT_STOPPED);
                break;
            }

            // before analysis proceeds, make sure that I2C master bus fence is cleared
            FAPI_EXEC_HWP(rc, proc_reset_i2cm_bus_fence, i_target);
            if (!rc.ok())
            {
                FAPI_ERR("Error from proc_reset_i2cm_bus_fence");
                break;
            }
            // mark that fence has been cleared
            i2cm_bus_fence_cleared = true;

            //  ensure correct halt code is captured
            rc = proc_sbe_utils_check_status(
                i_target,
                sbe_running,
                halt_code,
                istep_num,
                substep_num);
            if (!rc.ok())
            {
                FAPI_ERR("Error from proc_check_sbe_state_check_status");
                break;
            }

            // confirm that expected halt point was reached
            if (halt_code != SBE_EXIT_SUCCESS_0xF)
            {
                FAPI_ERR("SBE halted with error 0x%X (istep 0x%03X, substep 0x%X)",
                         halt_code, istep_num, substep_num);
                // extract & return error code from analyzing SBE state
                FAPI_EXEC_HWP(rc, proc_extract_sbe_rc, i_target, NULL, i_pSEEPROM, SBE);
                break;
            }

            if ((istep_num != PROC_SBE_SCAN_SERVICE_ISTEP_NUM) ||
                (substep_num != SUBSTEP_HALT_SUCCESS))
            {
                FAPI_ERR("Expected SBE istep 0x%03llX, substep 0x%X but found istep 0x%03X, substep 0x%X",
                         PROC_SBE_SCAN_SERVICE_ISTEP_NUM, SUBSTEP_HALT_SUCCESS,
                         istep_num, substep_num);
                const fapi::Target & TARGET = i_target;
                const uint32_t & ISTEP_NUM = istep_num;
                const uint32_t & SUBSTEP_NUM = substep_num;
                FAPI_SET_HWP_ERROR(rc, RC_PROC_STOP_SBE_SCAN_SERVICE_SBE_BAD_HALT);
                break;
            }

            // Reset the SBE so it can be used for MPIPL if needed
            ecmdDataBufferBase sbe_reset_data(64);
            rc = fapiPutScom(i_target, PORE_SBE_RESET_0x000E0002, sbe_reset_data);
            if (!rc.ok())
            {
                FAPI_ERR("Scom error resetting SBE\n");
                break;
            }
        }
        // error
        else
        {
            FAPI_ERR("SBE did not reach acceptable final state!");
            const fapi::Target & TARGET = i_target;
            const bool & SBE_RUNNING = sbe_running;
            const uint8_t & HALT_CODE = halt_code;
            const uint16_t & ISTEP_NUM = istep_num;
            const uint8_t & SUBSTEP_NUM = substep_num;
            FAPI_SET_HWP_ERROR(rc, RC_PROC_STOP_SBE_SCAN_SERVICE_UNEXPECTED_FINAL_STATE);
            break;
        }

    } while(0);

    // if an error occurred prior to the I2C master bus fence
    // being cleared, attempt to clear it prior to exit
    if (!rc.ok() && !i2cm_bus_fence_cleared)
    {
        // discard rc, return that of original fail
        fapi::ReturnCode rc_unused;
        FAPI_EXEC_HWP(rc_unused, proc_reset_i2cm_bus_fence, i_target);
    }

    // mark function entry
    FAPI_DBG("End");
    return rc;
}