summaryrefslogtreecommitdiffstats
path: root/src/usr/fapi2
diff options
context:
space:
mode:
authorRoland Veloz <rveloz@us.ibm.com>2019-03-06 13:44:46 -0600
committerDaniel M. Crowell <dcrowell@us.ibm.com>2019-04-10 13:48:37 -0500
commit8d531bced31e0dd68706db205b586c1e9e34b336 (patch)
tree82940514b94b13af46ce77b96e711ee0cf87fdea /src/usr/fapi2
parentf79af6ea7e3817c443fee39525973c7a67e55aa7 (diff)
downloadtalos-hostboot-8d531bced31e0dd68706db205b586c1e9e34b336.tar.gz
talos-hostboot-8d531bced31e0dd68706db205b586c1e9e34b336.zip
Added unit test for HWP call ddimm_get_efd
- Wrote a unit test for the HWP call ddimm_get_efd - Does negative and positive testing of the HWP call Change-Id: I9bbcbc2620a5fd5498244674d8e13ca3628fb371 RTC: 205964 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/72940 Reviewed-by: Matt Derksen <mderkse1@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/fapi2')
-rw-r--r--src/usr/fapi2/test/fapi2DdimmGetEfdTest.C1272
-rw-r--r--src/usr/fapi2/test/fapi2DdimmGetEfdTest.H401
-rw-r--r--src/usr/fapi2/test/fapi2Test.mk1
3 files changed, 1674 insertions, 0 deletions
diff --git a/src/usr/fapi2/test/fapi2DdimmGetEfdTest.C b/src/usr/fapi2/test/fapi2DdimmGetEfdTest.C
new file mode 100644
index 000000000..13f0ed87b
--- /dev/null
+++ b/src/usr/fapi2/test/fapi2DdimmGetEfdTest.C
@@ -0,0 +1,1272 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/fapi2/test/fapi2DdimmGetEfdTest.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+
+#include <cxxtest/TestSuite.H>
+#include <fapi2DdimmGetEfdTest.H>
+
+//******************************************************************************
+// Useful Constants
+//
+// Set up some constants to facilitate the testing
+//
+//******************************************************************************
+
+// Set a default size for the SPD buffer
+const size_t DEFAULT_SPD_BUFFER_SIZE_DEFAULT = (5 * KILOBYTE);
+
+// SPD DDIMM consts
+const size_t SPD_DDIMM_TYPE_OFFSET = 2;
+const uint8_t DEFAULT_SPD_DDIMM_TYPE = 0x0C;
+const size_t DEFAULT_SPD_DDIMM_SIZE = 512;
+
+// EFD data block consts
+const size_t DEFAULT_EFD_BLOCK_SIZE_MULTIPLIER = 4; // 4 thirty two bytes
+const size_t DEFAULT_EFD_BLOCK_SIZE =
+ (DEFAULT_EFD_BLOCK_SIZE_MULTIPLIER * 32);// 4 * 32 bytes = 128
+const size_t EFD_MEMORY_SPACE_OFFSET = 277;
+const size_t DEFAULT_EFD_MEMORY_SPACE_LOCATION = 1024;
+const size_t EFD_MEMORY_SPACE_SIZE_OFFSET = 285;
+const size_t DEFAULT_EFD_MEMORY_SPACE_SIZE = 0x02;
+const size_t EFD_COUNT_OFFSET = 286;
+const uint16_t DEFAULT_EFD_COUNT = 32;
+
+// DMB consts
+const size_t SPD_DMB_MFG_ID_OFFSET = 198;
+const uint16_t DEFAULT_SPD_DMB_MFG_ID = 0x2980;
+const size_t SPD_DMB_REVISION_OFFSET = 200;
+const uint8_t DEFAULT_SPD_DMB_REVISION = 0x00;
+
+/// EFD consts
+const size_t EFD_META_DATA_OFFSET = 288;
+// EFD's extended function type consts
+const size_t EXTENDED_FUNCTION_TYPE_MASK = 0x0F;
+const size_t EXTENDED_FUNCTION_TYPE_INVERSE_MASK = 0xF0;
+const uint8_t DEFAULT_EXTENDED_FUNCTION_TYPE = 0x03;
+// EFD's is implemented consts
+const size_t IS_IMPLEMENTED_MASK = 0x80;
+const size_t IS_IMPLEMENTED_INVERSE_MASK = 0x7F;
+
+// Frequency valid values and what they map to in the code
+// 12800(0x0001), 14930(0x0002), 17060(0x0004), 19200(0x0008),
+// 21330(0x0010), 23460(0x0020), 25600(0x0040)
+const uint16_t DEFAULT_FREQUENCY = 25600;
+
+// Master Rank valid values and what they map to in the code
+// MR0(0x01), MR1(0x02), MR3(0x04), MR4(0x08),
+const uint8_t DEFAULT_MASTER_RANK = 0; // MR0
+
+
+//******************************************************************************
+// Public API
+//******************************************************************************
+
+//******************************************************************************
+// fapi2DdimmGetEfdTest ctor
+//******************************************************************************
+fapi2DdimmGetEfdTest::fapi2DdimmGetEfdTest()
+ : iv_efdBufferPtr(nullptr),
+ iv_spdBufferPtr(nullptr),
+ iv_spdBufferSize(DEFAULT_SPD_BUFFER_SIZE_DEFAULT),
+ iv_efdMetaDataPtr(nullptr),
+ iv_efdBlockDataPtr(nullptr),
+ iv_efdBlockSizeMultiplier(DEFAULT_EFD_BLOCK_SIZE_MULTIPLIER),
+ iv_efdBlockSize(DEFAULT_EFD_BLOCK_SIZE),
+ iv_efdMemorySpaceLocation(DEFAULT_EFD_MEMORY_SPACE_LOCATION),
+ iv_efdMemorySpaceSize(DEFAULT_EFD_MEMORY_SPACE_SIZE),
+ iv_efdCount(DEFAULT_EFD_COUNT),
+ iv_spdDmbMfgId(DEFAULT_SPD_DMB_MFG_ID),
+ iv_spdDmbRevision(DEFAULT_SPD_DMB_REVISION),
+ iv_extendedFunctionType(DEFAULT_EXTENDED_FUNCTION_TYPE),
+ iv_frequency(DEFAULT_FREQUENCY),
+ iv_rank(DEFAULT_MASTER_RANK),
+ iv_ocmbChipTarget(nullptr),
+ iv_rc(fapi2::FAPI2_RC_SUCCESS),
+ iv_vpdInfo(fapi2::EFD),
+ iv_numTests(0),
+ iv_numFails(0),
+ iv_attrModel(TARGETING::MODEL_NA)
+{
+ FAPI_INF(">> fapi2DdimmGetEfdTest");
+
+ if(TARGETING::MODEL_AXONE != TARGETING::targetService().getProcessorModel())
+ {
+ FAPI_INF("<< fapi2DdimmGetEfdTest: This is not AXONE. "
+ "Skipping AXONE tests.");
+ return;
+ }
+
+ // Find a valid target of type OCMB_CHIP
+ TARGETING::TargetHandleList l_ocmbTargetList;
+ TARGETING::getAllChips(l_ocmbTargetList, TARGETING::TYPE_OCMB_CHIP, true);
+ if (!l_ocmbTargetList.size())
+ {
+ TS_FAIL("<< fapi2DdimmGetEfdTest: No valid TYPE_OCMB_CHIP target found. "
+ "Can not execute tests.");
+ return;
+ }
+ else
+ {
+ iv_ocmbChipTarget = l_ocmbTargetList[0];
+ }
+
+ // Initialize the SPD buffer to a known good state
+ initializeSpdBuffer();
+ // Initialize the VPDInfo to a known good state and match SPD buffer
+ initializeVpdInfo(iv_vpdInfo);
+ // Create EFD buffer to match VPDInfo iv_size
+ createEfdBuffer(iv_efdBufferPtr, iv_vpdInfo.iv_size);
+};
+
+//******************************************************************************
+// testDdimmGetEfdHwpCall
+//******************************************************************************
+void fapi2DdimmGetEfdTest::testDdimmGetEfdHwpCall()
+{
+ // If initialization process was unable to find an OCMB chip target, then
+ // exit without running any tests.
+ if (TARGETING::MODEL_AXONE != iv_attrModel || !iv_ocmbChipTarget)
+ {
+ return;
+ }
+
+ if (!sanityCheckTest())
+ {
+ TS_FAIL("<< fapi2DdimmGetEfdTest: Test configuration failed. "
+ "Test is broken - needs fixing/updating.");
+ }
+ else
+ {
+ // Call the actual tests
+ sizeMisMatchTest();
+ dmbDataTest();
+ vpdInfoInputTest();
+ findMatchTest();
+ }
+
+ FAPI_INF("<< fapi2DdimmGetEfdTest: Test Complete. %d/%d fails.",
+ iv_numFails, iv_numTests);
+}
+
+//******************************************************************************
+// Private Test Cases
+//******************************************************************************
+
+//******************************************************************************
+// sanityCheckTest
+//******************************************************************************
+bool fapi2DdimmGetEfdTest::sanityCheckTest()
+{
+ FAPI_INF(">> sanityCheckTest");
+
+ bool l_sanityCheckTestPassed(true);
+
+ // Create a TARGET_TYPE_OCMB_CHIP FAPI2 target
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
+ l_fapi2Target(iv_ocmbChipTarget);
+
+
+ ++iv_numTests;
+ // Should get a match immediately, if not, test setup is broken
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ l_sanityCheckTestPassed = false;
+ ++iv_numFails;
+ TS_FAIL("sanityCheckTest: Test configuration failed: "
+ "Should have found a match for frequency(%d) and master "
+ "rank(%d). Test is broken, please fix.",
+ iv_vpdInfo.iv_omi_freq_mhz, iv_vpdInfo.iv_rank);
+ }
+
+ FAPI_INF("<< sanityCheckTest");
+
+ return l_sanityCheckTestPassed;
+}
+
+//******************************************************************************
+// sizeMisMatchTest
+//******************************************************************************
+void fapi2DdimmGetEfdTest::sizeMisMatchTest()
+{
+ FAPI_INF(">> sizeMisMatchTest");
+
+ // Create a TARGET_TYPE_OCMB_CHIP FAPI2 target
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
+ l_fapi2Target(iv_ocmbChipTarget);
+
+ // Some handy variables
+ size_t l_bufferSize(0);
+ // This type is an invalid type, it is used for negative tetsting
+ uint8_t l_ddrType(0xAA);
+
+
+ ++iv_numTests;
+ /// Test when buffer size is 0
+ // Set the buffer size to 0
+ l_bufferSize = 0;
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, l_bufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("sizeMisMatchTest: test failed. Buffer size is %d",
+ l_bufferSize);
+ }
+
+
+ ++iv_numTests;
+ /// Test when buffer size is < the needed DDR size,
+ /// but DDR type is the correct type
+ // Set the buffer size to 1 less than size of the DDR type's size
+ l_bufferSize = DEFAULT_SPD_DDIMM_SIZE - 1;
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, l_bufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("sizeMisMatchTest: test failed. Buffer (%d) size is "
+ "less than the DDR size (%d)",
+ l_bufferSize, DEFAULT_SPD_DDIMM_SIZE);
+ }
+
+
+ ++iv_numTests;
+ /// Test when buffer size is large enough, but DDR type is incorrect
+ // Set the DDR type to an incorrect type
+ l_ddrType = 0xAA;
+ setSpdDdimmType(l_ddrType);
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("sizeMisMatchTest: test failed. "
+ "Should have failed with DDR type set at 0xAA");
+ }
+ // Restore the DDR type
+ setSpdDdimmType(DEFAULT_SPD_DDIMM_TYPE);
+
+
+ ++iv_numTests;
+ /// Test when buffer is a nullptr
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, nullptr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("sizeMisMatchTest: test failed: "
+ "Passing a nullptr EFD buffer is a valid value.");
+ }
+ else if (iv_vpdInfo.iv_size != DEFAULT_EFD_BLOCK_SIZE)
+ {
+ ++iv_numFails;
+ TS_FAIL("sizeMisMatchTest: test failed: "
+ "Returned EFD buffer size is not what is expected. "
+ "May just need to update test to reflect code.");
+ }
+
+
+ ++iv_numTests;
+ /// Test when EFD memory space location resides within the DDR4 memory space
+ // Set the memory space location to reside within the DDR4 memory space
+ setEfdMemorySpaceLocation(DEFAULT_SPD_DDIMM_SIZE - 1);
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("sizeMisMatchTest: test failed: "
+ "EFD memory space cannot reside in the DDR4 memory space.");
+ }
+ // Restore the memory space location
+ setEfdMemorySpaceLocation(iv_efdMemorySpaceLocation);
+
+
+ ++iv_numTests;
+ /// Test when mapping for EFD memory size is incorrect
+ // Set the memory space size mapping value to an incorrect value
+ setEfdMemorySpaceSize(0x07);
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("sizeMisMatchTest: test failed: "
+ "There is no EFD memory space maping for 0x07.");
+ }
+ // Restore the memory space size mapping value
+ setEfdMemorySpaceSize(iv_efdMemorySpaceSize);
+
+
+ ++iv_numTests;
+ /// Test when mapping for EFD memory size + EFD memory space offset
+ /// is out of bounds.
+ // In this scenario, increase the EFD memory space size beyond
+ // the VPD memory bounds.
+ setEfdMemorySpaceSize(iv_efdMemorySpaceSize + 1);
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("sizeMisMatchTest: test failed: "
+ "EFD memory size + EFD memory space offset is out of bounds.");
+ }
+ // Restore the EFD memory space size
+ setEfdMemorySpaceSize(iv_efdMemorySpaceSize);
+
+
+ ++iv_numTests;
+ /// Test when mapping for EFD memory size + EFD memory space location
+ /// is out of bounds
+ // In this scenario, increase the EFD memory space location such that the
+ // EFD memory size +EFD memory space offset is beyond the VPD memory bounds.
+ setEfdMemorySpaceLocation(iv_efdMemorySpaceLocation + 1);
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("sizeMisMatchTest: test failed: "
+ "EFD memory size + EFD memory space offset is out of bounds.");
+ }
+ // Restore the memory space location
+ setEfdMemorySpaceLocation(iv_efdMemorySpaceLocation);
+
+
+ ++iv_numTests;
+ /// Test when the number of EFDs is 0.
+ // Set EFD count to 0
+ setEfdCount(0);
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("sizeMisMatchTest: test failed: "
+ "Number of EFDs is 0, need at least one.");
+ }
+ // Restore the EFD count
+ setEfdCount(iv_efdCount);
+
+
+ ++iv_numTests;
+ /// Test when the size of the EFD data block size is greater than the
+ /// EFD buffer size
+ // Increase the EFD data block size
+ setAllEfdMetaDatasEfdDataBlockSize(5);
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("sizeMisMatchTest: test failed: "
+ "EFD data block size is greater than EFD buffer size.");
+ }
+ // Restore the EFD data block size
+ setAllEfdMetaDatasEfdDataBlockSize(iv_efdBlockSizeMultiplier);
+
+
+ ++iv_numTests;
+ // Test when the size of the EFD buffer size is less than the
+ // EFD data block size
+ // Shrink EFD buffer size
+ iv_vpdInfo.iv_size = DEFAULT_EFD_BLOCK_SIZE - 1;
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("sizeMisMatchTest: test failed: "
+ "EFD buffer size is greater than EFD data block size.");
+ }
+ // Restore the EFD buffer size
+ iv_vpdInfo.iv_size = DEFAULT_EFD_BLOCK_SIZE;
+
+ FAPI_INF("<< sizeMisMatchTest");
+}
+
+//******************************************************************************
+// dmbDataTest
+//******************************************************************************
+void fapi2DdimmGetEfdTest::dmbDataTest()
+{
+ FAPI_INF(">> dmbDataTest");
+
+ // Create a TARGET_TYPE_OCMB_CHIP FAPI2 target
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
+ l_fapi2Target(iv_ocmbChipTarget);
+
+
+ ++iv_numTests;
+ /// Test when DMB manufacturer ID is incorrect
+ // Set the DMB manufacturer ID to an incorrect value
+ // and FFDC enabled is false
+ setSpdDmbMfgId(0x5540);
+ iv_vpdInfo.iv_is_config_ffdc_enabled = false;
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("dmbDataTest: test failed: "
+ "EFD memory size + EFD memory space offset is out of bounds.");
+ }
+ // Restore the DMB manufacturer ID
+ setSpdDmbMfgId(iv_spdDmbMfgId);
+
+
+ ++iv_numTests;
+ /// Test when DMB revision is incorrect
+ // Set the DMB revision to an incorrect value
+ // and FFDC enabled is false
+ setSpdDmbRevision(0x20);
+ iv_vpdInfo.iv_is_config_ffdc_enabled = false;
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("dmbDataTest: test failed: "
+ "EFD memory size + EFD memory space offset is out of bounds.");
+ }
+ // Restore DMB manufacturer ID
+ setSpdDmbRevision(iv_spdDmbRevision);
+
+ /// Test when DMB manufacturer ID is incorrect
+ // Set the DMB manufacturer ID to an incorrect value
+ // and FFDC enabled is true
+ setSpdDmbMfgId(0x5540);
+ iv_vpdInfo.iv_is_config_ffdc_enabled = true;
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("dmbDataTest: test failed: "
+ "EFD memory size + EFD memory space offset is out of bounds.");
+ }
+ // Restore the DMB manufacturer ID
+ setSpdDmbMfgId(iv_spdDmbMfgId);
+
+
+ ++iv_numTests;
+ /// Test when DMB revision is incorrect
+ // Set the DMB revision to an incorrect value
+ // and FFDC enabled is true
+ setSpdDmbRevision(0x20);
+ iv_vpdInfo.iv_is_config_ffdc_enabled = true;
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("dmbDataTest: test failed: "
+ "EFD memory size + EFD memory space offset is out of bounds.");
+ }
+ // Restore DMB manufacturer ID
+ setSpdDmbRevision(iv_spdDmbRevision);
+
+
+ FAPI_INF("<< dmbDataTest");
+}
+
+//******************************************************************************
+// vpdInfoInputTest
+//******************************************************************************
+void fapi2DdimmGetEfdTest::vpdInfoInputTest()
+{
+ FAPI_INF(">> vpdInfoInputTest");
+
+ // Create a TARGET_TYPE_OCMB_CHIP FAPI2 target
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
+ l_fapi2Target(iv_ocmbChipTarget);
+
+
+ ++iv_numTests;
+ /// Test when caller passes in an incorrect frequency value and
+ /// set FFDC enabled flag to true
+ // Set the frequency to an incorrect value and enable FFDC flag
+ iv_vpdInfo.iv_omi_freq_mhz = iv_frequency - 1;
+ iv_vpdInfo.iv_is_config_ffdc_enabled = true;
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("vpdInfoInputTest: test failed: "
+ "VPD info frequency value (%d) is not valid.",
+ iv_vpdInfo.iv_omi_freq_mhz);
+ }
+ // Restore frequency
+ iv_vpdInfo.iv_omi_freq_mhz = iv_frequency;
+
+
+ ++iv_numTests;
+ /// Test when caller passes in an incorrect master rank and
+ /// set FFDC enabled flag to true
+ // Set the master rank to an incorrect value and enable FFDC flag
+ iv_vpdInfo.iv_rank = 4;
+ iv_vpdInfo.iv_is_config_ffdc_enabled = true;
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("vpdInfoInputTest: test failed: "
+ "VPD info master rank (%d) is not valid.",
+ iv_vpdInfo.iv_rank);
+ }
+ // Restore master rank
+ iv_vpdInfo.iv_rank = iv_rank;
+
+
+ ++iv_numTests;
+ /// Test when caller passes in an incorrect frequency value and
+ /// set FFDC enabled flag to false
+ // Set the frequency to an incorrect value and disable FFDC flag
+ iv_vpdInfo.iv_omi_freq_mhz = iv_frequency - 1;
+ iv_vpdInfo.iv_is_config_ffdc_enabled = false;
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("vpdInfoInputTest: test failed: "
+ "VPD info frequency value (%d) is not valid.",
+ iv_vpdInfo.iv_omi_freq_mhz);
+ }
+ // Restore frequency and FFDC flag
+ iv_vpdInfo.iv_omi_freq_mhz = iv_frequency;
+ iv_vpdInfo.iv_is_config_ffdc_enabled = true;
+
+
+ ++iv_numTests;
+ /// Test when caller passes in an incorrect master rank and
+ /// set FFDC enabled flag to false
+ // Set the master rank to an incorrect value and enable FFDC flag
+ iv_vpdInfo.iv_rank = 4;
+ iv_vpdInfo.iv_is_config_ffdc_enabled = false;
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("vpdInfoInputTest: test failed: "
+ "VPD info master rank (%d) is not valid.",
+ iv_vpdInfo.iv_rank);
+ }
+ // Restore master rank and FFDC flag
+ iv_vpdInfo.iv_rank = iv_rank;
+ iv_vpdInfo.iv_is_config_ffdc_enabled = true;
+
+ FAPI_INF("<< vpdInfoInputTest");
+}
+
+//******************************************************************************
+// findMatchTest
+//******************************************************************************
+void fapi2DdimmGetEfdTest::findMatchTest()
+{
+ FAPI_INF(">> findMatchTest");
+
+ // Create a TARGET_TYPE_OCMB_CHIP FAPI2 target
+ const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>
+ l_fapi2Target(iv_ocmbChipTarget);
+
+
+ ++iv_numTests;
+ // Match EFD data block[0]
+ configureEfdDataBlockN(0, iv_frequency, iv_rank, 0xAA, 0xDD);
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("findMatchTest: test failed: "
+ "VPD info frequency value (%d) / master rank (%d) "
+ "are valid. Should have been found in the EFD data block.",
+ iv_vpdInfo.iv_omi_freq_mhz, iv_vpdInfo.iv_rank);
+ }
+ else if ( !(verifyEfdBuffer(iv_frequency, iv_rank, 0xAA, 0xDD) ) )
+ {
+ ++iv_numFails;
+ TS_FAIL("findMatchTest: test failed: "
+ "Found matches for frequency value (%d) / master rank "
+ "(%d) but the EFD buffer returned frequency value "
+ "(%d) / master rank (%d) which don't match.",
+ iv_frequency, iv_rank,
+ iv_vpdInfo.iv_omi_freq_mhz, iv_vpdInfo.iv_rank);
+ }
+
+
+ ++iv_numTests;
+ /// Match EFD data block[31]
+ // 31 - The EFD data block to set up for this test
+ // 14930 - a valid frequency (see doc 1U2UDDIMM_SPD.docx) to be found
+ // 2 - a valid master rank (see doc 1U2UDDIMM_SPD.docx) to be found
+ // 0x11 and 0x22 - Tag data for the EFD data block. This will tag the
+ // EFD data block, at the start and end, so that it can be confirmed
+ // the actual EFD data block is returned. Without this tag, the
+ // ddimm_get_efd call can spoof data coming back. This is to keep the
+ // code honest.
+ configureEfdDataBlockN(31, 14930, 2, 0x11, 0x22);
+ iv_vpdInfo.iv_omi_freq_mhz = 14930;
+ iv_vpdInfo.iv_rank = 2;
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("findMatchTest: test failed: "
+ "VPD info frequency value (%d) / master rank (%d) "
+ "are valid. Should have been found in the EFD data block.",
+ iv_vpdInfo.iv_omi_freq_mhz, iv_vpdInfo.iv_rank);
+ }
+ else if ( !(verifyEfdBuffer(14930, 2, 0x11, 0x22) ) )
+ {
+ ++iv_numFails;
+ TS_FAIL("findMatchTest: test failed: "
+ "Found matches for frequency value (14930) / master rank "
+ "(2) but the EFD buffer returned frequency value "
+ "(%d) / master rank (%d) which don't match.",
+ iv_vpdInfo.iv_omi_freq_mhz, iv_vpdInfo.iv_rank);
+ }
+
+
+ ++iv_numTests;
+ /// Set EFD data block[31] to not implemented, no match
+ // 31 -The EFD data block to set to not implemented. Although
+ // the data is match, this should not be returned because it is
+ // not implemented.
+ setEfdMetaDataNisImplemented(31, false);
+ // 31 - The EFD data block to set up for this test
+ // 14930 - a valid frequency (see doc 1U2UDDIMM_SPD.docx) to be found
+ // 2 - a valid master rank (see doc 1U2UDDIMM_SPD.docx) to be found
+ // 0x11 and 0x22 - Tag data for the EFD data block. This will tag the
+ // EFD data block, at the start and end, so that it can be confirmed
+ // the actual EFD data block is returned. Without this tag, the
+ // ddimm_get_efd call can spoof data coming back. This is to keep the
+ // code honest. BUT, in this case nothing should be returned because
+ // the block is not implemented.
+ configureEfdDataBlockN(31, 14930, 2, 0x11, 0x22);
+ iv_vpdInfo.iv_omi_freq_mhz = 14930;
+ iv_vpdInfo.iv_rank = 2;
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("findMatchTest: test failed: "
+ "VPD info frequency value (%d) / master rank (%d) should "
+ "not have been found in the EFD data block, because the "
+ "implemented flag is false.",
+ iv_vpdInfo.iv_omi_freq_mhz, iv_vpdInfo.iv_rank);
+ }
+
+
+ ++iv_numTests;
+ /// Set EFD data block[31] to not implemented, turn FFDC off, no match
+ // 31 -The EFD data block to set to not implemented. Although
+ // the data is match, this should not be returned because it is
+ // not implemented.
+ setEfdMetaDataNisImplemented(31, false);
+ // 31 - The EFD data block to set up for this test
+ // 14930 - a valid frequency (see doc 1U2UDDIMM_SPD.docx) to be found
+ // 2 - a valid master rank (see doc 1U2UDDIMM_SPD.docx) to be found
+ // 0x11 and 0x22 - Tag data for the EFD data block. This will tag the
+ // EFD data block, at the start and end, so that it can be confirmed
+ // the actual EFD data block is returned. Without this tag, the
+ // ddimm_get_efd call can spoof data coming back. This is to keep the
+ // code honest. BUT, in this case nothing should be returned because
+ // the block is not implemented.
+ configureEfdDataBlockN(31, 14930, 2, 0x11, 0x22);
+ iv_vpdInfo.iv_omi_freq_mhz = 14930;
+ iv_vpdInfo.iv_rank = 2;
+ // Exercise the FFDC enabled flag to not do FFDC
+ iv_vpdInfo.iv_is_config_ffdc_enabled = false;
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc == fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("findMatchTest: test failed: "
+ "VPD info frequency value (%d) / master rank (%d) should "
+ "not have been found in the EFD data block, because the "
+ "implemented flag is false.",
+ iv_vpdInfo.iv_omi_freq_mhz, iv_vpdInfo.iv_rank);
+ }
+
+
+ ++iv_numTests;
+ /// Match on EFD data block[15]
+ // 31 -The EFD data block to set to implemented. So the EFD data block
+ // is returned when matched.
+ setEfdMetaDataNisImplemented(15, true);
+ // 15 - The EFD data block to set up for this test
+ // 21330 - a valid frequency (see doc 1U2UDDIMM_SPD.docx) to be found
+ // 2 - a valid master rank (see doc 1U2UDDIMM_SPD.docx) to be found
+ // 0x44 and 0x55 - Tag data for the EFD data block. This will tag the
+ // EFD data block, at the start and end, so that it can be confirmed
+ // the actual EFD data block is returned. Without this tag, the
+ // ddimm_get_efd call can spoof data coming back. This is to keep the
+ // code honest.
+ configureEfdDataBlockN(15, 21330, 2, 0x44, 0x55);
+ // 12800, 17060, 25600 - these valid frequencies (see doc
+ // 1U2UDDIMM_SPD.docx) will be ORed to all EFD data blocks. This will
+ // test if the data block is found when the frequency is obfuscated with
+ // other frequencies.
+ appendToAllEfdDataBlocksFreq(12800);
+ appendToAllEfdDataBlocksFreq(17060);
+ appendToAllEfdDataBlocksFreq(25600);
+ iv_vpdInfo.iv_omi_freq_mhz = 21330;
+ iv_vpdInfo.iv_rank = 2;
+ // Exercise the FFDC enabled flag to not do FFDC
+ iv_vpdInfo.iv_is_config_ffdc_enabled = false;
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("findMatchTest: test failed: "
+ "VPD info frequency value (%d) / master rank (%d) "
+ "are valid. Should have been found in the EFD data block.",
+ iv_vpdInfo.iv_omi_freq_mhz, iv_vpdInfo.iv_rank);
+ }
+ else if ( !(verifyEfdBuffer(21330, 2, 0x44, 0x55) ) )
+ {
+ ++iv_numFails;
+ TS_FAIL("findMatchTest: test failed: "
+ "Found matches for frequency value (21330) / master rank "
+ "(2) but the EFD buffer returned frequency value "
+ "(%d) / master rank (%d) which don't match.",
+ iv_vpdInfo.iv_omi_freq_mhz, iv_vpdInfo.iv_rank);
+ }
+
+
+ ++iv_numTests;
+ /// Match on EFD data block[23]
+ // 23 -The EFD data block to set to implemented. So the EFD data block
+ // is returned when matched.
+ setEfdMetaDataNisImplemented(23, true);
+ // 1 - set all EFD data blocks to this valid master rank (see doc
+ // 1U2UDDIMM_SPD.docx) will
+ setAllEfdDataBlocksRank(1);
+ // 12800 - set all EFD data blocks to this valid frequency (see doc
+ // 1U2UDDIMM_SPD.docx) will
+ setAllEfdDataBlocksFreq(12800);
+ // 23 - The EFD data block to set up for this test
+ // 19200 - a valid frequency (see doc 1U2UDDIMM_SPD.docx) to be found
+ // 3 - a valid master rank (see doc 1U2UDDIMM_SPD.docx) to be found
+ // 0x13 and 0x67 - Tag data for the EFD data block. This will tag the
+ // EFD data block, at the start and end, so that it can be confirmed
+ // the actual EFD data block is returned. Without this tag, the
+ // ddimm_get_efd call can spoof data coming back. This is to keep the
+ // code honest.
+ configureEfdDataBlockN(23, 19200, 3, 0x13, 0x67);
+ // 12800, 14930, 17060, 21330, 23460, 25600 - these valid frequencies (see
+ // doc 1U2UDDIMM_SPD.docx) will be ORed to all EFD data blocks. This will
+ // test if the data block is found when the frequency is obfuscated with
+ // other frequencies.
+ appendToAllEfdDataBlocksFreq(12800);
+ appendToAllEfdDataBlocksFreq(14930);
+ appendToAllEfdDataBlocksFreq(17060);
+ appendToAllEfdDataBlocksFreq(21330);
+ appendToAllEfdDataBlocksFreq(23460);
+ appendToAllEfdDataBlocksFreq(25600);
+ iv_vpdInfo.iv_omi_freq_mhz = 19200;
+ iv_vpdInfo.iv_rank = 3;
+ // Exercise the FFDC enabled flag to not do FFDC
+ iv_vpdInfo.iv_is_config_ffdc_enabled = false;
+ iv_rc = ddimm_get_efd(l_fapi2Target, iv_vpdInfo, iv_efdBufferPtr,
+ iv_spdBufferPtr, iv_spdBufferSize);
+ if (iv_rc != fapi2::FAPI2_RC_SUCCESS)
+ {
+ ++iv_numFails;
+ TS_FAIL("findMatchTest: test failed: "
+ "VPD info frequency value (%d) / master rank (%d) "
+ "are valid. Should have been found in the EFD data block.",
+ iv_vpdInfo.iv_omi_freq_mhz, iv_vpdInfo.iv_rank);
+ }
+ else if ( !(verifyEfdBuffer(19200, 3, 0x13, 0x67) ) )
+ {
+ ++iv_numFails;
+ TS_FAIL("findMatchTest: test failed: "
+ "Found matches for frequency value (19200) / master rank "
+ "(3) but the EFD buffer returned frequency value "
+ "(%d) / master rank (%d) which don't match.",
+ iv_vpdInfo.iv_omi_freq_mhz, iv_vpdInfo.iv_rank);
+ }
+
+ FAPI_INF("<< findMatchTest");
+}
+
+//******************************************************************************
+// Private Utilities To Facilitate Testing
+//******************************************************************************
+
+//******************************************************************************
+// initializeSpdBuffer
+//******************************************************************************
+void fapi2DdimmGetEfdTest::initializeSpdBuffer()
+{
+ // Create SPD buffer and scrub the memory
+ createSpdBuffer(iv_spdBufferPtr, iv_spdBufferSize);
+
+ // I am not going to check if buffer is large enough to do the
+ // following. I am not writing tests for test cases!!!
+
+ // Configure the SPD buffer to defaults
+ setSpdDdimmType(DEFAULT_SPD_DDIMM_TYPE);
+ setEfdMemorySpaceLocation(iv_efdMemorySpaceLocation);
+ setEfdMemorySpaceSize(iv_efdMemorySpaceSize);
+ setEfdCount(iv_efdCount);
+ setSpdDmbMfgId(iv_spdDmbMfgId);
+ setSpdDmbRevision(iv_spdDmbRevision);
+
+ // Configure the EFD meta data to defaults
+ setAllEfdMetaDatasEfdDataBlockSize(iv_efdBlockSizeMultiplier);
+ setAllEfdMetaDatasExtendedFunctionType(iv_extendedFunctionType);
+ setAllEfdMetaDatasIsImplemented(true);
+
+ // Configure the EFD data blocks to defaults
+ setAllEfdDataBlocksFreq(iv_frequency);
+ setAllEfdDataBlocksRank(iv_rank);
+}
+
+//******************************************************************************
+// createSpdBuffer
+//******************************************************************************
+void fapi2DdimmGetEfdTest::createSpdBuffer(uint8_t* &o_spdBufferPtr,
+ const size_t i_spdBufferSize)
+{
+ delete o_spdBufferPtr; // it is OK to delete a nullptr
+
+ o_spdBufferPtr = new uint8_t[i_spdBufferSize];
+ // Set data to all 1's, so testing can be more vigorous
+ memset(o_spdBufferPtr, 0xFF, i_spdBufferSize);
+
+ // Set the pointer to beginning of the EFD meta data
+ iv_efdMetaDataPtr = o_spdBufferPtr + EFD_META_DATA_OFFSET;
+}
+
+//******************************************************************************
+// setSpdDdimmType
+//******************************************************************************
+void fapi2DdimmGetEfdTest::setSpdDdimmType(const uint8_t i_spdDdimmType)
+{
+ memcpy(&(iv_spdBufferPtr[SPD_DDIMM_TYPE_OFFSET]),
+ reinterpret_cast<const uint8_t*>(&i_spdDdimmType),
+ sizeof(i_spdDdimmType) );
+}
+
+//******************************************************************************
+// setEfdMemorySpaceLocation
+//******************************************************************************
+void fapi2DdimmGetEfdTest::setEfdMemorySpaceLocation(
+ const uint64_t i_efdMemorySpaceLocation)
+{
+ uint64_t l_efdMemorySpaceLocation = le64toh(i_efdMemorySpaceLocation);
+ memcpy(&(iv_spdBufferPtr[EFD_MEMORY_SPACE_OFFSET]),
+ reinterpret_cast<const uint8_t*>(&l_efdMemorySpaceLocation),
+ sizeof(l_efdMemorySpaceLocation) );
+
+ // Update / Set EFD Memory Block pointer to point the beginning of the
+ // memory space
+ l_efdMemorySpaceLocation = *(reinterpret_cast<const uint64_t*>
+ (&iv_spdBufferPtr[EFD_MEMORY_SPACE_OFFSET]));
+ l_efdMemorySpaceLocation = le64toh(l_efdMemorySpaceLocation);
+ iv_efdBlockDataPtr = iv_spdBufferPtr + l_efdMemorySpaceLocation;
+}
+
+//******************************************************************************
+// setEfdMemorySpaceSize
+//******************************************************************************
+void fapi2DdimmGetEfdTest::setEfdMemorySpaceSize(
+ const uint8_t i_efdMemorySpaceSize)
+{
+ memcpy(&(iv_spdBufferPtr[EFD_MEMORY_SPACE_SIZE_OFFSET]),
+ &i_efdMemorySpaceSize,
+ sizeof(i_efdMemorySpaceSize) );
+}
+
+//******************************************************************************
+// setEfdCount
+//******************************************************************************
+void fapi2DdimmGetEfdTest::setEfdCount(const uint16_t i_efdCount)
+{
+ uint16_t l_efdCount = le16toh(i_efdCount);
+ memcpy(&(iv_spdBufferPtr[EFD_COUNT_OFFSET]),
+ reinterpret_cast<const uint8_t*>(&l_efdCount),
+ sizeof(l_efdCount) );
+}
+
+//******************************************************************************
+// setSpdDmbMfgId
+//******************************************************************************
+void fapi2DdimmGetEfdTest::setSpdDmbMfgId(const uint16_t i_spdDmbMfgId)
+{
+ uint16_t l_spdDmbMfgId = le16toh(i_spdDmbMfgId);
+ memcpy( &(iv_spdBufferPtr[SPD_DMB_MFG_ID_OFFSET]),
+ reinterpret_cast<const uint8_t*>(&l_spdDmbMfgId),
+ sizeof(l_spdDmbMfgId) );
+}
+
+//******************************************************************************
+// setSpdDmbRevision
+//******************************************************************************
+void fapi2DdimmGetEfdTest::setSpdDmbRevision(const uint8_t i_spdDmbRevision)
+{
+ memcpy( &(iv_spdBufferPtr[SPD_DMB_REVISION_OFFSET]),
+ &i_spdDmbRevision,
+ sizeof(i_spdDmbRevision) );
+}
+
+//******************************************************************************
+// setEfdMetaDataNEfdDataBlockEnd
+//******************************************************************************
+void fapi2DdimmGetEfdTest::setEfdMetaDataNEfdDataBlockEnd(
+ const size_t i_efdMetaDataN,
+ const uint8_t i_efdDataBlockEnd)
+{
+ memcpy( &(iv_efdMetaDataPtr[(i_efdMetaDataN * 4) + 2]),
+ &i_efdDataBlockEnd,
+ sizeof(i_efdDataBlockEnd) );
+}
+
+//******************************************************************************
+// setAllEfdMetaDatasEfdDataBlockSize
+//******************************************************************************
+void fapi2DdimmGetEfdTest::setAllEfdMetaDatasEfdDataBlockSize(
+ const uint8_t i_efdDataBlockSize)
+{
+ for (int ii = 0; ii < iv_efdCount; ++ii)
+ {
+ setEfdMetaDataNEfdDataBlockEnd(ii, (ii + 1) * i_efdDataBlockSize);
+ }
+}
+
+//******************************************************************************
+// setEfdMetaDataExtendedFunctionType
+//******************************************************************************
+void fapi2DdimmGetEfdTest::setEfdMetaDataExtendedFunctionType(
+ const size_t i_efdMetaDataN,
+ const uint8_t i_extendedFunctionType)
+
+{
+ // Extended Function Type is located 1 byte from the beginning of the meta
+ // data. It is in bits 4 - 7 of byte 1 (0 based)
+
+ // First extracts bits 4 to 7 from input
+ uint8_t l_eft = EXTENDED_FUNCTION_TYPE_MASK & i_extendedFunctionType;
+
+ // Retrieve the Extended Function Type
+ // (iv_efdMetaDataPtr[(i_efdMetaDataN * 4) + 1]) and zero out bits 4 - 7,
+ // then OR this with the given Extended Function Type (l_eft).
+ l_eft = (l_eft |
+ ( (iv_efdMetaDataPtr[(i_efdMetaDataN * 4) + 1]) &
+ EXTENDED_FUNCTION_TYPE_INVERSE_MASK) );
+
+ memcpy(&(iv_efdMetaDataPtr[(i_efdMetaDataN * 4) + 1]),
+ &l_eft,
+ sizeof(l_eft) );
+}
+
+//******************************************************************************
+// setAllEfdMetaDatasExtendedFunctionType
+//******************************************************************************
+void fapi2DdimmGetEfdTest::setAllEfdMetaDatasExtendedFunctionType(
+ const uint8_t i_extendedFunctionType)
+{
+ for (int ii = 0; ii < iv_efdCount; ++ii)
+ {
+ setEfdMetaDataExtendedFunctionType(ii, i_extendedFunctionType);
+ }
+}
+
+//******************************************************************************
+// setEfdMetaDataNisImplemented
+//******************************************************************************
+void fapi2DdimmGetEfdTest::setEfdMetaDataNisImplemented(
+ const size_t i_efdMetaDataN,
+ const bool i_isImplemented)
+{
+ // Initially set to false
+ uint8_t l_isImplemented = 0x00;
+ if (i_isImplemented)
+ {
+ // Change to true
+ l_isImplemented = 0x80;
+ }
+
+ // Implemented state is located 3 bytes from the beginning of the meta
+ // data. It is in bit 7 of byte 3 (0 based)
+ // Then map that to the byte that is there
+ l_isImplemented = l_isImplemented |
+ (iv_efdMetaDataPtr[(i_efdMetaDataN * 4) + 3] &
+ IS_IMPLEMENTED_INVERSE_MASK) ;
+
+ memcpy( &(iv_efdMetaDataPtr[(i_efdMetaDataN * 4) + 3]),
+ &l_isImplemented,
+ sizeof(l_isImplemented) );
+}
+
+//******************************************************************************
+// setAllEfdMetaDatasIsImplemented
+//******************************************************************************
+void fapi2DdimmGetEfdTest::setAllEfdMetaDatasIsImplemented(
+ const bool i_isImplemented)
+{
+ for (size_t ii = 0; ii < iv_efdCount; ++ii)
+ {
+ setEfdMetaDataNisImplemented(ii, i_isImplemented);
+ }
+}
+
+//******************************************************************************
+// convertFrequency
+//
+// Byte 0 of an EFD data block (data from document 1U2UDDIMM_SPD.docx)
+// INPUT: 25600 | 23460 | 21330 | 19200 | 17060 | 14930 | 12800
+// OUTPUT: Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
+//******************************************************************************
+uint16_t fapi2DdimmGetEfdTest::convertFrequency(const uint16_t i_frequency)
+{
+ uint16_t l_frequency(0);
+ switch (i_frequency)
+ {
+ // data from document 1U2UDDIMM_SPD.docx
+ case 12800: l_frequency = 0x0001; break;
+ case 14930: l_frequency = 0x0002; break;
+ case 17060: l_frequency = 0x0004; break;
+ case 19200: l_frequency = 0x0008; break;
+ case 21330: l_frequency = 0x0010; break;
+ case 23460: l_frequency = 0x0020; break;
+ case 25600: l_frequency = 0x0040; break;
+ default: TS_FAIL("Uknown Frequency (0x%.4X). Test needs updating "
+ "to accommodate this value", i_frequency ); break;
+ }
+
+ return le16toh(l_frequency);
+}
+
+//******************************************************************************
+// setEfdDataBlockNFreq
+//******************************************************************************
+void fapi2DdimmGetEfdTest::setEfdDataBlockNFreq(const size_t i_efdDataBlockN,
+ const uint16_t i_frequency)
+{
+ uint16_t l_frequency = convertFrequency(i_frequency);
+ memcpy(&(iv_efdBlockDataPtr[i_efdDataBlockN * iv_efdBlockSize]),
+ reinterpret_cast<const uint8_t*>(&l_frequency),
+ sizeof(l_frequency) );
+}
+
+//******************************************************************************
+// setAllEfdDataBlocksFreq
+//******************************************************************************
+void fapi2DdimmGetEfdTest::setAllEfdDataBlocksFreq(const uint16_t i_frequency)
+{
+ for (size_t ii = 0; ii < iv_efdCount; ++ii)
+ {
+ setEfdDataBlockNFreq(ii, i_frequency);
+ }
+}
+
+//******************************************************************************
+// appendToEfdDataBlockNFreq
+//******************************************************************************
+void fapi2DdimmGetEfdTest::appendToEfdDataBlockNFreq(
+ const size_t i_efdDataBlockN,
+ const uint16_t i_frequency)
+{
+ uint16_t l_frequency = convertFrequency(i_frequency);
+ uint16_t l_currentFreq = *(reinterpret_cast<const uint16_t*>(
+ &(iv_efdBlockDataPtr[i_efdDataBlockN * iv_efdBlockSize]) ) );
+ l_frequency = l_frequency | l_currentFreq;
+ memcpy(&(iv_efdBlockDataPtr[i_efdDataBlockN * iv_efdBlockSize]),
+ reinterpret_cast<const uint8_t*>(&l_frequency),
+ sizeof(l_frequency) );
+}
+
+
+//******************************************************************************
+// appendToAllEfdDataBlocksFreq
+//******************************************************************************
+void fapi2DdimmGetEfdTest::appendToAllEfdDataBlocksFreq(
+ const uint16_t i_frequency)
+{
+ for (size_t ii = 0; ii < iv_efdCount; ++ii)
+ {
+ appendToEfdDataBlockNFreq(ii, i_frequency);
+ }
+}
+
+//******************************************************************************
+// convertRank
+//
+// Master Rank (MR) (data from document 1U2UDDIMM_SPD.docx)
+// Byte 2 of an EFD data block
+// INPUT: MR 3 | MR 2 | MR 1 | MR 0
+// OUTPUT: Bit 3 | Bit 2 | Bit 1 | Bit 0
+//******************************************************************************
+uint8_t fapi2DdimmGetEfdTest::convertRank(const uint8_t i_rank)
+{
+ uint8_t l_rank(0);
+ switch (i_rank)
+ {
+ // data from document 1U2UDDIMM_SPD.docx
+ case 0: l_rank = 0x01; break;
+ case 1: l_rank = 0x02; break;
+ case 2: l_rank = 0x04; break;
+ case 3: l_rank = 0x08; break;
+ default: TS_FAIL("Uknown Rank (0x%.2X). Test needs updating "
+ "to accommodate this value", i_rank ); break;
+ }
+
+ return l_rank;
+}
+
+
+//******************************************************************************
+// setEfdDataBlockNRank
+//******************************************************************************
+void fapi2DdimmGetEfdTest::setEfdDataBlockNRank(const size_t i_efdDataBlockN,
+ const uint8_t i_rank)
+{
+ uint8_t l_rank = convertRank(i_rank);
+ memcpy( &(iv_efdBlockDataPtr[(i_efdDataBlockN * iv_efdBlockSize) + 2]),
+ &l_rank,
+ sizeof(l_rank) );
+}
+
+
+//******************************************************************************
+// setAllEfdDataBlocksRank
+//******************************************************************************
+void fapi2DdimmGetEfdTest::setAllEfdDataBlocksRank(const uint8_t i_rank)
+{
+ for (size_t ii = 0; ii < iv_efdCount; ++ii)
+ {
+ setEfdDataBlockNRank(ii, i_rank);
+ }
+}
+
+
+//******************************************************************************
+// createEfdBuffer
+//******************************************************************************
+void fapi2DdimmGetEfdTest::createEfdBuffer(uint8_t* &o_efdBufferPtr,
+ const size_t i_efdBufferSize)
+{
+ delete o_efdBufferPtr; // it is OK to delete a nullptr
+
+ o_efdBufferPtr = new uint8_t[i_efdBufferSize];
+ // Set data to all 1's, so testing can be more vigorous
+ memset(o_efdBufferPtr, 0xFF, i_efdBufferSize);
+}
+
+
+//******************************************************************************
+// initializeVpdInfo
+//******************************************************************************
+void fapi2DdimmGetEfdTest::initializeVpdInfo(
+ fapi2::VPDInfo<fapi2::TARGET_TYPE_OCMB_CHIP>& o_vpdInfo)
+{
+ // Set the size to a default value
+ o_vpdInfo.iv_size = iv_efdBlockSize;
+
+ // Set frequency to default value
+ o_vpdInfo.iv_omi_freq_mhz = iv_frequency;
+
+ // Set rank to default value
+ o_vpdInfo.iv_rank = iv_rank;
+
+ // Enable the FFDC enable flag
+ o_vpdInfo.iv_is_config_ffdc_enabled = true;
+}
+
+
+//******************************************************************************
+// configureEfdDataBlockN
+//******************************************************************************
+void fapi2DdimmGetEfdTest::configureEfdDataBlockN(
+ const size_t i_efdDataBlockN,
+ const uint16_t i_frequency,
+ const uint8_t i_rank,
+ const uint8_t i_beginTag,
+ const uint8_t i_endTag)
+{
+ setEfdDataBlockNFreq(i_efdDataBlockN, i_frequency);
+ setEfdDataBlockNRank(i_efdDataBlockN, i_rank);
+ tagEfdDataBlockN(i_efdDataBlockN, i_beginTag, i_endTag);
+}
+
+
+//******************************************************************************
+// verifyEfdBuffer
+//******************************************************************************
+bool fapi2DdimmGetEfdTest::verifyEfdBuffer(const uint16_t i_frequency,
+ const uint8_t i_rank,
+ const uint8_t i_beginTag,
+ const uint8_t i_endTag)
+
+{
+ uint8_t l_rank = convertRank(i_rank);
+ uint16_t l_frequency = convertFrequency(i_frequency);
+
+ const uint16_t l_efdfreq =
+ *(reinterpret_cast<const uint16_t*>(iv_efdBufferPtr));
+
+ return ( (l_rank == iv_efdBufferPtr[2]) &&
+ (l_frequency | l_efdfreq) &&
+ (iv_efdBufferPtr[4] == i_beginTag) &&
+ (iv_efdBufferPtr[iv_efdBlockSize - 1] == i_endTag) );
+}
+
+
+//******************************************************************************
+// tagEfdDataBlockN
+//******************************************************************************
+void fapi2DdimmGetEfdTest::tagEfdDataBlockN(const size_t i_efdDataBlockN,
+ const uint8_t i_beginTag,
+ const uint8_t i_endTag)
+{
+ // Tag data 4 bytes beyond the beginning of the EFD data block. The
+ // first bytes of the EFD data block contain the frequency and master
+ // rank. Need that data for comparison. Do not want to over write that
+ // data so tag after the frequency and master rank data.
+ memcpy(&(iv_efdBlockDataPtr[(i_efdDataBlockN * iv_efdBlockSize) + 4]),
+ &i_beginTag,
+ sizeof(i_beginTag) );
+
+ // Tag the ending byte.
+ memcpy(&(iv_efdBlockDataPtr[(i_efdDataBlockN * iv_efdBlockSize) +
+ (iv_efdBlockSize - 1)]),
+ &i_endTag,
+ sizeof(i_endTag) );
+}
diff --git a/src/usr/fapi2/test/fapi2DdimmGetEfdTest.H b/src/usr/fapi2/test/fapi2DdimmGetEfdTest.H
new file mode 100644
index 000000000..43a359381
--- /dev/null
+++ b/src/usr/fapi2/test/fapi2DdimmGetEfdTest.H
@@ -0,0 +1,401 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/fapi2/test/fapi2DdimmGetEfdTest.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2019 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+
+#ifndef __FAPI2_DDIMM_GET_EFD_TEST_H
+#define __FAPI2_DDIMM_GET_EFD_TEST_H
+
+#include <cxxtest/TestSuite.H>
+#include <ddimm_get_efd.H>
+
+//******************************************************************************
+// class fapi2DdimmGetEfdTest
+//
+// @brief This tests the HWP call ddimm_get_efd/ddr4_get_efd
+//
+//******************************************************************************
+class fapi2DdimmGetEfdTest : public CxxTest::TestSuite
+{
+public:
+
+//******************************************************************************
+// Public API
+//******************************************************************************
+
+//******************************************************************************
+// fapi2DdimmGetEfdTest ctor
+//******************************************************************************
+fapi2DdimmGetEfdTest();
+
+//******************************************************************************
+// testDdimmGetEfdHwpCall
+//
+// @brief A wrapper around the actual test procedures.
+//
+//******************************************************************************
+void testDdimmGetEfdHwpCall();
+
+private:
+
+//******************************************************************************
+// Private Test Cases
+//******************************************************************************
+
+//******************************************************************************
+// sanityCheckTest
+//
+// @brief The setup creates a perfect scenario to get a match from the get go.
+// If this fails, then setup is broken/corrupt, design has changed, etc.
+// Either way, no point in continuing until fixed.
+//
+// @return true if a match was found (which signifies that the test suite has
+// been initialized correctly), false if no match found (which
+// signifies that the test suite has NOT been initialized correctly)
+//
+//******************************************************************************
+bool sanityCheckTest();
+
+//******************************************************************************
+// sizeMisMatchTest
+//
+// @brief Do negative testing on the sizes of the different elements - SPD
+// buffer, EFD memory space size, etc.
+//
+//******************************************************************************
+void sizeMisMatchTest();
+
+//******************************************************************************
+// dmbDataTest
+//
+// @brief Do negative testing on the DMB manufacturer ID and the DMB revision.
+// Test for incorrect values.
+//
+//******************************************************************************
+void dmbDataTest();
+
+//******************************************************************************
+// vpdInfoInputTest
+//
+// @brief Do negative testing on the frequency and master rank data passed in
+// via the VPDInfo struct. Test for incorrect values.
+//
+//******************************************************************************
+void vpdInfoInputTest();
+
+//******************************************************************************
+// findMatchTest
+//
+// @brief Do positive testing on finding/not finding a match for given
+// frequency and rank.
+//
+//******************************************************************************
+void findMatchTest();
+
+
+
+//******************************************************************************
+//
+// Private utilities to facilitate the testing. These utilities help
+// to manipulate buffers for easy testing.
+//
+//******************************************************************************
+
+/*
+ * @brief Initialize the SPD buffer to a good state - one that has no issues
+ * finding an EFD to match the criteria in the VPDInfo struct.
+ */
+void initializeSpdBuffer();
+
+/*
+ * @brief Create the buffer for the SPD with given parameters.
+ *
+ * @param[out] o_spdBufferPtr, pointer to a newly created SPD buffer
+ * @param[in] i_spdBufferSize, size to make the SPD buffer
+ */
+void createSpdBuffer( uint8_t* &o_spdBufferPtr,
+ const size_t i_spdBufferSize);
+
+/*
+ * @brief Set the DDIMM type of SPD buffer at the proper location
+ * within the SPD buffer.
+ *
+ * @param[in] i_spdDdimmType, DDIMM type to set within the SPD buffe
+ */
+void setSpdDdimmType(const uint8_t i_spdDdimmType);
+
+/*
+ * @brief Set the EFD memory space location at the proper location
+ * within the SPD buffer.
+ *
+ * @param[in] i_efdMemorySpaceLocation, the EFD memory space location
+ */
+void setEfdMemorySpaceLocation(const uint64_t i_efdMemorySpaceLocation);
+
+/*
+ * @brief Set the EFD memory space size at the proper location
+ * within the SPD buffer.
+ *
+ * @param[in] i_efdMemorySpaceSize, the EFD memory space size
+ */
+void setEfdMemorySpaceSize(const uint8_t i_efdMemorySpaceSize);
+
+/*
+ * @brief Set the number of EFDs, for this buffer, at the proper location
+ * within the SPD buffer.
+ *
+ * @param[in] i_efdCount, the number of EFDs
+ */
+void setEfdCount(const uint16_t i_efdCount);
+
+/*
+ * @brief Set the DMB manufacturer ID at the proper location
+ * within the SPD buffer.
+ *
+ * @param[in] i_spdDmbMfgId, the DMB manufacturer ID
+ */
+void setSpdDmbMfgId(const uint16_t i_spdDmbMfgId);
+
+/*
+ * @brief Set the DMB revision at the proper location within the SPD buffer.
+ *
+ * @param[in] i_spdDmbMfgId, the DMB revision
+ */
+void setSpdDmbRevision(const uint8_t i_spdDmbRevision);
+
+/*
+ * @brief Set individual EFD data block ending offset within the EFD meta data
+ *
+ * @param[in] i_efdMetaDataN, the individual EFD meta data to modify, 0 based
+ * @param[in] i_efdDataBlockEnd, the corresponding EFD data block end
+ * for the given EFD meta data
+ */
+void setEfdMetaDataNEfdDataBlockEnd(const size_t i_efdMetaDataN,
+ const uint8_t i_efdDataBlockEnd);
+/*
+ * @brief Set all the EFD data block sizes within the EFD meta datas
+ *
+ * @param[in] i_efdDataBlockSize, size of the EFD data block
+ */
+void setAllEfdMetaDatasEfdDataBlockSize(const uint8_t i_efdDataBlockSize);
+
+/*
+ * @brief Set an individual EFD meta data's extended function type
+ *
+ * @param[in] i_efdMetaDataN, the individual EFD meta data to modify, 0 based
+ * @param[in] i_extendedFunctionType, the extended function type value
+ */
+void setEfdMetaDataExtendedFunctionType(const size_t i_efdMetaDataN,
+ const uint8_t i_extendedFunctionType);
+
+ /*
+ * @brief Set all the EFD meta data's extended function type
+ *
+ * @param[in] i_extendedFunctionType, the extended function type value
+ */
+void setAllEfdMetaDatasExtendedFunctionType(
+ const uint8_t i_extendedFunctionType);
+/*
+ * @brief Set an individual EFD meta data's implemented state
+ *
+ * @param[in] i_efdMetaDataN, the individual EFD meta data to modify, 0 based
+ * @param[in] i_isImplemented, state of the EFD meta data to be set to
+ */
+void setEfdMetaDataNisImplemented(const size_t i_efdMetaDataN,
+ const bool i_isImplemented);
+
+/*
+ * @brief Set all the EFD meta data's implemented state
+ *
+ * @param[in] i_isImplemented, state of the EFD meta data to be set to
+ */
+void setAllEfdMetaDatasIsImplemented(const bool i_isImplemented);
+
+ /*
+ * @brief Set an individual EFD data block's frequency
+ *
+ * @param[in] i_frequency, the frequency, in numeric form
+ */
+uint16_t convertFrequency(const uint16_t i_frequency);
+
+ /*
+ * @brief Set an individual EFD data block's frequency
+ *
+ * @param[in] i_efdDataBlockN, the individual EFD data block to modify, 0 based
+ * @param[in] i_frequency, the frequency, in numeric form, to set the
+ * individual EFD data block to
+ */
+void setEfdDataBlockNFreq(const size_t i_efdDataBlockN,
+ const uint16_t i_frequency);
+
+ /*
+ * @brief Set all the EFD data block's frequency
+ *
+ * @param[in] i_frequency, the frequency, in numeric form, to set all EFD
+ * data blocks to
+ */
+void setAllEfdDataBlocksFreq(const uint16_t i_frequency);
+
+ /*
+ * @brief Append a frequency to an individual EFD data block
+ *
+ * @param[in] i_efdDataBlockN, the individual EFD data block to modify, 0 based
+ * @param[in] i_frequency, the frequency, in numeric form, to append
+ */
+void appendToEfdDataBlockNFreq(const size_t i_efdDataBlockN,
+ const uint16_t i_frequency);
+
+ /*
+ * @brief Append a frequency to all EFD data blocks
+ *
+ * @param[in] i_frequency, the frequency, in numeric form, to append
+ */
+void appendToAllEfdDataBlocksFreq(const uint16_t i_frequency);
+
+/*
+ * @brief Map master rank to bit mask.
+ *
+ * @param[in] i_rank, the master rank, in numeric form
+ */
+uint8_t convertRank(const uint8_t i_rank);
+
+/*
+ * @brief Set an individual EFD data block's master rank
+ *
+ * @param[in] i_efdDataBlockN, the individual EFD data block to modify, 0 based
+ * @param[in] i_rank, the master rank, in numeric form, to set the individual
+ * EFD data block to
+ */
+void setEfdDataBlockNRank(const size_t i_efdDataBlockN,
+ const uint8_t i_rank);
+
+ /*
+ * @brief Set all the EFD data block's master rank
+ *
+ * @param[in] i_rank, the master rank, in numeric form, to set all EFD
+ * data blocks to
+ *
+ */
+void setAllEfdDataBlocksRank(const uint8_t i_rank);
+
+/*
+ * @brief Create the buffer for the EFD with given parameters.
+ *
+ * @param[out] o_efdBufferPtr, pointer to a newly created EFD buffer
+ * @param[in] i_efdBufferSize, size to make the EFD buffer
+ */
+void createEfdBuffer( uint8_t* &o_efdBufferPtr,
+ const size_t i_efdBufferSize);
+
+/*
+ * @brief Initialize a VPDInfo struct to a known state
+ *
+ * @param[out] o_vpdInfo, VPDInfo struct to initialize
+ */
+void initializeVpdInfo(fapi2::VPDInfo<fapi2::TARGET_TYPE_OCMB_CHIP>& o_vpdInfo);
+
+/*
+ * @brief Configure an EFD data block to given data
+ *
+ * @param[in] i_efdDataBlockN, the individual EFD data block to modify, 0 based
+ * @param[in] i_frequency, the frequency, in numeric form,
+ * to set EFD data block to
+ * @param[in] i_rank, the master rank, in numeric form,
+ * to set EFD data block to
+ * @param[in] i_beginTag, tag to use at the beginning of the EFD data block
+ * @param[in] i_endTag, tag to use at the end of the EFD data block
+ */
+void configureEfdDataBlockN(const size_t i_efdDataBlockN,
+ const uint16_t i_frequency,
+ const uint8_t i_rank,
+ const uint8_t i_beginTag,
+ const uint8_t i_endTag);
+
+/*
+ * @brief Verify the EFD buffer has the expected value. It is not enough to
+ * say we found a match. Must confirm we retrieved the correct EFD
+ * data block.
+ *
+ * @param[in] i_frequency, the frequency, in numeric form,
+ * to match in EFD data block
+ * @param[in] i_rank, the master rank, in numeric form,
+ * to match in EFD data block
+ * @param[in] i_beginTag, tag to match at the beginning of the EFD data block
+ * @param[in] i_endTag, tag to match at the end of the EFD data block
+ *
+ * @return true if the EFD buffer matches data given, else false if no match
+ */
+bool verifyEfdBuffer(const uint16_t i_frequency,
+ const uint8_t i_rank,
+ const uint8_t i_beginTag,
+ const uint8_t i_endTag);
+
+/*
+ * @brief Tag an EFD data block to help identify it when found
+ * Tagging the EFD data block at specific memory places within the EFD
+ * data block, ensures that when a match is found, indeed that block
+ * is returned - the called function cannot spoof the data. The tags
+ * ensure that the called function is returning the correct EFD data
+ * block in it's entirety.
+ *
+ * @param[in] i_efdDataBlockN, the individual EFD data block to modify, 0 based
+ * @param[in] i_beginTag, tag to use at the beginning of the EFD data block
+ * @param[in] i_endTag, tag to use at the end of the EFD data block
+ */
+void tagEfdDataBlockN(const size_t i_efdDataBlockN,
+ const uint8_t i_beginTag,
+ const uint8_t i_endTag);
+
+//******************************************************************************
+//
+// Private data members
+//
+//******************************************************************************
+
+ uint8_t* iv_efdBufferPtr;
+ uint8_t* iv_spdBufferPtr;
+ size_t iv_spdBufferSize;
+ uint8_t* iv_efdMetaDataPtr;
+ uint8_t* iv_efdBlockDataPtr;
+ uint8_t iv_efdBlockSizeMultiplier;
+ size_t iv_efdBlockSize;
+ size_t iv_efdMemorySpaceLocation;
+ size_t iv_efdMemorySpaceSize;
+ uint16_t iv_efdCount;
+ uint16_t iv_spdDmbMfgId;
+ uint8_t iv_spdDmbRevision;
+ uint8_t iv_extendedFunctionType;
+ uint16_t iv_frequency;
+ uint8_t iv_rank;
+
+ TARGETING::Target * iv_ocmbChipTarget;
+ fapi2::ReturnCode iv_rc;
+ fapi2::VPDInfo<fapi2::TARGET_TYPE_OCMB_CHIP> iv_vpdInfo;
+
+ size_t iv_numTests;
+ size_t iv_numFails;
+ TARGETING::MODEL iv_attrModel;
+}; // end class fapi2DdimmGetEfdTest
+
+#endif
+
diff --git a/src/usr/fapi2/test/fapi2Test.mk b/src/usr/fapi2/test/fapi2Test.mk
index dbe7268c2..54d8b37da 100644
--- a/src/usr/fapi2/test/fapi2Test.mk
+++ b/src/usr/fapi2/test/fapi2Test.mk
@@ -49,6 +49,7 @@ OBJS += p9_sample_procedure.o
OBJS += p9_hwtests.o
OBJS += rcSupport.o
OBJS += fapi2TestUtils.o
+OBJS += fapi2DdimmGetEfdTest.o
OBJS += getVpdTest.o
OBJS += p9_pm_get_poundv_bucket.o
OpenPOWER on IntegriCloud