Habanero Updates for SL
diff --git a/openpower/package/hostboot/hostboot-0015-Add-PNOR-Version-Information-to-IPMI-Fru-Inventory.patch b/openpower/package/hostboot/hostboot-0015-Add-PNOR-Version-Information-to-IPMI-Fru-Inventory.patch
new file mode 100644
index 0000000..83dca55
--- /dev/null
+++ b/openpower/package/hostboot/hostboot-0015-Add-PNOR-Version-Information-to-IPMI-Fru-Inventory.patch
@@ -0,0 +1,351 @@
+From 5bda70dc5e135261f5393858959056b44332885b Mon Sep 17 00:00:00 2001
+From: Bill Hoffa <wghoffa@us.ibm.com>
+Date: Mon, 30 Mar 2015 15:11:28 -0500
+Subject: [PATCH 6/7] Add PNOR Version Information to IPMI Fru Inventory
+
+Change-Id: Ib49fe67e9c6631b2b7ea0005e692c9aea6d84057
+RTC:123353
+(cherry picked from commit 90f8e938932e867283e28cade6741b6bf968602c)
+---
+ src/usr/ipmi/ipmifruinv.C | 207 +++++++++++++++++++++
+ src/usr/ipmi/ipmifruinvprvt.H | 47 +++++
+ .../targeting/common/xmltohb/attribute_types.xml | 8 +
+ src/usr/targeting/common/xmltohb/target_types.xml | 1 +
+ 4 files changed, 263 insertions(+)
+
+diff --git a/src/usr/ipmi/ipmifruinv.C b/src/usr/ipmi/ipmifruinv.C
+index c6c7a30..b376ebf 100644
+--- a/src/usr/ipmi/ipmifruinv.C
++++ b/src/usr/ipmi/ipmifruinv.C
+@@ -36,6 +36,7 @@
+ #include "ipmifru.H"
+ #include "ipmifruinvprvt.H"
+ #include <stdio.h>
++#include <pnor/pnorif.H>
+
+ extern trace_desc_t * g_trac_ipmi;
+
+@@ -83,6 +84,10 @@ IpmiFruInv *IpmiFruInv::Factory(TARGETING::TargetHandleList i_targets,
+ // @todo-RTC:117702
+ l_fru = new backplaneIpmiFruInv(l_target, i_targets, i_updateData);
+ break;
++ case TARGETING::TYPE_SYS:
++ // Use sys target for setting System Firmware Info
++ l_fru = new systemFwIpmiFruInv(l_target);
++ break;
+ default:
+ assert(false,
+ "IpmiFruInv::Factory: No support for target type given: [%08x]",
+@@ -926,6 +931,199 @@ errlHndl_t backplaneIpmiFruInv::addVpdData(std::vector<uint8_t> &io_data,
+ return l_errl;
+ }
+
++//##############################################################################
++systemFwIpmiFruInv::systemFwIpmiFruInv( TARGETING::TargetHandle_t i_target )
++ :IpmiFruInv(i_target)
++{
++
++};
++
++errlHndl_t systemFwIpmiFruInv::buildInternalUseArea(std::vector<uint8_t>
++ &io_data)
++{
++ //This section not needed for proc type
++ return IpmiFruInv::buildEmptyArea(io_data);
++}
++
++errlHndl_t systemFwIpmiFruInv::buildChassisInfoArea(std::vector<uint8_t>
++ &io_data)
++{
++ //This section not needed for system firmware type
++ return IpmiFruInv::buildEmptyArea(io_data);
++}
++
++errlHndl_t systemFwIpmiFruInv::buildBoardInfoArea(std::vector<uint8_t> &io_data)
++{
++ //This section not needed for system firmware type
++ return IpmiFruInv::buildEmptyArea(io_data);
++}
++
++errlHndl_t systemFwIpmiFruInv::buildProductInfoArea(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);
++
++ uint8_t l_data[] = {IPMIFRUINV::TYPELENGTH_BYTE_ASCII + 3,'I','B','M',
++ IPMIFRUINV::TYPELENGTH_BYTE_ASCII + 18, 'O','p','e',
++ 'n','P','O','W','E','R',' ','F','i','r','m','w','a',
++ 'r','e', IPMIFRUINV::TYPELENGTH_BYTE_NULL};
++
++ io_data.insert( io_data.end(),
++ &l_data[0],
++ &l_data[0] + (uint8_t(sizeof(l_data) / sizeof(uint8_t))));
++
++ //Get PNOR Version Here
++ PNOR::SectionInfo_t l_pnorInfo;
++ l_errl = getSectionInfo( PNOR::VERSION , l_pnorInfo);
++ if (l_errl) { break; }
++
++ uint8_t* l_versionData = reinterpret_cast<uint8_t*>( l_pnorInfo.vaddr );
++ //Total Bytes in PNOR Version String
++ uint8_t l_numBytes = 0;
++ uint8_t l_curOffset = 0;
++
++ //Total Number of fields needed to print PNOR Version String
++ uint8_t l_numFields = 0;
++ bool l_clearStandardFields = true;
++
++ //First determine number of bytes in PNOR Version string
++ // with the caveat there is a max record size allowed, so
++ // the string will be cut off if too long
++ //Also, remove whitespace/newline chars
++ while ((l_numBytes < IPMIFRUINV::MAX_RECORD_SIZE -
++ (uint8_t(sizeof(l_data) / sizeof(uint8_t))) -
++ IPMIFRUINV::COMMON_HEADER_FORMAT_SIZE - 8)
++ && (((char)(l_versionData[l_numBytes])) != '\0'))
++ {
++
++ if (((char)(l_versionData[l_numBytes])) == '\n')
++ {
++
++ if (l_numBytes > l_curOffset)
++ {
++ //Add on size of this field to the data buffer
++ io_data.push_back(
++ IPMIFRUINV::TYPELENGTH_BYTE_ASCII
++ + (l_numBytes-l_curOffset));
++
++ io_data.insert(io_data.end(),
++ &l_versionData[0]+(l_curOffset),
++ &l_versionData[0]+(l_numBytes));
++ }
++
++ //Null data for standard fields needs to be indicated once after
++ // the first segment of data is displayed to match the
++ // ipmi fru spec
++ if (l_clearStandardFields)
++ {
++ //Add Empty Asset Tag
++ io_data.push_back(uint8_t(0));
++ //FRU File ID - Empty
++ io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
++ io_data.push_back(uint8_t(0)); // Empty FRU File ID bytes
++ l_clearStandardFields = false;
++ }
++
++ //Increment past the newline char
++ l_curOffset = l_numBytes + 1;
++ }
++ l_numBytes++;
++ }
++
++ if (l_curOffset == 0)
++ {
++ //Calculate the number of fields required to display this data
++ // given only MAX_ASCII_FIELD_SIZE bytes can be in any one given
++ // IPMI fru inventory field
++ l_numFields = l_numBytes / IPMIFRUINV::MAX_ASCII_FIELD_SIZE;
++ if (l_numBytes % IPMIFRUINV::MAX_ASCII_FIELD_SIZE)
++ {
++ l_numFields += 1;
++ }
++
++ //Count by number of fields, adding the data to the buffer as
++ // we go.
++ for (uint8_t i=0; i < l_numFields; i++)
++ {
++ //Determine the data size for this particular field
++ uint8_t l_dataSize=IPMIFRUINV::MAX_ASCII_FIELD_SIZE;
++ if (i == l_numFields - 1)
++ {
++ l_dataSize = l_numBytes -
++ (i * IPMIFRUINV::MAX_ASCII_FIELD_SIZE);
++ }
++
++ //Add on size of this field to the data buffer
++ io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_ASCII
++ + l_dataSize);
++
++ //Insert this segment of version string data
++ io_data.insert(io_data.end(),
++ &l_versionData[0]+(i * IPMIFRUINV::MAX_ASCII_FIELD_SIZE),
++ &l_versionData[0]+(i * IPMIFRUINV::MAX_ASCII_FIELD_SIZE)
++ +l_dataSize);
++
++ //Null data for standard fields needs to be indicated once after
++ // the first segment of data is displayed to match the
++ // ipmi fru spec
++ if (l_clearStandardFields)
++ {
++ //Add Empty Asset Tag
++ io_data.push_back(uint8_t(0));
++ //FRU File ID - Empty
++ io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
++ //io_data.push_back(uint8_t(0)); // Empty FRU File ID bytes
++ l_clearStandardFields = false;
++ }
++
++ }
++ }
++ else
++ {
++ if (l_numBytes > l_curOffset)
++ {
++ io_data.push_back( IPMIFRUINV::TYPELENGTH_BYTE_ASCII
++ + (l_numBytes-l_curOffset));
++
++ io_data.insert(io_data.end(),
++ &l_versionData[0]+(l_curOffset),
++ &l_versionData[0]+(l_numBytes));
++ }
++
++ }
++
++ if (l_clearStandardFields)
++ {
++ //Add Asset Tag
++ io_data.push_back(uint8_t(0)); //No Asset Tag needed - O bytes
++ //FRU File ID - Empty
++ io_data.push_back(IPMIFRUINV::TYPELENGTH_BYTE_NULL);
++ //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);
++
++ return l_errl;
++}
++
++errlHndl_t systemFwIpmiFruInv::buildMultiRecordInfoArea(std::vector<uint8_t>
++ &io_data)
++{
++ //This section not needed for system firmware type
++ return IpmiFruInv::buildEmptyArea(io_data);
++}
++
++
++
+ void IpmiFruInv::addEcidData(const TARGETING::TargetHandle_t& i_target,
+ const TARGETING::ATTR_ECID_type& i_ecidInfo,
+ std::vector<uint8_t> &io_data)
+@@ -993,6 +1191,15 @@ void IPMIFRUINV::setData(bool i_updateData)
+ IPMIFRUINV::gatherClearData(pSys, frusToClear);
+ }
+
++ //Get System FW FRU_ID if available
++ uint32_t l_systemFwFruId;
++ bool hasSystemFwFruId =
++ pSys->tryGetAttr<TARGETING::ATTR_BMC_FRU_ID>(l_systemFwFruId);
++ if (hasSystemFwFruId)
++ {
++ l_potentialFrus.push_back(std::make_pair(pSys, l_systemFwFruId));
++ }
++
+ // Find list of all target types that may need a fru inv. record set
+ IPMIFRUINV::gatherSetData(pSys, frusToClear,
+ l_potentialFrus, i_updateData);
+diff --git a/src/usr/ipmi/ipmifruinvprvt.H b/src/usr/ipmi/ipmifruinvprvt.H
+index 2573a84..468a47f 100644
+--- a/src/usr/ipmi/ipmifruinvprvt.H
++++ b/src/usr/ipmi/ipmifruinvprvt.H
+@@ -42,6 +42,8 @@ namespace IPMIFRUINV
+ COMMON_HEADER_FORMAT_SIZE = 8, //size in bytes
+ DEFAULT_CHASSIS_TYPE = 0x05,
+ DEFAULT_FRU_OFFSET = 0,
++ MAX_ASCII_FIELD_SIZE = 0x3F, //size in bytes
++ MAX_RECORD_SIZE = 0xFF, //size in bytes
+ };
+ };
+
+@@ -460,4 +462,49 @@ class backplaneIpmiFruInv : public IpmiFruInv
+
+ };
+
++//Child class for building up System Firwmare Fru Inventory Record Data
++class systemFwIpmiFruInv : public IpmiFruInv
++{
++
++ public:
++ /**
++ * @brief Constructor
++ *
++ * @param[in] TargetHandle_t, Handle to target for which
++ * to get relevant IPMI FRU Data from
++ */
++ systemFwIpmiFruInv( TARGETING::TargetHandle_t i_target);
++
++ /**
++ * @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);
++
++};
++
+ #endif
+diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml
+index c961ebe..bbf02dd 100644
+--- a/src/usr/targeting/common/xmltohb/attribute_types.xml
++++ b/src/usr/targeting/common/xmltohb/attribute_types.xml
+@@ -11425,6 +11425,14 @@ firmware notes: Platforms should initialize this attribute to AUTO (0)</descript
+ </attribute>
+
+ <attribute>
++ <id>BMC_FRU_ID</id>
++ <description>BMC FRU ID attribute for node class</description>
++ <simpleType><uint32_t><default>0</default></uint32_t></simpleType>
++ <persistency>non-volatile</persistency>
++ <readable/>
++</attribute>
++
++<attribute>
+ <id>PLCK_IPL_ATTR_OVERRIDES_EXIST</id>
+ <description>
+ Set to 1 by HWSV to indicate that attribute overrides exist in a PLCK IPL
+diff --git a/src/usr/targeting/common/xmltohb/target_types.xml b/src/usr/targeting/common/xmltohb/target_types.xml
+index 6dc4e58..b4b9a30 100644
+--- a/src/usr/targeting/common/xmltohb/target_types.xml
++++ b/src/usr/targeting/common/xmltohb/target_types.xml
+@@ -305,6 +305,7 @@
+ <attribute><id>MNFG_TH_CEN_L4_CACHE_CES</id></attribute>
+ <attribute><id>OPT_MEMMAP_GROUP_POLICY</id></attribute>
+ <attribute><id>FRU_ID</id></attribute>
++ <attribute><id>BMC_FRU_ID</id></attribute>
+ </targetType>
+
+ <targetType>
+--
+1.8.2.2
+