rogue
Loading...
Searching...
No Matches
Hub.cpp
Go to the documentation of this file.
1
19#include "rogue/Directives.h"
20
22
23#include <inttypes.h>
24
25#include <cmath>
26#include <memory>
27#include <string>
28
29#include "rogue/GilRelease.h"
30#include "rogue/ScopedGil.h"
32
34
35#ifndef NO_PYTHON
36 #include <boost/python.hpp>
37namespace bp = boost::python;
38#endif
39
41rim::HubPtr rim::Hub::create(uint64_t offset, uint32_t min, uint32_t max) {
42 rim::HubPtr b = std::make_shared<rim::Hub>(offset, min, max);
43 return (b);
44}
45
47rim::Hub::Hub(uint64_t offset, uint32_t min, uint32_t max) : Master(), Slave(min, max) {
48 offset_ = offset;
49 root_ = (min != 0 && max != 0);
50 log_ = rogue::Logging::create("memory.Hub");
51}
52
54rim::Hub::~Hub() {}
55
57uint64_t rim::Hub::getOffset() {
58 return offset_;
59}
60
62uint64_t rim::Hub::getAddress() {
63 return (reqAddress() + offset_);
64}
65
67uint32_t rim::Hub::doSlaveId() {
68 if (root_)
69 return (rim::Slave::doSlaveId());
70 else
71 return (reqSlaveId());
72}
73
75std::string rim::Hub::doSlaveName() {
76 if (root_)
77 return (rim::Slave::doSlaveName());
78 else
79 return (reqSlaveName());
80}
81
83uint32_t rim::Hub::doMinAccess() {
84 if (root_)
85 return (rim::Slave::doMinAccess());
86 else
87 return (reqMinAccess());
88}
89
91uint32_t rim::Hub::doMaxAccess() {
92 // Transaction splitting allows for "unlimited" max access
93 if (root_)
94 return (rim::Slave::doMaxAccess());
95 else
96 return 0xFFFFFFFF;
97}
98
100uint64_t rim::Hub::doAddress() {
101 if (root_)
102 return (0);
103 else
104 return (reqAddress() + offset_);
105}
106
108void rim::Hub::doTransaction(rim::TransactionPtr tran) {
109 uint32_t maxAccess = getSlave()->doMaxAccess();
110
111 // Adjust address
112 tran->address_ += offset_;
113
114 // Split into smaller transactions if necessary
115 if (tran->size() > maxAccess) {
116 uint32_t numberOfTransactions = std::ceil(1.0 * tran->size() / maxAccess);
117
118 log_->debug("Splitting transaction %" PRIu32 " into %" PRIu32 " subtransactions",
119 tran->id_,
120 numberOfTransactions);
121
122 for (unsigned int i = 0; i < numberOfTransactions; ++i) {
123 rim::TransactionPtr subTran = tran->createSubTransaction();
124 subTran->iter_ = reinterpret_cast<uint8_t*>(tran->begin() + i * maxAccess);
125 if (tran->size() >= ((i + 1) * maxAccess)) {
126 subTran->size_ = maxAccess;
127 } else {
128 subTran->size_ = tran->size() % maxAccess;
129 }
130 subTran->address_ = tran->address_ + (i * maxAccess);
131 subTran->type_ = tran->type();
132
133 log_->debug("Created subTransaction %" PRIu32 ", parent=%" PRIu32 ", iter=%" PRIx32 ", size=%" PRIu32
134 ", address=%" PRIx64,
135 subTran->id_,
136 tran->id_,
137 subTran->iter_,
138 subTran->size_,
139 subTran->address_);
140 }
141
142 // Declare all subTransactions have been created
143 tran->doneSubTransactions();
144
145 // Forward the subTransactions
146 for (rim::TransactionMap::iterator it = tran->subTranMap_.begin(); it != tran->subTranMap_.end(); it++) {
147 getSlave()->doTransaction(it->second);
148 }
149 } else {
150 // Forward transaction
151 getSlave()->doTransaction(tran);
152 }
153}
154
155void rim::Hub::setup_python() {
156#ifndef NO_PYTHON
157 bp::class_<rim::HubWrap, rim::HubWrapPtr, bp::bases<rim::Master, rim::Slave>, boost::noncopyable>(
158 "Hub",
159 bp::init<uint64_t, uint32_t, uint32_t>())
160 .def("_blkMinAccess", &rim::Hub::doMinAccess)
161 .def("_blkMaxAccess", &rim::Hub::doMaxAccess)
162 .def("_getAddress", &rim::Hub::getAddress)
163 .def("_getOffset", &rim::Hub::getOffset)
164 .def("_doTransaction", &rim::Hub::doTransaction, &rim::HubWrap::defDoTransaction);
165
166 bp::implicitly_convertible<rim::HubPtr, rim::MasterPtr>();
167#endif
168}
169
170#ifndef NO_PYTHON
171
173rim::HubWrap::HubWrap(uint64_t offset, uint32_t min, uint32_t max) : rim::Hub(offset, min, max) {}
174
176void rim::HubWrap::doTransaction(rim::TransactionPtr transaction) {
177 {
179
180 if (boost::python::override pb = this->get_override("_doTransaction")) {
181 try {
182 pb(transaction);
183 return;
184 } catch (...) {
185 PyErr_Print();
186 }
187 }
188 }
189 rim::Hub::doTransaction(transaction);
190}
191
193void rim::HubWrap::defDoTransaction(rim::TransactionPtr transaction) {
194 rim::Hub::doTransaction(transaction);
195}
196
197#endif
static std::shared_ptr< rogue::Logging > create(const std::string &name, bool quiet=false)
Creates a logger instance.
Definition Logging.cpp:60
RAII helper that acquires the Python GIL for a scope.
Definition ScopedGil.h:35
Memory interface Hub device.
Definition Hub.h:72
Master endpoint for memory transactions.
Definition Master.h:50
Memory slave device.
Definition Slave.h:54
uint32_t max()
Returns configured maximum transaction size.
Definition Slave.cpp:116
uint32_t min()
Returns configured minimum transaction size.
Definition Slave.cpp:111
std::shared_ptr< rogue::interfaces::memory::Hub > HubPtr
Definition Hub.h:231
std::shared_ptr< rogue::interfaces::memory::Transaction > TransactionPtr
Shared pointer alias for Transaction.