Skip to content

Commit

Permalink
Added MRS attributes and MRS data handling for Explorer
Browse files Browse the repository at this point in the history
Change-Id: Ia5db0e40c9d0f3bdcc590a7803471f7dc0fdcd77
git-coreq:hostboot:Ia5db0e40c9d0f3bdcc590a7803471f7dc0fdcd77
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/89850
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Dev-Ready: STEPHEN GLANCY <sglancy@us.ibm.com>
Reviewed-by: Mark Pizzutillo <mark.pizzutillo@ibm.com>
Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com>
Reviewed-by: Louis Stermole <stermole@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Jennifer A Stofer <stofer@us.ibm.com>
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/90875
Reviewed-by: Daniel M Crowell <dcrowell@us.ibm.com>
Tested-by: Daniel M Crowell <dcrowell@us.ibm.com>
  • Loading branch information
Matthickman14 authored and dcrowell77 committed Apr 22, 2020
1 parent f253133 commit 6db3d46
Show file tree
Hide file tree
Showing 31 changed files with 1,271 additions and 1,759 deletions.
Expand Up @@ -62,15 +62,6 @@ class mrsTraits<mss::mc_type::EXPLORER>
static constexpr uint64_t TCCD_S = 4;
static constexpr uint64_t TMRD = 16;

///
/// @brief Returns an error for bad mrs parameter
/// @return mrs error
///
static fapi2::MSS_BAD_MR_PARAMETER bad_mr_parameter()
{
return fapi2::MSS_BAD_MR_PARAMETER();
}

///
/// @brief Returns if rcd mirror mode on
/// @return false, currently set to disabled
Expand All @@ -84,13 +75,36 @@ class mrsTraits<mss::mc_type::EXPLORER>
///
/// @brief Returns if mirror mode is enabled, currently set to disabled
/// @param[in] const ref to the fapi2::Target<fapi2::TARGET_TYPE_DIMM>
/// @param[in] i_rank the rank on which to operate from the port perspective
/// @param[out] ref to the value uint8_t
/// @return fapi2::ReturnCode - FAPI2_RC_SUCCESS iff get is OK
///
static fapi2::ReturnCode mirror_mode(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const uint64_t i_rank,
uint8_t& o_value)
{
return mss::attr::get_exp_dram_address_mirroring(i_target, o_value);
constexpr uint64_t SINGLE_RANK_MASK = 0x1;

// Makes sure that we have a good rank passed in
FAPI_ASSERT(i_rank < mss::exp::MAX_MRANK_PER_PORT,
fapi2::MSS_INVALID_RANK().
set_FUNCTION(mss::generic_ffdc_codes::MRS_MIRROR_MODE).
set_RANK(i_rank).
set_PORT_TARGET(mss::find_target<fapi2::TARGET_TYPE_MEM_PORT>(i_target)),
"%s mirror mode received invalid rank: %d",
mss::c_str(i_target), i_rank);

FAPI_TRY(mss::attr::get_exp_dram_address_mirroring(i_target, o_value));

{
const auto l_dimm_rank = i_rank % mss::exp::MAX_RANK_PER_DIMM;
o_value = o_value >> l_dimm_rank;
o_value &= SINGLE_RANK_MASK;
}

return fapi2::FAPI2_RC_SUCCESS;
fapi_try_exit:
return fapi2::current_err;
}

