diff options
Diffstat (limited to 'src/usr')
| -rwxr-xr-x | src/usr/fapi2/fapi2.mk | 1 | ||||
| -rw-r--r-- | src/usr/fapi2/plat_vpd_access.C | 122 | ||||
| -rw-r--r-- | src/usr/vpd/makefile | 3 | ||||
| -rw-r--r-- | src/usr/vpd/ocmb_spd.C | 156 | ||||
| -rw-r--r-- | src/usr/vpd/spd.C | 6 |
5 files changed, 276 insertions, 12 deletions
diff --git a/src/usr/fapi2/fapi2.mk b/src/usr/fapi2/fapi2.mk index f792bd3c7..c69d77c92 100755 --- a/src/usr/fapi2/fapi2.mk +++ b/src/usr/fapi2/fapi2.mk @@ -88,6 +88,7 @@ OBJS += plat_mmio_access.o include ${ROOTPATH}/procedure.rules.mk include ${HWP_PATH_1}/hwp/accessors/p9_get_mem_vpd_keyword.mk +include ${HWP_PATH_1}/hwp/accessors/ddimm_get_efd.mk #EKB Objects (mirrored in src/import) OBJS += error_info.o diff --git a/src/usr/fapi2/plat_vpd_access.C b/src/usr/fapi2/plat_vpd_access.C index f5a6c92e2..147d7e937 100644 --- a/src/usr/fapi2/plat_vpd_access.C +++ b/src/usr/fapi2/plat_vpd_access.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2012,2018 */ +/* Contributors Listed Below - COPYRIGHT 2012,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -33,9 +33,11 @@ #include <vpd_access_defs.H> #include <vpd_access.H> #include <p9_get_mem_vpd_keyword.H> +#include <ddimm_get_efd.H> #include <attribute_service.H> #include <vpd/dvpdenums.H> #include <errl/errlmanager.H> +#include <fapi2_spd_access.H> //The following can be uncommented for unit testing //#undef FAPI_DBG //#define FAPI_DBG(args...) FAPI_INF(args) @@ -79,7 +81,7 @@ fapi2::ReturnCode platGetVPD( VPD_KEYWORD_SIZE); /*@ * @errortype - * @moduleid fapi2::MOD_FAPI2_PLAT_GET_VPD + * @moduleid fapi2::MOD_FAPI2_PLAT_GET_VPD_MCS * @reasoncode fapi2::RC_BUFFER_TOO_SMALL * @userdata1 Buffer size * @userdata2 Expected size @@ -88,7 +90,7 @@ fapi2::ReturnCode platGetVPD( */ l_errl = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, - fapi2::MOD_FAPI2_PLAT_GET_VPD, + fapi2::MOD_FAPI2_PLAT_GET_VPD_MCS, fapi2::RC_BUFFER_TOO_SMALL, io_vpd_info.iv_size, VPD_KEYWORD_SIZE, @@ -184,7 +186,7 @@ fapi2::ReturnCode platGetVPD( io_vpd_info.iv_vpd_type); /*@ * @errortype - * @moduleid fapi2::MOD_FAPI2_PLAT_GET_VPD + * @moduleid fapi2::MOD_FAPI2_PLAT_GET_VPD_MCS * @reasoncode fapi2::RC_INVALID_TYPE * @userdata1 Vpd type * @userdata2 HUID of MCS target @@ -193,8 +195,8 @@ fapi2::ReturnCode platGetVPD( */ l_errl = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, - fapi2::MOD_FAPI2_PLAT_GET_VPD, - fapi2::RC_BUFFER_TOO_SMALL, + fapi2::MOD_FAPI2_PLAT_GET_VPD_MCS, + fapi2::RC_INVALID_TYPE, io_vpd_info.iv_vpd_type, TARGETING::get_huid(l_pMcsTarget), true); //software callout @@ -298,7 +300,7 @@ fapi2::ReturnCode platGetVPD( io_vpd_info.iv_size); /*@ * @errortype - * @moduleid fapi2::MOD_FAPI2_PLAT_GET_VPD + * @moduleid fapi2::MOD_FAPI2_PLAT_GET_VPD_MCS * @reasoncode fapi2::RC_RETURNED_VPD_TOO_SMALL * @userdata1[0:31] Returned vpd in bytes * @userdata1[32:64] Expected number of vpd bytes @@ -308,7 +310,7 @@ fapi2::ReturnCode platGetVPD( */ l_errl = new ERRORLOG::ErrlEntry( ERRORLOG::ERRL_SEV_UNRECOVERABLE, - fapi2::MOD_FAPI2_PLAT_GET_VPD, + fapi2::MOD_FAPI2_PLAT_GET_VPD_MCS, fapi2::RC_RETURNED_VPD_TOO_SMALL, TWO_UINT32_TO_UINT64( l_buffSize, @@ -334,4 +336,108 @@ fapi2::ReturnCode platGetVPD( return l_rc; } +fapi2::ReturnCode platGetVPD( + const fapi2::Target<fapi2::TARGET_TYPE_OCMB_CHIP>& i_ocmbFapi2Target, + VPDInfo<fapi2::TARGET_TYPE_OCMB_CHIP>& io_vpdInfo, + uint8_t* const o_blob) +{ + FAPI_DBG("platGetVPD(OCMB): enter"); + + fapi2::ReturnCode l_rc{fapi2::FAPI2_RC_SUCCESS}; + + errlHndl_t l_errl = nullptr; + + // Set up buffer we will read first 2KB of OCMB's eeprom to + // 1st KB is SPD info, 2nd KB is EFD info. Both are needed. + size_t l_spdBufferSize = SPD::OCMB_SPD_EFD_COMBINED_SIZE; + uint8_t* l_spdBuffer = nullptr; + + do + { + // Get targeting OCMB target + TARGETING::Target * l_ocmbTarget = nullptr; + l_errl = fapi2::platAttrSvc::getTargetingTarget(i_ocmbFapi2Target, + l_ocmbTarget); + if (l_errl) + { + FAPI_ERR("platGetVPD(OCMB): Error from getTargetingTarget"); + break; //return with error + } + + // Retrieve the EFD data or the EFD data size if o_blob is NULL + if (fapi2::EFD == io_vpdInfo.iv_vpd_type) + { + // Allocate buffer to hold SPD and init to 0 + l_spdBuffer = new uint8_t[l_spdBufferSize]; + memset(l_spdBuffer, 0, l_spdBufferSize); + + // Get the SPD buffer, where the EFD data is to be extracted from + // "ENTIRE_SPD" for OCMB target is first 2 KB of EEPROM + l_errl = deviceRead(l_ocmbTarget, + l_spdBuffer, + l_spdBufferSize, + DEVICE_SPD_ADDRESS(SPD::ENTIRE_SPD)); + + // If unable to retrieve the SPD buffer then can't + // extract the EFD data, so return error. + if (l_errl) + { + FAPI_ERR("platGetVPD(OCMB): Error from trying to read ENTIRE SPD from 0x%.08X ", + TARGETING::get_huid(l_ocmbTarget)); + break; + } + + // Retrieve the EFD data from the given SPD buffer. + // if o_blob is nullptr then size will be returned in io_vpdInfo.iv_size + FAPI_EXEC_HWP( l_rc, + ddimm_get_efd, + i_ocmbFapi2Target, + io_vpdInfo, + o_blob, + l_spdBuffer, + l_spdBufferSize ); + if (l_rc) + { + FAPI_ERR("platGetVPD(OCMB): Error returned from ddimm_get_efd called on target 0x%.08X", + TARGETING::get_huid(l_ocmbTarget)); + } + } // end if (fapi2::EFD == io_vpdInfo.iv_vpd_type) + else + { + /*@ + * @errortype + * @moduleid fapi2::MOD_FAPI2_PLAT_GET_VPD_OCMB + * @reasoncode fapi2::RC_INVALID_TYPE + * @userdata1 vpd_type attempted + * @userdata2 HUID of OCMB target + * @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_OCMB, + fapi2::RC_INVALID_TYPE, + io_vpdInfo.iv_vpd_type, + TARGETING::get_huid(l_ocmbTarget), + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); + } + } while (0); + + // Caller is not interested in the SPD buffer, so delete it. + if (l_spdBuffer) + { + delete []l_spdBuffer; + l_spdBuffer = nullptr; + } + + if ( l_errl ) + { + l_rc.setPlatDataPtr(reinterpret_cast<void *> (l_errl)); + } + + FAPI_DBG("platGetVPD(OCMB): exit"); + + return l_rc; +} + } // namespace diff --git a/src/usr/vpd/makefile b/src/usr/vpd/makefile index f038bb5a2..ad231ee9f 100644 --- a/src/usr/vpd/makefile +++ b/src/usr/vpd/makefile @@ -5,7 +5,7 @@ # # OpenPOWER HostBoot Project # -# Contributors Listed Below - COPYRIGHT 2013,2018 +# Contributors Listed Below - COPYRIGHT 2013,2019 # [+] International Business Machines Corp. # # @@ -31,6 +31,7 @@ include vpd.mk #include unique objects OBJS += vpd.o OBJS += dimmPres.o +OBJS += ocmb_spd.o OBJS += rtvpd_load.o SUBDIRS += test.d diff --git a/src/usr/vpd/ocmb_spd.C b/src/usr/vpd/ocmb_spd.C new file mode 100644 index 000000000..c4f8137cc --- /dev/null +++ b/src/usr/vpd/ocmb_spd.C @@ -0,0 +1,156 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/vpd/ocmb_spd.C $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 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 <vpd/spdenums.H> +#include <devicefw/driverif.H> +#include <i2c/eeprom_const.H> +#include <errl/errlentry.H> +#include <vpd/vpdreasoncodes.H> + +extern trace_desc_t * g_trac_spd; + +namespace SPD +{ + +/** + * @brief Handle SPD READ deviceOp to OCMB_CHIP targets + * This function performs read operations on OCMBs by in turn performing + * an EEPROM deviceOp on this target, reading the first 2 KB of the OCMB's + * Primary VPD eeprom and returning it via a buffer + * + * @param[in] i_opType Operation type, see driverif.H + * @param[in] i_target MMIO target + * @param[in/out] io_buffer Read: Pointer to output data storage + * Write: Pointer to input data storage + * @param[in/out] io_buflen Input: Read: size of data to read (in bytes) + * Output: Read: Size of output data + * @param[in] i_accessType Access type + * @param[in] i_args This is an argument list for DD framework. + * In this function, there is one argument, + * the l_keyword, so far we only support ENTIRE_SPD + * @return errlHndl_t + * + * NOTE: ONLY ENTIRE_SPD READ SUPPORTED CURRENTLY + */ +errlHndl_t ocmbSPDPerformOp(DeviceFW::OperationType i_opType, + TARGETING::Target* i_target, + void* io_buffer, + size_t& io_buflen, + int64_t i_accessType, + va_list i_args); + +// Register the perform Op with the routing code for OCMBs. +DEVICE_REGISTER_ROUTE( DeviceFW::READ, + DeviceFW::SPD, + TARGETING::TYPE_OCMB_CHIP, + ocmbSPDPerformOp ); + +/** + * @brief Read keyword from SPD + * + * Currently used to detect I2C_MUTEX and OCMB_CHIP targets + * + * @param[in] i_target OCMB target to read data from + * @param[in] i_keyword keyword from spdenums.H to read + * @param[in/out] io_buffer databuffer SPD will be written to + * @param[in] i_buflen length of the given data buffer + * + * @pre io_buffer and i_target must be non-null + * @pre currenlty only supported value for i_keyword is ENTIRE_SPD + * + * @return errlHndl_t + */ +errlHndl_t ocmbGetSPD(const TARGETING::Target* i_target, + const uint64_t & i_keyword, + void* const io_buffer, + const size_t& i_buflen) +{ + errlHndl_t l_errl = nullptr; + + TRACFCOMP( g_trac_spd, + ENTER_MRK"ocmbGetSPD()" ); + + // If any of these asserts fail it is a SW error + assert(io_buffer != nullptr, "io_buffer is nullptr in ocmbGetSPD"); + assert(i_target != nullptr, "i_target is nullptr in ocmbGetSPD"); + assert(i_buflen >= SPD::OCMB_SPD_EFD_COMBINED_SIZE, "Buffer must be at least 2 KB in ocmbGetSPD"); + + do { + + if(i_keyword != ENTIRE_SPD) + { + TRACFCOMP( g_trac_spd, + "ocmbGetSPD() only entire SPD currently supported, 0x%X is not supported", + i_keyword); + /*@ + * @errortype + * @moduleid VPD::VPD_OCMB_GET_SPD + * @reasoncode VPD::VPD_NOT_SUPPORTED + * @userdata1 Keyword Enum + * @userdata2 Target huid + * @devdesc Attempted to lookup SPD keyword not supported + * @custdesc Firmware error during system IPL + */ + l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + VPD::VPD_OCMB_GET_SPD, + VPD::VPD_NOT_SUPPORTED, + i_keyword, + i_target->getAttr<TARGETING::ATTR_HUID>(), + ERRORLOG::ErrlEntry::ADD_SW_CALLOUT); + break; + + } + size_t l_spdReadBufferLen = SPD::OCMB_SPD_EFD_COMBINED_SIZE; + + l_errl = DeviceFW::deviceOp(DeviceFW::READ, + const_cast<TARGETING::Target*>(i_target), + io_buffer, + l_spdReadBufferLen, + DEVICE_EEPROM_ADDRESS(EEPROM::VPD_PRIMARY, + 0, + EEPROM::AUTOSELECT) + ); + + + }while(0); + + return l_errl; +} + +// See above for details +errlHndl_t ocmbSPDPerformOp(DeviceFW::OperationType i_opType, + TARGETING::Target* i_target, + void* io_buffer, + size_t& io_buflen, + int64_t i_accessType, + va_list i_args) +{ + errlHndl_t l_errl = nullptr; + const uint64_t l_keyword = va_arg(i_args, uint64_t); + l_errl = ocmbGetSPD(i_target, l_keyword, io_buffer, io_buflen); + return l_errl; +} + + +} diff --git a/src/usr/vpd/spd.C b/src/usr/vpd/spd.C index b57297df0..a6b687ad0 100644 --- a/src/usr/vpd/spd.C +++ b/src/usr/vpd/spd.C @@ -2202,7 +2202,7 @@ void setPartAndSerialNumberAttributes( TARGETING::Target * i_target ) uint8_t l_memType(MEM_TYPE_INVALID); l_err = getMemType( l_memType, i_target, - VPD::PNOR ); + VPD::AUTOSELECT ); if( l_err ) { TRACDCOMP(g_trac_spd, ERR_MRK"spd.C::setPartAndSerialNumberAttributes(): Error after getMemType"); @@ -2249,7 +2249,7 @@ void setPartAndSerialNumberAttributes( TARGETING::Target * i_target ) l_partDataSize, i_target, l_memType, - VPD::PNOR ); + VPD::AUTOSELECT ); if( l_err ) { @@ -2265,7 +2265,7 @@ void setPartAndSerialNumberAttributes( TARGETING::Target * i_target ) l_serialDataSize, i_target, l_memType, - VPD::PNOR ); + VPD::AUTOSELECT ); if( l_err ) { |

