diff options
| author | Shakeeb <shakeebbk@in.ibm.com> | 2016-09-01 06:24:44 -0500 |
|---|---|---|
| committer | AMIT J. TENDOLKAR <amit.tendolkar@in.ibm.com> | 2016-09-01 07:48:28 -0400 |
| commit | 5e83bcb5cf9d400739cfb2beaab1a3173e8cafb2 (patch) | |
| tree | b3d6cd12b5eb0c92404ae5ac0352bb360b38fa95 /src/import/hwpf/fapi2/include | |
| parent | 1008ef70a71fcfdec398ff30923d5025991c85f4 (diff) | |
| download | talos-sbe-5e83bcb5cf9d400739cfb2beaab1a3173e8cafb2.tar.gz talos-sbe-5e83bcb5cf9d400739cfb2beaab1a3173e8cafb2.zip | |
SBE move import`
Change-Id: I726951318cdb19fd445af2f7910e0d6872eff18c
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/29086
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Sachin Gupta <sgupta2m@in.ibm.com>
Reviewed-by: AMIT J. TENDOLKAR <amit.tendolkar@in.ibm.com>
Diffstat (limited to 'src/import/hwpf/fapi2/include')
35 files changed, 7817 insertions, 0 deletions
diff --git a/src/import/hwpf/fapi2/include/buffer.H b/src/import/hwpf/fapi2/include/buffer.H new file mode 100644 index 00000000..7661a9cd --- /dev/null +++ b/src/import/hwpf/fapi2/include/buffer.H @@ -0,0 +1,781 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/buffer.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file buffer.H + * @brief definitions for fapi2 variable integral buffers + */ + +#ifndef __FAPI2_INTEGRAL_BUFFER__ +#define __FAPI2_INTEGRAL_BUFFER__ + +#include <buffer_parameters.H> +#include <buffer_traits.H> +#include <plat_trace.H> +#include <return_code_defs.H> + +namespace fapi2 +{ +/// @brief Class representing a FAPI buffer<T> +/// @tparam T, the integral type of the buffer (uint16_t, uint64_t, etc.) +template <typename T, typename TT = bufferTraits<T> > +class buffer +{ + 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::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<OT>::value, + "Input must be an integral type" ); + + const uint32_t length = TT:: template size<OT>(iv_data); + static const bits_type bits_in_value = parameterTraits<OT>::bit_length(); + const bits_type bit_length = TT::bit_length(iv_data); + + if (i_offset + 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<OT>::mask() << ((bits_in_value * length) - + bit_length); + } + + parameterTraits<OT>::template write_element<typename TT::unit_type> + (TT::get_address(iv_data), i_value, i_offset); + 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<uint64_t>().) Similarly, to get the length in words, + /// getLength<uin32_t>(). + /// + template< typename OT > + inline constexpr uint32_t getLength(void) const + { + return TT::template size<OT>(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<uint64_t>().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::ReturnCodes 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<T>().setBit<B, C>().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::ReturnCodes 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<T> 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<B, C>() : setBit<B, C>(); + 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<T>().setBit<B, C>(); + 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 + /// @note 0 is left-most + /// + template< bits_type B, bits_type C = 1> + inline bool getBit(void) const + { + return buffer<T>().setBit<B, C>() & iv_data; + } + + /// + /// @brief Get the value of 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 + /// @return true if *any* bit is on, false if *every* bit is off + /// @note 0 is left-most + /// + inline bool getBit(const bits_type& i_bit, + const bits_type& i_count = 1) + { + buffer<T> l_temp; + l_temp.setBit(i_bit, i_count); + return l_temp & 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<T>& operator>>(bits_type i_shiftnum); +#endif + + /// + /// @brief operator<<() + /// +#ifdef DOXYGEN + inline buffer<T>& operator<<(bits_type i_shiftnum); +#endif + + /// + /// @brief operator+() + /// +#ifdef DOXYGEN + inline buffer<T>& operator+(const T& rhs); +#endif + + /// + /// @brief operator+=() + /// +#ifdef DOXYGEN + inline buffer<T>& operator+=(const T& rhs); +#endif + + /// + /// @brief operator|=() + /// +#ifdef DOXYGEN + inline buffer<T>& operator|=(const T& rhs); +#endif + + /// + /// @brief operator&=() + /// +#ifdef DOXYGEN + inline buffer<T>& operator&=(const T& rhs); +#endif + + /// + /// @brief operator|() + /// +#ifdef DOXYGEN + inline buffer<T>& operator|(const T& rhs); +#endif + + /// + /// @brief operator&() + /// +#ifdef DOXYGEN + inline buffer<T>& operator&(const T& rhs); +#endif + + /// + /// @brief operator^=() + /// +#ifdef DOXYGEN + inline buffer<T>& operator^=(const T& rhs); +#endif + + /// + /// @brief operator~() + /// +#ifdef DOXYGEN + inline buffer<T>& 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<bits_type TS, bits_type L, bits_type SS = 0, typename OT> + inline buffer & insert(const OT i_datain) + { + const bits_type target_length = parameterTraits<T>::bit_length(); + const bits_type source_length = parameterTraits<OT>::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<uint64_t>(i_datain); + const uint64_t target = static_cast<uint64_t>(iv_data); + + const bits_type source_start = parameterTraits<uint64_t>::bit_length() - + (source_length - SS); + const bits_type target_start = parameterTraits<uint64_t>::bit_length() - + (target_length - TS); + + // Get mask value for Target buffer + // Note: Need "& 0ULL" because bit shift left for Target buffer doesn't roll off + uint64_t mask = ((~0ULL << (parameterTraits<uint64_t>::bit_length() - L)) & ~0ULL) + >> 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] i_targetStart bit to insert into (target start) + /// @param[in] i_len Length of bits to insert + /// @param[in] i_sourceStart Start bit in source - defaults to bit 0 + + /// @return FAPI2_RC_SUCCESS if successful + /// + template<typename OT> + fapi2::ReturnCodes 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<T>::bit_length(); + const bits_type source_length = parameterTraits<OT>::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<uint64_t>(i_datain); + const uint64_t target = static_cast<uint64_t>(iv_data); + + const bits_type source_start = parameterTraits<uint64_t>::bit_length() - + (source_length - i_sourceStart); + const bits_type target_start = parameterTraits<uint64_t>::bit_length() - + (target_length - i_targetStart); + + // Get mask value for Target buffer + // Note: Need "& 0ULL" because bit shift left for Target buffer doesn't roll off + uint64_t mask = ((~0ULL << (parameterTraits<uint64_t>::bit_length() - i_len)) & + ~0ULL) >> 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<bits_type TS, bits_type L, typename OT> + inline buffer& insertFromRight(const OT i_datain) + { + // Error if input data don't make sense + static_assert(L <= parameterTraits<OT>::bit_length(), + "insertFromRight(): Len > input buffer"); + static_assert(TS < parameterTraits<T>::bit_length(), + "insertFromRight(): Target Start is out of bounds"); + static_assert((TS + L) <= parameterTraits<T>::bit_length(), + "InsertFromRight(): (Target Start + Len) is out of bounds"); + + this->insert < TS, L, parameterTraits<OT>::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] i_targetStart Start bit to insert into + /// @param[in] i_len 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<typename OT> + fapi2::ReturnCodes 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<T>::bit_length()) + { + FAPI_ERR("insertFromRight(): (Target Start + Len) is out of bounds"); + return FAPI2_RC_INVALID_PARAMETER; + } + + if (i_targetStart >= parameterTraits<T>::bit_length()) + { + FAPI_ERR("insertFromRight(): Target Start is out of bounds"); + return FAPI2_RC_INVALID_PARAMETER; + } + + if (i_len > parameterTraits<OT>::bit_length()) + { + FAPI_ERR("insertFromRight(): Len > input buffer"); + return FAPI2_RC_INVALID_PARAMETER; + } + + return this->insert(i_datain, i_targetStart, i_len, + parameterTraits<OT>::bit_length() - i_len); + } + + /// + /// @brief Copy data from this buffer into an OT + /// @tparam SS Start bit in source + /// @tparam L Length of bits to insert + /// @tparam TS Start bit to insert into (target start) + /// @tparam OT the type of the outgoing (target) + /// @param[out] o_out OT to copy into - data is placed left aligned + /// @return const buffer& Useful for method chaining + /// + template<bits_type SS, bits_type L, bits_type TS = 0, typename OT> + inline const buffer & extract(OT& o_out) const + { + // Extraction is just an insert into o_out + + buffer<OT> out(o_out); + out.insert<TS, L, SS>(iv_data); + o_out = out; + return *this; + } + + /// + /// @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<bits_type SS, bits_type L, bits_type TS = 0, typename OT> + inline buffer & extract(OT& o_out) + { + // Extraction is just an insert into o_out + + buffer<OT> out(o_out); + out.insert<TS, L, SS>(iv_data); + o_out = out; + return *this; + } + + /// + /// @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] i_sourceStart Start bit in source + /// @param[in] i_len Length of bits to extract + /// @param[in] i_targetStart Start bit to insert into (target start) + /// @return FAPI2_RC_SUCCESS if ok + /// + template<typename OT> + fapi2::ReturnCodes extract(OT& o_out, const bits_type i_sourceStart, + const bits_type i_len, const bits_type i_targetStart = 0) const + { + // Extraction is just an insert into o_out + + buffer<OT> out(o_out); + + if (out.insert(iv_data, i_targetStart, i_len, + i_sourceStart) != FAPI2_RC_SUCCESS) + { + 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 const buffer& Useful for method chaining + /// + template<bits_type SS, bits_type L, typename OT> + inline const buffer& extractToRight(OT& o_out) const + { + extract < SS, L, parameterTraits<OT>::bit_length() - L > (o_out); + return *this; + } + + /// + /// @brief Copy data from this buffer into an OT and right justify + /// @tparam SS Start bit to insert into (source start) + /// @tparam L Length of bits to extract + /// @tparam OT the type of the outgoing (target) + /// @param[out] o_out OT to copy into - data is placed right aligned + /// @return buffer& Useful for method chaining + /// + template<bits_type SS, bits_type L, typename OT> + inline buffer& extractToRight(OT& o_out) + { + extract < SS, L, parameterTraits<OT>::bit_length() - L > (o_out); + return *this; + } + + /// + /// @brief Copy data from this buffer into an OT and right justify + /// @tparam OT the type of the outgoing (target) + /// @param[out] o_out OT to copy into - data is placed right aligned + /// @param[in] i_sourceStart Start bit to insert into (source start) + /// @param[in] i_len Length of bits to insert + /// @return FAPI2_RC_SUCCESS if ok + /// + template<typename OT> + fapi2::ReturnCodes extractToRight(OT& o_out, const bits_type i_sourceStart, + const bits_type i_len) const + { + return extract(o_out, i_sourceStart, i_len, + parameterTraits<OT>::bit_length() - i_len); + } + + ///@} + + private: + /// The contents of the buffer + T iv_data; +}; +} + +#endif diff --git a/src/import/hwpf/fapi2/include/buffer_parameters.H b/src/import/hwpf/fapi2/include/buffer_parameters.H new file mode 100644 index 00000000..aea03c66 --- /dev/null +++ b/src/import/hwpf/fapi2/include/buffer_parameters.H @@ -0,0 +1,76 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/buffer_parameters.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file buffer_parameters.H + * @brief definitions for fapi2 buffer parameter types + */ + +#ifndef __FAPI2_BUFFER_PARAM__ +#define __FAPI2_BUFFER_PARAM__ + +#include <stdint.h> + +namespace fapi2 +{ +/// @cond +/// @brief Traits of buffer parameters - things passed in +/// @tparam T is the type of i_value (typically an integral type) +template<typename T> +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<typename U> + 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/src/import/hwpf/fapi2/include/buffer_traits.H b/src/import/hwpf/fapi2/include/buffer_traits.H new file mode 100644 index 00000000..b14df7ea --- /dev/null +++ b/src/import/hwpf/fapi2/include/buffer_traits.H @@ -0,0 +1,275 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/buffer_traits.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file buffer_traits.H + * @brief trait definitions for fapi2 buffer base class + */ + +#ifndef __FAPI2_BUFFER_TRAITS__ +#define __FAPI2_BUFFER_TRAITS__ + +#include <stdint.h> +#include <vector> +#include <algorithm> +#include <buffer_parameters.H> + +#ifdef FAPI2_DEBUG + #include <iostream> +#endif + +#include <iterator> + +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<container_unit> 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<typename T, typename B = uint32_t> +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<uint64_t>(i_data) + << std::dec << std::endl; + } +#endif + + /// + /// @brief Return the size of the buffer in E units + /// @tparam E, the element size. + /// @param[in] i_buffer the buffer which to size + /// @return The size of the buffer in E's rounded up + /// + template<typename E> + constexpr static B size(const T& i_buffer) + { + return (bit_length(i_buffer) + + (parameterTraits<E>::bit_length() - 1)) / + parameterTraits<E>::bit_length(); + } + + /// + /// @brief Return the size of the buffer itself + /// @param[in] i_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<T>(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<T>(~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 + // + // @note from + // http://stackoverflow.com/questions/746171/best-algorithm-for-bit-reversal-from-msb-lsb-to-lsb-msb-in-c + /// + static inline void reverse( T& io_buffer) + { + T l_result = io_buffer; + size_t l_s = sizeof(T) * 8 - 1; + + for( io_buffer >>= 1; io_buffer; io_buffer >>= 1) + { + l_result <<= 1; + l_result |= io_buffer & 1; + l_s--; + } + + l_result <<= l_s; + + io_buffer = l_result; + } + /// + /// @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<bits_container, uint32_t> +{ + 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<container_unit>(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] i_buffer the buffer which to size + /// @return The size of the buffer in E's rounded up + /// + template<typename E> + constexpr static uint32_t size(const bits_container& i_buffer) + { + return (bit_length(i_buffer) + + (parameterTraits<E>::bit_length() - 1)) / + parameterTraits<E>::bit_length(); + } + + /// + /// @brief Return the size of the buffer itself + /// @param[in] i_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/src/import/hwpf/fapi2/include/error_info.H b/src/import/hwpf/fapi2/include/error_info.H new file mode 100644 index 00000000..9f0e0419 --- /dev/null +++ b/src/import/hwpf/fapi2/include/error_info.H @@ -0,0 +1,686 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/error_info.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/// +/// @file error_info.H +/// @brief Defines the Error Information structures and classes +/// + +#ifndef FAPI2_ERRORINFO_H_ +#define FAPI2_ERRORINFO_H_ + +#include <stdint.h> +#include <memory> +#include <vector> +#include <target.H> +#include <error_info_defs.H> + +namespace fapi2 +{ + +#if defined(MINIMUM_FFDC) && !defined(FAPI2_NO_FFDC) +// convert generic type to uint64_t +template<typename T> +inline uint64_t convertType( T& i_value ) +{ + // for simplicity sake, all FFDC chunks from the SBE + // are going to be sent as a uint64_t + return static_cast<uint64_t>(i_value); +}; + +// convert platform target handle to a uint64_t +template<fapi2::TargetType T> +inline uint64_t convertType( const fapi2::Target<T>& i_value) +{ + // send the target type and instance as ffdc they will be used + // to instantiate a target before logging the ffdc data + return static_cast<uint64_t>((static_cast<uint64_t>( + (i_value.get().getFapiTargetType())) << 32) | + i_value.get().getTargetInstance()); +}; +#endif + +#if !defined(FAPI2_NO_FFDC) && !defined(MINIMUM_FFDC) +// 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<uint8_t> 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<TARGET_TYPE_ALL>& 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<TARGET_TYPE_ALL> 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<TARGET_TYPE_ALL>& i_target1, + const Target<TARGET_TYPE_ALL>& 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<TARGET_TYPE_ALL> iv_target1; + Target<TARGET_TYPE_ALL> 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<TARGET_TYPE_ALL>& 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<TARGET_TYPE_ALL> 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_parentChip Reference to the parent target + /// @param[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<TARGET_TYPE_ALL>& 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<TARGET_TYPE_ALL> 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_traceId + /// + 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<std::shared_ptr<ErrorInfoFfdc> > iv_ffdcs; + + // Vector of Hardware to callout + std::vector<std::shared_ptr<ErrorInfoHwCallout> > iv_hwCallouts; + + // Vector of procedures to callout + std::vector<std::shared_ptr<ErrorInfoProcedureCallout> > + iv_procedureCallouts; + + // Vector of buses to callout + std::vector<std::shared_ptr<ErrorInfoBusCallout> > iv_busCallouts; + + // Vector of targets to callout/deconfigure/GARD + std::vector<std::shared_ptr<ErrorInfoCDG> > iv_CDGs; + + // Vector of children targets to callout/deconfigure/GARD + std::vector<std::shared_ptr<ErrorInfoChildrenCDG> > iv_childrenCDGs; + + // Vector of traces to collect + std::vector<std::shared_ptr<ErrorInfoCollectTrace> > 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<ErrorInfo> 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<ErrorInfo> 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<ErrorInfo> 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<ErrorInfo> 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<ErrorInfo> 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<ErrorInfo> 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<ErrorInfo> 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<ErrorInfo> 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 // !defined(FAPI2_NO_FFDC) && !defined(MINIMUM_FFDC) +} +#endif // FAPI2_ERRORINFO_H_ diff --git a/src/import/hwpf/fapi2/include/error_info_defs.H b/src/import/hwpf/fapi2/include/error_info_defs.H new file mode 100644 index 00000000..c67e4061 --- /dev/null +++ b/src/import/hwpf/fapi2/include/error_info_defs.H @@ -0,0 +1,344 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/error_info_defs.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/// +/// @file error_info_defs.H +/// @brief Defines to support the Error Information class +/// + +#ifndef FAPI2_ERRORINFO_DEFS_H_ +#define FAPI2_ERRORINFO_DEFS_H_ + +#include <stdint.h> +#include <target.H> + +#if !defined(MINIMUM_FFDC) && !defined(FAPI2_NO_FFDC) + #include <variable_buffer.H> + #include <utility> +#endif +namespace fapi2 +{ + +// $TEMP - funciton temp function to pass compiling +template<TargetType T> +Target<T>* getTarget(TargetType type, uint8_t instance) +{ + static_cast<void>(type); + static_cast<void>(instance); + return new Target<T>(0); +} + +/// +/// @brief Type to hold the ffdc data to be sent to hostboot +/// +/// Note: Typical data sent seems to be register/addresss info +/// rather than use extra space converting stuff just +/// send a uint64 always +/// +struct sbeFfdc_t +{ + uint32_t size; + uint64_t data; +}; + +// 10 entries limits the size of SbeFfdcData_t to 128 bytes +enum +{ + MAX_SBE_FFDC_ENTRIES = 10 +}; + +// Data type for SBE ffdc buffer sent through fifo +typedef struct +{ + uint32_t fapiRc; // Return code from failure + uint32_t ffdcLength; // length of Fapi FFDC data (in bytes) + struct sbeFfdc_t ffdcData[MAX_SBE_FFDC_ENTRIES]; // fapi FFDC data +} SbeFfdcData_t; // 128 bytes + +/// +/// @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. +/// +struct ffdc_struct +{ + const void* ptr; + int16_t size; +}; + + +class ffdc_t +{ + public: + ffdc_t(void) + {} + + void operator=(const ffdc_t& i ) + { + iv_value.ptr = i.ptr(); + iv_value.size = i.size(); + } + + operator const void* () const + { + return iv_value.ptr; + } + operator uint8_t() const + { + return *(reinterpret_cast<const uint8_t*>(iv_value.ptr)); + } + + int16_t size(void) const + { + return iv_value.size; + } + int16_t& size(void) + { + return iv_value.size; + } + + const void* ptr(void) const + { + return iv_value.ptr; + } + const void*& ptr(void) + { + return iv_value.ptr; + } + + private: + struct ffdc_struct 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<T> + 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, +}; + +#ifndef MINIMUM_FFDC +/// +/// @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 CollectTrace +/// +/// 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, +}; +} +#endif + +// NOTE - this assumes no buffer_t or variable_buffers are passed +// data is converted to a uint64_t when placed into the sbe ffdc +// buffer +inline fapi2::ffdc_t getFfdcData( sbeFfdc_t& i_sbeFfdc ) +{ + fapi2::ffdc_t temp; + + // passed in size is a uint32_t but, needs to be uint16_t + temp.size() = static_cast<uint16_t>(i_sbeFfdc.size); + + if(temp.size() == EI_FFDC_SIZE_TARGET) + { + uint64_t targetData = i_sbeFfdc.data; + fapi2::TargetType type = static_cast<fapi2::TargetType>(targetData >> 32); + uint8_t instance = static_cast<uint8_t>(targetData & 0xFFFFFFFF); + // call hostboot to get the fapi2 target reference + temp.ptr() = static_cast<void*>(getTarget<TARGET_TYPE_ALL>(type, instance)); + } + else + { + // adjust the pointer based on the data size. + temp.ptr() = static_cast<void*>(reinterpret_cast<uint8_t*>(&i_sbeFfdc.data) + + (sizeof(uint64_t) - i_sbeFfdc.size)); + } + + return temp; +} +/// +/// @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<typename T> +inline uint16_t getErrorInfoFfdcSize(const T&) +{ + static_assert(sizeof(T) <= EI_FFDC_MAX_SIZE, + "FFDC too large to capture"); + return sizeof(T); +} +#if !defined(MINIMUM_FFDC) && !defined(FAPI2_NO_FFDC) +/// +/// @brief Compile error if caller tries to get the FFDC size of a pointer +/// +template<typename T> +inline uint16_t getErrorInfoFfdcSize(const T*) +{ + static_assert(std::is_pointer<T>::value, + "pointer passed to getErrorInfoFfdcSize"); + return 0; +} +#endif +/// +/// @brief Get FFDC Size specialization for fapi2::Target +/// +template<fapi2::TargetType T, typename V> +inline uint16_t getErrorInfoFfdcSize(const fapi2::Target<T, V>&) +{ + return EI_FFDC_SIZE_TARGET; +} + +#if !defined(MINIMUM_FFDC) && !defined(FAPI2_NO_FFDC) +/// +/// @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<uint32_t>(EI_FFDC_MAX_SIZE), + i_thing.getLength<uint8_t>()); +} +#endif +}; + +#endif // FAPI2_ERRORINFO_DEFS_H_ diff --git a/src/import/hwpf/fapi2/include/error_scope.H b/src/import/hwpf/fapi2/include/error_scope.H new file mode 100644 index 00000000..1a00386c --- /dev/null +++ b/src/import/hwpf/fapi2/include/error_scope.H @@ -0,0 +1,37 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/error_scope.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file error_scope.H + * @brief platform specializations which create a scope for automatic error handling + */ + +#ifndef __FAPI2_ERROR_SCOPE__ +#define __FAPI2_ERROR_SCOPE__ + +#include <plat_error_scope.H> +#include <fapi2_error_scope.H> + + +#endif diff --git a/src/import/hwpf/fapi2/include/fapi2.H b/src/import/hwpf/fapi2/include/fapi2.H new file mode 100644 index 00000000..9965e8e5 --- /dev/null +++ b/src/import/hwpf/fapi2/include/fapi2.H @@ -0,0 +1,55 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/fapi2.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// +/// @file fapi2.H +/// @brief top level header for fapi2 +/// + +#ifndef __FAPI2_TOP_LEVEL__ +#define __FAPI2_TOP_LEVEL__ + +#include <target.H> +#include <return_code.H> +#include <buffer.H> +#include <hw_access.H> +#include <utils.H> +#include <plat_trace.H> + +// In turn includes the needed generated headers (hwp_ffd_classes, etc.) +#include <error_scope.H> +#include <set_sbe_error.H> // Generated file + +#include <fapi2_hwp_executor.H> +#include <fapi2_attribute_service.H> +#include <fapi2_chip_ec_feature.H> + +#include <mvpd_access.H> + +// Block of headers not currently in fapi2 +#ifdef FAPI2_MISSING_HEADERS + #include <mbvpdAccess.H> +#endif + +#endif // __FAPI2_TOP_LEVEL__ diff --git a/src/import/hwpf/fapi2/include/fapi2_attribute_service.H b/src/import/hwpf/fapi2/include/fapi2_attribute_service.H new file mode 100644 index 00000000..78655961 --- /dev/null +++ b/src/import/hwpf/fapi2/include/fapi2_attribute_service.H @@ -0,0 +1,148 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/fapi2_attribute_service.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// +/// @file 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 <stdint.h> +#include <attribute_ids.H> +#include <return_code.H> +#include <target.H> +#include <target_types.H> +#include <plat_attribute_service.H> + +/// @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<target type>& l_target = ????; +/// Ex: Target<TARGET_TYPE_PROC_CHIP>& l_target = ????; +/// +/// To get a copy of an integer attribute and set the attribute +/// uint64_t l_val = 0; +/// l_rc = FAPI_ATTR_GET(<ID>, l_target, l_val); +/// l_rc = FAPI_ATTR_SET(<ID>, 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(<ID>, l_target, l_pVal); +/// l_rc = FAPI_ATTR_SET(<ID>, 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<ID##_Privileged>(), \ + fapi2::Target<ID##_TargetType>(TARGET), \ + fapi2::checkIdType<ID##_Type>(ID, VAL), \ + ID##_GETMACRO(ID, TARGET, VAL)) + +#define FAPI_ATTR_SET(ID, TARGET, VAL) \ + (fapi2::failIfPrivileged<ID##_Privileged>(), \ + fapi2::Target<ID##_TargetType>(TARGET), \ + fapi2::checkIdType<ID##_Type>(ID, VAL), \ + ID##_SETMACRO(ID, TARGET, VAL)) + +#define FAPI_ATTR_GET_PRIVILEGED(ID, TARGET, VAL) \ + (fapi2::checkIdType<ID##_Type>(ID, VAL), \ + ID##_GETMACRO(ID, TARGET, VAL)) + +#define FAPI_ATTR_SET_PRIVILEGED(ID, TARGET, VAL) \ + (fapi2::checkIdType<ID##_Type>(ID, VAL), \ + ID##_SETMACRO(ID, TARGET, VAL)) + +namespace fapi2 +{ + +/// +/// @brief Get raw access to a FAPI2 Attribute. This is used to dump FAPI2 +/// Attrs +/// +/// 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 +/// +ReturnCode rawAccessAttr(const AttributeId i_id, + const Target<TARGET_TYPE_ALL>& i_target, + uint8_t* o_val); + +/** + * @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<typename T> 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<const bool PRIVILEGED> void failIfPrivileged() +{ + ErrorAccessingPrivilegedAttribute(); +} +template <> inline void failIfPrivileged<false>() {} + +} + +#endif // FAPI2ATTRIBUTESERVICE_H_ diff --git a/src/import/hwpf/fapi2/include/fapi2_error_scope.H b/src/import/hwpf/fapi2/include/fapi2_error_scope.H new file mode 100644 index 00000000..8a4833ac --- /dev/null +++ b/src/import/hwpf/fapi2/include/fapi2_error_scope.H @@ -0,0 +1,89 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/fapi2_error_scope.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @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 <stdint.h> +#include <plat_error_scope.H> +#include <hwp_ffdc_classes.H> + +/// @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 clean_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__ ) + +/// +/// @brief Create an eror log, commit it, but do not exit the hwp because of +/// the error condition. +/// @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_NOEXIT( __conditional__, __ffdc__, ... ) \ + PLAT_FAPI_ASSERT_NOEXIT( __conditional__, __ffdc__, __VA_ARGS__ ) + +#endif diff --git a/src/import/hwpf/fapi2/include/fapi2_hw_access.H b/src/import/hwpf/fapi2/include/fapi2_hw_access.H new file mode 100644 index 00000000..8dc871bb --- /dev/null +++ b/src/import/hwpf/fapi2/include/fapi2_hw_access.H @@ -0,0 +1,428 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/fapi2_hw_access.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// +/// @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 <spy_ids.H> + typedef uint64_t spyId_t; +#endif + +#include <stdint.h> +#include <buffer.H> + +// variable_buffer isn't supported on PPE +#ifndef __PPE__ + #include <variable_buffer.H> +#endif + +#include <return_code.H> +#include <target.H> +#include <hw_access_def.H> +#include <plat_hw_access.H> +#include <p9_ringId.H> + +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, typename V > +inline ReturnCode getScom(const Target<K, V>& i_target, const uint64_t i_address, + buffer<uint64_t>& 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, typename V > +inline ReturnCode putScom(const Target<K, V>& i_target, const uint64_t i_address, + const buffer<uint64_t> 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, typename V > +inline ReturnCode putScomUnderMask(const Target<K, V>& i_target, + const uint64_t i_address, + const buffer<uint64_t> i_data, + const buffer<uint64_t> 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, typename V > +inline ReturnCode getCfamRegister(const Target<K, V>& i_target, + const uint32_t i_address, + buffer<uint32_t>& 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, typename V > +inline ReturnCode putCfamRegister(const Target<K, V>& i_target, + const uint32_t i_address, + const buffer<uint32_t> 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, typename V > +inline ReturnCode modifyCfamRegister(const Target<K, V>& i_target, + const uint32_t i_address, + const buffer<uint32_t> i_data, + const ChipOpModifyMode i_modifyMode); + +/// @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_ringID Ring ID that will identify the Ring in the image. +/// @param[in] i_ringMode Ring operation mode. +/// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +template< TargetType K, typename V > +ReturnCode putRing(const Target<K, V>& i_target, + const RingID i_ringID, + const RingMode i_ringMode = RING_MODE_HEADER_CHECK); + +// 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, typename V > +inline ReturnCode getRing(const Target<K, V>& i_target, + const scanRingId_t i_address, + variable_buffer& o_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, typename V > +inline ReturnCode modifyRing(const Target<K, V>& i_target, + const scanRingId_t i_address, + const variable_buffer& i_data, + const ChipOpModifyMode i_modifyMode, + const RingMode i_ringMode = 0); +#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] TARGET Target to operate on. +/// @param[in] ID Id of the spy whose data to be read. +/// @param[out] 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, typename V > +inline ReturnCode getSpy(const Target<K, V>& i_target, + const spyId_t i_spyId, + variable_buffer& o_data); + +template< TargetType K > +inline ReturnCode getSpy(const Target<K>& i_target, + const spyId_t i_spyId, + variable_buffer& o_data, + const RingMode i_ringMode); +#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, typename V > +inline ReturnCode getSpy(const Target<K, V>& i_target, + const char* const i_spyId, + variable_buffer& o_data); + +template< TargetType K > +inline ReturnCode getSpy(const Target<K>& i_target, + const char* const i_spyId, + variable_buffer& o_data, + const RingMode i_ringMode); +#endif + +/// @brief Writes a spy on a chip. +/// @tparam K template parameter, passed in target. +/// @param[in] TARGET Target to operate on. +/// @param[in] ID Id of the spy to write data to. +/// @param[out] 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, typename V > +inline ReturnCode putSpy(const Target<K, V>& i_target, + const spyId_t i_spyId, + const 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, typename V > +inline ReturnCode putSpy(const Target<K, V>& i_target, + const char* const i_spyId, + const variable_buffer& i_data); + +template< TargetType K, typename V > +inline ReturnCode putSpy(const Target<K, V>& i_target, + const char* const i_spyId, + const char* i_enum); +#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] TARGET Target to operate on. +/// @param[in] ID Id of the spy. +/// @param[in] DATA1 Buffer that holds spy data to write into ring +/// image. +/// @param[out] DATA2 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, typename V > +inline ReturnCode putSpyImage(const Target<K, V>& 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, typename V > +inline ReturnCode putSpyImage(const Target<K, V>& 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] TARGET Target to operate on +/// @param[in] ID The spy's id +/// @param[out] DATA1 Buffer that holds data read from ring image. +/// @param[in] DATA2 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, typename V > +inline ReturnCode getSpyImage(const Target<K, V>& 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, typename V > +inline ReturnCode getSpyImage(const Target<K, V>& 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/src/import/hwpf/fapi2/include/fapi2_hwp_executor.H b/src/import/hwpf/fapi2/include/fapi2_hwp_executor.H new file mode 100644 index 00000000..78a18fba --- /dev/null +++ b/src/import/hwpf/fapi2/include/fapi2_hwp_executor.H @@ -0,0 +1,48 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/fapi2_hwp_executor.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// +/// @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 <hwp_executor.H> + +/** + * @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/src/import/hwpf/fapi2/include/fapi2_multicast.H b/src/import/hwpf/fapi2/include/fapi2_multicast.H new file mode 100644 index 00000000..c83be5bc --- /dev/null +++ b/src/import/hwpf/fapi2/include/fapi2_multicast.H @@ -0,0 +1,171 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/fapi2_multicast.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// +/// @file fapi2_multicast.H +/// @brief Common definitions for fapi2 multicast target value wrapper class +/// + +#ifndef __FAPI2_COMMON_MULTICAST__ +#define __FAPI2_COMMON_MULTICAST__ + +#include <target.H> +#include <fapi2_multicast_defs.H> + +namespace fapi2 +{ + +/// +/// @brief Class representing a FAPI2 Multicast target value wrapper +/// @tparam M the type of multicast operation +/// @tparam G the type of multicast group +/// @tparam V the type of the target's Value this class is wrapping +/// @remark This wrapper class defines how a handle will behave by +/// type and group if internal to the handle mulitcast operation +/// is enabled. If the handle used is not multicast enabled most +/// function of this class will be ignored. +/// +template<MulticastType M, MulticastGroup G, typename V = plat_target_handle_t > +class Multicast +{ + public: + /// + /// @brief Delagate default constructor to constructor + /// that takes in a value as a param + /// + Multicast() : Multicast(V()) {} + + /// + /// @brief Create a Multicast value with a target value + /// @param[in] Value the value (i.e., specific element this + /// target represents, or pointer) + /// @note Platforms can will update the handle value with + /// information on the multicast type and group + /// + Multicast(const V& value) : iv_handle(value) + { + updateHandle<M, G>(iv_handle); + } + + /// + /// @brief Create a Multicast value from another Multicast value + /// @param[in] other the value + /// @note Platforms can will update the handle value with + /// information on the multicast type and group + /// + template<MulticastType O, MulticastGroup N> + Multicast(const Multicast<O, N> other) : + iv_handle(static_cast<V>(other)) + { + updateHandle<M, G>(iv_handle); + } + + /// + /// @brief Get the handle as a V + /// @return V The Multicast wrapper's internal handle, or value + /// + inline operator V() const + { + return iv_handle; + } + + /// + /// @brief Get the handle as a V + /// @return V The Multicast wrapper's internal handle, or value + /// + inline V& operator()() const + { + return iv_handle; + } + + /// + /// @brief Has the handle been enabled for multicast operation + /// @return Return true if multicast, false otherwise + /// + inline bool isMulticast() const; + + private: + /// + /// @brief update the handle with group and type given + /// @tparam O the type of multicast operation + /// @tparam N the type of multicast group + /// @param[in] Value the value/handle + /// + template<MulticastType O, MulticastGroup N> + inline void updateHandle(V& value); + + V iv_handle; +}; + +// multicast from unicast +template<MulticastType M, MulticastGroup G, TargetType K, typename V> +inline Target<K, Multicast<M, G, V>> make_multicast(const Target<K, V>& t) +{ + return Target<K, Multicast<M, G, V>>(t.get()); +} + +// multicast from multicast -- changing type +template<MulticastType M, MulticastType N, MulticastGroup G, TargetType K, typename V> +inline Target<K, Multicast<M, G, V>> make_multicast(const Target<K, Multicast<N, G, V>>& t) +{ + return Target<K, Multicast<M, G, V>>(t.get()); +} + +// multicast from multicast -- changing type and group +template<MulticastType M, MulticastGroup O, MulticastType N, MulticastGroup G, TargetType K, typename V> +inline Target<K, Multicast<M, O, V>> make_multicast(const Target<K, Multicast<N, G, V>>& t) +{ + return Target<K, Multicast<M, O, V>>(t.get()); +} + +// unicast from multicast +template<MulticastType M, MulticastGroup G, TargetType K, typename V> +inline Target<K, V> make_unicast(const Target<K, Multicast<M, G, V>>& t) +{ + return Target<K, V>(t.get()); +} + +// test if a multicast target +template<MulticastType M, MulticastGroup G, TargetType K, typename V> +inline bool is_multicast(const Target<K, Multicast<M, G, V>>& t) +{ + const Multicast<M, G, V>& l_mref = t; + return l_mref.isMulticast(); +} + +// return false if testing a non-multicast target +template<TargetType K, typename V> +inline bool is_multicast(const Target<K, V>& t) +{ + return false; +} + +template<MulticastType M1, MulticastType M2> +constexpr bool is_same() +{ + return (M1 == M2); +} +} + +#endif diff --git a/src/import/hwpf/fapi2/include/fapi2_multicast_defs.H b/src/import/hwpf/fapi2/include/fapi2_multicast_defs.H new file mode 100644 index 00000000..6199b4e0 --- /dev/null +++ b/src/import/hwpf/fapi2/include/fapi2_multicast_defs.H @@ -0,0 +1,42 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/fapi2_multicast_defs.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __FAPI2_COMMON_MULTICAST_DEFS__ +#define __FAPI2_COMMON_MULTICAST_DEFS__ + +namespace fapi2 +{ +enum MulticastType +{ + MULTICAST_WRITE, + MULTICAST_READAND, + MULTICAST_READOR, + MULTICAST_READBITX, + MULTICAST_READCOMPARE, +}; + +typedef uint32_t MulticastGroup; +} + +#endif diff --git a/src/import/hwpf/fapi2/include/fapi2_target.H b/src/import/hwpf/fapi2/include/fapi2_target.H new file mode 100644 index 00000000..b41eb477 --- /dev/null +++ b/src/import/hwpf/fapi2/include/fapi2_target.H @@ -0,0 +1,549 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/fapi2_target.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// +/// @file fapi2_target.H +/// @brief Common definitions for fapi2 targets +/// + +#ifndef __FAPI2_COMMON_TARGET__ +#define __FAPI2_COMMON_TARGET__ + +#include <stdint.h> +#include <stdlib.h> +#include <vector> +#include <target_types.H> +#include <target_states.H> +#include <plat_target.H> +#include <return_code_defs.H> + +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<fapi2::TARGET_TYPE_PROC_CHIP> A(PROCESSOR_CHIP_A); +/// fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> C(SYSTEM_C); +/// fapi2::Target<fapi2::TARGET_TYPE_MEMBUF_CHIP> B(MEMBUF_CHIP_B); +/// @endcode +/// +/// * Functions which take composite target types +/// @code +/// void takesProcOrMembuf( +/// const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP | +/// fapi2::TARGET_TYPE_MEMBUF_CHIP>& V ); +/// +/// void takesAny(const fapi2::Target<fapi2::TARGET_TYPE_ALL>& V ); +/// +/// @endcode +/// +/// * Traversing the target "tree" +/// @code +/// fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> A(PROCESSOR_CHIP_A); +/// +/// // Get A's parent +/// A.getParent<fapi2::TARGET_TYPE_SYSTEM>(); +/// +/// // Get the 0x53'd core +/// fapi2::getTarget<fapi2::TARGET_TYPE_CORE>(0x53); +/// +/// // Get all *my* present/functional children which are cores +/// A.getChildren<fapi2::TARGET_TYPE_CORE>(); +/// +/// // Get all of the the cores relative to my base target +/// fapi2::getChildren<fapi2::TARGET_TYPE_CORE>(); +/// @endcode +/// +/// * Invalid casts +/// @code +/// // Can't cast to a specialized target +/// fapi2::Target<fapi2::TARGET_TYPE_NONE> D(MEMBUF_CHIP_B); +/// takesProcOrMembuf( D ); +/// +/// // Not one of the shared types +/// fapi2::Target<fapi2::TARGET_TYPE_ABUS_ENDPOINT> E; +/// takesProcOrMembuf( E ); +/// @endcode +template<TargetType K, typename V = plat_target_handle_t> +class Target +{ + public: + + /// + /// @brief Delagate default constructor to constructor + /// that takes in a value as a param + /// + Target(): Target(V()) + {}; + + /// + /// @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(const V& Value): + 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 Less Than Comparison Operator + /// @param[in] i_right Reference to Target to compare. + /// @return bool. True if less than i_right. + /// @note Platforms need to define this so that the physical + /// targets are determined to be less than 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<T> a target representing the parent + /// + template< TargetType T > + inline Target<T, V> 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 (isChip(K)); + } + + /// + /// @brief Static function check if a Target type value is that of + /// a chip. It will return false for compound types that + /// include non-chip Target type bits + /// + /// @param[in] i_type The value of the Target type. + /// @return Return true if this type is of a chip, false otherwise + /// + static inline bool isChip(const TargetType i_type) + { + bool l_retVal = false; + + // Target type must have only chip type bits set + if ( ((i_type & TARGET_TYPE_CHIPS) != 0) && + ((i_type & ~TARGET_TYPE_CHIPS) == 0) ) + { + l_retVal = true; + } + + return l_retVal; + } + + /// + /// @brief Is this target a chiplet? + /// @return Return true if this target is a chiplet, false otherwise + /// + inline constexpr bool isChiplet(void) const + { + return (isChiplet(K)); + } + + /// + /// @brief Static function check if a Target type value is that of + /// a chiplet. It will return false for compound types that + /// include non-chiplet Target type bits + /// + /// @param[in] i_type The value of the Target type. + /// @return Return true if this type is of a chiplet, false otherwise + /// + static inline bool isChiplet(const TargetType i_type) + { + bool l_retVal = false; + + // Target type must have only chiplet type bits set + if ( ((i_type & TARGET_TYPE_CHIPLETS) != 0) && + ((i_type & ~TARGET_TYPE_CHIPLETS) == 0) ) + { + l_retVal = true; + } + + return l_retVal; + } + + /// + /// @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<Target<T,V>> 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<Target<T, V> > + getChildren(const TargetState i_state = TARGET_STATE_FUNCTIONAL) const; + + /// + /// @brief Get this target's children, filtered + /// @tparam T The type of the parent + /// @param[in] i_filter The desired chiplet filter + /// @param[in] i_state The desired TargetState of the children + /// @return std::vector<Target<T,V>> a vector of present/functional + /// children + /// + template< TargetType T> + inline std::vector<Target<T, V> > + getChildren(const TargetFilter i_filter, + const TargetState i_state = TARGET_STATE_FUNCTIONAL) const; + + /// + /// @brief Get the target at the other end of a bus + /// @tparam T The type of the target on the other end + /// @param[out] o_target A target representing the thing on the other end + /// @param[in] i_state The desired TargetState of the other end + /// @return FAPI2_RC_SUCCESS if OK, platforms will return a non-success + /// ReturnCode in the event of failure + /// @note o_target is only valid if return is FAPI2_RC_SUCCESS + /// + + template<TargetType T> + inline fapi2::ReturnCodes + getOtherEnd(Target<T, V>& o_target, const TargetState i_state = TARGET_STATE_FUNCTIONAL) const; + + /// + /// @brief Is the target functional? + /// @return true if target is functional, false if non-functional + /// + + inline bool + isFunctional(void) const; + + /// + /// @brief Returns the chiplet number associated with the Target + /// @return The chiplet number for the Target. 0 is returned if the + /// Target does not have a chiplet number (for ex, the PROC_CHIP Target) + /// @note For logical targets such as the EX, the chiplet number of + /// their immediate parent chiplet is returned + /// + inline uint8_t + getChipletNumber(void) const; + + /// + /// @brief Copy from a Target<O> to a Target<K> + /// @tparam O the target type of the other + /// + template<TargetType O, typename VO> + inline Target( const Target<O, VO>& Other ): + Target<K, V>(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<K>::count >= bitCount<O>::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] i_ordinal the ordinal number of the normal core this thread belongs to +/// @param[in] i_thread_id 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] i_thread_id 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] i_thread_id 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] i_ordinal the ordinal number of the normal core this thread belongs to +/// @param[in] i_threads 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] i_ordinal the ordinal number of the normal core this thread belongs to +/// @param[in] i_threads 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<T,V> +/// @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, typename V > +inline void toString(const Target<T, V>& 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] i_target A pointer to the Target<T,V> +/// @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, typename V > +inline void toString(const Target<T, V>* 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<T> the target requested +/// +template<TargetType T, typename V = plat_target_handle_t> +inline Target<T, V> 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<Target<T,V>> a vector of present/functional +/// children +/// +template<TargetType T, typename V> +inline std::vector<Target<T, V>> getChildren() +{ + // For testing + return {Target<T, V>(), Target<T, V>()}; +} +#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<T,V> +/// @param[in] i_buffer buffer +/// @return void +/// @post The contents of the buffer is replaced with the string +/// representation of the target +/// +template<TargetType T, typename V, typename B> +inline void toString(const Target<T, V>& 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/src/import/hwpf/fapi2/include/fapi2_vpd_access.H b/src/import/hwpf/fapi2/include/fapi2_vpd_access.H new file mode 100644 index 00000000..d5b946b0 --- /dev/null +++ b/src/import/hwpf/fapi2/include/fapi2_vpd_access.H @@ -0,0 +1,96 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/fapi2_vpd_access.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// @file fapi2_vpd_access.H +/// @brief Common file that defines the vpd access functions that +/// platform code must implement. +/// +// + +#ifndef _FAPI2_VPDACCESS_H_ +#define _FAPI2_VPDACCESS_H_ + +#include <return_code.H> +#include <target_types.H> +#include <vpd_access_defs.H> +#include <plat_vpd_access.H> + +namespace fapi2 +{ + +/// constants for VPD Info +constexpr uint64_t VPD_INFO_INVALID = 0xffffffffffffffff; + +/// @brief Specialized class representing required VPDInfo to be used +/// in collecting VPD for the MCS target type. +/// @tparam T fapi2::TARGET_TYPE_MCS +template<> +class VPDInfo<TARGET_TYPE_MCS> +{ + public: + // @brief VPDInfo constructor + VPDInfo( const fapi2::MemVpdData& i_vpd_type) + : iv_vpd_type(i_vpd_type), + iv_size(VPD_INFO_INVALID), + iv_freq_mhz(VPD_INFO_INVALID), + iv_rank_count_dimm_0(VPD_INFO_INVALID), + iv_rank_count_dimm_1(VPD_INFO_INVALID) + {}; + // type of vpd field to return + fapi2::MemVpdData_t iv_vpd_type; + + // size of the vpd data + size_t iv_size; + uint64_t iv_freq_mhz; + uint64_t iv_rank_count_dimm_0; + uint64_t iv_rank_count_dimm_1; + +}; + + +/// @brief Return a blob of memory VPD data associated with the input target +/// @param[in] i_target a valid fapi2 target +/// @param[in] io_vpd_info fapi2::VPDInfo class that specifies which piece of data to return +/// @param[out] o_blob the blob of raw data from the vpd +/// @return FAPI2_RC_SUCCESS if there's no problem +/// @note passing nullptr for o_blob will return the size of the keyword +/// +/// Example: +/// fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS> vpdInfo(MR_keyword); +/// vpdInfo.iv_freq = 2667; +/// +/// uint8_t * blob = NULL; +/// +/// FAPI_TRY(getVPD( mcs, vpdInfo, blob )); +/// blob = static_cast<uint8_t *>(malloc(vpdInfo.iv_size)); +/// FAPI_TRY(getVPD( mcs, vpdInfo, blob )); +/// blob now contains the VPD data for the MCS. +/// +template<TargetType T, typename V> +ReturnCode getVPD(const Target<T, V>& i_target, + VPDInfo<T>& io_vpd_info, + uint8_t* o_blob); + +}; +#endif diff --git a/src/import/hwpf/fapi2/include/ffdc.H b/src/import/hwpf/fapi2/include/ffdc.H new file mode 100644 index 00000000..82483d54 --- /dev/null +++ b/src/import/hwpf/fapi2/include/ffdc.H @@ -0,0 +1,238 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/ffdc.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file ffdc.H + * @brief Defines the FirstFailureData class + */ + +#ifndef FAPI2_FFDC_H_ +#define FAPI2_FFDC_H_ + +#include <memory> +#include <hwp_return_codes.H> +#include <return_code_defs.H> +#include <plat_trace.H> +#include <error_info.H> +#include <target.H> + +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<typename T> +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 by default. It will be created + /// when its needed in the setHwpError() method. Note that dereferencing + /// the error info without first calling setHwpError() will create a + // problem. + /// + FirstFailureData(void): + iv_info( nullptr ), iv_platDataPtr(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<R*>(this)->operator=(i_rcValue); + + // Forget about any associated data (this is a new error) + iv_info.reset( new ErrorInfo()); + + } + + /// + /// @return void *. Pointer to error info data. If NULL then no data + /// + void* getData(void) const; + + /// + /// @brief Get a pointer to any error info 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 Error data. If NULL then no data + /// + inline void* releaseData(void) + { + void* l_pData = iv_info; + iv_info = NULL; + return l_pData; + } + + /// + /// @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 Add ErrorInfo + /// + /// This is called by the collectFfdc and collectRegFfdc functions + /// following the call to actually collect the ffdc data, the ffdc + /// collection functions return a vector of shared pointers to the + /// ErrorInfoFfdc objects + /// + /// @param[in] i_errorInfo - vector of shared pointers to + /// errorInfoFfdc objects + /// + inline void addErrorInfo(std::vector<std::shared_ptr<ErrorInfoFfdc>>& i_errorInfo) + { + for( auto p : i_errorInfo ) + { + iv_info->iv_ffdcs.push_back(p); + } + }; + + /// + /// @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; + } + + /// + /// @brief Returns the platform data pointer value to the caller. + /// + inline void* getPlatDataPtr() + { + return iv_platDataPtr; + }; + + /// + /// @brief Sets objects platform data pointer to the passed in value. + /// + /// + inline void setPlatDataPtr( void* i_ptr ) + { + static_cast<R*>(this)->operator=(FAPI2_RC_PLAT_ERR_SEE_DATA); + iv_platDataPtr = i_ptr; + }; + + + protected: + // Pointer to the error info + std::shared_ptr<ErrorInfo> iv_info; + + private: + // free format data, to be used by the platform + void* iv_platDataPtr; +}; + +} +#endif // FAPI2_FFDC_H_ diff --git a/src/import/hwpf/fapi2/include/hw_access_def.H b/src/import/hwpf/fapi2/include/hw_access_def.H new file mode 100644 index 00000000..9d67961c --- /dev/null +++ b/src/import/hwpf/fapi2/include/hw_access_def.H @@ -0,0 +1,83 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/hw_access_def.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// +/// @file hw_access_def.H +/// @brief Hardware access definitions +/// + +#ifndef FAPI2_HWACCESSDEF_H_ +#define FAPI2_HWACCESSDEF_H_ + +#include <stdint.h> + +/// @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_HEADER_CHECK = 0x00000000, ///< Check header + RING_MODE_SET_PULSE_NO_OPCG_COND = 0x00000001, ///< Set pulse with + /// no OPCG conditioning + RING_MODE_NO_HEADER_CHECK = 0x00000002, ///< Don't check header + RING_MODE_SET_PULSE_NSL = 0x00000004, ///< Set pulse with NSL + /// pulse + RING_MODE_SET_PULSE_SL = 0x00000008, ///< Set pulse with SL + /// pulse + RING_MODE_SET_PULSE_ALL = 0x00000010, ///< Set pulse with pulse + /// to all hold types +}; + +/// @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/src/import/hwpf/fapi2/include/mvpd_access.H b/src/import/hwpf/fapi2/include/mvpd_access.H new file mode 100644 index 00000000..532b32ee --- /dev/null +++ b/src/import/hwpf/fapi2/include/mvpd_access.H @@ -0,0 +1,87 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/mvpd_access.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/// +/// @file mvpd_access.H +/// +/// @brief Defines the Module VPD functions that platform must implement +/// + +#ifndef _FAPI2_MVPDACCESS_H_ +#define _FAPI2_MVPDACCESS_H_ + +#include <stdint.h> +#include <return_code.H> +#include <target.H> +#include <mvpd_access_defs.H> + +namespace fapi2 +{ +/// +/// @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<TARGET_TYPE_PROC_CHIP>& 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<TARGET_TYPE_PROC_CHIP>& i_target, + const uint8_t* const i_pBuffer, + const uint32_t i_fieldSize); +} + +#endif diff --git a/src/import/hwpf/fapi2/include/mvpd_access_defs.H b/src/import/hwpf/fapi2/include/mvpd_access_defs.H new file mode 100644 index 00000000..a1a4aaff --- /dev/null +++ b/src/import/hwpf/fapi2/include/mvpd_access_defs.H @@ -0,0 +1,121 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/mvpd_access_defs.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/// +/// @file mvpd_access_defs.H +/// +/// @brief Defines the Module VPD Records and Keywords +/// + +#ifndef _FAPI2_MVPDACCESS_DEFS_H_ +#define _FAPI2_MVPDACCESS_DEFS_H_ + +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, + MVPD_RECORD_LAST, //useful for testcases + MVPD_RECORD_FIRST = MVPD_RECORD_CRP0, //useful for testcases +}; + +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, + MVPD_KEYWORD_LAST, //useful for testcases + MVPD_KEYWORD_FIRST = MVPD_KEYWORD_VD, //useful for testcases +}; +} + +#endif diff --git a/src/import/hwpf/fapi2/include/plat/hw_access.H b/src/import/hwpf/fapi2/include/plat/hw_access.H new file mode 100644 index 00000000..fbe8ae6e --- /dev/null +++ b/src/import/hwpf/fapi2/include/plat/hw_access.H @@ -0,0 +1,560 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/plat/hw_access.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/// @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 <variable_buffer.H> +#endif + +#include <plat_hw_access.H> +#include <fapi2_hw_access.H> + +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<void>(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<void>(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_data Buffer that holds data read from HW target. +/// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +/// +template< TargetType K, typename V > +inline ReturnCode getScom(const Target<K, V>& i_target, + const uint64_t i_address, + buffer<uint64_t>& 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, typename V > +inline ReturnCode putScom(const Target<K, V>& i_target, + const uint64_t i_address, + const buffer<uint64_t> 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, typename V > +inline ReturnCode putScomUnderMask(const Target<K, V>& i_target, + const uint64_t i_address, + const buffer<uint64_t> i_data, + const buffer<uint64_t> 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, typename V > +inline ReturnCode getCfamRegister(const Target<K, V>& i_target, + const uint32_t i_address, + buffer<uint32_t>& 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, typename V > +inline ReturnCode putCfamRegister(const Target<K, V>& i_target, + const uint32_t i_address, + const buffer<uint32_t> 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, typename V > +inline ReturnCode modifyCfamRegister(const Target<K, V>& i_target, + const uint32_t i_address, + const buffer<uint32_t> 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; +} + +/// @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_ringID Ring ID that will identify the Ring in the image. +/// @param[in] i_ringMode Ring operation mode. +/// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code. +template< TargetType K, typename V > +ReturnCode putRing(const Target<K, V>& i_target, + const RingID i_ringID, + const RingMode i_ringMode) +{ + std::cout << std::hex << " putRing " + << "target: {" << i_target.getType() << "," + << uint64_t(i_target) << "}; " + << "Ring ID: " << i_ringID << "; " + << "ring mode: " << i_ringMode + << 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, typename V > +inline ReturnCode getRing(const Target<K, V>& 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 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, typename V > +inline ReturnCode modifyRing(const Target<K, V>& 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 + +// -------------------------------------------------------------------------- +// 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, typename V > +inline ReturnCode getSpy(const Target<K, V>& i_target, + const spyId_t i_spyId, + variable_buffer& o_data) +{ + static_assert(K == 0, "implement getSpy (enum)"); + return ~FAPI2_RC_SUCCESS; +} + +template< TargetType K > +inline ReturnCode getSpy(const Target<K>& i_target, + const spyId_t i_spyId, + variable_buffer& o_data, + const RingMode i_ringMode) +{ + static_assert(K == 0, "implement getSpy (enum)"); + return ~FAPI2_RC_SUCCESS; +} +#endif +#ifdef FAPI_SUPPORT_SPY_AS_STRING +template< TargetType K, typename V > +inline ReturnCode getSpy(const Target<K, V>& i_target, + const char* const i_spyId, + variable_buffer& o_data) +{ + static_assert(K == 0, "implement getSpy (string)"); + return ~FAPI2_RC_SUCCESS; +} + +template< TargetType K > +inline ReturnCode getSpy(const Target<K>& i_target, + const char* const i_spyId, + variable_buffer& o_data, + const RingMode i_ringMode) +{ + 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, typename V > +inline ReturnCode putSpy(const Target<K, V>& i_target, + const spyId_t i_spyId, + const 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, typename V > +inline ReturnCode putSpy(const Target<K, V>& i_target, + const char* const i_spyId, + const variable_buffer& i_data) +{ + static_assert(K == 0, "implement putSpy (string)"); + return ~FAPI2_RC_SUCCESS; +} + +template< TargetType K, typename V > +inline ReturnCode putSpy(const Target<K, V>& i_target, + const char* const i_spyId, + const char* i_enum) +{ + 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_imageData 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, typename V > +inline ReturnCode putSpyImage(const Target<K, V>& 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, typename V > +inline ReturnCode putSpyImage(const Target<K, V>& 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, typename V > +inline ReturnCode getSpyImage(const Target<K, V>& 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, typename V > +inline ReturnCode getSpyImage(const Target<K, V>& 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/src/import/hwpf/fapi2/include/plat/plat_error_scope.H b/src/import/hwpf/fapi2/include/plat/plat_error_scope.H new file mode 100644 index 00000000..4b198a10 --- /dev/null +++ b/src/import/hwpf/fapi2/include/plat/plat_error_scope.H @@ -0,0 +1,89 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/plat/plat_error_scope.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @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; \ + } + +/// +/// @brief Create an error log based on __conditional__, +/// the FFDC gathering function is called and the +/// trace is output as a FAPI error trace. An error log +/// is created and returned to the caller via the platform +/// log pointer of the fapi2::current_err return code object +/// The caller is responsible for handling the error object. +/// +/// @param[in] __conditional__ the condition to assert +/// @param[in] __ffdc__ the FFDC gathering function +/// @param[in] ... varargs, as input to FAPI_ERR +/// +/// @note: Plat error, if supported, is stored in RC object. Failing +/// the __conditional__ test does not cause a branch to fapi_try_exit +/// +/// +#define PLAT_FAPI_ASSERT_NOEXIT( __conditional__, __ffdc__, ... ) \ + if (! (__conditional__)) \ + { \ + __ffdc__.execute( \ + fapi2::FAPI2_ERRL_SEV_UNDEFINED, true); \ + FAPI_ERR(__VA_ARGS__); \ + } +/// @endcond + + +#endif diff --git a/src/import/hwpf/fapi2/include/plat/plat_hw_access.H b/src/import/hwpf/fapi2/include/plat/plat_hw_access.H new file mode 100644 index 00000000..10f162b4 --- /dev/null +++ b/src/import/hwpf/fapi2/include/plat/plat_hw_access.H @@ -0,0 +1,39 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/plat/plat_hw_access.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/// @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/src/import/hwpf/fapi2/include/plat/plat_target.H b/src/import/hwpf/fapi2/include/plat/plat_target.H new file mode 100644 index 00000000..4712cda5 --- /dev/null +++ b/src/import/hwpf/fapi2/include/plat/plat_target.H @@ -0,0 +1,45 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/plat/plat_target.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file plat_target.H + * @brief platform definitions for fapi2 targets + */ + +#ifndef __FAPI2_PLAT_TARGET__ +#define __FAPI2_PLAT_TARGET__ + +#include <stdint.h> + +// +// 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/src/import/hwpf/fapi2/include/plat/plat_trace.H b/src/import/hwpf/fapi2/include/plat/plat_trace.H new file mode 100644 index 00000000..fbd3aef6 --- /dev/null +++ b/src/import/hwpf/fapi2/include/plat/plat_trace.H @@ -0,0 +1,73 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/plat/plat_trace.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @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 <stdio.h> +#include <stdint.h> + +// 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_) + +#define FAPI_LAB(__fmt_, _args_...) \ + printf(_fmt_, ##_args_); \ + printf("\n") +#endif // FAPI2_PLATTRACE_H_ diff --git a/src/import/hwpf/fapi2/include/plat/plat_vpd_access.H b/src/import/hwpf/fapi2/include/plat/plat_vpd_access.H new file mode 100644 index 00000000..5ca078a8 --- /dev/null +++ b/src/import/hwpf/fapi2/include/plat/plat_vpd_access.H @@ -0,0 +1,64 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/plat/plat_vpd_access.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// @file plat_vpd_access.H +/// +/// @brief Platform vpd-access definitions +/// + +#ifndef _FAPI2_PLAT_VPDACCESS_H_ +#define _FAPI2_PLAT_VPDACCESS_H_ + +#include <fapi2_vpd_access.H> + +namespace fapi2 +{ +// -- platform specific getVPD implementation goes here -- + +// platform specific for MCS target -- test code only +inline fapi2::ReturnCode platGetVPD(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + VPDInfo<fapi2::TARGET_TYPE_MCS>& io_vpd_info, + uint8_t* o_blob) +{ + fapi2::ReturnCode l_rc = fapi2::FAPI2_RC_SUCCESS; + + if( o_blob == nullptr ) + { + io_vpd_info.iv_size = 2048; + } + else + { + o_blob[0] = 111; + + io_vpd_info.iv_freq_mhz = 10000; + io_vpd_info.iv_rank_count_dimm_0 = 1; + io_vpd_info.iv_rank_count_dimm_1 = 8; + + } + + return l_rc; +} + +}; +#endif // _FAPI2_PLAT_VPDACCESS_H_ diff --git a/src/import/hwpf/fapi2/include/plat/target.H b/src/import/hwpf/fapi2/include/plat/target.H new file mode 100644 index 00000000..842d9d1f --- /dev/null +++ b/src/import/hwpf/fapi2/include/plat/target.H @@ -0,0 +1,242 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/plat/target.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file target.H + * @brief platform specializations for fapi2 targets + */ + +#ifndef __FAPI2_TARGET__ +#define __FAPI2_TARGET__ + +#include <plat_target.H> +#include <fapi2_target.H> +#include <multicast.H> +#include <stdio.h> + +namespace fapi2 +{ + +/// +/// @brief Assignment Operator. +/// @param[in] i_right Reference to Target to assign from. +/// @return Reference to 'this' Target +/// +template<TargetType K, typename V> +Target<K, V>& Target<K, V>::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<TargetType K, typename V> +bool Target<K, V>::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<TargetType K, typename V> +bool Target<K, V>::operator!=(const Target& i_right) const +{ + return i_right.iv_handle != iv_handle; +} + +/// +/// @brief Less Than Comparison Operator +/// @param[in] i_right Reference to Target to compare. +/// @return bool. True if less than i_right. +/// @note Platforms need to define this so that the physical +/// targets are determined to be less than rather than just the handles +/// +template<TargetType K, typename V> +bool Target<K, V>::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<T> a target representing the parent +/// +template<TargetType K, typename V> +template<TargetType T> +inline Target<T, V> Target<K, V>::getParent(void) const +{ + // For testing + return Target<T, V>(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<Target<T> > 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 K, typename V> +template< TargetType T> +inline std::vector<Target<T, V> > +Target<K, V>::getChildren(const TargetState i_state) const +{ + // To keep the compiler quiet about unused variables + static_cast<void>(i_state); + // For testing + return {Target<T, V>(), Target<T, V>()}; +} +// Specialization of getChildren, filtered for pervasive targets. +template<> +template<> +inline std::vector<Target<TARGET_TYPE_PERV> > +Target<TARGET_TYPE_PERV>::getChildren(const TargetFilter i_filter, + const TargetState i_state ) const +{ + // To keep the compiler quiet about unused variables + static_cast<void>(i_state); + static_cast<void>(i_filter); + + // For testing + return {Target<TARGET_TYPE_PERV>(i_filter), Target<TARGET_TYPE_PERV>(i_filter)}; +} + +/// +/// @brief Get the target at the other end of a bus +/// @tparam T The type of the target on the other end +/// @param[out] o_target A target representing the thing on the other end +/// @param[in] i_state The desired TargetState of the other end +/// @return FAPI2_RC_SUCCESS if OK, platforms will return a non-success +/// ReturnCode in the event of failure +/// @note o_target is only valid if return is FAPI2_RC_SUCCESS +/// + +template<TargetType K, typename V> +template<TargetType T> +inline fapi2::ReturnCodes +Target<K, V>::getOtherEnd(Target<T, V>& o_target, + const TargetState i_state) const +{ + // To keep the compiler quiet about unused variables + static_cast<void>(i_state); + + o_target = Target<T, V>(); + + return FAPI2_RC_SUCCESS; +} + +/// +/// @brief Is the target functional? +/// @return true if target is functional, false if non-functional +/// + +template<TargetType K, typename V> +inline bool +Target<K, V>::isFunctional(void) const +{ + // Platform check if target is good + // Could check ATTR_FUNCTIONAL or ATTR_PG_* + return true; +} + +/// +/// @brief Returns the chiplet number associated with the Target +/// @return The chiplet number for the Target. 0 is returned if the +/// Target does not have a chiplet number (for ex, the PROC_CHIP Target) +/// @note For logical targets such as the EX, the chiplet number of +/// their immediate parent chiplet is returned +/// +template<TargetType K, typename V> +inline uint8_t +Target<K, V>::getChipletNumber(void) const +{ + // Platform can return the chiplet number stored in it's Target handle + return 0; +} + +/// +/// @brief Return the string interpretation of this target +/// @tparam T The type of the target +/// @param[in] i_target Target<T> +/// @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, typename V > +inline void toString(const Target<T, V>& 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] i_target A pointer to the Target<T> +/// @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, typename V > +inline void toString(const Target<T, V>* 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<T> the target requested +/// +template<TargetType T, typename V> +inline Target<T, V> getTarget(uint64_t Ordinal) +{ + // For testing + return Target<T, V>(Ordinal); +} +} + +#endif diff --git a/src/import/hwpf/fapi2/include/plat/vpd_access.H b/src/import/hwpf/fapi2/include/plat/vpd_access.H new file mode 100644 index 00000000..554a3469 --- /dev/null +++ b/src/import/hwpf/fapi2/include/plat/vpd_access.H @@ -0,0 +1,52 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/plat/vpd_access.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// @file vpd_access.H +/// +/// @brief VPD access functions that needs to be specialized for +/// platform implementation. +/// + +#ifndef __VPDACCESS_H_ +#define __VPDACCESS_H_ + +#include <target.H> +#include <return_code.H> +#include <plat_vpd_access.H> +#include <fapi2_vpd_access.H> +namespace fapi2 +{ +// -- platform specializations for getVPD go here -- + +// specialization for MCS target +template<> fapi2::ReturnCode getVPD(const fapi2::Target<fapi2::TARGET_TYPE_MCS>& i_target, + VPDInfo<fapi2::TARGET_TYPE_MCS>& io_vpd_info, + uint8_t* o_blob) +{ + return platGetVPD( i_target, io_vpd_info, o_blob ); +} + +}; + +#endif // _FAPI2_VPDACCESS_H_ diff --git a/src/import/hwpf/fapi2/include/return_code.H b/src/import/hwpf/fapi2/include/return_code.H new file mode 100644 index 00000000..f5569dc2 --- /dev/null +++ b/src/import/hwpf/fapi2/include/return_code.H @@ -0,0 +1,187 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/return_code.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file return_code.H + * @brief definitions for fapi2 return codes + */ + +#ifndef __FAPI2_RETURN_CODE__ +#define __FAPI2_RETURN_CODE__ + +#include <stdint.h> + +#ifndef FAPI2_NO_FFDC + #include <ffdc.H> +#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<ReturnCode> +#endif +{ + public: + + /// + /// @brief Constructor. + /// @param[in] i_rc the rc to set + /// + ReturnCode(const uint32_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 uint32_t() const + { + return iv_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 uint32_t& rhs); + inline ReturnCode& operator=(const ReturnCodes& rhs); +#endif + + inline bool operator==(const uint32_t& rhs) const + { + return rhs == iv_rc; + } + + inline bool operator==(const ReturnCodes& rhs) const + { + return rhs == iv_rc; + } + + inline bool operator!=(const uint32_t& rhs) const + { + return rhs != iv_rc; + } + + inline bool operator!=(const ReturnCodes& rhs) const + { + return rhs != iv_rc; + } + + /// + /// @brief Enumeration of return code creators + /// + enum returnCodeCreator + { + CREATOR_FAPI = 1, + CREATOR_PLAT = 2, + CREATOR_HWP = 3, + }; + + /// + /// @brief Gets the creator of the return code + /// @return ReturnCodeCreator + /// + inline returnCodeCreator getCreator(void) const + { + returnCodeCreator l_creator = CREATOR_HWP; + + if (iv_rc & FAPI2_RC_FAPI2_MASK) + { + l_creator = CREATOR_FAPI; + } + else if (iv_rc & FAPI2_RC_PLAT_MASK) + { + l_creator = CREATOR_PLAT; + } + + return l_creator; + } + + + /// + /// @brief explicit check for RC value + /// @return true if this instance has a matching RC + /// + inline bool isRC(const ReturnCodes i_rc) const + { + return static_cast<uint32_t>(i_rc) == iv_rc; + } + + + /// + /// @brief explicit check for RC value + /// @return true if this instance has a matching RC + /// + inline bool isRC(const uint32_t i_rc) const + { + return i_rc == iv_rc; + } + + + private: + uint32_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 uint64_t pib_error_mask; /// the pib mask +extern thread_local uint64_t operational_state; /// the operational mode +#ifndef PLAT_NO_THREAD_LOCAL_STORAGE + extern thread_local ReturnCode current_err; /// the current error state +#else + extern ReturnCode current_err; +#endif + +} + +#endif diff --git a/src/import/hwpf/fapi2/include/return_code_defs.H b/src/import/hwpf/fapi2/include/return_code_defs.H new file mode 100644 index 00000000..c7c95f09 --- /dev/null +++ b/src/import/hwpf/fapi2/include/return_code_defs.H @@ -0,0 +1,121 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/return_code_defs.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file return_code.H + * @brief definitions for fapi2 return codes + */ + +#ifndef __FAPI2_RETURN_CODE_DEFS_ +#define __FAPI2_RETURN_CODE_DEFS_ + +#include <stdint.h> + +/// +/// @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 : uint32_t +{ + ///< 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_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 + + FAPI2_RC_PLAT_ERR_RING_HEADER_CHECK = FAPI2_RC_PLAT_MASK | 0x04, + //Operation on putring fail because of header data mismatch + // + FAPI2_RC_PLAT_RING_DECODE_LENGTH_EXCEEDED = FAPI2_RC_PLAT_MASK | 0x05, + //Operation on putring fail because of decode length greater than actual + //ring length. + + FAPI2_RC_PLAT_RING_ID_NOT_FOUND_IN_RS4_IMAGE = FAPI2_RC_PLAT_MASK | 0x06, + //Operation on putring fail because of ringId not found in RS4 image +}; + +} + +#endif diff --git a/src/import/hwpf/fapi2/include/target_states.H b/src/import/hwpf/fapi2/include/target_states.H new file mode 100644 index 00000000..be29cb28 --- /dev/null +++ b/src/import/hwpf/fapi2/include/target_states.H @@ -0,0 +1,45 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/target_states.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @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/src/import/hwpf/fapi2/include/target_types.H b/src/import/hwpf/fapi2/include/target_types.H new file mode 100644 index 00000000..3e852a1e --- /dev/null +++ b/src/import/hwpf/fapi2/include/target_types.H @@ -0,0 +1,277 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/target_types.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file target_types.H + * @brief definitions for fapi2 target types + */ + +#ifndef __FAPI2_TARGET_TYPES__ +#define __FAPI2_TARGET_TYPES__ +#include <stdint.h> + +// File that plat uses to assign values to TargetFilter enum +#include <plat_target_filter.H> + + +/// 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 + + // Compound target types + TARGET_TYPE_CHIPS = TARGET_TYPE_PROC_CHIP | + TARGET_TYPE_MEMBUF_CHIP, + + TARGET_TYPE_CHIPLETS = TARGET_TYPE_EX | + TARGET_TYPE_MBA | + TARGET_TYPE_MCS | + TARGET_TYPE_XBUS | + TARGET_TYPE_ABUS | + TARGET_TYPE_L4 | + TARGET_TYPE_CORE | + TARGET_TYPE_EQ | + TARGET_TYPE_MCA | + TARGET_TYPE_MCBIST | + TARGET_TYPE_MI | + TARGET_TYPE_DMI | + TARGET_TYPE_OBUS | + TARGET_TYPE_NV | + TARGET_TYPE_SBE | + TARGET_TYPE_PPE | + TARGET_TYPE_PERV | + TARGET_TYPE_PEC | + TARGET_TYPE_PHB, + + // 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, +}; + +/// +/// @brief Enumeration of chiplet filters +/// @note plat_target_filter.H assigns enum value using PlatTargetFilter namespace +/// + +enum TargetFilter : uint64_t +{ + TARGET_FILTER_NONE = 0x0000000000000000, + TARGET_FILTER_TP = PlatTargetFilter::PLAT_TARGET_FILTER_TP, // Pervasive 1 + TARGET_FILTER_NEST_NORTH = PlatTargetFilter::PLAT_TARGET_FILTER_NEST_NORTH, // Pervasive 2 + TARGET_FILTER_NEST_EAST = PlatTargetFilter::PLAT_TARGET_FILTER_NEST_EAST, // Pervasive 3 + TARGET_FILTER_NEST_SOUTH = PlatTargetFilter::PLAT_TARGET_FILTER_NEST_SOUTH, // Pervasive 4 + TARGET_FILTER_NEST_WEST = PlatTargetFilter::PLAT_TARGET_FILTER_NEST_WEST, // Pervasive 5 + TARGET_FILTER_XBUS = PlatTargetFilter::PLAT_TARGET_FILTER_XBUS, // Pervasive 6 + TARGET_FILTER_MC_WEST = PlatTargetFilter::PLAT_TARGET_FILTER_MC_WEST, // Pervasive 7 + TARGET_FILTER_MC_EAST = PlatTargetFilter::PLAT_TARGET_FILTER_MC_EAST, // Pervasive 8 + TARGET_FILTER_OBUS0 = PlatTargetFilter::PLAT_TARGET_FILTER_OBUS0, // Pervasive 9 + TARGET_FILTER_OBUS1 = PlatTargetFilter::PLAT_TARGET_FILTER_OBUS1, // Pervasive 10 + TARGET_FILTER_OBUS2 = PlatTargetFilter::PLAT_TARGET_FILTER_OBUS2, // Pervasive 11 + TARGET_FILTER_OBUS3 = PlatTargetFilter::PLAT_TARGET_FILTER_OBUS3, // Pervasive 12 + TARGET_FILTER_PCI0 = PlatTargetFilter::PLAT_TARGET_FILTER_PCI0, // Pervasive 13 + TARGET_FILTER_PCI1 = PlatTargetFilter::PLAT_TARGET_FILTER_PCI1, // Pervasive 14 + TARGET_FILTER_PCI2 = PlatTargetFilter::PLAT_TARGET_FILTER_PCI2, // Pervasive 15 + TARGET_FILTER_CACHE0 = PlatTargetFilter::PLAT_TARGET_FILTER_CACHE0, // Pervasive 16 + TARGET_FILTER_CACHE1 = PlatTargetFilter::PLAT_TARGET_FILTER_CACHE1, // Pervasive 17 + TARGET_FILTER_CACHE2 = PlatTargetFilter::PLAT_TARGET_FILTER_CACHE2, // Pervasive 18 + TARGET_FILTER_CACHE3 = PlatTargetFilter::PLAT_TARGET_FILTER_CACHE3, // Pervasive 19 + TARGET_FILTER_CACHE4 = PlatTargetFilter::PLAT_TARGET_FILTER_CACHE4, // Pervasive 20 + TARGET_FILTER_CACHE5 = PlatTargetFilter::PLAT_TARGET_FILTER_CACHE5, // Pervasive 21 + TARGET_FILTER_CORE0 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE0, // Pervasive 32 + TARGET_FILTER_CORE1 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE1, // Pervasive 33 + TARGET_FILTER_CORE2 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE2, // Pervasive 34 + TARGET_FILTER_CORE3 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE3, // Pervasive 35 + TARGET_FILTER_CORE4 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE4, // Pervasive 36 + TARGET_FILTER_CORE5 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE5, // Pervasive 37 + TARGET_FILTER_CORE6 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE6, // Pervasive 38 + TARGET_FILTER_CORE7 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE7, // Pervasive 39 + TARGET_FILTER_CORE8 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE8, // Pervasive 20 + TARGET_FILTER_CORE9 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE9, // Pervasive 41 + TARGET_FILTER_CORE10 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE10, // Pervasive 42 + TARGET_FILTER_CORE11 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE11, // Pervasive 43 + TARGET_FILTER_CORE12 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE12, // Pervasive 44 + TARGET_FILTER_CORE13 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE13, // Pervasive 45 + TARGET_FILTER_CORE14 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE14, // Pervasive 46 + TARGET_FILTER_CORE15 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE15, // Pervasive 47 + TARGET_FILTER_CORE16 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE16, // Pervasive 48 + TARGET_FILTER_CORE17 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE17, // Pervasive 49 + TARGET_FILTER_CORE18 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE18, // Pervasive 50 + TARGET_FILTER_CORE19 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE19, // Pervasive 51 + TARGET_FILTER_CORE20 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE20, // Pervasive 52 + TARGET_FILTER_CORE21 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE21, // Pervasive 53 + TARGET_FILTER_CORE22 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE22, // Pervasive 54 + TARGET_FILTER_CORE23 = PlatTargetFilter::PLAT_TARGET_FILTER_CORE23, // Pervasive 55 + + // Composite filters follow + + // Pervasive 32-55 (all cores) + TARGET_FILTER_ALL_CORES = (TARGET_FILTER_CORE0 | + TARGET_FILTER_CORE1 | TARGET_FILTER_CORE2 | + TARGET_FILTER_CORE3 | TARGET_FILTER_CORE4 | + TARGET_FILTER_CORE5 | TARGET_FILTER_CORE6 | + TARGET_FILTER_CORE7 | TARGET_FILTER_CORE8 | + TARGET_FILTER_CORE9 | TARGET_FILTER_CORE10 | + TARGET_FILTER_CORE11 | TARGET_FILTER_CORE12 | + TARGET_FILTER_CORE13 | TARGET_FILTER_CORE14 | + TARGET_FILTER_CORE15 | TARGET_FILTER_CORE16 | + TARGET_FILTER_CORE17 | TARGET_FILTER_CORE18 | + TARGET_FILTER_CORE19 | TARGET_FILTER_CORE20 | + TARGET_FILTER_CORE21 | TARGET_FILTER_CORE22 | + TARGET_FILTER_CORE23), + + // Pervasive 16-21 (all caches) + TARGET_FILTER_ALL_CACHES = (TARGET_FILTER_CACHE0 | + TARGET_FILTER_CACHE1 | TARGET_FILTER_CACHE2 | + TARGET_FILTER_CACHE3 | TARGET_FILTER_CACHE4 | + TARGET_FILTER_CACHE5), + + // Pervasive 2-5 (eg N0-N3) < req'd + TARGET_FILTER_ALL_NEST = (TARGET_FILTER_NEST_NORTH | + TARGET_FILTER_NEST_SOUTH | TARGET_FILTER_NEST_EAST | + TARGET_FILTER_NEST_WEST), + + // Pervasive 2-4 (eg N0-N2) < req'd + TARGET_FILTER_NEST_SLAVES = + (TARGET_FILTER_NEST_NORTH | TARGET_FILTER_NEST_SOUTH | + TARGET_FILTER_NEST_EAST), + + // Pervasive 5 (eg N32) < req'd + TARGET_FILTER_NEST_MASTER = TARGET_FILTER_NEST_WEST, + + // Pervasive 7-8 (eg MC0-MC1) + TARGET_FILTER_ALL_MC = + (TARGET_FILTER_MC_WEST | TARGET_FILTER_MC_EAST), + + // Pervasive 9-12 (OB0-OB3) + TARGET_FILTER_ALL_OBUS = + (TARGET_FILTER_OBUS0 | TARGET_FILTER_OBUS1 | TARGET_FILTER_OBUS2 | + TARGET_FILTER_OBUS3), + + // Pervasive 13-15 (PCI0-PCI2) + TARGET_FILTER_ALL_PCI = + (TARGET_FILTER_PCI0 | TARGET_FILTER_PCI1 | TARGET_FILTER_PCI2), + + // Sync mode filter = All NEST + All MCS + TARGET_FILTER_SYNC_MODE_NEST = + (TARGET_FILTER_ALL_NEST | TARGET_FILTER_ALL_MC), + + // All IO Targets except NEST + TARGET_FILTER_ALL_IO_EXCEPT_NEST = + (TARGET_FILTER_XBUS | TARGET_FILTER_ALL_PCI | TARGET_FILTER_ALL_OBUS), + + // All sync mode IO except NEST + TARGET_FILTER_SYNC_MODE_ALL_IO_EXCEPT_NEST = + (TARGET_FILTER_ALL_MC | TARGET_FILTER_XBUS | TARGET_FILTER_ALL_PCI | + TARGET_FILTER_ALL_OBUS), + + // All sync mode NEST slaves + TARGET_FILTER_SYNC_MODE_NEST_SLAVES = + (TARGET_FILTER_ALL_MC | TARGET_FILTER_NEST_SLAVES), + + // All sync mode IO + TARGET_FILTER_SYNC_MODE_ALL_IO = + (TARGET_FILTER_ALL_MC | TARGET_FILTER_ALL_NEST | + TARGET_FILTER_ALL_OBUS | TARGET_FILTER_ALL_PCI | + TARGET_FILTER_XBUS), + + // All IO + TARGET_FILTER_ALL_IO = (TARGET_FILTER_ALL_NEST | + TARGET_FILTER_ALL_OBUS | TARGET_FILTER_ALL_PCI | + TARGET_FILTER_XBUS), + + // All sync mode except TP + TARGET_FILTER_SYNC_MODE_ALL_EXCEPT_TP = + (TARGET_FILTER_ALL_MC | TARGET_FILTER_ALL_NEST | + TARGET_FILTER_ALL_OBUS | TARGET_FILTER_ALL_PCI | + TARGET_FILTER_XBUS | TARGET_FILTER_ALL_CORES | + TARGET_FILTER_ALL_CACHES), +}; + + +/// @cond +constexpr TargetType operator|(TargetType x, TargetType y) +{ + return static_cast<TargetType>(static_cast<int>(x) | + static_cast<int>(y)); +} + +template<uint64_t V> +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/src/import/hwpf/fapi2/include/utils.H b/src/import/hwpf/fapi2/include/utils.H new file mode 100644 index 00000000..e4f5fa09 --- /dev/null +++ b/src/import/hwpf/fapi2/include/utils.H @@ -0,0 +1,171 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/utils.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file utils.H + * @brief Defines common fapi2 utilities + */ + +#ifndef FAPI2_UTILS_H_ +#define FAPI2_UTILS_H_ + +#include <stdint.h> +#include <return_code.H> +#include <target_types.H> +#include <plat_utils.H> + + +namespace fapi2 +{ + +/// +/// @brief Enable/Disable special wakeup on processor chip core(s) +/// +/// Special Wakeup Enable must be done when a HWP is doing an operation that +/// requires core(s) to be awake (e.g. modifying the Hcode image). For +/// each Special Wakeup Enable call, there must be a subsequent Special Wakeup +/// Disable call. +/// +/// This does not apply to SCOM operations, platforms must handle Special Wakeup +/// for SCOM operations internally. +/// +/// If Special Wakeup is enabled, a core will not go to sleep (if already +/// sleeping, it is woken up). If Special Wakeup is disabled, if there are no +/// other active Enables, the core is allowed to sleep. +/// +/// @note Implemented by platform code calling the cpu special wakeup HWP. +/// This is a FAPI2 function because each platform may do different things +/// Hostboot: Does nothing (cores cannot sleep while Hostboot running) +/// FSP: Uses an algorithm to decide when to disable special wakeup +/// Cronus: Does Special Wakeup enable/disable as requested +/// +/// @param[in] i_target +/// TARGET_TYPE_PROC_CHIP: Enables/Disables Special Wakeup on all +/// cores (EX,EQ chiplets) of the specified chip target. +/// TARGET_TYPE_CORE: Enables/Disables Special Wakeup on the +/// specified core target (EX,EQ chiplets) +/// TARGET_TYPE_EX: Enables/Disables Special Wakeup on the +/// specified EX target. +/// TARGET_TYPE_EQ: Enables/Disables Special Wakeup on the +/// specified EQ target. +/// +/// @param[in] i_enable true = enable. false = disable. +/// +/// @return ReturnCode. FAPI2_RC_SUCCESS on success, else platform specified error. +/// +/// +template<TargetType T, typename V> +inline ReturnCode specialWakeup(const Target<T, V>& i_target, + const bool i_enable) +{ + // enforce the allowed target types + static_assert( ((T == fapi2::TARGET_TYPE_PROC_CHIP) || + (T == fapi2::TARGET_TYPE_CORE) || + (T == fapi2::TARGET_TYPE_EX) || + (T == fapi2::TARGET_TYPE_EQ)), + "Invalid target type for this function"); + + ReturnCode l_rc = platSpecialWakeup( i_target, i_enable ); + + return l_rc; +} + +/// +/// @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 Create a platform error log +/// +/// This function will create a platform error log from the passed in +/// return code value and will populate the iv_platDataPtr of the return code +/// with a pointer to the newly created log. +/// +/// @param[in,out] io_rc - Reference to ReturnCode +/// +/// @param[in] i_sev Fapi error log severity defaulted to unrecoverable +// +// +/// @note Implemented by platform code +/// +void createPlatLog( + fapi2::ReturnCode& io_rc, + fapi2::errlSeverity_t i_sev = fapi2::FAPI2_ERRL_SEV_UNRECOVERABLE +); + +/// +/// @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] i_expression a boolean representing the assertion +/// +void Assert(bool i_expression); +}; + +#endif // FAPI2_UTILS_H_ diff --git a/src/import/hwpf/fapi2/include/variable_buffer.H b/src/import/hwpf/fapi2/include/variable_buffer.H new file mode 100644 index 00000000..e32c69e7 --- /dev/null +++ b/src/import/hwpf/fapi2/include/variable_buffer.H @@ -0,0 +1,1291 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/variable_buffer.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/** + * @file variable_buffer.H + * @brief definitions for fapi2 variable length buffers + */ + +#ifndef __FAPI2_VARIABLE_BUFFER__ +#define __FAPI2_VARIABLE_BUFFER__ + +#include <buffer_parameters.H> +#include <buffer_traits.H> +#include <return_code_defs.H> +#include <plat_trace.H> + +namespace fapi2 +{ + +// forward fapi2::Assert() +extern void Assert(bool); + + +/// @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<typename unit_type, typename bits_type, typename output_type> +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<unit_type>::bit_length(); + const bits_type bits_per_output_unit = parameterTraits<output_type>::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<bits_type>(~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<bits_type>(~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::vector of uint32_t +/// as this keeps simple compatibility with ecmdDataBuffers. Cronus (at +// least) needs to interwork the two. +class variable_buffer +{ + + public: + + /// Shortcut typedef to get to our traits class + typedef typename bufferTraits<bits_container>::bits_type bits_type; + /// Shortcut typedef to get to our traits class + typedef typename bufferTraits<bits_container>::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<unit_type, uint32_t>::value, + "code currently needs unit_type to be a unit32_t"); + } +#ifndef NO_INITIALIZER_LIST + /// + /// @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<unit_type>& i_value): + iv_data(i_value), + iv_perceived_bit_length(i_value.size() * sizeof(unit_type) * 8) + { + static_assert(std::is_same<unit_type, uint32_t>::value, + "code currently needs unit_type to be a unit32_t"); + } +#endif + /// + /// @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<unit_type, uint32_t>::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<bits_container>::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. + /// + /// It is possible to write the incomplete last OT of a buffer that's not + /// an integer multiple of OT's size in bits; in that case, the value will + /// be treated left aligned and truncated. + /// + /// @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<OT>::value, + "Input must be an integral type" ); + + const bits_type bits_in_value = parameterTraits<OT>::bit_length(); + const bits_type bit_offset = i_offset * bits_in_value; + + if (bit_offset >= iv_perceived_bit_length) + { + return FAPI2_RC_OVERFLOW; + } + + const bits_type available_space = iv_perceived_bit_length - bit_offset; + + return insert<OT>( i_value, (i_offset * bits_in_value), std::min(available_space, bits_in_value), 0); + + } + + /// + /// @brief Get an OT of data from buffer + /// + /// It is possible to read the incomplete last OT of a buffer that's not + /// an integer multiple of OT's size in bits; in that case, the return + /// value will contain the remaining bits left-aligned. + /// + /// @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 read the left most element) + /// @return OT + /// @note uint8_t b = get<uint8_t>(N) <- gets the N'th left byte from the buffer + /// + template< typename OT> + inline OT get(const bits_type i_offset = 0) const; + + /// @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<uint64_t>().) Similarly, to get the length in words, + /// getLength<uin32_t>(). + /// + 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 + fapi2::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 = 1) + { + ReturnCodes rc = invert().setBit(SB, L); + + invert(); + + return rc; + } + + /// + /// @brief invert a bit or range of bits in a buffer + /// @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 + /// + inline fapi2::ReturnCodes flipBit( bits_type SB, bits_type L = 1) + { + ReturnCodes rc; + + // make sure we are within our container + if((SB + L) <= this->iv_perceived_bit_length) + { + // loop for L bits flipping as you go + for( bits_type i = 0; i < L; i++) + { + bits_type bit = SB + i; + + if(this->isBitSet(bit)) + { + rc = this->clearBit(bit); + } + else + { + rc = this->setBit(bit); + } + } + } + else + { + rc = FAPI2_RC_OVERFLOW; + } + + return rc; + } + + /// + /// @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<uint64_t>().isBitSet(4,3); + inline bool isBitSet( bits_type SB, bits_type L = 1 ) const + { + // make sure we stay within our container + fapi2::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 + /// + inline bits_type getNumBitsSet(bits_type SB, bits_type L = 1) const + { + bits_type number_of_bits_set = 0; + + for(bits_type i = 0; i < L; i++) + { + if( this->isBitSet(SB + i) ) + { + number_of_bits_set++; + } + } + + return number_of_bits_set; + } + + /// + /// @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<bits_container>::clear(iv_data) : bufferTraits<bits_container>::set(iv_data); + return *this; + } + + /// + /// @brief Invert entire buffer + /// @return variable_buffer&, Useful for method chaining + /// + inline variable_buffer& invert(void) + { + bufferTraits<bits_container>::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] i_shiftNum number of bits to shift + /// @param[in] i_offset 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] i_shiftNum number of bits to shift + /// @param[in] i_offset 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<void>(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<void>(shiftLeft(i_shiftnum)); + return *this; + } + + + /// + /// @brief operator+() + /// @param[in] rhs 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] rhs 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] rhs 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<T>& operator+=(const T& rhs); +#endif + + /// + /// @brief operator|=() + /// +#ifdef DOXYGEN + inline variable_buffer<T>& operator|=(const T& rhs); +#endif + + /// + /// @brief operator&=() + /// +#ifdef DOXYGEN + inline variable_buffer<T>& operator&=(const T& rhs); +#endif + + /// + /// @brief operator|() + /// +#ifdef DOXYGEN + inline variable_buffer<T>& operator|(const T& rhs); +#endif + + /// + /// @brief operator&() + /// +#ifdef DOXYGEN + inline variable_buffer<T>& operator&(const T& rhs); +#endif + + /// + /// @brief operator^=() + /// +#ifdef DOXYGEN + inline variable_buffer<T>& 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<typename OT> + inline fapi2::ReturnCodes insert(const OT& i_data, + bits_type i_targetStart = 0, + bits_type i_len = ~0, + bits_type i_sourceStart = 0) + { + // Compile time check to make sure OT is integral + static_assert( std::is_integral<OT>::value, + "Input must be an integral type" ); + + // _insert likes 32-bit sources. So lets make our source 32 bits. + uint32_t l_source = static_cast<uint32_t>(i_data); + bits_type l_sourceStart = i_sourceStart + + parameterTraits<uint32_t>::bit_length() - + parameterTraits<OT>::bit_length(); + + return _insert(&l_source, parameterTraits<uint32_t>::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<typename OT> + inline fapi2::ReturnCodes insertFromRight(const OT& i_data, + bits_type i_targetStart = 0, + bits_type i_len = ~0) + { + return _insertFromRight(i_data, parameterTraits<OT>::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 they didn't pass an i_len, assume they want all the data + // which will fit. + if (i_len == static_cast<bits_type>(~0)) + { + i_len = std::min(getBitLength(), + parameterTraits<OT>::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<uint32_t>(o_out); + + ReturnCodes rc; + + if ((rc = _insert((container_unit*)&iv_data[0], getBitLength(), + &l_data, + parameterTraits<uint32_t>::bit_length(), + i_start, 0U, i_len)) != FAPI2_RC_SUCCESS) + { + return rc; + } + + // Shift back to the original bit width. + o_out = l_data >> (parameterTraits<uint32_t>::bit_length() - + parameterTraits<OT>::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<bits_type>(~0)) || + (i_len > parameterTraits<OT>::bit_length())) + { + i_len = std::min(getBitLength(), + parameterTraits<OT>::bit_length()); + } + + // _insert likes 32-bit targets. So lets make our target 32 bits. + uint32_t l_data = static_cast<uint32_t>(o_out); + + ReturnCodes rc; + + if ((rc = _insert( + reinterpret_cast<const container_unit*>(&iv_data[0]), + getBitLength(), + &l_data, + parameterTraits<uint32_t>::bit_length(), + i_start, + parameterTraits<uint32_t>::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_container>::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<unit_type>::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<unit_type>::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<typename OT> + 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<bits_type>(~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<uint32_t>((i_source & 0xFFFFFFFF00000000) >> 32), + static_cast<uint32_t>((i_source & 0x00000000FFFFFFFF)) + }; + + return _insert(l_source, parameterTraits<uint64_t>::bit_length(), + &(iv_data[0]), getBitLength(), + i_sourceStart, i_targetStart, i_len); +} + +// Insert another variable_buffer +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<const unit_type*>(&(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<bits_type>(~0)) || + (i_len > parameterTraits<uint64_t>::bit_length())) + { + i_len = std::min(getBitLength(), + parameterTraits<uint64_t>::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<uint32_t>((i_data & 0xFFFFFFFF00000000) >> 32), + static_cast<uint32_t>((i_data & 0x00000000FFFFFFFF)) + }; + + ReturnCodes rc; + + if ((rc = _insert((container_unit*)&iv_data[0], getBitLength(), + l_data, parameterTraits<uint64_t>::bit_length(), + i_start, 0U, i_len)) != FAPI2_RC_SUCCESS) + { + return rc; + } + + i_data = static_cast<uint64_t>(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<bits_type>(~0)) + { + i_len = i_data.getBitLength(); + } + + return _insert(reinterpret_cast<const container_unit*>( + &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<bits_type>(~0)) || + (i_len > parameterTraits<uint64_t>::bit_length())) + { + i_len = std::min(getBitLength(), + parameterTraits<uint64_t>::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<uint32_t>((i_data & 0xFFFFFFFF00000000) >> 32), + static_cast<uint32_t>((i_data & 0x00000000FFFFFFFF)) + }; + + ReturnCodes rc; + + if ((rc = _insert( + reinterpret_cast<const container_unit*>(&iv_data[0]), + getBitLength(), + l_data, parameterTraits<uint64_t>::bit_length(), + i_start, + parameterTraits<uint64_t>::bit_length() - i_len, i_len)) + != FAPI2_RC_SUCCESS) + { + return rc; + } + + i_data = static_cast<uint64_t>(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<bits_type>(~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) const +{ + const bits_type bits_in_value = parameterTraits<OT>::bit_length(); + const bits_type bit_offset = i_offset * bits_in_value; + + if (bit_offset >= iv_perceived_bit_length) + { + FAPI_ERR("Overrun in variable_buffer::get<OT>() - bits_in_value=%d bit_offset=%d iv_perceived_bit_length=%d", + bits_in_value, bit_offset, iv_perceived_bit_length); + fapi2::Assert(false); + } + + // Get is just an extract. + OT l_tmp = OT(0); + const bits_type available_space = iv_perceived_bit_length - bit_offset; + extract(l_tmp, bit_offset, std::min(available_space, bits_in_value)); + return l_tmp; +} +} +#endif diff --git a/src/import/hwpf/fapi2/include/variable_buffer_utils.H b/src/import/hwpf/fapi2/include/variable_buffer_utils.H new file mode 100644 index 00000000..b1ae4664 --- /dev/null +++ b/src/import/hwpf/fapi2/include/variable_buffer_utils.H @@ -0,0 +1,149 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/variable_buffer_utils.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2015,2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +#ifndef __FAPI2_VARIABLE_BUFFER_UTILS__ +#define __FAPI2_VARIABLE_BUFFER_UTILS__ + +#include <inttypes.h> + +#include <ecmdDataBufferBase.H> +#include <ecmdUtils.H> + +#include <variable_buffer.H> +#include <return_code_defs.H> +#include <plat_trace.H> + +namespace fapi2 +{ +/** @name Variable buffer utility functions for platforms that support eCMD **/ +//@{ + +/** + * @brief Copies contents of fapi2::variable_buffer to a ecmdDataBufferBase + * @param[in] i_src fapi::variable_buffer to copy from + * @param[out] o_dest ecmdDataBufferBase to copy to + * @return uint32_t return code zero if success + */ +inline uint32_t bufferCopy(ecmdDataBufferBase& o_dest, const fapi2::variable_buffer& i_src) +{ + uint32_t rc = 0; + uint32_t l_ecmdRc = 0; + uint32_t l_bitLength = i_src.getBitLength(); + const uint32_t l_bitsPerWord = sizeof(uint32_t) * 8; + uint32_t l_wordLength = l_bitLength / l_bitsPerWord; + uint32_t l_currentWord = 0; + uint32_t l_extractData = 0; + fapi2::ReturnCodes l_copy_rc = fapi2::FAPI2_RC_SUCCESS; + + l_ecmdRc = o_dest.setBitLength(l_bitLength); + + if (l_ecmdRc) + { + FAPI_ERR("Error calling o_dest.setBitLength(%d) rc = 0x%08X\n", + l_bitLength, l_ecmdRc); + rc = l_ecmdRc; + } + + while ((l_currentWord < l_wordLength) && (rc == 0)) + { + l_copy_rc = i_src.extract(l_extractData, l_currentWord * l_bitsPerWord, l_bitsPerWord); + + if (l_copy_rc != fapi2::FAPI2_RC_SUCCESS) + { + FAPI_ERR("Error calling i_src.extract(l_extractData, %d, %d) rc = 0x" UINT64_HEX16_FORMAT "\n", + l_currentWord * l_bitsPerWord, l_bitsPerWord, static_cast<uint64_t>(l_copy_rc)); + rc = static_cast<uint64_t>(l_copy_rc); + break; + } + + l_ecmdRc = o_dest.insert(l_extractData, l_currentWord * l_bitsPerWord, l_bitsPerWord, 0); + + if (l_ecmdRc) + { + FAPI_ERR("Error calling o_dest.insert(%08X, %d, %d, 0) rc = 0x%08X\n", + l_extractData, l_currentWord * l_bitsPerWord, l_bitsPerWord, l_ecmdRc); + rc = l_ecmdRc; + break; + } + + l_currentWord++; + } + + if ((l_bitLength > (l_wordLength * l_bitsPerWord)) && (rc == 0)) + { + uint32_t l_bitsRemaining = l_bitLength - (l_wordLength * l_bitsPerWord); + l_copy_rc = i_src.extract(l_extractData, l_wordLength * l_bitsPerWord, l_bitsRemaining); + + if (l_copy_rc != fapi2::FAPI2_RC_SUCCESS) + { + FAPI_ERR("error calling i_src.extract(l_extractData, %d, %d) rc = 0x" UINT64_HEX16_FORMAT "\n", + l_wordLength * l_bitsPerWord, l_bitsRemaining, static_cast<uint64_t>(l_copy_rc)); + rc = static_cast<uint64_t>(l_copy_rc); + } + else + { + l_ecmdRc = o_dest.insert(l_extractData, l_wordLength * l_bitsPerWord, l_bitsRemaining, 0); + + if (l_ecmdRc) + { + FAPI_ERR("Error calling o_dest.insert(%08X, %d, %d, 0) rc = 0x%08X\n", + l_extractData, l_wordLength * l_bitsPerWord, l_bitsRemaining, l_ecmdRc); + rc = l_ecmdRc; + } + } + } + + return rc; +} + +/** + * @brief Copies contents of ecmdDataBufferBase to a fapi2::variable_buffer + * @param[in] i_src ecmdDataBufferBase to copy from + * @param[out] o_dest fapi::variable_buffer to copy to + * @return uint32_t return code zero if success + */ +inline uint32_t bufferCopy(fapi2::variable_buffer& o_dest, ecmdDataBufferBase& i_src) +{ + uint32_t rc = 0; + uint32_t* l_data = ecmdDataBufferBaseImplementationHelper::getDataPtr(&i_src); + + if (l_data != NULL) + { + o_dest = fapi2::variable_buffer(l_data, i_src.getCapacity(), i_src.getBitLength()); + } + else + { + FAPI_ERR("Error getting data pointer to ecmdDataBufferBase\n"); + rc = 1; + } + + return rc; +} + +//@} + +} // namespace fapi2 + +#endif /* __FAPI2_VARIABLE_BUFFER_UTILS__ */ diff --git a/src/import/hwpf/fapi2/include/vpd_access_defs.H b/src/import/hwpf/fapi2/include/vpd_access_defs.H new file mode 100644 index 00000000..57d51e13 --- /dev/null +++ b/src/import/hwpf/fapi2/include/vpd_access_defs.H @@ -0,0 +1,58 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: import/hwpf/fapi2/include/vpd_access_defs.H $ */ +/* */ +/* OpenPOWER sbe Project */ +/* */ +/* Contributors Listed Below - COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* Licensed under the Apache License, Version 2.0 (the "License"); */ +/* you may not use this file except in compliance with the License. */ +/* You may obtain a copy of the License at */ +/* */ +/* http://www.apache.org/licenses/LICENSE-2.0 */ +/* */ +/* Unless required by applicable law or agreed to in writing, software */ +/* distributed under the License is distributed on an "AS IS" BASIS, */ +/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ +/* implied. See the License for the specific language governing */ +/* permissions and limitations under the License. */ +/* */ +/* IBM_PROLOG_END_TAG */ +/// +/// @file vpd_access_defs.H +/// +/// @brief VPD access definitions +/// + +#ifndef __VPDACCESSDEFS_H_ +#define __VPDACCESSDEFS_H_ + +#include <stdint.h> + +namespace fapi2 +{ + +// @brief VPD accesss enums +enum MemVpdData +{ + MR, //! Memory phase rotator + MT, //! Memory Termination + MP, //! Memory Power related info +}; + +typedef MemVpdData MemVpdData_t; + +/// @brief Class representing required VPDInfo to be used in vpd collection. +/// @tparam T, the type of target this class is used with. +/// +/// NOTE: to be defined by implementor +// +template<fapi2::TargetType T> +class VPDInfo; + +} +#endif |