///
Expand Down
Expand Up @@ -51,35 +51,60 @@ namespace unmask
{

///
/// @brief Check if any dimms exist that have RCD enabled
/// @brief Check if any dimms exist that have RCD enabled - explorer/PORT specialization
/// @param[in] i_target - the fapi2::Target we are starting from
/// @param[out] o_has_rcd - true iff any DIMM with RCD detected
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
template<>
fapi2::ReturnCode has_rcd<mss::mc_type::EXPLORER>( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
fapi2::ReturnCode has_rcd<mss::mc_type::EXPLORER>( const fapi2::Target<fapi2::TARGET_TYPE_MEM_PORT>& i_target,
bool& o_has_rcd )
{
// Assume RCD is not supported at beginning of check
o_has_rcd = false;

// Nested for loops to determine DIMM type if DIMMs exist
for (const auto& l_port : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target))
// Loop over all DIMM's and determine if we have an RCD
for(const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target))
{
for(const auto& l_dimm : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(l_port))
{
uint8_t l_dimm_type = 0;
uint8_t l_rcd_supported = 0;
uint8_t l_dimm_type = 0;
uint8_t l_rcd_supported = 0;

FAPI_TRY(mss::attr::get_dimm_type(l_dimm, l_dimm_type));
FAPI_TRY(mss::attr::get_supported_rcd(l_dimm, l_rcd_supported));

// OR with tmp_rcd to maintain running true/false if RCD on *any* DIMM
o_has_rcd |= ((l_dimm_type == fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_RDIMM) ||
(l_dimm_type == fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_LRDIMM));

o_has_rcd |= (l_rcd_supported == fapi2::ENUM_ATTR_MEM_EFF_SUPPORTED_RCD_RCD_PER_CHANNEL_1);
}

FAPI_TRY(mss::attr::get_dimm_type(l_dimm, l_dimm_type));
FAPI_TRY(mss::attr::get_supported_rcd(l_dimm, l_rcd_supported));
return fapi2::FAPI2_RC_SUCCESS;

// OR with tmp_rcd to maintain running true/false if RCD on *any* DIMM
o_has_rcd |= ((l_dimm_type == fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_RDIMM) ||
(l_dimm_type == fapi2::ENUM_ATTR_MEM_EFF_DIMM_TYPE_LRDIMM));
fapi_try_exit:

o_has_rcd |= (l_rcd_supported == fapi2::ENUM_ATTR_MEM_EFF_SUPPORTED_RCD_RCD_PER_CHANNEL_1);
}
return fapi2::current_err;
}

///
/// @brief Check if any dimms exist that have RCD enabled - explorer/OCMB specialization
/// @param[in] i_target - the fapi2::Target we are starting from
/// @param[out] o_has_rcd - true iff any DIMM with RCD detected
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
template<>
fapi2::ReturnCode has_rcd<mss::mc_type::EXPLORER>( const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
bool& o_has_rcd )
{
// Assume RCD is not supported at beginning of check
o_has_rcd = false;

// Nested for loops to determine DIMM type if DIMMs exist
for (const auto& l_port : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target))
{
bool l_current_port_rcd = false;
FAPI_TRY(has_rcd<mss::mc_type::EXPLORER>(l_port, l_current_port_rcd));
o_has_rcd |= l_current_port_rcd;
}

return fapi2::FAPI2_RC_SUCCESS;
Expand Down
Expand Up @@ -109,5 +109,208 @@ fapi_try_exit:
return fapi2::current_err;
}

