diff options
| author | whs <whs@us.ibm.com> | 2016-04-04 10:19:37 -0500 |
|---|---|---|
| committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-06-30 23:52:31 -0400 |
| commit | c9219373d4320bf513046e69903ce33243e84be6 (patch) | |
| tree | 93494842bf5a673b00910edc756f19d3e1e1a026 /src/usr/fapi2 | |
| parent | f07603a9f2eab60e8e524ff487787086b9a5304e (diff) | |
| download | blackbird-hostboot-c9219373d4320bf513046e69903ce33243e84be6.tar.gz blackbird-hostboot-c9219373d4320bf513046e69903ce33243e84be6.zip | |
Changes related to packaging of memory vpd on Nimbus - part 2
Add the "upper" half of the NIMBUS direct memory support.
Add ATTR_MEMVPD_FREQS_MHZ and ATTR_MEMVPD_POS attributes.
Implement plat_vpd_access to call p9_getmem_vpd_keyword which decodes which
vpd keyword to read for MR and MT.
Update dvpd DD with record and keyword list.
Update dvpd.dat simics vpd file to include MR and MT that map to J0 and X0.
Change-Id: Ife00aa4266a7c16dcff2f0f72837f4d547988b82
RTC: 144519
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/23245
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/usr/fapi2')
| -rwxr-xr-x | src/usr/fapi2/fapi2.mk | 12 | ||||
| -rw-r--r-- | src/usr/fapi2/plat_vpd_access.C | 274 | ||||
| -rw-r--r-- | src/usr/fapi2/test/fapi2GetVpdTest.H | 59 | ||||
| -rw-r--r-- | src/usr/fapi2/test/fapi2Test.mk | 2 | ||||
| -rw-r--r-- | src/usr/fapi2/test/getVpdTest.C | 612 | ||||
| -rw-r--r-- | src/usr/fapi2/test/getVpdTest.H | 79 |
6 files changed, 1038 insertions, 0 deletions
diff --git a/src/usr/fapi2/fapi2.mk b/src/usr/fapi2/fapi2.mk index 1bedbd2e5..89f00e9c7 100755 --- a/src/usr/fapi2/fapi2.mk +++ b/src/usr/fapi2/fapi2.mk @@ -29,11 +29,15 @@ # GENPATH?=$(ROOTPATH)/obj/genfiles +HWP_PATH += ${ROOTPATH}/src/import/chips/p9/procedures + EXTRAINCDIR += ${ROOTPATH}/src/import/hwpf/fapi2/include/ +EXTRAINCDIR += ${ROOTPATH}/src/include/usr EXTRAINCDIR += ${ROOTPATH}/src/include/usr/fapi2/ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils/ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils/imageProcs/ EXTRAINCDIR += $(ROOTPATH)/src/import/chips/p9/procedures/hwp/pm/ +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/accessors/ include ${ROOTPATH}/src/build/mkrules/verbose.rules.mk define __CLEAN_TARGET @@ -50,6 +54,13 @@ OBJS += target.o OBJS += plat_hw_access.o OBJS += plat_spd_access.o OBJS += plat_mvpd_access.o +OBJS += plat_vpd_access.o + + +#Required include before all the procedure.mk are included +include ${ROOTPATH}/procedure.rules.mk + +include ${HWP_PATH}/hwp/accessors/p9_get_mem_vpd_keyword.mk #EKB Objects (mirrored in src/import) OBJS += error_info.o @@ -113,6 +124,7 @@ include ${ROOTPATH}/src/import/hwpf/fapi2/tools/createIfAttrService.mk include $(ROOTPATH)/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundv_bucket.mk include $(ROOTPATH)/src/import/chips/p9/procedures/hwp/pm/p9_pm_get_poundv_bucket_attr.mk +VPATH += ${HWP_PATH}/hwp/accessors VPATH += ${ROOTPATH}/src/import/hwpf/fapi2/src/ VPATH += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/pm/ VPATH += ${GENPATH} diff --git a/src/usr/fapi2/plat_vpd_access.C b/src/usr/fapi2/plat_vpd_access.C new file mode 100644 index 000000000..91ea92506 --- /dev/null +++ b/src/usr/fapi2/plat_vpd_access.C @@ -0,0 +1,274 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/fapi2/plat_vpd_access.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2012,2016 */ +/* [+] 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 */ +/** + * @file plat_vpd_access.C + * + * @brief Implements the GetVpd function + */ + +#include <stdint.h> +#include <fapi2.H> +#include <vpd_access_defs.H> +#include <vpd_access.H> +#include <p9_get_mem_vpd_keyword.H> +#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) + +namespace fapi2 +{ + +fapi2::ReturnCode platGetVPD( + const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + VPDInfo<fapi2::TARGET_TYPE_MCS>& io_vpd_info, + uint8_t* o_blob) +{ + fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS; + errlHndl_t l_errl = nullptr; + keywordName_t l_keywordName = {0}; + // 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. + const size_t VPD_KEYWORD_SIZE = 255; + + FAPI_DBG("platGetVPD: enter"); + + do + { + // null blob pointer requests blob size + if ( nullptr == o_blob) // just return size + { + io_vpd_info.iv_size = VPD_KEYWORD_SIZE; + FAPI_DBG("platGetVPD: return blob size of %d", + io_vpd_info.iv_size); + break; //return success + } + + //Make sure passed blob buffer is big enough + if (VPD_KEYWORD_SIZE > io_vpd_info.iv_size) + { + FAPI_ERR("platGetVPD: blob size of %d too small, should be %d", + io_vpd_info.iv_size, + VPD_KEYWORD_SIZE); + /*@ + * @errortype + * @moduleid fapi2::MOD_FAPI2_PLAT_GET_VPD + * @reasoncode fapi2::RC_BUFFER_TOO_SMALL + * @userdata1 Buffer size + * @userdata2 Expected size + * @devdesc Passed buffer too small + * @custdesc Firmware Error + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi2::MOD_FAPI2_PLAT_GET_VPD, + fapi2::RC_BUFFER_TOO_SMALL, + io_vpd_info.iv_size, + VPD_KEYWORD_SIZE, + true); //software callout + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl)); + break; //return with error + } + + // Get targeting MCS target + TARGETING::Target * l_pMcsTarget = nullptr; + l_errl = fapi2::platAttrSvc::getTargetingTarget(i_target, l_pMcsTarget); + if (l_errl) + { + FAPI_ERR("platGetVPD: Error from getTargetingTarget"); + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl)); + break; //return with error + } + + //Validate type and check for override + uint64_t l_mapKeyword = 0; + uint64_t l_keywordEnum = 0; //set this now to be used later + if ( fapi2::MT == io_vpd_info.iv_vpd_type ) + { + if (1 == + l_pMcsTarget->getAttr<TARGETING::ATTR_VPD_OVERRIDE_MT_ENABLE>() ) + { + uint8_t l_override[VPD_KEYWORD_SIZE]={0}; + assert(l_pMcsTarget->tryGetAttr<TARGETING::ATTR_VPD_OVERRIDE_MT> + (l_override), + "platGetVPD: getAttr ATTR_VPD_OVERRIDE_MT failed"); + FAPI_DBG("platGetVPD: return MT override attr"); + memcpy(o_blob,l_override,VPD_KEYWORD_SIZE); + break; //return with overriden keyword + } + + // not overriden, continue + l_mapKeyword = DVPD::MT; + l_keywordEnum = DVPD::X0; + } + else if ( fapi2::MR == io_vpd_info.iv_vpd_type ) + { + if (1== + l_pMcsTarget->getAttr<TARGETING::ATTR_VPD_OVERRIDE_MR_ENABLE>() ) + { + uint8_t l_override[VPD_KEYWORD_SIZE]={0}; + assert(l_pMcsTarget->tryGetAttr<TARGETING::ATTR_VPD_OVERRIDE_MR> + (l_override), + "platGetVPD: getAttr ATTR_VPD_OVERRIDE_MR failed"); + FAPI_DBG("platGetVPD: return MR override attr"); + memcpy(o_blob,l_override,VPD_KEYWORD_SIZE); + break; //return with overriden keyword + } + + // not overriden, continue + l_mapKeyword = DVPD::MR; + l_keywordEnum = DVPD::J0; + } + else + { + FAPI_ERR("platGetVPD: invalid type = %d", + io_vpd_info.iv_vpd_type); + /*@ + * @errortype + * @moduleid fapi2::MOD_FAPI2_PLAT_GET_VPD + * @reasoncode fapi2::RC_INVALID_TYPE + * @userdata1 Vpd type + * @userdata2 HUID of MCS target + * @devdesc MR and MT types supported + * @custdesc Firmware Error + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi2::MOD_FAPI2_PLAT_GET_VPD, + fapi2::RC_BUFFER_TOO_SMALL, + io_vpd_info.iv_vpd_type, + TARGETING::get_huid(l_pMcsTarget), + true); //software callout + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl)); + break; //return with error + } + + //Read mapping keyword + size_t l_buffSize = VPD_KEYWORD_SIZE; + uint8_t * l_pMapping = new uint8_t[VPD_KEYWORD_SIZE]; + l_errl = deviceRead((TARGETING::Target *)l_pMcsTarget, + l_pMapping, + l_buffSize, + DEVICE_DVPD_ADDRESS(DVPD::MEMD, + l_mapKeyword)); + if (l_errl) + { + delete l_pMapping; + FAPI_ERR("platGetVPD: ERROR reading mapping keyword"); + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl)); + break; //return with error + } + + // Find vpd keyword name based on VPDInfo + FAPI_EXEC_HWP(l_rc, + p9_get_mem_vpd_keyword, + i_target, + io_vpd_info, + l_pMapping, + VPD_KEYWORD_SIZE, + l_keywordName); + delete l_pMapping; + if (l_rc) + { + FAPI_ERR("platGetVPD: ERROR returned from p9_get_mem_vpd_keyword"); + break; //return with error + } + FAPI_DBG("platGetVPD: keyword name = %s", + l_keywordName); + + //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) + { + l_keywordEnum += (l_keywordName[1] - '0'); + } + else //it is a char (A..Z) + { + l_keywordEnum += (l_keywordName[1] - 'A') + 10; + } + + //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 + } + + //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 ); + + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl)); + break; //return with error + } + } + while (0); + + FAPI_DBG("platGetVPD: exit"); + + return l_rc; +} + +} // namespace diff --git a/src/usr/fapi2/test/fapi2GetVpdTest.H b/src/usr/fapi2/test/fapi2GetVpdTest.H new file mode 100644 index 000000000..cfd560b28 --- /dev/null +++ b/src/usr/fapi2/test/fapi2GetVpdTest.H @@ -0,0 +1,59 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/fapi2/test/fapi2GetVpdTest.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] 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 __FAPI2GETVPDTEST_H +#define __FAPI2GETVPDTEST_H + +/** + * @file getVpdTest.H + * @brief simple testcase for vpd function + */ + +#include <stdint.h> + +#include <cxxtest/TestSuite.H> +#include <getVpdTest.H> + +class GetVPDTest : public CxxTest::TestSuite +{ + +public: + +void testGetVPD(void) +{ + testGetVPD_MR(); + + testGetVPD_MT(); + + testDecode_MR(); + + testDecode_MT(); + + testGetVPD_Override(); +} + +}; // GetVPDTest class + +#endif diff --git a/src/usr/fapi2/test/fapi2Test.mk b/src/usr/fapi2/test/fapi2Test.mk index b7544564a..1c0fd049a 100644 --- a/src/usr/fapi2/test/fapi2Test.mk +++ b/src/usr/fapi2/test/fapi2Test.mk @@ -35,12 +35,14 @@ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils/ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/utils/imageProcs/ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/common/include/ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/pm/ +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/accessors/ EXTRAINCDIR += ${ROOTPATH}/src/include/usr/targeting/common/ # Procedures OBJS += p9_sample_procedure.o OBJS += p9_hwtests.o OBJS += fapi2TestUtils.o +OBJS += getVpdTest.o TESTS += ${ROOTPATH}/src/usr/fapi2/test/*Test.H TESTS += ${ROOTPATH}/src/usr/fapi2/test/*TestCxx.H diff --git a/src/usr/fapi2/test/getVpdTest.C b/src/usr/fapi2/test/getVpdTest.C new file mode 100644 index 000000000..e582ab609 --- /dev/null +++ b/src/usr/fapi2/test/getVpdTest.C @@ -0,0 +1,612 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/fapi2/test/getVpdTest.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] 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 */ + +/** + * @file getVpdTest.C + * @brief getVpd for MCA memory test cases + */ + +#include <stdint.h> +#include <cxxtest/TestSuite.H> +#include <target.H> +#include <target_types.H> +#include <vpd_access_defs.H> +#include <return_code_defs.H> +#include <return_code.H> +#include <vpd_access.H> +#include <getVpdTest.H> +#include <p9_get_mem_vpd_keyword.H> +#include <attribute_service.H> + +//The following commented out section can be restored for unit testing +//#undef FAPI_DBG +//#define FAPI_DBG(args...) FAPI_INF(args) + +using TARGETING::ATTR_VPD_OVERRIDE_MT; +using TARGETING::ATTR_VPD_OVERRIDE_MT_ENABLE; +using TARGETING::ATTR_VPD_OVERRIDE_MR; +using TARGETING::ATTR_VPD_OVERRIDE_MR_ENABLE; + +const size_t VPD_KEYWORD_SIZE = 255; + +using namespace fapi2; + +// Find MCS of requested MEMVPD_POS +bool getTarget (TARGETING::ATTR_MEMVPD_POS_type i_memVpdPos, + TARGETING::Target * &o_target, + fapi2::Target<fapi2::TARGET_TYPE_MCS> &o_fapiTarget) +{ + bool l_rc = false; + + + TARGETING::TargetHandleList l_mcsTargetList; + getAllChiplets(l_mcsTargetList, TARGETING::TYPE_MCS, false); + FAPI_DBG("testGetVPD mcs count = %d", l_mcsTargetList.size()); + + for (const auto l_mcsTarget: l_mcsTargetList) + { + TARGETING::ATTR_MEMVPD_POS_type l_memVpdPos = + l_mcsTarget->getAttr<TARGETING::ATTR_MEMVPD_POS>(); + if (i_memVpdPos == l_memVpdPos) + { + o_target = l_mcsTarget; + fapi2::Target<fapi2::TARGET_TYPE_MCS> + l_fapiTarget(o_target); + o_fapiTarget = l_fapiTarget; + l_rc = true; + break; //found MCS + } + } + + return l_rc; +} + +//Common code for calling getVPD +ReturnCode testGetVPD( + fapi2::Target<fapi2::TARGET_TYPE_MCS> i_fapiTarget, + fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS> i_VPDInfo, + const fapi2::MemVpdData i_vpdType, + const char * i_check, //NULL for no check + int & numTests, + int & numFails) +{ + numTests = 0; + numFails = 0; + ReturnCode l_rc; + + FAPI_DBG("testGetVPD common enter"); + + do + { + // call with null blob pointer to get blob size + uint8_t* blob = nullptr; //first call + numTests++; + l_rc = getVPD(i_fapiTarget, i_VPDInfo, blob ); + if (l_rc) + { + TS_FAIL ("testGetVPD getVPD failed to get blob size"); + numFails++; + break; + } + + numTests++; + if ( i_VPDInfo.iv_vpd_type != i_vpdType ) + { + TS_FAIL ("testGetVPD invalid initial type" + "value = %d expected = %d", + i_VPDInfo.iv_vpd_type,i_vpdType); + numFails++; + } + numTests++; + if ( blob != nullptr ) + { + TS_FAIL ("testGetVPD blob pointer not NULL" + "value = %p expected = %d", + blob,0); + numFails++; + } + numTests++; + if ( i_VPDInfo.iv_size != VPD_KEYWORD_SIZE ) + { + TS_FAIL ("testGetVPD invalid size" + "value = %d expected = %d", + i_VPDInfo.iv_size,VPD_KEYWORD_SIZE); + numFails++; + } + if (numFails) break; + + // call to get blob + blob = new uint8_t[i_VPDInfo.iv_size]; + numTests++; + l_rc = getVPD(i_fapiTarget, i_VPDInfo, blob); + if (l_rc) + { + TS_FAIL ("testGetVPD getVPD failed to return blob"); + numFails++; + break; + } + + numTests++; + if ( blob == nullptr ) + { + TS_FAIL ("testGetVPD blob pointer NULL value = %p", + blob); + numFails++; + break; //don't use NULL pointer + } + + // compare to expected test data + numTests++; + if ( i_check && + (blob[0] != i_check[0]) && + (blob[1] != i_check[1]) ) + { + TS_FAIL ("testGetVPD:: invalid blob value" + "value = %x %x expected = %x %x", + blob[0],blob[1],i_check[0],i_check[1]); + numFails++; + } + delete blob; + blob = nullptr; + + } + while(0); + + FAPI_DBG("testGetVPD common exit"); + + return l_rc; +} + +void testDecode_MR(void) +{ + int numTests = 0; + int numFails = 0; + ReturnCode l_rc; + + FAPI_DBG("testDecode MR start"); + + do + { + // 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 ("testDecode_MR:: 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::MR); + l_info.iv_freq_mhz = 1866; // index = 0 + l_info.iv_rank_count_dimm_0 = 1; + l_info.iv_rank_count_dimm_1 = 4; + fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS; + + // set up the mapping data + uint8_t l_pMapping[VPD_KEYWORD_SIZE] = { + // Header: version=1, num entries=5, reserved + 1,5,0, + // miss: mcs match, pair match, freq miss + 0xff,0xff,0xff,0xff,0x7f,'0', + // miss: mcs match, pair missing, freq match + 0xff,0xff,0xfe,0xff,0xff,'1', + // miss: mcs miss, pair match, freq match + 0x7f,0xff,0xff,0xff,0xff,'2', + // match: + 0x80,0x00,0x01,0x00,0x80,'3', // <-- should be this one + // match everything + 0xff,0xff,0xff,0xff,0xff,'4', + // zero out rest + 0}; + + // decode keyword + keywordName_t l_keywordName = {0}; + numTests++; + + FAPI_EXEC_HWP(l_rc, + p9_get_mem_vpd_keyword, + l_fapiTarget, + l_info, + l_pMapping, + VPD_KEYWORD_SIZE, + l_keywordName); + if(l_rc) + { + TS_FAIL ("testDecode_MR:: p9_get_mem_vpd_keyword failed"); + numFails++; + break; // decode failed + } + + // compare to expected test data + numTests++; + if ( (l_keywordName[0] != 'J' ) && + (l_keywordName[1] != '3' ) ) + { + TS_FAIL ("testDecode_MR:: unexpected keyword name returned" + "value = %x %x expected = %x %x", + l_keywordName[0],l_keywordName[1],'J','3'); + numFails++; + } + + } + while(0); + + FAPI_INF("testDecode MR Test Complete, %d/%d fails", + numFails, numTests); +} + +void testDecode_MT(void) +{ + int numTests = 0; + int numFails = 0; + ReturnCode l_rc; + + FAPI_DBG("testDecode MT start"); + + do + { + // get a MCS fapi2 target for MEMVPD_POS 7 + TARGETING::ATTR_MEMVPD_POS_type l_memVpdPos = 7; + + fapi2::Target<fapi2::TARGET_TYPE_MCS> l_fapiTarget; + TARGETING::Target * l_target; + if(!getTarget(l_memVpdPos,l_target,l_fapiTarget)) + { + TS_FAIL ("testDecode_MT:: 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::MT); + l_info.iv_freq_mhz = 2667; //index 3 + l_info.iv_rank_count_dimm_0 = 4; + l_info.iv_rank_count_dimm_1 = 1; + + // set up the mapping data + uint8_t l_pMapping[VPD_KEYWORD_SIZE] = { + // Header: version=1, num entries=4, reserved + 1,4,0, + // miss: mcs match, pair match, freq miss + 0xff,0xff,0xff,0xff,0xef,'0', + // miss: mcs match, pair missing, freq match + 0xff,0xff,0xff,0xfd,0xff,'1', + // miss: mcs miss, pair match, freq match + 0xfe,0xff,0xff,0xff,0xff,'2', + // match: + 0x01,0x00,0x00,0x04,0x10,'3', // <-- should be this one + // zero out rest + 0}; + + // decode keyword + keywordName_t l_keywordName = {0}; + numTests++; + FAPI_EXEC_HWP(l_rc, + p9_get_mem_vpd_keyword, + l_fapiTarget, + l_info, + l_pMapping, + VPD_KEYWORD_SIZE, + l_keywordName); + if(l_rc) + { + TS_FAIL ("testDecode_MT:: p9_get_mem_vpd_keyword failed"); + numFails++; + break; // decode failed + } + + // compare to expected test data + numTests++; + if ( (l_keywordName[0] != 'X' ) && + (l_keywordName[1] != '3' ) ) + { + TS_FAIL ("testDecode_MT:: unexpected keyword name returned" + "value = %x %x expected = %x %x", + l_keywordName[0],l_keywordName[1],'X','3'); + numFails++; + } + + } + while(0); + + FAPI_INF("testDecode MT Test Complete, %d/%d fails", + numFails, numTests); +} + +void testGetVPD_MR(void) +{ + int numTests = 0; + int numFails = 0; + ReturnCode l_rc; + + FAPI_DBG("testGetVPD MR start"); + + do + { + // 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_MR:: could not find MCS MEMVPD_POS=%d", + l_memVpdPos); + numFails++; + break; //Target not found + } + + // set up VPDInfo + // simics test data will return keyword J0 + fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS> l_info(fapi2::MR); + l_info.iv_freq_mhz = 1866; + l_info.iv_rank_count_dimm_0 = 1; + l_info.iv_rank_count_dimm_1 = 4; + + l_rc = testGetVPD(l_fapiTarget, + l_info, + fapi2::MR, + nullptr, //don't test data, just ability to access + numTests, + numFails); + if(l_rc) + { + TS_FAIL ("testGetVPD MR:: testGetVPD decode failed"); + break; // decode failed (don't double count num tests and fails) + } + + } + while(0); + + FAPI_INF("testGetVPD MR Test Complete, %d/%d fails", + numFails, numTests); +} + +void testGetVPD_MT(void) +{ + int numTests = 0; + int numFails = 0; + ReturnCode l_rc; + + FAPI_DBG("testGetVPD MT start"); + + do + { + // get a MCS fapi2 target for MEMVPD_POS 7 + TARGETING::ATTR_MEMVPD_POS_type l_memVpdPos = 7; + + fapi2::Target<fapi2::TARGET_TYPE_MCS> l_fapiTarget; + TARGETING::Target * l_target; + if(!getTarget(l_memVpdPos,l_target,l_fapiTarget)) + { + TS_FAIL ("testGetVPD_MT:: could not find MCS MEMVPD_POS=%d", + l_memVpdPos); + numFails++; + break; //Target not found + } + + // set up VPDInfo + // simics test data will return keyword X0 + fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS> l_info(fapi2::MT); + l_info.iv_freq_mhz = 2667; + l_info.iv_rank_count_dimm_0 = 4; + l_info.iv_rank_count_dimm_1 = 1; + + l_rc = testGetVPD(l_fapiTarget, + l_info, + fapi2::MT, + nullptr, //don't test data, just ability to access + numTests, + numFails); + if(l_rc) + { + TS_FAIL ("testGetVPD MT:: testGetVPD decode failed"); + break; // decode failed (don't double count num tests and fails) + } + + } + while(0); + + FAPI_INF("testGetVPD MT Test Complete, %d/%d fails", + numFails, numTests); +} + +void testGetVPD_Override(void) +{ + int numMRTests = 0; + int numMRFails = 0; + int numMTTests = 0; + int numMTFails = 0; + ReturnCode l_rc; + + FAPI_DBG("testGetVPD Override start"); + + do + { + // get a MCS fapi2 target for MEMVPD_POS 4 + numMTTests++; + TARGETING::ATTR_MEMVPD_POS_type l_memVpdPos = 4; + fapi2::Target<fapi2::TARGET_TYPE_MCS> l_fapiTarget; + TARGETING::Target * l_target; + if(!getTarget(l_memVpdPos,l_target,l_fapiTarget)) + { + TS_FAIL ("testGetVPD_Overrides:: could not find MCS MEMVPD_POS=%d", + l_memVpdPos); + numMTFails++; + break; //Target not found + } + + //Skip test if already overriden + TARGETING::ATTR_VPD_OVERRIDE_MT_ENABLE_type l_mtType = + l_target->getAttr<TARGETING::ATTR_VPD_OVERRIDE_MT_ENABLE>(); + if (0 == l_mtType) + { + //Set the overriden data. + //Use the plat attr svc helper function to set the override + //attributes because the override attributes are not writable. + //The helper avoids the error checks. + uint8_t l_overrideMT[VPD_KEYWORD_SIZE] = {'O','T',0}; + bool l_setWorked = fapi2::platAttrSvc::setTargetingAttrHelper( + l_target, + TARGETING::ATTR_VPD_OVERRIDE_MT, + sizeof(l_overrideMT), + &l_overrideMT); + if (!l_setWorked) + { + TS_FAIL ("testGetVPD_Overrides:: " + "could not set ATTR_VPD_OVERRIDE_MT"); + numMTFails++; + break; //stop on error + } + + //Set override enable + numMTTests++; + l_mtType = 1; + l_setWorked = fapi2::platAttrSvc::setTargetingAttrHelper( + l_target, + TARGETING::ATTR_VPD_OVERRIDE_MT_ENABLE, + sizeof(l_mtType), + &l_mtType); + if (!l_setWorked) + { + TS_FAIL ("testGetVPD_Overrides:: " + "could not set ATTR_VPD_OVERRIDE_MT_ENABLE"); + numMTFails++; + break; //stop on error + } + + // set up VPDInfo, only type should matter + fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS> l_info(fapi2::MT); + + l_rc = testGetVPD(l_fapiTarget, + l_info, + fapi2::MT, + "OT", + numMTTests, + numMTFails); + if(l_rc) + { + TS_FAIL ("testGetVPD_Overrides:: testGetVPD failed"); + break; // failed (don't double count num tests and fails) + } + + // restore to not being overriden + numMTTests++; + l_mtType = 0; + l_setWorked = fapi2::platAttrSvc::setTargetingAttrHelper( + l_target, + TARGETING::ATTR_VPD_OVERRIDE_MT_ENABLE, + sizeof(l_mtType), + &l_mtType); + if (!l_setWorked) + { + TS_FAIL ("testGetVPD_Overrides:: " + "could not set ATTR_VPD_OVERRIDE_MT_ENABLE"); + numMTFails++; + break; //stop on error + } + } + + //Set override enable and data for MR + //Skip test if already overriden + TARGETING::ATTR_VPD_OVERRIDE_MR_ENABLE_type l_mrType = + l_target->getAttr<TARGETING::ATTR_VPD_OVERRIDE_MR_ENABLE>(); + if (0 == l_mrType) + { + //Set the overriden data. + uint8_t l_overrideMR[VPD_KEYWORD_SIZE] = {'O','R',0}; + bool l_setWorked = fapi2::platAttrSvc::setTargetingAttrHelper( + l_target, + TARGETING::ATTR_VPD_OVERRIDE_MR, + sizeof(l_overrideMR), + &l_overrideMR); + if (!l_setWorked) + { + TS_FAIL ("testGetVPD_Overrides:: " + "could not set ATTR_VPD_OVERRIDE_MR"); + numMRFails++; + break; //stop on error + } + + //Set override enable + numMRTests++; + l_mrType = 1; + l_setWorked = fapi2::platAttrSvc::setTargetingAttrHelper( + l_target, + TARGETING::ATTR_VPD_OVERRIDE_MR_ENABLE, + sizeof(l_mrType), + &l_mrType); + if (!l_setWorked) + { + TS_FAIL ("testGetVPD_Overrides:: " + "could not set ATTR_VPD_OVERRIDE_MR_ENABLE"); + numMRFails++; + break; //stop on error + } + + // set up VPDInfo, only type should matter + fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS> l_info(fapi2::MR); + + l_rc = testGetVPD(l_fapiTarget, + l_info, + fapi2::MR, + "OR", + numMRTests, + numMRFails); + if(l_rc) + { + TS_FAIL ("testGetVPD_Overrides:: testGetVPD failed"); + break; // failed (don't double count num tests and fails) + } + + // restore to not being overriden + numMRTests++; + l_mrType = 0; + l_setWorked = fapi2::platAttrSvc::setTargetingAttrHelper( + l_target, + TARGETING::ATTR_VPD_OVERRIDE_MR_ENABLE, + sizeof(l_mrType), + &l_mrType); + if (!l_setWorked) + { + TS_FAIL ("testGetVPD_Overrides:: " + "could not set ATTR_VPD_OVERRIDE_MR_ENABLE"); + numMRFails++; + break; //stop on error + } + } + } + while(0); + + FAPI_INF("testGetVPD Override Test Complete, %d/%d fails", + numMRFails+numMTFails, numMRTests+numMTTests); +} + diff --git a/src/usr/fapi2/test/getVpdTest.H b/src/usr/fapi2/test/getVpdTest.H new file mode 100644 index 000000000..b7b67e672 --- /dev/null +++ b/src/usr/fapi2/test/getVpdTest.H @@ -0,0 +1,79 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/fapi2/test/getVpdTest.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] 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 __GETVPDTEST_H +#define __GETVPDTEST_H + +/** + * @file getVpdTest.H + * @brief getVpd for MCS memory test cases + */ + +#include <stdint.h> + +/** + * @brief MCS getVpd MR tests + * + * Test the getVPD MR 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_MR(void); + +/** + * @brief MCS getVpd MT tests + * + * Test the getVPD MT 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. + */ +void testGetVPD_MT(void); + +/** + * @brief p9_get_mem_vpd_keyword MR decode tests + * + * Test the p9_get_mem_vpd_keyword decode MR interface. Based on a VPDInfo + * configuration, verify the expected keyword is returned. + */ +void testDecode_MR(void); + +/** + * @brief p9_get_mem_vpd_keyword MT decode tests + * + * Test the p9_get_mem_vpd_keyword decode MT interface. Based on a VPDInfo + * configuration, verify the expected keyword is returned. + */ +void testDecode_MT(void); +/** + * @brief MCS getVpd override test + * + * Verify that overriding the direct memory vpd works. + */ +void testGetVPD_Override(void); + +#endif |

