// 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;
}
    fapi::ReturnCode mss_eff_config_thermal_powercurve(const fapi::Target & i_target_mba)
    {
	fapi::ReturnCode rc = fapi::FAPI_RC_SUCCESS;

	FAPI_INF("*** Running mss_eff_config_thermal_powercurve on %s ***",
		 i_target_mba.toEcmdString());

// other variables used in this function
	fapi::Target target_chip;
	uint8_t port;
	uint8_t dimm;
	uint8_t custom_dimm;
	uint8_t dimm_ranks_array[NUM_PORTS][NUM_DIMMS];
	uint32_t power_slope_array[NUM_PORTS][NUM_DIMMS];
	uint32_t power_int_array[NUM_PORTS][NUM_DIMMS];
	uint32_t power_slope2_array[NUM_PORTS][NUM_DIMMS];
	uint32_t power_int2_array[NUM_PORTS][NUM_DIMMS];
	uint32_t total_power_slope_array[NUM_PORTS][NUM_DIMMS];
	uint32_t total_power_int_array[NUM_PORTS][NUM_DIMMS];
	uint32_t total_power_slope2_array[NUM_PORTS][NUM_DIMMS];
	uint32_t total_power_int2_array[NUM_PORTS][NUM_DIMMS];
	uint32_t cdimm_master_power_slope;
	uint32_t cdimm_master_power_intercept;
	uint32_t cdimm_supplier_power_slope;
	uint32_t cdimm_supplier_power_intercept;
	uint32_t cdimm_master_total_power_slope = 0;
	uint32_t cdimm_master_total_power_intercept = 0;
	uint32_t cdimm_supplier_total_power_slope = 0;
	uint32_t cdimm_supplier_total_power_intercept = 0;
	uint8_t l_dram_gen;
	uint8_t l_logged_error_power_curve = 0;
	uint8_t l_logged_error_total_power_curve = 0;
//------------------------------------------------------------------------------
// Get input attributes
//------------------------------------------------------------------------------

// Get Centaur target for the given MBA
	rc = fapiGetParentChip(i_target_mba, target_chip);
	if (rc) {
	    FAPI_ERR("Error from fapiGetParentChip");
	    return rc;
	}

	rc = FAPI_ATTR_GET(ATTR_EFF_CUSTOM_DIMM, &i_target_mba, custom_dimm);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_EFF_CUSTOM_DIMM");
	    return rc;
	}
	rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM,
			   &i_target_mba, dimm_ranks_array);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_EFF_NUM_RANKS_PER_DIMM");
	    return rc;
	}
	rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_GEN,
			   &i_target_mba, l_dram_gen);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_EFF_DRAM_GEN");
	    return rc;
	}
	// Only get power curve values for custom dimms to prevent errors
	if (custom_dimm == fapi::ENUM_ATTR_EFF_CUSTOM_DIMM_YES)
	{
	    // These are the CDIMM power curve values for only VMEM (DDR3 and DDR4)
	    rc = FAPI_ATTR_GET(ATTR_CDIMM_VPD_MASTER_POWER_SLOPE,
			       &target_chip, cdimm_master_power_slope);
	    if (rc) {
		FAPI_ERR("Error getting attribute ATTR_CDIMM_VPD_MASTER_POWER_SLOPE");
		return rc;
	    }
	    rc = FAPI_ATTR_GET(ATTR_CDIMM_VPD_MASTER_POWER_INTERCEPT,
			       &target_chip, cdimm_master_power_intercept);
	    if (rc) {
		FAPI_ERR("Error getting attribute ATTR_CDIMM_VPD_MASTER_POWER_INTERCEPT");
		return rc;
	    }

	    rc = FAPI_ATTR_GET(ATTR_CDIMM_VPD_SUPPLIER_POWER_SLOPE,
			       &target_chip, cdimm_supplier_power_slope);
	    if (rc) {
		FAPI_ERR("Error getting attribute ATTR_CDIMM_VPD_SUPPLIER_POWER_SLOPE");
		return rc;
	    }
	    rc = FAPI_ATTR_GET(ATTR_CDIMM_VPD_SUPPLIER_POWER_INTERCEPT,
			       &target_chip, cdimm_supplier_power_intercept);
	    if (rc) {
		FAPI_ERR("Error getting attribute ATTR_CDIMM_VPD_SUPPLIER_POWER_INTERCEPT");
		return rc;
	    }

	    // These are for the total CDIMM power (VMEM+VPP for DDR4)
	    if (l_dram_gen == fapi::ENUM_ATTR_EFF_DRAM_GEN_DDR4)
	    {

		rc = FAPI_ATTR_GET(ATTR_CDIMM_VPD_MASTER_TOTAL_POWER_SLOPE,
				   &target_chip, cdimm_master_total_power_slope);
		if (rc) {
		    FAPI_ERR("Error getting attribute ATTR_CDIMM_VPD_MASTER_TOTAL_POWER_SLOPE");
		    return rc;
		}
		rc = FAPI_ATTR_GET(ATTR_CDIMM_VPD_MASTER_TOTAL_POWER_INTERCEPT,
				   &target_chip, cdimm_master_total_power_intercept);
		if (rc) {
		    FAPI_ERR("Error getting attribute ATTR_CDIMM_VPD_MASTER_TOTAL_POWER_INTERCEPT");
		    return rc;
		}

		rc = FAPI_ATTR_GET(ATTR_CDIMM_VPD_SUPPLIER_TOTAL_POWER_SLOPE,
				   &target_chip, cdimm_supplier_total_power_slope);
		if (rc) {
		    FAPI_ERR("Error getting attribute ATTR_CDIMM_VPD_SUPPLIER_TOTAL_POWER_SLOPE");
		    return rc;
		}
		rc = FAPI_ATTR_GET(ATTR_CDIMM_VPD_SUPPLIER_TOTAL_POWER_INTERCEPT,
				   &target_chip, cdimm_supplier_total_power_intercept);
		if (rc) {
		    FAPI_ERR("Error getting attribute ATTR_CDIMM_VPD_SUPPLIER_TOTAL_POWER_INTERCEPT");
		    return rc;
		}
	    }
	    else
	    {
// Set total power curve variables to the VMEM power curve variables for DDR3
		cdimm_master_total_power_slope = cdimm_master_power_slope;
		cdimm_master_total_power_intercept = cdimm_master_power_intercept;
		cdimm_supplier_total_power_slope = cdimm_supplier_power_slope;
		cdimm_supplier_total_power_intercept = cdimm_supplier_power_intercept;
	    }
	}

//------------------------------------------------------------------------------
// Power Curve Determination
//------------------------------------------------------------------------------
// Iterate through the MBA ports to get power slope/intercept values
	for (port=0; port < NUM_PORTS; port++)
	{
// iterate through the dimms on each port again to determine power slope and
// intercept
	    for (dimm=0; dimm < NUM_DIMMS; dimm++)
	    {
// initialize dimm entries to zero
		power_slope_array[port][dimm] = 0;
		power_int_array[port][dimm] = 0;
		power_slope2_array[port][dimm] = 0;
		power_int2_array[port][dimm] = 0;
		total_power_slope_array[port][dimm] = 0;
		total_power_int_array[port][dimm] = 0;
		total_power_slope2_array[port][dimm] = 0;
		total_power_int2_array[port][dimm] = 0;
// only update values for dimms that are physically present
		if (dimm_ranks_array[port][dimm] > 0)
		{

// CDIMM power slope/intercept will come from VPD
// Data in VPD needs to be the power per virtual dimm on the CDIMM
		    if (custom_dimm == fapi::ENUM_ATTR_EFF_CUSTOM_DIMM_YES)
		    {
			power_slope_array[port][dimm] =
			  cdimm_master_power_slope;
			power_int_array[port][dimm] =
			  cdimm_master_power_intercept;
			power_slope2_array[port][dimm] =
			  cdimm_supplier_power_slope;
			power_int2_array[port][dimm] =
			  cdimm_supplier_power_intercept;
			total_power_slope_array[port][dimm] =
			  cdimm_master_total_power_slope;
			total_power_int_array[port][dimm] =
			  cdimm_master_total_power_intercept;
			total_power_slope2_array[port][dimm] =
			  cdimm_supplier_total_power_slope;
			total_power_int2_array[port][dimm] =
			  cdimm_supplier_total_power_intercept;

// check to see if VMEM power curve data is valid
			if (
			    (((cdimm_master_power_slope & 0x8000) != 0) &&
			     ((cdimm_master_power_intercept & 0x8000) != 0))
			    &&
			    (((cdimm_supplier_power_slope & 0x8000) != 0) &&
			     ((cdimm_supplier_power_intercept & 0x8000) != 0))
			    )
			{
			    power_slope_array[port][dimm] =
			      cdimm_master_power_slope & 0x1FFF;
			    power_int_array[port][dimm] =
			      cdimm_master_power_intercept & 0x1FFF;
			    power_slope2_array[port][dimm] =
			      cdimm_supplier_power_slope & 0x1FFF;
			    power_int2_array[port][dimm] =
			      cdimm_supplier_power_intercept & 0x1FFF;
// check to see if data is lab data
			    if (
				(((cdimm_master_power_slope & 0x4000) == 0) ||
				 ((cdimm_master_power_intercept & 0x4000) == 0))
				||
				(((cdimm_supplier_power_slope & 0x4000) == 0) ||
				 ((cdimm_supplier_power_intercept &
				   0x4000) == 0))
				)
			    {
				FAPI_INF("WARNING:  VMEM power curve data is lab data, not ship level data. Using data anyways.");
			    }
// check total power curve (VMEM+VPP) values for DDR4
			    if (l_dram_gen == fapi::ENUM_ATTR_EFF_DRAM_GEN_DDR4)
			    {
				if (
				    (((cdimm_master_total_power_slope & 0x8000) != 0) &&
				     ((cdimm_master_total_power_intercept & 0x8000) != 0))
				    &&
				    (((cdimm_supplier_total_power_slope & 0x8000) != 0) &&
				     ((cdimm_supplier_total_power_intercept & 0x8000) != 0))
				    )
				{
				    total_power_slope_array[port][dimm] =
				      cdimm_master_total_power_slope & 0x1FFF;
				    total_power_int_array[port][dimm] =
				      cdimm_master_total_power_intercept & 0x1FFF;
				    total_power_slope2_array[port][dimm] =
				      cdimm_supplier_total_power_slope & 0x1FFF;
				    total_power_int2_array[port][dimm] =
				      cdimm_supplier_total_power_intercept & 0x1FFF;
// check to see if data is lab data
				    if (
					(((cdimm_master_total_power_slope & 0x4000) == 0) ||
					 ((cdimm_master_total_power_intercept & 0x4000) == 0))
					||
					(((cdimm_supplier_total_power_slope & 0x4000) == 0) ||
					 ((cdimm_supplier_total_power_intercept &
					   0x4000) == 0))
					)
				    {
					FAPI_INF("WARNING:  Total power curve data is lab data, not ship level data. Using data anyways.");
				    }
				}
				else
				{
// Set to VMEM power curve values if total values are not valid and log an error
// early DDR4 CDIMMs will have the total power curve entries all zero (not valid)
				    total_power_slope_array[port][dimm] =
				      power_slope_array[port][dimm];
				    total_power_int_array[port][dimm] =
				      power_int_array[port][dimm];
				    total_power_slope2_array[port][dimm] =
				      power_slope2_array[port][dimm];
				    total_power_int2_array[port][dimm] =
				      power_int2_array[port][dimm];
// only log the error once per MBA, since all dimms will have the same power curve values
				    if (l_logged_error_total_power_curve == 0)
				    {
					l_logged_error_total_power_curve = 1;
					FAPI_ERR("Total power curve data not valid, use default values");
					const fapi::Target & MEM_CHIP =
					  target_chip;
					uint32_t FFDC_DATA_1 =
					  cdimm_master_total_power_slope;
					uint32_t FFDC_DATA_2 =
					  cdimm_master_total_power_intercept;
					uint32_t FFDC_DATA_3 =
					  cdimm_supplier_total_power_slope;
					uint32_t FFDC_DATA_4 =
					  cdimm_supplier_total_power_intercept;
					FAPI_SET_HWP_ERROR
					  (rc, RC_MSS_DIMM_POWER_CURVE_DATA_INVALID);
					if (rc) fapiLogError(rc);
				    }
				}
			    }
			    else
			    {
// Set total power curve values to VMEM power curve values for anything other than DDR4 (ie.  DDR3)
				total_power_slope_array[port][dimm] =
				  power_slope_array[port][dimm];
				total_power_int_array[port][dimm] =
				  power_int_array[port][dimm];
				total_power_slope2_array[port][dimm] =
				  power_slope2_array[port][dimm];
				total_power_int2_array[port][dimm] =
				  power_int2_array[port][dimm];
			    }
			}
			else
			{
// Set to default values and log an error if VMEM power curve values are not valid
			    power_slope_array[port][dimm] =
			      CDIMM_POWER_SLOPE_DEFAULT;
			    power_int_array[port][dimm] =
			      CDIMM_POWER_INT_DEFAULT;
			    power_slope2_array[port][dimm] =
			      CDIMM_POWER_SLOPE_DEFAULT;
			    power_int2_array[port][dimm] =
			      CDIMM_POWER_INT_DEFAULT;
			    total_power_slope_array[port][dimm] =
			      CDIMM_POWER_SLOPE_DEFAULT;
			    total_power_int_array[port][dimm] =
			      CDIMM_POWER_INT_DEFAULT;
			    total_power_slope2_array[port][dimm] =
			      CDIMM_POWER_SLOPE_DEFAULT;
			    total_power_int2_array[port][dimm] =
			      CDIMM_POWER_INT_DEFAULT;
// only log the error once per MBA, since all dimms will have the same power curve values
			    if (l_logged_error_power_curve == 0)
			    {
				l_logged_error_power_curve = 1;
				FAPI_ERR("VMEM power curve data not valid, use default values");
				const fapi::Target & MEM_CHIP =
				  target_chip;
				uint32_t FFDC_DATA_1 =
				  cdimm_master_power_slope;
				uint32_t FFDC_DATA_2 =
				  cdimm_master_power_intercept;
				uint32_t FFDC_DATA_3 =
				  cdimm_supplier_power_slope;
				uint32_t FFDC_DATA_4 =
				  cdimm_supplier_power_intercept;
				FAPI_SET_HWP_ERROR
				  (rc, RC_MSS_DIMM_POWER_CURVE_DATA_INVALID);
				if (rc) fapiLogError(rc);
			    }
			}
			FAPI_DBG("CDIMM VMEM Power [P%d:D%d][SLOPE=%d:INT=%d cW][SLOPE2=%d:INT2=%d cW]", port, dimm, power_slope_array[port][dimm], power_int_array[port][dimm], power_slope2_array[port][dimm], power_int2_array[port][dimm]);
			FAPI_DBG("CDIMM Total Power [P%d:D%d][VMEM SLOPE=%d:INT=%d cW][VMEM SLOPE2=%d:INT2=%d cW]", port, dimm, total_power_slope_array[port][dimm], total_power_int_array[port][dimm], total_power_slope2_array[port][dimm], total_power_int2_array[port][dimm]);
		    }
// non custom dimms will no longer use power curves
// These will use a simplified approach of using throttle values for certain ranges of power
// in mss_bulk_pwr_throttles.
		}
	    }
	}

// write output attributes
	rc = FAPI_ATTR_SET(ATTR_MSS_POWER_SLOPE,
			   &i_target_mba, power_slope_array);
	if (rc) {
	    FAPI_ERR("Error writing attribute ATTR_MSS_POWER_SLOPE");
	    return rc;
	}
	rc = FAPI_ATTR_SET(ATTR_MSS_POWER_INT, &i_target_mba, power_int_array);
	if (rc) {
	    FAPI_ERR("Error writing attribute ATTR_MSS_POWER_INT");
	    return rc;
	}

	rc = FAPI_ATTR_SET(ATTR_MSS_POWER_SLOPE2,
			   &i_target_mba, power_slope2_array);
	if (rc) {
	    FAPI_ERR("Error writing attribute ATTR_MSS_POWER_SLOPE2");
	    return rc;
	}
	rc = FAPI_ATTR_SET(ATTR_MSS_POWER_INT2,
			   &i_target_mba, power_int2_array);
	if (rc) {
	    FAPI_ERR("Error writing attribute ATTR_MSS_POWER_INT2");
	    return rc;
	}
	rc = FAPI_ATTR_SET(ATTR_MSS_TOTAL_POWER_SLOPE,
			   &i_target_mba, total_power_slope_array);
	if (rc) {
	    FAPI_ERR("Error writing attribute ATTR_MSS_TOTAL_POWER_SLOPE");
	    return rc;
	}
	rc = FAPI_ATTR_SET(ATTR_MSS_TOTAL_POWER_INT, &i_target_mba, total_power_int_array);
	if (rc) {
	    FAPI_ERR("Error writing attribute ATTR_MSS_TOTAL_POWER_INT");
	    return rc;
	}

	rc = FAPI_ATTR_SET(ATTR_MSS_TOTAL_POWER_SLOPE2,
			   &i_target_mba, total_power_slope2_array);
	if (rc) {
	    FAPI_ERR("Error writing attribute ATTR_MSS_TOTAL_POWER_SLOPE2");
	    return rc;
	}
	rc = FAPI_ATTR_SET(ATTR_MSS_TOTAL_POWER_INT2,
			   &i_target_mba, total_power_int2_array);
	if (rc) {
	    FAPI_ERR("Error writing attribute ATTR_MSS_TOTAL_POWER_INT2");
	    return rc;
	}

	FAPI_INF("*** mss_eff_config_thermal_powercurve COMPLETE on %s ***",
		 i_target_mba.toEcmdString());
	return rc;
    }
