Skip to content

Commit 9965909

Browse files
committed
[cru] Dynamically get FW SP FIFO size
1 parent 30c0970 commit 9965909

File tree

5 files changed

+46
-23
lines changed

5 files changed

+46
-23
lines changed

src/Cru/Constants.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ namespace Cru
3131
static constexpr int MAX_LINKS = 16;
3232

3333
/// Amount of available superpage descriptors per link
34-
static constexpr int MAX_SUPERPAGE_DESCRIPTORS = 128;
34+
static constexpr int MAX_SUPERPAGE_DESCRIPTORS_DEFAULT = 128;
3535

3636
/// DMA page length in bytes
3737
/// Note: the CRU has a firmware defined fixed page size
@@ -111,6 +111,10 @@ static constexpr Register DEBUG(0x00000c00);
111111
/// 0x11111111 -> Endpoint #1
112112
static constexpr Register ENDPOINT_ID(0x00000500);
113113

114+
/// Register to get the size of the internal CRU per-link Superpage FIFO
115+
/// If it returns 0, use the default of MAX_SUPERPAGE_DESCRIPTORS_DEFAULT
116+
static constexpr Register MAX_SUPERPAGE_DESCRIPTORS(0x00000c04);
117+
114118
///*** bar2 ***///
115119

116120
///////////////////////////////////////////////////////////////////////////////////////////////////

src/Cru/CruBar.cxx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,5 +1256,10 @@ void CruBar::setTimeFrameLength(uint16_t timeFrameLength)
12561256
bar0->modifyRegister(Cru::Registers::TIME_FRAME_LENGTH.index, 20, 12, timeFrameLength);
12571257
}
12581258

1259+
uint32_t CruBar::getMaxSuperpageDescriptors()
1260+
{
1261+
return readRegister(Cru::Registers::MAX_SUPERPAGE_DESCRIPTORS.index);
1262+
}
1263+
12591264
} // namespace roc
12601265
} // namespace o2

src/Cru/CruBar.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ class CruBar final : public BarInterfaceBase
113113

114114
std::vector<int> getDataTakingLinks();
115115

116+
uint32_t getMaxSuperpageDescriptors();
117+
116118
std::shared_ptr<Pda::PdaBar> getPdaBar()
117119
{
118120
return mPdaBar;

src/Cru/CruDmaChannel.cxx

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,18 @@ CruDmaChannel::CruDmaChannel(const Parameters& parameters)
7070
log(stream.str(), LogDebugDevel);
7171
}
7272

73+
// Calculate link and ready queue capacities
74+
{
75+
uint32_t maxSuperpageDescriptors = getBar()->getMaxSuperpageDescriptors();
76+
// If number of descriptors reported is 0, the feature is not supported by the firmware. Fall back to default value
77+
if (maxSuperpageDescriptors == 0x0) {
78+
maxSuperpageDescriptors = Cru::MAX_SUPERPAGE_DESCRIPTORS_DEFAULT;
79+
}
80+
81+
mLinkQueueCapacity = maxSuperpageDescriptors;
82+
mReadyQueueCapacity = maxSuperpageDescriptors * Cru::MAX_LINKS;
83+
}
84+
7385
// Insert links
7486
{
7587
std::stringstream stream;
@@ -79,7 +91,7 @@ CruDmaChannel::CruDmaChannel(const Parameters& parameters)
7991
for (auto const& link : links) {
8092
stream << link << " ";
8193
//Implicit constructors are deleted for the folly Queue. Workaround to keep the Link struct with a queue * field.
82-
std::shared_ptr<SuperpageQueue> linkQueue = std::make_shared<SuperpageQueue>(LINK_QUEUE_CAPACITY_ALLOCATIONS);
94+
std::shared_ptr<SuperpageQueue> linkQueue = std::make_shared<SuperpageQueue>(mLinkQueueCapacity + 1); // folly queue needs + 1
8395
Link newLink = { static_cast<LinkId>(link), 0, linkQueue };
8496
mLinks.push_back(newLink);
8597
}
@@ -89,6 +101,8 @@ CruDmaChannel::CruDmaChannel(const Parameters& parameters)
89101
if (mLinks.empty()) {
90102
BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("No links are enabled. Check with roc-status. Configure with roc-config."));
91103
}
104+
105+
mReadyQueue = std::make_unique<SuperpageQueue>(mReadyQueueCapacity + 1); // folly queue needs + 1
92106
}
93107
}
94108

