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

working behavior model

parent 556c74dd
...@@ -108,22 +108,16 @@ DescRing::setTailPtr(ptr_t ptr) ...@@ -108,22 +108,16 @@ DescRing::setTailPtr(ptr_t ptr)
this->_tailPtr = ptr; this->_tailPtr = ptr;
} }
void
DescRing::dmaDone(DMAOp *op)
{
// No action by default
}
bool bool
DescRing::empty() DescRing::empty()
{ {
return (this->_headPtr == this->_tailPtr); return (this->_headPtr == this->_currTail);
} }
bool bool
DescRing::full() DescRing::full()
{ {
return (this->_headPtr - this->_tailPtr >= this->_size); return (this->_currHead - this->_tailPtr >= this->_size);
} }
EventRing::EventRing() EventRing::EventRing()
...@@ -191,13 +185,17 @@ CplRing::dmaDone(DMAOp *op) ...@@ -191,13 +185,17 @@ CplRing::dmaDone(DMAOp *op)
{ {
assert(op->write); assert(op->write);
switch (op->type) { switch (op->type) {
case DMA_TYPE_CPL: case DMA_TYPE_TX_CPL:
case DMA_TYPE_RX_CPL: {
// TODO: assume in order transmission // TODO: assume in order transmission
assert(this->_headPtr == op->tag); assert(this->_headPtr == op->tag);
this->_headPtr++; this->_headPtr++;
this->eventRing->issueEvent(EVENT_TYPE_TX_CPL, 0); unsigned type = op->type == DMA_TYPE_TX_CPL ? EVENT_TYPE_TX_CPL :
EVENT_TYPE_RX_CPL;
this->eventRing->issueEvent(type, 0);
delete op; delete op;
break; break;
}
default: default:
fprintf(stderr, "Unknown DMA type %u\n", op->type); fprintf(stderr, "Unknown DMA type %u\n", op->type);
abort(); abort();
...@@ -205,7 +203,7 @@ CplRing::dmaDone(DMAOp *op) ...@@ -205,7 +203,7 @@ CplRing::dmaDone(DMAOp *op)
} }
void void
CplRing::complete(unsigned index, size_t len) CplRing::complete(unsigned index, size_t len, bool tx)
{ {
if (full()) { if (full()) {
fprintf(stderr, "Completion ring is full\n"); fprintf(stderr, "Completion ring is full\n");
...@@ -214,7 +212,7 @@ CplRing::complete(unsigned index, size_t len) ...@@ -214,7 +212,7 @@ CplRing::complete(unsigned index, size_t len)
addr_t dma_addr = this->_dmaAddr + (this->_currHead & this->_sizeMask) * CPL_SIZE; addr_t dma_addr = this->_dmaAddr + (this->_currHead & this->_sizeMask) * CPL_SIZE;
/* Issue DMA write */ /* Issue DMA write */
DMAOp *op = new DMAOp; DMAOp *op = new DMAOp;
op->type = DMA_TYPE_CPL; op->type = tx ? DMA_TYPE_TX_CPL : DMA_TYPE_RX_CPL;
op->dma_addr = dma_addr; op->dma_addr = dma_addr;
op->len = CPL_SIZE; op->len = CPL_SIZE;
op->ring = this; op->ring = this;
...@@ -260,9 +258,9 @@ TxRing::setHeadPtr(ptr_t ptr) ...@@ -260,9 +258,9 @@ TxRing::setHeadPtr(ptr_t ptr)
void void
TxRing::dmaDone(DMAOp *op) TxRing::dmaDone(DMAOp *op)
{ {
assert(!op->write);
switch (op->type) { switch (op->type) {
case DMA_TYPE_DESC: { case DMA_TYPE_DESC: {
assert(!op->write);
Desc *desc = (Desc *)op->data; Desc *desc = (Desc *)op->data;
op->type = DMA_TYPE_MEM; op->type = DMA_TYPE_MEM;
op->dma_addr = desc->addr; op->dma_addr = desc->addr;
...@@ -272,11 +270,12 @@ TxRing::dmaDone(DMAOp *op) ...@@ -272,11 +270,12 @@ TxRing::dmaDone(DMAOp *op)
break; break;
} }
case DMA_TYPE_MEM: case DMA_TYPE_MEM:
assert(!op->write);
eth_send(op->data, op->len); eth_send(op->data, op->len);
// TODO: assume in order transmission // TODO: assume in order transmission
assert(this->_tailPtr == op->tag); assert(this->_tailPtr == op->tag);
this->_tailPtr++; this->_tailPtr++;
this->txCplRing->complete(op->tag, op->len); this->txCplRing->complete(op->tag, op->len, true);
delete op; delete op;
break; break;
default: default:
...@@ -285,6 +284,66 @@ TxRing::dmaDone(DMAOp *op) ...@@ -285,6 +284,66 @@ TxRing::dmaDone(DMAOp *op)
} }
} }
RxRing::RxRing(CplRing *cplRing)
: rxCplRing(cplRing)
{
}
RxRing::~RxRing()
{
}
void
RxRing::dmaDone(DMAOp *op)
{
switch (op->type) {
case DMA_TYPE_DESC: {
assert(!op->write);
Desc *desc = (Desc *)op->data;
op->type = DMA_TYPE_MEM;
op->dma_addr = desc->addr;
op->len = op->rx_data->len;
memcpy((void *)op->data, (void *)op->rx_data->data, op->len);
delete op->rx_data;
op->write = true;
issue_dma_op(op);
break;
}
case DMA_TYPE_MEM:
assert(op->write);
// TODO: assume in order transmission
assert(this->_tailPtr == op->tag);
this->_tailPtr++;
this->rxCplRing->complete(op->tag, op->len, false);
delete op;
break;
default:
fprintf(stderr, "Unknown DMA type %u\n", op->type);
abort();
}
}
void
RxRing::rx(RxData *rx_data)
{
if (empty()) {
delete rx_data;
return;
}
addr_t dma_addr = this->_dmaAddr + (this->_currTail & this->_sizeMask) * DESC_SIZE;
/* Issue DMA read */
DMAOp *op = new DMAOp;
op->type = DMA_TYPE_DESC;
op->dma_addr = dma_addr;
op->len = DESC_SIZE;
op->ring = this;
op->rx_data = rx_data;
op->tag = this->_currTail;
op->write = false;
issue_dma_op(op);
this->_currTail++;
}
Port::Port() Port::Port()
: _id(0), _features(0), _mtu(0), : _id(0), _features(0), _mtu(0),
_schedCount(0), _schedOffset(0), _schedStride(0), _schedCount(0), _schedOffset(0), _schedStride(0),
...@@ -424,7 +483,7 @@ Port::queueDisable() ...@@ -424,7 +483,7 @@ Port::queueDisable()
Corundum::Corundum() Corundum::Corundum()
: txCplRing(&this->eventRing), rxCplRing(&this->eventRing), : txCplRing(&this->eventRing), rxCplRing(&this->eventRing),
txRing(&this->txCplRing) txRing(&this->txCplRing), rxRing(&this->rxCplRing)
{ {
this->port.setId(0); this->port.setId(0);
this->port.setFeatures(0x711); this->port.setFeatures(0x711);
...@@ -467,6 +526,10 @@ Corundum::readReg(addr_t addr) ...@@ -467,6 +526,10 @@ Corundum::readReg(addr_t addr)
return 0x80000; return 0x80000;
case PHC_REG_FEATURES: case PHC_REG_FEATURES:
return 0x1; return 0x1;
case PHC_REG_PTP_CUR_SEC_L:
return 0x0;
case PHC_REG_PTP_CUR_SEC_H:
return 0x0;
case IF_REG_IF_ID: case IF_REG_IF_ID:
return 0; return 0;
case IF_REG_IF_FEATURES: case IF_REG_IF_FEATURES:
...@@ -505,6 +568,10 @@ Corundum::readReg(addr_t addr) ...@@ -505,6 +568,10 @@ Corundum::readReg(addr_t addr)
return this->txRing.tailPtr(); return this->txRing.tailPtr();
case TX_CPL_QUEUE_HEAD_PTR_REG: case TX_CPL_QUEUE_HEAD_PTR_REG:
return this->txCplRing.headPtr(); return this->txCplRing.headPtr();
case RX_QUEUE_TAIL_PTR_REG:
return this->rxRing.tailPtr();
case RX_CPL_QUEUE_HEAD_PTR_REG:
return this->rxCplRing.headPtr();
case PORT_REG_PORT_ID: case PORT_REG_PORT_ID:
return this->port.id(); return this->port.id();
case PORT_REG_PORT_FEATURES: case PORT_REG_PORT_FEATURES:
...@@ -658,6 +725,12 @@ Corundum::writeReg(addr_t addr, reg_t val) ...@@ -658,6 +725,12 @@ Corundum::writeReg(addr_t addr, reg_t val)
} }
} }
void
Corundum::rx(uint8_t port, RxData *rx_data)
{
this->rxRing.rx(rx_data);
}
} //namespace corundum } //namespace corundum
using namespace corundum; using namespace corundum;
...@@ -696,14 +769,14 @@ static void ...@@ -696,14 +769,14 @@ static void
issue_dma_op(DMAOp *op) issue_dma_op(DMAOp *op)
{ {
volatile union cosim_pcie_proto_d2h *msg = d2h_alloc(); volatile union cosim_pcie_proto_d2h *msg = d2h_alloc();
printf("issue dma op %p addr %lx len %u\n", op, op->dma_addr, op->len); //printf("issue dma op %p addr %lx len %u\n", op, op->dma_addr, op->len);
if (op->write) { if (op->write) {
volatile struct cosim_pcie_proto_d2h_write *write = &msg->write; volatile struct cosim_pcie_proto_d2h_write *write = &msg->write;
write->req_id = (uintptr_t)op; write->req_id = (uintptr_t)op;
write->offset = op->dma_addr; write->offset = op->dma_addr;
write->len = op->len; write->len = op->len;
memcpy((void *)write->data, op->data, op->len); memcpy((void *)write->data, (void *)op->data, op->len);
// WMB(); // WMB();
write->own_type = COSIM_PCIE_PROTO_D2H_MSG_WRITE | write->own_type = COSIM_PCIE_PROTO_D2H_MSG_WRITE |
COSIM_PCIE_PROTO_D2H_OWN_HOST; COSIM_PCIE_PROTO_D2H_OWN_HOST;
...@@ -722,7 +795,7 @@ static void ...@@ -722,7 +795,7 @@ static void
msi_issue(uint8_t vec) msi_issue(uint8_t vec)
{ {
volatile union cosim_pcie_proto_d2h *msg = d2h_alloc(); volatile union cosim_pcie_proto_d2h *msg = d2h_alloc();
printf("issue MSI interrupt vec %u\n", vec); //printf("issue MSI interrupt vec %u\n", vec);
volatile struct cosim_pcie_proto_d2h_interrupt *intr = &msg->interrupt; volatile struct cosim_pcie_proto_d2h_interrupt *intr = &msg->interrupt;
intr->vector = vec; intr->vector = vec;
intr->inttype = COSIM_PCIE_PROTO_INT_MSI; intr->inttype = COSIM_PCIE_PROTO_INT_MSI;
...@@ -736,7 +809,7 @@ static void ...@@ -736,7 +809,7 @@ static void
h2d_read(Corundum &nic, volatile struct cosim_pcie_proto_h2d_read *read) h2d_read(Corundum &nic, volatile struct cosim_pcie_proto_h2d_read *read)
{ {
reg_t val = nic.readReg(read->offset); reg_t val = nic.readReg(read->offset);
printf("read(off=0x%lx, len=%u, val=0x%x)\n", read->offset, read->len, val); //printf("read(off=0x%lx, len=%u, val=0x%x)\n", read->offset, read->len, val);
volatile union cosim_pcie_proto_d2h *msg; volatile union cosim_pcie_proto_d2h *msg;
volatile struct cosim_pcie_proto_d2h_readcomp *rc; volatile struct cosim_pcie_proto_d2h_readcomp *rc;
...@@ -764,7 +837,7 @@ h2d_write(Corundum &nic, volatile struct cosim_pcie_proto_h2d_write *write) ...@@ -764,7 +837,7 @@ h2d_write(Corundum &nic, volatile struct cosim_pcie_proto_h2d_write *write)
msg = d2h_alloc(); msg = d2h_alloc();
wc = &msg->writecomp; wc = &msg->writecomp;
printf("write(off=0x%lx, len=%u, val=0x%x)\n", write->offset, write->len, val); //printf("write(off=0x%lx, len=%u, val=0x%x)\n", write->offset, write->len, val);
nic.writeReg(write->offset, val); nic.writeReg(write->offset, val);
wc->req_id = write->req_id; wc->req_id = write->req_id;
...@@ -786,9 +859,14 @@ static void h2d_writecomp(volatile struct cosim_pcie_proto_h2d_writecomp *wc) ...@@ -786,9 +859,14 @@ static void h2d_writecomp(volatile struct cosim_pcie_proto_h2d_writecomp *wc)
op->ring->dmaDone(op); op->ring->dmaDone(op);
} }
static void eth_recv(volatile struct cosim_eth_proto_n2d_recv *recv) static void eth_recv(Corundum &nic,
volatile struct cosim_eth_proto_n2d_recv *recv)
{ {
printf("RX recv(port=%u, len=%u)\n", recv->port, recv->len); //printf("RX recv(port=%u, len=%u)\n", recv->port, recv->len);
RxData *rx_data = new RxData;
memcpy((void *)rx_data->data, (void *)recv->data, recv->len);
rx_data->len = recv->len;
nic.rx(recv->port, rx_data);
} }
static void eth_send(void *data, size_t len) static void eth_send(void *data, size_t len)
...@@ -836,7 +914,7 @@ static void poll_h2d(Corundum &nic) ...@@ -836,7 +914,7 @@ static void poll_h2d(Corundum &nic)
nicif_h2d_next(); nicif_h2d_next();
} }
static void poll_n2d(void) static void poll_n2d(Corundum &nic)
{ {
volatile union cosim_eth_proto_n2d *msg = nicif_n2d_poll(); volatile union cosim_eth_proto_n2d *msg = nicif_n2d_poll();
uint8_t t; uint8_t t;
...@@ -847,7 +925,7 @@ static void poll_n2d(void) ...@@ -847,7 +925,7 @@ static void poll_n2d(void)
t = msg->dummy.own_type & COSIM_ETH_PROTO_N2D_MSG_MASK; t = msg->dummy.own_type & COSIM_ETH_PROTO_N2D_MSG_MASK;
switch (t) { switch (t) {
case COSIM_ETH_PROTO_N2D_MSG_RECV: case COSIM_ETH_PROTO_N2D_MSG_RECV:
eth_recv(&msg->recv); eth_recv(nic, &msg->recv);
break; break;
default: default:
...@@ -884,7 +962,7 @@ int main(int argc, char *argv[]) ...@@ -884,7 +962,7 @@ int main(int argc, char *argv[])
while (!exiting) { while (!exiting) {
poll_h2d(nic); poll_h2d(nic);
poll_n2d(); poll_n2d(nic);
} }
nicsim_cleanup(); nicsim_cleanup();
......
...@@ -24,6 +24,8 @@ typedef uint16_t ptr_t; ...@@ -24,6 +24,8 @@ typedef uint16_t ptr_t;
#define IF_FEATURE_RX_HASH (1 << 10) #define IF_FEATURE_RX_HASH (1 << 10)
#define PHC_REG_FEATURES 0x0200 #define PHC_REG_FEATURES 0x0200
#define PHC_REG_PTP_CUR_SEC_L 0x0218
#define PHC_REG_PTP_CUR_SEC_H 0x021C
#define PHC_REG_PTP_SET_FNS 0x0230 #define PHC_REG_PTP_SET_FNS 0x0230
#define PHC_REG_PTP_SET_NS 0x0234 #define PHC_REG_PTP_SET_NS 0x0234
#define PHC_REG_PTP_SET_SEC_L 0x0238 #define PHC_REG_PTP_SET_SEC_L 0x0238
...@@ -132,16 +134,23 @@ struct Event { ...@@ -132,16 +134,23 @@ struct Event {
uint16_t source; uint16_t source;
} __attribute__((packed)) ; } __attribute__((packed)) ;
struct RxData {
size_t len;
uint8_t data[MAX_DMA_LEN];
};
#define DMA_TYPE_DESC 0 #define DMA_TYPE_DESC 0
#define DMA_TYPE_MEM 1 #define DMA_TYPE_MEM 1
#define DMA_TYPE_CPL 2 #define DMA_TYPE_TX_CPL 2
#define DMA_TYPE_EVENT 3 #define DMA_TYPE_RX_CPL 3
#define DMA_TYPE_EVENT 4
struct DMAOp { struct DMAOp {
uint8_t type; uint8_t type;
addr_t dma_addr; addr_t dma_addr;
size_t len; size_t len;
DescRing *ring; DescRing *ring;
RxData *rx_data;
uint64_t tag; uint64_t tag;
bool write; bool write;
uint8_t data[MAX_DMA_LEN]; uint8_t data[MAX_DMA_LEN];
...@@ -165,7 +174,7 @@ public: ...@@ -165,7 +174,7 @@ public:
virtual void setHeadPtr(ptr_t ptr); virtual void setHeadPtr(ptr_t ptr);
void setTailPtr(ptr_t ptr); void setTailPtr(ptr_t ptr);
virtual void dmaDone(DMAOp *op); virtual void dmaDone(DMAOp *op) = 0;
protected: protected:
bool empty(); bool empty();
...@@ -198,7 +207,7 @@ public: ...@@ -198,7 +207,7 @@ public:
~CplRing(); ~CplRing();
virtual void dmaDone(DMAOp *op) override; virtual void dmaDone(DMAOp *op) override;
void complete(unsigned index, size_t len); void complete(unsigned index, size_t len, bool tx);
private: private:
EventRing *eventRing; EventRing *eventRing;
...@@ -216,6 +225,18 @@ private: ...@@ -216,6 +225,18 @@ private:
CplRing *txCplRing; CplRing *txCplRing;
}; };
class RxRing : public DescRing {
public:
RxRing(CplRing *cplRing);
~RxRing();
virtual void dmaDone(DMAOp *op) override;
void rx(RxData *rx_data);
private:
CplRing *rxCplRing;
};
class Port { class Port {
public: public:
Port(); Port();
...@@ -263,12 +284,13 @@ public: ...@@ -263,12 +284,13 @@ public:
reg_t readReg(addr_t addr); reg_t readReg(addr_t addr);
void writeReg(addr_t addr, reg_t val); void writeReg(addr_t addr, reg_t val);
void rx(uint8_t port, RxData *rx_data);
private: private:
EventRing eventRing; EventRing eventRing;
TxRing txRing; TxRing txRing;
CplRing txCplRing; CplRing txCplRing;
DescRing rxRing; RxRing rxRing;
CplRing rxCplRing; CplRing rxCplRing;
Port port; Port port;
}; };
......
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