Beispiel #3
0
//******************************************************************************
// fapiGetOtherSideOfMemChannel function
//******************************************************************************
fapi::ReturnCode fapiGetOtherSideOfMemChannel(
    const fapi::Target& i_target,
    fapi::Target & o_target,
    const fapi::TargetState i_state)
{
    fapi::ReturnCode l_rc;
    TargetHandleList l_targetList;

    FAPI_DBG(ENTER_MRK "fapiGetOtherSideOfMemChannel. State: 0x%08x",
             i_state);

   TargetHandle_t   l_target =
          reinterpret_cast<TargetHandle_t>(i_target.get());

    if (l_target == NULL)
    {
        FAPI_ERR("fapiGetOtherSideOfMemChannel. Embedded NULL target pointer");
        /*@
         * @errortype
         * @moduleid     fapi::MOD_FAPI_GET_OTHER_SIDE_OF_MEM_CHANNEL
         * @reasoncode   fapi::RC_EMBEDDED_NULL_TARGET_PTR
         * @devdesc      Target has embedded null target pointer
         */
        const bool hbSwError = true;
        errlHndl_t l_pError = new ERRORLOG::ErrlEntry(
                    ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                    fapi::MOD_FAPI_GET_OTHER_SIDE_OF_MEM_CHANNEL,
                    fapi::RC_EMBEDDED_NULL_TARGET_PTR,
                    0, 0, hbSwError);

        // Attach the error log to the fapi::ReturnCode
        l_rc.setPlatError(reinterpret_cast<void *> (l_pError));
    }
    else if (i_target.getType() == fapi::TARGET_TYPE_MCS_CHIPLET)
    {
        // find the Centaur that is associated with this MCS
        getChildAffinityTargets(l_targetList, l_target,
                        CLASS_CHIP, TYPE_MEMBUF, false);

        if(l_targetList.size() != 1) // one and only one expected
        {
            FAPI_ERR("fapiGetOtherSideOfMemChannel. expect 1 Centaur %d",
                     l_targetList.size());
            /*@
             * @errortype
             * @moduleid     fapi::MOD_FAPI_GET_OTHER_SIDE_OF_MEM_CHANNEL
             * @reasoncode   fapi::RC_NO_SINGLE_MEMBUFF
             * @userdata1    Number of Memory Buffers
             * @userdata2    MCS HUID
             * @devdesc      fapiGetOtherSideOfMemChannel could not find exactly
             *               one target on the other side of the correct state
             */
            const bool hbSwError = true;
            errlHndl_t l_pError = new ERRORLOG::ErrlEntry(
                ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                fapi::MOD_FAPI_GET_OTHER_SIDE_OF_MEM_CHANNEL,
                fapi::RC_NO_SINGLE_MEMBUFF,
                l_targetList.size(),
                TARGETING::get_huid(l_target),
                hbSwError);

            // Attach the error log to the fapi::ReturnCode
            l_rc.setPlatError(reinterpret_cast<void *> (l_pError));

        }
        else
        {
            o_target.setType(fapi::TARGET_TYPE_MEMBUF_CHIP);
            o_target.set(reinterpret_cast<void *>(l_targetList[0]));
        }

    }
    else if (i_target.getType() == fapi::TARGET_TYPE_MEMBUF_CHIP)
    {
        // find the MCS that is associated with this Centaur
        getParentAffinityTargets (l_targetList, l_target,
                           CLASS_UNIT, TYPE_MCS, false);

        if(l_targetList.size() != 1) // one and only one expected
        {
            FAPI_ERR("fapiGetOtherSideOfMemChannel. expect 1 MCS %d",
                     l_targetList.size());
            /*@
             * @errortype
             * @moduleid     fapi::MOD_FAPI_GET_OTHER_SIDE_OF_MEM_CHANNEL
             * @reasoncode   fapi::RC_NO_SINGLE_MCS
             * @userdata1    Number of MCSs
             * @userdata2    Membuf HUID
             * @devdesc      fapiGetOtherSideOfMemChannel could not find exactly
             *               one target on the other side of the correct state
             */
            const bool hbSwError = true;
            errlHndl_t l_pError = new ERRORLOG::ErrlEntry(
                ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                fapi::MOD_FAPI_GET_OTHER_SIDE_OF_MEM_CHANNEL,
                fapi::RC_NO_SINGLE_MCS,
                l_targetList.size(),
                TARGETING::get_huid(l_target),
                hbSwError);

            // Attach the error log to the fapi::ReturnCode
            l_rc.setPlatError(reinterpret_cast<void *> (l_pError));
        }
        else
        {
            o_target.setType(fapi::TARGET_TYPE_MCS_CHIPLET);
            o_target.set(reinterpret_cast<void *>(l_targetList[0]));
        }

    }
    else
    {
      FAPI_ERR("fapiGetOtherSideOfMemChannel. target 0x%08x not supported",
                     i_target.getType());
        /*@
         * @errortype
         * @moduleid     fapi::MOD_FAPI_GET_OTHER_SIDE_OF_MEM_CHANNEL
         * @reasoncode   fapi::RC_UNSUPPORTED_REQUEST
         * @userdata1    Requested type
         * @userdata2    Unsupported Target HUID
         * @devdesc      fapiGetOtherSideOfMemChannel request for unsupported
         *               or invalid target type
         */
        const bool hbSwError = true;
        errlHndl_t l_pError = new ERRORLOG::ErrlEntry(
                ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                fapi::MOD_FAPI_GET_OTHER_SIDE_OF_MEM_CHANNEL,
                fapi::RC_UNSUPPORTED_REQUEST,
                i_target.getType(),
                TARGETING::get_huid(l_target),
                hbSwError);

        // Attach the error log to the fapi::ReturnCode
        l_rc.setPlatError(reinterpret_cast<void *> (l_pError));
    }

    if (!l_rc)  // OK so far, check that state is as requested 
    {
       HwasState l_state =
                l_targetList[0]->getAttr<ATTR_HWAS_STATE>();

       if (((i_state == fapi::TARGET_STATE_PRESENT) && !l_state.present) ||
           ((i_state == fapi::TARGET_STATE_FUNCTIONAL) && !l_state.functional))
       {
           FAPI_ERR("fapiGetOtherSideOfMemChannel. state mismatch");
           /*@
            * @errortype
            * @moduleid     fapi::MOD_FAPI_GET_OTHER_SIDE_OF_MEM_CHANNEL
            * @reasoncode   fapi::RC_STATE_MISMATCH
            * @userdata1    Requested state
            * @userdata2    Other Target HUID
            * @devdesc      fapiGetOtherSideOfMemChannel target not present or
            *               functional as requested
            */
           const bool hbSwError = true;
           errlHndl_t l_pError = new ERRORLOG::ErrlEntry(
                ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                fapi::MOD_FAPI_GET_OTHER_SIDE_OF_MEM_CHANNEL,
                fapi::RC_STATE_MISMATCH,
                i_state,
                TARGETING::get_huid(l_targetList[0]),
                hbSwError);

           // Attach the error log to the fapi::ReturnCode
           l_rc.setPlatError(reinterpret_cast<void *> (l_pError));
       }

    }

    FAPI_DBG(EXIT_MRK "fapiGetOtherSideOfMemChannel. rc = 0x%x",
           static_cast<uint32_t>(l_rc));

    return l_rc;
}
/// \retval PM_SUCCESS if something good happens,
/// \retval PM_PROCPM_SPCWKUP* otherwise
    fapi::ReturnCode
    p8_cpu_special_wakeup(  const fapi::Target& i_ex_target,
                            PROC_SPCWKUP_OPS i_operation ,
                            PROC_SPCWKUP_ENTITY i_entity )

    {
        fapi::ReturnCode    rc;
        fapi::ReturnCode    oha_rc;
        uint32_t            e_rc = 0;
        ecmdDataBufferBase  data(64);
        ecmdDataBufferBase  fsi_data(64);
        ecmdDataBufferBase  polldata(64);

        fapi::Target        l_parentTarget;
        uint8_t             attr_chip_unit_pos = 0;

        const char* PROC_SPCWKUP_ENTITY_NAMES[] =
        {
            "HOST",
            "FSP",
            "OCC",
            "PHYP",
            "SPW_ALL"
        };

        const char* PROC_SPCWKUP_OPS_NAMES[] =
        {
            "DISABLE",
            "ENABLE",
            "INIT"
        };

        uint32_t            special_wakeup_max_polls;

        /// Time (binary in milliseconds) for the first poll check (running/nap
        ///     case.
        ///    uint32_t special_wakeup_quick_poll_time = 1;

        ///  Get an attribute that defines the maximum special wake-up polling
        ///         timing (binary in milliseconds).
        ///  Increased timeout to 200ms - 6/10/13

        uint32_t            special_wakeup_timeout = 200;

        ///  Get an attribute that defines the special wake-up polling interval
        ///         (binary in milliseconds).
        uint32_t            special_wakeup_poll_interval = 5;

        uint32_t            pollcount = 0;
        uint32_t            count = 0;

        std::vector<fapi::Target>      l_chiplets;
        std::vector<Target>::iterator  itr;

        uint8_t             oha_spwkup_flag = 0;
        uint8_t             ignore_xstop_flag = 0;
        bool                poll_during_xstop_flag = false;
        bool                xstop_flag = false;
        bool                bSpwuSetOnEntry = false;

        uint8_t             inst_pm_state = INST_PM_STATE_UNDEFINED;

        //--------------------------------------------------------------------------
        // Read the counts of different ENTITY (FSP,OCC,PHYP) from the Attributes
        //--------------------------------------------------------------------------

        uint32_t            phyp_spwkup_count = 0;
        uint32_t            fsp_spwkup_count  = 0;
        uint32_t            occ_spwkup_count  = 0;

        uint64_t            spwkup_address  = 0;
        uint64_t            history_address  = 0;

        // detect AISS capaiblity
        uint8_t             chipHasAISSSWUP = 0;

        do
        {

            FAPI_INF("Executing p8_cpu_special_wakeup %s for %s ...",
                     PROC_SPCWKUP_OPS_NAMES[i_operation],
                     PROC_SPCWKUP_ENTITY_NAMES[i_entity]);

            // Initialize the attributes to 0.
            if (i_operation == SPCWKUP_INIT)
            {
                FAPI_INF("Processing target %s", i_ex_target.toEcmdString());
                FAPI_INF("Initializing ATTR_PM_SPWUP_FSP");
                rc = FAPI_ATTR_SET(ATTR_PM_SPWUP_FSP, &i_ex_target, fsp_spwkup_count);
                if (rc)
                {
                    FAPI_ERR("fapiSetAttribute of ATTR_PM_SPWUP_FSP with rc = 0x%x", (uint32_t)rc);
                    break ;
                }

                FAPI_INF("Initializing ATTR_PM_SPWUP_OCC");
                rc = FAPI_ATTR_SET(ATTR_PM_SPWUP_OCC, &i_ex_target, occ_spwkup_count);
                if (rc)
                {
                    FAPI_ERR("fapiSetAttribute of ATTR_PM_SPWUP_OCC with rc = 0x%x", (uint32_t)rc);
                    break;
                }

                FAPI_INF("Initializing ATTR_PM_SPWUP_PHYP");
                rc = FAPI_ATTR_SET(ATTR_PM_SPWUP_PHYP, &i_ex_target, phyp_spwkup_count);
                if (rc)
                {
                    FAPI_ERR("fapiSetAttribute of ATTR_PM_SPWUP_PHYP with rc = 0x%x", (uint32_t)rc);
                    break;
                }

                FAPI_INF("Initializing ATTR_PM_SPWUP_OHA_FLAG");
                rc = FAPI_ATTR_SET(ATTR_PM_SPWUP_OHA_FLAG, &i_ex_target, oha_spwkup_flag);
                if (rc)
                {
                    FAPI_ERR("fapiSetAttribute of ATTR_PM_SPWUP_OHA_FLAG with rc = 0x%x", (uint32_t)rc);
                    break;
                }

                FAPI_INF("Initializing ATTR_PM_SPWUP_IGNORE_XSTOP_FLAG");
                rc = FAPI_ATTR_SET(ATTR_PM_SPWUP_IGNORE_XSTOP_FLAG, &i_ex_target, ignore_xstop_flag);
                if (rc)
                {
                    FAPI_ERR("fapiSetAttribute of ATTR_PM_SPWUP_IGNORE_XSTOP_FLAG with rc = 0x%x", (uint32_t)rc);
                    break ;
                }

                // Leave the procedure
                break;
            }

            //--------------------------------------------------------------------------
            //           Checking the ENTITY who raised this OPERATION
            //--------------------------------------------------------------------------

            // Get the parent chip to target the registers
            rc = fapiGetParentChip(i_ex_target, l_parentTarget);
            if (rc)
            {
                break;    // throw error
            }

            // Get the core number
            rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_ex_target, attr_chip_unit_pos);
            if (rc)
            {
                FAPI_ERR("fapiGetAttribute of ATTR_CHIP_UNIT_POS with rc = 0x%x", (uint32_t)rc);
                break;
            }

            FAPI_DBG("Core number = %d", attr_chip_unit_pos);

            // Read the Attributes to know the Special_wake counts from each entity
            // This should be different for different EX chiplets.
            rc = FAPI_ATTR_GET(ATTR_PM_SPWUP_FSP, &i_ex_target, fsp_spwkup_count);
            if (rc)
            {
                FAPI_ERR("fapiGetAttribute of ATTR_PM_SPWUP_FSP with rc = 0x%x", (uint32_t)rc);
                break;
            }

            rc = FAPI_ATTR_GET(ATTR_PM_SPWUP_OCC, &i_ex_target, occ_spwkup_count );
            if (rc)
            {
                FAPI_ERR("fapiGetAttribute of ATTR_PM_SPWUP_OCC with rc = 0x%x", (uint32_t)rc);
                break;
            }

            rc = FAPI_ATTR_GET(ATTR_PM_SPWUP_PHYP,&i_ex_target , phyp_spwkup_count );
            if (rc)
            {
                FAPI_ERR("fapiGetAttribute of ATTR_PM_SPWUP_PHYP with rc = 0x%x", (uint32_t)rc);
                break;
            }

            /// Calculate the maximum number of polls until a timeout is thrown
            special_wakeup_max_polls = special_wakeup_timeout / special_wakeup_poll_interval;

            // Process counts based on the calling entity
            if (i_entity == OCC)
            {
                count = occ_spwkup_count ;
                FAPI_INF("OCC count before = %d" , count);
                spwkup_address = PM_SPECIAL_WKUP_OCC_0x100F010C;
                history_address = EX_PMSTATEHISTOCC_REG_0x100F0112;
            }
            else if (i_entity == FSP)
            {
                count = fsp_spwkup_count ;
                FAPI_INF("FSP count before = %d" , count);
                spwkup_address = PM_SPECIAL_WKUP_FSP_0x100F010B;
                history_address = EX_PMSTATEHISTFSP_REG_0x100F0111;
            }
            else if (i_entity == PHYP)
            {
                count = phyp_spwkup_count ;
                FAPI_INF("PHYP count before = %d" , count);
                spwkup_address = PM_SPECIAL_WKUP_PHYP_0x100F010D;
                history_address = EX_PMSTATEHISTPHYP_REG_0x100F0110;
            }
            else
            {
                FAPI_ERR("Unknown entity passed to proc_special_wakeup. Entity %x ....", i_entity);
                //    I_ENTITY = i_entity;
                PROC_SPCWKUP_ENTITY & I_ENTITY = i_entity ;
                FAPI_SET_HWP_ERROR(rc, RC_PROCPM_SPCWKUP_CODE_BAD_ENTITY);
                break;
            }

            /////////////////////////////////////////////////////////////////////////////
            //           Checking the type of OPERATION and process the request
            /////////////////////////////////////////////////////////////////////////////

            rc=fapiGetScom(i_ex_target, EX_PMGP0_0x100F0100, data);
            if(rc)
            {
                break;
            }

            if (i_operation == SPCWKUP_ENABLE)
            {

                // If the OHA flag is set, then any subsequent calls to the this
                // procedure must return a "good" response or else an infinite
                // loop results for any calling algorithm that first sets
                // special wake-up, does a SCOM, and then clears special
                // wake-up.
                rc = FAPI_ATTR_GET(   ATTR_PM_SPWUP_OHA_FLAG,
                                      &i_ex_target,
                                      oha_spwkup_flag);
                if (rc)
                {
                    FAPI_ERR("fapiGetAttribute of ATTR_PM_SPWUP_OHA_FLAG with rc = 0x%x", (uint32_t)rc);
                    break;
                }

                if (oha_spwkup_flag)
                {
                    FAPI_INF("OHA special wakeup flag is set so returning with good response to break recursion.  Counts are NOT updated.");
                    // This is a purposeful mid-procedure return
                    return rc;
                }

                // Determine if xstop checking should be ignored base on a caller
                // set attribute.
                //
                // This is used during MPIPL clean-up to a core to clear FIRs that
                // will eventually clear the xstop condition.  However, to do so
                // needs the xstop check to not keep the special wake-up operation
                // from happening.
                rc = FAPI_ATTR_GET(   ATTR_PM_SPWUP_IGNORE_XSTOP_FLAG,
                                      &i_ex_target,
                                      ignore_xstop_flag);
                if (rc)
                {
                    FAPI_ERR("fapiGetAttribute of ATTR_PM_SPWUP_IGNORE_XSTOP_FLAG with rc = 0x%x", (uint32_t)rc);
                    break ;
                }

                FAPI_INF("Ignore XSTOP:  %s", (ignore_xstop_flag ? "YES" : "NO"));

                // Read system checkstop indicator
                GETSCOM(rc, l_parentTarget, PCBMS_INTERRUPT_TYPE_REG_0x000F001A, data);

                if( data.isBitSet( 2 ) )
                {
                    FAPI_INF( "Checkstop present" );
                    xstop_flag = true;
                }

                // Error out if system is checkstopped and not told to ignore it
                if (!ignore_xstop_flag && xstop_flag)
                {
                    FAPI_ERR( "This chip is xstopped and the attribute ATTR_PM_SPWUP_IGNORE_XSTOP_FLAG is NOT set" );
                    const uint64_t& PCBSINTRTYPE = data.getDoubleWord(0);
                    const uint8_t & ATTRIGNOREXSTOP = ignore_xstop_flag;
                    const fapi::Target & EX_TARGET = i_ex_target;
                    FAPI_SET_HWP_ERROR(rc, RC_PROCPM_CHKSTOP);
                    break;
                }

                // Proceed
                FAPI_INF("Setting Special Wake-up  ...") ;

                if (count == 0)
                {

                    GETSCOM(rc, i_ex_target, spwkup_address, data);

                    //cmo-20140710: Make a note of spwu is already asserted.
                    if (data.isBitSet(0))
                        bSpwuSetOnEntry = true;   // Due to rogue direct hw access.
                    else
                        bSpwuSetOnEntry = false;  // Just goodness..

                    e_rc  = data.flushTo0();
                    e_rc |= data.setBit(0);
                    E_RC_CHECK(e_rc, rc);

                    PUTSCOM(rc, i_ex_target, spwkup_address, data);

                    // Determine whether to poll for completion of Special wake-up.
                    // Running and Nap - can alsways be polled as these are not
                    //      dependent on an xstop condition.
                    // Sleep and Winkle - poll only if not in an xstop condition

                    // Get the IPMS state
                    rc = ex_determine_inst_pm_state(i_ex_target, 10000, 1, inst_pm_state);
                    if (!rc.ok() && inst_pm_state!=INST_PM_STATE_UNRESOLVED)
                    {
                        FAPI_ERR("ex_determine_inst_pm_state() failed w/rc=0x%x", (uint32_t)rc);
                        break;
                    }
                    FAPI_DBG("IPMS State = 0x%x", inst_pm_state);

                    switch(inst_pm_state)
                    {
                    case  INST_PM_STATE_RUN :           // Running
                    case  INST_PM_STATE_RUN_OHA_ENTRY : // OHA purging idle entry
                    case  INST_PM_STATE_NAP_STATIC :    // Nap
                        poll_during_xstop_flag = true;
                        break;

                    default   :                         // Any other IPMS state
                        poll_during_xstop_flag = false;
                        break;
                    }

                    // Poll for completion if conditions are right
                    if ( (!xstop_flag) || (xstop_flag && poll_during_xstop_flag) )
                    {
                        // poll for the set completion
                        pollcount = 0;
                        e_rc=data.flushTo0();
                        E_RC_CHECK(e_rc, rc);

                        while (data.isBitClear(31) && pollcount < special_wakeup_max_polls)
                        {
                            GETSCOM(rc, i_ex_target, EX_PMGP0_0x100F0100, data);
                            FAPI_DBG("  Loop get for PMGP0(31) to goto 1          => 0x%016llx", data.getDoubleWord(0));

                            rc = fapiDelay(special_wakeup_poll_interval*1000, 1000000);
                            if (rc)
                            {
                                break;
                            }
                            pollcount ++ ;
                        }
                        if (!rc.ok())
                        {
                            break;
                        }


                        rc = FAPI_ATTR_GET(ATTR_CHIP_EC_FEATURE_AISS_SPECIAL_WAKEUP,
                                           &i_ex_target,
                                           chipHasAISSSWUP);
                        if (rc)
                        {
                            FAPI_ERR("Error querying Chip EC feature: "
                                     "ATTR_CHIP_EC_FEATURE_PCBS_ERR_RESET");
                            break;
                        }

                        FAPI_INF("AISS Special Wake-up fix is %sbeing performed",
                                 (chipHasAISSSWUP ? "NOT " : ""));


                        if (!chipHasAISSSWUP)
                        {
                            // Workaround for HW255321 start here
                            // at timeout time:
                            //  - check for existing external interrupts or malf alerts pending :     PMGP0 bit52
                            //     AND if OHA is in the AISS-FSM-state  P7_SEQ_WAIT_INT_PENDING EX_OHA_RO_STATUS_REG_0x1002000B
                            // If yes - then OHA hangs
                            // To leave this FSM state:
                            //   -  Set  Bit 9  of  OHA_ARCH_IDLE_STATE_REG(  RESET_IDLE_STATE_SEQUENCER).  EX_OHA_ARCH_IDLE_STATE_REG_RWx10020011
                            // This resets the idle sequencer and  force OHA into the DO_NOTHING_STATE ...should be completed in the next cycle
                            //
                            // Continue further down and check special_wakeup completion by checking bit31 of EX_PMGP0_0x100F0100
                            // If set then is OHA awake else error


                            GETSCOM(rc, i_ex_target, EX_PMGP0_0x100F0100, data);

                            if (data.isBitClear(31) && data.isBitSet(52) )
                            {
                                FAPI_DBG("Timed out setting Special wakeup with regular wake-up available, the logical OR of external interrupt and malfunction alert   ... ");
                                FAPI_DBG("Checking for Hang-Situation in AISS-FSM-State P7_SEQ_WAIT_INT_PENDING ... ");
                                FAPI_DBG("Special Wake-up Done NOT asserted (PMGP0(31,52)!! =>0x%016llx", data.getDoubleWord(0));

                                oha_spwkup_flag = 1;

                                rc = FAPI_ATTR_SET(ATTR_PM_SPWUP_OHA_FLAG, &i_ex_target, oha_spwkup_flag);
                                if (rc)
                                {
                                    FAPI_ERR("fapiSetAttribute of ATTR_PM_SPWUP_OHA_FLAG with rc = 0x%x", (uint32_t)rc);
                                    break;
                                }
                                FAPI_INF("Set OHA special wakeup flag");

                                // Check now if OHA is in the AISS-FSM-state  P7_SEQ_WAIT_INT_PENDING  EX_OHA_RO_STATUS_REG_0x1002000B  (bit 13-19) 0b0011100
                                GETSCOM(rc, i_ex_target, EX_OHA_RO_STATUS_REG_0x1002000B, data);

                                FAPI_DBG("\tCURRENT_AISS_FSM_STATE_VECTOR  (OHA_RO_STATUS(13:19) => 0x%016llx", data.getDoubleWord(0));

                                if (data.isBitClear(13) &&      // 0
                                        data.isBitClear(14) &&      // 0
                                        data.isBitSet(15)   &&      // 1
                                        data.isBitSet(16)   &&      // 1
                                        data.isBitSet(17)   &&      // 1
                                        data.isBitClear(18) &&      // 0
                                        data.isBitClear(19) )       // 0
                                {
                                    FAPI_DBG("OHA hanging in AISS-FSM-state P7_SEQ_WAIT_INT_PENDING (0b11100) (OHA_RO_STATUS_REG(13:19) => 0x%016llx", data.getDoubleWord(0));
                                    FAPI_DBG("Start reset of IDLE STATE SEQUENCER: Set OHA_ARCH_IDLE_STATE_REG(9)");

                                    GETSCOM(rc, i_ex_target, EX_OHA_ARCH_IDLE_STATE_REG_RWx10020011, data);
                                    FAPI_DBG("\tEX_OHA_ARCH_IDLE_STATE_REG_RWx10020011 : 0x%016llx", data.getDoubleWord(0));

                                    //Set RESET_IDLE_STATE_SEQUENCER  ... Bit 9 of OHA_ARCH_IDLE_STATE_REG
                                    e_rc=data.setBit(9);
                                    E_RC_CHECK(e_rc, rc);

                                    PUTSCOM(rc, i_ex_target, EX_OHA_ARCH_IDLE_STATE_REG_RWx10020011, data);

                                    // This resets the idle sequencer and force OHA into the
                                    // DO_NOTHING_STATE ... should be completed in the next
                                    // cycle since special wakeup is still asserted, OHA should
                                    // not leave the DO_NOTHING_STATE

                                    // Check again for AISS-FSM-state  P7_SEQ_WAIT_INT_PENDING  EX_OHA_RO_STATUS_REG_0x1002000B  (bit 13-19) 0b11100
                                    GETSCOM(rc, i_ex_target, EX_OHA_RO_STATUS_REG_0x1002000B, data);
                                    FAPI_DBG("\tCURRENT_AISS_FSM_STATE_VECTOR  (OHA_RO_STATUS(13:19) => 0x%016llx", data.getDoubleWord(0));

                                    // We're done accessing the OHA so clear the flag
                                    oha_spwkup_flag = 0;
                                    rc = FAPI_ATTR_SET(ATTR_PM_SPWUP_OHA_FLAG, &i_ex_target, oha_spwkup_flag);
                                    if (rc)
                                    {
                                        FAPI_ERR("fapiSetAttribute to clear ATTR_PM_SPWUP_OHA_FLAG with rc = 0x%x", (uint32_t)rc);
                                        // This is a purposeful mid-procedure return
                                        return rc;
                                    }
                                    FAPI_INF("Cleared OHA special wakeup flag");
                                }
                            }

                            // Check again if special_wakeup completed
                            GETSCOM(rc, i_ex_target, EX_PMGP0_0x100F0100, data);

                        }    // Workaround for HW255321 ends here

                        if (data.isBitClear(31))
                        {
                            FAPI_ERR("Timed out in setting the CPU in Special wakeup    ... ");

                            GETSCOM(rc, i_ex_target, EX_PMGP0_0x100F0100, data);
                            FAPI_DBG("Special Wake-up Done NOT asserted (PMGP0(31)!! =>0x%016llx", data.getDoubleWord(0));
                            const uint64_t& PMGP0 =  data.getDoubleWord(0);

                            // The following are put in the procedure (vs the XML) to capture
                            // for Cronus debug

                            GETSCOM(rc, i_ex_target, spwkup_address , data);
                            FAPI_DBG("  After set of SPWKUP_REG (0x%08llx) => 0x%016llx", spwkup_address, data.getDoubleWord(0));
                            const uint64_t& SP_WKUP_REG_ADDRESS = spwkup_address;
                            const uint64_t& SP_WKUP_REG_VALUE =  data.getDoubleWord(0);

                            GETSCOM(rc, i_ex_target, history_address , data);
                            FAPI_DBG("  History addreess (0x%08llx) => 0x%016llx", history_address, data.getDoubleWord(0));
                            const uint64_t& HISTORY_ADDRESS = history_address;
                            const uint64_t& HISTORY_VALUE =  data.getDoubleWord(0);

                            //cmo-20140710: We can't leave a latent spwu bit in 0x100f010b/c/d. Even though
                            //  we gave it a very long time to complete, we can't take the chance that it
                            //  fires later. So, lets clear it now. This will do no harm since the presumption
                            //  at this point, anyway, is that it failed and so therefore it should be cleared
                            //  too.
                            //  Note, we only want to do this for count=0 and if bSpwuSetOnEntry==false as
                            //  this would be an indication that we, right now, just asserted the spwu
                            //  from a deasserted state. Therefore, we can safely also deassert it.
                            //  Question is though, do we also wanna do the following if count>0, which
                            //  would be a pretty messed up situation?
                            if (!bSpwuSetOnEntry)
                            {
                                e_rc=data.flushTo0();
                                E_RC_CHECK(e_rc, rc);
                                PUTSCOM(rc, i_ex_target, spwkup_address , data);
                                FAPI_DBG("  Clearing SPWKUP_REG (0x%08llx) => 0x%016llx", spwkup_address, data.getDoubleWord(0));
                                GETSCOM(rc, i_ex_target, spwkup_address , data);
                                FAPI_DBG("  After read (delay) of SPWKUP_REG (0x%08llx) 0x%016llx", spwkup_address, data.getDoubleWord(0));
                            }

                            const uint64_t& POLLCOUNT =  (uint64_t)pollcount;
                            const uint64_t& EX =  (uint64_t)attr_chip_unit_pos;
                            const uint64_t& ENTITY =  (uint64_t)i_entity;
                            PROC_SPCWKUP_OPS& I_OPERATION = i_operation ;

                            const fapi::Target & EX_IN_ERROR = i_ex_target;
                            const fapi::Target & CHIP = l_parentTarget;

                            FAPI_SET_HWP_ERROR(rc, RC_PROCPM_SPCWKUP_TIMEOUT);
                            break;

                        }
                        else
                        {
                            count++ ;
                            FAPI_INF("Special wakeup done is set.  SUCCESS!  ... ");
                        }
                    }  // Done checking
                    else
                    {
                        FAPI_INF("Special wakeup with a checkstop active was attempted to a chiplet in an idle state that cannot succeed");
                        const fapi::Target & EX_TARGET = i_ex_target;
                        FAPI_SET_HWP_ERROR(rc, RC_PROCPM_SPCWKUP_SLW_IN_CHKSTOP);
                        break;
                    }
                }
                // Count > 0
                else
                {
                    // Check that we really are in special wakeup.
                    // If not, the counts are messed up
                    GETSCOM(rc, i_ex_target, EX_PMGP0_0x100F0100, data);
                    if (data.isBitSet(31))
                    {
                        count++ ;
                    }
                    else
                    {
                        FAPI_ERR("Enabling special wakeup failed.");
                        FAPI_ERR("--> Reason is that %s COUNT > 0 but PMGP0(31) is not set", PROC_SPCWKUP_ENTITY_NAMES[i_entity]);
                        FAPI_ERR("  FSP_COUNT = %d , OCC_COUNT = %d , PHYP_COUNT = %d ", fsp_spwkup_count ,occ_spwkup_count ,phyp_spwkup_count);
                        const fapi::Target & EX_TARGET = i_ex_target;
                        const uint64_t & PMGP0 = data.getDoubleWord(0);
                        const uint32_t & ENTITY_COUNT = count;
                        const PROC_SPCWKUP_ENTITY & I_ENTITY = i_entity ;
                        FAPI_SET_HWP_ERROR( rc, RC_PROCPM_SPCWKUP_NOT_SET);
                        break;
                    }
                }
            }
            else if (i_operation == SPCWKUP_DISABLE)
            {

                FAPI_INF("Clearing Special Wake-up...");

                // If the OHA flag is set, then any subsequent calls to the this
                // procedure must return a "good" response or elso an infinite
                // loop results for any calling algorithm that first sets
                // special wake-up, does a SCOM, and then clears special
                // wake-up.

                rc = FAPI_ATTR_GET(ATTR_PM_SPWUP_OHA_FLAG, &i_ex_target, oha_spwkup_flag);
                if (rc)
                {
                    FAPI_ERR("fapiGetAttribute of ATTR_PM_SPWUP_OHA_FLAG with rc = 0x%x", (uint32_t)rc);
                    break;
                }

                if (oha_spwkup_flag)
                {
                    FAPI_INF("OHA special wakeup flag is set so returning with good response to break recursion.  Counts are NOT updated.");
                    // This is a purposeful mid-procedure return
                    return rc;
                }


                if ( count == 1 )
                {
                    GETSCOM(rc, i_ex_target, spwkup_address , data);
                    FAPI_DBG("  Before clear of SPWKUP_REG (0x%08llx) => =>0x%016llx",  spwkup_address, data.getDoubleWord(0));

                    e_rc=data.flushTo0();
                    E_RC_CHECK(e_rc, rc);

                    PUTSCOM(rc, i_ex_target, spwkup_address , data);
                    FAPI_DBG("  After clear putscom of SPWKUP_REG (0x%08llx) => 0x%016llx", spwkup_address, data.getDoubleWord(0));

                    // This puts an inherent delay in the propagation of the reset transition.
                    GETSCOM(rc, i_ex_target, spwkup_address , data);
                    FAPI_DBG("  After read (delay) of SPWKUP_REG (0x%08llx) 0x%016llx", spwkup_address, data.getDoubleWord(0));

                    count -- ;
                }
                else if ( count > 1 )
                {
                    FAPI_INF("Other processes have clear Special Wake-up pending.  Chiplet is still in Special Wake-up state.");
                    count -- ;
                }
                else // Equal 0
                {

                    // Check that we really are NOT in special wakeup.
                    // If not, clear that platform bit.  This can occur in Cronus startup
                    GETSCOM(rc, i_ex_target, spwkup_address , data);
                    FAPI_DBG("  Checking of SPWKUP_REG disable (0x%08llx) => =>0x%016llx",  spwkup_address, data.getDoubleWord(0));

                    if (data.isBitSet(0))
                    {
                        e_rc=data.flushTo0();
                        E_RC_CHECK(e_rc, rc);

                        PUTSCOM(rc, i_ex_target, spwkup_address , data);
                        FAPI_DBG("  Clearing SPWKUP_REG (0x%08llx) => 0x%016llx", spwkup_address, data.getDoubleWord(0));

                        // This puts an inherent delay in the propagation of the reset transition.
                        GETSCOM(rc, i_ex_target, spwkup_address , data);
                        FAPI_DBG("  After read (delay) of SPWKUP_REG (0x%08llx) 0x%016llx", spwkup_address, data.getDoubleWord(0));
                    }
                }

                GETSCOM(rc, i_ex_target, spwkup_address , data);
                FAPI_DBG("  After configuring  SPWKUP_REG value     =>0x%016llx", data.getDoubleWord(0));

            }
            else if (i_operation == SPCWKUP_FORCE_DEASSERT)
            {

                GETSCOM(rc, i_ex_target, spwkup_address , data);
                FAPI_DBG("  Before clear of SPWKUP_REG (0x%08llx) => =>0x%016llx",  spwkup_address, data.getDoubleWord(0));

                e_rc=data.flushTo0();
                E_RC_CHECK(e_rc, rc);

                PUTSCOM(rc, i_ex_target, spwkup_address , data);
                FAPI_DBG("  After clear putscom of SPWKUP_REG (0x%08llx) => 0x%016llx", spwkup_address, data.getDoubleWord(0));

                // This puts an inherent delay in the propagation of the reset transition.
                GETSCOM(rc, i_ex_target, spwkup_address , data);
                FAPI_DBG("  After read (delay) of SPWKUP_REG (0x%08llx) 0x%016llx", spwkup_address, data.getDoubleWord(0));

                count = 0;
            }
            else
            {
                FAPI_ERR("ENABLE, DISABLE or INIT must be specified. Operation %x", i_operation );
                PROC_SPCWKUP_OPS & I_OPERATION = i_operation ;
                FAPI_SET_HWP_ERROR(rc, RC_PROCPM_SPCWKUP_CODE_BAD_OP);
                break;
            }

            /////////////////////////////////////////////////
            // Update the attributes
            /////////////////////////////////////////////////

            if ( i_entity == OCC )
            {
                occ_spwkup_count  = count ;
                rc = FAPI_ATTR_SET(ATTR_PM_SPWUP_OCC, &i_ex_target, occ_spwkup_count );
                if (rc)
                {
                    FAPI_ERR("fapiSetAttribute of ATTR_PM_SPWUP_OCC with rc = 0x%x", (uint32_t)rc);
                    break;
                }
            }
            else if (i_entity == FSP)
            {
                fsp_spwkup_count = count ;
                rc = FAPI_ATTR_SET(ATTR_PM_SPWUP_FSP, &i_ex_target, fsp_spwkup_count );
                if (rc)
                {
                    FAPI_ERR("fapiSetAttribute of ATTR_PM_SPWUP_FSP with rc = 0x%x", (uint32_t)rc);
                    break;
                }
            }
            else if (i_entity == PHYP)
            {
                phyp_spwkup_count = count;
                rc = FAPI_ATTR_SET(ATTR_PM_SPWUP_PHYP, &i_ex_target, phyp_spwkup_count );
                if (rc)
                {
                    FAPI_ERR("fapiSetAttribute of ATTR_PM_SPWUP_PHYP with rc = 0x%x", (uint32_t)rc);
                    break;
                }
            }

            FAPI_INF ("  FSP_COUNT = %d , OCC_COUNT = %d , PHYP_COUNT = %d ", fsp_spwkup_count ,occ_spwkup_count ,phyp_spwkup_count);


        } while (0);

        // Clean up the OHA flag as it should not be set out of this exit (normal
        // and error) path.  Note:  there is ia mid-procedure return above.
        oha_rc = FAPI_ATTR_GET(ATTR_PM_SPWUP_OHA_FLAG, &i_ex_target, oha_spwkup_flag);
        if (oha_rc)
        {
            FAPI_ERR("fapiGetAttribute of ATTR_PM_SPWUP_OHA_FLAG with rc = 0x%x", (uint32_t)oha_rc);
        }
        else
        {
            if (oha_spwkup_flag)
            {
                oha_spwkup_flag = 0;

                oha_rc = FAPI_ATTR_SET(ATTR_PM_SPWUP_OHA_FLAG, &i_ex_target, oha_spwkup_flag);
                if (oha_rc)
                {
                    FAPI_ERR("fapiSetAttribute of ATTR_PM_SPWUP_OHA_FLAG with rc = 0x%x", (uint32_t)oha_rc);
                }

                FAPI_ERR("Clearing OHA flag attribute upon procedure exit.  This is NOT expected");
                PROC_SPCWKUP_OPS& I_OPERATION = i_operation ;
                const uint64_t& EX =  (uint64_t)attr_chip_unit_pos;
                const uint64_t& ENTITY =  (uint64_t)i_entity;
                const uint64_t& PHYP_SPCWKUP_COUNT = (uint64_t)phyp_spwkup_count;
                const uint64_t& FSP_SPCWKUP_COUNT  = (uint64_t)fsp_spwkup_count;
                const uint64_t& OCC_SPCWKUP_COUNT  = (uint64_t)occ_spwkup_count;
                FAPI_SET_HWP_ERROR(oha_rc, RC_PROCPM_SPCWKUP_OHA_FLAG_SET_ON_EXIT);
            }
        }

        // Exit with the proper return code.  rc has priority over oha_rc as it indicates
        // the first failure.
        if (!rc.ok())
        {
            return rc ;
        }
        else if (!oha_rc.ok())
        {
            return oha_rc ;
        }
        else
        {
            return rc;
        }
    }