@@ -101,8 +115,8 @@ auto CruDmaChannel::allowedChannels() -> AllowedChannels
101115
CruDmaChannel::~CruDmaChannel()
102116
{
103117
setBufferNonReady();
104-
if (mReadyQueue.sizeGuess() > 0) {
105-
log((format("Remaining superpages in the ready queue: %1%") % mReadyQueue.sizeGuess()).str(), LogDebugDevel);
118+
if (mReadyQueue->sizeGuess() > 0) {
119+
log((format("Remaining superpages in the ready queue: %1%") % mReadyQueue->sizeGuess()).str(), LogDebugDevel);
106120
}
107121

108122
if (mDataSource == DataSource::Internal) {
@@ -138,10 +152,10 @@ void CruDmaChannel::deviceStartDma()
138152
}
139153
link.superpageCounter = 0;
140154
}
141-
while (!mReadyQueue.isEmpty()) {
142-
mReadyQueue.popFront();
155+
while (!mReadyQueue->isEmpty()) {
156+
mReadyQueue->popFront();
143157
}
144-
mLinkQueuesTotalAvailable = LINK_QUEUE_CAPACITY * mLinks.size();
158+
mLinkQueuesTotalAvailable = mLinkQueueCapacity * mLinks.size();
145159

146160
// Start DMA
147161
setBufferReady();
@@ -249,7 +263,7 @@ bool CruDmaChannel::pushSuperpage(Superpage superpage)
249263
// Get the next link to push
250264
auto& link = mLinks[getNextLinkIndex()];
251265

252-
if (link.queue->sizeGuess() >= LINK_QUEUE_CAPACITY) {
266+
if (link.queue->sizeGuess() >= mLinkQueueCapacity) {
253267
// Is the link's FIFO out of space?
254268
// This should never happen
255269
BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Could not push superpage, link queue was full"));
@@ -268,19 +282,19 @@ bool CruDmaChannel::pushSuperpage(Superpage superpage)
268282

269283
auto CruDmaChannel::getSuperpage() -> Superpage
270284
{
271-
if (mReadyQueue.isEmpty()) {
285+
if (mReadyQueue->isEmpty()) {
272286
BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Could not get superpage, ready queue was empty"));
273287
}
274-
return *mReadyQueue.frontPtr();
288+
return *mReadyQueue->frontPtr();
275289
}
276290

277291
auto CruDmaChannel::popSuperpage() -> Superpage
278292
{
279-
if (mReadyQueue.isEmpty()) {
293+
if (mReadyQueue->isEmpty()) {
280294
BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Could not pop superpage, ready queue was empty"));
281295
}
282-
auto superpage = *mReadyQueue.frontPtr();
283-
mReadyQueue.popFront();
296+
auto superpage = *mReadyQueue->frontPtr();
297+
mReadyQueue->popFront();
284298

285299
return superpage;
286300
}
@@ -310,7 +324,7 @@ void CruDmaChannel::transferSuperpageFromLinkToReady(Link& link, bool reclaim)
310324
link.queue->frontPtr()->setReceived(0);
311325
}
312326

313-
mReadyQueue.write(*link.queue->frontPtr());
327+
mReadyQueue->write(*link.queue->frontPtr());
314328
link.queue->popFront();
315329
link.superpageCounter++;
316330
mLinkQueuesTotalAvailable++;
@@ -339,7 +353,7 @@ void CruDmaChannel::fillSuperpages()
339353
}
340354

341355
while (amountAvailable) {
342-
if (mReadyQueue.sizeGuess() >= READY_QUEUE_CAPACITY) {
356+
if (mReadyQueue->sizeGuess() >= mReadyQueueCapacity) {
343357
break;
344358
}
345359

@@ -358,19 +372,19 @@ int CruDmaChannel::getTransferQueueAvailable()
358372
// The transfer queue is empty when all its slots are available
359373
bool CruDmaChannel::isTransferQueueEmpty()
360374
{
361-
return mLinkQueuesTotalAvailable == (LINK_QUEUE_CAPACITY * mLinks.size());
375+
return mLinkQueuesTotalAvailable == (mLinkQueueCapacity * mLinks.size());
362376
}
363377

364378
int CruDmaChannel::getReadyQueueSize()
365379
{
366-
return mReadyQueue.sizeGuess();
380+
return mReadyQueue->sizeGuess();
367381
}
368382

369383
// Return a boolean that denotes whether the ready queue is full
370384
// The ready queue is full when the CRU has filled it up
371385
bool CruDmaChannel::isReadyQueueFull()
372386
{
373-
return mReadyQueue.isFull();
387+
return mReadyQueue->isFull();
374388
}
375389

376390
int32_t CruDmaChannel::getDroppedPackets()

src/Cru/CruDmaChannel.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,11 @@ class CruDmaChannel final : public DmaChannelPdaBase
7070
private:
7171
/// Max amount of superpages per link.
7272
/// This may not exceed the limit determined by the firmware capabilities.
73-
static constexpr size_t LINK_QUEUE_CAPACITY = Cru::MAX_SUPERPAGE_DESCRIPTORS;
74-
static constexpr size_t LINK_QUEUE_CAPACITY_ALLOCATIONS = LINK_QUEUE_CAPACITY + 1; // folly Queue needs + 1
73+
size_t mLinkQueueCapacity;
7574

7675
/// Max amount of superpages in the ready queue.
7776
/// This is an arbitrary size, can easily be increased if more headroom is needed.
78-
static constexpr size_t READY_QUEUE_CAPACITY = Cru::MAX_SUPERPAGE_DESCRIPTORS * Cru::MAX_LINKS;
79-
static constexpr size_t READY_QUEUE_CAPACITY_ALLOCATIONS = READY_QUEUE_CAPACITY + 1; // folly Queue needs + 1
77+
size_t mReadyQueueCapacity;
8078

8179
/// Queue for one link
8280
using SuperpageQueue = folly::ProducerConsumerQueue<Superpage>;
@@ -147,7 +145,7 @@ class CruDmaChannel final : public DmaChannelPdaBase
147145
size_t mLinkQueuesTotalAvailable;
148146

149147
/// Queue for superpages that have been transferred and are waiting for popping by the user
150-
SuperpageQueue mReadyQueue{ READY_QUEUE_CAPACITY_ALLOCATIONS };
148+
std::unique_ptr<SuperpageQueue> mReadyQueue;
151149

152150
// These variables are configuration parameters
153151

0 commit comments

Comments
 (0)