summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk+cubox@arm.linux.org.uk>2013-12-08 21:29:56 +0000
committerRussell King <rmk@arm.linux.org.uk>2013-12-08 22:02:42 +0000
commit6f2e8ec4c736fbffe3d0e0f1ec07f453910441a1 (patch)
tree3adfc685d5addab0a3d7a609a0d620b0046a6bee
parentdcad449e26e81b71e4a498dc5bfaf014a5566acd (diff)
BMMv2: dma_buf based BMMHEADv2.0.0master
This is a complete redesign and rewrite of libbmm. This implementation is based upon dma_bufs - where a dma_buf is a kernel-side buffer which can be passed to and from other subsystems. libbmm becomes a provider of dma_bufs - it permits userspace to allocate such things. When a dma_buf is allocated, userspace is handed a file descriptor which is unique to this buffer. This file descriptor can then be passed into other subsystems, which can then request access to this buffer. The file descriptor supports very few operations - it can be mmap()d to provide userspace access to the buffer, and it can be closed when it is no longer required. Internally in the kernel, dma_bufs are reference counted, so the dma_buf will only be freed when the last user gives up its reference.
-rw-r--r--.gitignore5
-rw-r--r--Makefile.am6
-rw-r--r--bmm_drv.h42
-rw-r--r--bmm_lib.c726
-rw-r--r--bmm_lib.h28
-rw-r--r--bmm_lib.pmem.c287
-rw-r--r--bmm_lib_priv.h51
-rw-r--r--bmm_test.c324
-rw-r--r--configure.ac6
-rw-r--r--debian/changelog7
-rw-r--r--debian/control17
-rw-r--r--debian/libbmm-dev.install1
-rw-r--r--debian/libbmm2.install (renamed from debian/libbmm1.install)0
-rwxr-xr-xdebian/rules3
14 files changed, 219 insertions, 1284 deletions
diff --git a/.gitignore b/.gitignore
index e1d0b76..2b9488f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,10 +19,13 @@ debian/*.log
debian/*.substvars
debian/libbmm-common/
debian/libbmm-dev/
-debian/libbmm1/
+debian/libbmm2/
debian/libbmm*-dbg/
debian/tmp/
debian/*.dirs
debian/*.shlibs
debian/*.symbols
debian/files
+debian/*.debhelper
+debian/autoreconf.after
+debian/autoreconf.before
diff --git a/Makefile.am b/Makefile.am
index fe67d9c..c32571d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,7 +5,7 @@ libbmm_la_LTLIBRARIES = libbmm.la
libbmm_ladir = $(libdir)
libbmm_la_LDFLAGS = -no-undefined -export-symbols-regex "bmm_*" \
-version-info @ABI_VERSION@:@ABI_REVISION@:@ABI_AGE@
-libbmm_la_SOURCES = bmm_lib.c bmm_lib_priv.h rb.c rb.h
+libbmm_la_SOURCES = bmm_lib.c bmm_drv.h rb.c rb.h
libbmm_laincludedir = $(includedir)
libbmm_lainclude_HEADERS = bmm_lib.h
@@ -13,10 +13,6 @@ libbmm_lainclude_HEADERS = bmm_lib.h
pkgconfigdir = @pkgconfigdir@
pkgconfig_DATA = libbmm.pc
-bin_PROGRAMS = bmm_test
-bmm_test_SOURCES = bmm_test.c
-bmm_test_LDADD = libbmm.la
-
dataudevdir = @udevrulesdir@
dataudev_DATA = etc/udev/rules.d/99-bmm.rules
diff --git a/bmm_drv.h b/bmm_drv.h
new file mode 100644
index 0000000..77855d4
--- /dev/null
+++ b/bmm_drv.h
@@ -0,0 +1,42 @@
+/*
+ * bmm_drv.h
+ *
+ * Copyright (C) 2013 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, you can distribute this file under the GNU Lesser
+ * General Public License version 2.1 as published by the Free Software
+ * Foundation.
+ */
+#ifndef __BMM_DRV_H__
+#define __BMM_DRV_H__
+
+#include <stdint.h>
+
+#define BMM_DEVICE_FILE "/dev/bmm"
+#define BMM_MINOR 94
+
+/* ioctl commands */
+struct bmm_dmabuf_alloc {
+ uint64_t size;
+ uint64_t align;
+ uint32_t attr;
+ int32_t fd;
+};
+
+struct bmm_dmabuf_flush {
+ uint64_t size;
+ uint64_t offset;
+ uint64_t ptr;
+ int32_t fd;
+ uint32_t direction;
+};
+
+#define BMEM_IOCTL_MAGIC 'G'
+#define BMM_DMABUF_ALLOC _IOWR(BMEM_IOCTL_MAGIC, 64, struct bmm_dmabuf_alloc)
+#define BMM_DMABUF_FLUSH _IOW(BMEM_IOCTL_MAGIC, 65, struct bmm_dmabuf_flush)
+
+#endif /* __BMM_DRV_H__ */
diff --git a/bmm_lib.c b/bmm_lib.c
index d6a3271..3a202f3 100644
--- a/bmm_lib.c
+++ b/bmm_lib.c
@@ -16,13 +16,14 @@
#include <sys/stat.h>
#include <sys/mman.h>
#include <assert.h>
+#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include "bmm_lib_priv.h"
+#include "bmm_drv.h"
#include "bmm_lib.h"
#include "rb.h"
@@ -34,35 +35,15 @@
#define pr_debug(fmt, arg...) do { if (0) fprintf(stderr, fmt, ##arg); } while (0)
#endif
-#define API_FEAT_MIN 0x0000
-#define API_COMP_MAX 0x0001
-#define API_FEAT(x) ((x) >> 16)
-#define API_COMP(x) ((x) & 0xffff)
-#define API_FEAT_GET_DMABUF_FD 0x0001
-#define API_FEAT_FREE_PHYS 0x0002
-#define API_FEAT_KEEP_FORK 0x0003
-
-static unsigned bmm_api;
static int bmm_fd = -1;
+static int bmm_use;
static pthread_mutex_t bmm_mutex = PTHREAD_MUTEX_INITIALIZER;
-static Rb_node virt_rb;
-static Rb_node phys_rb;
-
-struct bmm_virt_buffer;
-
-struct bmm_phys_buffer {
- unsigned long paddr;
- size_t size;
- int attr;
- struct bmm_virt_buffer *virt;
- unsigned attach;
-};
+static Rb_node bmm_virt_rb;
struct bmm_virt_buffer {
void *vaddr;
size_t size;
- unsigned phys_offset;
- struct bmm_phys_buffer *phys;
+ int fd;
};
static int cmp_virt(const void *key, const void *val)
@@ -70,17 +51,7 @@ static int cmp_virt(const void *key, const void *val)
const struct bmm_virt_buffer *vbuf = val;
void *k = (void *)key;
- return (k < vbuf->vaddr) ? -1 :
- (k - vbuf->vaddr < vbuf->size) ? 0 : 1;
-}
-
-static int cmp_phys(const void *key, const void *val)
-{
- const struct bmm_phys_buffer *pbuf = val;
- unsigned long k = (unsigned long)key;
-
- return (k < pbuf->paddr) ? -1 :
- (k - pbuf->paddr < pbuf->size) ? 0 : 1;
+ return (k < vbuf->vaddr) ? -1 : (k - vbuf->vaddr < vbuf->size) ? 0 : 1;
}
static struct bmm_virt_buffer *bmm_buf_find_virt(void *virt)
@@ -89,12 +60,12 @@ static struct bmm_virt_buffer *bmm_buf_find_virt(void *virt)
Rb_node node;
int found = 0;
- node = rb_find_key_n(virt_rb, virt, cmp_virt, &found);
+ node = rb_find_key_n(bmm_virt_rb, virt, cmp_virt, &found);
if (found) {
vbuf = rb_val(node);
- pr_debug("rb: %s(%p) phys=0x%08lx virt=%p size=0x%08zx\n",
- "find_virt", virt, vbuf->phys->paddr, vbuf->vaddr,
+ pr_debug("rb: %s(%p) virt=%p size=0x%08zx\n",
+ "find_virt", virt, vbuf->vaddr,
vbuf->size);
} else {
pr_debug("rb: %s(%p): not found\n",
@@ -104,66 +75,15 @@ static struct bmm_virt_buffer *bmm_buf_find_virt(void *virt)
return vbuf;
}
-static struct bmm_phys_buffer *bmm_buf_find_phys(unsigned long phys)
-{
- struct bmm_phys_buffer *pbuf = NULL;
- Rb_node node;
- int found = 0;
-
- node = rb_find_key_n(phys_rb, (void *)phys, cmp_phys, &found);
- if (found) {
- pbuf = rb_val(node);
-
- pr_debug("rb: %s(0x%08lx) phys=0x%08lx size=0x%08zx\n",
- "find_phys", (unsigned long)phys, pbuf->paddr, pbuf->size);
- } else {
- pr_debug("rb: %s(0x%08lx): not found\n",
- "find_phys", (unsigned long)phys);
- }
-
- return pbuf;
-}
-
-static void bmm_rb_phys_remove(struct bmm_phys_buffer *pbuf)
-{
- Rb_node node;
- int found = 0;
-
- pr_debug("%s: phys=0x%08lx size=0x%08zx\n",
- __FUNCTION__, pbuf->paddr, pbuf->size);
-
- node = rb_find_key_n(phys_rb, (void *)pbuf->paddr, cmp_phys, &found);
- assert(found);
- rb_delete_node(node);
-}
-
-static void bmm_rb_phys_insert(struct bmm_phys_buffer *pbuf)
-{
- Rb_node node;
- int found = 0;
-
- pr_debug("%s: phys=0x%08lx size=0x%08zx\n",
- __FUNCTION__, pbuf->paddr, pbuf->size);
-
- node = rb_find_key_n(phys_rb, (void *)pbuf->paddr, cmp_phys, &found);
- if (found) {
- struct bmm_phys_buffer *f = rb_val(node);
- pr_debug("rb: found: %p\n", f);
- pr_debug(" p0x%08lx s0x%08zx\n", f->paddr, f->size);
- }
- assert(found == 0);
- rb_insert_b(node, pbuf);
-}
-
static void bmm_rb_virt_remove(struct bmm_virt_buffer *vbuf)
{
Rb_node node;
int found = 0;
- pr_debug("%s: phys=0x%08lx virt=%p size=0x%08zx\n",
- __FUNCTION__, vbuf->phys->paddr, vbuf->vaddr, vbuf->size);
+ pr_debug("%s: virt=%p size=0x%08zx\n",
+ __FUNCTION__, vbuf->vaddr, vbuf->size);
- node = rb_find_key_n(virt_rb, vbuf->vaddr, cmp_virt, &found);
+ node = rb_find_key_n(bmm_virt_rb, vbuf->vaddr, cmp_virt, &found);
assert(found);
rb_delete_node(node);
}
@@ -173,583 +93,229 @@ static void bmm_rb_virt_insert(struct bmm_virt_buffer *vbuf)
Rb_node node;
int found = 0;
- pr_debug("%s: phys=0x%08lx virt=%p size=0x%08zx\n",
- __FUNCTION__, vbuf->phys->paddr, vbuf->vaddr, vbuf->size);
+ pr_debug("%s: virt=%p size=0x%08zx\n",
+ __FUNCTION__, vbuf->vaddr, vbuf->size);
- node = rb_find_key_n(virt_rb, vbuf->vaddr, cmp_virt, &found);
+ node = rb_find_key_n(bmm_virt_rb, vbuf->vaddr, cmp_virt, &found);
if (found) {
struct bmm_virt_buffer *f = rb_val(node);
pr_debug("rb: found: %p\n", f);
- pr_debug(" p0x%08lx v%p s0x%08zx\n", f->phys->paddr, f->vaddr, f->size);
+ pr_debug(" v%p s0x%08zx\n", f->vaddr, f->size);
}
assert(found == 0);
rb_insert_b(node, vbuf);
}
-static int bmm_get_api_version(void)
+/**
+ * bmm_dmabuf_alloc - allocate a DMA buffer
+ * @size: size of DMA buffer
+ * @attr: attributes of DMA buffer
+ * @align: requested alignment
+ *
+ * Returns: dma_buf file descriptor referring to buffer
+ */
+int bmm_dmabuf_alloc(unsigned long size, int attr, unsigned align)
{
- ioctl_arg_t io;
-
- /* Get the BMM API version */
- io.input = 0;
- io.arg = 0;
- io.output = 0;
- if (ioctl(bmm_fd, BMM_API_VERSION, &io) == 0 &&
- io.input == 0xdeaddead && io.arg == 0xfacebeef)
- bmm_api = io.output;
- else
- bmm_api = 0;
-
- pr_debug("BMM API version %08x\n", bmm_api);
-
- if (API_FEAT(bmm_api) < API_FEAT_MIN ||
- API_COMP(bmm_api) > API_COMP_MAX)
- return -1;
-
- return 0;
-}
+ struct bmm_dmabuf_alloc arg;
+ int ret;
-int bmm_init(void)
-{
- if (bmm_fd < 0) {
- virt_rb = make_rb();
- phys_rb = make_rb();
- if (!virt_rb || !phys_rb)
- goto err_rb;
+ /* obsolete, only for back-compatible */
+ if (attr & BMM_ATTR_NONBUFFERABLE && attr & BMM_ATTR_NONCACHEABLE)
+ attr = BMM_ATTR_NONCACHED;
- /* attempt to open the BMM driver */
- bmm_fd = open(BMM_DEVICE_FILE, O_RDWR | O_CLOEXEC);
- pr_debug("BMM device fd: %d\n", bmm_fd);
- if (bmm_fd < 0)
- goto err_open;
+ if (!(attr & BMM_ATTR_NONBUFFERABLE) && attr & BMM_ATTR_NONCACHEABLE)
+ attr = BMM_ATTR_WRITECOMBINE;
- if (bmm_get_api_version() < 0)
- goto err_api;
- }
+ arg.size = size;
+ arg.align = align;
+ arg.attr = attr;
- return bmm_fd;
+ ret = ioctl(bmm_fd, BMM_DMABUF_ALLOC, &arg);
- err_api:
- close(bmm_fd);
- bmm_fd = -1;
- err_open:
- err_rb:
- if (phys_rb)
- rb_free_tree(phys_rb);
- if (virt_rb)
- rb_free_tree(virt_rb);
- phys_rb = virt_rb = NULL;
- return bmm_fd;
-}
-
-void bmm_exit(void)
-{
- if (bmm_fd >= 0) {
- close(bmm_fd);
- rb_free_tree(phys_rb);
- rb_free_tree(virt_rb);
- phys_rb = virt_rb = NULL;
- }
- bmm_fd = -1;
+ return ret < 0 ? ret : arg.fd;
}
-void *bmm_malloc_aligned_phys(unsigned long size, int attr, unsigned align,
- unsigned long *paddr)
+/**
+ * bmm_dmabuf_map - map an allcoated DMA buffer
+ * @fd: dma_buf file descriptor
+ * @offset: page aligned offset into DMA buffer
+ * @size: size of buffer to map
+ *
+ * Map the requested buffer into userspace with the requested offset and size.
+ *
+ * Returns: address of mapped buffer, or NULL on error
+ */
+void *bmm_dmabuf_map(int fd, unsigned offset, unsigned size)
{
- struct bmm_phys_buffer *pbuf;
struct bmm_virt_buffer *vbuf;
- int ret;
void *vaddr;
- ioctl_arg_t io;
-
- if(size == 0)
- return NULL;
- if(bmm_init() < 0)
+ vaddr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset);
+ if (vaddr == (void *)-1)
return NULL;
- pbuf = malloc(sizeof(*pbuf));
vbuf = malloc(sizeof(*vbuf));
- if (!pbuf || !vbuf) {
- if (pbuf)
- free(pbuf);
- if (vbuf)
- free(vbuf);
+ if (!vbuf) {
+ munmap(vaddr, size);
return NULL;
}
- pr_debug("%s(size=%lu,attr=%x,align=%u,paddr=%p)\n",
- __FUNCTION__, size, attr, align, paddr);
-
- /* obsolete, only for back-compatible */
- if ((attr & BMM_ATTR_NONBUFFERABLE)&&(attr & BMM_ATTR_NONCACHEABLE))
- attr = BMM_ATTR_NONCACHED;
-
- if ((!(attr & BMM_ATTR_NONBUFFERABLE))&&(attr & BMM_ATTR_NONCACHEABLE))
- attr = BMM_ATTR_WRITECOMBINE;
-
- io.input = align;
- io.length = size;
- io.output = 0;
- io.arg = attr;
- ret = ioctl(bmm_fd, BMM_MALLOC_ALIGNED, &io);
- if (ret < 0 || io.output == 0)
- goto err_free_buf;
-
- pr_debug("%s return paddr = 0x%08lx\n", __FUNCTION__, io.output);
-
- vaddr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, bmm_fd, io.output);
- if ((int)vaddr == -1)
- goto err_free_bmm;
-
- if (paddr)
- *paddr = io.output;
-
- pbuf->paddr = io.output;
- pbuf->size = size;
- pbuf->attr = attr;
- pbuf->virt = vbuf;
- pbuf->attach = 1;
-
vbuf->vaddr = vaddr;
vbuf->size = size;
- vbuf->phys_offset = 0;
- vbuf->phys = pbuf;
+ vbuf->fd = fd;
pthread_mutex_lock(&bmm_mutex);
- bmm_rb_phys_insert(pbuf);
bmm_rb_virt_insert(vbuf);
pthread_mutex_unlock(&bmm_mutex);
- /*
- * If we keep bmm buffers across fork, they're reference
- * counted, so we can drop the allocation reference here.
- * This also "disowns" this buffer from this thread group.
- */
- if (API_FEAT(bmm_api) >= API_FEAT_KEEP_FORK) {
- io.input = io.output;
- io.output = 0;
- io.arg = 0;
- ioctl(bmm_fd, BMM_FREE_PHYS, &io);
- }
-
return vaddr;
-
- err_free_bmm:
- if (API_FEAT(bmm_api) >= API_FEAT_FREE_PHYS) {
- /* Modern APIs allow us to free this failed allocation */
- io.input = io.output;
- io.output = 0;
- io.arg = 0;
- ioctl(bmm_fd, BMM_FREE_PHYS, &io);
- }
-
- err_free_buf:
- free(pbuf);
- free(vbuf);
- return NULL;
}
-void *bmm_malloc_aligned(unsigned long size, int attr, unsigned align)
-{
- return bmm_malloc_aligned_phys(size, attr, align, NULL);
-}
-
-void *bmm_malloc(unsigned long size, int attr)
-{
- return bmm_malloc_aligned_phys(size, attr, sizeof(int), NULL);
-}
-
-void bmm_free(void *vaddr)
+/*
+ * bmm_dmabuf_unmap - unmap a dma_buf mapped previously with bmm_dmabuf_map
+ * @vaddr: virtual address returned from bmm_dmabuf_map()
+ */
+void bmm_dmabuf_unmap(void *vaddr)
{
- struct bmm_phys_buffer *pbuf = NULL;
struct bmm_virt_buffer *vbuf;
- ioctl_arg_t io;
-
- if (bmm_init() < 0)
- return;
pthread_mutex_lock(&bmm_mutex);
vbuf = bmm_buf_find_virt(vaddr);
- if (vbuf) {
- pbuf = vbuf->phys;
- if (pbuf->virt == vbuf)
- pbuf->virt = NULL;
+ if (vbuf)
bmm_rb_virt_remove(vbuf);
- if (--pbuf->attach == 0)
- bmm_rb_phys_remove(pbuf);
- }
pthread_mutex_unlock(&bmm_mutex);
- assert(vbuf);
- assert(pbuf);
-
- munmap(vbuf->vaddr, vbuf->size);
-
- /*
- * If we keep bmm buffers across fork, they're reference
- * counted, so we don't need to free them on the last munmap.
- */
- if (API_FEAT(bmm_api) < API_FEAT_KEEP_FORK) {
- if (API_FEAT(bmm_api) >= API_FEAT_FREE_PHYS) {
- io.input = pbuf->paddr;
- io.output = 0;
- io.arg = 0;
- ioctl(bmm_fd, BMM_FREE_PHYS, &io);
- } else {
- io.input = (unsigned long)vbuf->vaddr;
- io.output = 0;
- io.arg = 0;
- ioctl(bmm_fd, BMM_FREE, &io);
- }
+ if (vbuf) {
+ munmap(vbuf->vaddr, vbuf->size);
+ free(vbuf);
}
- if (pbuf->attach == 0)
- free(pbuf);
- free(vbuf);
}
-void *bmm_attach(unsigned long paddr, unsigned long len)
+int bmm_dmabuf_flush(int fd, void *addr, unsigned offset, unsigned size, unsigned direction)
{
- struct bmm_phys_buffer *pbuf, *new_pbuf;
struct bmm_virt_buffer *vbuf;
- void *vaddr;
-
- if(len == 0)
- return NULL;
-
- if(bmm_init() < 0)
- return NULL;
-
- /* Try to map it */
- vaddr = mmap(0, len, PROT_READ | PROT_WRITE, MAP_SHARED, bmm_fd, paddr);
- if (vaddr == (void *)-1)
- return NULL;
-
- vbuf = malloc(sizeof(*vbuf));
- new_pbuf = malloc(sizeof(*new_pbuf));
- if (!vbuf || !new_pbuf) {
- if (vbuf)
- free(vbuf);
- if (new_pbuf)
- free(new_pbuf);
- munmap(vaddr, len);
- return NULL;
- }
-
- vbuf->vaddr = vaddr;
- vbuf->size = len;
+ int ret = 0;
pthread_mutex_lock(&bmm_mutex);
- pbuf = bmm_buf_find_phys(paddr);
- if (pbuf) {
- /*
- * If we find the buffer, it means we already know about
- * this buffer. Increment the number of attachments we
- * know about for it, and insert the new virtual buffer.
- */
- pbuf->attach++;
- } else {
- /*
- * Otherwise, we're importing a new buffer which we know
- * nothing about. Create a new pbuf entry.
- */
- new_pbuf->paddr = paddr;
- new_pbuf->size = len;
- new_pbuf->attr = 0;
- new_pbuf->virt = NULL;
- new_pbuf->attach = 1;
- pbuf = new_pbuf;
-
- bmm_rb_phys_insert(new_pbuf);
- }
-
- if (!pbuf->virt)
- pbuf->virt = vbuf;
- vbuf->phys_offset = paddr - pbuf->paddr;
- vbuf->phys = pbuf;
- bmm_rb_virt_insert(vbuf);
-
+ vbuf = bmm_buf_find_virt(addr);
pthread_mutex_unlock(&bmm_mutex);
- /* If the new pbuf wasn't used, free it. */
- if (pbuf != new_pbuf)
- free(new_pbuf);
-
- return vaddr;
-}
-
-void bmm_detach(void *vaddr, unsigned long len)
-{
- struct bmm_virt_buffer *vbuf;
- struct bmm_phys_buffer *pbuf;
-
- if(bmm_init() < 0)
- return;
-
- pthread_mutex_lock(&bmm_mutex);
- vbuf = bmm_buf_find_virt(vaddr);
if (vbuf) {
- pbuf = vbuf->phys;
- assert(pbuf->attach > 0);
+ struct bmm_dmabuf_flush arg;
- if (pbuf->virt == vbuf)
- pbuf->virt = NULL;
+ if (fd != vbuf->fd) {
+ errno = EINVAL;
+ return -1;
+ }
- bmm_rb_virt_remove(vbuf);
+ arg.size = size;
+ arg.offset = offset;
+ arg.ptr = (uint64_t)(uintptr_t)addr;
+ arg.fd = vbuf->fd;
+ arg.direction = direction;
- if (--pbuf->attach == 0)
- bmm_rb_phys_remove(pbuf);
- else
- pbuf = NULL;
- } else {
- pbuf = NULL;
+ ret = ioctl(bmm_fd, BMM_DMABUF_FLUSH, &arg);
}
- pthread_mutex_unlock(&bmm_mutex);
-
- munmap(vbuf->vaddr, vbuf->size);
-
- free(vbuf);
- if (pbuf)
- free(pbuf);
-}
-
-void *bmm_get_vaddr(unsigned long paddr)
-{
- struct bmm_phys_buffer *pbuf;
- void *va = NULL;
-
- if (bmm_init() < 0)
- return 0;
-
- pthread_mutex_lock(&bmm_mutex);
- pbuf = bmm_buf_find_phys(paddr);
- if (pbuf && pbuf->virt)
- va = pbuf->virt->vaddr + (paddr - pbuf->paddr);
- pthread_mutex_unlock(&bmm_mutex);
-
- return va;
+ return ret;
}
-unsigned long bmm_get_paddr(void *vaddr)
+/**
+ * bmm_dmabuf_fd - return the dma_buf file descriptor for a mapped dma_buf
+ * @vaddr: virtual address returned from bmm_dmabuf_map()
+ *
+ * Returns the dma_buf file descriptor for the dma_buf previously mapped
+ * with bmm_dmabuf_map(), or -1 on error.
+ */
+int bmm_dmabuf_fd(void *vaddr)
{
struct bmm_virt_buffer *vbuf;
- unsigned long pa = 0;
-
- if (bmm_init() < 0)
- return 0;
+ int fd = -1;
pthread_mutex_lock(&bmm_mutex);
vbuf = bmm_buf_find_virt(vaddr);
if (vbuf)
- pa = vbuf->phys->paddr + vbuf->phys_offset +
- (vaddr - vbuf->vaddr);
+ fd = vbuf->fd;
pthread_mutex_unlock(&bmm_mutex);
- return pa;
+ return fd;
}
-int bmm_get_dmabuf_fd(void *vaddr)
-{
- int ret;
- ioctl_arg_t io;
-
- if (bmm_init() < 0 || API_FEAT(bmm_api) < API_FEAT_GET_DMABUF_FD)
- return -1;
-
- io.input = (unsigned long)vaddr;
- io.output = 0;
- io.arg = 0;
-
- ret = ioctl(bmm_fd, BMM_GET_DMABUF_FD, &io);
-
- return ret < 0 ? -1 : io.output;
-}
-
-int bmm_get_phys_dmabuf_fd(unsigned long paddr)
+/**
+ * bmm_dmabuf_free - free the dma_buf file descriptor
+ * @fd: dma_buf file descriptor returned by bmm_dmabuf_alloc()
+ *
+ * Closes the file descriptor associated with the DMA buffer. The actual
+ * DMA buffer will only be freed when all references to it are gone - in
+ * other words, after the buffer has been completely unmapped and any
+ * imported references are also released.
+ *
+ * After this call has completed, the file descriptor returned by a call
+ * to bmm_dmabuf_fd() is invalid.
+ */
+void bmm_dmabuf_free(int fd)
{
- int ret;
- ioctl_arg_t io;
-
- if (bmm_init() < 0 || API_FEAT(bmm_api) < API_FEAT_GET_DMABUF_FD)
- return -1;
-
- io.input = paddr;
- io.output = 0;
- io.arg = 0;
-
- ret = ioctl(bmm_fd, BMM_GET_PHYS_DMABUF_FD, &io);
-
- return ret < 0 ? -1 : io.output;
+ close(fd);
}
-unsigned long bmm_get_mem_size(void *vaddr)
+int bmm_init(void)
{
- struct bmm_virt_buffer *vbuf;
- unsigned long size = 0;
-
- if (bmm_init() < 0)
- return 0;
-
pthread_mutex_lock(&bmm_mutex);
- vbuf = bmm_buf_find_virt(vaddr);
- if (vbuf)
- size = vbuf->size;
- pthread_mutex_unlock(&bmm_mutex);
-
- return size;
-}
-
-int bmm_get_mem_attr(void *vaddr)
-{
- struct bmm_virt_buffer *vbuf;
- int attr = 0;
-
- if (bmm_init() < 0)
- return 0;
+ if (bmm_use++ == 0) {
+ bmm_virt_rb = make_rb();
+ if (!bmm_virt_rb)
+ goto err_rb;
- pthread_mutex_lock(&bmm_mutex);
- vbuf = bmm_buf_find_virt(vaddr);
- if (vbuf)
- attr = vbuf->phys->attr;
+ /* attempt to open the BMM driver */
+ bmm_fd = open(BMM_DEVICE_FILE, O_RDWR | O_CLOEXEC);
+ pr_debug("BMM device fd: %d\n", bmm_fd);
+ if (bmm_fd < 0)
+ goto err_open;
+ }
pthread_mutex_unlock(&bmm_mutex);
- return attr;
-}
-
-int bmm_set_mem_attr(void *vaddr, int attr)
-{
- struct bmm_virt_buffer *vbuf;
- int ret;
- ioctl_arg_t io;
-
- if(bmm_init() < 0)
- return 0;
-
- io.input = (unsigned long)vaddr;
- io.output = 0;
- io.arg = attr;
- ret = ioctl(bmm_fd, BMM_SET_MEM_ATTR, &io);
- if(ret < 0)
- return 0;
-
- attr = io.output;
+ return bmm_fd;
- pthread_mutex_lock(&bmm_mutex);
- vbuf = bmm_buf_find_virt(vaddr);
- if (vbuf)
- vbuf->phys->attr = attr;
+ err_open:
+ rb_free_tree(bmm_virt_rb);
+ bmm_virt_rb = NULL;
+ err_rb:
+ bmm_use--;
pthread_mutex_unlock(&bmm_mutex);
-
- return attr;
-}
-
-unsigned long bmm_get_total_space(void)
-{
- int ret;
- ioctl_arg_t io;
-
- if(bmm_init() < 0)
- return 0;
-
- io.input = 0;
- io.output = 0;
- io.arg = 0;
- ret = ioctl(bmm_fd, BMM_GET_TOTAL_SPACE, &io);
- if(ret < 0)
- return 0;
-
- return io.output;
-}
-
-unsigned long bmm_get_free_space(void)
-{
- int ret;
- ioctl_arg_t io;
-
- if(bmm_init() < 0)
- return 0;
-
- io.input = 0;
- io.output = 0;
- io.arg = 0;
- ret = ioctl(bmm_fd, BMM_GET_FREE_SPACE, &io);
- if(ret < 0)
- return 0;
-
- return io.output;
-}
-
-unsigned long bmm_get_allocated_space(void)
-{
- int ret;
- ioctl_arg_t io;
-
- if(bmm_init() < 0)
- return 0;
-
- io.input = 0;
- io.output = 0;
- io.arg = 0;
- ret = ioctl(bmm_fd, BMM_GET_ALLOCATED_SPACE, &io);
- if(ret < 0)
- return 0;
-
- return io.output;
+ return bmm_fd;
}
-void bmm_flush_cache(void *vaddr, int dir)
+void bmm_exit(void)
{
- ioctl_arg_t io;
-
- if(bmm_init() < 0)
- return;
-
- io.input = (unsigned long)vaddr;
- io.output = 0;
- io.arg = dir;
- ioctl(bmm_fd, BMM_FLUSH_CACHE, &io);
-}
+ pthread_mutex_lock(&bmm_mutex);
+ if (bmm_use && --bmm_use == 0) {
+ Rb_node node;
-void bmm_flush_cache_range(void *start, size_t size, int direction)
-{
- ioctl_arg_t io;
+ /* Clean up dangling buffers which the app hasn't released. */
+ rb_traverse(node, bmm_virt_rb) {
+ struct bmm_virt_buffer *vbuf = rb_val(node);
- if(bmm_init() < 0)
- return;
+ munmap(vbuf->vaddr, vbuf->size);
+ close(vbuf->fd);
+ free(vbuf);
+ }
- io.input = (unsigned long)start;
- io.length = size;
- io.output = 0;
- io.arg = direction;
- ioctl(bmm_fd, BMM_CONSISTENT_SYNC, &io);
-}
+ rb_free_tree(bmm_virt_rb);
+ bmm_virt_rb = NULL;
-void bmm_flush_user(void *start, long size, int direction)
-{
- ioctl_arg_t io;
-
- if (bmm_init() < 0)
- return;
- if (size <= 0)
- return;
-
- io.input = (unsigned long)start;
- io.length = size;
- io.output = 0;
- io.arg = direction;
- ioctl(bmm_fd, BMM_SYNC_USER, &io);
+ close(bmm_fd);
+ bmm_fd = -1;
+ }
+ pthread_mutex_unlock(&bmm_mutex);
}
-void bmm_dump(void)
+/*
+ * Destructor for this library: ensure it gets cleaned up when the
+ * library is unloaded.
+ */
+static void __attribute__((destructor)) bmm_destruct(void)
{
- ioctl_arg_t io;
-
- if(bmm_init() < 0)
- return;
-
- io.input = 0;
- io.output = 0;
- io.arg = 0;
- ioctl(bmm_fd, BMM_DUMP, &io);
+ if (bmm_use) {
+ bmm_use = 1;
+ bmm_exit();
+ }
}
-
diff --git a/bmm_lib.h b/bmm_lib.h
index 09348ef..a381f25 100644
--- a/bmm_lib.h
+++ b/bmm_lib.h
@@ -40,27 +40,13 @@ extern "C" {
int bmm_init(void);
void bmm_exit(void);
-void *bmm_malloc(unsigned long size, int attr);
-void *bmm_malloc_aligned(unsigned long size, int attr, unsigned align);
-void *bmm_malloc_aligned_phys(unsigned long size, int attr, unsigned align,
- unsigned long *paddr);
-void bmm_free(void *vaddr);
-void *bmm_attach(unsigned long paddr, unsigned long len);
-void bmm_detach(void *vaddr, unsigned long len);
-void *bmm_get_vaddr(unsigned long paddr);
-unsigned long bmm_get_paddr(void *vaddr);
-int bmm_get_dmabuf_fd(void *vaddr);
-int bmm_get_phys_dmabuf_fd(unsigned long paddr);
-int bmm_get_mem_attr(void *vaddr);
-int bmm_set_mem_attr(void *vaddr, int attr); /* Not supported yet */
-unsigned long bmm_get_mem_size(void *vaddr);
-unsigned long bmm_get_total_space(void);
-unsigned long bmm_get_free_space(void);
-unsigned long bmm_get_allocated_space(void);
-void bmm_flush_cache(void *vaddr, int dir);
-void bmm_flush_cache_range(void *start, size_t size, int direction);
-void bmm_flush_user(void *start, long size, int direction);
-void bmm_dump(void); /* for debugging */
+
+int bmm_dmabuf_alloc(unsigned long size, int attr, unsigned align);
+void *bmm_dmabuf_map(int fd, unsigned offset, unsigned size);
+void bmm_dmabuf_unmap(void *addr);
+int bmm_dmabuf_flush(int fd, void *addr, unsigned offset, unsigned size, unsigned direction);
+int bmm_dmabuf_fd(void *addr);
+void bmm_dmabuf_free(int fd);
#if defined (__cplusplus)
}
diff --git a/bmm_lib.pmem.c b/bmm_lib.pmem.c
deleted file mode 100644
index cb74a11..0000000
--- a/bmm_lib.pmem.c
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * bmm_lib.c
- *
- * Buffer Management Module for vMeta
- *
- * based on Android PMEM
- *
- * Steve Guo (steve.guo@marvell.com)
-
- *(C) Copyright 2007 Marvell International Ltd.
- * All Rights Reserved
- */
-
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <linux/android_pmem.h>
-#include <stdio.h>
-#include <stdlib.h>
-#define LOG_TAG "bmm-lib"
-#include <utils/Log.h>
-
-#include "bmm_lib.h"
-
-//#define DEBUG
-
-#ifdef DEBUG
- #define pr_debug(fmt, arg...) LOGD(fmt, ##arg)
-#else
- #define pr_debug(fmt, arg...) do { } while(0)
-#endif
-
-#define pr_error(fmt, arg...) LOGE(fmt, ##arg)
-#define NO_IMPLEMENTED LOGE("%s is not implemented yet.", __FUNCTION__)
-
-#define PMEM_DEVICE_FILE "/dev/pmem_adsp"
-
-
-/* We recorded all malloced physical address into a list. Due to the implementation of
-pmem, we can only open a new file to malloc some memory and close it to free memory. So
-we also record the opened fd associated with physical and virtual address map. */
-struct memory_item
-{
- int fd;
- void *paddr;
- void *vaddr;
- int size;
- struct memory_item *next;
-};
-
-static struct memory_item *header = NULL;
-
-int bmm_init()
-{
- pr_debug("bmm_init");
- header = NULL;
- return 0;
-}
-
-void bmm_exit()
-{
- struct memory_item *cur = header;
- struct memory_item *next = NULL;
- pr_debug("bmm_exit");
- while(cur != NULL)
- {
- next = cur->next;
- munmap(cur->vaddr, cur->size);
- close(cur->fd);
- free(cur);
- cur = next;
- }
-}
-
-void *bmm_malloc(unsigned long size, int attr)
-{
- void *vaddr;
- int pmem_fd = 0;
- struct memory_item *item = NULL;
- struct pmem_region region;
- int ret;
-
- if(size == 0)
- return NULL;
-
- pr_debug("bmm_malloc %d", size);
-
- /* attempt to open the PMEM driver */
- pmem_fd = open(PMEM_DEVICE_FILE, O_RDWR);
- if(pmem_fd <=0)
- {
- pr_error("cannot open %s file", PMEM_DEVICE_FILE);
- return NULL;
- }
-
- vaddr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, pmem_fd, 0);
- if((int)vaddr == -1)
- {
- pr_error("mmap %d failed, most likely no memory", size);
- close(pmem_fd);
- return NULL;
- }
-
- ret = ioctl(pmem_fd, PMEM_GET_PHYS, &region);
- if(ret != 0)
- {
- pr_error("call PMEM_GET_PHYS failed");
- munmap(vaddr, size);
- close(pmem_fd);
- return NULL;
- }
-
- item = (struct memory_item*)malloc(sizeof(struct memory_item));
- memset(item, 0 , sizeof(struct memory_item));
- item->fd = pmem_fd;
- item->paddr = (void*)region.offset;
- item->vaddr = vaddr;
- item->size = size;
-
- if(header == NULL)
- {
- header = item;
- }
- else
- {
- item->next = header;
- header = item;
- }
- return vaddr;
-}
-
-void bmm_free(void *vaddr)
-{
- pr_debug("bmm_free");
- struct memory_item *cur = header;
- struct memory_item *prev = NULL;
- struct memory_item *next = NULL;
- while(cur != NULL)
- {
- next = cur->next;
- if(cur->vaddr == vaddr)
- {
- munmap(cur->vaddr, cur->size);
- close(cur->fd);
- if(prev == NULL)
- {
- header = next;
- }
- else
- {
- prev->next = next;
- }
- free(cur);
- return;
- }
- prev = cur;
- cur = next;
- }
-}
-
-void *bmm_attach(void *paddr, unsigned long len)
-{
- NO_IMPLEMENTED;
- return NULL;
-}
-
-void bmm_detach(void *vaddr, unsigned long len)
-{
- NO_IMPLEMENTED;
-}
-
-void *bmm_get_vaddr(void *paddr)
-{
- pr_debug("bmm_get_vaddr");
- struct memory_item *cur = header;
- while(cur != NULL)
- {
- if(cur->paddr == paddr)
- return cur->vaddr;
- cur = cur->next;
- }
- return NULL;
-}
-
-void *bmm_get_paddr(void *vaddr)
-{
- pr_debug("bmm_get_paddr");
- struct memory_item *cur = header;
- while(cur != NULL)
- {
- if(cur->vaddr == vaddr)
- return cur->paddr;
- cur = cur->next;
- }
- return NULL;
-}
-
-unsigned long bmm_get_mem_size(void *vaddr)
-{
- struct memory_item *cur = header;
- while(cur != NULL)
- {
- if(cur->vaddr == vaddr)
- return cur->size;
- cur = cur->next;
- }
- return 0;
-}
-
-int bmm_get_mem_attr(void *vaddr)
-{
- NO_IMPLEMENTED;
- return 0;
-}
-
-int bmm_set_mem_attr(void *vaddr, int attr)
-{
- NO_IMPLEMENTED;
- return 0;
-}
-
-unsigned long bmm_get_total_space()
-{
- int pmem_fd = 0;
- struct pmem_region region;
- int ret;
-
- /* attempt to open the PMEM driver */
- pmem_fd = open(PMEM_DEVICE_FILE, O_RDWR);
- if(pmem_fd <=0)
- {
- pr_error("cannot open %s file", PMEM_DEVICE_FILE);
- return 0;
- }
-
- ret = ioctl(pmem_fd, PMEM_GET_TOTAL_SIZE, &region);
- if(ret != 0)
- {
- pr_error("call PMEM_GET_TOTAL_SIZE failed");
- close(pmem_fd);
- return 0;
- }
- close(pmem_fd);
- return region.len;
-}
-
-unsigned long bmm_get_free_space()
-{
- NO_IMPLEMENTED;
- return 0;
-}
-
-unsigned long bmm_get_allocated_space()
-{
- NO_IMPLEMENTED;
- return 0;
-}
-
-void bmm_flush_cache(void *vaddr, int dir)
-{
- NO_IMPLEMENTED;
-}
-
-void *bmm_dma_memcpy(void *dest, const void *src, size_t n)
-{
- NO_IMPLEMENTED;
- return NULL;
-}
-
-void bmm_dma_sync()
-{
- NO_IMPLEMENTED;
-}
-
-void bmm_flush_cache_range(void *start, size_t size, int direction)
-{
- NO_IMPLEMENTED;
-}
-
-void bmm_dump()
-{
- NO_IMPLEMENTED;
-}
-
diff --git a/bmm_lib_priv.h b/bmm_lib_priv.h
deleted file mode 100644
index 42d4e64..0000000
--- a/bmm_lib_priv.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * bmm_lib_priv.h
- *
- * Buffer Management Module
- *
- * User level BMM Defines/Globals/Functions
- *
- * Li Li (lea.li@marvell.com)
-
- *(C) Copyright 2007 Marvell International Ltd.
- * All Rights Reserved
- */
-
-#ifndef __BMM_LIB_PRIV_H__
-#define __BMM_LIB_PRIV_H__
-
-#define BMM_MINOR (94)
-
-typedef struct {
- unsigned long input; /* the starting address of the block of memory */
- unsigned long output; /* the starting address of the block of memory */
- unsigned long length; /* the length of the block of memory */
- unsigned long arg; /* the arg of cmd */
-} ioctl_arg_t;
-
-#define BMEM_IOCTL_MAGIC 'G'
-/* ioctl commands */
-#define BMM_MALLOC _IOWR(BMEM_IOCTL_MAGIC, 0, ioctl_arg_t)
-#define BMM_FREE _IOWR(BMEM_IOCTL_MAGIC, 1, ioctl_arg_t)
-#define BMM_GET_VIRT_ADDR _IOWR(BMEM_IOCTL_MAGIC, 2, ioctl_arg_t)
-#define BMM_GET_PHYS_ADDR _IOWR(BMEM_IOCTL_MAGIC, 3, ioctl_arg_t)
-#define BMM_GET_MEM_ATTR _IOWR(BMEM_IOCTL_MAGIC, 4, ioctl_arg_t)
-#define BMM_SET_MEM_ATTR _IOWR(BMEM_IOCTL_MAGIC, 5, ioctl_arg_t)
-#define BMM_GET_MEM_SIZE _IOWR(BMEM_IOCTL_MAGIC, 6, ioctl_arg_t)
-#define BMM_GET_TOTAL_SPACE _IOWR(BMEM_IOCTL_MAGIC, 7, ioctl_arg_t)
-#define BMM_GET_FREE_SPACE _IOWR(BMEM_IOCTL_MAGIC, 8, ioctl_arg_t)
-#define BMM_FLUSH_CACHE _IOWR(BMEM_IOCTL_MAGIC, 9, ioctl_arg_t)
-#define BMM_CONSISTENT_SYNC _IOWR(BMEM_IOCTL_MAGIC, 12, ioctl_arg_t)
-#define BMM_DUMP _IOWR(BMEM_IOCTL_MAGIC, 13, ioctl_arg_t)
-#define BMM_GET_ALLOCATED_SPACE _IOWR(BMEM_IOCTL_MAGIC, 14, ioctl_arg_t)
-#define BMM_GET_KERN_PHYS_ADDR _IOWR(BMEM_IOCTL_MAGIC, 15, ioctl_arg_t)
-#define BMM_SYNC_USER _IOWR(BMEM_IOCTL_MAGIC, 16, ioctl_arg_t)
-#define BMM_MALLOC_ALIGNED _IOWR(BMEM_IOCTL_MAGIC, 17, ioctl_arg_t)
-#define BMM_API_VERSION _IOWR(BMEM_IOCTL_MAGIC, 18, ioctl_arg_t)
-#define BMM_GET_DMABUF_FD _IOWR(BMEM_IOCTL_MAGIC, 19, ioctl_arg_t)
-#define BMM_FREE_PHYS _IOWR(BMEM_IOCTL_MAGIC, 20, ioctl_arg_t)
-#define BMM_GET_PHYS_DMABUF_FD _IOWR(BMEM_IOCTL_MAGIC, 21, ioctl_arg_t)
-
-#define BMM_DEVICE_FILE "/dev/bmm"
-
-#endif /* __BMM_LIB_PRIV_H__ */
diff --git a/bmm_test.c b/bmm_test.c
deleted file mode 100644
index ceadf9c..0000000
--- a/bmm_test.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * bmm_test.c
- *
- * Buffer Management Module
- *
- * User test application
- *
- * Li Li (lea.li@marvell.com)
-
- *(C) Copyright 2007 Marvell International Ltd.
- * All Rights Reserved
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <unistd.h>
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include "bmm_lib.h"
-
-static int debug = 0;
-
-int test_count = 0;
-int pass_count = 0;
-int fail_count = 0;
-
-#define PRINT_TEST_NAME printf("Testing %d: %s()\n", test_count++, __FUNCTION__)
-#define PRINT_TEST_RESULT(x) \
- do { \
- if(!x) \
- pass_count++, printf("\tPassed.\n"); \
- else \
- fail_count++, printf("\tFailed.\n"); \
- } while(0)
-#define PRINT_TEST_RESULTS() printf("Passed/Failed = %d/%d\n", pass_count, fail_count)
-
-static int test_bmm_init(void)
-{
- int ret;
-
- PRINT_TEST_NAME;
-
- ret = bmm_init();
- printf("\tbmm_init() return %d\n", ret);
-
- return (ret <= 0);
-}
-
-static int test_bmm_get_space(void)
-{
- unsigned long total_size;
- unsigned long free_size;
-
- PRINT_TEST_NAME;
-
- total_size = bmm_get_total_space();
- free_size = bmm_get_free_space();
-
- printf("\tbmm_get_total_space() return %ldKB\n", total_size/1024);
- printf("\tbmm_get_free_space() return %ldKB\n", free_size/1024);
-
- return (total_size <= 0 || total_size != free_size);
-}
-
-static int test_bmm_malloc(unsigned long size, int attr)
-{
- void *vaddr;
- unsigned long allocated_size1, free_size1;
- unsigned long allocated_size2, free_size2;
- unsigned long allocated_size3, free_size3;
- int off = 0;
- PRINT_TEST_NAME;
-
- allocated_size1 = bmm_get_allocated_space();
- free_size1 = bmm_get_free_space();
- vaddr = bmm_malloc(size, attr);
- if(vaddr == NULL) {
- printf("\tno enough memory\n");
- return -1;
- }
- for(off = 0; off < size; off += 1024*1024){
- unsigned long get_paddr = bmm_get_paddr(vaddr+off);
- void *get_vaddr = bmm_get_vaddr(get_paddr);
- int get_attr = bmm_get_mem_attr(get_vaddr);
- printf("\toff = 0x%x, vaddr=0x%p, get_vaddr=0x%p, get_paddr=0x%08lx\n", off, vaddr+off, get_vaddr, get_paddr);
- printf("\tset_attr=0x%x, get_attr=0x%x\n", attr, get_attr);
- if(vaddr+off != get_vaddr)
- return -1;
- }
-
- allocated_size2 = bmm_get_allocated_space();
- free_size2 = bmm_get_free_space();
- bmm_free(vaddr);
- allocated_size3 = bmm_get_allocated_space();
- free_size3 = bmm_get_free_space();
-
- printf("\tbmm_malloc(%ldKB) return 0x%08lx\n", size/1024, (unsigned long)vaddr);
- printf("\tbmm_get_allocated_space() return %ldKB %ldKB %ldKB\n",
- allocated_size1/1024, allocated_size2/1024, allocated_size3/1024);
- printf("\tbmm_get_free_space() return %ldKB %ldKB %ldKB\n",
- free_size1/1024, free_size2/1024, free_size3/1024);
-
- return (
- allocated_size2 - allocated_size1 != size ||
- allocated_size1 != allocated_size3 ||
- free_size1 - free_size2 != size ||
- free_size1 != free_size3);
-}
-
-static long gettickcount(void)
-{
- struct timeval g_tv;
- struct timezone g_tz;
-
- gettimeofday(&g_tv, &g_tz);
-
- return g_tv.tv_sec * 1000000 + g_tv.tv_usec;
-}
-
-static int test_bmm_flush_user(unsigned long size)
-{
- char *src;
- long t1 = 0, t2 = 0;
-
- PRINT_TEST_NAME;
-
- src = malloc(size);
- if (src == NULL) {
- printf("\tno enough memory\n");
- return -1;
- }
- t1 = gettickcount();
- bmm_flush_user(src, size, BMM_DMA_TO_DEVICE);
- t2 = gettickcount();
- printf("bmm_flush_user 0x%lx memory cost %ldusec\n", size, t2-t1);
- free(src);
-
- src = bmm_malloc(size, BMM_ATTR_DEFAULT);
- if (src == NULL) {
- printf("\tno enough memory\n");
- return -1;
- }
- t1 = gettickcount();
- bmm_flush_cache_range(src, size, BMM_DMA_TO_DEVICE);
- t2 = gettickcount();
- printf("bmm_flush_cache_range 0x%lx memory cost %ldusec\n", size, t2-t1);
- bmm_free(src);
-
- return 0;
-}
-
-static int test_bmm_share(unsigned long size)
-{
- char *src;
- char *dst;
- unsigned long psrc;
- unsigned long pdst;
- unsigned long i;
- unsigned long off, len;
- unsigned long free_size1;
- unsigned long free_size2;
- unsigned long free_size3;
- int ret = 0;
- int pid = 0;
- int pid1 = 0;
- int pid2 = 0;
- int ret1 = 0;
- int ret2 = 0;
-
- PRINT_TEST_NAME;
-
- free_size1 = bmm_get_free_space();
- src = bmm_malloc(size, BMM_ATTR_DEFAULT);
- memset(src, 0, size);
- free_size2 = bmm_get_free_space();
- if(src == NULL) {
- printf("\tno enough memory\n");
- return -1;
- }
- psrc = bmm_get_paddr(src);
- printf("\tFork 3 sub processes...\n");
- pid1 = fork();
- if(pid1 != 0) {
- pid2 = fork();
- if(pid2 != 0) {
- off = 0;
- len = size;
- dst = bmm_attach(psrc + off, len);
- for(i=0; i<size; i++)
- src[i] = i;
- bmm_flush_cache(src, BMM_DMA_TO_DEVICE);
- sleep(1);
- kill(0, SIGCONT);
- waitpid(pid2, &ret2, 0);
- waitpid(pid1, &ret1, 0);
- ret2 = WEXITSTATUS(ret2) ? -1 : 0;
- ret1 = WEXITSTATUS(ret1) ? -1 : 0;
- pid = 0;
- } else {
- raise(SIGSTOP);
- off = 4096;
- len = 4096;
- dst = bmm_attach(psrc + off, len);
- pid = 1;
- }
- } else {
- pid2 = fork();
- if(pid2 != 0) {
- raise(SIGSTOP);
- off = size / 4;
- len = size / 2;
- dst = bmm_attach(psrc + off, len);
- waitpid(pid2, &ret2, 0);
- ret2 = WEXITSTATUS(ret2) ? -1 : 0;
- pid = 2;
- } else {
- raise(SIGSTOP);
- off = size - 4096;
- len = 4096;
- dst = bmm_attach(psrc + off, len);
- pid = 3;
- }
- }
-
- pdst = bmm_get_paddr(dst);
- if(pdst == psrc + off)
- printf("\t[%d] pdst(0x%08lx) == psrc(0x%08lx) + off(%lx)\n", pid, pdst, psrc, off);
- else
- printf("\t[%d] Error: pdst(0x%08lx) != psrc(0x%08lx) + off(%lx)\n", pid, pdst, psrc, off);
-
- bmm_flush_cache(dst, BMM_DMA_FROM_DEVICE);
- for(i=0; i<len; i++) {
- if(dst[i] != (char)(off+i)) {
- ret--;
- if(debug)
- printf("\t[%d] [%ld+%ld]: %d != %d\n", pid, off, i, dst[i], (char)(off+i));
- else
- break;
- }
- }
-
- bmm_detach(dst, len);
-
- printf("\t[%d] bmm_share(%ldKB/%ld-%ld) = %d\n", pid, size/1024, off, len, ret);
-
- if(pid1 == 0 || pid2 == 0)
- exit(ret);
-
- bmm_free(src);
- free_size3 = bmm_get_free_space();
-
- printf("\t[%d] bmm_get_free_space() return %ldKB %ldKB %ldKB\n",
- pid, free_size1/1024, free_size2/1024, free_size3/1024);
-
- if(ret || ret1 || ret2)
- return ret + ret1 + ret2;
-
- printf("\tShare content OK. Checking free space...\n");
-
- return (free_size1 - free_size2 != size || free_size1 != free_size3);
-}
-
-int main(int argc, char * argv[])
-{
- int ret;
- unsigned long i, n;
- pid_t pid = getpid();
-
- if(argc > 1) {
- debug = 1;
- if(!strcmp(argv[1], "dump")) {
- ret = test_bmm_get_space();
- PRINT_TEST_RESULT(ret);
- bmm_dump();
- return 0;
- }
- }
-
- printf("%s running with pid=%d/%x\n", argv[0], pid, pid);
-
- if(debug)
- bmm_dump();
-
- ret = test_bmm_init();
- PRINT_TEST_RESULT(ret);
-
- ret = test_bmm_get_space();
- PRINT_TEST_RESULT(ret);
-
- n = 8;
- for(i=1; i<=n; i++) {
- ret = test_bmm_malloc(i*1024*1024, BMM_ATTR_DEFAULT);
- PRINT_TEST_RESULT(ret);
- }
- for(i=n; i>=1; i--) {
- ret = test_bmm_malloc(i*1024*1024, BMM_ATTR_NONCACHED);
- PRINT_TEST_RESULT(ret);
- }
-
- n = 8;
- for(i=1; i<=n; i++) {
- ret = test_bmm_share(i*1024*1024);
- PRINT_TEST_RESULT(ret);
- }
-
- n = 1;
- ret = test_bmm_flush_user(n*1024*1024);
- PRINT_TEST_RESULT(ret);
- PRINT_TEST_RESULTS();
-
- if(debug)
- bmm_dump();
-
- bmm_exit();
-
- if(debug)
- bmm_dump();
-
- return 0;
-}
-
diff --git a/configure.ac b/configure.ac
index 68200e6..5c3317b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,14 +1,14 @@
AC_PREREQ([2.63])
-AC_INIT([libbmm], [1.1.0], [], [libbmm])
+AC_INIT([libbmm], [2.0.0], [], [libbmm])
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([1.10 foreign dist-bzip2])
AM_MAINTAINER_MODE([enable])
-ABI_VERSION=2
+ABI_VERSION=3
ABI_REVISION=0
-ABI_AGE=1
+ABI_AGE=0
AC_SUBST(ABI_VERSION)
AC_SUBST(ABI_REVISION)
AC_SUBST(ABI_AGE)
diff --git a/debian/changelog b/debian/changelog
index ad0235c..bd83008 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+libbmm (2.0.0) precise; urgency=low
+
+ * Major update, now using purely dma_buf as a management system for
+ buffers.
+
+ -- Russell King <rmk@arm.linux.org.uk> Sat, 7 Dec 2013 15:01:15 +0000
+
marvell-libbmm (1.1.3) precise; urgency=low
* Fix dma_import() handling of offset buffers
diff --git a/debian/control b/debian/control
index de0a4bf..f375bbd 100644
--- a/debian/control
+++ b/debian/control
@@ -1,11 +1,10 @@
-Source: marvell-libbmm
+Source: libbmm
Priority: extra
-Maintainer: Michael Casadevall <mcasadevall@ubuntu.com>
+Maintainer: Russell King <rmk@arm.linux.org.uk>
XSBC-Original-Maintainer: Li Li <lea.li@marvell.com>
Build-Depends: debhelper (>= 7)
Standards-Version: 3.9.1
Section: libs
-Vcs-Bzr: https://code.launchpad.net/~adana-team/adana/marvell-libbmm
Package: libbmm-common
Section: libs
@@ -16,25 +15,23 @@ Description: Block/buffer memory management
Package: libbmm-dev
Section: libdevel
Architecture: armel armhf
-Depends: libbmm1 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
+Depends: libbmm2 (= ${binary:Version}), ${misc:Depends}
Description: Block/buffer memory management
Header files, static library and unit test case for BMM
-Package: libbmm1
+Package: libbmm2
Section: libs
Architecture: armel armhf
Depends: libbmm-common, ${shlibs:Depends}, ${misc:Depends}
Description: Block/buffer memory management
Allocate, manage and share large block of physical continuous memory
-Package: libbmm1-dbg
+Package: libbmm2-dbg
Section: debug
Priority: extra
Architecture: linux-any
-Depends:
- libbmm1 (= ${binary:Version}),
- ${misc:Depends},
+Depends: libbmm2 (= ${binary:Version}), ${misc:Depends},
Multi-Arch: same
Description: Block/buffer memory management
.
- This package provides debugging symbols for the libbmm0u package.
+ This package provides debugging symbols for the libbmm2 package.
diff --git a/debian/libbmm-dev.install b/debian/libbmm-dev.install
index 57bfa73..e5091ec 100644
--- a/debian/libbmm-dev.install
+++ b/debian/libbmm-dev.install
@@ -2,4 +2,3 @@ debian/tmp/usr/include/*.h
debian/tmp/usr/lib/*.a
debian/tmp/usr/lib/*.so
debian/tmp/usr/lib/pkgconfig/*.pc
-debian/tmp/usr/bin/bmm_test
diff --git a/debian/libbmm1.install b/debian/libbmm2.install
index 79bbe2f..79bbe2f 100644
--- a/debian/libbmm1.install
+++ b/debian/libbmm2.install
diff --git a/debian/rules b/debian/rules
index ced92e5..b0098b2 100755
--- a/debian/rules
+++ b/debian/rules
@@ -8,6 +8,7 @@
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
+LIBBMM=libbmm2
override_dh_auto_install:
dh_auto_install --destdir=debian/tmp
@@ -17,7 +18,7 @@ override_dh_install:
dh_install --fail-missing
override_dh_strip:
- dh_strip -plibbmm1 --dbg-package=libbmm1-dbg
+ dh_strip -p$(LIBBMM) --dbg-package=$(LIBBMM)-dbg
dh_strip -s --remaining-packages
%: