diff options
author | Corey Swenson <cswenson@us.ibm.com> | 2017-04-13 13:51:00 -0500 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2017-04-29 23:39:38 -0400 |
commit | 75d116c859dfac3cf279fb99c35a8e18fb44c2db (patch) | |
tree | 584462738718aeea09f39a4087a5de8800517457 /src/usr/fapi2 | |
parent | 65933dc2985b91be71ac35a6df2786f0e43ab779 (diff) | |
download | talos-hostboot-75d116c859dfac3cf279fb99c35a8e18fb44c2db.tar.gz talos-hostboot-75d116c859dfac3cf279fb99c35a8e18fb44c2db.zip |
Add support for selecting WOF tables
Change-Id: I23cfd9b1156d44a0a3277a0c2696d034a741d0ba
RTC:158589
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/38724
Reviewed-by: Martin Gloff <mgloff@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-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')
-rw-r--r-- | src/usr/fapi2/attribute_service.C | 21 | ||||
-rwxr-xr-x | src/usr/fapi2/fapi2.mk | 2 | ||||
-rw-r--r-- | src/usr/fapi2/plat_wof_access.C | 426 | ||||
-rw-r--r-- | src/usr/fapi2/test/fapi2WOFTest.H | 75 |
4 files changed, 521 insertions, 3 deletions
diff --git a/src/usr/fapi2/attribute_service.C b/src/usr/fapi2/attribute_service.C index 2261fed64..43ebb6bcb 100644 --- a/src/usr/fapi2/attribute_service.C +++ b/src/usr/fapi2/attribute_service.C @@ -417,7 +417,7 @@ ReturnCode platGetTargetPos(const Target<TARGET_TYPE_ALL>& i_pFapiTarget, if (l_errl) { - FAPI_ERR("getTargetName: Error from getTargetingTarget"); + FAPI_ERR("platGetTargetPos: Error from getTargetingTarget"); l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl)); } else @@ -459,7 +459,7 @@ ReturnCode platGetPoundVBucketData(const Target<TARGET_TYPE_ALL>& i_fapiTarget, errlHndl_t l_errl = getTargetingTarget(i_fapiTarget, l_pTarget); if (l_errl) { - FAPI_ERR("getTargetingAttr: Error from getTargetingTarget"); + FAPI_ERR("platGetPoundVBucketData: Error from getTargetingTarget"); rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl)); } else @@ -488,7 +488,7 @@ ReturnCode platGetPoundWBucketData(const Target<TARGET_TYPE_ALL>& i_fapiTarget, errlHndl_t l_errl = getTargetingTarget(i_fapiTarget, l_pTarget); if (l_errl) { - FAPI_ERR("getTargetingAttr: Error from getTargetingTarget"); + FAPI_ERR("platGetPoundWBucketData: Error from getTargetingTarget"); rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl)); } else @@ -500,6 +500,21 @@ ReturnCode platGetPoundWBucketData(const Target<TARGET_TYPE_ALL>& i_fapiTarget, return rc; } +ReturnCode platParseWOFTables(uint8_t* o_wofData); + +//****************************************************************************** +// fapi2::platAttrSvc::platGetWOFTableData function +//****************************************************************************** +ReturnCode platGetWOFTableData(const Target<TARGET_TYPE_ALL>& i_fapiTarget, + uint8_t * o_wofTableData) +{ + fapi2::ReturnCode rc; + + // Parse the tables and return a single wof table + rc = platParseWOFTables(o_wofTableData); + + return rc; +} } // End platAttrSvc namespace diff --git a/src/usr/fapi2/fapi2.mk b/src/usr/fapi2/fapi2.mk index 50267aefa..1bbd111bd 100755 --- a/src/usr/fapi2/fapi2.mk +++ b/src/usr/fapi2/fapi2.mk @@ -40,6 +40,7 @@ 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/sbe/ EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/accessors/ +EXTRAINCDIR += ${ROOTPATH}/src/import/chips/p9/procedures/hwp/lib/ include ${ROOTPATH}/src/build/mkrules/verbose.rules.mk define __CLEAN_TARGET @@ -57,6 +58,7 @@ OBJS += plat_hw_access.o OBJS += plat_spd_access.o OBJS += plat_mvpd_access.o OBJS += plat_vpd_access.o +OBJS += plat_wof_access.o #Required include before all the procedure.mk are included diff --git a/src/usr/fapi2/plat_wof_access.C b/src/usr/fapi2/plat_wof_access.C new file mode 100644 index 000000000..c1fd9983c --- /dev/null +++ b/src/usr/fapi2/plat_wof_access.C @@ -0,0 +1,426 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/fapi2/plat_wof_access.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2012,2017 */ +/* [+] 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_wof_access.C + * + * @brief Implements the GetWofTables function + */ + +#include <stdint.h> +#include <fapi2.H> +#include <attribute_service.H> +#include <attributeenums.H> +#include <errl/errludattribute.H> +#include <errl/errlreasoncodes.H> +#include <util/utillidmgr.H> +#include <p9_pstates_common.h> + +namespace fapi2 +{ + +namespace platAttrSvc +{ + +const uint32_t WOF_IMAGE_MAGIC_VALUE = 0x57544948; // WTIH +const uint32_t WOF_TABLES_MAGIC_VALUE = 0x57465448; // WFTH +const uint32_t RES_VERSION_MASK = 0xFF; +const uint32_t WOF_IMAGE_VERSION = 1; +const uint32_t WOF_TABLES_VERSION = 1; + + +/* + WOF Tables In PNOR + --------------------------- + | Image Header | Points to Section Table + |-------------------------| + | Section Table Entry 1 | Section Table + | Section Table Entry 2 | Each entry points to + | ... | a WOF Table + |-------------------------| + | WOF Tables Header 1 | WOF Table + | VRFT 1 | Returned if match + | VRFT 2 | + | ... | + |-------------------------| + | WOF Tables Header 2 | WOF Table + | VRFT 1 | Returned if match + | VRFT 2 | + | ... | + |-------------------------| + | ... | + --------------------------- + + The structs for the Image Header and + Section Table Entry are defined below. + The struct for the WOF Tables Header + is defined in p9_pstates_common.h. +*/ + + +typedef struct __attribute__((__packed__)) wofImageHeader +{ + uint32_t magicNumber; + uint8_t version; + uint8_t entryCount; + uint32_t offset; +} wofImageHeader_t; + + +typedef struct __attribute__((__packed__)) wofSectionTableEntry +{ + uint32_t offset; + uint32_t size; +} wofSectionTableEntry_t; + + +fapi2::ReturnCode platParseWOFTables(uint8_t* o_wofData) +{ + FAPI_DBG("Entering platParseWOFTables ...."); + + errlHndl_t l_errl = nullptr; + fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS;; + + TARGETING::Target * l_sys = nullptr; + TARGETING::Target * l_mProc = nullptr; + TARGETING::targetService().getTopLevelTarget(l_sys); + TARGETING::targetService().masterProcChipTargetHandle( l_mProc ); + + // Get the number of present cores + TARGETING::TargetHandleList pECList; + getChildChiplets(pECList, l_mProc, TARGETING::TYPE_CORE, false); + uint32_t l_numCores = pECList.size(); + + // Get the socket power + uint32_t l_socketPower = 0; + uint8_t l_wofPowerLimit = + l_sys->getAttr<TARGETING::ATTR_WOF_POWER_LIMIT>(); + + if(l_wofPowerLimit == TARGETING::WOF_POWER_LIMIT_TURBO) + { + l_socketPower = + l_sys->getAttr<TARGETING::ATTR_SOCKET_POWER_TURBO>(); + } + else + { + l_socketPower = + l_sys->getAttr<TARGETING::ATTR_SOCKET_POWER_NOMINAL>(); + } + + // Get the frequencies + uint32_t l_nestFreq = + l_sys->getAttr<TARGETING::ATTR_FREQ_PB_MHZ>(); + uint32_t l_nomFreq = + l_sys->getAttr<TARGETING::ATTR_NOMINAL_FREQ_MHZ>(); + + // Trace the input params + FAPI_INF("WOF table search: " + "Cores %d SocketPower 0x%X NestFreq 0x%X NomFreq 0x%X", + l_numCores, l_socketPower, l_nestFreq, l_nomFreq); + + void* l_pWofImage = nullptr; + size_t l_lidImageSize = 0; + + do { + // @todo RTC 172776 Make WOF table parser PNOR accesses more efficient + // Lid number is system dependent + uint32_t l_lidNumber = + l_sys->getAttr<TARGETING::ATTR_WOF_TABLE_LID_NUMBER>(); + UtilLidMgr l_wofLidMgr(l_lidNumber); + + // Get the size of the full wof tables image + l_errl = l_wofLidMgr.getLidSize(l_lidImageSize); + if(l_errl) + { + FAPI_ERR("platParseWOFTables getLidSize failed"); + l_rc.setPlatDataPtr(reinterpret_cast<void *>(l_errl)); + break; + } + + // Allocate space, remember to free it later + l_pWofImage = static_cast<void*>(malloc(l_lidImageSize)); + + // Get the tables from pnor or lid + l_errl = l_wofLidMgr.getLid(l_pWofImage, l_lidImageSize); + if(l_errl) + { + FAPI_ERR("platParseWOFTables getLid failed " + "pLidImage %p imageSize %d", + l_pWofImage, l_lidImageSize); + l_rc.setPlatDataPtr(reinterpret_cast<void *>(l_errl)); + break; + } + + // Get the Image Header + wofImageHeader_t* l_img = + reinterpret_cast<wofImageHeader_t*>(l_pWofImage); + + // Check for the eyecatcher + if(l_img->magicNumber != WOF_IMAGE_MAGIC_VALUE) + { + FAPI_ERR("Image Header Magic Value != WTIH(0x%X)", + WOF_IMAGE_MAGIC_VALUE); + /*@ + * @errortype + * @moduleid fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES + * @reasoncode fapi2::RC_WOF_IMAGE_MAGIC_MISMATCH + * @userdata1[00:31] Image header magic value + * @userdata1[32:63] Expected magic value + * @userdata2[00:31] LID ID + * @userdata2[32:63] Image header version + * @devdesc Image header magic value mismatch + * @custdesc Firmware Error + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES, + fapi2::RC_WOF_IMAGE_MAGIC_MISMATCH, + TWO_UINT32_TO_UINT64( + l_img->magicNumber, + WOF_IMAGE_MAGIC_VALUE), + TWO_UINT32_TO_UINT64( + l_lidNumber, + l_img->version), + true); //software callout + l_rc.setPlatDataPtr(reinterpret_cast<void *>(l_errl)); + break; + } + + // Check for a valid image header version + if(l_img->version > WOF_IMAGE_VERSION) + { + FAPI_ERR("Image header version not supported: " + " Header Version %d Supported Version %d", + l_img->version, WOF_IMAGE_VERSION); + /*@ + * @errortype + * @moduleid fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES + * @reasoncode fapi2::RC_WOF_IMAGE_VERSION_MISMATCH + * @userdata1[00:31] Image header version + * @userdata1[32:63] Supported header version + * @userdata2 LID ID + * @devdesc Image header version not supported + * @custdesc Firmware Error + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES, + fapi2::RC_WOF_IMAGE_VERSION_MISMATCH, + TWO_UINT32_TO_UINT64( + l_img->version, + WOF_IMAGE_VERSION), + l_lidNumber, + true); //software callout + l_rc.setPlatDataPtr(reinterpret_cast<void *>(l_errl)); + break; + } + + // Image info + FAPI_INF("WOF Image: Magic 0x%X Version %d Entries %d Offset %p", + l_img->magicNumber, l_img->version, + l_img->entryCount, l_img->offset); + + // Get a pointer to the first section table entry + wofSectionTableEntry_t* l_ste = + reinterpret_cast<wofSectionTableEntry_t*> + (reinterpret_cast<uint8_t*>(l_pWofImage) + l_img->offset); + + WofTablesHeader_t* l_wth = nullptr; + std::vector<WofTablesHeader_t*> l_headers; + l_headers.clear(); + uint32_t l_ent = 0; + uint32_t l_ver = 0; + + // Loop through all section table entries + for( l_ent = 0; l_ent < l_img->entryCount; l_ent++ ) + { + // Get a pointer to the WOF table + l_wth = reinterpret_cast<WofTablesHeader_t*> + (reinterpret_cast<uint8_t*>(l_pWofImage) + + l_ste[l_ent].offset); + l_ver = l_wth->reserved_version & RES_VERSION_MASK; + + // Check for the eyecatcher + if(l_wth->magic_number != WOF_TABLES_MAGIC_VALUE) + { + FAPI_ERR("WOF Tables Header Magic Number != WFTH(0x%X)", + WOF_TABLES_MAGIC_VALUE); + /*@ + * @errortype + * @moduleid fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES + * @reasoncode fapi2::RC_WOF_TABLES_MAGIC_MISMATCH + * @userdata1[00:31] WOF tables header magic value + * @userdata1[32:63] Expected magic value + * @userdata2[00:31] WOF tables entry number + * @userdata2[32:63] WOF tables header version + * @devdesc WOF tables header magic value mismatch + * @custdesc Firmware Error + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES, + fapi2::RC_WOF_TABLES_MAGIC_MISMATCH, + TWO_UINT32_TO_UINT64( + l_wth->magic_number, + WOF_TABLES_MAGIC_VALUE), + TWO_UINT32_TO_UINT64( + l_ent, + l_ver), + true); //software callout + l_rc.setPlatDataPtr(reinterpret_cast<void *>(l_errl)); + break; + } + + // Check for a valid tables header version + if(l_ver > WOF_TABLES_VERSION) + { + FAPI_ERR("WOF tables header version not supported: " + " Header Version %d Supported Version %d", + l_ver, WOF_TABLES_VERSION); + /*@ + * @errortype + * @moduleid fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES + * @reasoncode fapi2::RC_WOF_TABLES_VERSION_MISMATCH + * @userdata1[00:31] WOF tables header version + * @userdata1[32:63] Supported header version + * @userdata2 WOF tables entry number + * @devdesc WOF tables header version not supported + * @custdesc Firmware Error + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES, + fapi2::RC_WOF_TABLES_VERSION_MISMATCH, + TWO_UINT32_TO_UINT64( + l_ver, + WOF_TABLES_VERSION), + l_ent, + true); //software callout + l_rc.setPlatDataPtr(reinterpret_cast<void *>(l_errl)); + break; + } + + // Trace the WOF table fields + FAPI_INF("WOF table fields " + "SectionTableEntry %d " + "SectionTableOffset 0x%X " + "SectionTableSize %d " + "Version %d Cores %d SocketPower 0x%X " + "NestFreq 0x%X NomFreq 0x%X", + l_ent, l_ste[l_ent].offset, l_ste[l_ent].size, + l_ver, l_wth->core_count, l_wth->socket_power_w, + l_wth->nest_frequency_mhz, l_wth->sort_power_freq_mhz); + + // Compare the fields + if( (l_wth->core_count == l_numCores) && + (l_wth->socket_power_w == l_socketPower) && + (l_wth->nest_frequency_mhz == l_nestFreq) && + (l_wth->sort_power_freq_mhz == l_nomFreq) ) + { + // Found a match + FAPI_INF("Found a WOF table match"); + + // Copy the WOF table to the ouput pointer + memcpy(o_wofData, + reinterpret_cast<uint8_t*>(l_wth), + l_ste[l_ent].size); + + break; + } + else + { + // Save the header for later + l_headers.push_back(l_wth); + } + } + + if(l_errl) + { + break; + } + + //Check for no match + if(l_ent == l_img->entryCount) + { + FAPI_ERR("No WOF table match found"); + /*@ + * @errortype + * @moduleid fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES + * @reasoncode fapi2::RC_WOF_TABLE_NOT_FOUND + * @userdata1[00:31] Number of cores + * @userdata1[32:63] Socket power + * @userdata2[00:31] Nest frequency + * @userdata2[32:63] Nominal frequency + * @devdesc No WOF table match found + * @custdesc Firmware Error + */ + l_errl = new ERRORLOG::ErrlEntry( + ERRORLOG::ERRL_SEV_UNRECOVERABLE, + fapi2::MOD_FAPI2_PLAT_PARSE_WOF_TABLES, + fapi2::RC_WOF_TABLE_NOT_FOUND, + TWO_UINT32_TO_UINT64( + l_numCores, + l_socketPower), + TWO_UINT32_TO_UINT64( + l_nestFreq, + l_nomFreq), + true); //software callout + l_errl->collectTrace(FAPI_TRACE_NAME); + + // Add data + ERRORLOG::ErrlUserDetailsAttribute( + l_sys, + TARGETING::ATTR_WOF_TABLE_LID_NUMBER) + .addToLog(l_errl); + while(l_headers.size()) + { + l_errl->addFFDC( + HWPF_COMP_ID, + l_headers.back(), + sizeof(WofTablesHeader_t), + 0, // version + ERRORLOG::ERRL_UDT_NOFORMAT, // parser ignores data + false ); // merge + l_headers.pop_back(); + } + + l_rc.setPlatDataPtr(reinterpret_cast<void *>(l_errl)); + break; + } + + } while(0); + + // Free the wof tables memory + if(l_pWofImage != nullptr) + { + free(l_pWofImage); + } + + FAPI_DBG("Exiting platParseWOFTables ...."); + + return l_rc; +} + +} // End platAttrSvc namespace +} // End fapi2 namespace diff --git a/src/usr/fapi2/test/fapi2WOFTest.H b/src/usr/fapi2/test/fapi2WOFTest.H new file mode 100644 index 000000000..e0b7745d8 --- /dev/null +++ b/src/usr/fapi2/test/fapi2WOFTest.H @@ -0,0 +1,75 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/fapi2/test/fapi2WOFTest.H $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016,2017 */ +/* [+] 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 __WOFTEST_H__ +#define __WOFTEST_H__ + +/** + * @file fapi2WOFTest.H + * + * @brief Test case for WOF access code + */ + +#include <stdio.h> +#include <cxxtest/TestSuite.H> +#include <errl/errlmanager.H> +#include <errl/errlentry.H> +#include <fapi2.H> +#include <devicefw/userif.H> +#include <utilFilter.H> + +using namespace TARGETING; + +class WOFTest: public CxxTest::TestSuite +{ +public: + + /** + * @brief Test WOF table access attribute + * + */ + void testWOFTableAccess (void) + { + //fapi2::ReturnCode l_rc; + fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> l_sysParent; + + FAPI_INF("testWOFTableAccess: ENTER"); + + // TODO RTC 172778 Enable WOF test and check for correct table data + /* + //Set up a char array to hold the data from an attr read + fapi2::ATTR_WOF_TABLE_DATA_Type l_wofAttrData; + + //Perform an ATTR_GET on sys target + FAPI_ATTR_GET(fapi2::ATTR_WOF_TABLE_DATA, + l_sysParent, + l_wofAttrData); + */ + FAPI_INF("testWOFTableAccess: EXIT !!"); + + } // testWOFTableAccess + +}; + +#endif |