Skip to content

Commit

Permalink
Change cas latency to be per MCA
Browse files Browse the repository at this point in the history
Change-Id: I61684fe0b69c72dea4c79ad248f8928a007ffb0f
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/40052
Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com>
Reviewed-by: Louis Stermole <stermole@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Thi N. Tran <thi@us.ibm.com>
Dev-Ready: JACOB L. HARVEY <jlharvey@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/40501
Reviewed-by: Hostboot Team <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
JacobHarvey authored and dcrowell77 committed May 25, 2017
1 parent 53ec245 commit e734170
Show file tree
Hide file tree
Showing 10 changed files with 247 additions and 182 deletions.
Expand Up @@ -77,7 +77,7 @@ enum invalid_timing_function_encoding
/// @param[in] i_caches decoder caches
/// @param[out] o_rc returns FAPI2_RC_SUCCESS if constructor initialzed successfully
///
cas_latency::cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target,
cas_latency::cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const std::vector< std::shared_ptr<spd::decoder> >& i_caches,
fapi2::ReturnCode& o_rc ):
iv_dimm_list_empty(false),
Expand All @@ -86,7 +86,6 @@ cas_latency::cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target,
iv_proposed_tck(0),
iv_common_cl(UINT64_MAX) // Masks out supported CLs
{

if( i_caches.empty() )
{
FAPI_INF("cas latency ctor seeing no SPD caches for %s", mss::c_str(i_target) );
Expand All @@ -96,7 +95,7 @@ cas_latency::cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target,

for ( const auto& l_cache : i_caches )
{
// Retrive timing values from the SPD
// Retrieve timing values from the SPD
uint64_t l_taa_min_in_ps = 0;
uint64_t l_tckmax_in_ps = 0;
uint64_t l_tck_min_in_ps = 0;
Expand Down Expand Up @@ -191,7 +190,7 @@ fapi_try_exit:
/// @param[in] i_common_cl_mask common CAS latency mask we want to force (bitmap)
/// @param[in] i_is_3ds boolean for whether this is a 3DS SDRAM, 3DS is true, false otherwise (default)
///
cas_latency::cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target,
cas_latency::cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const uint64_t i_taa_min,
const uint64_t i_tck_min,
const uint64_t i_common_cl_mask,
Expand Down Expand Up @@ -244,7 +243,7 @@ fapi2::ReturnCode cas_latency::find_cl(uint64_t& o_cas_latency,
}

// Update output values after all criteria is met
// If the MCS has no dimm configured than both
// If the MCA has no dimm configured than both
// l_desired_latency & iv_proposed_tck is 0 by initialization
o_cas_latency = l_desired_cas_latency;
o_tck = iv_proposed_tck;
Expand Down
Expand Up @@ -84,7 +84,7 @@ class cas_latency
/// @param[in] i_caches decoder caches
/// @param[out] o_rc returns FAPI2_RC_SUCCESS if constructor initialzed successfully
///
cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target_mcs,
cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target_mcs,
const std::vector< std::shared_ptr<spd::decoder> >& i_caches,
fapi2::ReturnCode& o_rc);

Expand All @@ -96,7 +96,7 @@ class cas_latency
/// @param[in] i_is_3ds loading::IS_3DS if this is for 3DS,
/// loading::NOT_3DS otherwise (default)
///
cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target,
cas_latency(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const uint64_t i_taa_min,
const uint64_t i_tck_min,
const uint64_t i_common_cl_mask,
Expand Down Expand Up @@ -144,7 +144,7 @@ class cas_latency
/////////////////////////
// Private variables
/////////////////////////
fapi2::Target<fapi2::TARGET_TYPE_MCS> iv_target;
fapi2::Target<fapi2::TARGET_TYPE_MCA> iv_target;
uint64_t iv_largest_taamin;// cas latency time
uint64_t iv_proposed_tck;// cycle time
uint64_t iv_common_cl; // common cas latency
Expand Down
98 changes: 48 additions & 50 deletions src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.C
Expand Up @@ -300,14 +300,14 @@ fapi_try_exit:

///
/// @brief Create and sort a vector of supported MT/s (freq)
/// @param[in] MCS target for which to get the DIMM configs
/// @param[in] MCA target for which to get the DIMM configs
/// @param[in,out] reference to a std::vector<uint32_t> space to put the sorted vector
/// @return FAPI2_RC_SUCCESS iff ok
/// @note Taken from ATTR_MSS_MRW_SUPPORTED_FREQ. The result is sorted so such that the min
/// supported freq is std::vector<>.begin and the max is std::vector<>.end - 1. You can
/// search the resulting vector for valid frequencies as it is sorted.
///
fapi2::ReturnCode supported_freqs(const fapi2::Target<TARGET_TYPE_MCS>& i_target, std::vector<uint32_t>& io_freqs)
fapi2::ReturnCode supported_freqs(const fapi2::Target<TARGET_TYPE_MCA>& i_target, std::vector<uint32_t>& io_freqs)
{
std::vector<uint32_t> l_freqs(NUM_VPD_FREQS, 0);
std::vector<uint32_t> l_max_freqs(NUM_MAX_FREQS, 0);
Expand Down Expand Up @@ -337,7 +337,7 @@ fapi_try_exit:

///
/// @brief Create and sort a vector of supported MT/s (freq) - helper for testing purposes
/// @param[in] MCS target for which to get the DIMM configs
/// @param[in] MCA target for which to get the DIMM configs
/// @param[in] vector of MVPD freqs
/// @param[in] vector of max allowed freqs
/// @param[in] bool whether or not we're forced into sync mode
Expand All @@ -347,7 +347,7 @@ fapi_try_exit:
/// testing. So this helper allows us to use the attributes for the main path but
/// have a path for testing (DFT I think the cool kids call it.)
///
fapi2::ReturnCode supported_freqs_helper(const fapi2::Target<TARGET_TYPE_MCS>& i_target,
fapi2::ReturnCode supported_freqs_helper(const fapi2::Target<TARGET_TYPE_MCA>& i_target,
const std::vector<uint32_t>& i_freqs,
const std::vector<uint32_t>& i_max_freqs,
const bool i_req_sync_mode,
Expand Down Expand Up @@ -388,55 +388,53 @@ fapi2::ReturnCode supported_freqs_helper(const fapi2::Target<TARGET_TYPE_MCS>& i
FAPI_INF("max supported freqs %d %d %d %d %d",
i_max_freqs[0], i_max_freqs[1], i_max_freqs[2], i_max_freqs[3], i_max_freqs[4]);

// Given the max supported freqs, find the config based on our DIMMs. There's no great way to do this ...
for (const auto& p : mss::find_targets<TARGET_TYPE_MCA>(i_target))
const auto l_dimms = mss::find_targets<TARGET_TYPE_DIMM>(i_target);
uint64_t l_dimms_on_port = l_dimms.size();

FAPI_ASSERT( (l_dimms_on_port <= MAX_DIMM_PER_PORT),
fapi2::MSS_TOO_MANY_DIMMS_ON_PORT()
.set_DIMM_COUNT(l_dimms_on_port)
.set_MCA_TARGET(i_target),
"Seeing %d DIMM on port %s",
l_dimms_on_port,
mss::c_str(i_target));

for (const auto& d : l_dimms)
{
const auto l_dimms = mss::find_targets<TARGET_TYPE_DIMM>(p);
uint64_t l_dimms_on_port = l_dimms.size();

FAPI_ASSERT( (l_dimms_on_port <= MAX_DIMM_PER_PORT),
fapi2::MSS_TOO_MANY_DIMMS_ON_PORT()
.set_DIMM_COUNT(l_dimms_on_port)
.set_MCA_TARGET(p),
"Seeing %d DIMM on port %s",
uint8_t l_num_master_ranks = 0;
size_t l_index = 0xFF;

FAPI_TRY( mss::eff_num_master_ranks_per_dimm(d, l_num_master_ranks) );

// Just a quick check but we're in deep yogurt if this triggers
FAPI_ASSERT( (l_num_master_ranks <= MAX_RANK_PER_DIMM),
fapi2::MSS_TOO_MANY_PRIMARY_RANKS_ON_DIMM()
.set_RANK_COUNT(l_num_master_ranks)
.set_DIMM_TARGET(d),
"seeing %d primary ranks on DIMM %s",
l_dimms_on_port,
mss::c_str(p));
mss::c_str(d));

l_index = l_indexes[l_dimms_on_port - 1][l_num_master_ranks - 1];

FAPI_INF("%s rank config %d drop %d yields max freq attribute index of %d (%d)",
mss::c_str(d),
l_num_master_ranks,
l_dimms_on_port,
l_index,
i_max_freqs[l_index] );

FAPI_ASSERT( (l_index < NUM_MAX_FREQS),
fapi2::MSS_FREQ_INDEX_TOO_LARGE()
.set_INDEX(l_index)
.set_NUM_MAX_FREQS(NUM_MAX_FREQS),
"seeing %d index for %d DIMM and %d ranks on DIMM %s",
l_index,
l_dimms_on_port,
l_num_master_ranks,
mss::c_str(d));

for (const auto& d : l_dimms)
{
uint8_t l_num_master_ranks = 0;
size_t l_index = 0xFF;

FAPI_TRY( mss::eff_num_master_ranks_per_dimm(d, l_num_master_ranks) );

// Just a quick check but we're in deep yogurt if this triggers
FAPI_ASSERT( (l_num_master_ranks <= MAX_RANK_PER_DIMM),
fapi2::MSS_TOO_MANY_PRIMARY_RANKS_ON_DIMM()
.set_RANK_COUNT(l_num_master_ranks)
.set_DIMM_TARGET(p),
"seeing %d primary ranks on DIMM %s",
l_dimms_on_port,
mss::c_str(d));

FAPI_INF("%s rank config %d drop %d yields max freq attribute index of %d (%d)",
mss::c_str(d), l_num_master_ranks, l_dimms_on_port,
l_indexes[l_dimms_on_port - 1][l_num_master_ranks - 1],
i_max_freqs[l_indexes[l_dimms_on_port - 1][l_num_master_ranks - 1]] );

l_index = l_indexes[l_dimms_on_port - 1][l_num_master_ranks - 1];

FAPI_ASSERT( (l_index < NUM_MAX_FREQS),
fapi2::MSS_FREQ_INDEX_TOO_LARGE()
.set_INDEX(l_index)
.set_NUM_MAX_FREQS(NUM_MAX_FREQS),
"seeing %d index for %d DIMM and %d ranks on DIMM %s",
l_index,
l_dimms_on_port,
l_num_master_ranks,
mss::c_str(d));

l_our_max_freq = std::min(l_our_max_freq, i_max_freqs[l_index]);
}
l_our_max_freq = std::min(l_our_max_freq, i_max_freqs[l_index]);
}

FAPI_INF("after processing DIMM, max freq is %d", l_our_max_freq);
Expand Down
8 changes: 4 additions & 4 deletions src/import/chips/p9/procedures/hwp/memory/lib/freq/sync.H
Expand Up @@ -90,7 +90,7 @@ fapi2::ReturnCode select_sync_mode(const std::map< fapi2::Target<fapi2::TARGET_T

///
/// @brief Create and sort a vector of supported MT/s (freq) - helper for testing purposes
/// @param[in] MCS target for which to get the DIMM configs
/// @param[in] MCA target for which to get the DIMM configs
/// @param[in] vector of MVPD freqs
/// @param[in] vector of max allowed freqs
/// @param[in] bool whether or not we're forced into sync mode
Expand All @@ -100,22 +100,22 @@ fapi2::ReturnCode select_sync_mode(const std::map< fapi2::Target<fapi2::TARGET_T
/// supported freq is std::vector<>.begin and the max is std::vector<>.end - 1. You can
/// search the resulting vector for valid frequencies as it is sorted.
///
fapi2::ReturnCode supported_freqs_helper(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target,
fapi2::ReturnCode supported_freqs_helper(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const std::vector<uint32_t>& i_freqs,
const std::vector<uint32_t>& i_max_freqs,
const bool i_req_sync_mode,
std::vector<uint32_t>& io_freqs);

///
/// @brief Create and sort a vector of supported MT/s (freq)
/// @param[in] MCS target for which to get the DIMM configs
/// @param[in] MCA target for which to get the DIMM configs
/// @param[in,out] reference to a std::vector<uint32_t> space to put the sorted vector
/// @return FAPI2_RC_SUCCESS iff ok
/// @note Taken from ATTR_MSS_MRW_SUPPORTED_FREQ. The result is sorted so such that the min
/// supported freq is std::vector<>.begin and the max is std::vector<>.end - 1. You can
/// search the resulting vector for valid frequencies as it is sorted.
///
fapi2::ReturnCode supported_freqs(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target,
fapi2::ReturnCode supported_freqs(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
std::vector<uint32_t>& io_freqs);

///
Expand Down
53 changes: 1 addition & 52 deletions src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.C
Expand Up @@ -378,7 +378,7 @@ fapi_try_exit:
/// @note This is done after the SPD cache is configured so that it can reflect the results of the
/// factory and we don't need to worry about SPD versions. This is expressly different than the dram and dimm setters
///
static fapi2::ReturnCode master_ranks_per_dimm_setter(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
fapi2::ReturnCode master_ranks_per_dimm_setter(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
const std::shared_ptr<decoder>& i_pDecoder)
{
const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
Expand Down Expand Up @@ -757,57 +757,6 @@ fapi_try_exit:
return fapi2::current_err;
}

///
/// @brief Creates factory object & SPD data caches
/// @param[in] i_target controller target
/// @param[out] o_factory_caches vector of factory objects
/// @param[in] i_pDecoder custom decoder to populate cache (ignored for this specialization)
/// @return FAPI2_RC_SUCCESS if okay
/// @note This specialization is suited for creating a cache with platform
/// SPD data.
///
template<>
fapi2::ReturnCode populate_decoder_caches( const fapi2::Target<TARGET_TYPE_MCS>& i_target,
std::vector< std::shared_ptr<decoder> >& o_factory_caches,
const std::shared_ptr<decoder>& i_pDecoder)
{
// Input decoder for this version of populating cache would get overriden
// so I don't bother with it in this specialization
std::shared_ptr<decoder> l_pDecoder;

for( const auto& l_dimm : find_targets<TARGET_TYPE_DIMM>(i_target) )
{
size_t l_size = 0;
FAPI_TRY( fapi2::getSPD(l_dimm, nullptr, l_size),
"%s. Failed to retrieve SPD blob size", mss::c_str(i_target) );

{
// "Container" for SPD data
std::vector<uint8_t> l_spd(l_size);

// Retrive SPD data
FAPI_TRY( fapi2::getSPD(l_dimm, l_spd.data(), l_size),
"%s. Failed to retrieve SPD data", mss::c_str(i_target) );

// Retrieve factory object instance & populate spd data for that instance
FAPI_TRY( factory(l_dimm, l_spd, l_pDecoder),
"%s. Failed SPD factory, could not instantiate decoder object", mss::c_str(i_target) );

// Populate spd caches
o_factory_caches.push_back( l_pDecoder );
}

// Populate some of the DIMM attributes early. This allows the following code to make
// decisions based on DIMM information. Expressly done after the factory has decided on the SPD version
FAPI_TRY( master_ranks_per_dimm_setter(l_dimm, l_pDecoder),
"%s. Failed master_ranks_per_dimm_setter()", mss::c_str(i_target) );

}// end dimm

fapi_try_exit:
return fapi2::current_err;
}

///
/// @brief Creates factory object & SPD data caches
/// @param[in] i_target the dimm target
Expand Down
55 changes: 53 additions & 2 deletions src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.H
Expand Up @@ -42,9 +42,11 @@

// fapi2
#include <fapi2.H>
#include <fapi2_spd_access.H>

// mss lib
#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
#include <generic/memory/lib/utils/find.H>

namespace mss
{
Expand Down Expand Up @@ -147,18 +149,67 @@ fapi2::ReturnCode factory(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target
const std::vector<uint8_t>& i_spd_data,
std::shared_ptr<decoder>& o_fact_obj);


///
/// @brief Determines & sets effective config for number of master ranks per dimm
/// @param[in] i_target DIMM fapi2::Target
/// @param[in] i_pDecoder shared_ptr to SPD decoder
/// @return fapi2::FAPI2_RC_SUCCESS if okay
/// @note This is done after the SPD cache is configured so that it can reflect the results of the
/// factory and we don't need to worry about SPD versions. This is expressly different than the dram and dimm setters
///
fapi2::ReturnCode master_ranks_per_dimm_setter(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const std::shared_ptr<decoder>& i_pDecoder);

///
/// @brief Creates factory object & SPD data caches
/// @param[in] i_target the fapi2 target
/// @tparam T fapi2::TargetType, MCA, MCS, MCBIST, PROC_CHIP are possible TargetTypes
/// @param[in] i_target the fapi2 target to find DIMMs on
/// @param[out] o_factory_caches vector of factory objects
/// @param[in] i_pDecoder optional input decoder to insert custom decoder (nullptr default)
/// @return FAPI2_RC_SUCCESS if okay
///
template<fapi2::TargetType T>
fapi2::ReturnCode populate_decoder_caches(const fapi2::Target<T>& i_target,
std::vector< std::shared_ptr<decoder> >& o_factory_caches,
const std::shared_ptr<decoder>& i_pDecoder = nullptr);
const std::shared_ptr<decoder>& i_pDecoder = nullptr)
{
// Input decoder for this version of populating cache would get overriden
// so I don't bother with it in this specialization
std::shared_ptr<decoder> l_pDecoder;

for( const auto& l_dimm : find_targets<fapi2::TARGET_TYPE_DIMM>(i_target) )
{
size_t l_size = 0;
FAPI_TRY( fapi2::getSPD(l_dimm, nullptr, l_size),
"%s. Failed to retrieve SPD blob size", mss::c_str(i_target) );

{
// "Container" for SPD data
std::vector<uint8_t> l_spd(l_size);

// Retrieve SPD data
FAPI_TRY( fapi2::getSPD(l_dimm, l_spd.data(), l_size),
"%s. Failed to retrieve SPD data", mss::c_str(i_target) );

// Retrieve factory object instance & populate spd data for that instance
FAPI_TRY( factory(l_dimm, l_spd, l_pDecoder),
"%s. Failed SPD factory, could not instantiate decoder object", mss::c_str(i_target) );

// Populate spd caches
o_factory_caches.push_back( l_pDecoder );
}

// Populate some of the DIMM attributes early. This allows the following code to make
// decisions based on DIMM information. Expressly done after the factory has decided on the SPD version
FAPI_TRY( master_ranks_per_dimm_setter(l_dimm, l_pDecoder),
"%s. Failed master_ranks_per_dimm_setter()", mss::c_str(i_target) );

}// end dimm

fapi_try_exit:
return fapi2::current_err;
}

}// spd
}// mss
Expand Down

0 comments on commit e734170

Please sign in to comment.