summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/usr/devicefw/userif.H23
-rw-r--r--src/include/usr/vpd/cvpdenums.H1
-rw-r--r--src/include/usr/vpd/pvpdenums.H96
-rw-r--r--src/include/usr/vpd/vpd_if.H8
-rw-r--r--src/include/usr/vpd/vpdreasoncodes.H4
-rw-r--r--src/usr/devtree/bld_devtree.C85
-rw-r--r--src/usr/hwas/hwasPlat.C6
-rw-r--r--src/usr/hwas/hwasPlatCallout.C6
-rwxr-xr-xsrc/usr/i2c/eepromdd.C5
-rw-r--r--src/usr/ipmi/ipmifruinv.C502
-rw-r--r--src/usr/ipmi/ipmifruinvprvt.H112
-rw-r--r--src/usr/targeting/common/xmltohb/target_types.xml2
-rw-r--r--src/usr/targeting/common/xmltohb/target_types_hb.xml5
-rw-r--r--src/usr/vpd/HBconfig27
-rw-r--r--src/usr/vpd/cvpd.C36
-rw-r--r--src/usr/vpd/cvpd.H22
-rw-r--r--src/usr/vpd/ipvpd.C50
-rw-r--r--src/usr/vpd/ipvpd.H22
-rw-r--r--src/usr/vpd/pvpd.C369
-rw-r--r--src/usr/vpd/pvpd.H149
-rwxr-xr-xsrc/usr/vpd/vpd.C17
-rw-r--r--src/usr/vpd/vpd.H1
-rw-r--r--src/usr/vpd/vpd.mk5
23 files changed, 1307 insertions, 246 deletions
diff --git a/src/include/usr/devicefw/userif.H b/src/include/usr/devicefw/userif.H
index 6d041f2ee..eac5366aa 100644
--- a/src/include/usr/devicefw/userif.H
+++ b/src/include/usr/devicefw/userif.H
@@ -61,6 +61,7 @@ namespace DeviceFW
GPIO,
LPC,
IPMIBT, // As opposed to other phy's
+ PVPD,
LAST_ACCESS_TYPE,
};
@@ -166,6 +167,28 @@ namespace DeviceFW
static_cast<uint64_t>(( i_location ))
/**
+ * Construct the device addressing parameters for the PVPD device ops.
+ * @param[in] i_record - The enumeration of the PVPD record to access.
+ * @param[in] i_keyword - The enumeration of the PVPD keyword, located
+ * within the i_record Record to access.
+ */
+ #define DEVICE_PVPD_ADDRESS( i_record, i_keyword )\
+ DEVICE_PVPD_FORCE_ADDRESS( i_record, i_keyword, VPD::AUTOSELECT )
+
+ /**
+ * Construct the device addressing parameters for the PVPD device ops.
+ * @param[in] i_record - The enumeration of the PVPD record to access.
+ * @param[in] i_keyword - The enumeration of the PVPD keyword, located
+ * within the i_record Record to access.
+ * @param[in] i_location - The location of the data (PNOR/SEEPROM)
+ see vpd_if.H
+ */
+ #define DEVICE_PVPD_FORCE_ADDRESS( i_record, i_keyword, i_location )\
+ DeviceFW::PVPD, static_cast<uint64_t>(( i_record )),\
+ static_cast<uint64_t>(( i_keyword )),\
+ static_cast<uint64_t>(( i_location ))
+
+ /**
* Construct the device addressing parameters for the SCAN device ops.
* @param[in] i_ring - The ring address to scan
* @param[in] i_ringlen - The length of the ring to scan in bits
diff --git a/src/include/usr/vpd/cvpdenums.H b/src/include/usr/vpd/cvpdenums.H
index 4b5adb271..79b81093c 100644
--- a/src/include/usr/vpd/cvpdenums.H
+++ b/src/include/usr/vpd/cvpdenums.H
@@ -45,7 +45,6 @@ namespace CVPD
OPFR = 0x05,
VNDR = 0x06,
SPDX = 0x07,
- OSYS = 0x08,
// Last Record
CVPD_LAST_RECORD,
CVPD_TEST_RECORD, // Test purposes ONLY!
diff --git a/src/include/usr/vpd/pvpdenums.H b/src/include/usr/vpd/pvpdenums.H
new file mode 100644
index 000000000..acf3bbd22
--- /dev/null
+++ b/src/include/usr/vpd/pvpdenums.H
@@ -0,0 +1,96 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/include/usr/vpd/pvpdenums.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2013,2015 */
+/* [+] 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 __PVPDENUMS_H
+#define __PVPDENUMS_H
+
+#include <vpd/ipvpdenums.H>
+
+namespace PVPD
+{
+
+ /**
+ * @brief Enumeration for the PVPD Records that contain
+ * the keyword enumerations below.
+ *
+ */
+ enum pvpdRecord
+ {
+ PVPD_FIRST_RECORD = 0x00,
+ VINI = PVPD_FIRST_RECORD,
+ OSYS = 0x01,
+ OPFR = 0x02,
+ VNDR = 0x03,
+ // Last Record
+ PVPD_LAST_RECORD,
+ PVPD_TEST_RECORD, // Test purposes ONLY!
+
+ //Start common IPVPD enums
+ PVPD_INVALID_RECORD = IPVPD::INVALID_RECORD,
+ };
+
+ /**
+ * @brief Enumerations for PVPD keywords that can be
+ * accessed in the PVPD.
+ */
+ enum pvpdKeyword
+ {
+ PVPD_FIRST_KEYWORD = 0x00,
+ pdI = PVPD_FIRST_KEYWORD,
+ B3 = 0x01,
+ B4 = 0x02,
+ B7 = 0x03,
+ CC = 0x04,
+ CE = 0x05,
+ CT = 0x06,
+ DR = 0x07,
+ ET = 0x08,
+ FN = 0x09,
+ HE = 0x0a,
+ HW = 0x0b,
+ IN = 0x0c,
+ MM = 0x0d,
+ PF = 0x0e,
+ PN = 0x0f,
+ RT = 0x10,
+ SN = 0x11,
+ SS = 0x12,
+ VD = 0x13,
+ VN = 0x14,
+ VP = 0x15,
+ VS = 0x16,
+ VZ = 0x17,
+
+ // Last Keyword
+ PVPD_LAST_KEYWORD,
+ PVPD_TEST_KEYWORD, // Test purposes ONLY!
+
+ //Start common IPVPD enums
+ FULL_RECORD = IPVPD::FULL_RECORD,
+ PVPD_INVALID_KEYWORD = IPVPD::INVALID_KEYWORD,
+ };
+
+}; // end PVPD
+
+#endif
diff --git a/src/include/usr/vpd/vpd_if.H b/src/include/usr/vpd/vpd_if.H
index 0b3298a80..d3915ee6a 100644
--- a/src/include/usr/vpd/vpd_if.H
+++ b/src/include/usr/vpd/vpd_if.H
@@ -71,6 +71,14 @@ namespace VPD
bool cvpdPresent ( TARGETING::Target * i_target );
/**
+ * @brief This function checks to see if the given pvpd target
+ * is present
+ * @param[in] i_target - Target device to search for pvpd
+ * @return bool - true if pvpd is present, false if it is not.
+ */
+ bool pvpdPresent ( TARGETING::Target * i_target );
+
+ /**
* @brief This function checks if the PNOR cache for this target is in
* sync with the SEEPROM, if not it loads the PNOR cache from SEEPROM.
* @param[in] i_target - Target device
diff --git a/src/include/usr/vpd/vpdreasoncodes.H b/src/include/usr/vpd/vpdreasoncodes.H
index 88668b70c..2cfe8a68a 100644
--- a/src/include/usr/vpd/vpdreasoncodes.H
+++ b/src/include/usr/vpd/vpdreasoncodes.H
@@ -61,6 +61,9 @@ enum vpdModuleId
VPD_IPVPD_LOAD_PNOR = 0x33,
VPD_IPVPD_GET_RECORD_LIST_SEEPROM = 0x34,
+ // PVPD
+ VPD_PVPD_PRESENCEDETECT = 0x50,
+
// DIMM SPD
VPD_SPD_GET_KEYWORD_VALUE = 0x61,
VPD_SPD_GET_VALUE = 0x62,
@@ -131,6 +134,7 @@ enum vpdReasonCode
VPD_UNEXPECTED_TARGET_TYPE = VPD_COMP_ID | 0x33,
VPD_WRITE_DEST_UNRESOLVED = VPD_COMP_ID | 0x34,
VPD_CACHE_SIZE_EXCEEDED = VPD_COMP_ID | 0x35,
+ VPD_INVALID_LENGTH = VPD_COMP_ID | 0x36,
};
diff --git a/src/usr/devtree/bld_devtree.C b/src/usr/devtree/bld_devtree.C
index a8ece978a..a311efe04 100644
--- a/src/usr/devtree/bld_devtree.C
+++ b/src/usr/devtree/bld_devtree.C
@@ -45,7 +45,7 @@
#include <fsi/fsiif.H>
#include <config.h>
#include <devicefw/userif.H>
-#include <vpd/cvpdenums.H>
+#include <vpd/pvpdenums.H>
#include <i2c/i2cif.H>
#include <i2c/eepromif.H>
#include <ipmi/ipmisensor.H>
@@ -351,12 +351,9 @@ void add_i2c_info( const TARGETING::Target* i_targ,
}
else if( l_type == TARGETING::TYPE_MEMBUF )
{
- //@fixme-RTC:118373-Remove Hab/Palm workaround
- // once node vpd is supported
- sprintf( l_label, "system-vpd" );
- /*sprintf( l_label, "memb-vpd-%d",
+ sprintf( l_label, "memb-vpd-%d",
eep2->assocTarg
- ->getAttr<TARGETING::ATTR_POSITION>() );*/
+ ->getAttr<TARGETING::ATTR_POSITION>() );
}
else if( l_type == TARGETING::TYPE_DIMM )
{
@@ -1054,39 +1051,46 @@ errlHndl_t bld_fdt_system(devTree * i_dt, bool i_smallTree)
3) Default to 'unknown'
*/
bool foundvpd = false;
- // TODO RTC 118373 -- update to account for firestone/memory riser
- TARGETING::TargetHandleList l_membTargetList;
- getAllChips(l_membTargetList, TYPE_MEMBUF);
-
- //if can't find a centaur for the CVPD, default to unknown
- if (l_membTargetList.size())
+ TARGETING::TargetHandleList l_nodeTargetList;
+ PredicateCTM predNode(CLASS_ENC, TYPE_NODE);
+ PredicateHwas predFunctional;
+ predFunctional.functional(true);
+ PredicatePostfixExpr nodeCheckExpr;
+ nodeCheckExpr.push(&predNode).push(&predFunctional).And();
+
+ targetService().getAssociated(l_nodeTargetList, sys,
+ TargetService::CHILD, TargetService::IMMEDIATE,
+ &nodeCheckExpr);
+
+ //if can't find a node for the PVPD, default to unknown
+ if (l_nodeTargetList.size())
{
- TARGETING::Target * l_pMem = l_membTargetList[0];
+ TARGETING::Target * l_pNode = l_nodeTargetList[0];
size_t vpdSize = 0x0;
// Note: First read with NULL for o_buffer sets vpdSize to the
// correct length
- errhdl = deviceRead( l_pMem,
+ errhdl = deviceRead( l_pNode,
NULL,
vpdSize,
- DEVICE_CVPD_ADDRESS( CVPD::OSYS,
- CVPD::MM ));
+ DEVICE_PVPD_ADDRESS( PVPD::OSYS,
+ PVPD::MM ));
if(errhdl)
{
TRACFCOMP(g_trac_devtree,ERR_MRK" Couldn't get OSYS:MM size for HUID=0x%.8X",
- TARGETING::get_huid(l_pMem));
+ TARGETING::get_huid(l_pNode));
// Try the OPFR record
- errlHndl_t opfr_errhdl = deviceRead( l_pMem,
+ errlHndl_t opfr_errhdl = deviceRead( l_pNode,
NULL,
vpdSize,
- DEVICE_CVPD_ADDRESS( CVPD::OPFR,
- CVPD::DR ));
+ DEVICE_PVPD_ADDRESS( PVPD::OPFR,
+ PVPD::DR ));
if(opfr_errhdl)
{
TRACFCOMP(g_trac_devtree,ERR_MRK" Couldn't get OPFR:DR size for HUID=0x%.8X",
- TARGETING::get_huid(l_pMem));
+ TARGETING::get_huid(l_pNode));
delete opfr_errhdl; //delete OPFR log, VPD is just bad
}
else
@@ -1095,16 +1099,16 @@ errlHndl_t bld_fdt_system(devTree * i_dt, bool i_smallTree)
errhdl = NULL;
char drBuf[vpdSize+1];
memset(&drBuf, 0x0, (vpdSize+1)); //null terminated str
- errhdl = deviceRead( l_pMem,
+ errhdl = deviceRead( l_pNode,
reinterpret_cast<void*>( &drBuf ),
vpdSize,
- DEVICE_CVPD_ADDRESS( CVPD::OPFR,
- CVPD::DR ));
+ DEVICE_PVPD_ADDRESS( PVPD::OPFR,
+ PVPD::DR ));
if(errhdl)
{
TRACFCOMP(g_trac_devtree,ERR_MRK" Couldn't read OPFR:DR for HUID=0x%.8X",
- TARGETING::get_huid(l_pMem));
+ TARGETING::get_huid(l_pNode));
}
else
{
@@ -1117,16 +1121,16 @@ errlHndl_t bld_fdt_system(devTree * i_dt, bool i_smallTree)
{
char mmBuf[vpdSize+1];
memset(&mmBuf, 0x0, (vpdSize+1)); //ensure null terminated str
- errhdl = deviceRead( l_pMem,
+ errhdl = deviceRead( l_pNode,
reinterpret_cast<void*>( &mmBuf ),
vpdSize,
- DEVICE_CVPD_ADDRESS( CVPD::OSYS,
- CVPD::MM ));
+ DEVICE_PVPD_ADDRESS( PVPD::OSYS,
+ PVPD::MM ));
if(errhdl)
{
TRACFCOMP(g_trac_devtree,ERR_MRK" Couldn't read OSYS:MM for HUID=0x%.8X",
- TARGETING::get_huid(l_pMem));
+ TARGETING::get_huid(l_pNode));
}
else
{
@@ -1153,42 +1157,40 @@ errlHndl_t bld_fdt_system(devTree * i_dt, bool i_smallTree)
1) OSYS:SS
2) Default to 'unavailable'
*/
- // TODO RTC 118373 -- update to account for firestone/memory riser
foundvpd = false;
- if( l_membTargetList.size() )
+ if( l_nodeTargetList.size() )
{
- // TODO RTC 118373 - Should be able to read from attribute
- TARGETING::Target * l_pMem = l_membTargetList[0];
+ TARGETING::Target * l_pNode = l_nodeTargetList[0];
size_t vpdSize = 0x0;
// Note: First read with NULL for o_buffer sets vpdSize to the
// correct length
- errhdl = deviceRead( l_pMem,
+ errhdl = deviceRead( l_pNode,
NULL,
vpdSize,
- DEVICE_CVPD_ADDRESS( CVPD::OSYS,
- CVPD::SS ));
+ DEVICE_PVPD_ADDRESS( PVPD::OSYS,
+ PVPD::SS ));
if(errhdl)
{
TRACFCOMP(g_trac_devtree,ERR_MRK" Couldn't get OSYS:SS size for HUID=0x%.8X",
- TARGETING::get_huid(l_pMem));
+ TARGETING::get_huid(l_pNode));
// Note - not supporting old vpd versions without OSYS here
}
else
{
char ssBuf[vpdSize+1];
memset(&ssBuf, 0x0, (vpdSize+1)); //ensure null terminated str
- errhdl = deviceRead( l_pMem,
+ errhdl = deviceRead( l_pNode,
reinterpret_cast<void*>( &ssBuf ),
vpdSize,
- DEVICE_CVPD_ADDRESS( CVPD::OSYS,
- CVPD::SS ));
+ DEVICE_PVPD_ADDRESS( PVPD::OSYS,
+ PVPD::SS ));
if(errhdl)
{
TRACFCOMP(g_trac_devtree,ERR_MRK" Couldn't read OSYS:SS for HUID=0x%.8X",
- TARGETING::get_huid(l_pMem));
+ TARGETING::get_huid(l_pNode));
}
else
{
@@ -1205,7 +1207,6 @@ errlHndl_t bld_fdt_system(devTree * i_dt, bool i_smallTree)
delete errhdl;
errhdl = NULL;
}
-
if( !foundvpd ) //serial number not found, default to unavailable
{
i_dt->addPropertyString(rootNode, "system-id", "unavailable");
diff --git a/src/usr/hwas/hwasPlat.C b/src/usr/hwas/hwasPlat.C
index 80c36f95d..ef631b50a 100644
--- a/src/usr/hwas/hwasPlat.C
+++ b/src/usr/hwas/hwasPlat.C
@@ -421,9 +421,13 @@ errlHndl_t platPresenceDetect(TargetHandleList &io_targets)
HWAS_DBG("pTarget %.8X - detected present",
pTarget->getAttr<ATTR_HUID>());
- // on to the next target
+ // If there is planar VPD, then don't skip the presence detect.
+ // The presence detect will log any problems and load pnor.
+#if !defined(CONFIG_HAVE_PVPD)
+ // on to the next target if there is no Planar VPD
pTarget_it++;
continue;
+#endif
}
// call deviceRead() to see if they are present
diff --git a/src/usr/hwas/hwasPlatCallout.C b/src/usr/hwas/hwasPlatCallout.C
index 0f15082a7..03756a85f 100644
--- a/src/usr/hwas/hwasPlatCallout.C
+++ b/src/usr/hwas/hwasPlatCallout.C
@@ -122,10 +122,12 @@ errlHndl_t platHandleHWCallout(
} // switch i_deconfigState
// check to see if this target is the master processor
- // and if it's been deconfigured.
+ // and if it's being deconfigured.
+ // NOTE: will be non-functional early in IPL before discovery complete.
TARGETING::Target *l_masterProc;
TARGETING::targetService().masterProcChipTargetHandle(l_masterProc);
- if (i_pTarget == l_masterProc)
+ if ( (i_pTarget == l_masterProc) &&
+ (NO_DECONFIG != i_deconfigState) )
{
const TARGETING::HwasState hwasState =
l_masterProc->getAttr<TARGETING::ATTR_HWAS_STATE>();
diff --git a/src/usr/i2c/eepromdd.C b/src/usr/i2c/eepromdd.C
index 372fcc75a..b2e1c90e3 100755
--- a/src/usr/i2c/eepromdd.C
+++ b/src/usr/i2c/eepromdd.C
@@ -97,6 +97,11 @@ DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
TARGETING::TYPE_MEMBUF,
eepromPerformOp );
+// Register the perform Op with the routing code for Nodes.
+DEVICE_REGISTER_ROUTE( DeviceFW::WILDCARD,
+ DeviceFW::EEPROM,
+ TARGETING::TYPE_NODE,
+ eepromPerformOp );
// ------------------------------------------------------------------
// eepromPerformOp
diff --git a/src/usr/ipmi/ipmifruinv.C b/src/usr/ipmi/ipmifruinv.C
index cc2f06ad9..49c5e7e1d 100644
--- a/src/usr/ipmi/ipmifruinv.C
+++ b/src/usr/ipmi/ipmifruinv.C
@@ -29,6 +29,7 @@
#include <devicefw/userif.H>
#include <vpd/spdenums.H>
#include <vpd/cvpdenums.H>
+#include <vpd/pvpdenums.H>
#include <targeting/common/commontargeting.H>
#include <targeting/common/utilFilter.H>
#include <errl/errlmanager.H>
@@ -51,7 +52,17 @@ inline static bool comparePairs(
const std::pair<TARGETING::TargetHandle_t, uint8_t>& i_lhs,
const std::pair<TARGETING::TargetHandle_t, uint8_t>& i_rhs)
{
- return (i_lhs.second < i_rhs.second);
+ bool l_compare = i_lhs.second < i_rhs.second;
+
+ // in case of a tie, if the left is a Node, sort it first.
+ if (i_lhs.second == i_rhs.second)
+ {
+ if (TARGETING::TYPE_NODE==i_lhs.first->getAttr<TARGETING::ATTR_TYPE>())
+ {
+ l_compare = true;
+ }
+ }
+ return l_compare;
}
IpmiFruInv::IpmiFruInv(TARGETING::TargetHandle_t i_target)
@@ -82,7 +93,14 @@ IpmiFruInv *IpmiFruInv::Factory(TARGETING::TargetHandleList i_targets,
l_fru = new procIpmiFruInv(l_target, i_updateData);
break;
case TARGETING::TYPE_MEMBUF:
- // @todo-RTC:117702
+ // A memory riser card will have a mem buff with a distinct FRU ID
+ l_fru = new membufIpmiFruInv(l_target, i_targets, i_updateData);
+ break;
+ case TARGETING::TYPE_NODE:
+ // When the planar eeprom is shared for planar vpd and memory vpd,
+ // the node and membufs will have the same FRU ID. The node has
+ // been sorted ahead of the membufs. The membufs are extra targets
+ // for their ECIDs.
l_fru = new backplaneIpmiFruInv(l_target, i_targets, i_updateData);
break;
case TARGETING::TYPE_SYS:
@@ -425,11 +443,11 @@ errlHndl_t isdimmIpmiFruInv::buildProductInfoArea(std::vector<uint8_t> &io_data)
io_data.push_back(uint8_t(0)); // Empty FRU File ID bytes
io_data.push_back(IPMIFRUINV::END_OF_CUSTOM_FIELDS);
- //Finalize section formatting
- postFormatProcessing(io_data);
-
} while (0);
+ //Finalize section formatting
+ postFormatProcessing(io_data);
+
if (l_errl)
{
TRACFCOMP(g_trac_ipmi,"isdimIpmiFruInv::buildProductInfoArea - Errors "
@@ -580,11 +598,11 @@ errlHndl_t procIpmiFruInv::buildBoardInfoArea(std::vector<uint8_t> &io_data)
//Indicate end of custom fields
io_data.push_back(IPMIFRUINV::END_OF_CUSTOM_FIELDS);
- //Complete formatting for this data record
- postFormatProcessing(io_data);
-
} while (0);
+ //Complete formatting for this data record
+ postFormatProcessing(io_data);
+
if (l_errl)
{
TRACFCOMP(g_trac_ipmi,"buildBoardInfoArea - Errors Collecting ISDimm "
@@ -610,64 +628,18 @@ errlHndl_t procIpmiFruInv::buildMultiRecordInfoArea(
errlHndl_t procIpmiFruInv::addVpdData(std::vector<uint8_t> &io_data,
uint8_t i_record,
uint8_t i_keyword,
- bool i_ascii)
+ bool i_ascii,
+ bool i_typeLengthByte)
{
- size_t l_vpdSize = 0;
errlHndl_t l_errl = NULL;
- do {
-
- //First get size of data by passing NULL
- l_errl = deviceRead(iv_target,
- NULL,
- l_vpdSize,
- DEVICE_MVPD_ADDRESS(i_record, i_keyword));
-
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi,"procIpmiFruInv::addVpdData - Error while "
- "reading MVPD keyword size");
- break;
- }
-
- //Assert if vpd field is too large to fit in IPMI fru inventory format
- assert(l_vpdSize < IPMIFRUINV::TYPELENGTH_BYTE_ASCII);
-
- if (l_vpdSize > 0)
- {
- //Determine how big data is and expand it to handle the soon to
- //be read VPD data
- uint8_t l_offset = io_data.size();
- io_data.resize(l_offset + 1 + l_vpdSize);
-
- //Add on the data to the type/length byte indicating it is ascii
- // otherwise leave it as binary
- if (i_ascii)
- {
- io_data.at(l_offset) = l_vpdSize
- + IPMIFRUINV::TYPELENGTH_BYTE_ASCII;
- }
- else
- {
- io_data.at(l_offset) = l_vpdSize;
- }
-
- //Read the VPD data directly into fru inventory data buffer
- l_errl = deviceRead(iv_target,&io_data[l_offset+1],l_vpdSize,
- DEVICE_MVPD_ADDRESS(i_record, i_keyword));
- }
- else
- {
- TRACFCOMP(g_trac_ipmi,"procIpmiFruInv::addVpdData - "
- " No size returned for MVPD keyword");
- }
- } while(0);
-
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi, "addVpdData - Error acquiring data from Vpd.");
- }
-
+ l_errl = addCommonVpdData(iv_target,
+ io_data,
+ DeviceFW::MVPD,
+ i_record,
+ i_keyword,
+ i_ascii,
+ i_typeLengthByte);
return l_errl;
}
@@ -699,8 +671,7 @@ errlHndl_t backplaneIpmiFruInv::buildChassisInfoArea(
preFormatProcessing(io_data, false);
//Set Chassis Enclosure Type - Not Ascii
// Also, do not include type/length byte
- //@fixme RTC Story 118373
- l_errl = addVpdData(io_data, CVPD::OSYS, CVPD::ET, false, false);
+ l_errl = addVpdData(io_data, PVPD::OSYS, PVPD::ET, false, false);
//Support Legacy VPD without OSYS record
if (l_errl)
@@ -714,12 +685,10 @@ errlHndl_t backplaneIpmiFruInv::buildChassisInfoArea(
//Set default chassis type
io_data.push_back(IPMIFRUINV::DEFAULT_CHASSIS_TYPE);
//Set chassis part number - ascii formatted field
- //@fixme RTC Story 118373
- l_errl = addVpdData(io_data, CVPD::OPFR, CVPD::VP, true);
+ l_errl = addVpdData(io_data, PVPD::OPFR, PVPD::VP, true);
if (l_errl) { break; }
//Set chassis serial number - ascii formatted field
- //@fixme RTC Story 118373
- l_errl = addVpdData(io_data, CVPD::OPFR, CVPD::VS, true);
+ l_errl = addVpdData(io_data, PVPD::OPFR, PVPD::VS, true);
if (l_errl) { break; }
}
else
@@ -728,13 +697,11 @@ errlHndl_t backplaneIpmiFruInv::buildChassisInfoArea(
" Using NEW OSYS RECORD FOR Chassis VPD Data");
//Set chassis part number - ascii formatted field
- //@fixme RTC Story 118373
- l_errl = addVpdData(io_data, CVPD::OSYS, CVPD::MM, true);
+ l_errl = addVpdData(io_data, PVPD::OSYS, PVPD::MM, true);
if (l_errl) { break; }
//Set chassis serial number - ascii formatted field
- //@fixme RTC Story 118373
- l_errl = addVpdData(io_data, CVPD::OSYS, CVPD::SS, true);
+ l_errl = addVpdData(io_data, PVPD::OSYS, PVPD::SS, true);
if (l_errl) { break; }
}
@@ -743,10 +710,11 @@ errlHndl_t backplaneIpmiFruInv::buildChassisInfoArea(
io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
io_data.push_back(IPMIFRUINV::END_OF_CUSTOM_FIELDS);
- //Complete record data formatting
- postFormatProcessing(io_data);
} while (0);
+ //Complete record data formatting
+ postFormatProcessing(io_data);
+
if (l_errl)
{
TRACFCOMP(g_trac_ipmi,"backplaneIpmiFruInv::buildChassisInfoArea - "
@@ -771,67 +739,39 @@ errlHndl_t backplaneIpmiFruInv::buildBoardInfoArea(
io_data.push_back(0);
//Set Vendor Name - ascii formatted data
- //@fixme RTC Story 118373
- l_errl = addVpdData(io_data, CVPD::OPFR, CVPD::VN, true);
+ l_errl = addVpdData(io_data, PVPD::OPFR, PVPD::VN, true);
if (l_errl) { break; }
//Set Product Name - ascii formatted data
- //@fixme RTC Story 118373
- l_errl = addVpdData(io_data, CVPD::OPFR, CVPD::DR, true);
+ l_errl = addVpdData(io_data, PVPD::OPFR, PVPD::DR, true);
if (l_errl) { break; }
//Set Product Serial number - ascii formatted data
- //@fixme RTC Story 118373
- l_errl = addVpdData(io_data, CVPD::OPFR, CVPD::VS, true);
+ //TODO RTC:117702 use attribute when 122890 is available
+ l_errl = addVpdData(io_data, PVPD::OPFR, PVPD::VS, true);
if (l_errl) { break; }
//Set Product Part number - ascii formatted data
- //@fixme RTC Story 118373
- l_errl = addVpdData(io_data, CVPD::OPFR, CVPD::VP, true);
- if (l_errl) { break; }
+ //TODO RTC:117702 use attribute when 122890 is available
+ l_errl = addVpdData(io_data, PVPD::OPFR, PVPD::VP, true);
//Push Fru File ID Byte - NULL
io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
- bool l_setCustomData = false;
- // Check if we should add ECID
- for (TARGETING::TargetHandleList::const_iterator extraTargets_it =
- iv_extraTargets.begin();
- extraTargets_it != iv_extraTargets.end();
- ++extraTargets_it
- )
+ //Only set the ECID Data during an update scenario
+ if (iv_isUpdate == true)
{
- TARGETING::TargetHandle_t l_extraTarget = *extraTargets_it;
-
- //Only set the ECID Data during an update scenario
- if (iv_isUpdate == true &&
- (l_extraTarget->getAttr<TARGETING::ATTR_TYPE>() ==
- TARGETING::TYPE_MEMBUF))
- {
- TARGETING::ATTR_ECID_type ecidInfo;
- bool getEcid =
- l_extraTarget->tryGetAttr<TARGETING::ATTR_ECID>(ecidInfo);
- if (getEcid)
- {
- l_setCustomData = true;
- addEcidData(l_extraTarget, ecidInfo, io_data);
- }
- }
+ customEcidData (iv_extraTargets, io_data);
}
- //If no Custom data was sent, an Empty Byte is needed
- if (!l_setCustomData)
- {
- io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
- }
//Indicate End of Custom Fields
io_data.push_back(IPMIFRUINV::END_OF_CUSTOM_FIELDS);
- //Complete record data formatting
- postFormatProcessing(io_data);
-
} while (0);
+ //Complete record data formatting
+ postFormatProcessing(io_data);
+
if (l_errl)
{
TRACFCOMP(g_trac_ipmi,"backplaneIpmiFruInv::buildBoardInfoArea - "
@@ -860,74 +800,17 @@ errlHndl_t backplaneIpmiFruInv::addVpdData(std::vector<uint8_t> &io_data,
uint8_t i_keyword,
bool i_ascii,
bool i_typeLengthByte)
+
{
- size_t l_vpdSize = 0;
errlHndl_t l_errl = NULL;
- do {
- //First get size of data with NULL parameter
- l_errl = deviceRead(iv_target,
- NULL,
- l_vpdSize,
- //@fixme RTC Story 118373
- DEVICE_CVPD_ADDRESS(i_record, i_keyword));
-
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi,"backplaneIpmiFruInv::addVpdData - Error "
- "while reading CVPD keyword size");
- break;
- }
-
- //Assert if vpd field is too large to fit in IPMI fru inventory format
- assert(l_vpdSize < IPMIFRUINV::TYPELENGTH_BYTE_ASCII);
-
- if (l_vpdSize > 0)
- {
- uint8_t l_offset = 0;
- //Add on the typelength byte if requested
- if (i_typeLengthByte)
- {
- //Determine how big data is and expand it to handle the soon to
- //be read VPD data
- l_offset = io_data.size();
- io_data.resize(l_offset + 1 + l_vpdSize);
- //Add on the data to the type/length byte indicating it is ascii
- // otherwise leave it as binary
- if (i_ascii)
- {
- io_data.at(l_offset) = l_vpdSize
- + IPMIFRUINV::TYPELENGTH_BYTE_ASCII;
- }
- else
- {
- io_data.at(l_offset) = l_vpdSize;
- }
- l_offset += 1;
- }
- else
- {
- //Determine how big data is and expand it to handle the soon to
- //be read VPD data
- l_offset = io_data.size();
- io_data.resize(l_offset + l_vpdSize);
- }
- //Read the VPD data directly into fru inventory data buffer
- l_errl = deviceRead(iv_target,&io_data[l_offset],l_vpdSize,
- DEVICE_CVPD_ADDRESS(i_record, i_keyword));
- }
- else
- {
- TRACFCOMP(g_trac_ipmi,"backplaneIpmiFruInv::addVpdData - "
- " No size returned for CVPD keyword");
- }
- } while(0);
-
- if (l_errl)
- {
- TRACFCOMP(g_trac_ipmi, "backplaneIpmiFruInv::addVpdData - Error "
- "acquiring data from Vpd.");
- }
+ l_errl = addCommonVpdData(iv_target,
+ io_data,
+ DeviceFW::PVPD,
+ i_record,
+ i_keyword,
+ i_ascii,
+ i_typeLengthByte);
return l_errl;
}
@@ -1106,11 +989,11 @@ errlHndl_t systemFwIpmiFruInv::buildProductInfoArea(std::vector<uint8_t>
io_data.push_back(IPMIFRUINV::END_OF_CUSTOM_FIELDS);
- //Finalize section formatting
- postFormatProcessing(io_data);
-
} while(0);
+ //Finalize section formatting
+ postFormatProcessing(io_data);
+
return l_errl;
}
@@ -1121,7 +1004,155 @@ errlHndl_t systemFwIpmiFruInv::buildMultiRecordInfoArea(std::vector<uint8_t>
return IpmiFruInv::buildEmptyArea(io_data);
}
+//##############################################################################
+membufIpmiFruInv::membufIpmiFruInv( TARGETING::TargetHandle_t i_target,
+ TARGETING::TargetHandleList i_extraTargets,
+ bool i_isUpdate)
+ :IpmiFruInv(i_target),
+ iv_isUpdate(i_isUpdate),
+ iv_extraTargets(i_extraTargets)
+{
+};
+
+errlHndl_t membufIpmiFruInv::buildInternalUseArea(
+ std::vector<uint8_t> &io_data)
+{
+ //This section not needed for the mem buf type
+ return IpmiFruInv::buildEmptyArea(io_data);
+}
+
+errlHndl_t membufIpmiFruInv::buildChassisInfoArea(
+ std::vector<uint8_t> &io_data)
+{
+ //This section not needed for the mem buf type
+ return IpmiFruInv::buildEmptyArea(io_data);
+}
+
+errlHndl_t membufIpmiFruInv::buildBoardInfoArea(
+ std::vector<uint8_t> &io_data)
+{
+ errlHndl_t l_errl = NULL;
+
+ do {
+ //Set formatting data that goes at the beginning of the record
+ preFormatProcessing(io_data, true);
+
+ //Set MFG Date/Time - Blank
+ io_data.push_back(0);
+ io_data.push_back(0);
+ io_data.push_back(0);
+
+ //Set Vendor Name - ascii formatted data
+ l_errl = addVpdData(io_data, CVPD::OPFR, CVPD::VN, true);
+ if (l_errl) { break; }
+
+ //Set Product Name - ascii formatted data
+ l_errl = addVpdData(io_data, CVPD::OPFR, CVPD::DR, true);
+ if (l_errl) { break; }
+
+ //Set Product Serial number - ascii formatted data
+ //TODO RTC:117702 use attribute when 122890 is available
+ l_errl = addVpdData(io_data, CVPD::OPFR, CVPD::VS, true);
+ if (l_errl) { break; }
+
+ //Set Product Part number - ascii formatted data
+ //TODO RTC:117702 use attribute when 122890 is available
+ l_errl = addVpdData(io_data, CVPD::OPFR, CVPD::VP, true);
+ if (l_errl) { break; }
+
+ //Push Fru File ID Byte - NULL
+ io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
+
+ //Only set the ECID Data during an update scenario
+ if (iv_isUpdate == true)
+ {
+ customEcidData (iv_extraTargets, io_data);
+ }
+
+ //Indicate End of Custom Fields
+ io_data.push_back(IPMIFRUINV::END_OF_CUSTOM_FIELDS);
+
+ } while (0);
+
+ //Complete record data formatting
+ postFormatProcessing(io_data);
+
+ if (l_errl)
+ {
+ TRACFCOMP(g_trac_ipmi,"membufIpmiFruInv::buildBoardInfoArea - "
+ "Errors collecting board info data");
+ }
+
+ return l_errl;
+}
+
+errlHndl_t membufIpmiFruInv::buildProductInfoArea(
+ std::vector<uint8_t> &io_data)
+{
+ //This section not needed for the mem buf type
+ return IpmiFruInv::buildEmptyArea(io_data);
+}
+
+errlHndl_t membufIpmiFruInv::buildMultiRecordInfoArea(
+ std::vector<uint8_t> &io_data)
+{
+ //This section not needed for the mem buf type
+ return IpmiFruInv::buildEmptyArea(io_data);
+}
+
+errlHndl_t membufIpmiFruInv::addVpdData(std::vector<uint8_t> &io_data,
+ uint8_t i_record,
+ uint8_t i_keyword,
+ bool i_ascii,
+ bool i_typeLengthByte)
+{
+ errlHndl_t l_errl = NULL;
+
+ l_errl = addCommonVpdData(iv_target,
+ io_data,
+ DeviceFW::CVPD,
+ i_record,
+ i_keyword,
+ i_ascii,
+ i_typeLengthByte);
+ return l_errl;
+}
+//##############################################################################
+void IpmiFruInv::customEcidData(TARGETING::TargetHandleList i_extraTargets,
+ std::vector<uint8_t> &io_data)
+{
+
+ bool l_setCustomData = false;
+ // Check if we should add ECID
+ for (TARGETING::TargetHandleList::const_iterator extraTargets_it =
+ i_extraTargets.begin();
+ extraTargets_it != i_extraTargets.end();
+ ++extraTargets_it
+ )
+ {
+ TARGETING::TargetHandle_t l_extraTarget = *extraTargets_it;
+
+ //Only set the ECID Data during an update scenario
+ if ( l_extraTarget->getAttr<TARGETING::ATTR_TYPE>() ==
+ TARGETING::TYPE_MEMBUF)
+ {
+ TARGETING::ATTR_ECID_type ecidInfo;
+ bool getEcid =
+ l_extraTarget->tryGetAttr<TARGETING::ATTR_ECID>(ecidInfo);
+ if (getEcid)
+ {
+ l_setCustomData = true;
+ addEcidData(l_extraTarget, ecidInfo, io_data);
+ }
+ }
+ }
+ //If no Custom data was sent, an Empty Byte is needed
+ if (!l_setCustomData)
+ {
+ io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
+ }
+}
void IpmiFruInv::addEcidData(const TARGETING::TargetHandle_t& i_target,
const TARGETING::ATTR_ECID_type& i_ecidInfo,
@@ -1149,6 +1180,94 @@ void IpmiFruInv::addEcidData(const TARGETING::TargetHandle_t& i_target,
return;
}
+errlHndl_t IpmiFruInv::addCommonVpdData(
+ const TARGETING::TargetHandle_t& i_target,
+ std::vector<uint8_t> &io_data,
+ DeviceFW::AccessType i_accessType,
+ uint8_t i_record,
+ uint8_t i_keyword,
+ bool i_ascii,
+ bool i_typeLengthByte)
+{
+ size_t l_vpdSize = 0;
+ errlHndl_t l_errl = NULL;
+
+ do {
+ // First get size with NULL call:
+ // Bypass DEVICE_?VPD_ADDRESS inorder to maximize common code
+ l_errl = deviceRead(i_target,
+ NULL,
+ l_vpdSize,
+ i_accessType,
+ i_record,
+ i_keyword,
+ VPD::AUTOSELECT);
+
+ if (l_errl)
+ {
+ TRACFCOMP(g_trac_ipmi,"addCommonVpdData - Error "
+ "while reading keyword size");
+ break;
+ }
+
+ //Assert if vpd field is too large to fit in IPMI fru inventory format
+ assert(l_vpdSize < IPMIFRUINV::TYPELENGTH_BYTE_ASCII);
+
+ if (l_vpdSize > 0)
+ {
+ uint8_t l_offset = 0;
+ //Add on the typelength byte if requested
+ if (i_typeLengthByte)
+ {
+ //Determine how big data is and expand it to handle the soon to
+ //be read VPD data
+ l_offset = io_data.size();
+ io_data.resize(l_offset + 1 + l_vpdSize);
+ //Add on the data to the type/length byte indicating it is ascii
+ // otherwise leave it as binary
+ if (i_ascii)
+ {
+ io_data.at(l_offset) = l_vpdSize
+ + IPMIFRUINV::TYPELENGTH_BYTE_ASCII;
+ }
+ else
+ {
+ io_data.at(l_offset) = l_vpdSize;
+ }
+ l_offset += 1;
+ }
+ else
+ {
+ //Determine how big data is and expand it to handle the soon to
+ //be read VPD data
+ l_offset = io_data.size();
+ io_data.resize(l_offset + l_vpdSize);
+ }
+ //Read the VPD data directly into fru inventory data buffer
+ l_errl = deviceRead(i_target,
+ &io_data[l_offset],
+ l_vpdSize,
+ i_accessType,
+ i_record,
+ i_keyword,
+ VPD::AUTOSELECT);
+ }
+ else
+ {
+ TRACFCOMP(g_trac_ipmi,"addCommonVpdData - "
+ " No size returned for keyword");
+ }
+ } while(0);
+
+ if (l_errl)
+ {
+ TRACFCOMP(g_trac_ipmi, "addCommonVpdData - Error "
+ "acquiring data from Vpd.");
+ }
+
+ return l_errl;
+}
+
void IPMIFRUINV::clearData(uint8_t i_fruId)
{
uint8_t l_clearData[] =
@@ -1292,10 +1411,12 @@ void IPMIFRUINV::gatherClearData(const TARGETING::Target* i_pSys,
std::map<uint8_t,bool>& io_frusToClear)
{
TARGETING::PredicateCTM predChip(TARGETING::CLASS_CHIP);
+ TARGETING::PredicateCTM predNode(TARGETING::CLASS_ENC,
+ TARGETING::TYPE_NODE);
TARGETING::PredicateCTM predDimm(TARGETING::CLASS_LOGICAL_CARD,
TARGETING::TYPE_DIMM);
TARGETING::PredicatePostfixExpr checkAllExpr;
- checkAllExpr.push(&predChip).push(&predDimm).Or();
+ checkAllExpr.push(&predChip).push(&predNode).Or().push(&predDimm).Or();
TARGETING::TargetHandleList l_allPossibleFrus;
TARGETING::targetService().getAssociated( l_allPossibleFrus, i_pSys,
TARGETING::TargetService::CHILD, TARGETING::TargetService::ALL,
@@ -1336,14 +1457,19 @@ void IPMIFRUINV::gatherSetData(const TARGETING::Target* i_pSys,
// may be needed
l_present.present(true);
+ checkExpr.push(&predChip);
+ TARGETING::PredicateCTM predNode(TARGETING::CLASS_ENC,
+ TARGETING::TYPE_NODE);
+ checkExpr.push(&predNode).Or();
+
//When updating data on a later pass ignore dimms
if (i_updateData)
{
- checkExpr.push(&predChip).push(&l_present).And();
+ checkExpr.push(&l_present).And();
}
else
{
- checkExpr.push(&predChip).push(&predDimm).Or().push(&l_present).And();
+ checkExpr.push(&predDimm).Or().push(&l_present).And();
}
TARGETING::TargetHandleList pCheckPres;
@@ -1374,6 +1500,10 @@ void IPMIFRUINV::gatherSetData(const TARGETING::Target* i_pSys,
}
//Sort the vector by FRU_ID for later use.
+ //When the planar eeprom is shared for planar and memory buffer vpd, the
+ //node and membuffs will have the same FRU ID. For this case, sort the Node
+ //to be ahead of the mem buffs. The mem buffs will be extra targets for
+ //their ECIDs.
std::sort(io_potentialFrus.begin(),
io_potentialFrus.end(),
comparePairs);
diff --git a/src/usr/ipmi/ipmifruinvprvt.H b/src/usr/ipmi/ipmifruinvprvt.H
index 468a47f80..57d6e13cd 100644
--- a/src/usr/ipmi/ipmifruinvprvt.H
+++ b/src/usr/ipmi/ipmifruinvprvt.H
@@ -186,6 +186,32 @@ class IpmiFruInv
const TARGETING::ATTR_ECID_type& i_ecidInfo,
std::vector<uint8_t> &io_data);
+ /**
+ * @brief Adds Ecid attribute data from extra targets as custom data
+ * @param[in] TargetHandleList, Handle to list of extra
+ * targets associated with this FRU Record
+ * @param[in/out] data, The container to put ECID attribute data in
+ */
+ void customEcidData(TARGETING::TargetHandleList i_extraTargets,
+ std::vector<uint8_t> &io_data);
+
+ /**
+ * @brief Retrieve vpd record keyword and add to IPMI Fru Inventory record
+ * @param[in/out] data, The container with record data
+ * @param[in] access, Indicates vpd module to access (MVPD,PVPD,CPVD)
+ * @param[in] record, Indicates major offset in the VPD to get more data
+ * @param[in] keyword, Indicates minor offset in the VPD to get more data
+ * @param[in] ascii, Indicates if VPD field is in ascii format or not
+ */
+ errlHndl_t addCommonVpdData(
+ const TARGETING::TargetHandle_t& i_target,
+ std::vector<uint8_t> &io_data,
+ DeviceFW::AccessType i_accessType,
+ uint8_t i_record,
+ uint8_t i_keyword,
+ bool i_ascii,
+ bool i_typeLengthByte);
+
private:
/**
@@ -376,11 +402,13 @@ class procIpmiFruInv : public IpmiFruInv
* @param[in] record, Indicates major offset in the VPD to get more data
* @param[in] keyword, Indicates minor offset in the VPD to get more data
* @param[in] ascii, Indicates if VPD field is in ascii format or not
+ * @param[in] typeLengthBtye, Indicates whether type length to be added.
*/
errlHndl_t addVpdData(std::vector<uint8_t> &io_data,
uint8_t i_record,
uint8_t i_keyword,
- bool i_ascii=false);
+ bool i_ascii=false,
+ bool i_typeLengthByte=true);
};
@@ -453,13 +481,13 @@ class backplaneIpmiFruInv : public IpmiFruInv
* @param[in] record, Indicates major offset in the VPD to get more data
* @param[in] keyword, Indicates minor offset in the VPD to get more data
* @param[in] ascii, Indicates if VPD field is in ascii format or not
+ * @param[in] typeLengthBtye, Indicates whether type length to be added.
*/
errlHndl_t addVpdData(std::vector<uint8_t> &io_data,
uint8_t i_record,
uint8_t i_keyword,
bool i_ascii=false,
bool i_typeLengthByte=true);
-
};
//Child class for building up System Firwmare Fru Inventory Record Data
@@ -507,4 +535,84 @@ class systemFwIpmiFruInv : public IpmiFruInv
};
+//Child class for building up membuf Fru Inventory Record Data. For example,
+//for a memory riser card Fru.
+class membufIpmiFruInv : public IpmiFruInv
+{
+
+ public:
+
+ /**
+ * @brief Constructor
+ *
+ * @param[in] TargetHandle_t, Handle to target for which
+ * to get relevant IPMI FRU Data from
+ * @param[in] TargetHandleList, Handle to list of extra
+ * targets associated with this FRU Record
+ * @param[in] isUpdate, Indicator if the code is updating
+ * existing data, or setting base data.
+ */
+ membufIpmiFruInv( TARGETING::TargetHandle_t i_target,
+ TARGETING::TargetHandleList i_extraTargets,
+ bool i_isUpdate );
+
+ /**
+ * @brief Builds the Internal Use Area Data Section
+ * @param[in/out] data, The container to put internal use area data in
+ */
+ errlHndl_t buildInternalUseArea(std::vector<uint8_t> &io_data);
+
+ /**
+ * @brief Builds the Chassis Info Area Data Section
+ * @param[in/out] data, The container to put chassis info area data in
+ */
+ errlHndl_t buildChassisInfoArea(std::vector<uint8_t> &io_data);
+
+ /**
+ * @brief Builds the Board Info Area Data Section
+ * @param[in/out] data, The container to put board info area data in
+ */
+ errlHndl_t buildBoardInfoArea(std::vector<uint8_t> &io_data);
+
+ /**
+ * @brief Builds the Product Info Area Data Section
+ * @param[in/out] data, The container to put product info area data in
+ */
+ errlHndl_t buildProductInfoArea(std::vector<uint8_t>& io_data);
+
+ /**
+ * @brief Builds the MultiRecord Info Area Data Section
+ * @param[in/out] data, The container to put multirecord info area data in
+ */
+ errlHndl_t buildMultiRecordInfoArea(std::vector<uint8_t>& io_data);
+
+ protected:
+ //Indicator if a data update is happening.
+ //True - means we are solely updating certain data
+ //False - means we are doing the initial 'base' data set
+ bool iv_isUpdate;
+
+ //The list of Extra Targets if multiple targets are
+ //associated with one FRU_ID
+ TARGETING::TargetHandleList iv_extraTargets;
+
+ private:
+
+ /**
+ * @brief Adds the specified VPD data to the data to build up a given
+ * IPMI Fru Inventory record
+ * @param[in/out] data, The container with record data
+ * @param[in] record, Indicates major offset in the VPD to get more data
+ * @param[in] keyword, Indicates minor offset in the VPD to get more data
+ * @param[in] ascii, Indicates if VPD field is in ascii format or not
+ * @param[in] typeLengthBtye, Indicates whether type length to be added.
+ */
+ errlHndl_t addVpdData(std::vector<uint8_t> &io_data,
+ uint8_t i_record,
+ uint8_t i_keyword,
+ bool i_ascii=false,
+ bool i_typeLengthByte=true);
+
+};
+
#endif
diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml
index 5503e3ce1..6506a7a2a 100644
--- a/src/usr/targeting/common/xmltohb/target_types.xml
+++ b/src/usr/targeting/common/xmltohb/target_types.xml
@@ -917,6 +917,8 @@
<attribute><id>FRU_ID</id></attribute>
<attribute><id>TPM_PRIMARY_INFO</id></attribute>
<attribute><id>TPM_BACKUP_INFO</id></attribute>
+ <attribute><id>EEPROM_VPD_PRIMARY_INFO</id></attribute>
+ <attribute><id>VPD_REC_NUM</id></attribute>
</targetType>
<targetType>
diff --git a/src/usr/targeting/common/xmltohb/target_types_hb.xml b/src/usr/targeting/common/xmltohb/target_types_hb.xml
index b0429daf0..d023f507c 100644
--- a/src/usr/targeting/common/xmltohb/target_types_hb.xml
+++ b/src/usr/targeting/common/xmltohb/target_types_hb.xml
@@ -180,6 +180,11 @@
</targetTypeExtension>
<targetTypeExtension>
+ <id>enc-node-power8</id>
+ <attribute><id>VPD_SWITCHES</id></attribute>
+</targetTypeExtension>
+
+<targetTypeExtension>
<id>lcard-dimm</id>
<attribute><id>VPD_SWITCHES</id></attribute>
<attribute><id>IPMI_SENSORS</id></attribute>
diff --git a/src/usr/vpd/HBconfig b/src/usr/vpd/HBconfig
index 136183442..1d6e6f1b8 100644
--- a/src/usr/vpd/HBconfig
+++ b/src/usr/vpd/HBconfig
@@ -33,6 +33,28 @@ config CVPD_WRITE
help
Ensure at least one of the CVPD WRITEs are enabled
+config PVPD_READ_FROM_PNOR
+ default n
+ help
+ Read Planar VPD data from PNOR cache
+
+config PVPD_READ_FROM_HW
+ default n
+ help
+ Read Planar VPD data from HW resources
+
+config PVPD_WRITE_TO_PNOR
+ default y if PVPD_READ_FROM_PNOR
+ depends on PVPD_READ_FROM_PNOR
+ help
+ Write Planar VPD data to PNOR cache
+
+config PVPD_WRITE_TO_HW
+ default y if PVPD_READ_FROM_HW
+ depends on PVPD_READ_FROM_HW
+ help
+ Write Planar VPD data to HW resources
+
config MVPD_READ_FROM_PNOR
default y
help
@@ -105,6 +127,11 @@ config HAVE_MBVPD
help
Have MemBuff/Centaur VPD, PNOR or HW
+config HAVE_PVPD
+ default y if PVPD_READ_FROM_PNOR || PVPD_READ_FROM_HW
+ help
+ Have Planar VPD, PNOR or HW
+
config PALMETTO_PASS1
default n
help
diff --git a/src/usr/vpd/cvpd.C b/src/usr/vpd/cvpd.C
index 50815f135..fa37dc978 100644
--- a/src/usr/vpd/cvpd.C
+++ b/src/usr/vpd/cvpd.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2013,2014 */
+/* Contributors Listed Below - COPYRIGHT 2013,2015 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
/* */
@@ -31,7 +31,10 @@
#include <trace/interface.H>
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
+#include <targeting/common/commontargeting.H>
#include <targeting/common/targetservice.H>
+#include <targeting/common/util.H>
+#include <targeting/common/utilFilter.H>
#include <devicefw/driverif.H>
#include <vfs/vfs.H>
#include <vpd/vpdreasoncodes.H>
@@ -40,6 +43,7 @@
#include <i2c/eepromif.H>
#include <config.h>
#include "cvpd.H"
+#include "pvpd.H"
#include "vpd.H"
// ----------------------------------------------
@@ -233,15 +237,41 @@ IpVpdFacade(CVPD::SECTION_SIZE,
iv_configInfo.vpdReadHW = true;
#else
iv_configInfo.vpdReadHW = false;
-#endif
+#endif
#ifdef CONFIG_CVPD_WRITE_TO_PNOR
iv_configInfo.vpdWritePNOR = true;
#else
iv_configInfo.vpdWritePNOR = false;
-#endif
+#endif
#ifdef CONFIG_CVPD_WRITE_TO_HW
iv_configInfo.vpdWriteHW = true;
#else
iv_configInfo.vpdWriteHW = false;
#endif
}
+
+// Retrun lists of records that should be copied to pnor.
+void CvpdFacade::getRecordLists(
+ const recordInfo* & o_primaryVpdRecords,
+ uint64_t & o_primaryRecSize,
+ const recordInfo* & o_altVpdRecords,
+ uint64_t & o_altRecSize)
+{
+ // Always return this object's list
+ o_primaryVpdRecords = iv_vpdRecords;
+ o_primaryRecSize = iv_recSize;
+
+ // If the planar errprom being shared with a mem buf,
+ // then return the pvpd list as the alternative record list.
+ // At thip point, if the membufs are be processed, then the node
+ // might not have been discovered yet. If pvpd is being cached, then
+ // include the pvpd list as the altnative.
+#ifdef CONFIG_PVPD_READ_FROM_PNOR
+ o_altVpdRecords = Singleton<PvpdFacade>::instance().iv_vpdRecords;
+ o_altRecSize = Singleton<PvpdFacade>::instance().iv_recSize;
+#else
+ o_altVpdRecords = NULL;
+ o_altRecSize = 0;
+#endif
+}
+
diff --git a/src/usr/vpd/cvpd.H b/src/usr/vpd/cvpd.H
index e7a2d9f06..9c729c389 100644
--- a/src/usr/vpd/cvpd.H
+++ b/src/usr/vpd/cvpd.H
@@ -79,7 +79,6 @@ namespace CVPD
{ OPFR, "OPFR" },
{ VNDR, "VNDR" },
{ SPDX, "SPDX" },
- { OSYS, "OSYS" },
// -------------------------------------------------------------------
// DO NOT USE!! This is for test purposes ONLY!
{ CVPD_TEST_RECORD, "TEST" },
@@ -182,5 +181,26 @@ class CvpdFacade: public IpVpdFacade
*/
CvpdFacade( );
+ private:
+
+ /**
+ * @brief This function returns a primary and an alternate list of records
+ * that should be copied to pnor. The Alternate list is optional.
+ *
+ * @param[out] o_primaryVpdRecords - Pointer to array of VPD Records to use
+ *
+ * @param[out] o_primaryRecSize - Size of o_primaryVpdRecords array
+ *
+ * @param[out] o_altVpdRecords - Pointer to array of VPD Records to use
+ *
+ * @param[out] o_altRecSize - Size of o_altVpdRecords array
+ *
+ */
+ void getRecordLists(
+ const recordInfo* & o_primaryVpdRecords,
+ uint64_t & o_primaryRecSize,
+ const recordInfo* & o_altVpdRecords,
+ uint64_t & o_altRecSize);
+
};
#endif // __CVPD_H
diff --git a/src/usr/vpd/ipvpd.C b/src/usr/vpd/ipvpd.C
index 3da20b2ec..e148bc970 100644
--- a/src/usr/vpd/ipvpd.C
+++ b/src/usr/vpd/ipvpd.C
@@ -43,6 +43,7 @@
#include <vpd/ipvpdenums.H>
#include "vpd.H"
+#include "cvpd.H"
#include "ipvpd.H"
#include "errlud_vpd.H"
@@ -1336,6 +1337,19 @@ IpVpdFacade::getRecordListSeeprom ( std::list<TocPtRecord> & o_recList,
return err;
}
+ // Get the list of records that should be copied to pnor.
+ // The list of records for this vpd sub class will be the primary list.
+ // If the eeprom is being shared, then their might be an alternate list
+ // to also include.
+ const recordInfo* l_primaryVpdRecords = NULL;
+ uint64_t l_primaryRecSize = 0;
+ const recordInfo* l_altVpdRecords = NULL;
+ uint64_t l_altRecSize = 0;
+ getRecordLists(l_primaryVpdRecords,
+ l_primaryRecSize,
+ l_altVpdRecords,
+ l_altRecSize);
+
offset = le16toh( toc_rec->record_offset ) + 1; // skip 'large resource'
// Read the PT keyword(s) from the VTOC
@@ -1367,20 +1381,36 @@ IpVpdFacade::getRecordListSeeprom ( std::list<TocPtRecord> & o_recList,
vtoc_pt_offset < pt_len;
vtoc_pt_offset += sizeof(TocPtRecord) )
{
+ bool l_found = false;
toc_rec =
reinterpret_cast<TocPtRecord*>(l_buffer + vtoc_pt_offset);
// Save record if on the list for this target
- for ( uint32_t rec = 0; rec < iv_recSize; rec++ )
+ for ( uint32_t rec = 0; rec < l_primaryRecSize; rec++ )
{
if ( memcmp( toc_rec->record_name,
- iv_vpdRecords[rec].recordName,
+ l_primaryVpdRecords[rec].recordName,
RECORD_BYTE_SIZE ) == 0 )
{
o_recList.push_back(*toc_rec);
+ l_found = true;
break;
}
}
+ // if not found, check the alternate list
+ if (!l_found)
+ {
+ for ( uint32_t rec = 0; rec < l_altRecSize; rec++ )
+ {
+ if ( memcmp( toc_rec->record_name,
+ l_altVpdRecords[rec].recordName,
+ RECORD_BYTE_SIZE ) == 0 )
+ {
+ o_recList.push_back(*toc_rec);
+ break;
+ }
+ }
+ }
}
}
@@ -2182,3 +2212,19 @@ void IpVpdFacade::setConfigFlagsHW ( )
iv_configInfo.vpdWriteHW = true;
}
}
+
+// Return the lists of records that should be copied to pnor.
+// The default lists to use are this object's record list and size.
+// No Alternate.
+void IpVpdFacade::getRecordLists(
+ const recordInfo* & o_primaryVpdRecords,
+ uint64_t & o_primaryRecSize,
+ const recordInfo* & o_altVpdRecords,
+ uint64_t & o_altRecSize)
+{
+ o_primaryVpdRecords = iv_vpdRecords;
+ o_primaryRecSize = iv_recSize;
+ o_altVpdRecords = NULL;
+ o_altRecSize = 0;
+}
+
diff --git a/src/usr/vpd/ipvpd.H b/src/usr/vpd/ipvpd.H
index 5cc7bec7e..e4c416238 100644
--- a/src/usr/vpd/ipvpd.H
+++ b/src/usr/vpd/ipvpd.H
@@ -677,7 +677,24 @@ class IpVpdFacade
errlHndl_t checkBufferSize( size_t i_bufferSize,
size_t i_expectedSize,
TARGETING::Target * i_target );
-
+ /**
+ * @brief This function returns a primary and an alternate list of records
+ * that should be copied to pnor. The Alternate list is optional.
+ *
+ * @param[out] o_primaryVpdRecords - Pointer to array of VPD Records to use
+ *
+ * @param[out] o_primaryRecSize - Size of o_primaryVpdRecords array
+ *
+ * @param[out] o_altVpdRecords - Pointer to array of VPD Records to use
+ *
+ * @param[out] o_altRecSize - Size of o_altVpdRecords array
+ *
+ */
+ virtual void getRecordLists(
+ const recordInfo* & o_primaryVpdRecords,
+ uint64_t & o_primaryRecSize,
+ const recordInfo* & o_altVpdRecords,
+ uint64_t & o_altRecSize);
protected: // Variables
@@ -693,6 +710,8 @@ class IpVpdFacade
*/
uint64_t iv_vpdMaxSections;
+
+ public: // Variables
/**
* @brief Pointer to array of VPD Record information
*
@@ -705,6 +724,7 @@ class IpVpdFacade
*/
uint64_t iv_recSize;
+ protected: // Variables
/**
* @brief Pointer to array of VPD Keyword information
*
diff --git a/src/usr/vpd/pvpd.C b/src/usr/vpd/pvpd.C
new file mode 100644
index 000000000..ec6223709
--- /dev/null
+++ b/src/usr/vpd/pvpd.C
@@ -0,0 +1,369 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/vpd/pvpd.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2013,2015 */
+/* [+] 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 */
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include <string.h>
+#include <endian.h>
+#include <trace/interface.H>
+#include <errl/errlentry.H>
+#include <errl/errlmanager.H>
+#include <targeting/common/targetservice.H>
+#include <targeting/common/util.H>
+#include <targeting/common/utilFilter.H>
+#include <devicefw/driverif.H>
+#include <vfs/vfs.H>
+#include <vpd/vpdreasoncodes.H>
+#include <vpd/pvpdenums.H>
+#include <vpd/vpd_if.H>
+#include <i2c/eepromif.H>
+#include <config.h>
+#include "pvpd.H"
+#include "cvpd.H"
+#include "vpd.H"
+
+// ----------------------------------------------
+// Trace definitions
+// ----------------------------------------------
+extern trace_desc_t* g_trac_vpd;
+
+
+// ------------------------
+// Macros for unit testing
+//#define TRACUCOMP(args...) TRACFCOMP(args)
+#define TRACUCOMP(args...)
+//#define TRACSSCOMP(args...) TRACFCOMP(args)
+#define TRACSSCOMP(args...)
+
+namespace PVPD
+{
+ // ----------------------------------------------
+ // Globals
+ // ----------------------------------------------
+ mutex_t g_mutex = MUTEX_INITIALIZER;
+
+
+ /**
+ * @brief This function will perform the steps required to do a read from
+ * the Hostboot PVPD data.
+ *
+ * @param[in] i_opType - Operation Type - See DeviceFW::OperationType in
+ * driververif.H
+ *
+ * @param[in] i_target - Processor Target device
+ *
+ * @param [in/out] io_buffer - Pointer to the data that was read from
+ * the target device. This parameter, when set to NULL, will return
+ * the keyword size value in io_buflen.
+ *
+ * @param [in/out] io_buflen - Length of the buffer to be read or written
+ * to/from the target. This value should indicate the size of the
+ * io_buffer parameter that has been allocated. Being returned it
+ * will indicate the number of valid bytes in the buffer being
+ * returned. This parameter will contain the size of a keyword when
+ * the io_buffer parameter is passed in NULL.
+ *
+ * @param [in] i_accessType - Access Type - See DeviceFW::AccessType in
+ * usrif.H
+ *
+ * @param [in] i_args - This is an argument list for the device driver
+ * framework.
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+ errlHndl_t pvpdRead ( 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 err = NULL;
+ IpVpdFacade::input_args_t args;
+ args.record = ((pvpdRecord)va_arg( i_args, uint64_t ));
+ args.keyword = ((pvpdKeyword)va_arg( i_args, uint64_t ));
+ args.location = ((VPD::vpdCmdTarget)va_arg( i_args, uint64_t ));
+
+ TRACSSCOMP( g_trac_vpd,
+ ENTER_MRK"pvpdRead()" );
+
+ err = Singleton<PvpdFacade>::instance().read(i_target,
+ io_buffer,
+ io_buflen,
+ args);
+
+ return err;
+ }
+
+
+ /**
+ * @brief This function will perform the steps required to do a write to
+ * the Hostboot PVPD data.
+ *
+ * @param[in] i_opType - Operation Type - See DeviceFW::OperationType in
+ * driververif.H
+ *
+ * @param[in] i_target - Processor Target device
+ *
+ * @param [in/out] io_buffer - Pointer to the data that was read from
+ * the target device. It will also be used to contain data to
+ * be written to the device.
+ *
+ * @param [in/out] io_buflen - Length of the buffer to be read or written
+ * to/from the target. This value should indicate the size of the
+ * io_buffer parameter that has been allocated. Being returned it
+ * will indicate the number of valid bytes in the buffer being
+ * returned.
+ *
+ * @param [in] i_accessType - Access Type - See DeviceFW::AccessType in
+ * usrif.H
+ *
+ * @param [in] i_args - This is an argument list for the device driver
+ * framework.
+ *
+ * @return errlHndl_t - NULL if successful, otherwise a pointer to the
+ * error log.
+ */
+ errlHndl_t pvpdWrite ( 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 err = NULL;
+ IpVpdFacade::input_args_t args;
+ args.record = ((pvpdRecord)va_arg( i_args, uint64_t ));
+ args.keyword = ((pvpdKeyword)va_arg( i_args, uint64_t ));
+ args.location = ((VPD::vpdCmdTarget)va_arg( i_args, uint64_t ));
+
+ TRACSSCOMP( g_trac_vpd,
+ ENTER_MRK"pvpdWrite()" );
+
+
+ err = Singleton<PvpdFacade>::instance().write(i_target,
+ io_buffer,
+ io_buflen,
+ args);
+
+ return err;
+ }
+
+ // Register with the routing code
+ DEVICE_REGISTER_ROUTE( DeviceFW::READ,
+ DeviceFW::PVPD,
+ TARGETING::TYPE_NODE,
+ pvpdRead );
+ DEVICE_REGISTER_ROUTE( DeviceFW::WRITE,
+ DeviceFW::PVPD,
+ TARGETING::TYPE_NODE,
+ pvpdWrite );
+
+}; // end namespace PVPD
+
+#if !defined(__HOSTBOOT_RUNTIME)
+// --------------------------------------------------------
+// Presence Detection
+//---------------------------------------------------------
+
+/**
+ * @brief Performs a presence detect operation on a Node card.
+ *
+ * There is no FSI presence detection, just Planar vpd detection.
+ * Presence is always returned as Success (unless the unlikely case of too
+ * small of a buffer passed). A problem with planar EEPROM is logged but
+ * not passed up so that the enclosure and everything inside is not
+ * deconfigured.
+ *
+ * @param[in] i_opType Operation type, see DeviceFW::OperationType
+ * in driverif.H
+ * @param[in] i_target Presence detect target
+ * @param[in/out] io_buffer Read: Pointer to output data storage
+ * Write: Pointer to input data storage
+ * @param[in/out] io_buflen Input: size of io_buffer (in bytes, always 1)
+ * Output: Success = 1, Failure = 0
+ * @param[in] i_accessType DeviceFW::AccessType enum (userif.H)
+ * @param[in] i_args This is an argument list for DD framework.
+ * In this function, there are no arguments.
+ * @return errlHndl_t
+ */
+errlHndl_t nodePresenceDetect(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 = NULL;
+ bool pvpd_present = true;
+
+ if (unlikely(io_buflen < sizeof(bool)))
+ {
+ TRACFCOMP(g_trac_vpd,
+ ERR_MRK "nodePresenceDetect> Invalid data length: %d",
+ io_buflen);
+ /*@
+ * @errortype
+ * @moduleid VPD::VPD_PVPD_PRESENCEDETECT
+ * @reasoncode VPD::VPD_INVALID_LENGTH
+ * @userdata1 Data Length
+ * @devdesc presenceDetect> Invalid data length (!= 1 bytes)
+ */
+ l_errl =
+ new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ VPD::VPD_PVPD_PRESENCEDETECT,
+ VPD::VPD_INVALID_LENGTH,
+ TO_UINT64(io_buflen),
+ true /*SW error*/);
+ io_buflen = 0;
+ return l_errl;
+ }
+
+#if defined(CONFIG_PVPD_READ_FROM_HW) && defined(CONFIG_PVPD_READ_FROM_PNOR)
+ pvpd_present = VPD::pvpdPresent( i_target );
+ if( pvpd_present )
+ {
+ // Check if the VPD data in the PNOR matches the SEEPROM
+ l_errl = VPD::ensureCacheIsInSync( i_target );
+ if( l_errl )
+ {
+ TRACFCOMP(g_trac_vpd,ERR_MRK "nodePresenceDetect>"
+ " Error during ensureCacheIsInSync (PVPD)" );
+ errlCommit( l_errl, FSI_COMP_ID );
+ }
+ }
+ else
+ {
+ TRACFCOMP(g_trac_vpd,
+ ERR_MRK "nodePresenceDetect> failed presence detect");
+
+ // Invalidate PVPD in the PNOR
+ l_errl = VPD::invalidatePnorCache(i_target);
+ if (l_errl)
+ {
+ TRACFCOMP( g_trac_vpd, "Error invalidating PVPD in PNOR" );
+ errlCommit( l_errl, VPD_COMP_ID );
+ }
+ pvpd_present = true;
+ }
+#endif
+
+ // Always return presence.
+ // A returned error deconfigures the node and stops the IPL.
+ memcpy(io_buffer, &pvpd_present, sizeof(pvpd_present));
+ io_buflen = sizeof(pvpd_present);
+
+ return NULL;
+}
+
+// Register as the presence detect for nodes.
+DEVICE_REGISTER_ROUTE(DeviceFW::READ,
+ DeviceFW::PRESENT,
+ TARGETING::TYPE_NODE,
+ nodePresenceDetect);
+#endif
+
+bool VPD::pvpdPresent( TARGETING::Target * i_target )
+{
+ TRACSSCOMP( g_trac_vpd, ENTER_MRK"pvpdPresent()");
+#if(defined( CONFIG_PVPD_READ_FROM_HW ) && !defined( __HOSTBOOT_RUNTIME) )
+
+ return EEPROM::eepromPresence( i_target );
+
+#else
+ return Singleton<PvpdFacade>::instance().hasVpdPresent( i_target,
+ PVPD::OPFR,
+ PVPD::VP );
+#endif
+}
+
+
+//PVPD Class Functions
+/**
+ * @brief Constructor
+ * Planar VPD is included in the Centaur PNOR section.
+ * Including with Centaur vpd minimizes the number of PNOR sections.
+ */
+PvpdFacade::PvpdFacade() :
+IpVpdFacade(CVPD::SECTION_SIZE, // note use of CVPD
+ CVPD::MAX_SECTIONS, // note use of CVPD
+ PVPD::pvpdRecords,
+ (sizeof(PVPD::pvpdRecords)/sizeof(PVPD::pvpdRecords[0])),
+ PVPD::pvpdKeywords,
+ (sizeof(PVPD::pvpdKeywords)/sizeof(PVPD::pvpdKeywords[0])),
+ PNOR::CENTAUR_VPD, // note use of CVPD
+ PVPD::g_mutex,
+ VPD::VPD_WRITE_PLANAR)
+{
+ TRACUCOMP(g_trac_vpd, "PvpdFacade::PvpdFacade> " );
+
+#ifdef CONFIG_PVPD_READ_FROM_PNOR
+ iv_configInfo.vpdReadPNOR = true;
+#else
+ iv_configInfo.vpdReadPNOR = false;
+#endif
+#ifdef CONFIG_PVPD_READ_FROM_HW
+ iv_configInfo.vpdReadHW = true;
+#else
+ iv_configInfo.vpdReadHW = false;
+#endif
+#ifdef CONFIG_PVPD_WRITE_TO_PNOR
+ iv_configInfo.vpdWritePNOR = true;
+#else
+ iv_configInfo.vpdWritePNOR = false;
+#endif
+#ifdef CONFIG_PVPD_WRITE_TO_HW
+ iv_configInfo.vpdWriteHW = true;
+#else
+ iv_configInfo.vpdWriteHW = false;
+#endif
+}
+
+// Retrun lists of records that should be copied to pnor.
+void PvpdFacade::getRecordLists(
+ const recordInfo* & o_primaryVpdRecords,
+ uint64_t & o_primaryRecSize,
+ const recordInfo* & o_altVpdRecords,
+ uint64_t & o_altRecSize)
+{
+ // Always return this object's list
+ o_primaryVpdRecords = iv_vpdRecords;
+ o_primaryRecSize = iv_recSize;
+
+ // If the planar eeprom is being shared with a mem buf,
+ // then return the cvpd list as the alternative record list.
+ // At thip point, if the node is be processed, then the mem buffs
+ // might have not been discovered yet. If cvpd is being cached, then
+ // include the cvpd list as the altnative.
+#ifdef CONFIG_CVPD_READ_FROM_PNOR
+ o_altVpdRecords = Singleton<CvpdFacade>::instance().iv_vpdRecords;
+ o_altRecSize = Singleton<CvpdFacade>::instance().iv_recSize;
+#else
+ o_altVpdRecords = NULL;
+ o_altRecSize = 0;
+#endif
+}
+
diff --git a/src/usr/vpd/pvpd.H b/src/usr/vpd/pvpd.H
new file mode 100644
index 000000000..092dd45f7
--- /dev/null
+++ b/src/usr/vpd/pvpd.H
@@ -0,0 +1,149 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/vpd/pvpd.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2013,2015 */
+/* [+] 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 __PVPD_H
+#define __PVPD_H
+
+
+/**
+ * @file pvpd.H
+ *
+ * @brief Provides the interfaces for the PVPD device driver
+ *
+ */
+
+// ----------------------------------------------
+// Includes
+// ----------------------------------------------
+#include <errl/errlentry.H>
+#include <vpd/pvpdenums.H>
+
+#include "ipvpd.H"
+#include <config.h>
+
+namespace PVPD
+{
+
+ /**
+ * @brief Conversion of PVPD Records to corresponding character
+ * representation.
+ */
+ const IpVpdFacade::recordInfo pvpdRecords[] =
+ {
+ // -------------------------------------------------------------------
+ // NOTE: This list must remain an ordered list! There will be a
+ // testcase that checks this. When adding new entries to the
+ // list, be sure that the keyword in each entry (value 0)
+ // are in ascending order.
+ // -------------------------------------------------------------------
+ { VINI, "VINI" },
+ { OSYS, "OSYS" },
+ { OPFR, "OPFR" },
+ { VNDR, "VNDR" },
+ // -------------------------------------------------------------------
+ // DO NOT USE!! This is for test purposes ONLY!
+ { PVPD_TEST_RECORD, "TEST" },
+ // -------------------------------------------------------------------
+ };
+
+ /**
+ * @brief Conversion of PVPD Keywords to corresponding character
+ * representation.
+ */
+ const IpVpdFacade::keywordInfo pvpdKeywords[] =
+ {
+ // -------------------------------------------------------------------
+ // NOTE: This list must remain an ordered list! There will be a
+ // testcase that checks this. When adding new entries to
+ // the list, be sure that the keyword in each entry (value 0)
+ // are in ascending order.
+ // -------------------------------------------------------------------
+ { pdI, "#I" },
+ { B3, "B3" },
+ { B4, "B4" },
+ { B7, "B7" },
+ { CC, "CC" },
+ { CE, "CE" },
+ { CT, "CT" },
+ { DR, "DR" },
+ { ET, "ET" },
+ { FN, "FN" },
+ { HE, "HE" },
+ { HW, "HW" },
+ { IN, "IN" },
+ { MM, "MM" },
+ { PF, "PF" },
+ { PN, "PN" },
+ { RT, "RT" },
+ { SN, "SN" },
+ { SS, "SS" },
+ { VD, "VD" },
+ { VN, "VN" },
+ { VP, "VP" },
+ { VS, "VS" },
+ { VZ, "VZ" },
+
+ // -------------------------------------------------------------------
+ // DO NOT USE!! This is for test purposes ONLY!
+ { PVPD_TEST_KEYWORD, "XX" },
+ // -------------------------------------------------------------------
+
+ //Common ipvpd
+ { FULL_RECORD, "FL"},
+ };
+
+}; // end PVPD namespace
+
+class PvpdFacade: public IpVpdFacade
+{
+ public:
+
+ /**
+ * @brief Constructor
+ */
+ PvpdFacade( );
+
+ private:
+
+ /**
+ * @brief This function returns a primary and an alternate list of records
+ * that should be copied to pnor. The Alternate list is optional.
+ *
+ * @param[out] o_primaryVpdRecords - Pointer to array of VPD Records to use
+ *
+ * @param[out] o_primaryRecSize - Size of o_primaryVpdRecords array
+ *
+ * @param[out] o_altVpdRecords - Pointer to array of VPD Records to use
+ *
+ * @param[out] o_altRecSize - Size of o_altVpdRecords array
+ *
+ */
+ void getRecordLists(
+ const recordInfo* & o_primaryVpdRecords,
+ uint64_t & o_primaryRecSize,
+ const recordInfo* & o_altVpdRecords,
+ uint64_t & o_altRecSize);
+
+};
+#endif // __PVPD_H
diff --git a/src/usr/vpd/vpd.C b/src/usr/vpd/vpd.C
index 9b4e1f82c..3656696c4 100755
--- a/src/usr/vpd/vpd.C
+++ b/src/usr/vpd/vpd.C
@@ -34,10 +34,9 @@
#include "vpd.H"
#include "mvpd.H"
#include "cvpd.H"
+#include "pvpd.H"
#include "spd.H"
-
-
// ----------------------------------------------
// Trace definitions
// ----------------------------------------------
@@ -456,6 +455,13 @@ errlHndl_t ensureCacheIsInSync ( TARGETING::Target * i_target )
l_keywordPN = CVPD::VP;
l_keywordSN = CVPD::VS;
}
+ else if( l_type == TARGETING::TYPE_NODE )
+ {
+ l_ipvpd = &(Singleton<PvpdFacade>::instance());
+ l_record = PVPD::OPFR;
+ l_keywordPN = PVPD::VP;
+ l_keywordSN = PVPD::VS;
+ }
else if( l_type == TARGETING::TYPE_DIMM )
{
// SPD does not have a singleton instance
@@ -487,7 +493,8 @@ errlHndl_t ensureCacheIsInSync ( TARGETING::Target * i_target )
do
{
// Make sure we are comparing the correct pn/sn for CVPD
- if( l_type == TARGETING::TYPE_MEMBUF )
+ if( ( l_type == TARGETING::TYPE_MEMBUF ) ||
+ ( l_type == TARGETING::TYPE_NODE ) )
{
bool l_zeroPN;
l_err = l_ipvpd->cmpSeepromToZero( i_target,
@@ -523,6 +530,7 @@ errlHndl_t ensureCacheIsInSync ( TARGETING::Target * i_target )
// Compare the Part Numbers in PNOR/SEEPROM
bool l_matchPN = false;
if( ( l_type == TARGETING::TYPE_PROC ) ||
+ ( l_type == TARGETING::TYPE_NODE ) ||
( l_type == TARGETING::TYPE_MEMBUF ) )
{
l_err = l_ipvpd->cmpPnorToSeeprom( i_target,
@@ -577,7 +585,8 @@ errlHndl_t ensureCacheIsInSync ( TARGETING::Target * i_target )
HWAS::markTargetChanged(i_target);
// Load the PNOR data from the SEEPROM
- if( ( l_type == TARGETING::TYPE_PROC ) ||
+ if( ( l_type == TARGETING::TYPE_PROC ) ||
+ ( l_type == TARGETING::TYPE_NODE ) ||
( l_type == TARGETING::TYPE_MEMBUF ) )
{
l_err = l_ipvpd->loadPnor( i_target );
diff --git a/src/usr/vpd/vpd.H b/src/usr/vpd/vpd.H
index 9c39a7f3d..e6cada716 100644
--- a/src/usr/vpd/vpd.H
+++ b/src/usr/vpd/vpd.H
@@ -50,6 +50,7 @@ enum VPD_MSG_TYPE
VPD_WRITE_DIMM = 0x00C1, //< DIMM SPD
VPD_WRITE_PROC = 0x00C2, //< Processor MVPD
VPD_WRITE_MEMBUF = 0x00C3, //< Centaur FRU VPD
+ VPD_WRITE_PLANAR = 0x00C4, //< Planar VPD
};
/**
diff --git a/src/usr/vpd/vpd.mk b/src/usr/vpd/vpd.mk
index 9f857554e..65d22e344 100644
--- a/src/usr/vpd/vpd.mk
+++ b/src/usr/vpd/vpd.mk
@@ -5,7 +5,9 @@
#
# OpenPOWER HostBoot Project
#
-# COPYRIGHT International Business Machines Corp. 2013,2014
+# Contributors Listed Below - COPYRIGHT 2013,2015
+# [+] 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.
@@ -24,5 +26,6 @@
OBJS += ipvpd.o
OBJS += mvpd.o
OBJS += cvpd.o
+OBJS += pvpd.o
OBJS += spd.o
OBJS += errlud_vpd.o
OpenPOWER on IntegriCloud