Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 59 additions & 13 deletions backends/uio/include/UioAccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,67 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
#pragma once

// The mainline kernel linux define the maximum number of UIO maps as 5
#ifndef MAX_UIO_MAPS
# define MAX_UIO_MAPS 5
#endif

#include <boost/filesystem.hpp>

#include <array>
#include <atomic>
#include <memory>
#include <string>
#include <utility>

namespace ChimeraTK {
/// @brief Implements a generic userspace interface for UIO devices.
class UioAccess {
private:
boost::filesystem::path _deviceFilePath;
/// @brief Implements map interface for UIO devices .
class UioMap {
public:
UioMap();
UioMap(int deviceFileDescriptor, size_t uioMapIdx, const std::string& uioMapPath);
~UioMap();
UioMap(const UioMap&) = delete;
UioMap& operator=(const UioMap&) = delete;
UioMap(UioMap&& other) noexcept;
UioMap& operator=(UioMap&&) noexcept;

explicit operator bool() const noexcept;

/// @brief Read data from the specified memory offset address. The address range starts at '0'.
/// @param address Start address of memory to read from
/// @param data Address pointer to which data is to be copied
/// @param sizeInBytes Number of bytes to copy
void read(uint64_t address, int32_t* data, size_t sizeInBytes);

/// @brief Write data to the specified memory offset address. The address range starts at '0'.
/// @param address Start address of memory to write to
/// @param data Address pointer from which data is to be copied
/// @param sizeInBytes Number of bytes to copy
void write(uint64_t address, int32_t const* data, size_t sizeInBytes);

private:
/// @brief Calculate the address from the perspective of the UIO map
/// @param address Start address of memory of the request
/// @param sizeInBytes Number of bytes to copy
/// @param isWrite Determines if it is a read or a write request
/// @return Unsigned value
size_t validateAndGetMapOffset(uint64_t address, size_t sizeInBytes, bool isWrite);
size_t _deviceLowerBound = 0;
size_t _deviceHigherBound = 0;
void* _deviceUserBase = nullptr;
};

int _deviceFileDescriptor = 0;
void* _deviceUserBase = nullptr;
void* _deviceKernelBase = nullptr;
size_t _deviceMemSize = 0;
boost::filesystem::path _deviceFilePath;
std::string _filename;
std::array<UioMap, MAX_UIO_MAPS> _maps;
uint32_t _lastInterruptCount = 0;
std::atomic<bool> _opened{false};

/// @brief Maps user space memory range to address range of UIO device.
void UioMMap();

/// @brief Unmaps user space memory range for address range of UIO device.
void UioUnmap();
uint8_t _maps_number = 0;

/// @brief Subtracts uint32_t values taking overflow into account.
/// @param minuend Minuend of subtraction
Expand All @@ -35,12 +73,17 @@ namespace ChimeraTK {
/// @brief Reads a decimal formatted value from a file as unsigned 32-bit integer.
/// @param fileName File path to read from
/// @return Unsigned value
uint32_t readUint32FromFile(std::string fileName);
static uint32_t readUint32FromFile(std::string fileName);

/// @brief Reads a hexadecimal formatted value from a file as unsigned 64-bit integer.
/// @param fileName File path to read from
/// @return Unsigned value
uint64_t readUint64HexFromFile(std::string fileName);
static uint64_t readUint64HexFromFile(std::string fileName);

/// @brief Get an UIO map handle
/// @param map The map to open
/// @return Reference to the opened map
UioAccess::UioMap& getMap(size_t map);

public:
explicit UioAccess(const std::string& deviceFilePath);
Expand All @@ -52,8 +95,11 @@ namespace ChimeraTK {
/// @brief Closes UIO device.
void close();

/// @brief Check whether the passed map index is valid.
bool mapIndexValid(uint64_t map);

/// @brief Read data from the specified memory offset address. The address range starts at '0'.
/// @param map Selected UIO memory region. Only region '0' is currently supported.
/// @param map Selected UIO memory region.
/// @param address Start address of memory to read from
/// @param data Address pointer to which data is to be copied
/// @param sizeInBytes Number of bytes to copy
Expand Down
Loading