Skip to content

Commit

Permalink
Add structure and read of MCBIST compare test results
Browse files Browse the repository at this point in the history
  Add Suet actions for MCBIST RMW and RB array reads

Change-Id: Ie0de88652b8c61f3a66566ece1889996a1be5638
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/33178
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com>
Reviewed-by: JACOB L. HARVEY <jlharvey@us.ibm.com>
Reviewed-by: Brian R. Silver <bsilver@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/33602
Reviewed-by: Hostboot Team <hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
  • Loading branch information
stermole authored and dcrowell77 committed Jan 24, 2017
1 parent 2508661 commit 61ea8ae
Show file tree
Hide file tree
Showing 2 changed files with 322 additions and 1 deletion.
141 changes: 141 additions & 0 deletions src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.C
Expand Up @@ -40,6 +40,7 @@

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_MCS;

namespace mss
{
Expand Down Expand Up @@ -490,6 +491,146 @@ fapi_try_exit:
return fapi2::current_err;
}

///
/// @brief Read entries from MCBIST Read Modify Write (RMW) array
/// Specialization for fapi2::TARGET_TYPE_MCA
/// @param[in] i_target the target to effect
/// @param[in] i_start_addr the array address to read first
/// @param[in] i_num_entries the number of array entries to read
/// @param[in] i_roll_over_for_compare_mode set to true if only using first
/// NUM_COMPARE_INFO_ENTRIES of array, so array address rolls over at correct value
/// @param[out] o_data vector of output data
/// @param[out] o_ecc_data vector of ecc data
/// @return FAPI2_RC_SUCCSS iff ok
/// @note The number of entries in the array depends on i_roll_over_for_compare_mode parameter:
/// (NUM_COMPARE_LOG_ENTRIES for false, NUM_COMPARE_INFO_ENTRIES for true) but user may read more than
/// that since reads work in a circular buffer fashion
///
template<>
fapi2::ReturnCode read_rmw_array(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const uint64_t i_start_addr,
const uint64_t i_num_entries,
const bool i_roll_over_for_compare_mode,
std::vector< fapi2::buffer<uint64_t> >& o_data,
std::vector< fapi2::buffer<uint64_t> >& o_ecc_data)
{
typedef mcbistTraits<fapi2::TARGET_TYPE_MCA> TT;

fapi2::buffer<uint64_t> l_control_value;
fapi2::buffer<uint64_t> l_data;
uint64_t l_array_addr = i_start_addr;

// Clear out any stale values from output vectors
o_data.clear();
o_ecc_data.clear();

// Set the control register for the RMW array
l_control_value.writeBit<TT::RMW_WRT_BUFFER_SEL>(TT::SELECT_RMW_BUFFER)
// set start address
.insertFromRight<TT::RMW_WRT_ADDRESS, TT::RMW_WRT_ADDRESS_LEN>(l_array_addr)
// enable the auto increment bit
.setBit<TT::RMW_WRT_AUTOINC>()
// set ecc mode bit off
.clearBit<TT::RMW_WRT_ECCGEN>();

FAPI_INF("Setting the RMW array access control register.");
FAPI_TRY( mss::putScom(i_target, TT::RMW_WRT_BUF_CTL_REG, l_control_value) );

for (uint8_t l_index = 0; l_index < i_num_entries; ++l_index)
{
// Read info out of RMW array and put into output vector
// Note that since we enabled AUTOINC above, reading ECC_REG will increment
// the array pointer so the next DATA_REG read will read the next array entry
FAPI_TRY( mss::getScom(i_target, TT::RMW_WRT_BUF_DATA_REG, l_data) );

FAPI_INF("RMW data index %d is: %016lx", l_array_addr, l_data);
o_data.push_back(l_data);

// Need to read ecc register to increment array index
FAPI_TRY( mss::getScom(i_target, TT::RMW_WRT_BUF_ECC_REG, l_data) );
o_ecc_data.push_back(l_data);
++l_array_addr;

// Need to manually roll over address if we go beyond NUM_COMPARE_INFO_ENTRIES
// Since actual array is bigger than what is used for compare mode
if (i_roll_over_for_compare_mode &&
(l_array_addr >= TT::NUM_COMPARE_INFO_ENTRIES))
{
FAPI_INF("Rolling over the RMW array access control register address from %d to %d.", (i_start_addr + l_index), 0);
l_control_value.clearBit<TT::RMW_WRT_ADDRESS, TT::RMW_WRT_ADDRESS_LEN>();
FAPI_TRY( mss::putScom(i_target, TT::RMW_WRT_BUF_CTL_REG, l_control_value) );
l_array_addr = 0;
}
}

fapi_try_exit:
return fapi2::current_err;
}

