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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 49 additions & 4 deletions doc/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,31 @@ removed at run-time.
API Details:
============

==============================================================
=================
CMA File Support:
=================
libdfx now supports optional custom CMA (Contiguous Memory Allocator) file
specification for DMA buffer allocation. This feature provides flexibility for
different platform configurations and reserved memory setups.

Default DMA Heap Paths:
- /dev/dma_heap/reserved
- /dev/dma_heap/cma_reserved@800000000

Custom CMA File Usage:
- Users can specify a custom CMA file path as an optional parameter
- If provided, libdfx will attempt to use the custom path first
- If the custom path fails, it falls back to default paths
- This allows for platform-specific memory configurations

Examples of custom CMA paths:
- /dev/dma_heap/custom_cma
- /dev/dma_heap/cma_reserved@specific_address
- /dev/dma_heap/platform_specific_heap
=================================================================
 -pre-fetch:  dfx_cfg_init (const char *dfx_package_path,
const char *devpath, u32 flags);
==============================================================
const char *devpath, u32 flags, ...);
=================================================================

/* Provide a generic interface to the user to specify the required parameters
* for PR programming.
Expand All @@ -199,6 +220,11 @@ API Details:
* unsigned long flags: Flags to specify any special instructions for library
* to perform.
*
* Optional parameters (using variadic arguments):
* char *cma_file: (Optional) Custom CMA file path for DMA buffer allocation.
* If NULL or not provided, defaults to standard paths:
* "/dev/dma_heap/reserved" or "/dev/dma_heap/cma_reserved@800000000"
*
* Return: returns unique package_Id or Error code on failure.
*/

Expand All @@ -219,12 +245,19 @@ package_id2 = dfx_cfg_init ("/path/package2/", "/dev/fpga0", flags);

/* More code */

/* -store /Pre-fetch data - For custom CMA file use case*/
package_id3 = dfx_cfg_init ("/path/package3/", "/dev/fpga0", flags,
"/dev/dma_heap/custom_cma");

/* More code */

=============================================================================
-pre-fetch int dfx_cfg_init_file(const char *dfx_bin_file,
const char *dfx_dtbo_file,
const char *dfx_driver_dtbo_file,
const char *dfx_aes_key_file,
const char *devpath, unsigned long flags);
const char *devpath,
unsigned long flags, ...);
=============================================================================

/* Provide a generic interface to the user to specify the required parameters
Expand Down Expand Up @@ -255,6 +288,11 @@ package_id2 = dfx_cfg_init ("/path/package2/", "/dev/fpga0", flags);
* unsigned long flags: Flags to specify any special instructions for the
* library to perform.
*
* Optional parameters (using variadic arguments):
* char *cma_file: (Optional) Custom CMA file path for DMA buffer allocation.
* If NULL or not provided, defaults to standard paths:
* "/dev/dma_heap/reserved" or "/dev/dma_heap/cma_reserved@800000000"
*
* Return: returns unique package_Id or Error code on failure.
*/

