summaryrefslogtreecommitdiffstats
path: root/hwpf/plat
diff options
context:
space:
mode:
authorGreg Still <stillgs@us.ibm.com>2015-06-03 07:12:31 -0500
committerDerk Rembold <rembold@de.ibm.com>2015-06-16 13:20:49 -0500
commit5e9cb6846e5860c4f82d234760c32ca561ac3854 (patch)
tree95c4e1fbde8170fb6b7c8234c107bacf718e1030 /hwpf/plat
parent2315a070ebd8edeaac44df5d7a2d17ad7b44f1bb (diff)
downloadtalos-sbe-5e9cb6846e5860c4f82d234760c32ca561ac3854.tar.gz
talos-sbe-5e9cb6846e5860c4f82d234760c32ca561ac3854.zip
PPE FAPI2 resync changes
- Tested SCOMs (absolute and FAPI_TRY) on GPE SIMICS without RCs to chip target OCB registers. GPE SIMICS model does not have registers in non-chip level targets. - Testing on GPE SIMICS with RCs fails with illegal addresses in thread local storage initialization - Added ./ppe/sbe/plat platform specifics - Added missing ./ppe/hwpf/plat/include files - Added missing fapi2AttributeService.H - Add PPE specific (though likely temporary) versions of buffer.H (to deal with compile errors for "units_per_bit()" to "units_per_bit" and "bit_length()" to "bit_length") and return_code.H (to include return_code_defs.H) - Add ppe/plat/include/plat_error_scope.H to deal with SBE return code tracing - Deleted old file version - Added local version of buffer.H - Move current_err to global variable (vs thread local storage); This removes #include <thread>. - Enable PK_TRACE under FAPI_* Trace macros - Added plat_attributes.H to include generated platform specific files - Added -DUSE_PK_APP_CFG to img_defs.mk Change-Id: Ice6c24a5091d3cf8eb4e4d93a0d139086126df95 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/18239 Reviewed-by: Derk Rembold <rembold@de.ibm.com> Tested-by: Derk Rembold <rembold@de.ibm.com>
Diffstat (limited to 'hwpf/plat')
-rw-r--r--hwpf/plat/include/buffer.H684
-rw-r--r--hwpf/plat/include/buffer_traits.H28
-rw-r--r--hwpf/plat/include/fapi2.H4
-rw-r--r--hwpf/plat/include/fapi2AttributeService.H127
-rw-r--r--hwpf/plat/include/fapi2_hw_access.H464
-rw-r--r--hwpf/plat/include/fapi2_target.H496
-rw-r--r--hwpf/plat/include/hw_access.H33
-rw-r--r--hwpf/plat/include/plat_attributes.H36
-rw-r--r--hwpf/plat/include/plat_error_scope.H65
-rw-r--r--hwpf/plat/include/plat_hw_access.H4
-rw-r--r--hwpf/plat/include/plat_trace.H22
-rw-r--r--hwpf/plat/include/return_code.H108
-rw-r--r--hwpf/plat/include/target.H689
-rw-r--r--hwpf/plat/include/target_types.H2
-rw-r--r--hwpf/plat/include/utils.H15
-rw-r--r--hwpf/plat/src/fapi2ppefiles.mk2
-rw-r--r--hwpf/plat/src/plat_utils.C79
17 files changed, 2351 insertions, 507 deletions
diff --git a/hwpf/plat/include/buffer.H b/hwpf/plat/include/buffer.H
new file mode 100644
index 00000000..9e863c3b
--- /dev/null
+++ b/hwpf/plat/include/buffer.H
@@ -0,0 +1,684 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2014 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file buffer.H
+ * @brief definitions for fapi2 variable integral buffers
+ */
+
+#ifndef __FAPI2_INTEGRAL_BUFFER__
+#define __FAPI2_INTEGRAL_BUFFER__
+
+#include <buffer_parameters.H>
+#include <buffer_traits.H>
+#include <return_code.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::ReturnCode set(OT i_value, const bits_type i_offset = 0)
+ {
+ // Compile time check to make sure OT is integral
+ static_assert( std::is_integral<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::ReturnCode setBit(const bits_type& i_bit, const bits_type& i_count = 1)
+ {
+ if ((i_count + i_bit - 1) >= TT::bits_per_unit())
+ {
+ return FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ iv_data |= (T(~0) >> (TT::bits_per_unit() - i_count)) << (TT::bits_per_unit() - i_bit - i_count);
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ ///
+ /// @brief Clear a bit in buffer
+ /// @tparam B Bit in buffer to clear.
+ /// @tparam C the count of bits to clear, defaults to 1
+ /// @return buffer& Useful for method chaining
+ /// @note Asserting that all the parameters are known at
+ /// compile time so this can be templated only. If that is not
+ /// the case we can add a function parameter version.
+ ///
+ template< bits_type B, bits_type C = 1>
+ inline buffer& clearBit(void)
+ {
+ static_assert((B >= 0) &&
+ ((B + C - 1)< TT::bits_per_unit()), "failed range check");
+
+ iv_data &= buffer<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::ReturnCode clearBit(const bits_type& i_bit, const bits_type& i_count = 1)
+ {
+ if ((i_count + i_bit - 1) >= TT::bits_per_unit())
+ {
+ return FAPI2_RC_INVALID_PARAMETER;
+ }
+
+ fapi2::buffer<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
+ ///
+ template< bits_type B, bits_type C = 1>
+ inline bool getBit(void) const
+ {
+ return buffer<T>().setBit<B, C>() & 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 "& 0UL" because bit shift left for Target buffer doesn't roll off
+ uint64_t mask = ((~0UL << (parameterTraits<uint64_t>::bit_length - L)) & ~0UL) >> target_start;
+
+ // Align the source to the target. Make things signed so we know which way to shift.
+ int32_t shift = source_start - target_start;
+ if (shift > 0)
+ {
+ source <<= shift;
+ }
+ else
+ {
+ shift = target_start - source_start;
+ source >>= shift;
+ }
+
+ iv_data = ((target & ~mask) | (source & mask));
+ return *this;
+ }
+
+ ///
+ /// @brief Copy part of a OT into the DataBuffer
+ /// @tparam OT the type of the incoming (origin) data
+ /// @param[in] i_datain OT value to copy into DataBuffer
+ /// - data is taken left aligned
+ /// @param[in] Start bit to insert into (target start)
+ /// @param[in] Length of bits to insert
+ /// @param[in] Start bit in source - defaults to bit 0
+
+ /// @return FAPI2_RC_SUCCESS if successful
+ ///
+ template<typename OT>
+ fapi2::ReturnCode insert(const OT i_datain, const bits_type i_targetStart,
+ const bits_type i_len, const bits_type i_sourceStart = 0)
+ {
+ const bits_type target_length = parameterTraits<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 "& 0UL" because bit shift left for Target buffer doesn't roll off
+ uint64_t mask = ((~0UL << (parameterTraits<uint64_t>::bit_length - i_len)) & ~0UL) >> target_start;
+
+ // 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] Start bit to insert into
+ /// @param[in] Length of bits to insert
+ /// @return FAPi2_RC_SUCCESS if no error
+ /// @note Data is assumed to be aligned on the word boundary of L
+ ///
+ template<typename OT>
+ fapi2::ReturnCode insertFromRight(const OT i_datain, const bits_type i_targetStart,
+ const bits_type i_len)
+ {
+ // Error if input data don't make sense
+ if ((i_targetStart + i_len) > parameterTraits<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 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] Start bit in source
+ /// @param[in] Length of bits to extract
+ /// @param[in] Start bit to insert into (target start)
+ /// @return FAPI2_RC_SUCCESS if ok
+ ///
+ template<typename OT>
+ fapi2::ReturnCode extract(OT& o_out, const bits_type i_sourceStart,
+ const bits_type i_len, const bits_type i_targetStart = 0)
+ {
+ // Extraction is just an insert into o_out
+
+ buffer<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 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] Start bit to insert into (source start)
+ /// @param[in] Length of bits to insert
+ /// @return FAPI2_RC_SUCCESS if ok
+ ///
+ template<typename OT>
+ fapi2::ReturnCode extractToRight(OT& o_out, const bits_type i_sourceStart,
+ const bits_type i_len)
+ {
+ return extract(o_out, i_sourceStart, i_len, parameterTraits<OT>::bit_length() - i_len);
+ }
+
+ ///@}
+
+ private:
+ /// The contents of the buffer
+ T iv_data;
+ };
+}
+
+#endif
diff --git a/hwpf/plat/include/buffer_traits.H b/hwpf/plat/include/buffer_traits.H
index 08073fb6..8f42ce9e 100644
--- a/hwpf/plat/include/buffer_traits.H
+++ b/hwpf/plat/include/buffer_traits.H
@@ -35,17 +35,22 @@
#include <algorithm>
#include <buffer_parameters.H>
-#ifdef __FAPI2_DEBUG__
-// for debug printing ... can be removed for flight
+#ifdef FAPI2_DEBUG
#include <iostream>
#endif
+
+#if !defined(DOXYGEN) && defined(FAPI2_DEBUG)
#include <iterator>
+#endif
namespace fapi2
{
/// @cond
/// Types representing a container of bits. Used to create
- /// variable_buffer.
+ /// 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;
@@ -59,8 +64,8 @@ namespace fapi2
class bufferTraits
{
public:
-#ifndef DOXYGEN
-#ifdef __FAPI2_DEBUG__
+
+#if !defined(DOXYGEN) && defined(FAPI2_DEBUG)
///
/// @brief Print a container of bits
/// @param[in] i_data the container of bits
@@ -75,7 +80,6 @@ namespace fapi2
<< std::dec << std::endl;
}
#endif
-#endif
///
/// @brief Return the size of the buffer in E units
@@ -141,7 +145,8 @@ namespace fapi2
typedef B bits_type;
typedef T unit_type;
- enum { bits_per_unit = sizeof(unit_type) * 8 };
+ constexpr static uint32_t bits_per_unit(void)
+ { return sizeof(unit_type) * 8; }
};
//
@@ -153,8 +158,7 @@ namespace fapi2
class bufferTraits<bits_container, uint32_t>
{
public:
-#ifndef DOXYGEN
-#ifdef __FAPI2_DEBUG__
+#if !defined(DOXYGEN) && defined(FAPI2_DEBUG)
///
/// @brief Print a container of bits
/// @param[in] i_data the container of bits
@@ -167,7 +171,6 @@ namespace fapi2
std::cout << std::dec << std::endl;
}
#endif
-#endif
///
/// @brief Return the size of the buffer in E units
@@ -228,10 +231,11 @@ namespace fapi2
typedef uint32_t bits_type;
typedef container_unit unit_type;
- enum { bits_per_unit = sizeof(unit_type) * 8 };
+ constexpr static uint32_t bits_per_unit(void)
+ { return sizeof(unit_type) * 8; }
};
/// @endcond
-};
+}
diff --git a/hwpf/plat/include/fapi2.H b/hwpf/plat/include/fapi2.H
index c6197284..a3dd4fbe 100644
--- a/hwpf/plat/include/fapi2.H
+++ b/hwpf/plat/include/fapi2.H
@@ -27,11 +27,11 @@
#include <utils.H>
+
// In turn includes the needed generated headers (hwp_ffd_classes, etc.)
#include <error_scope.H>
#include <set_sbe_error.H> // Generated file
-#include <fapi2PlatAttributeService.H>
-#include <fapi2AttributeIds.H> // Generated file
+#include <plat_attributes.H>
#include <hwp_executor.H>
diff --git a/hwpf/plat/include/fapi2AttributeService.H b/hwpf/plat/include/fapi2AttributeService.H
new file mode 100644
index 00000000..ab49c9ab
--- /dev/null
+++ b/hwpf/plat/include/fapi2AttributeService.H
@@ -0,0 +1,127 @@
+///
+/// @file fapi2AttributeService.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 <fapi2AttributeIds.H>
+#include <target.H>
+#include <target_types.H>
+//#include <plat_attribute_service.H>
+#include <fapi2PlatAttributeService.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::checkIdType<ID##_Type>(ID, VAL), \
+ ID##_GETMACRO(ID, TARGET, VAL))
+
+#define FAPI_ATTR_SET(ID, TARGET, VAL) \
+ (fapi2::failIfPrivileged<ID##_Privileged>(), \
+ 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 an InitFile attribute for FAPI2
+///
+/// This function gets a copy of an attribute. In the case of an array attribute,
+/// The value in the specified index is retrieved. This should be used by the
+/// InitFile HWP only, that HWP processes a binary InitFile and therefore needs
+/// to read a variable ID of a variable data type. Standard HWPs should use the
+/// FAPI2_ATTR_GET macro which automatically checks the type for correct usage.
+///
+/// If there are ever attributes with more than 4 dimensions then this function
+/// will need to be updated.
+///
+/// @Tparam K template parameter, passed in target.
+/// @param[in] i_id AttributeID
+/// @param[in] i_target Reference to fapi2::Target (can be NULL for system)
+/// @param[out] o_val Reference to uint64_t where attribute value is set
+/// @param[in] i_arrayIndex1 If array attribute then index1
+/// @param[in] i_arrayIndex2 If at least 2D array attribute then index2
+/// @param[in] i_arrayIndex3 If at least 3D array attribute then index3
+/// @param[in] i_arrayIndex4 If at least 4D array attribute then index4
+///
+/// @return ReturnCode. Zero if success
+///
+template< TargetType K >
+ReturnCode getInitFileAttr(const AttributeId i_id,
+ const Target<K>& i_target,
+ uint64_t & o_val,
+ const uint32_t i_arrayIndex1 = 0,
+ const uint32_t i_arrayIndex2 = 0,
+ const uint32_t i_arrayIndex3 = 0,
+ const uint32_t i_arrayIndex4 = 0);
+
+/**
+ * @brief Check the ID and TYPE
+ *
+ * This is called by FAPI code to check at compile time that a FAPI attribute
+ * access is using the correct data type and a valid AttributeId
+ */
+template<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/hwpf/plat/include/fapi2_hw_access.H b/hwpf/plat/include/fapi2_hw_access.H
new file mode 100644
index 00000000..44a592f8
--- /dev/null
+++ b/hwpf/plat/include/fapi2_hw_access.H
@@ -0,0 +1,464 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2014 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+///
+/// @file fapi2_hw_access.H
+/// @brief Common file that defines the hardware access functions that
+/// platform code must implement.
+///
+
+#ifndef _FAPI2_COMMON_HWACCESS_H_
+#define _FAPI2_COMMON_HWACCESS_H_
+
+#ifdef FAPI_SUPPORT_SPY_AS_ENUM
+#include <spy_ids.H>
+typedef uint64_t spyId_t;
+#endif
+
+#include <stdint.h>
+//#include <thread>
+#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>
+
+#ifdef FAPI_SUPPORT_MULTI_SCOM
+#include <multi_scom.H>
+#endif
+
+namespace fapi2
+{
+ //--------------------------------------------------------------------------
+ // PIB Error Functions
+ //--------------------------------------------------------------------------
+
+ /// @brief Sets the PIB error mask - platform dependant
+ /// @param[in] i_mask The new error mask
+ inline void setPIBErrorMask(uint8_t i_mask);
+
+ /// @brief Gets the PIB error mask - platform dependant
+ /// @return uint8_t The current PIB error mask
+ inline uint8_t getPIBErrorMask(void);
+
+ //--------------------------------------------------------------------------
+ // Operational Mode Error Functions
+ //--------------------------------------------------------------------------
+
+ /// @brief Sets the operational mode
+ /// @param[in] i_mode The new mode
+ inline void setOpMode(const OpModes i_mode);
+
+ /// @brief Gets the operational mode
+ /// @return the operational mode
+ inline OpModes getOpMode(void);
+
+ //--------------------------------------------------------------------------
+ // HW Communication Functions
+ //--------------------------------------------------------------------------
+
+ /// @brief Reads a SCOM register from a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target HW target to operate on.
+ /// @param[in] i_address SCOM register address to read from.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline void getScom(const Target<K>& 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 >
+ inline void putScom(const Target<K>& 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 >
+ inline void putScomUnderMask(const Target<K>& 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 >
+ inline ReturnCode getCfamRegister(const Target<K>& 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 >
+ inline ReturnCode putCfamRegister(const Target<K>& 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 >
+ inline ReturnCode modifyCfamRegister(const Target<K>& i_target,
+ const uint32_t i_address,
+ const buffer<uint32_t> i_data,
+ const ChipOpModifyMode i_modifyMode);
+
+ // variable_buffer isn't supported on PPE
+#ifndef __PPE__
+ /// @brief Reads a ring from a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_address Ring address to read from.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @param[in] i_ringMode Ring operation mode.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode getRing(const Target<K>& i_target,
+ const scanRingId_t i_address,
+ variable_buffer& o_data,
+ const RingMode i_ringMode = 0);
+
+ /// @brief Writes a ring to a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_address Ring address to write to.
+ /// @param[in] i_data Buffer that contains RS4 compressed ring data
+ /// to write into address
+ /// @param[in] i_ringMode Ring operation mode.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode putRing(const Target<K>& i_target,
+ const scanRingId_t i_address,
+ const variable_buffer& i_data,
+ const RingMode i_ringMode = 0);
+
+
+ /// @brief Read-modify-write a ring on a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_address Ring address to modify.
+ /// @param[in] i_data Buffer that contains RS4 compressed ring data
+ /// to be modified.
+ /// @param[in] i_modifyMode The modify mode (or/and/xor)
+ /// @param[in] i_ringMode Ring operation mode.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ template< TargetType K >
+ inline ReturnCode modifyRing(const Target<K>& i_target,
+ const scanRingId_t i_address,
+ const variable_buffer& i_data,
+ const ChipOpModifyMode i_modifyMode,
+ const RingMode i_ringMode = 0);
+#endif
+
+#ifdef FAPI_SUPPORT_MULTI_SCOM
+ /// @brief Performs a multiple SCOM operation
+ /// This interface performs multiple SCOM operations on a chip in the
+ /// order specified by the input MultiScom object.
+ /// See fapiMultiScom.H for details of how to populate the MultiScom
+ /// object with SCOM operations.
+ ///
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in,out] io_multiScomObj Reference to a MultiScom object,
+ /// pre-populated with SingleScomInfo entries
+ /// to perform multiple SCOMs on input target
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note This is a synchronous interface and would return after all the
+ /// SCOM operations are completed or on the first failed operation
+ ///
+ /// @note SCOMs will be performed in the order they were added to the
+ /// input MultiScom object
+ ///
+ /// @note In case of errors, the platform code is responsible to collect
+ /// and add all the required error info and FFDC into the error data
+ /// for debugging
+ ///
+ /// @note If the SCOM operations added are specific to a processor chip,
+ /// then the FSI Shift Engine configured in scatter-gather DMA mode
+ /// extension would be used to execute the SCOM operations in a
+ /// performance optimize mode. In this mode, the special
+ /// SCOM_BULK_READ_MODE and SCOM_BULK_WRITE_MODE operations are
+ /// supported that allow a large bulk of SCOM access (in multiple of
+ /// 64 bits) for targets that support auto-increment. The
+ /// SCOM_WRITE_UNDER_MASK operation is not supported in this mode
+ ///
+ /// @note If the SCOM operations added are specific to a memory buffer
+ /// chip, then the regular SCOM engine is used to execute the SCOM
+ /// operations. SCOM_WRITE_UNDER_MASK operation is supported in
+ /// this mode, but the special SCOM_BULK_READ_MODE and
+ /// SCOM_BULK_WRITE_MODE operations are not supported due to
+ /// hardware limitations.
+ ///
+ template< TargetType K >
+ fapi2::ReturnCode multiScom (const Target<K>& i_target,
+ MultiScom& io_multiScomObj);
+#endif
+
+ // --------------------------------------------------------------------------
+ // NOTE:
+ // Implement platform Spy access functions if platform supports them.
+ // --------------------------------------------------------------------------
+
+ // variable_buffer isn't supported on PPE
+#ifndef __PPE__
+ /// @brief Reads a spy from a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_spyId Id of the spy whose data to be read.
+ /// @param[out] o_data Buffer that holds data read from HW target.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependant on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// 1. if the spy name contains a # procedure writers should replace
+ /// it with an __P__ for example -
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ /// becomes
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// 2. if the spy name has a number following a "." it must have an
+ /// underscore prepended to the number.
+ ///
+ /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY
+ /// becomes
+ /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY
+ ///
+ /// Example SPY name:
+ /// The hardware procedure should call the function like:
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// fapi2::ReturnCode rc = fapiGetSpy( targ,
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data );
+ ///
+ /// @note The ID is not in quotes the fapi code will handle adding
+ /// the quotes for the cronus environment
+#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(DOXYGEN)
+
+#define FAPI_GET_SPY(TARGET, ID, DATA) fapi2::getSpy(TARGET, FAPI_SPY_NAMES::ID.value, DATA)
+
+ template< TargetType K >
+ inline ReturnCode getSpy(const Target<K>& i_target,
+ const spyId_t i_spyId,
+ variable_buffer& o_data);
+#endif
+
+#if defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN)
+
+#define FAPI_GET_SPY(TARGET, ID, DATA) fapi2::getSpy(TARGET, #ID, DATA)
+
+ template< TargetType K >
+ inline ReturnCode getSpy(const Target<K>& i_target,
+ const char * const i_spyId,
+ variable_buffer& o_data);
+#endif
+
+ /// @brief Writes a spy on a chip.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_spyId Id of the spy to write data to.
+ /// @param[out] i_data Buffer that holds data to write into spy.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependent on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// 1. if the spy name contains a # procedure writers should replace
+ /// is with an __P__ for example -
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ /// becomes
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// 2. if the spy name has a number following a "." it must have an
+ /// underscore prepended to the number.
+ ///
+ /// EH.TPCHIP.2KX100_ARY_CLK_EDGES_DLY
+ /// becomes
+ /// EH.TPCHIP._2KX100_ARY_CLK_EDGES_DLY
+ ///
+ /// Example SPY name:
+ /// The hardware procedure should call the function like:
+ ///
+ /// ABUS.RX0.RXPACKS#0.RXPACK.RD.LC.LC.ACT_DIS
+ ///
+ /// fapi2::ReturnCode rc = fapiPutSpy( targ,
+ /// ABUS.RX0.RXPACKS__P__0.RXPACK.RD.LC.LC.ACT_DIS, data );
+ ///
+ /// @note The ID is not in quotes the fapi code will handle adding
+ /// the quotes for the cronus environment
+ ///
+#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(DOXYGEN)
+
+#define FAPI_PUT_SPY(TARGET, ID, DATA) fapi2::putSpy(TARGET, FAPI_SPY_NAMES::ID.value, DATA)
+
+ template< TargetType K >
+ inline ReturnCode putSpy(const Target<K>& i_target,
+ const spyId_t i_spyId,
+ variable_buffer& i_data);
+#endif
+
+#if defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN)
+
+#define FAPI_PUT_SPY(TARGET, ID, DATA) fapi2::putSpy(TARGET, #ID, DATA)
+
+ template< TargetType K >
+ inline ReturnCode putSpy(const Target<K>& i_target,
+ const char* const i_spyId,
+ variable_buffer& i_data);
+#endif
+
+ /// @brief Writes spy data into a buffer holding ring data image
+ /// This API is used by L2/L3 repair to put column repair data
+ /// into a ring buffer image.
+ /// @tparam K template parameter, passed in target.
+ /// @param[in] i_target Target to operate on.
+ /// @param[in] i_spyId Id of the spy.
+ /// @param[in] i_data Buffer that holds spy data to write into ring
+ /// image.
+ /// @param[out] o_data Buffer that holds updated ring image.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependent on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// See fapiPutSpy for details on spy id specifics.
+ ///
+#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(DOXYGEN)
+
+#define FAPI_PUT_SPY_IMAGE(TARGET, ID, DATA1, DATA2) \
+ fapi2::putSpyImage(TARGET, FAPI_SPY_NAMES::ID.value, \
+ DATA1, DATA2)
+
+ template< TargetType K >
+ inline ReturnCode putSpyImage(const Target<K>& i_target,
+ const spyId_t i_spyId,
+ const variable_buffer& i_data,
+ variable_buffer& o_imageData);
+#endif
+
+#if defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN)
+
+#define FAPI_PUT_SPY_IMAGE(TARGET, ID, DATA1, DATA2) \
+ fapi2::putSpyImage(TARGET, #ID, DATA1,DATA2)
+
+ template< TargetType K >
+ inline ReturnCode putSpyImage(const Target<K>& i_target,
+ const char* const i_spyId,
+ const variable_buffer& i_data,
+ variable_buffer& o_imageData);
+#endif
+
+ /// @brief Reads spy data from a ring image buffer
+ /// @param[in] i_target Target to operate on
+ /// @param[in] i_spyId The spy's id
+ /// @param[out] o_data Buffer that holds data read from ring image.
+ /// @param[in] i_imageData Buffer that holds ring image to read data
+ /// from.
+ /// @return fapi2::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
+ ///
+ /// @note: The string version is only supported for cronus.
+ ///
+ /// The fapi design to support both FSP and cronus use of get and
+ /// put spy functions is dependent on the SPY names being expanded
+ /// to resemble a valid C identifier. This design places some
+ /// restrictions on the SPY names which can be used.
+ ///
+ /// See fapiPutSpy for details on spy id specifics.
+ ///
+#if defined(FAPI_SUPPORT_SPY_AS_ENUM) || defined(DOXYGEN)
+
+#define FAPI_GET_SPY_IMAGE(TARGET, ID, DATA1, DATA2) \
+ fapi2:getSpyImage(TARGET, FAPI_SPY_NAMES::ID.value, \
+ DATA1, DATA2)
+
+ template< TargetType K >
+ inline ReturnCode getSpyImage(const Target<K>& i_target,
+ const spyId_t i_spyId,
+ variable_buffer& o_data,
+ const variable_buffer& i_imageData);
+#endif
+
+#if defined(FAPI_SUPPORT_SPY_AS_STRING) || defined(DOXYGEN)
+
+#define FAPI_GET_SPY_IMAGE(TARGET, ID, DATA1, DATA2) \
+ fapi2::getSpyImage(TARGET, #ID, DATA1,DATA2)
+
+ template< TargetType K >
+ inline ReturnCode getSpyImage(const Target<K>& 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/hwpf/plat/include/fapi2_target.H b/hwpf/plat/include/fapi2_target.H
new file mode 100644
index 00000000..5c753e9e
--- /dev/null
+++ b/hwpf/plat/include/fapi2_target.H
@@ -0,0 +1,496 @@
+///
+/// @file fapi2_target.H
+/// @brief Common definitions for fapi2 targets
+///
+
+#ifndef __FAPI2_COMMON_TARGET__
+#define __FAPI2_COMMON_TARGET__
+
+#include <stdint.h>
+#include <vector>
+#include <target_types.H>
+#include <target_states.H>
+#include <plat_target.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 Create a Target, with a value
+ /// @param[in] Value the value (i.e., specific element this
+ /// target represents, or pointer)
+ /// @note Platforms can mangle the value and K to get a
+ /// single uint64_t in value which represents all the information
+ /// they might need. value( K | V ), for example
+ ///
+ Target(V Value);
+
+// Target(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 Get the handle.
+ /// @return V The target's handle, or value
+ ///
+ V get(void) const
+ {
+ return this->iv_handle.value;
+ }
+
+ ///
+ /// @brief Get the handle as a V
+ /// @return V The target's handle, or value
+ ///
+ inline operator V() const
+ {
+ return this->iv_handle.value;
+ }
+
+ ///
+ /// @brief Get a target's value
+ /// @return V The target's handle, or value
+ ///
+ inline V& operator()(void)
+ {
+ return this->iv_handle.value;
+ }
+
+ ///
+ /// @brief Get the target type
+ /// @return The type of target represented by this target
+ ///
+ inline TargetType getType(void) const
+ {
+ return iv_type;
+ }
+
+#ifdef __PPE__
+
+ /// Need to optimize PPE Target resoulution in a cheap manner
+ /// Brian: not sure if the this is the place for this as
+ /// this is plaform specific.
+
+ ///
+ /// @brief Get address overlay to reduce runtime processing
+ /// @return Overlay as a type V
+ ///
+ inline V getAddressOverlay(void) const
+ {
+ return this->iv_handle.fields.address_overlay;
+ }
+
+ ///
+ /// @brief Get address overlay to reduce runtime processing
+ /// @return Overlay as a type V
+ ///
+ inline uint32_t getTargetNumber(void) const
+ {
+ return static_cast<uint32_t>(this->iv_handle.fields.type_target_num);
+ }
+#endif
+
+ ///
+ /// @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> getParent(void) const;
+
+ ///
+ /// @brief Is this target a chip?
+ /// @return Return true if this target is a chip, false otherwise
+ ///
+ inline constexpr bool isChip(void) const
+ {
+// return ( (K == TARGET_TYPE_PROC_CHIP) ||
+// (K == TARGET_TYPE_MEMBUF_CHIP) );
+
+ return ( (K == TARGET_TYPE_PROC_CHIP) );
+ }
+
+ ///
+ /// @brief Is this target a chiplet?
+ /// @return Return true if this target is a chiplet, false otherwise
+ ///
+ inline constexpr bool isChiplet(void) const
+ {
+ return ( (K == TARGET_TYPE_EX) ||
+// (K == TARGET_TYPE_MBA) ||
+ (K == TARGET_TYPE_MCS) ||
+// (K == TARGET_TYPE_XBUS) ||
+// (K == TARGET_TYPE_ABUS) ||
+// (K == TARGET_TYPE_L4) ||
+ (K == TARGET_TYPE_CORE) ||
+ (K == TARGET_TYPE_EQ) ||
+// (K == TARGET_TYPE_MCA) ||
+// (K == TARGET_TYPE_MCBIST) ||
+// (K == TARGET_TYPE_MI) ||
+// (K == TARGET_TYPE_DMI) ||
+// (K == TARGET_TYPE_OBUS) ||
+// (K == TARGET_TYPE_NV) ||
+// (K == TARGET_TYPE_SBE) ||
+// (K == TARGET_TYPE_PPE) ||
+// (K == TARGET_TYPE_PERV) ||
+ (K == TARGET_TYPE_PERV) );
+// (K == TARGET_TYPE_PEC) ||
+// (K == TARGET_TYPE_PHB) );
+ }
+
+ ///
+ /// @brief Get this target's children
+ /// @tparam T The type of the parent
+ /// @param[in] i_state The desired TargetState of the children
+ /// @return std::vector<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 T>
+ inline std::vector<Target<T> >
+ getChildren(const TargetState i_state = TARGET_STATE_FUNCTIONAL) const;
+
+ ///
+ /// @brief Get the target at the other end of a bus - dimm included
+ /// @tparam T The type of the parent
+ /// @param[in] i_state The desired TargetState of the children
+ /// @return Target<T> a target representing the thing on the other end
+ /// @note Can be easily changed to a vector if needed
+ ///
+ template<TargetType T>
+ inline Target<T>
+ getOtherEnd(const TargetState i_state = TARGET_STATE_FUNCTIONAL) const;
+
+ ///
+ /// @brief Copy from a Target<O> to a Target<K>
+ /// @tparam O the target type of the other
+ ///
+ template<TargetType O>
+ inline Target( const Target<O>& 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;
+
+ union iv_handle {
+ V value;
+ struct {
+#ifdef _BIG_ENDIAN
+ V chiplet_num : 8;
+ V type_target_num : 8;
+ V type : 8;
+ V _reserved_b6 : 6;
+ V present : 1;
+ V functional : 1;
+ V address_overlay : 32;
+#else
+ V address_overlay : 32;
+ V functional : 1;
+ V present : 1;
+ V _reserved_b6 : 6;
+ V type : 8;
+ V type_target_num : 8;
+ V chiplet_num : 8;
+#endif
+ } fields;
+ // Union Constructor
+// iv_handle(V i_value = 0):value(i_value) {}
+ } iv_handle;
+ };
+
+ // EX threads map to CORE threads:
+ // t0 / t2 / t4 / t6 fused = t0 / t1 / t2 / t3 normal (c0)
+ // t1 / t3 / t5 / t7 fused = t0 / t1 / t2 / t3 normal (c1)
+ // So when splitting the EX, we need to map from EX threads
+ // to CORE threads.
+
+ ///
+ /// @brief Given a normal core thread id, translate this to
+ /// a fused core thread id. (normal to fused)
+ /// @param[in] the ordinal number of the normal core this thread belongs to
+ /// @param[in] a normal core thread id - 0, ..., 3
+ /// @return the fused core thread id
+ ///
+ inline uint8_t thread_id_n2f(const uint8_t i_ordinal, const uint8_t i_thread_id)
+ {
+ return (i_thread_id << 1) | i_ordinal;
+ }
+
+ ///
+ /// @brief Given a fused core thread id, translate this to
+ /// a normal core thread id. (fused to normal)
+ /// @param[in] a fused core thread id - 0, ..., 7
+ /// @return the normal core thread id
+ ///
+ inline uint8_t thread_id_f2n(const uint8_t i_thread_id)
+ {
+ return i_thread_id >> 1;
+ }
+
+ ///
+ /// @brief Given a normal core thread id, translate this to a
+ /// normal core bitset.
+ /// @param[in] a normal core thread id - 0, ..., 3
+ /// @return the normal core bitset
+ /// @note to got from a fused core id to a normal core bitset,
+ /// translate from a fused core thread id first.
+ ///
+ inline uint8_t thread_id2bitset(const uint8_t i_thread_id)
+ {
+ // 0xff means "set all bits"
+ static const uint8_t all_threads = 0xff;
+ static const uint8_t all_normal_threads_bitset = 0x0f;
+
+ if (i_thread_id == all_threads)
+ {
+ return all_normal_threads_bitset;
+ }
+
+ // A thread_id is really just bit index.
+ return (1 << (4 - i_thread_id - 1));
+ }
+
+ ///
+ /// @brief Given a bitset of normal core thread ids, translate this to
+ /// a bit mask of fused core thread id. (normal to fused)
+ /// @param[in] the ordinal number of the normal core this thread belongs to
+ /// @param[in] a normal core thread bitset - b0000, ..., b1111
+ /// @return the corresponding fused core bitset
+ ///
+ inline uint8_t thread_bitset_n2f(const uint8_t i_ordinal, const uint8_t i_threads)
+ {
+ // Since we only have 4 bits I think this is better than a shift-type solution
+ // for interleaving bits
+ static uint8_t core_map[] = {
+ 0b00000000, // b0000
+ 0b00000010, // b0001
+ 0b00001000, // b0010
+ 0b00001010, // b0011
+ 0b00100000, // b0100
+ 0b00100010, // b0101
+ 0b00101000, // b0110
+ 0b00101010, // b0111
+ 0b10000000, // b1000
+ 0b10000010, // b1001
+ 0b10001000, // b1010
+ 0b10001010, // b1011
+ 0b10100000, // b1100
+ 0b10100010, // b1101
+ 0b10101000, // b1110
+ 0b10101010, // b1111
+ };
+
+ return core_map[i_threads] >> i_ordinal;
+ }
+
+ ///
+ /// @brief Given a fused core thread bitset, translate this to
+ /// a normal core thread bitset. (fused to normal)
+ /// @param[in] the ordinal number of the normal core this thread belongs to
+ /// @param[in] a fused core thread bitset - b00000000, ..., b11111111
+ /// @return the corresponding normal core bitset
+ ///
+ inline uint8_t thread_bitset_f2n(const uint8_t i_ordinal, const uint8_t i_threads)
+ {
+ uint8_t normal_set = 0;
+
+ // core 0 is the left-most bit in the pair
+ uint8_t pair_mask = (i_ordinal == 0) ? 0x2 : 0x1;
+
+ // For each bit which can be set in the normal core bit_set ...
+ for( auto i = 0; i <= 3; ++i )
+ {
+ // ... grab the two fused bits which represent it ...
+ // ... and mask off the bit in the pair which represents this normal core ...
+ // (the << 1 shifts the masks over as we walk the pairs of bits)
+ uint8_t bits = (((3 << (i << 1)) & i_threads) & (pair_mask << (i << 1)));
+
+ // ... if either bit is set, set the corresponding bit in
+ // the normal core bitset.
+ normal_set |= (bits != 0) << i;
+ }
+ return normal_set;
+ }
+
+ ///
+ /// @brief Return the string interpretation of this target
+ /// @tparam T The type of the target
+ /// @param[in] i_target Target<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 >
+ inline void toString(const Target<T>& i_target, char* i_buffer, size_t i_bsize);
+
+ ///
+ /// @brief Return the string interpretation of this target
+ /// @tparam T The type of the target
+ /// @tparam B The type of the buffer
+ /// @param[in] A pointer to the Target<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 >
+ inline void toString(const Target<T>* 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>
+ inline Target<T> 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> > a vector of present/functional
+ /// children
+ ///
+ template<TargetType T>
+ inline std::vector<Target<T> > getChildren()
+ {
+ // For testing
+ return {Target<T>(), Target<T>()};
+ }
+#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>
+ /// @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 B>
+ inline void toString(const Target<T>& 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/hwpf/plat/include/hw_access.H b/hwpf/plat/include/hw_access.H
index 591eab27..12da736b 100644
--- a/hwpf/plat/include/hw_access.H
+++ b/hwpf/plat/include/hw_access.H
@@ -38,6 +38,7 @@
#include <variable_buffer.H>
#endif
+#include <utils.H>
#include <plat_hw_access.H>
#include <fapi2_hw_access.H>
@@ -102,11 +103,7 @@ namespace fapi2
inline void getScom(const Target<K>& i_target, const uint64_t i_address,
buffer<uint64_t>& o_data)
{
- // PLAT_GETSCOM(i_target,
-// (uint32_t)(i_address & BITS(40,24)),
-// &(o_data()));
-
-// fapi2::ReturnCode l_rc;
+
PLAT_GETSCOM(current_err,
i_target,
(uint32_t)(i_address & BITS(40,24)),
@@ -122,12 +119,13 @@ namespace fapi2
/// @return fapi::ReturnCode. FAPI2_RC_SUCCESS if success, else error code.
template< TargetType K >
inline void putScom(const Target<K>& i_target, const uint64_t i_address,
- buffer<uint64_t>& i_data)
+ buffer<uint64_t> i_data)
{
- PLAT_PUTSCOM(i_target,
+ PLAT_PUTSCOM(current_err,
+ i_target,
(uint32_t)(i_address & BITS(40,24)),
- &(i_data()));
+ i_data());
}
/// @brief Read-modify-write a SCOM register on a chip
@@ -140,12 +138,13 @@ namespace fapi2
template< TargetType K >
inline void modifyScom( const Target<K>& i_target,
const uint64_t i_address,
- const buffer<uint64_t>& i_data,
+ const buffer<uint64_t> i_data,
const ChipOpModifyMode i_modifyMode)
{
fapi2::buffer<uint64_t> l_modifyDataBuffer;
- PLAT_GETSCOM(i_target,
+ PLAT_GETSCOM(current_err,
+ i_target,
(uint32_t)(i_address & BITS(40,24)),
&(l_modifyDataBuffer()));
@@ -164,9 +163,10 @@ namespace fapi2
l_modifyDataBuffer ^= i_data;
}
- PLAT_PUTSCOM(i_target,
+ PLAT_PUTSCOM(current_err,
+ i_target,
(uint32_t)(i_address & BITS(40,24)),
- &(l_modifyDataBuffer()));
+ l_modifyDataBuffer());
return;
}
@@ -180,16 +180,17 @@ namespace fapi2
template< TargetType K >
inline void putScomUnderMask(const Target<K>& i_target,
const uint64_t i_address,
- buffer<uint64_t>& i_data,
- buffer<uint64_t>& i_mask)
+ buffer<uint64_t> i_data,
+ buffer<uint64_t> i_mask)
{
fapi2::buffer<uint64_t> l_modifyDataBuffer = i_data;
l_modifyDataBuffer &= i_mask;
- PLAT_PUTSCOM(i_target,
+ PLAT_PUTSCOM(current_err,
+ i_target,
(uint32_t)(i_address & BITS(40,24)),
- &(l_modifyDataBuffer()));
+ l_modifyDataBuffer());
return;
}
diff --git a/hwpf/plat/include/plat_attributes.H b/hwpf/plat/include/plat_attributes.H
new file mode 100644
index 00000000..2a55b221
--- /dev/null
+++ b/hwpf/plat/include/plat_attributes.H
@@ -0,0 +1,36 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2014 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file plat_attributes.H
+ * @brief Platform specific attribute headers
+ */
+
+#ifndef __PLAT_ATTTRIBUTE_H__
+#define __PLAT_ATTTRIBUTE_H__
+
+#include <fapi2AttributeService.H>
+#include <fapi2AttributeIds.H> // Generated file
+
+#endif // __PLAT_ATTTRIBUTE_H__
diff --git a/hwpf/plat/include/plat_error_scope.H b/hwpf/plat/include/plat_error_scope.H
new file mode 100644
index 00000000..a2de6bd5
--- /dev/null
+++ b/hwpf/plat/include/plat_error_scope.H
@@ -0,0 +1,65 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2014 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file plat_error_scope.H
+ * @brief platform definitions which create a scope for automatic error handling
+ */
+
+#ifndef __FAPI2_PLAT_ERROR_SCOPE__
+#define __FAPI2_PLAT_ERROR_SCOPE__
+
+/// @cond
+#define PLAT_FAPI_TRY_NO_TRACE( __operation__ ) \
+ (__operation__)
+
+#define PLAT_FAPI_TRY_TRACE( __operation__, ... ) \
+ FAPI_DBG(__VA_ARGS)); \
+ (__operation__)
+
+///
+/// @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 Temporary macro for error label until all are removed.
+/// @todo REMOVE this in time.
+#define FAPI_CLEANUP() \
+fapi_try_exit:
+/// @endcond
+
+#endif
diff --git a/hwpf/plat/include/plat_hw_access.H b/hwpf/plat/include/plat_hw_access.H
index 9bfccfcc..7d8e3c86 100644
--- a/hwpf/plat/include/plat_hw_access.H
+++ b/hwpf/plat/include/plat_hw_access.H
@@ -51,8 +51,8 @@ asm volatile \
PPE_LVDX(_m_base.getAddressOverlay(), (uint32_t)(_m_offset & BITS(40,24)), _m_data)
/// PutScom
-#define PLAT_PUTSCOM(_m_base, _m_offset, _m_data) \
- PPE_STVDX(_m_rc, _m_base.getAddressOverlay(), (uint32_t)(_m_offset & BITS(40,24)), _m_data)
+#define PLAT_PUTSCOM(_m_rc, _m_base, _m_offset, _m_data) \
+ PPE_STVDX(_m_base.getAddressOverlay(), (uint32_t)(_m_offset & BITS(40,24)), _m_data)
/// ModifyScom
#define PLAT_MODSCOM(_m_base, _m_offset, _m_data, _m_mode) \
diff --git a/hwpf/plat/include/plat_trace.H b/hwpf/plat/include/plat_trace.H
index 9104e767..423ef6ea 100644
--- a/hwpf/plat/include/plat_trace.H
+++ b/hwpf/plat/include/plat_trace.H
@@ -38,6 +38,15 @@
#include <stdio.h>
#include <stdint.h>
+// @todo update these headers with extern "C" in a future commit
+// or not and leave this just as it is.
+extern "C"
+{
+#include "pk.h"
+#include <pk_trace.h>
+#include "trac_interface.h"
+}
+
// Why not a #define, why is this in the fapi2 namespace?
// To prevent problems with Cronus and the fapi1 definitions.
namespace fapi2
@@ -47,9 +56,16 @@ namespace fapi2
// 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")
+ PK_TRACE(_fmt_, ##_args_);
+
+
+/* The following is a desirous trace entry but the second line has a
+ compilation issue that is unresolved
+
+#define FAPI_TRACE(_id_, _fmt_, _args_...) \
+ PK_TRACE("%s: %s:%d ", _id_, __FUNCTION__, __LINE__); \
+ PK_TRACE(_fmt_, ##_args_);
+*/
#define FAPI_INF(_fmt_, _args_...) FAPI_TRACE("inf", _fmt_, ##_args_)
diff --git a/hwpf/plat/include/return_code.H b/hwpf/plat/include/return_code.H
new file mode 100644
index 00000000..fd2f7c29
--- /dev/null
+++ b/hwpf/plat/include/return_code.H
@@ -0,0 +1,108 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: $ */
+/* */
+/* OpenPOWER HostBoot Project */
+/* */
+/* Contributors Listed Below - COPYRIGHT 2012,2014 */
+/* [+] International Business Machines Corp. */
+/* */
+/* */
+/* Licensed under the Apache License, Version 2.0 (the "License"); */
+/* you may not use this file except in compliance with the License. */
+/* You may obtain a copy of the License at */
+/* */
+/* http://www.apache.org/licenses/LICENSE-2.0 */
+/* */
+/* Unless required by applicable law or agreed to in writing, software */
+/* distributed under the License is distributed on an "AS IS" BASIS, */
+/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
+/* implied. See the License for the specific language governing */
+/* permissions and limitations under the License. */
+/* */
+/* IBM_PROLOG_END_TAG */
+/**
+ * @file return_code.H
+ * @brief definitions for fapi2 return codes
+ */
+
+#ifndef __FAPI2_RETURN_CODE__
+#define __FAPI2_RETURN_CODE__
+
+#include <stdint.h>
+#include <return_code_defs.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 uint64_t i_rc = FAPI2_RC_SUCCESS):
+ iv_rc(i_rc)
+ {};
+
+ ///
+ /// @brief integral type conversion function. Returns the error code
+ /// @return The error code
+ ///
+ inline operator uint64_t() const { return iv_rc; }
+
+ ///
+ /// @brief Returns true iff iv_rc == SUCCESS
+ /// @return true or false
+ ///
+ inline operator bool() const { return iv_rc == FAPI2_RC_SUCCESS; }
+
+ ///
+ /// @brief Assignement operator
+ ///
+#ifdef DOXYGEN
+ inline ReturnCode& operator=(const uint64_t& rhs)
+ inline ReturnCode& operator=(const ReturnCodes& rhs)
+#endif
+
+ inline bool operator==(const uint64_t& rhs) const
+ { return rhs == iv_rc; }
+
+ inline bool operator==(const ReturnCodes& rhs) const
+ { return rhs == iv_rc; }
+
+ inline bool operator!=(const uint64_t& rhs) const
+ { return rhs != iv_rc; }
+
+ inline bool operator!=(const ReturnCodes& rhs) const
+ { return rhs != iv_rc; }
+
+ private:
+ uint64_t iv_rc;
+ };
+
+ /// This implementation assumes no exception handling and leverages thread-local
+ /// storage. For platforms without thread support, a global variable will
+ /// suffice for the error state.
+// extern thread_local ReturnCode current_err; /// the current error state
+ extern ReturnCode current_err; /// the current error state
+ extern thread_local uint64_t pib_error_mask; /// the pib mask
+ extern thread_local uint64_t operational_state; /// the operational mode
+}
+
+#endif
diff --git a/hwpf/plat/include/target.H b/hwpf/plat/include/target.H
index 0d7832b5..e2fe550b 100644
--- a/hwpf/plat/include/target.H
+++ b/hwpf/plat/include/target.H
@@ -24,530 +24,281 @@
/* IBM_PROLOG_END_TAG */
/**
* @file target.H
- * @brief definitions for fapi2 targets
+ * @brief platform specializations for fapi2 targets
*/
#ifndef __FAPI2_TARGET__
#define __FAPI2_TARGET__
-#include <stdint.h>
-//#include <vector>
-#include <target_types.H>
+#include <plat_target.H>
+#include <plat_target_parms.H>
+#include <fapi2_target.H>
#include <utils.H>
-#include "plat_target_parms.H"
-
-#define MC_ENABLE 0x1 << 6
-#define MC_WRITE 5
-#define MC_READ_OR 0
-#define MC_READ_AND 1
-
-#define EX_ADDRESS_MASK 0x0000FF00
-
-#ifdef __ASSEMBLER__
-
-#ifndef ULL
-#define ULL(x) x
-#endif
-
-#else
-
-#ifndef ULL
-#define ULL(x) x##ull
-
-#endif
-
-#endif // __ASSEMBLER
-
-/// Create a multi-bit mask of \a n bits starting at bit \a b
-#define BITS(b, n) ((ULL(0xffffffffffffffff) << (64 - (n))) >> (b))
-
-/// Create a single bit mask at bit \a b
-#define BIT(b) BITS((b), 1)
-
+#include <stdio.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 );
+{
+ /// @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
///
- /// @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 = uint64_t>
- class Target
+ template<TargetType K, typename V>
+ Target<K, V>::Target(V Value)
{
- public:
-
- ///
- /// @brief Create a Target, with a value
- /// @param[in] V 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
- ///
+ static_assert( ((K == TARGET_TYPE_CORE) &
+ (K == TARGET_TYPE_EQ) ) != true,
+ "TARGET_TYPE_CORE and TARGET_TYPE_EQ cannot be specified at the same time");
- /// Default constructor is basically a TARGET_TYPE_ALL
- Target()
+ this->iv_handle.value = 0;
+ if(K & TARGET_TYPE_PROC_CHIP)
{
- this->iv_handle.fields.chiplet_num = 0;
-// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
+ this->iv_handle.fields.chiplet_num = Value;
+ this->iv_handle.fields.type = TARGET_TYPE_PROC_CHIP;
+ this->iv_handle.fields.type_target_num = Value; // TODO: check this
}
-
- Target( V Value )
- {
- static_assert( ((K == TARGET_TYPE_CORE) &
- (K == TARGET_TYPE_EQ) ) != true,
- "TARGET_TYPE_CORE and TARGET_TYPE_EQ cannot be specified at the same time");
-
- if(K & TARGET_TYPE_PROC_CHIP)
- {
- this->iv_handle.fields.chiplet_num = Value;
- this->iv_handle.fields.type = TARGET_TYPE_PROC_CHIP;
- this->iv_handle.fields.type_target_num = Value; // TODO: check this
-// this->iv_address.fields.chiplet_num = Value;
- }
-
- if(K & TARGET_TYPE_PERV)
- {
- this->iv_handle.fields.chiplet_num = Value;
- this->iv_handle.fields.type = TARGET_TYPE_PERV | TARGET_TYPE_PROC_CHIP;
- this->iv_handle.fields.type_target_num = Value; // TODO: check this
-// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
- }
-
- if(K & TARGET_TYPE_CORE)
- {
- /*
- if (Value > CORE_CHIPLET_COUNT)
- {
- PK_TRACE("Chiplet number is greater than CORE_CHIPLET_COUNT");
- return -1;
- }
- */
- this->iv_handle.fields.chiplet_num = Value + CORE_CHIPLET_OFFSET;
- this->iv_handle.fields.type = TARGET_TYPE_CORE;
- this->iv_handle.fields.type_target_num = Value;
-// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
- }
- if(K & TARGET_TYPE_EQ)
- {
- this->iv_handle.fields.chiplet_num = Value + EQ_CHIPLET_OFFSET;
- this->iv_handle.fields.type = TARGET_TYPE_EQ;
- this->iv_handle.fields.type_target_num = Value;
-// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
- }
-
- if(K & TARGET_TYPE_EX)
- {
-
- this->iv_handle.fields.chiplet_num = (Value / 2) + EX_CHIPLET_OFFSET;
- this->iv_handle.fields.type = TARGET_TYPE_EX;
- this->iv_handle.fields.type_target_num = Value;
-// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
- }
-
- if(K & TARGET_TYPE_EQ_MC_WRITE)
- {
- this->iv_handle.fields.chiplet_num =
- (((MC_ENABLE) |
- ((MC_WRITE << 3) | (Value & 0x07))) &
- BITS(57,7));
- this->iv_handle.fields.type = TARGET_TYPE_EQ_MC_WRITE;
-// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
- }
-
- if(K & TARGET_TYPE_EQ_MC_READOR)
- {
- this->iv_handle.fields.chiplet_num =
- (((MC_ENABLE) |
- ((MC_READ_OR << 3) | (Value & 0x07))) &
- BITS(57,7));
- this->iv_handle.fields.type = TARGET_TYPE_EQ_MC_READOR;
-// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
- }
-
- if(K & TARGET_TYPE_EQ_MC_READAND)
- {
- this->iv_handle.fields.chiplet_num =
- (((MC_ENABLE) |
- ((MC_READ_AND << 3) | (Value & 0x07))) &
- BITS(57,7));
- this->iv_handle.fields.type = TARGET_TYPE_EQ_MC_READAND;
-// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
- }
-
- if(K & TARGET_TYPE_CORE_MC_WRITE)
- {
- this->iv_handle.fields.chiplet_num =
- (((MC_ENABLE) |
- ((MC_WRITE << 3) | (Value & 0x07))) &
- BITS(57,7));
- this->iv_handle.fields.type = TARGET_TYPE_CORE_MC_WRITE;
-// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
- }
-
- if(K & TARGET_TYPE_CORE_MC_READOR)
- {
- this->iv_handle.fields.chiplet_num =
- (((MC_ENABLE) |
- ((MC_READ_OR << 3) | (Value & 0x07))) &
- BITS(57,7));
- this->iv_handle.fields.type = TARGET_TYPE_CORE_MC_READOR;
-// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
- }
-
- if(K & TARGET_TYPE_CORE_MC_READAND)
- {
- this->iv_handle.fields.chiplet_num =
- (((MC_ENABLE) |
- ((MC_READ_AND << 3) | (Value & 0x07))) &
- BITS(57,7));
- this->iv_handle.fields.type = TARGET_TYPE_CORE_MC_READAND;
-// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
- }
-
- if(K == TARGET_TYPE_ALL)
- {
- this->iv_handle.fields.chiplet_num = Value;
- this->iv_handle.fields.type = TARGET_TYPE_ALL;
-// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
- }
-
-// if(K == TARGET_TYPE_ADDRESS)
-// {
-// this->iv_handle.fields.chiplet_num = Value;
-// this->iv_address.fields.chiplet_num = this->iv_handle.fields.chiplet_num;
-// }
- }
-
- ///
- /// @brief Assignment Operator.
- /// @param[in] i_right Reference to Target to assign from.
- /// @return Reference to 'this' Target
- ///
- Target<K,V>& operator=(const Target<K,V>& i_right)
+ if(K & TARGET_TYPE_PERV)
{
- this->iv_handle.value = i_right->iv_handle.value;
- this->iv_addresss.value = i_right->iv_address.value;
- return *this;
- }
-
- ///
- /// @brief Equality Comparison Operator
- /// @param[in] i_right Reference to Target to compare.
- /// @return bool. True if equal.
- ///
- bool operator==(const Target<K,V>& i_right) const
- {
- if (this->iv_handle.value == i_right->iv_handle.value)
- return true;
- else
- return false;
- }
- ///
- /// @brief Inquality Comparison Operator
- /// @param[in] i_right Reference to Target to compare.
- /// @return bool. True if equal.
- ///
- bool operator!=(const Target<K,V>& i_right) const
- {
- if (this->iv_handle.value != i_right->iv_handle.value)
- return true;
- else
- return false;
+ this->iv_handle.fields.chiplet_num = Value;
+ this->iv_handle.fields.type = TARGET_TYPE_PERV | TARGET_TYPE_PROC_CHIP;
+ this->iv_handle.fields.type_target_num = Value; // TODO: check this
}
- ///
- /// @brief Get the handle.
- /// @return V The target's handle, or value
- ///
- V get(void) const
- {
- return this->iv_handle.value;
- }
-
- ///
- /// @brief Get the handle as a V
- /// @return V The target's handle, or value
- ///
- operator V() const
+ if(K & TARGET_TYPE_CORE)
{
- return this->iv_handle.value;
- }
-
- ///
- /// @brief Get a target's value
- /// @return V The target's handle, or value
- ///
- V& operator()(void)
- {
- return *this->iv_handle;
+ /*
+ if (Value > CORE_CHIPLET_COUNT)
+ {
+ PK_TRACE("Chiplet number is greater than CORE_CHIPLET_COUNT");
+ return -1;
+ }
+ */
+ this->iv_handle.fields.chiplet_num = Value + CORE_CHIPLET_OFFSET;
+ this->iv_handle.fields.type = TARGET_TYPE_CORE;
+ this->iv_handle.fields.type_target_num = Value;
}
- ///
- /// @brief Get the target type
- /// @return The type of target represented by this target
- ///
- TargetType getType(void) const
+ if(K & TARGET_TYPE_EQ)
{
- return (TargetType)this->iv_handle.fields.type;
+ this->iv_handle.fields.chiplet_num = Value + EQ_CHIPLET_OFFSET;
+ this->iv_handle.fields.type = TARGET_TYPE_EQ;
+ this->iv_handle.fields.type_target_num = Value;
}
- ///
- /// @brief Get address overlay to reduce runtime processing
- /// @return Overlay as a type V
- ///
- V getAddressOverlay(void) const
- {
- return this->iv_handle.fields.address_overlay;
+ if(K & TARGET_TYPE_EX)
+ {
+
+ this->iv_handle.fields.chiplet_num = (Value / 2) + EX_CHIPLET_OFFSET;
+ this->iv_handle.fields.type = TARGET_TYPE_EX;
+ this->iv_handle.fields.type_target_num = Value;
+ this->iv_handle.fields.present = 1;
}
+// if(K & TARGET_TYPE_EQ_MC_WRITE)
+// {
+// this->iv_handle.fields.chiplet_num =
+// (((MC_ENABLE) |
+// ((MC_WRITE << 3) | (Value & 0x07))) &
+// BITS(57,7));
+// this->iv_handle.fields.type = TARGET_TYPE_EQ_MC_WRITE;
+// }
+//
+// if(K & TARGET_TYPE_EQ_MC_READOR)
+// {
+// this->iv_handle.fields.chiplet_num =
+// (((MC_ENABLE) |
+// ((MC_READ_OR << 3) | (Value & 0x07))) &
+// BITS(57,7));
+// this->iv_handle.fields.type = TARGET_TYPE_EQ_MC_READOR;
+// }
+//
+// if(K & TARGET_TYPE_EQ_MC_READAND)
+// {
+// this->iv_handle.fields.chiplet_num =
+// (((MC_ENABLE) |
+// ((MC_READ_AND << 3) | (Value & 0x07))) &
+// BITS(57,7));
+// this->iv_handle.fields.type = TARGET_TYPE_EQ_MC_READAND;
+// }
+//
+// if(K & TARGET_TYPE_CORE_MC_WRITE)
+// {
+// this->iv_handle.fields.chiplet_num =
+// (((MC_ENABLE) |
+// ((MC_WRITE << 3) | (Value & 0x07))) &
+// BITS(57,7));
+// this->iv_handle.fields.type = TARGET_TYPE_CORE_MC_WRITE;
+// }
+//
+// if(K & TARGET_TYPE_CORE_MC_READOR)
+// {
+// this->iv_handle.fields.chiplet_num =
+// (((MC_ENABLE) |
+// ((MC_READ_OR << 3) | (Value & 0x07))) &
+// BITS(57,7));
+// this->iv_handle.fields.type = TARGET_TYPE_CORE_MC_READOR;
+// }
+//
+// if(K & TARGET_TYPE_CORE_MC_READAND)
+// {
+// this->iv_handle.fields.chiplet_num =
+// (((MC_ENABLE) |
+// ((MC_READ_AND << 3) | (Value & 0x07))) &
+// BITS(57,7));
+// this->iv_handle.fields.type = TARGET_TYPE_CORE_MC_READAND;
+// }
-#if 0
- ///
- /// @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>
- Target<T,V> getParent(void) const
- {
- static_assert((T & ~(TARGET_TYPE_PROC_CHIP | TARGET_TYPE_PERV) != 0),
- "Only TARGET_TYPE_PROC_CHIP and TARGET_TYPE_PERV parent types supported");
-
- static_assert( ((((T & TARGET_TYPE_PROC_CHIP) == 0) &
- (T & TARGET_TYPE_PERV ) == 0) ),
- "Either TARGET_TYPE_PROC_CHIP or TARGET_TYPE_PERV parent type must be specified");
- }
-
- ///
- /// @brief Get this target's children
- /// @tparam T The type of the parent
- /// @return std::vector<Target<T> > a vector of present/functional
- /// children
- ///
- template< TargetType T>
- std::vector<Target<T,V> > getChildren(void) const
- {
- static_assert( ((T & ~TARGET_TYPE_PROC_CHIP) != 0 ) != true,
- "Only TARGET_TYPE_CHIP and TARGET_TYPE_EQ child types supported");
-
- if(K & TARGET_TYPE_PROC_CHIP)
- {
- std::vector<Target<T,V> chip_children(CHIPLET_COUNT);
- for (int i = 0; i < CHIPLET_COUNT; i++)
- {
- if (this->iv_handle.fields.type == TARGET_TYPE_PROC_CHIP &
- this->iv_handle.fields.present = 1 &
- this->iv_handle.fields.functional = 1 )
- {
- chip_children.push_back(this->iv_handle)
- }
- }
- return chip_children;
- }
-
- if(K & TARGET_TYPE_PERV)
- {
- this->iv_handle.fields.chiplet_num = Value;
- // this->iv_handle.fields.type_perv = 1;
- this->iv_handle.fields.type_target_num = 0;
- }
+ if(K == TARGET_TYPE_ALL)
+ {
+ this->iv_handle.fields.chiplet_num = Value;
+ this->iv_handle.fields.type = TARGET_TYPE_ALL;
+ }
+ this->iv_handle.fields.present = 1;
+ this->iv_handle.fields.address_overlay =
+ this->iv_handle.fields.chiplet_num << 24;
+
+ }
- }
+ ///
+ /// @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)
+ {
+ this->iv_handle.value = i_right->iv_handle.value;
+ 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
+ {
+ if (this->iv_handle.value == i_right->iv_handle.value)
+ return true;
+ else
+ return false;
+ }
- ///
- /// @brief Get the target at the other end of a bus - dimm included
- /// @tparam T The type of the parent
- /// @return Target<T> a target representing the thing on the other end
- /// @note Can be easily changed to a vector if needed
- ///
- template<TargetType T>
- Target<T,K> getOtherEnd(void) const
- {
- static_assert( false, "getOtherEnd() is not supported on PPE platforms");
- }
-#endif
+ ///
+ /// @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
+ {
+ if (this->iv_handle.value != i_right->iv_handle.value)
+ return true;
+ else
+ return false;
+ }
- ///
- /// @brief Copy from a Target<O> to a Target<K>
- /// @tparam O the target type of the other
- ///
- template<TargetType O>
- Target<K,V>( const Target<O>& Other ):
- Target<K,V>(Other.get())
- {
- static_assert( (K & O) != 0,
- "unable to cast Target, no shared types");
+ ///
+ /// @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> Target<K, V>::getParent(void) const
+ {
+ return this->iv_handle.value;
+ }
- static_assert( bitCount<K>::count >= bitCount<O>::count,
- "unable to cast to specialized Target");
- }
+ ///
+ /// @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> >
+ 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>(), Target<T>()};
+ }
- private:
+ ///
+ /// @brief Get the target at the other end of a bus - dimm included
+ /// @tparam T The type of the parent
+ /// @param[in] i_state The desired TargetState of the children
+ /// @return Target<T> a target representing the thing on the other end
+ /// @note Can be easily changed to a vector if needed
+ ///
+ template<TargetType K, typename V>
+ template<TargetType T>
+ inline Target<T>
+ Target<K, V>::getOtherEnd(const TargetState i_state) const
+ {
+// static_assert( false, "getOtherEnd() is not supported on PPE platforms");
+ }
-// union {
-// V value;
-// struct {
-// #ifdef _BIG_ENDIAN
-// V chiplet_num : 8;
-// V _reserved_b24 : 24;
-// #else
-// V _reserved_b24 : 24;
-// V chiplet_num : 8;
-// #endif
-// } fields;
-//
-// } iv_address;
-//
- union {
- V value;
- struct {
-#ifdef _BIG_ENDIAN
- V chiplet_num : 8;
- V type_target_num : 8;
- V type : 8;
- V _reserved_b6 : 6;
- V present : 1;
- V functional : 1;
- V address_overlay : 32;
-#else
- V address_overlay : 32;
- V functional : 1;
- V present : 1;
- V _reserved_b6 : 6;
- V type : 8;
- V type_target_num : 8;
- V chiplet_num : 8;
-#endif
- } fields;
- } iv_handle ;
-
-// uint64_t iv_present_children;
-// uint64_t iv_functional_children;
- };
-
+ ///
+ /// @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 >
+ inline void toString(const Target<T>& i_target, char* i_buffer, size_t i_bsize)
+ {
+ snprintf(i_buffer, i_bsize, "Target 0x%lx/0x%x", i_target.get(), T);
+ }
-#if 0
///
/// @brief Return the string interpretation of this target
/// @tparam T The type of the target
/// @tparam B The type of the buffer
- /// @param[in] The Target<T>
- /// @param[in] The buffer
+ /// @param[in] 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 B>
- void toString(const Target<T>& i_target, B& i_buffer)
+ template< TargetType T >
+ inline void toString(const Target<T>* i_target, char* i_buffer, size_t i_bsize)
{
- static_assert( false, "toString is not supported on PPE platforms");
+ 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] uint64_t representing the ordinal number of
+ /// @param[in] Ordinal representing the ordinal number of
/// the desired target
/// @return Target<T> the target requested
///
template<TargetType T>
- Target<T> getTarget(uint64_t Ordinal)
+ inline Target<T> getTarget(uint64_t Ordinal)
{
// For testing
return Target<T>(Ordinal);
}
-#endif
- // 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> > a vector of present/functional
- /// children
- ///
- template<TargetType T>
- std::vector<Target<T> > getChildren()
- {
- // For testing
- return {Target<T>(), Target<T>()};
- }
-#endif
-
- ///
- /// @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 >
- constexpr bool is_same(void)
- { return (K & T) != 0; }
-
-
-
+}
-};
-//#include "plat_ppe_targets_hold.H"
#endif
diff --git a/hwpf/plat/include/target_types.H b/hwpf/plat/include/target_types.H
index 19465982..4db4cf26 100644
--- a/hwpf/plat/include/target_types.H
+++ b/hwpf/plat/include/target_types.H
@@ -94,8 +94,6 @@ namespace fapi2
// TARGET_TYPE_CME_CORE1 = 0x80000000, ///< CME Core1 (CME only)
// TARGET_TYPE_ADDRESS = 0xAAAAAAAA, ///< Address Overlay Type
// TARGET_TYPE_ALL = 0xFFFFFFFF, ///< Any/All types
- };
-
// Mappings to target types found in the error xml files
TARGET_TYPE_EX_CHIPLET = TARGET_TYPE_EX,
diff --git a/hwpf/plat/include/utils.H b/hwpf/plat/include/utils.H
index 8a86e2ed..216656c8 100644
--- a/hwpf/plat/include/utils.H
+++ b/hwpf/plat/include/utils.H
@@ -52,5 +52,20 @@
/// Create a single bit mask at bit \a b
#define BIT(b) BITS((b), 1)
+#ifdef _BIG_ENDIAN
+
+#define revle16(x) x
+#define revle32(x) x
+#define revle64(x) x
+
+#else
+
+uint16_t revle16(uint16_t i_x);
+uint32_t revle32(uint32_t i_x);
+uint64_t revle64(uint64_t i_x);
+
+#endif
+
+
#endif // FAPI2_UTILS_H_
diff --git a/hwpf/plat/src/fapi2ppefiles.mk b/hwpf/plat/src/fapi2ppefiles.mk
index debd93f5..1f913872 100644
--- a/hwpf/plat/src/fapi2ppefiles.mk
+++ b/hwpf/plat/src/fapi2ppefiles.mk
@@ -19,6 +19,8 @@
FAPI2-C-SOURCES += fapi2PlatAttributeService.C
+FAPI2-C-SOURCES += plat_utils.C
+
FAPI2-S-SOURCES =
diff --git a/hwpf/plat/src/plat_utils.C b/hwpf/plat/src/plat_utils.C
index bc23c4b5..18aa4444 100644
--- a/hwpf/plat/src/plat_utils.C
+++ b/hwpf/plat/src/plat_utils.C
@@ -1,3 +1,4 @@
+
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
@@ -28,6 +29,8 @@
#include <stdint.h>
#include <plat_trace.H>
#include <return_code.H>
+
+#ifndef __PPE__
#include <error_info.H>
namespace fapi2
@@ -74,7 +77,7 @@ namespace fapi2
(*i)->iv_procedure, (*i)->iv_calloutPriority);
}
- FAPI_DBG("busCallouts: %lu", ei->iv_busCallouts.size());
+e FAPI_DBG("busCallouts: %lu", ei->iv_busCallouts.size());
for( auto i = ei->iv_busCallouts.begin(); i != ei->iv_busCallouts.end();
++i )
{
@@ -133,3 +136,77 @@ namespace fapi2
return FAPI2_RC_SUCCESS;
}
};
+
+
+/// Byte-reverse a 16-bit integer if on a little-endian machine
+
+uint16_t
+revle16(uint16_t i_x)
+{
+ uint16_t rx;
+
+#ifndef _BIG_ENDIAN
+ uint8_t *pix = (uint8_t*)(&i_x);
+ uint8_t *prx = (uint8_t*)(&rx);
+
+ prx[0] = pix[1];
+ prx[1] = pix[0];
+#else
+ rx = i_x;
+#endif
+
+ return rx;
+}
+
+#endif
+
+/// Byte-reverse a 32-bit integer if on a little-endian machine
+
+uint32_t
+revle32(uint32_t i_x)
+{
+ uint32_t rx;
+
+#ifndef _BIG_ENDIAN
+ uint8_t *pix = (uint8_t*)(&i_x);
+ uint8_t *prx = (uint8_t*)(&rx);
+
+ prx[0] = pix[3];
+ prx[1] = pix[2];
+ prx[2] = pix[1];
+ prx[3] = pix[0];
+#else
+ rx = i_x;
+#endif
+
+ return rx;
+}
+
+
+/// Byte-reverse a 64-bit integer if on a little-endian machine
+
+uint64_t
+revle64(const uint64_t i_x)
+{
+ uint64_t rx;
+
+#ifndef _BIG_ENDIAN
+ uint8_t *pix = (uint8_t*)(&i_x);
+ uint8_t *prx = (uint8_t*)(&rx);
+
+ prx[0] = pix[7];
+ prx[1] = pix[6];
+ prx[2] = pix[5];
+ prx[3] = pix[4];
+ prx[4] = pix[3];
+ prx[5] = pix[2];
+ prx[6] = pix[1];
+ prx[7] = pix[0];
+#else
+ rx = i_x;
+#endif
+
+ return rx;
+}
+
+
OpenPOWER on IntegriCloud