diff options
author | Matt Derksen <v2cibmd@us.ibm.com> | 2016-09-09 10:51:57 -0500 |
---|---|---|
committer | Christian R. Geddes <crgeddes@us.ibm.com> | 2016-09-16 15:24:08 -0400 |
commit | 3023dfca018c30c87072c4376c6f69dc35aef0d3 (patch) | |
tree | 40149cac472df14c4a3449ea00c61ae46f0e59a2 /src | |
parent | 48f5f0b3e5f1ec65e90d2307caed92ab000f869b (diff) | |
download | talos-hostboot-3023dfca018c30c87072c4376c6f69dc35aef0d3.tar.gz talos-hostboot-3023dfca018c30c87072c4376c6f69dc35aef0d3.zip |
Added CK and DQ vpd accessors
Change-Id: Ic72c985b1fe064273bc39f14bcc31595117c6a08
RTC:159347
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29421
Tested-by: PPE CI <ppe-ci+hostboot@us.ibm.com>
Reviewed-by: Martin Gloff <mgloff@us.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Matt K. Light <mklight@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29426
Reviewed-by: Hostboot Team <hostboot@us.ibm.com>
Tested-by: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/import/chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.C | 352 | ||||
-rw-r--r-- | src/import/chips/p9/procedures/hwp/accessors/p9_get_mem_vpd_keyword.H | 21 | ||||
-rw-r--r-- | src/import/chips/p9/procedures/xml/attribute_info/memory_override_attributes.xml | 53 | ||||
-rw-r--r-- | src/import/chips/p9/procedures/xml/error_info/p9_get_mem_vpd_keyword.xml | 12 | ||||
-rw-r--r-- | src/import/hwpf/fapi2/xml/attribute_info/hb_temp_defaults.xml | 18 | ||||
-rw-r--r-- | src/include/usr/vpd/dvpdenums.H | 10 | ||||
-rw-r--r-- | src/usr/fapi2/plat_vpd_access.C | 183 | ||||
-rw-r--r-- | src/usr/fapi2/test/getVpdTest.C | 116 | ||||
-rw-r--r-- | src/usr/fapi2/test/getVpdTest.H | 22 |
9 files changed, 578 insertions, 209 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 717d3ee5d..9ef8237b3 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 @@ -71,6 +71,15 @@ struct mappingHeader_t //header is first in mapping keyword uint8_t reserved; // reserved } __attribute__((packed)); +// header for Q0 and CK keywords +struct mappingHeader2_t //header is first in mapping keyword +{ + uint8_t layoutVersion; // decode version + uint8_t numEntries; // number of criteria mapping entries (DQ = # of map entries) + uint8_t blobSize; // # bytes in each data entry + uint8_t reserved; +} __attribute__((packed)); + struct mappingKeywordRow_t //criteria mapping entries follow header { uint8_t mcsMaskMSB; // mcs mask high order byte @@ -81,28 +90,39 @@ struct mappingKeywordRow_t //criteria mapping entries follow header char keywordChar; // 0..9,A..Z } __attribute__((packed)); +struct mappingDqRow_t // DQ map entries following header +{ + fapi2::ATTR_MEMVPD_POS_Type qPosition; + uint8_t qNum; +} __attribute__((packed)); + +const size_t DQ_MAP_SIZE = 36; +const size_t DQ_BLOB_SIZE = 160; + + extern "C" { /// @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. +/// The MR and MT keyword contains a header followed by a table. +/// Each row in the table has criteria to select a vpd keyword. +/// DQ keyword uses Q0 as a map to Q1-Q8 keywords. Q0 and CK have a header. /// /// @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_pMapping, MR, MT, Q0, or CK keyword data /// @param[in] i_mappingSize, size of i_pMapping buffer -/// @param[out] o_keywordName, keyword with vpd +/// @param[out] o_keywordInfo, keyword with its vpd information /// @return FAPI2_RC_SUCCESS iff ok fapi2::ReturnCode p9_get_mem_vpd_keyword( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, const fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS>& i_vpd_info, const uint8_t* i_pMapping, const size_t i_mappingSize, - fapi2::keywordName_t& o_keywordName) + fapi2::keywordInfo_t& o_keywordInfo) { char l_first = 0; //first character of return keyword name - char l_second = 0; //second character of return keyword name + char l_second = MAPPING_LAYOUT_INVALID; //second character of return keyword name fapi2::ATTR_MEMVPD_POS_Type l_mcsPos = 0; uint16_t l_mcsMask = 0; uint16_t l_rankMask = 0; @@ -113,49 +133,51 @@ extern "C" uint32_t l_freqTableCnt = sizeof(l_freqTable) / sizeof(l_freqTable[0]); uint32_t l_index = 0; //start with first criteria row uint32_t l_indexMax = MAPPING_LAYOUT_MAXROWS; + o_keywordInfo.kwBlobIndex = 0; // default blob is entire keyword data + o_keywordInfo.kwBlobSize = i_mappingSize; + const mappingHeader_t* l_mappingHeader = //pointer to header reinterpret_cast<const mappingHeader_t*>(i_pMapping); + const mappingHeader2_t* l_mappingHeader2 = //pointer to header2 (used for DQ and CK) + reinterpret_cast<const mappingHeader2_t*>(i_pMapping); + const mappingKeywordRow_t* l_mapping = //pointer to first criteria row reinterpret_cast<const mappingKeywordRow_t*>(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_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_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_mappingHeader->layoutVersion, - fapi2::GET_MEM_VPD_UNSUPPORTED_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_mappingHeader->layoutVersion, - MAPPING_LAYOUT_VERSION); + size_t l_mapping_layout_maxsize; + uint8_t l_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'; //MT vpd keyword name X0..X9,XA..XZ + l_mapping_layout_version = MAPPING_LAYOUT_VERSION; + l_mapping_layout_maxsize = sizeof(mappingHeader_t) + + size_t(sizeof(mappingKeywordRow_t) * MAPPING_LAYOUT_MAXROWS); break; case fapi2::MR: l_first = 'J'; //MR vpd keyword name J0..J9,JA..JZ + l_mapping_layout_version = MAPPING_LAYOUT_VERSION; + l_mapping_layout_maxsize = sizeof(mappingHeader_t) + + size_t(sizeof(mappingKeywordRow_t) * MAPPING_LAYOUT_MAXROWS); + break; + + case fapi2::DQ: + l_first = 'Q'; //DQ vpd keyword name Q1...Q8 + l_mapping_layout_version = MAPPING_LAYOUT_VERSION; + l_mapping_layout_maxsize = DQ_MAP_SIZE; + break; + + case fapi2::CK: + l_first = 'C'; //CKE vpd keyword name CK + l_mapping_layout_version = MAPPING_LAYOUT_VERSION; + l_mapping_layout_maxsize = sizeof(mappingHeader2_t) + + (l_mappingHeader2->numEntries * l_mappingHeader2->blobSize); break; default: @@ -165,8 +187,32 @@ extern "C" set_VPDTYPE(i_vpd_info.iv_vpd_type), "Invalid vpd type = %d", i_vpd_info.iv_vpd_type); + break; } + // Validate size of mapping to be at least large enough for biggest + // mapping table expected. + FAPI_ASSERT(l_mapping_layout_maxsize <= i_mappingSize, + fapi2::GET_MEM_VPD_MAPPING_TOO_SMALL(). + set_SIZE(size_t(i_mappingSize)). + set_EXPECTED(l_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, + l_mapping_layout_maxsize); + + // Validate mapping keyword version supported + FAPI_ASSERT(l_mapping_layout_version == l_mappingHeader->layoutVersion, + fapi2::GET_MEM_VPD_UNSUPPORTED_VERSION(). + set_VERSION(uint8_t(l_mappingHeader->layoutVersion)). + set_EXPECTED(uint8_t(l_mapping_layout_version)). + set_TARGET(i_target). + set_VPDTYPE(i_vpd_info.iv_vpd_type), + "Header version %d not supported % expected", + l_mappingHeader->layoutVersion, + l_mapping_layout_version); + // Get the MCS position and calculate mask FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEMVPD_POS, i_target, @@ -176,117 +222,162 @@ extern "C" FAPI_DBG ("p9_get_mem_vpd_keyword: mca position = %d mask=0x%04x", l_mcsPos, l_mcsMask); - // Get the frequency index and calculate mask - FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEMVPD_FREQS_MHZ, - fapi2::Target<TARGET_TYPE_SYSTEM>(), - 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_vpd_type == fapi2::CK) { - if (i_vpd_info.iv_freq_mhz == l_freqTable[l_freqTableIndex]) - { - break; // found it - } + // verify data index will be valid + FAPI_ASSERT(l_mcsPos < l_mappingHeader2->numEntries, + fapi2::GET_MEM_VPD_ENTRY_NOT_FOUND(). + set_ENTRY(l_mcsPos). + set_MAX_ENTRIES(uint8_t(l_mappingHeader2->numEntries)). + set_VERSION(uint8_t(l_mappingHeader2->layoutVersion)). + set_TARGET(i_target). + set_VPDTYPE(i_vpd_info.iv_vpd_type), + "Unsupported entry (%d), max entries (%d)", + l_mcsPos, + uint8_t(l_mappingHeader2->numEntries)); + + o_keywordInfo.kwBlobSize = l_mappingHeader2->blobSize; + + // Setup index to CK section data (ordered by memvpd pos) + o_keywordInfo.kwBlobIndex = (l_mcsPos * o_keywordInfo.kwBlobSize) + + sizeof(mappingHeader2_t); + + l_second = 'K'; } - - 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])). - 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_FREQ_0 >> l_freqTableIndex); //zero based - FAPI_DBG ("p9_get_mem_vpd_keyword: frequency index = %d mask=0x%02x", - l_freqTableIndex, l_freqMask); - - // 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) + else if (i_vpd_info.iv_vpd_type == fapi2::DQ) { - case 0: //index into pair order by multiplying by 4 - case 1: - case 2: - l_rankShift = i_vpd_info.iv_rank_count_dimm_0 * 4; - break; + // Find which Q# i_target is in + const mappingDqRow_t* l_dqmapping = //pointer to first criteria row + reinterpret_cast<const mappingDqRow_t*>(i_pMapping + + sizeof(mappingHeader2_t)); - case 4: // need to use value 3 for rank count 4 - l_rankShift = 3 * 4; - break; + for (uint8_t i = 0; i < l_mappingHeader->numEntries; i++) + { + if (l_dqmapping[i].qPosition == l_mcsPos) + { + l_second = l_dqmapping[i].qNum; + o_keywordInfo.kwBlobSize = DQ_BLOB_SIZE; + break; + } + } - default: - FAPI_ASSERT(false, - fapi2::GET_MEM_VPD_UNSUPPORTED_RANK(). - 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); + FAPI_DBG ("p9_get_mem_vpd_keyword: mcsPos %d -> Q%c keyword data", + l_mcsPos, l_second); } - - switch (i_vpd_info.iv_rank_count_dimm_1) + else { - case 0: //add in dimm 1 rank count index - case 1: - case 2: - l_rankShift += i_vpd_info.iv_rank_count_dimm_1; - break; + // Get the frequency index and calculate mask + FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_MEMVPD_FREQS_MHZ, + fapi2::Target<TARGET_TYPE_SYSTEM>(), + l_freqTable), + "p9_get_mem_vpd_keyword: get ATTR_MEMVPD_FREQS_MHZ failed"); - case 4: // need to use value 3 for rank count 4 - l_rankShift += 3; - break; + for (; l_freqTableIndex < l_freqTableCnt; l_freqTableIndex++) + { + if (i_vpd_info.iv_freq_mhz == l_freqTable[l_freqTableIndex]) + { + break; // found it + } + } - default: - FAPI_ASSERT(false, - fapi2::GET_MEM_VPD_UNSUPPORTED_RANK(). - 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_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])). + 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_FREQ_0 >> l_freqTableIndex); //zero based + FAPI_DBG ("p9_get_mem_vpd_keyword: frequency index = %d mask=0x%02x", + l_freqTableIndex, l_freqMask); + + // 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: //index into pair order by multiplying by 4 + case 1: + case 2: + l_rankShift = i_vpd_info.iv_rank_count_dimm_0 * 4; + break; + + 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_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); + } - 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); + switch (i_vpd_info.iv_rank_count_dimm_1) + { + case 0: //add in dimm 1 rank count index + case 1: + case 2: + l_rankShift += i_vpd_info.iv_rank_count_dimm_1; + break; + + 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_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); + } - // 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; - } + 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); - for (l_index = 0; l_index < l_indexMax; l_index++) - { - if (MAPPING_LAYOUT_LAST == l_mapping[l_index].keywordChar) + // 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) { - break; //Hit end of table (not expected, but being careful. - //The keyword is zero padded by genMemVpd.pl + l_indexMax = l_mappingHeader->numEntries; } - 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) ) + for (l_index = 0; l_index < l_indexMax; l_index++) { - // This row covers mca, ranks, and freq - l_second = l_mapping[l_index].keywordChar; - break; + if (MAPPING_LAYOUT_LAST == l_mapping[l_index].keywordChar) + { + break; //Hit end of table (not expected, but being careful. + //The keyword is zero padded by genMemVpd.pl + } + + 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 sensitive + l_mapping[l_index].rankMaskLSB)) && + (l_freqMask & l_mapping[l_index].freqMask) ) + { + // This row covers mca, ranks, and freq + l_second = l_mapping[l_index].keywordChar; + break; + } } } @@ -301,6 +392,7 @@ extern "C" 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(). @@ -318,11 +410,11 @@ extern "C" "Unsupported configuration"); // build the keyword name - o_keywordName[0] = l_first; - o_keywordName[1] = l_second; - o_keywordName[2] = 0; + o_keywordInfo.kwName[0] = l_first; + o_keywordInfo.kwName[1] = l_second; + o_keywordInfo.kwName[2] = 0; FAPI_DBG("p9_get_mem_vpd_keyword: keyword name = %s", - o_keywordName); + o_keywordInfo.kwName); fapi_try_exit: FAPI_DBG("p9_get_mem_vpd_keyword: exit"); 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 cff749fa2..4baff3fa9 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 @@ -43,7 +43,7 @@ namespace fapi2 { -/// vpd keyword to be read based on input parameters and MR/MT mapping. +/// vpd keyword to be read based on input parameters and MR/MT/DQ mapping. /// For example, X0...XZ for MT or J0...JZ for MR vpd data. /// Return as a string for convenient debug traces. enum @@ -51,6 +51,14 @@ enum KEYWORD_BYTE_SIZE = 2, }; typedef char keywordName_t [KEYWORD_BYTE_SIZE + 1]; + +typedef struct kwInfo +{ + keywordName_t kwName; // keyword, like X0..XZ, J0..JZ, Q1..Q8, or CK + uint16_t kwBlobSize; // blob size (valid for Q# and CK) + uint16_t kwBlobIndex; // offset of blob from start of keyword data +} keywordInfo_t; + } typedef fapi2::ReturnCode (*p9_get_mem_vpd_keyword_FP_t)( @@ -58,7 +66,7 @@ typedef fapi2::ReturnCode (*p9_get_mem_vpd_keyword_FP_t)( const fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS>&, const uint8_t*, const size_t, - fapi2::keywordName_t&); + fapi2::keywordInfo_t&); extern "C" { @@ -88,7 +96,7 @@ extern "C" /// 0x80 index 0 /// ... through .. /// 0x10 index 3 - // (frequency index 4-7 reserved) + /// (frequency index 4-7 reserved) /// dddd second char in keyword name /// /// All the configurations for a particular keyword are 'OR'ed into the @@ -98,19 +106,20 @@ extern "C" /// /// Note: this interface should not be called directly by HWPs, /// it is provided for platform use behind the getVPD() interface. + /// DQ keyword uses Q0 as a map to Q1-Q8 keywords. Q0 and CK have a header. /// /// @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_pMapping, MR, MT, Q0, or CK keyword data /// @param[in] i_mappingSize, size of i_pMapping buffer - /// @param[out] o_keywordName, keyword with vpd + /// @param[out] o_keywordInfo, keyword with its vpd information /// @return FAPI2_RC_SUCCESS iff ok fapi2::ReturnCode p9_get_mem_vpd_keyword ( const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, const fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS>& i_vpd_info, const uint8_t* i_pMapping, const size_t i_mappingSize, - fapi2::keywordName_t& o_keywordName); + fapi2::keywordInfo_t& o_keywordInfo); } diff --git a/src/import/chips/p9/procedures/xml/attribute_info/memory_override_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/memory_override_attributes.xml index 768280602..8f9c60d11 100644 --- a/src/import/chips/p9/procedures/xml/attribute_info/memory_override_attributes.xml +++ b/src/import/chips/p9/procedures/xml/attribute_info/memory_override_attributes.xml @@ -78,6 +78,59 @@ </attribute> <attribute> + <id>ATTR_VPD_OVERRIDE_DQ</id> + <targetType>TARGET_TYPE_MCS</targetType> + <description> + Byte-for-byte override for the bucket of DQ data that would + normally come from VPD. If ATTR_VPD_OVERRIDE_DQ_ENABLE!=0 then + the value of this attribute will be returned to callers of + fapi2::getVPD() instead of the actual VPD contents. + </description> + <valueType>uint8</valueType> + <array>160</array> + <platInit/> + <overrideOnly/> + </attribute> + + <attribute> + <id>ATTR_VPD_OVERRIDE_DQ_ENABLE</id> + <targetType>TARGET_TYPE_MCS</targetType> + <description> + Set equal to 1 to activate the use of ATTR_VPD_OVERRIDE_DQ. + </description> + <valueType>uint8</valueType> + <platInit/> + <overrideOnly/> + </attribute> + + <attribute> + <id>ATTR_VPD_OVERRIDE_CK</id> + <targetType>TARGET_TYPE_MCS</targetType> + <description> + Byte-for-byte override for the bucket of CK data that would + normally come from VPD. If ATTR_VPD_OVERRIDE_CK_ENABLE!=0 then + the value of this attribute will be returned to callers of + fapi2::getVPD() instead of the actual VPD contents. + </description> + <valueType>uint8</valueType> + <array>16</array> + <platInit/> + <overrideOnly/> + </attribute> + + <attribute> + <id>ATTR_VPD_OVERRIDE_CK_ENABLE</id> + <targetType>TARGET_TYPE_MCS</targetType> + <description> + Set equal to 1 to activate the use of ATTR_VPD_OVERRIDE_CK. + </description> + <valueType>uint8</valueType> + <platInit/> + <overrideOnly/> + </attribute> + + + <attribute> <id>ATTR_VPD_OVERRIDE_MW</id> <targetType>TARGET_TYPE_MCA</targetType> <description> diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_get_mem_vpd_keyword.xml b/src/import/chips/p9/procedures/xml/error_info/p9_get_mem_vpd_keyword.xml index 413cc15db..88de7eba7 100644 --- a/src/import/chips/p9/procedures/xml/error_info/p9_get_mem_vpd_keyword.xml +++ b/src/import/chips/p9/procedures/xml/error_info/p9_get_mem_vpd_keyword.xml @@ -45,7 +45,7 @@ <!-- ********************************************************************* --> <hwpError> <rc>RC_GET_MEM_VPD_UNSUPPORTED_TYPE</rc> - <description>Type not supported. Supported types are MR and MT</description> + <description>Type not supported. Supported types are MR, MT, DQ, and CK</description> <ffdc>TARGET</ffdc> <ffdc>VPDTYPE</ffdc> </hwpError> @@ -99,4 +99,14 @@ <ffdc>VPDTYPE</ffdc> </hwpError> <!-- ********************************************************************* --> + <hwpError> + <rc>RC_GET_MEM_VPD_ENTRY_NOT_FOUND</rc> + <description>Entry outside of possible entries</description> + <ffdc>ENTRY</ffdc> + <ffdc>MAX_ENTRIES</ffdc> + <ffdc>VERSION</ffdc> + <ffdc>TARGET</ffdc> + <ffdc>VPDTYPE</ffdc> + </hwpError> + <!-- ********************************************************************* --> </hwpErrors> diff --git a/src/import/hwpf/fapi2/xml/attribute_info/hb_temp_defaults.xml b/src/import/hwpf/fapi2/xml/attribute_info/hb_temp_defaults.xml index a53cea2b0..b8796f9c0 100644 --- a/src/import/hwpf/fapi2/xml/attribute_info/hb_temp_defaults.xml +++ b/src/import/hwpf/fapi2/xml/attribute_info/hb_temp_defaults.xml @@ -56,9 +56,21 @@ <!-- ===================================================================== Start of temporary definitions ================================================================= --> - <attribute> - <id>ATTR_PM_SPWUP_IGNORE_XSTOP_FLAG</id> - </attribute> + <attribute> + <id>ATTR_PM_SPWUP_IGNORE_XSTOP_FLAG</id> + </attribute> + <attribute> + <id>ATTR_VPD_OVERRIDE_DQ</id> + </attribute> + <attribute> + <id>ATTR_VPD_OVERRIDE_DQ_ENABLE</id> + </attribute> + <attribute> + <id>ATTR_VPD_OVERRIDE_CK</id> + </attribute> + <attribute> + <id>ATTR_VPD_OVERRIDE_CK_ENABLE</id> + </attribute> <!-- ===================================================================== End of temporary definitions diff --git a/src/include/usr/vpd/dvpdenums.H b/src/include/usr/vpd/dvpdenums.H index ee39e9905..c36b64ef7 100644 --- a/src/include/usr/vpd/dvpdenums.H +++ b/src/include/usr/vpd/dvpdenums.H @@ -159,6 +159,16 @@ namespace DVPD XX = 0x61, XY = 0x62, XZ = 0x63, + Q0 = 0x64, + Q1 = 0x65, + Q2 = 0x66, + Q3 = 0x67, + Q4 = 0x68, + Q5 = 0x69, + Q6 = 0x6A, + Q7 = 0x6B, + Q8 = 0x6C, + CK = 0X6D, // Last Keyword DVPD_LAST_KEYWORD, diff --git a/src/usr/fapi2/plat_vpd_access.C b/src/usr/fapi2/plat_vpd_access.C index 91ea92506..878441898 100644 --- a/src/usr/fapi2/plat_vpd_access.C +++ b/src/usr/fapi2/plat_vpd_access.C @@ -36,6 +36,7 @@ #include <attribute_service.H> #include <vpd/dvpdenums.H> + //The following can be uncommented for unit testing //#undef FAPI_DBG //#define FAPI_DBG(args...) FAPI_INF(args) @@ -50,7 +51,8 @@ fapi2::ReturnCode platGetVPD( { fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS; errlHndl_t l_errl = nullptr; - keywordName_t l_keywordName = {0}; + keywordInfo_t l_keywordInfo; + // Assume that all memory keywords (MR,MT,J0..JZ,X0...XZ) are all the // same size of 255. This avoids going through the decode and asking // the vpd DD the size of the keyword. @@ -63,6 +65,7 @@ fapi2::ReturnCode platGetVPD( // null blob pointer requests blob size if ( nullptr == o_blob) // just return size { + // use a generic max blob size (DQ and CK need less) io_vpd_info.iv_size = VPD_KEYWORD_SIZE; FAPI_DBG("platGetVPD: return blob size of %d", io_vpd_info.iv_size); @@ -144,6 +147,40 @@ fapi2::ReturnCode platGetVPD( l_mapKeyword = DVPD::MR; l_keywordEnum = DVPD::J0; } + else if ( fapi2::DQ == io_vpd_info.iv_vpd_type ) + { + if (1== + l_pMcsTarget->getAttr<TARGETING::ATTR_VPD_OVERRIDE_DQ_ENABLE>() ) + { + ATTR_VPD_OVERRIDE_DQ_Type l_override={0}; + assert(l_pMcsTarget->tryGetAttr<TARGETING::ATTR_VPD_OVERRIDE_DQ> + (l_override), + "platGetVPD: getAttr ATTR_VPD_OVERRIDE_DQ failed"); + FAPI_DBG("platGetVPD: return DQ override attr"); + memcpy(o_blob,l_override,sizeof(ATTR_VPD_OVERRIDE_DQ_Type)); + break; //return with overriden keyword + } + + // not overriden, continue + l_mapKeyword = DVPD::Q0; + l_keywordEnum = DVPD::Q0; + } + else if ( fapi2::CK == io_vpd_info.iv_vpd_type ) + { + if (1== + l_pMcsTarget->getAttr<TARGETING::ATTR_VPD_OVERRIDE_CK_ENABLE>() ) + { + ATTR_VPD_OVERRIDE_CK_Type l_override={0}; + assert(l_pMcsTarget->tryGetAttr<TARGETING::ATTR_VPD_OVERRIDE_CK> + (l_override), + "platGetVPD: getAttr ATTR_VPD_OVERRIDE_CK failed"); + FAPI_DBG("platGetVPD: return CK override attr"); + memcpy(o_blob,l_override,sizeof(ATTR_VPD_OVERRIDE_CK_Type)); + break; //return with overriden keyword + } + l_mapKeyword = DVPD::CK; + l_keywordEnum = DVPD::CK; + } else { FAPI_ERR("platGetVPD: invalid type = %d", @@ -191,77 +228,105 @@ fapi2::ReturnCode platGetVPD( io_vpd_info, l_pMapping, VPD_KEYWORD_SIZE, - l_keywordName); - delete l_pMapping; + l_keywordInfo); + if (l_rc) { + delete l_pMapping; FAPI_ERR("platGetVPD: ERROR returned from p9_get_mem_vpd_keyword"); break; //return with error } FAPI_DBG("platGetVPD: keyword name = %s", - l_keywordName); + l_keywordInfo.kwName); - //Convert keyword name to keyword enumeration. - //ascii 0..9 runs from 0x30 to 0x39. - //The conversion assumes the input is valid (0..9,A..Z) - //and that the enumeration is in order and consecutive. - if ( '0' == (l_keywordName[1] & 0xf0)) //it is a digit (0..9) + // Skip grabbing CK keyword data again and just use the index provided + // by the hwp to get the specific data for this particular mcs target + if (l_mapKeyword == DVPD::CK ) { - l_keywordEnum += (l_keywordName[1] - '0'); + l_buffSize = l_keywordInfo.kwBlobSize; + + // Just a safety check so you don't copy out of bounds + if (l_buffSize <= VPD_KEYWORD_SIZE) + { + // o_blob was already checked for nullptr + // copy blob of l_buffSize past the 4 byte header + // (each indexed section is l_buffSize bytes) + memcpy(o_blob, l_pMapping + l_keywordInfo.kwBlobIndex, l_buffSize); + } + else + { + memcpy(o_blob, + l_pMapping + l_keywordInfo.kwBlobIndex, + VPD_KEYWORD_SIZE); + } + delete l_pMapping; } - else //it is a char (A..Z) + else { - l_keywordEnum += (l_keywordName[1] - 'A') + 10; - } + delete l_pMapping; - //Read vpd blob - l_buffSize = io_vpd_info.iv_size; - l_errl = deviceRead((TARGETING::Target *)l_pMcsTarget, - o_blob, - l_buffSize, - DEVICE_DVPD_ADDRESS(DVPD::MEMD, - l_keywordEnum)); - if (l_errl) - { - FAPI_ERR("platGetVPD: ERROR reading keyword"); - l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl)); - break; //return with error - } + //Convert keyword name to keyword enumeration. + //ascii 0..9 runs from 0x30 to 0x39. + //The conversion assumes the input is valid (0..9,A..Z) + //and that the enumeration is in order and consecutive. + if ( '0' == (l_keywordInfo.kwName[1] & 0xf0)) //it is a digit (0..9) + { + l_keywordEnum += (l_keywordInfo.kwName[1] - '0'); + } + else //it is a char (A..Z) + { + l_keywordEnum += (l_keywordInfo.kwName[1] - 'A') + 10; + } - //Confirm all expected data was returned - if (VPD_KEYWORD_SIZE > l_buffSize) - { - FAPI_ERR("platGetVPD: insufficient vpd returned" - " for keyword %d;" - " %d returned, %d expected", - l_keywordEnum, - l_buffSize, - VPD_KEYWORD_SIZE); - /*@ - * @errortype - * @moduleid fapi2::MOD_FAPI2_PLAT_GET_VPD - * @reasoncode fapi2::RC_RETURNED_VPD_TOO_SMALL - * @userdata1[0:31] Returned vpd in bytes - * @userdata1[32:64] Expected number of vpd bytes - * @userdata2 Keyword - * @devdesc Less than expected number of bytes returned. - * @custdesc Firmware Error - */ - l_errl = new ERRORLOG::ErrlEntry( - ERRORLOG::ERRL_SEV_UNRECOVERABLE, - fapi2::MOD_FAPI2_PLAT_GET_VPD, - fapi2::RC_RETURNED_VPD_TOO_SMALL, - TWO_UINT32_TO_UINT64( - l_buffSize, - VPD_KEYWORD_SIZE), - l_keywordEnum); - l_errl->addHwCallout( l_pMcsTarget, - HWAS::SRCI_PRIORITY_LOW, - HWAS::NO_DECONFIG, - HWAS::GARD_NULL ); + //Read vpd blob + l_buffSize = l_keywordInfo.kwBlobSize; + l_errl = deviceRead((TARGETING::Target *)l_pMcsTarget, + o_blob, + l_buffSize, + DEVICE_DVPD_ADDRESS(DVPD::MEMD, + l_keywordEnum)); + if (l_errl) + { + FAPI_ERR("platGetVPD: ERROR reading keyword"); + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl)); + break; //return with error + } - l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl)); - break; //return with error + //Confirm all expected data was returned + if (l_keywordInfo.kwBlobSize > l_buffSize) + { + FAPI_ERR("platGetVPD: insufficient vpd returned" + " for keyword %d;" + " %d returned, %d expected", + l_keywordEnum, + l_buffSize, + io_vpd_info.iv_size); + /*@ + * @errortype + * @moduleid fapi2::MOD_FAPI2_PLAT_GET_VPD + * @reasoncode fapi2::RC_RETURNED_VPD_TOO_SMALL + * @userdata1[0:31] Returned vpd in bytes + * @userdata1[32:64] Expected number of vpd bytes + * @userdata2 Keyword + * @devdesc Less than expected number of bytes returned. + * @custdesc Firmware Error + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi2::MOD_FAPI2_PLAT_GET_VPD, + fapi2::RC_RETURNED_VPD_TOO_SMALL, + TWO_UINT32_TO_UINT64( + l_buffSize, + l_keywordInfo.kwBlobSize), + l_keywordEnum); + l_errl->addHwCallout( l_pMcsTarget, + HWAS::SRCI_PRIORITY_LOW, + HWAS::NO_DECONFIG, + HWAS::GARD_NULL ); + + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl)); + break; //return with error + } } } while (0); diff --git a/src/usr/fapi2/test/getVpdTest.C b/src/usr/fapi2/test/getVpdTest.C index e582ab609..6005d2d0a 100644 --- a/src/usr/fapi2/test/getVpdTest.C +++ b/src/usr/fapi2/test/getVpdTest.C @@ -227,7 +227,7 @@ void testDecode_MR(void) 0}; // decode keyword - keywordName_t l_keywordName = {0}; + keywordInfo_t l_keywordInfo = {0}; numTests++; FAPI_EXEC_HWP(l_rc, @@ -236,7 +236,7 @@ void testDecode_MR(void) l_info, l_pMapping, VPD_KEYWORD_SIZE, - l_keywordName); + l_keywordInfo); if(l_rc) { TS_FAIL ("testDecode_MR:: p9_get_mem_vpd_keyword failed"); @@ -246,12 +246,12 @@ void testDecode_MR(void) // compare to expected test data numTests++; - if ( (l_keywordName[0] != 'J' ) && - (l_keywordName[1] != '3' ) ) + if ( (l_keywordInfo.kwName[0] != 'J' ) && + (l_keywordInfo.kwName[1] != '3' ) ) { TS_FAIL ("testDecode_MR:: unexpected keyword name returned" "value = %x %x expected = %x %x", - l_keywordName[0],l_keywordName[1],'J','3'); + l_keywordInfo.kwName[0],l_keywordInfo.kwName[1],'J','3'); numFails++; } @@ -307,7 +307,7 @@ void testDecode_MT(void) 0}; // decode keyword - keywordName_t l_keywordName = {0}; + keywordInfo_t l_keywordInfo = {0}; numTests++; FAPI_EXEC_HWP(l_rc, p9_get_mem_vpd_keyword, @@ -315,7 +315,7 @@ void testDecode_MT(void) l_info, l_pMapping, VPD_KEYWORD_SIZE, - l_keywordName); + l_keywordInfo); if(l_rc) { TS_FAIL ("testDecode_MT:: p9_get_mem_vpd_keyword failed"); @@ -325,12 +325,12 @@ void testDecode_MT(void) // compare to expected test data numTests++; - if ( (l_keywordName[0] != 'X' ) && - (l_keywordName[1] != '3' ) ) + if ( (l_keywordInfo.kwName[0] != 'X' ) && + (l_keywordInfo.kwName[1] != '3' ) ) { TS_FAIL ("testDecode_MT:: unexpected keyword name returned" "value = %x %x expected = %x %x", - l_keywordName[0],l_keywordName[1],'X','3'); + l_keywordInfo.kwName[0],l_keywordInfo.kwName[1],'X','3'); numFails++; } @@ -610,3 +610,99 @@ void testGetVPD_Override(void) numMRFails+numMTFails, numMRTests+numMTTests); } + +void testGetVPD_DQ(void) +{ + int numTests = 0; + int numFails = 0; + ReturnCode l_rc; + + FAPI_DBG("testGetVPD DQ start"); + + do + { + numTests++; // find MCS MEMVPD_POS + // get a MCS fapi2 target for MEMVPD_POS 0 + TARGETING::ATTR_MEMVPD_POS_type l_memVpdPos = 0; + + fapi2::Target<fapi2::TARGET_TYPE_MCS> l_fapiTarget; + TARGETING::Target * l_target; + if(!getTarget(l_memVpdPos,l_target,l_fapiTarget)) + { + TS_FAIL ("testGetVPD_DQ:: could not find MCS MEMVPD_POS=%d", + l_memVpdPos); + numFails++; + break; //Target not found + } + + // set up VPDInfo + fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS> l_info(fapi2::DQ); + + l_rc = testGetVPD(l_fapiTarget, + l_info, + fapi2::DQ, + nullptr, //don't test data, just ability to access + numTests, + numFails); + if(l_rc) + { + TS_FAIL ("testGetVPD DQ:: testGetVPD decode failed"); + break; // decode failed (don't double count num tests and fails) + } + + } + while(0); + + FAPI_INF("testGetVPD DQ Test Complete, %d/%d fails", + numFails, numTests); +} + +void testGetVPD_CK(void) +{ + int numTests = 0; + int numFails = 0; + ReturnCode l_rc; + + FAPI_DBG("testGetVPD CK start"); + + do + { + numTests++; // find MCS MEMVPD_POS + + // get a MCS fapi2 target for MEMVPD_POS 0 + TARGETING::ATTR_MEMVPD_POS_type l_memVpdPos = 0; + + fapi2::Target<fapi2::TARGET_TYPE_MCS> l_fapiTarget; + TARGETING::Target * l_target; + if(!getTarget(l_memVpdPos,l_target,l_fapiTarget)) + { + TS_FAIL ("testGetVPD_DQ:: could not find MCS MEMVPD_POS=%d", + l_memVpdPos); + numFails++; + break; //Target not found + } + + // set up VPDInfo + fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS> l_info(fapi2::CK); + + // modify this if the data changes (currently common for all positions) + const char testData[] = {0x80,0x40, 0}; + + l_rc = testGetVPD(l_fapiTarget, + l_info, + fapi2::CK, + testData, + numTests, + numFails); + if(l_rc) + { + TS_FAIL ("testGetVPD CK:: testGetVPD decode failed"); + break; // decode failed (don't double count num tests and fails) + } + + } + while(0); + + FAPI_INF("testGetVPD CK Test Complete, %d/%d fails", + numFails, numTests); +} diff --git a/src/usr/fapi2/test/getVpdTest.H b/src/usr/fapi2/test/getVpdTest.H index b7b67e672..bc435e1b8 100644 --- a/src/usr/fapi2/test/getVpdTest.H +++ b/src/usr/fapi2/test/getVpdTest.H @@ -76,4 +76,26 @@ void testDecode_MT(void); */ void testGetVPD_Override(void); +/** + * @brief MCS getVpd DQ tests + * + * Test the getVPD DQ interface. Based on a VPDInfo configuration, + * verify the expected direct memory vpd is returned. + * There is a dependency to update standalone simics direct memory (dvpd.dat) + * for the configuration to map to a keyword, but there is no data dependency. + * expected data. + */ +void testGetVPD_DQ(void); + +/** + * @brief MCS getVpd CK tests + * + * Test the getVPD CK interface. Based on a VPDInfo configuration, + * verify the expected direct memory vpd is returned. + * There is a dependency to update standalone simics direct memory (dvpd.dat) + * for the configuration to map to a keyword, but there is no data dependency. + * expected data. + */ +void testGetVPD_CK(void); + #endif |