summaryrefslogtreecommitdiffstats
path: root/src/usr/hdat
diff options
context:
space:
mode:
authornagurram-in <nagendra.g@in.ibm.com>2017-01-13 16:09:22 -0600
committerWilliam G. Hoffa <wghoffa@us.ibm.com>2017-03-27 17:06:21 -0400
commit27f352e4a1e3a695fa6cde169f4637fce647e10b (patch)
treefb761a70067d374981e926499167ff3a9b7d600c /src/usr/hdat
parent8ae9a2c137ebc771ed1ad34c24d93f55d508e175 (diff)
downloadtalos-hostboot-27f352e4a1e3a695fa6cde169f4637fce647e10b.tar.gz
talos-hostboot-27f352e4a1e3a695fa6cde169f4637fce647e10b.zip
IPMI structure port to master
Change-Id: Ica8b6a87612d961e337a164d8c67d3f6531e118e Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/34869 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Jayashankar Padath <jayashankar.padath@in.ibm.com> Reviewed-by: Elizabeth K. Liner <eliner@us.ibm.com> Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com>
Diffstat (limited to 'src/usr/hdat')
-rw-r--r--src/usr/hdat/hdatipmi.C266
-rw-r--r--src/usr/hdat/hdatipmi.H227
-rwxr-xr-xsrc/usr/hdat/hdatspiraS.C17
-rwxr-xr-xsrc/usr/hdat/hdatspiraS.H5
-rw-r--r--src/usr/hdat/makefile1
5 files changed, 513 insertions, 3 deletions
diff --git a/src/usr/hdat/hdatipmi.C b/src/usr/hdat/hdatipmi.C
new file mode 100644
index 000000000..d0bf785dd
--- /dev/null
+++ b/src/usr/hdat/hdatipmi.C
@@ -0,0 +1,266 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hdat/hdatipmi.C $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] 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 <sys/mm.h>
+#include <sys/mmio.h>
+#include <hdat/hdat.H>
+#include <string.h>
+#include <targeting/common/util.H>
+#include <targeting/common/target.H>
+#include <util/align.H>
+#include "hdatipmi.H"
+#include "hdatutil.H"
+#include <ipmi/ipmisensor.H>
+
+using namespace TARGETING;
+using namespace SENSOR;
+
+namespace HDAT
+{
+extern trace_desc_t *g_trac_hdat;
+
+uint32_t HdatIpmi::cv_actualCnt = 0;
+
+
+
+
+
+/*******************************************************************************
+* IPMI Constructor
+* IPMI sensor data structure is pretty simple with only 2 internal data pointers.
+* But each of those data pointers are arrays by itself.( FRU sensor and LED sensor)
+* In the constructor we initialize all the member variables including the
+* sensor vectors as those are needed to calculate the whole struct size
+*******************************************************************************/
+HdatIpmi::HdatIpmi(errlHndl_t &o_errlHndl, const hdatMsAddr_t &i_msAddr):
+ HdatHdif(o_errlHndl, HDAT_IPMI_STRUCT_NAME,
+ HDAT_IPMI_DA_LAST, cv_actualCnt++, HDAT_NO_CHILD,
+ HDAT_IPMI_DATA_VERSION),iv_ipmiDataSize(0),
+ iv_ipmiData(NULL)
+{
+ HDAT_ENTER();
+ errlHndl_t l_errl = NULL;
+ do{
+
+ // Populating the FRU sensor and LED sensor vectors.
+ // Filter out all targets and loop them through to fill the FRU and LED sensor arrays.
+
+ TARGETING::TargetService & l_targetService = TARGETING::targetService();
+ TARGETING::PredicateHwas l_predHwas;
+ l_predHwas.present(true);
+
+ TARGETING::PredicateCTM l_procFilter(TARGETING::CLASS_CHIP,
+ TARGETING::TYPE_PROC);
+
+ TARGETING::PredicateCTM l_sysFilter(TARGETING::CLASS_SYS,
+ TARGETING::TYPE_SYS);
+
+ TARGETING::PredicateCTM l_nodeFilter(TARGETING::CLASS_ENC,
+ TARGETING::TYPE_NODE);
+
+ TARGETING::PredicateCTM l_dimmFilter(TARGETING::CLASS_LOGICAL_CARD,
+ TARGETING::TYPE_DIMM);
+
+ TARGETING::PredicatePostfixExpr l_presentTargExpr;
+ l_presentTargExpr.push(&l_procFilter).push(&l_sysFilter).Or().
+ push(&l_nodeFilter).Or().push(&l_dimmFilter).Or().
+ push(&l_predHwas).And();
+
+ TARGETING::TargetRangeFilter l_targFilter(
+ l_targetService.begin(),
+ l_targetService.end(),
+ &l_presentTargExpr);
+
+ for(; l_targFilter; ++l_targFilter)
+ {
+#ifdef CONFIG_BMC_IPMI
+ // Create a new array entry and push it to FRU/LED sensor vector
+ hdatIPMIFRUSensorMapEntry_t l_fruEntry;
+ uint8_t l_sensorType = 0;
+ uint8_t l_eventReadingType = 0;
+ l_fruEntry.SLCAIndex = (*l_targFilter)->getAttr<ATTR_SLCA_INDEX>();
+ l_fruEntry.IPMISensorID = getFaultSensorNumber(*l_targFilter);
+ l_errl = SensorBase::getSensorType(l_fruEntry.IPMISensorID,
+ l_sensorType, l_eventReadingType);
+ if(l_errl == NULL)
+ {
+ l_fruEntry.IPMISensorType = l_sensorType;
+ }
+ else
+ {
+ HDAT_ERR(" Error in getsensor type");
+ break;
+ }
+ iv_ipmiFruEntry.push_back(l_fruEntry);
+#endif
+ }
+ iv_ipmiDataSize = sizeof(hdatHDIF_t)+
+ HDAT_IPMI_PADDING +
+ ( sizeof(hdatHDIFDataHdr_t) * HDAT_IPMI_NUM_DATA_PTRS)+
+ ( sizeof(hdatIPMIFRUSensorMapEntry_t) * iv_ipmiFruEntry.size())+
+ ( sizeof(hdatIPMILEDSensorMapEntry_t) * iv_ipmiLedEntry.size())+
+ ( 2 * sizeof(uint32_t));
+
+ // Copy the input phy address to this object member variable
+ iv_msAddr = ((uint64_t) i_msAddr.hi << 32) | i_msAddr.lo;
+
+ // Allocate space and get virt addr with mem map
+ void *l_virt_addr = mm_block_map (
+ reinterpret_cast<void*>(ALIGN_PAGE_DOWN(iv_msAddr)),
+ (ALIGN_PAGE(iv_ipmiDataSize)+ PAGESIZE));
+ iv_ipmiData = static_cast<uint8_t*>(l_virt_addr) +
+ (iv_msAddr - ALIGN_PAGE_DOWN(iv_msAddr));
+
+ // initializing the space to zero
+ memset(iv_ipmiData , 0x0, iv_ipmiDataSize);
+
+ }while(0);
+ o_errlHndl = l_errl;
+
+ HDAT_EXIT();
+}
+
+/*******************************************************************************
+* setIpmiData : Sets all the ipmi data in mainstore pointed by passed in virtaddr
+*******************************************************************************/
+
+void HdatIpmi::setIpmiData()
+{
+ HDAT_ENTER();
+
+ // Update size and ofset of internal data pointers in HDif int dptr section.
+ this->addData(HDAT_IPMI_FRU_SENSOR_MAPPING,
+ (sizeof(hdatIPMIFRUSensorMapEntry_t) * iv_ipmiFruEntry.size()) + sizeof(uint32_t));
+ this->addData(HDAT_IPMI_LED_SENSOR_ID_MAPPING,
+ (sizeof(hdatIPMILEDSensorMapEntry_t) * iv_ipmiLedEntry.size()) + sizeof(uint32_t));
+
+ // Set the HDIF header data
+ iv_ipmiData = this->setHdif(iv_ipmiData);
+
+ // Add the padding before adding int data pointers. ( Refer Spec)
+ this->align();
+
+ // Each internal data pointer has number of array elements followed by
+ // array data.Hence fill the array size first.
+
+ uint32_t l_ipmiFruArraySize = iv_ipmiFruEntry.size();
+ memcpy( iv_ipmiData, &l_ipmiFruArraySize, sizeof(uint32_t));
+ iv_ipmiData+=sizeof(uint32_t);
+
+ // Lets fillup array data.
+ if(iv_ipmiFruEntry.size() > 0)
+ {
+ memcpy(iv_ipmiData, &iv_ipmiFruEntry[0],
+ sizeof(hdatIPMIFRUSensorMapEntry_t) * iv_ipmiFruEntry.size());
+ iv_ipmiData += sizeof(hdatIPMIFRUSensorMapEntry_t) * iv_ipmiFruEntry.size();
+ }
+
+
+ uint32_t l_ipmiLedArraySize = iv_ipmiLedEntry.size();
+ memcpy( iv_ipmiData, &l_ipmiLedArraySize, sizeof(uint32_t));
+ iv_ipmiData+=sizeof(uint32_t);
+ if(iv_ipmiLedEntry.size() > 0)
+ {
+ memcpy(iv_ipmiData, &iv_ipmiLedEntry[0],
+ sizeof(hdatIPMILEDSensorMapEntry_t) * iv_ipmiLedEntry.size());
+ iv_ipmiData += sizeof(hdatIPMILEDSensorMapEntry_t) * iv_ipmiLedEntry.size();
+ }
+
+ HDAT_EXIT();
+}
+
+
+/***********************************************************
+* getIpmiEntrySize() : returns size of whole ipmi structure
+************************************************************/
+uint32_t HdatIpmi::getIpmiEntrySize()
+{
+ return iv_ipmiDataSize;
+}
+
+
+/*******************************************************************************
+* hdatLoadIpmi : API called by SPiraS for ipmi data loading.
+ *******************************************************************************/
+
+
+errlHndl_t hdatLoadIpmi(const hdatMsAddr_t &i_msAddr,uint32_t &o_size, uint32_t &o_count)
+{
+ HDAT_ENTER();
+ errlHndl_t l_errl;
+ do{
+ HdatIpmi l_hdatIpmi(l_errl,i_msAddr);
+ if(l_errl != NULL)
+ {
+ HDAT_ERR(" error in constructor");
+ break;
+ }
+ l_hdatIpmi.setIpmiData();
+ o_size = l_hdatIpmi.getIpmiEntrySize();
+ o_count= HdatIpmi::cv_actualCnt;
+ }while(0);
+ HDAT_EXIT();
+ return(l_errl);
+}
+
+
+
+/** @brief See the prologue in hdathdatspsubsys.H
+ */
+HdatIpmi::~HdatIpmi()
+{
+ errlHndl_t o_errlHndl=NULL;
+
+ HDAT_ENTER();
+
+ // Free the memory allocated for filling this entry.
+ int rc=0;
+ rc = mm_block_unmap(reinterpret_cast<void*>(
+ ALIGN_PAGE_DOWN((uint64_t)iv_ipmiData)));
+ if( rc != 0)
+ {
+ /*@
+ * @errortype
+ * @moduleid HDAT::MOD_HDAT_IPMI_DTOR
+ * @reasoncode HDAT::RC_DEV_MAP_FAIL
+ * @devdesc Unmap a mapped region failed
+ * @custdesc Firmware encountered an internal error.
+ */
+ hdatBldErrLog(o_errlHndl,
+ HDAT::MOD_HDAT_IPMI_DTOR,
+ RC_DEV_MAP_FAIL,
+ 0,0,0,0,
+ ERRORLOG::ERRL_SEV_UNRECOVERABLE,
+ HDAT_VERSION1,
+ true);
+ }
+
+ HDAT_EXIT();
+ return;
+}
+
+
+} // end namespace
+
+
diff --git a/src/usr/hdat/hdatipmi.H b/src/usr/hdat/hdatipmi.H
new file mode 100644
index 000000000..737ce4097
--- /dev/null
+++ b/src/usr/hdat/hdatipmi.H
@@ -0,0 +1,227 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hdat/hdatipmi.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
+/* [+] 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 */
+/**
+ * @file hdatipmi.H
+ *
+ * @brief This file contains the class definition for the ipmi sensor data
+ *
+ */
+
+#ifndef HDATIPMI_H
+#define HDATIPMI_H
+
+/*--------------------------------------------------------------------------*/
+/* Includes */
+/*--------------------------------------------------------------------------*/
+#include <stdint.h> // standard types
+#include <hdat/hdat.H> // HDAT header type definitions
+#include "hdathdif.H" // HdatHdif base class definition
+#include <hdat/hdat_reasoncodes.H>
+
+namespace HDAT
+{
+
+/*--------------------------------------------------------------------------*/
+/* Type definitions */
+/*--------------------------------------------------------------------------*/
+
+// The number of data pointers in hdatDataPtrs (defined in hdatipmi.C)
+#define HDAT_IPMI_NUM_DATA_PTRS 2
+#define HDAT_IPMI_DATA_VERSION 0x0010
+#define HDAT_IPMI_PADDING 16
+
+/** @brief eye catcher for the HDIF header for the IPMI data area*/
+const char HDAT_IPMI_STRUCT_NAME[] = "FRUSE ";
+
+/** @enum hdatDataPtrs
+ * Enumeration which defines the data sections of the IPMI data
+ */
+enum hdatIPMIDataPtrs
+{
+ HDAT_IPMI_FRU_SENSOR_MAPPING = 0,
+ HDAT_IPMI_LED_SENSOR_ID_MAPPING = 1,
+ HDAT_IPMI_DA_LAST = 2,
+};
+
+struct hdatIPMIFRUSensorMapEntry_t
+{
+ uint32_t SLCAIndex;
+ uint8_t IPMISensorType;
+ uint8_t IPMISensorID;
+ uint16_t Reserved;
+}__attribute__ ((packed));
+
+struct hdatIPMILEDSensorMapEntry_t
+{
+ char LEDLocCode[80];
+ uint8_t IPMISensorID;
+ union {
+ uint8_t value;
+ struct {
+ uint8_t FaultSupported:1;
+ uint8_t BllinkSupported:1;
+ uint8_t Reserved1:2;
+ uint8_t Blue:1;
+ uint8_t Amber:1;
+ uint8_t Green:1;
+ uint8_t Reserved2:1;
+ }LEDCaps;
+ } Capabilities;
+ uint16_t Reserved;
+}__attribute__ ((packed));
+
+
+/** @brief Defines the IPMI.
+ */
+struct hdatIPMIData_t
+{
+ hdatHDIF_t hdatHdr;
+ hdatHDIFDataHdr_t hdatIPMIIntData[HDAT_IPMI_DA_LAST];
+ uint8_t hdatpadding[16];
+} __attribute__ ((packed));
+
+
+
+/*----------------------------------------------------------------------------*/
+/* C++ class definition */
+/*----------------------------------------------------------------------------*/
+
+/** Begin Class Description
+ *
+ * @brief The HdatIpmiData class is used to construct the IPMI Sensor data object.
+ *
+ * Description: This class defines a specialized object. It is not intended
+ * that any component can create an object of this type.
+ *
+ * The real purpose of the object is to create the IPMI sensor data
+ * for all the FRU's in an array format as defined
+ * by the PHYP Initialization architecture.
+ *
+ * End Class Description
+ */
+class HdatIpmi : public HdatHdif
+{
+ public:
+ /**
+ * @brief Construct an HdatIpmiData object
+ *
+ * This is the constructor for the HdatIpmiData object.
+ *
+ * @pre None
+ *
+ * @post An HdatIpmiData object pointer would be pointing to the host memory
+ * where the data would be directly written on to the memory.
+ *
+ * @param[out] o_errlHndl
+ * If any errors occur, the HdatIpmiData object is NOT constructed
+ * and errors are returned in this parameter
+
+ * @param[in] i_msAddr
+ * The main memory address that the IPMI structure will be populated to.
+ *
+ * @return A null error log handle if successful, else the return code
+ * pointed to by o_errlHndl.
+ *
+ */
+
+ HdatIpmi(errlHndl_t &o_errlHndl,
+ const hdatMsAddr_t &i_msAddr);
+
+ /**
+ * @brief HdatIpmiData object destructor
+ *
+ * This is the destructor for an HdatIpmiData object.
+ *
+ * @pre No preconditions exist
+ *
+ * @post The HdatIpmiData object has been destroyed and can no longer be used.
+ *
+ */
+
+ ~HdatIpmi();
+
+ /**
+ * @brief Returns IPMI data whole structure size
+ */
+
+ uint32_t getIpmiEntrySize();
+ /**
+ * @brief copies all the ipmi data to mainstore address
+ */
+ void setIpmiData();
+
+ /** Class (static) Data
+ *
+ * Only one copy of this data exists in a process.
+ * @li cv_actualCnt - a count of how many HdatIpmi objects are created
+ */
+ static uint32_t cv_actualCnt;
+
+ private:
+
+ /** Object instance Data
+ *
+ * @li iv_msAddr - mainstore phyisical address
+ * @li iv_ipmiDataSize - Size of whole ipmi data structure
+ * @li iv_ipmiData - virtual address for ipmi data
+ * @li iv_ipmiFruEntry - FRU sensor array vactor
+ * @li iv_ipmiLedEntry - LED sensor array vector
+ */
+
+ uint64_t iv_msAddr;
+ uint32_t iv_ipmiDataSize; // Size of a IPMI entry
+ uint8_t * iv_ipmiData;
+ std::vector<hdatIPMIFRUSensorMapEntry_t> iv_ipmiFruEntry;
+ std::vector<hdatIPMILEDSensorMapEntry_t> iv_ipmiLedEntry;
+
+};
+
+ /**
+ * @brief Load the HdatIpmiData object
+ *
+ * This function is used to the load the HdatIpmiData object with all the
+ * sensor data for all the FRU's
+ * @param[in] i_msAddr
+ * Mainstore address to fill up the ipmi data.
+ * @param[out] o_size
+ * Size of IPMIData object which are written onto Host memory.
+ *
+ * @param[out] o_count
+ * Count of IPMI objects which are written onto Host memory.
+ *
+ * @pre HdatIpmiData Object should be constructed with the main memory address
+ *
+ * @post The HdatIpmiData object with all the sensor data populated.
+ *
+ * @return A null error log handle if successful, else the return code
+ * pointed to by o_errlHndl.
+ */
+ errlHndl_t hdatLoadIpmi(const hdatMsAddr_t &i_msAddr,
+ uint32_t &o_size, uint32_t &o_count);
+
+
+
+}// HDAT namespace
+#endif
diff --git a/src/usr/hdat/hdatspiraS.C b/src/usr/hdat/hdatspiraS.C
index b6fc0b049..da84e275b 100755
--- a/src/usr/hdat/hdatspiraS.C
+++ b/src/usr/hdat/hdatspiraS.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -54,6 +54,7 @@
#include "hdatbldda.H"
#include "hdatiohub.H"
#include "hdathbrt.H"
+#include "hdatipmi.H"
#include <util/align.H>
#include <targeting/common/commontargeting.H>
@@ -572,6 +573,20 @@ errlHndl_t HdatSpiraS::loadDataArea( const hdat5Tuple_t& i_spirasHostEntry,
}
}
break;
+ case HDAT_SPIRAS_IPMI:
+ {
+ HDAT_DBG("Calling IPMI Sensor Data structure from spiras");
+ l_err = hdatLoadIpmi(l_addrToPass,l_size,l_count);
+ if ( l_err )
+ {
+ HDAT_ERR("loading IPMI data failed");
+ }
+ else
+ {
+ HDAT_DBG("IPMI count=%d,size=0x%x",l_count,l_size);
+ }
+ }
+ break;
default:
{
HDAT_ERR("not a valid data area");
diff --git a/src/usr/hdat/hdatspiraS.H b/src/usr/hdat/hdatspiraS.H
index 97d6a5972..d536f3652 100755
--- a/src/usr/hdat/hdatspiraS.H
+++ b/src/usr/hdat/hdatspiraS.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2016 */
+/* Contributors Listed Below - COPYRIGHT 2016,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -80,8 +80,9 @@ enum hdatSpiraSDataAreas
HDAT_SPIRAS_PCRD = 13, // PCRD (Chip related data area)
HDAT_SPIRAS_HOSTSR = 14, // HOSTSR (Host service data)
HDAT_SPIRAS_HBRT = 15, //HBRT (runtime data)
+ HDAT_SPIRAS_IPMI = 16, // IPMI Sensor MApping Data
- HDAT_SPIRAS_DA_LAST = 16
+ HDAT_SPIRAS_DA_LAST = 17
};
diff --git a/src/usr/hdat/makefile b/src/usr/hdat/makefile
index a2d95b15e..810c05022 100644
--- a/src/usr/hdat/makefile
+++ b/src/usr/hdat/makefile
@@ -49,5 +49,6 @@ OBJS += hdathostservices.o
OBJS += hdathbrt.o
OBJS += hdatspiraS.o
OBJS += hdatspiraH.o
+OBJS += hdatipmi.o
include ${ROOTPATH}/config.mk
OpenPOWER on IntegriCloud