From f8861cd116368d7af30fb2c30e2920848fb35a94 Mon Sep 17 00:00:00 2001 From: whs Date: Thu, 28 Apr 2016 07:25:54 -0500 Subject: Changes related to packaging of memory vpd on Nimbus Create a HWP to process MR and MT keyword to map to memory vpd keyword. Change specialization from MCS to MCA. Change-Id: I1fa9110ffa9bb9c13ced33aac7ec091753ee73b8 Original-Change-Id: I426e4c7600e2158737c82e3c2380518c392ada5b RTC: 144519 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/23775 Tested-by: Jenkins Server Reviewed-by: Brian R. Silver Tested-by: PPE CI Tested-by: Hostboot CI Reviewed-by: Daniel M. Crowell Reviewed-by: Matt K. Light Reviewed-by: Jennifer A. Stofer Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/26182 Tested-by: FSP CI Jenkins --- .../hwp/accessors/p9_get_mem_vpd_keyword.C | 268 +++++++++++++++++++++ .../hwp/accessors/p9_get_mem_vpd_keyword.H | 138 +++++++++++ .../hwp/accessors/p9_get_mem_vpd_keyword.mk | 22 ++ 3 files changed, 428 insertions(+) create mode 100644 src/import/chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.C create mode 100644 src/import/chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.H create mode 100644 src/import/chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.mk (limited to 'src/import/chips/p9/procedures/hwp/accessors') 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 new file mode 100644 index 000000000..edaed1fd0 --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.C @@ -0,0 +1,268 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* EKB Project */ +/* */ +/* COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/// +/// @file p9_get_mem_vpd_keyword.C +/// @brief Return mem vpd keyword based on VDPInfo +/// +// *HWP HWP Owner: Dan Crowell +// *HWP HWP Backup: Matt Light +// *HWP FW Owner: Dan Crowell +// *HWP Team: +// *HWP Level: 3 +// *HWP Consumed by: Cronus, FSP, HB + +#include +#include +#include + +using fapi2::TARGET_TYPE_MCS; +using fapi2::TARGET_TYPE_SYSTEM; +using fapi2::FAPI2_RC_SUCCESS; +using fapi2::mappingKeywordRow; +using fapi2::MAPPING_LAYOUT_VERSION; +using fapi2::MAPPING_LAYOUT_INVALID; +using fapi2::MAPPING_LAYOUT_LAST; +using fapi2::MAPPING_LAYOUT_MAXROWS; +using fapi2::MAPPING_LAYOUT_MCA0; +using fapi2::MAPPING_LAYOUT_DIMM0_RANK0; +using fapi2::MAPPING_LAYOUT_DIMM0_RANK4; +using fapi2::MAPPING_LAYOUT_DIMM1_RANK0; +using fapi2::MAPPING_LAYOUT_DIMM1_RANK4; +using fapi2::MAPPING_LAYOUT_FREQ0; +using fapi2::MAPPING_LAYOUT_FREQ3; + +extern "C" +{ + +/// @brief Return VPD keyword based on MCA, VPDInfo, and MR/MT mapping +/// The MR and MT keyword contains a header followed by a table. Each +/// row in the table has criteria to select a vpd keyword. +/// +/// @param[in] i_target, the MCA +/// @param[in] i_vpd_info, vpd criteria +/// @param[in] i_pMapping, MR or MT keyword data +/// @param[in] i_mappingSize, size of i_pMapping buffer +/// @param[out] o_keywordName, keyword with vpd +/// @return FAPI2_RC_SUCCESS iff ok + fapi2::ReturnCode p9_get_mem_vpd_keyword( + const fapi2::Target& i_target, + const fapi2::VPDInfo& i_vpd_info, + const uint8_t* i_pMapping, + const size_t i_mappingSize, + fapi2::keywordName_t& o_keywordName) + { + char l_first = 0; + char l_second = 0; + fapi2::ATTR_MEMVPD_POS_Type l_mcaPos = 0; + uint16_t l_mcaMask = 0; + uint8_t l_rankMask = 0; + uint8_t l_freqMask = 0; + uint32_t l_freqTableIndex = 0; + fapi2::ATTR_MEMVPD_FREQS_MHZ_Type l_freqTable = {0}; + uint32_t l_freqTableCnt = sizeof(l_freqTable) / sizeof(l_freqTable[0]); + uint32_t index = 0; //start with header + const mappingKeywordRow* l_mapping = + reinterpret_cast(i_pMapping); + + FAPI_DBG("p9_get_mem_vpd_keyword: enter"); + + // Validate size of mapping to be at least large enough for biggest + // mapping table expected. + const size_t MAPPING_LAYOUT_MAXSIZE = + size_t(sizeof(mappingKeywordRow) * MAPPING_LAYOUT_MAXROWS); + FAPI_ASSERT(MAPPING_LAYOUT_MAXSIZE <= i_mappingSize, + fapi2::GET_MEM_VPD_MAPPING_TOO_SMALL(). + set_SIZE(size_t(i_mappingSize)). + set_EXPECTED(size_t(MAPPING_LAYOUT_MAXSIZE)), + "Mapping keyword size %d less than min %d expected", + i_mappingSize, + MAPPING_LAYOUT_MAXSIZE); + + // Validate mapping keyword version supported + FAPI_ASSERT(MAPPING_LAYOUT_VERSION == l_mapping[index].layoutVersion, + fapi2::GET_MEM_VPD_UNSUPPORTED_VERSION(). + set_VERSION(uint8_t(l_mapping[index].layoutVersion)). + set_EXPECTED(uint8_t(MAPPING_LAYOUT_VERSION)), + "Header version %d not supported % expected", + l_mapping[index].layoutVersion, + MAPPING_LAYOUT_VERSION); + + // Validate vpd type and set first keyword name character based on type + switch (i_vpd_info.iv_vpd_type) + { + case fapi2::MT: + l_first = 'X'; //vpd keyword name X0..X9,XA..XZ + break; + + case fapi2::MR: + l_first = 'J'; //vpd keyword name J0..J9,JA..JZ + break; + + default: + FAPI_ASSERT(false, + fapi2::GET_MEM_VPD_UNSUPPORTED_TYPE(). + set_TYPE(fapi2::MemVpdData(i_vpd_info.iv_vpd_type)), + "Invalid vpd type = %d", + i_vpd_info.iv_vpd_type); + } + + // Get the MCA position + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEMVPD_POS, + i_target, + l_mcaPos), + "p9_get_mem_vpd_keyword: get ATTR_MEMVPD_POS failed"); + l_mcaMask = (MAPPING_LAYOUT_MCA0 >> l_mcaPos); //zero based + FAPI_DBG ("p9_get_mem_vpd_keyword: mca position = %d mask=%x", + l_mcaPos, l_mcaMask); + + // Get the frequency index + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEMVPD_FREQS_MHZ, + fapi2::Target(), + l_freqTable), + "p9_get_mem_vpd_keyword: get ATTR_MEMVPD_FREQS_MHZ failed"); + + for (; l_freqTableIndex < l_freqTableCnt; l_freqTableIndex++) + { + if (i_vpd_info.iv_freq_mhz == l_freqTable[l_freqTableIndex]) + { + break; // found it + } + } + + FAPI_ASSERT(l_freqTableIndex < l_freqTableCnt, + fapi2::GET_MEM_VPD_UNSUPPORTED_FREQUENCY(). + set_UNSUPPORTEDFREQ(uint32_t(i_vpd_info.iv_freq_mhz)). + set_MEMVPDFREQ0(uint32_t(l_freqTable[0])). + set_MEMVPDFREQ1(uint32_t(l_freqTable[1])). + set_MEMVPDFREQ2(uint32_t(l_freqTable[2])). + set_MEMVPDFREQ3(uint32_t(l_freqTable[3])), + "Frequency %d not in ATTR_MEMVPD_FREQS_MHZ", + i_vpd_info.iv_freq_mhz); + l_freqMask = (MAPPING_LAYOUT_FREQ0 >> l_freqTableIndex); //zero based + FAPI_DBG ("p9_get_mem_vpd_keyword: frequency index = %d mask=%x", + l_freqTableIndex, l_freqMask); + + // Get rank mask. Valid ranks are 0,1,2,4 + // Mask = rrrrssss rrrr for rank0, ssss for rank1 + switch (i_vpd_info.iv_rank_count_dimm_0) + { + case 0: //can use shift, high order nibble + case 1: + case 2: + l_rankMask = + (MAPPING_LAYOUT_DIMM0_RANK0 >> i_vpd_info.iv_rank_count_dimm_0); + break; + + case 4: + l_rankMask = MAPPING_LAYOUT_DIMM0_RANK4; + break; + + default: + FAPI_ASSERT(false, + fapi2::GET_MEM_VPD_UNSUPPORTED_RANK(). + set_RANK(uint64_t(i_vpd_info.iv_rank_count_dimm_0)), + "Unsupported rank = %d should be 0,1,2, or 4", + i_vpd_info.iv_rank_count_dimm_0); + } + + switch (i_vpd_info.iv_rank_count_dimm_1) + { + case 0: //can use shift, low order nibble + case 1: + case 2: + l_rankMask |= + (MAPPING_LAYOUT_DIMM1_RANK0 >> i_vpd_info.iv_rank_count_dimm_1); + break; + + case 4: + l_rankMask |= MAPPING_LAYOUT_DIMM1_RANK4; + break; + + default: + FAPI_ASSERT(false, + fapi2::GET_MEM_VPD_UNSUPPORTED_RANK(). + set_RANK(uint64_t(i_vpd_info.iv_rank_count_dimm_1)), + "Unsupported rank = %d should be 0,1,2, or 4", + i_vpd_info.iv_rank_count_dimm_1); + } + + FAPI_DBG("p9_get_mem_vpd_keyword: rank0=%d rank1=%d mask=%x", + i_vpd_info.iv_rank_count_dimm_0, + i_vpd_info.iv_rank_count_dimm_1, + l_rankMask); + + // Use mapping data to find the second vpd keyword character + // Skip first row which is the version header. + for (index = 1; index < MAPPING_LAYOUT_MAXROWS - 1; index++) + { + if (MAPPING_LAYOUT_LAST == l_mapping[index].keywordChar) + { + break; //hit end of table + } + + if ( (l_mcaMask & + (((l_mapping[index].mcaMaskMSB) << 8) | //endian sensitive + l_mapping[index].mcaMaskLSB)) && + (l_rankMask & l_mapping[index].rankMask) && + (l_freqMask & l_mapping[index].freqMask) ) + { + // This row covers mca, ranks, and freq + l_second = l_mapping[index].keywordChar; + break; + } + } + + //Was a matching row found? + FAPI_ASSERT(0 != l_second, + fapi2::GET_MEM_VPD_NO_MATCH_FOUND(). + set_TYPE(fapi2::MemVpdData(i_vpd_info.iv_vpd_type)). + set_MCA(fapi2::ATTR_MEMVPD_POS_Type(l_mcaPos)). + 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_HEADER(mappingKeywordRow(l_mapping[0])), + "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_TYPE(fapi2::MemVpdData(i_vpd_info.iv_vpd_type)). + set_MCA(fapi2::ATTR_MEMVPD_POS_Type(l_mcaPos)). + 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_VPDMCAMASK(uint16_t(((l_mapping[index].mcaMaskMSB) << 8) | + l_mapping[index].mcaMaskLSB)). + set_VPDFREQMASK(uint8_t(l_mapping[index].freqMask)). + set_VPDRANKMASK(uint8_t(l_mapping[index].rankMask)), + "Unsupported configuration"); + + // build keyword + o_keywordName[0] = l_first; + o_keywordName[1] = l_second; + o_keywordName[2] = 0; + FAPI_DBG("p9_get_mem_vpd_keyword: keyword name = %s", + o_keywordName); + fapi_try_exit: + + FAPI_DBG("p9_get_mem_vpd_keyword: exit"); + return fapi2::current_err; + } + +} //extern C diff --git a/src/import/chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.H b/src/import/chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.H new file mode 100644 index 000000000..dca3b3fad --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.H @@ -0,0 +1,138 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* EKB Project */ +/* */ +/* COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/// +/// @file p9_get_mem_vpd_keyword.H +/// @brief Return mem vpd keyword based on VPDInfo +/// + +// *HWP HWP Owner: Dan Crowell +// *HWP HWP Backup: Matt Light +// *HWP FW Owner: Dan Crowell +// *HWP Team: +// *HWP Level: 3 +// *HWP Consumed by: Cronus, FSP, HB + +#ifndef _GET_MEM_VPD_KEYWORD_H_ +#define _GET_MEM_VPD_KEYWORD_H_ + +#include +#include + +namespace fapi2 +{ +/// vpd keyword to be read based on input parameters and MR/MT mapping. +/// For example, X0...XZ for MT or J0...JZ for MR vpd data. +/// Return as a string for convenient debug traces. +enum +{ + KEYWORD_BYTE_SIZE = 2, +}; +typedef char keywordName_t [KEYWORD_BYTE_SIZE + 1]; + +/// Structure for the layout of the MR and MT mapping keyword +enum mappingKeywordEnum +{ + MAPPING_LAYOUT_VERSION = 1, + MAPPING_LAYOUT_INVALID = 0xff, + MAPPING_LAYOUT_LAST = 0x00, + MAPPING_LAYOUT_MAXROWS = 38, //header,0..9,A..Z,end mark + + MAPPING_LAYOUT_MCA0 = 0x8000, //mca position 0 + MAPPING_LAYOUT_MCA15 = 0x0001, //mca position 15 + MAPPING_LAYOUT_DIMM0_RANK0 = 0x80, //Dimm 0 rank count = 0 + MAPPING_LAYOUT_DIMM0_RANK4 = 0x10, //Dimm 0 rank count = 4 + MAPPING_LAYOUT_DIMM1_RANK0 = 0x08, //Dimm 1 rank count = 0 + MAPPING_LAYOUT_DIMM1_RANK4 = 0x01, //Dimm 1 rank count = 4 + MAPPING_LAYOUT_FREQ0 = 0x08, //Frequency index 0 + MAPPING_LAYOUT_FREQ3 = 0x01, //Frequency index 3 +}; +union mappingKeywordRow +{ + struct //first entry is version + { + uint8_t layoutVersion; + uint16_t headerReserved; + uint16_t dataVersion; + } __attribute__((packed)); + struct //criteria mapping entries + { + uint8_t mcaMaskMSB; // mca mask high order byte + uint8_t mcaMaskLSB; // mca mask low order byte + uint8_t rankMask; // high nibble rank 0, low nibble rank 1 + uint8_t freqMask; // high nibble reserved + char keywordChar; // 0..9,A..Z + } __attribute__((packed)); +}; +} + +typedef fapi2::ReturnCode (*p9_get_mem_vpd_keyword_t)( + const fapi2::Target&, + const fapi2::VPDInfo&, + const uint8_t*, + const size_t, + fapi2::keywordName_t&); +extern "C" +{ + + /// @brief Return VPD keyword based on MCA, VPDInfo, and MR/MT mapping + /// The MR and MT keyword contains a header followed by a table. Each + /// row in the table has criteria to select a vpd keyword. + /// + /// 0 1 2 3 4 + /// mmmm.mmmm.mmmm.mmmm.rrrr.ssss.xxxx.ffff.dddd.dddd + /// + /// m...m mca position + /// 0x8000 mca position 0 + /// 0x0001 mca position 15 + /// rrrr dimm 0 rank count = 0,1,2,4 + /// 0x80 rank count 0 + /// 0x10 rank count 4 + /// ssss dimm 1 rank count = 0,1,2,4 + /// 0x08 rank count 0 + /// 0x01 rank count 4 + /// ffff frequency index from ATTR_MEMVPD_FREQS_MHZ + /// 0x08 index 0 + /// 0x01 index 3 + /// dddd second char in keyword name + /// + /// All the configurations for a particular keyword are 'OR'ed into the + /// row for that keyword. + /// Rows with all 0's do not need to be included. The last row has dddd = 0. + /// Unsupported configurations can be mapped to dddd = 0xff. + /// + /// Note: this interface should not be called directly by HWPs, + /// it is provided for platform use behind the getVPD() interface. + /// + /// @param[in] i_target, the MCA + /// @param[in] i_vpd_info, vpd criteria + /// @param[in] i_pMapping, MR or MT keyword data + /// @param[in] i_mappingSize, size of i_pMapping buffer + /// @param[out] o_keywordName, keyword with vpd + /// @return FAPI2_RC_SUCCESS iff ok + fapi2::ReturnCode p9_get_mem_vpd_keyword ( + const fapi2::Target& i_target, + const fapi2::VPDInfo& i_vpd_info, + const uint8_t* i_pMapping, + const size_t i_mappingSize, + fapi2::keywordName_t& o_keywordName); + +} + +#endif diff --git a/src/import/chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.mk b/src/import/chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.mk new file mode 100644 index 000000000..b93626c84 --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.mk @@ -0,0 +1,22 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.mk $ +# +# IBM CONFIDENTIAL +# +# EKB Project +# +# COPYRIGHT 2015,2016 +# [+] International Business Machines Corp. +# +# +# The source code for this program is not published or otherwise +# divested of its trade secrets, irrespective of what has been +# deposited with the U.S. Copyright Office. +# +# IBM_PROLOG_END_TAG + +# Include the macros and things for MSS procedures +PROCEDURE=p9_get_mem_vpd_keyword +$(call BUILD_PROCEDURE) -- cgit v1.2.1