Beispiel #5
0
/**
 * Trace PCBS FSMs for a given EX
 *
 * @param[in] i_target Chip target
 * @param[in] i_msg    String to put out in the trace
 *
 * @retval ECMD_SUCCESS
 */
fapi::ReturnCode
p8_pm_pcbs_fsm_trace  ( const fapi::Target& i_target,
                        uint32_t            i_ex_number,
                        const char *        i_msg)
{
    fapi::ReturnCode                rc;
    ecmdDataBufferBase              data(64);
    uint64_t                        address;
    uint8_t                         trace_en_flag = false;
    uint64_t                        ex_offset;

    do
    {
        rc = FAPI_ATTR_GET(ATTR_PM_PCBS_FSM_TRACE_EN, NULL, trace_en_flag);
        if (rc)
        {
            FAPI_ERR("fapiGetAttribute of ATTR_PM_PCBS_FSM_TRACE_EN with rc = 0x%x", (uint32_t)rc);
            break;
        }

        // If trace is not enabled, leave.
        if (!trace_en_flag)
        {
            break;
        }
    
        ex_offset = i_ex_number * 0x01000000;

        //  Note: i_msg is put on on each record to allow for trace "greps"
        //  so as to see the "big picture" across when

        //  ******************************************************************
        //  Read PCBS FSM Monitor0
        //  ******************************************************************
        address =  EX_PCBS_FSM_MONITOR1_REG_0x100F0170 + ex_offset;
        GETSCOM(rc, i_target, address, data);
        FAPI_INF("PCBS Monitor0 = 0x%016llX;  %s target:%s" ,
                                    data.getDoubleWord(0),
                                    i_msg,
                                    i_target.toEcmdString());

        //  ******************************************************************
        //  Read PCBS FSM Monitor1
        //  ******************************************************************
        address =  EX_PCBS_FSM_MONITOR2_REG_0x100F0171 + ex_offset;
        GETSCOM(rc, i_target, address, data);
        FAPI_INF("PCBS Monitor1 = 0x%016llX;  %s target:%s" ,
                                    data.getDoubleWord(0),
                                    i_msg,
                                    i_target.toEcmdString());

        //  ******************************************************************
        //  Read PCBS DPLL CPM PARM REG
        //  ******************************************************************
        address =  EX_DPLL_CPM_PARM_REG_0x100F0152 + ex_offset;
        GETSCOM(rc, i_target, address, data);
        FAPI_INF("DPLLC Monitor = 0x%016llX;  %s target:%s" ,
                                    data.getDoubleWord(0),
                                    i_msg,
                                    i_target.toEcmdString());

        //  ******************************************************************
        //  Read PCBS PMGP0
        //  ******************************************************************
        address =  EX_PMGP0_0x100F0100 + ex_offset;
        GETSCOM(rc, i_target, address, data);
        FAPI_INF("PMGP0 Monitor = 0x%016llX;  %s target:%s" ,
                                    data.getDoubleWord(0),
                                    i_msg,
                                    i_target.toEcmdString());

    } while(0);
    return rc;
}
Beispiel #6
0
//******************************************************************************
// fapiGetParentChip function
//******************************************************************************
fapi::ReturnCode fapiGetParentChip(
    const fapi::Target& i_chiplet,
    fapi::Target & o_chip)
{
    FAPI_DBG(ENTER_MRK "fapiGetParentChip");

    fapi::ReturnCode l_rc;

    // Extract the HostBoot Target pointer for the input chiplet
    TARGETING::Target * l_pChiplet =
        reinterpret_cast<TARGETING::Target*>(i_chiplet.get());

    // Check that the input target is a chiplet
    if (!i_chiplet.isChiplet())
    {
        FAPI_ERR("fapiGetParentChip. Input target type 0x%08x is not a chiplet",
                 i_chiplet.getType());

        /*@
         * @errortype
         * @moduleid     fapi::MOD_FAPI_GET_PARENT_CHIP
         * @reasoncode   fapi::RC_INVALID_REQUEST
         * @userdata1    Type of input target
         * @userdata2    Input Target HUID
         * @devdesc      fapiGetParentChip request for non-chiplet
         */
        const bool hbSwError = true;
        errlHndl_t l_pError = new ERRORLOG::ErrlEntry(
            ERRORLOG::ERRL_SEV_UNRECOVERABLE,
            fapi::MOD_FAPI_GET_PARENT_CHIP,
            fapi::RC_INVALID_REQUEST,
            i_chiplet.getType(),
            TARGETING::get_huid(l_pChiplet),
            hbSwError);

        // Attach the error log to the fapi::ReturnCode
        l_rc.setPlatError(reinterpret_cast<void *> (l_pError));
    }
    else
    {
        if (l_pChiplet == NULL)
        {
            /*@
             * @errortype
             * @moduleid     fapi::MOD_FAPI_GET_PARENT_CHIP
             * @reasoncode   fapi::RC_EMBEDDED_NULL_TARGET_PTR
             * @devdesc      Target has embedded null target pointer
             */
            const bool hbSwError = true;
            errlHndl_t l_pError = new ERRORLOG::ErrlEntry(
                ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                fapi::MOD_FAPI_GET_PARENT_CHIP,
                fapi::RC_EMBEDDED_NULL_TARGET_PTR,
                0, 0, hbSwError);

            // Attach the error log to the fapi::ReturnCode
            l_rc.setPlatError(reinterpret_cast<void *> (l_pError));
        }
        else
        {
            const TARGETING::Target * l_pChip =
                TARGETING::getParentChip(l_pChiplet);

            if (l_pChip == NULL)
            {
                FAPI_ERR("fapiGetParentChip. Parent not found");
                /*@
                 * @errortype
                 * @moduleid     fapi::MOD_FAPI_GET_PARENT_CHIP
                 * @reasoncode   fapi::RC_NO_SINGLE_PARENT
                 * @userdata1    Input Chiplet Target HUID
                 * @devdesc      fapiGetParentChip did not find one parent
                 */
                const bool hbSwError = true;
                errlHndl_t l_pError = new ERRORLOG::ErrlEntry(
                    ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                    fapi::MOD_FAPI_GET_PARENT_CHIP,
                    fapi::RC_NO_SINGLE_PARENT,
                    TARGETING::get_huid(l_pChiplet),
                    0, hbSwError);

                // Attach the error log to the fapi::ReturnCode
                l_rc.setPlatError(reinterpret_cast<void *> (l_pError));
            }
            else
            {
                // Set the output chip type
                if (l_pChip->getAttr<TARGETING::ATTR_TYPE>() ==
                    TARGETING::TYPE_PROC)
                {
                    o_chip.setType(fapi::TARGET_TYPE_PROC_CHIP);
                }
                else
                {
                    o_chip.setType(fapi::TARGET_TYPE_MEMBUF_CHIP);
                }

                // Set the output chip (platform specific) handle
                o_chip.set(reinterpret_cast<void *>
                    (const_cast<TARGETING::Target*>(l_pChip)));
            }
        }
    }

    FAPI_DBG(EXIT_MRK "fapiGetParentChip");
    return l_rc;
}
Beispiel #7
0
// HWP entry point, comments in header
fapi::ReturnCode proc_pcie_config(
    const fapi::Target & i_target)
{
    fapi::ReturnCode rc;
    uint8_t pcie_enabled;
    uint8_t num_phb;

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

    do
    {
        // check for supported target type
        if (i_target.getType() != fapi::TARGET_TYPE_PROC_CHIP)
        {
            FAPI_ERR("proc_pcie_config: Unsupported target type");
            const fapi::Target & TARGET = i_target;
            FAPI_SET_HWP_ERROR(rc, RC_PROC_PCIE_CONFIG_INVALID_TARGET);
            break;
        }

        // query PCIE partial good attribute
        rc = FAPI_ATTR_GET(ATTR_PROC_PCIE_ENABLE,
                           &i_target,
                           pcie_enabled);
        if (!rc.ok())
        {
            FAPI_ERR("proc_pcie_config: Error querying ATTR_PROC_PCIE_ENABLE");
            break;
        }

        // initialize PBCQ/AIB, configure PBCQ FIRs (only if partial good
        // atttribute is set)
        if (pcie_enabled == fapi::ENUM_ATTR_PROC_PCIE_ENABLE_ENABLE)
        {
            // determine PHB configuration
            rc = FAPI_ATTR_GET(ATTR_PROC_PCIE_NUM_PHB,
                               &i_target,
                               num_phb);
            if (!rc.ok())
            {
                FAPI_ERR("proc_pcie_config: Error from FAPI_ATTR_GET (ATTR_PROC_PCIE_NUM_PHB)");
                break;
            }

            rc = proc_pcie_config_pbcq(i_target);
            if (!rc.ok())
            {
                FAPI_ERR("proc_pcie_config: Error from proc_pcie_config_pbcq");
                break;
            }

            rc = proc_pcie_config_pbcq_fir(i_target, num_phb);
            if (!rc.ok())
            {
                FAPI_ERR("proc_pcie_config: Error from proc_pcie_config_pbcq_fir");
                break;
            }

            rc = proc_a_x_pci_dmi_pll_setup_unmask_lock(
                i_target,
                PCIE_CHIPLET_0x09000000);
            if (!rc.ok())
            {
                FAPI_ERR("proc_pcie_config: Error from proc_a_x_pci_dmi_pll_setup_unmask_lock");
                break;
            }
        }
        else
        {
            FAPI_DBG("proc_pcie_config: Skipping initialization (partial good)");
        }

    } while(0);

    // mark HWP exit
    FAPI_INF("proc_pcie_config: End");
    return rc;
}
fapi::ReturnCode parse_addr(const fapi::Target & i_target_mba,
                            char addr_string[],
                            uint8_t mr3_valid,
                            uint8_t mr2_valid,
                            uint8_t mr1_valid,
                            uint8_t l_dram_rows,
                            uint8_t l_dram_cols,
                            uint8_t l_addr_inter)
{
    fapi::ReturnCode rc;
    uint8_t i = MAX_ADDR_BITS;

    uint8_t l_slave_rank = 0;
    uint8_t l_value;
    uint32_t l_value32 = 0;
    uint32_t l_sbit, rc_num;
    uint32_t l_start = 0;
    uint32_t l_len = 0;
    uint64_t l_readscom_value = 0;
    uint64_t l_end = 0;
    uint64_t l_start_addr = 0;
    uint8_t l_value_zero = 0;
    uint8_t l_user_end_addr = 0;
    ecmdDataBufferBase l_data_buffer_64(64);
    ecmdDataBufferBase l_data_buffer_rd64(64);
    uint8_t l_attr_addr_mode = 0;
    uint8_t l_num_cols = 0;
    uint8_t l_num_rows = 0;

    rc = FAPI_ATTR_GET(ATTR_EFF_SCHMOO_ADDR_MODE, &i_target_mba, l_attr_addr_mode);
    if (rc) return rc;
    rc = FAPI_ATTR_GET(ATTR_MCBIST_ADDR_NUM_COLS, &i_target_mba, l_num_cols);
    if (rc) return rc;
    rc = FAPI_ATTR_GET(ATTR_MCBIST_ADDR_NUM_ROWS, &i_target_mba, l_num_rows);
    if (rc) return rc;

    if (l_num_cols == 0)
    {
        l_num_cols = l_dram_cols;
    }

    if (l_num_rows == 0)
    {
        l_num_rows = l_dram_rows;
    }

    //Set all the addr reg to 0
    //Define Custom String
    //Set all Params based on the string.
    rc_num = l_data_buffer_64.flushTo0();
    if (rc_num)
    {
        FAPI_ERR("Error in function  parse_addr:");
        rc.setEcmdError(rc_num);
        return rc;
    }

    l_sbit = 0;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c9, l_data_buffer_64);
    if (rc) return rc;
    rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
    if (rc_num)
    {
        FAPI_ERR("Error in function  parse_addr:");
        rc.setEcmdError(rc_num);
        return rc;
    }
    rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
    if (rc) return rc;
    i--;

    l_sbit = 54;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c8, l_data_buffer_64);
    if (rc) return rc;
    rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
    if (rc_num)
    {
        FAPI_ERR("Error in function  parse_addr:");
        rc.setEcmdError(rc_num);
        return rc;
    }
    rc = fapiPutScom(i_target_mba, 0x030106c8, l_data_buffer_64);
    if (rc) return rc;
    i--;

    ////FAPI_INF("Inside strcmp ba2");
    l_sbit = 48;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c8, l_data_buffer_64);
    if (rc) return rc;
    rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
    if (rc_num)
    {
        FAPI_ERR("Error in function  parse_addr:");
        rc.setEcmdError(rc_num);
        return rc;
    }
    rc = fapiPutScom(i_target_mba, 0x030106c8, l_data_buffer_64);
    if (rc) return rc;
    i--;

    ////FAPI_INF("Inside strcmp ba3");
    l_sbit = 42;
    l_value = i;
    //------- Enable these for DDR4 --- for now constant map to zero
    rc = fapiGetScom(i_target_mba, 0x030106c8, l_data_buffer_64);
    if (rc) return rc;
    //FAPI_INF("ba3 Invalid");
    rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
    if (rc_num)
    {
        FAPI_ERR("Error in function  parse_addr:");
        rc.setEcmdError(rc_num);
        return rc;
    }
    rc = fapiPutScom(i_target_mba, 0x030106c8, l_data_buffer_64);
    if (rc) return rc;
    i++;

    ////FAPI_INF("Inside strcmp mr3");
    l_sbit = 18;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c8, l_data_buffer_64);
    if (rc) return rc;
    if (mr3_valid == 1)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c8, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c8, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("mr3 Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp mr2");
    l_sbit = 12;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c8, l_data_buffer_64);
    if (rc) return rc;
    if (mr2_valid == 1)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        //FAPI_INF("Inside mr2 --- l_addr_inter");
        rc = fapiPutScom(i_target_mba, 0x030106c8, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c8, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("mr2 Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp mr1");
    l_sbit = 6;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c8, l_data_buffer_64);
    if (rc) return rc;
    if (mr1_valid == 1)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        //FAPI_INF("Inside mr1 --- l_addr_inter");
        rc = fapiPutScom(i_target_mba, 0x030106c8, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    else
    {
        rc_num =  l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c8, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("mr1 Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp mr0");
    l_sbit = 0;
    l_value = i;
    //------- Enable these for DDR4 --- for now constant map to zero
    rc = fapiGetScom(i_target_mba, 0x030106c8, l_data_buffer_64);
    if (rc) return rc;
    rc_num =  l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
    if (rc_num)
    {
        FAPI_ERR("Error in function  parse_addr:");
        rc.setEcmdError(rc_num);
        return rc;
    }
    rc = fapiPutScom(i_target_mba, 0x030106c8, l_data_buffer_64);
    if (rc) return rc;
    i++;
    ////FAPI_INF("Value of i = %d",i);
    //FAPI_INF("mr0 Invalid\n");

    ////FAPI_INF("Inside strcmp cl3");
    l_sbit = 42;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106cb, l_data_buffer_64);
    if (rc) return rc;
    rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
    if (rc_num)
    {
        FAPI_ERR("Error in function  parse_addr:");
        rc.setEcmdError(rc_num);
        return rc;
    }
    rc = fapiPutScom(i_target_mba, 0x030106cb, l_data_buffer_64);
    if (rc) return rc;
    i++;
    //FAPI_INF("col2 Invalid");
    ////FAPI_INF("Value of i = %d",i);
    ////FAPI_INF("Inside strcmp cl3");
    l_sbit = 36;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106cb, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_cols >= 1)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106cb, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106cb, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("Col 3 -- Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp cl4");
    l_sbit = 30;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106cb, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_cols >= 2)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106cb, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106cb, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("Col 4 -- Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp cl5");
    l_sbit = 24;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106cb, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_cols >= 3)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106cb, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106cb, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("Col 5 -- Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp cl6");
    l_sbit = 18;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106cb, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_cols >= 4)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106cb, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106cb, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("Col 6 -- Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp cl7");
    l_sbit = 12;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106cb, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_cols >= 5)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106cb, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num =  l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106cb, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("Col 7 -- Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp cl8");
    l_sbit = 6;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106cb, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_cols >= 6)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106cb, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106cb, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("Col 8 -- Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp cl9");
    l_sbit = 0;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106cb, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_cols >= 7)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106cb, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }

    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106cb, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("Col 9 -- Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp cl11");
    l_sbit = 54;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106ca, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_cols >= 11)
    {
        if (l_dram_cols >= 11)
        {
            rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
            if (rc_num)
            {
                FAPI_ERR("Error in function  parse_addr:");
                rc.setEcmdError(rc_num);
                return rc;
            }
            rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
            if (rc) return rc;
            //FAPI_DBG("%s: Inside l_dram_cols > 10");
            i--;
        }
        else
        {
            rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
            if (rc_num)
            {
                FAPI_ERR("Error in function  parse_addr:");
                rc.setEcmdError(rc_num);
                return rc;
            }
            rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
            if (rc) return rc;
            FAPI_DBG("%s:Col 11 -- Invalid", i_target_mba.toEcmdString());
            i++;
        }
    }
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("Col 11 -- Invalid");
        i++;
    }

    ////FAPI_INF("Value of i = %d",i);
    ////FAPI_INF("Inside strcmp cl13");
    l_sbit = 48;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106ca, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_cols >= 12)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("Col 13 Invalid");
        i++;
    }
    ////FAPI_INF("Value of i = %d",i);
    ////FAPI_INF("Inside strcmp r0");
    l_sbit = 42;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106ca, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_rows > 0)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("row 0 --  Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp r1");
    l_sbit = 36;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106ca, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_rows > 1)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("row 1 --  Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp r2");
    l_sbit = 30;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106ca, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_rows > 2)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("row 2 --  Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp r3");
    l_sbit = 24;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106ca, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_rows > 3)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("row 3 --  Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp r4");
    l_sbit = 18;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106ca, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_rows > 4)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("row 4 --  Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp r5");
    l_sbit = 12;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106ca, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_rows > 5)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("row 5 --  Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp r6");
    l_sbit = 6;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106ca, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_rows > 6)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("row 6 --  Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp r7");
    l_sbit = 0;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106ca, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_rows > 7)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106ca, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("row 7 --  Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp r8");
    l_sbit = 54;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c9, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_rows > 8)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("row 8 --  Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp r9");
    l_sbit = 48;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c9, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_rows > 9)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("row 9 --  Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp r10");
    l_sbit = 42;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c9, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_rows > 10)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("row 10 --  Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp r11");
    l_sbit = 36;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c9, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_rows > 11)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("row 11 --  Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp r12");
    l_sbit = 30;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c9, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_rows > 12)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("row 12 --  Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp r13");
    l_sbit = 24;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c9, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_rows > 13)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("row 13 --  Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp r14");
    l_sbit = 18;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c9, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_rows > 14)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    ////FAPI_INF("Value of i = %d",i);
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("row 14 --  Invalid");
        i++;
    }

    ////FAPI_INF("Inside strcmp r15");
    l_sbit = 12;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c9, l_data_buffer_64);
    if (rc) return rc;
    if (l_num_rows > 15)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    else
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        //FAPI_INF("row 15 --  Invalid");
        i++;
    }
    ////FAPI_INF("Value of i = %d",i);
    ////FAPI_INF("Inside strcmp r16 and l_dram_rows = %d",l_dram_rows);
    l_sbit = 6;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c9, l_data_buffer_64);
    if (rc) return rc;
    if (l_dram_rows >= 17)
    {
        rc_num = l_data_buffer_64.insertFromRight(l_value, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        i--;
    }
    else
    {
        ////FAPI_INF("r16 not used");
        rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        //FAPI_INF("Row 16 Invalid");
        rc = fapiPutScom(i_target_mba, 0x030106c9, l_data_buffer_64);
        if (rc) return rc;
        i++;
    }
    ////FAPI_INF("Value of i = %d",i);


    ////FAPI_INF("Inside strcmp sl2");
    l_sbit = 36;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c8, l_data_buffer_64);
    if (rc) return rc;
    //------- Enable these for later --- for now constant map to zero
    if (l_slave_rank == 0)
    {
        l_value = 0;
    }
    rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
    if (rc_num)
    {
        FAPI_ERR("Error in function  parse_addr:");
        rc.setEcmdError(rc_num);
        return rc;
    }
    rc = fapiPutScom(i_target_mba, 0x030106c8, l_data_buffer_64);
    if (rc) return rc;
    //FAPI_INF("sl2 Invalid");
    i++;
    ////FAPI_INF("Value of i = %d",i);
    ////FAPI_INF("Inside strcmp sl1");
    l_sbit = 30;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c8, l_data_buffer_64);
    if (rc) return rc;
    //------- Enable these for later --- for now constant map to zero
    if (l_slave_rank == 0)
    {
        l_value = 0;
    }
    rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
    if (rc_num)
    {
        FAPI_ERR("Error in function  parse_addr:");
        rc.setEcmdError(rc_num);
        return rc;
    }
    rc = fapiPutScom(i_target_mba, 0x030106c8, l_data_buffer_64);
    if (rc) return rc;
    i++;
    //FAPI_INF("sl1 Invalid");
    ////FAPI_INF("Value of i = %d",i);
    ////FAPI_INF("Inside strcmp sl0");
    l_sbit = 24;
    l_value = i;
    rc = fapiGetScom(i_target_mba, 0x030106c8, l_data_buffer_64);
    if (rc) return rc;
    //------- Enable these for later --- for now constant map to zero
    if (l_slave_rank == 0)
    {
        l_value = 0;
    }
    rc_num = l_data_buffer_64.insertFromRight(l_value_zero, l_sbit, 6);
    if (rc_num)
    {
        FAPI_ERR("Error in function  parse_addr:");
        rc.setEcmdError(rc_num);
        return rc;
    }
    rc = fapiPutScom(i_target_mba, 0x030106c8, l_data_buffer_64);
    if (rc) return rc;
    //FAPI_INF("sl0 Invalid");
    i++;
    ////FAPI_INF("Value of i = %d",i);

    //------ Setting Start and end addr counters

    //FAPI_INF("Debug - --------------- Setting Start and End Counters -----------\n");
    rc_num = l_data_buffer_rd64.flushTo0();
    if (rc_num)
    {
        FAPI_ERR("Error in function  parse_addr:");
        rc.setEcmdError(rc_num);
        return rc;
    }
    rc = fapiPutScom(i_target_mba, 0x030106d0, l_data_buffer_rd64);
    if (rc) return rc;
    l_value = i + 1;
    //FAPI_INF("Setting end_addr Value of i = %d",i);
    rc_num = l_data_buffer_rd64.flushTo0();

    //Calculate and set Valid bits for end_addr
    for (i = l_value; i <= 37; i++)
    {
        rc_num |= l_data_buffer_rd64.clearBit(i);
        rc_num |= l_data_buffer_rd64.setBit(i);
    }
    if (rc_num)
    {
        FAPI_ERR("Error in function  parse_addr:");
        rc.setEcmdError(rc_num);
        return rc;
    }

    l_readscom_value = l_data_buffer_rd64.getDoubleWord(0);

    rc = FAPI_ATTR_GET(ATTR_EFF_SCHMOO_ADDR_MODE, &i_target_mba, l_attr_addr_mode);
    if (rc) return rc;
    rc = FAPI_ATTR_GET(ATTR_MCBIST_START_ADDR, &i_target_mba, l_start_addr);
    if (rc) return rc;
    //FAPI_INF("User Defined ATTR - Start = %016llX",l_start_addr);
    rc = FAPI_ATTR_GET(ATTR_MCBIST_END_ADDR, &i_target_mba, l_end);
    if (rc) return rc;
    rc = FAPI_ATTR_GET(ATTR_MCBIST_RANK, &i_target_mba, l_user_end_addr);
    if (rc) return rc;

    if (l_user_end_addr == 1)
    {
        //Setting start and end Temp
        rc_num = l_data_buffer_rd64.setDoubleWord(0, l_start_addr);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106d0, l_data_buffer_rd64);
        if (rc) return rc;
        rc = fapiPutScom(i_target_mba, 0x030106d1, l_data_buffer_rd64);
        if (rc) return rc;

        rc_num = l_data_buffer_rd64.setDoubleWord(0, l_end);
        if (rc_num)
        {
            FAPI_ERR("Error in function  parse_addr:");
            rc.setEcmdError(rc_num);
            return rc;
        }
        rc = fapiPutScom(i_target_mba, 0x030106d2, l_data_buffer_rd64);
        if (rc) return rc;
        rc = fapiPutScom(i_target_mba, 0x030106d3, l_data_buffer_rd64);
        if (rc) return rc;
    }

    else
    {
        if (l_attr_addr_mode == 0)
        {
            //FAPI_INF("ATTR_EFF_SCHMOO_ADDR_MODE - %d ---- Few Address Mode --------",l_attr_addr_mode);
            l_sbit = 32;
            rc_num = l_data_buffer_rd64.flushTo0();
            l_start = 24;
            l_len = 8;
            l_value32 = 28;
            rc_num |= l_data_buffer_rd64.insert(l_value32, l_sbit, l_len,  l_start);
            l_readscom_value = 0x000003FFF8000000ull;
            rc_num |= l_data_buffer_rd64.setDoubleWord(0, l_readscom_value);
            if (rc_num)
            {
                FAPI_ERR("Error in function  parse_addr:");
                rc.setEcmdError(rc_num);
                return rc;
            }

            rc = fapiPutScom(i_target_mba, 0x030106d2, l_data_buffer_rd64);
            if (rc) return rc;
            rc = fapiPutScom(i_target_mba, 0x030106d3, l_data_buffer_rd64);
            if (rc) return rc;
            l_readscom_value = l_data_buffer_rd64.getDoubleWord(0);
            //FAPI_INF("Debug - Final End addr for 0x030106d2 = %016llX",l_readscom_value);
        }
        else if (l_attr_addr_mode == 1)
        {
            //FAPI_INF("ATTR_EFF_SCHMOO_ADDR_MODE - %d ---- QUARTER ADDRESSING Mode --------",l_attr_addr_mode);
            l_readscom_value = l_readscom_value >> 2;
            //FAPI_INF("Debug - Final End addr for 0x030106d2 = %016llX",l_readscom_value);
            rc_num = l_data_buffer_rd64.setDoubleWord(0, l_readscom_value);
            if (rc_num)
            {
                FAPI_ERR("Error in function  parse_addr:");
                rc.setEcmdError(rc_num);
                return rc;
            }
            rc = fapiPutScom(i_target_mba, 0x030106d2, l_data_buffer_rd64);
            if (rc) return rc;
            rc = fapiPutScom(i_target_mba, 0x030106d3, l_data_buffer_rd64);
            if (rc) return rc;
        }
        else if (l_attr_addr_mode == 2)
Beispiel #9
0
    /**
     * @brief Execute procedures and steps necessary
     *        to load OCC data in specified processor
     *
     * @param[in] i_target   Target proc to load
     * @param[in] i_homerVirtAddrBase Virtual
     *                       address of current
     *                       proc's HOMER
     * @param[in] i_homerPhysAddrBase Physical
     *                       address of current
     *                       proc's HOMER
     *
     * @return errlHndl_t  Error log image load failed
     */
     errlHndl_t loadOCC(TARGETING::Target* i_target,
                    uint64_t i_homerPhysAddr,
                    uint64_t i_homerVirtAddr,
                    uint64_t i_commonPhysAddr)
    {
        errlHndl_t  l_errl  =   NULL;
        TRACFCOMP( g_fapiTd,
                   ENTER_MRK"loadOCC" );
        do{
            // Remember where we put things
            if( i_target )
            {
                i_target->setAttr<ATTR_HOMER_PHYS_ADDR>(i_homerPhysAddr);
                i_target->setAttr<ATTR_HOMER_VIRT_ADDR>(i_homerVirtAddr);
            }
            // cast OUR type of target to a FAPI type of target.
            const fapi::Target l_fapiTarg(fapi::TARGET_TYPE_PROC_CHIP,
                    (const_cast<Target*>(i_target)));
            TRACFCOMP( g_fapiTd, "FapiTarget: %s",l_fapiTarg.toEcmdString());

            //==============================
            //Setup for OCC Load
            //==============================

            // BAR0 is the Entire HOMER (start of HOMER contains OCC base Image)
            // Bar size is in MB, obtained value of 4MB from Greg Still
            TRACUCOMP( g_fapiImpTd,
                       INFO_MRK"loadOCC: OCC Address: 0x%.8X, size=0x%.8X",
                       i_homerPhysAddr, VMM_HOMER_INSTANCE_SIZE_IN_MB);

            FAPI_INVOKE_HWP( l_errl,
                             p8_pba_bar_config,
                             l_fapiTarg,
                             0,
                             i_homerPhysAddr,
                             VMM_HOMER_INSTANCE_SIZE_IN_MB,
                             PBA_CMD_SCOPE_NODAL );

            if (l_errl)
            {
                TRACFCOMP( g_fapiImpTd,
                           ERR_MRK"loadOCC: Bar0 config failed!" );
                l_errl->collectTrace(FAPI_TRACE_NAME,256);
                l_errl->collectTrace(FAPI_IMP_TRACE_NAME,256);

                break;
            }

            // BAR1 is what OCC uses to talk to the Centaur
            // Bar size is in MB
            uint64_t centaur_addr =
              i_target->getAttr<ATTR_IBSCOM_PROC_BASE_ADDR>();
            FAPI_INVOKE_HWP( l_errl,
                             p8_pba_bar_config,
                             l_fapiTarg,
                             1,                                 //i_index
                             centaur_addr,                      //i_pba_bar_addr
                             (uint64_t)OCC_IBSCOM_RANGE_IN_MB,  //i_pba_bar_size
                             PBA_CMD_SCOPE_NODAL );             //i_pba_cmd_scope

            if ( l_errl )
            {
                TRACFCOMP( g_fapiImpTd,
                           ERR_MRK"loadOCC: Bar1 config failed!" );
                l_errl->collectTrace(FAPI_TRACE_NAME,256);
                l_errl->collectTrace(FAPI_IMP_TRACE_NAME,256);

                break;
            }

           // BAR3 is the OCC Common Area
           // Bar size is in MB, obtained value of 8MB from Tim Hallett
            TRACUCOMP( g_fapiImpTd,
                       INFO_MRK"loadOCC: OCC Common Addr: 0x%.8X,size=0x%.8X",
                       i_commonPhysAddr,VMM_OCC_COMMON_SIZE_IN_MB);

            FAPI_INVOKE_HWP( l_errl,
                             p8_pba_bar_config,
                             l_fapiTarg,
                             3,
                             i_commonPhysAddr,
                             VMM_OCC_COMMON_SIZE_IN_MB,
                             PBA_CMD_SCOPE_NODAL );

            if ( l_errl != NULL )
            {
                TRACFCOMP( g_fapiImpTd,
                           ERR_MRK"loadOCC: Bar3 config failed!" );
                l_errl->collectTrace(FAPI_TRACE_NAME,256);
                l_errl->collectTrace(FAPI_IMP_TRACE_NAME,256);

                break;
            }

            //==============================
            //Load the OCC HOMER image
            //==============================
            void* occVirt = reinterpret_cast<void *>(i_homerVirtAddr);
            l_errl = loadOCCImageToHomer( occVirt );
            if( l_errl != NULL )
            {
                TRACFCOMP(g_fapiImpTd,
                        ERR_MRK"loadOCC: loadOCCImageToHomer failed!");
                break;
            }
        }while(0);

        TRACFCOMP( g_fapiTd,
                   EXIT_MRK"loadOCC");

        return l_errl;

    }
  //------------------------------------------------------------------------------
  // name: proc_mpipl_chip_cleanup
  //------------------------------------------------------------------------------
  // purpose: 
  // To enable MCD recovery
  //
  // Note: PHBs are left in ETU reset state after executing proc_mpipl_nest_cleanup, which runs before this procedure.  PHYP releases PHBs from ETU reset post HostBoot IPL.
  //
  // SCOM regs
  //
  // 1) MCD even recovery control register
  // 0000000002013410 (SCOM)
  // bit 0 (MCD_REC_EVEN_ENABLE): 0 to 1 transition needed to start, reset to 0 at end of request.
  // bit 5 (MCD_REC_EVEN_REQ_PEND)
  //
  //
  // 2) MCD odd recovery control register
  // 0000000002013411 (SCOM)
  // bit 0 (MCD_REC_ODD_ENABLE): 0 to 1 transition needed to start, reset to 0 at end of request.
  // bit 5 (MCD_REC_ODD_REQ_PEND)
  //
  // 3) Clear PCI Nest FIR registers
  // 02012000 (SCOM) 
  // 02012400 (SCOM) 
  // 02012800 (SCOM) 
  //
  // parameters: 
  // 'i_target' is reference to chip target
  //
  // returns:
  // FAPI_RC_SUCCESS (success, MCD recovery enabled for odd and even slices)
  //
  // RC_MCD_RECOVERY_NOT_DISABLED_RC (MCD recovery for even or odd slice is not disabled; therefore can't re-enable MCD recovery)
  // (Note: refer to file eclipz/chips/p8/working/procedures/xml/error_info/proc_mpipl_chip_cleanup_errors.xml)
  // 
  // getscom/putscom fapi errors
  // fapi error assigned from eCMD function failure
  // 
  //------------------------------------------------------------------------------
  fapi::ReturnCode proc_mpipl_chip_cleanup(const fapi::Target &i_target){
    const char *procedureName = "proc_mpipl_chip_cleanup"; //Name of this procedure
    fapi::ReturnCode rc; //fapi return code value
    uint32_t rc_ecmd = 0;    //ecmd return code value
    const uint32_t data_size = 64; //Size of data buffer
    const int MAX_MCD_DIRS = 2; //Max of 2 MCD Directories (even and odd)
    ecmdDataBufferBase fsi_data[MAX_MCD_DIRS];
    const uint64_t ARY_MCD_RECOVERY_CTRL_REGS_ADDRS[MAX_MCD_DIRS] = {
      0x0000000002013410, //MCD even recovery control register address
      0x0000000002013411  //MCD odd recovery control register address
    };     
    const uint32_t MCD_RECOVERY_CTRL_REG_BIT_POS0 = 0; //Bit 0 of MCD even and odd recovery control regs
    const char *ARY_MCD_DIR_STRS[MAX_MCD_DIRS] = {
      "Even", //Ptr to char string "Even" for even MCD
      "Odd"   //Ptr to char string "Odd" for odd MCD
    }; 
    const int MAX_PHBS = 3;
    const uint64_t PCI_NEST_FIR_REG_ADDRS[MAX_PHBS] = {
      0x02012000,
      0x02012400,
      0x02012800
    };     
    
    do {
      //Set bit length for 64-bit buffers
      rc_ecmd = fsi_data[0].setBitLength(data_size);
      rc_ecmd |= fsi_data[1].setBitLength(data_size);
      if(rc_ecmd) {
        rc.setEcmdError(rc_ecmd);
        break;
      }
  
      //Verify MCD recovery was previously disabled for even and odd slices
      //If not, this is an error condition
      for (int counter = 0; counter < MAX_MCD_DIRS; counter++) {
        FAPI_DBG("Verifying MCD %s Recovery is disabled, target=%s", ARY_MCD_DIR_STRS[counter], i_target.toEcmdString());
        
        //Get data from MCD Even or Odd Recovery Ctrl reg
        rc = fapiGetScom(i_target, ARY_MCD_RECOVERY_CTRL_REGS_ADDRS[counter], fsi_data[counter]);
        if (!rc.ok()) {
          FAPI_ERR("%s: fapiGetScom error (addr: 0x%08llX), target=%s", procedureName, ARY_MCD_RECOVERY_CTRL_REGS_ADDRS[counter], i_target.toEcmdString());
          break;
        }
        
  
        //Check whether bit 0 is 0, meaning MCD recovery is disabled as expected
        if( fsi_data[counter].getBit(MCD_RECOVERY_CTRL_REG_BIT_POS0) ) {
          FAPI_ERR("%s: MCD %s Recovery not disabled as expected, target=%s", procedureName, ARY_MCD_DIR_STRS[counter], i_target.toEcmdString());
          const fapi::Target & CHIP_TARGET = i_target;
  	  const uint64_t & MCD_RECOV_CTRL_REG_ADDR = ARY_MCD_RECOVERY_CTRL_REGS_ADDRS[counter];
          ecmdDataBufferBase & MCD_RECOV_CTRL_REG_DATA = fsi_data[counter];
          FAPI_SET_HWP_ERROR(rc, RC_MPIPL_MCD_RECOVERY_NOT_DISABLED_RC);
          break;
        }
      }
      if(!rc.ok()) {
        break;
      }
  
      //Assert bit 0 of MCD Recovery Ctrl regs to enable MCD recovery
      for (int counter = 0; counter < MAX_MCD_DIRS; counter++) {
        FAPI_DBG("Enabling MCD %s Recovery, target=%s", ARY_MCD_DIR_STRS[counter], i_target.toEcmdString());
        
        //Assert bit 0 of MCD Even or Odd Recovery Control reg to enable recovery
        rc_ecmd = fsi_data[counter].setBit(MCD_RECOVERY_CTRL_REG_BIT_POS0 );
        if(rc_ecmd) {
          FAPI_ERR("%s: Error (%u) asserting bit pos %u in ecmdDataBufferBase that stores value of MCD %s Recovery Control reg (addr: 0x%08llX), target=%s", procedureName, rc_ecmd, MCD_RECOVERY_CTRL_REG_BIT_POS0, ARY_MCD_DIR_STRS[counter], ARY_MCD_RECOVERY_CTRL_REGS_ADDRS[counter], i_target.toEcmdString());
          rc.setEcmdError(rc_ecmd);
          break;
        }
        
        //Write data to MCD Even or Odd Recovery Control reg
        rc = fapiPutScom(i_target, ARY_MCD_RECOVERY_CTRL_REGS_ADDRS[counter], fsi_data[counter]);
        if (!rc.ok()) {
          FAPI_ERR("%s: fapiPutScom error (addr: 0x%08llX), target=%s", procedureName, ARY_MCD_RECOVERY_CTRL_REGS_ADDRS[counter], i_target.toEcmdString());
          break;
        }
      }
      if(!rc.ok()) {
        break;
      }
  
      // SW227429: clear PCI Nest FIR registers
      // hostboot is blindly sending EOIs in order to ensure no interrupts are pending when  PHYP starts up again
      // with ETU held in reset, these get trapped in PCI and force a freeze to occur (PCI Nest FIR(14))
      // clearing the FIR should remove the freeze condition
      rc_ecmd = fsi_data[0].flushTo0();
      if (rc_ecmd) {
        FAPI_ERR("%s: Error (%u) forming PCI Nest FIR clear data buffer, target=%s", procedureName, rc_ecmd, i_target.toEcmdString());
        rc.setEcmdError(rc_ecmd);
        break;
      }
      
      for (int counter = 0; counter < MAX_PHBS; counter++) {
        FAPI_DBG("Clearing PCI%d Nest FIR, target=%s", counter, i_target.toEcmdString());
        rc = fapiPutScom(i_target, PCI_NEST_FIR_REG_ADDRS[counter], fsi_data[0]);
        if (!rc.ok()) {
          FAPI_ERR("%s: fapiPutScom error (addr: 0x%08llX), target=%s", procedureName, PCI_NEST_FIR_REG_ADDRS[counter], i_target.toEcmdString());
          break;
        }
      }
    } while(0);

    FAPI_IMP("Exiting %s", procedureName);

    return rc;
  }
    /**
     * p8_pm_prep_for_reset Call underlying unit procedure to perform readiness for
     *          reinitialization of PM complex.
     *
     * @param[in] i_primary_chip_target   Primary Chip target which will be passed
     *        to all the procedures
     * @param[in] i_secondary_chip_target Secondary Chip target will be passed for
     *        pmc_init -reset only if it is DCM otherwise this should be NULL.
     * @param[in] i_mode (PM_RESET (hard - will kill the PMC);
     *                    PM_RESET_SOFT (will not fully reset the PMC))
     *
     * @retval ECMD_SUCCESS
     * @retval ERROR defined in xml
     */
    fapi::ReturnCode
    p8_pm_prep_for_reset(   const fapi::Target &i_primary_chip_target,
                            const fapi::Target &i_secondary_chip_target,
                            uint32_t            i_mode                  )
    {

        fapi::ReturnCode                rc;
        fapi::ReturnCode                rc_hold;
        uint32_t                        e_rc = 0;
        std::vector<fapi::Target>       l_exChiplets;
        ecmdDataBufferBase              data(64);
        ecmdDataBufferBase              mask(64);
        uint64_t                        address = 0;

        const char *        PM_MODE_NAME_VAR; // Defines storage for PM_MODE_NAME

        bool                            b_special_wakeup_pri = false;
        bool                            b_special_wakeup_sec = false;

        fapi::Target dummy;

        do
        {

            FAPI_INF("p8_pm_prep_for_reset start  ....");

            uint8_t ipl_mode = 0;
            rc = FAPI_ATTR_GET(ATTR_IS_MPIPL, NULL, ipl_mode);
            if (!rc.ok())
            {
                FAPI_ERR("fapiGetAttribute of ATTR_IS_MPIPL rc = 0x%x", (uint32_t)rc);
                break;
            }

            FAPI_INF("IPL mode = %s", ipl_mode ? "MPIPL" : "NORMAL");


            if (i_mode == PM_RESET)
            {
                FAPI_INF("Hard reset detected");
            }
            else if (i_mode == PM_RESET_SOFT)
            {
                FAPI_INF("Soft reset detected.  Idle functions will not be affected");
            }
            else
            {
                FAPI_ERR("Mode parameter value not supported: %u", i_mode);
                uint32_t & MODE = i_mode;
                FAPI_SET_HWP_ERROR(rc, RC_PROCPM_PREP_UNSUPPORTED_MODE_ERR);
                break;
            }

            if ( i_secondary_chip_target.getType() == TARGET_TYPE_NONE )
            {
                if ( i_primary_chip_target.getType() == TARGET_TYPE_NONE )
                {
                    FAPI_ERR("Set primay target properly for SCM " );
                    const fapi::Target PRIMARY_TARGET = i_primary_chip_target;
                    FAPI_SET_HWP_ERROR(rc, RC_PROCPM_PREP_TARGET_ERR);
                    break;
                }
                FAPI_INF("Running on SCM");
            }
            else
            {
                FAPI_INF("Running on DCM");
            }

            // ******************************************************************
            //  Clear the Deep Exit Masks to allow Special Wake-up to occur
            // ******************************************************************

            // Primary
            rc = clear_deep_exit_mask(i_primary_chip_target);
            if (rc)
            {
                FAPI_ERR("clear_deep_exit_mask: Failed for Primary Target %s",
                         i_primary_chip_target.toEcmdString());
                break;
            }

            // Secondary
            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {
                rc = clear_deep_exit_mask(i_secondary_chip_target);
                if (rc)
                {
                    FAPI_ERR("clear_deep_exit_mask: Failed for Secondary Target %s",
                             i_secondary_chip_target.toEcmdString());
                    break;
                }
            }


            //  ******************************************************************
            //  FSM trace
            //  ******************************************************************
            rc = p4rs_pcbs_fsm_trace (i_primary_chip_target, i_secondary_chip_target, "start of prep for reset");
            if (!rc.ok())
            {
                break;
            }

            //  ******************************************************************
            //  Put all EX chiplets in special wakeup
            //  *****************************************************************
            //  This is done before FIR masking to ensure that idle functions
            //  are properly monitored

            // Primary
            rc = special_wakeup_all (i_primary_chip_target, true);
            if (rc)
            {
                FAPI_ERR("special_wakeup_all - Enable: Failed for Target %s",
                         i_primary_chip_target.toEcmdString());
                break;
            }
            b_special_wakeup_pri = true;

            rc = p8_pm_glob_fir_trace (i_primary_chip_target, "after SPWKUP");
            if (!rc.ok()) {
                break;
            }

            // Secondary
            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {
                rc = special_wakeup_all (i_secondary_chip_target, true);
                if (rc)
                {
                    FAPI_ERR("special_wakeup_all - Enable: Failed for Target %s",
                             i_secondary_chip_target.toEcmdString());
                    break;
                }
                b_special_wakeup_sec = true;

                rc = p8_pm_glob_fir_trace (i_secondary_chip_target, "after SPWKUP");
                if (!rc.ok()) {
                    break;
                }

            }

            //  ******************************************************************
            //  FSM trace
            //  ******************************************************************
            rc = p4rs_pcbs_fsm_trace (i_primary_chip_target, i_secondary_chip_target,
                                      "after special wake-up setting");
            if (!rc.ok())
            {
                break;
            }

            //  ******************************************************************
            //  Mask the FIRs as error can occur in what follows
            //  ******************************************************************
            FAPI_INF("Executing:p8_pm_firinit in mode PM_RESET");

            FAPI_EXEC_HWP(rc, p8_pm_firinit, i_primary_chip_target , i_mode );
            if (rc)
            {
                FAPI_ERR("ERROR: p8_pm_firinit detected failed  result");
                break;
            }

            rc = p8_pm_glob_fir_trace (i_primary_chip_target, "after Masking");
            if (!rc.ok()) {
                break;
            }

            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {

                FAPI_EXEC_HWP(rc, p8_pm_firinit, i_secondary_chip_target , PM_RESET );
                if (rc)
                {
                    FAPI_ERR("ERROR: p8_pm_firinit detected failed  result");
                    break;
                }

                rc = p8_pm_glob_fir_trace (i_secondary_chip_target, "after Masking");
                if (!rc.ok()) {
                    break;
                }
            }

            //  ******************************************************************
            //  FSM trace
            //  ******************************************************************
            rc = p4rs_pcbs_fsm_trace (i_primary_chip_target, i_secondary_chip_target,
                                      "after FIR masking");
            if (!rc.ok())
            {
                break;
            }

            //  ******************************************************************
            //  Disable PMC OCC HEARTBEAT before reset OCC
            //  ******************************************************************
            // Primary
            rc = fapiGetScom(i_primary_chip_target, PMC_OCC_HEARTBEAT_REG_0x00062066 , data );
            if (rc)
            {
                FAPI_ERR("fapiGetScom(PMC_OCC_HEARTBEAT_REG_0x00062066) failed.");
                break;
            }

            e_rc = data.clearBit(16);
            if (e_rc)
            {
                FAPI_ERR("ecmdDataBufferBase error setting up PMC_OCC_HEARTBEAT_REG_0x00062066 on master during reset");
                rc.setEcmdError(e_rc);
                break;
            }

            rc = fapiPutScom(i_primary_chip_target, PMC_OCC_HEARTBEAT_REG_0x00062066 , data );
            if (rc)
            {
                FAPI_ERR("fapiPutScom(PMC_OCC_HEARTBEAT_REG_0x00062066) failed.");
                break;
            }

            // Secondary
            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {
                rc = fapiGetScom(i_secondary_chip_target, PMC_OCC_HEARTBEAT_REG_0x00062066 , data );
                if (rc)
                {
                    FAPI_ERR("fapiGetScom(PMC_OCC_HEARTBEAT_REG_0x00062066) failed.");
                    break;
                }

                e_rc = data.clearBit(16);
                if (e_rc)
                {
                    FAPI_ERR("ecmdDataBufferBase error setting up PMC_OCC_HEARTBEAT_REG_0x00062066 on slave during reset");
                    rc.setEcmdError(e_rc);
                    break;
                }

                rc = fapiPutScom(i_secondary_chip_target, PMC_OCC_HEARTBEAT_REG_0x00062066 , data );
                if (rc)
                {
                    FAPI_ERR("fapiPutScom(PMC_OCC_HEARTBEAT_REG_0x00062066) failed.");
                    break;
                }
            }

            //  ******************************************************************
            //  Put OCC PPC405 into reset safely
            //  ******************************************************************
            FAPI_INF("Put OCC PPC405 into reset safely");
            FAPI_DBG("Executing: p8_occ_control.C");

            FAPI_EXEC_HWP(rc, p8_occ_control, i_primary_chip_target, PPC405_RESET_SEQUENCE, 0);
            if (rc)
            {
                FAPI_ERR("p8_occ_control: Failed to prepare OCC for RESET. With rc = 0x%x", (uint32_t)rc);
                break;
            }

            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {
                FAPI_EXEC_HWP(rc, p8_occ_control, i_secondary_chip_target, PPC405_RESET_SEQUENCE, 0);
                if (rc)
                {
                    FAPI_ERR("p8_occ_control: Failed to prepare OCC for RESET. With rc = 0x%x", (uint32_t)rc);
                    break;
                }
            }

            //  ******************************************************************
            //  FSM trace
            //  ******************************************************************
            rc = p4rs_pcbs_fsm_trace (i_primary_chip_target, i_secondary_chip_target,
                                      "after OCC Reset");
            if (!rc.ok())
            {
                break;
            }

            //  Check for xstops and recoverables

            rc = p8_pm_glob_fir_trace (i_primary_chip_target, "after OCC Reset");
            if (!rc.ok()) {
                break;
            }

            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {
                rc = p8_pm_glob_fir_trace (i_secondary_chip_target, "after OCC Reset");
                if (!rc.ok()) {
                    break;
                }
            }

            //  ******************************************************************
            //  Force Vsafe value into voltage controller
            //  ******************************************************************
            FAPI_INF("Force Vsafe value into voltage controller");
            FAPI_DBG("Executing: p8_pmc_force_vsafe.C");

            // Primary
            //   Secondary passed in for FFDC reasons upon error
            FAPI_EXEC_HWP(rc, p8_pmc_force_vsafe, i_primary_chip_target, i_secondary_chip_target);
            if (rc)
            {
                FAPI_ERR("Failed to force Vsafe value into voltage controller. With rc = 0x%x", (uint32_t)rc);
                break;
            }

            // Secondary
            //   Primary passed in for FFDC reasons upon error
            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {
                FAPI_EXEC_HWP(rc, p8_pmc_force_vsafe, i_secondary_chip_target, i_primary_chip_target);
                if (rc)
                {
                    FAPI_ERR("Failed to force Vsafe value into voltage controller. With rc = 0x%x", (uint32_t)rc);
                    break;
                }
            }

            //  ******************************************************************
            //  FSM trace
            //  ******************************************************************
            rc = p4rs_pcbs_fsm_trace (i_primary_chip_target, i_secondary_chip_target,
                                      "after force Vsafe");
            if (!rc.ok())
            {
                break;
            }

            //  Check for xstops and recoverables
            rc = p8_pm_glob_fir_trace (i_primary_chip_target, "after Force Vsafe");
            if (!rc.ok()) {
                break;
            }

            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {
                rc = p8_pm_glob_fir_trace (i_secondary_chip_target, "after Force Vsafe");
                if (!rc.ok()) {
                    break;
                }
            }

            //  ******************************************************************
            //  Prepare PCBS_PM for RESET
            //  ******************************************************************
            //      - p8_pcbs_init internally loops over all enabled chiplets
            FAPI_INF("Prepare PCBSLV_PM for RESET");
            FAPI_DBG("Executing: p8_pcbs_init.C");

            // Primary
            FAPI_EXEC_HWP(rc, p8_pcbs_init, i_primary_chip_target, PM_RESET);
            if (rc)
            {
                FAPI_ERR("p8_pcbs_init: Failed to prepare PCBSLV_PM for RESET. With rc = 0x%x", (uint32_t)rc);
                break;
            }

            address =  READ_GLOBAL_RECOV_FIR_0x570F001C;
            GETSCOM(rc, i_primary_chip_target, address, data);
            if (data.getNumBitsSet(0,64))
            {
                FAPI_INF("Recoverable attention is **ACTIVE** in prep_for_reset after PCBS reset");
            }

            // Secondary
            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {

                FAPI_EXEC_HWP(rc, p8_pcbs_init, i_secondary_chip_target, PM_RESET);
                if (rc)
                {
                    FAPI_ERR("p8_pcbs_init: Failed to prepare PCBSLV_PM for RESET. With rc = 0x%x", (uint32_t)rc);
                    break;
                }

                GETSCOM(rc, i_secondary_chip_target, address, data);
                if (data.getNumBitsSet(0,64))
                {
                    FAPI_INF("Recoverable attention is **ACTIVE** in prep_for_reset after  PCBS reset");
                }
            }

            //  ******************************************************************
            //  FSM trace
            //  ******************************************************************
            rc = p4rs_pcbs_fsm_trace (i_primary_chip_target, i_secondary_chip_target, "after PCBS reset");
            if (!rc.ok())
            {
                break;
            }

            //  Check for xstops and recoverables
            rc = p8_pm_glob_fir_trace (i_primary_chip_target, "after PCBS reset");
            if (!rc.ok()) {
                break;
            }

            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {
                rc = p8_pm_glob_fir_trace (i_secondary_chip_target, "after PCBS reset");
                if (!rc.ok()) {
                    break;
                }
            }

            //  ******************************************************************
            //  Reset PMC
            //  ******************************************************************
            FAPI_INF("Issue reset to PMC");
            FAPI_DBG("Executing: p8_pmc_init");

            FAPI_EXEC_HWP(rc, p8_pmc_init, i_primary_chip_target, i_secondary_chip_target, i_mode);
            if (rc)
            {
                FAPI_ERR("p8_pmc_init: Failed to issue PMC reset. With rc = 0x%x", (uint32_t)rc);
                break;
            }

            //  ******************************************************************
            //  FSM trace
            //  ******************************************************************
            rc = p4rs_pcbs_fsm_trace (i_primary_chip_target, i_secondary_chip_target,
                                      "after PMC reset");
            if (!rc.ok())
            {
                break;
            }

            //  ******************************************************************
            //  As the PMC reset kills ALL of the configuration, the idle portion
            //  must be reestablished to allow that portion to operate.  This is
            //  what p8_poreslw_init -init does. Additionally, this lets us drop
            //  special wake-up  before exiting.
            //  ******************************************************************
            //     - call p8_poreslw_init.C *chiptarget, ENUM:PM_INIT
            //

            FAPI_INF("Re-establish PMC Idle configuration");
            FAPI_DBG("Executing: p8_poreslw_init in mode %s", PM_MODE_NAME(PM_INIT_PMC));

            // Primary
            FAPI_EXEC_HWP(rc, p8_poreslw_init, i_primary_chip_target, PM_INIT_PMC);
            if (rc)
            {
                FAPI_ERR("p8_poreslw_init: Failed to to reinialize the idle portion of the PMC. With rc = 0x%x", (uint32_t)rc);
                break;
            }

            // Secondary
            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {

                FAPI_EXEC_HWP(rc, p8_poreslw_init, i_secondary_chip_target, PM_INIT_PMC);
                if (rc)
                {
                    FAPI_ERR("p8_poreslw_init: Failed to to reinialize the idle portion of the PMC. With rc = 0x%x", (uint32_t)rc);
                    break;
                }
            }

            //  Check for xstops and recoverables
            rc = p8_pm_glob_fir_trace (i_primary_chip_target,  "after PMC and SLW reinit");
            if (!rc.ok()) {
                break;
            }

            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {
                rc = p8_pm_glob_fir_trace (i_secondary_chip_target,  "after PMC and SLW reinit");
                if (!rc.ok()) {
                    break;
                }
            }

            //  ******************************************************************
            //  Issue reset to PSS macro
            //  ******************************************************************
            FAPI_INF("Issue reset to PSS macro");
            FAPI_DBG("Executing: p8_pss_init.C");

            // Primary
            FAPI_EXEC_HWP(rc, p8_pss_init, i_primary_chip_target, PM_RESET);
            if (rc)
            {
                FAPI_ERR("p8_pss_init: Failed to issue reset to PSS macro. With rc = 0x%x", (uint32_t)rc);
                break;
            }

            // Secondary
            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {

                FAPI_DBG("FAPI_EXEC_HWP(rc, p8_pss_init, i_secondary_chip_target, PM_RESET);");

                FAPI_EXEC_HWP(rc, p8_pss_init, i_secondary_chip_target, PM_RESET);
                if (rc)
                {
                    FAPI_ERR("p8_pss_init: Failed to issue reset to PSS macro. With rc = 0x%x", (uint32_t)rc);
                    break;
                }
            }

            //  ******************************************************************
            //  Issue reset to PORE General Purpose Engine
            //  ******************************************************************
            FAPI_INF("Issue reset to PORE General Purpose Engine");
            FAPI_DBG("Executing: p8_poregpe_init.C");

            // Primary
            FAPI_EXEC_HWP(rc, p8_poregpe_init, i_primary_chip_target, PM_RESET, GPEALL );
            if (rc)
            {
                FAPI_ERR("p8_poregpe_init: Failed to issue reset to PORE General Purpose Engine. With rc = 0x%x", (uint32_t)rc);
                break;
            }

            // Secondary
            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {
                FAPI_EXEC_HWP(rc, p8_poregpe_init, i_secondary_chip_target, PM_RESET, GPEALL );
                if (rc)
                {
                    FAPI_ERR("p8_poregpe_init: Failed to issue reset to PORE General Purpose Engine. With rc = 0x%x", (uint32_t)rc);
                    break;
                }
            }

            //  ******************************************************************
            //  Issue reset to PBA
            //  ******************************************************************
            //  Note:  this voids the channel used by the SLW engine
            FAPI_INF("Issue reset to PBA");
            FAPI_DBG("Executing: p8_pba_init.C");

            // Primary
            FAPI_EXEC_HWP(rc, p8_pba_init, i_primary_chip_target, PM_RESET );
            if (rc)
            {
                FAPI_ERR("p8_pba_init: Failed to issue reset to PBA. With rc = 0x%x", (uint32_t)rc);
                break;
            }

            // Secondary
            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {
                FAPI_EXEC_HWP(rc, p8_pba_init, i_secondary_chip_target, PM_RESET );
                if (rc)
                {
                    FAPI_ERR("p8_pba_init: Failed to issue reset to PBA. With rc = 0x%x", (uint32_t)rc);
                    break;
                }
            }
            //  Check for xstops and recoverables
            rc = p8_pm_glob_fir_trace (i_primary_chip_target, "after PBA reset");
            if (!rc.ok()) {
                break;
            }

            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {
                rc = p8_pm_glob_fir_trace (i_secondary_chip_target, "after PBA reset");
                if (!rc.ok()) {
                    break;
                }
            }

            //  ******************************************************************
            //  Issue reset to OCC-SRAM
            //  ******************************************************************
            FAPI_INF("Issue reset to OCC-SRAM");
            FAPI_DBG("Executing: p8_occ_sram_init.C");

            // Primary
            FAPI_EXEC_HWP(rc, p8_occ_sram_init, i_primary_chip_target, PM_RESET );
            if (rc)
            {
                FAPI_ERR("p8_occ_sram_init: Failed to issue reset to OCC-SRAM. With rc = 0x%x", (uint32_t)rc);
                break;
            }

            // Secondary
            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {
                FAPI_EXEC_HWP(rc, p8_occ_sram_init, i_secondary_chip_target, PM_RESET );
                if (rc)
                {
                    FAPI_ERR("p8_occ_sram_init: Failed to issue reset to OCC-SRAM. With rc = 0x%x", (uint32_t)rc);
                    break;
                }
            }

            //  ******************************************************************
            //  Issue reset to OCB
            //  ******************************************************************

            FAPI_INF("Issue reset to OCB");
            FAPI_DBG("Executing: p8_ocb_init.C");

            // Primary
            FAPI_EXEC_HWP(rc, p8_ocb_init, i_primary_chip_target, PM_RESET,0 , 0, 0, 0, 0, 0 );
            if (rc)
            {
                FAPI_ERR("p8_ocb_init: Failed to issue reset to OCB. With rc = 0x%x", (uint32_t)rc);
                break;
            }

            // Secondary
            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {
                FAPI_EXEC_HWP(rc, p8_ocb_init, i_secondary_chip_target, PM_RESET,0 , 0, 0, 0, 0, 0 );
                if (rc)
                {
                    FAPI_ERR("p8_ocb_init: Failed to issue reset to OCB. With rc = 0x%x", (uint32_t)rc);
                    break;
                }
            }

            //  Check for xstops and recoverables
            rc = p8_pm_glob_fir_trace (i_primary_chip_target, "after OCB reset");
            if (!rc.ok()) {
                break;
            }

            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {
                rc = p8_pm_glob_fir_trace (i_secondary_chip_target, "after OCB reset");
                if (!rc.ok()) {
                    break;
                }
            }
            //  ******************************************************************
            //  Remove the EX chiplet special wakeups
            //  *****************************************************************

            // Primary
            rc = special_wakeup_all (i_primary_chip_target, false);
            if (rc)
            {
                FAPI_ERR("special_wakeup_all - Disable: Failed for Target %s",
                         i_primary_chip_target.toEcmdString());
                break;
            }
            b_special_wakeup_pri = false;


            // Secondary
            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {
                rc = special_wakeup_all (i_secondary_chip_target, false);
                if (rc)
                {
                    FAPI_ERR("special_wakeup_all - Disable: Failed for Target %s",
                             i_secondary_chip_target.toEcmdString());
                    break;
                }

                b_special_wakeup_sec = false;
            }


            //  ******************************************************************
            //  FSM trace
            //  ******************************************************************
            rc = p4rs_pcbs_fsm_trace (i_primary_chip_target, i_secondary_chip_target,
                                      "after special wake-up clearing");
            if (!rc.ok())
            {
                break;
            }

            //  Check for xstops and recoverables
            rc = p8_pm_glob_fir_trace (i_primary_chip_target, "after special wake-up clearing");
            if (!rc.ok()) {
                break;
            }

            if ( i_secondary_chip_target.getType() != TARGET_TYPE_NONE )
            {
                rc = p8_pm_glob_fir_trace (i_secondary_chip_target, "after special wake-up clearing");
                if (!rc.ok()) {
                    break;
                }
            }

        } while(0);


        // Clear special wakeups that might have been set before a subsequent
        // error occured.  Only attempts them on targets that have the boolean
        // flag set that they were successfully put into special wakeup.
        if (!rc.ok())
        {
            // Save the original RC
            rc_hold = rc;

            do
            {
                // Primary
                if (b_special_wakeup_pri)
                {
                    // Primary
                    rc = special_wakeup_all (i_primary_chip_target, false);
                    if (rc)
                    {
                        FAPI_ERR("special_wakeup_all - Disable: Failed during cleanup from a previous error for Target %s",
                                 i_primary_chip_target.toEcmdString());
                        FAPI_ERR("special_wakeup_all - Disable: The original error is being returned");
                        fapiLogError(rc, fapi::FAPI_ERRL_SEV_RECOVERED);
                        break;
                    }
                }

                // Secondary
                if (b_special_wakeup_sec)
                {
                    rc = special_wakeup_all (i_secondary_chip_target, false);
                    if (rc)
                    {
                        FAPI_ERR("special_wakeup_all - Disable: Failed during cleanup from a previous error for Target %s",
                                 i_primary_chip_target.toEcmdString());
                        FAPI_ERR("special_wakeup_all - Disable: The original error is being returned");
                        fapiLogError(rc, fapi::FAPI_ERRL_SEV_RECOVERED);
                        break;
                    }
                }
            } while(0);

            // Restore the original RC
            rc = rc_hold;
        }

        FAPI_INF("p8_pm_prep_for_reset end ....");

        return rc;
    } // Procedure
Beispiel #12
0
// function: xxx
/// \param[in] i_target Chip target
// returns: ECMD_SUCCESS if something good happens,
//          BAD_RETURN_CODE otherwise
fapi::ReturnCode
p8_pmc_force_vsafe( const fapi::Target& i_target,
                    const fapi::Target& i_dcm_target)
{
    fapi::ReturnCode    rc;
    ecmdDataBufferBase  data(64);
    ecmdDataBufferBase  pmcstatusreg(64);
    uint32_t            e_rc = 0;

    // maximum number of status poll attempts to make before giving up
    const uint32_t   MAX_POLL_ATTEMPTS    = 0x200;

    uint32_t            count = 0;
    uint16_t            pvsafe = 0;
    bool                l_set;
    uint16_t            pstate_target = 0;
    uint16_t            pstate_step_target = 0;
    uint16_t            pstate_actual = 0;
    uint8_t             DONE_FLAG = 0;
    uint8_t             pmc_error = 0;
    uint8_t             intchp_error = 0;
    uint8_t             any_error = 0;
    uint8_t             any_ongoing = 0;
    uint8_t             dummy = 0;

    FAPI_INF("p8_pmc_force_vsafe start to primary target %s",
                            i_target.toEcmdString());

    do
    {
        //  ******************************************************************
        //     -  PMC_MODE_REG checking
        //  ******************************************************************
        rc = fapiGetScom(i_target, PMC_MODE_REG_0x00062000, data );
        if (rc)
        {
            FAPI_ERR("fapiGetScom(PMC_MODE_REG_0x00062000) failed.");
            break;
        }


        if ( (data.isBitClear(0) && data.isBitClear(1) ))
        {
            FAPI_INF("PMC is not in HARDWARE or FIRMWARE AUCTION MODE so hardware mechanism cannot be used.");
            break;
        }

        if ( ( data.isBitClear(3) ))
        {
            FAPI_ERR("PMC is disabled for Voltage changes");
            const fapi::Target & CHIP = i_target;
            const uint64_t & PMCMODE  = data.getDoubleWord(0);
            FAPI_SET_HWP_ERROR(rc, RC_PROCPM_VOLTAGE_CHANGE_MODE_ERR);
            break;
        }

        if ( ( !data.isBitClear(5) ))
        {
            FAPI_ERR("PMC is disabled PMC_MASTER_SEQUENCER");
            const fapi::Target & CHIP = i_target;
            const uint64_t & PMCMODE  = data.getDoubleWord(0);
            FAPI_SET_HWP_ERROR(rc, RC_PROCPM_MST_SEQUENCER_STATE_ERR);
            break;
        }

        //  ****************************************************************************
        //     -  PMC_STATE_MONITOR_AND_CTRL_REG PMC_PARAMETER_REG1 before the psafe
        //  ****************************************************************************

        rc = fapiGetScom(i_target, PMC_PARAMETER_REG1_0x00062006, data );
        if (rc)
        {
            FAPI_ERR("fapiGetScom(PMC_PARAMETER_REG1_0x00062006) failed.");
            break;
        }

        e_rc |= data.extractToRight( &pvsafe,22,8);
        if (e_rc)
        {
            rc.setEcmdError(e_rc);
            break;
        }

        rc = fapiGetScom(i_target, PMC_PSTATE_MONITOR_AND_CTRL_REG_0x00062002, data );
        if (rc)
        {
            FAPI_ERR("fapiGetScom(PMC_PSTATE_MONITOR_AND_CTRL_REG_0x00062002) failed.");
            break;
        }

        e_rc |= data.extractToRight( &pstate_target,0,8);
        e_rc |= data.extractToRight( &pstate_step_target,8,8);
        e_rc |= data.extractToRight( &pstate_actual,16,8);
        if (e_rc)
        {
            rc.setEcmdError(e_rc);
            break;
        }

        FAPI_INF(" voltage values before the hearbeat loss " );
        FAPI_INF(" pvsafe => %x     , ptarget => %x   , pstarget  => %x ,pactual  =>  %x " , pvsafe , pstate_target ,pstate_step_target , pstate_actual);

        //  ******************************************************************
        //     -  SEE PMC_STATUS_REG if debug_mode ==1
        //  ******************************************************************

        rc = fapiGetScom(i_target, PMC_STATUS_REG_0x00062009, data );
        if (rc)
        {
            FAPI_ERR("fapiGetScom(PMC_STATUS_REG_0x00062009) failed.");
            break;
        }
        FAPI_DBG("   debug_mode : status_b4_heartbeat_loss      =>  0x%16llx",  data.getDoubleWord(0));

        l_set = data.isBitSet(0);
        FAPI_DBG("   pstate_processing_is_susp     => %x ",  l_set ) ;
        l_set = data.isBitSet(1);
        FAPI_DBG("   gpsa_bdcst_error              => %x ",  l_set );

        e_rc = data.extractToRight( &dummy,2,3);
        if (e_rc)
        {
            rc.setEcmdError(e_rc);
            break;
        }
        FAPI_DBG("   gpsa_bdcst_resp_info          => %x ",  dummy );
        l_set = data.isBitSet(5);
        FAPI_DBG("   gpsa_vchg_error               => %x ",  l_set );
        l_set = data.isBitSet(6);
        FAPI_DBG("   gpsa_timeout_error            => %x ",  l_set );
        l_set = data.isBitSet(7);
        FAPI_DBG("   gpsa_chg_ongoing              => %x ",  l_set );
        l_set = data.isBitSet(8);
        FAPI_DBG("   volt_chg_ongoing              => %x ",  l_set );
        l_set = data.isBitSet(9);
        FAPI_DBG("   brd_cst_ongoing               => %x ",  l_set );
        l_set = data.isBitSet(10);
        FAPI_DBG("   gpsa_table_error              => %x ",  l_set );
        l_set = data.isBitSet(11);
        FAPI_DBG("   pstate_interchip_error        => %x ",  l_set );
        l_set = data.isBitSet(12);
        FAPI_DBG("   istate_processing_is_susp     => %x ",  l_set );


        //  ******************************************************************
        //     -  PMC_OCC_HEARTBEAT_REG
        //  ******************************************************************

        FAPI_INF("Forcing PMC Heartbeat loss                  ");

        e_rc |= data.flushTo0();
        e_rc |= data.setBit(16);
        if (e_rc)
        {
            rc.setEcmdError(e_rc);
            break;
        }

        rc = fapiPutScom(i_target, PMC_OCC_HEARTBEAT_REG_0x00062066, data );
        if (rc)
        {
            FAPI_ERR("fapiPutScom(PMC_OCC_HEARTBEAT_REG_0x00062066) failed.");
            break;
        }

        // delay to reduce number of polling loops
        rc = fapiDelay(1000, 1000);

        //  ******************************************************************
        //       POLL for PMC_STATUS_REG --> BIT_8 to go to 0 or any errors
        //  ******************************************************************
        FAPI_DBG("Start polling for ongoing to go low ... ");
        // Loop only if count is less thean poll attempts and DONE_FLAG = 0 and no error
        for(count=0; ((count<=MAX_POLL_ATTEMPTS) && (DONE_FLAG == 0) && (any_error == 0)); count++)
        {
            rc = fapiGetScom(i_target, PMC_STATUS_REG_0x00062009, pmcstatusreg );
            if (rc)
            {
                FAPI_ERR("fapiGetScom(PMC_STATUS_REG_0x00062009) failed.");
                break;
            }

            FAPI_DBG("   PMC Status poll  => 0x%16llx",  pmcstatusreg.getDoubleWord(0));

            pmc_error = (   pmcstatusreg.isBitSet(1)  ||    // GPSA_BDCST_ERROR
                            pmcstatusreg.isBitSet(5)  ||    // GPSA_VCHG_ERROR
                            pmcstatusreg.isBitSet(6)  ||    // GPSA_TIMEOUT_ERROR
                            pmcstatusreg.isBitSet(10) ||    // GPS_TABLE_ERROR
                            pmcstatusreg.isBitSet(12)   );  // ISTATE_PROCESSING_IS_SUSPENDED

            any_ongoing = ( pmcstatusreg.isBitSet(7) ||     // GPSA_CHG_ONGOING
                            pmcstatusreg.isBitSet(8) ||     // VOLT_CHG_ONGOING
                            pmcstatusreg.isBitSet(9)   );   // BRD_CST_ONGOING

                       
            // If there is an interchip error, determine if it is expected or not
            // Unexpected:  gpsa_timeout or ECC UE error
            if (pmcstatusreg.isBitSet(11))                  // PSTATE_INTERCHIP_ERROR
            {
                rc = fapiGetScom(i_target, PMC_INTCHP_STATUS_REG_0x00062013, data );
                if (rc)
                {
                    FAPI_ERR("fapiGetScom(PMC_STATUS_REG_0x00062009) failed.");
                    break;
                }
                
                intchp_error = (data.isBitSet(18) ||        // GPSA_TIMEOUT_ERROR
                                data.isBitSet(19)   );      // ECC UE ERROR                
            }
            
            any_error = (pmc_error || intchp_error);
            
            // log status if voltage change has any error
            // Due to SW258130
            // This block only dumps any detected hw error status
            // without taking out an error log and stop the reset flow. 
            // Since this procedure is only used by p8_pm_prep_for_reset
            // we will and should be able to recover from such hardware errors
            // by going through occ reset flow, thus no FAPI error logged.
            // Also since if hardware error occurs, there is no need to check 
            // for pstate ongoing or pstate equals to pvsafe due to possible
            // hardware stuck; therefore, this if/else logic remains. 
            if (any_error)
            {
                // dump individual error status 
                FAPI_INF(" PMC_STATUS_REG upon Error");
                if (pmcstatusreg.isBitSet(0))
                    FAPI_INF("   pstate_processing_is_susp active");
                if (pmcstatusreg.isBitSet(1))
                    FAPI_INF("   gpsa_bdcst_error active");

                e_rc = pmcstatusreg.extractToRight( &dummy,2,3);
                if (e_rc)
                {
                    rc.setEcmdError(e_rc);
                    break;
                }
                if (dummy)
                    FAPI_INF("   gpsa_bdcst_resp_info is non-zero => %x ",  dummy );

                if (pmcstatusreg.isBitSet(5))
                    FAPI_INF("   gpsa_vchg_error active");
                if (pmcstatusreg.isBitSet(6))
                    FAPI_INF("   gpsa_timeout_error active");
                if (pmcstatusreg.isBitSet(7))
                    FAPI_INF("   gpsa_chg_ongoing active");
                if (pmcstatusreg.isBitSet(8))
                    FAPI_INF("   volt_chg_ongoing active");
                if (pmcstatusreg.isBitSet(9))
                    FAPI_INF("   brd_cst_ongoing active");
                if (pmcstatusreg.isBitSet(10))
                    FAPI_INF("   gpsa_table_error active");
                if (pmcstatusreg.isBitSet(11))
                    FAPI_INF("   pstate_interchip_error active");
                if (pmcstatusreg.isBitSet(12))
                    FAPI_INF("   istate_processing_is_susp active");

                FAPI_INF("Status dumpped with PMC on-going deassertion during safe voltage movement, now continue on reset");
            } // end of status log if
            else if (any_ongoing == 0)
            {
                // Voltage change done (not on-going) and not errors
                FAPI_INF("PMC completed performing safe mode transition");                                
                l_set = pmcstatusreg.isBitSet(0);
                if (l_set) FAPI_INF("   pstate_processing_is_susp => %x ",  l_set ) ;
                
                l_set = pmcstatusreg.isBitSet(1);
                if (l_set) FAPI_INF("   gpsa_bdcst_error          => %x ",  l_set );

                e_rc = pmcstatusreg.extractToRight( &dummy,2,3);
                if (e_rc)
                {
                    rc.setEcmdError(e_rc);
                    break;
                }
                if (l_set) FAPI_INF("   gpsa_bdcst_resp_info      => %x ",  dummy );
                
                l_set = pmcstatusreg.isBitSet(5);
                if (l_set) FAPI_INF("   gpsa_vchg_error           => %x ",  l_set );
                              
                l_set = pmcstatusreg.isBitSet(6);
                if (l_set) FAPI_INF("   gpsa_timeout_error        => %x ",  l_set );
                
                l_set = pmcstatusreg.isBitSet(7);
                if (l_set) FAPI_INF("   gpsa_chg_ongoing          => %x ",  l_set );
                
                l_set = pmcstatusreg.isBitSet(8);
                if (l_set) FAPI_INF("   volt_chg_ongoing          => %x ",  l_set );
                
                l_set = pmcstatusreg.isBitSet(9);
                if (l_set) FAPI_INF("   brd_cst_ongoing           => %x ",  l_set );
                
                l_set = pmcstatusreg.isBitSet(10);
                if (l_set) FAPI_INF("   gpsa_table_error          => %x ",  l_set );
                
                l_set = pmcstatusreg.isBitSet(11);
                if (l_set) FAPI_INF("   pstate_interchip_error    => %x ",  l_set );
                
                l_set = pmcstatusreg.isBitSet(12);
                if (l_set) FAPI_INF("   istate_processing_is_susp => %x ",  l_set );
                

                rc = fapiGetScom(i_target, PMC_PARAMETER_REG1_0x00062006, data );
                if (rc)
                {
                    FAPI_ERR("fapiGetScom(PMC_PARAMETER_REG1_0x00062006) failed.");
                    break;
                }

                e_rc = data.extractToRight( &pvsafe,22,8);
                if (e_rc)
                {
                    rc.setEcmdError(e_rc);
                    break;
                }

                rc = fapiGetScom(i_target, PMC_PSTATE_MONITOR_AND_CTRL_REG_0x00062002, data );
                if (rc)
                {
                    FAPI_ERR("fapiGetScom(PMC_PSTATE_MONITOR_AND_CTRL_REG_0x00062002) failed.");
                    break;
                }

                e_rc |= data.extractToRight( &pstate_target,0,8);
                e_rc |= data.extractToRight( &pstate_step_target,8,8);
                e_rc |= data.extractToRight( &pstate_actual,16,8);
                if (e_rc)
                {
                    rc.setEcmdError(e_rc);
                    break;
                }
                FAPI_INF(" pvsafe => %x     , ptarget => %x   , pstarget  => %x ,pactual  =>  %x " , pvsafe , pstate_target ,pstate_step_target , pstate_actual);

                // Check that PVSAFE Pstate (in PMC Parameter Reg1) is the value
                // in the voltage stepper in the following fields of
                // PMC_STATE_MONITOR_AND_CRTL_REG
                // 0:7      - Global Pstate Target
                // 8:15     - Global Pstate Step Target
                // 16:23    - Global Pstate Actual
                // if the above do not match, post an error
                if (pstate_target != pvsafe || pstate_step_target != pvsafe || pstate_actual != pvsafe )
                {
                    FAPI_ERR("Pstate monitor and control register targets did not match");
                    const fapi::Target & THISCHIP = i_target;
                    const fapi::Target & DCMCHIP = i_dcm_target;
                    const uint64_t & PSTATETARGET = (uint64_t)pstate_target;
                    const uint64_t & PSTATESTEPTARGET = (uint64_t)pstate_step_target;
                    const uint64_t & PSTATEACTUAL = (uint64_t)pstate_actual;
                    FAPI_SET_HWP_ERROR(rc, RC_PROCPM_PSTATE_MONITOR_ERR);
                    break;
                }
                DONE_FLAG = 1;
            }
            else  // voltage change is ongoing so wait and then poll again
            {

                // wait for 1 millisecond in hardware
                rc = fapiDelay(1000*1000, 20000000);
                if (rc)
                {
                    FAPI_ERR("fapi delay ends up with error");
                    break;
                }
            }
        }  // For loop
        // Inner loop error check
        if (!rc.ok())
        {
            break;
        }

        // Check if the above loop timed out
        if (count>=MAX_POLL_ATTEMPTS)
        {
            FAPI_ERR("Timed out wait for voltage change on-going to drop");
            const uint64_t & PSTATETARGET = (uint64_t)pstate_target;
            const uint64_t & PSTATESTEPTARGET = (uint64_t)pstate_step_target;
            const uint64_t & PSTATEACTUAL = (uint64_t)pstate_actual;
            const fapi::Target & THISCHIP = i_target;
            const fapi::Target & DCMCHIP = i_dcm_target;
            FAPI_SET_HWP_ERROR(rc, RC_PROCPM_VLT_TIMEOUT);
            break;
        }

    } while(0);

    FAPI_INF("p8_pmc_force_vsafe end  ....");

    return rc ;
} // Procedure
Beispiel #13
0
ReturnCode io_fir_isolation(const fapi::Target &i_target){

    ReturnCode o_rc;
    uint32_t rc_ecmd=0;
    fir_io_interface_t interface;
    io_interface_t gcr_interface; // requires different base address for gcr scoms
    uint32_t group;
    ecmdDataBufferBase    fir_data(64);
    rc_ecmd|=fir_data.flushTo0();
    if(rc_ecmd)
    {
        o_rc.setEcmdError(rc_ecmd);
        return(o_rc);
    }

    //on dmi
    if( (i_target.getType() == fapi::TARGET_TYPE_MCS_CHIPLET )){
          FAPI_DBG("This is a Processor DMI bus using base DMI scom address");
          interface=FIR_CP_IOMC0_P0; // base scom for MC bus
          gcr_interface=CP_IOMC0_P0;
          o_rc=read_fir_reg(i_target,interface,fir_data);
          group=3;
          if(o_rc)
                        return(o_rc);
          o_rc=io_error_isolation(i_target,gcr_interface,group,fir_data);

     }
     //on cen side
     else if((i_target.getType() ==  fapi::TARGET_TYPE_MEMBUF_CHIP)){
            FAPI_DBG("This is a Centaur DMI bus using base DMI scom address");
            interface=FIR_CEN_DMI;
            gcr_interface=CEN_DMI;
            o_rc=read_fir_reg(i_target,interface,fir_data);
            group=0;
            if(o_rc)
                        return(o_rc);
            o_rc=io_error_isolation(i_target,gcr_interface,group,fir_data);

     }
     // on x bus
     else if((i_target.getType() == fapi::TARGET_TYPE_XBUS_ENDPOINT)){
            FAPI_DBG("This is a X Bus invocation");
            interface=FIR_CP_FABRIC_X0;
            gcr_interface=CP_FABRIC_X0;
            o_rc=read_fir_reg(i_target,interface,fir_data);
            group=0;
            if(o_rc)
                        return(o_rc);
            o_rc=io_error_isolation(i_target,gcr_interface,group,fir_data);

     }
     //on a bus
     else if((i_target.getType() == fapi::TARGET_TYPE_ABUS_ENDPOINT)){
            FAPI_DBG("This is an A Bus invocation");
            interface=FIR_CP_FABRIC_A0;
            gcr_interface=CP_FABRIC_A0;
            o_rc=read_fir_reg(i_target,interface,fir_data);
            group=0;
            if(o_rc)
                        return(o_rc);
            o_rc=io_error_isolation(i_target,gcr_interface,group,fir_data);

     }
     else{
        FAPI_ERR("Invalid io_fir HWP invocation . Target doesnt belong to DMI/X/A instances");
        const fapi::Target & ENDPOINT = i_target;
        FAPI_SET_HWP_ERROR(o_rc, IO_FIR_INVALID_INVOCATION_RC);
     }

     return(o_rc);


}
    fapi::ReturnCode mss_eff_config_thermal_throttles(const fapi::Target & i_target_mba)
    {
	fapi::ReturnCode rc = fapi::FAPI_RC_SUCCESS;

	FAPI_INF("*** Running mss_eff_config_thermal_throttles on %s ***",
		 i_target_mba.toEcmdString());

// variables used in this function
	fapi::Target target_chip;
	std::vector<fapi::Target> target_mba_array;
	std::vector<fapi::Target> target_dimm_array;
	uint8_t custom_dimm;
	uint8_t num_dimms_on_port;
	uint32_t runtime_throttle_n_per_mba;
	uint32_t runtime_throttle_n_per_chip;
	uint32_t runtime_throttle_d;
	uint32_t dimm_thermal_power_limit;
	uint32_t channel_pair_thermal_power_limit;
	uint8_t num_mba_with_dimms = 0;
	uint8_t mba_index;
	uint8_t ras_increment;
	uint8_t cas_increment;
	uint32_t l_max_dram_databus_util;
	uint32_t l_dimm_reg_power_limit_per_dimm_adj;
	uint32_t l_dimm_reg_power_limit_per_dimm;
	uint8_t l_max_number_dimms_per_reg;
	uint8_t l_dimm_reg_power_limit_adj_enable;
	uint8_t l_reg_max_dimm_count;
	uint8_t l_dram_gen;
	uint32_t l_power_slope_array[NUM_PORTS][NUM_DIMMS];
	uint32_t l_power_int_array[NUM_PORTS][NUM_DIMMS];
	uint32_t l_total_power_slope_array[NUM_PORTS][NUM_DIMMS];
	uint32_t l_total_power_int_array[NUM_PORTS][NUM_DIMMS];

//------------------------------------------------------------------------------
// Get input attributes
//------------------------------------------------------------------------------

// Get Centaur target for the given MBA
	rc = fapiGetParentChip(i_target_mba, target_chip);
	if (rc) {
	    FAPI_ERR("Error from fapiGetParentChip");
	    return rc;
	}

	rc = FAPI_ATTR_GET(ATTR_EFF_CUSTOM_DIMM, &i_target_mba, custom_dimm);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_EFF_CUSTOM_DIMM");
	    return rc;
	}
	rc = FAPI_ATTR_GET(ATTR_EFF_NUM_DROPS_PER_PORT,
			   &i_target_mba, num_dimms_on_port);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_EFF_NUM_DROPS_PER_PORT");
	    return rc;
	}
	rc = FAPI_ATTR_GET(ATTR_MRW_THERMAL_MEMORY_POWER_LIMIT,
			   NULL, dimm_thermal_power_limit);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_MRW_THERMAL_MEMORY_POWER_LIMIT");
	    return rc;
	}

	rc = FAPI_ATTR_GET(ATTR_MRW_MEM_THROTTLE_DENOMINATOR, NULL, runtime_throttle_d);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_MRW_MEM_THROTTLE_DENOMINATOR");
	    return rc;
	}
	rc = FAPI_ATTR_GET(ATTR_MRW_MAX_DRAM_DATABUS_UTIL,
			   NULL, l_max_dram_databus_util);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_MRW_MAX_DRAM_DATABUS_UTIL");
	    return rc;
	}
	rc = FAPI_ATTR_GET(ATTR_MRW_VMEM_REGULATOR_MEMORY_POWER_LIMIT_PER_DIMM,
			   NULL, l_dimm_reg_power_limit_per_dimm);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_MRW_VMEM_REGULATOR_MEMORY_POWER_LIMIT_PER_DIMM");
	    return rc;
	}
	rc = FAPI_ATTR_GET(ATTR_MRW_MAX_NUMBER_DIMMS_POSSIBLE_PER_VMEM_REGULATOR,
			   NULL, l_max_number_dimms_per_reg);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_MRW_MAX_NUMBER_DIMMS_POSSIBLE_PER_VMEM_REGULATOR");
	    return rc;
	}
	rc = FAPI_ATTR_GET(ATTR_MRW_VMEM_REGULATOR_POWER_LIMIT_PER_DIMM_ADJ_ENABLE,
			   NULL, l_dimm_reg_power_limit_adj_enable);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_MRW_VMEM_REGULATOR_POWER_LIMIT_PER_DIMM_ADJ_ENABLE");
	    return rc;
	}
	rc = FAPI_ATTR_GET(ATTR_MSS_VMEM_REGULATOR_MAX_DIMM_COUNT,
			   NULL, l_reg_max_dimm_count);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_MSS_VMEM_REGULATOR_MAX_DIMM_COUNT");
	    return rc;
	}
	rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_GEN,
			   &i_target_mba, l_dram_gen);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_EFF_DRAM_GEN");
	    return rc;
	}
	rc = FAPI_ATTR_GET(ATTR_MSS_POWER_SLOPE,
			   &i_target_mba, l_power_slope_array);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_MSS_POWER_SLOPE");
	    return rc;
	}
	rc = FAPI_ATTR_GET(ATTR_MSS_POWER_INT,
			   &i_target_mba, l_power_int_array);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_MSS_POWER_INT");
	    return rc;
	}
	rc = FAPI_ATTR_GET(ATTR_MSS_TOTAL_POWER_SLOPE,
			   &i_target_mba, l_total_power_slope_array);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_MSS_TOTAL_POWER_SLOPE");
	    return rc;
	}
	rc = FAPI_ATTR_GET(ATTR_MSS_TOTAL_POWER_INT,
			   &i_target_mba, l_total_power_int_array);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_MSS_TOTAL_POWER_INT");
	    return rc;
	}

// Get number of Centaur MBAs that have dimms present
// Custom dimms (CDIMMs) use mba/chip throttling, so count number of mbas that have dimms
	if (custom_dimm == fapi::ENUM_ATTR_EFF_CUSTOM_DIMM_YES)
	{
	    rc = fapiGetChildChiplets(target_chip,
				      fapi::TARGET_TYPE_MBA_CHIPLET,
				      target_mba_array,
				      fapi::TARGET_STATE_PRESENT);
	    if (rc) {
		FAPI_ERR("Error from fapiGetChildChiplets");
		return rc;
	    }
	    num_mba_with_dimms = 0;
	    for (mba_index=0; mba_index < target_mba_array.size(); mba_index++)
	    {
		rc = fapiGetAssociatedDimms(target_mba_array[mba_index],
					    target_dimm_array,
					    fapi::TARGET_STATE_PRESENT);
		if (rc) {
		    FAPI_ERR("Error from fapiGetAssociatedDimms");
		    return rc;
		}
		if (target_dimm_array.size() > 0)
		{
		    num_mba_with_dimms++;
		}
	    }
	}
// ISDIMM (non custom dimm) uses dimm/mba throttling, so set num_mba_with_dimms to 1
	else
	{
	    num_mba_with_dimms = 1;
	}


//------------------------------------------------------------------------------
// Memory Throttle Determination
//------------------------------------------------------------------------------

// Determine memory throttle settings needed based on dimm thermal power limit

//------------------------------------------------------------------------------
// Determine the thermal power limit to use, which represents a single channel
// pair power limit for the dimms on that channel pair (ie.  power for all dimms
// attached to one MBA).   The procedure mss_bulk_power_throttles takes the
// input of channel pair power to determine throttles.
// CDIMM thermal power limit from MRW is per CDIMM, so divide by number of mbas
// that have dimms to get channel pair power
// CDIMM:  Allow all commands to be directed toward one MBA to achieve the power
// limit
//   This means that the power limit for a MBA channel pair must be the total
// CDIMM power limit minus the idle power of the other MBAs logical dimms
//------------------------------------------------------------------------------

// adjust the regulator power limit per dimm if enabled and use this if less than the thermal limit
// If reg power limit is zero, then set to thermal limit - needed for ISDIMM systems since some of these MRW attributes are not defined
	if (l_dimm_reg_power_limit_per_dimm == 0)
	{
	    l_dimm_reg_power_limit_per_dimm = dimm_thermal_power_limit;
	}
	l_dimm_reg_power_limit_per_dimm_adj = l_dimm_reg_power_limit_per_dimm;
	if (l_dimm_reg_power_limit_adj_enable == fapi::ENUM_ATTR_MRW_VMEM_REGULATOR_POWER_LIMIT_PER_DIMM_ADJ_ENABLE_TRUE)
	{
// adjust reg power limit per cdimm only if l_reg_max_dimm_count>0 and l_reg_max_dimm_count<l_max_number_dimms_per_reg
	    if (
		(l_reg_max_dimm_count > 0)
		 && (l_reg_max_dimm_count < l_max_number_dimms_per_reg)
		)
	    {
		l_dimm_reg_power_limit_per_dimm_adj =
		  l_dimm_reg_power_limit_per_dimm
		  * l_max_number_dimms_per_reg
		  / l_reg_max_dimm_count;
		FAPI_INF("VMEM Regulator Power/DIMM Limit Adjustment from %d to %d cW (DIMMs under regulator %d/%d)", l_dimm_reg_power_limit_per_dimm, l_dimm_reg_power_limit_per_dimm_adj, l_reg_max_dimm_count, l_max_number_dimms_per_reg);
	    }
	}
