From a4f8acaca4eecb0bf4d5cda4b2b81bd42b99fe2b Mon Sep 17 00:00:00 2001 From: Derk Rembold Date: Mon, 29 Jun 2015 09:57:08 +0200 Subject: add fapi2 headers into importtemp added bin dir in tools removed absolute path from makefile Change-Id: Ib86e3ab64151e323ceea260ce989ca5f79193461 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/18817 Reviewed-by: Derk Rembold Tested-by: Derk Rembold --- importtemp/fapi2/include/array.H | 174 +++ importtemp/fapi2/include/buffer.H | 684 +++++++++++ importtemp/fapi2/include/buffer_parameters.H | 70 ++ importtemp/fapi2/include/buffer_traits.H | 240 ++++ importtemp/fapi2/include/collect_reg_ffdc.H | 78 ++ importtemp/fapi2/include/error_info.H | 652 +++++++++++ importtemp/fapi2/include/error_info_defs.H | 246 ++++ importtemp/fapi2/include/error_scope.H | 37 + importtemp/fapi2/include/fapi2.H | 47 + importtemp/fapi2/include/fapi2_attribute_service.H | 127 +++ importtemp/fapi2/include/fapi2_chip_ec_feature.H | 39 + importtemp/fapi2/include/fapi2_error_scope.H | 79 ++ importtemp/fapi2/include/fapi2_hw_access.H | 464 ++++++++ importtemp/fapi2/include/fapi2_hwp_executor.H | 24 + importtemp/fapi2/include/fapi2_target.H | 433 +++++++ importtemp/fapi2/include/ffdc.H | 190 ++++ importtemp/fapi2/include/hw_access.H | 582 ++++++++++ importtemp/fapi2/include/hw_access_def.H | 77 ++ importtemp/fapi2/include/mvpd_access.H | 159 +++ importtemp/fapi2/include/plat_error_scope.H | 64 ++ importtemp/fapi2/include/plat_hw_access.H | 39 + importtemp/fapi2/include/plat_target.H | 43 + importtemp/fapi2/include/plat_trace.H | 70 ++ importtemp/fapi2/include/return_code.H | 114 ++ importtemp/fapi2/include/return_code_defs.H | 114 ++ importtemp/fapi2/include/target.H | 171 +++ importtemp/fapi2/include/target_states.H | 45 + importtemp/fapi2/include/target_types.H | 82 ++ importtemp/fapi2/include/utils.H | 91 ++ importtemp/fapi2/include/variable_buffer.H | 1198 ++++++++++++++++++++ sbe/image/Makefile | 1 + sbe/image/img_defs.mk | 2 +- tools/image/Makefile | 4 +- tools/image/bin/.empty | 0 34 files changed, 6437 insertions(+), 3 deletions(-) create mode 100644 importtemp/fapi2/include/array.H create mode 100644 importtemp/fapi2/include/buffer.H create mode 100644 importtemp/fapi2/include/buffer_parameters.H create mode 100644 importtemp/fapi2/include/buffer_traits.H create mode 100644 importtemp/fapi2/include/collect_reg_ffdc.H create mode 100644 importtemp/fapi2/include/error_info.H create mode 100644 importtemp/fapi2/include/error_info_defs.H create mode 100644 importtemp/fapi2/include/error_scope.H create mode 100644 importtemp/fapi2/include/fapi2.H create mode 100644 importtemp/fapi2/include/fapi2_attribute_service.H create mode 100644 importtemp/fapi2/include/fapi2_chip_ec_feature.H create mode 100644 importtemp/fapi2/include/fapi2_error_scope.H create mode 100644 importtemp/fapi2/include/fapi2_hw_access.H create mode 100644 importtemp/fapi2/include/fapi2_hwp_executor.H create mode 100644 importtemp/fapi2/include/fapi2_target.H create mode 100644 importtemp/fapi2/include/ffdc.H create mode 100644 importtemp/fapi2/include/hw_access.H create mode 100644 importtemp/fapi2/include/hw_access_def.H create mode 100644 importtemp/fapi2/include/mvpd_access.H create mode 100644 importtemp/fapi2/include/plat_error_scope.H create mode 100644 importtemp/fapi2/include/plat_hw_access.H create mode 100644 importtemp/fapi2/include/plat_target.H create mode 100644 importtemp/fapi2/include/plat_trace.H create mode 100644 importtemp/fapi2/include/return_code.H create mode 100644 importtemp/fapi2/include/return_code_defs.H create mode 100644 importtemp/fapi2/include/target.H create mode 100644 importtemp/fapi2/include/target_states.H create mode 100644 importtemp/fapi2/include/target_types.H create mode 100644 importtemp/fapi2/include/utils.H create mode 100644 importtemp/fapi2/include/variable_buffer.H create mode 100644 tools/image/bin/.empty diff --git a/importtemp/fapi2/include/array.H b/importtemp/fapi2/include/array.H new file mode 100644 index 00000000..1b976f2b --- /dev/null +++ b/importtemp/fapi2/include/array.H @@ -0,0 +1,174 @@ +/* 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 array.H + * @brief definitions for fapi2 arrays + */ + +#ifndef __FAPI2_ARRAY__ +#define __FAPI2_ARRAY__ + +#include +#include +#include +#include + +namespace fapi2 +{ + /// + /// @brief Class representing a FAPI2 array + /// FAPI2 arrays are defined to be very lightweight but support + /// c++ container operations (iterators, bounds checking, assignment, etc.) + /// To avoid the code-bloat associated with std::vector templates, + /// fapi2::array is presently limited to 64-bit elements. + /// + /// To construct an array, you can either pass in an existing chunk + /// of memory, or let the container allocate memory for you: + /// fapi2::array foo(3, &PIB_MEM_BLOCK); + /// creates an array 3 x uit64_t in size, located at &PIB_MEM_BLOCK. + /// The memory pointed to by the address passed in is untouched + /// during creation. This allows for a light-weight overlay on top + /// of existing memory. It also means you need to initialize the space + /// yourself. + /// fapi2_array foo(3); + /// creates an array 3 x uint64_t in size, and that memory will be + /// allocated by the constructor and initiaized to 0's. + /// + /// + class array + { + public: + + typedef uint64_t element_type; + typedef element_type* iterator; + typedef const element_type* const_iterator; + + /// + /// @brief Create an array + /// @param[in] the size of the array + /// @param[in] a pointer to memory of appropriate size + /// defaults to nullptr which causes the platform to + /// allocate memory of size * element_type + /// @warning fapi2::arrays, like arrays, can not be re-sized after + /// creation. + /// + array(const uint32_t i_size, element_type* i_data = nullptr); + + /// + /// @brief Destroy an array + /// + ~array(void); + + /// + /// @brief operator[] + /// @param[in] the index of the element + /// @return a reference to the element in question. + /// @note array[0] = 0 works as well as foo = array[0] + /// + element_type& operator[](const uint32_t i_index); + + /// + /// @brief operator=() + /// @param[in] the other array + /// @return a reference to this, after the assignement + /// + array& operator=(const array& i_other); + + /// + /// @brief move operator=() + /// @note To use: new_array = std::move(old_array). old_array will be + /// destroyed and no copy will be made (moved) + /// + array& operator=(array&& i_other); + + /// + /// @brief operator==() + /// + bool operator==(const array& i_other); + + /// + /// @brief operator!=() + /// + __attribute__ ((always_inline)) + bool operator!=(const array& i_other) + { return ! operator==(i_other); } + + /// + /// @brief Return an iterator the to beginning of the array + /// @return An iterator to the beginning of the array + /// + __attribute__ ((always_inline)) + iterator begin(void) + { return iv_data; } + + /// + /// @brief Return an iterator the to end of the array + /// @return An iterator to the end of the array + /// + __attribute__ ((always_inline)) + iterator end(void) + { return iv_data + size(); } + + /// + /// @brief Return a const_iterator the to beginning of the array + /// @return A const_iterator to the beginning of the array + /// + __attribute__ ((always_inline)) + const_iterator begin(void) const + { return iv_data; } + + /// + /// @brief Return a const_iterator the to end of the array + /// @return A const_iterator to the end the array + /// + __attribute__ ((always_inline)) + const_iterator end(void) const + { return iv_data + size(); } + + private: + + enum + { + // Bit in iv_size representing whether we delete in the dtor + delete_bit = 0x80000000, + + // The resulting size limit + size_limit = 0x7FFFFFFF, + }; + + __attribute__ ((always_inline)) + uint32_t size(void) + { return (iv_size & ~delete_bit); } + + __attribute__ ((always_inline)) + uint32_t size(void) const + { return (iv_size & ~delete_bit); } + + uint32_t iv_size; + element_type* iv_data; + }; +} + +#endif diff --git a/importtemp/fapi2/include/buffer.H b/importtemp/fapi2/include/buffer.H new file mode 100644 index 00000000..d8ad212a --- /dev/null +++ b/importtemp/fapi2/include/buffer.H @@ -0,0 +1,684 @@ +/* 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.H + * @brief definitions for fapi2 variable integral buffers + */ + +#ifndef __FAPI2_INTEGRAL_BUFFER__ +#define __FAPI2_INTEGRAL_BUFFER__ + +#include +#include +#include + +namespace fapi2 +{ + /// @brief Class representing a FAPI buffer + /// @tparam T, the integral type of the buffer (uint16_t, uint64_t, etc.) + template > + class buffer + { + public: + /// Shortcut typedef to get to our traits class + typedef typename TT::bits_type bits_type; + + /// + /// @brief Integral buffer assignment constructor + /// @param[in] i_value initial value of the buffer + /// Meaningless for variable types and thus protected. + /// + inline buffer(T i_value = 0): + iv_data(i_value) + { + } + + ~buffer(void) = default; + +#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 + + /// + /// @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; } + + /// @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 is integral + static_assert( std::is_integral::value, + "Input must be an integral type" ); + + const uint32_t length = TT:: template size(iv_data); + static const bits_type bits_in_value = parameterTraits::bit_length(); + const bits_type bit_length = TT::bit_length(iv_data); + + if (i_offset + bits_in_value >= bit_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::mask() << ((bits_in_value * length) - bit_length); + } + + parameterTraits::template write_element(TT::get_address(iv_data), i_value, i_offset); + return FAPI2_RC_SUCCESS; + } + + /// @name Bit/Word Manipulation Functions + ///@{ + + /// + /// @brief Return the length of the buffer in bits + /// @return Length in bits + /// + inline constexpr uint32_t getBitLength(void) const + { return TT::bit_length(iv_data); } + + /// + /// @brief Return the length of the buffer in OT units + /// @return Length in OT units rounded up + /// @tparam OT the type to get the length of. For example, if one + /// wanted the length in double words, OT would be uint64_t + /// (getLength().) Similarly, to get the length in words, + /// getLength(). + /// + template< typename OT > + inline constexpr uint32_t getLength(void) const + { + return TT::template size(iv_data); + } + + /// + /// @brief Templated setBit for integral types + /// @tparam B the bit number to set. + /// @tparam C the count of bits to set, defaults to 1 + /// @return buffer& Useful for method chaining + /// @note 0 is left-most + /// @note Example: fapi2::buffer().setBit<3>(); + /// + template< bits_type B, bits_type C = 1 > + inline buffer& setBit(void) + { + static_assert((B >= 0) && + ((B + C - 1) < TT::bits_per_unit()), "failed range check"); + + // 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); + return *this; + } + + /// + /// @brief Set a bit in the buffer + /// @param[in] i_bit the bit number to set. + /// @param[in] i_count the count of bits to set, defaults to 1 + /// @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) + { + 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); + + return FAPI2_RC_SUCCESS; + } + + /// + /// @brief Clear a bit in buffer + /// @tparam B Bit in buffer to clear. + /// @tparam C the count of bits to clear, defaults to 1 + /// @return buffer& Useful for method chaining + /// @note Asserting that all the parameters are known at + /// compile time so this can be templated only. If that is not + /// the case we can add a function parameter version. + /// + template< bits_type B, bits_type C = 1> + inline buffer& clearBit(void) + { + static_assert((B >= 0) && + ((B + C - 1)< TT::bits_per_unit()), "failed range check"); + + iv_data &= buffer().setBit().invert(); + return *this; + } + + /// + /// @brief Clear a bit in the buffer + /// @param[in] i_bit the bit number to clear. + /// @param[in] i_count the count of bits to clear, defaults to 1 + /// @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) + { + if ((i_count + i_bit - 1) >= TT::bits_per_unit()) + { + return FAPI2_RC_INVALID_PARAMETER; + } + + fapi2::buffer l_scratch; + + if (l_scratch.setBit(i_bit, i_count) != FAPI2_RC_SUCCESS) + { + return FAPI2_RC_INVALID_PARAMETER; + } + + iv_data &= l_scratch.invert(); + + return FAPI2_RC_SUCCESS; + } + + /// + /// @brief Write a bit in buffer to a given value + /// @tparam B Bit in buffer to write + /// @tparam C the count of bits to write, defaults to 1 + /// @return buffer& Useful for method chaining + /// @note Asserting that all the parameters are known at + /// compile time so this can be templated only. If that is not + /// the case we can add a function parameter version. + /// + template< bits_type B, bits_type C = 1 > + inline buffer& writeBit(const bool i_value) + { + static_assert((B >= 0) && + ((B + C - 1)< TT::bits_per_unit()), "failed range check"); + + (i_value == 0) ? clearBit() : setBit(); + return *this; + } + + + /// + /// @brief Invert bit + /// @tparam B Bit in buffer to invert. + /// @tparam C the count of bits to flip, defaults to 1 + /// @return buffer& Useful for method chaining + /// @note Asserting that all the parameters are known at + /// compile time so this can be templated only. If that is not + /// the case we can add a function parameter version. + /// + template< bits_type B, bits_type C = 1 > + inline buffer& flipBit(void) + { + static_assert((B >= 0) && + ((B + C - 1) < TT::bits_per_unit()), "failed range check"); + + iv_data ^= buffer().setBit(); + return *this; + } + + /// + /// @brief Get the value of a bit in the buffer + /// @tparam B Bit in buffer to get. + /// @tparam C the count of bits to get, defaults to 1 + /// @return true if *any* bit is on, false if *every* bit is off + /// + template< bits_type B, bits_type C = 1> + inline bool getBit(void) const + { + return buffer().setBit() & iv_data; + } + + /// + /// @brief Set and entire buffer to X's + /// @tparam X {0,1} depending if you want to clear (0) + /// or fill (1) a buffer + /// @return buffer_base&, Useful for method chaining + /// + 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; + } + + /// + /// @brief Invert entire buffer + /// @return buffer_base&, Useful for method chaining + /// + inline buffer& invert(void) + { 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; } + + + ///@} + + /// @name Buffer Manipulation Functions + ///@{ + + /// + /// @brief Get a pointer to the buffer bits + /// @return Pointer to the buffer itself + /// + 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 + // documenation purposes. + + /// + /// @brief operator>>() + /// +#ifdef DOXYGEN + inline buffer& operator>>(bits_type i_shiftnum); +#endif + + /// + /// @brief operator<<() + /// +#ifdef DOXYGEN + inline buffer& operator<<(bits_type i_shiftnum); +#endif + + /// + /// @brief operator+() + /// +#ifdef DOXYGEN + inline buffer& operator+(const T& rhs); +#endif + + /// + /// @brief operator+=() + /// +#ifdef DOXYGEN + inline buffer& operator+=(const T& rhs); +#endif + + /// + /// @brief operator|=() + /// +#ifdef DOXYGEN + inline buffer& operator|=(const T& rhs); +#endif + + /// + /// @brief operator&=() + /// +#ifdef DOXYGEN + inline buffer& operator&=(const T& rhs); +#endif + + /// + /// @brief operator|() + /// +#ifdef DOXYGEN + inline buffer& operator|(const T& rhs); +#endif + + /// + /// @brief operator&() + /// +#ifdef DOXYGEN + inline buffer& operator&(const T& rhs); +#endif + + /// + /// @brief operator^=() + /// +#ifdef DOXYGEN + inline buffer& operator^=(const T& rhs); +#endif + + /// + /// @brief operator~() + /// +#ifdef DOXYGEN + inline buffer& operator~(const T& rhs) const; +#endif + + /// + /// @brief operator==() + /// +#ifdef DOXYGEN + inline bool operator==(const T& rhs) const; +#endif + + /// + /// @brief operator!=() + /// +#ifdef DOXYGEN + inline bool operator!=(const T& rhs) const; +#endif + + /// + /// @brief Copy part of a OT into the DataBuffer + /// @tparam TS Start bit to insert into (target start) + /// @tparam L Length of bits to insert + /// @tparam SS Start bit in source - defaults to bit 0 + /// @tparam OT the type of the incoming (origin) data + /// @param[in] i_datain OT value to copy into DataBuffer + /// - data is taken left aligned + /// @return buffer& Useful for method chaining + /// + template + inline buffer& insert(const OT i_datain) + { + const bits_type target_length = parameterTraits::bit_length(); + const bits_type source_length = parameterTraits::bit_length(); + + // Error if input data don't make sense + static_assert((TS + L) <= target_length, + "insert(): (Target Start + Len) is out of bounds"); + static_assert((SS + L) <= source_length, + "insert(): (Source Start + Len) is out of bounds"); + static_assert(TS < target_length, + "insert(): Target Start is out of bounds"); + static_assert(SS < source_length, + "insert(): Source Start is out of bounds"); + + // Normalize the input to 2 64 bit integers and adjust the starts accordingly + uint64_t source = static_cast(i_datain); + const uint64_t target = static_cast(iv_data); + + const bits_type source_start = parameterTraits::bit_length() - (source_length - SS); + const bits_type target_start = parameterTraits::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::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; + } + else + { + shift = target_start - source_start; + source >>= shift; + } + + iv_data = ((target & ~mask) | (source & mask)); + return *this; + } + + /// + /// @brief Copy part of a OT into the DataBuffer + /// @tparam OT the type of the incoming (origin) data + /// @param[in] i_datain OT value to copy into DataBuffer + /// - data is taken left aligned + /// @param[in] Start bit to insert into (target start) + /// @param[in] Length of bits to insert + /// @param[in] Start bit in source - defaults to bit 0 + + /// @return FAPI2_RC_SUCCESS if successful + /// + template + fapi2::ReturnCode insert(const OT i_datain, const bits_type i_targetStart, + const bits_type i_len, const bits_type i_sourceStart = 0) + { + const bits_type target_length = parameterTraits::bit_length(); + const bits_type source_length = parameterTraits::bit_length(); + + // Error if input data don't make sense + if ((i_targetStart + i_len) > target_length) + { + FAPI_ERR("insert(): (Target Start + Len) is out of bounds"); + return FAPI2_RC_INVALID_PARAMETER; + } + + if ((i_sourceStart + i_len) > source_length) + { + FAPI_ERR("insert(): (Source Start + Len) is out of bounds"); + return FAPI2_RC_INVALID_PARAMETER; + } + + if (i_targetStart >= target_length) + { + FAPI_ERR("insert(): Target Start is out of bounds"); + return FAPI2_RC_INVALID_PARAMETER; + } + + if (i_sourceStart >= source_length) + { + FAPI_ERR("insert(): Source Start is out of bounds"); + return FAPI2_RC_INVALID_PARAMETER; + } + + // Normalize the input to 2 64 bit integers and adjust the starts accordingly + uint64_t source = static_cast(i_datain); + const uint64_t target = static_cast(iv_data); + + const bits_type source_start = parameterTraits::bit_length() - (source_length - i_sourceStart); + const bits_type target_start = parameterTraits::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::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; + } + else + { + shift = target_start - source_start; + source >>= shift; + } + + iv_data = ((target & ~mask) | (source & mask)); + return FAPI2_RC_SUCCESS; + } + + /// + /// @brief Copy in a right aligned value + /// @tparam SB Start bit to insert into + /// @tparam L Length of bits to insert + /// @tparam OT the type of the incoming (origin) data + /// @param[in] i_datain OT value to copy into DataBuffer + /// - data is taken right aligned + /// @return buffer& Useful for method chaining + /// @note Data is assumed to be aligned on the word boundary of L + /// + template + inline buffer& insertFromRight(const OT i_datain) + { + // Error if input data don't make sense + static_assert(L <= parameterTraits::bit_length(), + "insertFromRight(): Len > input buffer"); + static_assert(TS < parameterTraits::bit_length(), + "insertFromRight(): Target Start is out of bounds"); + static_assert((TS + L) <= parameterTraits::bit_length(), + "InsertFromRight(): (Target Start + Len) is out of bounds"); + + this->insert::bit_length() - L>(i_datain); + return *this; + } + + /// + /// @brief Copy in a right aligned value + /// @tparam OT the type of the incoming (origin) data + /// @param[in] i_datain OT value to copy into DataBuffer + /// - data is taken right aligned + /// @param[in] Start bit to insert into + /// @param[in] Length of bits to insert + /// @return FAPi2_RC_SUCCESS if no error + /// @note Data is assumed to be aligned on the word boundary of L + /// + template + 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 + if ((i_targetStart + i_len) > parameterTraits::bit_length()) + { + FAPI_ERR("insertFromRight(): (Target Start + Len) is out of bounds"); + return FAPI2_RC_INVALID_PARAMETER; + } + + if (i_targetStart >= parameterTraits::bit_length()) + { + FAPI_ERR("insertFromRight(): Target Start is out of bounds"); + return FAPI2_RC_INVALID_PARAMETER; + } + + if (i_len > parameterTraits::bit_length()) + { + FAPI_ERR("insertFromRight(): Len > input buffer"); + return FAPI2_RC_INVALID_PARAMETER; + } + + return this->insert(i_datain, i_targetStart, i_len, parameterTraits::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 buffer& Useful for method chaining + /// + template + inline buffer& extract(OT& o_out) + { + // Extraction is just an insert into o_out + + buffer out(o_out); + out.insert(iv_data); + o_out = out; + return *this; + } + + /// + /// @brief Copy data from this buffer into an OT + /// @tparam OT the type of the outgoing (target) + /// @param[out] o_out OT to copy into - data is placed left aligned + /// @param[in] Start bit in source + /// @param[in] Length of bits to extract + /// @param[in] Start bit to insert into (target start) + /// @return FAPI2_RC_SUCCESS if ok + /// + template + fapi2::ReturnCode extract(OT& o_out, const bits_type i_sourceStart, + const bits_type i_len, const bits_type i_targetStart = 0) + { + // Extraction is just an insert into o_out + + buffer out(o_out); + if (out.insert(iv_data, i_targetStart, i_len, i_sourceStart) != FAPI2_RC_SUCCESS) + { + return FAPI2_RC_INVALID_PARAMETER; + } + + o_out = out; + return FAPI2_RC_SUCCESS; + } + + /// + /// @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 + inline buffer& extractToRight(OT& o_out) + { + extract::bit_length() - L>(o_out); + return *this; + } + + /// + /// @brief Copy data from this buffer into an OT and right justify + /// @tparam OT the type of the outgoing (target) + /// @param[out] o_out OT to copy into - data is placed right aligned + /// @param[in] Start bit to insert into (source start) + /// @param[in] Length of bits to insert + /// @return FAPI2_RC_SUCCESS if ok + /// + template + fapi2::ReturnCode extractToRight(OT& o_out, const bits_type i_sourceStart, + const bits_type i_len) + { + return extract(o_out, i_sourceStart, i_len, parameterTraits::bit_length() - i_len); + } + + ///@} + + private: + /// The contents of the buffer + T iv_data; + }; +} + +#endif diff --git a/importtemp/fapi2/include/buffer_parameters.H b/importtemp/fapi2/include/buffer_parameters.H new file mode 100644 index 00000000..2a6e6100 --- /dev/null +++ b/importtemp/fapi2/include/buffer_parameters.H @@ -0,0 +1,70 @@ +/* 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_parameters.H + * @brief definitions for fapi2 buffer parameter types + */ + +#ifndef __FAPI2_BUFFER_PARAM__ +#define __FAPI2_BUFFER_PARAM__ + +#include + +namespace fapi2 +{ + /// @cond + /// @brief Traits of buffer parameters - things passed in + /// @tparam T is the type of i_value (typically an integral type) + template + class parameterTraits + { + public: + // 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 + inline static void write_element(void* i_data, T i_value, uint32_t i_offset) + { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + T* ptr = (T*)i_data + (i_offset ^ ((sizeof(U) / sizeof(T)) - 1)); +#else + T* ptr = (T*)i_data + i_offset; +#endif + *ptr = i_value; + } + }; + /// @endcond +} + +#endif diff --git a/importtemp/fapi2/include/buffer_traits.H b/importtemp/fapi2/include/buffer_traits.H new file mode 100644 index 00000000..c1f5df54 --- /dev/null +++ b/importtemp/fapi2/include/buffer_traits.H @@ -0,0 +1,240 @@ +/* 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_traits.H + * @brief trait definitions for fapi2 buffer base class + */ + +#ifndef __FAPI2_BUFFER_TRAITS__ +#define __FAPI2_BUFFER_TRAITS__ + +#include +#include +#include +#include + +#ifdef FAPI2_DEBUG +#include +#endif + +#include + +namespace fapi2 +{ + /// @cond + /// Types representing a container of bits. Used to create + /// variable_buffer. container_unit must remain 32-bits + /// for now - there will be a lot of code to change if it + /// changes. There are assertions helping to enforce this + /// in places in the code. + typedef uint32_t container_unit; + typedef std::vector bits_container; + + /// @brief Traits of buffers + // In general, we try to give buffers traits reflecting integral types. If + // this fails, the compiler will let someone know. + /// + /// @tparam T is the type of iv_data (std::vector, etc) + /// @tparam B is the type of the bit-specifier, typically uint32_t + template + class bufferTraits + { + public: + +#if !defined(DOXYGEN) && defined(FAPI2_DEBUG) + /// + /// @brief Print a container of bits + /// @param[in] i_data the container of bits + /// + static inline void print(const T& i_data) + { + // convert to uint64_t to prevent uint8_t from being + // printed as a char. + std::cout << "\tdata is " + << std::hex + << static_cast(i_data) + << std::dec << std::endl; + } +#endif + + /// + /// @brief Return the size of the buffer in E units + /// @tparam E, the element size. + /// @param[in] io_buffer the buffer which to size + /// @return The size of the buffer in E's rounded up + /// + template + constexpr static B size(const T& i_buffer) + { + return (bit_length(i_buffer) + + (parameterTraits::bit_length() - 1)) / + parameterTraits::bit_length(); + } + + /// + /// @brief Return the size of the buffer itself + /// @param[in] io_buffer the buffer which to size + /// @return The size of the buffer in bits (not units) + /// + constexpr static B bit_length(const T&) + { return sizeof(T) * 8; } + + /// + /// @brief Clear the buffer + /// @param[in,out] io_buffer the buffer which to clear + /// + static inline void clear(T& io_buffer) + { io_buffer = static_cast(0); } + + /// + /// @brief Set the buffer + /// @param[in,out] io_buffer the buffer which to set + /// + static inline void set(T& io_buffer) + { io_buffer = static_cast(~0); } + + /// + /// @brief Invert the buffer + /// @param[in,out] io_buffer the buffer which to invert + /// + static inline void invert(T& io_buffer) + { io_buffer = ~io_buffer; } + + /// + /// @brief Reverse the buffer + /// @param[in,out] io_buffer the buffer which to reverse + /// + static inline void reverse(T& io_buffer) + { + io_buffer = + ((io_buffer & 0xAAAAAAAAAAAAAAAA) >> 1) | + ((io_buffer & 0x5555555555555555) << 1); + } + + /// + /// @brief Get the address of the buffer as an array + /// @param[in] i_buffer the buffer which to invert + /// @return The address of the first element of the buffer + /// + static inline void* get_address(T& i_buffer) + { return (void*)&i_buffer; } + + typedef B bits_type; + typedef T unit_type; + constexpr static uint32_t bits_per_unit(void) + { return sizeof(unit_type) * 8; } + }; + + // + // + /// @brief Traits for buffers which are a container of bits + // + // + template<> + class bufferTraits + { + public: +#if !defined(DOXYGEN) && defined(FAPI2_DEBUG) + /// + /// @brief Print a container of bits + /// @param[in] i_data the container of bits + /// + static inline void print(const bits_container& i_data) + { + std::cout << "\tdata is " << std::hex; + std::copy(i_data.begin(), i_data.end(), + std::ostream_iterator(std::cout, " ")); + std::cout << std::dec << std::endl; + } +#endif + + /// + /// @brief Return the size of the buffer in E units + /// @tparam E, the element size. + /// @param[in] io_buffer the buffer which to size + /// @return The size of the buffer in E's rounded up + /// + template + constexpr static uint32_t size(const bits_container& i_buffer) + { + return (bit_length(i_buffer) + + (parameterTraits::bit_length() - 1)) / + parameterTraits::bit_length(); + } + + /// + /// @brief Return the size of the buffer itself + /// @param[in,out] io_buffer the buffer which to size + /// @return The size of the buffer in bits (not units) + /// + static inline uint32_t bit_length(const bits_container& i_buffer) + { return i_buffer.size() * sizeof(container_unit) * 8; } + + /// + /// @brief Clear the buffer + /// @param[in,out] io_buffer the buffer which to clear + /// + static inline void clear(bits_container& io_buffer) + { io_buffer.assign(io_buffer.size(), 0); } + + /// + /// @brief Set the buffer + /// @param[in,out] io_buffer the buffer which to set + /// + static inline void set(bits_container& io_buffer) + { io_buffer.assign(io_buffer.size(), ~0); } + + /// + /// @brief Invert the buffer + /// @param[in,out] io_buffer the buffer which to invert + /// + static inline void invert(bits_container& io_buffer) + { + std::transform(io_buffer.begin(), io_buffer.end(), + io_buffer.begin(), + [](container_unit u) { return ~u; }); + } + + /// + /// @brief Get the address of the buffer as an array + /// @param[in] i_buffer the buffer which to invert + /// @return The address of the first element of the buffer + /// + static inline void* get_address(bits_container& i_buffer) + { + return (void*)&(i_buffer[0]); + } + + typedef uint32_t bits_type; + typedef container_unit unit_type; + constexpr static uint32_t bits_per_unit(void) + { return sizeof(unit_type) * 8; } + }; + /// @endcond +} + + + +#endif diff --git a/importtemp/fapi2/include/collect_reg_ffdc.H b/importtemp/fapi2/include/collect_reg_ffdc.H new file mode 100644 index 00000000..764bb3c8 --- /dev/null +++ b/importtemp/fapi2/include/collect_reg_ffdc.H @@ -0,0 +1,78 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012,2014 */ +/* */ +/* 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 collect_reg_ffdc.H + * + * @brief Defines the collectRegFfdc function that collects chip or + * chiplet register FFDC data. This is called automatically by + * FAPI_SET_HWP_ERROR (when a HWP creates an error) and + * FAPI_ADD_INFO_TO_HWP_ERROR (when an FFDC HWP adds error information + * to an existing error) if the error XML contains a + * element. This function should not be called + * directly by any user code. The function implementation is + * automatically generated from FAPI Error XML files. + */ + +#ifndef FAPI2_COLLECT_REG_FFDC_H_ +#define FAPI2_COLLECT_REG_FFDC_H_ + +#include +#include +#include +#include + +namespace fapi2 +{ + + /// + /// @brief Collects Register FFDC from a chip or chiplet + /// + /// @warning This should only be called by FAPI during FAPI_SET_HWP_ERROR or + /// FAPI_ADD_INFO_TO_HWP_ERROR + /// + /// @param[in] i_target Pointer to Target to collect FFDC from (ffdc_t.ptr()) + /// @param[in] i_ffdcId FFDC Identifier + /// @param[out] o_rc Reference to ReturnCode that FFDC is added to + /// @param[in] i_child Specifies type of i_target's chiplet to collect + /// FFDC from. If this parameter is TARGET_TYPE_NONE + /// (default value), then register FFDC is collected + /// from i_target, else, register FFDC is collected + /// from all functional child chiplets i_target of + /// the specified type + /// @param[in] i_presChild When specified, register FFDC will be collected + /// from i_target's registers based on present chiplets + /// of this type. + /// @param[in] i_childOffsetMult Specifies the chiplet position offset multiplier. + /// This is used in calculating the scom register + /// addresses when collecting register FFDC based on + /// present child chiplets. + /// + void collectRegFfdc(const fapi2::ffdc_t& i_target, + const fapi2::HwpFfdcId i_ffdcId, + fapi2::ReturnCode & o_rc, + const TargetType i_child = TARGET_TYPE_NONE, + const TargetType i_presChild = TARGET_TYPE_NONE, + uint32_t i_childOffsetMult = 0); +} + +#endif diff --git a/importtemp/fapi2/include/error_info.H b/importtemp/fapi2/include/error_info.H new file mode 100644 index 00000000..cc555b8c --- /dev/null +++ b/importtemp/fapi2/include/error_info.H @@ -0,0 +1,652 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2011,2015 */ +/* [+] 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 error_info.H +/// @brief Defines the Error Information structures and classes +/// + +#ifndef FAPI2_ERRORINFO_H_ +#define FAPI2_ERRORINFO_H_ + +#include +#include +#include +#include +#include + +namespace fapi2 +{ + // forward fapi2::Assert() + extern void Assert(bool); + + /// + /// @class ErrorInfoFfdc + /// + /// This class contains a copy of some FFDC data + /// + class ErrorInfoFfdc + { + public: + /// + /// @brief Constructor + /// + /// @param[in] i_ffdcId FFDC Identifier (used to decode FFDC) + /// @param[in] i_pFfdc Pointer to the FFDC to copy + /// @param[in] i_size Size of the FFDC to copy + /// + ErrorInfoFfdc(const uint32_t i_ffdcId, + const void* i_pFfdc, + const uint32_t i_size); + + /// + /// @brief Get a pointer to the FfdcData + /// + /// @param[out] o_size Reference to uint32_t that is filled in with + /// the FFDC size + /// + /// @return void *. Pointer to the FFDC + /// + inline const void* getData(uint32_t & o_size) const + { + o_size = iv_size; + return iv_pFfdc.get(); + } + + /// + /// @brief Get a pointer to the FfdcData + /// @return void *. Pointer to the FFDC + /// + inline void* getData(void) const + { return iv_pFfdc.get(); } + + /// + /// @brief Get the FFDC Identifier + /// + /// @return uint32_t The FFDC Identifier + /// + inline uint32_t getFfdcId(void) + { return iv_ffdcId; } + +#ifdef FAPI_CUSTOM_MALLOC + /// + /// @brief Overload new operator to use platform-specific allocator + /// + /// @param[in] i_sz Size of memory to allocate in bytes + /// + /// @return Pointer to allocated memory + /// + static void* operator new(size_t i_sz); + + /// + /// @brief Overload delete operator to use platform-specific deallocator + /// + /// @param[in] i_ptr Pointer to memory previously allocated with new + /// + static void operator delete(void* i_ptr); +#endif + + private: + + // FFDC Identifier + uint32_t iv_ffdcId; + + // Pointer to the FFDC + std::shared_ptr iv_pFfdc; + + // Size of the FFDC + uint32_t iv_size; + + // Disabled + ErrorInfoFfdc(const ErrorInfoFfdc &) = delete; + ErrorInfoFfdc & operator=(const ErrorInfoFfdc &) = delete; + }; + + /// + /// @struct ErrorInfoHwCallout + /// + /// This struct contains hardware to callout + /// + struct ErrorInfoHwCallout + { + /// + /// @brief Constructor. + /// + /// @param[in] i_hw Hardware to callout + /// @param[in] i_calloutPriority Priority of callout + /// @param[in] i_refTarget Reference to reference target + /// + ErrorInfoHwCallout( + const HwCallouts::HwCallout i_hw, + const CalloutPriorities::CalloutPriority i_calloutPriority, + const Target & i_refTarget); + +#ifdef FAPI_CUSTOM_MALLOC + /// + /// @brief Overload new operator to use platform-specific allocator + /// + /// @param[in] i_sz Size of memory to allocate in bytes + /// + /// @return Pointer to allocated memory + /// + static void* operator new(size_t i_sz); + + /// + /// @brief Overload delete operator to use platform-specific deallocator + /// + /// @param[in] i_ptr Pointer to memory previously allocated with new + /// + static void operator delete(void* i_ptr); +#endif + + // The hw to callout + HwCallouts::HwCallout iv_hw; + + // The callout priority + CalloutPriorities::CalloutPriority iv_calloutPriority; + + // The reference target (needed for some HW callouts to identify what to + // callout). The target handle is NULL if there is no reference target. + Target iv_refTarget; + }; + + /// + /// @struct ErrorInfoProcedureCallout + /// + /// This struct contains a procedure to callout + /// + struct ErrorInfoProcedureCallout + { + /// + /// @brief Constructor. + /// + /// @param[in] i_procedure Procedure to callout + /// @param[in] i_calloutPriority Priority of callout + /// + ErrorInfoProcedureCallout( + const ProcedureCallouts::ProcedureCallout i_procedure, + const CalloutPriorities::CalloutPriority i_calloutPriority); + +#ifdef FAPI_CUSTOM_MALLOC + /// + /// @brief Overload new operator to use platform-specific allocator + /// + /// @param[in] i_sz Size of memory to allocate in bytes + /// + /// @return Pointer to allocated memory + /// + static void* operator new(size_t i_sz); + + /// + /// @brief Overload delete operator to use platform-specific deallocator + /// + /// @param[in] i_ptr Pointer to memory previously allocated with new + /// + static void operator delete(void* i_ptr); +#endif + + // The procedure to callout + ProcedureCallouts::ProcedureCallout iv_procedure; + + // The callout priority + CalloutPriorities::CalloutPriority iv_calloutPriority; + }; + + /// + /// @struct ErrorInfoBusCallout + /// + /// This struct contains a bus to callout + /// + struct ErrorInfoBusCallout + { + /// + /// @brief Constructor. + /// + /// @param[in] i_target1 Reference to target on one end of the bus + /// @param[in] i_target2 Reference to target on other end of the bus + /// @param[in] i_calloutPriority Priority of callout + /// + ErrorInfoBusCallout( + const Target & i_target1, + const Target & i_target2, + const CalloutPriorities::CalloutPriority i_calloutPriority); + +#ifdef FAPI_CUSTOM_MALLOC + /// + /// @brief Overload new operator to use platform-specific allocator + /// + /// @param[in] i_sz Size of memory to allocate in bytes + /// + /// @return Pointer to allocated memory + /// + static void* operator new(size_t i_sz); + + /// + /// @brief Overload delete operator to use platform-specific deallocator + /// + /// @param[in] i_ptr Pointer to memory previously allocated with new + /// + static void operator delete(void* i_ptr); +#endif + + // The targets on each end of the bus to callout + Target iv_target1; + Target iv_target2; + + // The callout priority + CalloutPriorities::CalloutPriority iv_calloutPriority; + }; + + /// + /// @struct ErrorInfoCDG + /// + /// This struct contains a target to callout/deconfigure/GARD + /// + struct ErrorInfoCDG + { + /// + /// @brief Constructor. + /// + /// @param[in] i_target Reference to the target to c/d/g + /// @param[in] i_callout True if Target should be called out + /// @param[in] i_deconfigure True if Target should be deconfigured + /// @param[in] i_gard True if Target should be GARDed + /// @param[in] i_priority The priority of any callout + /// + ErrorInfoCDG(const Target & i_target, + const bool i_callout, + const bool i_deconfigure, + const bool i_gard, + const CalloutPriorities::CalloutPriority i_priority); + +#ifdef FAPI_CUSTOM_MALLOC + /// + /// @brief Overload new operator to use platform-specific allocator + /// + /// @param[in] i_sz Size of memory to allocate in bytes + /// + /// @return Pointer to allocated memory + /// + static void* operator new(size_t i_sz); + + /// + /// @brief Overload delete operator to use platform-specific deallocator + /// + /// @param[in] i_ptr Pointer to memory previously allocated with new + /// + static void operator delete(void* i_ptr); +#endif + + // The target to callout/deconfigure/GARD + Target iv_target; + + // Callout Information + bool iv_callout; + CalloutPriorities::CalloutPriority iv_calloutPriority; + + // Deconfigure Information + bool iv_deconfigure; + + // GARD Information + bool iv_gard; + }; + + /// + /// @struct ErrorInfoChildrenCDG + /// + /// This struct contains children targets to callout/deconfigure/GARD + /// + /// Children by containment can be CDG (chiplets belonging to a parent chip) + /// e.g. + /// - PROC_CHIP -> EX_CHIPLET + /// - MEMBUF_CHIP -> MBA_CHIPLET + /// Children by affinity can be CDG. + /// Any from PROC_CHIP->MCS_CHIPLET->MEMBUF_CHIP->MBA_CHIPLET->DIMM e.g. + /// - PROC_CHIP->MEMBUF_CHIP + /// - MEMBUF_CHIP->DIMM + /// - MBA_CHIPLET->DIMM + /// Port and Number criteria can be applied to the child target as + /// detailed in the constructor + /// + struct ErrorInfoChildrenCDG + { + /// + /// @brief Constructor. + /// + /// @param[in] i_parent Reference to the parent target + /// @oaram[in] i_childType Child target type to c/d/g + /// @param[in] i_callout True if Target should be called out + /// @param[in] i_deconfigure True if Target should be deconfigured + /// @param[in] i_gard True if Target should be GARDed + /// @param[in] i_priority The priority of any callout + /// @param[in] i_childPort Child Port + /// For DIMM children, the MBA port number + /// @param[in] i_childNum Child Number + /// For DIMM children, the dimm socket number + /// For Chip children, the chip position + /// For Chiplet children, the chiplet unit pos + /// + ErrorInfoChildrenCDG(const Target & i_parentChip, + const TargetType i_childType, + const bool i_callout, + const bool i_deconfigure, + const bool i_gard, + const CalloutPriorities::CalloutPriority i_priority, + const uint8_t i_childPort, const uint8_t i_childNum); + +#ifdef FAPI_CUSTOM_MALLOC + /// + /// @brief Overload new operator to use platform-specific allocator + /// + /// @param[in] i_sz Size of memory to allocate in bytes + /// + /// @return Pointer to allocated memory + /// + static void* operator new(size_t i_sz); + + /// + /// @brief Overload delete operator to use platform-specific deallocator + /// + /// @param[in] i_ptr Pointer to memory previously allocated with new + /// + static void operator delete(void* i_ptr); +#endif + + // The parent chip + Target iv_parent; + + // The child target types to c/d/g + TargetType iv_childType; + + // Callout Information + bool iv_callout; + CalloutPriorities::CalloutPriority iv_calloutPriority; + + // Deconfigure Information + bool iv_deconfigure; + + // GARD Information + bool iv_gard; + + // Child Port + static const uint8_t ALL_CHILD_PORTS = 0xff; + uint8_t iv_childPort; + + // Child Number + static const uint8_t ALL_CHILD_NUMBERS = 0xff; + uint8_t iv_childNumber; + }; + + /// + /// @struct ErrorInfoCollectTrace + /// + /// This struct contains trace ID to add to the error log + /// + struct ErrorInfoCollectTrace + { + /// + /// @brief Constructor. + /// + /// @param[in] i_trace + /// + ErrorInfoCollectTrace(CollectTraces::CollectTrace i_traceId); + + +#ifdef FAPI_CUSTOM_MALLOC + /// + /// @brief Overload new operator to use platform-specific allocator + /// + /// @param[in] i_sz Size of memory to allocate in bytes + /// + /// @return Pointer to allocated memory + /// + static void* operator new(size_t i_sz); + + /// + /// @brief Overload delete operator to use platform-specific deallocator + /// + /// @param[in] i_ptr Pointer to memory previously allocated with new + /// + static void operator delete(void* i_ptr); +#endif + + // trace + CollectTraces::CollectTrace iv_eiTraceId; + }; + + /// + /// @struct ErrorInfo + /// + /// This struct defines the error information associated with a fapi2::ffdc + /// Users are allowed to access the data directly + /// + struct ErrorInfo + { + +#ifdef FAPI_CUSTOM_MALLOC + /// + /// @brief Overload new operator to use platform-specific allocator + /// + /// @param[in] i_sz Size of memory to allocate in bytes + /// + /// @return Pointer to allocated memory + /// + static void* operator new(size_t i_sz); + + /// + /// @brief Overload delete operator to use platform-specific deallocator + /// + /// @param[in] i_ptr Pointer to memory previously allocated with new + /// + static void operator delete(void* i_ptr); +#endif + + // Vector of FFDC Data + std::vector > iv_ffdcs; + + // Vector of Hardware to callout + std::vector > iv_hwCallouts; + + // Vector of procedures to callout + std::vector > + iv_procedureCallouts; + + // Vector of buses to callout + std::vector > iv_busCallouts; + + // Vector of targets to callout/deconfigure/GARD + std::vector > iv_CDGs; + + // Vector of children targets to callout/deconfigure/GARD + std::vector > iv_childrenCDGs; + + // Vector of traces to collect + std::vector > iv_traces; + }; + + /// + /// @brief Structure representing a single ErrorInfo entry. + /// + /// An array of these is passed to the addErrorInfo function when a HWP + /// generates an error by calling the FAPI_SET_HWP_ERROR macro + // Why aren't these inherited classes? Saves on allocation overhead. + // We create an array of ErrorInfoEntries as automatics when we start + // FFDC collection. If we did this as inherited classes it would either + // be allocating and deallocating or we'd need to allocate an array of + // the largest and map each struct in to it. That's messy to do without + // unions (that's what they're for) so we do it like this. The inherited + // model would result in a jump table anyway, so we're basically doing + // all of that by hand to avoid the mess. + // + struct ErrorInfoEntryFfdc + { + uint8_t iv_ffdcObjIndex; + uint16_t iv_ffdcSize; + uint32_t iv_ffdcId; + void addErrorInfo(std::shared_ptr i_info, + const void* const* i_object) const; + }; + + /// + /// @brief Structure representing a hardware callout + /// + struct ErrorInfoEntryHwCallout + { + uint8_t iv_hw; + uint8_t iv_calloutPriority; + uint8_t iv_refObjIndex; + void addErrorInfo(std::shared_ptr i_info, + const void* const* i_object) const; + }; + + /// + /// @brief Structure representing a procedure callout + /// + struct ErrorInfoEntryProcCallout + { + uint8_t iv_procedure; + uint8_t iv_calloutPriority; + void addErrorInfo(std::shared_ptr i_info, + const void* const* i_object) const; + + ErrorInfoEntryProcCallout(uint8_t i_procedure, uint8_t i_calloutPriority): + iv_procedure(i_procedure), + iv_calloutPriority(i_calloutPriority) + {} + + ErrorInfoEntryProcCallout(void) = default; + }; + + /// + /// @brief Structure representing a bus callout + /// + struct ErrorInfoEntryBusCallout + { + uint8_t iv_endpoint1ObjIndex; + uint8_t iv_endpoint2ObjIndex; + uint8_t iv_calloutPriority; + void addErrorInfo(std::shared_ptr i_info, + const void* const* i_object) const; + }; + + /// + /// @brief Structure representing a target callout + /// + struct ErrorInfoEntryTargetCDG + { + uint8_t iv_targetObjIndex; + uint8_t iv_callout; + uint8_t iv_deconfigure; + uint8_t iv_gard; + uint8_t iv_calloutPriority; + void addErrorInfo(std::shared_ptr i_info, + const void* const* i_object) const; + }; + + /// + /// @brief Structure representing a child callout + /// + struct ErrorInfoEntryChildrenCDG + { + uint8_t iv_parentObjIndex; + uint8_t iv_callout; + uint8_t iv_deconfigure; + uint32_t iv_childType; + uint8_t iv_childPort; + uint8_t iv_childNumber; + uint8_t iv_gard; + uint8_t iv_calloutPriority; + void addErrorInfo(std::shared_ptr i_info, + const void* const* i_object) const; + }; + + /// + /// @brief Structure representing collected trace information + /// + struct ErrorInfoEntryCollectTrace + { + uint32_t iv_eieTraceId; + void addErrorInfo(std::shared_ptr i_info, + const void* const* i_object) const; + }; + + /// + /// @brief Union of all the error info types + /// + struct ErrorInfoEntry + { + uint8_t iv_type; // Value from ErrorInfoType + union + { + ErrorInfoEntryFfdc ffdc; + ErrorInfoEntryHwCallout hw_callout; + ErrorInfoEntryProcCallout proc_callout; + ErrorInfoEntryBusCallout bus_callout; + ErrorInfoEntryTargetCDG target_cdg; + ErrorInfoEntryChildrenCDG children_cdg; + ErrorInfoEntryCollectTrace collect_trace; + }; + + /// + /// @brief Add error information to the FFDC object + /// @param[in] i_info a shared pointer to the error info + /// @param[in] i_object the list of ffdc objects being collected + /// + void addErrorInfo(std::shared_ptr i_info, + const void* const* i_object) const + { + // "unhandled error info type"); + fapi2::Assert(iv_type < EI_LAST_TYPE); + + switch(iv_type) + { + case EI_TYPE_FFDC: + ffdc.addErrorInfo(i_info, i_object); + break; + case EI_TYPE_HW_CALLOUT: + hw_callout.addErrorInfo(i_info, i_object); + break; + case EI_TYPE_PROCEDURE_CALLOUT: + proc_callout.addErrorInfo(i_info, i_object); + break; + case EI_TYPE_BUS_CALLOUT: + bus_callout.addErrorInfo(i_info, i_object); + break; + case EI_TYPE_CDG: + target_cdg.addErrorInfo(i_info, i_object); + break; + case EI_TYPE_CHILDREN_CDG: + children_cdg.addErrorInfo(i_info, i_object); + break; + case EI_TYPE_COLLECT_TRACE: + collect_trace.addErrorInfo(i_info, i_object); + break; + }; + return; + } + }; +} + +#endif // FAPI2_ERRORINFO_H_ diff --git a/importtemp/fapi2/include/error_info_defs.H b/importtemp/fapi2/include/error_info_defs.H new file mode 100644 index 00000000..31fc3429 --- /dev/null +++ b/importtemp/fapi2/include/error_info_defs.H @@ -0,0 +1,246 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2011,2015 */ +/* [+] 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 error_info_defs.H +/// @brief Defines to support the Error Information class +/// + +#ifndef FAPI2_ERRORINFO_DEFS_H_ +#define FAPI2_ERRORINFO_DEFS_H_ + +#include +#include +#include + +#include + +namespace fapi2 +{ + /// + /// @brief Type to hold the ffdc element in the ffdc class + /// Needed so that the size can be squirled away before the + /// macro is called. + /// + class ffdc_t + { + public: + ffdc_t(void) + {} + + operator const void*() const { return iv_value.first; } + operator uint8_t() const + { return *(reinterpret_cast(iv_value.first)); } + + int16_t size(void) const { return iv_value.second; } + int16_t& size(void) { return iv_value.second; } + + const void* ptr(void) const { return iv_value.first; } + const void*& ptr(void) { return iv_value.first; } + + private: + std::pair iv_value; + }; + + /// + /// @brief Enumeration of ErrorInfo FFDC sizes that are used to indicate a + /// special type that cannot simply be memcopied + enum ErrorInfoFfdcSize + { + EI_FFDC_SIZE_BUF = 0xffff, // fapi2::buffer + EI_FFDC_SIZE_TARGET = 0xfffe, // fapi2::Target + EI_FFDC_SIZE_VBUF = 0xfffd, // fapi2::variable_buffer + EI_FFDC_MAX_SIZE = 0x1000, // Limit regular FFDC capture to 4kb + }; + + /// + /// @brief Enumeration of error log severity. + /// + enum errlSeverity_t + { + FAPI2_ERRL_SEV_UNDEFINED = 0x00, /// Used internally by ffdc mechanism + FAPI2_ERRL_SEV_RECOVERED = 0x10, /// Not seen by customer + FAPI2_ERRL_SEV_PREDICTIVE = 0x20, /// Error recovered but customer will see + FAPI2_ERRL_SEV_UNRECOVERABLE = 0x40 /// Unrecoverable, general + }; + + /// + /// @brief Enumeration of ErrorInfo types + /// + enum ErrorInfoType + { + EI_TYPE_FFDC = 0, + EI_TYPE_HW_CALLOUT = 1, + EI_TYPE_PROCEDURE_CALLOUT = 2, + EI_TYPE_BUS_CALLOUT = 3, + EI_TYPE_CDG = 4, // Target Callout/Deconfig/GARD + EI_TYPE_CHILDREN_CDG = 5, // Children Callout/Deconfig/GARD + EI_TYPE_COLLECT_TRACE = 6, + EI_LAST_TYPE = EI_TYPE_COLLECT_TRACE + 1, + }; + + /// + /// @enum HwCallout + /// + /// This enumeration defines the possible Hardware Callouts that are not + /// represented by fapi2::Targets + /// + /// Note that platform code may depend on the enum values starting at 0 and + /// incrementing in order to efficiently convert to a platform callout value + /// so do not reorder without consulting all platforms + /// + namespace HwCallouts + { + enum HwCallout + { + // Where indicated, a HW Callout in FAPI Error XML must include a + // reference target that is used to identify the HW. e.g. for + // TOD_CLOCK, the proc chip that the clock is attached to must be + // specified + TOD_CLOCK = 0, // Include proc-chip ref (or child chiplet) + MEM_REF_CLOCK = 1, // Include membuf-chip ref (or child chiplet) + PROC_REF_CLOCK = 2, // Include proc-chip ref (or child chiplet) + PCI_REF_CLOCK = 3, // Include proc-chip ref (or child chiplet) + FLASH_CONTROLLER_PART = 4, + PNOR_PART = 5, + SBE_SEEPROM_PART = 6, + VPD_PART = 7, + LPC_SLAVE_PART = 8, + GPIO_EXPANDER_PART = 9, + SPIVID_SLAVE_PART = 10, + }; + } + + /// + /// @enum ProcedureCallout + /// + /// This enumeration defines the possible Procedure Callouts + /// These instruct the customer/customer-engineer what to do + /// + /// Note that platform code may depend on the enum values starting at 0 and + /// incrementing in order to efficiently convert to a platform callout value + /// so do not reorder without consulting all platforms + /// + namespace ProcedureCallouts + { + enum ProcedureCallout + { + CODE = 0, // Code problem + LVL_SUPPORT = 1, // Call next level of support + MEMORY_PLUGGING_ERROR = 2, // DIMM Plugging error + BUS_CALLOUT = 3, // Bus Called Out + }; + } + + /// + /// @enum CalloutPriority + /// + /// This enumeration defines the possible Procedure and Target callout priorities + /// + /// Note that platform code may depend on the enum values starting at 0 and + /// incrementing in order to efficiently convert to a platform priority value + /// so do not reorder without consulting all platforms + /// + namespace CalloutPriorities + { + enum CalloutPriority + { + LOW = 0, + MEDIUM = 1, + HIGH = 2, + }; + } + + /// + /// @enum Collect Trace + /// + /// This enumeration defines the possible firmware traces to collect + /// + namespace CollectTraces + { + const uint32_t TRACE_SIZE = 256; // limit collected trace size + enum CollectTrace + { + FSI = 1, + SCOM = 2, + SCAN = 3, + MBOX = 4, + }; + } + + /// + /// @brief Get FFDC Size + /// + /// This is called by the FAPI_SET_HWP_ERROR macro to find out the size of + /// FFDC data. If the data is of a special type that is handled differently + /// than types that are simply memcopied then it is handled by a template + /// specialization. + /// If this function template is instantiated with a pointer, the compile + /// will fail. + /// + /// @return uint16_t. Size of the FFDC data + /// + template + inline uint16_t getErrorInfoFfdcSize(const T &) + { + static_assert(sizeof(T) <= EI_FFDC_MAX_SIZE, + "FFDC too large to capture"); + return sizeof(T); + } + + /// + /// @brief Compile error if caller tries to get the FFDC size of a pointer + /// + template + inline uint16_t getErrorInfoFfdcSize(const T*) + { + static_assert(std::is_pointer::value, + "pointer passed to getErrorInfoFfdcSize"); + return 0; + } + + /// + /// @brief Get FFDC Size specialization for fapi2::Target + /// + template + inline uint16_t getErrorInfoFfdcSize(const fapi2::Target&) + { + return EI_FFDC_SIZE_TARGET; + } + + /// + /// @brief Get FFDC Size specialization for variable buffers + /// + template<> + inline uint16_t getErrorInfoFfdcSize(const fapi2::variable_buffer& i_thing) + { + // Limit a variable buffer to 4kb bytes, and we can memcpy the storage. + return std::min(static_cast(EI_FFDC_MAX_SIZE), + i_thing.getLength()); + } + +}; + +#endif // FAPI2_ERRORINFO_DEFS_H_ diff --git a/importtemp/fapi2/include/error_scope.H b/importtemp/fapi2/include/error_scope.H new file mode 100644 index 00000000..d742dd0e --- /dev/null +++ b/importtemp/fapi2/include/error_scope.H @@ -0,0 +1,37 @@ +/* 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 error_scope.H + * @brief platform specializations which create a scope for automatic error handling + */ + +#ifndef __FAPI2_ERROR_SCOPE__ +#define __FAPI2_ERROR_SCOPE__ + +#include +#include + + +#endif diff --git a/importtemp/fapi2/include/fapi2.H b/importtemp/fapi2/include/fapi2.H new file mode 100644 index 00000000..4e7121fd --- /dev/null +++ b/importtemp/fapi2/include/fapi2.H @@ -0,0 +1,47 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: hwpf/fapi2/include/fapi2.H $ */ +/* */ +/* 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 */ +/// +/// @file fapi2.H +/// @brief top level header for fapi2 +/// + +#ifndef __FAPI2_TOP_LEVEL__ +#define __FAPI2_TOP_LEVEL__ + +#include +#include +#include +#include +#include +#include + +// In turn includes the needed generated headers (hwp_ffd_classes, etc.) +#include +#include // Generated file + +#include + +#include + +// Block of headers not currently in fapi2 +#ifdef FAPI2_MISSING_HEADERS + #include +#endif + +#endif // __FAPI2_TOP_LEVEL__ diff --git a/importtemp/fapi2/include/fapi2_attribute_service.H b/importtemp/fapi2/include/fapi2_attribute_service.H new file mode 100644 index 00000000..b031f6e8 --- /dev/null +++ b/importtemp/fapi2/include/fapi2_attribute_service.H @@ -0,0 +1,127 @@ +/// +/// @file src/include/usr/hwpf/fapi2/fapi2_attribute_service.H +/// +/// @brief Defines the FAPI_ATTR_GET and FAPI_ATTR_SET macros that a user +/// calls to get/set attributes and a check function that the macros use to +/// verify correct usage +/// + +#ifndef FAPI2ATTRIBUTESERVICE_H_ +#define FAPI2ATTRIBUTESERVICE_H_ +#include +#include +#include +#include +#include + +/// @brief Macros called by user to get/set attributes for FAPI2 targets +/// +/// Code must have a reference to a FAPI2 Target and an attribute ID (from +/// XML file): +/// fapi2::ReturnCode l_rc; +/// fapi2::Target& l_target = ????; +/// Ex: Target& l_target = ????; +/// +/// To get a copy of an integer attribute and set the attribute +/// uint64_t l_val = 0; +/// l_rc = FAPI_ATTR_GET(, l_target, l_val); +/// l_rc = FAPI_ATTR_SET(, l_target, l_val); +/// +/// To get a copy of an integer array attribute and set the attribute +/// uint32_t l_pVal[4] = {0}; +/// l_rc = FAPI_ATTR_GET(, l_target, l_pVal); +/// l_rc = FAPI_ATTR_SET(, l_target, l_pVal); +/// +/// A priveleged attribute is one that a HWP should not generally access, +/// examples include ATTR_NAME and ATTR_EC, where usage can lead to a non +/// data-driven design. A privileged attribute can be accessed with +/// FAPI_ATTR_GET_PRIVILEGED and FAPI_ATTR_SET_PRIVILEGED +/// +/// The non-PRIVILEGED macros first call a template function (compiler will +/// optimize out) that will cause a compile failure if the attribute is +/// privileged, they then call a PRIVILEGED macro to get/set the attribute +/// +/// The PRIVILEGED macros call a template function (compiler will optimize out) +/// that will cause a compile failure if the ID is not valid or VAL is not the +/// correct type. +// + +#define FAPI_ATTR_GET(ID, TARGET, VAL) \ + (fapi2::failIfPrivileged(), \ + fapi2::Target(TARGET), \ + fapi2::checkIdType(ID, VAL), \ + ID##_GETMACRO(ID, TARGET, VAL)) + +#define FAPI_ATTR_SET(ID, TARGET, VAL) \ + (fapi2::failIfPrivileged(), \ + fapi2::Target(TARGET), \ + fapi2::checkIdType(ID, VAL), \ + ID##_SETMACRO(ID, TARGET, VAL)) + +#define FAPI_ATTR_GET_PRIVILEGED(ID, TARGET, VAL) \ + (fapi2::checkIdType(ID, VAL), \ + ID##_GETMACRO(ID, TARGET, VAL)) + +#define FAPI_ATTR_SET_PRIVILEGED(ID, TARGET, VAL) \ + (fapi2::checkIdType(ID, VAL), \ + ID##_SETMACRO(ID, TARGET, VAL)) + +namespace fapi2 +{ + +/// +/// @brief Get an InitFile attribute for FAPI2 +/// +/// This function gets a copy of an attribute. In the case of an array attribute, +/// The value in the specified index is retrieved. This should be used by the +/// InitFile HWP only, that HWP processes a binary InitFile and therefore needs +/// to read a variable ID of a variable data type. Standard HWPs should use the +/// FAPI2_ATTR_GET macro which automatically checks the type for correct usage. +/// +/// If there are ever attributes with more than 4 dimensions then this function +/// will need to be updated. +/// +/// @Tparam K template parameter, passed in target. +/// @param[in] i_id AttributeID +/// @param[in] i_target Reference to fapi2::Target (can be NULL for system) +/// @param[out] o_val Reference to uint64_t where attribute value is set +/// @param[in] i_arrayIndex1 If array attribute then index1 +/// @param[in] i_arrayIndex2 If at least 2D array attribute then index2 +/// @param[in] i_arrayIndex3 If at least 3D array attribute then index3 +/// @param[in] i_arrayIndex4 If at least 4D array attribute then index4 +/// +/// @return ReturnCode. Zero if success +/// +template< TargetType K > +ReturnCode getInitFileAttr(const AttributeId i_id, + const Target& i_target, + uint64_t & o_val, + const uint32_t i_arrayIndex1 = 0, + const uint32_t i_arrayIndex2 = 0, + const uint32_t i_arrayIndex3 = 0, + const uint32_t i_arrayIndex4 = 0); + +/** + * @brief Check the ID and TYPE + * + * This is called by FAPI code to check at compile time that a FAPI attribute + * access is using the correct data type and a valid AttributeId + */ +template inline void checkIdType(AttributeId, T &) {} + +/** + * @brief Fail if attribute privileged + * + * This is called by FAPI code to check at compile time that a standard FAPI + * attribute access (FAPI_ATTR_GET) is not accessing a privileged attribute + */ +class ErrorAccessingPrivilegedAttribute; +template void failIfPrivileged() +{ + ErrorAccessingPrivilegedAttribute(); +} +template <> inline void failIfPrivileged() {} + +} + +#endif // FAPI2ATTRIBUTESERVICE_H_ diff --git a/importtemp/fapi2/include/fapi2_chip_ec_feature.H b/importtemp/fapi2/include/fapi2_chip_ec_feature.H new file mode 100644 index 00000000..2398b5da --- /dev/null +++ b/importtemp/fapi2/include/fapi2_chip_ec_feature.H @@ -0,0 +1,39 @@ +/// +/// @file src/include/usr/hwpf/fapi2/fapi2_chip_ec_feature.H +/// +/// @brief Defines the queryChipEcFeature function that allows HWPs to +/// query if a particular chip has a feature determined by its EC level. +/// Chip EC features are specified in attribute XML files and the +/// queryChipEcFeature function implementation is auto-generated. +/// HWPs should not call this function directly, but should access the +/// corresponding HWPF attribute using FAPI_ATTR_GET +/// + +#ifndef FAPI2CHIPECFEATURE_H_ +#define FAPI2CHIPECFEATURE_H_ + +#include +#include +#include + +namespace fapi2 +{ + +/// +/// @brief Queries if a Chip has a particular feature +/// +/// This should only be called by FAPI during the processing of a FAPI_ATTR_GET +/// for a Chip EC Feature attribute +/// +/// @param[in] i_id Attribute ID of the Chip EC Feature +/// @param[in] i_target Reference to chip target +/// @param[out] o_hasFeature Set to 1 if chip has feature else 0 +/// @return ReturnCode. Zero on success, else platform specified error +/// +template< TargetType K > +ReturnCode queryChipEcFeature(AttributeId i_id, + const Target& i_target, + uint8_t & o_hasFeature); +} + +#endif diff --git a/importtemp/fapi2/include/fapi2_error_scope.H b/importtemp/fapi2/include/fapi2_error_scope.H new file mode 100644 index 00000000..43278c53 --- /dev/null +++ b/importtemp/fapi2/include/fapi2_error_scope.H @@ -0,0 +1,79 @@ +/* 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 fapi2_error_scope.H + * @brief common definitions which create a scope for automatic error handling + */ + +#ifndef __FAPI2_COMMON_ERROR_SCOPE__ +#define __FAPI2_COMMON_ERROR_SCOPE__ + +#include +#include +#include +#include + +/// @cond +#define FAPI_VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N +#define FAPI_VA_NARGS(...) FAPI_VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1) + +#define FAPI_TRY_IMPL2(count, ...) FAPI_TRY ## count (__VA_ARGS__) +#define FAPI_TRY_IMPL(count, ...) FAPI_TRY_IMPL2(count, __VA_ARGS__) + +#define FAPI_TRY_NO_TRACE( __operation__ ) PLAT_FAPI_TRY_NO_TRACE( __operation__ ) +#define FAPI_TRY_TRACE( __operation__, ... ) PLAT_FAPI_TRY_TRACE( __operation__, __VA_ARGS__ ) + +#define FAPI_TRY1 FAPI_TRY_NO_TRACE +#define FAPI_TRY2 FAPI_TRY_TRACE +#define FAPI_TRY3 FAPI_TRY_TRACE +#define FAPI_TRY4 FAPI_TRY_TRACE +#define FAPI_TRY5 FAPI_TRY_TRACE +/// @endcond + +/// +/// @brief Wrapper to check an operation for an error state +/// and jump to the label cleam_up if there is an error. +/// @param[in] __operation__ an operation which returns a fapi::ReturnCode +/// @param[in] ... vararg format/agruments for trace output (optional) +/// @note This implementation does not support PIB error masks or +/// FSP operational states. +/// +#ifdef DOXYGEN +#define FAPI_TRY(__operation__, ...) FAPI_TRY_IMPL +#else +#define FAPI_TRY(...) FAPI_TRY_IMPL(FAPI_VA_NARGS(__VA_ARGS__), __VA_ARGS__) +#endif + +/// +/// @brief Assert a conditional is true. +/// If it is not, the FFDC gathering function is called and the +/// trace is output as a FAPI error trace. +/// @param[in] __conditional__ the condition to assert +/// @param[in] __ffdc__ the FFDC gathering function +/// @param[in] ... varargs, as input to FAPI_ERR +/// +#define FAPI_ASSERT( __conditional__, __ffdc__, ... ) PLAT_FAPI_ASSERT( __conditional__, __ffdc__, __VA_ARGS__ ) + +#endif diff --git a/importtemp/fapi2/include/fapi2_hw_access.H b/importtemp/fapi2/include/fapi2_hw_access.H new file mode 100644 index 00000000..fca775b1 --- /dev/null +++ b/importtemp/fapi2/include/fapi2_hw_access.H @@ -0,0 +1,464 @@ +/* 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 fapi2_hw_access.H +/// @brief Common file that defines the hardware access functions that +/// platform code must implement. +/// + +#ifndef _FAPI2_COMMON_HWACCESS_H_ +#define _FAPI2_COMMON_HWACCESS_H_ + +#ifdef FAPI_SUPPORT_SPY_AS_ENUM +#include +typedef uint64_t spyId_t; +#endif + +#include +#include +#include + +// variable_buffer isn't supported on PPE +#ifndef __PPE__ +#include +#endif + +#include +#include +#include +#include + +#ifdef FAPI_SUPPORT_MULTI_SCOM +#include +#endif + +namespace fapi2 +{ + //-------------------------------------------------------------------------- + // PIB Error Functions + //-------------------------------------------------------------------------- + + /// @brief Sets the PIB error mask - platform dependant + /// @param[in] i_mask The new error mask + inline void setPIBErrorMask(uint8_t i_mask); + + /// @brief Gets the PIB error mask - platform dependant + /// @return uint8_t The current PIB error mask + inline uint8_t getPIBErrorMask(void); + + //-------------------------------------------------------------------------- + // Operational Mode Error Functions + //-------------------------------------------------------------------------- + + /// @brief Sets the operational mode + /// @param[in] i_mode The new mode + inline void setOpMode(const OpModes i_mode); + + /// @brief Gets the operational mode + /// @return the operational mode + inline OpModes getOpMode(void); + + //-------------------------------------------------------------------------- + // HW Communication Functions + //-------------------------------------------------------------------------- + + /// @brief Reads a SCOM register from a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address SCOM register address to read from. + /// @param[out] o_data Buffer that holds data read from HW target. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K > + inline ReturnCode getScom(const Target& i_target, const uint64_t i_address, + buffer& o_data); + + /// @brief Writes a SCOM register on a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address SCOM register address to write to. + /// @param[in] i_data Buffer that holds data to write into address. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K > + inline ReturnCode putScom(const Target& i_target, const uint64_t i_address, + const buffer i_data); + + /// @brief Writes a SCOM register under mask on a chip + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address SCOM register address to write to. + /// @param[in] i_data Buffer that holds data to write into address. + /// @param[in] i_mask Buffer that holds the mask value. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K > + inline ReturnCode putScomUnderMask(const Target& i_target, + const uint64_t i_address, + const buffer i_data, + const buffer i_mask); + + /// @brief Reads a CFAM register from a chip. + /// CFAM register is 32-bit wide. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address CFAM register address to read from. + /// @param[out] o_data Buffer that holds data read from HW target. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K > + inline ReturnCode getCfamRegister(const Target& i_target, + const uint32_t i_address, + buffer& o_data); + + /// @brief Writes a CFAM register on a chip. + /// CFAM register is 32-bit wide. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address CFAM register address to write to. + /// @param[in] i_data Buffer that holds data to write into address. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K > + inline ReturnCode putCfamRegister(const Target& i_target, + const uint32_t i_address, + const buffer i_data); + + /// @brief Read-modify-write a CFAM register on a chip. + /// CFAM register is 32-bit wide. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address CFAM register address to modify. + /// @param[in] i_data Buffer that holds data to be modified. + /// @param[in] i_modifyMode The modify mode (or/and/xor). + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K > + inline ReturnCode modifyCfamRegister(const Target& i_target, + const uint32_t i_address, + const buffer i_data, + const ChipOpModifyMode i_modifyMode); + + // variable_buffer isn't supported on PPE +#ifndef __PPE__ + /// @brief Reads a ring from a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_address Ring address to read from. + /// @param[out] o_data Buffer that holds data read from HW target. + /// @param[in] i_ringMode Ring operation mode. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K > + inline ReturnCode getRing(const Target& i_target, + const scanRingId_t i_address, + variable_buffer& o_data, + const RingMode i_ringMode = 0); + + /// @brief Writes a ring to a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_address Ring address to write to. + /// @param[in] i_data Buffer that contains RS4 compressed ring data + /// to write into address + /// @param[in] i_ringMode Ring operation mode. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K > + inline ReturnCode putRing(const Target& i_target, + const scanRingId_t i_address, + const variable_buffer& i_data, + const RingMode i_ringMode = 0); + + + /// @brief Read-modify-write a ring on a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_address Ring address to modify. + /// @param[in] i_data Buffer that contains RS4 compressed ring data + /// to be modified. + /// @param[in] i_modifyMode The modify mode (or/and/xor) + /// @param[in] i_ringMode Ring operation mode. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K > + inline ReturnCode modifyRing(const Target& i_target, + const scanRingId_t i_address, + const variable_buffer& i_data, + const ChipOpModifyMode i_modifyMode, + const RingMode i_ringMode = 0); +#endif + +#ifdef FAPI_SUPPORT_MULTI_SCOM + /// @brief Performs a multiple SCOM operation + /// This interface performs multiple SCOM operations on a chip in the + /// order specified by the input MultiScom object. + /// See fapiMultiScom.H for details of how to populate the MultiScom + /// object with SCOM operations. + /// + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in,out] io_multiScomObj Reference to a MultiScom object, + /// pre-populated with SingleScomInfo entries + /// to perform multiple SCOMs on input target + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note This is a synchronous interface and would return after all the + /// SCOM operations are completed or on the first failed operation + /// + /// @note SCOMs will be performed in the order they were added to the + /// input MultiScom object + /// + /// @note In case of errors, the platform code is responsible to collect + /// and add all the required error info and FFDC into the error data + /// for debugging + /// + /// @note If the SCOM operations added are specific to a processor chip, + /// then the FSI Shift Engine configured in scatter-gather DMA mode + /// extension would be used to execute the SCOM operations in a + /// performance optimize mode. In this mode, the special + /// SCOM_BULK_READ_MODE and SCOM_BULK_WRITE_MODE operations are + /// supported that allow a large bulk of SCOM access (in multiple of + /// 64 bits) for targets that support auto-increment. The + /// SCOM_WRITE_UNDER_MASK operation is not supported in this mode + /// + /// @note If the SCOM operations added are specific to a memory buffer + /// chip, then the regular SCOM engine is used to execute the SCOM + /// operations. SCOM_WRITE_UNDER_MASK operation is supported in + /// this mode, but the special SCOM_BULK_READ_MODE and + /// SCOM_BULK_WRITE_MODE operations are not supported due to + /// hardware limitations. + /// + template< TargetType K > + fapi2::ReturnCode multiScom (const Target& i_target, + MultiScom& io_multiScomObj); +#endif + + // -------------------------------------------------------------------------- + // NOTE: + // Implement platform Spy access functions if platform supports them. + // -------------------------------------------------------------------------- + + // variable_buffer isn't supported on PPE +#ifndef __PPE__ + /// @brief Reads a spy from a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_spyId Id of the spy whose data to be read. + /// @param[out] o_data Buffer that holds data read from HW target. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note: The string version is only supported for cronus. + /// + /// The fapi design to support both FSP and cronus use of get and + /// put spy functions is dependant on the SPY names being expanded + /// to resemble a valid C identifier. This design places some + /// restrictions on the SPY names which can be used. + /// + /// 1. if the spy name contains a # procedure writers should replace + /// it with an __P__ for example - + /// + /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS + /// becomes + /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS + /// + /// 2. if the spy name has a number following a "." it must have an + /// underscore prepended to the number. + /// + /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY + /// becomes + /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY + /// + /// Example SPY name: + /// The hardware procedure should call the function like: + /// + /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS + /// + /// fapi2::ReturnCode rc = fapiGetSpy( targ, + /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data ); + /// + /// @note The ID is not in quotes the fapi code will handle adding + /// the quotes for the cronus environment +#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(DOXYGEN) + +#define FAPI_GET_SPY(TARGET, ID, DATA) fapi2::getSpy(TARGET, FAPI_SPY_NAMES::ID.value, DATA) + + template< TargetType K > + inline ReturnCode getSpy(const Target& i_target, + const spyId_t i_spyId, + variable_buffer& o_data); +#endif + +#if defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN) + +#define FAPI_GET_SPY(TARGET, ID, DATA) fapi2::getSpy(TARGET, #ID, DATA) + + template< TargetType K > + inline ReturnCode getSpy(const Target& i_target, + const char * const i_spyId, + variable_buffer& o_data); +#endif + + /// @brief Writes a spy on a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_spyId Id of the spy to write data to. + /// @param[out] i_data Buffer that holds data to write into spy. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note: The string version is only supported for cronus. + /// + /// The fapi design to support both FSP and cronus use of get and + /// put spy functions is dependent on the SPY names being expanded + /// to resemble a valid C identifier. This design places some + /// restrictions on the SPY names which can be used. + /// + /// 1. if the spy name contains a # procedure writers should replace + /// is with an __P__ for example - + /// + /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS + /// becomes + /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS + /// + /// 2. if the spy name has a number following a "." it must have an + /// underscore prepended to the number. + /// + /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY + /// becomes + /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY + /// + /// Example SPY name: + /// The hardware procedure should call the function like: + /// + /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS + /// + /// fapi2::ReturnCode rc = fapiPutSpy( targ, + /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data ); + /// + /// @note The ID is not in quotes the fapi code will handle adding + /// the quotes for the cronus environment + /// +#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(DOXYGEN) + +#define FAPI_PUT_SPY(TARGET, ID, DATA) fapi2::putSpy(TARGET, FAPI_SPY_NAMES::ID.value, DATA) + + template< TargetType K > + inline ReturnCode putSpy(const Target& i_target, + const spyId_t i_spyId, + variable_buffer& i_data); +#endif + +#if defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN) + +#define FAPI_PUT_SPY(TARGET, ID, DATA) fapi2::putSpy(TARGET, #ID, DATA) + + template< TargetType K > + inline ReturnCode putSpy(const Target& i_target, + const char* const i_spyId, + variable_buffer& i_data); +#endif + + /// @brief Writes spy data into a buffer holding ring data image + /// This API is used by L2/L3 repair to put column repair data + /// into a ring buffer image. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_spyId Id of the spy. + /// @param[in] i_data Buffer that holds spy data to write into ring + /// image. + /// @param[out] o_data Buffer that holds updated ring image. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note: The string version is only supported for cronus. + /// + /// The fapi design to support both FSP and cronus use of get and + /// put spy functions is dependent on the SPY names being expanded + /// to resemble a valid C identifier. This design places some + /// restrictions on the SPY names which can be used. + /// + /// See fapiPutSpy for details on spy id specifics. + /// +#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(DOXYGEN) + +#define FAPI_PUT_SPY_IMAGE(TARGET, ID, DATA1, DATA2) \ + fapi2::putSpyImage(TARGET, FAPI_SPY_NAMES::ID.value, \ + DATA1, DATA2) + + template< TargetType K > + inline ReturnCode putSpyImage(const Target& i_target, + const spyId_t i_spyId, + const variable_buffer& i_data, + variable_buffer& o_imageData); +#endif + +#if defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN) + +#define FAPI_PUT_SPY_IMAGE(TARGET, ID, DATA1, DATA2) \ + fapi2::putSpyImage(TARGET, #ID, DATA1,DATA2) + + template< TargetType K > + inline ReturnCode putSpyImage(const Target& i_target, + const char* const i_spyId, + const variable_buffer& i_data, + variable_buffer& o_imageData); +#endif + + /// @brief Reads spy data from a ring image buffer + /// @param[in] i_target Target to operate on + /// @param[in] i_spyId The spy's id + /// @param[out] o_data Buffer that holds data read from ring image. + /// @param[in] i_imageData Buffer that holds ring image to read data + /// from. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note: The string version is only supported for cronus. + /// + /// The fapi design to support both FSP and cronus use of get and + /// put spy functions is dependent on the SPY names being expanded + /// to resemble a valid C identifier. This design places some + /// restrictions on the SPY names which can be used. + /// + /// See fapiPutSpy for details on spy id specifics. + /// +#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(DOXYGEN) + +#define FAPI_GET_SPY_IMAGE(TARGET, ID, DATA1, DATA2) \ + fapi2:getSpyImage(TARGET, FAPI_SPY_NAMES::ID.value, \ + DATA1, DATA2) + + template< TargetType K > + inline ReturnCode getSpyImage(const Target& i_target, + const spyId_t i_spyId, + variable_buffer& o_data, + const variable_buffer& i_imageData); +#endif + +#if defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN) + +#define FAPI_GET_SPY_IMAGE(TARGET, ID, DATA1, DATA2) \ + fapi2::getSpyImage(TARGET, #ID, DATA1,DATA2) + + template< TargetType K > + inline ReturnCode getSpyImage(const Target& i_target, + const char * const i_spyId, + variable_buffer& o_data, + const variable_buffer& i_imageData); +#endif + +#endif // PPE +}; + +#endif // _FAPI2_HWACCESS_H_ diff --git a/importtemp/fapi2/include/fapi2_hwp_executor.H b/importtemp/fapi2/include/fapi2_hwp_executor.H new file mode 100644 index 00000000..e92d1427 --- /dev/null +++ b/importtemp/fapi2/include/fapi2_hwp_executor.H @@ -0,0 +1,24 @@ +/// +/// @file fapi2_hwp_executor.H +/// +/// @brief Defines the FAPI2 HWP Executor Macro. +/// +/// The FAPI2 HWP Executor macro is called when a PLAT invoker function or a HWP +/// wants to execute a HWP. +/// + +#ifndef FAPI2HWPEXECUTOR_H_ +#define FAPI2HWPEXECUTOR_H_ + +#include + +/** + * @brief HWP Executor macro + * + * This macro calls a PLAT macro which will do any platform specific work to + * execute the HWP (e.g. dlopening a shared library) + */ +#define FAPI_EXEC_HWP(RC, FUNC, _args_...) \ + FAPI_PLAT_EXEC_HWP(RC, FUNC, ##_args_) + +#endif // FAPI2HWPEXECUTOR_H_ diff --git a/importtemp/fapi2/include/fapi2_target.H b/importtemp/fapi2/include/fapi2_target.H new file mode 100644 index 00000000..b479fca7 --- /dev/null +++ b/importtemp/fapi2/include/fapi2_target.H @@ -0,0 +1,433 @@ +/// +/// @file fapi2_target.H +/// @brief Common definitions for fapi2 targets +/// + +#ifndef __FAPI2_COMMON_TARGET__ +#define __FAPI2_COMMON_TARGET__ + +#include +#include +#include +#include +#include + +namespace fapi2 +{ + /// + /// @brief Class representing a FAPI2 Target + /// @tparam K the type (Kind) of target + /// @tparam V the type of the target's Value + /// @remark TargetLite targets are uint64_t, Targets + /// are uintptr_t (void*). + /// + /// Assuming there are representations of a processor, + /// a membuf and a system here are some examples: + /// @code + /// #define PROCESSOR_CHIP_A 0xFFFF0000 + /// #define MEMBUF_CHIP_B 0x0000FFFF + /// #define SYSTEM_C 0x0000AAAA + /// @endcode + /// + /// * To define a target: + /// @code + /// fapi2::Target A(PROCESSOR_CHIP_A); + /// fapi2::Target C(SYSTEM_C); + /// fapi2::Target B(MEMBUF_CHIP_B); + /// @endcode + /// + /// * Functions which take composite target types + /// @code + /// void takesProcOrMembuf( + /// const fapi2::Target& V ); + /// + /// void takesAny(const fapi2::Target& V ); + /// + /// @endcode + /// + /// * Traversing the target "tree" + /// @code + /// fapi2::Target A(PROCESSOR_CHIP_A); + /// + /// // Get A's parent + /// A.getParent(); + /// + /// // Get the 0x53'd core + /// fapi2::getTarget(0x53); + /// + /// // Get all *my* present/functional children which are cores + /// A.getChildren(); + /// + /// // Get all of the the cores relative to my base target + /// fapi2::getChildren(); + /// @endcode + /// + /// * Invalid casts + /// @code + /// // Can't cast to a specialized target + /// fapi2::Target D(MEMBUF_CHIP_B); + /// takesProcOrMembuf( D ); + /// + /// // Not one of the shared types + /// fapi2::Target E; + /// takesProcOrMembuf( E ); + /// @endcode + template + class Target + { + public: + + /// + /// @brief Create a Target, with a value + /// @param[in] Value the value (i.e., specific element this + /// target represents, or pointer) + /// @note Platforms can mangle the value and K to get a + /// single uint64_t in value which represents all the information + /// they might need. value( K | V ), for example + /// + Target(V Value = 0): + iv_handle(Value) + {} + + /// + /// @brief Assignment Operator. + /// @param[in] i_right Reference to Target to assign from. + /// @return Reference to 'this' Target + /// + Target& operator=(const Target& i_right); + + /// + /// @brief Equality Comparison Operator + /// @param[in] i_right Reference to Target to compare. + /// @return bool. True if equal. + /// @note Platforms need to define this so that the physical + /// targets are determined to be equivilent rather than just the handles + /// + bool operator==(const Target& i_right) const; + + /// + /// @brief Inquality Comparison Operator + /// @param[in] i_right Reference to Target to compare. + /// @return bool. True if not equal. + /// @note Platforms need to define this so that the physical + /// targets are determined to be equivilent rather than just the handles + /// + bool operator!=(const Target& i_right) const; + + /// + /// @brief Get the handle. + /// @return V The target's handle, or value + /// + V get(void) const + { return iv_handle; } + + /// + /// @brief Get the handle as a V + /// @return V The target's handle, or value + /// + inline operator V() const { return iv_handle; } + + /// + /// @brief Get a target's value + /// @return V The target's handle, or value + /// + inline V& operator()(void) { return iv_handle; } + + /// + /// @brief Get the target type + /// @return The type of target represented by this target + /// + inline TargetType getType(void) const { return iv_type; } + + /// + /// @brief Get this target's immediate parent + /// @tparam T The type of the parent + /// @return Target a target representing the parent + /// + template< TargetType T > + inline Target getParent(void) const; + + /// + /// @brief Is this target a chip? + /// @return Return true if this target is a chip, false otherwise + /// + inline constexpr bool isChip(void) const + { + return ( (K == TARGET_TYPE_PROC_CHIP) || + (K == TARGET_TYPE_MEMBUF_CHIP) ); + } + + /// + /// @brief Is this target a chiplet? + /// @return Return true if this target is a chiplet, false otherwise + /// + inline constexpr bool isChiplet(void) const + { + return ( (K == TARGET_TYPE_EX) || + (K == TARGET_TYPE_MBA) || + (K == TARGET_TYPE_MCS) || + (K == TARGET_TYPE_XBUS) || + (K == TARGET_TYPE_ABUS) || + (K == TARGET_TYPE_L4) || + (K == TARGET_TYPE_CORE) || + (K == TARGET_TYPE_EQ) || + (K == TARGET_TYPE_MCA) || + (K == TARGET_TYPE_MCBIST) || + (K == TARGET_TYPE_MI) || + (K == TARGET_TYPE_DMI) || + (K == TARGET_TYPE_OBUS) || + (K == TARGET_TYPE_NV) || + (K == TARGET_TYPE_SBE) || + (K == TARGET_TYPE_PPE) || + (K == TARGET_TYPE_PERV) || + (K == TARGET_TYPE_PEC) || + (K == TARGET_TYPE_PHB) ); + } + + /// + /// @brief Get this target's children + /// @tparam T The type of the parent + /// @param[in] i_state The desired TargetState of the children + /// @return std::vector > a vector of present/functional + /// children + /// @warning The children of EX's (cores) are expected to be returned + /// in order. That is, core 0 is std::vector[0]. + /// + template< TargetType T> + inline std::vector > + getChildren(const TargetState i_state = TARGET_STATE_FUNCTIONAL) const; + + /// + /// @brief Get the target at the other end of a bus - dimm included + /// @tparam T The type of the parent + /// @param[in] i_state The desired TargetState of the children + /// @return Target a target representing the thing on the other end + /// @note Can be easily changed to a vector if needed + /// + template + inline Target + getOtherEnd(const TargetState i_state = TARGET_STATE_FUNCTIONAL) const; + + /// + /// @brief Copy from a Target to a Target + /// @tparam O the target type of the other + /// + template + inline Target( const Target& Other ): + Target(Other.get()) + { + // In case of recursion depth failure, use -ftemplate-depth= + static_assert( (K & O) != 0, + "unable to cast Target, no shared types"); + + static_assert( bitCount::count >= bitCount::count, + "unable to cast to specialized Target"); + } + + private: + // Don't use enums here as it makes it hard to assign + // in the platform target cast constructor. + static const TargetType iv_type = K; + V iv_handle; + + }; + + // EX threads map to CORE threads: + // t0 / t2 / t4 / t6 fused = t0 / t1 / t2 / t3 normal (c0) + // t1 / t3 / t5 / t7 fused = t0 / t1 / t2 / t3 normal (c1) + // So when splitting the EX, we need to map from EX threads + // to CORE threads. + + /// + /// @brief Given a normal core thread id, translate this to + /// a fused core thread id. (normal to fused) + /// @param[in] the ordinal number of the normal core this thread belongs to + /// @param[in] a normal core thread id - 0, ..., 3 + /// @return the fused core thread id + /// + inline uint8_t thread_id_n2f(const uint8_t i_ordinal, const uint8_t i_thread_id) + { + return (i_thread_id << 1) | i_ordinal; + } + + /// + /// @brief Given a fused core thread id, translate this to + /// a normal core thread id. (fused to normal) + /// @param[in] a fused core thread id - 0, ..., 7 + /// @return the normal core thread id + /// + inline uint8_t thread_id_f2n(const uint8_t i_thread_id) + { + return i_thread_id >> 1; + } + + /// + /// @brief Given a normal core thread id, translate this to a + /// normal core bitset. + /// @param[in] a normal core thread id - 0, ..., 3 + /// @return the normal core bitset + /// @note to got from a fused core id to a normal core bitset, + /// translate from a fused core thread id first. + /// + inline uint8_t thread_id2bitset(const uint8_t i_thread_id) + { + // 0xff means "set all bits" + static const uint8_t all_threads = 0xff; + static const uint8_t all_normal_threads_bitset = 0x0f; + + if (i_thread_id == all_threads) + { + return all_normal_threads_bitset; + } + + // A thread_id is really just bit index. + return (1 << (4 - i_thread_id - 1)); + } + + /// + /// @brief Given a bitset of normal core thread ids, translate this to + /// a bit mask of fused core thread id. (normal to fused) + /// @param[in] the ordinal number of the normal core this thread belongs to + /// @param[in] a normal core thread bitset - b0000, ..., b1111 + /// @return the corresponding fused core bitset + /// + inline uint8_t thread_bitset_n2f(const uint8_t i_ordinal, const uint8_t i_threads) + { + // Since we only have 4 bits I think this is better than a shift-type solution + // for interleaving bits + static uint8_t core_map[] = { + 0b00000000, // b0000 + 0b00000010, // b0001 + 0b00001000, // b0010 + 0b00001010, // b0011 + 0b00100000, // b0100 + 0b00100010, // b0101 + 0b00101000, // b0110 + 0b00101010, // b0111 + 0b10000000, // b1000 + 0b10000010, // b1001 + 0b10001000, // b1010 + 0b10001010, // b1011 + 0b10100000, // b1100 + 0b10100010, // b1101 + 0b10101000, // b1110 + 0b10101010, // b1111 + }; + + return core_map[i_threads] >> i_ordinal; + } + + /// + /// @brief Given a fused core thread bitset, translate this to + /// a normal core thread bitset. (fused to normal) + /// @param[in] the ordinal number of the normal core this thread belongs to + /// @param[in] a fused core thread bitset - b00000000, ..., b11111111 + /// @return the corresponding normal core bitset + /// + inline uint8_t thread_bitset_f2n(const uint8_t i_ordinal, const uint8_t i_threads) + { + uint8_t normal_set = 0; + + // core 0 is the left-most bit in the pair + uint8_t pair_mask = (i_ordinal == 0) ? 0x2 : 0x1; + + // For each bit which can be set in the normal core bit_set ... + for( auto i = 0; i <= 3; ++i ) + { + // ... grab the two fused bits which represent it ... + // ... and mask off the bit in the pair which represents this normal core ... + // (the << 1 shifts the masks over as we walk the pairs of bits) + uint8_t bits = (((3 << (i << 1)) & i_threads) & (pair_mask << (i << 1))); + + // ... if either bit is set, set the corresponding bit in + // the normal core bitset. + normal_set |= (bits != 0) << i; + } + return normal_set; + } + + /// + /// @brief Return the string interpretation of this target + /// @tparam T The type of the target + /// @param[in] i_target Target + /// @param[in] i_buffer buffer to write in to + /// @param[in] i_bsize size of the buffer + /// @return void + /// @post The contents of the buffer is replaced with the string + /// representation of the target + /// + template< TargetType T > + inline void toString(const Target& i_target, char* i_buffer, size_t i_bsize); + + /// + /// @brief Return the string interpretation of this target + /// @tparam T The type of the target + /// @tparam B The type of the buffer + /// @param[in] A pointer to the Target + /// @param[in] i_buffer buffer to write in to + /// @param[in] i_bsize size of the buffer + /// @return void + /// @post The contents of the buffer is replaced with the string + /// representation of the target + /// + template< TargetType T > + inline void toString(const Target* i_target, char* i_buffer, size_t i_bsize); + + /// + /// @brief Get an enumerated target of a specific type + /// @tparam T The type of the target + /// @param[in] Ordinal representing the ordinal number of + /// the desired target + /// @return Target the target requested + /// + template + inline Target getTarget(uint64_t Ordinal); + + // Why has the been removed? For starters, the API name + // is probably wrong as it's already been confused with + // Target::getChildren(). And if I'm going to change it + // I really want to see if we need it. I'm still not + // clear on whether we're alloing this traversal or not. +#if 0 + /// + /// @brief Get the base target's children + /// @tparam T The type of the target + /// @return std::vector > a vector of present/functional + /// children + /// + template + inline std::vector > getChildren() + { + // For testing + return {Target(), Target()}; + } +#endif + + /// + /// @brief Return the string interpretation of this target + /// @tparam T The type of the target + /// @tparam B The type of the buffer + /// @param[in] i_target Target + /// @param[in] i_buffer buffer + /// @return void + /// @post The contents of the buffer is replaced with the string + /// representation of the target + /// + template + inline void toString(const Target& i_target, B& i_buffer); + + /// + /// @brief Check if the target is of a type, or in a type subset. + /// @tparam K the TargetType to check + /// @tparam T TargetType or TargetType composite to check against + /// @return True, iff K is a proper T + /// + template< TargetType K, TargetType T > + inline constexpr bool is_same(void) + { return (K & T) != 0; } + + +} + +#endif diff --git a/importtemp/fapi2/include/ffdc.H b/importtemp/fapi2/include/ffdc.H new file mode 100644 index 00000000..6ebf87ff --- /dev/null +++ b/importtemp/fapi2/include/ffdc.H @@ -0,0 +1,190 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2014 */ +/* */ +/* 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 ffdc.H + * @brief Defines the FirstFailureData class + */ + +#ifndef FAPI2_FFDC_H_ +#define FAPI2_FFDC_H_ + +#include +#include +#include +#include +#include + +using fapi2::TARGET_TYPE_ALL; + +namespace fapi2 +{ + /// + /// @brief Check the type of a variable + /// + /// This function can be called to check that a variable type is as expected + /// @note This mechanism will allow for cast ctor's which other static type + /// checking might not. + /// + template + inline + void checkType(const T &) {} + + class ReturnCode; + + /// + /// @class FirstFailureData + /// + /// This class provides storage and methods for creating and manipulating + /// FFDC. + /// It is not needed on all platforms - platforms which need this class have + /// specified this by forcing their fapi2::ReturnCode to be a subclass of + /// this class. + /// + template< class R = fapi2::ReturnCode > + class FirstFailureData + { + public: + + /// + /// @brief Default constructor. + /// @note We don't create our error info be default. It will be created + /// when its needed in the setHwpError() method. Note that dereferencing + /// the error info without will create a problem. + /// + FirstFailureData(void): + iv_info( nullptr ) + {} + + /// + /// @brief Copy Constructor + /// + /// @param[in] i_right Reference to FirstFailureData to copy + /// @note Generates default copy constructor - no deep pointer + /// copies necessary. + /// + FirstFailureData(const FirstFailureData & i_right) = default; + + /// + /// @brief Destructor + /// + ~FirstFailureData(void) = default; + + /// + /// @brief Assignment Operator. + /// + /// @param[in] i_right Reference to FirstFailureData to assign from. + /// @return Reference to 'this' FirstFailureData + /// + FirstFailureData & operator=(const FirstFailureData & i_right) = default; + + /// + /// @brief Sets a HWP error. Sets the rcValue to the supplied value (from + /// the HwpFirstFailureData enumeration) and deletes any + /// associated data. + /// + /// HWP code must call the FAPI_SET_HWP_ERROR macro rather than this + /// function + /// directly to generate an error so that any error information is + /// automatically added to the FirstFailureData + /// + /// @param[in] i_rcValue Error value to set + /// + inline void _setHwpError(const fapi2::HwpReturnCode i_rcValue) + { + FAPI_ERR("_setHwpError: Creating HWP error 0x%x", i_rcValue); + static_cast(this)->operator=(i_rcValue); + + // Forget about any associated data (this is a new error) + iv_info.reset(new ErrorInfo()); + } + + /// + /// @brief Get a pointer to any PlatData. FirstFailureData is still + /// responsible for deletion of the data. The caller must not + /// delete + /// + /// This is called by PLAT. The expected use-case is to get a pointer to + /// a platform error log. The data pointer should be used immediately in + /// the same thread. + /// + /// @return void *. Pointer to any PlatData. If NULL then no data + /// + void* getData(void) const; + + /// + /// @brief Get a pointer to any PlatData and release ownership from + /// FirstFailureData. The caller is responsible for deletion. + /// + /// This is called by PLAT. The expected use-case is to retrieve a + /// platform error log. + /// + /// @return void*. Pointer to any PlatData. If NULL then no data + /// + void* releaseData(void); + + /// + /// @brief Add ErrorInfo + /// + /// This is called by the FAPI_SET_HWP_ERROR and macro to add ErrorInfo + /// to the FirstFailureData when a HWP generates an error. The function + /// is designed to add all the ErrorInfo at once rather than the + /// FAPI_SET_HWP_ERROR macro making multiple function calls to add each + /// piece of ErrorInfo individually in order to minimize code size + /// + /// @param[in] i_pObjects Pointer to array of const pointers to const + /// objects that are referred to by ErrorInfoEntry objects + /// @param[in] i_pEntries Pointer to array of ErrorInfoEntry objects + /// defining the ErrorInfo that needs to be added + /// @param[in] i_count Number of ErrorInfoEntry entries + /// + void addErrorInfo(const void* const * i_pObjects, + const ErrorInfoEntry* i_pEntries, + const uint8_t i_count); + + /// + /// @brief Get a pointer to any ErrorInfo + /// + /// This is called by PLAT to find information about an error + /// + /// @return ErrorInfo *. Pointer to any ErrorInfo. If NULL then no info + /// + inline const fapi2::ErrorInfo* getErrorInfo(void) const + { return iv_info.get(); } + + /// + /// @brief Forgets about any associated data (PlatData and ErrorInfo) + /// + /// If this is the only FirstFailureData pointing to the data then the + /// data is deleted + /// + inline void forgetData(void) + { iv_info = nullptr; } + + private: + + // Pointer to the data + std::shared_ptr iv_info; + }; + +} +#endif // FAPI2_FFDC_H_ diff --git a/importtemp/fapi2/include/hw_access.H b/importtemp/fapi2/include/hw_access.H new file mode 100644 index 00000000..d1c2ad28 --- /dev/null +++ b/importtemp/fapi2/include/hw_access.H @@ -0,0 +1,582 @@ +/* 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 hw_access.H +/// +/// @brief Hardware access functions that needs to be specialized for +/// platform implementation. +/// + +#ifndef _FAPI2_HWACCESS_H_ +#define _FAPI2_HWACCESS_H_ + + // variable_buffer isn't supported on PPE +#ifndef __PPE__ +#include +#endif + +#include +#include + +namespace fapi2 +{ + //-------------------------------------------------------------------------- + // PIB Error Functions + //-------------------------------------------------------------------------- + + /// @brief Sets the PIB error mask - platform dependant + /// @param[in] i_mask The new error mask + // note: this can be moved to a C file if desired + inline void setPIBErrorMask(uint8_t i_mask) + { + // Keeps the compiler from complaining about the unused i_mask + static_cast(i_mask); + + return; + } + + /// @brief Gets the PIB error mask - platform dependant + /// @return uint8_t The current PIB error mask + // note: this can be moved to a C file if desired + inline uint8_t getPIBErrorMask(void) + { + return 0; + } + + //-------------------------------------------------------------------------- + // Operational Mode Error Functions + //-------------------------------------------------------------------------- + + /// @brief Sets the operational mode + /// @param[in] i_mode The new mode + // note: this can be moved to a C file if desired + inline void setOpMode(const OpModes i_mode) + { + // Keeps the compiler from complaining about the unused i_mode + static_cast(i_mode); + + // No-op for now. Should set thread-local operational mode + return; + } + + /// @brief Gets the operational mode + /// @return the operational mode + // note: this can be moved to a C file if desired + inline OpModes getOpMode(void) + { + // No-op for now. Should read thread-local operational mode + return NORMAL; + } + + //------------------------------------------------------------------------------ + // HW Communication Functions to be implemented at the platform layer. + //------------------------------------------------------------------------------ + + /// + /// @brief Platform-level implementation of getScom() + /// @Tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address SCOM register address to read from. + /// @param[out] o_date Buffer that holds data read from HW target. + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + template< TargetType K > + inline ReturnCode getScom(const Target& i_target, + const uint64_t i_address, + buffer& o_data) + { + o_data = 0x0000FEEDFACE0000; + std::cout << std::hex << " getScom " + << "target: {" << i_target.getType() << "," + << uint64_t(i_target) << "}; " + << "address: " << i_address << "; " + << "output data: " << uint64_t(o_data) + << std::dec << std::endl; + + return FAPI2_RC_SUCCESS; + } + + /// @brief Platform-level implementation of putScom() + /// @Tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address SCOM register address to write to. + /// @param[in] i_data Buffer that holds data to write into address. + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K > + inline ReturnCode putScom(const Target& i_target, + const uint64_t i_address, + const buffer i_data) + { + std::cout << std::hex << " putScom " + << "target: {" << i_target.getType() << "," + << uint64_t(i_target) << "}; " + << "address: " << i_address << "; " + << "input data: " << uint64_t(i_data) + << std::dec << std::endl; + return FAPI2_RC_SUCCESS; + } + + /// @brief Platform-level implementation of putScomUnderMask() + /// @tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address SCOM register address to write to. + /// @param[in] i_data Buffer that holds data to write into address. + /// @param[in] i_mask Buffer that holds the mask value. + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K > + inline ReturnCode putScomUnderMask(const Target& i_target, + const uint64_t i_address, + const buffer i_data, + const buffer i_mask) + { + std::cout << std::hex << " putScomUnderMask " + << "target: {" << i_target.getType() << "," + << uint64_t(i_target) << "}; " + << "address: " << i_address << "; " + << "input data: " << uint64_t(i_data) << "; " + << "input mask: " << uint64_t(i_mask) + << std::dec << std::endl; + return FAPI2_RC_SUCCESS; + } + + /// + /// @brief Platform-level implementation called by getCfamRegister() + /// Hardware procedures writers will not call this function. + /// @Tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address CFAM address to read from. + /// @param[out] o_data 32-bit buffer that holds data read from HW target. + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + template< TargetType K > + inline ReturnCode getCfamRegister(const Target& i_target, + const uint32_t i_address, + buffer& o_data) + { + o_data = 0xFEED0CFA; + std::cout << std::hex << " getCfamRegister " + << "target: {" << i_target.getType() << "," + << uint64_t(i_target) << "}; " + << "address: " << i_address << "; " + << "output data: " << uint32_t(o_data) + << std::dec << std::endl; + return FAPI2_RC_SUCCESS; + } + + /// + /// @brief Platform-level implementation of putCfamRegister() + /// Hardware procedures writers will not call this function. + /// @Tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address CFAM address to write to. + /// @param[out] i_data 32-bit buffer that holds data to write into address. + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + template< TargetType K > + inline ReturnCode putCfamRegister(const Target& i_target, + const uint32_t i_address, + const buffer i_data) + { + std::cout << std::hex << " putCfamRegister " + << "target: {" << i_target.getType() << "," + << uint64_t(i_target) << "}; " + << "address: " << i_address << "; " + << "input data: " << uint32_t(i_data) + << std::dec << std::endl; + return FAPI2_RC_SUCCESS; + } + + + /// + /// @brief Platform-level implementation of modifyCfamRegister() + /// Hardware procedures writers will not call this function. + /// @Tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address CFAM register address to modify. + /// @param[out] i_data 32-bit buffer that holds data to modify. + /// @param[in] i_modifyMode The modify mode (or/and/xor). + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + template< TargetType K > + inline ReturnCode modifyCfamRegister(const Target& i_target, + const uint32_t i_address, + const buffer i_data, + const fapi2::ChipOpModifyMode i_modifyMode) + { + std::cout << std::hex << " modifyCfamRegister " + << "target: {" << i_target.getType() << "," + << uint64_t(i_target) << "}; " + << "address: " << i_address << "; " + << "input modifying data: " << uint32_t(i_data) << "; " + << "input ChipOpModifyMode: " << i_modifyMode + << std::dec << std::endl; + return FAPI2_RC_SUCCESS; + } + + // variable_buffer isn't supported on PPE +#ifndef __PPE__ + /// + /// @brief Platform-level implementation of getRing() + /// Hardware procedures writers will not call this function. + /// @Tparam K template parameter, passed in target. + /// @param[in] i_target HW target to operate on. + /// @param[in] i_address Ring address to read from. + /// @param[out] o_data Buffer that holds ring data read from HW target. + /// @param[in] i_ringMode Ring operation mode. + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + template< TargetType K > + inline ReturnCode getRing(const Target& i_target, + const scanRingId_t i_address, + variable_buffer& o_data, + const RingMode i_ringMode) + { + o_data.setBit(0); + o_data.setBit(3); + std::cout << std::hex << " getRing " + << "target: {" << i_target.getType() << "," + << uint64_t(i_target) << "}; " + << "ring address: " << i_address << "; " + << "ring mode: " << i_ringMode << "; " + << "first element of output data: " << o_data()[0] + << std::endl; + + return FAPI2_RC_SUCCESS; + } + + /// @brief Platform-level implementation of putRing() + /// Hardware procedures writers will not call this function. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_address Ring address to write to. + /// @param[in] i_data Buffer that contains RS4 compressed ring data + /// to write into address + /// @param[in] i_ringMode Ring operation mode. + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K > + inline ReturnCode putRing(const Target& i_target, + const scanRingId_t i_address, + const variable_buffer& i_data, + const RingMode i_ringMode) + { + std::cout << std::hex << " putRing " + << "target: {" << i_target.getType() << "," + << uint64_t(i_target) << "}; " + << "address: " << i_address << "; " + << "ring mode: " << i_ringMode << "; " + << "first element of the input data: " << i_data()[0] + << std::endl; + + return FAPI2_RC_SUCCESS; + } + + /// @brief Platform-level implementation of modifyRing() + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_address Ring address to modify. + /// @param[in] i_data Buffer that contains RS4 compressed ring data + /// to be modified. + /// @param[in] i_modifyMode The modify mode (or/and/xor) + /// @param[in] i_ringMode Ring operation mode. + /// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + template< TargetType K > + inline ReturnCode modifyRing(const Target& i_target, + const scanRingId_t i_address, + const variable_buffer& i_data, + const ChipOpModifyMode i_modifyMode, + const RingMode i_ringMode) + { + std::cout << std::hex << " modifyRing " + << "target: {" << i_target.getType() << "," + << uint64_t(i_target) << "}; " + << "address: " << i_address << "; " + << "input ChipOpModifyMode: " << i_modifyMode << "; " + << "ring mode: " << i_ringMode << "; " + << "first element of the input data: " << i_data()[0] + << std::endl; + + return FAPI2_RC_SUCCESS; + } +#endif + +#ifdef FAPI_SUPPORT_MULTI_SCOM + /// @brief Performs a multiple SCOM operation + /// This interface performs multiple SCOM operations on a chip in the + /// order specified by the input MultiScom object. + /// See fapiMultiScom.H for details of how to populate the MultiScom + /// object with SCOM operations. + /// + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in,out] io_multiScomObj Reference to a MultiScom object, + /// pre-populated with SingleScomInfo entries + /// to perform multiple SCOMs on input target + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note This is a synchronous interface and would return after all the + /// SCOM operations are completed or on the first failed operation + /// + /// @note SCOMs will be performed in the order they were added to the + /// input MultiScom object + /// + /// @note In case of errors, the platform code is responsible to collect + /// and add all the required error info and FFDC into the error data + /// for debugging + /// + /// @note If the SCOM operations added are specific to a processor chip, + /// then the FSI Shift Engine configured in scatter-gather DMA mode + /// extension would be used to execute the SCOM operations in a + /// performance optimize mode. In this mode, the special + /// SCOM_BULK_READ_MODE and SCOM_BULK_WRITE_MODE operations are + /// supported that allow a large bulk of SCOM access (in multiple of + /// 64 bits) for targets that support auto-increment. The + /// SCOM_WRITE_UNDER_MASK operation is not supported in this mode + /// + /// @note If the SCOM operations added are specific to a memory buffer + /// chip, then the regular SCOM engine is used to execute the SCOM + /// operations. SCOM_WRITE_UNDER_MASK operation is supported in + /// this mode, but the special SCOM_BULK_READ_MODE and + /// SCOM_BULK_WRITE_MODE operations are not supported due to + /// hardware limitations. + /// + template< TargetType K > + fapi2::ReturnCode multiScom (const Target& i_target, + MultiScom& io_multiScomObj) + { + } +#endif + + // -------------------------------------------------------------------------- + // NOTE: + // Implement platform Spy access functions if platform supports them. + // -------------------------------------------------------------------------- + + // variable_buffer isn't supported on PPE +#ifndef __PPE__ + /// @brief Reads a spy from a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_spyId Id of the spy whose data to be read. + /// @param[out] o_data Buffer that holds data read from HW target. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note: The string version is only supported for cronus. + /// + /// The fapi design to support both FSP and cronus use of get and + /// put spy functions is dependant on the SPY names being expanded + /// to resemble a valid C identifier. This design places some + /// restrictions on the SPY names which can be used. + /// + /// 1. if the spy name contains a # procedure writers should replace + /// it with an __P__ for example - + /// + /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS + /// becomes + /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS + /// + /// 2. if the spy name has a number following a "." it must have an + /// underscore prepended to the number. + /// + /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY + /// becomes + /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY + /// + /// Example SPY name: + /// The hardware procedure should call the function like: + /// + /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS + /// + /// fapi2::ReturnCode rc = fapiGetSpy( targ, + /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data ); + /// + /// @note The ID is not in quotes the fapi code will handle adding + /// the quotes for the cronus environment + /// +#ifdef FAPI_SUPPORT_SPY_AS_ENUM + template< TargetType K > + inline ReturnCode getSpy(const Target& i_target, + const spyId_t i_spyId, + variable_buffer& o_data) + { + static_assert(K == 0, "implement getSpy (string)"); + return ~FAPI2_RC_SUCCESS; + } +#endif +#ifdef FAPI_SUPPORT_SPY_AS_STRING + template< TargetType K > + inline ReturnCode getSpy(const Target& i_target, + const char * const i_spyId, + variable_buffer& o_data) + { + static_assert(K == 0, "implement getSpy (string)"); + return ~FAPI2_RC_SUCCESS; + } +#endif + /// @brief Writes a spy on a chip. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_spyId Id of the spy to write data to. + /// @param[out] i_data Buffer that holds data to write into spy. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note: The string version is only supported for cronus. + /// + /// The fapi design to support both FSP and cronus use of get and + /// put spy functions is dependent on the SPY names being expanded + /// to resemble a valid C identifier. This design places some + /// restrictions on the SPY names which can be used. + /// + /// 1. if the spy name contains a # procedure writers should replace + /// is with an __P__ for example - + /// + /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS + /// becomes + /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS + /// + /// 2. if the spy name has a number following a "." it must have an + /// underscore prepended to the number. + /// + /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY + /// becomes + /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY + /// + /// Example SPY name: + /// The hardware procedure should call the function like: + /// + /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS + /// + /// fapi2::ReturnCode rc = fapiPutSpy( targ, + /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data ); + /// + /// @note The ID is not in quotes the fapi code will handle adding + /// the quotes for the cronus environment + /// +#ifdef FAPI_SUPPORT_SPY_AS_ENUM + template< TargetType K > + inline ReturnCode putSpy(const Target& i_target, + const spyId_t i_spyId, + variable_buffer& i_data) + { + static_assert(K == 0, "implement putSpy (enum)"); + return ~FAPI2_RC_SUCCESS; + } +#endif +#ifdef FAPI_SUPPORT_SPY_AS_STRING + template< TargetType K > + inline ReturnCode putSpy(const Target& i_target, + const char* const i_spyId, + variable_buffer& i_data) + { + static_assert(K == 0, "implement putSpy (string)"); + return ~FAPI2_RC_SUCCESS; + } +#endif + /// @brief Writes spy data into a buffer holding ring data image + /// This API is used by L2/L3 repair to put column repair data + /// into a ring buffer image. + /// @tparam K template parameter, passed in target. + /// @param[in] i_target Target to operate on. + /// @param[in] i_spyId Id of the spy. + /// @param[in] i_data Buffer that holds spy data to write into ring + /// image. + /// @param[out] o_data Buffer that holds updated ring image. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note: The string version is only supported for cronus. + /// + /// The fapi design to support both FSP and cronus use of get and + /// put spy functions is dependent on the SPY names being expanded + /// to resemble a valid C identifier. This design places some + /// restrictions on the SPY names which can be used. + /// + /// See fapiPutSpy for details on spy id specifics. + /// +#ifdef FAPI_SUPPORT_SPY_AS_ENUM + template< TargetType K > + inline ReturnCode putSpyImage(const Target& i_target, + const spyId_t i_spyId, + const variable_buffer& i_data, + variable_buffer& o_imageData) + { + static_assert(K == 0, "implement putSpyImage (enum)"); + return ~FAPI2_RC_SUCCESS; + } +#endif +#ifdef FAPI_SUPPORT_SPY_AS_STRING + template< TargetType K > + inline ReturnCode putSpyImage(const Target& i_target, + const char* const i_spyId, + const variable_buffer& i_data, + variable_buffer& o_imageData) + { + static_assert(K == 0, "implement putSpyImage (string)"); + return ~FAPI2_RC_SUCCESS; + } +#endif + /// @brief Reads spy data from a ring image buffer + /// @param[in] i_target Target to operate on + /// @param[in] i_spyId The spy's id + /// @param[out] o_data Buffer that holds data read from ring image. + /// @param[in] i_imageData Buffer that holds ring image to read data + /// from. + /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. + /// + /// @note: The string version is only supported for cronus. + /// + /// The fapi design to support both FSP and cronus use of get and + /// put spy functions is dependent on the SPY names being expanded + /// to resemble a valid C identifier. This design places some + /// restrictions on the SPY names which can be used. + /// + /// See fapiPutSpy for details on spy id specifics. + /// +#ifdef FAPI_SUPPORT_SPY_AS_ENUM + template< TargetType K > + inline ReturnCode getSpyImage(const Target& i_target, + const spyId_t i_spyId, + variable_buffer& o_data, + const variable_buffer& i_imageData) + { + static_assert(K == 0, "implement getSpyImage (enum)"); + return ~FAPI2_RC_SUCCESS; + } +#endif +#ifdef FAPI_SUPPORT_SPY_AS_STRING + template< TargetType K > + inline ReturnCode getSpyImage(const Target& i_target, + const char * const i_spyId, + variable_buffer& o_data, + const variable_buffer& i_imageData) + { + static_assert(K == 0, "implement getSpyImage (string)"); + return ~FAPI2_RC_SUCCESS; + } +#endif + +#endif // PPE + +}; + +#endif // _FAPI2_HWACCESS_H_ diff --git a/importtemp/fapi2/include/hw_access_def.H b/importtemp/fapi2/include/hw_access_def.H new file mode 100644 index 00000000..098efb8c --- /dev/null +++ b/importtemp/fapi2/include/hw_access_def.H @@ -0,0 +1,77 @@ +/* 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 hw_access_def.H +/// @brief Hardware access definitions +/// + +#ifndef FAPI2_HWACCESSDEF_H_ +#define FAPI2_HWACCESSDEF_H_ + +#include + +/// @cond +typedef uint64_t spyId_t; +typedef uint64_t scanRingId_t; +/// @endcond + +namespace fapi2 +{ + /// + /// @enum fapi2::ChipOpModifyMode + /// @brief Enumeration of modify modes used in HW access modify operations + /// + enum ChipOpModifyMode + { + CHIP_OP_MODIFY_MODE_OR = 1, ///< Modify or mode + CHIP_OP_MODIFY_MODE_AND = 2, ///< Modify and mode + CHIP_OP_MODIFY_MODE_XOR = 3, ///< Modify xor mode + }; + + /// + /// @enum fapi2::RingMode + /// @brief Enumeration of Ring access operation modes + /// This is a bitmap to allow the user to specify multiple modes. + /// + enum RingMode + { + RING_MODE_SET_PULSE = 0x00000001, ///< Set pulse + RING_MODE_NO_HEADER_CHECK = 0x00000002, ///< Dont' check header + // FUTURE_MODE = 0x00000004, + // FUTURE_MODE = 0x00000008, + }; + + /// @enum OpModes operational Mode Error Functions + enum OpModes + { + // These are bit-masks in case they need to be or'd together + NORMAL = 0x00, + IGNORE_HW_ERROR = 0x01, + DO_NOT_DO_WAKEUP = 0x02, + }; + +} + +#endif diff --git a/importtemp/fapi2/include/mvpd_access.H b/importtemp/fapi2/include/mvpd_access.H new file mode 100644 index 00000000..8288d8b8 --- /dev/null +++ b/importtemp/fapi2/include/mvpd_access.H @@ -0,0 +1,159 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: hwpf/fapi2/include/mvpd_access.H $ */ +/* */ +/* 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 */ + +/// +/// @file mvpd_access.H +/// +/// @brief Defines the Module VPD functions that platform must implement +/// + +#ifndef _FAPI2_MVPDACCESS_H_ +#define _FAPI2_MVPDACCESS_H_ + +#include +#include +#include + +namespace fapi2 +{ +enum MvpdRecord +{ + MVPD_RECORD_CRP0 = 0x00, + MVPD_RECORD_CP00 = 0x01, + MVPD_RECORD_VINI = 0x02, + MVPD_RECORD_LRP0 = 0x03, + MVPD_RECORD_LRP1 = 0x04, + MVPD_RECORD_LRP2 = 0x05, + MVPD_RECORD_LRP3 = 0x06, + MVPD_RECORD_LRP4 = 0x07, + MVPD_RECORD_LRP5 = 0x08, + MVPD_RECORD_LRP6 = 0x09, + MVPD_RECORD_LRP7 = 0x0a, + MVPD_RECORD_LRP8 = 0x0b, + MVPD_RECORD_LRP9 = 0x0c, + MVPD_RECORD_LRPA = 0x0d, + MVPD_RECORD_LRPB = 0x0e, + MVPD_RECORD_LRPC = 0x0f, + MVPD_RECORD_LRPD = 0x10, + MVPD_RECORD_LRPE = 0x11, + MVPD_RECORD_LWP0 = 0x12, + MVPD_RECORD_LWP1 = 0x13, + MVPD_RECORD_LWP2 = 0x14, + MVPD_RECORD_LWP3 = 0x15, + MVPD_RECORD_LWP4 = 0x16, + MVPD_RECORD_LWP5 = 0x17, + MVPD_RECORD_LWP6 = 0x18, + MVPD_RECORD_LWP7 = 0x19, + MVPD_RECORD_LWP8 = 0x1a, + MVPD_RECORD_LWP9 = 0x1b, + MVPD_RECORD_LWPA = 0x1c, + MVPD_RECORD_LWPB = 0x1d, + MVPD_RECORD_LWPC = 0x1e, + MVPD_RECORD_LWPD = 0x1f, + MVPD_RECORD_LWPE = 0x20, + MVPD_RECORD_VWML = 0x21, + MVPD_RECORD_MER0 = 0x22, +}; + +enum MvpdKeyword +{ + MVPD_KEYWORD_VD = 0x00, + MVPD_KEYWORD_ED = 0x01, + MVPD_KEYWORD_TE = 0x02, + MVPD_KEYWORD_DD = 0x03, + MVPD_KEYWORD_PDP = 0x04, + MVPD_KEYWORD_ST = 0x05, + MVPD_KEYWORD_DN = 0x06, + MVPD_KEYWORD_PG = 0x07, + MVPD_KEYWORD_PK = 0x08, + MVPD_KEYWORD_PDR = 0x09, + MVPD_KEYWORD_PDV = 0x0a, + MVPD_KEYWORD_PDH = 0x0b, + MVPD_KEYWORD_SB = 0x0c, + MVPD_KEYWORD_DR = 0x0d, + MVPD_KEYWORD_VZ = 0x0e, + MVPD_KEYWORD_CC = 0x0f, + MVPD_KEYWORD_CE = 0x10, + MVPD_KEYWORD_FN = 0x11, + MVPD_KEYWORD_PN = 0x12, + MVPD_KEYWORD_SN = 0x13, + MVPD_KEYWORD_PR = 0x14, + MVPD_KEYWORD_HE = 0x15, + MVPD_KEYWORD_CT = 0x16, + MVPD_KEYWORD_HW = 0x17, + MVPD_KEYWORD_PDM = 0x18, + MVPD_KEYWORD_IN = 0x19, + MVPD_KEYWORD_PD2 = 0x1a, + MVPD_KEYWORD_PD3 = 0x1b, + MVPD_KEYWORD_OC = 0x1c, + MVPD_KEYWORD_FO = 0x1d, + MVPD_KEYWORD_PDI = 0x1e, + MVPD_KEYWORD_PDG = 0x1f, + MVPD_KEYWORD_MK = 0x20, + MVPD_KEYWORD_PB = 0x21, + MVPD_KEYWORD_CH = 0x22, + MVPD_KEYWORD_IQ = 0x23, +}; + +/// +/// @brief Get Module VPD field. +/// +/// A Module VPD field is specified using a record and keyword enumerator +/// +/// Suggested way to call this routine is to call it once with a NULL buffer +/// pointer to to retrieve the size of the record, then allocate the proper +/// size of the buffer and call again. +/// +/// @param[in] i_record Record enumerator +/// @param[in] i_keyword Keyword enumerator +/// @param[in] i_target Reference to processor chip target for the record +/// @param[in] i_pBuffer Pointer to buffer where record will be stored. If +/// NULL then the size of record will be stored in +/// io_fieldSize +/// @param[in,out] io_fieldSize Size of i_pBuffer in bytes +/// +/// @return fapi2::ReturnCode. FAPI_RC_SUCCESS, or failure value. +/// +ReturnCode getMvpdField(const MvpdRecord i_record, + const MvpdKeyword i_keyword, + const Target &i_target, + uint8_t * const i_pBuffer, + uint32_t &io_fieldSize); + +/// +/// @brief Set Module VPD field. +/// +/// A Module VPD field is specified using a record and keyword enumerator +/// +/// @param[in] i_record Record enumerator +/// @param[in] i_keyword Keyword enumerator +/// @param[in] i_target Reference to processor chip target for the record +/// @param[in] i_pBuffer Pointer to buffer where data to set is stored +/// @param[in] i_fieldSize Size of i_pBuffer in bytes +/// +/// @return fapi2::ReturnCode. FAPI_RC_SUCCESS, or failure value. +/// +ReturnCode setMvpdField(const MvpdRecord i_record, + const MvpdKeyword i_keyword, + const Target &i_target, + const uint8_t * const i_pBuffer, + const uint32_t i_fieldSize); +} + +#endif diff --git a/importtemp/fapi2/include/plat_error_scope.H b/importtemp/fapi2/include/plat_error_scope.H new file mode 100644 index 00000000..ff4421dd --- /dev/null +++ b/importtemp/fapi2/include/plat_error_scope.H @@ -0,0 +1,64 @@ +/* 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 plat_error_scope.H + * @brief platform definitions which create a scope for automatic error handling + */ + +#ifndef __FAPI2_PLAT_ERROR_SCOPE__ +#define __FAPI2_PLAT_ERROR_SCOPE__ + +/// @cond +#define PLAT_FAPI_TRY_NO_TRACE( __operation__ ) \ + if ((fapi2::current_err = (__operation__)) != fapi2::FAPI2_RC_SUCCESS) \ + { \ + goto fapi_try_exit; \ + } + +#define PLAT_FAPI_TRY_TRACE( __operation__, ... ) \ + if ((fapi2::current_err = (__operation__)) != fapi2::FAPI2_RC_SUCCESS) \ + { \ + FAPI_ERR(__VA_ARGS__); \ + goto fapi_try_exit; \ + } + +/// +/// @brief Assert a conditional is true. +/// If it is not, the FFDC gathering function is called and the +/// trace is output as a FAPI error trace. +/// @param[in] __conditional__ the condition to assert +/// @param[in] __ffdc__ the FFDC gathering function +/// @param[in] ... varargs, as input to FAPI_ERR +/// +#define PLAT_FAPI_ASSERT( __conditional__, __ffdc__, ... ) \ + if (! (__conditional__)) \ + { \ + (__ffdc__).execute(); \ + FAPI_ERR(__VA_ARGS__); \ + goto fapi_try_exit; \ + } +/// @endcond + +#endif diff --git a/importtemp/fapi2/include/plat_hw_access.H b/importtemp/fapi2/include/plat_hw_access.H new file mode 100644 index 00000000..208ed759 --- /dev/null +++ b/importtemp/fapi2/include/plat_hw_access.H @@ -0,0 +1,39 @@ +/* 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 plat_hw_access.H +/// +/// @brief Platform hardware-access definitions +/// + +#ifndef _FAPI2_PLAT_HWACCESS_H_ +#define _FAPI2_PLAT_HWACCESS_H_ + +namespace fapi2 +{ + +} + +#endif // _FAPI2_PLAT_HWACCESS_H_ diff --git a/importtemp/fapi2/include/plat_target.H b/importtemp/fapi2/include/plat_target.H new file mode 100644 index 00000000..86c70465 --- /dev/null +++ b/importtemp/fapi2/include/plat_target.H @@ -0,0 +1,43 @@ +/* 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 plat_target.H + * @brief platform definitions for fapi2 targets + */ + +#ifndef __FAPI2_PLAT_TARGET__ +#define __FAPI2_PLAT_TARGET__ + +// +// Define what a platform handle looks like. For Hostboot, +// for example, this might be a void*. For the SBE, this +// will be a uint64_t ... +// +namespace fapi2 +{ + typedef uint64_t plat_target_handle_t; +} + +#endif diff --git a/importtemp/fapi2/include/plat_trace.H b/importtemp/fapi2/include/plat_trace.H new file mode 100644 index 00000000..9104e767 --- /dev/null +++ b/importtemp/fapi2/include/plat_trace.H @@ -0,0 +1,70 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: $ */ +/* */ +/* OpenPOWER HostBoot Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2011,2015 */ +/* [+] 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 plat_trace.H + * @brief Defines the FAPI2 trace macros. + * + * Note that platform code must provide the implementation. + * + * FAPI has provided a default implementation. Platform code must + * provide an alternate implementation if needed. + */ + +#ifndef FAPI2_PLATTRACE_H_ +#define FAPI2_PLATTRACE_H_ + +#include +#include + +// Why not a #define, why is this in the fapi2 namespace? +// To prevent problems with Cronus and the fapi1 definitions. +namespace fapi2 +{ + static const uint32_t MAX_ECMD_STRING_LEN = 64; +}; + +// Information traces (go into fast trace buffer that can wrap often) +#define FAPI_TRACE(_id_, _fmt_, _args_...) \ + printf("%s: %s:%d ", _id_, __func__, __LINE__); \ + printf(_fmt_, ##_args_); \ + printf("\n") + +#define FAPI_INF(_fmt_, _args_...) FAPI_TRACE("inf", _fmt_, ##_args_) + +// Important traces (go into slow trace buffer that should not wrap often) +#define FAPI_IMP(_fmt_, _args_...) FAPI_TRACE("imp", _fmt_, ##_args_) + +// Error traces (go into slow trace buffer that should not wrap often) +#define FAPI_ERR(_fmt_, _args_...) FAPI_TRACE("err", _fmt_, ##_args_) + +// Debug traces (go into fast trace buffer that can wrap often) +#define FAPI_DBG(_fmt_, _args_...) FAPI_TRACE("dbg", _fmt_, ##_args_) + +// Scan traces +#define FAPI_SCAN(_fmt_, _args_...) FAPI_TRACE("scan", _fmt_, ##_args_) + +#define FAPI_MFG(_fmt_, _args_...) FAPI_TRACE("mfg", _fmt_, ##_args_) + +#endif // FAPI2_PLATTRACE_H_ diff --git a/importtemp/fapi2/include/return_code.H b/importtemp/fapi2/include/return_code.H new file mode 100644 index 00000000..2f8f3460 --- /dev/null +++ b/importtemp/fapi2/include/return_code.H @@ -0,0 +1,114 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: hwpf/fapi2/include/return_code.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* EKB Project */ +/* */ +/* COPYRIGHT 2012,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 */ +/** + * @file return_code.H + * @brief definitions for fapi2 return codes + */ + +#ifndef __FAPI2_RETURN_CODE__ +#define __FAPI2_RETURN_CODE__ + +#include + +#ifndef FAPI2_NO_FFDC + #include +#endif + +namespace fapi2 +{ +/// +/// @brief Class representing a FAPI2 ReturnCode +/// +// Remove the inheritance relationship with FirstFailureData if +// the platform doesn't support FFDC. +#ifdef FAPI2_NO_FFDC +class ReturnCode +#else +class ReturnCode : public FirstFailureData +#endif +{ + public: + + /// + /// @brief Constructor. + /// @param[in] i_rc the rc to set + /// + ReturnCode(const uint64_t i_rc = FAPI2_RC_SUCCESS): + iv_rc(i_rc) + {}; + + /// + /// @brief integral type conversion function. Returns the error code + /// @return The error code + /// + inline operator uint64_t() const + { + return iv_rc; + } + + /// + /// @brief Returns true iff iv_rc == SUCCESS + /// @return true or false + /// + inline operator bool() const + { + return iv_rc != FAPI2_RC_SUCCESS; + } + + /// + /// @brief Assignement operator + /// + #ifdef DOXYGEN + inline ReturnCode& operator=(const uint64_t& rhs) + inline ReturnCode& operator=(const ReturnCodes& rhs) + #endif + + inline bool operator==(const uint64_t& rhs) const + { + return rhs == iv_rc; + } + + inline bool operator==(const ReturnCodes& rhs) const + { + return rhs == iv_rc; + } + + inline bool operator!=(const uint64_t& rhs) const + { + return rhs != iv_rc; + } + + inline bool operator!=(const ReturnCodes& rhs) const + { + return rhs != iv_rc; + } + + private: + uint64_t iv_rc; +}; + +/// This implementation assumes no exception handling and leverages thread-local +/// storage. For platforms without thread support, a global variable will +/// suffice for the error state. +extern thread_local ReturnCode current_err; /// the current error state +extern thread_local uint64_t pib_error_mask; /// the pib mask +extern thread_local uint64_t operational_state; /// the operational mode +} + +#endif diff --git a/importtemp/fapi2/include/return_code_defs.H b/importtemp/fapi2/include/return_code_defs.H new file mode 100644 index 00000000..404bfafa --- /dev/null +++ b/importtemp/fapi2/include/return_code_defs.H @@ -0,0 +1,114 @@ +/* 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 return_code.H + * @brief definitions for fapi2 return codes + */ + +#ifndef __FAPI2_RETURN_CODE_DEFS_ +#define __FAPI2_RETURN_CODE_DEFS_ + +#include + +/// +/// @brief Set HWP Error macro +/// +/// This macro should be used by a HWP to create an error. The ReturnCode's +/// internal return code is set and any error information in the Error XML file +/// is added to the ReturnCode +/// +#define FAPI_SET_HWP_ERROR(RC, ERROR) \ + RC._setHwpError(fapi2::ERROR); \ + ERROR##_CALL_FUNCS_TO_COLLECT_FFDC(RC); \ + ERROR##_CALL_FUNCS_TO_COLLECT_REG_FFDC(RC); \ + ERROR##_ADD_ERROR_INFO(RC) + +/// +/// @brief Add info to HWP Error macro +/// +/// This macro should be used by an FFDC HWP to add error information from an +/// Error XML file to an existing error. +/// +#define FAPI_ADD_INFO_TO_HWP_ERROR(RC, ERROR) \ + ERROR##_CALL_FUNCS_TO_COLLECT_FFDC(RC); \ + ERROR##_CALL_FUNCS_TO_COLLECT_REG_FFDC(RC); \ + ERROR##_ADD_ERROR_INFO(RC) + +namespace fapi2 +{ + /// + /// @brief Enumeration of return codes + /// + enum ReturnCodes + { + ///< Success + FAPI2_RC_SUCCESS = 0, + + // Flag bits indicating which code generated the error. + FAPI2_RC_FAPI2_MASK = 0x04000000, ///< FAPI2 mask + FAPI2_RC_PLAT_MASK = 0x02000000, ///< Platform mask + FAPI2_RC_HWP_MASK = 0x00000000, ///< HWP mask + + // + // FAPI generated return codes + // + + FAPI2_RC_INVALID_ATTR_GET = FAPI2_RC_FAPI2_MASK | 0x01, + ///< Initfile requested an attribute with an invalid attribute ID + + FAPI2_RC_INVALID_CHIP_EC_FEATURE_GET = FAPI2_RC_FAPI2_MASK | 0x02, + ///< HWP requested a chip EC feature with an invalid attribute ID + + FAPI2_RC_INVALID_MULTISCOM_LENGTH = FAPI2_RC_FAPI2_MASK | 0x03, + ///< Invalid multiscom parameters + + FAPI2_RC_INVALID_PARAMETER = FAPI2_RC_FAPI2_MASK | 0x04, + ///< Invalid parameters to a FAPI2 function + + FAPI2_RC_OVERFLOW = FAPI2_RC_FAPI2_MASK | 0x05, + ///< Overflow condition, typically a buffer operation + + FAPI2_RC_FALSE = FAPI2_RC_FAPI2_MASK | 0x06, + ///< The logical opposite of SUCCESS. Needed where procedures want + ///< a multi-bool type of operation (e.g., true, false, scom error) + + // + // PLAT generated return codes. Additional details may be contained in + // ReturnCode platData (this can only be looked at by PLAT code) + // + + FAPI2_RC_PLAT_ERR_SEE_DATA = FAPI2_RC_PLAT_MASK | 0x01, + ///< Generic platform error + + FAPI2_RC_PLAT_ERR_ADU_LOCKED = FAPI2_RC_PLAT_MASK | 0x02, + ///< Operation to AlterDisplay unit failed because it is locked + + FAPI2_RC_PLAT_NOT_SUPPORTED_AT_RUNTIME = FAPI2_RC_PLAT_MASK | 0x03, + ///< Operation not supported by HB runtime + }; + +} + +#endif diff --git a/importtemp/fapi2/include/target.H b/importtemp/fapi2/include/target.H new file mode 100644 index 00000000..1cd14451 --- /dev/null +++ b/importtemp/fapi2/include/target.H @@ -0,0 +1,171 @@ +/* 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 target.H + * @brief platform specializations for fapi2 targets + */ + +#ifndef __FAPI2_TARGET__ +#define __FAPI2_TARGET__ + +#include +#include +#include + +namespace fapi2 +{ + + /// + /// @brief Assignment Operator. + /// @param[in] i_right Reference to Target to assign from. + /// @return Reference to 'this' Target + /// + template + Target& Target::operator=(const Target& i_right) + { iv_handle = i_right.iv_handle; return *this; } + + /// + /// @brief Equality Comparison Operator + /// @param[in] i_right Reference to Target to compare. + /// @return bool. True if equal. + /// @note Platforms need to define this so that the physical + /// targets are determined to be equivilent rather than just the handles + /// + template + bool Target::operator==(const Target& i_right) const + { return i_right.iv_handle == iv_handle; } + + /// + /// @brief Inquality Comparison Operator + /// @param[in] i_right Reference to Target to compare. + /// @return bool. True if not equal. + /// @note Platforms need to define this so that the physical + /// targets are determined to be equivilent rather than just the handles + /// + template + bool Target::operator!=(const Target& i_right) const + { return i_right.iv_handle != iv_handle; } + + /// + /// @brief Get this target's immediate parent + /// @tparam T The type of the parent + /// @return Target a target representing the parent + /// + template + template + inline Target Target::getParent(void) const + { + // For testing + return Target(iv_handle); + } + + /// + /// @brief Get this target's children + /// @tparam T The type of the parent + /// @param[in] i_state The desired TargetState of the children + /// @return std::vector > a vector of present/functional + /// children + /// @warning The children of EX's (cores) are expected to be returned + /// in order. That is, core 0 is std::vector[0]. + /// + template + template< TargetType T> + inline std::vector > + Target::getChildren(const TargetState i_state) const + { + // To keep the compiler quiet about unused variables + static_cast(i_state); + // For testing + return {Target(), Target()}; + } + + /// + /// @brief Get the target at the other end of a bus - dimm included + /// @tparam T The type of the parent + /// @param[in] i_state The desired TargetState of the children + /// @return Target a target representing the thing on the other end + /// @note Can be easily changed to a vector if needed + /// + template + template + inline Target + Target::getOtherEnd(const TargetState i_state) const + { + // Implementation note: cast to a composite of + // bus types and the compiler will check if this is + // a good function at compile time + return Target(); + } + + + /// + /// @brief Return the string interpretation of this target + /// @tparam T The type of the target + /// @param[in] i_target Target + /// @param[in] i_buffer buffer to write in to + /// @param[in] i_bsize size of the buffer + /// @return void + /// @post The contents of the buffer is replaced with the string + /// representation of the target + /// + template< TargetType T > + inline void toString(const Target& i_target, char* i_buffer, size_t i_bsize) + { + snprintf(i_buffer, i_bsize, "Target 0x%lx/0x%x", i_target.get(), T); + } + + /// + /// @brief Return the string interpretation of this target + /// @tparam T The type of the target + /// @tparam B The type of the buffer + /// @param[in] A pointer to the Target + /// @param[in] i_buffer buffer to write in to + /// @param[in] i_bsize size of the buffer + /// @return void + /// @post The contents of the buffer is replaced with the string + /// representation of the target + /// + template< TargetType T > + inline void toString(const Target* i_target, char* i_buffer, size_t i_bsize) + { + snprintf(i_buffer, i_bsize, "Target 0x%lx/0x%x", i_target->get(), T); + } + + /// + /// @brief Get an enumerated target of a specific type + /// @tparam T The type of the target + /// @param[in] Ordinal representing the ordinal number of + /// the desired target + /// @return Target the target requested + /// + template + inline Target getTarget(uint64_t Ordinal) + { + // For testing + return Target(Ordinal); + } +} + +#endif diff --git a/importtemp/fapi2/include/target_states.H b/importtemp/fapi2/include/target_states.H new file mode 100644 index 00000000..bebd43d0 --- /dev/null +++ b/importtemp/fapi2/include/target_states.H @@ -0,0 +1,45 @@ +/* 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 target_states.H + * @brief common state for fapi2 targets + */ + +#ifndef __FAPI2_TARGET_STATES__ +#define __FAPI2_TARGET_STATES__ + +namespace fapi2 +{ + /// + /// @brief Enumeration of target state values (bitmask values) + /// + enum TargetState + { + TARGET_STATE_PRESENT = 0x00000001, + TARGET_STATE_FUNCTIONAL = 0x00000002, + }; +} + +#endif diff --git a/importtemp/fapi2/include/target_types.H b/importtemp/fapi2/include/target_types.H new file mode 100644 index 00000000..7fd959f5 --- /dev/null +++ b/importtemp/fapi2/include/target_types.H @@ -0,0 +1,82 @@ +/** + * @file target_types.H + * @brief definitions for fapi2 target types + */ + +#ifndef __FAPI2_TARGET_TYPES__ +#define __FAPI2_TARGET_TYPES__ + +/// FAPI namespace +namespace fapi2 +{ + /// + /// @enum fapi::TargetType + /// @brief Types, kinds, of targets + /// @note TYPE_NONE is used to represent empty/NULL targets in lists + /// or tables. TYPE_ALL is used to pass targets to methods which + /// can act generally on any type of target + /// + + /// Target Kind + enum TargetType + { + TARGET_TYPE_NONE = 0x00000000, ///< No type + TARGET_TYPE_SYSTEM = 0x00000001, ///< System type + TARGET_TYPE_DIMM = 0x00000002, ///< DIMM type + TARGET_TYPE_PROC_CHIP = 0x00000004, ///< Processor type + TARGET_TYPE_MEMBUF_CHIP = 0x00000008, ///< Membuf type + TARGET_TYPE_EX = 0x00000010, ///< EX - 2x Core, L2, L3 - can be deconfigured + TARGET_TYPE_MBA = 0x00000020, ///< MBA type + TARGET_TYPE_MCS = 0x00000040, ///< MCS type + TARGET_TYPE_XBUS = 0x00000080, ///< XBUS type + TARGET_TYPE_ABUS = 0x00000100, ///< ABUS type + TARGET_TYPE_L4 = 0x00000200, ///< L4 type + TARGET_TYPE_CORE = 0x00000400, ///< Core - 4x threads(?) - can be deconfigured + TARGET_TYPE_EQ = 0x00000800, ///< EQ - 4x core, 2x L2, 2x L3 - can be deconfigured + TARGET_TYPE_MCA = 0x00001000, ///< MCA type + TARGET_TYPE_MCBIST = 0x00002000, ///< MCBIST type + TARGET_TYPE_MI = 0x00004000, ///< MI Memory Interface (Cumulus) + TARGET_TYPE_CAPP = 0x00008000, ///< CAPP target + TARGET_TYPE_DMI = 0x00010000, ///< DMI type + TARGET_TYPE_OBUS = 0x00020000, ///< OBUS type + TARGET_TYPE_NV = 0x00040000, ///< NV bus type + TARGET_TYPE_SBE = 0x00080000, ///< SBE type + TARGET_TYPE_PPE = 0x00100000, ///< PPE type + TARGET_TYPE_PERV = 0x00200000, ///< Pervasive type + TARGET_TYPE_PEC = 0x00400000, ///< PEC type + TARGET_TYPE_PHB = 0x00800000, ///< PHB type + + TARGET_TYPE_ALL = 0xFFFFFFFF, ///< Any/All types + + // Mappings to target types found in the error xml files + TARGET_TYPE_EX_CHIPLET = TARGET_TYPE_EX, + TARGET_TYPE_MBA_CHIPLET = TARGET_TYPE_MBA, + TARGET_TYPE_MCS_CHIPLET = TARGET_TYPE_MCS, + TARGET_TYPE_XBUS_ENDPOINT = TARGET_TYPE_XBUS, + TARGET_TYPE_ABUS_ENDPOINT = TARGET_TYPE_ABUS, + }; + + /// @cond + constexpr TargetType operator|(TargetType x, TargetType y) + { + return static_cast(static_cast(x) | + static_cast(y)); + } + + template + class bitCount { + public: + // Don't use enums, too hard to compare + static const uint8_t count = bitCount<(V >> 1)>::count + (V & 1); + }; + + template<> + class bitCount<0> { + public: + static const uint8_t count = 0; + }; + /// @endcond + +} + +#endif diff --git a/importtemp/fapi2/include/utils.H b/importtemp/fapi2/include/utils.H new file mode 100644 index 00000000..28a70a06 --- /dev/null +++ b/importtemp/fapi2/include/utils.H @@ -0,0 +1,91 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: hwpf/fapi2/include/utils.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* EKB Project */ +/* */ +/* COPYRIGHT 2011,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 */ +/** + * @file utils.H + * @brief Defines common fapi2 utilities + */ + +#ifndef FAPI2_UTILS_H_ +#define FAPI2_UTILS_H_ + +#include +#include +#include + +namespace fapi2 +{ +/// +/// @brief Log an error. +/// +/// @param[in,out] io_rc Reference to ReturnCode (Any references to data and error +/// target are removed and rc value is set to success after +/// function ends.) +/// @param[in] i_sev Fapi error log severity defaulted to unrecoverable +/// @param[in] i_unitTestError - flag to log error which does not cause a unit +/// test to fail. +/// +/// @note This function is called from the ffdc collection classes and no longer +/// needs to be called directly. +/// @note Implemented by platform code +/// +void logError( + fapi2::ReturnCode & io_rc, + fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE, + bool i_unitTestError = false ); + +/// +/// @brief Delay this thread. Hostboot will use the nanoseconds parameter +/// and make a syscall to nanosleep. While in the syscall, the hostboot +/// kernel will continue to consume CPU cycles as it looks for a runnable +/// task. When the delay time expires, the task becomes runnable and will soon +/// return from the syscall. Callers of delay() in the hostboot environment +/// will likely have to know the mHz clock speed they are running on and +/// compute a non-zero value for i_nanoSeconds. +/// +/// On the FSP, it was sometimes acceptable to just provide zero for the +/// sleep delay time, causing the task to yield its time slice. By the +/// time the calling task could run again, it was pretty certain enough +/// host cycles had past. This is probably not acceptable in +/// the hostboot environment. Callers should calculate and provide a +/// sleep value in nanoseconds relative to host clock speed. +/// +/// On FSP when VBU is the target, then the i_simCycles parameter will be +/// used instead. The FSP needs to use the simdispatcher client/server +/// API and issue a command to the awan to advance the simulation the +/// specified number of cycles. +/// +/// @param[in] i_nanoSeconds nanoseconds to sleep +/// @param[in] i_simCycles count of Awan cycles to advance +/// @param[in] i_fixed Determination, for DFT, if this time is +/// fixed or not. Defaults to non-fixed +/// +/// @return ReturnCode. Zero on success, else platform specified error. +/// +ReturnCode delay(uint64_t i_nanoSeconds, uint64_t i_simCycles, + bool i_fixed = false); + +/// +/// @brief Assert a condition, and halt +/// +/// @param[in] a boolean representing the assertion +/// +void Assert(bool i_expression); +}; + +#endif // FAPI2_UTILS_H_ diff --git a/importtemp/fapi2/include/variable_buffer.H b/importtemp/fapi2/include/variable_buffer.H new file mode 100644 index 00000000..b1739be9 --- /dev/null +++ b/importtemp/fapi2/include/variable_buffer.H @@ -0,0 +1,1198 @@ +/* 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 variable_buffer.H + * @brief definitions for fapi2 variable length buffers + */ + +#ifndef __FAPI2_VARIABLE_BUFFER__ +#define __FAPI2_VARIABLE_BUFFER__ + +#include +#include +#include +#include + +namespace fapi2 +{ + /// @brief Get a 32 bit mask quickly + // This is one of the main reasons we static_assert in the ctor's + // to ensure the unit_type is 32 bits. + inline uint32_t fast_mask32(int32_t i_pos, int32_t i_len) + { + // generates an arbitrary 32-bit mask using two operations, not too shabby + + static const uint32_t l_mask32[] = { + 0x00000000, + 0x80000000, 0xC0000000, 0xE0000000, 0xF0000000, + 0xF8000000, 0xFC000000, 0xFE000000, 0xFF000000, + 0xFF800000, 0xFFC00000, 0xFFE00000, 0xFFF00000, + 0xFFF80000, 0xFFFC0000, 0xFFFE0000, 0xFFFF0000, + 0xFFFF8000, 0xFFFFC000, 0xFFFFE000, 0xFFFFF000, + 0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, 0xFFFFFF00, + 0xFFFFFF80, 0xFFFFFFC0, 0xFFFFFFE0, 0xFFFFFFF0, + 0xFFFFFFF8, 0xFFFFFFFC, 0xFFFFFFFE, 0xFFFFFFFF, + }; + return l_mask32[i_len] >> i_pos; + } + + // + // General set a series of bits in the buffer. + // + + /// + /// @cond + /// @brief Internal bit inserting method. + /// @tparam unit_type The type of a unit of the arrays + /// @tparam bits_type The type of the bit counting values + /// @param[in] i_source The incoming data + /// @param[in] i_source_length The length in bits of the incoming data + /// @param[in] i_target The outgoing data + /// @param[in] i_target_length The length in bits of the outgoing data + /// @param[in] i_source_start_bit The starting bit location in the + /// incoming data + /// @param[in] i_target_start_bit The starting bit position in this + /// @param[in] i_length The length, in bits, the user wants copied. + /// + template + inline fapi2::ReturnCodes _insert(const unit_type* i_source, + bits_type i_source_length, + output_type* i_target, + bits_type i_target_length, + bits_type i_source_start_bit, + bits_type i_target_start_bit, + bits_type i_length) + { + const bits_type bits_per_input_unit = parameterTraits::bit_length(); + const bits_type bits_per_output_unit =parameterTraits::bit_length(); + + // targetStart is defaulted to the sizeof(target) - (sizeof(source) - i_source_start_bit) + // which makes this act like insert from right + if (i_target_start_bit == static_cast(~0)) + { + i_target_start_bit = (i_target_length - (i_source_length - i_source_start_bit)); + } + + // len defaults to (sizeof(OT) * 8) - i_source_start_bit + if (i_length == static_cast(~0)) + { + i_length = i_source_length - i_source_start_bit; + } + + // Check for overflow + if ((i_length + i_target_start_bit > i_target_length) || + (i_length + i_source_start_bit > i_source_length)) + { + return fapi2::FAPI2_RC_OVERFLOW; + } + + do + { + const bits_type src_idx = i_source_start_bit / bits_per_input_unit; + const bits_type trg_idx = i_target_start_bit / bits_per_output_unit; + + // "slop" = unaligned bits + const bits_type src_slop = i_source_start_bit % bits_per_input_unit; + const bits_type trg_slop = i_target_start_bit % bits_per_output_unit; + + // "cnt" = largest number of bits to be moved each pass + bits_type cnt = std::min(i_length, bits_per_input_unit); + cnt = std::min(cnt, bits_per_input_unit - src_slop); + cnt = std::min(cnt, bits_per_output_unit - trg_slop); + + // generate the source mask only once + bits_type mask = fast_mask32(src_slop, cnt); + + // read the source bits only once + bits_type src_bits = i_source[src_idx] & mask; + + // "shift" = amount of shifting needed for target alignment + int32_t shift = trg_slop - src_slop; + + if (shift < 0) + { + src_bits <<= -shift; + mask <<= -shift; + } + else + { + src_bits >>= shift; + mask >>= shift; + } + + // clear source '0' bits in the target + i_target[trg_idx] &= ~mask; + + // set source '1' bits in the target + i_target[trg_idx] |= src_bits; + + i_source_start_bit += cnt; + i_target_start_bit += cnt; + + i_length -= cnt; + + } while (0 < i_length); + + return fapi2::FAPI2_RC_SUCCESS; + } + /// @endcond + + /// @brief Class representing a FAPI variable_buffer. + /// @remark Variable buffers are buffers which can be variable in length + /// (and "odd sized.") These best represent the FAPI 1.X ecmdDataBuffer, + /// however they are implemented using the same template techniques + /// as the new fapi::buffer. + /// @note Variable buffers are not (presently) declared as std::bitset + /// as bitsets' size is fixed at runtime. It is not clear if this is + /// acceptable for variable_buffers at this time. + /// @note Variable buffers are implemented as a std::vecor of uint32_t + /// as this keeps simple compatibility with ecmdDataBuffers. Cronus (at + //least) need to interwork the two. + class variable_buffer + { + + public: + + /// Shortcut typedef to get to our traits class + typedef typename bufferTraits::bits_type bits_type; + /// Shortcut typedef to get to our traits class + typedef typename bufferTraits::unit_type unit_type; + + /// + /// @brief Variable buffer constructor + /// @param[in] i_value number of *bits* (sizeof(uint_type) * 8) + /// needed. + inline variable_buffer(bits_type i_value = 0): + iv_data(_vector_size(i_value)), + iv_perceived_bit_length(i_value) + { + static_assert(std::is_same::value, + "code currently needs unit_type to be a unit32_t"); + } + + /// + /// @brief Variable buffer list constructor + /// @param[in] i_value an initializer list to initialize the container. + /// @warning Input data is assumed to be right-aligned and must be 32 bits + /// + inline variable_buffer(const std::initializer_list& i_value): + iv_data(i_value), + iv_perceived_bit_length(i_value.size() * sizeof(unit_type) * 8) + { + static_assert(std::is_same::value, + "code currently needs unit_type to be a unit32_t"); + } + + /// + /// @brief Variable buffer copy constructor + /// @param[in] i_buffer the buffer to copy from + /// + inline variable_buffer(const variable_buffer& i_buffer) + { + iv_perceived_bit_length = i_buffer.iv_perceived_bit_length; + iv_data = i_buffer.iv_data; + } + + /// + /// @brief Variable buffer move constructor + /// @param[in] i_buffer the buffer to move + /// + inline variable_buffer(variable_buffer&& i_buffer) + { + iv_perceived_bit_length = i_buffer.iv_perceived_bit_length; + i_buffer.iv_perceived_bit_length = 0; + iv_data = std::move(i_buffer.iv_data); + } + + /// + /// @brief Variable buffer array constructor + /// @param[in] i_value a uint32_t array to initialize the container. + /// @param[in] i_length the length of the array in 32-bit words + /// @param[in] i_bit_length the length of the resulting buffer in bits. + /// @warning This assumes the underlying container of a variable_buffer + /// is a uint32_t - which it is. + /// @note To use this constructor given an ecmdDataBuffer, you would + /// ecmd.memCopyOut( buffer, ... ); + /// variable_buffer( buffer, ecmd.getCapacity(), ecmd.getBitLength()); + /// + inline variable_buffer(const uint32_t* i_value, const uint32_t i_length, + const uint32_t i_bit_length): + iv_perceived_bit_length(i_bit_length) + { + static_assert(std::is_same::value, + "code currently needs unit_type to be a unit32_t"); + + // Copy the array in to our vector. + iv_data.insert(iv_data.end(), i_value, &i_value[i_length]); + } + + +#if !defined(DOXYGEN) && defined(FAPI2_DEBUG) + /// @brief Print the contents of the buffer to stdout + inline void print(void) const + { bufferTraits::print(iv_data); } +#endif + + /// + /// @brief Get the contents of the buffer + /// @return The contents of the buffer + /// + inline operator bits_container() const { return iv_data; } + + /// + /// @brief Get the contents of the buffer + /// @return The contents of the buffer + /// + inline operator bits_container&() { return iv_data; } + + /// + /// @brief Get the contents of the buffer + /// @return The contents of the buffer + /// + inline bits_container& operator()(void) { return iv_data; } + + /// + /// @brief Get the contents of the buffer + /// @return Reference to the contents of the buffer + /// + inline const bits_container& operator()(void) const { 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 + /// + template< typename OT> + inline fapi2::ReturnCodes set(OT i_value, const bits_type i_offset = 0) + { + // Compile time check to make sure OT is integral + static_assert( std::is_integral::value, + "Input must be an integral type" ); + + const uint32_t length = bufferTraits:: template size(iv_data); + static const bits_type bits_in_value = parameterTraits::bit_length(); + const bits_type bit_length = bufferTraits::bit_length(iv_data); + + if ((i_offset + bits_in_value) >= iv_perceived_bit_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 (doesn't use fastmask as OT isn't always 32 bits) + if (((i_offset + 1) == length) && (bit_length % bits_in_value)) { + i_value &= parameterTraits::mask() << ((bits_in_value * length) - bit_length); + } + + parameterTraits::template write_element(bufferTraits::get_address(iv_data), i_value, i_offset); + return FAPI2_RC_SUCCESS; + } + + /// + /// @brief Get an OT of data from buffer + /// @tparam OT the type of the data to get + /// @param[in] i_offset Start OT (start word, for example) in buffer + /// - defaults to 0 (will by default write the left most element) + /// @return OT + /// @note uint8_t b = get(N) <- gets the N'th left byte from the buffer + /// + template< typename OT> + inline OT get(const bits_type i_offset = 0); + + /// @name Bit/Word Manipulation Functions + ///@{ + + /// + /// @brief Return the length of the buffer in bits + /// @return Length in bits + /// + inline uint32_t getBitLength(void) const + { return iv_perceived_bit_length; } + + /// + /// @brief Return the length of the buffer in OT units + /// @return Length in OT units rounded up + /// @tparam OT the type to get the length of. For example, if one + /// wanted the length in double words, OT would be uint64_t + /// (getLength().) Similarly, to get the length in words, + /// getLength(). + /// + template< typename OT > + inline uint32_t getLength(void) const + { + static const uint32_t bits_in_ot = sizeof(OT) * 8; + return (getBitLength() + (bits_in_ot - 1)) / bits_in_ot; + } + + /// + /// @brief Set a bit in buffer + /// @tparam SB Start bit in buffer to clear. + /// @tparam L Number of consecutive bits from start bit to + /// clear + /// @return FAPI2_RC_SUCCESS on success + inline fapi2::ReturnCodes setBit( const bits_type SB, bits_type L = 1) + { + + ReturnCodes rc; + // make sure we stay within our container + assert((L > 0) && ((SB + L) <= this->iv_perceived_bit_length) ); + + uint32_t mask = 0; + + // last bit to check + bits_type EB = SB + L -1; + + // index where first bit to check is located + bits_type start_index = SB/bits_per_unit; + + // index where last bit is located + bits_type end_index = EB/bits_per_unit; + + if( start_index == end_index ) + { + // normalize our SB to be within a unit + bits_type TempSB = SB - (start_index*bits_per_unit); + + // grab a mask from SB for L number of bits. + mask = fast_mask32(TempSB, L); + + iv_data[start_index] |= mask; + + rc = FAPI2_RC_SUCCESS; + + } + else + { + // the bits span more than one internal unit, need to break + // it up to process it. + + // make TempSB point to the start of the next unit, adjust the + // length and go again, process the bits in the previous index + // when we get back. + bits_type TempSB = (start_index + 1) * bits_per_unit; + bits_type TempL = EB - TempSB + 1; + + rc = this->setBit( TempSB, TempL ); + + if(rc == FAPI2_RC_SUCCESS) + { + // now check the bits in the previous index up to the next index. + // normalize our SB to be within a unit + TempSB = SB - (start_index*bits_per_unit); + + // get a mask for the new SB location to the end of this unit. + mask = fast_mask32(TempSB, L-TempL); + + // merge theses bits with the others. + iv_data[start_index] |= mask; + } + + } + + return rc; + } + + /// + /// @brief Clear a bit in buffer + /// @tparam SB Start bit in buffer to clear. + /// @tparam L Number of consecutive bits from start bit to + /// clear + /// @return FAPI2_RC_SUCCESS on success + /// @note Asserting that all the parameters are known at + /// compile time so this can be templated only. If that is not + /// the case we can add a function parameter version. + /// + inline fapi2::ReturnCodes clearBit(bits_type SB, bits_type L = 0) + { + ReturnCodes rc = invert().setBit(SB,L); + + invert(); + + return rc; + } + + /// + /// @brief Invert bit + /// @tparam SB Start bit in buffer to invert. + /// @tparam L Number of consecutive bits from start bit to + /// invert, defaults to 1 + /// @return FAPI2_RC_SUCCESS on success + /// @note Asserting that all the parameters are known at + /// compile time so this can be templated only. If that is not + /// the case we can add a function parameter version. + /// + template< bits_type SB, bits_type L = 1 > + inline fapi2::ReturnCodes flipBit(void); + + /// + /// @brief Get the value of a bit in the buffer + /// @tparam B Bit in buffer to get. + /// @return true/1 if bit is on, false/0 if bit is off + /// @note Asserting that all the parameters are known at + /// compile time so this can be templated only. If that is not + /// the case we can add a function parameter version. + /// + template< bits_type B > + inline bool getBit(void) const + { + const bits_type index = B / bits_per_unit; + const unit_type mask = unit_type(1) << + ((bits_per_unit - 1) - (B - (index * bits_per_unit))); + return iv_data[index] & mask; + } + + /// + /// @brief Test if multiple bits are set + /// @param SB Start bit in buffer to test. + /// @param L Number of consecutive bits from start bit to + /// test, defaults to 1 + /// @return true if all bits in range are set - false if any + /// bit is clear + /// @note Example: fapi2::buffer().isBitSet(4,3); + inline bool isBitSet( bits_type SB, bits_type L = 1 ) const + { + // make sure we stay within our container + assert( ((L > 0) && ((SB + L) <= this->iv_perceived_bit_length)) ); + + bool is_set = false; + uint32_t mask = 0; + + // last bit to check + bits_type EB = SB + L - 1; + + // index where first bit to check is located + bits_type start_index = SB/bits_per_unit; + + // index where last bit is located + bits_type end_index = EB/bits_per_unit; + + if( start_index == end_index ) + { + // normalize our SB to be within a unit + bits_type TempSB = SB - (start_index*bits_per_unit); + + // grab a mask from SB for L number of bits. + mask = fast_mask32(TempSB, L); + + is_set = + (( iv_data[start_index] & mask) == mask ) ? true : false; + + } + else + { + // the bits span more than one internal unit, need to break + // it up to process it. + + // make TempSB point to the start of the next unit, adjust the + // length and go again, process the bits in the previous index + // when we get back. + bits_type TempSB = (start_index + 1) * bits_per_unit; + bits_type TempL = EB - TempSB + 1; + + is_set = this->isBitSet( TempSB, TempL ); + + // now check the bits in the previous index up to the next index. + // normalize our SB to be within a unit + TempSB = SB - (start_index*bits_per_unit); + + // get a mask for the new SB location to the end of this unit. + mask = fast_mask32(TempSB, L-TempL); + + // test these bits against the others.. + is_set &= + (( iv_data[start_index] & mask) == mask ) ? true : false; + + } + + return is_set; + } + + /// + /// @brief Test if multiple bits are clear + /// @param SB Start bit in buffer to test. + /// @param L Number of consecutive bits from start bit to + /// test, defaults to 1 + /// @return true if bit is clear - false if bit is set + /// + inline bool isBitClear( bits_type SB, bits_type L =1 ) const + { + variable_buffer l_buf = *this; + + return l_buf.invert().isBitSet(SB,L); + } + + /// + /// @brief Count number of bits set in a range + /// @tparam SB Start bit in buffer to test. + /// @tparam L Number of consecutive bits from start bit to + /// test, defaults to 1 + /// @note Asserting that all the parameters are known at + /// compile time so this can be templated only. If that is not + /// the case we can add a function parameter version. + /// @return Number of bits set in range + /// + template< bits_type SB, bits_type L = 1 > + inline bits_type getNumBitsSet(void) const; + + /// + /// @brief Set and entire buffer to X's + /// @tparam X {0,1} depending if you want to clear (0) + /// or fill (1) a buffer + /// @return variable_buffer&, Useful for method chaining + /// + template< uint8_t X > + inline variable_buffer& flush(void) + { + static_assert( (X == 1) || (X == 0), "bad argument to flush" ); + (0 == X) ? bufferTraits::clear(iv_data) : bufferTraits::set(iv_data); + return *this; + } + + /// + /// @brief Invert entire buffer + /// @return variable_buffer&, Useful for method chaining + /// + inline variable_buffer& invert(void) + { bufferTraits::invert(iv_data); return *this; } + + ///@} + + /// @name Buffer Manipulation Functions + ///@{ + + /// + /// @brief Shift a buffer left a defined number of bits, from a start bit + /// @param[in] number of bits to shift + /// @param[in] offset from 0 to start shift, defaults to ~0 (see operator<<()) + /// @note an offset of ~(0) implies "end of the buffer" + /// @warning there is no shiftLeftandResize - resizing the buffer is left to + /// the caller to alight the operations with integral buffers. + /// @return FAPI2_RC_SUCCESS on success + /// + inline ReturnCodes shiftLeft(bits_type i_shiftNum, bits_type i_offset = ~0); + + /// + /// @brief Shift a buffer right a defined number of bits, from a start bit + /// @param[in] number of bits to shift + /// @param[in] offset from 0 to start shift, defaults to 0 (see operator>>()) + /// @warning there is no shiftRightandResize - resizing the buffer is left to + /// the caller to alight the operations with integral buffers. + /// @return FAPI2_RC_SUCCESS on success + /// + inline ReturnCodes shiftRight(bits_type i_shiftNum, bits_type i_offset = 0); + + /// + /// @brief move operator=() + /// @note To use: new_buffer = std::move(old_buffer). old_buffer will be + /// destroyed and no copy will be made (moved) + /// + inline variable_buffer& operator=(variable_buffer&& other) + { + iv_perceived_bit_length = other.iv_perceived_bit_length; + other.iv_perceived_bit_length = 0; + iv_data = std::move(other.iv_data); + return *this; + } + + /// + /// @brief operator=() + /// + inline variable_buffer& operator=(const variable_buffer& other) + { + iv_perceived_bit_length = other.iv_perceived_bit_length; + iv_data = other.iv_data; + return *this; + } + + /// + /// @brief operator>>() + /// + inline variable_buffer& operator>>(bits_type i_shiftnum) + { + // This is just a right shift from the begining of the buffer + // Why void? Well, there's no place to return the return + // code and in reality the only problem which can arise + // is the offset is out of bounds. But since we're hard-wiring it + // to 0, it can't be out of bounds. So there's no real problem + // which can arise here. + static_cast(shiftRight(i_shiftnum)); + return *this; + } + + /// + /// @brief operator<<() + /// + inline variable_buffer& operator<<(bits_type i_shiftnum) + { + // This is just a left shift from the end of the buffer + // Why void? Well, there's no place to return the return + // code and in reality the only problem which can arise + // is the offset is out of bounds. But since we're hard-wiring it + // to 0, it can't be out of bounds. So there's no real problem + // which can arise here. + static_cast(shiftLeft(i_shiftnum)); + return *this; + } + + + /// + /// @brief operator+() + /// @param[in] A variable_buffer to append to this + /// + inline variable_buffer& operator+(const variable_buffer& rhs) + { + iv_perceived_bit_length += rhs.iv_perceived_bit_length; + iv_data.insert(iv_data.end(), rhs.iv_data.begin(), rhs.iv_data.end()); + return *this; + } + + /// + /// @brief operator+() + /// @param[in] A number of bits to add to this buffer + /// + inline variable_buffer& operator+(const bits_type& rhs) + { + if (rhs != 0) + { + iv_perceived_bit_length += rhs; + iv_data.resize(_vector_size(iv_perceived_bit_length)); + } + return *this; + } + + /// + /// @brief resize() + /// @param[in] Desired resulting size of the buffer, in bits + /// + inline variable_buffer& resize(const bits_type& rhs) + { + return operator+(rhs - iv_perceived_bit_length); + } + + /// + /// @brief operator+=() + /// +#ifdef DOXYGEN + inline variable_buffer& operator+=(const T& rhs); +#endif + + /// + /// @brief operator|=() + /// +#ifdef DOXYGEN + inline variable_buffer& operator|=(const T& rhs); +#endif + + /// + /// @brief operator&=() + /// +#ifdef DOXYGEN + inline variable_buffer& operator&=(const T& rhs); +#endif + + /// + /// @brief operator|() + /// +#ifdef DOXYGEN + inline variable_buffer& operator|(const T& rhs); +#endif + + /// + /// @brief operator&() + /// +#ifdef DOXYGEN + inline variable_buffer& operator&(const T& rhs); +#endif + + /// + /// @brief operator^=() + /// +#ifdef DOXYGEN + inline variable_buffer& operator^=(const T& rhs); +#endif + + /// + /// @brief Get a pointer to the buffer bits + /// @return Pointer to the buffer itself + /// + inline unit_type* pointer(void) { return &(iv_data[0]); } + + /// + /// @brief operator!=() + /// + inline bool operator!=(const variable_buffer& rhs) const + { return ! operator==(rhs); } + + /// + /// @brief operator==() + /// @return true if and only if lhs == rhs + /// + inline bool operator==(const variable_buffer& rhs) const + { + if (&iv_data == &rhs.iv_data) + { + return true; + } + + return (iv_data == rhs.iv_data) && + (iv_perceived_bit_length == rhs.iv_perceived_bit_length); + } + + /// + /// @brief Copy part of an element into the DataBuffer + /// @param[in] i_data OT value to copy into DataBuffer + /// @param[in] i_targetStart The position in this where the copy starts + /// @param[in] i_len How many bits to copy + /// @param[in] i_sourceStart The start positon in i_data, defaults to 0 + /// @return FAPI2_RC_SUCCESS on success, FAPi2_RC_OVERFLOW otherwise + /// + template + inline fapi2::ReturnCodes insert(const OT& i_data, + bits_type i_targetStart = 0, + bits_type i_len = ~0, + bits_type i_sourceStart = 0) + { + // _insert likes 32-bit sources. So lets make our source 32 bits. + uint32_t l_source = static_cast(i_data); + bits_type l_sourceStart = i_sourceStart + + parameterTraits::bit_length() - + parameterTraits::bit_length(); + + return _insert(&l_source, parameterTraits::bit_length(), + &(iv_data[0]), getBitLength(), + l_sourceStart, i_targetStart, i_len); + } + + /// + /// @brief Copy in a right aligned (decimal) element + /// @param[in] i_data the incoming data + /// - data is taken right aligned + /// @param[in] i_targetStart The starting bit position in this + /// - Defaults to 0 + /// @param[in] i_len The length, in bits, the user wants copied. + /// - Defaults to all of the bits in the source which fit + /// @return FAPI2_RC_SUCCESS on success, FAPI2_RC_OVERFLOW otherwise + /// + template + inline fapi2::ReturnCodes insertFromRight(const OT& i_data, + bits_type i_targetStart = 0, + bits_type i_len = ~0) + { + return _insertFromRight(i_data, parameterTraits::bit_length(), + i_targetStart, i_len); + } + + /// + /// @brief Copy data from this buffer into an OT + /// @tparam OT the type of the outgoing data + /// @param[out] o_out OT to copy into - data is placed left aligned + /// @param[in] i_start Start bit to copy from - defaults to 0 + /// @param[in] i_len Length of bits to copy - defaults to filling o_out + /// @return FAPI2_RC_SUCCESS on success + /// @warning fapi2::extract() does not extend the argument buffer. The caller + /// should adjust the size proir to calling extract() (resize()). This is to + /// keep the semantics the same with integral buffers, which can't be resized. + /// + // Generic extract. Extract is an insert with the arguments reversed. + template< typename OT > + inline fapi2::ReturnCodes extract(OT& o_out, + bits_type i_start = 0, + bits_type i_len = ~0) const + { + // If thy didn't pass an i_len, assume they want all the data + // which will fit. + if (i_len == static_cast(~0)) + { + i_len = std::min(getBitLength(), + parameterTraits::bit_length()); + } + + if (i_len > getBitLength()) + { + return FAPI2_RC_INVALID_PARAMETER; + } + + // _insert likes 32-bit targets. So lets make our target 32 bits. + uint32_t l_data = static_cast(o_out); + + ReturnCodes rc; + if ((rc = _insert((container_unit*)&iv_data[0], getBitLength(), + &l_data, + parameterTraits::bit_length(), + i_start, 0U, i_len)) != FAPI2_RC_SUCCESS) + { + return rc; + } + + // Shift back to the original bit width. + o_out = l_data >> (parameterTraits::bit_length() - + parameterTraits::bit_length()); + return FAPI2_RC_SUCCESS; + } + + /// + /// @brief Copy data from this buffer into an OT and right justify + /// @tparam OT the type of the outgoing data + /// @param[out] o_out OT to copy into - data is placed right aligned + /// @param[in] i_start Start bit to copy from - defaults to 0 + /// @param[in] i_len Length of bits to copy - defaults to filling o_out + /// @return FAPI2_RC_SUCCESS on success + /// + // Extract is an insert with the arguments reversed. + template< typename OT > + inline fapi2::ReturnCodes extractToRight(OT& o_out, + bits_type i_start = 0, + bits_type i_len = ~0) const + { + // If thy didn't pass an i_len, assume they want all the data + // which will fit. + if ((i_len == static_cast(~0)) || + (i_len > parameterTraits::bit_length())) + { + i_len = std::min(getBitLength(), + parameterTraits::bit_length()); + } + + // _insert likes 32-bit targets. So lets make our target 32 bits. + uint32_t l_data = static_cast(o_out); + + ReturnCodes rc; + if ((rc = _insert( + reinterpret_cast(&iv_data[0]), + getBitLength(), + &l_data, + parameterTraits::bit_length(), + i_start, + parameterTraits::bit_length() - + i_len, i_len)) != FAPI2_RC_SUCCESS) + { + return rc; + } + + o_out = l_data; + return FAPI2_RC_SUCCESS; + } + + ///@} + + private: + // Just shorthand ... + static const bits_type bits_per_unit = bufferTraits::bits_per_unit(); + + ///@cond + /// + /// @brief Return the size of the internal vector given a desired bit size + /// @param[in] The size in bits + /// @return The size in units. + /// + inline bits_type _vector_size(const bits_type& bits_size) + { + // If we fit in one unit, we allocate one unit. + if (bits_size < parameterTraits::bit_length()) + { + return 1; + } + + // Otherwise, the number of units is calculates - add one if + // we cross the unit boundary. + else + { + bits_type my_size = bits_type(bits_size / 8 / sizeof(unit_type)); + my_size += (bits_size % parameterTraits::bit_length() == 0) ? 0 : 1; + return my_size; + } + } + ///@endcond + + /// The contents of the buffer + bits_container iv_data; + + // The number of bits the user asked for. The actual size of the + // container might be larger. + bits_type iv_perceived_bit_length; + + /// + /// @brief Internal insertFromRight + /// @param[in] i_data, the incoming data + /// @param[in] i_data_length The length in bits of the incoming data + /// @param[in] i_target_start_bit The starting bit position in this + /// @param[in] i_length The length, in bits, the user wants copied. + /// + template + inline fapi2::ReturnCodes _insertFromRight(const OT& i_data, + bits_type i_data_length, + bits_type i_targetStart, + bits_type i_len) + { + // If they didn't pass in a length, assume they want all the i_data + // which will fit. + if( i_len == static_cast(~0) ) + { + // The longest the length can be is the length of the data + // This is the miniumum of the length of the data or the + // number of available bits + i_len = std::min(i_data_length, getBitLength() - i_targetStart); + } + + // Source start is the length, counted from the right + return insert(i_data, i_targetStart, i_len, i_data_length - i_len); + } + + }; + + // If the source is 64-bits, treat that as 2x32 + template<> + inline fapi2::ReturnCodes variable_buffer::insert(const uint64_t& i_source, + bits_type i_targetStart, + bits_type i_len, + bits_type i_sourceStart) + { + // _insert wants 32 bit chunks, so lets turn our uint64_t into a + // uint32_t array (of 64 bits in length). Looks like a 64 bit + // variable_buffer. + uint32_t l_source[2] = + {static_cast((i_source & 0xFFFFFFFF00000000) >> 32), + static_cast((i_source & 0x00000000FFFFFFFF))}; + + return _insert(l_source, parameterTraits::bit_length(), + &(iv_data[0]), getBitLength(), + i_sourceStart, i_targetStart, i_len); + } + + // Insert another variable_bufer + template<> + inline fapi2::ReturnCodes variable_buffer::insert( + const variable_buffer& i_data, + bits_type i_targetStart, + bits_type i_len, + bits_type i_sourceStart) + { + return _insert(reinterpret_cast(&(i_data()[0])), + i_data.getBitLength(), + &(iv_data[0]), getBitLength(), + i_sourceStart, i_targetStart, i_len); + } + + // variable_buffer insert from right + template<> + inline fapi2::ReturnCodes variable_buffer::insertFromRight( + const variable_buffer& i_data, + bits_type i_targetStart, + bits_type i_len) + { + const bits_type bit_length_of_source = i_data.getBitLength(); + return _insertFromRight(i_data, bit_length_of_source, + i_targetStart, i_len); + } + + template<> + inline fapi2::ReturnCodes variable_buffer::extract( + uint64_t& i_data, + bits_type i_start, + bits_type i_len) const + { + // If thy didn't pass an i_len, assume they want all the data + // which will fit. + if ((i_len == static_cast(~0)) || + (i_len > parameterTraits::bit_length())) + { + i_len = std::min(getBitLength(), + parameterTraits::bit_length()); + } + + // _insert wants 32 bit chunks, so lets turn our uint64_t into a + // uint32_t array (of 64 bits in length). Looks like a 64 bit + // variable_buffer. + uint32_t l_data[2] = + {static_cast((i_data & 0xFFFFFFFF00000000) >> 32), + static_cast((i_data & 0x00000000FFFFFFFF))}; + + ReturnCodes rc; + if ((rc = _insert((container_unit*)&iv_data[0], getBitLength(), + l_data, parameterTraits::bit_length(), + i_start, 0U, i_len)) != FAPI2_RC_SUCCESS) + { + return rc; + } + + i_data = static_cast(l_data[0]) << 32; + i_data |= l_data[1]; + + return FAPI2_RC_SUCCESS; + } + + // Extract in to another variable_bufer + template<> + inline fapi2::ReturnCodes variable_buffer::extract( + variable_buffer& i_data, + bits_type i_start, + bits_type i_len) const + { + // If thy didn't pass an i_len, assume they want all the data + // which will fit. + if (i_len == static_cast(~0)) + { + i_len = i_data.getBitLength(); + } + + return _insert(reinterpret_cast( + &iv_data[0]), + getBitLength(), + &(i_data()[0]), i_data.getBitLength(), + i_start, 0U, i_len); + } + + template<> + inline fapi2::ReturnCodes variable_buffer::extractToRight( + uint64_t& i_data, + bits_type i_start, + bits_type i_len) const + { + // If thy didn't pass an i_len, assume they want all the data + // which will fit. + if ((i_len == static_cast(~0)) || + (i_len > parameterTraits::bit_length())) + { + i_len = std::min(getBitLength(), + parameterTraits::bit_length()); + } + + // _insert wants 32 bit chunks, so lets turn our uint64_t into a + // uint32_t array (of 64 bits in length). + uint32_t l_data[2] = + {static_cast((i_data & 0xFFFFFFFF00000000) >> 32), + static_cast((i_data & 0x00000000FFFFFFFF))}; + + ReturnCodes rc; + if ((rc = _insert( + reinterpret_cast(&iv_data[0]), + getBitLength(), + l_data, parameterTraits::bit_length(), + i_start, + parameterTraits::bit_length() - i_len, i_len)) + != FAPI2_RC_SUCCESS) + { + return rc; + } + + i_data = static_cast(l_data[0]) << 32; + i_data |= l_data[1]; + + return FAPI2_RC_SUCCESS; + } + + inline fapi2::ReturnCodes variable_buffer::shiftLeft( + bits_type i_shiftNum, + bits_type i_offset) + { + if (i_offset == 0) + { + return FAPI2_RC_SUCCESS; + } + + if (i_offset == static_cast(~0)) + { + i_offset = getBitLength(); + } + + else if (i_offset > getBitLength()) + { + return FAPI2_RC_INVALID_PARAMETER; + } + + /* To shift the data, extact the piece being shifted and then re-insert it at the new location */ + variable_buffer shiftData(i_offset); + ReturnCodes rc; + + // Get the hunk of data + if ((rc = extract(shiftData, 0, i_offset)) != FAPI2_RC_SUCCESS) + { + return rc; + } + + // Clear the hole that was opened + if ((rc = clearBit((i_offset - i_shiftNum), i_shiftNum)) != FAPI2_RC_SUCCESS) + { + return rc; + } + + // Stick the data back in + rc = insert(shiftData, 0, (shiftData.getBitLength() - i_shiftNum), i_shiftNum); + + return rc; + } + + inline fapi2::ReturnCodes variable_buffer::shiftRight( + bits_type i_shiftNum, + bits_type i_offset) + { + if (i_offset == getBitLength()) + { + return FAPI2_RC_SUCCESS; + } + + if (i_offset > getBitLength()) + { + return FAPI2_RC_INVALID_PARAMETER; + } + + /* To shift the data, extact the piece being shifted and then re-insert it at the new location */ + variable_buffer shiftData(getBitLength() - i_offset); + ReturnCodes rc; + + // Get the hunk of data + if ((rc = extract(shiftData, i_offset, getBitLength() - i_offset)) != FAPI2_RC_SUCCESS) + { + return rc; + } + + // Clear the hole that was opened + if ((rc = clearBit(i_offset, i_shiftNum)) != FAPI2_RC_SUCCESS) + { + return rc; + } + + // Stick the data back in + rc = insert(shiftData, (i_offset + i_shiftNum), (shiftData.getBitLength() - i_shiftNum)); + + return rc; + } + + template< typename OT> + inline OT variable_buffer::get(const bits_type i_offset) + { + // Get is just an extract. + OT l_tmp; + extract(l_tmp, parameterTraits::bit_length() * i_offset, parameterTraits::bit_length()); + return l_tmp; + } +} +#endif diff --git a/sbe/image/Makefile b/sbe/image/Makefile index 2b90d774..2038b7a6 100644 --- a/sbe/image/Makefile +++ b/sbe/image/Makefile @@ -223,6 +223,7 @@ tracehash: clean: rm -fr $(OBJDIR) rm $(TOP-FIXED-HEADERS) + rm -fr $(TOOLS_IMAGE_DIR)/bin/* rm *.dump diff --git a/sbe/image/img_defs.mk b/sbe/image/img_defs.mk index 2e96b86b..6ca0a9bd 100644 --- a/sbe/image/img_defs.mk +++ b/sbe/image/img_defs.mk @@ -100,7 +100,7 @@ export PPE_FAPI2_DIR = $(abspath ../../hwpf/plat) endif ifndef BASE_FAPI2_DIR -export BASE_FAPI2_DIR = $(abspath /afs/apd/u/rembold/ekb/hwpf/fapi2) +export BASE_FAPI2_DIR = $(abspath ../../importtemp/fapi2) endif ifndef CC_ROOT diff --git a/tools/image/Makefile b/tools/image/Makefile index d5991d5e..0afc09ee 100644 --- a/tools/image/Makefile +++ b/tools/image/Makefile @@ -61,7 +61,7 @@ INCLUDES += -I ../../pk/kernel/ INCLUDES += -I ../../pk/std/ INCLUDES += -I ../../pk/trace/ INCLUDES += -I ../../tools/ppetracepp/ -INCLUDES += -I /afs/apd/u/rembold/ekb/hwpf/fapi2/include +INCLUDES += -I ../../importtemp/fapi2/include/ INCLUDES += -I$(CRONUS_PATH) INCLUDES += -I$(ECMD_PATH)/capi @@ -83,7 +83,7 @@ GCC-RELEASE = 4.8.2 GCC-VERSION = $(shell gcc -v 2>&1 | grep "$(GCC-RELEASE)") ifeq ($(GCC-VERSION),) -$(error wrong compiler version. Use $(GCC-RELEASE) compiler. Try to execute scl enable devtoolset-2 bash first) +$(error wrong compiler version. Use $(GCC-RELEASE) compiler. Try: "scl enable devtoolset-2 bash") else CC = gcc CXX = g++ diff --git a/tools/image/bin/.empty b/tools/image/bin/.empty new file mode 100644 index 00000000..e69de29b -- cgit v1.2.1