Commit ca9a38d4 authored by Wesley W. Terpstra's avatar Wesley W. Terpstra

Add a device to talk over PCIe to the WR card

parent 626617a8
......@@ -26,4 +26,5 @@ libcomponents_a_SOURCES = \
lm32/lm32-read.cpp \
lm32/lm32-drom.cpp \
gdb-rsp/gdb-rsp.cpp \
gdb-rsp/gdb-serial.cpp
gdb-rsp/gdb-serial.cpp \
rawrabbit/rawrabbit.cpp
#include "common/compat.h"
#include "rawrabbit.h"
#include "pinouts/pinouts.h"
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
struct rr_iocmd {
uint32_t address;
uint32_t datasize;
union {
uint32_t data32;
uint64_t data64;
};
};
#define RR_READ 0xc0103402
#define RR_WRITE 0x40103403
RawRabbit::RawRabbit(Interconnect* ic, const std::string& device)
: Component(ic),
address(*addMasterPort("address", uint32_pinout)),
read (*addMasterPort("read", command_pinout)),
write (*addMasterPort("write", uint32_pinout)),
effect (*addSlavePort ("effect", command_pinout)) {
fd = open(device.c_str(), O_RDWR);
}
RawRabbit::~RawRabbit() {
if (fd >= 0) close(fd);
}
SendQueue::const_iterator RawRabbit::send(SendQueue::const_iterator i, SendQueue::const_iterator end) {
for (; i != end; ++i) {
if (i->master == &reset) {
currentAddress = 0;
} else if (i->master == &address) {
currentAddress = static_cast<uint32_t>(i->bits);
} else if (i->master == &read) {
Operation op;
op.address = currentAddress;
op.data = 0;
op.write = false;
toExecute.push(op);
effect();
} else {
Bits b(i->bits);
b.resize(32);
Operation op;
op.address = currentAddress;
op.data = static_cast<uint32_t>(b);
op.write = true;
toExecute.push(op);
effect();
}
}
return i;
}
void RawRabbit::execute() {
if (toExecute.empty())
throw ProtocolViolation(this, "No pending side-effects in execute");
Operation& o = toExecute.front();
struct rr_iocmd iocmd;
iocmd.address =
0x80000 | /* WB base address */
(0 << 28) | /* Bar 0 */
o.address;
iocmd.datasize = 4;
iocmd.data32 = o.data;
if (o.write) {
ioctl(fd, RR_WRITE, &iocmd);
} else {
ioctl(fd, RR_READ, &iocmd);
}
o.data = iocmd.data32;
toRecv.push(o);
toExecute.pop();
}
void RawRabbit::recv(RecvQueue::const_iterator i, RecvQueue::const_iterator end) {
for (; i != end; ++i) {
if (toRecv.empty())
throw ProtocolViolation(this, "too many effects");
const Operation& o = toRecv.front();
if (!o.write) read(Bits(o.data));
toRecv.pop();
}
}
#ifndef RAWRABBIT_H
#define RAWRABBIT_H
#include "common/component.h"
#include <queue>
class RawRabbit : public Component {
public:
RawRabbit(Interconnect* ic, const std::string& device = "/dev/rawrabbit");
~RawRabbit();
void recv(RecvQueue::const_iterator i, RecvQueue::const_iterator end);
SendQueue::const_iterator send(SendQueue::const_iterator i, SendQueue::const_iterator end);
void execute();
public:
MasterPort& address;
MasterPort& read;
MasterPort& write;
SlavePort& effect;
protected:
int fd;
uint32_t currentAddress;
struct Operation {
uint32_t address;
uint32_t data;
bool write;
};
typedef std::queue<Operation> Operations;
Operations toExecute;
Operations toRecv;
};
#endif
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