// Use the smaller of the thermal limit and regulator power limit per dimm
	if (l_dimm_reg_power_limit_per_dimm_adj < dimm_thermal_power_limit)
	{
	    dimm_thermal_power_limit = l_dimm_reg_power_limit_per_dimm_adj;
	}

// Adjust the thermal/power limit to represent the power for all dimms under an MBA
	if (custom_dimm == fapi::ENUM_ATTR_EFF_CUSTOM_DIMM_YES)
	{
	    channel_pair_thermal_power_limit =
	      dimm_thermal_power_limit / num_mba_with_dimms;
	}
// ISDIMMs thermal power limit from MRW is per DIMM, so multiply by number of dimms on channel to get channel power and multiply by 2 to get channel pair power
	else
	{
		// ISDIMMs
	    channel_pair_thermal_power_limit =
	      dimm_thermal_power_limit * num_dimms_on_port * 2;
	}

// Update the channel pair power limit attribute
	rc = FAPI_ATTR_SET(ATTR_MSS_MEM_WATT_TARGET,
			   &i_target_mba, channel_pair_thermal_power_limit);
	if (rc) {
	    FAPI_ERR("Error writing attribute ATTR_MSS_MEM_WATT_TARGET");
	    return rc;
	}

// Initialize the runtime throttle attributes to an unthrottled value for mss_bulk_pwr_throttles
// max utilization comes from MRW value in c% - convert to %
	float MAX_UTIL = (float) l_max_dram_databus_util / 100;
	runtime_throttle_n_per_mba = (int)(runtime_throttle_d * (MAX_UTIL / 100) / 4);
	runtime_throttle_n_per_chip = (int)(runtime_throttle_d * (MAX_UTIL / 100) / 4) *
	  num_mba_with_dimms;

