summaryrefslogtreecommitdiff
path: root/bmm_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'bmm_test.c')
-rw-r--r--bmm_test.c462
1 files changed, 462 insertions, 0 deletions
diff --git a/bmm_test.c b/bmm_test.c
new file mode 100644
index 0000000..27b2dd1
--- /dev/null
+++ b/bmm_test.c
@@ -0,0 +1,462 @@
+/*
+ * 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)
+
+int test_bmm_init()
+{
+ int ret;
+
+ PRINT_TEST_NAME;
+
+ ret = bmm_init();
+ printf("\tbmm_init() return %d\n", ret);
+
+ return (ret <= 0);
+}
+
+int test_bmm_get_space()
+{
+ 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);
+}
+
+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){
+ void *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%p\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 ((int)vaddr <= 0 ||
+ allocated_size2 - allocated_size1 != size ||
+ allocated_size1 != allocated_size3 ||
+ free_size1 - free_size2 != size ||
+ free_size1 != free_size3);
+}
+
+int test_bmm_dma_memcpy(unsigned long size)
+{
+ char *src;
+ char *dst;
+ unsigned long i;
+ unsigned long free_size1;
+ unsigned long free_size2;
+ unsigned long free_size3;
+ int ret = 0;
+
+ PRINT_TEST_NAME;
+
+ free_size1 = bmm_get_free_space();
+ src = bmm_malloc(size, BMM_ATTR_DEFAULT);
+ dst = bmm_malloc(size, BMM_ATTR_DEFAULT);
+ memset(src, 0, size);
+ memset(dst, 0, size);
+ free_size2 = bmm_get_free_space();
+ if(src == NULL) {
+ printf("\tno enough memory\n");
+ return -1;
+ }
+ if(dst == NULL) {
+ printf("\tno enough memory\n");
+ bmm_free(src);
+ return -2;
+ }
+ for(i=0; i<size; i++)
+ src[i] = dst[size-i-1] = i;
+ bmm_flush_cache(src, BMM_DMA_TO_DEVICE);
+ bmm_flush_cache(dst, BMM_DMA_TO_DEVICE);
+ bmm_dma_memcpy(dst, src, size);
+ bmm_dma_sync();
+ bmm_flush_cache(dst, BMM_DMA_FROM_DEVICE);
+ for(i=0; i<size; i++) {
+ if(src[i] != dst[i]) {
+ ret--;
+ if(debug)
+ printf("\t[%ld]: %d != %d\n", i, src[i], dst[i]);
+ else
+ break;
+ }
+ }
+
+ bmm_free(src);
+ bmm_free(dst);
+ free_size3 = bmm_get_free_space();
+
+ printf("\tbmm_dma_memcpy(%ld/%ld) = %d\n", size, i, ret);
+ printf("\tbmm_get_free_space() return %ldKB %ldKB %ldKB\n",
+ free_size1/1024, free_size2/1024, free_size3/1024);
+
+ if(ret)
+ return ret;
+
+ return (free_size1 - free_size2 != size << 1 || free_size1 != free_size3);
+}
+
+int test_bmm_dma_memcpy_range(unsigned long size)
+{
+ char *src;
+ char *dst;
+ unsigned long i, offset;
+ unsigned long free_size1;
+ unsigned long free_size2;
+ unsigned long free_size3;
+ int ret = 0;
+
+ PRINT_TEST_NAME;
+
+ free_size1 = bmm_get_free_space();
+ src = bmm_malloc(size, BMM_ATTR_DEFAULT);
+ dst = bmm_malloc(size, BMM_ATTR_DEFAULT);
+ memset(src, 0, size);
+ memset(dst, 0, size);
+ free_size2 = bmm_get_free_space();
+ if(src == NULL) {
+ printf("\tno enough memory\n");
+ return -1;
+ }
+ if(dst == NULL) {
+ printf("\tno enough memory\n");
+ bmm_free(src);
+ return -2;
+ }
+ for(i=0; i<size; i++)
+ src[i] = dst[size-i-1] = i;
+ for(offset=0; offset+size/2<size && offset<8096; offset+=128) {
+ bmm_flush_cache_range(src+offset, size/2, BMM_DMA_TO_DEVICE);
+ bmm_flush_cache_range(dst+offset, size/2, BMM_DMA_TO_DEVICE);
+ bmm_dma_memcpy(dst+offset, src+offset, size/2);
+ bmm_dma_sync();
+ bmm_flush_cache_range(dst+offset, size/2, BMM_DMA_FROM_DEVICE);
+ for(i=offset; i<size/2; i++) {
+ if(src[i] != dst[i]) {
+ ret--;
+ if(debug)
+ printf("\t[%ld]: %d != %d\n", i, src[i], dst[i]);
+ else
+ break;
+ }
+ }
+ }
+
+ bmm_free(src);
+ bmm_free(dst);
+ free_size3 = bmm_get_free_space();
+
+ printf("\tbmm_dma_memcpy(%ld/%ld) = %d\n", size, i, ret);
+ printf("\tbmm_get_free_space() return %ldKB %ldKB %ldKB\n",
+ free_size1/1024, free_size2/1024, free_size3/1024);
+
+ if(ret)
+ return ret;
+
+ return (free_size1 - free_size2 != size << 1 || free_size1 != free_size3);
+}
+
+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;
+}
+
+int test_bmm_flush_user(long size)
+{
+ char *src;
+ unsigned long offset;
+ 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%x memory cost %dusec\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%x memory cost %dusec\n", size, t2-t1);
+ bmm_free(src);
+
+ return 0;
+}
+
+int test_bmm_share(unsigned long size)
+{
+ char *src;
+ char *dst;
+ char *psrc;
+ char *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(%p) == psrc(%p) + off(%lx)\n", pid, pdst, psrc, off);
+ else
+ printf("\t[%d] Error: pdst(%p) != psrc(%p) + 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);
+ }
+
+#if 0
+ n = 128;
+ for(i=1; i<=n; i++) {
+ ret = test_bmm_dma_memcpy(i*4096);
+ PRINT_TEST_RESULT(ret);
+ }
+
+ n = 4;
+ for(i=1; i<=n; i++) {
+ ret = test_bmm_dma_memcpy(i*1024*1024);
+ PRINT_TEST_RESULT(ret);
+ }
+
+ n = 128;
+ for(i=1; i<=n; i++) {
+ ret = test_bmm_dma_memcpy_range(i*4096);
+ PRINT_TEST_RESULT(ret);
+ }
+#endif
+ 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;
+}
+