24 if(boost::filesystem::is_symlink(_deviceFilePath)) {
25 _deviceFilePath = boost::filesystem::canonical(_deviceFilePath);
27 std::string fileName = _deviceFilePath.filename().string();
28 _deviceKernelBase = (
void*)readUint64HexFromFile(
"/sys/class/uio/" + fileName +
"/maps/map0/addr");
29 _deviceMemSize = readUint64HexFromFile(
"/sys/class/uio/" + fileName +
"/maps/map0/size");
30 _lastInterruptCount = readUint32FromFile(
"/sys/class/uio/" + fileName +
"/event");
33 _deviceFileDescriptor =
::open(_deviceFilePath.c_str(), O_RDWR);
34 if(_deviceFileDescriptor < 0) {
49 void UioAccess::read(uint64_t map, uint64_t address, int32_t* __restrict__ data,
size_t sizeInBytes) {
55 address = address %
reinterpret_cast<uint64_t
>(_deviceKernelBase);
57 if(address + sizeInBytes > _deviceMemSize) {
61 volatile int32_t* rptr =
static_cast<volatile int32_t*
>(_deviceUserBase) + address /
sizeof(int32_t);
62 while(sizeInBytes >=
sizeof(int32_t)) {
63 *(data++) = *(rptr++);
64 sizeInBytes -=
sizeof(int32_t);
68 void UioAccess::write(uint64_t map, uint64_t address, int32_t
const* data,
size_t sizeInBytes) {
74 address = address %
reinterpret_cast<uint64_t
>(_deviceKernelBase);
76 if(address + sizeInBytes > _deviceMemSize) {
80 volatile int32_t* __restrict__ wptr =
static_cast<volatile int32_t*
>(_deviceUserBase) + address /
sizeof(int32_t);
81 while(sizeInBytes >=
sizeof(int32_t)) {
82 *(wptr++) = *(data++);
83 sizeInBytes -=
sizeof(int32_t);
89 uint32_t totalInterruptCount = 0;
91 uint32_t occurredInterruptCount = 0;
94 pfd.fd = _deviceFileDescriptor;
97 int ret = poll(&pfd, 1, timeoutMs);
101 ret =
::read(_deviceFileDescriptor, &totalInterruptCount,
sizeof(totalInterruptCount));
103 if(ret != (ssize_t)
sizeof(totalInterruptCount)) {
108 occurredInterruptCount = subtractUint32OverflowSafe(totalInterruptCount, _lastInterruptCount);
109 _lastInterruptCount = totalInterruptCount;
113 occurredInterruptCount = 0;
118 return occurredInterruptCount;
123 ssize_t ret =
::write(_deviceFileDescriptor, &unmask,
sizeof(unmask));
125 if(ret != (ssize_t)
sizeof(unmask)) {
131 return _deviceFilePath.string();
134 void UioAccess::UioMMap() {
135 _deviceUserBase = mmap(NULL, _deviceMemSize, PROT_READ | PROT_WRITE, MAP_SHARED, _deviceFileDescriptor, 0);
136 if(_deviceUserBase == MAP_FAILED) {
137 ::close(_deviceFileDescriptor);
143 void UioAccess::UioUnmap() {
144 munmap(_deviceUserBase, _deviceMemSize);
147 uint32_t UioAccess::subtractUint32OverflowSafe(uint32_t minuend, uint32_t subtrahend) {
148 if(subtrahend > minuend) {
150 (uint32_t)(
static_cast<uint64_t
>(std::numeric_limits<uint32_t>::max()) -
static_cast<uint64_t
>(subtrahend));
153 return minuend - subtrahend;
157 uint32_t UioAccess::readUint32FromFile(std::string fileName) {
159 std::ifstream inputFile(fileName);
161 if(inputFile.is_open()) {
165 return (uint32_t)value;
168 uint64_t UioAccess::readUint64HexFromFile(std::string fileName) {
170 std::ifstream inputFile(fileName);
172 if(inputFile.is_open()) {
173 inputFile >> std::hex >> value;