///
/// @brief Read entries from MCBIST Read Buffer (RB) array
/// Specialization for fapi2::TARGET_TYPE_MCA
/// @param[in] i_target the target to effect
/// @param[in] i_start_addr the array address to read first
/// @param[in] i_num_entries the number of array entries to read
/// @param[out] o_data vector of output data
/// @param[out] o_ecc_data vector of ecc data
/// @return FAPI2_RC_SUCCSS iff ok
///
template<>
fapi2::ReturnCode read_rb_array(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const uint64_t i_start_addr,
const uint64_t i_num_entries,
std::vector< fapi2::buffer<uint64_t> >& o_data,
std::vector< fapi2::buffer<uint64_t> >& o_ecc_data)
{
typedef mcbistTraits<fapi2::TARGET_TYPE_MCS> TT;

fapi2::buffer<uint64_t> l_control_value;
fapi2::buffer<uint64_t> l_data;
uint64_t l_array_addr = i_start_addr;

const auto& l_mcs = mss::find_target<TARGET_TYPE_MCS>(i_target);

// Clear out any stale values from output vectors
o_data.clear();
o_ecc_data.clear();

// set BUFFER according to port position within MCS
l_control_value.writeBit<TT::RB_BUFFER_SEL>(mss::relative_pos<fapi2::TARGET_TYPE_MCS>(i_target))
// set start address
.insertFromRight<TT::RB_ADDRESS, TT::RB_ADDRESS_LEN>(l_array_addr)
// enable the auto increment bit
.setBit<TT::RB_AUTOINC>();

FAPI_INF("Setting the RB array access control register.");
FAPI_TRY( mss::putScom(l_mcs, TT::RD_BUF_CTL_REG, l_control_value) );

for (uint8_t l_index = 0; l_index < i_num_entries; ++l_index)
{
// Note that since we enabled AUTOINC above, reading ECC_REG will increment
// the array pointer so the next DATA_REG read will read the next array entry
FAPI_TRY( mss::getScom(l_mcs, TT::RD_BUF_DATA_REG, l_data) );
FAPI_INF("RB data index %d is: 0x%016lx", l_array_addr, l_data);
o_data.push_back(l_data);

// Need to read ecc register to increment array index
FAPI_TRY( mss::getScom(l_mcs, TT::RD_BUF_ECC_REG, l_data) );
o_ecc_data.push_back(l_data);
++l_array_addr;

// Array address automatically rolls over if we go beyond NUM_COMPARE_LOG_ENTRIES
if (l_array_addr >= TT::NUM_COMPARE_LOG_ENTRIES)
{
l_array_addr = 0;
}

}

fapi_try_exit:
return fapi2::current_err;
}

} // namespace

// Note: outside of the mcbist namespace
Expand Down
182 changes: 181 additions & 1 deletion src/import/chips/p9/procedures/hwp/memory/lib/mcbist/mcbist.H
Expand Up @@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2015,2016 */
/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
Expand Down Expand Up @@ -319,6 +319,96 @@ class mcbistTraits<fapi2::TARGET_TYPE_MCBIST>
CFG_DGEN_RNDD_SEED2_LEN = MCBIST_MCBRDS1Q_DGEN_RNDD_SEED2_LEN,
CFG_DGEN_RNDD_DATA_MAPPING = MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING,
CFG_DGEN_RNDD_DATA_MAPPING_LEN = MCBIST_MCBRDS1Q_DGEN_RNDD_DATA_MAPPING_LEN,

