rogue
Loading...
Searching...
No Matches
MemMap.cpp
Go to the documentation of this file.
1
17#include "rogue/Directives.h"
18
20
21#include <fcntl.h>
22#include <inttypes.h>
23#include <sys/mman.h>
24#include <sys/stat.h>
25#include <sys/types.h>
26#include <unistd.h>
27
28#include <cstdio>
29#include <cstring>
30#include <memory>
31#include <thread>
32
33#include "rogue/GeneralError.h"
34#include "rogue/GilRelease.h"
38
39namespace rh = rogue::hardware;
41
42#ifndef NO_PYTHON
43 #include <boost/python.hpp>
44namespace bp = boost::python;
45#endif
46
48rh::MemMapPtr rh::MemMap::create(uint64_t base, uint32_t size) {
49 rh::MemMapPtr r = std::make_shared<rh::MemMap>(base, size);
50 return (r);
51}
52
54rh::MemMap::MemMap(uint64_t base, uint32_t size) : rim::Slave(4, 0xFFFFFFFF) {
55 log_ = rogue::Logging::create("MemMap");
56
57 size_ = size;
58
59 fd_ = ::open(MAP_DEVICE, O_RDWR);
60
61 if (fd_ < 0) throw(rogue::GeneralError::create("MemMap::MemMap", "Failed to open device file: %s", MAP_DEVICE));
62
63 if ((map_ = reinterpret_cast<uint8_t*>(mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, base))) ==
64 reinterpret_cast<void*>(-1))
65 throw(rogue::GeneralError::create("MemMap::MemMap", "Failed to map memory to user space."));
66
67 log_->debug("Created map to 0x%" PRIx64 " with size 0x%" PRIx32, base, size);
68
69 // Start read thread
70 threadEn_ = true;
71 thread_ = new std::thread(&rh::MemMap::runThread, this);
72}
73
75rh::MemMap::~MemMap() {
76 this->stop();
77}
78
79void rh::MemMap::stop() {
80 if (threadEn_) {
82 threadEn_ = false;
83 queue_.stop();
84 thread_->join();
85 munmap(reinterpret_cast<void*>(const_cast<uint8_t*>(map_)), size_);
86 ::close(fd_);
87 }
88}
89
91void rh::MemMap::doTransaction(rim::TransactionPtr tran) {
93 queue_.push(tran);
94}
95
97void rh::MemMap::runThread() {
99
100 uint32_t* tPtr;
101 uint32_t* mPtr;
102 uint32_t count;
103
104 log_->logThreadId();
105
106 while (threadEn_) {
107 if ((tran = queue_.pop()) != NULL) {
108 count = 0;
109
110 rim::TransactionLockPtr lock = tran->lock();
111
112 if (tran->expired()) {
113 log_->warning("Transaction expired. Id=%" PRIu32, tran->id());
114 tran.reset();
115 continue;
116 }
117
118 if ((tran->size() % 4) != 0) {
119 tran->error("Invalid transaction size %" PRIu32 ", must be an integer number of 4 bytes", tran->size());
120 tran.reset();
121 continue;
122 }
123
124 // Check that the address is legal
125 if ((tran->address() + tran->size()) > size_) {
126 tran->error("Request transaction to address 0x%" PRIx64 " with size %" PRIu32 " is out of bounds",
127 tran->address(),
128 tran->size());
129 tran.reset();
130 continue;
131 }
132
133 tPtr = reinterpret_cast<uint32_t*>(tran->begin());
134 mPtr = const_cast<uint32_t*>(reinterpret_cast<volatile uint32_t*>(map_ + tran->address()));
135
136 while (count != tran->size()) {
137 // Write or post
138 if (tran->type() == rim::Write || tran->type() == rim::Post) *mPtr = *tPtr;
139
140 // Read or verify
141 else
142 *tPtr = *mPtr;
143
144 ++mPtr;
145 ++tPtr;
146 count += 4;
147 }
148
149 log_->debug("Transaction id=%" PRIu32 ", addr 0x%08" PRIx64 ". Size=%" PRIu32 ", type=%" PRIu32,
150 tran->id(),
151 tran->address(),
152 tran->size(),
153 tran->type());
154 tran->done();
155 }
156 }
157}
158
159void rh::MemMap::setup_python() {
160#ifndef NO_PYTHON
161
162 bp::class_<rh::MemMap, rh::MemMapPtr, bp::bases<rim::Slave>, boost::noncopyable>("MemMap",
163 bp::init<uint64_t, uint32_t>());
164
165 bp::implicitly_convertible<rh::MemMapPtr, rim::SlavePtr>();
166#endif
167}
#define MAP_DEVICE
Definition MemMap.h:32
static GeneralError create(std::string src, const char *fmt,...)
Creates a formatted error instance.
RAII helper that releases the Python GIL for a scope.
Definition GilRelease.h:36
static std::shared_ptr< rogue::Logging > create(const std::string &name, bool quiet=false)
Creates a logger instance.
Definition Logging.cpp:60
std::shared_ptr< rogue::hardware::MemMap > MemMapPtr
Shared pointer alias for MemMap.
Definition MemMap.h:128
std::shared_ptr< rogue::interfaces::memory::TransactionLock > TransactionLockPtr
Shared pointer alias for TransactionLock.
static const uint32_t Write
Memory write transaction type.
Definition Constants.h:43
std::shared_ptr< rogue::interfaces::memory::Transaction > TransactionPtr
Shared pointer alias for Transaction.
static const uint32_t Post
Memory posted write transaction type.
Definition Constants.h:50