1111
1212#include " udmaio/UioMemSgdma.hpp"
1313
14+ #include < cstddef>
1415#include < cstdint>
16+ #include < memory>
17+ #include < stdexcept>
18+ #include < string>
19+ #include < vector>
20+
21+ #include " udmaio/DmaBufferAbstract.hpp"
1522
1623namespace udmaio {
1724
@@ -43,12 +50,16 @@ void UioMemSgdma::write_cyc_mode(const std::vector<UioRegion>& dst_bufs) {
4350 }
4451}
4552
46- void UioMemSgdma::init_buffers (DmaBufferAbstract& mem, size_t num_buffers, size_t buf_size) {
53+ void UioMemSgdma::init_buffers (std::shared_ptr<DmaBufferAbstract> mem,
54+ size_t num_buffers,
55+ size_t buf_size) {
56+ _mem = mem;
57+
4758 // FIXME: enforce alignment constraints?
4859 std::vector<UioRegion> dst_bufs;
4960 _buf_addrs.clear ();
5061 for (size_t i = 0 ; i < num_buffers; i++) {
51- uint64_t addr = mem. get_phys_region ().addr + i * buf_size;
62+ uint64_t addr = mem-> get_phys_region ().addr + i * buf_size;
5263 dst_bufs.push_back ({
5364 .addr = addr,
5465 .size = buf_size,
@@ -97,8 +108,8 @@ std::ostream& operator<<(std::ostream& os, const UioRegion& buf_info) {
97108 return os;
98109}
99110
100- std::vector<UioRegion > UioMemSgdma::get_full_buffers() {
101- std::vector<UioRegion> bufs ;
111+ std::vector<size_t > UioMemSgdma::get_full_buffers() {
112+ std::vector<size_t> result ;
102113
103114 for (size_t i = 0; i < _nr_cyc_desc; i++) {
104115 auto stat = desc_statuses[_next_readable_buf].rd();
@@ -107,29 +118,42 @@ std::vector<UioRegion> UioMemSgdma::get_full_buffers() {
107118 }
108119
109120 if ((!stat.rxeof && (stat.num_stored_bytes != _buf_size)) || stat.num_stored_bytes == 0) {
110- BOOST_LOG_SEV(_lg, bls::error)
111- << " Descriptor #" << i << " size mismatch (expected " << _buf_size << " , received "
112- << stat.num_stored_bytes << " ), skipping";
113-
114- print_desc (descriptors[_next_readable_buf].rd ());
115- continue ;
121+ throw std::runtime_error(" Descriptor #" + std::to_string(i) +
122+ " size mismatch (expected " + std::to_string(_buf_size) +
123+ " , received " + std::to_string(stat.num_stored_bytes) + " )");
116124 }
117125
118- stat.cmplt = 0 ;
119- desc_statuses[_next_readable_buf].wr(stat);
120-
121- const uint64_t buf_addr = _buf_addrs[_next_readable_buf];
122- bufs.emplace_back(UioRegion{static_cast <uintptr_t >(buf_addr), stat.num_stored_bytes });
123-
124- BOOST_LOG_SEV (_lg, bls::trace)
125- << " save buf #" << _next_readable_buf << " (" << stat.num_stored_bytes << " bytes) @ 0x"
126- << std::hex << buf_addr;
126+ result.push_back(_next_readable_buf);
127127
128128 _next_readable_buf++;
129129 _next_readable_buf %= _nr_cyc_desc;
130130 }
131131
132- return bufs;
132+ return result;
133+ }
134+
135+ std::vector<uint8_t > UioMemSgdma::read_buffers (const std::vector<size_t > indices) {
136+ // Read statuses for all buffers
137+ std::vector<S2mmDescStatus> stats{indices.size ()};
138+ size_t result_size = 0 ;
139+ for (size_t i = 0 ; i < indices.size (); i++) {
140+ stats[i] = desc_statuses[indices[i]].rd ();
141+ result_size += stats[i].num_stored_bytes ;
142+ }
143+
144+ std::vector<uint8_t > result;
145+ // Reserve enough space in advance to avoid re-allocation / copying
146+ result.reserve (result_size);
147+ for (size_t i = 0 ; i < indices.size (); i++) {
148+ auto region = UioRegion{_buf_addrs[indices[i]], stats[i].num_stored_bytes };
149+ BOOST_LOG_SEV (_lg, bls::trace) << " save buf #" << indices[i] << " (" << region.size
150+ << " bytes) @ 0x" << std::hex << region.addr ;
151+ _mem->append_from_buf (region, result);
152+ // Clear complete flag after having read the data
153+ stats[i].cmplt = 0 ;
154+ desc_statuses[indices[i]].wr (stats[i]);
155+ }
156+ return result;
133157}
134158
135159} // namespace udmaio
0 commit comments