summaryrefslogtreecommitdiff
path: root/python/openvino/runtime/streaming/image_streaming_app/uio
diff options
context:
space:
mode:
Diffstat (limited to 'python/openvino/runtime/streaming/image_streaming_app/uio')
-rw-r--r--python/openvino/runtime/streaming/image_streaming_app/uio/CMakeLists.txt35
-rw-r--r--python/openvino/runtime/streaming/image_streaming_app/uio/include/IUioDevice.h40
-rw-r--r--python/openvino/runtime/streaming/image_streaming_app/uio/source/UioDevice.cpp168
-rw-r--r--python/openvino/runtime/streaming/image_streaming_app/uio/source/UioDevice.h56
4 files changed, 299 insertions, 0 deletions
diff --git a/python/openvino/runtime/streaming/image_streaming_app/uio/CMakeLists.txt b/python/openvino/runtime/streaming/image_streaming_app/uio/CMakeLists.txt
new file mode 100644
index 0000000..4c445a2
--- /dev/null
+++ b/python/openvino/runtime/streaming/image_streaming_app/uio/CMakeLists.txt
@@ -0,0 +1,35 @@
+# Copyright 2023 Intel Corporation
+#
+# This software and the related documents are Intel copyrighted materials,
+# and your use of them is governed by the express license under which they
+# were provided to you ("License"). Unless the License provides otherwise,
+# you may not use, modify, copy, publish, distribute, disclose or transmit
+# this software or the related documents without Intel's prior written
+# permission.
+#
+# This software and the related documents are provided as is, with no express
+# or implied warranties, other than those that are expressly stated in the
+# License.
+
+project(uio)
+
+set(header_files "")
+set(source_files "")
+
+# specify the C++ standard
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED True)
+
+# Header files
+set(header_files ${header_files} "include/IUioDevice.h")
+set(header_files ${header_files} "source/UioDevice.h")
+
+# Source files
+set(source_files ${source_files} "source/UioDevice.cpp")
+
+set(all_files ${header_files} ${source_files})
+
+add_library(${PROJECT_NAME} STATIC ${all_files})
+
+# Include directories
+target_include_directories(${PROJECT_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
diff --git a/python/openvino/runtime/streaming/image_streaming_app/uio/include/IUioDevice.h b/python/openvino/runtime/streaming/image_streaming_app/uio/include/IUioDevice.h
new file mode 100644
index 0000000..9b964a7
--- /dev/null
+++ b/python/openvino/runtime/streaming/image_streaming_app/uio/include/IUioDevice.h
@@ -0,0 +1,40 @@
+// Copyright 2023 Intel Corporation.
+//
+// This software and the related documents are Intel copyrighted materials,
+// and your use of them is governed by the express license under which they
+// were provided to you ("License"). Unless the License provides otherwise,
+// you may not use, modify, copy, publish, distribute, disclose or transmit
+// this software or the related documents without Intel's prior written
+// permission.
+//
+// This software and the related documents are provided as is, with no express
+// or implied warranties, other than those that are expressly stated in the
+// License.
+
+#pragma once
+#include <filesystem>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace UIO {
+class DeviceItem {
+ public:
+ std::string _name;
+ uint32_t _index;
+ std::string _indexedName;
+ std::filesystem::path _rootPath;
+};
+
+class IDevice {
+ public:
+ static std::shared_ptr<IDevice> Load(const std::string& deviceName, uint32_t index = 0);
+ static std::vector<DeviceItem> GetDevices();
+
+ virtual uint32_t Read(uint32_t registerIndex) = 0;
+ virtual void Write(uint32_t registerIndex, uint32_t value) = 0;
+ virtual void ReadBlock(void* host_addr, size_t offset, size_t size) = 0;
+ virtual void WriteBlock(const void* host_addr, size_t offset, size_t size) = 0;
+};
+
+} // namespace UIO
diff --git a/python/openvino/runtime/streaming/image_streaming_app/uio/source/UioDevice.cpp b/python/openvino/runtime/streaming/image_streaming_app/uio/source/UioDevice.cpp
new file mode 100644
index 0000000..d1b5d17
--- /dev/null
+++ b/python/openvino/runtime/streaming/image_streaming_app/uio/source/UioDevice.cpp
@@ -0,0 +1,168 @@
+// Copyright 2023 Intel Corporation.
+//
+// This software and the related documents are Intel copyrighted materials,
+// and your use of them is governed by the express license under which they
+// were provided to you ("License"). Unless the License provides otherwise,
+// you may not use, modify, copy, publish, distribute, disclose or transmit
+// this software or the related documents without Intel's prior written
+// permission.
+//
+// This software and the related documents are provided as is, with no express
+// or implied warranties, other than those that are expressly stated in the
+// License.
+
+#include "UioDevice.h"
+#include <fcntl.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <filesystem>
+#include <fstream>
+
+namespace UIO {
+static const std::string uioDriverFolder = "/sys/class/uio";
+
+std::shared_ptr<IDevice> IDevice::Load(const std::string& deviceName, uint32_t index) {
+ std::vector<DeviceItem> deviceItems = GetDevices();
+ std::string indexedDeviceName = deviceName + std::to_string(index);
+
+ for (auto& deviceItem : deviceItems) {
+ if (deviceItem._indexedName == indexedDeviceName) {
+ auto spUioDevice = std::make_shared<Device>(deviceItem);
+ return spUioDevice->IsValid() ? spUioDevice : nullptr;
+ }
+ }
+
+ return nullptr;
+}
+
+std::vector<DeviceItem> IDevice::GetDevices() {
+ std::vector<DeviceItem> deviceItems;
+
+ for (const auto& entry : std::filesystem::directory_iterator(uioDriverFolder)) {
+ // Filter out uio*
+ if (entry.is_directory()) {
+ std::filesystem::path filePath = entry.path();
+ std::string stem = filePath.filename();
+ if (stem.substr(0, 3) == "uio") {
+ std::string indexedDeviceName = Device::ReadStringFromFile(filePath / "name");
+ if (not indexedDeviceName.empty()) {
+ std::string deviceName;
+ uint32_t index = 0;
+ Device::SplitIndexedDeviceName(indexedDeviceName, deviceName, index);
+ deviceItems.push_back({deviceName, index, indexedDeviceName, filePath});
+ }
+ }
+ }
+ }
+
+ return deviceItems;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+Device::Device(const DeviceItem& deviceItem) : _deviceItem(deviceItem) { MapRegion(); }
+
+Device::~Device() { UnmapRegion(); }
+
+bool Device::IsValid() { return (_fd >= 0); }
+
+uint32_t Device::Read(uint32_t registerIndex) {
+ if (registerIndex >= _maximumRegisterIndex) return 0;
+
+ uint32_t* pRegister = (uint32_t*)_pPtr;
+
+ uint32_t value = pRegister[registerIndex];
+ return value;
+}
+
+void Device::Write(uint32_t registerIndex, uint32_t value) {
+ if (registerIndex < _maximumRegisterIndex) {
+ uint32_t* pRegister = (uint32_t*)_pPtr;
+ pRegister[registerIndex] = value;
+ }
+}
+
+void Device::ReadBlock(void* pHostDestination, size_t offset, size_t size) {
+ if ((offset + size) < _size) {
+ uint8_t* pDeviceMem = (uint8_t*)_pPtr + offset;
+ ::memcpy(pHostDestination, pDeviceMem, size);
+ }
+}
+
+void Device::WriteBlock(const void* pHostSourceAddress, size_t offset, size_t size) {
+ if ((offset + size) < _size) {
+ uint8_t* pDeviceMem = (uint8_t*)_pPtr + offset;
+ ::memcpy(pDeviceMem, pHostSourceAddress, size);
+ }
+}
+
+uint64_t Device::ReadValueFromFile(const std::filesystem::path& path) {
+ std::string line = ReadStringFromFile(path);
+ int base = (line.substr(0, 2) == "0x") ? 16 : 10;
+ return std::stoull(line, nullptr, base);
+}
+
+std::string Device::ReadStringFromFile(const std::filesystem::path& path) {
+ std::ifstream inputStream(path);
+ if (inputStream.good()) {
+ std::string line;
+ std::getline(inputStream, line);
+ return line;
+ }
+ return "";
+}
+
+bool Device::MapRegion() {
+ _size = ReadValueFromFile(_deviceItem._rootPath / "maps/map0/size");
+ _offset = ReadValueFromFile(_deviceItem._rootPath / "maps/map0/offset");
+ _physicalAddress = ReadValueFromFile(_deviceItem._rootPath / "maps/map0/addr");
+ _maximumRegisterIndex = _size / sizeof(uint32_t);
+
+ std::filesystem::path uioDevicePath = "/dev";
+ std::filesystem::path uioDeviceId = _deviceItem._rootPath.stem();
+ uioDevicePath /= uioDeviceId;
+
+ _fd = ::open(uioDevicePath.c_str(), O_RDWR);
+ if (_fd < 0) {
+ return false;
+ }
+
+ // Map the region into userspace
+ _pBase = (uint8_t*)::mmap(NULL, (size_t)_size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0);
+ if (_pBase == MAP_FAILED) {
+ return false;
+ }
+
+ // CST base address is at _pBase + _offset
+ _pPtr = (uint32_t*)(_pBase + _offset);
+
+ return true;
+};
+
+void Device::UnmapRegion() {
+ int r = 0;
+ if (_pBase) {
+ r = ::munmap(_pBase, _size);
+ _pBase = nullptr;
+ }
+
+ if (_fd >= 0) {
+ r = ::close(_fd);
+ _fd = -1;
+ }
+ (void)r;
+}
+
+void Device::SplitIndexedDeviceName(const std::string& indexedDeviceName, std::string& deviceName, uint32_t& index) {
+ int32_t len = static_cast<int32_t>(indexedDeviceName.length());
+ int32_t nDecimals = 0;
+ for (int32_t i = (len - 1); i >= 0; i--) {
+ if (::isdigit(indexedDeviceName[i])) nDecimals++;
+ }
+
+ deviceName = indexedDeviceName.substr(0, len - nDecimals);
+ index = std::stoul(indexedDeviceName.substr(len - nDecimals));
+}
+
+} // namespace UIO
diff --git a/python/openvino/runtime/streaming/image_streaming_app/uio/source/UioDevice.h b/python/openvino/runtime/streaming/image_streaming_app/uio/source/UioDevice.h
new file mode 100644
index 0000000..49c6f51
--- /dev/null
+++ b/python/openvino/runtime/streaming/image_streaming_app/uio/source/UioDevice.h
@@ -0,0 +1,56 @@
+// Copyright 2023 Intel Corporation.
+//
+// This software and the related documents are Intel copyrighted materials,
+// and your use of them is governed by the express license under which they
+// were provided to you ("License"). Unless the License provides otherwise,
+// you may not use, modify, copy, publish, distribute, disclose or transmit
+// this software or the related documents without Intel's prior written
+// permission.
+//
+// This software and the related documents are provided as is, with no express
+// or implied warranties, other than those that are expressly stated in the
+// License.
+
+#pragma once
+
+#include <filesystem>
+#include <memory>
+#include <string>
+#include <vector>
+#include "IUioDevice.h"
+
+namespace UIO {
+class Device : public IDevice {
+ public:
+ Device(const DeviceItem& deviceItem);
+ ~Device();
+
+ // IDevice interface
+ uint32_t Read(uint32_t registerIndex) override;
+ void Write(uint32_t registerIndex, uint32_t value) override;
+ void ReadBlock(void* host_addr, size_t offset, size_t size) override;
+ void WriteBlock(const void* host_addr, size_t offset, size_t size) override;
+
+ bool IsValid();
+ static uint64_t ReadValueFromFile(const std::filesystem::path& path);
+ static std::string ReadStringFromFile(const std::filesystem::path& path);
+ static void SplitIndexedDeviceName(const std::string& indexedDeviceName, std::string& deviceName, uint32_t& index);
+
+ private:
+ Device() = delete;
+ Device(Device const&) = delete;
+ void operator=(Device const&) = delete;
+
+ bool MapRegion();
+ void UnmapRegion();
+
+ DeviceItem _deviceItem;
+ uint32_t _maximumRegisterIndex = 0;
+ int _fd = -1; // File pointer to UIO - Used to indicate the the Device is valid
+ uint64_t _physicalAddress = 0;
+ uint64_t _size = 0; // Size of the mmapped region
+ uint64_t _offset = 0; // Offset of the first register
+ uint8_t* _pBase = nullptr; // Base of the mmapped region
+ uint32_t* _pPtr = nullptr; // The first register
+};
+} // namespace UIO