[meego-commits] 5427: Changes to Trunk:Testing/dsp-tools
Felipe Contreras
felipe.contreras at nokia.com
Thu Jul 8 18:04:37 UTC 2010
Hi,
I have made the following changes to dsp-tools in project Trunk:Testing. Please review and accept ASAP.
Thank You,
Felipe Contreras
[This message was auto-generated]
---
Request #5427:
submit: home:fcontrer/dsp-tools(r6) -> Trunk:Testing/dsp-tools
Message:
Hi,
Updated to a newer version. I didn't tag 1.2.0 as I was hoping, so I'm using a
git version (57 patches on top of laster release).
Also, I applied reivew comments:
- remove BuildRoot
- add ExclusiveArch
I left the disttag because I want this spec to be distro-agnostic. OBS is
overriding the Version field anyway so there's no conflict.
State: new 2010-07-08T06:00:07 fcontrer
Comment: None
old:
----
0001-build-remove-dsp-manager.patch
dsp-tools-1.2.0.tar.gz
new:
----
dsp-tools-1.1.0.g57.tar.gz
spec files:
-----------
--- dsp-tools.spec
+++ dsp-tools.spec
@@ -1,5 +1,5 @@
Name: dsp-tools
-Version: 1.2.0
+Version: 1.1.0.g57
Release: 1%{?dist}
Summary: Miscellaneous utilities for TI's C64x+ DSP
@@ -7,8 +7,8 @@
License: LGPLv2
URL: http://meego.gitorious.org/maemo-multimedia/dsp-tools
Source0: %{name}-%{version}.tar.gz
-Patch1: 0001-build-remove-dsp-manager.patch
-BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
+
+ExclusiveArch: %{arm}
%description
A bunch of tools useful for debugging/testing TI's C64x+ DSP.
@@ -16,7 +16,6 @@
%prep
%setup -q
-%patch1 -p1
%build
@@ -36,9 +35,10 @@
%defattr(-,root,root,-)
%{_bindir}/dsp-load
%{_bindir}/dsp-probe
-%{_bindir}/dsp-ping
+%{_bindir}/dsp-test
+%{_bindir}/dsp-exec
%changelog
-* Fri May 07 2010 Felipe Contreras <felipe.contreras at gmail.com> - 1.1.0-1
+* Thu Jul 08 2010 Felipe Contreras <felipe.contreras at nokia.com> - 1.1.0.g57-1
- Inital packaging
other changes:
--------------
++++++ dsp-tools-1.2.0.tar.gz -> dsp-tools-1.1.0.g57.tar.gz
--- .gitignore
+++ .gitignore
@@ -1,5 +1,4 @@
-*.o
-dsp-manager
+*.[od]
dsp-load
dsp-probe
-dsp-ping
+dsp-test
--- .version
+++ .version
@@ -1 +1 @@
-1.2.0
+1.1.0.g57
--- Makefile
+++ Makefile
@@ -1,31 +1,33 @@
CROSS_COMPILE ?= arm-linux-
CC := $(CROSS_COMPILE)gcc
-CFLAGS := -O2 -Wall -Wextra -Wno-unused-parameter
+CFLAGS := -O2 -Wall -Wextra -Wno-unused-parameter -std=c99
override CFLAGS += -D_GNU_SOURCE
-ifdef NEW
- override CFLAGS += -DNEW_API
+DSP_API := 1
+
+override CFLAGS += -DDSP_API=$(DSP_API)
+
+ifdef DEBUG
+ override CFLAGS += -DDEBUG
endif
version := $(shell ./get-version)
all:
-# dsp-manager
-
-dsp-manager: dsp_manager.o dsp_bridge.o log.o
-bins += dsp-manager
-
dsp-load: dsp_load.o dsp_bridge.o
bins += dsp-load
dsp-probe: dsp_probe.o dsp_bridge.o log.o
bins += dsp-probe
-dsp-ping: dsp_ping.o dsp_bridge.o log.o
-bins += dsp-ping
+dsp-test: dsp_test.o dsp_bridge.o log.o
+bins += dsp-test
+
+dsp-exec: dsp_exec.o dsp_bridge.o log.o
+bins += dsp-exec
all: $(bins)
@@ -39,20 +41,19 @@
endif
%.o:: %.c
- $(QUIET_CC)$(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $<
+ $(QUIET_CC)$(CC) $(CFLAGS) $(INCLUDES) -MMD -o $@ -c $<
$(bins):
$(QUIET_LINK)$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
clean:
- $(QUIET_CLEAN)$(RM) $(bins) *.o
+ $(QUIET_CLEAN)$(RM) $(bins) *.o *.d
install: $(bins)
- install -m 755 dsp-manager -D $(D)/usr/sbin/dsp-manager
- install -m 755 scripts/dsp-recover -D $(D)/usr/libexec/dsp-recover
install -m 755 dsp-load -D $(D)/usr/bin/dsp-load
install -m 755 dsp-probe -D $(D)/usr/bin/dsp-probe
- install -m 755 dsp-ping -D $(D)/usr/bin/dsp-ping
+ install -m 755 dsp-test -D $(D)/usr/bin/dsp-test
+ install -m 755 dsp-exec -D $(D)/usr/bin/dsp-exec
dist: base := dsp-tools-$(version)
dist:
@@ -63,3 +64,5 @@
tar --append -f /tmp/$(base).tar --owner root --group root $(base)/.version
rm -r $(base)
gzip /tmp/$(base).tar
+
+-include *.d
--- README
+++ README
+= dsp-tools =
+
+Miscellaneous utilities for TI's C64x+ DSP.
+
+ * dsp-test: runs simple trivial tests
+ * dsp-load: prints the DSP CPU load and frequency
+ * dsp-probe: checks running tasks
+
+== building ==
+
+There are no dependencies, so just type 'make'. If you are using an old version
+of TI's dspbrdige driver, do 'make OLD=y'.
--- dmm_buffer.h
+++ dmm_buffer.h
+/*
+ * Copyright (C) 2009-2010 Felipe Contreras
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Authors:
+ * Felipe Contreras <felipe.contreras at nokia.com>
+ * Marco Ballesio <marco.ballesio at nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef DMM_BUFFER_H
+#define DMM_BUFFER_H
+
+#include <stdlib.h> /* for calloc, free */
+#include <unistd.h> /* for getpagesize */
+
+#include "dsp_bridge.h"
+#include "log.h"
+
+#define ROUND_UP(num, scale) (((num) + ((scale) - 1)) & ~((scale) - 1))
+
+typedef struct {
+ int handle;
+ dsp_node_t *node;
+ void *data;
+ void *allocated_data;
+ size_t size;
+ size_t len;
+ void *reserve;
+ void *map;
+ bool need_copy;
+ size_t alignment;
+ void *user_data;
+ bool used;
+ bool keyframe;
+} dmm_buffer_t;
+
+static inline dmm_buffer_t *
+dmm_buffer_new(int handle,
+ dsp_node_t *node)
+{
+ dmm_buffer_t *b;
+ b = calloc(1, sizeof(*b));
+
+ pr_debug("%p", b);
+ b->handle = handle;
+ b->node = node;
+ b->alignment = 128;
+
+ return b;
+}
+
+static inline void
+dmm_buffer_free(dmm_buffer_t *b)
+{
+ pr_debug("%p", b);
+ if (!b)
+ return;
+ if (b->map)
+ dsp_unmap(b->handle, b->node, b->map);
+ if (b->reserve)
+ dsp_unreserve(b->handle, b->node, b->reserve);
+ free(b->allocated_data);
+ free(b);
+}
+
+static inline void
+dmm_buffer_map(dmm_buffer_t *b)
+{
+ pr_debug("%p", b);
+ if (b->map)
+ dsp_unmap(b->handle, b->node, b->map);
+ dsp_map(b->handle, b->node, b->data, b->size, b->reserve, &b->map, 0);
+}
+
+static inline void
+dmm_buffer_unmap(dmm_buffer_t *b)
+{
+ pr_debug("%p", b);
+ if (!b->map)
+ return;
+ dsp_unmap(b->handle, b->node, b->map);
+ b->map = NULL;
+}
+
+static inline void
+dmm_buffer_clean(dmm_buffer_t *b,
+ size_t len)
+{
+ pr_debug(NULL, "%p", b);
+ dsp_flush(b->handle, b->node, b->data, len, 1);
+}
+
+static inline void
+dmm_buffer_invalidate(dmm_buffer_t *b,
+ size_t len)
+{
+ pr_debug("%p", b);
+ dsp_invalidate(b->handle, b->node, b->data, len);
+}
+
+static inline void
+dmm_buffer_flush(dmm_buffer_t *b,
+ size_t len)
+{
+ pr_debug("%p", b);
+ dsp_flush(b->handle, b->node, b->data, len, 0);
+}
+
+static inline void
+dmm_buffer_reserve(dmm_buffer_t *b,
+ size_t size)
+{
+ size_t to_reserve;
+ size_t page_size;
+ page_size = getpagesize();
+ if (b->reserve) {
+ if (ROUND_UP(size, page_size) <= ROUND_UP(b->size, page_size))
+ goto leave;
+ dsp_unreserve(b->handle, b->node, b->reserve);
+ }
+ to_reserve = ROUND_UP(size, page_size) + page_size;
+ dsp_reserve(b->handle, b->node, to_reserve, &b->reserve);
+leave:
+ b->size = size;
+}
+
+static inline void
+dmm_buffer_allocate(dmm_buffer_t *b,
+ size_t size)
+{
+ pr_debug("%p", b);
+ dmm_buffer_unmap(b);
+ free(b->allocated_data);
+ if (b->alignment != 0) {
+ if (posix_memalign(&b->allocated_data, b->alignment, ROUND_UP(size, b->alignment)) != 0)
+ b->allocated_data = NULL;
+ b->data = b->allocated_data;
+ }
+ else
+ b->data = b->allocated_data = malloc(size);
+ dmm_buffer_reserve(b, size);
+ dmm_buffer_map(b);
+}
+
+static inline void
+dmm_buffer_use(dmm_buffer_t *b,
+ void *data,
+ size_t size)
+{
+ pr_debug("%p", b);
+ dmm_buffer_unmap(b);
+ b->data = data;
+ dmm_buffer_reserve(b, size);
+ dmm_buffer_map(b);
+}
+
+#endif /* DMM_BUFFER_H */
--- dsp_bridge.c
+++ dsp_bridge.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2009 Felipe Contreras
+ * Copyright (C) 2009-2010 Felipe Contreras
+ * Copyright (C) 2009-2010 Nokia Corporation
* Copyright (C) 2007 Texas Instruments, Incorporated
*
* Author: Felipe Contreras <felipe.contreras at gmail.com>
@@ -40,6 +41,10 @@
#include <sys/mman.h> /* for mmap */
#endif
+#if DSP_API < 2
+#include <errno.h>
+#endif
+
/*
* Dspbridge ioctl numbering scheme
*
@@ -61,7 +66,7 @@
#define DB_MODULE_MASK 0xE0
#define DB_IOC_MASK 0x1F
-#ifdef NEW_API
+#if DSP_API >= 1
#include <linux/ioctl.h>
@@ -76,7 +81,7 @@
#define DB_IOC(module, num) \
(((module) & DB_MODULE_MASK) | ((num) & DB_IOC_MASK))
-#else /* NEW_API */
+#else
#define DB_MGR 1
#define DB_PROC 7
@@ -94,7 +99,7 @@
#define _IOW(type, nr, size) (nr)
#define _IOWR(type, nr, size) (nr)
-#endif /* NEW_API */
+#endif /* DSP_API */
/* MGR Module */
#define MGR_WAIT _IOWR(DB, DB_IOC(DB_MGR, 4), unsigned long)
@@ -115,6 +120,10 @@
#define PROC_INVALIDATEMEMORY _IOW(DB, DB_IOC(DB_PROC, 16), unsigned long)
#define PROC_GET_STATE _IOWR(DB, DB_IOC(DB_PROC, 5), unsigned long)
#define PROC_ENUMRESOURCES _IOWR(DB, DB_IOC(DB_PROC, 4), unsigned long)
+#define PROC_ENUMNODE _IOWR(DB, DB_IOC(DB_PROC, 3), unsigned long)
+#define PROC_STOP _IOWR(DB, DB_IOC(DB_PROC, 15), unsigned long)
+#define PROC_LOAD _IOW(DB, DB_IOC(DB_PROC, 7), unsigned long)
+#define PROC_START _IOW(DB, DB_IOC(DB_PROC, 9), unsigned long)
/* NODE Module */
#define NODE_REGISTERNOTIFY _IOWR(DB, DB_IOC(DB_NODE, 11), unsigned long)
@@ -128,11 +137,22 @@
#define NODE_ALLOCMSGBUF _IOWR(DB, DB_IOC(DB_NODE, 1), unsigned long)
#define NODE_GETUUIDPROPS _IOWR(DB, DB_IOC(DB_NODE, 14), unsigned long)
#define NODE_ALLOCATE _IOWR(DB, DB_IOC(DB_NODE, 0), unsigned long)
+#define NODE_CONNECT _IOW(DB, DB_IOC(DB_NODE, 3), unsigned long)
/* CMM Module */
#define CMM_GETHANDLE _IOR(DB, DB_IOC(DB_CMM, 2), unsigned long)
#define CMM_GETINFO _IOR(DB, DB_IOC(DB_CMM, 3), unsigned long)
+/* STRM Module */
+#define STRM_OPEN _IOWR(DB, DB_IOC(DB_STRM, 7), unsigned long)
+#define STRM_CLOSE _IOW(DB, DB_IOC(DB_STRM, 1), unsigned long)
+#define STRM_GETINFO _IOWR(DB, DB_IOC(DB_STRM, 4), unsigned long)
+#define STRM_ALLOCATEBUFFER _IOWR(DB, DB_IOC(DB_STRM, 0), unsigned long)
+#define STRM_IDLE _IOW(DB, DB_IOC(DB_STRM, 5), unsigned long)
+#define STRM_RECLAIM _IOWR(DB, DB_IOC(DB_STRM, 8), unsigned long)
+#define STRM_FREEBUFFER _IOWR(DB, DB_IOC(DB_STRM, 2), unsigned long)
+#define STRM_ISSUE _IOW(DB, DB_IOC(DB_STRM, 6), unsigned long)
+
int dsp_open(void)
{
return open("/dev/DspBridge", O_RDWR);
@@ -200,6 +220,52 @@
return DSP_SUCCEEDED(ioctl(handle, PROC_REGISTERNOTIFY, &arg));
}
+struct proc_start {
+ void *proc_handle;
+};
+
+bool dsp_start(int handle,
+ void *proc_handle)
+{
+ struct proc_start arg = {
+ .proc_handle = proc_handle,
+ };
+
+ return DSP_SUCCEEDED(ioctl(handle, PROC_START, &arg));
+}
+
+bool dsp_stop(int handle,
+ void *proc_handle)
+{
+ struct proc_start arg = {
+ .proc_handle = proc_handle,
+ };
+
+ return DSP_SUCCEEDED(ioctl(handle, PROC_STOP, &arg));
+}
+
+struct proc_load {
+ void *proc_handle;
+ int argc;
+ char **argv;
+ char **env;
+};
+
+bool dsp_load(int handle,
+ void *proc_handle,
+ int argc, char **argv,
+ char **env)
+{
+ struct proc_load arg = {
+ .proc_handle = proc_handle,
+ .argc = argc,
+ .argv = argv,
+ .env = env,
+ };
+
+ return DSP_SUCCEEDED(ioctl(handle, PROC_LOAD, &arg));
+}
+
struct node_register_notify {
void *node_handle;
unsigned int event_mask;
@@ -243,7 +309,19 @@
.timeout = timeout,
};
+#if DSP_API >= 2
return DSP_SUCCEEDED(ioctl(handle, MGR_WAIT, &arg));
+#else
+ /*
+ * Temporary hack since libc only saves errors -1 to -4095; 0x80008017
+ * is not stored.
+ */
+ int r;
+ r = ioctl(handle, MGR_WAIT, &arg);
+ if (r == (int)0x80008017)
+ errno = ETIME;
+ return DSP_SUCCEEDED(r);
+#endif
}
struct enum_node {
@@ -657,6 +735,8 @@
#ifdef ALLOCATE_SM
if (!allocate_segments(handle, proc_handle, node)) {
dsp_node_delete(handle, node);
+ free(node->heap);
+ free(node);
return false;
}
#endif
@@ -666,10 +746,41 @@
return true;
}
+struct node_connect {
+ void *node_handle;
+ unsigned int stream;
+ void *other_node_handle;
+ unsigned int other_stream;
+ struct dsp_stream_attr *attrs;
+ void *params;
+};
+
+bool dsp_node_connect(int handle,
+ dsp_node_t *node,
+ unsigned int stream,
+ dsp_node_t *other_node,
+ unsigned int other_stream,
+ struct dsp_stream_attr *attrs,
+ void *params)
+{
+ struct node_connect arg = {
+ .node_handle = node->handle,
+ .stream = stream,
+ .other_node_handle = other_node->handle,
+ .other_stream = other_stream,
+ .attrs = attrs,
+ .params = params,
+ };
+
+ return DSP_SUCCEEDED(ioctl(handle, NODE_CONNECT, &arg));
+}
+
bool dsp_node_free(int handle,
dsp_node_t *node)
{
+#ifdef ALLOCATE_SM
munmap(node->msgbuf_addr, node->msgbuf_size);
+#endif
dsp_node_delete(handle, node);
free(node->heap);
free(node);
@@ -825,7 +936,7 @@
.size = size,
};
- return DSP_SUCCEEDED(ioctl(handle, PROC_GET_STATE, &arg));
+ return DSP_SUCCEEDED(ioctl(handle, PROC_ENUMRESOURCES, &arg));
}
struct enum_nodes {
@@ -851,5 +962,265 @@
.allocated = allocated,
};
- return DSP_SUCCEEDED(ioctl(handle, PROC_ENUMRESOURCES, &arg));
+ return DSP_SUCCEEDED(ioctl(handle, PROC_ENUMNODE, &arg));
+}
+
+struct stream_attr {
+ void *event;
+ char *name;
+ void *base;
+ unsigned long size;
+ struct dsp_stream_attr_in *attrin;
+};
+
+struct stream_open {
+ void *node_handle;
+ unsigned int direction;
+ unsigned int index;
+ struct stream_attr *attr;
+ void *stream;
+};
+
+bool dsp_stream_open(int handle,
+ dsp_node_t *node,
+ unsigned int direction,
+ unsigned int index,
+ struct dsp_stream_attr_in *attrin,
+ void *stream)
+{
+ struct stream_attr strm_attr = {
+ .attrin = attrin,
+ };
+ struct stream_open stream_arg = {
+ .node_handle = node->handle,
+ .direction = direction,
+ .index = index,
+ .attr = &strm_attr,
+ .stream = stream,
+ };
+
+ if (attrin && (attrin->mode == STRMMODE_ZEROCOPY ||
+ attrin->mode == STRMMODE_RDMA)) {
+ struct dsp_cmm_info cmm_info;
+
+ if (!get_cmm_info(handle, NULL, &cmm_info))
+ return false;
+
+ if (cmm_info.segments > 0) {
+ void *base;
+ struct dsp_cmm_seg_info *seg;
+
+ seg = &cmm_info.info[0];
+ base = mmap(NULL, seg->size,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED | 0x2000 /* MAP_LOCKED */,
+ handle, seg->base_pa);
+
+ if (!base)
+ return false;
+
+ strm_attr.base = base;
+ strm_attr.size = seg->size;
+ }
+ }
+
+ return DSP_SUCCEEDED(ioctl(handle, STRM_OPEN, &stream_arg));
+}
+
+struct stream_info {
+ enum dsp_stream_mode mode;
+ unsigned int segment;
+ void *base;
+ struct dsp_stream_info *info;
+};
+
+struct stream_get_info {
+ void *stream;
+ struct stream_info *info;
+ unsigned int size;
+};
+
+static inline bool get_stream_info(int handle,
+ void *stream,
+ struct stream_info *info,
+ unsigned int size)
+{
+ struct stream_get_info arg = {
+ .stream = stream,
+ .info = info,
+ .size = size,
+ };
+
+ return DSP_SUCCEEDED(ioctl(handle, STRM_GETINFO, &arg));
+}
+
+bool dsp_stream_close(int handle,
+ void *stream)
+{
+ struct stream_info info;
+ if (!get_stream_info(handle, stream, &info, sizeof(struct stream_info)))
+ return false;
+
+ if (info.base) {
+ struct dsp_cmm_info cmm_info;
+
+ if (!get_cmm_info(handle, NULL, &cmm_info))
+ return false;
+
+ if (cmm_info.segments > 0) {
+ struct dsp_cmm_seg_info *seg;
+ seg = &cmm_info.info[0];
+ if (munmap(info.base, seg->size))
+ return false;
+ }
+ }
+
+ return DSP_SUCCEEDED(ioctl(handle, STRM_CLOSE, &stream));
+}
+
+struct stream_idle {
+ void *stream;
+ bool flush;
+};
+
+bool dsp_stream_idle(int handle,
+ void *stream,
+ bool flush)
+{
+ struct stream_idle arg = {
+ .stream = stream,
+ .flush = flush,
+ };
+ return DSP_SUCCEEDED(ioctl(handle, STRM_IDLE, &arg));
+}
+
+struct stream_reclaim {
+ void *stream;
+ unsigned char **buff;
+ unsigned long *data_size;
+ unsigned long *buff_size;
+ unsigned long *flag;
+};
+
+bool dsp_stream_reclaim(int handle,
+ void *stream,
+ unsigned char **buff,
+ unsigned long *data_size,
+ unsigned long *buff_size,
+ unsigned long *flag)
+{
+ struct stream_reclaim arg = {
+ .stream = stream,
+ .buff = buff,
+ .data_size = data_size,
+ .buff_size = buff_size,
+ .flag = flag,
+ };
+ return DSP_SUCCEEDED(ioctl(handle, STRM_RECLAIM, &arg));
+}
+
+struct stream_issue {
+ void *stream;
+ unsigned char *buff;
+ unsigned long data_size;
+ unsigned long buff_size;
+ unsigned long flag;
+};
+
+bool dsp_stream_issue(int handle,
+ void *stream,
+ unsigned char *buff,
+ unsigned long data_size,
+ unsigned long buff_size,
+ unsigned long flag)
+{
+ struct stream_issue arg = {
+ .stream = stream,
+ .buff = buff,
+ .data_size = data_size,
+ .buff_size = buff_size,
+ .flag = flag,
+ };
+ return DSP_SUCCEEDED(ioctl(handle, STRM_ISSUE, &arg));
+}
+
+bool dsp_stream_get_info(int handle,
+ void *stream,
+ struct dsp_stream_info *info,
+ unsigned int size)
+{
+ struct stream_info stream_info = {
+ .info = info
+ };
+
+ return get_stream_info(handle, stream, &stream_info, size);
+}
+
+
+struct stream_allocate_buffer {
+ void *stream;
+ unsigned int size;
+ unsigned char **buff;
+ unsigned int num_buf;
+};
+
+bool dsp_stream_allocate_buffers(int handle,
+ void *stream,
+ unsigned int size,
+ unsigned char **buff,
+ unsigned int num_buf)
+{
+ unsigned int i;
+ struct stream_info info;
+ if (!get_stream_info(handle, stream, &info, sizeof(struct stream_info)))
+ return false;
+
+ if (info.segment > 0) {
+ struct stream_allocate_buffer arg = {
+ .stream = stream,
+ .size = size,
+ .buff = buff,
+ .num_buf = num_buf,
+ };
+
+ return DSP_SUCCEEDED(ioctl(handle, STRM_ALLOCATEBUFFER, &arg));
+ }
+
+ for (i = 0; i < num_buf; i++)
+ buff[i] = (unsigned char *) malloc(size);
+
+ return true;
+}
+
+struct stream_free_buffers {
+ void *stream;
+ unsigned char **buff;
+ unsigned int num_buf;
+};
+
+bool dsp_stream_free_buffers(int handle,
+ void *stream,
+ unsigned char **buff,
+ unsigned int num_buf)
+{
+ unsigned int i;
+ struct stream_info info;
+ if (!get_stream_info(handle, stream, &info, sizeof(struct stream_info)))
+ return false;
+
+ if (info.segment) {
+ struct stream_free_buffers arg = {
+ .stream = stream,
+ .buff = buff,
+ .num_buf = num_buf,
+ };
+ return DSP_SUCCEEDED(ioctl(handle, STRM_FREEBUFFER, &arg));
+ }
+
+ for (i = 0; i < num_buf; i++) {
+ free(buff[i]);
+ buff[i] = NULL;
+ }
+
+ return true;
}
--- dsp_bridge.h
+++ dsp_bridge.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Felipe Contreras
+ * Copyright (C) 2009-2010 Felipe Contreras
*
* Author: Felipe Contreras <felipe.contreras at gmail.com>
*
@@ -44,7 +44,6 @@
uint8_t field_6[6];
} dsp_uuid_t;
-
typedef struct {
void *handle;
void *heap;
@@ -172,6 +171,51 @@
unsigned int stream_index;
};
+enum dsp_stream_mode {
+ STRMMODE_PROCCOPY,
+ STRMMODE_ZEROCOPY,
+ STRMMODE_LDMA,
+ STRMMODE_RDMA
+};
+
+struct dsp_stream_attr {
+ unsigned int seg_id;
+ unsigned int buf_size;
+ unsigned int num_bufs;
+ unsigned int alignment;
+ unsigned int timeout;
+ enum dsp_stream_mode mode;
+ unsigned int dma_chnl_id;
+ unsigned int dma_priority;
+};
+
+struct dsp_stream_attr_in {
+ unsigned long cb;
+ unsigned int timeout;
+ unsigned int segment;
+ unsigned int alignment;
+ unsigned int num_bufs;
+ enum dsp_stream_mode mode;
+ unsigned int dma_chnl_id;
+ unsigned int dma_priority;
+};
+
+enum dsp_stream_state {
+ STREAM_IDLE,
+ STREAM_READY,
+ STREAM_PENDING,
+ STREAM_DONE
+};
+
+struct dsp_stream_info {
+ unsigned long cb;
+ unsigned int num_bufs_allowed;
+ unsigned int num_bufs_in_stream;
+ unsigned long num_bytes;
+ void *sync_handle;
+ enum dsp_stream_state state;
+};
+
enum dsp_node_state {
NODE_ALLOCATED,
NODE_CREATED,
@@ -211,6 +255,17 @@
bool dsp_detach(int handle,
void *proc_handle);
+bool dsp_start(int handle,
+ void *proc_handle);
+
+bool dsp_stop(int handle,
+ void *proc_handle);
+
+bool dsp_load(int handle,
+ void *proc_handle,
+ int argc, char **argv,
+ char **env);
+
bool dsp_node_allocate(int handle,
void *proc_handle,
const dsp_uuid_t *node_uuid,
@@ -221,6 +276,14 @@
bool dsp_node_free(int handle,
dsp_node_t *node);
+bool dsp_node_connect(int handle,
+ dsp_node_t *node,
+ unsigned int stream,
+ dsp_node_t *other_node,
+ unsigned int other_stream,
+ struct dsp_stream_attr *attrs,
+ void *params);
+
bool dsp_node_create(int handle,
dsp_node_t *node);
@@ -340,4 +403,48 @@
unsigned *num_nodes,
unsigned *allocated);
+bool dsp_stream_open(int handle,
+ dsp_node_t *node,
+ unsigned int direction,
+ unsigned int index,
+ struct dsp_stream_attr_in *attrin,
+ void *stream);
+
+bool dsp_stream_close(int handle,
+ void *stream);
+
+bool dsp_stream_idle(int handle,
+ void *stream,
+ bool flush);
+
+bool dsp_stream_reclaim(int handle,
+ void *stream,
+ unsigned char **buff,
+ unsigned long *data_size,
+ unsigned long *buff_size,
+ unsigned long *args);
+
+bool dsp_stream_issue(int handle,
+ void *stream,
+ unsigned char *buff,
+ unsigned long data_size,
+ unsigned long buff_size,
+ unsigned long arg);
+
+bool dsp_stream_get_info(int handle,
+ void *stream,
+ struct dsp_stream_info *info,
+ unsigned int size);
+
+bool dsp_stream_allocate_buffers(int handle,
+ void *stream,
+ unsigned int size,
+ unsigned char **buff,
+ unsigned int num_buf);
+
+bool dsp_stream_free_buffers(int handle,
+ void *stream,
+ unsigned char **buff,
+ unsigned int num_buf);
+
#endif /* DSP_BRIDGE_H */
--- dsp_exec.c
+++ dsp_exec.c
+/*
+ * Copyright (C) 2009-2010 Igalia S.L.
+ *
+ * Author: Víctor Manuel Jáquez Leal <vjaquez at igalia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+#include "dsp_bridge.h"
+#include "log.h"
+
+int
+main(int argc,
+ const char **argv)
+{
+ int ret = 0;
+ int dsp_handle;
+ void *proc;
+ char *cmd[1];
+
+ if (argc != 2) {
+ pr_err("Wrong arguments: %s <dsp_program>", argv[0]);
+ return -1;
+ }
+
+ dsp_handle = dsp_open();
+
+ if (dsp_handle < 0) {
+ pr_err("dsp open failed");
+ return -1;
+ }
+
+ if (!dsp_attach(dsp_handle, 0, NULL, &proc)) {
+ pr_err("dsp attach failed");
+ ret = -1;
+ goto leave;
+ }
+
+ if (!dsp_stop(dsp_handle, proc)) {
+ pr_err("dsp stop failed");
+ ret = -1;
+ goto leave;
+ }
+
+ cmd[0] = (char *) argv[1];
+ if (!dsp_load(dsp_handle, proc, 1, cmd, NULL)) {
+ pr_err("dsp load failed");
+ ret = -1;
+ goto leave;
+ }
+
+ if (!dsp_start(dsp_handle, proc)) {
+ pr_err("dsp start failed");
+ ret = -1;
+ }
+
+leave:
+ if (proc) {
+ if (!dsp_detach(dsp_handle, proc)) {
+ pr_err("dsp detach failed");
+ ret = -1;
+ }
+ proc = NULL;
+ }
+
+ if (dsp_handle > 0) {
+ if (dsp_close(dsp_handle) < 0) {
+ pr_err("dsp close failed");
+ return -1;
+ }
+ }
+
+ return ret;
+}
--- dsp_load.c
+++ dsp_load.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Nokia Corporation.
+ * Copyright (C) 2009-2010 Nokia Corporation
*
* Authors:
* Felipe Contreras <felipe.contreras at nokia.com>
@@ -27,7 +27,7 @@
#include "dsp_bridge.h"
-unsigned delay = 500; /* in ms */
+static unsigned delay = 500; /* in ms */
static void
display(void)
--- dsp_manager.c
+++ dsp_manager.c
-/*
- * Copyright (C) 2009 Nokia Corporation.
- * Copyright (C) 2009 Texas Instruments, Incorporated
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation
- * version 2.1 of the License.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <stdlib.h>
-#include <signal.h>
-#include <unistd.h> /* for sleep */
-
-#include "log.h"
-#include "dsp_bridge.h"
-
-#ifdef SYSLOG
-#include <syslog.h>
-#endif
-
-static int dsp_handle;
-static void *proc;
-
-const char *process = "dsp-manager";
-const char *recover_script = "/usr/libexec/dsp-recover";
-
-void reset_dsp(void)
-{
- int ret;
-
- dsp_detach(dsp_handle, proc);
- dsp_close(dsp_handle);
-
- ret = system(recover_script);
-
- sleep(2);
-
- if (ret == 0)
- pr_info("recovered");
- else
- pr_err("couldn't recover");
-}
-
-void signal_handler(int n) {
- pr_info("signal %d received", n);
- reset_dsp();
-}
-
-bool attach(void)
-{
- dsp_handle = dsp_open();
-
- if (dsp_handle < 0) {
- pr_err("could not open");
- return false;
- }
-
- pr_info("opened");
-
- if (!dsp_attach(dsp_handle, 0, NULL, &proc)) {
- pr_err("could not attach");
- return false;
- }
-
- pr_info("attached");
-
- return true;
-}
-
-int main(void)
-{
- struct dsp_notification *n_mmufault = NULL;
- struct dsp_notification *n_syserror = NULL;
- struct dsp_notification *n_objects[2];
- int ret = -1;
-
- signal(SIGUSR1, signal_handler);
-
-#ifdef SYSLOG
- openlog(process, 0, LOG_USER);
-#endif
-
- n_mmufault = calloc(1, sizeof(n_mmufault));
- if (!n_mmufault) {
- pr_err("not enough memory");
- goto leave;
- }
-
- n_syserror = calloc(1, sizeof(n_syserror));
- if (!n_syserror) {
- pr_err("not enough memory");
- goto leave;
- }
-
- while (true) {
- unsigned int count;
- unsigned int index = 0;
-
- for (count = 0; count < 3; count++) {
- if (attach()) {
- pr_info("attached");
- break;
- }
- pr_err("failed to attach, retry");
- sleep(2);
- }
-
- if (count == 3) {
- pr_err("could not attach");
- goto leave;
- }
-
- if (!dsp_register_notify(dsp_handle, proc,
- DSP_MMUFAULT, 1,
- n_mmufault))
- {
- pr_err("failed to register for DSP_MMUFAULT");
- goto leave;
- }
- n_objects[0] = n_mmufault;
-
- if (!dsp_register_notify(dsp_handle, proc,
- DSP_SYSERROR, 1,
- n_syserror))
- {
- pr_err("failed to register for DSP_SYSERROR");
- goto leave;
- }
- n_objects[1] = n_syserror;
-
- pr_info("begin");
-
- if (!dsp_wait_for_events(dsp_handle, n_objects, 2, &index, -1)) {
- pr_err("failed waiting for events");
- goto leave;
- }
-
- if (index == 0 || index == 1) {
- pr_err("DSP crash detected: %u", index);
- reset_dsp();
- }
- else
- pr_err("what?");
- }
-
- ret = 0;
-
-leave:
- free(n_mmufault);
- free(n_syserror);
- if (proc)
- dsp_detach(dsp_handle, proc);
- if (dsp_handle > 0)
- dsp_close(dsp_handle);
-
- pr_info("end");
-
- return ret;
-}
--- dsp_ping.c
+++ dsp_ping.c
-/*
- * Copyright (C) 2009 Nokia Corporation.
- *
- * Author: Víctor M. Jáquez L. <vjaquez at igalia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation
- * version 2.1 of the License.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "dsp_bridge.h"
-#include "log.h"
-
-static int dsp_handle;
-static void *proc;
-static int count = 50;
-
-#define SNDIR "/lib/dsp"
-
-static inline dsp_node_t *
-create_node(void)
-{
- dsp_node_t *node = NULL;
-
- const dsp_uuid_t uuid = { 0x12a3c3c1, 0xd015, 0x11d4, 0x9f, 0x69,
- { 0x00, 0xc0, 0x4f, 0x3a, 0x59, 0xae } };
-
- if (!dsp_register(dsp_handle, &uuid, DSP_DCD_LIBRARYTYPE,
- SNDIR "/pingdyn_3430.dll64P"))
- return NULL;
-
- if (!dsp_register(dsp_handle, &uuid, DSP_DCD_NODETYPE,
- SNDIR "/pingdyn_3430.dll64P"))
- return NULL;
-
- if (!dsp_node_allocate(dsp_handle, proc, &uuid, NULL, NULL,
- &node)) {
- pr_err("dsp node allocate failed");
- return NULL;
- }
-
- if (!dsp_node_create(dsp_handle, node)) {
- pr_err("dsp node create failed");
- return NULL;
- }
-
- return node;
-}
-
-static inline bool
-destroy_node(dsp_node_t *node)
-{
- if (node) {
- if (!dsp_node_free(dsp_handle, node)) {
- pr_err("dsp node free failed");
- return false;
- }
- }
-
- return true;
-}
-
-static bool
-run_task(dsp_node_t *node)
-{
- unsigned long exit_status;
- unsigned int index;
- struct dsp_notification event, *notifications;
- int n;
-
- if (!dsp_node_register_notify(dsp_handle, node,
- DSP_NODEMESSAGEREADY, 1,
- &event))
- pr_err("dsp node register notify failed");
-
- if (!dsp_node_run(dsp_handle, node)) {
- pr_err("dsp node run failed");
- return false;
- }
-
- notifications = &event;
-
- for (n = 0; n < count; n++) {
- if (!dsp_send_message(dsp_handle, node, 1, 0, 0)) {
- pr_err("dsp node put message failed");
- continue;
- }
-
- if (!dsp_wait_for_events(dsp_handle, ¬ifications,
- 1, &index, -1)
- && index == 0) {
- pr_err("dsp wait for events failed");
- break;
- }
-
- dsp_msg_t msg;
- if (dsp_node_get_message (dsp_handle, node, &msg, 0))
- printf("Ping: Id %d Msg %d Mem %d\n",
- msg.cmd, msg.arg_1, msg.arg_2);
- }
-
- if (!dsp_node_terminate (dsp_handle, node, &exit_status)) {
- pr_err("dsp node terminate failed: %lx", exit_status);
- return false;
- }
-
- return true;
-}
-
-int
-main(int argc, char **argv)
-{
- dsp_node_t *node;
- int ret = 0;
-
- if (argc == 2) {
- long int c = strtol(argv[1], NULL, 0);
- if (c > 0)
- count = c;
- }
-
- dsp_handle = dsp_open();
-
- if (dsp_handle < 0) {
- pr_err("failed to open DSP");
- return -1;
- }
-
- if (!dsp_attach(dsp_handle, 0, NULL, &proc)) {
- pr_err("dsp attach failed");
- ret = -1;
- goto leave;
- }
-
- node = create_node();
-
- if (!node) {
- pr_err("dsp node creation failed");
- ret = -1;
- goto leave;
- }
-
- run_task(node);
-
- destroy_node(node);
-
-leave:
- if (proc) {
- if (!dsp_detach(dsp_handle, proc)) {
- pr_err("dsp detach failed");
- ret = 1;
- goto leave;
- }
- proc = NULL;
- }
-
- if (dsp_close(dsp_handle) < 0) {
- pr_err("dsp close failed");
- return -1;
- }
-
- return ret;
-}
--- dsp_probe.c
+++ dsp_probe.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Nokia Corporation.
+ * Copyright (C) 2009-2010 Nokia Corporation
*
* Author: Felipe Contreras <felipe.contreras at nokia.com>
*
@@ -32,16 +32,16 @@
node_type_to_str(enum dsp_node_type type)
{
switch (type) {
- case DSP_NODE_DEVICE:
- return "device";
- case DSP_NODE_MESSAGE:
- return "message";
- case DSP_NODE_TASK:
- return "task";
- case DSP_NODE_DAISSOCKET:
- return "dais socket";
- default:
- return NULL;
+ case DSP_NODE_DEVICE:
+ return "device";
+ case DSP_NODE_MESSAGE:
+ return "message";
+ case DSP_NODE_TASK:
+ return "task";
+ case DSP_NODE_DAISSOCKET:
+ return "dais socket";
+ default:
+ return NULL;
}
}
@@ -49,18 +49,18 @@
node_status_to_str(enum dsp_node_state state)
{
switch (state) {
- case NODE_ALLOCATED:
- return "allocated";
- case NODE_CREATED:
- return "created";
- case NODE_RUNNING:
- return "running";
- case NODE_PAUSED:
- return "paused";
- case NODE_DONE:
- return "done";
- default:
- return NULL;
+ case NODE_ALLOCATED:
+ return "allocated";
+ case NODE_CREATED:
+ return "created";
+ case NODE_RUNNING:
+ return "running";
+ case NODE_PAUSED:
+ return "paused";
+ case NODE_DONE:
+ return "done";
+ default:
+ return NULL;
}
}
@@ -82,10 +82,10 @@
{
struct dsp_ndb_props props;
unsigned num = 0, i;
- void **tmp_table;
void *proc_handle;
- unsigned node_count = 0, allocated_count = 0;
struct node_info *node_table;
+ void **tmp_table;
+ unsigned node_count = 0, allocated_count = 0;
if (!dsp_enum(dsp_handle, 0, &props, sizeof(props), &num)) {
pr_err("failed to enumerate nodes");
@@ -108,24 +108,24 @@
}
tmp_table = calloc(num, sizeof(*tmp_table));
- if (!dsp_enum_nodes(dsp_handle, proc_handle, tmp_table, num,
- &node_count, &allocated_count)) {
- pr_err("failed to enumerate nodes");
- goto leave;
- }
-
- for (i = 0; i < node_count; i++) {
- struct dsp_node_attr attr;
- dsp_node_t node = { .handle = tmp_table[i] };
- if (dsp_node_get_attr(dsp_handle, &node, &attr, sizeof(attr))) {
- unsigned j;
- for (j = 0; j < num; j++) {
- if (uuidcmp(&node_table[j].id, &attr.info.props.uiNodeID)) {
- node_table[j].state = attr.info.state;
- break;
+ if (dsp_enum_nodes(dsp_handle, proc_handle, tmp_table, num,
+ &node_count, &allocated_count))
+ {
+ for (i = 0; i < node_count; i++) {
+ struct dsp_node_attr attr;
+ dsp_node_t node = { .handle = tmp_table[i] };
+ if (dsp_node_get_attr(dsp_handle, &node, &attr, sizeof(attr))) {
+ unsigned j;
+ for (j = 0; j < num; j++) {
+ if (uuidcmp(&node_table[j].id, &attr.info.props.uiNodeID)) {
+ node_table[j].state = attr.info.state;
+ break;
+ }
}
}
}
+ } else {
+ pr_err("failed to list active nodes");
}
for (i = 0; i < num; i++) {
@@ -144,9 +144,8 @@
if (!dsp_detach(dsp_handle, proc_handle))
pr_err("dsp detach failed");
-leave:
- free(node_table);
free(tmp_table);
+ free(node_table);
return true;
}
--- dsp_test.c
+++ dsp_test.c
+/*
+ * Copyright (C) 2009-2010 Felipe Contreras
+ * Copyright (C) 2009-2010 Nokia Corporation
+ * Copyright (C) 2009 Igalia S.L
+ *
+ * Author: Felipe Contreras <felipe.contreras at nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <stdio.h>
+
+#include "dmm_buffer.h"
+#include "dsp_bridge.h"
+#include "log.h"
+
+static unsigned long input_buffer_size = 0x1000;
+static unsigned long output_buffer_size = 0x1000;
+static bool done;
+static int ntimes;
+static bool do_fault;
+static bool do_ping;
+static bool do_write;
+
+static int dsp_handle;
+static void *proc;
+struct dsp_notification *events[3];
+
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+static void
+signal_handler(int signal)
+{
+ done = true;
+}
+
+static inline dsp_node_t *
+create_node(void)
+{
+ dsp_node_t *node;
+ const dsp_uuid_t test_uuid = { 0x3dac26d0, 0x6d4b, 0x11dd, 0xad, 0x8b,
+ { 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } };
+
+ if (!dsp_register(dsp_handle, &test_uuid, DSP_DCD_LIBRARYTYPE, "/lib/dsp/test.dll64P"))
+ return false;
+
+ if (!dsp_register(dsp_handle, &test_uuid, DSP_DCD_NODETYPE, "/lib/dsp/test.dll64P"))
+ return false;
+
+ if (!dsp_node_allocate(dsp_handle, proc, &test_uuid, NULL, NULL, &node)) {
+ pr_err("dsp node allocate failed");
+ return NULL;
+ }
+
+ if (!dsp_node_create(dsp_handle, node)) {
+ pr_err("dsp node create failed");
+ return NULL;
+ }
+
+ pr_info("dsp node created");
+
+ return node;
+}
+
+static inline bool
+destroy_node(dsp_node_t *node)
+{
+ if (node) {
+ if (!dsp_node_free(dsp_handle, node)) {
+ pr_err("dsp node free failed");
+ return false;
+ }
+
+ pr_info("dsp node deleted");
+ }
+
+ return true;
+}
+
+static inline void
+configure_dsp_node(void *node,
+ dmm_buffer_t *input_buffer,
+ dmm_buffer_t *output_buffer)
+{
+ dsp_msg_t msg;
+
+ msg.cmd = 0;
+ msg.arg_1 = (uint32_t) input_buffer->map;
+ msg.arg_2 = (uint32_t) output_buffer->map;
+ if (do_fault)
+ msg.arg_2 = 0x12345678;
+ dsp_node_put_message(dsp_handle, node, &msg, -1);
+}
+
+static bool
+register_msgs(dsp_node_t *node)
+{
+ events[0] = calloc(1, sizeof(struct dsp_notification));
+ if (!dsp_node_register_notify(dsp_handle, node,
+ DSP_NODEMESSAGEREADY, 1,
+ events[0]))
+ return false;
+
+ events[1] = calloc(1, sizeof(struct dsp_notification));
+ if (!dsp_register_notify(dsp_handle, proc,
+ DSP_MMUFAULT, 1,
+ events[1]))
+ return false;
+
+ events[2] = calloc(1, sizeof(struct dsp_notification));
+ if (!dsp_register_notify(dsp_handle, proc,
+ DSP_SYSERROR, 1,
+ events[2]))
+ return false;
+
+ return true;
+}
+
+static bool
+check_events(dsp_node_t *node,
+ dsp_msg_t *msg)
+{
+ unsigned int index = 0;
+ pr_debug("waiting for events");
+ if (!dsp_wait_for_events(dsp_handle, events, 3, &index, 1000)) {
+ pr_warning("failed waiting for events");
+ return false;
+ }
+
+ switch (index) {
+ case 0:
+ dsp_node_get_message(dsp_handle, node, msg, 100);
+ pr_debug("got dsp message: 0x%0x 0x%0x 0x%0x",
+ msg->cmd, msg->arg_1, msg->arg_2);
+ return true;
+ case 1:
+ pr_err("got DSP MMUFAULT");
+ return false;
+ case 2:
+ pr_err("got DSP SYSERROR");
+ return false;
+ default:
+ pr_err("wrong event index");
+ return false;
+ }
+}
+
+void run_dmm(dsp_node_t *node,
+ unsigned long times)
+{
+ dmm_buffer_t *input_buffer;
+ dmm_buffer_t *output_buffer;
+
+ input_buffer = dmm_buffer_new(dsp_handle, proc);
+ output_buffer = dmm_buffer_new(dsp_handle, proc);
+
+ dmm_buffer_allocate(input_buffer, input_buffer_size);
+ dmm_buffer_allocate(output_buffer, output_buffer_size);
+
+ configure_dsp_node(node, input_buffer, output_buffer);
+
+ pr_info("running %lu times", times);
+
+ while (!done) {
+ dsp_msg_t msg;
+
+ if (do_write) {
+ static unsigned char foo = 1;
+ unsigned int i;
+ for (i = 0; i < input_buffer->size; i++)
+ ((char *) input_buffer->data)[i] = foo;
+ foo++;
+ }
+
+ dmm_buffer_clean(input_buffer, input_buffer->size);
+ dmm_buffer_invalidate(output_buffer, output_buffer->size);
+ msg.cmd = 1;
+ msg.arg_1 = input_buffer->size;
+ dsp_node_put_message(dsp_handle, node, &msg, -1);
+ if (!check_events(node, &msg)) {
+ done = true;
+ break;
+ }
+
+ if (--times == 0)
+ break;
+ }
+
+ dmm_buffer_unmap(output_buffer);
+ dmm_buffer_unmap(input_buffer);
+
+ dmm_buffer_free(output_buffer);
+ dmm_buffer_free(input_buffer);
+}
+
+void run_ping(dsp_node_t *node,
+ unsigned long times)
+{
+ while (!done) {
+ dsp_msg_t msg;
+
+ if (!dsp_send_message(dsp_handle, node, 2, 0, 0)) {
+ pr_err("dsp node put message failed");
+ continue;
+ }
+
+ if (!check_events(node, &msg)) {
+ done = true;
+ break;
+ }
+
+ printf("ping: id=%d, msg=%d, mem=%d\n",
+ msg.cmd, msg.arg_1, msg.arg_2);
+
+ if (--times == 0)
+ break;
+ }
+}
+
+static bool
+run_task(dsp_node_t *node,
+ unsigned long times)
+{
+ unsigned long exit_status;
+
+ register_msgs(node);
+
+ if (!dsp_node_run(dsp_handle, node)) {
+ pr_err("dsp node run failed");
+ return false;
+ }
+
+ pr_info("dsp node running");
+
+ if (do_ping)
+ run_ping(node, times);
+ else
+ run_dmm(node, times);
+
+ if (!dsp_node_terminate(dsp_handle, node, &exit_status)) {
+ pr_err("dsp node terminate failed: %lx", exit_status);
+ return false;
+ }
+
+ pr_info("dsp node terminated");
+
+ return true;
+}
+
+static void
+handle_options(int *argc,
+ const char ***argv)
+{
+ while (*argc > 0) {
+ const char *cmd = (*argv)[0];
+ if (cmd[0] != '-')
+ break;
+
+#ifdef DEBUG
+ if (!strcmp(cmd, "-d") || !strcmp(cmd, "--debug"))
+ debug_level = 3;
+#endif
+
+ if (!strcmp(cmd, "-n") || !strcmp(cmd, "--ntimes")) {
+ if (*argc < 2) {
+ pr_err("bad option");
+ exit(-1);
+ }
+ ntimes = atoi((*argv)[1]);
+ (*argv)++;
+ (*argc)--;
+ }
+
+ if (!strcmp(cmd, "-s") || !strcmp(cmd, "--size")) {
+ if (*argc < 2) {
+ pr_err("bad option");
+ exit(-1);
+ }
+ input_buffer_size = output_buffer_size = atol((*argv)[1]);
+ (*argv)++;
+ (*argc)--;
+ }
+
+ if (!strcmp(cmd, "-f") || !strcmp(cmd, "--fault"))
+ do_fault = 1;
+
+ if (!strcmp(cmd, "-p") || !strcmp(cmd, "--ping"))
+ do_ping = 1;
+
+ if (!strcmp(cmd, "-w") || !strcmp(cmd, "--write"))
+ do_write = 1;
+
+ (*argv)++;
+ (*argc)--;
+ }
+}
+
+int
+main(int argc,
+ const char **argv)
+{
+ dsp_node_t *node;
+ int ret = 0;
+ unsigned i;
+
+ signal(SIGINT, signal_handler);
+
+#ifdef DEBUG
+ debug_level = 2;
+#endif
+ ntimes = 1000;
+
+ argc--; argv++;
+ handle_options(&argc, &argv);
+
+ dsp_handle = dsp_open();
+
+ if (dsp_handle < 0) {
+ pr_err("dsp open failed");
+ return -1;
+ }
+
+ if (!dsp_attach(dsp_handle, 0, NULL, &proc)) {
+ pr_err("dsp attach failed");
+ ret = -1;
+ goto leave;
+ }
+
+ node = create_node();
+ if (!node) {
+ pr_err("dsp node creation failed");
+ ret = -1;
+ goto leave;
+ }
+
+ run_task(node, ntimes);
+ destroy_node(node);
+
+leave:
+ if (proc) {
+ if (!dsp_detach(dsp_handle, proc)) {
+ pr_err("dsp detach failed");
+ ret = -1;
+ }
+ proc = NULL;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(events); i++)
+ free(events[i]);
+
+ if (dsp_handle > 0) {
+ if (dsp_close(dsp_handle) < 0) {
+ pr_err("dsp close failed");
+ return -1;
+ }
+ }
+
+ return ret;
+}
--- log.c
+++ log.c
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2009 Felipe Contreras
+ * Copyright (C) 2009-2010 Felipe Contreras
+ * Copyright (C) 2009-2010 Nokia Corporation
*
* Author: Felipe Contreras <felipe.contreras at gmail.com>
*
@@ -29,19 +30,35 @@
#include <syslog.h>
#endif
+#ifdef DEBUG
+unsigned debug_level = 1;
+#endif
+
#ifdef SYSLOG
static inline int
log_level_to_syslog(unsigned int level)
{
switch (level) {
- case 0: return LOG_ERR;
- case 1: return LOG_WARNING;
- case 2: return LOG_INFO;
- default: return LOG_DEBUG;
+ case 0: return LOG_ERR;
+ case 1: return LOG_WARNING;
+ case 2: return LOG_INFO;
+ default: return LOG_DEBUG;
}
}
#endif
+static inline const char *
+log_level_to_string(unsigned int level)
+{
+ switch (level) {
+ case 0: return "error"; break;
+ case 1: return "warning"; break;
+ case 2: return "info"; break;
+ case 3: return "debug"; break;
+ default: return NULL; break;
+ }
+}
+
void pr_helper(unsigned int level,
const char *file,
const char *function,
@@ -52,17 +69,30 @@
char *tmp;
va_list args;
+#ifdef DEBUG
+ if (level > debug_level)
+ return;
+#endif
+
va_start(args, fmt);
vasprintf(&tmp, fmt, args);
- if (level <= 2) {
+ if (level <= 1) {
#ifdef SYSLOG
syslog(log_level_to_syslog(level), "%s", tmp);
-#else
- printf("%s: %s\n", function, tmp);
#endif
+ fprintf(stderr, "%s: %s: %s\n",
+ log_level_to_string(level), function, tmp);
}
+#ifdef DEBUG
+ else if (level == 2)
+ fprintf(stderr, "%s: %s: %s\n",
+ log_level_to_string(level), function, tmp);
+ else if (level == 3)
+ fprintf(stderr, "%s: %s:%s(%u): %s\n",
+ log_level_to_string(level), file, function, line, tmp);
+#endif
free(tmp);
--- log.h
+++ log.h
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2009 Felipe Contreras
+ * Copyright (C) 2009-2010 Felipe Contreras
+ * Copyright (C) 2009-2010 Nokia Corporation
*
* Author: Felipe Contreras <felipe.contreras at gmail.com>
*
@@ -22,7 +23,9 @@
#ifndef LOG_H
#define LOG_H
-/* #define DEBUG */
+#ifdef DEBUG
+extern int debug_level;
+#endif
void pr_helper(unsigned int level,
const char *file,
@@ -35,12 +38,13 @@
#define pr_err(...) pr_base(0, __VA_ARGS__)
#define pr_warning(...) pr_base(1, __VA_ARGS__)
-#define pr_info(...) pr_base(2, __VA_ARGS__)
#ifdef DEBUG
+#define pr_info(...) pr_base(2, __VA_ARGS__)
#define pr_debug(...) pr_base(3, __VA_ARGS__)
#else
-#define pr_debug(...)
+#define pr_info(...) ({ if (0) pr_base(2, __VA_ARGS__); })
+#define pr_debug(...) ({ if (0) pr_base(3, __VA_ARGS__); })
#endif
#endif /* LOG_H */
--- scripts
+++ scripts
-(directory)
--- scripts/dsp-recover
+++ scripts/dsp-recover
-#!/bin/sh
-
-kill_users()
-{
- users=$(for x in `lsof -t /dev/DspBridge`; do basename `cat /proc/$x/cmdline | tr '\0' ':' | cut -f1 -d :`; done)
- logger -s -t "dsp-recover" "FIXME! killing users of 'bridgedriver': $users"
- kill -9 `lsof -t /dev/DspBridge`
- sleep 5
-}
-
-MODULE_USAGE=`grep bridgedriver /proc/modules | cut -d ' ' -f3`
-COUNT=0
-while [ $MODULE_USAGE -ne 0 ]
-do
- MODULE_USAGE=`grep bridgedriver /proc/modules | cut -d ' ' -f3`
- if [ $COUNT -ge 10 ]; then
- logger -t "dsp-recover" "gave up waiting for 'bridgedriver' to become free"
- kill_users
- break
- fi
-
- sleep 1
- COUNT=$(($COUNT + 1))
-done
-
-modprobe -r bridgedriver
-if [ $? == 0 ]; then
- modprobe bridgedriver
-else
- logger -t "dsp-recover" "initial restart failed, reloading image"
- /lib/dsp/cexec.out -v -T /lib/dsp/baseimage.dof | grep -q failed
- test $? != 0 # revert the result
-fi
-if [ $? == 0 ]; then
- logger -t "dsp-recover" "DSP restarted"
-else
- logger -t "dsp-recover" "couldn't restart the DSP"
-fi
++++++ deleted files:
--- 0001-build-remove-dsp-manager.patch
More information about the MeeGo-commits
mailing list