// Bit mapping for MCBIST error log control data (address+ in Nimbus doc)
ERROR_LOG_SUBTEST = 0,
ERROR_LOG_SUBTEST_LEN = 5,
ERROR_LOG_SUBCMD = 5,
ERROR_LOG_SUBCMD_LEN = 2,
ERROR_LOG_ADDR_DIMM = 7,
ERROR_LOG_ADDR_MRANK = 8,
ERROR_LOG_ADDR_MRANK_LEN = 2,
ERROR_LOG_ADDR_SRANK = 10,
ERROR_LOG_ADDR_SRANK_LEN = 3,
ERROR_LOG_ADDR_BANK_GROUP = 13,
ERROR_LOG_ADDR_BANK_GROUP_LEN = 2,
ERROR_LOG_ADDR_BANK = 15,
ERROR_LOG_ADDR_BANK_LEN = 3,
ERROR_LOG_ADDR_ROW = 18,
ERROR_LOG_ADDR_ROW_LEN = 18,
ERROR_LOG_ADDR_COLUMN = 36,
ERROR_LOG_ADDR_COLUMN_LEN = 8,
ERROR_LOG_BEAT = 44,
ERROR_LOG_BEAT_LEN = 2,
ERROR_LOG_TYPE = 46,
ERROR_LOG_TYPE_LEN = 2,
};

};

///
/// @class mcbistTraits
/// @brief a collection of traits associated with the Nimbus MCA
///
template<>
class mcbistTraits<fapi2::TARGET_TYPE_MCA>
{
public:
// MCBIST error log related registers
static constexpr uint64_t ERROR_LOG_PTR_REG = MCA_ELPR;
static constexpr uint64_t RMW_WRT_BUF_CTL_REG = MCA_WREITE_AACR;
static constexpr uint64_t RMW_WRT_BUF_DATA_REG = MCA_AADR;
static constexpr uint64_t RMW_WRT_BUF_ECC_REG = MCA_AAER;

enum
{
// Register field constants
ERROR_LOG_PTR = MCA_ELPR_LOG_POINTER,
ERROR_LOG_PTR_LEN = MCA_ELPR_LOG_POINTER_LEN,
ERROR_LOG_FULL = MCA_ELPR_LOG_FULL,
RMW_WRT_BUFFER_SEL = MCA_WREITE_AACR_BUFFER,
RMW_WRT_ADDRESS = MCA_WREITE_AACR_ADDRESS,
RMW_WRT_ADDRESS_LEN = MCA_WREITE_AACR_ADDRESS_LEN,
RMW_WRT_AUTOINC = MCA_WREITE_AACR_AUTOINC,
RMW_WRT_ECCGEN = MCA_WREITE_AACR_ECCGEN,

// Constants used for field settings
SELECT_RMW_BUFFER = 0,
SELECT_WRT_BUFFER = 1,

// Other constants
NUM_COMPARE_LOG_ENTRIES = 64,
// In compare mode, there is one "info" entry per 4 data (log) entries
// so compare mode only uses 16 info entries total in the rmw array
NUM_COMPARE_DATA_PER_INFO_LOG = 4,
NUM_COMPARE_INFO_ENTRIES = 16,
};

};

///
/// @class mcbistTraits
/// @brief a collection of traits associated with the Nimbus MCS
///
template<>
class mcbistTraits<fapi2::TARGET_TYPE_MCS>
{
public:
// MCBIST error log related registers
static constexpr uint64_t RD_BUF_CTL_REG = MCS_PORT02_AACR;
static constexpr uint64_t RD_BUF_DATA_REG = MCS_PORT02_AADR;
static constexpr uint64_t RD_BUF_ECC_REG = MCS_PORT02_AAER;

enum
{
// Register field constants
RB_BUFFER_SEL = MCS_PORT02_AACR_BUFFER,
RB_ADDRESS = MCS_PORT02_AACR_ADDRESS,
RB_ADDRESS_LEN = MCS_PORT02_AACR_ADDRESS_LEN,
RB_AUTOINC = MCS_PORT02_AACR_AUTOINC,

// Other constants
NUM_COMPARE_LOG_ENTRIES = 64,
};

};
Expand Down Expand Up @@ -2807,6 +2897,96 @@ inline fapi2::ReturnCode load_thresholds( const fapi2::Target<T>& i_target, cons
return load_thresholds(i_target, i_program.iv_thresholds);
}

