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
+