This commit adds the test mode in gem driver API.
It means that memory allocator can keep the same code semantics regardless the test mode.
Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
* @bug No known bugs except for NYI items
*/
-#include <GEMdrvAPI.h>
+#include "GEMdrvAPI.h"
#include <stdio.h>
#include <string.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
+/* npu-engine */
+#include <ne-conf.h>
+
#define DRM_BASE_PATH "/dev/dri/card"
+#define ALIGN_SIZE 4096
+#define DUMMY_HANDLE 0xdeadbeef
+#define DUMMY_FD 2848
+
+static void *malloc_buf = NULL; /* testing purpose */
/* internal implementation functions */
uint64_t value;
int offset, fd = -1;
+ if (conf->test_mode == 1)
+ return DUMMY_FD;
+
for (offset = 0; offset < 16; offset++) {
if ((fd = __gem_open_driver (offset, name)) > 0)
break;
}
/**
+ * @brief close gem driver
+ * @param[in] fd file descriptor
+ */
+void
+gem_close (int fd)
+{
+ if (conf->test_mode == 0)
+ close (fd);
+}
+
+/**
* @brief create a dumb buffer for gem object
* @param[in] fd the file descriptor of driver
* @param[in] size_in the requested buffer size
assert (fd > 0);
assert (size_in > 0);
+ if (conf->test_mode == 1) {
+ /* 4KB-aligned size */
+ *size_out = ((size_in - 1) / ALIGN_SIZE + 1) * ALIGN_SIZE;
+ malloc_buf = malloc (*size_out);
+ if (!malloc_buf)
+ return 0;
+
+ return DUMMY_HANDLE;
+ }
+
return __gem_create (fd, size_in, size_out);
}
assert (fd > 0);
assert (handle > 0);
+ if (conf->test_mode == 1) {
+ if (!malloc_buf)
+ return -EINVAL;
+ free (malloc_buf);
+ return 0;
+ }
+
return __gem_destroy (fd, handle);
}
assert (handle > 0);
assert (size > 0);
- ptr = __gem_mmap(fd, handle, size, prot, dmabuf);
+ if (conf->test_mode == 0)
+ ptr = __gem_mmap(fd, handle, size, prot, dmabuf);
+ else
+ ptr = malloc_buf;
return ptr != MAP_FAILED ? ptr : NULL;
}
/**
+ * @brief munmap operation for gem object
+ * @param[in] ptr mmapped pointer
+ * @param[in] size mmapped size
+ * @return 0 if no error, otherwise a negative errno
+ */
+int
+gem_munmap (void *ptr, uint32_t size)
+{
+ if (conf->test_mode == 0) {
+ if (munmap (ptr, size) != 0)
+ return -errno;
+ }
+ return 0;
+}
+
+/**
* @brief export a GEM buffer object into a global dmabuf fd handle
* @param[in] fd a file descriptor of driver
* @param[in] handle a GEM buffer object handle
assert (fd > 0);
assert (handle > 0);
+ if (conf->test_mode == 1)
+ return DUMMY_FD;
+
return __gem_prime_export (fd, handle);
}
assert (fd > 0);
assert (dmabuf_fd > 0);
+ if (conf->test_mode == 1)
+ return DUMMY_HANDLE;
+
return __gem_prime_import (fd, dmabuf_fd);
}
gem_open (const char *name);
/**
+ * @brief close gem driver
+ * @param[in] fd file descriptor
+ */
+void
+gem_close (int fd);
+
+/**
* @brief create a dumb buffer for gem object
* @param[in] fd the file descriptor of driver
* @param[in] size_in the requested buffer size
gem_mmap (int fd, uint32_t handle, uint32_t size, int prot, bool dmabuf);
/**
+ * @brief munmap operation for gem object
+ * @param[in] ptr mmapped pointer
+ * @param[in] size mmapped size
+ * @return 0 if no error, otherwise a negative errno
+ */
+int
+gem_munmap (void *ptr, uint32_t size);
+
+/**
* @brief export a GEM buffer object into a global dmabuf fd handle
* @param[in] fd a file descriptor of driver
* @param[in] handle a GEM buffer object handle
libgem_src = ['GEMdrvAPI.c']
libgem_inc = include_directories('.')
-libgem_dependencies = [libdrm_dep]
+libgem_dependencies = [libdrm_dep, libutils_dep]
# Build library (static)
libgem_build = static_library('gem-core',
* @bug No known bugs except for NYI items
*/
-#include <ne-mem.h>
-#include <ne-utils.h>
-#include <ne-conf.h>
+#include "ne-mem.h"
+#include "ne-utils.h"
#include <GEMdrvAPI.h>
#include <stdio.h>
* @brief memory chunk structure
*/
typedef struct {
- mem_size_t offset; /**< chunk offset */
- mem_size_t size; /**< chunk size */
+ mem_size_t offset; /**< chunk offset */
+ mem_size_t size; /**< chunk size */
chunk_state state; /**< chunk state */
list_node list; /**< list element */
int fd; /**< file descriptor of a GEM driver */
int dmabuf; /**< dmabuf fd handle */
uint32_t handle; /**< GEM buffer object handle for memory pool */
- mem_size_t size; /**< memory pool size */
+ mem_size_t size; /**< memory pool size */
void* virtaddr; /**< base virtual address for memory pool */
buffer *buffer [MEM_NUM_BUFFERS]; /**< buffer array */
int buffer_head; /**< buffer head (changed by .switch_buffers()) */
- mem_size_t buffer_size; /**< buffer size for each */
+ mem_size_t buffer_size; /**< buffer size for each */
pthread_mutex_t mutex; /**< mutex for locking */
pthread_cond_t cond; /**< cond for broadcasting */
}
if ((fd = gem_open (GEM_NAME)) <= 0) {
- if (conf->test_mode == 0) {
- logerr(MEM_TAG, "Fail to open a GEM driver\n");
- return -EACCES;
- } else {
- logwarn(MEM_TAG, "Fail to open a GEM driver.. fall back to test mode using malloc()\n");
- }
+ logerr(MEM_TAG, "Fail to open a GEM driver\n");
+ return -EACCES;
}
- if (conf->test_mode == 0) {
- do {
- /**
- * the minimum size of allocation is MEM_BASE_SIZE
- * note that gem_create() supports only 32bit allocation (currently)
- */
- uint32_t size_in_32 = size_in;
- uint32_t size_out_32;
-
- if ((handle = gem_create (fd, size_in_32, &size_out_32)) == 0)
- /* if failed, retry with a smaller size */
- size_in = size_in >> 1;
- else
- *size_out = size_out_32;
- } while (handle == 0 && size_in >= MEM_BASE_SIZE);
-
- if (handle == 0) {
- close (fd);
- logerr (MEM_TAG, "no available memory\n");
- return -ENOMEM;
- }
- } else {
- handle = fd = 1; /* dummy */
- *size_out = size_in;
+ do {
+ /**
+ * the minimum size of allocation is MEM_BASE_SIZE
+ * note that gem_create() supports only 32bit allocation (currently)
+ */
+ uint32_t size_in_32 = size_in;
+ uint32_t size_out_32;
+
+ if ((handle = gem_create (fd, size_in_32, &size_out_32)) == 0)
+ /* if failed, retry with a smaller size */
+ size_in = size_in >> 1;
+ else
+ *size_out = size_out_32;
+ } while (handle == 0 && size_in >= MEM_BASE_SIZE);
+
+ if (handle == 0) {
+ gem_close (fd);
+ logerr (MEM_TAG, "no available memory\n");
+ return -ENOMEM;
}
/* setup private data */
mpriv.handle = handle;
mpriv.buffer_size = 0;
- if (conf->test_mode == 0) {
- /* export the handle to dmabuf fd handle */
- mpriv.dmabuf = gem_prime_export (fd, handle);
- assert (mpriv.dmabuf > 0);
- /**
- * mmap() for the GEM buffer and assign its base addresses.
- * The reason to mmap() for the whole CMA space is that
- * frequent system calls for mmap()/munmap() may decrease the performance.
- * So, we will just return a hwmem with offset/size to users.
- */
- mpriv.virtaddr = gem_mmap (mpriv.fd, mpriv.handle, mpriv.size,
- PROT_WRITE | PROT_READ, false);
- } else {
- mpriv.dmabuf = 1; /* dummy */
- mpriv.virtaddr = malloc (size_in);
- if (mpriv.virtaddr == NULL) {
- logerr (MEM_TAG, "no available memory\n");
- return -ENOMEM;
- }
- }
+ /* export the handle to dmabuf fd handle */
+ mpriv.dmabuf = gem_prime_export (fd, handle);
+ assert (mpriv.dmabuf > 0);
+ /**
+ * mmap() for the GEM buffer and assign its base addresses.
+ * The reason to mmap() for the whole CMA space is that
+ * frequent system calls for mmap()/munmap() may decrease the performance.
+ * So, we will just return a hwmem with offset/size to users.
+ */
+ mpriv.virtaddr = gem_mmap (mpriv.fd, mpriv.handle, mpriv.size,
+ PROT_WRITE | PROT_READ, false);
assert (mpriv.virtaddr != NULL);
chunk_free (chunk);
}
- if (conf->test_mode == 0) {
- munmap (mpriv.virtaddr, mpriv.size);
+ gem_munmap (mpriv.virtaddr, mpriv.size);
- /* close dmabuf handle */
- close (mpriv.dmabuf);
+ /* close dmabuf handle */
+ gem_close (mpriv.dmabuf);
- /* release the gem buffer object handle */
- gem_destroy (mpriv.fd, mpriv.handle);
+ /* release the gem buffer object handle */
+ gem_destroy (mpriv.fd, mpriv.handle);
- /* close gem driver */
- close (mpriv.fd);
- } else {
- free (mpriv.virtaddr);
- }
+ /* close gem driver */
+ gem_close (mpriv.fd);
return 0;
}
"did you load it? (i.e., sudo modprobe cgem)\n");
ASSERT_GT (fd, 0);
- close (fd);
+ gem_close (fd);
}
/**
ASSERT_EQ (size, 1 << 22);
gem_destroy (fd, handle);
- close (fd);
+ gem_close (fd);
}
/**
for (page = 0; page < size >> 2; page += 1 << 10)
ptr[page] = 0;
- munmap (ptr, size);
+ gem_munmap (ptr, size);
gem_destroy (fd, handle);
- close (fd);
+ gem_close (fd);
}
/**
for (page = 0; page < (size >> 2); page += 1 << 10)
ptr[page] = page;
- munmap (ptr, size);
+ gem_munmap (ptr, size);
- close (dmabuf_fd);
+ gem_close (dmabuf_fd);
/* mmap */
ptr = (uint32_t *) gem_mmap (fd, handle, size, PROT_READ, false);
/* compare data */
for (page = 0; page < (size >> 2); page += 1 << 10)
ASSERT_EQ (ptr[page], page);
- munmap (ptr, size);
+ gem_munmap (ptr, size);
gem_destroy (fd, handle);
- close (fd);
+ gem_close (fd);
}
/**
gtest_dep = dependency('gtest', required: false)
if gtest_dep.found()
-#### TODO libgem unittest is not working on gbs because cgem driver is not installed
-#### Therefore, we skip the build this UnitTest temporally.
-# libgem_unittest_deps = [
-# libgem_dep,
-# gtest_dep
-# ]
-#
-# unittest_libgem = executable('unittest_libgem',
-# ['libgem_test.cpp'],
-# dependencies: [libgem_unittest_deps],
-# cpp_args : '-std=c++11'
-# )
-#
-# test('unittest_libgem', unittest_libgem)
+ libgem_unittest_deps = [
+ libgem_dep,
+ gtest_dep
+ ]
+
+ unittest_libgem = executable('unittest_libgem',
+ ['libgem_test.cpp'],
+ dependencies: [libgem_unittest_deps],
+ cpp_args : '-std=c++11',
+ install : true,
+ install_dir : join_paths(ne_bindir, 'unittests')
+ )
+
+ test('unittest_libgem', unittest_libgem)
libnpu_unittest_deps = [
libnpucore_dep,