///
/// @brief Read entries from MCBIST Read Modify Write (RMW) array
/// @tparam T, the fapi2::TargetType
/// @tparam TT, the mcbistTraits associated with T - derived
/// @param[in] i_target the target to effect
/// @param[in] i_start_addr the array address to read first
/// @param[in] i_num_entries the number of array entries to read
/// @param[in] i_roll_over_for_compare_mode set to true if only using first
/// NUM_COMPARE_INFO_ENTRIES of array, so array address rolls over at correct value
/// @param[out] o_data vector of output data
/// @param[out] o_ecc_data vector of ecc data
/// @return FAPI2_RC_SUCCSS iff ok
/// @note The number of entries in the array depends on i_roll_over_for_compare_mode parameter:
/// (NUM_COMPARE_LOG_ENTRIES for false, NUM_COMPARE_INFO_ENTRIES for true) but user may read more than
/// that since reads work in a circular buffer fashion
///
template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
fapi2::ReturnCode read_rmw_array(const fapi2::Target<T>& i_target,
const uint64_t i_start_addr,
const uint64_t i_num_entries,
const bool i_roll_over_for_compare_mode,
std::vector< fapi2::buffer<uint64_t> >& o_data,
std::vector< fapi2::buffer<uint64_t> >& o_ecc_data);

///
/// @brief Read entries from MCBIST Read Modify Write (RMW) array
/// Overload for the case where o_ecc_data is not needed
/// @tparam T, the fapi2::TargetType
/// @tparam TT, the mcbistTraits associated with T - derived
/// @param[in] i_target the target to effect
/// @param[in] i_start_addr the array address to read first
/// @param[in] i_num_entries the number of array entries to read
/// @param[in] i_roll_over_for_compare_mode set to true if only using first
/// NUM_COMPARE_INFO_ENTRIES of array, so array address rolls over at correct value
/// @param[out] o_data vector of output data
/// @return FAPI2_RC_SUCCSS iff ok
/// @note The number of entries in the array depends on i_roll_over_for_compare_mode parameter:
/// (NUM_COMPARE_LOG_ENTRIES for false, NUM_COMPARE_INFO_ENTRIES for true) but user may read more than
/// that since reads work in a circular buffer fashion
///
template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
inline fapi2::ReturnCode read_rmw_array(const fapi2::Target<T>& i_target,
const uint64_t i_start_addr,
const uint64_t i_num_entries,
const bool i_roll_over_for_compare_mode,
std::vector< fapi2::buffer<uint64_t> >& o_data)
{
std::vector< fapi2::buffer<uint64_t> > l_temp;
return read_rmw_array(i_target, i_start_addr, i_num_entries, i_roll_over_for_compare_mode, o_data, l_temp);
}

///
/// @brief Read entries from MCBIST Read Buffer (RB) array
/// @tparam T, the fapi2::TargetType
/// @tparam TT, the mcbistTraits associated with T - derived
/// @param[in] i_target the target to effect
/// @param[in] i_start_addr the array address to read first
/// @param[in] i_num_entries the number of array entries to read
/// @param[out] o_data vector of output data
/// @param[out] o_ecc_data vector of ecc data
/// @return FAPI2_RC_SUCCSS iff ok
///
template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
fapi2::ReturnCode read_rb_array(const fapi2::Target<T>& i_target,
const uint64_t i_start_addr,
const uint64_t i_num_entries,
std::vector< fapi2::buffer<uint64_t> >& o_data,
std::vector< fapi2::buffer<uint64_t> >& o_ecc_data);

///
/// @brief Read entries from MCBIST Read Buffer (RB) array
/// Overload for the case where o_ecc_data is not needed
/// @tparam T, the fapi2::TargetType
/// @tparam TT, the mcbistTraits associated with T - derived
/// @param[in] i_target the target to effect
/// @param[in] i_start_addr the array address to read first
/// @param[in] i_num_entries the number of array entries to read
/// @param[out] o_data vector of output data
/// @return FAPI2_RC_SUCCSS iff ok
///
template< fapi2::TargetType T, typename TT = mcbistTraits<T> >
fapi2::ReturnCode read_rb_array(const fapi2::Target<T>& i_target,
const uint64_t i_start_addr,
const uint64_t i_num_entries,
std::vector< fapi2::buffer<uint64_t> >& o_data)
{
std::vector< fapi2::buffer<uint64_t> > l_temp;
return read_rb_array(i_target, i_start_addr, i_num_entries, o_data, l_temp);
}

} // namespace

} // namespace
Expand Down

0 comments on commit 61ea8ae

Please sign in to comment.