summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr')
-rwxr-xr-xsrc/usr/fapi2/fapi2.mk1
-rw-r--r--src/usr/fapi2/plat_vpd_access.C122
-rw-r--r--src/usr/vpd/makefile3
-rw-r--r--src/usr/vpd/ocmb_spd.C156
-rw-r--r--src/usr/vpd/spd.C6
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 )
{
OpenPOWER on IntegriCloud