// for better custom dimm performance for DDR4, set the per mba throttle to the per chip throttle
// Not planning on doing this for DDR3
	if ( (l_dram_gen == fapi::ENUM_ATTR_EFF_DRAM_GEN_DDR4)
	     && (custom_dimm == fapi::ENUM_ATTR_EFF_CUSTOM_DIMM_YES) )
	{
	    runtime_throttle_n_per_mba = runtime_throttle_n_per_chip;
	}

	rc = FAPI_ATTR_SET(ATTR_MSS_RUNTIME_MEM_THROTTLE_NUMERATOR_PER_MBA,
			   &i_target_mba, runtime_throttle_n_per_mba);
	if (rc) {
	    FAPI_ERR("Error writing attribute ATTR_MSS_RUNTIME_MEM_THROTTLE_NUMERATOR_PER_MBA");
	    return rc;
	}
	rc = FAPI_ATTR_SET(ATTR_MSS_RUNTIME_MEM_THROTTLE_NUMERATOR_PER_CHIP,
			   &i_target_mba, runtime_throttle_n_per_chip);
	if (rc) {
	    FAPI_ERR("Error writing attribute ATTR_MSS_RUNTIME_MEM_THROTTLE_NUMERATOR_PER_CHIP");
	    return rc;
	}
	rc = FAPI_ATTR_SET(ATTR_MSS_RUNTIME_MEM_THROTTLE_DENOMINATOR,
			   &i_target_mba, runtime_throttle_d);
	if (rc) {
	    FAPI_ERR("Error writing attribute ATTR_MSS_RUNTIME_MEM_THROTTLE_DENOMINATOR");
	    return rc;
	}

	FAPI_INF("Min Power/Thermal Limit per MBA %d cW.  Unthrottled values [%d/%d/%d].", channel_pair_thermal_power_limit, runtime_throttle_n_per_mba, runtime_throttle_n_per_chip, runtime_throttle_d);


// For DDR4, use the VMEM power to determine the runtime throttle settings that are based
//  on a VMEM power limit (not a VMEM+VPP power limit which is to be used at runtime for tmgt)
// Need to temporarily override attributes for mss_bulk_pwr_throttles to use
// Needed to determines runtime memory throttle settings based on any VMEM power limits
	if (l_dram_gen == fapi::ENUM_ATTR_EFF_DRAM_GEN_DDR4)
	{
	    rc = FAPI_ATTR_SET(ATTR_MSS_TOTAL_POWER_SLOPE,
			       &i_target_mba, l_power_slope_array);
	    if (rc) {
		FAPI_ERR("Error writing attribute ATTR_MSS_TOTAL_POWER_SLOPE");
		return rc;
	    }
	    rc = FAPI_ATTR_SET(ATTR_MSS_TOTAL_POWER_INT, &i_target_mba, l_power_int_array);
	    if (rc) {
		FAPI_ERR("Error writing attribute ATTR_MSS_TOTAL_POWER_INT");
		return rc;
	    }
	}

// Call the procedure function that takes a channel pair power limit and
// converts it to throttle values
	FAPI_EXEC_HWP(rc, mss_bulk_pwr_throttles, i_target_mba);
	if (rc)
	{
	    FAPI_ERR("Error (0x%x) calling mss_bulk_pwr_throttles", static_cast<uint32_t>(rc));
	    return rc;
	}

// Reset the total power curve attributes back to the original values
	if (l_dram_gen == fapi::ENUM_ATTR_EFF_DRAM_GEN_DDR4)
	{
	    rc = FAPI_ATTR_SET(ATTR_MSS_TOTAL_POWER_SLOPE,
			       &i_target_mba, l_total_power_slope_array);
	    if (rc) {
		FAPI_ERR("Error writing attribute ATTR_MSS_TOTAL_POWER_SLOPE");
		return rc;
	    }
	    rc = FAPI_ATTR_SET(ATTR_MSS_TOTAL_POWER_INT, &i_target_mba, l_total_power_int_array);
	    if (rc) {
		FAPI_ERR("Error writing attribute ATTR_MSS_TOTAL_POWER_INT");
		return rc;
	    }
	}

// Read back in the updated throttle attribute values (these are now set to
// values that will give dimm/channel power underneath the thermal power limit)
	rc = FAPI_ATTR_GET(ATTR_MSS_MEM_THROTTLE_NUMERATOR_PER_MBA,
			   &i_target_mba, runtime_throttle_n_per_mba);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_MSS_MEM_THROTTLE_NUMERATOR_PER_MBA");
	    return rc;
	}
	rc = FAPI_ATTR_GET(ATTR_MSS_MEM_THROTTLE_NUMERATOR_PER_CHIP,
			   &i_target_mba, runtime_throttle_n_per_chip);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_MSS_MEM_THROTTLE_NUMERATOR_PER_CHIP");
	    return rc;
	}
	rc = FAPI_ATTR_GET(ATTR_MSS_MEM_THROTTLE_DENOMINATOR,
			   &i_target_mba, runtime_throttle_d);
	if (rc) {
	    FAPI_ERR("Error getting attribute ATTR_MSS_MEM_THROTTLE_DENOMINATOR");
	    return rc;
	}

// Setup the RAS and CAS increments used in the throttling register
	ras_increment=0;
	cas_increment=1;

// update output attributes
	rc = FAPI_ATTR_SET(ATTR_MSS_RUNTIME_MEM_THROTTLE_NUMERATOR_PER_MBA,
			   &i_target_mba, runtime_throttle_n_per_mba);
	if (rc) {
	    FAPI_ERR("Error writing attribute ATTR_MSS_RUNTIME_MEM_THROTTLE_NUMERATOR_PER_MBA");
	    return rc;
	}
	rc = FAPI_ATTR_SET(ATTR_MSS_RUNTIME_MEM_THROTTLE_NUMERATOR_PER_CHIP,
			   &i_target_mba, runtime_throttle_n_per_chip);
	if (rc) {
	    FAPI_ERR("Error writing attribute ATTR_MSS_RUNTIME_MEM_THROTTLE_NUMERATOR_PER_CHIP");
	    return rc;
	}
	rc = FAPI_ATTR_SET(ATTR_MSS_RUNTIME_MEM_THROTTLE_DENOMINATOR,
			   &i_target_mba, runtime_throttle_d);
	if (rc) {
	    FAPI_ERR("Error writing attribute ATTR_MSS_RUNTIME_MEM_THROTTLE_DENOMINATOR");
	    return rc;
	}
	rc = FAPI_ATTR_SET(ATTR_MSS_THROTTLE_CONTROL_RAS_WEIGHT,
			   &i_target_mba, ras_increment);
	if (rc) {
	    FAPI_ERR("Error writing attribute ATTR_MSS_THROTTLE_CONTROL_RAS_WEIGHT");
	    return rc;
	}
	rc = FAPI_ATTR_SET(ATTR_MSS_THROTTLE_CONTROL_CAS_WEIGHT,
			   &i_target_mba, cas_increment);
	if (rc) {
	    FAPI_ERR("Error writing attribute ATTR_MSS_THROTTLE_CONTROL_CAS_WEIGHT");
	    return rc;
	}

	FAPI_INF("*** mss_eff_config_thermal_throttles COMPLETE on %s ***",
		 i_target_mba.toEcmdString());
	return rc;
    }
