summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp
diff options
context:
space:
mode:
authorAndre Marin <aamarin@us.ibm.com>2016-08-09 15:06:58 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-10-13 14:32:38 -0400
commitabe596145276ef0c0bd6496df3c787e76a12515a (patch)
tree3fe2dfd3196297004cc9ce180cace89b63321f04 /src/import/chips/p9/procedures/hwp
parent34194ec6550d9d97d5dd888e889f99691cc908a7 (diff)
downloadtalos-hostboot-abe596145276ef0c0bd6496df3c787e76a12515a.tar.gz
talos-hostboot-abe596145276ef0c0bd6496df3c787e76a12515a.zip
Add FW/Cronus VPD integration
Fixed FAPI_ASSERT bug in p9_get_mem_vpd_keyword.C Updated VPD binary from Chris to support all freqs Edited eff_config to match expected API vpd_info to be filled in completely. Edited ekb_ci_p9_full_cnfg to take VPD path Change-Id: I755d3121dbb058470a7693aeb8f46bceb502858b Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29298 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Brian R. Silver <bsilver@us.ibm.com> Reviewed-by: Steven B. Janssen <janssens@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: JACOB L. HARVEY <jlharvey@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29530 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp')
-rw-r--r--src/import/chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.C29
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C181
2 files changed, 111 insertions, 99 deletions
diff --git a/src/import/chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.C b/src/import/chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.C
index af72417c1..a1ce17203 100644
--- a/src/import/chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.C
+++ b/src/import/chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.C
@@ -389,20 +389,21 @@ extern "C"
"No match in mapping table");
//Was a valid keyword name found?
- FAPI_ASSERT(MAPPING_LAYOUT_INVALID != l_second,
- fapi2::GET_MEM_VPD_UNSUPPORTED_CONFIGURATION().
- set_MCS(fapi2::ATTR_MEMVPD_POS_Type(l_mcsPos)).
- set_FREQ(uint32_t(i_vpd_info.iv_freq_mhz)).
- set_DIMM0RANK(uint64_t(i_vpd_info.iv_rank_count_dimm_0)).
- set_DIMM1RANK(uint64_t(i_vpd_info.iv_rank_count_dimm_1)).
- set_VPDMCSMASK(uint16_t(((l_mapping[l_index].mcsMaskMSB) << 8) |
- l_mapping[l_index].mcsMaskLSB)).
- set_VPDFREQMASK(uint8_t(l_mapping[l_index].freqMask)).
- set_VPDRANKMASK(uint8_t(((l_mapping[l_index].rankMaskMSB) << 8) |
- l_mapping[l_index].rankMaskLSB)).
- set_TARGET(i_target).
- set_VPDTYPE(i_vpd_info.iv_vpd_type),
- "Unsupported configuration");
+ // Cast needed due to implicit int of enums
+ FAPI_ASSERT( static_cast<char>(MAPPING_LAYOUT_INVALID) != l_second,
+ fapi2::GET_MEM_VPD_UNSUPPORTED_CONFIGURATION().
+ set_MCS(fapi2::ATTR_MEMVPD_POS_Type(l_mcsPos)).
+ set_FREQ(uint32_t(i_vpd_info.iv_freq_mhz)).
+ set_DIMM0RANK(uint64_t(i_vpd_info.iv_rank_count_dimm_0)).
+ set_DIMM1RANK(uint64_t(i_vpd_info.iv_rank_count_dimm_1)).
+ set_VPDMCSMASK(uint16_t(((l_mapping[l_index].mcsMaskMSB) << 8) |
+ l_mapping[l_index].mcsMaskLSB)).
+ set_VPDFREQMASK(uint8_t(l_mapping[l_index].freqMask)).
+ set_VPDRANKMASK(uint8_t(((l_mapping[l_index].rankMaskMSB) << 8) |
+ l_mapping[l_index].rankMaskLSB)).
+ set_TARGET(i_target).
+ set_VPDTYPE(i_vpd_info.iv_vpd_type),
+ "Unsupported configuration");
// build the keyword name
o_keywordInfo.kwName[0] = l_first;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C
index 70aa4306e..ea214b833 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C
@@ -39,6 +39,7 @@
// mss lib
#include <lib/eff_config/eff_config.H>
+#include <lib/utils/fake_vpd.H>
#include <lib/mss_vpd_decoder.H>
#include <lib/spd/spd_factory.H>
#include <lib/spd/common/spd_decoder.H>
@@ -47,7 +48,6 @@
#include <lib/dimm/rank.H>
#include <lib/utils/conversions.H>
#include <lib/utils/find.H>
-#include <lib/utils/fake_vpd.H>
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_MCS;
@@ -3495,78 +3495,92 @@ fapi2::ReturnCode eff_config::decode_vpd(const fapi2::Target<TARGET_TYPE_MCS>& i
uint8_t l_mr_blob[mss::VPD_KEYWORD_MAX] = {0};
uint8_t l_cke_blob[mss::VPD_KEYWORD_MAX] = {0};
uint8_t l_dq_blob[mss::VPD_KEYWORD_MAX] = {0};
+
std::vector<uint8_t*> l_mt_blobs(PORTS_PER_MCS, nullptr);
+ fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS> l_vpd_info(fapi2::MemVpdData::MT);
// For sanity. Not sure this will break us, but we're certainly making assumptions below.
static_assert(MAX_DIMM_PER_PORT == 2, "Max DIMM per port isn't 2");
- // Get MT data
+ // We need to set up all VPD info before calling getVPD, the API assumes this
+ // For MR we need to tell the VPDInfo the frequency (err ... mt/s - why is this mhz?)
+ FAPI_TRY( mss::freq(find_target<TARGET_TYPE_MCBIST>(i_target), l_vpd_info.iv_freq_mhz) );
+ FAPI_INF("%s. VPD info - dimm data rate: %d MT/s", c_str(i_target), l_vpd_info.iv_freq_mhz);
+
+ // Make sure to create 0 filled blobs for all the possible blobs, not just for the
+ // chiplets which are configured. This prevents the decoder from accessing nullptrs
+ // but the code which uses the VPD will only access the information for the chiplets
+ // which exist - so the 0's are meaningless
+ for (auto& b : l_mt_blobs)
{
- fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS> l_vpd_info(fapi2::MemVpdData::MT);
+ b = new uint8_t[mss::VPD_KEYWORD_MAX];
+ memset(b, 0, mss::VPD_KEYWORD_MAX);
+ }
- // Check the max for giggles. Programming bug so we should assert.
- FAPI_TRY( mss::getVPD(i_target, l_vpd_info, nullptr) );
+ // For MT we need to fill in the rank information
+ // But, of course, the rank information can differ per port. However, the vpd interface doesn't
+ // allow this in a straight-forward way. So, we have to get VPD blobs for MCS which contain
+ // ports which have the rank configuration in question. This means, basically, we pass a MCS MT
+ // blob to the decoder for each MCA, regardless of whether the port configurations are the same.
+ for (const auto& p : find_targets<TARGET_TYPE_MCA>(i_target))
+ {
+ // Find our blob in the vector of blob pointers
+ uint8_t* l_mt_blob = l_mt_blobs[mss::index(p)];
+ uint64_t l_rank_count_dimm[MAX_DIMM_PER_PORT] = {0};
- if (l_vpd_info.iv_size > mss::VPD_KEYWORD_MAX)
+ // If we don't have any DIMM, don't worry about it. This will just drop the blob full of 0's into our index.
+ // This will fill the VPD attributes with 0's which is perfectly ok.
+ for (const auto& d : mss::find_targets<TARGET_TYPE_DIMM>(p))
{
- FAPI_ERR("VPD MT keyword is too big for our array");
- fapi2::Assert(false);
+ uint8_t l_num_master_ranks = 0;
+ FAPI_TRY( mss::eff_num_master_ranks_per_dimm(d, l_num_master_ranks) );
+ l_rank_count_dimm[mss::index(d)] = l_num_master_ranks;
}
- // Make sure to create 0 filled blobs for all the possible blobs, not just for the
- // chiplets which are configured. This prevents the decoder from accessing nullptrs
- // but the code which uses the VPD will only access the information for the chiplets
- // which exist - so the 0's are meaningless
- for (auto& b : l_mt_blobs)
- {
- b = new uint8_t[mss::VPD_KEYWORD_MAX];
- memset(b, 0, mss::VPD_KEYWORD_MAX);
- }
+ // This value will, of course, be 0 if there is no DIMM in the port.
+ l_vpd_info.iv_rank_count_dimm_0 = l_rank_count_dimm[0];
+ l_vpd_info.iv_rank_count_dimm_1 = l_rank_count_dimm[1];
- // For MT we need to fill in the rank information
- // But, of course, the rank information can differ per port. However, the vpd interface doesn't
- // allow this in a straight-forward way. So, we have to get VPD blobs for MCS which contain
- // ports which have the rank configuration in question. This means, basically, we pass a MCS MT
- // blob to the decoder for each MCA, regardless of whether the port configurations are the same.
- for (const auto& p : find_targets<TARGET_TYPE_MCA>(i_target))
- {
- // Find our blob in the vector of blob pointers
- uint8_t* l_mt_blob = l_mt_blobs[mss::index(p)];
- uint64_t l_rank_count_dimm[MAX_DIMM_PER_PORT] = {0};
+ FAPI_INF("%s. VPD info - rank count for dimm_0: %d, dimm_1: %d",
+ c_str(i_target), l_vpd_info.iv_rank_count_dimm_0, l_vpd_info.iv_rank_count_dimm_1);
- // If we don't have any DIMM, don't worry about it. This will just drop the blob full of 0's into our index.
- // This will fill the VPD attributes with 0's which is perfectly ok.
- for (const auto& d : mss::find_targets<TARGET_TYPE_DIMM>(p))
+ // Get the MCS blob for this specific rank combination *only if* we have DIMM. Remember,
+ // Cronus can give us functional MCA which have no DIMM - and we'd puke getting the VPD.
+ if ((l_vpd_info.iv_rank_count_dimm_0 != 0) || (l_vpd_info.iv_rank_count_dimm_1 != 0))
+ {
+ // If getVPD returns us an error, then we don't have VPD for the DIMM configuration.
+ // This is the root of our plug-rules: if you want a configuration of DIMM to be
+ // supported, it needs to have VPD defined. Likewise, if you don't want a configuration
+ // of DIMM supported be sure to leave it out of the VPD. Note that we don't return a specific
+ // plug-rule error as f/w (Dan) suggested this would duplicate errors leading to confusion.
+ l_vpd_info.iv_vpd_type = fapi2::MemVpdData::MT;
+
+ // Check the max for giggles. Programming bug so we should assert.
+ FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, nullptr),
+ "Failed to retrieve MT size from VPD");
+
+ if (l_vpd_info.iv_size > mss::VPD_KEYWORD_MAX)
{
- uint8_t l_num_master_ranks = 0;
- FAPI_TRY( mss::eff_num_master_ranks_per_dimm(d, l_num_master_ranks) );
- l_rank_count_dimm[mss::index(d)] = l_num_master_ranks;
+ FAPI_ERR("VPD MT keyword is too big for our array");
+ fapi2::Assert(false);
}
- // This value will, of course, be 0 if there is no DIMM in the port.
- l_vpd_info.iv_rank_count_dimm_0 = l_rank_count_dimm[0];
- l_vpd_info.iv_rank_count_dimm_1 = l_rank_count_dimm[1];
-
- // Get the MCS blob for this specific rank combination *only if* we have DIMM. Remember,
- // Cronus can give us functional MCA which have no DIMM - and we'd puke getting the VPD.
- if ((l_vpd_info.iv_rank_count_dimm_0 != 0) || (l_vpd_info.iv_rank_count_dimm_1 != 0))
- {
- // If getVPD returns us an error, then we don't have VPD for the DIMM configuration.
- // This is the root of our plug-rules: if you want a configuration of DIMM to be
- // supported, it needs to have VPD defined. Likewise, if you don't want a configuration
- // of DIMM supported be sure to leave it out of the VPD. Note that we don't return a specific
- // plug-rule error as f/w (Dan) suggested this would duplicate errors leading to confusion.
- FAPI_TRY( mss::getVPD(i_target, l_vpd_info, &(l_mt_blob[0])) );
- }
+ FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, &(l_mt_blob[0])),
+ "Failed to retrieve MT VPD");
}
- }
+ }// mca
- // Get MR data
+ // Only get the MR blob if we have a freq. It's possible for Cronus to give us an MCS which
+ // is connected to a controller which has 0 DIMM installed. In this case, we won't have
+ // a frequency, and thus we'd fail getting the VPD. So we initiaized the VPD to 0's and if
+ // there's no freq, we us a 0 filled VPD.
+ if (l_vpd_info.iv_freq_mhz != 0)
{
- fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS> l_vpd_info(fapi2::MemVpdData::MR);
+ l_vpd_info.iv_vpd_type = fapi2::MemVpdData::MR;
// Check the max for giggles. Programming bug so we should assert.
- FAPI_TRY( mss::getVPD(i_target, l_vpd_info, nullptr) );
+ FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, nullptr),
+ "Failed to retrieve MR size from VPD");
if (l_vpd_info.iv_size > mss::VPD_KEYWORD_MAX)
{
@@ -3574,51 +3588,48 @@ fapi2::ReturnCode eff_config::decode_vpd(const fapi2::Target<TARGET_TYPE_MCS>& i
fapi2::Assert(false);
}
- // For MR we need to tell the VPDInfo the frequency (err ... mt/s - why is this mhz?)
- FAPI_TRY( mss::freq(find_target<TARGET_TYPE_MCBIST>(i_target), l_vpd_info.iv_freq_mhz) );
-
- // Only get the MR blob if we have a freq. It's possible for Cronus to give us an MCS which
- // is connected to a controller which has 0 DIMM installed. In this case, we won't have
- // a frequency, and thus we'd fail getting the VPD. So we initiaized the VPD to 0's and if
- // there's no freq, we us a 0 filled VPD.
- if (l_vpd_info.iv_freq_mhz != 0)
- {
- FAPI_TRY( mss::getVPD(i_target, l_vpd_info, &(l_mr_blob[0])) );
- }
+ FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, &(l_mr_blob[0])),
+ "Failed to retrieve MR VPD");
}
- // Get CKE data
- {
- fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS> l_vpd_info(fapi2::MemVpdData::CK);
+ // Until CK/DQ integration is working, we differentiate getting our fake_vpd for those ids.
+ // This gives us an extended API we can use for testing which won't be seen by HB because we'd use this to limit it
+#ifndef __HOSTBOOT_MODULE
- // Check the max for giggles. Programming bug so we should assert.
- FAPI_TRY( mss::getVPD(i_target, l_vpd_info, nullptr) );
+ // Get CKE data
+ l_vpd_info.iv_vpd_type = fapi2::MemVpdData::CK;
- if (l_vpd_info.iv_size > mss::VPD_KEYWORD_MAX)
- {
- FAPI_ERR("VPD MR keyword is too big for our array");
- fapi2::Assert(false);
- }
+ // Check the max for giggles. Programming bug so we should assert.
+ FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, nullptr),
+ "Failed to retrieve CK size from VPD");
- FAPI_TRY( mss::getVPD(i_target, l_vpd_info, &(l_cke_blob[0])) );
+ if (l_vpd_info.iv_size > mss::VPD_KEYWORD_MAX)
+ {
+ FAPI_ERR("VPD CK keyword is too big for our array");
+ fapi2::Assert(false);
}
- // Get DQ data
- {
- fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS> l_vpd_info(fapi2::MemVpdData::DQ);
+ FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, &(l_cke_blob[0])),
+ "Failed to retrieve DQ VPD");
- // Check the max for giggles. Programming bug so we should assert.
- FAPI_TRY( mss::getVPD(i_target, l_vpd_info, nullptr) );
+ // Get DQ data
+ l_vpd_info.iv_vpd_type = fapi2::MemVpdData::DQ;
- if (l_vpd_info.iv_size > mss::VPD_KEYWORD_MAX)
- {
- FAPI_ERR("VPD MR keyword is too big for our array");
- fapi2::Assert(false);
- }
+ // Check the max for giggles. Programming bug so we should assert.
+ FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, nullptr),
+ "Failed to retrieve DQ size from VPD");
- FAPI_TRY( mss::getVPD(i_target, l_vpd_info, &(l_dq_blob[0])) );
+ if (l_vpd_info.iv_size > mss::VPD_KEYWORD_MAX)
+ {
+ FAPI_ERR("VPD DQ keyword is too big for our array");
+ fapi2::Assert(false);
}
+ FAPI_TRY( fapi2::getVPD(i_target, l_vpd_info, &(l_dq_blob[0])),
+ "Failed to retrieve DQ VPD");
+
+#endif
+
FAPI_TRY( mss::eff_decode(i_target, l_mt_blobs, l_mr_blob, l_cke_blob, l_dq_blob) );
fapi_try_exit:
OpenPOWER on IntegriCloud