Commit ae43f294 authored by Jialin Li's avatar Jialin Li
Browse files

corundum_bm: fix out-of-order dma completion

parent 3995c5f0
...@@ -94,6 +94,7 @@ DescRing::setSizeLog(size_t size_log) ...@@ -94,6 +94,7 @@ DescRing::setSizeLog(size_t size_log)
this->_sizeLog = size_log & 0xFF; this->_sizeLog = size_log & 0xFF;
this->_size = 1 << this->_sizeLog; this->_size = 1 << this->_sizeLog;
this->_sizeMask = this->_size - 1; this->_sizeMask = this->_size - 1;
this->cplDma.resize(this->_size, false);
} }
void void
...@@ -130,6 +131,33 @@ DescRing::full() ...@@ -130,6 +131,33 @@ DescRing::full()
return (this->_currHead - this->_tailPtr >= this->_size); return (this->_currHead - this->_tailPtr >= this->_size);
} }
bool
DescRing::updatePtr(ptr_t ptr, bool head)
{
ptr_t curr_ptr = head ? this->_headPtr : this->_tailPtr;
if (ptr != curr_ptr) {
// out of order completion
this->cplDma[ptr & this->_sizeMask] = true;
return false;
}
/* Safe to update the pointer. Also check if any DMA is completed
* out-of-order in front of us.
*/
curr_ptr = ptr & this->_sizeMask;
do {
if (head) {
this->_headPtr++;
} else {
this->_tailPtr++;
}
this->cplDma[curr_ptr] = false;
curr_ptr = (curr_ptr + 1) & this->_sizeMask;
} while (this->cplDma.at(curr_ptr));
return true;
}
EventRing::EventRing() EventRing::EventRing()
{ {
} }
...@@ -144,10 +172,9 @@ EventRing::dmaDone(DMAOp *op) ...@@ -144,10 +172,9 @@ EventRing::dmaDone(DMAOp *op)
assert(op->write); assert(op->write);
switch (op->type) { switch (op->type) {
case DMA_TYPE_EVENT: case DMA_TYPE_EVENT:
// TODO: assume in order transmission if (updatePtr((ptr_t)op->tag, true)) {
assert(this->_headPtr == op->tag);
this->_headPtr++;
msi_issue(0); msi_issue(0);
}
delete op; delete op;
break; break;
default: default:
...@@ -200,12 +227,11 @@ CplRing::dmaDone(DMAOp *op) ...@@ -200,12 +227,11 @@ CplRing::dmaDone(DMAOp *op)
switch (op->type) { switch (op->type) {
case DMA_TYPE_TX_CPL: case DMA_TYPE_TX_CPL:
case DMA_TYPE_RX_CPL: { case DMA_TYPE_RX_CPL: {
// TODO: assume in order transmission if (updatePtr((ptr_t)op->tag, true)) {
assert(this->_headPtr == op->tag);
this->_headPtr++;
unsigned type = op->type == DMA_TYPE_TX_CPL ? EVENT_TYPE_TX_CPL : unsigned type = op->type == DMA_TYPE_TX_CPL ? EVENT_TYPE_TX_CPL :
EVENT_TYPE_RX_CPL; EVENT_TYPE_RX_CPL;
this->eventRing->issueEvent(type, 0); this->eventRing->issueEvent(type, 0);
}
delete op; delete op;
break; break;
} }
...@@ -290,9 +316,7 @@ TxRing::dmaDone(DMAOp *op) ...@@ -290,9 +316,7 @@ TxRing::dmaDone(DMAOp *op)
case DMA_TYPE_MEM: case DMA_TYPE_MEM:
assert(!op->write); assert(!op->write);
eth_send(op->data, op->len); eth_send(op->data, op->len);
// TODO: assume in order transmission updatePtr((ptr_t)op->tag, false);
assert(this->_tailPtr == op->tag);
this->_tailPtr++;
this->txCplRing->complete(op->tag, op->len, true); this->txCplRing->complete(op->tag, op->len, true);
delete op; delete op;
break; break;
...@@ -329,9 +353,7 @@ RxRing::dmaDone(DMAOp *op) ...@@ -329,9 +353,7 @@ RxRing::dmaDone(DMAOp *op)
} }
case DMA_TYPE_MEM: case DMA_TYPE_MEM:
assert(op->write); assert(op->write);
// TODO: assume in order transmission updatePtr((ptr_t)op->tag, false);
assert(this->_tailPtr == op->tag);
this->_tailPtr++;
this->rxCplRing->complete(op->tag, op->len, false); this->rxCplRing->complete(op->tag, op->len, false);
delete op; delete op;
break; break;
......
#pragma once #pragma once
#include <list> #include <list>
#include <vector>
#include <stdint.h> #include <stdint.h>
typedef uint32_t reg_t; typedef uint32_t reg_t;
...@@ -180,6 +181,7 @@ public: ...@@ -180,6 +181,7 @@ public:
protected: protected:
bool empty(); bool empty();
bool full(); bool full();
bool updatePtr(ptr_t ptr, bool head);
addr_t _dmaAddr; addr_t _dmaAddr;
size_t _sizeLog; size_t _sizeLog;
...@@ -192,6 +194,7 @@ protected: ...@@ -192,6 +194,7 @@ protected:
ptr_t _currTail; ptr_t _currTail;
bool active; bool active;
bool armed; bool armed;
std::vector<bool> cplDma;
}; };
class EventRing : public DescRing { class EventRing : public DescRing {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment