From 038631ba24f02f4019473f452d728c5604075176 Mon Sep 17 00:00:00 2001 From: Roland Veloz Date: Wed, 27 Feb 2019 16:50:21 -0600 Subject: Updated file ddimm_get_efd.C to be in sync with file ddimm_get_efd.xml The FAPI error xml file ddimm_get_efd.xml has been updated. Changes to this file are added to keep in sync with those changes. Also tweaked some of the callouts and added some more FFDC. Change-Id: I0f8173b474011b7c104f59b360f711c1bb4e52c5 RTC:203718 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/72594 Tested-by: FSP CI Jenkins Tested-by: Jenkins Server Reviewed-by: Roland Veloz Tested-by: Hostboot CI Reviewed-by: ANDRE A. MARIN Reviewed-by: Daniel M. Crowell Reviewed-by: Jennifer A. Stofer Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/72599 Tested-by: Jenkins OP Build CI Tested-by: Jenkins OP HW Reviewed-by: Christian R. Geddes --- .../p9/procedures/hwp/accessors/ddimm_get_efd.C | 451 +++++++++++++++------ 1 file changed, 317 insertions(+), 134 deletions(-) (limited to 'src/import/chips/p9/procedures/hwp/accessors') diff --git a/src/import/chips/p9/procedures/hwp/accessors/ddimm_get_efd.C b/src/import/chips/p9/procedures/hwp/accessors/ddimm_get_efd.C index 1ac156002..058067490 100644 --- a/src/import/chips/p9/procedures/hwp/accessors/ddimm_get_efd.C +++ b/src/import/chips/p9/procedures/hwp/accessors/ddimm_get_efd.C @@ -107,7 +107,8 @@ const size_t SPD_EFD_META_DATA_EFD_BLOCK_OFFSET_MASK = 0x1F; // Byte 3 offset to an individual EFD meta data // Bits 0 - 4: EFD block offset extension to an EFD in the EFD memory space // Currently not used -// Bits 7: Flag that indicates if an EFD, in the EFD memory space, is implemented +// Bits 7: Flag that indicates if an EFD, in the EFD memory space, is +// implemented. // SPD_EFD_META_DATA_EFD_IS_IMPLEMENTED_MASK can mask this bit out // size is 1 byte; address 3 const size_t SPD_EFD_META_DATA_EFD_BYTE_3_OFFSET = 3; @@ -122,6 +123,12 @@ const size_t SPD_EFD_INCREMENTAL_BLOCK_BYTE_SIZE = 32; // is a, value found at SPD_EFD_MEMORY_SPACE_SIZE_ADDR is b, and x is 2 // also see SPD_EFD_MEMORY_SPACE_SIZE_ADDR and calculateEfdMemorySpaceSize(..) const size_t EFD_EXPONENTIAL_BLOCK_MEMORY_SIZE = 1024; +// The 'assumed' maximum byte size. The reason it is assumed, is because +// the maximum size could get updated. Having this value allows for quick +// turn around on initial call. On subsequent call, size is verified and +// asserted if the assumption is incorrect. +const size_t SPD_EFD_ASSUMED_MAX_BYTE_SIZE = (4 * + SPD_EFD_INCREMENTAL_BLOCK_BYTE_SIZE); /// EFD - DDR4 memory addressing constants. /// These offsets are relative to the start of the actual EFD block @@ -150,6 +157,10 @@ const uint16_t SPD_DDR4_EXPECTED_DMB_MFG_ID = 0x2980; // size is 1 byte const uint8_t SPD_DDR4_EXPECTED_DMB_REVISION = 0x00; +// Maximum number of FFDC elements we will save off +// (should stay in sync with error xml) +const size_t MAX_EFD_FFDC = 32; + /// Local enumerations // * Bytes 205 and 206 of SPD and bytes 0 & 1 of EFD contain the frequency info. enum DDR_FREQUENCY : uint16_t @@ -289,6 +300,7 @@ uint64_t calculateEfdMemorySpaceSize(const uint8_t i_exponentialFactor) return retVal; }; + extern "C" { @@ -312,7 +324,7 @@ extern "C" const fapi2::Target& i_ocmbFapi2Target, fapi2::VPDInfo& io_vpdInfo, // Can modify data uint8_t* const o_efdData, // Don't change pointer but can modify data - const uint8_t* const i_spdBuffer, // Don't change pointer nor modify data + const uint8_t* const i_spdBuffer,// Don't change pointer nor modify data size_t i_spdBufferSize); // Don't modify // ddimm_get_efd @@ -328,24 +340,39 @@ extern "C" // Initialize the error flag to success fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - // Determine DDIMM type and do some sanity checks + // Sanity check that buffer is large enough to read DIMM Type // SPD size must be large enough to gather the DDIMM type info FAPI_ASSERT( (i_spdBufferSize > SPD_MEM_TYPE_ADDR), - fapi2::TEST_ERROR_A().set_TARGET(i_ocmbFapi2Target), - "SPD data size (%d) is insufficient to gather data from.", - i_spdBufferSize); + fapi2::DDIMM_GET_EFD_VPD_BUFFER_INADEQUATE_TO_GET_DDR_TYPE(). + set_VPD_BUFFER_SIZE(i_spdBufferSize). + set_REQUIRED_MIN_BUFFER_SIZE(static_cast + (SPD_MEM_TYPE_ADDR)). + set_OCMB_CHIP_TARGET(i_ocmbFapi2Target). + set_VPD_TYPE(io_vpdInfo.iv_vpd_type), + "ddimm_get_efd::The VPD buffer size (%d) is insufficient to " + "retrive the DDR type at location(%d).", + i_spdBufferSize, + SPD_MEM_TYPE_ADDR); // If working with a DDR4 then the SPD data size must // be at a minumum of what is required for a DDR4 FAPI_ASSERT( ( (i_spdBuffer[SPD_MEM_TYPE_ADDR] == SPD_DDR4_TYPE) && (i_spdBufferSize >= SPD_DDR4_SIZE) ), - fapi2::TEST_ERROR_A().set_TARGET(i_ocmbFapi2Target), - "Either memory type(0x%.2X) is not valid or size " - "of SPD data(%d) is insufficient for type", + fapi2::DDIMM_GET_EFD_VPD_BUFFER_INADEQUATE_FOR_DDR(). + set_VPD_BUFFER_SIZE(i_spdBufferSize). + set_DDR_TYPE(static_cast + (i_spdBuffer[SPD_MEM_TYPE_ADDR])). + set_REQUIRED_MIN_BUFFER_SIZE(SPD_DDR4_SIZE). + set_REQUIRED_DDR_TYPE(SPD_DDR4_TYPE). + set_OCMB_CHIP_TARGET(i_ocmbFapi2Target). + set_VPD_TYPE(io_vpdInfo.iv_vpd_type), + "ddimm_get_efd::Either the VPD buffer size(%d) is less " + "than the required DDR4 size(%d) or the DDR memory " + "type(0x%.2X) does not match the DDR4 memory type(0x%.2X)", + i_spdBufferSize, + SPD_DDR4_SIZE, i_spdBuffer[SPD_MEM_TYPE_ADDR], - i_spdBufferSize); - - FAPI_DBG ("ddimm_get_efd: working with a DDR4"); + SPD_DDR4_TYPE); // Call the explicit code for a DDR4 FAPI_TRY(ddr4_get_efd( i_ocmbFapi2Target, @@ -353,6 +380,7 @@ extern "C" o_efdData, i_spdBuffer, i_spdBufferSize)); + fapi_try_exit: FAPI_DBG("ddimm_get_efd: exiting with %s", @@ -374,47 +402,53 @@ extern "C" // Initialize the error flag fapi2::current_err = fapi2::FAPI2_RC_SUCCESS; - // The variable round up + // The variable round up. These variables MUST come before any call + // to FAPI_ASSERT, FAPI_TRY and 'goto fapi_try_exit'. uint64_t l_efdMemorySpaceOffset{0}; // The EFD memory location - uint64_t l_efdMemorySpaceSize{0}; // The EFD size of the EFD memory space - uint16_t l_efdCount{0}; // The number EFDs - size_t l_efdSize{0}; // The size of an EFD, not EFD meta data - uint16_t l_dmbMfgId{0}; // The DMB manufacture ID - uint16_t l_freqMask{0}; // The frequency mask as found in EFD - uint8_t l_rankMask{0}; // The rank mask as found in EFD - int ii{0}; // A loop index - const uint8_t* l_efdMetaDataPtr - { - nullptr - }; // Pointer the beginning of the EFD meta data - const uint8_t* l_efdDataPtr - { - nullptr - }; // Pointer the beginning of the EFD block - const uint8_t* l_efdMetaDataNptr - { - nullptr - }; // Pointer to an individual EFD meta data - const uint8_t* l_efdDataNptr + uint64_t l_efdMemorySpaceSize{0}; // The EFD size of the EFD mem space + uint16_t l_efdCount{0}; // The number of EFDs + size_t l_efdSize{0}; // The size of an EFD, not EFD meta data + uint16_t l_dmbMfgId{0}; // The DMB manufacture ID + uint16_t l_freqMask{0}; // The frequency mask as found in EFD + uint8_t l_rankMask{0}; // The rank mask as found in EFD + size_t ii{0}; // A loop index + // Pointer the beginning of the EFD meta data + const uint8_t* l_efdMetaDataPtr(nullptr); + // Pointer the beginning of the EFD block + const uint8_t* l_efdDataPtr(nullptr); + // Pointer to an individual EFD meta data + const uint8_t* l_efdMetaDataNptr(nullptr); + // Pointer to an individual EFD + const uint8_t* l_efdDataNptr(nullptr); + + // Fill in a data buffer for FFDC purposes that contains + // the first 8 bytes from the SPD (freq,rank,channel,dimms) + uint64_t l_ffdc_EFD[MAX_EFD_FFDC]; + memset( l_ffdc_EFD, 0, sizeof(l_ffdc_EFD) ); + + // On initial call, with nullptr for o_efdData, return the maximum size + // for the EFD. Will verify, on subsequent call, that the returned size + // is in fact large enough to hold the EFD data. + // Immediately setting the maximum size will expedite the code, not + // forcing caller to go thru a lot of code, twice, to verify size. + if ( nullptr == o_efdData ) // just return size { - nullptr - }; // Pointer to an individual EFD + io_vpdInfo.iv_size = SPD_EFD_ASSUMED_MAX_BYTE_SIZE; + FAPI_INF ("ddr4_get_efd: Caller passed in an EFD data nullptr, so " + "returning size = %d so caller can allocate space for " + "EFD data", + io_vpdInfo.iv_size); - //// First, set all the variables necessary to retrieve data from - //// the SPD, EFD meta data and the EFD memory space/block + goto fapi_try_exit; + } - FAPI_DBG ( "ddr4_get_efd: SPD buffer size = %d, SPD DDR4 size = %d", - i_spdBufferSize, SPD_DDR4_SIZE); - /// Sanity check the SPD buffer size. - // Make sure the size of the SPD buffer is large enough to contain the - // DDR4 SPD data. If not, can't reliably gather data from the buffer. - FAPI_ASSERT( (i_spdBufferSize >= SPD_DDR4_SIZE), - fapi2::TEST_ERROR_A().set_TARGET(i_ocmbFapi2Target), - "ddr4_get_efd: SPD buffer size = %d is insufficient to " - "gather data from, minimum required size is = %d", - i_spdBufferSize, - SPD_DDR4_SIZE ); + //// First, set and validate all the variables necessary to retrieve + //// data from the SPD, EFD meta data and the EFD memory space/block + + // From previous assert, buffer size is large enough to contain DDR4 + FAPI_DBG ( "ddr4_get_efd: SPD DDR4 size = %d, SPD buffer size = %d", + SPD_DDR4_SIZE, i_spdBufferSize); /// Get the EFD memory space offset (8 bytes) // The address where the EFD memory space is located at within the @@ -432,9 +466,15 @@ extern "C" // space. The EFD memory space cannot share the same memory space as // the SPD DDR4. FAPI_ASSERT( (l_efdMemorySpaceOffset >= SPD_DDR4_SIZE), - fapi2::TEST_ERROR_A().set_TARGET(i_ocmbFapi2Target), + fapi2::DDIMM_GET_EFD_EFD_MEMORY_SPACE_OFFSET_ERROR(). + set_EFD_MEMORY_SPACE_OFFSET(l_efdMemorySpaceOffset). + set_DDR4_MEMORY_SIZE(static_cast(SPD_DDR4_SIZE)). + set_OCMB_CHIP_TARGET(i_ocmbFapi2Target). + set_VPD_TYPE(static_cast(io_vpdInfo.iv_vpd_type)). + set_DDR_TYPE(static_cast + (i_spdBuffer[SPD_MEM_TYPE_ADDR])), "ddr4_get_efd: EFD memory space offset = %d resides " - "within the SPD DDR4 buffer size = %d. These two cannot " + "within the SPD DDR4 memory size = %d. These two cannot " "share the same meory space.", l_efdMemorySpaceOffset, SPD_DDR4_SIZE ); @@ -446,8 +486,8 @@ extern "C" i_spdBuffer[SPD_EFD_MEMORY_SPACE_SIZE_ADDR] & SPD_EFD_MEMORY_SPACE_SIZE_MASK); - FAPI_DBG ("ddr4_get_efd: EFD memory space size exponential factor = %d " - " converted to EFD memory space size = %d ", + FAPI_DBG ("ddr4_get_efd: EFD memory space size factor = %d, " + "converted to EFD memory space size = %d ", static_cast (i_spdBuffer[SPD_EFD_MEMORY_SPACE_SIZE_ADDR] & SPD_EFD_MEMORY_SPACE_SIZE_MASK), @@ -456,9 +496,16 @@ extern "C" // If the memory space is 0, then calculating the EFD memory // space size failed. FAPI_ASSERT( l_efdMemorySpaceSize, - fapi2::TEST_ERROR_A().set_TARGET(i_ocmbFapi2Target), - "ddr4_get_efd: Conversion unsuccessful for EFD space size " - "exponential factor = 0x%0.2X", + fapi2::DDIMM_GET_EFD_EFD_MEMORY_SIZE_MAPPING_ERROR(). + set_EFD_MEMORY_SPACE_MAPPING_VALUE + (static_cast + (i_spdBuffer[SPD_EFD_MEMORY_SPACE_SIZE_ADDR])). + set_OCMB_CHIP_TARGET(i_ocmbFapi2Target). + set_VPD_TYPE(static_cast(io_vpdInfo.iv_vpd_type)). + set_DDR_TYPE(static_cast + (i_spdBuffer[SPD_MEM_TYPE_ADDR])), + "ddr4_get_efd: Mapping unsuccessful for EFD space " + "size factor = 0x%0.2X", i_spdBuffer[SPD_EFD_MEMORY_SPACE_SIZE_ADDR] ); /// Sanity check the EFD memory space offset + EFD memory space size. @@ -468,10 +515,17 @@ extern "C" // the end of the DDR4 SPD data. FAPI_ASSERT( (i_spdBufferSize >= (l_efdMemorySpaceOffset + l_efdMemorySpaceSize)), - fapi2::TEST_ERROR_A().set_TARGET(i_ocmbFapi2Target), + fapi2::DDIMM_GET_EFD_EFD_MEMORY_SPACE_SIZE_ERROR(). + set_EFD_MEMORY_SPACE_OFFSET(l_efdMemorySpaceOffset). + set_EFD_MEMORY_SPACE_SIZE(l_efdMemorySpaceSize). + set_VPD_BUFFER_SIZE(i_spdBufferSize). + set_OCMB_CHIP_TARGET(i_ocmbFapi2Target). + set_VPD_TYPE(static_cast(io_vpdInfo.iv_vpd_type)). + set_DDR_TYPE(static_cast + (i_spdBuffer[SPD_MEM_TYPE_ADDR])), "ddr4_get_efd: SPD buffer size = %d is insufficient to " "accommodate the EFD memory space size = %d at " - "offset = %d; a minimum SPD buffer needed = %d", + "offset = %d; a minimum SPD buffer needed = %d", i_spdBufferSize, l_efdMemorySpaceSize, l_efdMemorySpaceOffset, @@ -486,14 +540,17 @@ extern "C" // Extract the number of EFDs l_efdCount &= SPD_EFD_COUNT_MASK; - FAPI_DBG ("ddr4_get_efd: number of EFDs = %d", l_efdCount); + FAPI_DBG ("ddr4_get_efd: The number of EFDs = %d", l_efdCount); /// Sanity check the number of EFDs extracted. // Make sure there is at least one EFD to work with FAPI_ASSERT( (l_efdCount), - fapi2::TEST_ERROR_A().set_TARGET(i_ocmbFapi2Target), - "ddr4_get_efd: The number of EFDs = %d. Need at least one", - l_efdCount); + fapi2::DDIMM_GET_EFD_NUMBER_OF_EFD_IS_ZERO(). + set_OCMB_CHIP_TARGET(i_ocmbFapi2Target). + set_VPD_TYPE(static_cast(io_vpdInfo.iv_vpd_type)). + set_DDR_TYPE(static_cast + (i_spdBuffer[SPD_MEM_TYPE_ADDR])), + "ddr4_get_efd: The number of EFDs is 0. Need at least one"); // The size of the EFD can be extrapolated from the first EFD. // Use the ending block info (byte 2) from EFD[0] to determine size. @@ -505,19 +562,24 @@ extern "C" SPD_EFD_META_DATA_EFD_BLOCK_OFFSET_MASK) * SPD_EFD_INCREMENTAL_BLOCK_BYTE_SIZE; - FAPI_DBG ("ddr4_get_efd: the EFD block size = %d", l_efdSize); - - // null o_efdData pointer = request for o_efdData size - if ( nullptr == o_efdData ) // just return size - { - io_vpdInfo.iv_size = l_efdSize; - FAPI_INF ("ddr4_get_efd: Caller passed in an EFD data nullptr, so " - "returning size = %d so caller can allocate space for " - "EFD data", - io_vpdInfo.iv_size); - - goto fapi_try_exit; - } + FAPI_DBG ("ddr4_get_efd: The EFD data block size = %d", l_efdSize); + + // Verify that io_vpdInfo.iv_size is large enough to + // hold the EFD data. If not, then assert. + FAPI_ASSERT( (io_vpdInfo.iv_size >= l_efdSize), + fapi2::DDIMM_GET_EFD_INADEQUATE_EFD_BUFFER_SIZE(). + set_EFD_BUFFER_SIZE(io_vpdInfo.iv_size). + set_EFD_BLOCK_SIZE(l_efdSize). + set_OCMB_CHIP_TARGET(i_ocmbFapi2Target). + set_VPD_TYPE(static_cast(io_vpdInfo.iv_vpd_type)). + set_DDR_TYPE(static_cast + (i_spdBuffer[SPD_MEM_TYPE_ADDR])), + "ddr4_get_efd: EFD block size = %d exceeds outgoing buffer " + "size = %d. Code const SPD_EFD_ASSUMED_MAX_BYTE_SIZE = %d " + "needs a size increase to match the EFD block size", + l_efdSize, + io_vpdInfo.iv_size, + static_cast(SPD_EFD_ASSUMED_MAX_BYTE_SIZE)); //// Secondly, get/confirm and set as much outgoing data as possible @@ -535,39 +597,52 @@ extern "C" // Swap endianess to host format. l_dmbMfgId = le16toh(l_dmbMfgId); - FAPI_DBG ( "ddr4_get_efd: SPD DMB manufacturer ID = 0x%.4X " + FAPI_DBG ( "ddr4_get_efd: SPD DMB manufacturer ID = 0x%.4X, " "expected DMB manufacturer ID = 0x%.4X", l_dmbMfgId, SPD_DDR4_EXPECTED_DMB_MFG_ID ); - // Confirm the DMB manufacturer ID value is what we expect + // Confirm the DMB manufacturer ID value is what is expected FAPI_ASSERT( (SPD_DDR4_EXPECTED_DMB_MFG_ID == l_dmbMfgId), - fapi2::TEST_ERROR_A().set_TARGET(i_ocmbFapi2Target), + fapi2::DDIMM_GET_EFD_UNSUPPORTED_DMB_MFG_ID(). + set_DMB_MFG_ID(static_cast(l_dmbMfgId)). + set_EXPECTED(static_cast + (SPD_DDR4_EXPECTED_DMB_MFG_ID)). + set_OCMB_CHIP_TARGET(i_ocmbFapi2Target). + set_VPD_TYPE(io_vpdInfo.iv_vpd_type). + set_DDR_TYPE(static_cast + (i_spdBuffer[SPD_MEM_TYPE_ADDR])), "ddr4_get_efd: SPD DMB manufacturer ID 0x%.4X is not the " "expected DMB manufacturer ID 0x%.4X ", l_dmbMfgId, - SPD_DDR4_EXPECTED_DMB_REVISION); + SPD_DDR4_EXPECTED_DMB_MFG_ID); // Set the outgoing DMB manufacturer ID - io_vpdInfo.iv_dmb_mfg_id = SPD_DDR4_EXPECTED_DMB_MFG_ID; + io_vpdInfo.iv_dmb_mfg_id = l_dmbMfgId; FAPI_DBG ( "ddr4_get_efd: SPD DMB manufacturer ID = 0x%.4X", io_vpdInfo.iv_dmb_mfg_id); - FAPI_DBG ( "ddr4_get_efd: SPD DMB revision = 0x%.2X " + FAPI_DBG ( "ddr4_get_efd: SPD DMB revision = 0x%.2X, " "expected DMB revision = 0x%.2X", i_spdBuffer[SPD_DMB_REVISION_ADDR], SPD_DDR4_EXPECTED_DMB_REVISION ); - /// Confirm that the DMB revision of the SPD data is - /// the revision we expect + // Confirm that the DMB revision is what is expected FAPI_ASSERT( (SPD_DDR4_EXPECTED_DMB_REVISION == - i_spdBuffer[SPD_DMB_REVISION_ADDR] ), - fapi2::TEST_ERROR_A().set_TARGET(i_ocmbFapi2Target), + i_spdBuffer[SPD_DMB_REVISION_ADDR]), + fapi2::DDIMM_GET_EFD_UNSUPPORTED_DMB_REVISION(). + set_DMB_REVISION(static_cast + (SPD_DDR4_EXPECTED_DMB_REVISION)). + set_EXPECTED(static_cast(SPD_DMB_REVISION_ADDR)). + set_OCMB_CHIP_TARGET(i_ocmbFapi2Target). + set_VPD_TYPE(io_vpdInfo.iv_vpd_type). + set_DDR_TYPE(static_cast + (i_spdBuffer[SPD_MEM_TYPE_ADDR])), "ddr4_get_efd: SPD DMB revision 0x%.2X is not the expected " "revision 0x%.2X", i_spdBuffer[SPD_DMB_REVISION_ADDR], - SPD_DDR4_EXPECTED_DMB_REVISION ); + SPD_DDR4_EXPECTED_DMB_REVISION); // Set the outgoing DMB revision io_vpdInfo.iv_dmb_revision = SPD_DDR4_EXPECTED_DMB_REVISION; @@ -587,11 +662,38 @@ extern "C" FAPI_DBG ( "ddr4_get_efd: Caller supplied frquency = %d", io_vpdInfo.iv_omi_freq_mhz ); - // If no value for frequency, then mapping of frequency was unsuccessful - FAPI_ASSERT( l_freqMask, - fapi2::TEST_ERROR_A().set_TARGET(i_ocmbFapi2Target), - "ddr4_get_efd: Frequency %d not supported by Axone", - io_vpdInfo.iv_omi_freq_mhz ); + // Confirm that mapping the frequency succeeded + if (!l_freqMask) + { + + // If no value for freq, then mapping of frequency was unsuccessful + FAPI_ASSERT( ( !io_vpdInfo.iv_is_config_ffdc_enabled ), + fapi2::DDIMM_GET_EFD_UNSUPPORTED_FREQUENCY(). + set_UNSUPPORTED_FREQ(static_cast + (io_vpdInfo.iv_omi_freq_mhz)). + set_FREQ0(static_cast(DDR4_FREQ_VAL_0)). + set_FREQ1(static_cast(DDR4_FREQ_VAL_1)). + set_FREQ2(static_cast(DDR4_FREQ_VAL_2)). + set_FREQ3(static_cast(DDR4_FREQ_VAL_3)). + set_FREQ4(static_cast(DDR4_FREQ_VAL_4)). + set_FREQ5(static_cast(DDR4_FREQ_VAL_5)). + set_FREQ6(static_cast(DDR4_FREQ_VAL_6)). + set_OCMB_CHIP_TARGET(i_ocmbFapi2Target). + set_VPD_TYPE(io_vpdInfo.iv_vpd_type). + set_DDR_TYPE(static_cast + (i_spdBuffer[SPD_MEM_TYPE_ADDR])), + "ddr4_get_efd: Frequency %d is not supported by Axone", + io_vpdInfo.iv_omi_freq_mhz ); + + // If not asserting, still must exit .. can't continue with bad data + FAPI_INF("ddr4_get_efd: Frequency %d not supported by Axone. Valid " + "values are %d, %d, %d, %d, %d, %d or %d", + io_vpdInfo.iv_omi_freq_mhz, DDR4_FREQ_VAL_0, DDR4_FREQ_VAL_1, + DDR4_FREQ_VAL_2, DDR4_FREQ_VAL_3, DDR4_FREQ_VAL_4, + DDR4_FREQ_VAL_5, DDR4_FREQ_VAL_6); + + FAPI_TRY(fapi2::FAPI2_RC_FALSE); + } FAPI_DBG ("ddr4_get_efd: Caller supplied frquency = %d, " "converted to frequency bit value mask = 0x%.4X", @@ -601,22 +703,47 @@ extern "C" // Look up the bit mask for the given MR l_rankMask = ddrMasterRankToBitMask( io_vpdInfo.iv_rank); - // If no value for MR, then mapping of MR was unsuccessful - FAPI_ASSERT( l_rankMask, - fapi2::TEST_ERROR_A().set_TARGET(i_ocmbFapi2Target), - "ddr4_get_efd: Master rank %d not supported by Axone", - io_vpdInfo.iv_rank ); + // Confirm that mapping the master rank succeeded + if ( !l_rankMask) + { + // If no value for MR, then mapping of MR was unsuccessful + FAPI_ASSERT( ( !io_vpdInfo.iv_is_config_ffdc_enabled ), + fapi2::DDIMM_GET_EFD_UNSUPPORTED_RANK(). + set_UNSUPPORTED_RANK(static_cast + (io_vpdInfo.iv_rank)). + set_RANK0(static_cast(DDR_MR_VAL_0)). + set_RANK1(static_cast(DDR_MR_VAL_1)). + set_RANK2(static_cast(DDR_MR_VAL_2)). + set_RANK3(static_cast(DDR_MR_VAL_3)). + set_OCMB_CHIP_TARGET(i_ocmbFapi2Target). + set_VPD_TYPE(io_vpdInfo.iv_vpd_type). + set_DDR_TYPE(static_cast + (i_spdBuffer[SPD_MEM_TYPE_ADDR])), + "ddr4_get_efd: Master rank %d is not supported by " + "Axone. ", + io_vpdInfo.iv_rank ); + + // If not asserting, still must exit .. can't continue with bad data + FAPI_INF("ddr4_get_efd: Master rank %d not supported by Axone. " + "Valid values are %d, %d, %d, or %d", + io_vpdInfo.iv_rank, + static_cast(DDR_MR_VAL_0), + static_cast(DDR_MR_VAL_1), + static_cast(DDR_MR_VAL_2), + static_cast(DDR_MR_VAL_3) ); + + FAPI_TRY(fapi2::FAPI2_RC_FALSE); + } FAPI_DBG ("ddr4_get_efd: Caller supplied master rank = %d, " "converted to master rank bit value mask = 0x%.2X", io_vpdInfo.iv_rank, l_rankMask); + //// Fourthly, find the EFD that matches the given frequency //// and master rank - // Point to the beginning of the EFD meta data AKA EFD[0] meta data - // The EFD[0] meta data contains the location and size of the - // individual EFDs + // Point to the beginning of the EFD meta data, AKA EFD[0] meta data. l_efdMetaDataPtr = i_spdBuffer + SPD_EFD_META_DATA_ADDR; // Point to the beginning of the EFD data AKA EFD[0] data @@ -644,10 +771,19 @@ extern "C" // beginning of the EFD data l_efdDataNptr = l_efdDataPtr + (ii * l_efdSize); - // Sanity check that the EFD and size is within the EFD memory space + // Sanity check that the EFD size is within the EFD memory space FAPI_ASSERT( ( (l_efdMemorySpaceOffset + l_efdMemorySpaceSize) >= (l_efdMemorySpaceOffset + (ii * l_efdSize) + l_efdSize) ), - fapi2::TEST_ERROR_A().set_TARGET(i_ocmbFapi2Target), + fapi2::DDIMM_GET_EFD_EFD_BLOCK_SIZE_IS_OUT_OF_BOUNDS(). + set_EFD_MEMORY_SPACE_OFFSET(l_efdMemorySpaceOffset). + set_EFD_MEMORY_SPACE_SIZE(l_efdMemorySpaceSize). + set_EFD_BLOCK(ii). + set_EFD_BLOCK_SIZE(l_efdSize). + set_OCMB_CHIP_TARGET(i_ocmbFapi2Target). + set_VPD_TYPE(static_cast + (io_vpdInfo.iv_vpd_type)). + set_DDR_TYPE(static_cast + (i_spdBuffer[SPD_MEM_TYPE_ADDR])), "EFD[%d] at location = %d plus EFD size = %d is " "outside the bounds of the EFD memory space = %d", ii, @@ -657,6 +793,15 @@ extern "C" // From previous assert, we know there is enough buffer to inspect // the EFD. + + // Copy data into FFDC buffer in case we find no matches + if( ii < MAX_EFD_FFDC ) + { + memcpy( &(l_ffdc_EFD[ii]), + l_efdDataNptr, + sizeof(l_ffdc_EFD[ii]) ); + } + // Get the EFD's frequency bit mask uint16_t l_efdFreqMask = *reinterpret_cast (&l_efdDataNptr[EFD_DDR4_FREQUENCY_ADDR]); @@ -672,63 +817,101 @@ extern "C" (l_efdFreqMask & l_freqMask) && (l_efdDataNptr[EFD_DDR4_MASTER_RANK_ADDR] == l_rankMask) ) { - // Make sure the buffer to copy data to is large enough to - // hold the EFD. If not, then assert. - FAPI_ASSERT( (l_efdSize > io_vpdInfo.iv_size), - fapi2::TEST_ERROR_A().set_TARGET(i_ocmbFapi2Target), - "EFD[%d] matches frequency and MR criteria but EFD " - "size %d exceeds outgoing buffer size %d", - ii, - l_efdSize, - io_vpdInfo.iv_size); - - if (io_vpdInfo.iv_size > l_efdSize) - { - // If returning buffer larger than the EFD's size, then - // clear the buffer so no extraneous data is left in buffer - memset(o_efdData, 0, io_vpdInfo.iv_size); - } + // io_vpdInfo.iv_size and EFD block size compatibility + // have been verified above // Copy the EFD data, that matched the given criteria, // to the out going buffer memcpy(o_efdData, l_efdDataNptr, l_efdSize); + // Set the outgoing size to the actual size, it could + // be different, but no more than what was given. + io_vpdInfo.iv_size = l_efdSize; + // Set the outgoing EFD function type io_vpdInfo.iv_efd_type = l_efdMetaDataNptr[SPD_EFD_META_DATA_EFD_BYTE_1_OFFSET] & SPD_EFD_META_DATA_EFD_FUNCTION_TYPE_MASK; - FAPI_INF ("ddr4_get_efd: EFD[%d] block matched frequency " - "criteria = 0x%.4X and master rank = 0x%.2X; " - "efd size = %d", - ii, l_freqMask, l_rankMask, l_efdSize); + FAPI_INF ("ddr4_get_efd: EFD[%d] block matched frequency %d " + "(frequency bit mask 0x%.4X) and master rank %d " + "(master rank bit mask 0x%.2X), efd size = %d", + ii, + io_vpdInfo.iv_omi_freq_mhz, l_freqMask, + io_vpdInfo.iv_rank, l_rankMask, + l_efdSize); break; // exit stage left, we are done - } // end if ((l_efdMetaDataNptr[SPD_EFD_META_DATA_EFD_BYTE_3_OFFSET]... + } // end if ((l_efdMetaDataNptr[SPD_EFD_META_DATA_EFD_ ... // This EFD is not a match, send trace stating so - FAPI_DBG ("ddr4_get_efd: Match failed for EFD[%d], freq bit mask " + FAPI_INF ("ddr4_get_efd: Match failed for EFD[%d], freq bit mask " "= 0x%.4X, rank bit mask = 0x%.2X, EFD memory location " - "= %d, EFD size = %d, is implemented flag = %d", + "= %d, EFD size = %d, is implemented flag = %s", ii, l_efdFreqMask, l_efdDataNptr[EFD_DDR4_MASTER_RANK_ADDR], (l_efdMemorySpaceOffset + (ii * l_efdSize)), l_efdSize, - (l_efdMetaDataNptr[SPD_EFD_META_DATA_EFD_BYTE_3_OFFSET] & - SPD_EFD_META_DATA_EFD_IS_IMPLEMENTED_MASK)); + ((l_efdMetaDataNptr[SPD_EFD_META_DATA_EFD_BYTE_3_OFFSET] & + SPD_EFD_META_DATA_EFD_IS_IMPLEMENTED_MASK) + ? "true" : "false" ) ); - } // end for (int i = 0; i < l_efdCount; ++i) + } // end for (; ii < l_efdCount; ++ii) if (ii >= l_efdCount) { // Did not find an EFD to match frequency and master rank criteria // Collect FFDC and assert if iv_is_config_ffdc_enabled is true FAPI_ASSERT( ( !io_vpdInfo.iv_is_config_ffdc_enabled ), - fapi2::TEST_ERROR_A().set_TARGET(i_ocmbFapi2Target), - "ALL EFDs have been exhausted. NO match " - "for frequency %d (frequency bit mask 0x%.4X) and " - "master rank %d (master rank bit mask 0x%.2X)", + fapi2::DDIMM_GET_EFD_EFD_NOT_FOUND(). + set_FREQUENCY(io_vpdInfo.iv_omi_freq_mhz). + set_FREQUENCY_MAPPED_VALUE + (static_cast(l_freqMask)). + set_MASTER_RANK(io_vpdInfo.iv_rank). + set_MASTER_RANK_MAPPED_VALUE + (static_cast(l_rankMask)). + set_OCMB_CHIP_TARGET(i_ocmbFapi2Target). + set_VPD_TYPE(static_cast + (io_vpdInfo.iv_vpd_type)). + set_DDR_TYPE(static_cast + (i_spdBuffer[SPD_MEM_TYPE_ADDR])). + set_EFD_METADATA0(l_ffdc_EFD[0]). + set_EFD_METADATA1(l_ffdc_EFD[1]). + set_EFD_METADATA2(l_ffdc_EFD[2]). + set_EFD_METADATA3(l_ffdc_EFD[3]). + set_EFD_METADATA4(l_ffdc_EFD[4]). + set_EFD_METADATA5(l_ffdc_EFD[5]). + set_EFD_METADATA6(l_ffdc_EFD[6]). + set_EFD_METADATA7(l_ffdc_EFD[7]). + set_EFD_METADATA8(l_ffdc_EFD[8]). + set_EFD_METADATA9(l_ffdc_EFD[9]). + set_EFD_METADATA10(l_ffdc_EFD[10]). + set_EFD_METADATA11(l_ffdc_EFD[11]). + set_EFD_METADATA12(l_ffdc_EFD[12]). + set_EFD_METADATA13(l_ffdc_EFD[13]). + set_EFD_METADATA14(l_ffdc_EFD[14]). + set_EFD_METADATA15(l_ffdc_EFD[15]). + set_EFD_METADATA16(l_ffdc_EFD[16]). + set_EFD_METADATA17(l_ffdc_EFD[17]). + set_EFD_METADATA18(l_ffdc_EFD[18]). + set_EFD_METADATA19(l_ffdc_EFD[19]). + set_EFD_METADATA20(l_ffdc_EFD[20]). + set_EFD_METADATA21(l_ffdc_EFD[21]). + set_EFD_METADATA22(l_ffdc_EFD[22]). + set_EFD_METADATA23(l_ffdc_EFD[23]). + set_EFD_METADATA24(l_ffdc_EFD[24]). + set_EFD_METADATA25(l_ffdc_EFD[25]). + set_EFD_METADATA26(l_ffdc_EFD[26]). + set_EFD_METADATA27(l_ffdc_EFD[27]). + set_EFD_METADATA28(l_ffdc_EFD[28]). + set_EFD_METADATA29(l_ffdc_EFD[29]). + set_EFD_METADATA30(l_ffdc_EFD[30]). + set_EFD_METADATA31(l_ffdc_EFD[31]), + "ddr4_get_efd: ALL EFDs have been exhausted. NO " + "match for frequency %d (frequency bit mask 0x%.4X) " + "and master rank %d (master rank bit mask 0x%.2X), or " + "there was a match but the block is not implemented.", io_vpdInfo.iv_omi_freq_mhz, l_freqMask, io_vpdInfo.iv_rank, l_rankMask); @@ -736,17 +919,17 @@ extern "C" // and exit with false FAPI_ERR ("ddr4_get_efd: ALL EFDs have been exhausted. NO match " "for frequency = %d (frequency bit mask = 0x%.4X) and " - "master rank = %d (master rank bit mask = 0x%.2X)", + "master rank = %d (master rank bit mask = 0x%.2X), or " + "there was a match but the block is not implemented.", io_vpdInfo.iv_omi_freq_mhz, l_freqMask, io_vpdInfo.iv_rank, l_rankMask); - fapi2::current_err == fapi2::FAPI2_RC_FALSE; - goto fapi_try_exit; + FAPI_TRY(fapi2::FAPI2_RC_FALSE); } fapi_try_exit: - FAPI_DBG("ddimm_get_efd: exiting with %s", + FAPI_DBG("ddr4_get_efd: exiting with %s", ( (fapi2::current_err == fapi2::FAPI2_RC_SUCCESS) ? "no errors" : "errors" )); return fapi2::current_err; -- cgit v1.2.1