diff options
author | Sachin Gupta <sgupta2m@in.ibm.com> | 2015-07-14 05:18:40 -0500 |
---|---|---|
committer | Jennifer A. Stofer <stofer@us.ibm.com> | 2015-07-28 15:21:17 -0500 |
commit | d553cfa7b58b4529e72557b219b87319c11da043 (patch) | |
tree | 153ee4403caa10105a1e5280c4916076f659b183 | |
parent | 8fd7df0b85039d5dc5f8a23f0d80cbce7d30a600 (diff) | |
download | talos-sbe-d553cfa7b58b4529e72557b219b87319c11da043.tar.gz talos-sbe-d553cfa7b58b4529e72557b219b87319c11da043.zip |
Add SBE support for per directory error XML files
- Added parseErrorInfo.pl
Change-Id: I263797070f09d0b869f3de52916049574d272cb6
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/18819
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Tested-by: Jennifer A. Stofer <stofer@us.ibm.com>
-rw-r--r-- | hwp/cache/cachehcderrors.mk | 28 | ||||
-rw-r--r-- | hwp/core/corehcderrors.mk | 30 | ||||
-rw-r--r-- | hwp/lib/libcommonerrors.mk | 20 | ||||
-rw-r--r-- | hwp/lib/p9_avsbus_lib_errors.xml | 50 | ||||
-rw-r--r-- | hwp/perv/p9_sbe_setup_evid_errors.xml | 50 | ||||
-rw-r--r-- | hwp/perv/perverrors.mk | 17 | ||||
-rw-r--r-- | hwp/utils/utilserrors.mk | 15 | ||||
-rw-r--r-- | hwpf/plat/include/buffer.H | 220 | ||||
-rwxr-xr-x | hwpf/plat/include/buffer_base.H | 331 | ||||
-rw-r--r-- | hwpf/plat/include/buffer_parameters.H | 19 | ||||
-rw-r--r-- | hwpf/plat/include/buffer_traits.H | 8 | ||||
-rw-r--r-- | hwpf/plat/include/utils.H | 12 | ||||
-rw-r--r-- | importtemp/fapi2/include/error_info_defs.H | 7 | ||||
-rw-r--r-- | sbe/image/Makefile | 27 | ||||
-rw-r--r-- | sbe/image/img_defs.mk | 12 | ||||
-rw-r--r-- | sbe/image/sbe_xip_image.c | 156 | ||||
-rw-r--r-- | sbe/image/topfiles.mk | 4 | ||||
-rw-r--r-- | tools/image/sbe_xip_tool.c | 876 | ||||
-rwxr-xr-x | tools/scripts/parseErrorInfo.pl | 1511 |
19 files changed, 2753 insertions, 640 deletions
diff --git a/hwp/cache/cachehcderrors.mk b/hwp/cache/cachehcderrors.mk new file mode 100644 index 00000000..486af276 --- /dev/null +++ b/hwp/cache/cachehcderrors.mk @@ -0,0 +1,28 @@ +# @file cachehcderrors.mk +# +# @brief mk for including cache error files +# +# @page ChangeLogs Change Logs +# @section cachehcderrors.mk +# +########################################################################## +# Error Files +########################################################################## + +CACHE_CURR_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) + +# This variable name must not change +#ERROR_XML_FILES += $(CACHE_CURR_DIR)/p9_hcd_cache_arrayinit.C +#ERROR_XML_FILES += $(CACHE_CURR_DIR)/p9_hcd_cache_chiplet_init.C +#ERROR_XML_FILES += $(CACHE_CURR_DIR)/p9_hcd_cache_chiplet_reset.C +#ERROR_XML_FILES += $(CACHE_CURR_DIR)/p9_hcd_cache_dpll_setup.C +#ERROR_XML_FILES += $(CACHE_CURR_DIR)/p9_hcd_cache_gptr_time_initf.C +#ERROR_XML_FILES += $(CACHE_CURR_DIR)/p9_hcd_cache_initf.C +#ERROR_XML_FILES += $(CACHE_CURR_DIR)/p9_hcd_cache_occ_runtime_scom.C +#ERROR_XML_FILES += $(CACHE_CURR_DIR)/p9_hcd_cache_poweron.C +#ERROR_XML_FILES += $(CACHE_CURR_DIR)/p9_hcd_cache_ras_runtime_scom.C +#ERROR_XML_FILES += $(CACHE_CURR_DIR)/p9_hcd_cache_repair_initf.C +#ERROR_XML_FILES += $(CACHE_CURR_DIR)/p9_hcd_cache_runinit.C +#ERROR_XML_FILES += $(CACHE_CURR_DIR)/p9_hcd_cache_scomcust.C +#ERROR_XML_FILES += $(CACHE_CURR_DIR)/p9_hcd_cache_scominit.C +#ERROR_XML_FILES += $(CACHE_CURR_DIR)/p9_hcd_cache_startclocks.C diff --git a/hwp/core/corehcderrors.mk b/hwp/core/corehcderrors.mk new file mode 100644 index 00000000..a4a021c4 --- /dev/null +++ b/hwp/core/corehcderrors.mk @@ -0,0 +1,30 @@ +# @file corehcderrors.mk +# +# @brief mk for including core error files +# +# @page ChangeLogs Change Logs +# @section corehcderrors.mk +# +########################################################################## +# Error Files +########################################################################## + +CORE_CURR_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) + +# This variable name must not change +#ERROR_XML_FILES += $(CORE_CURR_DIR)/p9_hcd_core_arrayinit_errors.xml +#ERROR_XML_FILES += $(CORE_CURR_DIR)/p9_hcd_core_chiplet_init_errors.xml +#ERROR_XML_FILES += $(CORE_CURR_DIR)/p9_hcd_core_chiplet_reset_errors.xml +#ERROR_XML_FILES += $(CORE_CURR_DIR)/p9_hcd_core_gptr_time_initf_errors.xml +#ERROR_XML_FILES += $(CORE_CURR_DIR)/p9_hcd_core_initf_errors.xml +#ERROR_XML_FILES += $(CORE_CURR_DIR)/p9_hcd_core_occ_runtime_scom_errors.xml +#ERROR_XML_FILES += $(CORE_CURR_DIR)/p9_hcd_core_pcb_arb_errors.xml +#ERROR_XML_FILES += $(CORE_CURR_DIR)/p9_hcd_core_poweron_errors.xml +#ERROR_XML_FILES += $(CORE_CURR_DIR)/p9_hcd_core_ras_runtime_scom_errors.xml +#ERROR_XML_FILES += $(CORE_CURR_DIR)/p9_hcd_core_repair_initf_errors.xml +#ERROR_XML_FILES += $(CORE_CURR_DIR)/p9_hcd_core_runinit_errors.xml +#ERROR_XML_FILES += $(CORE_CURR_DIR)/p9_hcd_core_scomcust_errors.xml +#ERROR_XML_FILES += $(CORE_CURR_DIR)/p9_hcd_core_scominit_errors.xml +#ERROR_XML_FILES += $(CORE_CURR_DIR)/p9_hcd_core_startclocks_errors.xml + + diff --git a/hwp/lib/libcommonerrors.mk b/hwp/lib/libcommonerrors.mk new file mode 100644 index 00000000..a344d6b1 --- /dev/null +++ b/hwp/lib/libcommonerrors.mk @@ -0,0 +1,20 @@ +# @file libcommonerrors.mk +# +# @brief Error XML mk for common library files +# +# @page ChangeLogs Change Logs +# @section libcommonerrors.mk +# @verbatim +# +# +# @endverbatim +# +########################################################################## +# Error Files +########################################################################## + +LIB_CURR_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) + +# This variable name must not change +ERROR_XML_FILES += $(LIB_CURR_DIR)/p9_avsbus_lib_errors.xml +#ERROR_XML_FILES += $(LIB_CURR_DIR)/p9_common_pro_epi_log_errors.xml diff --git a/hwp/lib/p9_avsbus_lib_errors.xml b/hwp/lib/p9_avsbus_lib_errors.xml new file mode 100644 index 00000000..4211c58c --- /dev/null +++ b/hwp/lib/p9_avsbus_lib_errors.xml @@ -0,0 +1,50 @@ +<!-- IBM_PROLOG_BEGIN_TAG --> +<!-- This is an automatically generated prolog. --> +<!-- --> +<!-- $Source: chips/p9/procedures/ipl/ppe/hwp/p9_avsbus_lib_errors.xml $ --> +<!-- --> +<!-- IBM CONFIDENTIAL --> +<!-- --> +<!-- EKB Project --> +<!-- --> +<!-- COPYRIGHT 2015 --> +<!-- [+] International Business Machines Corp. --> +<!-- --> +<!-- --> +<!-- The source code for this program is not published or otherwise --> +<!-- divested of its trade secrets, irrespective of what has been --> +<!-- deposited with the U.S. Copyright Office. --> +<!-- --> +<!-- IBM_PROLOG_END_TAG --> + +<!-- *HWP HWP Owner: Greg Still <stillgs @us.ibm.com> --> +<!-- *HWP FW Owner: Bilicon Patil <bilpatil@in.ibm.com> --> +<!-- *HWP Team: PM --> +<!-- *HWP Level: 1 --> +<!-- *HWP Consumed by: FSP:HS --> + +<!-- Error definitions for p9_avsbus_lib procedure --> +<hwpErrors> + <!-- ******************************************************************** --> + <hwpError> + <rc>RC_PROCPM_AVSBUS_READVOLTAGE_TIMEOUT</rc> + <description> + A timeout occured reading voltage from an AVSBus interface + </description> + </hwpError> + <!-- ******************************************************************** --> + <hwpError> + <rc>RC_PROCPM_AVSBUS_WRITEVOLTAGE_TIMEOUT</rc> + <description> + A timeout occured writing a voltage to an AVSBus interface + </description> + </hwpError> + <!-- ******************************************************************** --> + <hwpError> + <rc>RC_PROCPM_AVSBUS_IDLEFRAME_TIMEOUT</rc> + <description> + A timeout occured writing an idle from to an AVSBus interface + </description> + </hwpError> + <!-- ******************************************************************** --> +</hwpErrors> diff --git a/hwp/perv/p9_sbe_setup_evid_errors.xml b/hwp/perv/p9_sbe_setup_evid_errors.xml new file mode 100644 index 00000000..d0489a63 --- /dev/null +++ b/hwp/perv/p9_sbe_setup_evid_errors.xml @@ -0,0 +1,50 @@ +<!-- IBM_PROLOG_BEGIN_TAG --> +<!-- This is an automatically generated prolog. --> +<!-- --> +<!-- $Source: chips/p9/procedures/ipl/ppe/hwp/p9_avsbus_lib_errors.xml $ --> +<!-- --> +<!-- IBM CONFIDENTIAL --> +<!-- --> +<!-- EKB Project --> +<!-- --> +<!-- COPYRIGHT 2015 --> +<!-- [+] International Business Machines Corp. --> +<!-- --> +<!-- --> +<!-- The source code for this program is not published or otherwise --> +<!-- divested of its trade secrets, irrespective of what has been --> +<!-- deposited with the U.S. Copyright Office. --> +<!-- --> +<!-- IBM_PROLOG_END_TAG --> + +<!-- *HWP HWP Owner: Greg Still <stillgs @us.ibm.com> --> +<!-- *HWP FW Owner: Bilicon Patil <bilpatil@in.ibm.com> --> +<!-- *HWP Team: PM --> +<!-- *HWP Level: 1 --> +<!-- *HWP Consumed by: FSP:HS --> + +<!-- Error definitions for p9_avsbus_lib procedure --> +<hwpErrors> + <!-- ******************************************************************** --> + <hwpError> + <rc>RC_PROCPM_EVID_READVOLTAGE_TIMEOUT</rc> + <description> + A timeout occured reading voltage from an AVSBus interface + </description> + </hwpError> + <!-- ******************************************************************** --> + <hwpError> + <rc>RC_PROCPM_EVID_WRITEVOLTAGE_TIMEOUT</rc> + <description> + A timeout occured writing a voltage to an AVSBus interface + </description> + </hwpError> + <!-- ******************************************************************** --> + <hwpError> + <rc>RC_PROCPM_EVID_IDLEFRAME_TIMEOUT</rc> + <description> + A timeout occured writing an idle from to an AVSBus interface + </description> + </hwpError> + <!-- ******************************************************************** --> +</hwpErrors> diff --git a/hwp/perv/perverrors.mk b/hwp/perv/perverrors.mk new file mode 100644 index 00000000..1642766b --- /dev/null +++ b/hwp/perv/perverrors.mk @@ -0,0 +1,17 @@ +# @file perverrors.mk +# +# @brief mk for including library common error files +# +# @page ChangeLogs Change Logs +# @section perverrors.mk +# +########################################################################## +# Error Files +########################################################################## + +PERV_CURR_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) + +# This variable name must not change +ERROR_XML_FILES += $(PERV_CURR_DIR)/p9_sbe_setup_evid_errors.xml + + diff --git a/hwp/utils/utilserrors.mk b/hwp/utils/utilserrors.mk new file mode 100644 index 00000000..5556bfe9 --- /dev/null +++ b/hwp/utils/utilserrors.mk @@ -0,0 +1,15 @@ +# @file utilserrors.mk +# +# @brief mk for including utils error files +# +# @page ChangeLogs Change Logs +# @section utilserrors.mk +# +########################################################################## +# Error Files +########################################################################## + +UTILS_CURR_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) + +# This variable name must not change +#ERROR_XML_FILES += $(UTILS_CURR_DIR)/p9_XXX_errors.xml diff --git a/hwpf/plat/include/buffer.H b/hwpf/plat/include/buffer.H index 9e863c3b..62e7e7cf 100644 --- a/hwpf/plat/include/buffer.H +++ b/hwpf/plat/include/buffer.H @@ -36,11 +36,11 @@ namespace fapi2 { - /// @brief Class representing a FAPI buffer<T> - /// @tparam T, the integral type of the buffer (uint16_t, uint64_t, etc.) - template <typename T, typename TT = bufferTraits<T> > - class buffer - { +/// @brief Class representing a FAPI buffer<T> +/// @tparam T, the integral type of the buffer (uint16_t, uint64_t, etc.) +template <typename T, typename TT = bufferTraits<T> > +class buffer +{ public: /// Shortcut typedef to get to our traits class typedef typename TT::bits_type bits_type; @@ -52,40 +52,54 @@ namespace fapi2 /// inline buffer(T i_value = 0): iv_data(i_value) - { - } + { + } ~buffer(void) = default; -#if !defined(DOXYGEN) && defined(FAPI2_DEBUG) + #if !defined(DOXYGEN) && defined(FAPI2_DEBUG) /// @brief Print the contents of the buffer to stdout inline void print(void) const - { TT::print(iv_data); } -#endif + { + TT::print(iv_data); + } + #endif /// /// @brief Get the contents of the buffer /// @return The contents of the buffer /// - inline operator T() const { return iv_data; } + inline operator T() const + { + return iv_data; + } /// /// @brief Get the contents of the buffer /// @return The contents of the buffer /// - inline operator T&() { return iv_data; } + inline operator T&() + { + return iv_data; + } /// /// @brief Get the contents of the buffer /// @return The contents of the buffer /// - inline T& operator()(void) { return iv_data; } + inline T& operator()(void) + { + return iv_data; + } /// /// @brief Get the contents of the buffer /// @return Reference to the contents of the buffer /// - inline const T& operator()(void) const { return iv_data; } + inline const T& operator()(void) const + { + return iv_data; + } /// @name Buffer Manipulation Functions ///@{ @@ -118,11 +132,14 @@ namespace fapi2 // Create mask if part of this byte is not in the valid part of the buffer, // Shift it left by the amount of unused bits, // Clear the unused bits - if (((i_offset + 1) == length) && (bit_length % bits_in_value)) { - i_value &= parameterTraits<OT>::mask() << ((bits_in_value * length) - bit_length); + if (((i_offset + 1) == length) && (bit_length % bits_in_value)) + { + i_value &= parameterTraits<OT>::mask() << ((bits_in_value * length) - + bit_length); } - parameterTraits<OT>::template write_element<typename TT::unit_type>(TT::get_address(iv_data), i_value, i_offset); + parameterTraits<OT>::template write_element<typename TT::unit_type> + (TT::get_address(iv_data), i_value, i_offset); return FAPI2_RC_SUCCESS; } @@ -134,7 +151,9 @@ namespace fapi2 /// @return Length in bits /// inline constexpr uint32_t getBitLength(void) const - { return TT::bit_length(iv_data); } + { + return TT::bit_length(iv_data); + } /// /// @brief Return the length of the buffer in OT units @@ -167,7 +186,8 @@ namespace fapi2 // This would be a candidate for a fast_mask (see variable_buffer) but // we'd need tables for all the integral types which maybe we need to // do ... - iv_data |= (T(~0) >> (TT::bits_per_unit() - C)) << (TT::bits_per_unit() - B - C); + iv_data |= (T(~0) >> (TT::bits_per_unit() - C)) << (TT::bits_per_unit() - B - + C); return *this; } @@ -178,14 +198,16 @@ namespace fapi2 /// @note 0 is left-most /// @return FAPI2_RC_SUCCESS if OK /// - inline fapi2::ReturnCode setBit(const bits_type& i_bit, const bits_type& i_count = 1) + inline fapi2::ReturnCode setBit(const bits_type& i_bit, + const bits_type& i_count = 1) { if ((i_count + i_bit - 1) >= TT::bits_per_unit()) { return FAPI2_RC_INVALID_PARAMETER; } - iv_data |= (T(~0) >> (TT::bits_per_unit() - i_count)) << (TT::bits_per_unit() - i_bit - i_count); + iv_data |= (T(~0) >> (TT::bits_per_unit() - i_count)) << + (TT::bits_per_unit() - i_bit - i_count); return FAPI2_RC_SUCCESS; } @@ -216,7 +238,8 @@ namespace fapi2 /// @note 0 is left-most /// @return FAPI2_RC_SUCCESS if OK /// - inline fapi2::ReturnCode clearBit(const bits_type& i_bit, const bits_type& i_count = 1) + inline fapi2::ReturnCode clearBit(const bits_type& i_bit, + const bits_type& i_count = 1) { if ((i_count + i_bit - 1) >= TT::bits_per_unit()) { @@ -282,9 +305,9 @@ namespace fapi2 /// template< bits_type B, bits_type C = 1> inline bool getBit(void) const - { - return buffer<T>().setBit<B, C>() & iv_data; - } + { + return buffer<T>().setBit<B, C>() & iv_data; + } /// /// @brief Set and entire buffer to X's @@ -294,25 +317,31 @@ namespace fapi2 /// template< uint8_t X > inline buffer& flush(void) - { - static_assert( (X == 1) || (X == 0), "bad argument to flush" ); - (0 == X) ? TT::clear(iv_data) : TT::set(iv_data); - return *this; - } + { + static_assert( (X == 1) || (X == 0), "bad argument to flush" ); + (0 == X) ? TT::clear(iv_data) : TT::set(iv_data); + return *this; + } /// /// @brief Invert entire buffer /// @return buffer_base&, Useful for method chaining /// inline buffer& invert(void) - { TT::invert(iv_data); return *this; } + { + TT::invert(iv_data); + return *this; + } /// /// @brief Bit reverse entire buffer /// @return buffer_base&, Useful for method chaining /// inline buffer& reverse(void) - { TT::reverse(iv_data); return *this; } + { + TT::reverse(iv_data); + return *this; + } ///@} @@ -324,7 +353,10 @@ namespace fapi2 /// @brief Get a pointer to the buffer bits /// @return Pointer to the buffer itself /// - inline T* pointer(void) { return &iv_data; } + inline T* pointer(void) + { + return &iv_data; + } // Note: Many (all?) of these are not needed and the compiler complains // as the cast to T yields a better operator. There are here mainly for @@ -333,86 +365,86 @@ namespace fapi2 /// /// @brief operator>>() /// -#ifdef DOXYGEN + #ifdef DOXYGEN inline buffer<T>& operator>>(bits_type i_shiftnum); -#endif + #endif /// /// @brief operator<<() /// -#ifdef DOXYGEN + #ifdef DOXYGEN inline buffer<T>& operator<<(bits_type i_shiftnum); -#endif + #endif /// /// @brief operator+() /// -#ifdef DOXYGEN + #ifdef DOXYGEN inline buffer<T>& operator+(const T& rhs); -#endif + #endif /// /// @brief operator+=() /// -#ifdef DOXYGEN + #ifdef DOXYGEN inline buffer<T>& operator+=(const T& rhs); -#endif + #endif /// /// @brief operator|=() /// -#ifdef DOXYGEN + #ifdef DOXYGEN inline buffer<T>& operator|=(const T& rhs); -#endif + #endif /// /// @brief operator&=() /// -#ifdef DOXYGEN + #ifdef DOXYGEN inline buffer<T>& operator&=(const T& rhs); -#endif + #endif /// /// @brief operator|() /// -#ifdef DOXYGEN + #ifdef DOXYGEN inline buffer<T>& operator|(const T& rhs); -#endif + #endif /// /// @brief operator&() /// -#ifdef DOXYGEN + #ifdef DOXYGEN inline buffer<T>& operator&(const T& rhs); -#endif + #endif /// /// @brief operator^=() /// -#ifdef DOXYGEN + #ifdef DOXYGEN inline buffer<T>& operator^=(const T& rhs); -#endif + #endif /// /// @brief operator~() /// -#ifdef DOXYGEN + #ifdef DOXYGEN inline buffer<T>& operator~(const T& rhs) const; -#endif + #endif /// /// @brief operator==() /// -#ifdef DOXYGEN + #ifdef DOXYGEN inline bool operator==(const T& rhs) const; -#endif + #endif /// /// @brief operator!=() /// -#ifdef DOXYGEN + #ifdef DOXYGEN inline bool operator!=(const T& rhs) const; -#endif + #endif /// /// @brief Copy part of a OT into the DataBuffer @@ -444,15 +476,19 @@ namespace fapi2 uint64_t source = static_cast<uint64_t>(i_datain); const uint64_t target = static_cast<uint64_t>(iv_data); - const bits_type source_start = parameterTraits<uint64_t>::bit_length - (source_length - SS); - const bits_type target_start = parameterTraits<uint64_t>::bit_length - (target_length - TS); + const bits_type source_start = parameterTraits<uint64_t>::bit_length() - + (source_length - SS); + const bits_type target_start = parameterTraits<uint64_t>::bit_length() - + (target_length - TS); // Get mask value for Target buffer // Note: Need "& 0UL" because bit shift left for Target buffer doesn't roll off - uint64_t mask = ((~0UL << (parameterTraits<uint64_t>::bit_length - L)) & ~0UL) >> target_start; + uint64_t mask = ((~0UL << (parameterTraits<uint64_t>::bit_length() - L)) & ~0UL) + >> target_start; // Align the source to the target. Make things signed so we know which way to shift. int32_t shift = source_start - target_start; + if (shift > 0) { source <<= shift; @@ -514,15 +550,19 @@ namespace fapi2 uint64_t source = static_cast<uint64_t>(i_datain); const uint64_t target = static_cast<uint64_t>(iv_data); - const bits_type source_start = parameterTraits<uint64_t>::bit_length - (source_length - i_sourceStart); - const bits_type target_start = parameterTraits<uint64_t>::bit_length - (target_length - i_targetStart); + const bits_type source_start = parameterTraits<uint64_t>::bit_length() - + (source_length - i_sourceStart); + const bits_type target_start = parameterTraits<uint64_t>::bit_length() - + (target_length - i_targetStart); // Get mask value for Target buffer // Note: Need "& 0UL" because bit shift left for Target buffer doesn't roll off - uint64_t mask = ((~0UL << (parameterTraits<uint64_t>::bit_length - i_len)) & ~0UL) >> target_start; + uint64_t mask = ((~0UL << (parameterTraits<uint64_t>::bit_length() - i_len)) & + ~0UL) >> target_start; // Align the source to the target. Make things signed so we know which way to shift. int32_t shift = source_start - target_start; + if (shift > 0) { source <<= shift; @@ -573,7 +613,8 @@ namespace fapi2 /// @note Data is assumed to be aligned on the word boundary of L /// template<typename OT> - fapi2::ReturnCode insertFromRight(const OT i_datain, const bits_type i_targetStart, + fapi2::ReturnCode insertFromRight(const OT i_datain, + const bits_type i_targetStart, const bits_type i_len) { // Error if input data don't make sense @@ -595,7 +636,28 @@ namespace fapi2 return FAPI2_RC_INVALID_PARAMETER; } - return this->insert(i_datain, i_targetStart, i_len, parameterTraits<OT>::bit_length() - i_len); + return this->insert(i_datain, i_targetStart, i_len, + parameterTraits<OT>::bit_length() - i_len); + } + + /// + /// @brief Copy data from this buffer into an OT + /// @tparam SS Start bit in source + /// @tparam L Length of bits to insert + /// @tparam TS Start bit to insert into (target start) + /// @tparam OT the type of the outgoing (target) + /// @param[out] o_out OT to copy into - data is placed left aligned + /// @return const buffer& Useful for method chaining + /// + template<bits_type SS, bits_type L, bits_type TS = 0, typename OT> + inline const buffer& extract(OT& o_out) const + { + // Extraction is just an insert into o_out + + buffer<OT> out(o_out); + out.insert<TS, L, SS>(iv_data); + o_out = out; + return *this; } /// @@ -629,12 +691,14 @@ namespace fapi2 /// template<typename OT> fapi2::ReturnCode extract(OT& o_out, const bits_type i_sourceStart, - const bits_type i_len, const bits_type i_targetStart = 0) + const bits_type i_len, const bits_type i_targetStart = 0) const { // Extraction is just an insert into o_out buffer<OT> out(o_out); - if (out.insert(iv_data, i_targetStart, i_len, i_sourceStart) != FAPI2_RC_SUCCESS) + + if (out.insert(iv_data, i_targetStart, i_len, + i_sourceStart) != FAPI2_RC_SUCCESS) { return FAPI2_RC_INVALID_PARAMETER; } @@ -649,6 +713,21 @@ namespace fapi2 /// @tparam L Length of bits to extract /// @tparam OT the type of the outgoing (target) /// @param[out] o_out OT to copy into - data is placed right aligned + /// @return const buffer& Useful for method chaining + /// + template<bits_type SS, bits_type L, typename OT> + inline const buffer& extractToRight(OT& o_out) const + { + extract<SS, L, parameterTraits<OT>::bit_length() - L>(o_out); + return *this; + } + + /// + /// @brief Copy data from this buffer into an OT and right justify + /// @tparam SS Start bit to insert into (source start) + /// @tparam L Length of bits to extract + /// @tparam OT the type of the outgoing (target) + /// @param[out] o_out OT to copy into - data is placed right aligned /// @return buffer& Useful for method chaining /// template<bits_type SS, bits_type L, typename OT> @@ -668,9 +747,10 @@ namespace fapi2 /// template<typename OT> fapi2::ReturnCode extractToRight(OT& o_out, const bits_type i_sourceStart, - const bits_type i_len) + const bits_type i_len) const { - return extract(o_out, i_sourceStart, i_len, parameterTraits<OT>::bit_length() - i_len); + return extract(o_out, i_sourceStart, i_len, + parameterTraits<OT>::bit_length() - i_len); } ///@} @@ -678,7 +758,7 @@ namespace fapi2 private: /// The contents of the buffer T iv_data; - }; +}; } #endif diff --git a/hwpf/plat/include/buffer_base.H b/hwpf/plat/include/buffer_base.H new file mode 100755 index 00000000..a6e8c4ad --- /dev/null +++ b/hwpf/plat/include/buffer_base.H @@ -0,0 +1,331 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2012,2014 */ +/* [+] 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 buffer_base.H + * @brief definitions for fapi2 buffer base class + */ + +#ifndef __FAPI2_BUFFER_BASE__ +#define __FAPI2_BUFFER_BASE__ + +#include <stdint.h> +#include <initializer_list> +#include <error_scope.H> +#include <buffer_parameters.H> +#include <buffer_traits.H> +#include <return_code.H> + +namespace fapi2 +{ + /// @brief Base class for buffers and variable buffers + /// @tparam T is the type of iv_data (std::vector, etc) + /// @tparam TT is the template trait, defaults to the trait for T + /// + /// Buffers can be of two styles; buffers made from an integral type and + /// buffers made from a container. Integral type buffers, while limited + /// in size, can be tightly controlled via the compiler by using c++ + /// templates. + /// + /// C++ templates allow for very explicit control, but yield a + /// syntax different than the FAPI 1.x functional interface. For example, + /// a fapi2::buffer is defined as having a type: + /// @code + /// fapi2::buffer<uint64_t> new_buffer; + /// @endcode + /// defines a buffer with exactly 64 bits, and can be manipulated by the + /// compiler as a single intrgral value. These implementations result + /// in concise instruction streams, and a platform may choose to implement + /// all or some or none of the integral buffer types. + /// + /// Buffers which have containers as their underlying implementation + /// are found in the class fapi2::variable_buffer. variable_buffer is little + /// more than + /// @code + /// fapi2::buffer<fapi2::bits_container> + /// @endcode + /// where bits_container is the typedef of the underlying container (a + /// vector of uint32_t, for example) + /// + /// Examples:<br> + /// + /// * Simple uint64_t buffer + /// @code + /// const uint32_t x = 2; + /// + /// // this data buffer will contain data in a uint64_t type + /// fapi2::buffer<uint64_t> data; + /// + /// // Set using the template and a constant + /// data.setBit<x>(); + /// + /// // Set using the template and a value + /// data.setBit<3>(); + /// + /// // Set using the function interface, and a value + /// data.setBit(1); + /// + /// // compiler gets smart. + /// // movabs $0x7000000000000000,%rsi + /// @endcode + /// + /// * variable_buffer, same thing + /// @code + /// + /// const uint32_t x = 2; + /// + /// // Note: only 15 bits long + /// fapi2::variable_buffer data(15); + /// + /// + /// data.setBit(x); + /// data.setBit(3); + /// data.setBit(1); + /// @endcode + /// + /// * method chaining + /// Buffers support method chaining. So, rather than + /// this + /// @code + /// buffer<T> mask; + /// mask.setBit<B>(); + /// mask.invert(); + /// my_buffer &= mask; + /// @endcode + /// You can do + /// @code + /// my_buffer &= buffer<T>().setBit<B>.invert(); + /// @endcode + /// + /// * buffer operations + /// @code + /// + /// // An 8 bit buffer, initialized with a value + /// fapi2::buffer<uint8_t> eight_bits = 0xAA; + /// fapi2::buffer<uint8_t> another_eight; + /// fapi2::buffer<uint16_t> sixteen_bits; + /// + /// // You can't assign an 8 bit buffer to a 16 bit buffer. + /// sixteen_bits = eight_bits; ERROR + /// + /// // But you can assign buffers of the same type + /// another_eight = eight_bits; + /// + /// // You can assign constants (or other known values) directly: + /// sixteen_bits = 0xAABB; + /// @endcode + /// + /// * Variable buffer operations + /// + /// @code + /// fapi2::variable_buffer data(16); + /// + /// // Very large buffers can be initialized rather than set bit by bit. + /// const fapi2::variable_buffer bit_settings_known( + /// {0xFFFF0000, 0xAABBF0F0, + /// 0xFFFF0000, 0xAABBF0F0, + /// 0xFFFF0000, 0xAABBF0F0,}); + /// + /// // Assignment will expand or shrink the size automatically. + /// data = bit_settings_known; + /// + /// // You can assign directly to the buffer: + /// fapi2::variable_buffer other_bits; + /// const fapi2::container_unit x = 0xFF00AA55; + /// other_bits = {x, 0xDEADBEEF}; + /// @endcode + /// + template <typename T, typename TT = bufferTraits<T> > + class buffer_base + { + + public: + + /// Shortcut typedef to get to our traits class + typedef typename TT::bits_type bits_type; + /// Shortcut typedef to get to our traits class + typedef typename TT::unit_type unit_type; + + /// + /// @brief Default constructor + /// @note iv_data will get the "default" construction, which is + /// correct - 0 for integral types, an empty container for the others. + /// + buffer_base(void): + iv_data() + {} + + virtual ~buffer_base(void) + {} + +#ifndef DOXYGEN + /// @brief Print the contents of the buffer to stdout + inline void print(void) const + { TT::print(iv_data); } +#endif + /// + /// @brief Get the contents of the buffer + /// @return The contents of the buffer + /// + inline operator T() const { return iv_data; } + + /// + /// @brief Get the contents of the buffer + /// @return The contents of the buffer + /// + inline operator T&() { return iv_data; } + + /// + /// @brief Get the contents of the buffer + /// @return The contents of the buffer + /// + inline T& operator()(void) { return iv_data; } + + /// + /// @brief Get the contents of the buffer + /// @return Reference to the contents of the buffer + /// + inline const T& operator()(void) const { return iv_data; } + + /// + /// @brief Get a pointer to the buffer bits + /// @return Pointer to the buffer itself + /// + inline T* pointer(void) { return &iv_data; } + + /// @name Buffer Manipulation Functions + ///@{ + + /// + /// @brief Set an OT of data in buffer + /// @param[in] i_value sizeof(OT) bits of data + /// @param[in] i_offset Start OT (start word, for example) in buffer + /// - defaults to 0 (will by default write the left most element) + /// @return FAPI2_RC_SUCCESS on success, FAPI2_RC_OVERFLOW otherwise + /// @note This is is only available for integral types. To set a + /// variable_buffer into a variable_buffer, use insert() + /// + template< typename OT> + inline fapi2::ReturnCode set(OT i_value, const bits_type i_offset = 0) + { + // Compile time check to make sure OT isn't a variable buffer + static_assert( !std::is_same<bits_container, OT>::value, + "Can't use a variable_buffer as input to set()" ); + + // + // There's a gotcha in here. size<OT>() returns the size in the buffer + // in OT units *rounded up*. This is the actual size of the buffer, not + // the perceived size of a variable_buffer. This should be OK however, + // as what we're trying to prevent is overflow, which this should do. + // + const uint32_t length = TT:: template size<OT>(iv_data); + static const bits_type bits_in_value = parameterTraits<OT>::bit_length; + const bits_type bit_length = TT::bit_length(iv_data); + + if (i_offset >= length) + { + return FAPI2_RC_OVERFLOW; + } + + // Create mask if part of this byte is not in the valid part of the buffer, + // Shift it left by the amount of unused bits, + // Clear the unused bits + if (((i_offset + 1) == length) && (bit_length % bits_in_value)) { + i_value &= parameterTraits<OT>::mask << ((bits_in_value * length) - bit_length); + } + + parameterTraits<OT>::template write_element<unit_type>(TT::get_address(iv_data), i_value, i_offset); + return FAPI2_RC_SUCCESS; + } + + /// + /// @brief Set and entire buffer to X's + /// @tparam X {0,1} depending if you want to clear (0) + /// or fill (1) a buffer + /// + template< uint8_t X > + inline void flush(void) + { + static_assert( (X == 1) || (X == 0), "bad argument to flush" ); + (0 == X) ? TT::clear(iv_data) : TT::set(iv_data); + } + + /// + /// @brief Invert entire buffer + /// @return buffer_base&, Useful for method chaining + /// + inline buffer_base& invert(void) + { TT::invert(iv_data); return *this; } + + /// + /// @brief Bit reverse entire buffer + /// @return buffer_base&, Useful for method chaining + /// + inline buffer_base& reverse(void) + { TT::reverse(iv_data); return *this; } + + //@} + protected: + + /// + /// @brief Variable buffer constructor + /// @param[in] i_value number of *bits* (sizeof(container_units) * 8) + /// needed. Meaningless for integral types and thus protected. + /// + buffer_base(bits_type i_value); + + /// + /// @brief Variable buffer construct from a list + /// @param[in] i_value an initializer list to initialize the container. + /// Meaningless for integral types and thus protected + /// + buffer_base(std::initializer_list<unit_type> i_value); + + /// + /// @brief Clear the buffer + /// + inline void clear(void) + { TT::clear(iv_data); } + + /// The contents of the buffer + T iv_data; + }; + + template <typename T, typename TT> + inline buffer_base<T, TT>::buffer_base(bits_type i_value): + iv_data( std::max(bits_type(1), + bits_type(i_value / 8 / sizeof(bits_type)))) + { + } + + template <typename T, typename TT> + inline buffer_base<T, TT>::buffer_base(std::initializer_list<unit_type> i_value): + iv_data(i_value) + { + } +}; + + + +#endif diff --git a/hwpf/plat/include/buffer_parameters.H b/hwpf/plat/include/buffer_parameters.H index 3dc41b26..2a6e6100 100644 --- a/hwpf/plat/include/buffer_parameters.H +++ b/hwpf/plat/include/buffer_parameters.H @@ -41,12 +41,17 @@ namespace fapi2 class parameterTraits { public: - enum - { - mask = T(~0), - bit_length = sizeof(T) * 8, - byte_length = sizeof(T), - }; + // Why constexpr functions? Enums are hard to do math on, and + // static const doesn't work without -O1 (or greater.) That might + // be a bug in g++ but this works just the same. + constexpr static T mask(void) + { return T(~0); } + + constexpr static uint32_t byte_length(void) + { return sizeof(T); } + + constexpr static uint32_t bit_length(void) + { return sizeof(T) * 8; } template<typename U> inline static void write_element(void* i_data, T i_value, uint32_t i_offset) @@ -60,6 +65,6 @@ namespace fapi2 } }; /// @endcond -}; +} #endif diff --git a/hwpf/plat/include/buffer_traits.H b/hwpf/plat/include/buffer_traits.H index 8f42ce9e..7cab81ff 100644 --- a/hwpf/plat/include/buffer_traits.H +++ b/hwpf/plat/include/buffer_traits.H @@ -91,8 +91,8 @@ namespace fapi2 constexpr static B size(const T& i_buffer) { return (bit_length(i_buffer) + - (parameterTraits<E>::bit_length - 1)) / - parameterTraits<E>::bit_length; + (parameterTraits<E>::bit_length() - 1)) / + parameterTraits<E>::bit_length(); } /// @@ -182,8 +182,8 @@ namespace fapi2 constexpr static uint32_t size(const bits_container& i_buffer) { return (bit_length(i_buffer) + - (parameterTraits<E>::bit_length - 1)) / - parameterTraits<E>::bit_length; + (parameterTraits<E>::bit_length() - 1)) / + parameterTraits<E>::bit_length(); } /// diff --git a/hwpf/plat/include/utils.H b/hwpf/plat/include/utils.H index 216656c8..69e84d20 100644 --- a/hwpf/plat/include/utils.H +++ b/hwpf/plat/include/utils.H @@ -66,6 +66,16 @@ uint64_t revle64(uint64_t i_x); #endif - +namespace fapi2 +{ + /// @brief Delay this thread. + /// @param[in] i_nanoSeconds nanoseconds to sleep + /// @param[in] i_simCycles count of Awan cycles to advance + /// @return ReturnCode. Zero on success, else platform specified error. + inline ReturnCode delay(uint64_t i_nanoSeconds, uint64_t i_simCycles) + { + return FAPI2_RC_SUCCESS; + } +} #endif // FAPI2_UTILS_H_ diff --git a/importtemp/fapi2/include/error_info_defs.H b/importtemp/fapi2/include/error_info_defs.H index 31fc3429..e0f4a898 100644 --- a/importtemp/fapi2/include/error_info_defs.H +++ b/importtemp/fapi2/include/error_info_defs.H @@ -33,9 +33,9 @@ #include <stdint.h> #include <target.H> -#include <variable_buffer.H> +//#include <variable_buffer.H> -#include <iostream> +//#include <iostream> namespace fapi2 { @@ -230,6 +230,8 @@ namespace fapi2 return EI_FFDC_SIZE_TARGET; } + // Comment out this code temporarily for compilation +#if 0 /// /// @brief Get FFDC Size specialization for variable buffers /// @@ -240,6 +242,7 @@ namespace fapi2 return std::min(static_cast<uint32_t>(EI_FFDC_MAX_SIZE), i_thing.getLength<uint8_t>()); } +#endif }; diff --git a/sbe/image/Makefile b/sbe/image/Makefile index 576602db..82e9e703 100644 --- a/sbe/image/Makefile +++ b/sbe/image/Makefile @@ -55,6 +55,7 @@ HWPLIB_MAKE_DIR := $(HWPLIB_SRCDIR) LIB_DIRS += -L$(OBJDIR)/lib HWPLIB := $(OBJDIR)/libcommon.a LLIBS += -lcommon +include $(HWPLIB_SRCDIR)/libcommonerrors.mk # Common Cache HWP Exit library CACHE_MAKE_DIR := $(CACHE_SRCDIR) @@ -74,6 +75,7 @@ PERV_MAKE_DIR := $(PERV_SRCDIR) LIB_DIRS += -L$(OBJDIR)/perv PERVLIB := $(OBJDIR)/perv/libperv.a LLIBS += -lperv +include $(PERV_SRCDIR)/perverrors.mk # Common Nest libraries NEST_MAKE_DIR := $(NEST_SRCDIR) @@ -211,6 +213,8 @@ $(NESTLIB): $(MAKE) -I $(IMAGE_SRCDIR) -C $(NEST_MAKE_DIR) -f Makefile #Build the comming HWP lib procedures + +#Build the HWP lib procedures $(HWPLIB): @echo "Processing HWP lib makefile" $(MAKE) -I $(IMAGE_SRCDIR) -C $(HWPLIB_MAKE_DIR) -f Makefile @@ -234,6 +238,27 @@ normalize: $(SBE_TOOLS) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin defaultset: $(SBE_TOOLS) $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin normalize $(TOOLS_IMAGE_DIR)/ppeSetFixed.pl $(TOOLS_IMAGE_DIR) $(BASE_OBJDIR)/$(IMAGE_SEEPROM_NAME).bin $(IMPORT_XML_DIR)/p9_ppe_attributes.xml $(ATTRFILES) +# Build hwp_error_info.H. If the script fails then print the contents of +# the header and then delete whatever garbage the script left to force it to +# be built again. +# +# -*- HACK -*- Use local version of parseErrorInfo.pl until FW team +# updates the standard version to work in assembly. The source for this +# script is : $(FAPI)/capi/scripts/parseErrorInfo.pl + +.PHONY : xml + +xml: $(FAPI_RC) + +$(FAPI_RC): $(TOOLS_ATTR_DIR)/parseErrorInfo.pl $(ERROR_XML_FILES) + $(TOOLS_ATTR_DIR)/parseErrorInfo.pl --empty-ffdc-classes --output-dir=. $(ERROR_XML_FILES) +# if [ $$? -ne 0 ]; then \ +# echo "Build of hwp_error_info.H failed; Current contents :"; \ +# cat hwp_error_info.H; \ +# rm -f hwp_error_info.H; \ +# exit 1; fi +# The above is commented out as the current version of make produces errors +# This was taken from the P8 SBE Makefile which worked. $(OBJDIR)/fixed.bin: $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin $(TOOLS_IMAGE_DIR)/sbe_xip_tool $(OBJDIR)/$(IMAGE_SEEPROM_NAME).bin extract .fixed $(BASE_OBJDIR)/fixed.bin @@ -261,7 +286,7 @@ clean: rm -f $(TOP-FIXED-HEADERS) rm -fr $(TOOLS_IMAGE_DIR)/bin/* rm -f *.dump - + rm -f hwp_return_codes.H hwp_error_info.H hwp_ffdc_classes.H collect_reg_ffdc.C set_sbe_error.H dump: objdump -s $(OBJDIR)/$(IMAGE_SEEPROM_NAME).out > $(IMAGE_SEEPROM_NAME).dump diff --git a/sbe/image/img_defs.mk b/sbe/image/img_defs.mk index 640d3be8..522562ad 100644 --- a/sbe/image/img_defs.mk +++ b/sbe/image/img_defs.mk @@ -126,6 +126,11 @@ ifndef BINUTILS-TOOL-PREFIX BINUTILS-TOOL-PREFIX = $(CTEPATH)/tools/ppetools/prod/powerpc-eabi/bin/ endif +ifndef FAPI_RC +FAPI_RC = hwp_return_codes.H +#FAPI_RC = +endif + OBJDIR = $(BASE_OBJDIR)$(SUB_OBJDIR) CC_ASM = $(GCC-TOOL-PREFIX)gcc @@ -196,6 +201,7 @@ export LD_LIBRARY_PATH = /afs/awd.austin.ibm.com/proj/p3/cte/tools/gcc405lin/vol INCLUDES += $(IMG_INCLUDES) INCLUDES += -I$(IMAGE_SRCDIR)/../../../include +INCLUDES += -I$(HWPLIB_SRCDIR) INCLUDES += -I$(PLAT_FAPI2_DIR)/include INCLUDES += -I$(PPE_FAPI2_DIR)/include INCLUDES += -I$(BASE_FAPI2_DIR)/include @@ -305,14 +311,14 @@ endif # work as Make targets. The *.d files are include-ed in the # subdirectory Makefiles. -$(OBJDIR)/%.d: %.C +$(OBJDIR)/%.d: %.C $(FAPI_RC) @set -e; rm -f $@; \ echo -n "$(OBJDIR)/" > $@.$$$$; \ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< >> $@.$$$$; \ sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ rm -f $@.$$$$ -$(OBJDIR)/%.d: %.c +$(OBJDIR)/%.d: %.c $(FAPI_RC) @set -e; rm -f $@; \ echo -n "$(OBJDIR)/" > $@.$$$$; \ echo "$(INCLUDES)"; \ @@ -320,7 +326,7 @@ $(OBJDIR)/%.d: %.c sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ rm -f $@.$$$$ -$(OBJDIR)/%.d: %.S +$(OBJDIR)/%.d: %.S $(FAPI_RC) @set -e; rm -f $@; \ echo -n "$(OBJDIR)/" > $@.$$$$; \ $(CC_ASM) -MM $(INCLUDES) $(CPPFLAGS) $(DEFS) $< >> $@.$$$$; \ diff --git a/sbe/image/sbe_xip_image.c b/sbe/image/sbe_xip_image.c index 91576d50..270b450d 100644 --- a/sbe/image/sbe_xip_image.c +++ b/sbe/image/sbe_xip_image.c @@ -1,5 +1,3 @@ -// $Id: sbe_xip_image.c,v 1.28 2013/12/11 00:12:41 bcbrock Exp $ - /// \file sbe_xip_image.c /// \brief APIs for validating, normalizing, searching and manipulating /// SBE-XIP images. @@ -1735,115 +1733,6 @@ sbe_xip_find(void* i_image, } -int -sbe_xip_map_halt(void* io_image, - int (*i_fn)(void* io_image, - const uint64_t i_imageAddress, - const char* i_rcString, - void* io_arg), - void* io_arg) -{ - int rc; - SbeXipSection haltSection; - SbeXipHalt *halt; - uint32_t size; - uint32_t actualSize; - - do { - rc = xipQuickCheck(io_image, 0); - if (rc) break; - - rc = sbe_xip_get_section(io_image, SBE_XIP_SECTION_HALT, &haltSection); - if (rc) break; - - halt = (SbeXipHalt*)((unsigned long)io_image + haltSection.iv_offset); - size = haltSection.iv_size; - - while (size) { - - rc = i_fn(io_image, - xipRevLe64(halt->iv_address), - halt->iv_string, - io_arg); - if (rc) break; - - // The SbeXipHalt structure claims a 4-character string. The - // computation below computes the actual record size based on the - // actual length of the string, including the 0-byte termination. - - actualSize = 8 + (((strlen(halt->iv_string) + 4) / 4) * 4); - - if (size < actualSize) { - rc = TRACE_ERRORX(SBE_XIP_IMAGE_ERROR, - "The .halt section is improperly formed\n"); - break; - } - - size -= actualSize; - halt = (SbeXipHalt*)((unsigned long)halt + actualSize); - }; - - if (rc) break; - - } while (0); - - return rc; -} - - -typedef struct { - uint64_t iv_address; - const char* iv_string; -} GetHaltStruct; - - -XIP_STATIC int -xipGetHaltMap(void* io_image, - const uint64_t i_imageAddress, - const char* i_rcString, - void* io_arg) -{ - int rc; - - GetHaltStruct* s = (GetHaltStruct*)io_arg; - - if (i_imageAddress == s->iv_address) { - s->iv_string = i_rcString; - rc = -1; - } else { - rc = 0; - } - - return rc; -} - - -int -sbe_xip_get_halt(void* io_image, - const uint64_t i_imageAddress, - const char** o_rcString) -{ - int rc; - GetHaltStruct s; - - s.iv_address = i_imageAddress; - do { - rc = xipQuickCheck(io_image, 0); - if (rc) break; - - rc = sbe_xip_map_halt(io_image, xipGetHaltMap, &s); - if (rc == 0) { - rc = TRACE_ERRORX(SBE_XIP_ITEM_NOT_FOUND, - "sbe_xip_get_halt: No HALT code is associated " - "with address " F0x012llx "\n", i_imageAddress); - } else if (rc < 0) { - *o_rcString = s.iv_string; - rc = 0; - } - } while (0); - - return rc; -} int @@ -1858,12 +1747,27 @@ sbe_xip_get_scalar(void *i_image, const char* i_id, uint64_t* o_data) case SBE_XIP_UINT8: *o_data = *((uint8_t*)(item.iv_imageData)); break; + case SBE_XIP_UINT16: + *o_data = xipRevLe16(*((uint16_t*)(item.iv_imageData))); + break; case SBE_XIP_UINT32: *o_data = xipRevLe32(*((uint32_t*)(item.iv_imageData))); break; case SBE_XIP_UINT64: *o_data = xipRevLe64(*((uint64_t*)(item.iv_imageData))); break; + case SBE_XIP_INT8: + *o_data = *((int8_t*)(item.iv_imageData)); + break; + case SBE_XIP_INT16: + *o_data = xipRevLe16(*((int16_t*)(item.iv_imageData))); + break; + case SBE_XIP_INT32: + *o_data = xipRevLe32(*((int32_t*)(item.iv_imageData))); + break; + case SBE_XIP_INT64: + *o_data = xipRevLe64(*((int64_t*)(item.iv_imageData))); + break; case SBE_XIP_ADDRESS: *o_data = item.iv_address; break; @@ -1898,12 +1802,27 @@ sbe_xip_get_element(void *i_image, case SBE_XIP_UINT8: *o_data = ((uint8_t*)(item.iv_imageData))[i_index]; break; + case SBE_XIP_UINT16: + *o_data = xipRevLe16(((uint16_t*)(item.iv_imageData))[i_index]); + break; case SBE_XIP_UINT32: *o_data = xipRevLe32(((uint32_t*)(item.iv_imageData))[i_index]); break; case SBE_XIP_UINT64: *o_data = xipRevLe64(((uint64_t*)(item.iv_imageData))[i_index]); break; + case SBE_XIP_INT8: + *o_data = ((int8_t*)(item.iv_imageData))[i_index]; + break; + case SBE_XIP_INT16: + *o_data = xipRevLe16(((int16_t*)(item.iv_imageData))[i_index]); + break; + case SBE_XIP_INT32: + *o_data = xipRevLe32(((int32_t*)(item.iv_imageData))[i_index]); + break; + case SBE_XIP_INT64: + *o_data = xipRevLe64(((int64_t*)(item.iv_imageData))[i_index]); + break; default: rc = TRACE_ERROR(SBE_XIP_TYPE_ERROR); break; @@ -1976,12 +1895,27 @@ sbe_xip_set_scalar(void* io_image, const char* i_id, const uint64_t i_data) case SBE_XIP_UINT8: *((uint8_t*)(item.iv_imageData)) = (uint8_t)i_data; break; + case SBE_XIP_UINT16: + *((uint16_t*)(item.iv_imageData)) = xipRevLe16((uint16_t)i_data); + break; case SBE_XIP_UINT32: *((uint32_t*)(item.iv_imageData)) = xipRevLe32((uint32_t)i_data); break; case SBE_XIP_UINT64: *((uint64_t*)(item.iv_imageData)) = xipRevLe64((uint64_t)i_data); break; + case SBE_XIP_INT8: + *((int8_t*)(item.iv_imageData)) = (int8_t)i_data; + break; + case SBE_XIP_INT16: + *((int16_t*)(item.iv_imageData)) = xipRevLe16((int16_t)i_data); + break; + case SBE_XIP_INT32: + *((int32_t*)(item.iv_imageData)) = xipRevLe32((int32_t)i_data); + break; + case SBE_XIP_INT64: + *((int64_t*)(item.iv_imageData)) = xipRevLe64((int64_t)i_data); + break; default: rc = TRACE_ERROR(SBE_XIP_TYPE_ERROR); break; diff --git a/sbe/image/topfiles.mk b/sbe/image/topfiles.mk index 36e541e8..37af6c2b 100644 --- a/sbe/image/topfiles.mk +++ b/sbe/image/topfiles.mk @@ -1,5 +1,5 @@ -TOP-C-SOURCES = -TOP-CPP-SOURCES = sbe_main.C sbe_loader.c +TOP-C-SOURCES = sbe_loader.c +TOP-CPP-SOURCES = sbe_main.C TOP-S-SOURCES = base_ppe_header.S TOP-FIXED-HEADERS += $(IMAGE_SRCDIR)/proc_sbe_fixed_perv.H diff --git a/tools/image/sbe_xip_tool.c b/tools/image/sbe_xip_tool.c index 195a29ef..75448a25 100644 --- a/tools/image/sbe_xip_tool.c +++ b/tools/image/sbe_xip_tool.c @@ -77,13 +77,9 @@ // // The 'report' command prints a report including a dump of the header and // section table, a listing of the types and values of all items that appear -// in the TOC, and a dump of the .halt section. The TOC listing includes the +// in the TOC. The TOC listing includes the // sequence number of the entry in the TOC, the item name, the item type and -// the item value. The .halt listing displays a map of HALT PC values to the -// string form of the halt code associated with the HALT address. The optional -// <regex> expression, if present, is a POSIX Basic Regular Expression. If -// <regex> is specified, then no header, section table or .halt dumps are -// provided, and only the TOC entries matching <regex> will be listed. +// the item value. // // The 'append' command either creates or extends the section named by the // section argument, by appending the contents of the named file verbatim. @@ -158,13 +154,9 @@ const char* g_usage = "\n" "The 'report' command prints a report including a dump of the header and\n" "section table, a listing of the types and values of all items that appear\n" -"in the TOC, and a dump of the .halt section. The TOC listing includes the\n" +"in the TOC. The TOC listing includes the\n" "sequence number of the entry in the TOC, the item name, the item type and\n" -"the item value. The .halt listing displays a map of HALT PC values to the\n" -"string form of the halt code associated with the HALT address. The optional\n" -"<regex> expression, if present, is a POSIX Basic Regular Expression. If\n" -"<regex> is specified, then no header, section table or .halt dumps are\n" -"provided, and only the TOC entries matching <regex> will be listed.\n" +"the item value.\n" "\n" "The 'append' command either creates or extends the section named by the\n" "section argument, by appending the contents of the named file verbatim.\n" @@ -332,16 +324,41 @@ tocListing(void* io_image, if (rc) break; printf("0x%02x", (uint8_t)data); break; + case SBE_XIP_INT8: + rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data); + if (rc) break; + printf("%d", (int8_t)data); + break; + case SBE_XIP_UINT16: + rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data); + if (rc) break; + printf("0x%08x", (uint16_t)data); + break; + case SBE_XIP_INT16: + rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data); + if (rc) break; + printf("%d", (int16_t)data); + break; case SBE_XIP_UINT32: rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data); if (rc) break; printf("0x%08x", (uint32_t)data); break; + case SBE_XIP_INT32: + rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data); + if (rc) break; + printf("%d", (int32_t)data); + break; case SBE_XIP_UINT64: rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data); if (rc) break; printf("0x%016llx", data); break; + case SBE_XIP_INT64: + rc = sbe_xip_get_scalar(io_image, i_item->iv_id, &data); + if (rc) break; + printf("%d", (int64_t)data); + break; case SBE_XIP_STRING: rc = sbe_xip_get_string(io_image, i_item->iv_id, &s); if (rc) break; @@ -355,6 +372,7 @@ tocListing(void* io_image, (uint32_t)(data & 0xffffffff)); break; default: + printf("unknown type\n"); rc = SBE_XIP_BUG; break; } @@ -421,19 +439,6 @@ dumpHeader(void* i_image) } -// Dump an entry from .halt - -int -haltListing(void* io_image, - const uint64_t i_homerAddress, - const char* i_rcString, - void* io_arg) -{ - printf("%016llx : %s\n", i_homerAddress, i_rcString); - return 0; -} - - // Print a report int @@ -475,17 +480,6 @@ report(void* io_image, const int i_argc, const char** i_argv) rc = sbe_xip_map_toc(io_image, tocListing, (void*)(&control)); if (rc) break; - // Dump the .halt section - - if (i_argc == 0) { - printf("\nHALT report\n\n"); - rc = sbe_xip_map_halt(io_image, haltListing, 0); - if (rc == SBE_XIP_ITEM_NOT_FOUND) { - rc = 0; - } - if (rc) break; - } - } while (0); return rc; @@ -550,6 +544,7 @@ set(void* io_image, const int i_argc, const char** i_argv, int i_setv) switch (item.iv_type) { case SBE_XIP_UINT8: + case SBE_XIP_UINT16: case SBE_XIP_UINT32: case SBE_XIP_UINT64: @@ -586,6 +581,15 @@ set(void* io_image, const int i_argc, const char** i_argv, int i_setv) } break; + case SBE_XIP_UINT16: + if ((uint16_t)newValue != newValue) { + fprintf(stderr, + "Value 0x%016llx too large for 16-bit type\n", + newValue); + exit(1); + } + break; + case SBE_XIP_UINT32: if ((uint32_t)newValue != newValue) { fprintf(stderr, @@ -616,7 +620,18 @@ set(void* io_image, const int i_argc, const char** i_argv, int i_setv) rc = sbe_xip_set_string(io_image, key, (char*)value); if (rc) rc = SBE_XIP_BUG; break; - + case SBE_XIP_INT8: + case SBE_XIP_INT16: + case SBE_XIP_INT32: + case SBE_XIP_INT64: + fprintf(stderr, + "Item %s has int type %s, " + "which is not supported for '%s'.\n", + i_argv[arg], + SBE_XIP_TYPE_STRING(g_typeStrings, item.iv_type), + (i_setv ? "setv" : "set")); + exit(1); + break; default: fprintf(stderr, "Item %s has type %s, " @@ -713,6 +728,7 @@ get(void* i_image, const int i_argc, const char** i_argv, int i_getv) switch (item.iv_type) { case SBE_XIP_UINT8: + case SBE_XIP_UINT16: case SBE_XIP_UINT32: case SBE_XIP_UINT64: rc = sbe_xip_get_element(i_image, key, index_val, &data); @@ -724,6 +740,9 @@ get(void* i_image, const int i_argc, const char** i_argv, int i_getv) case SBE_XIP_UINT8: printf("0x%02x\n", (uint8_t)data); break; + case SBE_XIP_UINT16: + printf("0x%04x\n", (uint16_t)data); + break; case SBE_XIP_UINT32: printf("0x%08x\n", (uint32_t)data); break; @@ -762,7 +781,14 @@ get(void* i_image, const int i_argc, const char** i_argv, int i_getv) } printf("%s\n", s); break; - + case SBE_XIP_INT8: + case SBE_XIP_INT16: + case SBE_XIP_INT32: + case SBE_XIP_INT64: + fprintf(stderr, "%s%d : Bug, int types not implemented %d\n", + __FILE__, __LINE__, item.iv_type); + exit(1); + break; default: fprintf(stderr, "%s%d : Bug, unexpected type %d\n", __FILE__, __LINE__, item.iv_type); @@ -1332,18 +1358,6 @@ TEST(void* io_image, const int i_argc, const char** i_argv) BOMB_IF(sbe_xip_find(io_image, "proc_sbe_ex_dpll_initf", 0) != 0); } - // Run the embedded delete and append tests. This assumes that the - // test image does not contain the .fit and .ffdc sections. We just - // append zeros here, we're mostly interested in whether we can handle - // errors and return the image back to its original state. - - BOMB_IF((deleteAppendImage = malloc(imageSize + 2000)) == 0); - memcpy(deleteAppendImage, io_image, imageSize); - - BOMB_IF(sbe_xip_append(deleteAppendImage, SBE_XIP_SECTION_FIT, - 0, 973, imageSize + 2000, 0) != 0); - BOMB_IF(sbe_xip_append(deleteAppendImage, SBE_XIP_SECTION_FFDC, - 0, 973, imageSize + 2000, 0) != 0); #ifdef DEBUG_SBE_XIP_IMAGE printf("\nYou will see an expected warning below " @@ -1351,14 +1365,6 @@ TEST(void* io_image, const int i_argc, const char** i_argv) "It means the TEST is working (not failing)\n\n"); #endif - BOMB_IF(sbe_xip_append(deleteAppendImage, SBE_XIP_SECTION_FFDC, - 0, 973, imageSize + 2000, 0) == 0); - - BOMB_IF(sbe_xip_delete_section(deleteAppendImage, SBE_XIP_SECTION_FFDC) != 0); - BOMB_IF(sbe_xip_delete_section(deleteAppendImage, SBE_XIP_SECTION_FIT) != 0); - - memcpy(io_image, deleteAppendImage, imageSize); - // Finally compare against the original BOMB_IF(memcmp(io_image, originalImage, imageSize)); @@ -1473,440 +1479,432 @@ int disassembleSection(void *i_image, int i_argc, const char **i_argv) { - int rc=0, rcSet=0; - uint32_t rcCount=0; - char *disList=NULL; - uint32_t sizeSection=0, nextLinkOffsetBlock=0; - uint32_t sizeBlock=0, sizeData=0, sizeCode=0, sizeData2=0; - uint32_t sizeDisLine=0, sizeList=0, sizeListMax=0; - uint32_t offsetCode=0; - uint8_t typeRingsSection=0; // 0: RS4 1: Wiggle-Flip - uint8_t bSummary=0, bFoundInToc=0; - uint32_t sectionId; - uint64_t backPtr=0, fwdPtr=0; - PairingInfo pairingInfo; - const char *sectionName; + int rc=0, rcSet=0; + uint32_t rcCount=0; + char *disList=NULL; + uint32_t sizeSection=0, nextLinkOffsetBlock=0; + uint32_t sizeBlock=0, sizeData=0, sizeCode=0, sizeData2=0; + uint32_t sizeDisLine=0, sizeList=0, sizeListMax=0; + uint32_t offsetCode=0; + uint8_t typeRingsSection=0; // 0: RS4 1: Wiggle-Flip + uint8_t bSummary=0, bFoundInToc=0; + uint32_t sectionId; + uint64_t backPtr=0, fwdPtr=0; + PairingInfo pairingInfo; + const char *sectionName; char *ringName; uint32_t ringSeqNo=0; // Ring sequence location counter. uint8_t vectorPos,overRidable; - void *nextBlock, *nextSection; - SbeXipHeader hostHeader; - SbeXipSection hostSection; - ImageInlineContext ctx; - ImageInlineDisassembly dis; - char lineDis[LISTING_STRING_SIZE]; - void *hostRs4Container; - uint32_t compressedBits=0, ringLength=0; - double compressionPct=0; - - if (i_argc != 1) { - fprintf(stderr, g_usage); - exit(1); - } - sectionName = i_argv[0]; - - // Determine SBE-XIP section ID from the section name, e.g. - // .ipl_text => SBE_XIP_SECTION_IPL_TEXT - // .text => SBE_XIP_SECTION_TEXT - // .rings => SBE_XIP_SECTION_RINGS - if (strcmp(sectionName, ".header")==0) - sectionId = SBE_XIP_SECTION_HEADER; - else - if (strcmp(sectionName, ".fixed")==0) - sectionId = SBE_XIP_SECTION_FIXED; - else - if (strcmp(sectionName, ".fixed_toc")==0) - sectionId = SBE_XIP_SECTION_FIXED_TOC; - else - if (strcmp(sectionName, ".ipl_text")==0) - sectionId = SBE_XIP_SECTION_IPL_TEXT; - else - if (strcmp(sectionName, ".ipl_data")==0) - sectionId = SBE_XIP_SECTION_IPL_DATA; - else - if (strcmp(sectionName, ".text")==0) - sectionId = SBE_XIP_SECTION_TEXT; - else - if (strcmp(sectionName, ".data")==0) - sectionId = SBE_XIP_SECTION_DATA; - else - if (strcmp(sectionName, ".toc")==0) - sectionId = SBE_XIP_SECTION_TOC; - else - if (strcmp(sectionName, ".strings")==0) - sectionId = SBE_XIP_SECTION_STRINGS; - else - if (strcmp(sectionName, ".pibmem0")==0) - sectionId = SBE_XIP_SECTION_PIBMEM0; - else - if (strcmp(sectionName, ".rings")==0) - sectionId = SBE_XIP_SECTION_RINGS; - else - if (strcmp(sectionName, ".rings_summary")==0) { - sectionId = SBE_XIP_SECTION_RINGS; - bSummary = 1; - } - else - if (strcmp(sectionName, ".dcrings")==0) - sectionId = SBE_XIP_SECTION_DCRINGS; - else - if (strcmp(sectionName, ".halt")==0) - sectionId = SBE_XIP_SECTION_HALT; - else - if (strcmp(sectionName, ".slw")==0) - sectionId = SBE_XIP_SECTION_SLW; - else - if (strcmp(sectionName, ".ffdc")==0) - sectionId = SBE_XIP_SECTION_FFDC; - else { - fprintf(stderr,"ERROR : %s is an invalid section name.\n",sectionName); - fprintf(stderr,"Valid <section> names for the 'dis' function are:\n"); - fprintf(stderr,"\t.header\n"); - fprintf(stderr,"\t.fixed\n"); - fprintf(stderr,"\t.fixed_toc\n"); - fprintf(stderr,"\t.ipl_text\n"); - fprintf(stderr,"\t.ipl_data\n"); - fprintf(stderr,"\t.text\n"); - fprintf(stderr,"\t.data\n"); - fprintf(stderr,"\t.toc\n"); - fprintf(stderr,"\t.strings\n"); - fprintf(stderr,"\t.pibmem0\n"); - fprintf(stderr,"\t.rings\n"); - fprintf(stderr,"\t.rings_summary\n"); - fprintf(stderr,"\t.dcrings\n"); - fprintf(stderr,"\t.halt\n"); - fprintf(stderr,"\t.slw\n"); - fprintf(stderr,"\t.ffdc\n"); - exit(1); - } - - // Get host header and section pointer. - // - sbe_xip_translate_header( &hostHeader, (SbeXipHeader*)i_image); - rc = sbe_xip_get_section( i_image, sectionId, &hostSection); - if (rc) { - fprintf( stderr, "sbe_xip_get_section() failed : %s\n", SBE_XIP_ERROR_STRING(g_errorStrings, rc)); - return SBE_XIP_DISASSEMBLER_ERROR; - } - sizeSection = hostSection.iv_size; - nextBlock = (void*)(hostSection.iv_offset + (uintptr_t)i_image); - nextSection = (void*)((uint64_t)nextBlock + (uint64_t)sizeSection); + void *nextBlock, *nextSection; + SbeXipHeader hostHeader; + SbeXipSection hostSection; + ImageInlineContext ctx; + ImageInlineDisassembly dis; + char lineDis[LISTING_STRING_SIZE]; + void *hostRs4Container; + uint32_t compressedBits=0, ringLength=0; + double compressionPct=0; + + if (i_argc != 1) { + fprintf(stderr, g_usage); + exit(1); + } + sectionName = i_argv[0]; + + // Determine SBE-XIP section ID from the section name, e.g. + // .loader_text => SBE_XIP_SECTION_LOADER_TEXT + // .text => SBE_XIP_SECTION_TEXT + // .rings => SBE_XIP_SECTION_RINGS + if (strcmp(sectionName, ".header")==0) + sectionId = SBE_XIP_SECTION_HEADER; + else + if (strcmp(sectionName, ".fixed")==0) + sectionId = SBE_XIP_SECTION_FIXED; + else + if (strcmp(sectionName, ".fixed_toc")==0) + sectionId = SBE_XIP_SECTION_FIXED_TOC; + else + if (strcmp(sectionName, ".loader_text")==0) + sectionId = SBE_XIP_SECTION_LOADER_TEXT; + else + if (strcmp(sectionName, ".loader_data")==0) + sectionId = SBE_XIP_SECTION_LOADER_DATA; + else + if (strcmp(sectionName, ".text")==0) + sectionId = SBE_XIP_SECTION_TEXT; + else + if (strcmp(sectionName, ".data")==0) + sectionId = SBE_XIP_SECTION_DATA; + else + if (strcmp(sectionName, ".toc")==0) + sectionId = SBE_XIP_SECTION_TOC; + else + if (strcmp(sectionName, ".strings")==0) + sectionId = SBE_XIP_SECTION_STRINGS; + else + if (strcmp(sectionName, ".base")==0) + sectionId = SBE_XIP_SECTION_BASE; + else + if (strcmp(sectionName, ".baseloader")==0) + sectionId = SBE_XIP_SECTION_BASELOADER; + else + if (strcmp(sectionName, ".rings")==0) + sectionId = SBE_XIP_SECTION_RINGS; + else + if (strcmp(sectionName, ".rings_summary")==0) { + sectionId = SBE_XIP_SECTION_RINGS; + bSummary = 1; + } + else + if (strcmp(sectionName, ".overlays")==0) + sectionId = SBE_XIP_SECTION_OVERLAYS; + else { + fprintf(stderr,"ERROR : %s is an invalid section name.\n",sectionName); + fprintf(stderr,"Valid <section> names for the 'dis' function are:\n"); + fprintf(stderr,"\t.header\n"); + fprintf(stderr,"\t.fixed\n"); + fprintf(stderr,"\t.fixed_toc\n"); + fprintf(stderr,"\t.loader_text\n"); + fprintf(stderr,"\t.loader_data\n"); + fprintf(stderr,"\t.text\n"); + fprintf(stderr,"\t.data\n"); + fprintf(stderr,"\t.toc\n"); + fprintf(stderr,"\t.strings\n"); + fprintf(stderr,"\t.base\n"); + fprintf(stderr,"\t.baseloader\n"); + fprintf(stderr,"\t.overlays\n"); + fprintf(stderr,"\t.rings\n"); + fprintf(stderr,"\t.rings_summary\n"); + exit(1); + } + + // Get host header and section pointer. + // + sbe_xip_translate_header( &hostHeader, (SbeXipHeader*)i_image); + rc = sbe_xip_get_section( i_image, sectionId, &hostSection); + if (rc) { + fprintf( stderr, "sbe_xip_get_section() failed : %s\n", SBE_XIP_ERROR_STRING(g_errorStrings, rc)); + return SBE_XIP_DISASSEMBLER_ERROR; + } + sizeSection = hostSection.iv_size; + nextBlock = (void*)(hostSection.iv_offset + (uintptr_t)i_image); + nextSection = (void*)((uint64_t)nextBlock + (uint64_t)sizeSection); - // Relocatable offset of section at hand. - nextLinkOffsetBlock = (uint32_t)hostHeader.iv_linkAddress + hostSection.iv_offset; - - // Allocate buffer to hold disassembled listing. (Start out with minimum 10k buffer size.) - // - if (sizeSection>10000) - sizeListMax = sizeSection; // Just to use something as an initial guess. - else - sizeListMax = 10000; - disList = (char*)malloc(sizeListMax); - if (disList==NULL) { - fprintf( stderr, "ERROR : malloc() failed.\n"); - fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_MEMORY_ERROR)); - return SBE_XIP_DISASSEMBLER_ERROR; - } - *disList = '\0'; // Make sure the buffer is NULL terminated (though probably not needed.) - sizeList = 0; - - // Create context and point it to image section. - // - rc = image_inline_context_create( &ctx, - nextBlock, - sizeSection, - nextLinkOffsetBlock, - 0); - if (rc) { - fprintf( stderr, "ERROR : %s (rc=%i)\n",image_inline_error_strings[rc],rc); - fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_DISASM_ERROR)); - return SBE_XIP_DISASSEMBLER_ERROR; - } + // Relocatable offset of section at hand. + nextLinkOffsetBlock = (uint32_t)hostHeader.iv_linkAddress + hostSection.iv_offset; - while ((uint64_t)nextBlock<(uint64_t)nextSection) { + // Allocate buffer to hold disassembled listing. (Start out with minimum 10k buffer size.) + // + if (sizeSection>10000) + sizeListMax = sizeSection; // Just to use something as an initial guess. + else + sizeListMax = 10000; + disList = (char*)malloc(sizeListMax); + if (disList==NULL) { + fprintf( stderr, "ERROR : malloc() failed.\n"); + fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_MEMORY_ERROR)); + return SBE_XIP_DISASSEMBLER_ERROR; + } + *disList = '\0'; // Make sure the buffer is NULL terminated (though probably not needed.) + sizeList = 0; - // Disassemble sections based on their types and intents. + // Create context and point it to image section. // - if (sectionId==SBE_XIP_SECTION_RINGS || sectionId==SBE_XIP_SECTION_DCRINGS) { - // Ring section (with a mix of data and code.) - // ...use BaseRingLayout structure to decode each ring block. - offsetCode = (uint32_t)myRev64(((BaseRingLayout*)nextBlock)->entryOffset); - sizeBlock = myRev32(((BaseRingLayout*)nextBlock)->sizeOfThis); - // ...determine ring type, either RS4 or Wiggle-flip. - if (offsetCode-(myRev32(((BaseRingLayout*)nextBlock)->sizeOfMeta)+3)/4*4>28) { - typeRingsSection = 0; // RS4 w/32-byte header. - sizeData2 = sizeBlock - offsetCode - ASM_RS4_LAUNCH_BUF_SIZE; - } - else - typeRingsSection = 1; // Wiggle-flip w/24-byte header. - // ...get the backPtr and fwdPtr and put at top of disasm listing. - backPtr = myRev64(((BaseRingLayout*)nextBlock)->backItemPtr); - sbe_xip_read_uint64(i_image, - backPtr, - &fwdPtr); + rc = image_inline_context_create( &ctx, + nextBlock, + sizeSection, + nextLinkOffsetBlock, + 0); + if (rc) { + fprintf( stderr, "ERROR : %s (rc=%i)\n",image_inline_error_strings[rc],rc); + fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_DISASM_ERROR)); + return SBE_XIP_DISASSEMBLER_ERROR; + } + + while ((uint64_t)nextBlock<(uint64_t)nextSection) { + + // Disassemble sections based on their types and intents. + // + if (sectionId==SBE_XIP_SECTION_RINGS || sectionId==SBE_XIP_SECTION_OVERLAYS) { + // Ring section (with a mix of data and code.) + // ...use BaseRingLayout structure to decode each ring block. + offsetCode = (uint32_t)myRev64(((BaseRingLayout*)nextBlock)->entryOffset); + sizeBlock = myRev32(((BaseRingLayout*)nextBlock)->sizeOfThis); + // ...determine ring type, either RS4 or Wiggle-flip. + if (offsetCode-(myRev32(((BaseRingLayout*)nextBlock)->sizeOfMeta)+3)/4*4>28) { + typeRingsSection = 0; // RS4 w/32-byte header. + sizeData2 = sizeBlock - offsetCode - ASM_RS4_LAUNCH_BUF_SIZE; + } + else + typeRingsSection = 1; // Wiggle-flip w/24-byte header. + // ...get the backPtr and fwdPtr and put at top of disasm listing. + backPtr = myRev64(((BaseRingLayout*)nextBlock)->backItemPtr); + sbe_xip_read_uint64(i_image, + backPtr, + &fwdPtr); - // Calculate RS4 compression efficiency if RS4 rings. - if (typeRingsSection==0) { - hostRs4Container = (void*)( (uintptr_t)nextBlock + - offsetCode + ASM_RS4_LAUNCH_BUF_SIZE ); - compressedBits = myRev32(((CompressedScanData*)hostRs4Container)->iv_algorithmReserved) * 4; - ringLength = myRev32(((CompressedScanData*)hostRs4Container)->iv_length); - compressionPct = (double)compressedBits / (double)ringLength * 100.0; + // Calculate RS4 compression efficiency if RS4 rings. + if (typeRingsSection==0) { + hostRs4Container = (void*)( (uintptr_t)nextBlock + + offsetCode + ASM_RS4_LAUNCH_BUF_SIZE ); + compressedBits = myRev32(((CompressedScanData*)hostRs4Container)->iv_algorithmReserved) * 4; + ringLength = myRev32(((CompressedScanData*)hostRs4Container)->iv_length); + compressionPct = (double)compressedBits / (double)ringLength * 100.0; } - // + // // Map over TOC or do a targeted search of FIXED_TOC to pair backPtr addr // with ring name and override and/or vector position (i.e. multi-chiplet). // - sbe_xip_get_section( i_image, SBE_XIP_SECTION_TOC, &hostSection); + sbe_xip_get_section( i_image, SBE_XIP_SECTION_TOC, &hostSection); if (hostSection.iv_offset) { - // TOC exists. - pairingInfo.address = backPtr; + // TOC exists. + pairingInfo.address = backPtr; // Search for pairing. First exhaust base position (pos=0), then next, then next, ... for (pairingInfo.vectorpos=0;pairingInfo.vectorpos<32;pairingInfo.vectorpos++) { - rc = sbe_xip_map_toc( i_image, pairRingNameAndAddr, (void*)(&pairingInfo)); + rc = sbe_xip_map_toc( i_image, pairRingNameAndAddr, (void*)(&pairingInfo)); if (rc) break; } - if (rc==DIS_RING_NAME_ADDR_MATCH_FAILURE) { - fprintf( stderr,"ERROR : Error associated with sbe_xip_map_toc().\n"); - fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_RING_NAME_ADDR_MATCH_FAILURE)); - return SBE_XIP_DISASSEMBLER_ERROR; - } - ringSeqNo++; + if (rc==DIS_RING_NAME_ADDR_MATCH_FAILURE) { + fprintf( stderr,"ERROR : Error associated with sbe_xip_map_toc().\n"); + fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_RING_NAME_ADDR_MATCH_FAILURE)); + return SBE_XIP_DISASSEMBLER_ERROR; + } + ringSeqNo++; if (rc==DIS_RING_NAME_ADDR_MATCH_SUCCESS) { bFoundInToc = 1; - ringName = pairingInfo.name; // The ring name matched in pairRingNameAndAddr() + ringName = pairingInfo.name; // The ring name matched in pairRingNameAndAddr() vectorPos = pairingInfo.vectorpos; // The vector position matched in pairRingNameAndAddr() overRidable = pairingInfo.overridable; // Whether the ring supports on override ring. - if (pairingInfo.override) { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# ------------------------------\n# %i.\n# ringName = %s (override)\n# vectorPos = %i\n# overRidable = %i\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n", - ringSeqNo, ringName,vectorPos,overRidable,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct); - } - else { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# ------------------------------\n# %i.\n# ringName = %s (base)\n# vectorPos = %i\n# overRidable = %i\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n", - ringSeqNo,ringName,vectorPos,overRidable,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct); - } + if (pairingInfo.override) { + sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, + "# ------------------------------\n# %i.\n# ringName = %s (override)\n# vectorPos = %i\n# overRidable = %i\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n", + ringSeqNo, ringName,vectorPos,overRidable,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct); + } + else { + sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, + "# ------------------------------\n# %i.\n# ringName = %s (base)\n# vectorPos = %i\n# overRidable = %i\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n", + ringSeqNo,ringName,vectorPos,overRidable,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct); + } } - else { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# ------------------------------\n# %i.\n# ringName = Not found (but TOC's available)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n", - ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr); + else { + sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, + "# ------------------------------\n# %i.\n# ringName = Not found (but TOC's available)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n", + ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr); } - } + } else { - // TOC doesn't exist. First try targeted search of MVPD ring names in FIXED_TOC. - bFoundInToc = 0; // If we find in fixed_toc, then change to 1. + // TOC doesn't exist. First try targeted search of MVPD ring names in FIXED_TOC. + bFoundInToc = 0; // If we find in fixed_toc, then change to 1. // 2012-11-13: CMO TBD. Try using pairRingNameAndAddr by enabling a sequential - // traversing of each of the MVPD lists inside that function. You'll - // need to call pairRing manually from right here (or from a - // sbe_xip_search_fixed_toc()-like function). Maybe you can add a + // traversing of each of the MVPD lists inside that function. You'll + // need to call pairRing manually from right here (or from a + // sbe_xip_search_fixed_toc()-like function). Maybe you can add a // 4th arg to pairRing that is zero by default, meaning it is to be // used by xip_map_toc(). But if non-zero, it is to be used in a // traversing manner. Or you could add another member to the - // PairingInfo struct to indirectly pass this info to the function. + // PairingInfo struct to indirectly pass this info to the function. // You'd also need to pass two more arguments to get_vpd_ring_list_ - // entry() to indicate sequence number and the MVPD keyword. - // rc = pairRingNameAndAddr(); + // entry() to indicate sequence number and the MVPD keyword. + // rc = pairRingNameAndAddr(); // if (rc==DIS_RING_NAME_ADDR_MATCH_SUCCESS) { - // bFoundInToc = 1; - // // Do same as in TOC section above. - // break; - // } - // // OK, so ring name wasn't in TOC nor in FIXED_TOC. That happens if the ring - // // is a non-Mvpd ring and the TOC has been removed, such as in an IPL or - // // Seeprom image. - ringSeqNo++; - if (typeRingsSection==0) { - // RS4 header, which has override info - if (((Rs4RingLayout*)nextBlock)->override==0) { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# ------------------------------\n# %i.\n# ringName = Not available (base)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n", - ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct); - } + // bFoundInToc = 1; + // // Do same as in TOC section above. + // break; + // } + // // OK, so ring name wasn't in TOC nor in FIXED_TOC. That happens if the ring + // // is a non-Mvpd ring and the TOC has been removed, such as in an IPL or + // // Seeprom image. + ringSeqNo++; + if (typeRingsSection==0) { + // RS4 header, which has override info + if (((Rs4RingLayout*)nextBlock)->override==0) { + sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, + "# ------------------------------\n# %i.\n# ringName = Not available (base)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n", + ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct); + } else { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# ------------------------------\n# %i.\n# ringName = Not available (override)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n", - ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct); + sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, + "# ------------------------------\n# %i.\n# ringName = Not available (override)\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n# Compressed Bits = %u\n# Ring Length Bits = %u\n# Compression = %0.2f%%\n", + ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr,compressedBits,ringLength,compressionPct); } - } + } else { - // WF header, which doesn't have override info - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# ------------------------------\n# %i.\n# ringName and override = Not available\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n", - ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr); + // WF header, which doesn't have override info + sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, + "# ------------------------------\n# %i.\n# ringName and override = Not available\n# backPtr = 0x%08x\n# fwdPtr = 0x%08x\n", + ringSeqNo,(uint32_t)backPtr,(uint32_t)fwdPtr); } - } - sizeList = sizeList + sizeDisLine; - disList = strcat(disList,lineDis); + } + sizeList = sizeList + sizeDisLine; + disList = strcat(disList,lineDis); } - else if ( sectionId==SBE_XIP_SECTION_IPL_TEXT || - sectionId==SBE_XIP_SECTION_TEXT) { - // Sections that have only code. - offsetCode = 0; - sizeBlock = sizeSection; - } - else { - // Sections that have only data. - offsetCode = sizeSection; - sizeBlock = sizeSection; - } - sizeData = offsetCode; - sizeCode = sizeBlock - offsetCode - sizeData2; - - if (sectionId==SBE_XIP_SECTION_RINGS && bSummary) { - // - // Summarize rings section. - - if (typeRingsSection==0) { // RS4 header. - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# ddLevel = 0x%02x\n# override= %i\n# sysPhase= %i\n# Block size= %i\n", - myRev32(((Rs4RingLayout*)nextBlock)->ddLevel), - ((Rs4RingLayout*)nextBlock)->override, - ((Rs4RingLayout*)nextBlock)->sysPhase, - sizeBlock); - } - else { // WF header. + else if ( sectionId==SBE_XIP_SECTION_LOADER_TEXT || + sectionId==SBE_XIP_SECTION_TEXT) { + // Sections that have only code. + offsetCode = 0; + sizeBlock = sizeSection; + } + else { + // Sections that have only data. + offsetCode = sizeSection; + sizeBlock = sizeSection; + } + sizeData = offsetCode; + sizeCode = sizeBlock - offsetCode - sizeData2; + + if (sectionId==SBE_XIP_SECTION_RINGS && bSummary) { + // + // Summarize rings section. + + if (typeRingsSection==0) { // RS4 header. + sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, + "# ddLevel = 0x%02x\n# override= %i\n# sysPhase= %i\n# Block size= %i\n", + myRev32(((Rs4RingLayout*)nextBlock)->ddLevel), + ((Rs4RingLayout*)nextBlock)->override, + ((Rs4RingLayout*)nextBlock)->sysPhase, + sizeBlock); + } + else { // WF header. if (bFoundInToc) { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# override= %i\n# Block size= %i\n", - pairingInfo.override, sizeBlock); + sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, + "# override= %i\n# Block size= %i\n", + pairingInfo.override, sizeBlock); } else { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "# override= Not available\n# Block size= %i\n", - sizeBlock); + sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, + "# override= Not available\n# Block size= %i\n", + sizeBlock); } - } - sizeList = sizeList + sizeDisLine; - disList = strcat(disList,lineDis); - // Readjust list buffer size, if needed. - if (sizeList > sizeListMax-1000) { - sizeListMax = 2*sizeListMax; - disList = (char*)realloc( (void*)(disList), sizeListMax); - } - - } - else { - // - // Do disassembly. - - // ...data disassembly - if (sizeData>0) { - ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA; - do { - rc = image_inline_disassemble( &ctx, &dis); - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s); - sizeList = sizeList + sizeDisLine; - disList = strcat(disList,lineDis); - if (rc) { - rcSet = rcSet | 0x1; - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "WARNING: %s (rc=%i) -> Stopping disasm. Check code and sectionID=%i.\n", - image_inline_error_strings[rc],rc,sectionId); + } sizeList = sizeList + sizeDisLine; disList = strcat(disList,lineDis); - } - // Readjust list buffer size, if needed. - if (sizeList > sizeListMax-1000) { - sizeListMax = 2*sizeListMax; - disList = (char*)realloc( (void*)(disList), sizeListMax); - } - } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeData); - } - if (rcSet) - rc = 0; - - // ...code disassembly - if (sizeCode>0) { - ctx.options = IMAGE_INLINE_LISTING_MODE; - do { - rc = image_inline_disassemble( &ctx, &dis); - ctx.options = IMAGE_INLINE_LISTING_MODE; - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s); - sizeList = sizeList + sizeDisLine; - disList = strcat(disList,lineDis); - if (rc && rcCount<100) { - rcSet = rcSet | 0x2; - rcCount++; - if (sectionId==SBE_XIP_SECTION_RINGS) { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "WARNING: %s (rc=%i) -> Trying data disasm mode. Check code, xyzRingLayout structures and image section.\n", - image_inline_error_strings[rc],rc); + // Readjust list buffer size, if needed. + if (sizeList > sizeListMax-1000) { + sizeListMax = 2*sizeListMax; + disList = (char*)realloc( (void*)(disList), sizeListMax); } - else { - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "WARNING: %s (rc=%i) -> Trying data disasm mode.\n", - image_inline_error_strings[rc],rc); + + } + else { + // + // Do disassembly. + + // ...data disassembly + if (sizeData>0) { + ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA; + do { + rc = image_inline_disassemble( &ctx, &dis); + sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s); + sizeList = sizeList + sizeDisLine; + disList = strcat(disList,lineDis); + if (rc) { + rcSet = rcSet | 0x1; + sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, + "WARNING: %s (rc=%i) -> Stopping disasm. Check code and sectionID=%i.\n", + image_inline_error_strings[rc],rc,sectionId); + sizeList = sizeList + sizeDisLine; + disList = strcat(disList,lineDis); + } + // Readjust list buffer size, if needed. + if (sizeList > sizeListMax-1000) { + sizeListMax = 2*sizeListMax; + disList = (char*)realloc( (void*)(disList), sizeListMax); + } + } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeData); } - sizeList = sizeList + sizeDisLine; - disList = strcat(disList,lineDis); - ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA; - rc = 0; - } - else { - if (rc && rcCount>=1000) { - fprintf(stderr, "Too many disasm warnings. Check output listing.\n"); - fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_TOO_MANY_DISASM_WARNINGS)); - return SBE_XIP_DISASSEMBLER_ERROR; + if (rcSet) + rc = 0; + + // ...code disassembly + if (sizeCode>0) { + ctx.options = IMAGE_INLINE_LISTING_MODE; + do { + rc = image_inline_disassemble( &ctx, &dis); + ctx.options = IMAGE_INLINE_LISTING_MODE; + sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s); + sizeList = sizeList + sizeDisLine; + disList = strcat(disList,lineDis); + if (rc && rcCount<100) { + rcSet = rcSet | 0x2; + rcCount++; + if (sectionId==SBE_XIP_SECTION_RINGS) { + sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, + "WARNING: %s (rc=%i) -> Trying data disasm mode. Check code, xyzRingLayout structures and image section.\n", + image_inline_error_strings[rc],rc); + } + else { + sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, + "WARNING: %s (rc=%i) -> Trying data disasm mode.\n", + image_inline_error_strings[rc],rc); + } + sizeList = sizeList + sizeDisLine; + disList = strcat(disList,lineDis); + ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA; + rc = 0; + } + else { + if (rc && rcCount>=1000) { + fprintf(stderr, "Too many disasm warnings. Check output listing.\n"); + fprintf( stderr, "\tMore info: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_TOO_MANY_DISASM_WARNINGS)); + return SBE_XIP_DISASSEMBLER_ERROR; + } + } + // Readjust list buffer size, if needed. + if (sizeList > sizeListMax-1000) { + sizeListMax = 2*sizeListMax; + disList = (char*)realloc( (void*)(disList), sizeListMax); + } + } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeData+sizeCode); } - } - // Readjust list buffer size, if needed. - if (sizeList > sizeListMax-1000) { - sizeListMax = 2*sizeListMax; - disList = (char*)realloc( (void*)(disList), sizeListMax); - } - } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeData+sizeCode); - } - if (rcSet) - rc = 0; + if (rcSet) + rc = 0; - // ...data2 disassembly (only done for rings section if RS4 type.) - if (sizeData2>0) { - ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA; - do { - rc = image_inline_disassemble( &ctx, &dis); - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s); - sizeList = sizeList + sizeDisLine; - disList = strcat(disList,lineDis); - if (rc) { - rcSet = rcSet | 0x4; - sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, - "WARNING: %s (rc=%i) -> Stopping disasm. Check code and sectionID=%i.\n", - image_inline_error_strings[rc],rc,sectionId); - sizeList = sizeList + sizeDisLine; - disList = strcat(disList,lineDis); - } - // Readjust list buffer size, if needed. - if (sizeList > sizeListMax-1000) { - sizeListMax = 2*sizeListMax; - disList = (char*)realloc( (void*)(disList), sizeListMax); - } - } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeBlock); - } - if (rcSet) - rc = 0; + // ...data2 disassembly (only done for rings section if RS4 type.) + if (sizeData2>0) { + ctx.options = IMAGE_INLINE_LISTING_MODE | IMAGE_INLINE_DISASSEMBLE_DATA; + do { + rc = image_inline_disassemble( &ctx, &dis); + sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE,"%s\n",dis.s); + sizeList = sizeList + sizeDisLine; + disList = strcat(disList,lineDis); + if (rc) { + rcSet = rcSet | 0x4; + sizeDisLine = snprintf(lineDis,LISTING_STRING_SIZE, + "WARNING: %s (rc=%i) -> Stopping disasm. Check code and sectionID=%i.\n", + image_inline_error_strings[rc],rc,sectionId); + sizeList = sizeList + sizeDisLine; + disList = strcat(disList,lineDis); + } + // Readjust list buffer size, if needed. + if (sizeList > sizeListMax-1000) { + sizeListMax = 2*sizeListMax; + disList = (char*)realloc( (void*)(disList), sizeListMax); + } + } while (rc==0 && ctx.lc<nextLinkOffsetBlock+sizeBlock); + } + if (rcSet) + rc = 0; - } // End of if (bSummary) condition. + } // End of if (bSummary) condition. - nextBlock = (void*)((uint64_t)nextBlock + (uint64_t)sizeBlock); - nextLinkOffsetBlock = nextLinkOffsetBlock + sizeBlock; + nextBlock = (void*)((uint64_t)nextBlock + (uint64_t)sizeBlock); + nextLinkOffsetBlock = nextLinkOffsetBlock + sizeBlock; - } // End of while(nextBlock...) loop. + } // End of while(nextBlock...) loop. - // Adjust final buffer size, add 1 for NULL char and print it. - if (disList) { - disList = (char*)realloc( (void*)(disList), sizeList+1); - fprintf(stdout,"%s\n",disList); - free(disList); - } + // Adjust final buffer size, add 1 for NULL char and print it. + if (disList) { + disList = (char*)realloc( (void*)(disList), sizeList+1); + fprintf(stdout,"%s\n",disList); + free(disList); + } - if (rcSet) - fprintf( stderr, "INFO : There were some hickups: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_DISASM_TROUBLES)); + if (rcSet) + fprintf( stderr, "INFO : There were some hickups: %s\n", DIS_ERROR_STRING(g_errorStringsDis, DIS_DISASM_TROUBLES)); - return 0; + return 0; } #endif diff --git a/tools/scripts/parseErrorInfo.pl b/tools/scripts/parseErrorInfo.pl new file mode 100755 index 00000000..61b6c96d --- /dev/null +++ b/tools/scripts/parseErrorInfo.pl @@ -0,0 +1,1511 @@ +#!/usr/bin/perl +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/hwpf/fapi/fapiParseErrorInfo.pl $ +# +# OpenPOWER HostBoot Project +# +# Contributors Listed Below - COPYRIGHT 2011,2014 +# [+] 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 +# $Id: fapiParseErrorInfo.pl,v 1.30 2014/07/25 00:36:41 jmcgill Exp $ +# Purpose: This perl script will parse HWP Error XML files and create required +# FAPI code. +# +# Author: CamVan Nguyen and Mike Jones +# Reworked for fapi2/P9 +# +# Usage: +# fapiParseErrorInfo.pl <output dir> <filename1> <filename2> ... + +use strict; + +#------------------------------------------------------------------------------ +# Set PREFERRED_PARSER to XML::Parser. Otherwise it uses XML::SAX which contains +# bugs that result in XML parse errors that can be fixed by adjusting white- +# space (i.e. parse errors that do not make sense). +#------------------------------------------------------------------------------ +$XML::Simple::PREFERRED_PARSER = 'XML::Parser'; + +#------------------------------------------------------------------------------ +# Specify perl modules to use +#------------------------------------------------------------------------------ +use Digest::MD5 qw(md5_hex); +use XML::Simple; +my $xml = new XML::Simple (KeyAttr=>[]); + +# Uncomment to enable debug output +use Data::Dumper; +use Getopt::Long; + +my $target_ffdc_type = "fapi2::Target<T>"; +my $buffer_ffdc_type = "fapi2::buffer"; +my $variable_buffer_ffdc_type = "fapi2::variable_buffer"; +my $ffdc_type = "fapi2::ffdc_t"; + +# We want to keep the signatures for the ffdc gathering hwp so that +# we can create members of the proper types for the ffdc classes. +my %signatures = ("proc_extract_pore_halt_ffdc" => ["por_base_state", + "por_halt_type_t", + "por_ffdc_offset_t"], + "hwpTestFfdc1" => [$target_ffdc_type], + "proc_extract_pore_base_ffdc" => ["por_base_state", "por_sbe_base_state"], + "proc_tp_collect_dbg_data" => [$target_ffdc_type], + ); + +# There are some names used in the XML files which exist in either +# c++ keywords (case, for example) or macros (DOMAIN). The one's which +# cause problems and need to be changed are here. +# +# DOMAIN is defined to 1 in math.h +my %mangle_names = ("DOMAIN" => "FAPI2_DOMAIN"); + +# A list of deprecated elements. These will report messages to the +# user, and not define anything. They have not been found to be used, +# but that doesn't mean they're not ... +my %deprecated = ("RC_PROCPM_PMCINIT_TIMEOUT" => "CHIP_IN_ERROR is defined as a callout procedure"); + +#------------------------------------------------------------------------------ +# Print Command Line Help +#------------------------------------------------------------------------------ +my $arg_empty_ffdc = undef; +my $arg_output_dir = undef; +my $arg_use_variable_buffers = undef; + +# Get the options from the command line - the rest of @ARGV will +# be filenames +GetOptions("empty-ffdc-classes" => \$arg_empty_ffdc, + "output-dir=s" => \$arg_output_dir, + "use-variable-buffers" => \$arg_use_variable_buffers); + +my $numArgs = $#ARGV + 1; +if (($numArgs < 1) || ($arg_output_dir eq undef)) +{ + print ("Usage: parseErrorInfo.pl [--empty-ffdc-classes] [--use-variable-buffers] --output-dir=<output dir> <filename1> <filename2> ...\n"); + print (" This perl script will parse HWP Error XML files and creates\n"); + print (" the following files:\n"); + print (" - hwp_return_codes.H. HwpReturnCode enumeration (HWP generated errors)\n"); + print (" - hwp_error_info.H. Error information (used by FAPI_SET_HWP_ERROR\n"); + print (" when a HWP generates an error)\n"); + print (" - collect_reg_ffdc.C. Function to collect register FFDC\n"); + print (" - set_sbe_error.H. Macro to create an SBE error\n"); + print (" The --empty-ffdc-classes option is for platforms which don't collect ffdc.\n"); + exit(1); +} + +#------------------------------------------------------------------------------ +# Hashes containing error names/enum-values +#------------------------------------------------------------------------------ +my %errNameToValueHash; +my %errValuePresentHash; + +#------------------------------------------------------------------------------ +# Hashes containing ffdc names/enum-values +#------------------------------------------------------------------------------ +my %ffdcNameToValueHash; +my %ffdcValuePresentHash; + +#------------------------------------------------------------------------------ +# Subroutine that checks if an entry exists in an array. If it doesn't exist +# then it is added. The index of the entry within the array is returned +#------------------------------------------------------------------------------ +sub addEntryToArray +{ + my ($arrayref, $entry ) = @_; + + my $match = 0; + my $index = 0; + + foreach my $element (@$arrayref) + { + if ($element eq $entry) + { + $match = 1; + last; + } + else + { + $index++; + } + } + + if (!($match)) + { + push(@$arrayref, $entry); + } + + return $index; +} + +#------------------------------------------------------------------------------ +# Subroutine that figures out an error enum value from an error name and stores +# it in global hashes +#------------------------------------------------------------------------------ +sub setErrorEnumValue +{ + my $name = $_[0]; + + #-------------------------------------------------------------------------- + # Check that the error name is not a duplicate + #-------------------------------------------------------------------------- + if (exists($errNameToValueHash{$name})) + { + # Two different errors with the same name! + print ("fapiParseErrorInfo.pl ERROR. Duplicate error name ", $name, "\n"); + exit(1); + } + + #-------------------------------------------------------------------------- + # Figure out the error enum-value. This is a hash value generated from + # the error name. A hash is used for Cronus so that if a HWP is not + # recompiled against a new eCMD/Cronus version where the errors have + # changed then there will not be a mismatch in error values. + # This is a 24bit hash value because FAPI has a requirement that the + # top byte of the 32 bit error value be zero to store flags indicating + # the creator of the error + #-------------------------------------------------------------------------- + my $errHash128Bit = md5_hex($name); + my $errHash24Bit = substr($errHash128Bit, 0, 6); + + #-------------------------------------------------------------------------- + # Check that the error enum-value is not a duplicate + #-------------------------------------------------------------------------- + if (exists($errValuePresentHash{$errHash24Bit})) + { + # Two different errors generate the same hash-value! + print ("fapiParseAttributeInfo.pl ERROR. Duplicate error hash value\n"); + exit(1); + } + + #-------------------------------------------------------------------------- + # Update the hashes with the error name and ID + #-------------------------------------------------------------------------- + $errValuePresentHash{$errHash24Bit} = 1; + $errNameToValueHash{$name} = $errHash24Bit; +} + +#------------------------------------------------------------------------------ +# Subroutine that figures out an FFDC ID value from an FFDC name and stores it +# in global hashes for use when creating the enumeration of FFDC IDs +#------------------------------------------------------------------------------ +sub setFfdcIdValue +{ + my $name = $_[0]; + + #-------------------------------------------------------------------------- + # Check that the FFDC name is not a duplicate + #-------------------------------------------------------------------------- + if (exists($ffdcNameToValueHash{$name})) + { + # Two different FFDCs with the same name! + print ("fapiParseErrorInfo.pl ERROR. Duplicate FFDC name ", $name, "\n"); + exit(1); + } + + #-------------------------------------------------------------------------- + # Figure out the FFDC enum-value. This is a hash value generated from + # the FFDC name. + #-------------------------------------------------------------------------- + my $ffdcHash128Bit = md5_hex($name); + my $ffdcHash32Bit = substr($ffdcHash128Bit, 0, 8); + + #-------------------------------------------------------------------------- + # Check that the error enum-value is not a duplicate + #-------------------------------------------------------------------------- + if (exists($ffdcValuePresentHash{$ffdcHash32Bit})) + { + # Two different FFDCs generate the same hash-value! + print ("fapiParseAttributeInfo.pl ERROR. Duplicate FFDC hash value\n"); + exit(1); + } + + #-------------------------------------------------------------------------- + # Update the hashes with the error name and ID + #-------------------------------------------------------------------------- + $ffdcValuePresentHash{$ffdcHash32Bit} = 1; + $ffdcNameToValueHash{$name} = $ffdcHash32Bit; +} + +#------------------------------------------------------------------------------ +# Subroutine to create ffdc methods +#------------------------------------------------------------------------------ +sub addFfdcMethod +{ + my $methods = shift; + my $ffdc_uc = shift; + my $class_name = shift; + my $type = shift; + + # Remove the leading *_ + $class_name = (split (/_/, $class_name, 2))[1]; + + # If we didn't get a type passed in, this element will get an ffdc_t pair. + $type = $ffdc_type if ($type eq undef); + + # Mangle the uppercase name if needed + $ffdc_uc = $mangle_names{$ffdc_uc} if ($mangle_names{$ffdc_uc} ne undef); + + my $key = $ffdc_uc.$type; + my $key_target = $ffdc_uc.$target_ffdc_type; + my $key_ffdc = $ffdc_uc.$ffdc_type; + + # Check to see if this element already has been recorded with this + # type or a target type. Note the effect we're shooting for here is + # to define the member if it's not been defined before *or* it's + # changing from an ffdc_t to a target due to other information in the xml + return if ($methods->{$key}{type} eq $type); + return if ($methods->{$key_target}{type} eq $target_ffdc_type); + + # Just leave if this is a variable_buffer ans we're not supporting that. + return if (($type eq $variable_buffer_ffdc_type) && ($arg_use_variable_buffers eq undef)); + + # Set the proper type, and clear out any previous members/methods if + # we're going from an ffdc_t to a target. + $methods->{$key}{type} = $type; + delete $methods->{$key_ffdc} if ($type eq $target_ffdc_type); + + my $method = ""; + my $method_body = ""; + + # If we're generating empty classes, not using an argument name will avoid the unused parameter warnings + my $param = ($arg_empty_ffdc eq undef) ? "i_value" : ""; + + if ($type eq $ffdc_type) + { + $method = "\n template< typename T >\n"; + $method .= " inline $class_name& set_$ffdc_uc(const T& $param)\n"; + $method_body = " {$ffdc_uc.ptr() = &i_value; $ffdc_uc.size() = fapi2::getErrorInfoFfdcSize(i_value); return *this;}\n\n"; + + $methods->{$key}{member} = "$ffdc_type $ffdc_uc;\n "; + } + + elsif ($type eq $buffer_ffdc_type) + { + # Two methods - one for integral buffers and one for variable_buffers + $method = "\n template< typename T >\n"; + $method .= " inline $class_name& set_$ffdc_uc(const fapi2::buffer<T>& $param)\n"; + $method_body = " {$ffdc_uc.ptr() = &i_value(); $ffdc_uc.size() = i_value.template getLength<uint8_t>(); return *this;}\n\n"; + + $methods->{$key}{member} = "$ffdc_type $ffdc_uc;\n "; + } + + elsif ($type eq $variable_buffer_ffdc_type) + { + $method = "\n inline $class_name& set_$ffdc_uc(const fapi2::variable_buffer& $param)\n"; + $method_body = " {$ffdc_uc.ptr() = &i_value(); $ffdc_uc.size() = i_value.template getLength<uint8_t>(); return *this;}\n\n"; + + # No need to add the member here, it was added with fapi2::buffer. And we can't have variable + # buffer support with out integral buffer support (can we?) + } + + elsif ($type eq $target_ffdc_type) + { + $method = "\n template< TargetType T >\n"; + $method .= " inline $class_name& set_$ffdc_uc(const $type& $param)\n"; + $method_body .= " {$ffdc_uc.ptr() = &i_value; $ffdc_uc.size() = fapi2::getErrorInfoFfdcSize(i_value); return *this;}\n\n"; + + $methods->{$key}{member} = "$ffdc_type $ffdc_uc;\n "; + } + + else + { + print ("ffdc type $type is unknown"); + exit(1); + } + + $method .= ($arg_empty_ffdc eq undef) ? $method_body : " {return *this;}\n\n"; + $methods->{$key}{method} = $method; +} + +#------------------------------------------------------------------------------ +# Open output files for writing +#------------------------------------------------------------------------------ +my $rcFile = $arg_output_dir; +$rcFile .= "/"; +$rcFile .= "hwp_return_codes.H"; +open(RCFILE, ">", $rcFile); + +my $eiFile = $arg_output_dir; +$eiFile .= "/"; +$eiFile .= "hwp_error_info.H"; +open(EIFILE, ">", $eiFile); + +my $ecFile = $arg_output_dir; +$ecFile .= "/"; +$ecFile .= "hwp_ffdc_classes.H"; +open(ECFILE, ">", $ecFile); + +my $crFile = $arg_output_dir; +$crFile .= "/"; +$crFile .= "collect_reg_ffdc.C"; +open(CRFILE, ">", $crFile); + +my $sbFile = $arg_output_dir; +$sbFile .= "/"; +$sbFile .= "set_sbe_error.H"; +open(SBFILE, ">", $sbFile); + +#------------------------------------------------------------------------------ +# Print start of file information to hwp_error_info.H +#------------------------------------------------------------------------------ +print EIFILE "// hwp_error_info.H\n"; +print EIFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n"; +print EIFILE "#ifndef FAPI2_HWPERRORINFO_H_\n"; +print EIFILE "#define FAPI2_HWPERRORINFO_H_\n\n"; +print EIFILE "#include <target.H>\n"; +print EIFILE "#include <plat_trace.H>\n"; +print EIFILE "#include <hwp_return_codes.H>\n"; +print EIFILE "#include <set_sbe_error.H>\n"; +print EIFILE "/**\n"; +print EIFILE " * \@brief Error Information macros and HwpFfdcId enumeration\n"; +print EIFILE " *\/\n"; + +#------------------------------------------------------------------------------ +# Print start of file information to hwp_ffdc_classes.H +#------------------------------------------------------------------------------ +print ECFILE "// hwp_ffdc_classes.H\n"; +print ECFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n"; +print ECFILE "#ifndef FAPI2_HWP_FFDC_CLASSES_H_\n"; +print ECFILE "#define FAPI2_HWP_FFDC_CLASSES_H_\n\n"; +print ECFILE "#include <ffdc.H>\n"; +print ECFILE "#include <buffer.H>\n"; +print ECFILE "#include <variable_buffer.H>\n" if ($arg_use_variable_buffers ne undef); +print ECFILE "#include <error_info.H>\n"; +print ECFILE "#include <utils.H>\n"; +print ECFILE "#include <hwp_error_info.H>\n"; +print ECFILE "#include <collect_reg_ffdc.H>\n"; +#print ECFILE "#include <proc_extract_sbe_rc.H>\n\n"; +print ECFILE "/**\n"; +print ECFILE " * \@brief FFDC gathering classes\n"; +print ECFILE " *\/\n"; +print ECFILE "namespace fapi2\n{\n"; + +#------------------------------------------------------------------------------ +# Print start of file information to collectRegFfdc.C +#------------------------------------------------------------------------------ +print CRFILE "// collect_reg_ffdc.C\n"; +print CRFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n"; +print CRFILE "#include <stdint.h>\n"; +print CRFILE "#include <vector>\n"; + +print CRFILE "#include <buffer.H>\n"; +print CRFILE "#include <collect_reg_ffdc.H>\n"; +print CRFILE "#include <target.H>\n"; +print CRFILE "#include <return_code.H>\n"; +print CRFILE "#include <hw_access.H>\n"; +print CRFILE "#include <plat_trace.H>\n\n"; + +print CRFILE "namespace fapi2\n"; +print CRFILE "{\n"; +print CRFILE "void collectRegFfdc(const fapi2::ffdc_t& i_target,\n"; +print CRFILE " const fapi2::HwpFfdcId i_ffdcId,\n"; +print CRFILE " fapi2::ReturnCode & o_rc,\n"; +print CRFILE " const TargetType i_child,\n"; +print CRFILE " const TargetType i_presChild,\n"; +print CRFILE " uint32_t i_childOffsetMult)\n"; +print CRFILE "{\n"; +print CRFILE " FAPI_INF(\"collectRegFfdc. FFDC ID: 0x%x\", i_ffdcId);\n"; +print CRFILE " fapi2::ReturnCode l_rc;\n"; +print CRFILE " fapi2::buffer<uint64_t> l_buf;\n"; +print CRFILE " uint32_t l_cfamData = 0;\n"; +print CRFILE " uint64_t l_scomData = 0;\n"; +print CRFILE " std::vector<uint32_t> l_cfamAddresses;\n"; +print CRFILE " std::vector<uint64_t> l_scomAddresses;\n"; +print CRFILE " uint32_t l_ffdcSize = 0;\n\n"; +print CRFILE " switch (i_ffdcId)\n"; +print CRFILE " {\n"; +print CRFILE " // void statments for the unused variables\n"; +print CRFILE " static_cast<void>(l_cfamData);\n"; +print CRFILE " static_cast<void>(l_scomData);\n"; +print CRFILE " static_cast<void>(l_ffdcSize);\n"; +print CRFILE " static_cast<const void>(i_target);\n"; +print CRFILE " static_cast<void>(o_rc);\n"; +print CRFILE " static_cast<void>(i_child);\n"; +print CRFILE " static_cast<void>(i_presChild);\n"; +print CRFILE " static_cast<void>(i_childOffsetMult);\n"; +#------------------------------------------------------------------------------ +# Print start of file information to setSbeError.H +#------------------------------------------------------------------------------ +print SBFILE "// setSbeError.H\n"; +print SBFILE "// This file is generated by the perl script parseErrorInfo.pl\n\n"; +print SBFILE "// When SBE code creates an error, it produces an error value\n"; +print SBFILE "// that matches a value in the HwpReturnCode enum in\n"; +print SBFILE "// fapiHwpReturnCodes.H. The SBE uses the __ASSEMBLER__\n"; +print SBFILE "// primitives in hwpReturnCodes.H to do this. The function\n"; +print SBFILE "// that extracts the error value from the SBE needs to call\n"; +print SBFILE "// FAPI_SET_HWP_ERROR to create the error and get all the\n"; +print SBFILE "// actions in the error XML file performed, but that macro can\n"; +print SBFILE "// only be called with the enumerator, not the value. This\n"; +print SBFILE "// FAPI_SET_SBE_ERROR macro can be called instead, it calls\n"; +print SBFILE "// FAPI_SET_HWP_ERROR with the correct error enumerator.\n"; +print SBFILE "// Errors containing <sbeError/> in their XML are supported\n"; +print SBFILE "// in this macro.\n\n"; +print SBFILE "// Note that it is expected that this macro will be called\n"; +print SBFILE "// in one place (the function that extracts the error from\n"; +print SBFILE "// the SBE), if this changes and it is called in multiple\n"; +print SBFILE "// places then the macro could be turned into a function to\n"; +print SBFILE "// avoid the code size increase of expanding the macro in\n"; +print SBFILE "// multiple places. The function approach is slightly more\n"; +print SBFILE "// complicated, there is an extra C file and the function\n"; +print SBFILE "// must take a parameter for the generic chip ID in the error\n"; +print SBFILE "// XML.\n\n"; +print SBFILE "#ifndef FAPI2_SETSBEERROR_H_\n"; +print SBFILE "#define FAPI2_SETSBEERROR_H_\n\n"; +print SBFILE "#define FAPI_SET_SBE_ERROR(RC, ERRVAL)\\\n"; +print SBFILE "{\\\n"; +print SBFILE "switch (ERRVAL)\\\n"; +print SBFILE "{\\\n"; + +#------------------------------------------------------------------------------ +# For each XML file +#------------------------------------------------------------------------------ +foreach my $argnum (0 .. $#ARGV) +{ + my $infile = $ARGV[$argnum]; + my $count = 0; + + #-------------------------------------------------------------------------- + # Read XML file. The ForceArray option ensures that there is an array of + # elements even if there is only one element + #-------------------------------------------------------------------------- + my $errors = $xml->XMLin($infile, ForceArray => + ['hwpError', 'collectFfdc', 'ffdc', 'callout', 'deconfigure', 'gard', + 'registerFfdc', 'collectRegisterFfdc', 'cfamRegister', 'scomRegister', + 'id','collectTrace', 'buffer']); + + # Uncomment to get debug output of all errors + #print "\nFile: ", $infile, "\n", Dumper($errors), "\n"; + + #-------------------------------------------------------------------------- + # For each Error + #-------------------------------------------------------------------------- + foreach my $err (@{$errors->{hwpError}}) + { + # Hash of methods for the ffdc-gathering class + my %methods; + + #---------------------------------------------------------------------- + # Check that expected fields are present + #---------------------------------------------------------------------- + if (! exists $err->{rc}) + { + print ("parseErrorInfo.pl ERROR. rc missing\n"); + exit(1); + } + + if (! exists $err->{description}) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. description missing\n"); + exit(1); + } + + #---------------------------------------------------------------------- + # Check that this rc hasn't been deprecated + #---------------------------------------------------------------------- + if ($deprecated{$err->{rc}} ne undef) + { + print "WARNING: $err->{rc} has been deprecated because $deprecated{$err->{rc}}\n"; + next; + } + + #---------------------------------------------------------------------- + # Set the error enum value in a global hash + #--------------------------------------------------------------------- + setErrorEnumValue($err->{rc}); + + #---------------------------------------------------------------------- + # If this is an SBE error, add it to set_sbe_error.H + #---------------------------------------------------------------------- + if (exists $err->{sbeError}) + { + print SBFILE " case fapi2::$err->{rc}:\\\n"; + print SBFILE " FAPI_SET_HWP_ERROR(RC, $err->{rc});\\\n"; + print SBFILE " break;\\\n"; + } + + #---------------------------------------------------------------------- + # Print the CALL_FUNCS_TO_COLLECT_FFDC macro to hwp_error_info.H + #---------------------------------------------------------------------- + print EIFILE "#define $err->{rc}_CALL_FUNCS_TO_COLLECT_FFDC(RC) "; + + # For now, this code is removed. It appears to work just fine but + # will require more of the fapi2 infrastructure to be in place. + # Because the ffdc collection classes create members with real types, + # the declarations of the types need to be visible - and they're not + # right now. When we get further along, we can enable this code. +=begin NO_FFDC_COLLECT_HWP + $count = 0; + + foreach my $collectFfdc (@{$err->{collectFfdc}}) + { + if ($count == 0) + { + print EIFILE "{ fapi2::ReturnCode l_tempRc; "; + } + $count++; + + print EIFILE "FAPI_EXEC_HWP(l_tempRc, $collectFfdc, RC); "; + + # collectFfdc is a string we're going to stuff into FAPI_EXEC_HWP + # but we need to create the arguments in the ffdc class. The first + # element inthe collectFfdc string is the function to call. + my @elements = split /,/, $collectFfdc; + my @signature = @{$signatures{@elements[0]}}; + for (my $i = 1; $i <= $#elements; $i++) + { + @elements[$i] =~ s/^\s+|\s+$//g; + addFfdcMethod(\%methods, @elements[$i], $err->{rc}, @signature[$i-1]); + } + } + + if ($count > 0) + { + print EIFILE "}"; + } +=cut NO_FFDC_COLLECT_HWP + print EIFILE "\n"; + + #---------------------------------------------------------------------- + # Print the CALL_FUNCS_TO_COLLECT_REG_FFDC macro to hwp_error_info.H + #---------------------------------------------------------------------- + print EIFILE "#define $err->{rc}_CALL_FUNCS_TO_COLLECT_REG_FFDC(RC) "; + + foreach my $collectRegisterFfdc (@{$err->{collectRegisterFfdc}}) + { + #------------------------------------------------------------------ + # Check that expected fields are present + #------------------------------------------------------------------ + if (! exists $collectRegisterFfdc->{id}[0]) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. id(s) missing from collectRegisterFfdc\n"); + exit(1); + } + foreach my $id (@{$collectRegisterFfdc->{id}}) + { + #--------------------------------------------------------------------------------- + # Check FFDC register collection type: target, child, or based on present children + #--------------------------------------------------------------------------------- + if (exists $collectRegisterFfdc->{target}) + { + print EIFILE "fapi2::collectRegFfdc($collectRegisterFfdc->{target}, "; + print EIFILE "fapi2::$id, RC, fapi2::TARGET_TYPE_NONE, fapi2::TARGET_TYPE_NONE); "; + addFfdcMethod(\%methods, $collectRegisterFfdc->{target}, + $err->{rc}, $target_ffdc_type); + } + elsif (exists $collectRegisterFfdc->{childTargets}) + { + if (! exists $collectRegisterFfdc->{childTargets}->{parent}) + { + print ("parseErrorInfo.pl ERROR: parent missing from collectRegisterFfdc\n"); + exit(1); + } + if (! exists $collectRegisterFfdc->{childTargets}->{childType}) + { + print ("parseErrorInfo.pl ERROR: childType missing from collectRegisterFfdc\n"); + exit(1); + } + print EIFILE "fapi2::collectRegFfdc($collectRegisterFfdc->{childTargets}->{parent}, fapi2::$id, "; + print EIFILE "RC, fapi2::$collectRegisterFfdc->{childTargets}->{childType}, fapi2::TARGET_TYPE_NONE); "; + addFfdcMethod(\%methods, $collectRegisterFfdc->{childTargets}->{parent}, + $err->{rc}, $target_ffdc_type); + } + elsif (exists $collectRegisterFfdc->{basedOnPresentChildren}) + { + if (! exists $collectRegisterFfdc->{basedOnPresentChildren}->{target}) + { + print ("parseErrorInfo.pl ERROR: target missing from collectRegisterFfdc\n"); + exit(1); + } + if (! exists $collectRegisterFfdc->{basedOnPresentChildren}->{childType}) + { + print ("parseErrorInfo.pl ERROR: childType missing from collectRegisterFfdc\n"); + exit(1); + } + if (! exists $collectRegisterFfdc->{basedOnPresentChildren}->{childPosOffsetMultiplier}) + { + print ("parseErrorInfo.pl ERROR: childPosOffsetMultiplier missing from collectRegisterFfdc\n"); + exit(1); + } + print EIFILE "fapi2::collectRegFfdc($collectRegisterFfdc->{basedOnPresentChildren}->{target}, fapi2::$id, RC, "; + print EIFILE "fapi2::TARGET_TYPE_NONE, fapi2::$collectRegisterFfdc->{basedOnPresentChildren}->{childType}, "; + print EIFILE "$collectRegisterFfdc->{basedOnPresentChildren}->{childPosOffsetMultiplier}); "; + addFfdcMethod(\%methods, $collectRegisterFfdc->{basedOnPresentChildren}->{target}, + $err->{rc}, $target_ffdc_type); + } + else + { + print ("parseErrorInfo.pl ERROR: Invalid collectRegisterFfdc configuration\n"); + exit(1); + } + } + } + + print EIFILE "\n"; + + #---------------------------------------------------------------------- + # Print the ADD_ERROR_INFO macro to hwp_error_info.H + #---------------------------------------------------------------------- + print EIFILE "#define $err->{rc}_ADD_ERROR_INFO(RC) "; + + # Array of EI Objects + my @eiObjects; + + my $eiObjectStr = "const void * l_objects[] = {"; + my $eiEntryStr = ""; + my $eiEntryCount = 0; + my %cdgTargetHash; # Records the callout/deconfigure/gards for Targets + my %cdgChildHash; # Records the callout/deconfigure/gards for Children + + # collect firmware trace + foreach my $collectTrace (@{$err->{collectTrace}}) + { + # Add an EI entry to eiEntryStr + $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_COLLECT_TRACE; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].collect_trace.iv_eieTraceId = fapi2::CollectTraces::$collectTrace; \\\n"; + $eiEntryCount++; + } + + # Local FFDC + foreach my $ffdc (@{$err->{ffdc}}) + { + # Set the FFDC ID value in a global hash. The name is <rc>_<ffdc> + my $ffdcName = $err->{rc} . "_"; + $ffdcName = $ffdcName . $ffdc; + setFfdcIdValue($ffdcName); + + # Add the FFDC data to the EI Object array if it doesn't already exist + my $objNum = addEntryToArray(\@eiObjects, $ffdc); + + # Add a method to the ffdc-gathering class + addFfdcMethod(\%methods, $ffdc, $err->{rc}); + + $ffdc = $mangle_names{$ffdc} if ($mangle_names{$ffdc} ne undef); + + # Add an EI entry to eiEntryStr + $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_FFDC; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcObjIndex = $objNum; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcId = fapi2::$ffdcName; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcSize = $ffdc.size(); \\\n"; + $eiEntryCount++; + } + + # Buffers, looks a lot like local ffdc + foreach my $buffer (@{$err->{buffer}}) + { + # Set the FFDC ID value in a global hash. The name is <rc>_<ffdc> + my $bufferName = $err->{rc} . "_"; + $bufferName = $bufferName . $buffer; + setFfdcIdValue($bufferName); + + # Add the FFDC data to the EI Object array if it doesn't already exist + my $objNum = addEntryToArray(\@eiObjects, $buffer); + + # Add a method to the ffdc-gathering class - one for each buffer type + addFfdcMethod(\%methods, $buffer, $err->{rc}, $buffer_ffdc_type); + addFfdcMethod(\%methods, $buffer, $err->{rc}, $variable_buffer_ffdc_type); + + # Add an EI entry to eiEntryStr + $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_FFDC; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcObjIndex = $objNum; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcId = fapi2::$bufferName; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].ffdc.iv_ffdcSize = fapi2::getErrorInfoFfdcSize($buffer); \\\n"; + $eiEntryCount++; + } + + # Procedure/Target/Bus/Child callouts + foreach my $callout (@{$err->{callout}}) + { + if (! exists $callout->{priority}) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout priority missing\n"); + exit(1); + } + + my $elementsFound = 0; + if (exists $callout->{hw}) + { + # HW Callout + if (! exists $callout->{hw}->{hwid}) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. HW Callout hwid missing\n"); + exit(1); + } + + # Check that those HW callouts that need reference targets have them + if (($callout->{hw}->{hwid} eq "TOD_CLOCK") || + ($callout->{hw}->{hwid} eq "MEM_REF_CLOCK") || + ($callout->{hw}->{hwid} eq "PROC_REF_CLOCK") || + ($callout->{hw}->{hwid} eq "PCI_REF_CLOCK")) + { + if (! exists $callout->{hw}->{refTarget}) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout missing refTarget\n"); + exit(1); + } + } + + # Add an EI entry to eiEntryStr + $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_HW_CALLOUT; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_hw = fapi2::HwCallouts::$callout->{hw}->{hwid}; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_calloutPriority = fapi2::CalloutPriorities::$callout->{priority}; \\\n"; + if (exists $callout->{hw}->{refTarget}) + { + # Add the Targets to the objectlist if they don't already exist + my $objNum = addEntryToArray(\@eiObjects, $callout->{hw}->{refTarget}); + $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_refObjIndex = $objNum; \\\n"; + + # Add a method to the ffdc-gathering class + addFfdcMethod(\%methods, $callout->{hw}->{refTarget}, $err->{rc}); + } + else + { + $eiEntryStr .= " l_entries[$eiEntryCount].hw_callout.iv_refObjIndex = 0xff; \\\n"; + } + $eiEntryCount++; + $elementsFound++; + } + if (exists $callout->{procedure}) + { + # Procedure Callout + # Add an EI entry to eiEntryStr + $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_PROCEDURE_CALLOUT; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].proc_callout.iv_procedure = fapi2::ProcedureCallouts::$callout->{procedure}; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].proc_callout.iv_calloutPriority = fapi2::CalloutPriorities::$callout->{priority}; \\\n"; + $eiEntryCount++; + $elementsFound++; + } + if (exists $callout->{bus}) + { + # A Bus Callout consists of two targets separated by + # commas/spaces + my @targets = split(/\s*,\s*|\s+/, $callout->{bus}); + + if (scalar @targets != 2) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. did not find two targets in bus callout\n"); + exit(1); + } + + # Add the Targets to the objectlist if they don't already exist + my $objNum1 = addEntryToArray(\@eiObjects, $targets[0]); + + my $objNum2 = addEntryToArray(\@eiObjects, $targets[1]); + + # Add a method to the ffdc-gathering class + addFfdcMethod(\%methods, $targets[0], $err->{rc}, $target_ffdc_type); + addFfdcMethod(\%methods, $targets[1], $err->{rc}, $target_ffdc_type); + + # Add an EI entry to eiEntryStr + $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_BUS_CALLOUT; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].bus_callout.iv_endpoint1ObjIndex = $objNum1; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].bus_callout.iv_endpoint2ObjIndex = $objNum2; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].bus_callout.iv_calloutPriority = fapi2::CalloutPriorities::$callout->{priority}; \\\n"; + $eiEntryCount++; + $elementsFound++; + } + if (exists $callout->{target}) + { + # Add the Target to cdgTargetHash to be processed with any + # deconfigure and GARD requests + $cdgTargetHash{$callout->{target}}{callout} = 1; + $cdgTargetHash{$callout->{target}}{priority} = + $callout->{priority}; + + $elementsFound++; + } + if (exists $callout->{childTargets}) + { + # Check that the parent and childType subelements exist + if (! exists $callout->{childTargets}->{parent}) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Callout parent missing\n"); + exit(1); + } + + if (! exists $callout->{childTargets}->{childType}) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Callout childType missing\n"); + exit(1); + } + + # Add the child info to cdgChildHash to be processed with + # any deconfigure and GARD requests + my $parent = $callout->{childTargets}->{parent}; + my $childType = $callout->{childTargets}->{childType}; + $cdgChildHash{$parent}{$childType}{callout} = 1; + $cdgChildHash{$parent}{$childType}{priority} = + $callout->{priority}; + + $elementsFound++; + + if (exists $callout->{childTargets}->{childPort}) + { + my $childPort = $callout->{childTargets}->{childPort}; + + $cdgChildHash{$parent}{$childType}{childPort} = $childPort; + } + + if (exists $callout->{childTargets}->{childNumber}) + { + my $childNum = $callout->{childTargets}->{childNumber}; + $cdgChildHash{$parent}{$childType}{childNumber} = $childNum; + } + + } + if ($elementsFound == 0) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout incomplete\n"); + exit(1); + } + elsif ($elementsFound > 1) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. Callout has multiple elements\n"); + exit(1); + } + } # callout + + # Target/Child deconfigures + foreach my $deconfigure (@{$err->{deconfigure}}) + { + my $elementsFound = 0; + if (exists $deconfigure->{target}) + { + # Add the Target to cdgTargetHash to be processed with any + # callout and GARD requests + $cdgTargetHash{$deconfigure->{target}}{deconf} = 1; + $elementsFound++; + } + if (exists $deconfigure->{childTargets}) + { + # Check that the parent and childType subelements exist + if (! exists $deconfigure->{childTargets}->{parent}) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Deconfigure parent missing\n"); + exit(1); + } + if (! exists $deconfigure->{childTargets}->{childType}) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. Child Deconfigure childType missing\n"); + exit(1); + } + + # Add the child info to cdgChildHash to be processed with + # any callout and GARD requests + my $parent = $deconfigure->{childTargets}->{parent}; + my $childType = $deconfigure->{childTargets}->{childType}; + $cdgChildHash{$parent}{$childType}{deconf} = 1; + + $elementsFound++; + + if ( exists $deconfigure->{childTargets}->{childPort}) + { + my $childPort = $deconfigure->{childTargets}->{childPort}; + + $cdgChildHash{$parent}{$childType}{childPort} = $childPort; + } + + if ( exists $deconfigure->{childTargets}->{childNumber}) + { + my $childNum = $deconfigure->{childTargets}->{childNumber}; + $cdgChildHash{$parent}{$childType}{childNumber} = $childNum; + + } + } + if ($elementsFound == 0) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. Deconfigure incomplete\n"); + exit(1); + } + elsif ($elementsFound > 1) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. Deconfigure has multiple elements\n"); + exit(1); + } + } # deconfigure + + # Target/Child Gards + foreach my $gard (@{$err->{gard}}) + { + my $elementsFound = 0; + if (exists $gard->{target}) + { + # Add the Target to cdgTargetHash to be processed with any + # callout and deconfigure requests + $cdgTargetHash{$gard->{target}}{gard} = 1; + $elementsFound++; + } + if (exists $gard->{childTargets}) + { + # Check that the parent and childType subelements exist + if (! exists $gard->{childTargets}->{parent}) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. Child GARD parent missing\n"); + exit(1); + } + if (! exists $gard->{childTargets}->{childType}) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. Child GARD childType missing\n"); + exit(1); + } + + # Add the child info to cdgChildHash to be processed with + # any callout and deconfigure requests + my $parent = $gard->{childTargets}->{parent}; + my $childType = $gard->{childTargets}->{childType}; + $cdgChildHash{$parent}{$childType}{gard} = 1; + + $elementsFound++; + + if ( exists $gard->{childTargets}->{childPort}) + { + my $childPort = $gard->{childTargets}->{childPort}; + + $cdgChildHash{$parent}{$childType}{childPort} = $childPort; + + } + + if ( exists $gard->{childTargets}->{childNumber}) + { + my $childNum = $gard->{childTargets}->{childNumber}; + $cdgChildHash{$parent}{$childType}{childNumber} = $childNum; + } + } + if ($elementsFound == 0) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. GARD incomplete\n"); + exit(1); + } + elsif ($elementsFound > 1) + { + print ("parseErrorInfo.pl ERROR in $err->{rc}. GARD has multiple elements\n"); + exit(1); + } + } # gard + + # Process the callout, deconfigures and GARDs for each Target + foreach my $cdg (keys %cdgTargetHash) + { + my $callout = 0; + my $priority = 'LOW'; + my $deconf = 0; + my $gard = 0; + + if (exists $cdgTargetHash{$cdg}->{callout}) + { + $callout = 1; + } + if (exists $cdgTargetHash{$cdg}->{priority}) + { + $priority = $cdgTargetHash{$cdg}->{priority}; + } + if (exists $cdgTargetHash{$cdg}->{deconf}) + { + $deconf = 1; + } + if (exists $cdgTargetHash{$cdg}->{gard}) + { + $gard = 1; + } + + # Add the Target to the objectlist if it doesn't already exist + my $objNum = addEntryToArray(\@eiObjects, $cdg); + + # Add a method to the ffdc-gathering class + addFfdcMethod(\%methods, $cdg, $err->{rc}, $target_ffdc_type); + + # Add an EI entry to eiEntryStr + $eiEntryStr .= " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_CDG; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_targetObjIndex = $objNum; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_callout = $callout; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_deconfigure = $deconf; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_gard = $gard; \\\n"; + $eiEntryStr .= " l_entries[$eiEntryCount].target_cdg.iv_calloutPriority = fapi2::CalloutPriorities::$priority; \\\n"; + $eiEntryCount++; + } + + # Process the callout, deconfigures and GARDs for Child Targets + foreach my $parent (keys %cdgChildHash) + { + foreach my $childType (keys %{$cdgChildHash{$parent}}) + { + my $callout = 0; + my $priority = 'LOW'; + my $deconf = 0; + my $gard = 0; + my $childPort = 0xFF; + my $childNumber = 0xFF; + + if (exists $cdgChildHash{$parent}{$childType}->{callout}) + { + $callout = 1; + } + if (exists $cdgChildHash{$parent}->{$childType}->{priority}) + { + $priority = + $cdgChildHash{$parent}->{$childType}->{priority}; + } + if (exists $cdgChildHash{$parent}->{$childType}->{deconf}) + { + $deconf = 1; + } + if (exists $cdgChildHash{$parent}->{$childType}->{childPort}) + { + $childPort = + $cdgChildHash{$parent}->{$childType}->{childPort} ; + addFfdcMethod(\%methods, $childPort, $err->{rc}); + } + if (exists $cdgChildHash{$parent}->{$childType}->{childNumber}) + { + $childNumber = + $cdgChildHash{$parent}->{$childType}->{childNumber} ; + addFfdcMethod(\%methods, $childNumber, $err->{rc}); + } + if (exists $cdgChildHash{$parent}->{$childType}->{gard}) + { + $gard = 1; + } + + + # Add the Target to the objectlist if it doesn't already exist + my $objNum = addEntryToArray(\@eiObjects, $parent); + addFfdcMethod(\%methods, $parent, $err->{rc}, $target_ffdc_type); + + # Add an EI entry to eiEntryStr + $eiEntryStr .= + " l_entries[$eiEntryCount].iv_type = fapi2::EI_TYPE_CHILDREN_CDG; \\\n"; + $eiEntryStr .= + " l_entries[$eiEntryCount].children_cdg.iv_parentObjIndex = $objNum; \\\n"; + $eiEntryStr .= + " l_entries[$eiEntryCount].children_cdg.iv_callout = $callout; \\\n"; + $eiEntryStr .= + " l_entries[$eiEntryCount].children_cdg.iv_deconfigure = $deconf; \\\n"; + $eiEntryStr .= + " l_entries[$eiEntryCount].children_cdg.iv_childType = fapi2::$childType; \\\n"; + $eiEntryStr .= + " l_entries[$eiEntryCount].children_cdg.iv_childPort = $childPort; \\\n"; + $eiEntryStr .= + " l_entries[$eiEntryCount].children_cdg.iv_childNumber = $childNumber; \\\n"; + $eiEntryStr .= + " l_entries[$eiEntryCount].children_cdg.iv_gard = $gard; \\\n"; + $eiEntryStr .= + " l_entries[$eiEntryCount].children_cdg.iv_calloutPriority = fapi2::CalloutPriorities::$priority; \\\n"; + $eiEntryCount++; + } + } + + # Add all objects to $eiObjectStr + my $objCount = 0; + + foreach my $eiObject (@eiObjects) + { + if ($objCount > 0) + { + $eiObjectStr .= ", "; + } + + if ($mangle_names{$eiObject} eq undef) + { + $eiObjectStr .= "$eiObject" + } + else + { + $eiObjectStr .= $mangle_names{$eiObject}; + } + + $objCount++; + } + $eiObjectStr .= "};"; + + # Print info to file + if ($eiEntryCount > 0) + { + print EIFILE "\\\n{ \\\n $eiObjectStr \\\n"; + print EIFILE " fapi2::ErrorInfoEntry l_entries[$eiEntryCount]; \\\n"; + print EIFILE "$eiEntryStr"; + print EIFILE " RC.addErrorInfo(l_objects, l_entries, $eiEntryCount); \\\n}"; + } + + print EIFILE "\n"; + + #---------------------------------------------------------------------- + # Print the return code class to hwp_error_info.H + #---------------------------------------------------------------------- + # Remove the repeated whitespace and newlines other characters from the description + $err->{description} =~ s/^\s+|\s+$|"//g; + $err->{description} =~ tr{\n}{ }; + $err->{description} =~ s/\h+/ /g; + + #---------------------------------------------------------------------- + # Print the return code class to hwp_error_info.H + #---------------------------------------------------------------------- + my $class_name = $err->{rc}; + # Remove everything upto and including the first _. This makes the ffdc class + # names different from the error code value enum names. + $class_name = (split (/_/, $class_name, 2))[1]; + + # Class declaration + print ECFILE "\nclass $class_name\n{\n public:\n"; + + # Constructor. This traces the description. If this is too much, we can + # remove it. + if ($arg_empty_ffdc eq undef) + { + print ECFILE " $class_name(fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE, fapi2::ReturnCode& i_rc = fapi2::current_err):\n"; + print ECFILE " iv_rc(i_rc),\n"; + print ECFILE " iv_sev(i_sev)\n"; + print ECFILE " { FAPI_ERR(\"$err->{description}\"); }\n"; + } + else + { + # Void expression keeps the compiler from complaining about the unused arguments. + # We want to set the i_rc to the RC if we're empty. This otherwise gets done in _setHwpError() + print ECFILE " $class_name(fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE, fapi2::ReturnCode& i_rc = fapi2::current_err)\n"; + print ECFILE " {\n"; + print ECFILE " static_cast<void>(i_sev);\n"; + print ECFILE " i_rc = $err->{rc};\n"; + print ECFILE " }\n\n"; + } + + # Methods + foreach my $key (keys %methods) + { + print ECFILE $methods{$key}{method}; + } + + # Stick the execute method at the end of the other methods. We allow + # passing in of the severity so that macros which call execute() can over-ride + # the default severity. + print ECFILE " void execute(fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNDEFINED)\n"; + if ($arg_empty_ffdc eq undef) + { + print ECFILE " {\n"; + print ECFILE " FAPI_SET_HWP_ERROR(iv_rc, $err->{rc});\n"; + print ECFILE " fapi2::logError(iv_rc, (i_sev == fapi2::FAPI2_ERRL_SEV_UNDEFINED) ? iv_sev : i_sev);\n"; + print ECFILE " }\n\n"; + } + else + { + print ECFILE " {\n"; + print ECFILE " static_cast<void>(i_sev);\n"; + print ECFILE " }\n\n"; + } + + # Instance variables + if ($arg_empty_ffdc eq undef) + { + print ECFILE " private:\n "; + foreach my $key (keys %methods) + { + print ECFILE $methods{$key}{member}; + } + + print ECFILE "fapi2::ReturnCode& iv_rc;\n"; + print ECFILE " fapi2::errlSeverity_t iv_sev;\n"; + } + + print ECFILE "};\n\n\n\n"; + } + + #-------------------------------------------------------------------------- + # For each registerFfdc. + #-------------------------------------------------------------------------- + foreach my $registerFfdc (@{$errors->{registerFfdc}}) + { + #---------------------------------------------------------------------- + # Check that expected fields are present + #---------------------------------------------------------------------- + if (! exists $registerFfdc->{id}[0]) + { + print ("parseErrorInfo.pl ERROR. id missing from registerFfdc\n"); + exit(1); + } + + if (scalar @{$registerFfdc->{id}} > 1) + { + print ("parseErrorInfo.pl ERROR. multiple ids in registerFfdc\n"); + exit(1); + } + + #---------------------------------------------------------------------- + # Set the FFDC ID value in a global hash + #---------------------------------------------------------------------- + setFfdcIdValue($registerFfdc->{id}[0]); + + #---------------------------------------------------------------------- + # Generate code to capture the registers in collect_reg_ffdc.C + #---------------------------------------------------------------------- + print CRFILE " case $registerFfdc->{id}[0]:\n"; + +=begin NEED_P9_REGISTERS + # Look for CFAM Register addresses + foreach my $cfamRegister (@{$registerFfdc->{cfamRegister}}) + { + print CRFILE " l_cfamAddresses.push_back($cfamRegister);\n"; + print CRFILE " l_ffdcSize += sizeof(l_cfamData);\n"; + } + + # Look for SCOM Register addresses + foreach my $scomRegister (@{$registerFfdc->{scomRegister}}) + { + print CRFILE " l_scomAddresses.push_back($scomRegister);\n"; + print CRFILE " l_ffdcSize += sizeof(l_scomData);\n"; + } +=cut NEED_P9_REGISTERS + + print CRFILE " break;\n"; + } + +} + +#------------------------------------------------------------------------------ +# Print end of file information to collect_reg_ffdc.C +#------------------------------------------------------------------------------ +print CRFILE " default:\n"; +print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Invalid FFDC ID 0x%x\", "; +print CRFILE "i_ffdcId);\n"; +print CRFILE " return;\n"; +print CRFILE " }\n\n"; + +=begin NEED_P9_REGISTERS + +print CRFILE " uint8_t * l_pBuf = NULL;\n"; +print CRFILE " uint8_t * l_pData = NULL;\n"; +print CRFILE " std::vector<fapi::Target> l_targets;\n"; +print CRFILE " uint32_t l_chipletPos32 = 0;\n"; +#--------------------------------------------------------------------------------------------------------- +# Populate chiplet vectors (if required by register collection method) and adjust buffer sizes accordingly +#--------------------------------------------------------------------------------------------------------- +print CRFILE " if (fapi2::TARGET_TYPE_NONE != i_child)\n"; +print CRFILE " {\n"; +print CRFILE " l_rc = fapiGetChildChiplets(i_target, i_child, l_targets, TARGET_STATE_FUNCTIONAL);\n"; +print CRFILE " if (l_rc)\n"; +print CRFILE " {\n"; +print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error: fapiGetChildChiplets: failed to get chiplets.\");\n"; +print CRFILE " return;\n"; +print CRFILE " }\n"; +print CRFILE " if (l_targets.empty())\n"; +print CRFILE " {\n"; +print CRFILE " FAPI_INF(\"collect_reg_ffdc.C: Error: No functional chiplets found. \");\n"; +print CRFILE " return;\n"; +print CRFILE " }\n"; +print CRFILE " l_ffdcSize += sizeof(l_chipletPos32);\n"; +print CRFILE " l_ffdcSize *= l_targets.size();\n"; +print CRFILE " l_pBuf = new uint8_t[l_ffdcSize];\n"; +print CRFILE " l_pData = l_pBuf;\n"; +print CRFILE " }\n"; +print CRFILE " else if (fapi2::TARGET_TYPE_NONE != i_presChild)\n"; +print CRFILE " {\n"; +print CRFILE " l_rc = fapiGetChildChiplets(i_target, i_presChild, l_targets, TARGET_STATE_PRESENT);\n"; +print CRFILE " if (l_rc)\n"; +print CRFILE " {\n"; +print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error: fapiGetChildChiplets: failed to get chiplets.\");\n"; +print CRFILE " return;\n"; +print CRFILE " }\n"; +print CRFILE " if (l_targets.empty())\n"; +print CRFILE " {\n"; +print CRFILE " FAPI_INF(\"collect_reg_ffdc.C: Error: No functional chiplets found. \");\n"; +print CRFILE " return;\n"; +print CRFILE " }\n"; +print CRFILE " l_ffdcSize += sizeof(l_chipletPos32);\n"; +print CRFILE " l_ffdcSize *= l_targets.size();\n"; +print CRFILE " l_pBuf = new uint8_t[l_ffdcSize];\n"; +print CRFILE " l_pData = l_pBuf;\n"; +print CRFILE " }\n"; +print CRFILE " else\n"; +print CRFILE " {\n"; +print CRFILE " l_ffdcSize += sizeof(l_chipletPos32);\n"; +print CRFILE " l_pBuf = new uint8_t[l_ffdcSize];\n"; +print CRFILE " l_pData = l_pBuf;\n"; +print CRFILE " l_targets.push_back(i_target);\n"; +print CRFILE " }\n\n"; +#--------------------------------------------------------------------------------------------------------- +# Obtain target position and insert as the first word in the buffer +#--------------------------------------------------------------------------------------------------------- +print CRFILE " bool l_targIsChiplet = i_target.isChiplet();\n\n"; +print CRFILE " for (std::vector<fapi::Target>::const_iterator targetIter = l_targets.begin();\n"; +print CRFILE " targetIter != l_targets.end(); ++targetIter)\n"; +print CRFILE " {\n"; +print CRFILE " if ((fapi2::TARGET_TYPE_NONE != i_child) ||\n"; +print CRFILE " (fapi2::TARGET_TYPE_NONE != i_presChild) ||\n"; +print CRFILE " (true == l_targIsChiplet))\n"; +print CRFILE " {\n"; +print CRFILE " uint8_t l_chipletPos = 0;\n"; +print CRFILE " l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &(*targetIter), l_chipletPos);\n"; +print CRFILE " if (l_rc)\n"; +print CRFILE " {\n"; +print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error getting chiplet position\");\n"; +print CRFILE " l_chipletPos = 0xFF;\n"; +print CRFILE " }\n"; + #------------------------------------------------------------------------- + # We print the target's position in the error log whether the target is a + # chip or chiplet, so we need to store the chiplet position in a uint32_t + # to have consitency in the buffer as ATTR_POS below returns a uint32_t + #------------------------------------------------------------------------- +print CRFILE " l_chipletPos32 = l_chipletPos;\n"; +print CRFILE " }\n"; +print CRFILE " else\n"; +print CRFILE " {\n"; +print CRFILE " l_rc = FAPI_ATTR_GET(ATTR_POS, &(*targetIter), l_chipletPos32);\n"; +print CRFILE " if (l_rc)\n"; +print CRFILE " {\n"; +print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: Error getting chip position\");\n"; +print CRFILE " l_chipletPos32 = 0xFFFFFFFF;\n"; +print CRFILE " }\n"; +print CRFILE " }\n"; +print CRFILE " *(reinterpret_cast<uint32_t *>(l_pData)) = l_chipletPos32;\n"; +print CRFILE " l_pData += sizeof(l_chipletPos32);\n"; +#--------------------------------------------------------------------------------------------------------- +# Instert cfam data (if any) related to this chip / chiplet into the buffer +# If collecting FFDC based on present children, adjust the register address by the appropriate offset +#--------------------------------------------------------------------------------------------------------- +print CRFILE " for (std::vector<uint32_t>::const_iterator cfamIter = l_cfamAddresses.begin();\n"; +print CRFILE " cfamIter != l_cfamAddresses.end(); ++cfamIter)\n"; +print CRFILE " {\n"; +print CRFILE " if (fapi2::TARGET_TYPE_NONE != i_presChild)\n"; +print CRFILE " {\n"; +print CRFILE " l_rc = fapiGetCfamRegister(i_target, (*cfamIter + (l_chipletPos32 * i_childOffsetMult)), l_buf);\n"; +print CRFILE " }\n"; +print CRFILE " else\n"; +print CRFILE " {\n"; +print CRFILE " l_rc = fapiGetCfamRegister(*targetIter, *cfamIter, l_buf);\n"; +print CRFILE " }\n"; +print CRFILE " if (l_rc)\n"; +print CRFILE " {\n"; +print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: CFAM error for 0x%x\","; +print CRFILE "*cfamIter);\n"; +print CRFILE " l_cfamData = 0xbaddbadd;\n"; +print CRFILE " }\n"; +print CRFILE " else\n"; +print CRFILE " {\n"; +print CRFILE " l_cfamData = l_buf.getWord(0);\n"; +print CRFILE " }\n"; +print CRFILE " *(reinterpret_cast<uint32_t *>(l_pData)) = l_cfamData;\n"; +print CRFILE " l_pData += sizeof(l_cfamData);\n"; +print CRFILE " }\n\n"; +#--------------------------------------------------------------------------------------------------------- +# Instert any scom data (if any) related to this chip / chiplet into the buffer +# If collecting FFDC based on present children, adjust the register address by the appropriate offset +#--------------------------------------------------------------------------------------------------------- +print CRFILE " for (std::vector<uint64_t>::const_iterator scomIter = l_scomAddresses.begin();\n"; +print CRFILE " scomIter != l_scomAddresses.end(); ++scomIter)\n"; +print CRFILE " {\n"; +print CRFILE " if (fapi2::TARGET_TYPE_NONE != i_presChild)\n"; +print CRFILE " {\n"; +print CRFILE " l_rc = fapiGetScom(i_target, (*scomIter + (l_chipletPos32 * i_childOffsetMult)), l_buf);\n"; +print CRFILE " }\n"; +print CRFILE " else\n"; +print CRFILE " {\n"; +print CRFILE " l_rc = fapiGetScom(*targetIter, *scomIter, l_buf);\n"; +print CRFILE " }\n"; +print CRFILE " if (l_rc)\n"; +print CRFILE " {\n"; +print CRFILE " FAPI_ERR(\"collect_reg_ffdc.C: SCOM error for 0x%llx\","; +print CRFILE "*scomIter);\n"; +print CRFILE " l_scomData = 0xbaddbaddbaddbaddULL;\n"; +print CRFILE " }\n"; +print CRFILE " else\n"; +print CRFILE " {\n"; +print CRFILE " l_scomData = l_buf.getDoubleWord(0);\n"; +print CRFILE " }\n"; +print CRFILE " *(reinterpret_cast<uint64_t *>(l_pData)) = l_scomData;\n"; +print CRFILE " l_pData += sizeof(l_scomData);\n"; +print CRFILE " }\n"; +print CRFILE " }\n\n"; +print CRFILE " o_rc.addEIFfdc(i_ffdcId, l_pBuf, l_ffdcSize);\n"; +print CRFILE " delete [] l_pBuf;\n"; +=cut NEED_P9_REGISTERS + +print CRFILE "}\n"; +print CRFILE "}\n"; + + +#------------------------------------------------------------------------------ +# Print the fapiHwpReturnCodes.H file +#------------------------------------------------------------------------------ +print RCFILE "// fapiHwpReturnCodes.H\n"; +print RCFILE "// This file is generated by perl script parseErrorInfo.pl\n\n"; +print RCFILE "#ifndef FAPI2_HWPRETURNCODES_H_\n"; +print RCFILE "#define FAPI2_HWPRETURNCODES_H_\n\n"; +print RCFILE "#ifndef __ASSEMBLER__\n"; +print RCFILE "namespace fapi2\n"; +print RCFILE "{\n\n"; +print RCFILE "/**\n"; +print RCFILE " * \@brief Enumeration of HWP return codes\n"; +print RCFILE " *\/\n"; +print RCFILE "enum HwpReturnCode\n"; +print RCFILE "{\n"; +foreach my $key (keys %errNameToValueHash) +{ + print RCFILE " $key = 0x$errNameToValueHash{$key},\n"; +} +print RCFILE "};\n\n"; +print RCFILE "}\n\n"; +print RCFILE "#else\n"; +foreach my $key (keys %errNameToValueHash) +{ + print RCFILE " .set $key, 0x$errNameToValueHash{$key}\n"; +} +print RCFILE "#endif\n"; +print RCFILE "#endif\n"; + +#------------------------------------------------------------------------------ +# Print the HwpFfdcId enumeration to hwp_error_info.H +#------------------------------------------------------------------------------ +print EIFILE "namespace fapi2\n"; +print EIFILE "{\n\n"; +print EIFILE "/**\n"; +print EIFILE " * \@brief Enumeration of FFDC identifiers\n"; +print EIFILE " *\/\n"; +print EIFILE "enum HwpFfdcId\n"; +print EIFILE "{\n"; +foreach my $key (keys %ffdcNameToValueHash) +{ + print EIFILE " $key = 0x$ffdcNameToValueHash{$key},\n"; +} +print EIFILE "};\n\n"; +print EIFILE "}\n\n"; + +#------------------------------------------------------------------------------ +# Print end of file information to hwp_error_info.H +#------------------------------------------------------------------------------ +print EIFILE "\n\n#endif\n"; + +#------------------------------------------------------------------------------ +# Print end of file information to hwp_ffdc_classes.H +#------------------------------------------------------------------------------ +print ECFILE "\n};\n"; # close the namespace +print ECFILE "\n\n#endif\n"; + +#------------------------------------------------------------------------------ +# Print end of file information to set_sbe_error.H +#------------------------------------------------------------------------------ +print SBFILE " default:\\\n"; +print SBFILE " FAPI_SET_HWP_ERROR(RC, RC_SBE_UNKNOWN_ERROR);\\\n"; +print SBFILE " break;\\\n"; +print SBFILE "}\\\n"; +print SBFILE "}\n\n"; +print SBFILE "#endif\n"; + +#------------------------------------------------------------------------------ +# Close output files +#------------------------------------------------------------------------------ +close(RCFILE); +close(EIFILE); +close(ECFILE); +close(CRFILE); +close(SBFILE); |