Beispiel #15
0
//******************************************************************************
// fapiGetChildChiplets function
//******************************************************************************
fapi::ReturnCode fapiGetChildChiplets(
    const fapi::Target & i_chip,
    const fapi::TargetType i_chipletType,
    std::vector<fapi::Target> & o_chiplets,
    const fapi::TargetState i_state)
{
    FAPI_DBG(ENTER_MRK "fapiGetChildChiplets. Chiplet Type:0x%08x State:0x%08x",
             i_chipletType, i_state);

    fapi::ReturnCode l_rc;
    o_chiplets.clear();

    // Extract the HostBoot Target pointer for the input chip
    TARGETING::Target * l_pChip =
        reinterpret_cast<TARGETING::Target*>(i_chip.get());

    // Check that the input target is a chip
    if (!i_chip.isChip())
    {
        FAPI_ERR("fapiGetChildChiplets. Input target type 0x%08x is not a chip",
                 i_chip.getType());
        /*@
         * @errortype
         * @moduleid     fapi::MOD_FAPI_GET_CHILD_CHIPLETS
         * @reasoncode   fapi::RC_INVALID_REQUEST
         * @userdata1    Type of input target
         * @userdata2    Input Target HUID
         * @devdesc      fapiGetChildChiplets request for non-chip
         */
        const bool hbSwError = true;
        errlHndl_t l_pError = new ERRORLOG::ErrlEntry(
            ERRORLOG::ERRL_SEV_UNRECOVERABLE,
            fapi::MOD_FAPI_GET_CHILD_CHIPLETS,
            fapi::RC_INVALID_REQUEST,
            i_chip.getType(),
            TARGETING::get_huid(l_pChip),
            hbSwError);

        // Attach the error log to the fapi::ReturnCode
        l_rc.setPlatError(reinterpret_cast<void *> (l_pError));
    }
    else
    {
        TARGETING::TYPE l_type = TARGETING::TYPE_NA;

        if (i_chipletType == fapi::TARGET_TYPE_EX_CHIPLET)
        {
            l_type = TARGETING::TYPE_EX;
        }
        else if (i_chipletType == fapi::TARGET_TYPE_MBA_CHIPLET)
        {
            l_type = TARGETING::TYPE_MBA;
        }
        else if (i_chipletType == fapi::TARGET_TYPE_MCS_CHIPLET)
        {
            l_type = TARGETING::TYPE_MCS;
        }
        else if (i_chipletType == fapi::TARGET_TYPE_XBUS_ENDPOINT)
        {
            l_type = TARGETING::TYPE_XBUS;
        }
        else if (i_chipletType == fapi::TARGET_TYPE_ABUS_ENDPOINT)
        {
            l_type = TARGETING::TYPE_ABUS;
        }
        else if (i_chipletType == fapi::TARGET_TYPE_L4)
        {
            l_type = TARGETING::TYPE_L4;
        }
        else
        {
            FAPI_ERR("fapiGetChildChiplets. Chiplet type 0x%08x not supported",
                     i_chipletType);
            /*@
             * @errortype
             * @moduleid     fapi::MOD_FAPI_GET_CHILD_CHIPLETS
             * @reasoncode   fapi::RC_UNSUPPORTED_REQUEST
             * @userdata1    Type of requested chiplet
             * @userdata2    Input Chip Target HUID
             * @devdesc      fapiGetChildChiplets request for unsupported
             *               or invalid chiplet type
             */
            const bool hbSwError = true;
            errlHndl_t l_pError = new ERRORLOG::ErrlEntry(
                ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                fapi::MOD_FAPI_GET_CHILD_CHIPLETS,
                fapi::RC_UNSUPPORTED_REQUEST,
                i_chipletType,
                TARGETING::get_huid(l_pChip),
                hbSwError);

            // Attach the error log to the fapi::ReturnCode
            l_rc.setPlatError(reinterpret_cast<void *> (l_pError));
        }
        if (!l_rc)
        {
            if (l_pChip == NULL)
            {
                FAPI_ERR("fapiGetChildChiplets. Embedded NULL target pointer");
                /*@
                 * @errortype
                 * @moduleid     fapi::MOD_FAPI_GET_CHILD_CHIPLETS
                 * @reasoncode   fapi::RC_EMBEDDED_NULL_TARGET_PTR
                 * @devdesc      Target has embedded null target pointer
                 */
                const bool hbSwError = true;
                errlHndl_t l_pError = new ERRORLOG::ErrlEntry(
                    ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                    fapi::MOD_FAPI_GET_CHILD_CHIPLETS,
                    fapi::RC_EMBEDDED_NULL_TARGET_PTR,
                    0, 0, hbSwError);

                // Attach the error log to the fapi::ReturnCode
                l_rc.setPlatError(reinterpret_cast<void *> (l_pError));
            }
            else
            {
                TARGETING::TargetHandleList l_chipletList;

                TARGETING::getChildChiplets(l_chipletList, l_pChip, l_type,
                                            false);

                // Return fapi::Targets to the caller
                for (TARGETING::TargetHandleList::const_iterator
                        chipletIter = l_chipletList.begin();
                        chipletIter != l_chipletList.end();
                        ++chipletIter)
                {
                    TARGETING::HwasState l_state =
                        (*chipletIter)->getAttr<TARGETING::ATTR_HWAS_STATE>();

                    // HWPs/FAPI considers partial good chiplets as present, but
                    // firmware considers them not-present. Return all chiplets
                    // in the model when caller requests PRESENT
                    if ((fapi::TARGET_STATE_FUNCTIONAL == i_state) &&
                        !l_state.functional)
                    {
                        continue;
                    }

                    fapi::Target l_chiplet(i_chipletType,
                        reinterpret_cast<void *>(*chipletIter));
                    o_chiplets.push_back(l_chiplet);
                }
            }
        }
    }

    FAPI_DBG(EXIT_MRK "fapiGetChildChiplets. %d results", o_chiplets.size());
    return l_rc;
}
//******************************************************************************
//* name=mss_eff_config_rank_group, param=i_target_mba, return=ReturnCode
//******************************************************************************
fapi::ReturnCode mss_eff_config_rank_group(const fapi::Target i_target_mba) {
   fapi::ReturnCode rc = fapi::FAPI_RC_SUCCESS;
   const char * const PROCEDURE_NAME = "mss_eff_config_rank_group";
   const fapi::Target& TARGET_MBA = i_target_mba;
   FAPI_INF("*** Running %s on %s ... ***", PROCEDURE_NAME, i_target_mba.toEcmdString());

   const uint8_t PORT_SIZE = 2;
   const uint8_t DIMM_SIZE = 2;
   // ATTR_EFF_DRAM_GEN: EMPTY = 0, DDR3 = 1, DDR4 = 2,
   // ATTR_EFF_DIMM_TYPE: CDIMM = 0, RDIMM = 1, UDIMM = 2, LRDIMM = 3,
   uint8_t num_ranks_per_dimm_u8array[PORT_SIZE][DIMM_SIZE];
   uint8_t dram_gen_u8;
   uint8_t dimm_type_u8;

   rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target_mba, num_ranks_per_dimm_u8array); if(rc) return rc;
   rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_GEN, &i_target_mba, dram_gen_u8); if(rc) return rc;
   rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target_mba, dimm_type_u8); if(rc) return rc;

   uint8_t primary_rank_group0_u8array[PORT_SIZE];
   uint8_t primary_rank_group1_u8array[PORT_SIZE];
   uint8_t primary_rank_group2_u8array[PORT_SIZE];
   uint8_t primary_rank_group3_u8array[PORT_SIZE];
   uint8_t secondary_rank_group0_u8array[PORT_SIZE];
   uint8_t secondary_rank_group1_u8array[PORT_SIZE];
   uint8_t secondary_rank_group2_u8array[PORT_SIZE];
   uint8_t secondary_rank_group3_u8array[PORT_SIZE];
   uint8_t tertiary_rank_group0_u8array[PORT_SIZE];
   uint8_t tertiary_rank_group1_u8array[PORT_SIZE];
   uint8_t tertiary_rank_group2_u8array[PORT_SIZE];
   uint8_t tertiary_rank_group3_u8array[PORT_SIZE];
   uint8_t quanternary_rank_group0_u8array[PORT_SIZE];
   uint8_t quanternary_rank_group1_u8array[PORT_SIZE];
   uint8_t quanternary_rank_group2_u8array[PORT_SIZE];
   uint8_t quanternary_rank_group3_u8array[PORT_SIZE];

   for (uint8_t cur_port = 0; cur_port < PORT_SIZE; cur_port += 1) {
      //Removed 32G CDIMM 1R dualdrop workaround.
      //NOTE: Needs mss_draminit_training.C v1.57 or newer.
      //if ((dimm_type_u8 == CDIMM) && (num_ranks_per_dimm_u8array[cur_port][0] == 1) && (num_ranks_per_dimm_u8array[cur_port][1] == 1)) {
         // NOTE: 32G CDIMM 1R dualdrop workaround, normally primary_rank_group0=0, primary_rank_group1=4.
         //primary_rank_group0_u8array[cur_port] = 0;
         //primary_rank_group1_u8array[cur_port] = INVALID;
         //primary_rank_group2_u8array[cur_port] = INVALID;
         //primary_rank_group3_u8array[cur_port] = INVALID;
         //secondary_rank_group0_u8array[cur_port] = 4;
         //secondary_rank_group1_u8array[cur_port] = INVALID;
         //secondary_rank_group2_u8array[cur_port] = INVALID;
         //secondary_rank_group3_u8array[cur_port] = INVALID;
         //tertiary_rank_group0_u8array[cur_port] = INVALID;
         //tertiary_rank_group1_u8array[cur_port] = INVALID;
         //tertiary_rank_group2_u8array[cur_port] = INVALID;
         //tertiary_rank_group3_u8array[cur_port] = INVALID;
         //quanternary_rank_group0_u8array[cur_port] = INVALID;
         //quanternary_rank_group1_u8array[cur_port] = INVALID;
         //quanternary_rank_group2_u8array[cur_port] = INVALID;
         //quanternary_rank_group3_u8array[cur_port] = INVALID;
      //} else if (dimm_type_u8 == LRDIMM) {
      if (dimm_type_u8 == LRDIMM) {
         primary_rank_group2_u8array[cur_port] = INVALID;
         secondary_rank_group2_u8array[cur_port] = INVALID;
         tertiary_rank_group2_u8array[cur_port] = INVALID;
         quanternary_rank_group2_u8array[cur_port] = INVALID;

         primary_rank_group3_u8array[cur_port] = INVALID;
         secondary_rank_group3_u8array[cur_port] = INVALID;
         tertiary_rank_group3_u8array[cur_port] = INVALID;
         quanternary_rank_group3_u8array[cur_port] = INVALID;

         // dimm 0 (far socket)
         switch (num_ranks_per_dimm_u8array[cur_port][0]) {
           case 4:               // 4 rank lrdimm
                 primary_rank_group0_u8array[cur_port] = 0;
                 secondary_rank_group0_u8array[cur_port] = 1;
                 tertiary_rank_group0_u8array[cur_port] = 2;
                 quanternary_rank_group0_u8array[cur_port] = 3;
                 break;
           case 8:               // 8 rank lrdimm falls through to 2 rank case
         // Rank Multiplication mode needed, CS2 & CS3 used as address lines into LRBuffer
         // RM=4 -> only 2 CS valid, each CS controls 4 ranks with CS2 & CS3 as address
         // CS0 = rank 0, 2, 4, 6;  CS1 = rank 1, 3, 5, 7
           case 2:               // 2 rank lrdimm
                 primary_rank_group0_u8array[cur_port] = 0;
                 secondary_rank_group0_u8array[cur_port] = 1;
                 tertiary_rank_group0_u8array[cur_port] = INVALID;
                 quanternary_rank_group0_u8array[cur_port] = INVALID;
                 break;
           case 1:               // 1 rank lrdimm
                 primary_rank_group0_u8array[cur_port] = 0;
                 secondary_rank_group0_u8array[cur_port] = INVALID;
                 tertiary_rank_group0_u8array[cur_port] = INVALID;
                 quanternary_rank_group0_u8array[cur_port] = INVALID;
                 break;
           default:              // not 1, 2, 4, or 8 ranks
                 primary_rank_group0_u8array[cur_port] = INVALID;
                 secondary_rank_group0_u8array[cur_port] = INVALID;
                 tertiary_rank_group0_u8array[cur_port] = INVALID;
                 quanternary_rank_group0_u8array[cur_port] = INVALID;
         }
         // dimm 1 (near socket)
         switch (num_ranks_per_dimm_u8array[cur_port][1]) {
           case 4:               // 4 rank lrdimm
                 primary_rank_group1_u8array[cur_port] = 4;
                 secondary_rank_group1_u8array[cur_port] = 5;
                 tertiary_rank_group1_u8array[cur_port] = 6;
                 quanternary_rank_group1_u8array[cur_port] = 7;
                 break;
           case 8:               // 8 rank lrdimm falls through to case 2
         // Rank Multiplication mode needed, CS6 & CS7 used as address lines into LRBuffer
         // RM=4 -> only 2 CS valid, each CS controls 4 ranks with CS6 & CS7 as address
         // CS4 = rank 0, 2, 4, 6;  CS5 = rank 1, 3, 5, 7
           case 2:               // 2 rank lrdimm, RM=0
                 primary_rank_group1_u8array[cur_port] = 4;
                 secondary_rank_group1_u8array[cur_port] = 5;
                 tertiary_rank_group1_u8array[cur_port] = INVALID;
                 quanternary_rank_group1_u8array[cur_port] = INVALID;
                 break;
           case 1:               // 1 rank lrdimm
                 primary_rank_group1_u8array[cur_port] = 4;
                 secondary_rank_group1_u8array[cur_port] = INVALID;
                 tertiary_rank_group1_u8array[cur_port] = INVALID;
                 quanternary_rank_group1_u8array[cur_port] = INVALID;
                 break;
           default:              // not 1, 2, 4, or 8 ranks
                 primary_rank_group1_u8array[cur_port] = INVALID;
                 secondary_rank_group1_u8array[cur_port] = INVALID;
                 tertiary_rank_group1_u8array[cur_port] = INVALID;
                 quanternary_rank_group1_u8array[cur_port] = INVALID;
         }

      } else { // RDIMM or CDIMM
         if ((num_ranks_per_dimm_u8array[cur_port][0] > 0) && (num_ranks_per_dimm_u8array[cur_port][1] == 0)) {
            primary_rank_group0_u8array[cur_port] = 0;
            if (num_ranks_per_dimm_u8array[cur_port][0] > 1) {
               primary_rank_group1_u8array[cur_port] = 1;
            } else {
               primary_rank_group1_u8array[cur_port] = INVALID;
            }
            if (num_ranks_per_dimm_u8array[cur_port][0] > 2) {
               primary_rank_group2_u8array[cur_port] = 2;
               primary_rank_group3_u8array[cur_port] = 3;
            } else {
               primary_rank_group2_u8array[cur_port] = INVALID;
               primary_rank_group3_u8array[cur_port] = INVALID;
            }
            secondary_rank_group0_u8array[cur_port] = INVALID;
            secondary_rank_group1_u8array[cur_port] = INVALID;
            secondary_rank_group2_u8array[cur_port] = INVALID;
            secondary_rank_group3_u8array[cur_port] = INVALID;
         } else if ((num_ranks_per_dimm_u8array[cur_port][0] > 0) && (num_ranks_per_dimm_u8array[cur_port][1] > 0)) {
            if (num_ranks_per_dimm_u8array[cur_port][0] != num_ranks_per_dimm_u8array[cur_port][1]) {
               FAPI_ERR("%s: FAILED!", PROCEDURE_NAME);
               FAPI_ERR("Plug rule violation, num_ranks_per_dimm=%d[0],%d[1] on %s PORT%d!", num_ranks_per_dimm_u8array[cur_port][0], num_ranks_per_dimm_u8array[cur_port][1], i_target_mba.toEcmdString(), cur_port);
               FAPI_SET_HWP_ERROR(rc, RC_MSS_EFF_CONFIG_RANK_GROUP_NON_MATCH_RANKS);
               return rc;
            }
            primary_rank_group0_u8array[cur_port] = 0;
            primary_rank_group1_u8array[cur_port] = 4;
            primary_rank_group2_u8array[cur_port] = INVALID;
            primary_rank_group3_u8array[cur_port] = INVALID;
            secondary_rank_group0_u8array[cur_port] = INVALID;
            secondary_rank_group1_u8array[cur_port] = INVALID;
            secondary_rank_group2_u8array[cur_port] = INVALID;
            secondary_rank_group3_u8array[cur_port] = INVALID;
            if (num_ranks_per_dimm_u8array[cur_port][0] == 2) {
               primary_rank_group2_u8array[cur_port] = 1;
               primary_rank_group3_u8array[cur_port] = 5;
            } else if (num_ranks_per_dimm_u8array[cur_port][0] == 4) {
               primary_rank_group2_u8array[cur_port] = 2;
               primary_rank_group3_u8array[cur_port] = 6;
               secondary_rank_group0_u8array[cur_port] = 1;
               secondary_rank_group1_u8array[cur_port] = 5;
               secondary_rank_group2_u8array[cur_port] = 3;
               secondary_rank_group3_u8array[cur_port] = 7;
            } else if (num_ranks_per_dimm_u8array[cur_port][0] != 1) {
               FAPI_ERR("%s: FAILED!", PROCEDURE_NAME);
               FAPI_ERR("Plug rule violation, num_ranks_per_dimm=%d[0],%d[1] on %s PORT%d!", num_ranks_per_dimm_u8array[cur_port][0], num_ranks_per_dimm_u8array[cur_port][1], i_target_mba.toEcmdString(), cur_port);
               FAPI_SET_HWP_ERROR(rc, RC_MSS_EFF_CONFIG_RANK_GROUP_NUM_RANKS_NEQ1);
               return rc;
            }
         } else if ((num_ranks_per_dimm_u8array[cur_port][0] == 0) && (num_ranks_per_dimm_u8array[cur_port][1] == 0)) {
            primary_rank_group0_u8array[cur_port] = INVALID;
            primary_rank_group1_u8array[cur_port] = INVALID;
            primary_rank_group2_u8array[cur_port] = INVALID;
            primary_rank_group3_u8array[cur_port] = INVALID;
            secondary_rank_group0_u8array[cur_port] = INVALID;
            secondary_rank_group1_u8array[cur_port] = INVALID;
            secondary_rank_group2_u8array[cur_port] = INVALID;
            secondary_rank_group3_u8array[cur_port] = INVALID;
         } else {
            FAPI_ERR("%s: FAILED!", PROCEDURE_NAME);
            FAPI_ERR("Plug rule violation, num_ranks_per_dimm=%d[0],%d[1] on %s PORT%d!", num_ranks_per_dimm_u8array[cur_port][0], num_ranks_per_dimm_u8array[cur_port][1], i_target_mba.toEcmdString(), cur_port);
            FAPI_SET_HWP_ERROR(rc, RC_MSS_EFF_CONFIG_RANK_GROUP_NO_MATCH);
            return rc;
         }
         tertiary_rank_group0_u8array[cur_port] = INVALID;
         tertiary_rank_group1_u8array[cur_port] = INVALID;
         tertiary_rank_group2_u8array[cur_port] = INVALID;
         tertiary_rank_group3_u8array[cur_port] = INVALID;
         quanternary_rank_group0_u8array[cur_port] = INVALID;
         quanternary_rank_group1_u8array[cur_port] = INVALID;
         quanternary_rank_group2_u8array[cur_port] = INVALID;
         quanternary_rank_group3_u8array[cur_port] = INVALID;
      }
      FAPI_INF("P[%02d][%02d][%02d][%02d],S[%02d][%02d][%02d][%02d],T[%02d][%02d][%02d][%02d],Q[%02d][%02d][%02d][%02d] on %s PORT%d.", primary_rank_group0_u8array[cur_port], primary_rank_group1_u8array[cur_port], primary_rank_group2_u8array[cur_port], primary_rank_group3_u8array[cur_port], secondary_rank_group0_u8array[cur_port], secondary_rank_group1_u8array[cur_port], secondary_rank_group2_u8array[cur_port], secondary_rank_group3_u8array[cur_port], tertiary_rank_group0_u8array[cur_port], tertiary_rank_group1_u8array[cur_port], tertiary_rank_group2_u8array[cur_port], tertiary_rank_group3_u8array[cur_port], quanternary_rank_group0_u8array[cur_port], quanternary_rank_group1_u8array[cur_port], quanternary_rank_group2_u8array[cur_port], quanternary_rank_group3_u8array[cur_port], i_target_mba.toEcmdString(), cur_port);
   }
   rc = FAPI_ATTR_SET(ATTR_EFF_PRIMARY_RANK_GROUP0, &i_target_mba, primary_rank_group0_u8array); if(rc) return rc;
   rc = FAPI_ATTR_SET(ATTR_EFF_PRIMARY_RANK_GROUP1, &i_target_mba, primary_rank_group1_u8array); if(rc) return rc;
   rc = FAPI_ATTR_SET(ATTR_EFF_PRIMARY_RANK_GROUP2, &i_target_mba, primary_rank_group2_u8array); if(rc) return rc;
   rc = FAPI_ATTR_SET(ATTR_EFF_PRIMARY_RANK_GROUP3, &i_target_mba, primary_rank_group3_u8array); if(rc) return rc;
   rc = FAPI_ATTR_SET(ATTR_EFF_SECONDARY_RANK_GROUP0, &i_target_mba, secondary_rank_group0_u8array); if(rc) return rc;
   rc = FAPI_ATTR_SET(ATTR_EFF_SECONDARY_RANK_GROUP1, &i_target_mba, secondary_rank_group1_u8array); if(rc) return rc;
   rc = FAPI_ATTR_SET(ATTR_EFF_SECONDARY_RANK_GROUP2, &i_target_mba, secondary_rank_group2_u8array); if(rc) return rc;
   rc = FAPI_ATTR_SET(ATTR_EFF_SECONDARY_RANK_GROUP3, &i_target_mba, secondary_rank_group3_u8array); if(rc) return rc;
   rc = FAPI_ATTR_SET(ATTR_EFF_TERTIARY_RANK_GROUP0, &i_target_mba, tertiary_rank_group0_u8array); if(rc) return rc;
   rc = FAPI_ATTR_SET(ATTR_EFF_TERTIARY_RANK_GROUP1, &i_target_mba, tertiary_rank_group1_u8array); if(rc) return rc;
   rc = FAPI_ATTR_SET(ATTR_EFF_TERTIARY_RANK_GROUP2, &i_target_mba, tertiary_rank_group2_u8array); if(rc) return rc;
   rc = FAPI_ATTR_SET(ATTR_EFF_TERTIARY_RANK_GROUP3, &i_target_mba, tertiary_rank_group3_u8array); if(rc) return rc;
   rc = FAPI_ATTR_SET(ATTR_EFF_QUATERNARY_RANK_GROUP0, &i_target_mba, quanternary_rank_group0_u8array); if(rc) return rc;
   rc = FAPI_ATTR_SET(ATTR_EFF_QUATERNARY_RANK_GROUP1, &i_target_mba, quanternary_rank_group1_u8array); if(rc) return rc;
   rc = FAPI_ATTR_SET(ATTR_EFF_QUATERNARY_RANK_GROUP2, &i_target_mba, quanternary_rank_group2_u8array); if(rc) return rc;
   rc = FAPI_ATTR_SET(ATTR_EFF_QUATERNARY_RANK_GROUP3, &i_target_mba, quanternary_rank_group3_u8array); if(rc) return rc;

   FAPI_INF("%s on %s COMPLETE", PROCEDURE_NAME, i_target_mba.toEcmdString());
   return rc;
}
Beispiel #17
0
//******************************************************************************
// fapiGetAssociatedDimms function
//******************************************************************************
fapi::ReturnCode fapiGetAssociatedDimms(
    const fapi::Target& i_target,
    std::vector<fapi::Target> & o_dimms,
    const fapi::TargetState i_state)
{
    FAPI_DBG(ENTER_MRK "fapiGetAssociatedDimms. State: 0x%08x", i_state);

    fapi::ReturnCode l_rc;
    o_dimms.clear();

    // Extract the HostBoot Target pointer for the input target
    TARGETING::Target * l_pTarget =
        reinterpret_cast<TARGETING::Target*>(i_target.get());

    if (l_pTarget == NULL)
    {
        FAPI_ERR("fapiGetAssociatedDimms. Embedded NULL target pointer");
        /*@
         * @errortype
         * @moduleid     fapi::MOD_FAPI_GET_ASSOCIATE_DIMMS
         * @reasoncode   fapi::RC_EMBEDDED_NULL_TARGET_PTR
         * @devdesc      Target has embedded null target pointer
         */
        const bool hbSwError = true;
        errlHndl_t l_pError = new ERRORLOG::ErrlEntry(
                ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                fapi::MOD_FAPI_GET_ASSOCIATE_DIMMS,
                fapi::RC_EMBEDDED_NULL_TARGET_PTR,
                0, 0, hbSwError);

        // Attach the error log to the fapi::ReturnCode
        l_rc.setPlatError(reinterpret_cast<void *> (l_pError));
    }
    else
    {
        // Get associated dimms
        TARGETING::PredicateCTM l_predicate(TARGETING::CLASS_LOGICAL_CARD,
                                            TARGETING::TYPE_DIMM);
        TARGETING::TargetHandleList l_dimmList;

        TARGETING::targetService().
        getAssociated(l_dimmList, l_pTarget,
                      TARGETING::TargetService::CHILD_BY_AFFINITY,
                      TARGETING::TargetService::ALL, &l_predicate);

        // Return fapi::Targets to the caller
        for (TARGETING::TargetHandleList::const_iterator
                dimmIter = l_dimmList.begin();
                dimmIter != l_dimmList.end();
                ++dimmIter)
        {
            TARGETING::HwasState l_state =
                (*dimmIter)->getAttr<TARGETING::ATTR_HWAS_STATE>();

            if ((fapi::TARGET_STATE_PRESENT == i_state) && !l_state.present)
            {
                continue;
            }
            if ((fapi::TARGET_STATE_FUNCTIONAL == i_state) &&
                !l_state.functional)
            {
                continue;
            }

            fapi::Target l_dimm(fapi::TARGET_TYPE_DIMM,
                                reinterpret_cast<void *>(*dimmIter));
            o_dimms.push_back(l_dimm);
        }
    }

    FAPI_DBG(EXIT_MRK "fapiGetAssociatedDimms. %d results", o_dimms.size());
    return l_rc;
}
Beispiel #18
0
// HWP entry point
fapi::ReturnCode proc_getecid(
    const fapi::Target& i_target,
    ecmdDataBufferBase& io_fuseString)
{
    // return code
    fapi::ReturnCode rc;
    uint32_t rc_ecmd = 0;
    uint64_t attr_data[2];

    // mark HWP entry
    FAPI_DBG("proc_getecid: Start");

    io_fuseString.setBitLength(112); // sets size and zeros out buffer
    ecmdDataBufferBase otprom_mode_data(64);
    ecmdDataBufferBase ecid_data(64);

    do
    {

      //
      // clear ECC enable before reading ECID data (read-modify-write OTPROM Mode register)
      //

      rc = fapiGetScom(i_target, OTPC_M_MODE_REGISTER_0x00010008, otprom_mode_data);
      if (!rc.ok())
      {
          FAPI_ERR("proc_getecid: fapiGetScom error (OTPC_M_MODE_REGISTER_0x00010008) for %s",
                   i_target.toEcmdString());
          break;
      }

      rc_ecmd |= otprom_mode_data.clearBit(OTPC_M_MODE_REGISTER_ECC_ENABLE_BIT);
      if (rc_ecmd)
      {
          FAPI_ERR("proc_getecid: Error 0x%X setting up OTPROM Mode register data buffer",
                   rc_ecmd);
          rc.setEcmdError(rc_ecmd);
          break;
      }

      rc = fapiPutScom(i_target, OTPC_M_MODE_REGISTER_0x00010008, otprom_mode_data);
      if (!rc.ok())
      {
          FAPI_ERR("proc_getecid: fapiPutScom error (OTPC_M_MODE_REGISTER_0x00010008) for %s",
                   i_target.toEcmdString());
          break;
      }


      //
      // extract and manipulate ECID data
      //

      rc = fapiGetScom(i_target, ECID_PART_0_0x00018000, ecid_data);
      if (!rc.ok())
      {
          FAPI_ERR("proc_getecid: fapiGetScom error (ECID_PART_0_0x00018000) for %s",
                   i_target.toEcmdString());
          break;
      }

      // 0:63 become 63:0
      rc_ecmd |= ecid_data.reverse();
      // copy bits 0:63 from the scom into 0:63 of the fuseString/attribute data
      rc_ecmd |= io_fuseString.insert(ecid_data,  0, 64);
      attr_data[0] = ecid_data.getDoubleWord(0);

      if (rc_ecmd)
      {
          FAPI_ERR("proc_getecid: Error 0x%X processing ECID (part 0) data buffer",
                   rc_ecmd);
          rc.setEcmdError(rc_ecmd);
          break;
      }

      rc = fapiGetScom(i_target, ECID_PART_1_0x00018001, ecid_data);
      if (!rc.ok())
      {
          FAPI_ERR("proc_getecid: fapiGetScom error (ECID_PART_1_0x00018001) for %s",
                   i_target.toEcmdString());
          break;
      }

      // 0:63 become 63:0
      rc_ecmd |= ecid_data.reverse();
      // copy bits 0:47 from the scom into 64:111 of the fuseString
      // all bits into attribute data
      rc_ecmd |= io_fuseString.insert(ecid_data, 64, 48);
      attr_data[1] = ecid_data.getDoubleWord(0);

      if (rc_ecmd)
      {
          FAPI_ERR("proc_getecid: Error 0x%X processing ECID (part 1) data buffer",
                   rc_ecmd);
          rc.setEcmdError(rc_ecmd);
          break;
      }

      // push fuse string into attribute
      rc = FAPI_ATTR_SET(ATTR_ECID,
                         &i_target,
                         attr_data);
      if (!rc.ok())
      {
          FAPI_ERR("proc_getecid: Error from FAPI_ATTR_SET (ATTR_ECID) for %s (attr_data[0] = %016llX, attr_data[1] = %016llX",
                   i_target.toEcmdString(), attr_data[0], attr_data[1]);
          break;
      }

      //
      // restore ECC enable setting
      //

      rc_ecmd |= otprom_mode_data.setBit(OTPC_M_MODE_REGISTER_ECC_ENABLE_BIT);
      if (rc_ecmd)
      {
          FAPI_ERR("proc_getecid: Error 0x%X setting up OTPROM Mode register data buffer",
                   rc_ecmd);
          rc.setEcmdError(rc_ecmd);
          break;
      }

      rc = fapiPutScom(i_target, OTPC_M_MODE_REGISTER_0x00010008, otprom_mode_data);
      if (!rc.ok())
      {
          FAPI_ERR("proc_getecid: fapiPutScom error (OTPC_M_MODE_REGISTER_0x00010008) for %s",
                   i_target.toEcmdString());
          break;
      }

    } while(0);

    // mark HWP exit
    FAPI_DBG("proc_getecid: End");
    return rc;
}
Beispiel #19
0
//******************************************************************************
// fapiSpecialWakeup
//******************************************************************************
fapi::ReturnCode fapiSpecialWakeup(const fapi::Target & i_target,
                                   const bool i_enable)
{
    fapi::ReturnCode fapi_rc = fapi::FAPI_RC_SUCCESS;
    FAPI_INF("fapiSpecialWakeup");
#ifdef __HOSTBOOT_RUNTIME
    if(!INITSERVICE::spBaseServicesEnabled())
    {
        TARGETING::Target* l_EXtarget =
            reinterpret_cast<TARGETING::Target*>(i_target.get());

        errlHndl_t err_SW = handleSpecialWakeup(l_EXtarget,i_enable);
        if(err_SW)
        {
            fapi_rc.setPlatError(reinterpret_cast<void *>(err_SW));
        }

    }
    else if(g_hostInterfaces && g_hostInterfaces->wakeup)
    {
        TARGETING::Target* target =
            reinterpret_cast<TARGETING::Target*>(i_target.get());

        RT_TARG::rtChipId_t core_id = 0;
        errlHndl_t err = RT_TARG::getRtTarget(target, core_id);
        if(err)
        {
            fapi_rc.setPlatError(reinterpret_cast<void *>(err));
        }
        else
        {
            uint32_t mode = 0;   //Force awake
            if(!i_enable)
            {
                mode = 1;       // clear force
            }
            int rc = g_hostInterfaces->wakeup(core_id, mode);

            if(rc)
            {
                FAPI_ERR("CPU core wakeup call to hypervisor returned rc = %d",
                         rc);
                /*@
                 * @errortype
                 * @moduleid     fapi::MOD_PLAT_SPECIAL_WAKEUP
                 * @reasoncode   fapi::RC_RT_WAKEUP_FAILED
                 * @userdata1    Hypervisor return code
                 * @userdata2    Chiplet HUID
                 * @devdesc      Error code from hypervisor wakeup call
                 */
                const bool hbSwError = true;
                err = new ERRORLOG::ErrlEntry(
                                              ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                              fapi::MOD_PLAT_SPECIAL_WAKEUP,
                                              fapi::RC_RT_WAKEUP_FAILED,
                                              rc,
                                              TARGETING::get_huid(target),
                                              hbSwError);

                fapi_rc.setPlatError(reinterpret_cast<void*>(err));
            }
        }
    }
#endif
    // On Hostboot, processor cores cannot sleep so return success to the
    // fapiSpecialWakeup enable/disable calls
    return fapi_rc;
}