aboutsummaryrefslogtreecommitdiffstats
path: root/host/include
diff options
context:
space:
mode:
authorAshish Chaudhari <ashish@ettus.com>2019-05-14 16:46:07 -0700
committerMartin Braun <martin.braun@ettus.com>2019-11-26 11:49:14 -0800
commita38845de27ccf51b60dca342101dff7a2ba552ec (patch)
tree4e5a8beae6483e2945020d3066ebeecade61ea42 /host/include
parentc97bdc6c94c98753215a90cf499af4bdf06db8e2 (diff)
downloaduhd-a38845de27ccf51b60dca342101dff7a2ba552ec.tar.gz
uhd-a38845de27ccf51b60dca342101dff7a2ba552ec.tar.bz2
uhd-a38845de27ccf51b60dca342101dff7a2ba552ec.zip
rfnoc: Refactored CHDR packet interfaces
- Moved packet interface code from public to private include - Split packet interface into two files: payload paring and packet iface - Added support for all CHDR packet types - Added more test cases to unit test
Diffstat (limited to 'host/include')
-rw-r--r--host/include/uhd/rfnoc/CMakeLists.txt1
-rw-r--r--host/include/uhd/rfnoc/chdr/CMakeLists.txt12
-rw-r--r--host/include/uhd/rfnoc/chdr/chdr_header.hpp285
-rw-r--r--host/include/uhd/rfnoc/chdr/chdr_packet.hpp294
4 files changed, 0 insertions, 592 deletions
diff --git a/host/include/uhd/rfnoc/CMakeLists.txt b/host/include/uhd/rfnoc/CMakeLists.txt
index bc5d7f054..894d4fda4 100644
--- a/host/include/uhd/rfnoc/CMakeLists.txt
+++ b/host/include/uhd/rfnoc/CMakeLists.txt
@@ -42,7 +42,6 @@ if(ENABLE_RFNOC)
COMPONENT headers
)
endif(ENABLE_RFNOC)
-add_subdirectory(chdr)
add_subdirectory(blocks)
#add_subdirectory(components)
diff --git a/host/include/uhd/rfnoc/chdr/CMakeLists.txt b/host/include/uhd/rfnoc/chdr/CMakeLists.txt
deleted file mode 100644
index 3ef4d3b64..000000000
--- a/host/include/uhd/rfnoc/chdr/CMakeLists.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# Copyright 2019 Ettus Research, a National Instruments Brand
-#
-# SPDX-License-Identifier: GPL-3.0-or-later
-#
-
-UHD_INSTALL(FILES
- chdr_header.hpp
- chdr_packet.hpp
- DESTINATION ${PKG_DATA_DIR}/rfnoc/chdr
- COMPONENT headers # TODO: Different component
-)
diff --git a/host/include/uhd/rfnoc/chdr/chdr_header.hpp b/host/include/uhd/rfnoc/chdr/chdr_header.hpp
deleted file mode 100644
index 1fdbdc0b5..000000000
--- a/host/include/uhd/rfnoc/chdr/chdr_header.hpp
+++ /dev/null
@@ -1,285 +0,0 @@
-//
-// Copyright 2019 Ettus Research, a National Instruments Brand
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_RFNOC_CHDR_HEADER_HPP
-#define INCLUDED_RFNOC_CHDR_HEADER_HPP
-
-#include <uhd/types/endianness.hpp>
-#include <uhd/utils/byteswap.hpp>
-#include <uhd/exception.hpp>
-#include <cassert>
-#include <memory>
-
-namespace uhd { namespace rfnoc { namespace chdr {
-
-static constexpr size_t FLAGS_OFFSET = 58;
-static constexpr size_t PKT_TYPE_OFFSET = 55;
-static constexpr size_t NUM_METADATA_OFFSET = 48;
-static constexpr size_t SEQ_NUM_OFFSET = 32;
-static constexpr size_t LENGTH_OFFSET = 16;
-static constexpr size_t DST_EPID_OFFSET = 0;
-static constexpr uint64_t FLAGS_MASK = ((uint64_t)0x3F << FLAGS_OFFSET);
-static constexpr uint64_t PKT_TYPE_MASK = ((uint64_t)0x7 << PKT_TYPE_OFFSET);
-static constexpr uint64_t NUM_METADATA_MASK = ((uint64_t)0x7F << NUM_METADATA_OFFSET);
-static constexpr uint64_t SEQ_NUM_MASK = ((uint64_t)0xFFFF << SEQ_NUM_OFFSET);
-static constexpr uint64_t LENGTH_MASK = ((uint64_t)0xFFFF << LENGTH_OFFSET);
-static constexpr uint64_t DST_EPID_MASK = ((uint64_t)0xFFFF << DST_EPID_OFFSET);
-
-enum class packet_type_t {
- PACKET_TYPE_MGMT = 0x0, // Management packet
- PACKET_TYPE_STS = 0x1, // Stream status
- PACKET_TYPE_STC = 0x2, // Stream Command
- PACKET_TYPE_CTRL = 0x4, // Control Transaction
- PACKET_TYPE_DATA_NO_TS = 0x6, // Data Packet without TimeStamp
- PACKET_TYPE_DATA_WITH_TS = 0x7, // Data Packet with TimeStamp
-};
-
-
-class chdr_header_iface
-{
-public:
- using uptr = std::unique_ptr<chdr_header_iface>;
-
- static uptr make(size_t chdr_w, uint64_t header_val);
- static uptr make(size_t chdr_w, packet_type_t pkt_type);
- virtual size_t get_word_size() const = 0;
- virtual uint64_t get() const = 0;
- virtual uint8_t get_flags() const = 0;
- virtual packet_type_t get_pkt_type() const = 0;
- virtual uint8_t get_num_metadata() const = 0;
- virtual uint8_t get_num_bytes_metadata() const = 0;
- virtual uint16_t get_seq_num() const = 0;
- virtual uint16_t get_length() const = 0;
- virtual uint16_t get_dst_epid() const = 0;
- virtual size_t get_num_words_payload() const = 0;
- virtual size_t get_num_bytes_payload() const = 0;
- virtual size_t get_metadata_offset() const = 0;
- virtual size_t get_payload_offset() const = 0;
- virtual void set_flags(uint8_t flags) = 0;
- virtual void set_seq_num(uint16_t seq_num) = 0;
- virtual void set_dst_epid(uint16_t dst_epid) = 0;
- virtual void set_packet_size(size_t num_payload, size_t num_metadata = 0) = 0;
-};
-
-/*! Header information of a data packet
- * This is the first 64-bit
- */
-template <size_t chdr_w>
-class chdr_header : public chdr_header_iface
-{
-public:
- ~chdr_header() = default;
-
- chdr_header(packet_type_t packet_type)
- {
- _set_pkt_type(packet_type);
- }
-
- chdr_header(uint64_t header_val) : _header_val(header_val) {}
-
- /*! Return the word size in bytes
- */
- constexpr size_t get_word_size() const
- {
- return chdr_w / 8;
- }
-
- /*! Returns the 64 header bits in native byte order
- */
- uint64_t get() const
- {
- return _header_val;
- }
-
- /*! Get flags field of this CHDR packet
- */
- inline uint8_t get_flags() const
- {
- return _get_value<uint8_t>(_header_val, FLAGS_MASK, FLAGS_OFFSET);
- };
-
- /*! Get packet type field of this CHDR packet
- */
- inline packet_type_t get_pkt_type() const
- {
- return _get_value<packet_type_t>(_header_val, PKT_TYPE_MASK, PKT_TYPE_OFFSET);
- }
-
- /*! Get number length of metadata of this CHDR packet in words
- */
- inline uint8_t get_num_metadata() const
- {
- return _get_value<uint8_t>(_header_val, NUM_METADATA_MASK, NUM_METADATA_OFFSET);
- }
-
- /*! Get number length of metadata of this CHDR packet in bytes
- */
- inline uint8_t get_num_bytes_metadata() const
- {
- return get_num_metadata() * get_word_size();
- }
-
- /*! Get sequence number field of this CHDR packet
- */
- inline uint16_t get_seq_num() const
- {
- return _get_value<uint16_t>(_header_val, SEQ_NUM_MASK, SEQ_NUM_OFFSET);
- }
-
- /*! Get length (in bytes) of this CHDR packet
- */
- inline uint16_t get_length() const
- {
- return _get_value<uint16_t>(_header_val, LENGTH_MASK, LENGTH_OFFSET);
- }
-
- /*! Get dst_epid field of this CHDR packet
- */
- inline uint16_t get_dst_epid() const
- {
- return _get_value<uint16_t>(_header_val, DST_EPID_MASK, DST_EPID_OFFSET);
- }
-
- /*! Return number of payload in the packet (in CHDR word unit)
- */
- inline size_t get_num_words_payload() const
- {
- return (get_length() / get_word_size()) - get_num_metadata() - 1
- - _has_timestamp(get_pkt_type());
- }
-
- /*! Return number of payload in the packet (in CHDR word unit)
- */
- inline size_t get_num_bytes_payload() const
- {
- return get_length() - get_num_bytes_metadata() - get_word_size()
- - _has_timestamp(get_pkt_type()) * get_word_size();
- }
-
- /*! Return offset to payload this offset in bytes unit
- */
- inline size_t get_metadata_offset() const
- {
- return (1 + _has_timestamp(get_pkt_type())) * get_word_size();
- }
-
- /*! Return offset to payload this offset in bytes unit
- */
- inline size_t get_payload_offset() const
- {
- return get_metadata_offset() + get_num_metadata() * get_word_size();
- }
-
-
- /*********** Setters *****************************************************/
-
- /*! Set flags field of this CHDR packet
- * \param flags value to set to flags field of this CHDR packet
- */
- inline void set_flags(uint8_t flags)
- {
- _set_value(_header_val, flags, FLAGS_OFFSET, FLAGS_MASK);
- }
-
- /*! Set sequence number field of this CHDR packet
- *\param seq_num value to set to sequence number field of this CHDR packet
- */
- inline void set_seq_num(uint16_t seq_num)
- {
- _set_value(_header_val, seq_num, SEQ_NUM_OFFSET, SEQ_NUM_MASK);
- }
-
- /*! Set dst_epid field of this CHDR packet
- * \param dst_epid value to set to dst_epid field of CHDR packet
- */
- inline void set_dst_epid(uint16_t dst_epid)
- {
- _set_value(_header_val, dst_epid, DST_EPID_OFFSET, DST_EPID_MASK);
- }
-
- /*! Set the size of payload and metadata in word unit
- *\param num_payload number of payload in word
- *\param num_metadata number of metadata in word
- */
- inline void set_packet_size(size_t num_payload, size_t num_metadata = 0)
- {
- _set_num_metadata(num_metadata);
- _update_length(num_metadata, num_payload);
- }
-
-private:
- /*! The actual header bits, stored in native (host) byte order
- */
- uint64_t _header_val = 0;
-
- template <typename value_t, typename data_t>
- inline value_t _get_value(const data_t data, data_t mask, size_t offset) const
- {
- return static_cast<value_t>((data & mask) >> offset);
- }
-
- template <typename data_t, typename value_t>
- inline void _set_value(data_t& data, value_t value, size_t offset, data_t mask)
- {
- data = (data & ~mask) | (static_cast<data_t>(value) << offset);
- }
-
- inline uint8_t _has_timestamp(packet_type_t pkt_type) const
- {
- return pkt_type == packet_type_t::PACKET_TYPE_DATA_WITH_TS and chdr_w == 64 ? 1
- : 0;
- }
-
- inline void _update_length(uint8_t num_metadata, size_t num_payload)
- {
- _set_length(static_cast<uint16_t>(
- (num_metadata + num_payload + 1 + _has_timestamp(get_pkt_type())) * chdr_w
- / 8));
- }
-
- inline void _set_length(uint16_t length)
- {
- _set_value(_header_val, length, LENGTH_OFFSET, LENGTH_MASK);
- }
-
- inline void _set_pkt_type(packet_type_t pkt_type)
- {
- _set_value(_header_val, pkt_type, PKT_TYPE_OFFSET, PKT_TYPE_MASK);
- }
-
- /*! Set number of metadata (in word) of this CHDR packet
- * This function also update the total length field of this CHDR packet
- * \param num_metadata number of metadata (in word) of this CHDR packet
- */
- inline void _set_num_metadata(uint8_t num_metadata)
- {
- _set_value(_header_val, num_metadata, NUM_METADATA_OFFSET, NUM_METADATA_MASK);
- }
-};
-
-chdr_header_iface::uptr chdr_header_iface::make(size_t chdr_w, uint64_t header_val)
-{
- if (chdr_w == 256)
- return uptr(new chdr_header<256>(header_val));
- else
- return uptr(new chdr_header<64>(header_val));
-}
-
-chdr_header_iface::uptr chdr_header_iface::make(size_t chdr_w, packet_type_t pkt_type)
-{
- switch (chdr_w) {
- case 256:
- return uptr(new chdr_header<256>(pkt_type));
- case 64:
- return uptr(new chdr_header<64>(pkt_type));
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
-}
-
-}}} // namespace uhd::rfnoc::chdr
-
-#endif /* INCLUDED_RFNOC_CHDR_HEADER_HPP */
diff --git a/host/include/uhd/rfnoc/chdr/chdr_packet.hpp b/host/include/uhd/rfnoc/chdr/chdr_packet.hpp
deleted file mode 100644
index 0a2ae68f3..000000000
--- a/host/include/uhd/rfnoc/chdr/chdr_packet.hpp
+++ /dev/null
@@ -1,294 +0,0 @@
-//
-// Copyright 2019 Ettus Research, a National Instruments Brand
-//
-// SPDX-License-Identifier: GPL-3.0-or-later
-//
-
-#ifndef INCLUDED_RFNOC_CHDR_DATA_PACKET_HPP
-#define INCLUDED_RFNOC_CHDR_DATA_PACKET_HPP
-
-#include <uhd/rfnoc/chdr/chdr_header.hpp>
-#include <uhd/exception.hpp>
-#include <cassert>
-#include <memory>
-
-namespace uhd { namespace rfnoc { namespace chdr {
-
-class chdr_packet_iface
-{
-public:
- typedef std::unique_ptr<chdr_packet_iface> uptr;
- static uptr make(void* pkt_buff);
- static uptr make(size_t chdr_w, endianness_t endianness, void* pkt_buff);
- static uptr make(
- size_t chdr_w, endianness_t endianness, uint64_t header_val, void* pkt_buff);
- virtual uint64_t get_header_val() const = 0;
- virtual void set_header_val(uint64_t header_val) = 0;
- virtual uint64_t get_timestamp() const = 0;
- virtual void set_timestamp(uint64_t timestamp) = 0;
- virtual uint64_t* metadata_ptr_of_type_uint64_t() const = 0;
- virtual uint32_t* metadata_ptr_of_type_uint32_t() const = 0;
- virtual uint64_t* payload_ptr_of_type_uint64_t() const = 0;
- virtual uint32_t* payload_ptr_of_type_uint32_t() const = 0;
- virtual uint16_t* payload_ptr_of_type_uint16_t() const = 0;
-};
-
-/*! CHDR Packet Abstraction Class
- *
- * This class wraps a pointer to a buffer containing a CHDR packet. It also
- * provides access to the packet header in native byte ordering. The byte
- * ordering of the metadata and payload needs to be handled elsewhere, but it
- * needs to be also passed into this class as a template argument \p endianness.
- * The byte ordering refers to the byte order on the transport.
- *
- * No size checking is performed in this class. The size of the buffer needs to
- * be tracked separately in order to avoid buffer overflows.
- *
- * NOTE: This assumes the host is little-endian.
- */
-template <size_t chdr_w, endianness_t endianness>
-class chdr_packet : public chdr_packet_iface
-{
-public:
- typedef chdr_header<chdr_w> header_t;
-
- ~chdr_packet() = default;
-
- /*! This constructor is used to parse an incoming CHDR packet.
- *
- * Note: If the header declares the size of the packet to be larger than the
- * valid memory readable at \p pkt_buff, then there is the possibility of a
- * buffer overflow ocurring.
- *
- * \param pkt_buff a pointer to the packet buffer. Its byte ordering has to be
- * provided as the template argument \p endianness
- */
- chdr_packet(void* pkt_buff)
- {
- assert(pkt_buff != NULL);
- _pkt_buff = static_cast<uint64_t*>(pkt_buff);
- if (endianness == endianness_t::ENDIANNESS_BIG) {
- _header = header_t(ntohx<uint64_t>(*_pkt_buff));
- } else {
- _header = header_t(*_pkt_buff);
- }
- }
-
- /*! This constructor is used to construct an outgoing CHDR packet with given header.
- *
- * \param header CHDR header (in host-native byte ordering)
- * \param pkt_buff a pointer to packet buffer. Its byte ordering has to be provided
- * as the template argument \p endianness
- */
- chdr_packet(header_t header, void* pkt_buff) : _header(header)
- {
- assert(pkt_buff != NULL);
- _pkt_buff = static_cast<uint64_t*>(pkt_buff);
- if (endianness == endianness_t::ENDIANNESS_BIG) {
- *_pkt_buff = htonx<uint64_t>(header.get());
- } else {
- *_pkt_buff = header.get();
- }
- }
-
- /*! Get a copy of the header data (the first 64-bit of the CHDR packet)
- *
- * This copy will be in native byte order.
- */
- inline header_t get_header() const
- {
- return _header;
- }
-
- /*! Get a copy of the 64-bit value of the packet header (the first 64-bit
- * of the CHDR packet)
- *
- * This copy will be in native byte order.
- */
- inline uint64_t get_header_val() const
- {
- return _header.get();
- }
-
- /*! Set 64-bit value of the packet header (the first 64-bit of the CHDR
- * packet)
- *
- * This set 64_bit value will swap byte to native byte order.
- */
- inline void set_header_val(uint64_t header_val)
- {
- if (endianness == endianness_t::ENDIANNESS_BIG) {
- _header = header_t(ntohx<uint64_t>(header_val));
- } else {
- _header = header_t(header_val);
- }
- }
-
- /*! Return the pointer to the first byte of metadata of this CHDR packet
- *
- * Note: This class does no bounds checking. It is up to the user to only
- * to the metadata portion of the the CHDR buffer.
- *
- * ~~~{.cpp}
- * // Assume chdrpkt is of type chdr_packet:
- * uint8_t* metadata_ptr = chdrpkt.metadata_ptr_of_type<uint8_t>();
- * const size_t metadata_size = chdrpkt.get_header().get_num_bytes_metadata();
- * // The following expression is fine if metadata_size > 0:
- * metadata_ptr[0] = 0xF0;
- * // The following expression is never fine, but the code will not throw an
- * // exception (most likely, it won't segfault either, unless the payload
- * // size is zero):
- * metadata_ptr[metadata_size] = 0xF0;
- * ~~~
- */
- template <typename data_t>
- inline data_t* metadata_ptr_of_type() const
- {
- return reinterpret_cast<data_t*>(
- reinterpret_cast<char*>(_pkt_buff) + _header.get_metadata_offset());
- }
-
- /*! Get 64-bit timestamp of this CHDR packet in native byte order
- *
- * This will byteswap if necessary.
- *
- */
- inline uint64_t get_timestamp() const
- {
- assert(_header.get_pkt_type() == packet_type_t::PACKET_TYPE_DATA_WITH_TS);
- return endianness_t::ENDIANNESS_BIG ? ntohx<uint64_t>(*(_pkt_buff + 1))
- : *(_pkt_buff + 1);
- }
-
- /*! Set 64-bit timestamp of this CHDR packet.
- *
- * If this packet is not a data packet with timestamp, this operation will
- * overwrite the metadata or payload memory.
- *
- * \param timestamp 64-bit value of timestamp of this CHDR packet
- */
- inline void set_timestamp(uint64_t timestamp)
- {
- assert(_header.get_pkt_type() == packet_type_t::PACKET_TYPE_DATA_WITH_TS);
- *(_pkt_buff + 1) = endianness_t::ENDIANNESS_BIG ? htonx<uint64_t>(timestamp)
- : timestamp;
- }
-
- /*! Return the pointer to the first payload byte of this CHDR packet
- *
- * Note: This class does no bounds checking. It is up to the user to only
- * to the metadata portion of the the CHDR buffer.
- *
- * ~~~{.cpp}
- * // Assume chdrpkt is of type chdr_packet:
- * uint8_t* payload_ptr = chdrpkt.metadata_ptr_of_type<uint8_t>();
- * const size_t payload_size = chdrpkt.get_header().get_num_bytes_payload();
- * // The following expression is fine if payload_size > 0:
- * payload_ptr[0] = 0xF0;
- * // The following expression is never fine, but the code will not throw an
- * // exception. Instead, it could even segfault:
- * payload_ptr[payload_size] = 0xF0;
- * ~~~
- */
- template <typename payload_t>
- inline payload_t* payload_ptr_of_type() const
- {
- return reinterpret_cast<payload_t*>(
- reinterpret_cast<char*>(_pkt_buff) + _header.get_payload_offset());
- }
-
- inline uint64_t* payload_ptr_of_type_uint64_t() const
- {
- return reinterpret_cast<uint64_t*>(
- reinterpret_cast<char*>(_pkt_buff) + _header.get_payload_offset());
- }
-
- inline uint32_t* payload_ptr_of_type_uint32_t() const
- {
- return reinterpret_cast<uint32_t*>(
- reinterpret_cast<char*>(_pkt_buff) + _header.get_payload_offset());
- }
-
- inline uint16_t* payload_ptr_of_type_uint16_t() const
- {
- return reinterpret_cast<uint16_t*>(
- reinterpret_cast<char*>(_pkt_buff) + _header.get_payload_offset());
- }
-
- inline uint64_t* metadata_ptr_of_type_uint64_t() const
- {
- return reinterpret_cast<uint64_t*>(
- reinterpret_cast<char*>(_pkt_buff) + _header.get_metadata_offset());
- }
-
- inline uint32_t* metadata_ptr_of_type_uint32_t() const
- {
- return reinterpret_cast<uint32_t*>(
- reinterpret_cast<char*>(_pkt_buff) + _header.get_metadata_offset());
- }
-
-private:
- uint64_t* _pkt_buff;
- header_t _header = header_t(0);
-};
-
-chdr_packet_iface::uptr chdr_packet_iface::make(void* pkt_buff)
-{
- return uptr(new chdr_packet<64, ENDIANNESS_LITTLE>(pkt_buff));
-}
-
-chdr_packet_iface::uptr chdr_packet_iface::make(
- size_t chdr_w, endianness_t endianness, void* pkt_buff)
-{
- if (endianness == ENDIANNESS_BIG) {
- switch (chdr_w) {
- case 256:
- return uptr(new chdr_packet<256, ENDIANNESS_BIG>(pkt_buff));
- case 64:
- return uptr(new chdr_packet<64, ENDIANNESS_BIG>(pkt_buff));
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
- } else {
- switch (chdr_w) {
- case 256:
- return uptr(new chdr_packet<256, ENDIANNESS_LITTLE>(pkt_buff));
- case 64:
- return uptr(new chdr_packet<64, ENDIANNESS_LITTLE>(pkt_buff));
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
- }
-}
-
-chdr_packet_iface::uptr chdr_packet_iface::make(
- size_t chdr_w, endianness_t endianness, uint64_t header_val, void* pkt_buff)
-{
- if (endianness == ENDIANNESS_BIG) {
- switch (chdr_w) {
- case 256:
- return uptr(new chdr_packet<256, ENDIANNESS_BIG>(
- chdr_header<256>(header_val), pkt_buff));
- case 64:
- return uptr(new chdr_packet<64, ENDIANNESS_BIG>(
- chdr_header<64>(header_val), pkt_buff));
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
- } else {
- switch (chdr_w) {
- case 256:
- return uptr(new chdr_packet<256, ENDIANNESS_LITTLE>(
- chdr_header<256>(header_val), pkt_buff));
- case 64:
- return uptr(new chdr_packet<64, ENDIANNESS_LITTLE>(
- chdr_header<64>(header_val), pkt_buff));
- default:
- UHD_THROW_INVALID_CODE_PATH();
- }
- }
-}
-
-}}} // namespace uhd::rfnoc::chdr
-
-#endif /* INCLUDED_RFNOC_CHDR_DATA_PACKET_HPP */