summaryrefslogtreecommitdiffstats
path: root/src/import/hwpf/fapi2/include/variable_buffer.H
diff options
context:
space:
mode:
authorBrian Silver <bsilver@us.ibm.com>2015-03-13 10:50:16 -0500
committerPatrick Williams <iawillia@us.ibm.com>2015-12-11 13:40:20 -0600
commit3bb48d75411345dc6f01ed5b19c632c90702d463 (patch)
treec7d03e5c6c5b15d7efacab34ee2d145f7cffd323 /src/import/hwpf/fapi2/include/variable_buffer.H
parent5a2a0c9508b0a42faef465c2e0f6085285913618 (diff)
downloadtalos-hostboot-3bb48d75411345dc6f01ed5b19c632c90702d463.tar.gz
talos-hostboot-3bb48d75411345dc6f01ed5b19c632c90702d463.zip
Buffer, targeting updates
Update target types for ex, l2/l3 Add variable_buffer resize Update, fix, variable_buffer insert/extract variable_buffer array constructor -Wall clean up Refactor buffer::insert, bit_lengths Change-Id: I2bbec294f275a80c33917dc2df2f8b8220f6d8d6 Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/16359 Reviewed-by: Matt K. Light <mklight@us.ibm.com> Reviewed-by: MATTHEW A. PLOETZ <maploetz@us.ibm.com> Reviewed-by: Brian Silver <bsilver@us.ibm.com> Tested-by: Brian Silver <bsilver@us.ibm.com>
Diffstat (limited to 'src/import/hwpf/fapi2/include/variable_buffer.H')
-rw-r--r--src/import/hwpf/fapi2/include/variable_buffer.H316
1 files changed, 270 insertions, 46 deletions
diff --git a/src/import/hwpf/fapi2/include/variable_buffer.H b/src/import/hwpf/fapi2/include/variable_buffer.H
index a12808308..95183b32f 100644
--- a/src/import/hwpf/fapi2/include/variable_buffer.H
+++ b/src/import/hwpf/fapi2/include/variable_buffer.H
@@ -73,26 +73,27 @@ namespace fapi2
/// @param[in] i_target_start_bit The starting bit position in this
/// @param[in] i_length The length, in bits, the user wants copied.
///
- template<typename unit_type, typename bits_type>
+ template<typename unit_type, typename bits_type, typename output_type>
inline fapi2::ReturnCode _insert(const unit_type* i_source,
bits_type i_source_length,
- unit_type* i_target,
+ output_type* i_target,
bits_type i_target_length,
bits_type i_source_start_bit,
bits_type i_target_start_bit,
bits_type i_length)
{
- const bits_type bits_per_unit = fapi2::parameterTraits<unit_type>::bit_length;
+ const bits_type bits_per_input_unit = parameterTraits<unit_type>::bit_length();
+ const bits_type bits_per_output_unit =parameterTraits<output_type>::bit_length();
- // tartgetStart is defaulted to the sizeof(target) - (sizeof(source) - i_source_start_bit)
+ // targetStart is defaulted to the sizeof(target) - (sizeof(source) - i_source_start_bit)
// which makes this act like insert from right
- if (i_target_start_bit == ~0)
+ if (i_target_start_bit == static_cast<bits_type>(~0))
{
i_target_start_bit = (i_target_length - (i_source_length - i_source_start_bit));
}
// len defaults to (sizeof(OT) * 8) - i_source_start_bit
- if (i_length == ~0)
+ if (i_length == static_cast<bits_type>(~0))
{
i_length = i_source_length - i_source_start_bit;
}
@@ -106,17 +107,17 @@ namespace fapi2
do
{
- const bits_type src_idx = i_source_start_bit / bits_per_unit;
- const bits_type trg_idx = i_target_start_bit / bits_per_unit;
+ const bits_type src_idx = i_source_start_bit / bits_per_input_unit;
+ const bits_type trg_idx = i_target_start_bit / bits_per_output_unit;
// "slop" = unaligned bits
- const bits_type src_slop = i_source_start_bit % bits_per_unit;
- const bits_type trg_slop = i_target_start_bit % bits_per_unit;
+ const bits_type src_slop = i_source_start_bit % bits_per_input_unit;
+ const bits_type trg_slop = i_target_start_bit % bits_per_output_unit;
// "cnt" = largest number of bits to be moved each pass
- bits_type cnt = std::min(i_length, bits_per_unit);
- cnt = std::min(cnt, bits_per_unit - src_slop);
- cnt = std::min(cnt, bits_per_unit - trg_slop);
+ bits_type cnt = std::min(i_length, bits_per_input_unit);
+ cnt = std::min(cnt, bits_per_input_unit - src_slop);
+ cnt = std::min(cnt, bits_per_output_unit - trg_slop);
// generate the source mask only once
bits_type mask = fast_mask32(src_slop, cnt);
@@ -127,9 +128,6 @@ namespace fapi2
// "shift" = amount of shifting needed for target alignment
int32_t shift = trg_slop - src_slop;
- // ideally (i << -1) would yield (i >> 1), but it
- // doesn't, so we need an extra branch here
-
if (shift < 0)
{
src_bits <<= -shift;
@@ -143,6 +141,7 @@ namespace fapi2
// clear source '0' bits in the target
i_target[trg_idx] &= ~mask;
+
// set source '1' bits in the target
i_target[trg_idx] |= src_bits;
@@ -150,6 +149,7 @@ namespace fapi2
i_target_start_bit += cnt;
i_length -= cnt;
+
} while (0 < i_length);
return fapi2::FAPI2_RC_SUCCESS;
@@ -182,9 +182,47 @@ namespace fapi2
///
/// @brief Variable buffer list constructor
/// @param[in] i_value an initializer list to initialize the container.
+ /// @warning Input data is assumed to be right-aligned and must be 32 bits
///
variable_buffer(const std::initializer_list<unit_type>& i_value);
+ ///
+ /// @brief Variable buffer copy constructor
+ /// @param[in] i_buffer the buffer to copy from
+ ///
+ variable_buffer(const variable_buffer& i_buffer):
+ buffer_base()
+ {
+ iv_perceived_bit_length = i_buffer.iv_perceived_bit_length;
+ iv_data = i_buffer.iv_data;
+ }
+
+ ///
+ /// @brief Variable buffer move constructor
+ /// @param[in] i_buffer the buffer to move
+ ///
+ variable_buffer(variable_buffer&& i_buffer):
+ buffer_base()
+ {
+ iv_perceived_bit_length = i_buffer.iv_perceived_bit_length;
+ i_buffer.iv_perceived_bit_length = 0;
+ iv_data = std::move(i_buffer.iv_data);
+ }
+
+ ///
+ /// @brief Variable buffer array constructor
+ /// @param[in] i_value a uint32_t array to initialize the container.
+ /// @param[in] i_length the length of the array in 32-bit words
+ /// @param[in] i_bit_length the length of the resulting buffer in bits.
+ /// @warning This assumes the underlying container of a variable_buffer
+ /// is a uint32_t - which it is.
+ /// @note To use this constructor given an ecmdDataBuffer, you would
+ /// ecmd.memCopyOut( buffer, ... );
+ /// variable_buffer( buffer, ecmd.getCapacity(), ecmd.getBitLength());
+ ///
+ variable_buffer(const uint32_t* i_value, const uint32_t i_length,
+ const uint32_t i_bit_length);
+
/// @name Bit/Word Manipulation Functions
///@{
@@ -226,8 +264,8 @@ namespace fapi2
}
iv_data[index] |=
- unit_type(1) << (bits_per_unit - 1) -
- (i_bit - (index * bits_per_unit));
+ unit_type(1) << ((bits_per_unit - 1) -
+ (i_bit - (index * bits_per_unit)));
return FAPI2_RC_SUCCESS;
}
@@ -319,9 +357,28 @@ namespace fapi2
/// @name Buffer Manipulation Functions
///@{
- // 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 move operator=()
+ /// @note To use: new_buffer = std::move(old_buffer). old_buffer will be
+ /// destroyed and no copy will be made (moved)
+ ///
+ variable_buffer& operator=(variable_buffer&& other)
+ {
+ iv_perceived_bit_length = other.iv_perceived_bit_length;
+ other.iv_perceived_bit_length = 0;
+ iv_data = std::move(other.iv_data);
+ return *this;
+ }
+
+ ///
+ /// @brief operator=()
+ ///
+ variable_buffer& operator=(const variable_buffer& other)
+ {
+ iv_perceived_bit_length = other.iv_perceived_bit_length;
+ iv_data = other.iv_data;
+ return *this;
+ }
///
/// @brief operator>>()
@@ -339,10 +396,37 @@ namespace fapi2
///
/// @brief operator+()
+ /// @param[in] A variable_buffer to append to this
///
-#ifdef DOXYGEN
- variable_buffer<T>& operator+(const T& rhs);
-#endif
+ variable_buffer& operator+(const variable_buffer& rhs)
+ {
+ iv_perceived_bit_length += rhs.iv_perceived_bit_length;
+ iv_data.insert(iv_data.end(), rhs.iv_data.begin(), rhs.iv_data.end());
+ return *this;
+ }
+
+ ///
+ /// @brief operator+()
+ /// @param[in] A number of bits to add to this buffer
+ ///
+ variable_buffer& operator+(const bits_type& rhs)
+ {
+ if (rhs != 0)
+ {
+ iv_perceived_bit_length += rhs;
+ iv_data.resize(_vector_size(iv_perceived_bit_length));
+ }
+ return *this;
+ }
+
+ ///
+ /// @brief resize()
+ /// @param[in] Desired resulting size of the buffer, in bits
+ ///
+ variable_buffer& resize(const bits_type& rhs)
+ {
+ return operator+(rhs - iv_perceived_bit_length);
+ }
///
/// @brief operator+=()
@@ -389,22 +473,22 @@ namespace fapi2
///
/// @brief operator!=()
///
-#ifdef DOXYGEN
- bool operator!=(const T& rhs) const;
-#endif
+ bool operator!=(const variable_buffer& rhs) const
+ { return ! operator==(rhs); }
///
/// @brief operator==()
/// @return true if and only if lhs == rhs
///
- inline bool operator==(const fapi2::bits_container& rhs) const
+ inline bool operator==(const fapi2::variable_buffer& rhs) const
{
- if (&iv_data == &rhs)
+ if (&iv_data == &rhs.iv_data)
{
return true;
}
- return iv_data == rhs;
+ return (iv_data == rhs.iv_data) &&
+ (iv_perceived_bit_length == rhs.iv_perceived_bit_length);
}
///
@@ -466,7 +550,7 @@ namespace fapi2
private:
// Just shorthand ...
static const bits_type bits_per_unit =
- bufferTraits<bits_container>::bits_per_unit;
+ bufferTraits<bits_container>::bits_per_unit();
// The number of bits the user asked for. The actual size of the
// container might be larger.
@@ -517,7 +601,17 @@ namespace fapi2
"code currently needs unit_type to be a unit32_t");
}
+ inline variable_buffer::
+ variable_buffer(const uint32_t* i_value, const uint32_t i_length,
+ const uint32_t i_bit_length):
+ iv_perceived_bit_length(i_bit_length)
+ {
+ static_assert(std::is_same<unit_type, uint32_t>::value,
+ "code currently needs unit_type to be a unit32_t");
+ // Copy the array in to our vector.
+ iv_data.insert(iv_data.end(), i_value, &i_value[i_length]);
+ }
/// @cond
//
@@ -529,7 +623,30 @@ namespace fapi2
bits_type i_len,
bits_type i_sourceStart)
{
- return _insert((unit_type*)(&i_source), parameterTraits<OT>::bit_length,
+ // _insert likes 32-bit sources. So lets make our source 32 bits.
+ uint32_t l_source = static_cast<uint32_t>(i_source);
+ bits_type l_sourceStart = i_sourceStart +
+ parameterTraits<uint32_t>::bit_length() - parameterTraits<OT>::bit_length();
+
+ return _insert(&l_source, parameterTraits<uint32_t>::bit_length(),
+ &(iv_data[0]), getBitLength(),
+ l_sourceStart, i_targetStart, i_len);
+ }
+
+ //
+ // If the source is 64-bits, treat that as 2x32
+ template<>
+ inline fapi2::ReturnCode variable_buffer::insert(const uint64_t& i_source,
+ bits_type i_targetStart,
+ bits_type i_len,
+ bits_type i_sourceStart)
+ {
+ // _insert wants 32 bit chunks, so lets turn our uint64_t into a
+ // uint32_t array (of 64 bits in length). Looks like a 64 bit variable_buffer.
+ uint32_t l_source[2] = {static_cast<uint32_t>((i_source & 0xFFFFFFFF00000000) >> 32),
+ static_cast<uint32_t>((i_source & 0x00000000FFFFFFFF))};
+
+ return _insert(l_source, parameterTraits<uint64_t>::bit_length(),
&(iv_data[0]), getBitLength(),
i_sourceStart, i_targetStart, i_len);
}
@@ -544,7 +661,8 @@ namespace fapi2
bits_type i_len,
bits_type i_sourceStart)
{
- return _insert((unit_type*)&(i_data()[0]), i_data.getBitLength(),
+ return _insert(reinterpret_cast<const unit_type*>(&(i_data()[0])),
+ i_data.getBitLength(),
&(iv_data[0]), getBitLength(),
i_sourceStart, i_targetStart, i_len);
}
@@ -558,7 +676,7 @@ namespace fapi2
bits_type i_targetStart,
bits_type i_len)
{
- _insertFromRight(i_data, parameterTraits<OT>::bit_length, i_targetStart, i_len);
+ return _insertFromRight(i_data, parameterTraits<OT>::bit_length(), i_targetStart, i_len);
}
//
@@ -571,7 +689,7 @@ namespace fapi2
bits_type i_len)
{
const bits_type bit_length_of_source = i_data.getBitLength();
- _insertFromRight(i_data, bit_length_of_source, i_targetStart, i_len);
+ return _insertFromRight(i_data, bit_length_of_source, i_targetStart, i_len);
}
@@ -586,19 +704,125 @@ namespace fapi2
bits_type i_start,
bits_type i_len) const
{
- // Needed to trick the compiler into matching the template below
- const bits_type max_length = parameterTraits<OT>::bit_length;
+ // If thy didn't pass an i_len, assume they want all the data
+ // which will fit.
+ if (i_len == static_cast<bits_type>(~0))
+ {
+ i_len = std::min(getBitLength(), parameterTraits<OT>::bit_length());
+ }
+
+ // _insert likes 32-bit targets. So lets make our target 32 bits.
+ uint32_t l_data = static_cast<uint32_t>(i_data);
+
+ ReturnCode rc;
+ if ((rc = _insert((container_unit*)&iv_data[0], getBitLength(),
+ &l_data, parameterTraits<uint32_t>::bit_length(),
+ i_start, 0U, i_len)) != FAPI2_RC_SUCCESS)
+ {
+ return rc;
+ }
+
+ // Shift back to the original bit width.
+ i_data = l_data >> (parameterTraits<uint32_t>::bit_length() - parameterTraits<OT>::bit_length());
+ return FAPI2_RC_SUCCESS;
+ }
+ template<>
+ inline fapi2::ReturnCode variable_buffer::extract(
+ uint64_t& i_data,
+ bits_type i_start,
+ bits_type i_len) const
+ {
// If thy didn't pass an i_len, assume they want all the data
// which will fit.
- if (i_len == ~0)
+ if ((i_len == static_cast<bits_type>(~0)) ||
+ (i_len > parameterTraits<uint64_t>::bit_length()))
{
- i_len = max_length;
+ i_len = std::min(getBitLength(), parameterTraits<uint64_t>::bit_length());
}
- return _insert((container_unit*)&iv_data[0], getBitLength(),
- &i_data, max_length,
- i_start, 0U, i_len);
+ // _insert wants 32 bit chunks, so lets turn our uint64_t into a
+ // uint32_t array (of 64 bits in length). Looks like a 64 bit variable_buffer.
+ uint32_t l_data[2] = {static_cast<uint32_t>((i_data & 0xFFFFFFFF00000000) >> 32),
+ static_cast<uint32_t>((i_data & 0x00000000FFFFFFFF))};
+
+ ReturnCode rc;
+ if ((rc = _insert((container_unit*)&iv_data[0], getBitLength(),
+ l_data, parameterTraits<uint64_t>::bit_length(),
+ i_start, 0U, i_len)) != FAPI2_RC_SUCCESS)
+ {
+ return rc;
+ }
+
+ i_data = static_cast<uint64_t>(l_data[0]) << 32;
+ i_data |= l_data[1];
+
+ return FAPI2_RC_SUCCESS;
+ }
+
+ //
+ // Generic extractToRight. Extract is an insert with the arguments reversed.
+ //
+ template<typename OT>
+ inline fapi2::ReturnCode variable_buffer::extractToRight(
+ OT& i_data,
+ bits_type i_start,
+ bits_type i_len) const
+ {
+ // If thy didn't pass an i_len, assume they want all the data
+ // which will fit.
+ if ((i_len == static_cast<bits_type>(~0)) ||
+ (i_len > parameterTraits<OT>::bit_length()))
+ {
+ i_len = std::min(getBitLength(), parameterTraits<OT>::bit_length());
+ }
+
+ // _insert likes 32-bit targets. So lets make our target 32 bits.
+ uint32_t l_data = static_cast<uint32_t>(i_data);
+
+ ReturnCode rc;
+ if ((rc = _insert(reinterpret_cast<const container_unit*>(&iv_data[0]), getBitLength(),
+ &l_data, parameterTraits<uint32_t>::bit_length(),
+ i_start, parameterTraits<uint32_t>::bit_length() - i_len, i_len)) != FAPI2_RC_SUCCESS)
+ {
+ return rc;
+ }
+
+ i_data = l_data;
+ return FAPI2_RC_SUCCESS;
+ }
+
+ template<>
+ inline fapi2::ReturnCode variable_buffer::extractToRight(
+ uint64_t& i_data,
+ bits_type i_start,
+ bits_type i_len) const
+ {
+ // If thy didn't pass an i_len, assume they want all the data
+ // which will fit.
+ if ((i_len == static_cast<bits_type>(~0)) ||
+ (i_len > parameterTraits<uint64_t>::bit_length()))
+ {
+ i_len = std::min(getBitLength(), parameterTraits<uint64_t>::bit_length());
+ }
+
+ // _insert wants 32 bit chunks, so lets turn our uint64_t into a
+ // uint32_t array (of 64 bits in length).
+ uint32_t l_data[2] = {static_cast<uint32_t>((i_data & 0xFFFFFFFF00000000) >> 32),
+ static_cast<uint32_t>((i_data & 0x00000000FFFFFFFF))};
+
+ ReturnCode rc;
+ if ((rc = _insert(reinterpret_cast<const container_unit*>(&iv_data[0]), getBitLength(),
+ l_data, parameterTraits<uint64_t>::bit_length(),
+ i_start, parameterTraits<uint64_t>::bit_length() - i_len, i_len)) != FAPI2_RC_SUCCESS)
+ {
+ return rc;
+ }
+
+ i_data = static_cast<uint64_t>(l_data[0]) << 32;
+ i_data |= l_data[1];
+
+ return FAPI2_RC_SUCCESS;
}
//
@@ -612,11 +836,11 @@ namespace fapi2
{
// If thy didn't pass an i_len, assume they want all the data
// which will fit.
- if (i_len == ~0)
+ if (i_len == static_cast<bits_type>(~0))
{
i_len = i_data.getBitLength();
}
- return _insert((container_unit*)&iv_data[0], getBitLength(),
+ return _insert(reinterpret_cast<const container_unit*>(&iv_data[0]), getBitLength(),
&(i_data()[0]), i_data.getBitLength(),
i_start, 0U, i_len);
}
@@ -632,7 +856,7 @@ namespace fapi2
{
// If they didn't pass in a length, assume they want all the i_data
// which will fit.
- if( i_len == ~0 )
+ if( i_len == static_cast<bits_type>(~0) )
{
// The longest the length can be is the length of the data
// This is the miniumum of the length of the data or the
@@ -657,7 +881,7 @@ namespace fapi2
bits_type i_offset);
#endif
/// @endcond
-};
+}
#endif
OpenPOWER on IntegriCloud