From 45c6a566f49ea3223492e35e21abc7fa9a058970 Mon Sep 17 00:00:00 2001 From: whs Date: Thu, 2 Jun 2016 13:45:11 -0500 Subject: Packaging of memory vpd on Nimbus, MCA->MCS Change from MCA to MCS target. Update decode logic. Change-Id: I71408c25ce33cf6e342bb704b5d173f8d98229dc RTC: 144519 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/25403 Tested-by: Jenkins Server Tested-by: PPE CI Tested-by: Hostboot CI Reviewed-by: William H. Schwartz Reviewed-by: ANDRE A. MARIN Reviewed-by: Daniel M. Crowell Reviewed-by: Jennifer A. Stofer Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/25472 Tested-by: FSP CI Jenkins --- .../hwp/accessors/p9_get_mem_vpd_keyword.C | 216 +++++++++++++-------- .../hwp/accessors/p9_get_mem_vpd_keyword.H | 81 +++----- 2 files changed, 164 insertions(+), 133 deletions(-) (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 index edaed1fd0..bbc136ce2 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 @@ -35,104 +35,142 @@ 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; + +//remove the following comments for unit testing +//#undef FAPI_DBG +//#define FAPI_DBG(args...) FAPI_INF(args) + +/// Local declartions + +/// 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 = 36, //0..9,A..Z + + MAPPING_LAYOUT_MCS_0 = 0x8000, //mcs position 0 + MAPPING_LAYOUT_MCS_15 = 0x0001, //mcs position 15 + MAPPING_LAYOUT_RANKPAIR_00 = 0x8000, //Rank pair 0x00 + MAPPING_LAYOUT_RANKPAIR_44 = 0x0001, //Rank pair 0x44 + MAPPING_LAYOUT_FREQ_0 = 0x80, //Frequency index 0 + MAPPING_LAYOUT_FREQ_3 = 0x10, //Frequency index 3 +}; + +struct mappingHeader_t //header is first in mapping keyword +{ + uint8_t layoutVersion; // decode version + uint8_t numEntries; // number of criteria mapping entries + uint8_t reserved; // reserved +} __attribute__((packed)); + +struct mappingKeywordRow_t //criteria mapping entries follow header +{ + uint8_t mcsMaskMSB; // mcs mask high order byte + uint8_t mcsMaskLSB; // mcs mask low order byte + uint8_t rankMaskMSB; // rank mask high order byte + uint8_t rankMaskLSB; // rank mask low order byte + uint8_t freqMask; // low nibble reserved + char keywordChar; // 0..9,A..Z +} __attribute__((packed)); extern "C" { -/// @brief Return VPD keyword based on MCA, VPDInfo, and MR/MT mapping +/// @brief Return VPD keyword based on MCS, 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_target, the MCS /// @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 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; + char l_first = 0; //first character of return keyword name + char l_second = 0; //second character of return keyword name + fapi2::ATTR_MEMVPD_POS_Type l_mcsPos = 0; + uint16_t l_mcsMask = 0; + uint16_t l_rankMask = 0; + uint8_t l_rankShift = 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); + uint32_t l_index = 0; //start with first criteria row + uint32_t l_indexMax = MAPPING_LAYOUT_MAXROWS; + const mappingHeader_t* l_mappingHeader = //pointer to header + reinterpret_cast(i_pMapping); + const mappingKeywordRow_t* l_mapping = //pointer to first criteria row + reinterpret_cast(i_pMapping + + sizeof(mappingHeader_t)); 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); + size_t(sizeof(mappingKeywordRow_t) * MAPPING_LAYOUT_MAXROWS) + + sizeof(mappingHeader_t); 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)), + set_EXPECTED(size_t(MAPPING_LAYOUT_MAXSIZE)). + set_TARGET(i_target). + set_VPDTYPE(i_vpd_info.iv_vpd_type), "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, + FAPI_ASSERT(MAPPING_LAYOUT_VERSION == l_mappingHeader->layoutVersion, fapi2::GET_MEM_VPD_UNSUPPORTED_VERSION(). - set_VERSION(uint8_t(l_mapping[index].layoutVersion)). - set_EXPECTED(uint8_t(MAPPING_LAYOUT_VERSION)), + set_VERSION(uint8_t(l_mappingHeader->layoutVersion)). + set_EXPECTED(uint8_t(MAPPING_LAYOUT_VERSION)). + set_TARGET(i_target). + set_VPDTYPE(i_vpd_info.iv_vpd_type), "Header version %d not supported % expected", - l_mapping[index].layoutVersion, + l_mappingHeader->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 + l_first = 'X'; //MT vpd keyword name X0..X9,XA..XZ break; case fapi2::MR: - l_first = 'J'; //vpd keyword name J0..J9,JA..JZ + l_first = 'J'; //MR 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)), + set_TARGET(i_target). + set_VPDTYPE(i_vpd_info.iv_vpd_type), "Invalid vpd type = %d", i_vpd_info.iv_vpd_type); } - // Get the MCA position + // Get the MCS position and calculate mask FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEMVPD_POS, i_target, - l_mcaPos), + l_mcsPos), "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); + l_mcsMask = (MAPPING_LAYOUT_MCS_0 >> l_mcsPos); //zero based + FAPI_DBG ("p9_get_mem_vpd_keyword: mca position = %d mask=0x%04x", + l_mcsPos, l_mcsMask); - // Get the frequency index + // Get the frequency index and calculate mask FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEMVPD_FREQS_MHZ, fapi2::Target(), l_freqTable), @@ -152,79 +190,96 @@ extern "C" 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])), + set_MEMVPDFREQ3(uint32_t(l_freqTable[3])). + set_TARGET(i_target). + set_VPDTYPE(i_vpd_info.iv_vpd_type), "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_freqMask = (MAPPING_LAYOUT_FREQ_0 >> l_freqTableIndex); //zero based + FAPI_DBG ("p9_get_mem_vpd_keyword: frequency index = %d mask=0x%02x", l_freqTableIndex, l_freqMask); - // Get rank mask. Valid ranks are 0,1,2,4 - // Mask = rrrrssss rrrr for rank0, ssss for rank1 + // Calculate rank count mask. Valid rank counts are 0,1,2 or 4. + // The mask has a bit for each of the 16 rank pairs of + // dimm0 rank count by dimm1 count rank. + // This notation is used by genMemVpd.pl to specify pairs. + // Order= 0x00, 0x01, 0x02, 0x04, 0x11, 0x12, ... 0x42, 0x44 switch (i_vpd_info.iv_rank_count_dimm_0) { - case 0: //can use shift, high order nibble + case 0: //index into pair order by multiplying by 4 case 1: case 2: - l_rankMask = - (MAPPING_LAYOUT_DIMM0_RANK0 >> i_vpd_info.iv_rank_count_dimm_0); + l_rankShift = i_vpd_info.iv_rank_count_dimm_0 * 4; break; - case 4: - l_rankMask = MAPPING_LAYOUT_DIMM0_RANK4; + case 4: // need to use value 3 for rank count 4 + l_rankShift = 3 * 4; break; default: FAPI_ASSERT(false, fapi2::GET_MEM_VPD_UNSUPPORTED_RANK(). - set_RANK(uint64_t(i_vpd_info.iv_rank_count_dimm_0)), + set_RANK(uint64_t(i_vpd_info.iv_rank_count_dimm_0)). + set_TARGET(i_target). + set_VPDTYPE(i_vpd_info.iv_vpd_type), "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 0: //add in dimm 1 rank count index case 1: case 2: - l_rankMask |= - (MAPPING_LAYOUT_DIMM1_RANK0 >> i_vpd_info.iv_rank_count_dimm_1); + l_rankShift += i_vpd_info.iv_rank_count_dimm_1; break; - case 4: - l_rankMask |= MAPPING_LAYOUT_DIMM1_RANK4; + case 4: // need to use value 3 for rank count 4 + l_rankShift += 3; break; default: FAPI_ASSERT(false, fapi2::GET_MEM_VPD_UNSUPPORTED_RANK(). - set_RANK(uint64_t(i_vpd_info.iv_rank_count_dimm_1)), + set_RANK(uint64_t(i_vpd_info.iv_rank_count_dimm_1)). + set_TARGET(i_target). + set_VPDTYPE(i_vpd_info.iv_vpd_type), "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", + l_rankMask = (MAPPING_LAYOUT_RANKPAIR_00 >> l_rankShift); + FAPI_DBG("p9_get_mem_vpd_keyword: rank0=%d rank1=%d mask=0x%04x", 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++) + // Use mapping data to find the second vpd keyword character. + // Select the row where the MCS, Frequency, and rank count pair + // bit are on in the criteria row in the mapping keyword. + if (MAPPING_LAYOUT_MAXROWS > l_mappingHeader->numEntries) + { + l_indexMax = l_mappingHeader->numEntries; + } + + for (l_index = 0; l_index < l_indexMax; l_index++) { - if (MAPPING_LAYOUT_LAST == l_mapping[index].keywordChar) + if (MAPPING_LAYOUT_LAST == l_mapping[l_index].keywordChar) { - break; //hit end of table + break; //Hit end of table (not expected, but being careful. + //The keyword is zero padded by genMemVpd.pl } - 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) ) + if ( (l_mcsMask & + (((l_mapping[l_index].mcsMaskMSB) << 8) | //endian sensitive + l_mapping[l_index].mcsMaskLSB)) && + (l_rankMask & + (((l_mapping[l_index].rankMaskMSB) << 8) | //endian sensitve + l_mapping[l_index].rankMaskLSB)) && + (l_freqMask & l_mapping[l_index].freqMask) ) { // This row covers mca, ranks, and freq - l_second = l_mapping[index].keywordChar; + l_second = l_mapping[l_index].keywordChar; break; } } @@ -232,28 +287,31 @@ extern "C" //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_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_HEADER(mappingKeywordRow(l_mapping[0])), + set_HEADER(mappingHeader_t(*l_mappingHeader)). + set_TARGET(i_target). + set_VPDTYPE(i_vpd_info.iv_vpd_type), "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_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_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)), + 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 keyword + // build the keyword name o_keywordName[0] = l_first; o_keywordName[1] = l_second; o_keywordName[2] = 0; 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 index dca3b3fad..6f8c2d9e2 100644 --- 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 @@ -45,71 +45,44 @@ 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 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 + /// @brief Return VPD keyword based on MCS, 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 + /// 0 1 2 3 4 5 + /// mmmm.mmmm.mmmm.mmmm.rrrr.rrrr.rrrr.rrrr.ffff.xxxx.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 + /// m...m mcs ATTR_MEMVPD_POS position + /// 0x8000 mcs vpd position 0 (proc 0, postion 0) + /// ... through .. + /// 0x1000 mcs vpd position 3 (proc 0, postion 3) + /// 0x0800 mcs vpd position 4 (proc 1, postion 0) + /// ... through .. + /// 0x0100 mcs vpd position 7 (proc 1, position 3) + /// ... through .. + /// 0x0001 mcs vpd position 15(proc 3, position 3) + /// r...r Dimm rank count pair + /// 0x8000 dimm0 rank count 0, dimm1 rank count 0 + /// 0x4000 dimm0 rank count 0, dimm1 rank count 1 + /// ... through .. + /// 0x0002 dimm0 rank count 4, dimm1 rank count 2 + /// 0x0001 dimm0 rank count 4, dimm1 rank count 4 /// ffff frequency index from ATTR_MEMVPD_FREQS_MHZ - /// 0x08 index 0 - /// 0x01 index 3 + /// 0x80 index 0 + /// ... through .. + /// 0x10 index 3 + // (frequency index 4-7 reserved) /// dddd second char in keyword name /// /// All the configurations for a particular keyword are 'OR'ed into the @@ -120,15 +93,15 @@ extern "C" /// 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_target, the MCS /// @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 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); -- cgit v1.2.1