summaryrefslogtreecommitdiff
path: root/python/openvino/runtime/coredla_device/mmd/hps_platform
diff options
context:
space:
mode:
Diffstat (limited to 'python/openvino/runtime/coredla_device/mmd/hps_platform')
-rw-r--r--python/openvino/runtime/coredla_device/mmd/hps_platform/.gitignore20
-rw-r--r--python/openvino/runtime/coredla_device/mmd/hps_platform/CMakeLists.txt59
-rw-r--r--python/openvino/runtime/coredla_device/mmd/hps_platform/host/acl_hps.cpp473
-rw-r--r--python/openvino/runtime/coredla_device/mmd/hps_platform/host/acl_hps.h111
-rw-r--r--python/openvino/runtime/coredla_device/mmd/hps_platform/host/dma_device.cpp120
-rw-r--r--python/openvino/runtime/coredla_device/mmd/hps_platform/host/dma_device.h56
-rw-r--r--python/openvino/runtime/coredla_device/mmd/hps_platform/host/hps_types.h44
-rw-r--r--python/openvino/runtime/coredla_device/mmd/hps_platform/host/mmd_device.cpp129
-rw-r--r--python/openvino/runtime/coredla_device/mmd/hps_platform/host/mmd_device.h75
-rw-r--r--python/openvino/runtime/coredla_device/mmd/hps_platform/host/uio_device.cpp469
-rw-r--r--python/openvino/runtime/coredla_device/mmd/hps_platform/host/uio_device.h162
-rw-r--r--python/openvino/runtime/coredla_device/mmd/hps_platform/include/aocl_mmd.h645
12 files changed, 2363 insertions, 0 deletions
diff --git a/python/openvino/runtime/coredla_device/mmd/hps_platform/.gitignore b/python/openvino/runtime/coredla_device/mmd/hps_platform/.gitignore
new file mode 100644
index 0000000..0948b39
--- /dev/null
+++ b/python/openvino/runtime/coredla_device/mmd/hps_platform/.gitignore
@@ -0,0 +1,20 @@
+*~
+*#
+*.marks
+release_build/
+build/
+example_designs/mem_bandwidth/bin/
+example_designs/mem_bandwidth/simulation.tar.gz
+example_designs/mem_bandwidth/temp_simulation/
+linux64/lib/
+linux64/libexec/diagnose
+linux64/libexec/program
+ase/mpf_src
+*.pyc
+*.swp
+*.kwlp
+*.kwps
+temp_simulation/
+simulation.tar.gz
+
+backup
diff --git a/python/openvino/runtime/coredla_device/mmd/hps_platform/CMakeLists.txt b/python/openvino/runtime/coredla_device/mmd/hps_platform/CMakeLists.txt
new file mode 100644
index 0000000..d8bf50d
--- /dev/null
+++ b/python/openvino/runtime/coredla_device/mmd/hps_platform/CMakeLists.txt
@@ -0,0 +1,59 @@
+# (C) 2017 Intel Corporation. All rights reserved.
+# Your use of Intel Corporation's design tools, logic functions and other
+# software and tools, and its AMPP partner logic functions, and any output
+# files any of the foregoing (including device programming or simulation
+# files), and any associated documentation or information are expressly subject
+# to the terms and conditions of the Intel Program License Subscription
+# Agreement, Intel MegaCore Function License Agreement, or other applicable
+# license agreement, including, without limitation, that your use is for the
+# sole purpose of programming logic devices manufactured by Intel and sold by
+# Intel or its authorized distributors. Please refer to the applicable
+# agreement for further details.
+
+cmake_minimum_required(VERSION 2.8.12)
+project(mmd)
+
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
+
+# DLA specific modifications made to the MMD
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DDLA_MMD")
+
+# Select PCIE Gen3 x8
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGEN3_x8")
+
+# from the opencl makefile
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DKERNEL_64BIT -DOPTION3=1 -DACL_USE_DMA=1 -DACL_COMPILER_IS_MSVC=0 -Wall -Wno-unknown-pragmas -DACL_HAS_STDLIB_STDIO")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector -Wformat -Wformat-security -D_GLIBCXX_USE_CXX11_ABI=0 -fPIC -DACL_HOST_RUNTIME_IS_STATIC=0")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DACL_OPENCL_HOST_SYS=linux -DACL_OPENCL_HOST_BIT=64 -DACL_TARGET_SYS=linux -DACL_TARGET_BIT=64 -DLINUX -DACL_MAX_DEVICE=128")
+
+set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -D_FORTIFY_SOURCE=2 -O3")
+enable_language(C ASM)
+
+set(ASM_OPTIONS "-x assembler-with-cpp")
+if(${CMAKE_C_COMPILER_ID} STREQUAL "Clang")
+ set(ASM_OPTIONS "${ASM_OPTIONS} -no-integrated-as")
+endif()
+
+set(CMAKE_ASM_FLAGS "${CFLAGS} ${ASM_OPTIONS}")
+
+if(RUNTIME_POLLING)
+ add_definitions(-DRUNTIME_POLLING)
+endif(RUNTIME_POLLING)
+
+set(MMD_SRC
+ ./host/acl_hps.cpp
+ ./host/mmd_device.cpp
+ ./host/dma_device.cpp
+ ./host/uio_device.cpp
+)
+
+add_library(hps_platform_mmd SHARED ${MMD_SRC})
+
+target_include_directories(hps_platform_mmd PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+target_link_libraries(hps_platform_mmd)
+
+install(TARGETS hps_platform_mmd
+ LIBRARY DESTINATION lib
+ COMPONENT hps_platform_mmd
+)
diff --git a/python/openvino/runtime/coredla_device/mmd/hps_platform/host/acl_hps.cpp b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/acl_hps.cpp
new file mode 100644
index 0000000..53055ef
--- /dev/null
+++ b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/acl_hps.cpp
@@ -0,0 +1,473 @@
+// (c) 1992-2021 Intel Corporation.
+// Intel, the Intel logo, Intel, MegaCore, NIOS II, Quartus and TalkBack words
+// and logos are trademarks of Intel Corporation or its subsidiaries in the U.S.
+// and/or other countries. Other marks and brands may be claimed as the property
+// of others. See Trademarks on intel.com for full list of Intel trademarks or
+// the Trademarks & Brands Names Database (if Intel) or See www.Intel.com/legal (if Altera)
+// Your use of Intel Corporation's design tools, logic functions and other
+// software and tools, and its AMPP partner logic functions, and any output
+// files any of the foregoing (including device programming or simulation
+// files), and any associated documentation or information are expressly subject
+// to the terms and conditions of the Altera Program License Subscription
+// Agreement, Intel MegaCore Function License Agreement, or other applicable
+// license agreement, including, without limitation, that your use is for the
+// sole purpose of programming logic devices manufactured by Intel and sold by
+// Intel or its authorized distributors. Please refer to the applicable
+// agreement for further details.
+
+/* ===- HPS.cpp ------------------------------------------------- C++ -*-=== */
+/* */
+/* Intel(R) HPS MMD Driver */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+/* */
+/* This file implements the functions that are defined in aocl_mmd.h */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+
+// common and its own header files
+#include "acl_hps.h"
+
+// other standard header files
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <memory>
+#include <map>
+#include <sstream>
+#include <string>
+#include <utility>
+
+#include "mmd_device.h"
+
+#ifdef DLA_MMD
+#include <chrono>
+#include <thread>
+#endif
+
+#if defined(LINUX)
+#include <fcntl.h>
+#include <semaphore.h>
+#include <signal.h>
+#include <unistd.h>
+#endif // LINUX
+
+#define MAX_HPS_FPGA_DEVICES (1)
+
+// MAX size of line read from pipe-ing the output of system call to MMD
+#define BUF_SIZE 1024
+// MAX size of command passed to system for invoking system call from MMD
+#define SYSTEM_CMD_SIZE 4 * 1024
+
+#ifndef DLA_MMD
+// static helper functions
+static bool blob_has_elf_signature(void *data, size_t data_size);
+#endif
+
+
+// Function to return the number of boards installed in the system
+unsigned int get_offline_num_boards() {
+ board_names names = mmd_get_devices(MAX_HPS_FPGA_DEVICES);
+ return (unsigned int)names.size();
+}
+
+// Get information about the board using the enum aocl_mmd_offline_info_t for
+// offline info (called without a handle), and the enum aocl_mmd_info_t for
+// info specific to a certain board.
+#define RESULT_INT(X) \
+ { \
+ *((int *)param_value) = X; \
+ if (param_size_ret) *param_size_ret = sizeof(int); \
+ }
+#define RESULT_UNSIGNED(X) \
+ { \
+ *((unsigned *)param_value) = X; \
+ if (param_size_ret) *param_size_ret = sizeof(unsigned); \
+ }
+#define RESULT_SIZE_T(X) \
+ { \
+ *((size_t *)param_value) = X; \
+ if (param_size_ret) *param_size_ret = sizeof(size_t); \
+ }
+#if defined(WINDOWS)
+#define RESULT_STR(X) \
+ do { \
+ size_t Xlen = strnlen(X, MAX_NAME_SIZE) + 1; \
+ memcpy_s((void *)param_value, param_value_size, X, (param_value_size <= Xlen) ? param_value_size : Xlen); \
+ if (param_size_ret) *param_size_ret = Xlen; \
+ } while (0)
+#else
+#define RESULT_STR(X) \
+ do { \
+ size_t Xlen = strnlen(X, MAX_NAME_SIZE) + 1; \
+ memcpy((void *)param_value, X, (param_value_size <= Xlen) ? param_value_size : Xlen); \
+ if (param_size_ret) *param_size_ret = Xlen; \
+ } while (0)
+#endif
+#define ACL_VENDOR_NAME "Intel"
+int aocl_mmd_get_offline_info(aocl_mmd_offline_info_t requested_info_id,
+ size_t param_value_size,
+ void *param_value,
+ size_t *param_size_ret) {
+ unsigned int num_boards;
+ switch (requested_info_id) {
+ case AOCL_MMD_VERSION:
+ RESULT_STR(MMD_VERSION);
+ break;
+ case AOCL_MMD_NUM_BOARDS: {
+ num_boards = MAX_HPS_FPGA_DEVICES;
+ RESULT_INT((int)num_boards);
+ break;
+ }
+ case AOCL_MMD_BOARD_NAMES: {
+ // Retrieve all the CoreDLA cores in the system
+ board_names names = mmd_get_devices(MAX_HPS_FPGA_DEVICES);
+ // Construct a list of all possible devices supported by this MMD layer
+ std::ostringstream board;
+ auto name = names.begin();
+ while(name != names.end() )
+ {
+ board << *name;
+ name++;
+ if( name != names.end() )
+ {
+ board << ";";
+ }
+ }
+
+ RESULT_STR(board.str().c_str());
+ break;
+ }
+ case AOCL_MMD_VENDOR_NAME: {
+ RESULT_STR(ACL_VENDOR_NAME);
+ break;
+ }
+ case AOCL_MMD_VENDOR_ID:
+ RESULT_INT(0);
+ break;
+ case AOCL_MMD_USES_YIELD:
+ RESULT_INT(0); /* TODO: Can we yield? */
+ break;
+ case AOCL_MMD_MEM_TYPES_SUPPORTED:
+ RESULT_INT(AOCL_MMD_PHYSICAL_MEMORY); /* TODO: Confirm this is the right memory type */
+ break;
+ }
+ return 0;
+}
+
+// If the MMD is loaded dynamically, destructors in the MMD will execute before the destructors in the runtime
+// upon program termination. The DeviceMapManager guards accesses to the device/handle maps to make sure
+// the runtime doesn't get to reference them after MMD destructors have been called.
+// Destructor makes sure that all devices are closed at program termination regardless of what the runtime does.
+// Implemented as a singleton.
+class DeviceMapManager final {
+public:
+ typedef std::map<int, mmd_device_ptr> map_handle_to_dev_t;
+ ~DeviceMapManager()
+ {
+ }
+
+ int add_device(const char *name)
+ {
+ int handle = idx++;
+
+ mmd_device_ptr spDevice = std::make_shared<mmd_device>(name, handle);
+ if( spDevice->bValid() )
+ {
+ auto it = handle_to_dev.find(handle);
+ HPS_ERROR_IF( it != handle_to_dev.end(), return FAILURE, "Error: Handle already used.\n" );
+ handle_to_dev.insert({handle, spDevice});
+ return handle;
+ }
+ return FAILURE;
+ }
+
+ mmd_device_ptr get_device(const int handle)
+ {
+ auto it = handle_to_dev.find(handle);
+ HPS_ERROR_IF( it == handle_to_dev.end(), return nullptr, "Error: Invalid handle.\n" );
+ return it->second;
+ }
+
+ bool remove_device(const int handle)
+ {
+ auto it = handle_to_dev.find(handle);
+ HPS_ERROR_IF( it == handle_to_dev.end(), return false, "Error: Handle does not exist.\n" );
+ handle_to_dev.erase(it);
+ return true;
+ }
+
+ DeviceMapManager()
+ {
+ }
+private:
+ map_handle_to_dev_t handle_to_dev = {};
+ int idx = {0};
+};
+static DeviceMapManager _gDeviceMapManager;
+
+int aocl_mmd_get_info(
+ int handle, aocl_mmd_info_t requested_info_id, size_t param_value_size, void *param_value, size_t *param_size_ret) {
+ HPS_ERROR_IF(true,
+ return FAILURE,
+ "aocl_mmd_get_info not supported on platform. \n");
+}
+
+#undef RESULT_INT
+#undef RESULT_STR
+
+
+// Open and initialize the named device.
+int AOCL_MMD_CALL aocl_mmd_open(const char *name) {
+ return _gDeviceMapManager.add_device(name);
+}
+
+// Close an opened device, by its handle.
+int AOCL_MMD_CALL aocl_mmd_close(int handle) {
+ if ( _gDeviceMapManager.remove_device(handle) )
+ return SUCCESS;
+ return FAILURE;
+}
+
+// Set the interrupt handler for the opened device.
+int AOCL_MMD_CALL aocl_mmd_set_interrupt_handler(int handle, aocl_mmd_interrupt_handler_fn fn, void *user_data) {
+ mmd_device_ptr spDevice = _gDeviceMapManager.get_device(handle);
+ if( nullptr == spDevice ) {
+ return FAILURE;
+ }
+ return spDevice->set_interrupt_handler(fn, user_data);
+}
+
+// Set the device interrupt handler for the opened device.
+int AOCL_MMD_CALL aocl_mmd_set_device_interrupt_handler(int handle,
+ aocl_mmd_device_interrupt_handler_fn fn,
+ void *user_data) {
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ return -1;
+}
+
+// Set the operation status handler for the opened device.
+int AOCL_MMD_CALL aocl_mmd_set_status_handler(int handle, aocl_mmd_status_handler_fn fn, void *user_data) {
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ return -1;
+}
+
+// Called when the host is idle and hence possibly waiting for events to be
+// processed by the device
+int AOCL_MMD_CALL aocl_mmd_yield(int handle)
+{
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ return -1;
+}
+
+// Read, write and copy operations on a single interface.
+int AOCL_MMD_CALL aocl_mmd_read(int handle, aocl_mmd_op_t op, size_t len, void *dst, int mmd_interface, size_t offset) {
+ mmd_device_ptr spDevice = _gDeviceMapManager.get_device(handle);
+ if( nullptr == spDevice ) {
+ return FAILURE;
+ }
+ return spDevice->read_block(op, mmd_interface, dst, offset, len);
+}
+
+int AOCL_MMD_CALL
+aocl_mmd_write(int handle, aocl_mmd_op_t op, size_t len, const void *src, int mmd_interface, size_t offset) {
+ mmd_device_ptr spDevice = _gDeviceMapManager.get_device(handle);
+ if( nullptr == spDevice ) {
+ return FAILURE;
+ }
+ return spDevice->write_block(op, mmd_interface, src, offset, len);
+}
+
+int AOCL_MMD_CALL
+aocl_mmd_copy(int handle, aocl_mmd_op_t op, size_t len, int mmd_interface, size_t src_offset, size_t dst_offset) {
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ /* Not called by CoreDLA, so not implementing */
+ return -1;
+}
+
+// Initialize host channel specified in channel_name
+int AOCL_MMD_CALL aocl_mmd_hostchannel_create(int handle, char *channel_name, size_t queue_depth, int direction) {
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ /* Not called by CoreDLA, so not implementing */
+ return -1;
+}
+
+// reset the host channel specified with channel handle
+int AOCL_MMD_CALL aocl_mmd_hostchannel_destroy(int handle, int channel) {
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ /* Not called by CoreDLA, so not implementing */
+ return -1;
+}
+
+// Get the pointer to buffer the user can write/read from the kernel with
+AOCL_MMD_CALL void *aocl_mmd_hostchannel_get_buffer(int handle, int channel, size_t *buffer_size, int *status) {
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ /* Not called by CoreDLA, so not implementing */
+ return NULL;
+}
+
+// Acknolwedge from the user that they have written/read send_size amount of buffer obtained from get_buffer
+size_t AOCL_MMD_CALL aocl_mmd_hostchannel_ack_buffer(int handle, int channel, size_t send_size, int *status) {
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ /* Not called by CoreDLA, so not implementing */
+ return -1;
+}
+
+#ifdef DLA_MMD
+// Reprogram the device given the sof file name
+int AOCL_MMD_CALL aocl_mmd_program_sof(int handle, const char *sof_filename) {
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ /* We don't support reprogramming the SOF on a HPS device */
+ return -1;
+}
+#else
+// Reprogram the device based on the program mode
+int AOCL_MMD_CALL aocl_mmd_program(int handle, void *data, size_t data_size, aocl_mmd_program_mode_t program_mode) {
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ /* We don't support reprogramming the SOF on a HPS device */
+ return -1;
+}
+#endif
+// Shared memory allocator
+AOCL_MMD_CALL void *aocl_mmd_shared_mem_alloc(int handle, size_t size, unsigned long long *device_ptr_out) {
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ /* Not called by CoreDLA, so not implementing */
+ return NULL;
+}
+
+// Shared memory de-allocator
+AOCL_MMD_CALL void aocl_mmd_shared_mem_free(int handle, void *host_ptr, size_t size) {
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ /* Not called by CoreDLA, so not implementing */
+ return;
+}
+
+#ifndef DLA_MMD
+// This function checks if the input data has an ELF-formatted blob.
+// Return true when it does.
+static bool blob_has_elf_signature(void *data, size_t data_size) {
+ bool result = false;
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ if (data && data_size > 4) {
+ unsigned char *cdata = (unsigned char *)data;
+ const unsigned char elf_signature[4] = {0177, 'E', 'L', 'F'}; // Little endian
+ result = (cdata[0] == elf_signature[0]) && (cdata[1] == elf_signature[1]) && (cdata[2] == elf_signature[2]) &&
+ (cdata[3] == elf_signature[3]);
+ }
+ return result;
+}
+#endif
+
+// Return a positive number when single device open. Otherwise, return -1
+AOCL_MMD_CALL int get_open_handle() {
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ return -1;
+}
+
+AOCL_MMD_CALL void *aocl_mmd_host_alloc(int *handles,
+ size_t num_devices,
+ size_t size,
+ size_t alignment,
+ aocl_mmd_mem_properties_t *properties,
+ int *error) {
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ // Not supported on this BSP
+ return NULL;
+}
+
+AOCL_MMD_CALL int aocl_mmd_free(void *mem) {
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ // Not supported on this BSP
+ return 0;
+}
+
+AOCL_MMD_CALL void *aocl_mmd_device_alloc(
+ int handle, size_t size, size_t alignment, aocl_mmd_mem_properties_t *properties, int *error) {
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ // Not supported on this BSP
+ return NULL;
+}
+
+AOCL_MMD_CALL void *aocl_mmd_shared_alloc(
+ int handle, size_t size, size_t alignment, aocl_mmd_mem_properties_t *properties, int *error) {
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ // Not supported on this BSP
+ return NULL;
+}
+
+AOCL_MMD_CALL int aocl_mmd_shared_migrate(int handle, void *shared_ptr, size_t size, aocl_mmd_migrate_t destination) {
+ printf("%s:%s:%d\n", __FILE__, __PRETTY_FUNCTION__, __LINE__);
+ // Not supported on this BSP
+ return 0;
+}
+
+#ifdef DLA_MMD
+// Query functions to get board-specific values
+AOCL_MMD_CALL int dla_mmd_get_max_num_instances()
+{
+ return 1;
+}
+
+AOCL_MMD_CALL uint64_t dla_mmd_get_ddr_size_per_instance() {
+ return 1ULL << 29;
+}
+
+// AGX7 HPS board uses 333.3325 MHz (1333.33/4) for the DLA DDR Clock
+// All other boards use 266.666666 MHz (1066.66666/4)
+AOCL_MMD_CALL double dla_mmd_get_ddr_clock_freq() {
+#ifdef HPS_AGX7
+ return 333.332500;
+#else
+ return 266.666666;
+#endif
+} // MHz
+
+// Helper functions for the wrapper functions around CSR and DDR
+uint64_t dla_get_raw_csr_address(int instance, uint64_t addr) {
+ return (0x1000 * instance) + addr;
+}
+uint64_t dla_get_raw_ddr_address(int instance, uint64_t addr) {
+ return addr;
+}
+
+// Wrappers around CSR and DDR reads and writes to abstract away board-specific offsets
+AOCL_MMD_CALL int dla_mmd_csr_write(int handle, int instance, uint64_t addr, const uint32_t *data) {
+ return aocl_mmd_write(
+ handle, NULL, sizeof(uint32_t), data, HPS_MMD_COREDLA_CSR_HANDLE, dla_get_raw_csr_address(instance, addr));
+}
+AOCL_MMD_CALL int dla_mmd_csr_read(int handle, int instance, uint64_t addr, uint32_t *data) {
+ return aocl_mmd_read(
+ handle, NULL, sizeof(uint32_t), data, HPS_MMD_COREDLA_CSR_HANDLE, dla_get_raw_csr_address(instance, addr));
+}
+AOCL_MMD_CALL int dla_mmd_ddr_write(int handle, int instance, uint64_t addr, uint64_t length, const void *data) {
+ return aocl_mmd_write(handle, NULL, length, data, HPS_MMD_MEMORY_HANDLE, dla_get_raw_ddr_address(instance, addr));
+}
+AOCL_MMD_CALL int dla_mmd_ddr_read(int handle, int instance, uint64_t addr, uint64_t length, void *data) {
+ return aocl_mmd_read(handle, NULL, length, data, HPS_MMD_MEMORY_HANDLE, dla_get_raw_ddr_address(instance, addr));
+}
+
+#ifdef STREAM_CONTROLLER_ACCESS
+AOCL_MMD_CALL bool dla_is_stream_controller_valid(int handle, int instance) {
+ mmd_device_ptr spDevice = _gDeviceMapManager.get_device(handle);
+ if( nullptr == spDevice ) {
+ return FAILURE;
+ }
+ return spDevice->bStreamControllerValid();
+}
+
+AOCL_MMD_CALL int dla_mmd_stream_controller_write(int handle, int instance, uint64_t addr, uint64_t length, const void *data) {
+ return aocl_mmd_write(handle, NULL, length, data, HPS_MMD_STREAM_CONTROLLER_HANDLE, addr);
+}
+
+AOCL_MMD_CALL int dla_mmd_stream_controller_read(int handle, int instance, uint64_t addr, uint64_t length, void* data) {
+ return aocl_mmd_read(
+ handle, NULL, length, data, HPS_MMD_STREAM_CONTROLLER_HANDLE, addr);
+}
+#endif
+
+AOCL_MMD_CALL double dla_mmd_get_coredla_clock_freq(int handle) {
+ return 200;
+}
+
+#endif
diff --git a/python/openvino/runtime/coredla_device/mmd/hps_platform/host/acl_hps.h b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/acl_hps.h
new file mode 100644
index 0000000..7c85a24
--- /dev/null
+++ b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/acl_hps.h
@@ -0,0 +1,111 @@
+#ifndef ACL_HPS_H
+#define ACL_HPS_H
+
+/* (c) 1992-2021 Intel Corporation. */
+/* Intel, the Intel logo, Intel, MegaCore, NIOS II, Quartus and TalkBack words */
+/* and logos are trademarks of Intel Corporation or its subsidiaries in the U.S. */
+/* and/or other countries. Other marks and brands may be claimed as the property */
+/* of others. See Trademarks on intel.com for full list of Intel trademarks or */
+/* the Trademarks & Brands Names Database (if Intel) or See www.Intel.com/legal (if Altera) */
+/* Your use of Intel Corporation's design tools, logic functions and other */
+/* software and tools, and its AMPP partner logic functions, and any output */
+/* files any of the foregoing (including device programming or simulation */
+/* files), and any associated documentation or information are expressly subject */
+/* to the terms and conditions of the Altera Program License Subscription */
+/* Agreement, Intel MegaCore Function License Agreement, or other applicable */
+/* license agreement, including, without limitation, that your use is for the */
+/* sole purpose of programming logic devices manufactured by Intel and sold by */
+/* Intel or its authorized distributors. Please refer to the applicable */
+/* agreement for further details. */
+
+/* ===- acl_hps.h --------------------------------------------------- C++ -*-=== */
+/* */
+/* Intel(R) HPS MMD Driver */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+/* */
+/* This file defines macros and types that are used inside the MMD driver */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+
+#ifndef ACL_HPS_EXPORT
+#define ACL_HPS_EXPORT __declspec(dllimport)
+#endif
+
+#define MMD_VERSION AOCL_MMD_VERSION_STRING
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdio.h>
+#ifdef DLA_MMD
+#include <cstdint>
+#endif
+#include "aocl_mmd.h"
+
+#include "hps_types.h"
+
+#if defined(WINDOWS)
+#error Currently not available for windows
+#endif
+
+#if defined(LINUX)
+typedef uintptr_t KPTR;
+typedef int fpga_handle;
+typedef unsigned int fpga_result;
+#define FPGA_OK 0
+
+typedef unsigned int DWORD;
+typedef unsigned long long QWORD;
+typedef char INT8;
+typedef unsigned char UINT8;
+typedef int16_t INT16;
+typedef uint16_t UINT16;
+typedef int INT32;
+typedef unsigned int UINT32;
+typedef long long INT64;
+typedef unsigned long long UINT64;
+
+#define INVALID_HANDLE_VALUE ((int)(-1))
+
+#define INVALID_DEVICE (-1)
+#define WD_STATUS_SUCCESS 0
+
+// define for the format string for DWORD type
+#define DWORD_FMT_U "%u"
+#define DWORD_FMT_X "%x"
+#define DWORD_FMT_4X "%04X"
+
+// define for the format string for size_t type
+#define SIZE_FMT_U "%zu"
+#define SIZE_FMT_X "%zx"
+
+#endif // LINUX
+
+#define MAX_NAME_SIZE (1204)
+
+#define HPS_ASSERT(COND, ...) \
+ do { \
+ if (!(COND)) { \
+ printf("\nMMD FATAL: %s:%d: ", __FILE__, __LINE__); \
+ printf(__VA_ARGS__); \
+ fflush(stdout); \
+ assert(0); \
+ } \
+ } while (0)
+
+#define HPS_ERROR_IF(COND, NEXT, ...) \
+ do { \
+ if (COND) { \
+ printf("\nMMD ERROR: " __VA_ARGS__); \
+ fflush(stdout); \
+ NEXT; \
+ } \
+ } while (0)
+
+#define HPS_INFO(...) \
+ do { \
+ printf("MMD INFO : " __VA_ARGS__); \
+ fflush(stdout); \
+ } while (0)
+
+#endif // ACL_HPS_H
diff --git a/python/openvino/runtime/coredla_device/mmd/hps_platform/host/dma_device.cpp b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/dma_device.cpp
new file mode 100644
index 0000000..e403823
--- /dev/null
+++ b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/dma_device.cpp
@@ -0,0 +1,120 @@
+/* (c) 1992-2021 Intel Corporation. */
+/* Intel, the Intel logo, Intel, MegaCore, NIOS II, Quartus and TalkBack words */
+/* and logos are trademarks of Intel Corporation or its subsidiaries in the U.S. */
+/* and/or other countries. Other marks and brands may be claimed as the property */
+/* of others. See Trademarks on intel.com for full list of Intel trademarks or */
+/* the Trademarks & Brands Names Database (if Intel) or See www.Intel.com/legal (if Altera) */
+/* Your use of Intel Corporation's design tools, logic functions and other */
+/* software and tools, and its AMPP partner logic functions, and any output */
+/* files any of the foregoing (including device programming or simulation */
+/* files), and any associated documentation or information are expressly subject */
+/* to the terms and conditions of the Altera Program License Subscription */
+/* Agreement, Intel MegaCore Function License Agreement, or other applicable */
+/* license agreement, including, without limitation, that your use is for the */
+/* sole purpose of programming logic devices manufactured by Intel and sold by */
+/* Intel or its authorized distributors. Please refer to the applicable */
+/* agreement for further details. */
+
+/* ===- dma_device.h ------------------------------------------------- C++ -*-=== */
+/* */
+/* dma device access functions */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+/* */
+/* This file implements the functions used access the dma device objects */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+
+// common and its own header files
+#include "dma_device.h"
+#include <unistd.h>
+#include <glob.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+#include <memory.h>
+
+// Copied from Linux driver: /drivers/dma/altera-msgdma.c
+#define MSGDMA_DESC_NUM 1024
+
+// Same page size as used in /meta-intel-fpga-coredla/recipes-drivers/msgdma-userio/files/msgdma_userio_chr.c
+#define PAGE_SIZE 4096
+
+//////////////////////////////////////////////////////
+
+#define ERR(format, ...) \
+printf("%s:%u() **ERROR** : " format, \
+ __func__, __LINE__, ##__VA_ARGS__)
+
+//////////////////////////////////////////////////////
+dma_device::dma_device(std::string &name)
+{
+ _pFile = fopen(name.c_str(), "r+");
+ if( _pFile == nullptr )
+ {
+ ERR("dma_device::dma_device failed to open %s\n", name.c_str());
+ return;
+ }
+
+ // Turn off buffering
+ setvbuf(_pFile, NULL, _IONBF, 0);
+}
+
+dma_device::~dma_device()
+{
+ if( _pFile )
+ {
+ fclose(_pFile);
+ _pFile = NULL;
+ }
+}
+
+int dma_device::read_block(void *host_addr, size_t offset, size_t size)
+{
+ // Use 32bit seek as DDR memory current < 32bits
+ if( fseek(_pFile, (uint32_t)offset, SEEK_SET) != 0 ) {
+ return FAILURE;
+ }
+
+ size_t read_size = fread(host_addr, 1, size, _pFile);
+ return (read_size == size) ? SUCCESS : FAILURE;
+}
+
+int dma_device::write_block(const void *host_addr, size_t offset, size_t size)
+{
+ // The MSGDMA driver only supports a maximum of 1024 x 4096 = 4MBytes in the worst case scenario,
+ // in the event that the virtual buffer is fully fragmented. As the buffer gets more fragmented it's
+ // possible to run out of DMA descriptors. To prevent this, slice the data into 4MB chunks.
+
+ // chunk_size is chosen based on the size of a page (12 bits) and default number of descriptors (1024).
+ // The descriptor count is reduced by 1 since if the host_addr is not aligned to a page then an extra page
+ // will be added at the end. This would then increase the descriptor count by 1.
+ size_t chunk_size = PAGE_SIZE * (MSGDMA_DESC_NUM - 1);
+ size_t write_size = 0;
+
+ // Use 32bit seek as DDR memory current < 32bits
+ if( fseek(_pFile, (uint32_t)offset, SEEK_SET) != 0 ) {
+ return FAILURE;
+ }
+
+ for (size_t host_addr_offset = 0; host_addr_offset < size; host_addr_offset += chunk_size) {
+ size_t current_size = chunk_size;
+
+ // If the current address is within one chunk_size from the end of the data, set current_size
+ // to the bytes left to send
+ if (size - host_addr_offset < chunk_size) {
+ current_size = size - host_addr_offset;
+ }
+
+ size_t current_write_size = fwrite((uint8_t *)host_addr + host_addr_offset, 1, current_size, _pFile);
+
+ if (current_write_size != current_size) {
+ return FAILURE;
+ }
+
+ write_size += current_write_size;
+ }
+
+ return (write_size == size) ? SUCCESS : FAILURE;
+}
diff --git a/python/openvino/runtime/coredla_device/mmd/hps_platform/host/dma_device.h b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/dma_device.h
new file mode 100644
index 0000000..24f89e4
--- /dev/null
+++ b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/dma_device.h
@@ -0,0 +1,56 @@
+#ifndef DMA_DEVICE_H_
+#define DMA_DEVICE_H_
+
+/* (c) 1992-2021 Intel Corporation. */
+/* Intel, the Intel logo, Intel, MegaCore, NIOS II, Quartus and TalkBack words */
+/* and logos are trademarks of Intel Corporation or its subsidiaries in the U.S. */
+/* and/or other countries. Other marks and brands may be claimed as the property */
+/* of others. See Trademarks on intel.com for full list of Intel trademarks or */
+/* the Trademarks & Brands Names Database (if Intel) or See www.Intel.com/legal (if Altera) */
+/* Your use of Intel Corporation's design tools, logic functions and other */
+/* software and tools, and its AMPP partner logic functions, and any output */
+/* files any of the foregoing (including device programming or simulation */
+/* files), and any associated documentation or information are expressly subject */
+/* to the terms and conditions of the Altera Program License Subscription */
+/* Agreement, Intel MegaCore Function License Agreement, or other applicable */
+/* license agreement, including, without limitation, that your use is for the */
+/* sole purpose of programming logic devices manufactured by Intel and sold by */
+/* Intel or its authorized distributors. Please refer to the applicable */
+/* agreement for further details. */
+
+/* ===- dma_device.h ------------------------------------------------- C++ -*-=== */
+/* */
+/* dma device access functions */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+/* */
+/* This file implements the functions used access the dma device objects */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+#include <vector>
+#include <string>
+#include <memory>
+
+#include "hps_types.h"
+
+class dma_device
+{
+public:
+ dma_device(std::string &name);
+ ~dma_device();
+
+ int read_block(void *host_addr, size_t offset, size_t size);
+ int write_block(const void *host_addr, size_t offset, size_t size);
+
+ bool bValid() { return _pFile != nullptr; };
+private:
+
+ dma_device() = delete;
+ dma_device(dma_device const&) = delete;
+ void operator=(dma_device const &) = delete;
+
+ FILE *_pFile = {nullptr}; // File pointer to UIO - Used to indicate the the uio_device is valid
+};
+typedef std::shared_ptr<dma_device> dma_device_ptr;
+
+#endif // DMA_DEVICE_H_
diff --git a/python/openvino/runtime/coredla_device/mmd/hps_platform/host/hps_types.h b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/hps_types.h
new file mode 100644
index 0000000..3f11c4a
--- /dev/null
+++ b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/hps_types.h
@@ -0,0 +1,44 @@
+#ifndef HPS_TYPES_H_
+#define HPS_TYPES_H_
+
+/* (c) 1992-2021 Intel Corporation. */
+/* Intel, the Intel logo, Intel, MegaCore, NIOS II, Quartus and TalkBack words */
+/* and logos are trademarks of Intel Corporation or its subsidiaries in the U.S. */
+/* and/or other countries. Other marks and brands may be claimed as the property */
+/* of others. See Trademarks on intel.com for full list of Intel trademarks or */
+/* the Trademarks & Brands Names Database (if Intel) or See www.Intel.com/legal (if Altera) */
+/* Your use of Intel Corporation's design tools, logic functions and other */
+/* software and tools, and its AMPP partner logic functions, and any output */
+/* files any of the foregoing (including device programming or simulation */
+/* files), and any associated documentation or information are expressly subject */
+/* to the terms and conditions of the Altera Program License Subscription */
+/* Agreement, Intel MegaCore Function License Agreement, or other applicable */
+/* license agreement, including, without limitation, that your use is for the */
+/* sole purpose of programming logic devices manufactured by Intel and sold by */
+/* Intel or its authorized distributors. Please refer to the applicable */
+/* agreement for further details. */
+
+/* ===- hps_types.h -------------------------------------------------- C++ -*-=== */
+/* */
+/* Useful HPS Types */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+/* */
+/* This file contains useful type definition */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+#include <vector>
+#include <string>
+
+#define SUCCESS (0)
+#define FAILURE (1)
+
+typedef std::vector<std::string> board_names;
+
+typedef enum {
+ HPS_MMD_COREDLA_CSR_HANDLE = 1, // COREDLA CSR Interface
+ HPS_MMD_MEMORY_HANDLE = 2, // Device Memory transfers
+ HPS_MMD_STREAM_CONTROLLER_HANDLE = 3 // Stream Controller Interface
+} hps_mmd_interface_t;
+
+#endif // HPS_TYPES_H_
diff --git a/python/openvino/runtime/coredla_device/mmd/hps_platform/host/mmd_device.cpp b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/mmd_device.cpp
new file mode 100644
index 0000000..b52c1d8
--- /dev/null
+++ b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/mmd_device.cpp
@@ -0,0 +1,129 @@
+/* (c) 1992-2021 Intel Corporation. */
+/* Intel, the Intel logo, Intel, MegaCore, NIOS II, Quartus and TalkBack words */
+/* and logos are trademarks of Intel Corporation or its subsidiaries in the U.S. */
+/* and/or other countries. Other marks and brands may be claimed as the property */
+/* of others. See Trademarks on intel.com for full list of Intel trademarks or */
+/* the Trademarks & Brands Names Database (if Intel) or See www.Intel.com/legal (if Altera) */
+/* Your use of Intel Corporation's design tools, logic functions and other */
+/* software and tools, and its AMPP partner logic functions, and any output */
+/* files any of the foregoing (including device programming or simulation */
+/* files), and any associated documentation or information are expressly subject */
+/* to the terms and conditions of the Altera Program License Subscription */
+/* Agreement, Intel MegaCore Function License Agreement, or other applicable */
+/* license agreement, including, without limitation, that your use is for the */
+/* sole purpose of programming logic devices manufactured by Intel and sold by */
+/* Intel or its authorized distributors. Please refer to the applicable */
+/* agreement for further details. */
+
+/* ===- mmd_device.h ------------------------------------------------- C++ -*-=== */
+/* */
+/* mmd device access functions */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+/* */
+/* This file implements the functions used access the mmd device object */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+
+#include "mmd_device.h"
+
+// Defined names of the UIO Nodes
+#define UIO_COREDLA_PREFIX "coredla"
+#define STREAM_CONTROLLER_PREFIX "stream_controller"
+
+// Defined name of the msgdma device
+#define DMA_DEVICE_PREFIX "/dev/msgdma_coredla"
+#define UIO_DEVICE_PREFIX "uio"
+
+board_names mmd_get_devices(const int max_fpga_devices)
+{
+ return uio_get_devices(UIO_COREDLA_PREFIX, max_fpga_devices);
+}
+
+
+/////////////////////////////////////////////////////////
+mmd_device::mmd_device(std::string name, const int mmd_handle)
+: _name(name), _mmd_handle(mmd_handle) {
+ _spCoredlaDevice = std::make_shared<uio_device>(name, _mmd_handle, true);
+ int32_t index = extract_index(_name);
+ if( (index >= 0) && _spCoredlaDevice && _spCoredlaDevice->bValid() )
+ {
+ std::string dma_name(DMA_DEVICE_PREFIX);
+ dma_name += std::to_string(index);
+ _spDmaDevice = std::make_shared<dma_device>(dma_name);
+
+ if( (_spDmaDevice==nullptr) || (!_spDmaDevice->bValid()) ) {
+ _spDmaDevice = nullptr;
+ return;
+ }
+ std::string stream_controller_name = uio_get_device(STREAM_CONTROLLER_PREFIX, index);
+ if( !stream_controller_name.empty() ) {
+ // Create a uio_device but don't attach any interrupt support as the stream controller
+ // does not require interrupts
+ _spStreamControllerDevice = std::make_shared<uio_device>(stream_controller_name, _mmd_handle, false);
+ if( _spStreamControllerDevice && !_spStreamControllerDevice->bValid() ) {
+ // The stream controller does not exist
+ _spStreamControllerDevice = nullptr;
+ }
+ }
+ }
+}
+
+int mmd_device::read_block(aocl_mmd_op_t op, int mmd_interface, void *host_addr, size_t offset, size_t size)
+{
+ if( op ) {
+ LOG_ERR("op not support : %s\n", __func__ );
+ return FAILURE;
+ }
+ if( mmd_interface == HPS_MMD_MEMORY_HANDLE ) {
+ return _spDmaDevice->read_block(host_addr, offset, size);
+ } else if( mmd_interface == HPS_MMD_COREDLA_CSR_HANDLE ) {
+ return _spCoredlaDevice->read_block(host_addr, offset, size);
+ } else if( mmd_interface == HPS_MMD_STREAM_CONTROLLER_HANDLE ) {
+ if ( _spStreamControllerDevice ) {
+ return _spStreamControllerDevice->read_block(host_addr, offset, size);
+ }
+ }
+
+ return FAILURE;
+}
+
+int mmd_device::write_block(aocl_mmd_op_t op, int mmd_interface, const void *host_addr, size_t offset, size_t size)
+{
+ if( op ) {
+ LOG_ERR("op not support : %s\n", __func__ );
+ return FAILURE;
+ }
+ if( mmd_interface == HPS_MMD_MEMORY_HANDLE ) {
+ return _spDmaDevice->write_block(host_addr, offset, size);
+ } else if ( mmd_interface == HPS_MMD_COREDLA_CSR_HANDLE ) {
+ return _spCoredlaDevice->write_block(host_addr, offset, size);
+ } else if ( mmd_interface == HPS_MMD_STREAM_CONTROLLER_HANDLE ) {
+ if( _spStreamControllerDevice ) {
+ return _spStreamControllerDevice->write_block(host_addr, offset, size);
+ }
+ }
+ return FAILURE;
+}
+
+int mmd_device::set_interrupt_handler(aocl_mmd_interrupt_handler_fn fn, void *user_data) {
+ if( _spCoredlaDevice ) {
+ return _spCoredlaDevice->set_interrupt_handler(fn, user_data);
+ }
+ return FAILURE;
+}
+
+// Returns the index of a uio device
+// If index cannot be found then returns -1
+int mmd_device::extract_index(const std::string name) {
+ std::string prefix(UIO_DEVICE_PREFIX);
+
+ if (name.length() <= prefix.length() && name.compare(0, prefix.length(), prefix)) {
+ LOG_ERR("Error parsing device name '%s'\n", name.c_str());
+ return -1;
+ }
+
+ std::string device_num_str = name.substr(prefix.length());
+ int32_t index = std::stoi(device_num_str, 0, 10);
+ return index;
+}
diff --git a/python/openvino/runtime/coredla_device/mmd/hps_platform/host/mmd_device.h b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/mmd_device.h
new file mode 100644
index 0000000..9cb0c71
--- /dev/null
+++ b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/mmd_device.h
@@ -0,0 +1,75 @@
+#ifndef MMD_DEVICE_H_
+#define MMD_DEVICE_H_
+
+/* (c) 1992-2021 Intel Corporation. */
+/* Intel, the Intel logo, Intel, MegaCore, NIOS II, Quartus and TalkBack words */
+/* and logos are trademarks of Intel Corporation or its subsidiaries in the U.S. */
+/* and/or other countries. Other marks and brands may be claimed as the property */
+/* of others. See Trademarks on intel.com for full list of Intel trademarks or */
+/* the Trademarks & Brands Names Database (if Intel) or See www.Intel.com/legal (if Altera) */
+/* Your use of Intel Corporation's design tools, logic functions and other */
+/* software and tools, and its AMPP partner logic functions, and any output */
+/* files any of the foregoing (including device programming or simulation */
+/* files), and any associated documentation or information are expressly subject */
+/* to the terms and conditions of the Altera Program License Subscription */
+/* Agreement, Intel MegaCore Function License Agreement, or other applicable */
+/* license agreement, including, without limitation, that your use is for the */
+/* sole purpose of programming logic devices manufactured by Intel and sold by */
+/* Intel or its authorized distributors. Please refer to the applicable */
+/* agreement for further details. */
+
+/* ===- mmd_device.h ------------------------------------------------- C++ -*-=== */
+/* */
+/* mmd device access functions */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+/* */
+/* This file implements the functions used access the mmd device object */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+#include <memory>
+#include <string>
+
+#include "hps_types.h"
+#include "dma_device.h"
+#include "uio_device.h"
+
+#include "aocl_mmd.h"
+
+// LOG ERRORS
+#define MMD_ERR_LOGGING 1
+#ifdef MMD_ERR_LOGGING
+#define LOG_ERR(...) fprintf(stderr, __VA_ARGS__)
+#else
+#define LOG_ERR(...)
+#endif
+
+class mmd_device {
+public:
+ mmd_device(std::string name, const int mmd_handle);
+
+ bool bValid() { return _spCoredlaDevice && _spCoredlaDevice->bValid() && _spDmaDevice && _spDmaDevice->bValid(); };
+ bool bStreamControllerValid() { return _spCoredlaDevice && _spStreamControllerDevice && _spStreamControllerDevice->bValid(); };
+ int write_block(aocl_mmd_op_t op, int mmd_interface, const void *host_addr, size_t offset, size_t size);
+ int read_block(aocl_mmd_op_t op, int mmd_interface, void *host_addr, size_t offset, size_t size);
+
+ int set_interrupt_handler(aocl_mmd_interrupt_handler_fn fn, void *user_data);
+private:
+ int32_t extract_index(const std::string name);
+
+ mmd_device() = delete;
+ mmd_device(mmd_device const&) = delete;
+ void operator=(mmd_device const &) = delete;
+ std::string _name;
+
+ uio_device_ptr _spCoredlaDevice;
+ uio_device_ptr _spStreamControllerDevice;
+ dma_device_ptr _spDmaDevice;
+ int _mmd_handle;
+};
+
+typedef std::shared_ptr<mmd_device> mmd_device_ptr;
+
+extern board_names mmd_get_devices(const int max_fpga_devices);
+
+#endif // MMD_DEVICE_H_
diff --git a/python/openvino/runtime/coredla_device/mmd/hps_platform/host/uio_device.cpp b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/uio_device.cpp
new file mode 100644
index 0000000..95a9567
--- /dev/null
+++ b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/uio_device.cpp
@@ -0,0 +1,469 @@
+// (c) 1992-2021 Intel Corporation.
+// Intel, the Intel logo, Intel, MegaCore, NIOS II, Quartus and TalkBack words
+// and logos are trademarks of Intel Corporation or its subsidiaries in the U.S.
+// and/or other countries. Other marks and brands may be claimed as the property
+// of others. See Trademarks on intel.com for full list of Intel trademarks or
+// the Trademarks & Brands Names Database (if Intel) or See www.Intel.com/legal (if Altera)
+// Your use of Intel Corporation's design tools, logic functions and other
+// software and tools, and its AMPP partner logic functions, and any output
+// files any of the foregoing (including device programming or simulation
+// files), and any associated documentation or information are expressly subject
+// to the terms and conditions of the Altera Program License Subscription
+// Agreement, Intel MegaCore Function License Agreement, or other applicable
+// license agreement, including, without limitation, that your use is for the
+// sole purpose of programming logic devices manufactured by Intel and sold by
+// Intel or its authorized distributors. Please refer to the applicable
+// agreement for further details.
+
+/* ===- uio_device.cpp ----------------------------------------------- C++ -*-=== */
+/* */
+/* uio device access functions */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+/* */
+/* This file implements the functions used access the uio device objects */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+
+// common and its own header files
+#include "uio_device.h"
+#include <unistd.h>
+#include <glob.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <poll.h>
+
+#include <cinttypes>
+#include <memory.h>
+
+//////////////////////////////////////////////////////
+#define UIO_BASE_NAME "uio*"
+#define UIO_BASE_PATH "/sys/class/uio/"
+#define UIO_BASE_SEARCH UIO_BASE_PATH UIO_BASE_NAME
+#define UIO_MAX_PATH (256)
+
+#define ERR(format, ...) \
+fprintf(stderr, "%s:%u **ERROR** : " format, \
+ __FILE__, __LINE__, ##__VA_ARGS__)
+
+//////////////////////////////////////////////////////
+#define MAX_NAME (20)
+bool uio_read_sysfs_uint64(const char *device_name, const char *sysfs_name, uint64_t &value)
+{
+ FILE *fp;
+ char param_path[UIO_MAX_PATH];
+
+ if( snprintf(param_path, sizeof(param_path), "%s/%s", device_name, sysfs_name) < 0 )
+ {
+ ERR("Path too long. %s, %s\n", device_name, sysfs_name);
+ return false;
+ }
+
+ fp = fopen(param_path, "r");
+ if( !fp )
+ {
+ ERR("Failed to fopen - %s\n", param_path);
+ return false;
+ }
+
+ if( fscanf(fp, "%" PRIx64, &value) != 1 )
+ {
+ ERR("Failed fscanf - %s\n", param_path);
+ fclose(fp);
+ return false;
+ }
+
+ fclose(fp);
+ return true;
+}
+
+bool uio_read_sysfs_string(const char *uio_path, const char *sysfs_name, std::string &result)
+{
+ char uio_name[MAX_NAME];
+ FILE *fp;
+ char param_path[UIO_MAX_PATH];
+
+ if( snprintf(param_path, sizeof(param_path), "%s/%s", uio_path, sysfs_name) < 0 )
+ {
+ ERR("Path too long. %s, %s\n", uio_path, sysfs_name);
+ return false;
+ }
+
+ fp = fopen(param_path, "r");
+ if( !fp )
+ {
+ ERR("Failed to fopen - %s\n", param_path);
+ return false;
+ }
+
+ int num_read = fread(uio_name, 1, MAX_NAME, fp);
+ if( num_read <= 0 )
+ {
+ ERR("Failed to read name - %s\n", param_path);
+ fclose(fp);
+ return false;
+ }
+
+ uio_name[num_read-1] = '\0'; // Terminate
+ result = std::string(uio_name);
+ fclose(fp);
+
+ return true;
+}
+
+std::string uio_get_device(const std::string prefix, const int32_t index)
+{
+ glob_t globbuf = {0};
+ std::string uio_name;
+
+ int glob_res = glob(UIO_BASE_SEARCH, GLOB_NOSORT, NULL, &globbuf);
+ if( (glob_res == 0) && (globbuf.gl_pathc) )
+ {
+ std::string device_name;
+ device_name = prefix + std::to_string(index);
+
+ for( size_t i=0; i<globbuf.gl_pathc; i++ )
+ {
+ std::string name;
+ uio_read_sysfs_string(globbuf.gl_pathv[i], "name", name);
+
+ if( name.find(device_name) != std::string::npos )
+ {
+ // We will return just the device name without the UIO_BASE_PATH
+ std::string name = std::string(globbuf.gl_pathv[i]);
+ uio_name = name.substr(sizeof(UIO_BASE_PATH)-1);
+ }
+ }
+ }
+ return uio_name;
+}
+
+board_names uio_get_devices(const std::string device_name, const int max_devices)
+{
+ board_names names;
+ int device = 0;
+
+ glob_t globbuf = {0};
+
+ int glob_res = glob(UIO_BASE_SEARCH, GLOB_NOSORT, NULL, &globbuf);
+ if( (glob_res == 0) && (globbuf.gl_pathc) )
+ {
+ for( size_t i=0; (i<globbuf.gl_pathc) && (device < max_devices); i++ )
+ {
+ std::string name;
+ uio_read_sysfs_string(globbuf.gl_pathv[i], "name", name);
+
+ if( name.find(device_name) != std::string::npos )
+ {
+ // We will return just the device name without the UIO_BASE_PATH
+ std::string name = std::string(globbuf.gl_pathv[i]);
+ name = name.substr(sizeof(UIO_BASE_PATH)-1);
+ names.push_back(name);
+ device++;
+ }
+ }
+ }
+ return names;
+}
+
+//////////////////////////////////////////////////////////////
+uio_device::uio_device(std::string &name, const int mmd_handle, const bool bEnableIRQ)
+: _mmd_handle(mmd_handle)
+{
+ // Map the first address space
+ if ( !map_region(name, 0) ) {
+ ERR("Failed to map region 0 on %s\n", name.c_str());
+ return;
+ }
+#ifndef RUNTIME_POLLING
+ if( bEnableIRQ ) {
+ _spInterrupt = std::make_shared<uio_interrupt>(_fd, _mmd_handle);
+ if( !_spInterrupt->initialized() ) {
+ _spInterrupt = nullptr; // If the uio_interrupt failed to initialize then delete
+ }
+ _bIrqEnabled = bEnableIRQ;
+ }
+#endif
+}
+
+bool uio_device::bValid() {
+ bool bValid = (_fd >=0);
+#ifndef RUNTIME_POLLING // If we're not polling check that the interrupt handling is working
+ if( _bIrqEnabled ) {
+ bValid |= (_spInterrupt != nullptr);
+ }
+#endif
+ return bValid;
+};
+
+uio_device::~uio_device()
+{
+#ifndef RUNTIME_POLLING
+ _spInterrupt = nullptr; // Shutdown the interrupt handler
+#endif
+ unmap_region();
+}
+
+uint32_t uio_device::read(const uint32_t reg)
+{
+ // NOT YET IMPLEMENTED
+ return 0;
+}
+
+void uio_device::write(const uint32_t reg, const uint32_t value)
+{
+ // NOT YET IMPLEMENTED
+ return;
+}
+
+// Copies the block of data from the FPGA to the host
+// memcpy is not used as this can cause multiple transfers of the AXI bus depending
+// on the implementation of memcpy
+int uio_device::read_block(void *host_addr, size_t offset, size_t size)
+{
+ // Support for only 32bit aligned transfers
+ if( (offset % sizeof(uint32_t)) || (size % sizeof(uint32_t)) ){
+ return FAILURE;
+ }
+
+ // Transfer the data in 32bit chunks
+ volatile const uint32_t *pDeviceMem32 = reinterpret_cast<volatile const uint32_t*>(reinterpret_cast<uint8_t*>(_pPtr) + offset);
+ uint32_t *host_addr32 = reinterpret_cast<uint32_t *>(host_addr);
+ while (size >= sizeof(uint32_t)) {
+ *host_addr32++ = *pDeviceMem32++;
+ size -= sizeof(uint32_t);
+ }
+
+ return SUCCESS;
+}
+
+// Copies the block of data from the host to the FPGA
+// memcpy is not used as this can cause multiple transfers of the AXI bus depending
+// on the implementation of memcpy
+int uio_device::write_block(const void *host_addr, size_t offset, size_t size)
+{
+ // Support for only 32bit aligned transfers
+ if( (offset % sizeof(uint32_t)) || (size % sizeof(uint32_t)) ){
+ return FAILURE;
+ }
+
+ // Transfer the remaining 32bits of data
+ volatile uint32_t *pDeviceMem32 = reinterpret_cast<volatile uint32_t*>(reinterpret_cast<uint8_t*>(_pPtr) + offset);
+ const uint32_t *host_addr32 = reinterpret_cast<const uint32_t*>(host_addr);
+ while( size >= sizeof(uint32_t) ) {
+ *pDeviceMem32++ = *host_addr32++;
+ size -= sizeof(uint32_t);
+ }
+ return SUCCESS;
+}
+
+int uio_device::set_interrupt_handler(aocl_mmd_interrupt_handler_fn fn, void* user_data) {
+#ifndef RUNTIME_POLLING
+ if( _spInterrupt ) {
+ return _spInterrupt->set_interrupt_handler(fn, user_data);
+ }
+#endif
+ return FAILURE;
+}
+
+/////////////////////////////////////////////////////////////////
+void uio_device::unmap_region()
+{
+ if( _pBase )
+ {
+ munmap(_pBase, _size);
+ _pBase = nullptr;
+ }
+
+ if( _fd >= 0 )
+ {
+ close(_fd);
+ _fd = -1;
+ }
+}
+
+bool uio_device::map_region( std::string &name, const uint32_t index)
+{
+ char map_path[UIO_MAX_PATH];
+
+ std::string uio_params_path(UIO_BASE_PATH);
+ uio_params_path += name;
+
+ // char device_path[UIO_MAX_PATH];
+ // const char *p;
+
+ if( snprintf(map_path, sizeof(map_path), "maps/map%d/size", index ) < 0 )
+ {
+ ERR("Failed to make map addr name.\n");
+ return false;
+ }
+ if( !uio_read_sysfs_uint64(uio_params_path.c_str(), map_path, _size) )
+ {
+ ERR("Failed to read size\n");
+ return false;
+ }
+ // Make sure that the size doesn't exceed 32bits, as this will fail the mapping
+ // call on 32bit systems
+ if( _size > UINT32_MAX ) {
+ ERR("Invalid size value\n");
+ return false;
+ }
+
+ if( snprintf(map_path, sizeof(map_path), "maps/map%d/offset", index ) < 0 )
+ {
+ ERR("Failed to make map offset name.\n");
+ return false;
+ }
+ if( !uio_read_sysfs_uint64(uio_params_path.c_str(), map_path, _offset) )
+ {
+ ERR("Failed to read offset\n");
+ return false;
+ }
+
+ std::string uio_dev_path("/dev/");
+ uio_dev_path += name;
+
+ _fd = open(uio_dev_path.c_str(), O_RDWR );
+ if( _fd < 0 )
+ {
+ ERR("Failed to open - %s\n", uio_dev_path.c_str());
+ return false;
+ }
+ // Map the region into userspace
+ // The base of the region is the page_size offset of the index
+ uint32_t page_size = (uint32_t)sysconf(_SC_PAGESIZE);
+
+ _pBase = (uint8_t*)mmap(NULL, (size_t)_size, PROT_READ|PROT_WRITE, MAP_SHARED, _fd, (off_t) (index * page_size));
+ if( _pBase == MAP_FAILED )
+ {
+ ERR("Failed to map uio region.\n");
+ close(_fd);
+ _fd = -1;
+ return false;
+ }
+ // CST base address is at _pBase + _offset
+ _pPtr = (uint32_t*)(_pBase + _offset);
+
+ return true;
+};
+
+#ifndef RUNTIME_POLLING
+///////////////////////////////////////////////////////////////////////////////////
+uio_interrupt::uio_interrupt(const int fd, const int mmd_handle)
+: _device_fd(fd), _mmd_handle(mmd_handle) {
+ if( is_irq_available() ) {
+ // Create a eventfd_object to be used for shutting down the work_thread
+ _spShutdown_event = std::make_shared<eventfd_object>();
+ if( _spShutdown_event->initialized() ) {
+ _pThread = new std::thread(work_thread, std::ref(*this));
+ } else {
+ _spShutdown_event = nullptr;
+ }
+ } else {
+ ERR("No device interrupt found.\n");
+ }
+}
+
+uio_interrupt::~uio_interrupt() {
+ // kill the thread
+ if (_pThread && _spShutdown_event) {
+ // send message to thread to end it
+ _spShutdown_event->notify(1);
+
+ // join with thread until it ends
+ _pThread->join();
+
+ delete _pThread;
+ _pThread = NULL;
+
+ _spShutdown_event = nullptr;
+ }
+}
+
+bool uio_interrupt::is_irq_available() {
+ // Disable the interrupt handling, this will fail if the IRQ has not been setup correctly.
+ // For example devicetree is incorrect.
+ return disable_irq();
+}
+
+bool uio_interrupt::enable_irq() {
+ // Enable interrupts from the device
+ uint32_t info = 1;
+ ssize_t nb = write(_device_fd, &info, sizeof(info));
+ if( nb != (ssize_t)sizeof(info) ) {
+ ERR( "Failed in enable CoreDLA Interrupt = %s\n", strerror(errno));
+ return false;
+ }
+ return true;
+}
+
+bool uio_interrupt::disable_irq() {
+ // Enable interrupts from the device
+ uint32_t info = 0;
+ ssize_t nb = write(_device_fd, &info, sizeof(info));
+ if( nb != (ssize_t)sizeof(info) ) {
+ ERR( "Failed in disable CoreDLA Interrupt = %s\n", strerror(errno));
+ return false;
+ }
+ return true;
+}
+
+void uio_interrupt::work_thread(uio_interrupt& obj) {
+ obj.run_thread();
+}
+
+#define UIO_INTERRUPT_TIMEOUT (-1)
+void uio_interrupt::run_thread() {
+ while( true ) {
+ // Need to re-enable the UIO interrupt handling as UIO disables the IRQ each time it is fired
+ if ( !enable_irq() ) {
+ exit(-1);
+ }
+ // Poll for the shutdown_event and uio interrupt
+ struct pollfd pollfd_arr[2];
+ pollfd_arr[0].fd = _spShutdown_event->get_fd();
+ pollfd_arr[0].events = POLLIN;
+ pollfd_arr[0].revents = 0;
+ pollfd_arr[1].fd = _device_fd;
+ pollfd_arr[1].events = POLLIN;
+ pollfd_arr[1].revents = 0;
+
+ int res = poll(pollfd_arr, 2, UIO_INTERRUPT_TIMEOUT);
+ if (res < 0) {
+ ERR( "Poll error errno = %s\n", strerror(errno));
+ exit(-1);
+ } else if (res > 0 && pollfd_arr[0].revents == POLLIN) {
+ uint64_t count;
+ ssize_t bytes_read = read(pollfd_arr[0].fd, &count, sizeof(count));
+ if (bytes_read > 0) {
+ break; // We've been asked to shutdown
+ } else {
+ ERR( "Error: poll failed: %s\n", bytes_read < 0 ? strerror(errno) : "zero bytes read");
+ exit(-1);
+ }
+ } else if (res > 0 && pollfd_arr[1].revents == POLLIN) {
+ uint32_t count;
+ ssize_t bytes_read = read(pollfd_arr[1].fd, &count, sizeof(count));
+ if (bytes_read > 0) {
+ if( _interrupt_fn ) { // Run the callback to the application
+ _interrupt_fn(get_mmd_handle(), _interrupt_fn_user_data );
+ }
+ } else {
+ ERR( "Error: poll failed: %s\n", bytes_read < 0 ? strerror(errno) : "zero bytes read");
+ exit(-1);
+ }
+ }
+ }
+ // Disable interrupt handling in UIO
+ if( !disable_irq() ){
+ exit(-1);
+ }
+}
+
+int uio_interrupt::set_interrupt_handler(aocl_mmd_interrupt_handler_fn fn, void* user_data) {
+ _interrupt_fn = fn;
+ _interrupt_fn_user_data = user_data;
+ return SUCCESS;
+}
+#endif
diff --git a/python/openvino/runtime/coredla_device/mmd/hps_platform/host/uio_device.h b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/uio_device.h
new file mode 100644
index 0000000..c5f3ed5
--- /dev/null
+++ b/python/openvino/runtime/coredla_device/mmd/hps_platform/host/uio_device.h
@@ -0,0 +1,162 @@
+#ifndef UIO_DEVICE_H_
+#define UIO_DEVICE_H_
+
+/* (c) 1992-2021 Intel Corporation. */
+/* Intel, the Intel logo, Intel, MegaCore, NIOS II, Quartus and TalkBack words */
+/* and logos are trademarks of Intel Corporation or its subsidiaries in the U.S. */
+/* and/or other countries. Other marks and brands may be claimed as the property */
+/* of others. See Trademarks on intel.com for full list of Intel trademarks or */
+/* the Trademarks & Brands Names Database (if Intel) or See www.Intel.com/legal (if Altera) */
+/* Your use of Intel Corporation's design tools, logic functions and other */
+/* software and tools, and its AMPP partner logic functions, and any output */
+/* files any of the foregoing (including device programming or simulation */
+/* files), and any associated documentation or information are expressly subject */
+/* to the terms and conditions of the Altera Program License Subscription */
+/* Agreement, Intel MegaCore Function License Agreement, or other applicable */
+/* license agreement, including, without limitation, that your use is for the */
+/* sole purpose of programming logic devices manufactured by Intel and sold by */
+/* Intel or its authorized distributors. Please refer to the applicable */
+/* agreement for further details. */
+
+/* ===- uio_device.h ------------------------------------------------- C++ -*-=== */
+/* */
+/* uio device access functions */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+/* */
+/* This file implements the functions used access the uio device objects */
+/* */
+/* ===-------------------------------------------------------------------------=== */
+#include <vector>
+#include <string>
+#include <string.h>
+#include <memory>
+#include <thread>
+#include <mutex>
+#include <sys/eventfd.h>
+#include <unistd.h>
+
+#include "aocl_mmd.h"
+#include "hps_types.h"
+
+// simple wrapper class for managing eventfd objects
+class eventfd_object final {
+ public:
+ eventfd_object() {
+ m_initialized = false;
+ // Note: EFD_SEMAPHORE and EFD_NONBLOCK are not set
+ // The implementation of functions using eventfd assumes that
+ m_fd = eventfd(0, 0);
+ if (m_fd < 0) {
+ fprintf(stderr, "eventfd : %s", strerror(errno));
+ return;
+ }
+
+ m_initialized = true;
+ }
+
+ ~eventfd_object() {
+ if (m_initialized) {
+ if (close(m_fd) < 0) {
+ fprintf(stderr, "eventfd : %s", strerror(errno));
+ }
+ }
+ }
+
+ bool notify(uint64_t count) {
+ ssize_t res = write(m_fd, &count, sizeof(count));
+ if (res < 0) {
+ fprintf(stderr, "eventfd : %s", strerror(errno));
+ return false;
+ }
+ return true;
+ }
+
+ int get_fd() { return m_fd; }
+ bool initialized() { return m_initialized; }
+
+ private:
+ // not used and not implemented
+ eventfd_object(eventfd_object& other);
+ eventfd_object& operator=(const eventfd_object& other);
+
+ // member varaibles
+ int m_fd;
+ int m_initialized;
+}; // class eventfd_object
+typedef std::shared_ptr<eventfd_object> eventfd_object_ptr;
+
+#ifndef RUNTIME_POLLING
+class uio_interrupt final {
+ public:
+ uio_interrupt(const int fd, const int mmd_handle);
+ ~uio_interrupt();
+ bool initialized() { return _pThread != nullptr; }; // If the thread is not created then must be invalid
+ int set_interrupt_handler(aocl_mmd_interrupt_handler_fn fn, void* user_data);
+
+ private:
+ bool is_irq_available(); // Checks that the interrupt has been mapped into userspace
+ bool enable_irq(); // Enables UIO Irq handling
+ bool disable_irq(); // Disabled UIO Irq handling
+
+ static void work_thread(uio_interrupt &obj);
+ void run_thread(); // Function which handles waiting for interrupts
+
+ uio_interrupt() = delete;
+ uio_interrupt(uio_interrupt const&) = delete;
+ void operator=(uio_interrupt const&) = delete;
+
+ int get_mmd_handle() {return _mmd_handle; };
+
+ std::thread *_pThread = {nullptr}; // Pointer to a thread object for waiting for interrupts
+ int _device_fd = {-1}; // /dev/uio* device pointer
+ int _mmd_handle = {-1}; // handle to the parent mmd_device
+ eventfd_object_ptr _spShutdown_event = {nullptr}; // Shutdown thread event object
+
+ aocl_mmd_interrupt_handler_fn _interrupt_fn = {nullptr};
+ void *_interrupt_fn_user_data = {nullptr};
+};
+typedef std::shared_ptr<uio_interrupt> uio_interrupt_ptr;
+#endif
+
+class uio_device
+{
+public:
+ uio_device(std::string &name, const int mmd_handle, const bool bEnableIrq=false);
+ ~uio_device();
+
+ uint32_t read(const uint32_t reg);
+ void write(const uint32_t reg, const uint32_t value);
+
+ int read_block(void *host_addr, size_t offset, size_t size);
+ int write_block(const void *host_addr, size_t offset, size_t size);
+ int set_interrupt_handler(aocl_mmd_interrupt_handler_fn fn, void* user_data);
+
+ bool bValid();
+
+private:
+ bool map_region( std::string &name, const uint32_t index );
+ void unmap_region();
+
+ uio_device() = delete;
+ uio_device(uio_device const&) = delete;
+ void operator=(uio_device const &) = delete;
+
+ int _mmd_handle; // Handle to the parent mmd device
+ int _fd = {-1}; // File pointer to UIO - Used to indicate the the uio_device is valid
+ uint64_t _size; // Size of the mmapped region
+ uint64_t _offset; // Offset of the first register
+ uint8_t *_pBase; // Base of the mmapped region
+
+ uint32_t *_pPtr; // The first register
+#ifndef RUNTIME_POLLING
+ bool _bIrqEnabled; // Indicates that we tried to create with IRQ
+ uio_interrupt_ptr _spInterrupt; // Object to handle UIO Interrupts
+#endif
+};
+typedef std::shared_ptr<uio_device> uio_device_ptr;
+
+extern board_names uio_get_devices(const std::string name, const int max_devices);
+extern std::string uio_get_device(const std::string prefix, const int32_t index);
+
+#endif // UIO_DEVICE_H_
diff --git a/python/openvino/runtime/coredla_device/mmd/hps_platform/include/aocl_mmd.h b/python/openvino/runtime/coredla_device/mmd/hps_platform/include/aocl_mmd.h
new file mode 100644
index 0000000..7c1c73d
--- /dev/null
+++ b/python/openvino/runtime/coredla_device/mmd/hps_platform/include/aocl_mmd.h
@@ -0,0 +1,645 @@
+#ifndef AOCL_MMD_H
+#define AOCL_MMD_H
+
+/* (c) 1992-2021 Intel Corporation. */
+/* Intel, the Intel logo, Intel, MegaCore, NIOS II, Quartus and TalkBack words */
+/* and logos are trademarks of Intel Corporation or its subsidiaries in the U.S. */
+/* and/or other countries. Other marks and brands may be claimed as the property */
+/* of others. See Trademarks on intel.com for full list of Intel trademarks or */
+/* the Trademarks & Brands Names Database (if Intel) or See www.Intel.com/legal (if Altera) */
+/* Your use of Intel Corporation's design tools, logic functions and other */
+/* software and tools, and its AMPP partner logic functions, and any output */
+/* files any of the foregoing (including device programming or simulation */
+/* files), and any associated documentation or information are expressly subject */
+/* to the terms and conditions of the Altera Program License Subscription */
+/* Agreement, Intel MegaCore Function License Agreement, or other applicable */
+/* license agreement, including, without limitation, that your use is for the */
+/* sole purpose of programming logic devices manufactured by Intel and sold by */
+/* Intel or its authorized distributors. Please refer to the applicable */
+/* agreement for further details. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Support for memory mapped ACL devices.
+ *
+ * Typical API lifecycle, from the perspective of the caller.
+ *
+ * 1. aocl_mmd_open must be called first, to provide a handle for further
+ * operations.
+ *
+ * 2. The interrupt and status handlers must be set.
+ *
+ * 3. Read and write operations are performed.
+ *
+ * 4. aocl_mmd_close may be called to shut down the device. No further
+ * operations are permitted until a subsequent aocl_mmd_open call.
+ *
+ * aocl_mmd_get_offline_info can be called anytime including before
+ * open. aocl_mmd_get_info can be called anytime between open and close.
+ */
+
+#ifndef AOCL_MMD_CALL
+#if defined(_WIN32)
+#define AOCL_MMD_CALL __declspec(dllimport)
+#else
+#define AOCL_MMD_CALL __attribute__((visibility ("default")))
+#endif
+#endif
+
+#ifndef WEAK
+#if defined(_WIN32)
+#define WEAK
+#else
+/* This normally comes with "__attribute__((weak))" but for reasons not presently
+ * understood, the shared library is not properly loaded on Ubuntu18 when the functions
+ * are weak.
+ */
+#define WEAK
+#endif
+#endif
+
+#ifdef DLA_MMD
+#include <cstddef> //size_t
+#include <cstdint> //uint32_t
+#endif
+
+/* The MMD API's version - the runtime expects this string when
+ * AOCL_MMD_VERSION is queried. This changes only if the API has changed */
+#define AOCL_MMD_VERSION_STRING "20.3"
+
+/* Memory types that can be supported - bitfield. Other than physical memory
+ * these types closely align with the OpenCL SVM types.
+ *
+ * AOCL_MMD_PHYSICAL_MEMORY - The vendor interface includes IP to communicate
+ * directly with physical memory such as DDR, QDR, etc.
+ *
+ * AOCL_MMD_SVM_COARSE_GRAIN_BUFFER - The vendor interface includes support for
+ * caching SVM pointer data and requires explicit function calls from the user
+ * to synchronize the cache between the host processor and the FPGA. This level
+ * of SVM is not currently supported by Altera except as a subset of
+ * SVM_FINE_GAIN_SYSTEM support.
+ *
+ * AOCL_MMD_SVM_FINE_GRAIN_BUFFER - The vendor interface includes support for
+ * caching SVM pointer data and requires additional information from the user
+ * and/or host runtime that can be collected during pointer allocation in order
+ * to synchronize the cache between the host processor and the FPGA. Once this
+ * additional data is provided for an SVM pointer, the vendor interface handles
+ * cache synchronization between the host processor & the FPGA automatically.
+ * This level of SVM is not currently supported by Altera except as a subset
+ * of SVM_FINE_GRAIN_SYSTEM support.
+ *
+ * AOCL_MMD_SVM_FINE_GRAIN_SYSTEM - The vendor interface includes support for
+ * caching SVM pointer data and does not require any additional information to
+ * synchronize the cache between the host processor and the FPGA. The vendor
+ * interface handles cache synchronization between the host processor & the
+ * FPGA automatically for all SVM pointers. This level of SVM support is
+ * currently under development by Altera and some features may not be fully
+ * supported.
+ */
+#define AOCL_MMD_PHYSICAL_MEMORY (1 << 0)
+#define AOCL_MMD_SVM_COARSE_GRAIN_BUFFER (1 << 1)
+#define AOCL_MMD_SVM_FINE_GRAIN_BUFFER (1 << 2)
+#define AOCL_MMD_SVM_FINE_GRAIN_SYSTEM (1 << 3)
+
+/* program modes - bitfield
+ *
+ * AOCL_MMD_PROGRAM_PRESERVE_GLOBAL_MEM - preserve contents of global memory
+ * when this bit is set to 1. If programming can't occur without preserving
+ * global memory contents, the program function must fail, in which case the
+ * runtime may re-invoke program with this bit set to 0, allowing programming
+ * to occur even if doing so destroys global memory contents.
+ *
+ * more modes are reserved for stacking on in the future
+ */
+#define AOCL_MMD_PROGRAM_PRESERVE_GLOBAL_MEM (1 << 0)
+typedef int aocl_mmd_program_mode_t;
+
+typedef void* aocl_mmd_op_t;
+
+typedef struct {
+ unsigned lo; /* 32 least significant bits of time value. */
+ unsigned hi; /* 32 most significant bits of time value. */
+} aocl_mmd_timestamp_t;
+
+/* Defines the set of characteristics that can be probed about the board before
+ * opening a device. The type of data returned by each is specified in
+ * parentheses in the adjacent comment.
+ *
+ * AOCL_MMD_NUM_BOARDS and AOCL_MMD_BOARD_NAMES
+ * These two fields can be used to implement multi-device support. The MMD
+ * layer may have a list of devices it is capable of interacting with, each
+ * identified with a unique name. The length of the list should be returned
+ * in AOCL_MMD_NUM_BOARDS, and the names of these devices returned in
+ * AOCL_MMD_BOARD_NAMES. The OpenCL runtime will try to call aocl_mmd_open
+ * for each board name returned in AOCL_MMD_BOARD_NAMES.
+ */
+typedef enum {
+ AOCL_MMD_VERSION = 0, /* Version of MMD (char*)*/
+ AOCL_MMD_NUM_BOARDS = 1, /* Number of candidate boards (int)*/
+ AOCL_MMD_BOARD_NAMES = 2, /* Names of boards available delimiter=; (char*)*/
+ AOCL_MMD_VENDOR_NAME = 3, /* Name of vendor (char*) */
+ AOCL_MMD_VENDOR_ID = 4, /* An integer ID for the vendor (int) */
+ AOCL_MMD_USES_YIELD = 5, /* 1 if yield must be called to poll hw (int) */
+ /* The following can be combined in a bit field:
+ * AOCL_MMD_PHYSICAL_MEMORY, AOCL_MMD_SVM_COARSE_GRAIN_BUFFER, AOCL_MMD_SVM_FINE_GRAIN_BUFFER,
+ * AOCL_MMD_SVM_FINE_GRAIN_SYSTEM. Prior to 14.1, all existing devices supported physical memory and no types of SVM
+ * memory, so this is the default when this operation returns '0' for board MMDs with a version prior to 14.1
+ */
+ AOCL_MMD_MEM_TYPES_SUPPORTED = 6,
+} aocl_mmd_offline_info_t;
+
+/** Possible capabilities to return from AOCL_MMD_*_MEM_CAPABILITIES query */
+/**
+ * If not set allocation function is not supported, even if other capabilities are set.
+ */
+#define AOCL_MMD_MEM_CAPABILITY_SUPPORTED (1 << 0)
+/**
+ * Supports atomic access to the memory by either the host or device.
+ */
+#define AOCL_MMD_MEM_CAPABILITY_ATOMIC (1 << 1)
+/**
+ * Supports concurrent access to the memory either by host or device if the
+ * accesses are not on the same block. Block granularity is defined by
+ * AOCL_MMD_*_MEM_CONCURRENT_GRANULARITY., blocks are aligned to this
+ * granularity
+ */
+#define AOCL_MMD_MEM_CAPABILITY_CONCURRENT (1 << 2)
+/**
+ * Memory can be accessed by multiple devices at the same time.
+ */
+#define AOCL_MMD_MEM_CAPABILITY_P2P (1 << 3)
+
+/* Defines the set of characteristics that can be probed about the board after
+ * opening a device. This can involve communication to the device
+ *
+ * AOCL_MMD_NUM_KERNEL_INTERFACES - The number of kernel interfaces, usually 1
+ *
+ * AOCL_MMD_KERNEL_INTERFACES - the handle for each kernel interface.
+ * param_value will have size AOCL_MMD_NUM_KERNEL_INTERFACES * sizeof int
+ *
+ * AOCL_MMD_PLL_INTERFACES - the handle for each pll associated with each
+ * kernel interface. If a kernel interface is not clocked by acl_kernel_clk
+ * then return -1
+ *
+ * */
+typedef enum {
+ AOCL_MMD_NUM_KERNEL_INTERFACES = 1, /* Number of Kernel interfaces (int) */
+ AOCL_MMD_KERNEL_INTERFACES = 2, /* Kernel interface (int*) */
+ AOCL_MMD_PLL_INTERFACES = 3, /* Kernel clk handles (int*) */
+ AOCL_MMD_MEMORY_INTERFACE = 4, /* Global memory handle (int) */
+ AOCL_MMD_TEMPERATURE = 5, /* Temperature measurement (float) */
+ AOCL_MMD_PCIE_INFO = 6, /* PCIe information (char*) */
+ AOCL_MMD_BOARD_NAME = 7, /* Name of board (char*) */
+ AOCL_MMD_BOARD_UNIQUE_ID = 8, /* Unique ID of board (int) */
+ AOCL_MMD_CONCURRENT_READS = 9, /* # of parallel reads; 1 is serial*/
+ AOCL_MMD_CONCURRENT_WRITES = 10, /* # of parallel writes; 1 is serial*/
+ AOCL_MMD_CONCURRENT_READS_OR_WRITES = 11, /* total # of concurrent operations read + writes*/
+ AOCL_MMD_MIN_HOST_MEMORY_ALIGNMENT = 12, /* Min alignment that the BSP supports for host allocations (size_t) */
+ AOCL_MMD_HOST_MEM_CAPABILITIES = 13, /* Capabilities of aocl_mmd_host_alloc() (unsigned int)*/
+ AOCL_MMD_SHARED_MEM_CAPABILITIES = 14, /* Capabilities of aocl_mmd_shared_alloc (unsigned int)*/
+ AOCL_MMD_DEVICE_MEM_CAPABILITIES = 15, /* Capabilities of aocl_mmd_device_alloc (unsigned int)*/
+ AOCL_MMD_HOST_MEM_CONCURRENT_GRANULARITY = 16, /*(size_t)*/
+ AOCL_MMD_SHARED_MEM_CONCURRENT_GRANULARITY = 17, /*(size_t)*/
+ AOCL_MMD_DEVICE_MEM_CONCURRENT_GRANULARITY = 18, /*(size_t)*/
+} aocl_mmd_info_t;
+
+typedef struct {
+ unsigned long long int exception_type;
+ void* user_private_info;
+ size_t user_cb;
+} aocl_mmd_interrupt_info;
+
+typedef void (*aocl_mmd_interrupt_handler_fn)(int handle, void* user_data);
+typedef void (*aocl_mmd_device_interrupt_handler_fn)(int handle, aocl_mmd_interrupt_info* data_in, void* user_data);
+typedef void (*aocl_mmd_status_handler_fn)(int handle, void* user_data, aocl_mmd_op_t op, int status);
+
+/* Get information about the board using the enum aocl_mmd_offline_info_t for
+ * offline info (called without a handle), and the enum aocl_mmd_info_t for
+ * info specific to a certain board.
+ * Arguments:
+ *
+ * requested_info_id - a value from the aocl_mmd_offline_info_t enum
+ *
+ * param_value_size - size of the param_value field in bytes. This should
+ * match the size of the return type expected as indicated in the enum
+ * definition. For example, the AOCL_MMD_TEMPERATURE returns a float, so
+ * the param_value_size should be set to sizeof(float) and you should
+ * expect the same number of bytes returned in param_size_ret.
+ *
+ * param_value - pointer to the variable that will receive the returned info
+ *
+ * param_size_ret - receives the number of bytes of data actually returned
+ *
+ * Returns: a negative value to indicate error.
+ */
+AOCL_MMD_CALL int aocl_mmd_get_offline_info(aocl_mmd_offline_info_t requested_info_id,
+ size_t param_value_size,
+ void* param_value,
+ size_t* param_size_ret) WEAK;
+
+// AOCL_MMD_CALL int aocl_mmd_get_info(int handle,
+// aocl_mmd_info_t requested_info_id,
+// size_t param_value_size,
+// void* param_value,
+// size_t* param_size_ret) WEAK;
+
+/* Open and initialize the named device.
+ *
+ * The name is typically one specified by the AOCL_MMD_BOARD_NAMES offline
+ * info.
+ *
+ * Arguments:
+ * name - open the board with this name (provided as a C-style string,
+ * i.e. NUL terminated ASCII.)
+ *
+ * Returns: the non-negative integer handle for the board, otherwise a
+ * negative value to indicate error. Upon receiving the error, the OpenCL
+ * runtime will proceed to open other known devices, hence the MMD mustn't
+ * exit the application if an open call fails.
+ */
+AOCL_MMD_CALL int aocl_mmd_open(const char* name) WEAK;
+
+/* Close an opened device, by its handle.
+ * Returns: 0 on success, negative values on error.
+ */
+AOCL_MMD_CALL int aocl_mmd_close(int handle) WEAK;
+
+/* Set the interrupt handler for the opened device.
+ * The interrupt handler is called whenever the client needs to be notified
+ * of an asynchronous event signaled by the device internals.
+ * For example, the kernel has completed or is stalled.
+ *
+ * Important: Interrupts from the kernel must be ignored until this handler is
+ * set
+ *
+ * Arguments:
+ * fn - the callback function to invoke when a kernel interrupt occurs
+ * user_data - the data that should be passed to fn when it is called.
+ *
+ * Returns: 0 if successful, negative on error
+ */
+AOCL_MMD_CALL int aocl_mmd_set_interrupt_handler(int handle, aocl_mmd_interrupt_handler_fn fn, void* user_data) WEAK;
+
+/* Set the device interrupt handler for the opened device.
+ * The device interrupt handler is called whenever the client needs to be notified
+ * of a device event signaled by the device internals.
+ * For example, an ECC error has been reported.
+ *
+ * Important: Interrupts from the device must be ignored until this handler is
+ * set
+ *
+ * Arguments:
+ * fn - the callback function to invoke when a device interrupt occurs
+ * user_data - the data that should be passed to fn when it is called.
+ *
+ * Returns: 0 if successful, negative on error
+ */
+// AOCL_MMD_CALL int aocl_mmd_set_device_interrupt_handler(int handle,
+// aocl_mmd_device_interrupt_handler_fn fn,
+// void* user_data) WEAK;
+
+/* Set the operation status handler for the opened device.
+ * The operation status handler is called with
+ * status 0 when the operation has completed successfully.
+ * status negative when the operation completed with errors.
+ *
+ * Arguments:
+ * fn - the callback function to invoke when a status update is to be
+ * performed.
+ * user_data - the data that should be passed to fn when it is called.
+ *
+ * Returns: 0 if successful, negative on error
+ */
+//AOCL_MMD_CALL int aocl_mmd_set_status_handler(int handle, aocl_mmd_status_handler_fn fn, void* user_data) WEAK;
+
+/* If AOCL_MMD_USES_YIELD is 1, this function is called when the host is idle
+ * and hence possibly waiting for events to be processed by the device.
+ * If AOCL_MMD_USES_YIELD is 0, this function is never called and the MMD is
+ * assumed to provide status/event updates via some other execution thread
+ * such as through an interrupt handler.
+ *
+ * Returns: non-zero if the yield function performed useful work such as
+ * processing DMA transactions, 0 if there is no useful work to be performed
+ *
+ * NOTE: yield may be called continuously as long as it reports that it has useful work
+ */
+//AOCL_MMD_CALL int aocl_mmd_yield(int handle) WEAK;
+
+/* Read, write and copy operations on a single interface.
+ * If op is NULL
+ * - Then these calls must block until the operation is complete.
+ * - The status handler is not called for this operation.
+ *
+ * If op is non-NULL, then:
+ * - These may be non-blocking calls
+ * - The status handler must be called upon completion, with status 0
+ * for success, and a negative value for failure.
+ *
+ * Arguments:
+ * op - the operation object used to track this operations progress
+ *
+ * len - the size in bytes to transfer
+ *
+ * src - the host buffer being read from
+ *
+ * dst - the host buffer being written to
+ *
+ * mmd_interface - the handle to the interface being accessed. E.g. To
+ * access global memory this handle will be whatever is returned by
+ * aocl_mmd_get_info when called with AOCL_MMD_MEMORY_INTERFACE.
+ *
+ * offset/src_offset/dst_offset - the byte offset within the interface that
+ * the transfer will begin at.
+ *
+ * The return value is 0 if the operation launch was successful, and
+ * negative otherwise.
+ */
+AOCL_MMD_CALL int aocl_mmd_read(
+ int handle, aocl_mmd_op_t op, size_t len, void* dst, int mmd_interface, size_t offset) WEAK;
+AOCL_MMD_CALL int aocl_mmd_write(
+ int handle, aocl_mmd_op_t op, size_t len, const void* src, int mmd_interface, size_t offset) WEAK;
+// AOCL_MMD_CALL int aocl_mmd_copy(
+// int handle, aocl_mmd_op_t op, size_t len, int mmd_interface, size_t src_offset, size_t dst_offset) WEAK;
+
+/* Host Channel create operation
+ * Opens channel between host and kernel.
+ *
+ * Arguments:
+ * channel_name - name of channel to initialize. Same name as used in board_spec.xml
+ *
+ * queue_depth - the size in bytes of pinned memory queue in system memory
+ *
+ * direction - the direction of the channel
+ *
+ * The return value is negative if initialization was unsuccessful, and
+ * positive otherwise. Positive return value is handle to the channel to be used for
+ * subsequent calls for the channel.
+ */
+//AOCL_MMD_CALL int aocl_mmd_hostchannel_create(int handle, char* channel_name, size_t queue_depth, int direction) WEAK;
+
+/* Host Channel destroy operation
+ * Closes channel between host and kernel.
+ *
+ * Arguments:
+ * channel - the handle to the channel to close, that was obtained with
+ * create channel
+ *
+ * The return value is 0 if the destroy was successful, and negative
+ * otherwise.
+ */
+//AOCL_MMD_CALL int aocl_mmd_hostchannel_destroy(int handle, int channel) WEAK;
+
+/* Host Channel get buffer operation
+ * Provide host with pointer to buffer they can access to write or
+ * read from kernel, along with space or data available in the buffer
+ * in bytes.
+ *
+ * Arguments:
+ * channel - the handle to the channel to get the buffer for
+ *
+ * buffer_size - the address that this call will write the amount of
+ * space or data that's available in the buffer,
+ * depending on direction of the channel, in bytes
+ *
+ * status - the address that this call will write to for result of this
+ * call. Value will be 0 for success, and negative otherwise
+ *
+ * The return value is the pointer to the buffer that host can write
+ * to or read from. NULL if the status is negative.
+ */
+//AOCL_MMD_CALL void* aocl_mmd_hostchannel_get_buffer(int handle, int channel, size_t* buffer_size, int* status) WEAK;
+
+/* Host Channel acknowledge buffer operation
+ * Acknowledge to the channel that the user has written or read data from
+ * it. This will make the data or additional buffer space available to
+ * write to or read from kernel.
+ *
+ * Arguments:
+ * channel - the handle to the channel that user is acknowledging
+ *
+ * send_size - the size in bytes that the user is acknowledging
+ *
+ * status - the address that this call will write to for result of this
+ * call. Value will be 0 for success, and negative otherwise
+ *
+ * The return value is equal to send_size if send_size was less than or
+ * equal to the buffer_size from get buffer call. If send_size was
+ * greater, then return value is the amount that was actually sent.
+ */
+//AOCL_MMD_CALL size_t aocl_mmd_hostchannel_ack_buffer(int handle, int channel, size_t send_size, int* status) WEAK;
+
+/* Program the device
+ *
+ * The host will guarantee that no operations are currently executing on the
+ * device. That means the kernels will be idle and no read/write/copy
+ * commands are active. Interrupts should be disabled and the FPGA should
+ * be reprogrammed with the data from user_data which has size size. The host
+ * will then call aocl_mmd_set_status_handler and aocl_mmd_set_interrupt_handler
+ * again. At this point interrupts can be enabled.
+ *
+ * The new handle to the board after reprogram does not have to be the same as
+ * the one before.
+ *
+ * Arguments:
+ * user_data - The binary contents of the fpga.bin file created during
+ * Quartus II compilation.
+ * size - the size in bytes of user_data
+ * program_mode - bit field for programming attributes. See
+ * aocl_mmd_program_mode_t definition
+ *
+ * Returns: the new non-negative integer handle for the board, otherwise a
+ * negative value to indicate error.
+ */
+
+// #ifdef DLA_MMD
+// // CoreDLA BSP has removed some stuff that MMD tries to handshake with, so provide a "raw access" function to
+// // reprogram the FPGA directly from the sof. Can't call quartus_pgm directly since the MMD still needs to mask
+// // the PCIe surprise down error (when full-chip programming the FPGA, the CPU thinks a PCIe device has disappeared).
+// // BEWARE: reprogramming will invalidate the handle
+// AOCL_MMD_CALL int aocl_mmd_program_sof(int handle, const char* sof_filename) WEAK;
+// #else
+// AOCL_MMD_CALL int aocl_mmd_program(int handle, void* user_data, size_t size, aocl_mmd_program_mode_t program_mode) WEAK;
+// #endif
+
+/** Error values*/
+#define AOCL_MMD_ERROR_SUCCESS 0
+#define AOCL_MMD_ERROR_INVALID_HANDLE -1
+#define AOCL_MMD_ERROR_OUT_OF_MEMORY -2
+#define AOCL_MMD_ERROR_UNSUPPORTED_ALIGNMENT -3
+#define AOCL_MMD_ERROR_UNSUPPORTED_PROPERTY -4
+#define AOCL_MMD_ERROR_INVALID_POINTER -5
+#define AOCL_MMD_ERROR_INVALID_MIGRATION_SIZE -6
+
+/** Memory properties*/
+typedef enum {
+ /**
+ * Specifies the name of a global memory that can be found in the
+ * board_spec.xml file for the BSP. Allocations will be allocated to this
+ * global memory interface.
+ */
+ AOCL_MMD_MEM_PROPERTIES_GLOBAL_MEMORY = 1,
+ /**
+ * Specifies the index of a bank inside the global memory interface that can be found in
+ * the board_spec.xml file for the BSP. Allocations will be allocated to this
+ * memory bank. It is invalid to specify this property without also specifying
+ * AOCL_MMD_GLOBAL_MEMORY_INTERFACE.
+ */
+ AOCL_MMD_MEM_PROPERTIES_MEMORY_BANK
+} aocl_mmd_mem_properties_t;
+
+/**
+ * Host allocations provide memory that is allocated on the host. Host
+ * allocations are accessible by the host and one or more devices.
+ * The same pointer to a host allocation may be used on the host and all
+ * supported devices; they have address equivalence. This memory must be
+ * deallocated with aocl_mmd_free();
+ *
+ * Once the device has signaled completion through
+ * aocl_mmd_interrupt_handler_fn() the host can assume it has access to the
+ * latest contents of the memory, allocated by this call.
+ *
+ * @param handles Handles for devices that will need access to this memory
+ * @param num_devices Number of devices in the handles
+ * @param size The size of the memory region
+ * @param alignment The alignment in bytes of the allocation
+ * @param properties Specifies additional information about the allocated
+ * memory, described by a property type name and its corresponding value.
+ * Each property type name is immediately followed by the corresponding
+ * desired value. The list is terminated with 0. Supported values are
+ * described above. Example: [<property1>, <value1>, <property2>, <value2>, 0]
+ * @param error The error code defined by AOCL_MMD_ERROR*
+ * @return valid pointer, on error NULL
+ */
+// AOCL_MMD_CALL void* aocl_mmd_host_alloc(int* handles,
+// size_t num_devices,
+// size_t size,
+// size_t alignment,
+// aocl_mmd_mem_properties_t* properties,
+// int* error) WEAK;
+
+/**
+ * Frees memory that has been allocated by MMD
+ *
+ * @param mem The pointer to the memory region. Must be a pointer that is
+ * allocated by the MMD.
+ * @return AOCL_MMD_ERROR_SUCCESS if success, else error code
+ */
+// AOCL_MMD_CALL int aocl_mmd_free(void* mem) WEAK;
+
+/**
+ * Allocate memory that is owned by the device. This pointer can only be
+ * accessed by the kernel; can't be accessed by the host. The host is able to
+ * manipulate the pointer (e.g. increment it) just not access the underlying
+ * data. This memory must be deallocated by aocl_mmd_free();
+ *
+ * @param handle Device that will have access to this memory
+ * @param size The size of the memory region
+ * @param alignment The alignment in bytes of the memory region
+ * @param properties Specifies additional information about the allocated
+ * memory, described by a property type name and its corresponding value.
+ * Each property type name is immediately followed by the corresponding
+ * desired value. The list is terminated with 0. Supported values are
+ * described above. Example: [<property1>, <value1>, <property2>, <value2>, 0]
+ * @param error The error code defined by AOCL_MMD_ERROR*
+ * @return Pointer that can be passed into the kernel. NULL on failure.
+ */
+// AOCL_MMD_CALL void* aocl_mmd_device_alloc(
+// int handle, size_t size, size_t alignment, aocl_mmd_mem_properties_t* properties, int* error) WEAK;
+
+/**
+ * Shared allocations may migrate between the host and one or more associated
+ * device. The same pointer to a shared allocation may be used on the host and
+ * the supported device; they have address equivalence.
+ *
+ * If the device does not support concurrent access to memory allocated by
+ * aocl_mmd_shared_alloc() then a call must be made to
+ * aocl_mmd_shared_mem_migrate() to indicate that the shared allocation should
+ * be migrated to the device before the device accesses this memory. For
+ * example, a call to aocl_mmd_shared_mem_migrate() should be made before a
+ * kernel accessing this memory is launched). Conversely,
+ * aocl_mmd_shared_mem_migrate() should be called again to indicate that the
+ * shared allocation should be migrated to the host before the host accesses
+ * this memory again. If the device supports concurrent access to memory
+ * allocated with aocl_mmd_shared_alloc(), then the call to
+ * aocl_mmd_shared_mem_migrate() is not necessary, but may still be made. In
+ * the case of concurrent access, it is the responsibility of the MMD to ensure
+ * both the device and host can access aocl_mmd_shared_alloc() allocations at
+ * all times.
+ *
+ * Memory allocated by aocl_mmd_shared_alloc() must be deallocated with
+ * aocl_mmd_free().
+ *
+ * @param handle Device that will have access to this memory
+ * @param size The size of the memory region
+ * @param alignment The alignment in bytes of the memory region
+ * @param properties Specifies additional information about the allocated
+ * memory, described by a property type name and its corresponding value.
+ * Each property type name is immediately followed by the corresponding
+ * desired value. The list is terminated with 0. Supported properties are
+ * listed above and have the prefix AOCL_MMD_MEM_PROPERTIES_.
+ * Example: [<property1>, <value1>, <property2>, <value2>, 0]
+ * @param error The error code defined by AOCL_MMD_ERROR*
+ * @return valid pointer, on error NULL
+ */
+// AOCL_MMD_CALL void* aocl_mmd_shared_alloc(
+// int handle, size_t size, size_t alignment, aocl_mmd_mem_properties_t* properties, int* error) WEAK;
+
+typedef enum { AOCL_MMD_MIGRATE_TO_HOST = 0, AOCL_MMD_MIGRATE_TO_DEVICE = 1 } aocl_mmd_migrate_t;
+
+/**
+ * A call to aocl_mmd_shared_migrate() must be made for non-concurrent shared
+ * allocations any time the accessor of the allocation changes. For example,
+ * aocl_mmd_shared_migrate() should be called indicating that the allocation
+ * should be migrated to the device before a kernel accessing the allocation
+ * is launched on the device. Similarly, aocl_mmd_shared_migrate() should be
+ * called indicating that the allocation is migrated to the host before the
+ * host accesses the memory after kernel completion.
+ *
+ * For concurrent allocations this call may be used as a performance hint, but
+ * is not strictly required for functionality.
+ *
+ * @param handle Device that will have access to this memory
+ * @param shared_ptr Pointer allocated by aocl_mmd_shared_alloc()
+ * @param size In bytes, the size of the migration. Must be of multiple of a
+ * page boundary that the BSP supports.
+ * @param destination The destination of migration
+ * @return The error code defined by AOCL_MMD_ERROR*
+ */
+// AOCL_MMD_CALL int aocl_mmd_shared_migrate(int handle,
+// void* shared_ptr,
+// size_t size,
+// aocl_mmd_migrate_t destination) WEAK;
+
+// CoreDLA modifications
+// To support multiple different FPGA boards, anything board specific must be implemented in a
+// board-specific MMD instead of the CoreDLA runtime layer.
+#ifdef DLA_MMD
+// Query functions to get board-specific values
+AOCL_MMD_CALL int dla_mmd_get_max_num_instances() WEAK;
+AOCL_MMD_CALL uint64_t dla_mmd_get_ddr_size_per_instance() WEAK;
+AOCL_MMD_CALL double dla_mmd_get_ddr_clock_freq() WEAK;
+
+// Wrappers around CSR and DDR reads and writes to abstract away board-specific offsets
+AOCL_MMD_CALL int dla_mmd_csr_write(int handle, int instance, uint64_t addr, const uint32_t* data) WEAK;
+AOCL_MMD_CALL int dla_mmd_csr_read(int handle, int instance, uint64_t addr, uint32_t* data) WEAK;
+AOCL_MMD_CALL int dla_mmd_ddr_write(int handle, int instance, uint64_t addr, uint64_t length, const void* data) WEAK;
+AOCL_MMD_CALL int dla_mmd_ddr_read(int handle, int instance, uint64_t addr, uint64_t length, void* data) WEAK;
+
+#define STREAM_CONTROLLER_ACCESS
+#ifdef STREAM_CONTROLLER_ACCESS
+AOCL_MMD_CALL bool dla_is_stream_controller_valid(int handle, int instance) WEAK;
+AOCL_MMD_CALL int dla_mmd_stream_controller_write(int handle, int instance, uint64_t addr, uint64_t length, const void* data) WEAK;
+AOCL_MMD_CALL int dla_mmd_stream_controller_read(int handle, int instance, uint64_t addr, uint64_t length, void* data) WEAK;
+#endif
+
+// Get the PLL clock frequency in MHz, returns a negative value if there is an error
+AOCL_MMD_CALL double dla_mmd_get_coredla_clock_freq(int handle) WEAK;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif