diff options
author | nagurram-in <nagendra.g@in.ibm.com> | 2017-01-13 16:09:22 -0600 |
---|---|---|
committer | William G. Hoffa <wghoffa@us.ibm.com> | 2017-03-27 17:06:21 -0400 |
commit | 27f352e4a1e3a695fa6cde169f4637fce647e10b (patch) | |
tree | fb761a70067d374981e926499167ff3a9b7d600c /src/usr/hdat | |
parent | 8ae9a2c137ebc771ed1ad34c24d93f55d508e175 (diff) | |
download | talos-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.C | 266 | ||||
-rw-r--r-- | src/usr/hdat/hdatipmi.H | 227 | ||||
-rwxr-xr-x | src/usr/hdat/hdatspiraS.C | 17 | ||||
-rwxr-xr-x | src/usr/hdat/hdatspiraS.H | 5 | ||||
-rw-r--r-- | src/usr/hdat/makefile | 1 |
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 |