summaryrefslogtreecommitdiffstats
path: root/src/import/hwpf/fapi2/include/collect_reg_ffdc.H
diff options
context:
space:
mode:
Diffstat (limited to 'src/import/hwpf/fapi2/include/collect_reg_ffdc.H')
-rw-r--r--src/import/hwpf/fapi2/include/collect_reg_ffdc.H609
1 files changed, 609 insertions, 0 deletions
diff --git a/src/import/hwpf/fapi2/include/collect_reg_ffdc.H b/src/import/hwpf/fapi2/include/collect_reg_ffdc.H
new file mode 100644
index 000000000..753a245a1
--- /dev/null
+++ b/src/import/hwpf/fapi2/include/collect_reg_ffdc.H
@@ -0,0 +1,609 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/import/hwpf/fapi2/include/collect_reg_ffdc.H $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* [+] 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 FAPI2_COLLECT_REG_FFDC_H_
+#define FAPI2_COLLECT_REG_FFDC_H_
+#include <stdint.h>
+#include <vector>
+#include <hw_access.H>
+#include <ffdc.H>
+#include <hwp_error_info.H>
+#include <error_info_defs.H>
+#include <buffer.H>
+#include <target.H>
+#include <return_code.H>
+#include <fapi2_attribute_service.H>
+#include <plat_trace.H>
+
+
+namespace fapi2
+{
+
+// in generated file collect_reg_ffdc_regs.C
+void getAddressData(const fapi2::HwpFfdcId i_ffdcId,
+ std::vector<uint64_t>& o_scomAddresses ,
+ std::vector<uint32_t>& o_cfamAddresses ,
+ uint32_t& o_ffdcSize );
+
+
+///
+/// @brief converts value to a type to enable overloading based on values
+///
+/// @tparam[in] v - value to create to a unique type
+///
+/// @return v - value.
+///
+template <int v>
+struct toType
+{
+ enum { value = v };
+};
+
+///
+/// @class TargetPosition
+///
+/// helper class to get the position for the passed in chip
+/// or chiplet.
+///
+///
+template < TargetType T, bool isChiplet = T& TARGET_TYPE_CHIPLETS >
+class TargetPosition
+{
+
+ public:
+ ///
+ /// @brief constructor
+ ///
+ TargetPosition(const Target<T>& t)
+ : iv_targ(t)
+ {};
+
+ ///
+ /// @brief Return position of either a chip or chiplet target
+ ///
+ /// @param[out] o_pos - position of chip/chiplet target
+ /// @param[in] is_chiplet - converted to type for overloading
+ /// to correct function call.
+ ///
+ /// @return fapi2::ReturnCode. FAPI_RC_SUCCESS, or failure value.
+ ///
+ fapi2::ReturnCode getPosition( uint32_t& o_pos)
+ {
+ return getPosition(o_pos, toType<isChiplet>());
+ }
+
+ private:
+ ///
+ /// @brief return target position for chiplet
+ ///
+ /// @param[out] o_pos - chiplet position
+ /// @param[in] is_chiplet = true
+ ///
+ /// @return fapi2::ReturnCode. FAPI_RC_SUCCESS, or failure value.
+ ///
+ fapi2::ReturnCode getPosition(uint32_t& o_pos, toType<true>)
+ {
+ fapi2::ReturnCode l_rc;
+
+ uint8_t l_chipletPos = 0;
+
+ l_rc = FAPI_ATTR_GET(fapi2::ATTR_CHIP_UNIT_POS, iv_targ, l_chipletPos);
+
+ if (l_rc)
+ {
+ FAPI_ERR("collect_reg_ffdc.C: Error getting chiplet position");
+ l_chipletPos = 0xFF;
+ }
+
+ o_pos = static_cast<uint32_t>(l_chipletPos);
+
+ return l_rc;
+ }
+
+ ///
+ /// @brief return target position for chip
+ ///
+ /// @param[out] o_pos - chiplet position
+ /// @param[in] is_chiplet = false
+ ///
+ /// @return fapi2::ReturnCode. FAPI_RC_SUCCESS, or failure value.
+ ///
+ fapi2::ReturnCode getPosition(uint32_t& o_pos, toType<false>)
+ {
+ fapi2::ReturnCode l_rc;
+
+ uint32_t l_Pos = 0;
+
+ l_rc = FAPI_ATTR_GET(fapi2::ATTR_POS, iv_targ, l_Pos);
+
+ if (l_rc)
+ {
+ FAPI_ERR("collect_reg_ffdc.C: Error getting position");
+ l_Pos = 0xFF;
+ }
+
+ o_pos = l_Pos;
+
+ return l_rc;
+ }
+
+ const fapi2::Target<T>& iv_targ;
+};
+
+
+
+
+const fapi2::TargetType TARGET_TYPE_PROC_CHIPLETS = fapi2::TARGET_TYPE_EX |
+ fapi2::TARGET_TYPE_MCS |
+ fapi2::TARGET_TYPE_XBUS |
+ fapi2::TARGET_TYPE_CORE |
+ fapi2::TARGET_TYPE_EQ |
+ fapi2::TARGET_TYPE_MCA |
+ fapi2::TARGET_TYPE_MCBIST |
+ fapi2::TARGET_TYPE_MI |
+ fapi2::TARGET_TYPE_CAPP |
+ fapi2::TARGET_TYPE_DMI |
+ fapi2::TARGET_TYPE_OBUS |
+ fapi2::TARGET_TYPE_NV |
+ fapi2::TARGET_TYPE_SBE |
+ fapi2::TARGET_TYPE_PPE |
+ fapi2::TARGET_TYPE_PERV |
+ fapi2::TARGET_TYPE_PEC |
+ fapi2::TARGET_TYPE_PHB;
+
+const fapi2::TargetType TARGET_TYPE_SCOM_TARGET = fapi2::TARGET_TYPE_PROC_CHIP |
+ fapi2::TARGET_TYPE_MEMBUF_CHIP |
+ fapi2::TARGET_TYPE_EX |
+ fapi2::TARGET_TYPE_MBA |
+ fapi2::TARGET_TYPE_MCS |
+ fapi2::TARGET_TYPE_XBUS |
+ fapi2::TARGET_TYPE_ABUS |
+ fapi2::TARGET_TYPE_L4 |
+ fapi2::TARGET_TYPE_CORE |
+ fapi2::TARGET_TYPE_EQ |
+ fapi2::TARGET_TYPE_MCA |
+ fapi2::TARGET_TYPE_MCBIST |
+ fapi2::TARGET_TYPE_MI |
+ fapi2::TARGET_TYPE_DMI |
+ fapi2::TARGET_TYPE_OBUS |
+ fapi2::TARGET_TYPE_NV |
+ fapi2::TARGET_TYPE_SBE |
+ fapi2::TARGET_TYPE_PPE |
+ fapi2::TARGET_TYPE_PERV |
+ fapi2::TARGET_TYPE_PEC |
+ fapi2::TARGET_TYPE_PHB;
+
+
+
+template< TargetType T>
+inline fapi2::Target<fapi2::TARGET_TYPE_CHIPS>
+getChipTarget(const fapi2::Target<T>& i_target)
+{
+ return getChipTarget(i_target);
+}
+
+// handle membuf/proc targets
+inline fapi2::Target<fapi2::TARGET_TYPE_CHIPS>
+getChipTarget(const fapi2::Target<fapi2::TARGET_TYPE_CHIPS>& i_target)
+{
+ return i_target;
+}
+
+// handle dimms
+inline fapi2::Target<fapi2::TARGET_TYPE_CHIPS>
+getChipTarget(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target)
+{
+ return i_target.getParent<fapi2::TARGET_TYPE_MBA>().getParent<fapi2::TARGET_TYPE_MEMBUF_CHIP>();
+}
+
+// everything else is w/proc chip?
+inline fapi2::Target<fapi2::TARGET_TYPE_CHIPS>
+getChipTarget(const
+ fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIPLETS>& i_target)
+{
+ return i_target.getParent<fapi2::TARGET_TYPE_CHIPS>();
+}
+
+template < TargetType T>
+fapi2::Target<fapi2::TARGET_TYPE_SCOM_TARGET>
+getScomTarget(const fapi2::Target<T>& i_target)
+{
+ return i_target;
+}
+
+inline fapi2::Target<fapi2::TARGET_TYPE_SCOM_TARGET>
+getScomTarget(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target)
+{
+ return i_target.getParent<fapi2::TARGET_TYPE_MBA>();
+}
+
+
+template<TargetType T>
+class CfamReader
+{
+ public:
+ CfamReader(const fapi2::Target<T>& i_target)
+ : iv_target(i_target) {};
+
+ ReturnCode
+ read_register(const uint32_t address, fapi2::buffer<uint32_t>& i_buf)
+ {
+ FAPI_DBG("CfamReader.read_register - no-op");
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ private:
+ const fapi2::Target<T>& iv_target;
+};
+
+template<>
+class CfamReader<TARGET_TYPE_MEMBUF_CHIP>
+{
+ public:
+ CfamReader(const fapi2::Target<TARGET_TYPE_MEMBUF_CHIP>& i_target)
+ : iv_target(i_target) {};
+
+ ReturnCode read_register
+ (const uint32_t address, fapi2::buffer<uint32_t>& i_buf)
+ {
+ FAPI_DBG("CfamReader.read_register - MEMBUF VERSION");
+ return fapi2::getCfamRegister(iv_target, address, i_buf);
+ }
+
+ private:
+ const fapi2::Target<TARGET_TYPE_MEMBUF_CHIP>& iv_target;
+};
+
+template<>
+class CfamReader<TARGET_TYPE_PROC_CHIP>
+{
+ public:
+ CfamReader(const fapi2::Target<TARGET_TYPE_PROC_CHIP>& i_target)
+ : iv_target(i_target) {};
+
+ ReturnCode
+ read_register(const uint32_t address, fapi2::buffer<uint32_t>& i_buf)
+ {
+ FAPI_DBG("CfamReader.read_register - PROC VERSION");
+ return fapi2::getCfamRegister(iv_target, address, i_buf);
+ }
+
+ private:
+ const fapi2::Target<TARGET_TYPE_PROC_CHIP>& iv_target;
+};
+
+///
+/// @class ScomReader
+///
+/// Class to abstract away details of reading of a scom register
+///
+template< TargetType T >
+class ScomReader
+{
+ public:
+ ScomReader(const fapi2::Target<T>& i_target)
+ : iv_target(i_target)
+ {};
+
+ ReturnCode read_register(const uint64_t i_address,
+ fapi2::buffer<uint64_t>& o_buf)
+ {
+ FAPI_DBG("ScomReader.read_register - BASE version");
+ return getScom(iv_target, i_address, o_buf);
+ }
+ private:
+ const fapi2::Target<T>& iv_target;
+};
+
+///
+/// @brief class to handle reading from scom registers from generic function
+///
+template<>
+class ScomReader<TARGET_TYPE_DIMM>
+{
+ public:
+ ScomReader(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
+ : iv_target(getScomTarget(i_target))
+ {};
+
+ ReturnCode
+ read_register(const uint64_t i_address, fapi2::buffer<uint64_t>& o_buf)
+ {
+ FAPI_DBG("ScomReader.read_register - DIMM version");
+ ReturnCode l_rc = getScom(iv_target, i_address, o_buf);
+ return l_rc;
+ }
+
+ private:
+ const fapi2::Target<TARGET_TYPE_SCOM_TARGET>& iv_target;
+
+};
+
+///
+/// @brief collectRegisterData
+///
+/// collect all the data from a list of registers and return it to the caller
+///
+/// @tparam[in] T register data size - uint32_t or uint64_t
+/// @tparam[in] U - reader object for specific data type
+/// @param[in] i_addresses - vector containing either cfam or scom addresses
+/// @param[in] i_offset - optional offset to add to the address values
+/// passed in the vector of addresses
+/// @param[out] o_pData - pointer to the data destination
+///
+/// @return fapi2::ReturnCode. FAPI_RC_SUCCESS, or failure value.
+///
+template< typename T, class U>
+ReturnCode collectRegisterData(std::vector<T>& i_addresses, U& i_reader,
+ uint32_t i_offset, uint8_t* o_pData)
+{
+ FAPI_DBG("collectRegisterData -> address count: 0x%lx", i_addresses.size());
+
+ T l_data = 0;
+
+ ReturnCode l_rc = FAPI2_RC_SUCCESS;
+
+ for( auto address : i_addresses )
+ {
+ fapi2::buffer<T> l_buf;
+
+ const T l_address = address + i_offset;
+
+ l_rc = i_reader.read_register(l_address, l_buf);
+
+ if(l_rc)
+ {
+ l_data = 0xbaddbadd;
+ }
+ else
+ {
+ l_data = l_buf();
+ }
+
+ memcpy(o_pData, &l_data, sizeof(T));
+
+ o_pData += sizeof(T);
+
+ }
+
+ return l_rc;
+}
+
+
+///
+/// @brief read registers
+///
+/// Template function to allow reading either scom and cfam data from registers
+/// for a given target
+///
+/// @tparam[in] T - fapi2::TargetType
+/// @param[out] o_pData - pointer to a location to store register data
+/// @param[in] i_cfamAddresses - vector of cfam addresses to read
+/// @param[in] i_scomAddresses - vector of scom addresses to read
+/// @param[i/o] input/output parm description
+///
+/// @return fapi2::ReturnCode. FAPI_RC_SUCCESS, or failure value.
+///
+template<fapi2::TargetType T>
+void readRegisters(const fapi2::Target<T>& i_target,
+ uint8_t* o_pData,
+ std::vector<uint32_t> i_cfamAddresses,
+ std::vector<uint64_t> i_scomAddresses,
+ uint32_t i_childOffset = 0)
+{
+ FAPI_DBG("readRegisters()");
+
+ // create an object to read Cfam registers
+ CfamReader<T> l_cfamReader(i_target);
+
+ // Create an object to read scom registers
+ ScomReader<T> l_scomReader(i_target);
+
+ // read data from the cfam registers if required
+ ReturnCode rc = collectRegisterData<uint32_t,
+ CfamReader<T> >(i_cfamAddresses, l_cfamReader,
+ i_childOffset, o_pData);
+
+ if(rc)
+ {
+ FAPI_ERR("An error occured when reading from the cfam registers skipping..");
+ }
+
+ // read data from Scom registers if present
+ rc = collectRegisterData<uint64_t,
+ ScomReader<T> >(i_scomAddresses, l_scomReader,
+ i_childOffset, o_pData);
+
+ if(rc)
+ {
+ FAPI_ERR("An error occured when reading the scom registers..");
+ }
+
+ FAPI_DBG("readRegisters() exit");
+}
+
+///
+/// @brief Collect register data for child targets
+///
+/// @tparam[in] C - child target type
+/// @tparam[in] T - parent target type
+/// @param[in] i_parent - fapi2::Target
+/// @param[in] i_childState - fapi2::TargetState for child targets
+/// @param[in] i_ffdcId - type of ffdc to be collected
+/// @param[out] o_errorInfo - vector of shared pointers to fapi2::ErrorInfoFfdc type
+/// for returned register data
+/// @param[in] i_childOffsetMult - child offset for register calculations
+/// @param[i/o] input/output parm description
+///
+///
+template<fapi2::TargetType C, fapi2::TargetType T>
+void collectRegFfdc(const fapi2::ffdc_t i_parent,
+ const fapi2::TargetState i_childState,
+ const HwpFfdcId i_ffdcId,
+ std::vector<std::shared_ptr<fapi2::ErrorInfoFfdc>>& o_errorInfoFfdc,
+ uint32_t i_childOffsetMult = 0)
+{
+
+ FAPI_INF("collectRegFfdc child targets version");
+
+ std::vector<fapi2::Target<C> > l_targets;
+
+ Target<T> l_parent =
+ *(static_cast<const Target<T>*>(i_parent.ptr()));
+
+ // Collect FFDC for functional or present chiplets of
+ // type C associated with i_target - yeah, odd syntax.
+ l_targets = l_parent.template getChildren<C>(i_childState);
+
+ if (l_targets.empty())
+ {
+ FAPI_INF("collect_reg_ffdc.C: Error: No chiplets found. ");
+ return;
+ }
+
+ std::vector<uint32_t> l_cfamAddresses;
+ std::vector<uint64_t> l_scomAddresses;
+
+ uint32_t l_ffdcSize = 0;
+
+ // call generated code to fetch the address vectors
+ getAddressData(i_ffdcId, l_scomAddresses, l_cfamAddresses, l_ffdcSize);
+
+ uint32_t l_position = 0;
+
+ // add the position size to the total
+ l_ffdcSize += sizeof(l_position);
+
+ // update size for each target
+ l_ffdcSize += (l_ffdcSize * l_targets.size());
+
+ uint8_t l_pBuf[l_ffdcSize];
+
+ uint8_t* l_pData = &l_pBuf[0];
+
+ // grab the data for each child target
+ for( auto target : l_targets)
+ {
+ ReturnCode l_rc =
+ TargetPosition<C>(target).getPosition(l_position);
+
+ // add chip/chiplets position to the data
+ memcpy(l_pData, &l_position, sizeof(l_position));
+
+ // advance the pointer into our buffer
+ l_pData += sizeof(l_position);
+
+ if(i_childState == TARGET_STATE_FUNCTIONAL)
+ {
+ FAPI_INF(" calling version for TARGET_STATE_FUNCTIONAL ");
+
+ // since its functional just read from the child target
+ readRegisters(target, l_pData, l_cfamAddresses,
+ l_scomAddresses, i_childOffsetMult);
+ }
+ else
+ {
+ // use the parent and read address + offset since the
+ // child targets may not be functional
+ uint32_t l_offset = i_childOffsetMult * l_position;
+
+ FAPI_INF(" calling version for TARGET_STATE_PRESENT ");
+
+ readRegisters(l_parent, l_pData, l_cfamAddresses,
+ l_scomAddresses, l_offset);
+ }
+ }
+
+ FAPI_INF("collectRegFfdc. SCOM address count: %#lx", l_scomAddresses.size());
+ FAPI_INF("collectRegFfdc. CFAM address count: %#lx", l_cfamAddresses.size());
+
+ FAPI_DBG("size info i_ffdcId = %d, l_pBuf = %p, l_ffdcSize=%d", i_ffdcId, l_pBuf, l_ffdcSize);
+
+ // Create a ErrorInfoFfdc object and pass it back
+ o_errorInfoFfdc.push_back(std::shared_ptr<fapi2::ErrorInfoFfdc>(new ErrorInfoFfdc(i_ffdcId, l_pBuf, l_ffdcSize)));
+
+}
+///
+/// @brief Collect register data for a single target
+///
+/// @tparam[in] T - target type
+/// @param[in] i_target - fapi2::Target
+/// @param[in] i_ffdcId - type of ffdc to be collected
+/// @param[out] o_errorInfo - shared pointer to fapi2::ErrorInfoFfdc type
+/// for returned register data
+/// @param[in] i_childOffsetMult - child offset for register calculations
+///
+template<fapi2::TargetType T>
+void collectRegFfdc(const fapi2::ffdc_t i_target,
+ const HwpFfdcId i_ffdcId,
+ std::vector<std::shared_ptr<fapi2::ErrorInfoFfdc> >& o_errorInfoFfdc,
+ uint32_t i_childOffset = 0)
+{
+
+ FAPI_INF("single target no children - ");
+
+ Target<T> l_target =
+ *(static_cast<const Target<T>*>(i_target.ptr()));
+
+ std::vector<uint32_t> l_cfamAddresses;
+ std::vector<uint64_t> l_scomAddresses;
+
+ uint32_t l_ffdcSize = 0;
+
+ // call generated code to fetch the address vectors
+ getAddressData(i_ffdcId, l_scomAddresses, l_cfamAddresses, l_ffdcSize);
+
+ uint32_t l_position = 0;
+
+ ReturnCode l_rc = TargetPosition<T>(l_target).getPosition(l_position);
+
+ l_ffdcSize += sizeof(l_position);
+
+ uint8_t l_pBuf[l_ffdcSize];
+
+ uint8_t* l_pData = &l_pBuf[0];
+
+ // add chip/chiplets position to the data
+ memcpy(l_pData, &l_position, sizeof(l_position));
+
+ l_pData += sizeof(l_position);
+
+ // do the work
+ readRegisters(l_target, l_pData, l_cfamAddresses, l_scomAddresses,
+ i_childOffset);
+
+ FAPI_DBG("size info i_ffdcId = %d, l_pBuf = %p, l_ffdcSize=%d", i_ffdcId, l_pBuf, l_ffdcSize);
+ // Create a ErrorInfoFfdc object and add it to the Error Information
+ // object of the FFDC class
+ o_errorInfoFfdc.push_back(std::shared_ptr<fapi2::ErrorInfoFfdc>(new ErrorInfoFfdc(i_ffdcId, l_pBuf, l_ffdcSize)));
+
+ FAPI_INF("collectRegFfdc. SCOM address count: 0x%lx", l_scomAddresses.size());
+ FAPI_INF("collectRegFfdc. CFAM address count: 0x%lx", l_cfamAddresses.size());
+
+ FAPI_INF("collectRegFfdc() - exit");
+}
+
+}// end namespace
+#endif
OpenPOWER on IntegriCloud