///
/// @brief Parse the MRS data from the response to correct attributes
/// @param[in] i_target OCMB chip
/// @param[in] i_resp MRS response struct
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff success
///
fapi2::ReturnCode parse_mrs_data_attributes(const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_target,
const user_response_mrs_msdg_t& i_resp)
{
using TT = mss::rank::rankTraits<mss::mc_type::EXPLORER>;

uint8_t l_temp_attr = 0;

fapi2::buffer<uint16_t> l_MR0(i_resp.MR0);
fapi2::buffer<uint16_t> l_MR1(i_resp.MR1[0]);
fapi2::buffer<uint16_t> l_MR2(i_resp.MR2[0]);
fapi2::buffer<uint16_t> l_MR3(i_resp.MR3);
fapi2::buffer<uint16_t> l_MR4(i_resp.MR4);
fapi2::buffer<uint16_t> l_MR5(i_resp.MR5[0]);
fapi2::buffer<uint16_t> l_MR6(i_resp.MR6[0][0]);

for (const auto& l_port_target : mss::find_targets<fapi2::TARGET_TYPE_MEM_PORT>(i_target))
{
uint8_t l_odic_arr[mss::exp::MAX_DIMM_PER_PORT][TT::MAX_RANKS_PER_DIMM] = {0};
uint8_t l_rtt_nom_arr[mss::exp::MAX_DIMM_PER_PORT][TT::MAX_RANKS_PER_DIMM] = {0};
uint8_t l_rtt_wr_arr[mss::exp::MAX_DIMM_PER_PORT][TT::MAX_RANKS_PER_DIMM] = {0};
uint8_t l_rtt_park_arr[mss::exp::MAX_DIMM_PER_PORT][TT::MAX_RANKS_PER_DIMM] = {0};
uint8_t l_vrefdq_value[mss::exp::MAX_DIMM_PER_PORT][TT::MAX_RANKS_PER_DIMM][mss::exp::MAX_NIBBLES_PER_PORT] = {0};
uint8_t l_vrefdq_range[mss::exp::MAX_DIMM_PER_PORT][TT::MAX_RANKS_PER_DIMM][mss::exp::MAX_NIBBLES_PER_PORT] = {0};
uint8_t l_vrefdq_enable[mss::exp::MAX_DIMM_PER_PORT][TT::MAX_RANKS_PER_DIMM][mss::exp::MAX_NIBBLES_PER_PORT] = {0};

std::vector<mss::rank::info<>> l_ranks;
FAPI_TRY(mss::rank::ranks_on_port(l_port_target, l_ranks));

// Parse MR0 Attributes
l_temp_attr = l_MR0.getBit<MR0_EFF_DRAM_RBT>();
FAPI_TRY( mss::attr::set_exp_resp_dram_rbt(l_port_target, l_temp_attr) );

l_temp_attr = l_MR0.getBit<MR0_EFF_DRAM_TM>();
FAPI_TRY( mss::attr::set_exp_resp_dram_tm(l_port_target, l_temp_attr) );

l_temp_attr = l_MR0.getBit<MR0_EFF_DRAM_DLL_RESET>();
FAPI_TRY( mss::attr::set_exp_resp_dram_dll_reset(l_port_target, l_temp_attr) );

l_temp_attr = 0;
l_MR0.extractToRight<MR0_EFF_BURST_LENGTH, MR0_EFF_BURST_LENGTH_LEN>(l_temp_attr);
FAPI_TRY( mss::attr::set_exp_resp_dram_burst_length(l_port_target, l_temp_attr) );

// Parse MR1 Attributes
l_temp_attr = l_MR1.getBit<MR1_EFF_DRAM_DLL_ENABLE>();
FAPI_TRY( mss::attr::set_exp_resp_dram_dll_enable(l_port_target, l_temp_attr) );

l_temp_attr = 0;
l_MR1.extractToRight<MR1_EFF_DRAM_AL, MR1_EFF_DRAM_AL_LEN>(l_temp_attr);
FAPI_TRY( mss::attr::set_exp_resp_dram_al(l_port_target, l_temp_attr) );

l_temp_attr = l_MR1.getBit<MR1_EFF_DRAM_WR_LVL_ENABLE>();
FAPI_TRY( mss::attr::set_exp_resp_dram_wr_lvl_enable(l_port_target, l_temp_attr) );

l_temp_attr = l_MR1.getBit<MR1_EFF_DRAM_TDQS>();
FAPI_TRY( mss::attr::set_exp_resp_dram_tdqs(l_port_target, l_temp_attr) );

l_temp_attr = l_MR1.getBit<MR1_EFF_DRAM_OUTPUT_BUFFER>();
FAPI_TRY( mss::attr::set_exp_resp_dram_output_buffer(l_port_target, l_temp_attr) );

// Parse MR2 Attributes
l_temp_attr = 0;
l_MR2.extractToRight<MR2_EFF_DRAM_LPASR, MR2_EFF_DRAM_LPASR_LEN>(l_temp_attr);
FAPI_TRY( mss::attr::set_exp_resp_dram_lpasr(l_port_target, l_temp_attr) );

// Parse MR3 Attributes
l_temp_attr = 0;
l_MR3.extractToRight<MR3_EFF_MPR_PAGE, MR3_EFF_MPR_PAGE_LEN>(l_temp_attr);
FAPI_TRY( mss::attr::set_exp_resp_mpr_page(l_port_target, l_temp_attr) );

l_temp_attr = l_MR3.getBit<MR3_EFF_MPR_MODE>();
FAPI_TRY( mss::attr::set_exp_resp_mpr_mode(l_port_target, l_temp_attr) );

l_temp_attr = l_MR3.getBit<MR3_EFF_GEARDOWN_MODE>();
FAPI_TRY( mss::attr::set_exp_resp_geardown_mode(l_port_target, l_temp_attr) );

l_temp_attr = l_MR3.getBit<MR3_EFF_PER_DRAM_ACCESS>();
FAPI_TRY( mss::attr::set_exp_resp_per_dram_access(l_port_target, l_temp_attr) );

l_temp_attr = l_MR3.getBit<MR3_EFF_TEMP_READOUT>();
FAPI_TRY( mss::attr::set_exp_resp_temp_readout(l_port_target, l_temp_attr) );

l_temp_attr = 0;
l_MR3.extractToRight<MR3_EFF_CRC_WR_LATENCY, MR3_EFF_CRC_WR_LATENCY_LEN>(l_temp_attr);
FAPI_TRY( mss::attr::set_exp_resp_crc_wr_latency(l_port_target, l_temp_attr) );

l_temp_attr = 0;
l_MR3.extractToRight<MR3_EFF_MPR_RD_FORMAT, MR3_EFF_MPR_RD_FORMAT_LEN>(l_temp_attr);
FAPI_TRY( mss::attr::set_exp_resp_mpr_rd_format(l_port_target, l_temp_attr) );

// Parse MR4 Attributes
l_temp_attr = l_MR4.getBit<MR4_EFF_MAX_POWERDOWN_MODE>();
FAPI_TRY( mss::attr::set_exp_resp_max_powerdown_mode(l_port_target, l_temp_attr) );

l_temp_attr = l_MR4.getBit<MR4_EFF_INTERNAL_VREF_MONITOR>();
FAPI_TRY( mss::attr::set_exp_resp_internal_vref_monitor(l_port_target, l_temp_attr) );

l_temp_attr = l_MR4.getBit<MR4_EFF_SELF_REF_ABORT>();
FAPI_TRY( mss::attr::set_exp_resp_self_ref_abort(l_port_target, l_temp_attr) );

l_temp_attr = l_MR4.getBit<MR4_EFF_RD_PREAMBLE_TRAIN>();
FAPI_TRY( mss::attr::set_exp_resp_rd_preamble_train(l_port_target, l_temp_attr) );

l_temp_attr = l_MR4.getBit<MR4_EFF_RD_PREAMBLE>();
FAPI_TRY( mss::attr::set_exp_resp_rd_preamble(l_port_target, l_temp_attr) );

l_temp_attr = l_MR4.getBit<MR4_EFF_WR_PREAMBLE>();
FAPI_TRY( mss::attr::set_exp_resp_wr_preamble(l_port_target, l_temp_attr) );

// Parse MR5 Attributes
l_temp_attr = l_MR5.getBit<MR5_EFF_CRC_ERROR_CLEAR>();
FAPI_TRY( mss::attr::set_exp_resp_crc_error_clear(l_port_target, l_temp_attr) );

l_temp_attr = l_MR5.getBit<MR5_EFF_CA_PARITY_ERROR_STATUS>();
FAPI_TRY( mss::attr::set_exp_resp_ca_parity_error_status(l_port_target, l_temp_attr) );

l_temp_attr = l_MR5.getBit<MR5_EFF_ODT_INPUT_BUFF>();
FAPI_TRY( mss::attr::set_exp_resp_odt_input_buff(l_port_target, l_temp_attr) );

l_temp_attr = l_MR5.getBit<MR5_EFF_CA_PARITY>();
FAPI_TRY( mss::attr::set_exp_resp_ca_parity(l_port_target, l_temp_attr) );

l_temp_attr = l_MR5.getBit<MR5_EFF_DATA_MASK>();
FAPI_TRY( mss::attr::set_exp_resp_data_mask(l_port_target, l_temp_attr) );

l_temp_attr = l_MR5.getBit<MR5_EFF_WRITE_DBI>();
FAPI_TRY( mss::attr::set_exp_resp_write_dbi(l_port_target, l_temp_attr) );

l_temp_attr = l_MR5.getBit<MR5_EFF_READ_DBI>();
FAPI_TRY( mss::attr::set_exp_resp_read_dbi(l_port_target, l_temp_attr) );

// Parse rank based MRs
// Note: we're only parsing for existing ranks
// Any ranks that do not exist will have 0 values for their attributes
// That's ok, we should not use those values anyways
for(const auto& l_rank_info : l_ranks)
{
const auto l_phy_rank = l_rank_info.get_phy_rank();
const auto l_dimm_rank = l_rank_info.get_dimm_rank();
const auto l_dimm_index = mss::index(l_rank_info.get_dimm_target());

// Set Rank level MRs
fapi2::buffer<uint16_t> l_MR1_Rank(i_resp.MR1[l_phy_rank]);
fapi2::buffer<uint16_t> l_MR2_Rank(i_resp.MR2[l_phy_rank]);
fapi2::buffer<uint16_t> l_MR5_Rank(i_resp.MR5[l_phy_rank]);

l_temp_attr = 0;
l_MR1_Rank.extractToRight<MR1_EFF_DRAM_ODIC, MR1_EFF_DRAM_ODIC_LEN>(l_temp_attr);
l_odic_arr[l_dimm_index][l_dimm_rank] = l_temp_attr;

l_temp_attr = 0;
l_MR1_Rank.extractToRight<MR1_EFF_DRAM_RTT_NOM, MR1_EFF_DRAM_RTT_NOM_LEN>(l_temp_attr);
l_rtt_nom_arr[l_dimm_index][l_dimm_rank] = l_temp_attr;

l_temp_attr = 0;
l_MR2_Rank.extractToRight<MR2_EFF_DRAM_RTT_WR, MR2_EFF_DRAM_RTT_WR_LEN>(l_temp_attr);
l_rtt_wr_arr[l_dimm_index][l_dimm_rank] = l_temp_attr;

l_temp_attr = 0;
l_MR5_Rank.extractToRight<MR5_EFF_DRAM_RTT_PARK, MR5_EFF_DRAM_RTT_PARK_LEN>(l_temp_attr);
l_rtt_park_arr[l_dimm_index][l_dimm_rank] = l_temp_attr;

// Set DRAM based MRs
for (int d = 0; d < mss::exp::MAX_NIBBLES_PER_PORT; d++)
{
fapi2::buffer<uint16_t> l_MR6_Rank(i_resp.MR6[l_phy_rank][d]);

l_temp_attr = l_MR6.getBit<MR6_VREFDQ_TRAINING_RANGE>();
l_vrefdq_range[l_dimm_index][l_dimm_rank][d] = l_temp_attr;

l_temp_attr = l_MR6.getBit<MR6_VREFDQ_TRAINING_ENABLE>();
l_vrefdq_enable[l_dimm_index][l_dimm_rank][d] = l_temp_attr;

l_temp_attr = 0;
l_MR6_Rank.extractToRight<MR6_VREFDQ_TRAINING_VALUE, MR6_VREFDQ_TRAINING_VALUE_LEN>(l_temp_attr);
l_vrefdq_value[l_dimm_index][l_dimm_rank][d] = l_temp_attr;

} // End of DRAM loop

} // End rank loop

FAPI_TRY( mss::attr::set_exp_resp_vref_dq_train_value(l_port_target, l_vrefdq_value) );
FAPI_TRY( mss::attr::set_exp_resp_vref_dq_train_range(l_port_target, l_vrefdq_range) );
FAPI_TRY( mss::attr::set_exp_resp_vref_dq_train_enable(l_port_target, l_vrefdq_enable) );
FAPI_TRY( mss::attr::set_exp_resp_dram_odic(l_port_target, l_odic_arr) );
FAPI_TRY( mss::attr::set_exp_resp_dram_rtt_nom(l_port_target, l_rtt_nom_arr) );
FAPI_TRY( mss::attr::set_exp_resp_dram_rtt_park(l_port_target, l_rtt_park_arr) );
FAPI_TRY( mss::attr::set_exp_resp_dram_rtt_wr(l_port_target, l_rtt_wr_arr) );

} // End port loop

return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
FAPI_DBG("Exiting with return code : 0x%08X...", (uint64_t)fapi2::current_err);
return fapi2::current_err;
}

} // ns exp
} // ns mss

0 comments on commit 6db3d46

Please sign in to comment.