Expand Down Expand Up @@ -287,6 +325,13 @@ package_id3 = dfx_cfg_init_file("/lib/firmware/xilinx/example/example.bin ",
/dev/fpga0", flags);
/* More code */

/* -store /Pre-fetch data - For custom CMA file use case*/
package_id4 = dfx_cfg_init_file("/lib/firmware/xilinx/example/example.bin ",
"/lib/firmware/xilinx/example/example.dtbo",
NULL, NULL, "/dev/fpga0", flags,
"/dev/dma_heap/custom_cma");
/* More code */

================================================================
-fpga-load:  int dfx_cfg_load(struct dfx_package_Id package_Id)
================================================================
Expand Down
44 changes: 32 additions & 12 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#***************************************************************
#******************************************************************************
#* Copyright (c) 2020 Xilinx, Inc. All rights reserved.
#* Copyright (C) 2023, Advanced Micro Devices, Inc. All Rights Reserved
#* Copyright (C) 2023 - 2025, Advanced Micro Devices, Inc. All Rights Reserved
#* SPDX-License-Identifier: MIT
#***************************************************************
#******************************************************************************

include(GNUInstallDirs)

# Specify the minimum version for CMake
cmake_minimum_required(VERSION 2.8.9)
cmake_minimum_required(VERSION 2.8.9)

# Project's name
project(dfx)
enable_language(C ASM)
Expand All @@ -20,21 +22,39 @@ set(LIBDFX_INCLUDE_DIRS
"include/"
)

SET(LIBDFX_VERSION 1.0)
# ---- Library versioning ----
set(LIBDFX_VERSION_MAJOR 1)
set(LIBDFX_VERSION_MINOR 0)
set(LIBDFX_VERSION_PATCH 1)
set(LIBDFX_VERSION ${LIBDFX_VERSION_MAJOR}.${LIBDFX_VERSION_MINOR}.${LIBDFX_VERSION_PATCH})

# Copy header to build directory for IDE support
file(COPY include/libdfx.h DESTINATION ${CMAKE_BINARY_DIR}/include)

# ---- Shared library (with SONAME) ----
add_library(dfx_shared SHARED ${libdfx_sources})
SET_TARGET_PROPERTIES(dfx_shared PROPERTIES SOVERSION ${LIBDFX_VERSION} OUTPUT_NAME "dfx")
SET_TARGET_PROPERTIES(dfx_shared PROPERTIES CLEAN_DIRECT_OUTPUT 1)
set_target_properties(dfx_shared PROPERTIES
VERSION ${LIBDFX_VERSION}
SOVERSION ${LIBDFX_VERSION_MAJOR}
OUTPUT_NAME "dfx"
CLEAN_DIRECT_OUTPUT 1
)

# ---- Static library ----
add_library(dfx_static STATIC ${libdfx_sources})
SET_TARGET_PROPERTIES(dfx_static PROPERTIES OUTPUT_NAME "dfx")
SET_TARGET_PROPERTIES(dfx_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
set_target_properties(dfx_static PROPERTIES
OUTPUT_NAME "dfx"
CLEAN_DIRECT_OUTPUT 1
)

# ---- Include directories ----
target_include_directories(dfx_shared PUBLIC ${LIBDFX_INCLUDE_DIRS})
target_include_directories(dfx_static PUBLIC ${LIBDFX_INCLUDE_DIRS})

# ---- Install rules ----
install(FILES "include/libdfx.h" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(TARGETS dfx_shared; dfx_static
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

install(TARGETS dfx_shared dfx_static
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
67 changes: 60 additions & 7 deletions src/dmabuf_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,71 @@
#include "dmabuf_alloc.h"
#include "dma-heap.h"

static int open_device (int *devfd)
#include <dirent.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

static int is_cma_default_node(const char *node_name)
{
char path[512];

snprintf(path, sizeof(path),
"/sys/firmware/devicetree/base/reserved-memory/%s/linux,cma-default",
node_name);

/* returns 1 if property exists, 0 if not */
return (access(path, F_OK) == 0);
}

static int open_device(const char *cma_file, int *devfd)
{
if (!devfd) {
printf("%s: Invalid devfd pointer\n", __func__);
return -1;
}

// Try user-provided heap path first
if (cma_file != NULL) {
*devfd = open(cma_file, O_RDWR);
if (*devfd >= 0)
return 0;
}

// Try default kernel reserved CMA heap
*devfd = open("/dev/dma_heap/reserved", O_RDWR);
if (*devfd >= 0) {
if (*devfd >= 0)
return 0;
} else {
*devfd = open("/dev/dma_heap/cma_reserved@800000000", O_RDWR);
if (*devfd >= 0) {
return 0;

// Dynamic scan for cma_reserved@* that also has linux,cma-default
DIR *dir = opendir("/dev/dma_heap");
if (dir) {
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (strncmp(entry->d_name, "cma_reserved@", 13) == 0) {

// Check if the DT node has the linux,cma-default flag
if (!is_cma_default_node(entry->d_name))
continue;

char path[256];
snprintf(path, sizeof(path),
"/dev/dma_heap/%s", entry->d_name);

*devfd = open(path, O_RDWR);

if (*devfd >= 0) {
closedir(dir);
return 0;
}
}
}
closedir(dir);
}

printf("%s: No valid CMA heap found\n", __func__);

return -1;
}

Expand Down Expand Up @@ -84,7 +137,7 @@ int export_dma_buffer(struct dma_buffer_info *dma_data)
return -1;
}

ret = open_device(&devfd);
ret = open_device(dma_data->cma_file, &devfd);
if (ret)
return ret;

Expand Down
1 change: 1 addition & 0 deletions src/include/dmabuf_alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
struct dma_buffer_info {
int devfd;
int dma_buffd;
const char *cma_file;
unsigned char *dma_buffer;
unsigned long dma_buflen;
};
Expand Down
5 changes: 3 additions & 2 deletions src/include/libdfx.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@


int dfx_cfg_init(const char *dfx_package_path,
const char *devpath, unsigned long flags);
const char *devpath, unsigned long flags,
...);
int dfx_cfg_load(int package_id);
int dfx_cfg_drivers_load(int package_id);
int dfx_cfg_remove(int package_id);
Expand All @@ -82,5 +83,5 @@ int dfx_get_active_uid_list(int *buffer);
int dfx_get_meta_header(char *binfile, int *buffer, int buf_size);
int dfx_cfg_init_file(const char *dfx_bin_file, const char *dfx_dtbo_file,
const char *dfx_driver_dtbo_file, const char *dfx_aes_key_file,
const char *devpath, unsigned long flags);
const char *devpath, unsigned long flags, ...);
#endif
Loading