[Sound-open-firmware] [PATCH v2 1/3] tune: add testbench common header and source files
Ranjani Sridharan
ranjani.sridharan at linux.intel.com
Sat May 12 07:41:15 CEST 2018
On Thu, 2018-05-10 at 16:28 +0100, Liam Girdwood wrote:
> On Wed, 2018-05-09 at 15:58 -0700, Ranjani Sridharan wrote:
> > This patch adds the common header and source files required for all
> > component testbench. These files include routines for parsing
> > topology files, initializing sof ipc, scheduler, memory allocation
> > and pipeline structures. It also provides simpler implementations
> > for
> > some of the SOF features such as tracing.
> >
> > Signed-off-by: Ranjani Sridharan <ranjani.sridharan at linux.intel.com
> > >
> > ---
> > Makefile.am | 2 +-
> > configure.ac | 4 +-
> > tune/Makefile.am | 1 +
> > tune/include/common_test.h | 63 ++++
> > tune/include/topology.h | 201 ++++++++++
> > tune/include/trace.h | 38 ++
> > tune/src/Makefile.am | 15 +
> > tune/src/alloc.c | 74 ++++
> > tune/src/common_test.c | 212 +++++++++++
> > tune/src/ipc.c | 81 ++++
> > tune/src/schedule.c | 98 +++++
> > tune/src/topology.c | 908
> > +++++++++++++++++++++++++++++++++++++++++++++
> > tune/src/trace.c | 150 ++++++++
> > 13 files changed, 1845 insertions(+), 2 deletions(-)
> > create mode 100644 tune/Makefile.am
> > create mode 100644 tune/include/common_test.h
> > create mode 100644 tune/include/topology.h
> > create mode 100644 tune/include/trace.h
>
> Can these go at src/include/test like the others ?
Just to confirm, do we want all headers to go in tune/src/include/test
and all source files in tune/src/test?
>
> > create mode 100644 tune/src/Makefile.am
> > create mode 100644 tune/src/alloc.c
> > create mode 100644 tune/src/common_test.c
> > create mode 100644 tune/src/ipc.c
> > create mode 100644 tune/src/schedule.c
> > create mode 100644 tune/src/topology.c
> > create mode 100644 tune/src/trace.c
>
>
> I thought this was all going in test/
>
> >
> > diff --git a/Makefile.am b/Makefile.am
> > index ea5d746..2f494d9 100644
> > --- a/Makefile.am
> > +++ b/Makefile.am
> > @@ -1 +1 @@
> > -SUBDIRS = rmbox topology
> > +SUBDIRS = rmbox topology tune
> > diff --git a/configure.ac b/configure.ac
> > index b95c44c..30ec1c7 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -12,7 +12,7 @@ dnl Initialize maintainer mode
> > AM_MAINTAINER_MODE([enable])
> >
> > AC_PROG_CC
> > -
> > +LT_INIT
> > AC_OUTPUT([
> > Makefile
> > rmbox/Makefile
> > @@ -22,6 +22,8 @@ AC_OUTPUT([
> > topology/m4/Makefile
> > topology/sof/Makefile
> > topology/test/Makefile
> > + tune/Makefile
> > + tune/src/Makefile
> > ])
> >
> > echo "
> > diff --git a/tune/Makefile.am b/tune/Makefile.am
> > new file mode 100644
> > index 0000000..af437a6
> > --- /dev/null
> > +++ b/tune/Makefile.am
> > @@ -0,0 +1 @@
> > +SUBDIRS = src
> > diff --git a/tune/include/common_test.h
> > b/tune/include/common_test.h
> > new file mode 100644
> > index 0000000..d6f6037
> > --- /dev/null
> > +++ b/tune/include/common_test.h
> > @@ -0,0 +1,63 @@
> > +/*
> > + * Copyright (c) 2018, Intel Corporation
> > + * All rights reserved.
> > + *
> > + * Redistribution and use in source and binary forms, with or
> > without
> > + * modification, are permitted provided that the following
> > conditions are
> > met:
> > + * * Redistributions of source code must retain the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer.
> > + * * Redistributions in binary form must reproduce the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer in the
> > + * documentation and/or other materials provided with the
> > distribution.
> > + * * Neither the name of the Intel Corporation nor the
> > + * names of its contributors may be used to endorse or promote
> > products
> > + * derived from this software without specific prior written
> > permission.
> > + *
> > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> > CONTRIBUTORS "AS
> > IS"
> > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > LIMITED TO, THE
> > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> > PARTICULAR PURPOSE
> > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> > CONTRIBUTORS BE
> > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> > EXEMPLARY, OR
> > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> > PROCUREMENT OF
> > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> > BUSINESS
> > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
> > WHETHER IN
> > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> > OTHERWISE)
> > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
> > ADVISED OF THE
> > + * POSSIBILITY OF SUCH DAMAGE.
> > + *
> > + * Author: Seppo Ingalsuo <seppo.ingalsuo at linux.intel.com>
> > + * Liam Girdwood <liam.r.girdwood at linux.intel.com>
> > + * Keyon Jie <yang.jie at linux.intel.com>
> > + * Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
>
> Indentation looks off ?
>
> > + */
> > +#ifndef _COMMON_TEST_H
> > +#define _COMMON_TEST_H
> > +
> > +#include <stdint.h>
> > +#include <stddef.h>
> > +#include <time.h>
> > +#include <stdio.h>
> > +#include <uapi/ipc.h>
> > +#include <sof/sof.h>
> > +#include <sof/audio/component.h>
> > +#include <sof/audio/format.h>
> > +
> > +#define DEBUG_MSG_LEN 256
> > +
> > +int scheduler_init(struct sof *sof);
> > +
> > +void sys_comp_file_init(void);
> > +
> > +void sys_comp_filewrite_init(void);
> > +
> > +int tb_pipeline_setup(struct sof *sof);
> > +
> > +int tb_pipeline_start(struct ipc *ipc, int nch, char *bits_in,
> > + struct sof_ipc_pipe_new *ipc_pipe);
> > +
> > +int tb_pipeline_params(struct ipc *ipc, int nch, char *bits_in,
> > + struct sof_ipc_pipe_new *ipc_pipe);
> > +
> > +void debug_print(char *message);
> > +
> > +#endif
> > diff --git a/tune/include/topology.h b/tune/include/topology.h
> > new file mode 100644
> > index 0000000..378c2b6
> > --- /dev/null
> > +++ b/tune/include/topology.h
> > @@ -0,0 +1,201 @@
> > +/*
> > + * Copyright (c) 2018, Intel Corporation
> > + * All rights reserved.
> > + *
> > + * Redistribution and use in source and binary forms, with or
> > without
> > + * modification, are permitted provided that the following
> > conditions are
> > met:
> > + * * Redistributions of source code must retain the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer.
> > + * * Redistributions in binary form must reproduce the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer in the
> > + * documentation and/or other materials provided with the
> > distribution.
> > + * * Neither the name of the Intel Corporation nor the
> > + * names of its contributors may be used to endorse or promote
> > products
> > + * derived from this software without specific prior written
> > permission.
> > + *
> > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> > CONTRIBUTORS "AS
> > IS"
> > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > LIMITED TO, THE
> > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> > PARTICULAR PURPOSE
> > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> > CONTRIBUTORS BE
> > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> > EXEMPLARY, OR
> > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> > PROCUREMENT OF
> > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> > BUSINESS
> > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
> > WHETHER IN
> > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> > OTHERWISE)
> > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
> > ADVISED OF THE
> > + * POSSIBILITY OF SUCH DAMAGE.
> > + *
> > + * Author: Liam Girdwood <liam.r.girdwood at linux.intel.com>
> > + * Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
> > + */
> > +#ifndef _COMMON_TPLG_H
> > +#define _COMMON_TPLG_H
> > +
> > +#include <sound/asoc.h>
> > +#include "common_test.h"
> > +
> > +/*
> > + * Tokens - must match values in topology configurations
> > + */
> > +
> > +/* buffers */
> > +#define SOF_TKN_BUF_SIZE 100
> > +#define SOF_TKN_BUF_CAPS 101
> > +
> > +/* scheduling */
> > +#define SOF_TKN_SCHED_DEADLINE 200
> > +#define SOF_TKN_SCHED_PRIORITY 201
> > +#define SOF_TKN_SCHED_MIPS 202
> > +#define SOF_TKN_SCHED_CORE 203
> > +#define SOF_TKN_SCHED_FRAMES 204
> > +#define SOF_TKN_SCHED_TIMER 205
> > +
> > +/* volume */
> > +#define SOF_TKN_VOLUME_RAMP_STEP_TYPE 250
> > +#define SOF_TKN_VOLUME_RAMP_STEP_MS 251
> > +
> > +/* SRC */
> > +#define SOF_TKN_SRC_RATE_IN 300
> > +#define SOF_TKN_SRC_RATE_OUT 301
> > +
> > +/* Generic components */
> > +#define SOF_TKN_COMP_PERIOD_SINK_COUNT 400
> > +#define SOF_TKN_COMP_PERIOD_SOURCE_COUNT 401
> > +#define SOF_TKN_COMP_FORMAT 402
> > +#define SOF_TKN_COMP_PRELOAD_COUNT 403
> > +
>
> Can we include these macro token numbers from the kernel UAPI header
> ?
>
>
> > +struct comp_info {
> > + char *name;
> > + int id;
> > + int type;
> > + int pipeline_id;
> > +};
> > +
> > +struct frame_types {
> > + char *name;
> > + enum sof_ipc_frame frame;
> > +};
> > +
> > +static const struct frame_types sof_frames[] = {
> > + /* TODO: fix topology to use ALSA formats */
> > + {"s16le", SOF_IPC_FRAME_S16_LE},
> > + {"s24le", SOF_IPC_FRAME_S24_4LE},
> > + {"s32le", SOF_IPC_FRAME_S32_LE},
> > + {"float", SOF_IPC_FRAME_FLOAT},
> > + /* ALSA formats */
> > + {"S16_LE", SOF_IPC_FRAME_S16_LE},
> > + {"S24_LE", SOF_IPC_FRAME_S24_4LE},
> > + {"S32_LE", SOF_IPC_FRAME_S32_LE},
> > + {"FLOAT_LE", SOF_IPC_FRAME_FLOAT},
> > +};
> > +
> > +struct sof_topology_token {
> > + uint32_t token;
> > + uint32_t type;
> > + int (*get_token)(void *elem, void *object, uint32_t
> > offset,
> > + uint32_t size);
> > + uint32_t offset;
> > + uint32_t size;
> > +};
> > +
> > +enum sof_ipc_frame find_format(const char *name);
> > +
> > +int get_token_uint32_t(void *elem, void *object, uint32_t offset,
> > + uint32_t size);
> > +
> > +int get_token_comp_format(void *elem, void *object, uint32_t
> > offset,
> > + uint32_t size);
> > +
> > +/* Buffers */
> > +static const struct sof_topology_token buffer_tokens[] = {
> > + {SOF_TKN_BUF_SIZE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
> > get_token_uint32_t,
> > + offsetof(struct sof_ipc_buffer, size), 0},
> > + {SOF_TKN_BUF_CAPS, SND_SOC_TPLG_TUPLE_TYPE_WORD,
> > get_token_uint32_t,
> > + offsetof(struct sof_ipc_buffer, caps), 0},
> > +};
> > +
> > +/* scheduling */
> > +static const struct sof_topology_token sched_tokens[] = {
> > + {SOF_TKN_SCHED_DEADLINE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
> > + get_token_uint32_t,
> > + offsetof(struct sof_ipc_pipe_new, deadline), 0},
> > + {SOF_TKN_SCHED_PRIORITY, SND_SOC_TPLG_TUPLE_TYPE_WORD,
> > + get_token_uint32_t,
> > + offsetof(struct sof_ipc_pipe_new, priority), 0},
> > + {SOF_TKN_SCHED_MIPS, SND_SOC_TPLG_TUPLE_TYPE_WORD,
> > + get_token_uint32_t,
> > + offsetof(struct sof_ipc_pipe_new, mips), 0},
> > + {SOF_TKN_SCHED_CORE, SND_SOC_TPLG_TUPLE_TYPE_WORD,
> > + get_token_uint32_t,
> > + offsetof(struct sof_ipc_pipe_new, core), 0},
> > + {SOF_TKN_SCHED_FRAMES, SND_SOC_TPLG_TUPLE_TYPE_WORD,
> > + get_token_uint32_t,
> > + offsetof(struct sof_ipc_pipe_new,
> > frames_per_sched), 0},
> > + {SOF_TKN_SCHED_TIMER, SND_SOC_TPLG_TUPLE_TYPE_WORD,
> > + get_token_uint32_t,
> > + offsetof(struct sof_ipc_pipe_new, timer), 0},
> > +};
> > +
> > +/* volume */
> > +static const struct sof_topology_token volume_tokens[] = {
> > + {SOF_TKN_VOLUME_RAMP_STEP_TYPE,
> > SND_SOC_TPLG_TUPLE_TYPE_WORD,
> > + get_token_uint32_t,
> > + offsetof(struct sof_ipc_comp_volume, ramp), 0},
> > + {SOF_TKN_VOLUME_RAMP_STEP_MS,
> > + SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_uint32_t,
> > + offsetof(struct sof_ipc_comp_volume,
> > initial_ramp), 0},
> > +};
> > +
> > +/* SRC */
> > +static const struct sof_topology_token src_tokens[] = {
> > + {SOF_TKN_SRC_RATE_IN, SND_SOC_TPLG_TUPLE_TYPE_WORD,
> > + get_token_uint32_t,
> > + offsetof(struct sof_ipc_comp_src, source_rate),
> > 0},
> > + {SOF_TKN_SRC_RATE_OUT, SND_SOC_TPLG_TUPLE_TYPE_WORD,
> > + get_token_uint32_t,
> > + offsetof(struct sof_ipc_comp_src, sink_rate), 0},
> > +};
> > +
> > +/* Tone */
> > +static const struct sof_topology_token tone_tokens[] = {
> > +};
> > +
> > +/* Generic components */
> > +static const struct sof_topology_token comp_tokens[] = {
> > + {SOF_TKN_COMP_PERIOD_SINK_COUNT,
> > + SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_uint32_t,
> > + offsetof(struct sof_ipc_comp_config,
> > periods_sink), 0},
> > + {SOF_TKN_COMP_PERIOD_SOURCE_COUNT,
> > + SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_uint32_t,
> > + offsetof(struct sof_ipc_comp_config,
> > periods_source), 0},
> > + {SOF_TKN_COMP_FORMAT,
> > + SND_SOC_TPLG_TUPLE_TYPE_STRING,
> > get_token_comp_format,
> > + offsetof(struct sof_ipc_comp_config, frame_fmt),
> > 0},
> > + {SOF_TKN_COMP_PRELOAD_COUNT,
> > + SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_uint32_t,
> > + offsetof(struct sof_ipc_comp_config,
> > preload_count), 0},
> > +};
> > +
> > +int sof_parse_tokens(void *object,
> > + const struct sof_topology_token
> > *tokens,
> > + int count,
> > + struct snd_soc_tplg_vendor_array
> > *array,
> > + int priv_size);
>
> Indentation looks wrong here, did checkpatch complain ?
>
> > +void sof_parse_string_tokens(void *object,
> > + const struct sof_topology_token
> > *tokens,
> > + int count,
> > + struct snd_soc_tplg_vendor_array
> > *array);
> > +void sof_parse_uuid_tokens(void *object,
> > + const struct sof_topology_token
> > *tokens,
> > + int count,
> > + struct snd_soc_tplg_vendor_array
> > *array);
> > +void sof_parse_word_tokens(void *object,
> > + const struct sof_topology_token
> > *tokens,
> > + int count,
> > + struct snd_soc_tplg_vendor_array
> > *array);
> > +
> > +int parse_topology(char *filename, struct sof *sof, int *fr_id,
> > int *fw_id,
> > + int *sched_id, char *bits_in,
> > + char *in_file, char *out_file, void
> > *volume_library);
> > +
> > +#endif
> > diff --git a/tune/include/trace.h b/tune/include/trace.h
> > new file mode 100644
> > index 0000000..d1908b1
> > --- /dev/null
> > +++ b/tune/include/trace.h
> > @@ -0,0 +1,38 @@
> > +/*
> > + * Copyright (c) 2017, Intel Corporation
> > + * All rights reserved.
> > + *
> > + * Redistribution and use in source and binary forms, with or
> > without
> > + * modification, are permitted provided that the following
> > conditions are
> > met:
> > + * * Redistributions of source code must retain the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer.
> > + * * Redistributions in binary form must reproduce the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer in the
> > + * documentation and/or other materials provided with the
> > distribution.
> > + * * Neither the name of the Intel Corporation nor the
> > + * names of its contributors may be used to endorse or promote
> > products
> > + * derived from this software without specific prior written
> > permission.
> > + *
> > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> > CONTRIBUTORS "AS
> > IS"
> > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > LIMITED TO, THE
> > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> > PARTICULAR PURPOSE
> > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> > CONTRIBUTORS BE
> > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> > EXEMPLARY, OR
> > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> > PROCUREMENT OF
> > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> > BUSINESS
> > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
> > WHETHER IN
> > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> > OTHERWISE)
> > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
> > ADVISED OF THE
> > + * POSSIBILITY OF SUCH DAMAGE.
> > + *
> > + * Author: Seppo Ingalsuo <seppo.ingalsuo at linux.intel.com>
> > + * Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
> > + */
> > +#ifndef _TRACE_H
> > +#define _TRACE_H
> > +
> > +void tb_enable_trace(void);
> > +
> > +void tb_disable_trace(void);
> > +
> > +#endif
> > diff --git a/tune/src/Makefile.am b/tune/src/Makefile.am
> > new file mode 100644
> > index 0000000..f7a4f85
> > --- /dev/null
> > +++ b/tune/src/Makefile.am
> > @@ -0,0 +1,15 @@
> > +noinst_LIBRARIES = libtb_common.a
> > +
> > +libtb_common_a_SOURCES = \
> > + common_test.c \
> > + topology.c \
> > + file.c \
> > + trace.c \
> > + ipc.c \
> > + schedule.c \
> > + alloc.c
> > +
> > +libtb_common_a_CFLAGS = \
> > + -I $(prefix)/include/sof \
> > + -I ../include/ \
> > + -g -Wall
> > diff --git a/tune/src/alloc.c b/tune/src/alloc.c
> > new file mode 100644
> > index 0000000..6ae808c
> > --- /dev/null
> > +++ b/tune/src/alloc.c
> > @@ -0,0 +1,74 @@
> > +/*
> > + * Copyright (c) 2018, Intel Corporation
> > + * All rights reserved.
> > + *
> > + * Redistribution and use in source and binary forms, with or
> > without
> > + * modification, are permitted provided that the following
> > conditions are
> > met:
> > + * * Redistributions of source code must retain the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer.
> > + * * Redistributions in binary form must reproduce the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer in the
> > + * documentation and/or other materials provided with the
> > distribution.
> > + * * Neither the name of the Intel Corporation nor the
> > + * names of its contributors may be used to endorse or promote
> > products
> > + * derived from this software without specific prior written
> > permission.
> > + *
> > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> > CONTRIBUTORS "AS
> > IS"
> > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > LIMITED TO, THE
> > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> > PARTICULAR PURPOSE
> > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> > CONTRIBUTORS BE
> > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> > EXEMPLARY, OR
> > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> > PROCUREMENT OF
> > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> > BUSINESS
> > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
> > WHETHER IN
> > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> > OTHERWISE)
> > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
> > ADVISED OF THE
> > + * POSSIBILITY OF SUCH DAMAGE.
> > + *
> > + * Author: Seppo Ingalsuo <seppo.ingalsuo at linux.intel.com>
> > + * Liam Girdwood <liam.r.girdwood at linux.intel.com>
> > + * Keyon Jie <yang.jie at linux.intel.com>
> > + * Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
> > +
> > + */
> > +#include <stdlib.h>
> > +#include <stdint.h>
> > +#include <stdio.h>
> > +#include <sof/alloc.h>
> > +#include "common_test.h"
> > +
> > +/* testbench mem alloc definition */
> > +
> > +void *rmalloc(int zone, uint32_t caps, size_t bytes)
> > +{
> > + return malloc(bytes);
> > +}
> > +
> > +void *rzalloc(int zone, uint32_t caps, size_t bytes)
> > +{
> > + void *x;
> > +
> > + x = malloc(bytes);
> > + bzero(x, bytes);
>
> calloc() ?
>
> > + return x;
> > +}
> > +
> > +void rfree(void *ptr)
> > +{
> > + free(ptr);
> > +}
> > +
> > +void *rballoc(int zone, uint32_t caps, size_t bytes)
> > +{
> > + return malloc(bytes);
> > +}
> > +
> > +void rbfree(void *ptr)
> > +{
> > + free(ptr);
> > +}
>
> iirc, rbfree has gone....
>
> > +
> > +void *xthal_memcpy(void *dest, const void *src, size_t size)
> > +{
> > + return memcpy(dest, src, size);
> > +}
> > diff --git a/tune/src/common_test.c b/tune/src/common_test.c
> > new file mode 100644
> > index 0000000..2fdeac2
> > --- /dev/null
> > +++ b/tune/src/common_test.c
> > @@ -0,0 +1,212 @@
> > +/* Simple test bench versions of SOF functions */
> > +
> > +/*
> > + * Copyright (c) 2017, Intel Corporation
> > + * All rights reserved.
> > + *
> > + * Redistribution and use in source and binary forms, with or
> > without
> > + * modification, are permitted provided that the following
> > conditions are
> > met:
> > + * * Redistributions of source code must retain the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer.
> > + * * Redistributions in binary form must reproduce the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer in the
> > + * documentation and/or other materials provided with the
> > distribution.
> > + * * Neither the name of the Intel Corporation nor the
> > + * names of its contributors may be used to endorse or promote
> > products
> > + * derived from this software without specific prior written
> > permission.
> > + *
> > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> > CONTRIBUTORS "AS
> > IS"
> > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > LIMITED TO, THE
> > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> > PARTICULAR PURPOSE
> > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> > CONTRIBUTORS BE
> > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> > EXEMPLARY, OR
> > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> > PROCUREMENT OF
> > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> > BUSINESS
> > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
> > WHETHER IN
> > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> > OTHERWISE)
> > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
> > ADVISED OF THE
> > + * POSSIBILITY OF SUCH DAMAGE.
> > + *
> > + * Author: Seppo Ingalsuo <seppo.ingalsuo at linux.intel.com>
> > + * Liam Girdwood <liam.r.girdwood at linux.intel.com>
> > + * Keyon Jie <yang.jie at linux.intel.com>
> > + * Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
> > + */
> > +
> > +#include <stdint.h>
> > +#include <stddef.h>
> > +#include <time.h>
> > +#include <stdio.h>
> > +#include <stdlib.h>
> > +#include <string.h>
> > +#include <math.h>
> > +#include <sof/task.h>
> > +#include <sof/alloc.h>
> > +#include <sof/ipc.h>
> > +#include <sof/dai.h>
> > +#include <sof/dma.h>
> > +#include <sof/work.h>
> > +#include <sof/wait.h>
> > +#include <sof/intel-ipc.h>
> > +#include <sof/audio/pipeline.h>
> > +#include "common_test.h"
> > +#include "topology.h"
> > +
> > +/* print debug messages */
> > +void debug_print(char *message)
> > +{
> > +#ifdef DEBUG
> > + printf("debug: %s", message);
> > +#endif
>
> This should be enabled at runtime with a cmd line switch.
>
> > +}
> > +
> > +/* testbench helper functions for pipeline setup and trigger */
> > +
> > +int tb_pipeline_setup(struct sof *sof)
> > +{
> > +
> > + /* init components */
> > + sys_comp_init();
> > +
> > + /* init IPC */
> > + if (ipc_init(sof) < 0) {
> > + fprintf(stderr, "error: IPC init\n");
> > + return -EINVAL;
> > + }
> > +
> > + /* init scheduler */
> > + if (scheduler_init(sof) < 0) {
> > + fprintf(stderr, "error: scheduler init\n");
> > + return -EINVAL;
> > + }
> > +
> > + /* init pipeline system */
> > + if (pipeline_init() < 0) {
> > + fprintf(stderr, "error: pipeline init\n");
> > + return -EINVAL;
> > + }
> > +
> > + debug_print("ipc, scheduler and pipeline initialized\n");
> > +
> > + return 0;
> > +}
> > +
> > +/* set up pcm params, prepare and trigger pipeline */
> > +int tb_pipeline_start(struct ipc *ipc, int nch, char *bits_in,
> > + struct sof_ipc_pipe_new *ipc_pipe)
> > +{
> > + struct ipc_comp_dev *pcm_dev;
> > + struct pipeline *p;
> > + struct comp_dev *cd;
> > + int ret;
> > +
> > + /* set up pipeline params */
> > + ret = tb_pipeline_params(ipc, nch, bits_in, ipc_pipe);
> > + if (ret < 0) {
> > + printf("error: pipeline params\n");
> > + return -EINVAL;
> > + }
> > +
> > + /* Get IPC component device for pipeline */
> > + pcm_dev = ipc_get_comp(ipc, ipc_pipe->sched_id);
> > + if (pcm_dev == NULL) {
> > + printf("error: ipc get comp\n");
> > + return -EINVAL;
> > + }
> > +
> > + /* Point to pipeline */
> > + cd = pcm_dev->cd;
> > + p = pcm_dev->cd->pipeline;
> > +
> > + /* Component prepare */
> > + ret = pipeline_prepare(p, cd);
> > +
> > + /* Start the pipeline */
> > + ret = pipeline_trigger(p, cd, COMP_TRIGGER_START);
> > + if (ret < 0)
> > + printf("Warning: Failed start pipeline
> > command.\n");
> > +
> > + return ret;
> > +}
> > +
> > +/* pipeline pcm params */
> > +int tb_pipeline_params(struct ipc *ipc, int nch, char *bits_in,
> > + struct sof_ipc_pipe_new *ipc_pipe)
> > +{
> > + int fs_period, ret = 0;
> > + struct ipc_comp_dev *pcm_dev;
> > + struct pipeline *p;
> > + struct comp_dev *cd;
> > + struct sof_ipc_pcm_params params;
> > + int fs, deadline;
> > +
> > + deadline = ipc_pipe->deadline;
> > + fs = deadline * ipc_pipe->frames_per_sched;
> > +
> > + /* Compute period from sample rates */
> > + fs_period = (int) (0.9999 + fs * deadline / 1e6);
>
> Maybe nice to state period as debug ?
>
> > +
> > + params.comp_id = ipc_pipe->comp_id;
> > + params.params.buffer_fmt = SOF_IPC_BUFFER_INTERLEAVED;
> > + params.params.frame_fmt = find_format(bits_in);
> > + params.params.direction = SOF_IPC_STREAM_PLAYBACK;
> > + params.params.rate = fs;
> > + params.params.channels = nch;
> > + switch (params.params.frame_fmt) {
> > + case(SOF_IPC_FRAME_S16_LE):
> > + params.params.sample_container_bytes = 2;
> > + params.params.sample_valid_bytes = 2;
> > + params.params.host_period_bytes = fs_period * nch
> > *
> > + params.params.sample_container_bytes;
> > + break;
> > + case(SOF_IPC_FRAME_S24_4LE):
> > + params.params.sample_container_bytes = 4;
> > + params.params.sample_valid_bytes = 3;
> > + params.params.host_period_bytes = fs_period * nch
> > *
> > + params.params.sample_container_bytes;
> > + break;
> > + case(SOF_IPC_FRAME_S32_LE):
> > + params.params.sample_container_bytes = 4;
> > + params.params.sample_valid_bytes = 4;
> > + params.params.host_period_bytes = fs_period * nch
> > *
> > + params.params.sample_container_bytes;
> > + break;
> > + default:
> > + printf("error: invalid frame format\n");
> > + return -EINVAL;
> > + }
> > +
> > + /* get scheduling component device for pipeline*/
> > + pcm_dev = ipc_get_comp(ipc, ipc_pipe->sched_id);
> > + if (pcm_dev == NULL) {
> > + printf("error: ipc get comp\n");
> > + return -EINVAL;
> > + }
> > +
> > + /* point to pipeline */
> > + cd = pcm_dev->cd;
> > + p = pcm_dev->cd->pipeline;
> > + if (p == NULL) {
> > + printf("error: pipeline NULL\n");
> > + return -EINVAL;
> > + }
> > +
> > + /* pipeline params */
> > + ret = pipeline_params(p, cd, ¶ms);
> > + if (ret < 0)
> > + printf("error: pipeline_params\n");
> > +
> > + return ret;
> > +}
> > +
> > +/* The following definitions are to satisfy libsof linker errors
> > */
> > +
> > +struct dai *dai_get(uint32_t type, uint32_t index)
> > +{
> > + return NULL;
> > +}
> > +
> > +struct dma *dma_get(int dmac_id)
> > +{
> > + return NULL;
> > +}
> > diff --git a/tune/src/ipc.c b/tune/src/ipc.c
> > new file mode 100644
> > index 0000000..aef588d
> > --- /dev/null
> > +++ b/tune/src/ipc.c
> > @@ -0,0 +1,81 @@
> > +/*
> > + * Copyright (c) 2018, Intel Corporation
> > + * All rights reserved.
> > + *
> > + * Redistribution and use in source and binary forms, with or
> > without
> > + * modification, are permitted provided that the following
> > conditions are
> > met:
> > + * * Redistributions of source code must retain the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer.
> > + * * Redistributions in binary form must reproduce the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer in the
> > + * documentation and/or other materials provided with the
> > distribution.
> > + * * Neither the name of the Intel Corporation nor the
> > + * names of its contributors may be used to endorse or promote
> > products
> > + * derived from this software without specific prior written
> > permission.
> > + *
> > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> > CONTRIBUTORS "AS
> > IS"
> > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > LIMITED TO, THE
> > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> > PARTICULAR PURPOSE
> > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> > CONTRIBUTORS BE
> > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> > EXEMPLARY, OR
> > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> > PROCUREMENT OF
> > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> > BUSINESS
> > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
> > WHETHER IN
> > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> > OTHERWISE)
> > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
> > ADVISED OF THE
> > + * POSSIBILITY OF SUCH DAMAGE.
> > + *
> > + * Author: Seppo Ingalsuo <seppo.ingalsuo at linux.intel.com>
> > + * Liam Girdwood <liam.r.girdwood at linux.intel.com>
> > + * Keyon Jie <yang.jie at linux.intel.com>
> > + * Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
> > + */
> > +
> > +#include <sof/ipc.h>
> > +#include <sof/intel-ipc.h>
> > +
> > +/* testbench ipc */
> > +struct ipc *_ipc;
> > +
> > +int platform_ipc_init(struct ipc *ipc)
> > +{
> > + struct intel_ipc_data *iipc;
> > + int i;
> > +
> > + _ipc = ipc;
> > +
> > + /* init ipc data */
> > + iipc = malloc(sizeof(struct intel_ipc_data));
> > + ipc_set_drvdata(_ipc, iipc);
> > + _ipc->dsp_msg = NULL;
> > + list_init(&ipc->empty_list);
> > + list_init(&ipc->msg_list);
> > + spinlock_init(&ipc->lock);
> > +
> > + for (i = 0; i < MSG_QUEUE_SIZE; i++)
> > + list_item_prepend(&ipc->message[i].list, &ipc-
> > >empty_list);
> > +
> > + /* allocate page table buffer */
> > + iipc->page_table = malloc(HOST_PAGE_SIZE);
> > + if (iipc->page_table)
> > + bzero(iipc->page_table, HOST_PAGE_SIZE);
> > +
> > + /* PM */
> > + iipc->pm_prepare_D3 = 0;
> > +
> > + return 0;
> > +}
> > +
> > +/* The following definitions are to satisfy libsof linker errors
> > */
> > +
> > +int ipc_stream_send_position(struct comp_dev *cdev,
> > + struct sof_ipc_stream_posn *posn)
> > +{
> > + return 0;
> > +}
> > +
> > +int ipc_stream_send_xrun(struct comp_dev *cdev,
> > + struct sof_ipc_stream_posn *posn)
> > +{
> > + return 0;
> > +}
> > diff --git a/tune/src/schedule.c b/tune/src/schedule.c
> > new file mode 100644
> > index 0000000..9c2990c
> > --- /dev/null
> > +++ b/tune/src/schedule.c
> > @@ -0,0 +1,98 @@
> > +/*
> > + * Copyright (c) 2018, Intel Corporation
> > + * All rights reserved.
> > + *
> > + * Redistribution and use in source and binary forms, with or
> > without
> > + * modification, are permitted provided that the following
> > conditions are
> > met:
> > + * * Redistributions of source code must retain the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer.
> > + * * Redistributions in binary form must reproduce the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer in the
> > + * documentation and/or other materials provided with the
> > distribution.
> > + * * Neither the name of the Intel Corporation nor the
> > + * names of its contributors may be used to endorse or promote
> > products
> > + * derived from this software without specific prior written
> > permission.
> > + *
> > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> > CONTRIBUTORS "AS
> > IS"
> > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > LIMITED TO, THE
> > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> > PARTICULAR PURPOSE
> > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> > CONTRIBUTORS BE
> > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> > EXEMPLARY, OR
> > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> > PROCUREMENT OF
> > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> > BUSINESS
> > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
> > WHETHER IN
> > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> > OTHERWISE)
> > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
> > ADVISED OF THE
> > + * POSSIBILITY OF SUCH DAMAGE.
> > + *
> > + * Author: Seppo Ingalsuo <seppo.ingalsuo at linux.intel.com>
> > + * Liam Girdwood <liam.r.girdwood at linux.intel.com>
> > + * Keyon Jie <yang.jie at linux.intel.com>
> > + * Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
> > + */
> > +
> > +#include <sof/audio/component.h>
> > +#include <sof/task.h>
> > +#include <stdint.h>
> > +#include <sof/wait.h>
> > +
> > +/* scheduler testbench definition */
> > +
> > +struct schedule_data {
> > + spinlock_t lock;
> > + struct list_item list; /* list of tasks in priority queue
> > */
> > + uint32_t clock;
> > +};
> > +static struct schedule_data *sch;
> > +
> > +void schedule_task_complete(struct task *task)
> > +{
> > + list_item_del(&task->list);
> > + task->state = TASK_STATE_COMPLETED;
> > +}
> > +
> > +/* schedule task */
> > +void schedule_task(struct task *task, uint64_t start, uint64_t
> > deadline)
> > +{
> > + task->deadline = deadline;
> > + list_item_prepend(&task->list, &sch->list);
> > + task->state = TASK_STATE_QUEUED;
> > +
> > + if (task->func)
> > + task->func(task->data);
> > +
> > + schedule_task_complete(task);
> > +}
> > +
> > +/* initialize scheduler */
> > +int scheduler_init(struct sof *sof)
> > +{
> > + trace_pipe("ScI");
> > +
> > + sch = malloc(sizeof(*sch));
> > + list_init(&sch->list);
> > + spinlock_init(&sch->lock);
> > +
> > + return 0;
> > +}
> > +
> > +/* The following definitions are to satisfy libsof linker errors
> > */
> > +
> > +void schedule(void)
> > +{
> > +}
> > +
> > +void schedule_task_idle(struct task *task, uint64_t deadline)
> > +{
> > +}
> > +
> > +/* testbench work definition */
> > +
> > +void work_schedule_default(struct work *w, uint64_t timeout)
> > +{
> > +}
> > +
> > +void work_cancel_default(struct work *work)
> > +{
> > +}
> > +
> > diff --git a/tune/src/topology.c b/tune/src/topology.c
> > new file mode 100644
> > index 0000000..c824591
> > --- /dev/null
> > +++ b/tune/src/topology.c
> > @@ -0,0 +1,908 @@
> > +/*
> > + * Copyright (c) 2018, Intel Corporation
> > + * All rights reserved.
> > + *
> > + * Redistribution and use in source and binary forms, with or
> > without
> > + * modification, are permitted provided that the following
> > conditions are
> > met:
> > + * * Redistributions of source code must retain the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer.
> > + * * Redistributions in binary form must reproduce the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer in the
> > + * documentation and/or other materials provided with the
> > distribution.
> > + * * Neither the name of the Intel Corporation nor the
> > + * names of its contributors may be used to endorse or promote
> > products
> > + * derived from this software without specific prior written
> > permission.
> > + *
> > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> > CONTRIBUTORS "AS
> > IS"
> > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > LIMITED TO, THE
> > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> > PARTICULAR PURPOSE
> > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> > CONTRIBUTORS BE
> > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> > EXEMPLARY, OR
> > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> > PROCUREMENT OF
> > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> > BUSINESS
> > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
> > WHETHER IN
> > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> > OTHERWISE)
> > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
> > ADVISED OF THE
> > + * POSSIBILITY OF SUCH DAMAGE.
> > + *
> > + * Author: Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
> > + * Liam Girdwood <liam.r.girdwood at linux.intel.com>
> > + */
> > +
> > +/*
> > + * Topology parser to parse topology bin file
> > + * and set up components and pipeline
> > + */
> > +
> > +#include <sof/ipc.h>
> > +#include <stdio.h>
> > +#include <string.h>
> > +#include <dlfcn.h>
> > +#include <sof/audio/component.h>
> > +#include "topology.h"
> > +#include "file.h"
> > +
> > +char *input_file;
> > +char *output_file;
> > +void *volume_lib;
> > +FILE *file;
> > +
> > +/*
> > + * Register component driver
> > + * Only needed once per component type
> > + */
> > +static void register_comp(int comp_type)
> > +{
> > + static int pga_reg;
> > + static int file_reg;
> > +
> > + switch (comp_type) {
> > + case SND_SOC_TPLG_DAPM_PGA:
> > + debug_print("register pga comp driver\n");
> > + if (pga_reg)
> > + return;
> > + /* register volume driver */
> > + void (*sys_comp_volume_init)(void) =
> > + (void (*)(void))dlsym(volume_lib,
> > + "sys_comp_volume_ini
> > t");
> > + sys_comp_volume_init();
> > + pga_reg = 1;
> > + break;
> > + case SND_SOC_TPLG_DAPM_DAI_IN:
> > + case SND_SOC_TPLG_DAPM_AIF_IN:
> > + debug_print("register file comp driver\n");
> > + if (file_reg)
> > + return;
> > + /* register file driver */
> > + sys_comp_file_init();
> > + file_reg = 1;
> > + break;
> > + default:
> > + break;
> > + }
> > +}
> > +
> > +/* read vendor tuples array from topology */
> > +static int read_array(struct snd_soc_tplg_vendor_array *array)
> > +{
> > + struct snd_soc_tplg_vendor_uuid_elem uuid;
> > + struct snd_soc_tplg_vendor_string_elem string;
> > + struct snd_soc_tplg_vendor_value_elem value;
> > + int j, ret = 0;
> > + size_t size;
> > +
> > + switch (array->type) {
> > + case SND_SOC_TPLG_TUPLE_TYPE_UUID:
> > + /* copy uuid elems into array */
> > + for (j = 0; j < array->num_elems; j++) {
> > + size = sizeof(struct
> > snd_soc_tplg_vendor_uuid_elem);
> > + ret = fread(&uuid, size, 1, file);
> > + if (ret != 1)
> > + return -EINVAL;
> > + memcpy(&array->uuid[j], &uuid, size);
> > + }
> > + break;
> > + case SND_SOC_TPLG_TUPLE_TYPE_STRING:
> > + /* copy string elems into array */
> > + for (j = 0; j < array->num_elems; j++) {
> > + size = sizeof(struct
> > snd_soc_tplg_vendor_string_elem);
> > + ret = fread(&string, size, 1, file);
> > + if (ret != 1)
> > + return -EINVAL;
> > + memcpy(&array->string[j], &string, size);
> > + }
> > + break;
> > + case SND_SOC_TPLG_TUPLE_TYPE_BOOL:
> > + case SND_SOC_TPLG_TUPLE_TYPE_BYTE:
> > + case SND_SOC_TPLG_TUPLE_TYPE_WORD:
> > + case SND_SOC_TPLG_TUPLE_TYPE_SHORT:
> > + for (j = 0; j < array->num_elems; j++) {
> > + size = sizeof(struct
> > snd_soc_tplg_vendor_value_elem);
> > + ret = fread(&value, size, 1, file);
> > + if (ret != 1)
> > + return -EINVAL;
> > + memcpy(&array->value[j], &value, size);
> > + }
> > + break;
> > + default:
> > + printf("error: unknown token type %d\n", array-
> > >type);
> > + return -EINVAL;
> > + }
> > + return 0;
> > +}
> > +
> > +/* load pipeline graph DAPM widget*/
> > +static int load_graph(struct sof *sof, struct comp_info
> > *temp_comp_list,
> > + int count, int num_comps, int pipeline_id)
> > +{
> > + struct sof_ipc_pipe_comp_connect connection;
> > + struct snd_soc_tplg_dapm_graph_elem *graph_elem;
> > + size_t size;
> > + int i, j, ret = 0;
> > +
> > + /* allocate memory for graph elem */
> > + size = sizeof(struct snd_soc_tplg_dapm_graph_elem);
> > + graph_elem = (struct snd_soc_tplg_dapm_graph_elem
> > *)malloc(size);
> > + if (!graph_elem) {
> > + printf("error: mem alloc\n");
> > + return -EINVAL;
> > + }
> > +
> > + /* set up component connections */
> > + connection.source_id = connection.sink_id = -1;
> > + for (i = 0; i < count; i++) {
> > + size = sizeof(struct
> > snd_soc_tplg_dapm_graph_elem);
> > + ret = fread(graph_elem, size, 1, file);
> > + if (ret != 1)
> > + return -EINVAL;
> > + for (j = 0; j < num_comps; j++) {
> > + /* look up component id from the component
> > list */
> > + if (strcmp(temp_comp_list[j].name,
> > + graph_elem->source) == 0)
> > + connection.source_id =
> > temp_comp_list[j].id;
> > + if (strcmp(temp_comp_list[j].name,
> > + graph_elem->sink) == 0)
> > + connection.sink_id =
> > temp_comp_list[j].id;
> > + }
> > + /* connect source and sink */
> > + if (connection.source_id != -1 &&
> > connection.sink_id != -1)
> > + if (ipc_comp_connect(sof->ipc,
> > &connection) < 0) {
> > + fprintf(stderr, "error: comp
> > connect\n");
> > + return -EINVAL;
> > + }
> > + }
> > +
> > + /* pipeline complete after pipeline connections are
> > established */
> > + for (i = 0; i < num_comps; i++) {
> > + if (temp_comp_list[i].pipeline_id == pipeline_id
> > &&
> > + temp_comp_list[i].type ==
> > SND_SOC_TPLG_DAPM_SCHEDULER)
> > + ipc_pipeline_complete(sof->ipc,
> > temp_comp_list[i].id);
> > + }
> > +
> > + free(graph_elem);
> > + return 0;
> > +}
> > +
> > +/* load buffer DAPM widget */
> > +static int load_buffer(struct sof *sof, int comp_id, int
> > pipeline_id, int
> > size)
> > +{
> > + struct sof_ipc_buffer buffer;
> > + struct snd_soc_tplg_vendor_array *array = NULL;
> > + int ret = 0;
> > +
> > + /* configure buffer */
> > + buffer.comp.id = comp_id;
> > + buffer.comp.pipeline_id = pipeline_id;
> > +
> > + /* allocate memory for vendor tuple array */
> > + array = (struct snd_soc_tplg_vendor_array *)malloc(size);
> > + ret = fread(array, sizeof(struct
> > snd_soc_tplg_vendor_array), 1,
> > file);
> > + if (ret != 1)
> > + return -EINVAL;
> > +
> > + read_array(array);
> > + /* parse buffer tokens */
> > + ret = sof_parse_tokens(&buffer, buffer_tokens,
> > + ARRAY_SIZE(buffer_tokens), array,
> > + size);
> > +
> > + /* create buffer component */
> > + if (ipc_buffer_new(sof->ipc, &buffer) < 0) {
> > + fprintf(stderr, "error: buffer new\n");
> > + return -EINVAL;
> > + }
> > + free(array);
> > + return 0;
> > +}
> > +
> > +/* load fileread component */
> > +static int load_fileread(struct sof *sof, int comp_id, int
> > pipeline_id,
> > + int size, char *bits_in, int *fr_id, int
> > *sched_id)
> > +{
> > + struct sof_ipc_comp_file fileread;
> > + struct snd_soc_tplg_vendor_array *array = NULL;
> > + size_t total_array_size = 0, read_size;
> > + int ret = 0;
> > +
> > + fileread.config.frame_fmt = find_format(bits_in);
> > +
> > + /* allocate memory for vendor tuple array */
> > + array = (struct snd_soc_tplg_vendor_array *)malloc(size);
> > + if (!array) {
> > + printf("error: mem alloc\n");
> > + return -EINVAL;
> > + }
> > +
> > + /* read vendor tokens */
> > + while (total_array_size < size) {
> > + read_size = sizeof(struct
> > snd_soc_tplg_vendor_array);
> > + ret = fread(array, read_size, 1, file);
> > + if (ret != 1)
> > + return -EINVAL;
> > + read_array(array);
> > + /* parse comp tokens */
> > + ret = sof_parse_tokens(&fileread.config,
> > comp_tokens,
> > + ARRAY_SIZE(comp_tokens), array,
> > + array->size);
> > + if (ret != 0) {
> > + printf("error: parse fileread tokens
> > %d\n", size);
> > + return -EINVAL;
> > + }
> > + total_array_size += array->size;
> > + }
> > +
> > + /* configure fileread */
> > + fileread.fn = strdup(input_file);
> > + fileread.mode = FILE_READ;
> > + fileread.comp.id = comp_id;
> > + /* use fileread comp as scheduling comp */
> > + *fr_id = *sched_id = comp_id;
> > + fileread.comp.hdr.size = sizeof(struct sof_ipc_comp_file);
> > + fileread.comp.type = SOF_COMP_FILEREAD;
> > + fileread.comp.pipeline_id = pipeline_id;
> > +
> > + /* create fileread component */
> > + if (ipc_comp_new(sof->ipc, (struct sof_ipc_comp
> > *)&fileread) < 0) {
> > + fprintf(stderr, "error: comp register\n");
> > + return -EINVAL;
> > + }
> > +
> > + free(array);
> > + return 0;
> > +}
> > +
> > +/* load filewrite component */
> > +static int load_filewrite(struct sof *sof, int comp_id, int
> > pipeline_id,
> > + int size, int *fw_id)
> > +{
> > +
> > + struct sof_ipc_comp_file filewrite;
> > + struct snd_soc_tplg_vendor_array *array = NULL;
> > + size_t total_array_size = 0, read_size;
> > + int ret = 0;
> > +
> > + /* allocate memory for vendor tuple array */
> > + array = (struct snd_soc_tplg_vendor_array *)malloc(size);
> > + if (!array) {
> > + printf("error: mem alloc\n");
> > + return -EINVAL;
> > + }
> > +
> > + /* read vendor tokens */
> > + while (total_array_size < size) {
> > + read_size = sizeof(struct
> > snd_soc_tplg_vendor_array);
> > + ret = fread(array, read_size, 1, file);
> > + if (ret != 1)
> > + return -EINVAL;
> > +
> > + read_array(array);
> > + /* parse comp tokens */
> > + ret = sof_parse_tokens(&filewrite.config,
> > comp_tokens,
> > + ARRAY_SIZE(comp_tokens), array,
> > + array->size);
> > + if (ret != 0) {
> > + printf("error: parse filewrite tokens
> > %d\n", size);
> > + return -EINVAL;
> > + }
> > + total_array_size += array->size;
> > + }
> > +
> > + /* configure filewrite */
> > + filewrite.fn = strdup(output_file);
> > + filewrite.comp.id = comp_id;
> > + filewrite.mode = FILE_WRITE;
> > + *fw_id = comp_id;
> > + filewrite.comp.hdr.size = sizeof(struct
> > sof_ipc_comp_file);
> > + filewrite.comp.type = SOF_COMP_FILEREAD;
> > + filewrite.comp.pipeline_id = pipeline_id;
> > +
> > + /* create filewrite component */
> > + if (ipc_comp_new(sof->ipc, (struct sof_ipc_comp
> > *)&filewrite) < 0) {
> > + fprintf(stderr, "error: comp register\n");
> > + return -EINVAL;
> > + }
> > +
> > + free(array);
> > + return 0;
> > +}
> > +
> > +/* load pda dapm widget */
> > +static int load_pga(struct sof *sof, int comp_id, int pipeline_id,
> > + int size)
> > +{
> > + struct sof_ipc_comp_volume volume;
> > + struct snd_soc_tplg_vendor_array *array = NULL;
> > + size_t total_array_size = 0, read_size;
> > + int ret = 0;
> > +
> > + /* allocate memory for vendor tuple array */
> > + array = (struct snd_soc_tplg_vendor_array *)malloc(size);
> > + if (!array) {
> > + printf("error: mem alloc\n");
> > + return -EINVAL;
> > + }
> > +
> > + /* read vendor tokens */
> > + while (total_array_size < size) {
> > + read_size = sizeof(struct
> > snd_soc_tplg_vendor_array);
> > + ret = fread(array, read_size, 1, file);
> > + if (ret != 1)
> > + return -EINVAL;
> > + read_array(array);
> > +
> > + /* parse volume tokens */
> > + ret = sof_parse_tokens(&volume.config,
> > comp_tokens,
> > + ARRAY_SIZE(comp_tokens), array,
> > + array->size);
> > + if (ret != 0) {
> > + printf("error: parse pga tokens %d\n",
> > size);
> > + return -EINVAL;
> > + }
> > + total_array_size += array->size;
> > + }
> > +
> > + /* configure volume */
> > + volume.comp.id = comp_id;
> > + volume.comp.hdr.size = sizeof(struct sof_ipc_comp_volume);
> > + volume.comp.type = SOF_COMP_VOLUME;
> > + volume.comp.pipeline_id = pipeline_id;
> > +
> > + /* load volume component */
> > + if (ipc_comp_new(sof->ipc, (struct sof_ipc_comp *)&volume)
> > < 0) {
> > + fprintf(stderr, "error: comp register\n");
> > + return -EINVAL;
> > + }
> > +
> > + free(array);
> > + return 0;
> > +}
> > +
> > +/* load scheduler dapm widget */
> > +static int load_pipeline(struct sof *sof, struct sof_ipc_pipe_new
> > *pipeline,
> > + int comp_id, int pipeline_id, int size,
> > int
> > *sched_id)
> > +{
> > + struct snd_soc_tplg_vendor_array *array = NULL;
> > + size_t total_array_size = 0, read_size;
> > + int ret = 0;
> > +
> > + /* configure pipeline */
> > + pipeline->sched_id = *sched_id;
> > + pipeline->comp_id = comp_id;
> > + pipeline->pipeline_id = pipeline_id;
> > +
> > + /* allocate memory for vendor tuple array */
> > + array = (struct snd_soc_tplg_vendor_array *)malloc(size);
> > + if (!array) {
> > + printf("error: mem alloc\n");
> > + return -EINVAL;
> > + }
> > +
> > + /* read vendor array */
> > + while (total_array_size < size) {
> > + read_size = sizeof(struct
> > snd_soc_tplg_vendor_array);
> > + ret = fread(array, read_size, 1, file);
> > + if (ret != 1)
> > + return -EINVAL;
> > + ret = read_array(array);
> > + if (ret < 0)
> > + return -EINVAL;
> > + /* parse scheduler tokens */
> > + ret = sof_parse_tokens(pipeline, sched_tokens,
> > + ARRAY_SIZE(sched_tokens), array,
> > + array->size);
> > + if (ret != 0) {
> > + printf("error: parse pipeline tokens
> > %d\n", size);
> > + return -EINVAL;
> > + }
> > + total_array_size += array->size;
> > + }
> > +
> > + /* Create pipeline */
> > + if (ipc_pipeline_new(sof->ipc, pipeline) < 0) {
> > + fprintf(stderr, "error: pipeline new\n");
> > + return -EINVAL;
> > + }
> > +
> > + free(array);
> > + return 0;
> > +}
> > +
> > +/* load dapm widget kcontrols
> > + * we dont use controls in the testbench atm.
> > + * so just skip to the next dapm widget
> > + */
> > +static int load_controls(struct sof *sof, int num_kcontrols)
> > +{
> > + struct snd_soc_tplg_ctl_hdr *ctl_hdr;
> > + struct snd_soc_tplg_mixer_control *mixer_ctl;
> > + struct snd_soc_tplg_enum_control *enum_ctl;
> > + struct snd_soc_tplg_bytes_control *bytes_ctl;
> > + size_t read_size, size;
> > + int j, ret = 0;
> > +
> > + /* allocate memory */
> > + size = sizeof(struct snd_soc_tplg_ctl_hdr);
> > + ctl_hdr = (struct snd_soc_tplg_ctl_hdr *)malloc(size);
> > + if (!ctl_hdr) {
> > + printf("error: mem alloc\n");
> > + return -EINVAL;
> > + }
> > +
> > + size = sizeof(struct snd_soc_tplg_mixer_control);
> > + mixer_ctl = (struct snd_soc_tplg_mixer_control
> > *)malloc(size);
> > + if (!mixer_ctl) {
> > + printf("error: mem alloc\n");
> > + return -EINVAL;
> > + }
> > +
> > + size = sizeof(struct snd_soc_tplg_enum_control);
> > + enum_ctl = (struct snd_soc_tplg_enum_control
> > *)malloc(size);
> > + if (!enum_ctl) {
> > + printf("error: mem alloc\n");
> > + return -EINVAL;
> > + }
> > +
> > + size = sizeof(struct snd_soc_tplg_bytes_control);
> > + bytes_ctl = (struct snd_soc_tplg_bytes_control
> > *)malloc(size);
> > + if (!bytes_ctl) {
> > + printf("error: mem alloc\n");
> > + return -EINVAL;
> > + }
> > +
> > + for (j = 0; j < num_kcontrols; j++) {
> > + /* read control header */
> > + read_size = sizeof(struct snd_soc_tplg_ctl_hdr);
> > + ret = fread(ctl_hdr, read_size, 1, file);
> > + if (ret != 1)
> > + return -EINVAL;
> > + /* load control based on type */
> > + switch (ctl_hdr->ops.info) {
> > + case SND_SOC_TPLG_CTL_VOLSW:
> > + case SND_SOC_TPLG_CTL_STROBE:
> > + case SND_SOC_TPLG_CTL_VOLSW_SX:
> > + case SND_SOC_TPLG_CTL_VOLSW_XR_SX:
> > + case SND_SOC_TPLG_CTL_RANGE:
> > + case SND_SOC_TPLG_DAPM_CTL_VOLSW:
> > + /* load mixer type control */
> > + read_size = sizeof(struct
> > snd_soc_tplg_ctl_hdr);
> > + fseek(file, read_size * -1, SEEK_CUR);
> > + read_size = sizeof(struct
> > snd_soc_tplg_mixer_control);
> > + ret = fread(mixer_ctl, read_size, 1,
> > file);
> > + if (ret != 1)
> > + return -EINVAL;
> > + /* skip mixer private data */
> > + fseek(file, mixer_ctl->priv.size,
> > SEEK_CUR);
> > + break;
> > + case SND_SOC_TPLG_CTL_ENUM:
> > + case SND_SOC_TPLG_CTL_ENUM_VALUE:
> > + case SND_SOC_TPLG_DAPM_CTL_ENUM_DOUBLE:
> > + case SND_SOC_TPLG_DAPM_CTL_ENUM_VIRT:
> > + case SND_SOC_TPLG_DAPM_CTL_ENUM_VALUE:
> > + /* load enum type control */
> > + read_size = sizeof(struct
> > snd_soc_tplg_ctl_hdr);
> > + fseek(file, read_size * -1, SEEK_CUR);
> > + read_size = sizeof(struct
> > snd_soc_tplg_enum_control);
> > + ret = fread(enum_ctl, read_size, 1, file);
> > + if (ret != 1)
> > + return -EINVAL;
> > + /* skip enum private data */
> > + fseek(file, enum_ctl->priv.size,
> > SEEK_CUR);
> > + break;
> > + case SND_SOC_TPLG_CTL_BYTES:
> > + /* load bytes type controls */
> > + read_size = sizeof(struct
> > snd_soc_tplg_ctl_hdr);
> > + fseek(file, read_size * -1, SEEK_CUR);
> > + read_size = sizeof(struct
> > snd_soc_tplg_bytes_control);
> > + ret = fread(bytes_ctl, read_size, 1,
> > file);
> > + if (ret != 1)
> > + return -EINVAL;
> > + /* skip bytes private data */
> > + fseek(file, bytes_ctl->priv.size,
> > SEEK_CUR);
> > + break;
> > + default:
> > + printf("control type not supported\n");
> > + return -EINVAL;
> > + }
> > + }
> > +
> > + /* free all data */
> > + free(mixer_ctl);
> > + free(enum_ctl);
> > + free(bytes_ctl);
> > + free(ctl_hdr);
> > + return 0;
> > +}
> > +
> > +/* load dapm widget */
> > +static int load_widget(struct sof *sof, int *fr_id, int *fw_id,
> > + int *sched_id, char *bits_in,
> > + struct comp_info *temp_comp_list,
> > + struct sof_ipc_pipe_new *pipeline, int comp_id,
> > + int comp_index, int pipeline_id)
> > +{
> > + struct snd_soc_tplg_dapm_widget *widget;
> > + char message[DEBUG_MSG_LEN];
> > + size_t read_size, size;
> > + int ret = 0;
> > +
> > + /* allocate memory for widget */
> > + size = sizeof(struct snd_soc_tplg_dapm_widget);
> > + widget = (struct snd_soc_tplg_dapm_widget *)malloc(size);
> > + if (!widget) {
> > + printf("error: mem alloc\n");
> > + return -EINVAL;
> > + }
> > +
> > + /* read widget data */
> > + read_size = sizeof(struct snd_soc_tplg_dapm_widget);
> > + ret = fread(widget, read_size, 1, file);
> > + if (ret != 1)
> > + return -EINVAL;
> > +
> > + /*
> > + * create a list with all widget info
> > + * containing mapping between component names and ids
> > + * which will be used for setting up component connections
> > + */
> > + temp_comp_list[comp_index].id = comp_id;
> > + temp_comp_list[comp_index].name = strdup(widget->name);
> > + temp_comp_list[comp_index].type = widget->id;
> > + temp_comp_list[comp_index].pipeline_id = pipeline_id;
> > +
> > + sprintf(message, "loading widget %s id %d\n",
> > + temp_comp_list[comp_index].name,
> > + temp_comp_list[comp_index].id);
> > + debug_print(message);
> > +
> > + /* register comp driver */
> > + register_comp(temp_comp_list[comp_index].type);
> > +
> > + /* load widget based on type */
> > + switch (temp_comp_list[comp_index].type) {
> > + case(SND_SOC_TPLG_DAPM_PGA):
> > + /* load pga widget */
> > + if (load_pga(sof, temp_comp_list[comp_index].id,
> > + pipeline_id, widget->priv.size) < 0)
> > {
> > + printf("error: load pga\n");
> > + return -EINVAL;
> > + }
> > + break;
> > + case(SND_SOC_TPLG_DAPM_AIF_IN):
> > + /* replace pcm playback component with fileread in
> > testbench
> > */
> > + if (load_fileread(sof,
> > temp_comp_list[comp_index].id,
> > + pipeline_id, widget->priv.size,
> > bits_in,
> > + fr_id, sched_id) < 0) {
> > + printf("error: load fileread\n");
>
> its best to use fprintf() for output. As you can print normal
> messages to stdout
> and errors like above to stderr.
>
> Liam
>
>
> > + return -EINVAL;
> > + }
> > + break;
> > + case(SND_SOC_TPLG_DAPM_DAI_IN):
> > + /* replace dai in component with filewrite in
> > testbench */
> > + if (load_filewrite(sof,
> > temp_comp_list[comp_index].id,
> > + pipeline_id, widget->priv.size,
> > + fw_id) < 0) {
> > + printf("error: load filewrite\n");
> > + return -EINVAL;
> > + }
> > + break;
> > + case(SND_SOC_TPLG_DAPM_BUFFER):
> > + /* load buffer */
> > + if (load_buffer(sof,
> > temp_comp_list[comp_index].id,
> > + pipeline_id, widget->priv.size) <
> > 0) {
> > + printf("error: load buffer\n");
> > + return -EINVAL;
> > + }
> > + break;
> > + case(SND_SOC_TPLG_DAPM_SCHEDULER):
> > + /* load pipeline */
> > + if (load_pipeline(sof, pipeline,
> > + temp_comp_list[comp_index].id,
> > + pipeline_id,
> > + widget->priv.size,
> > + sched_id) < 0) {
> > + printf("error: load buffer\n");
> > + return -EINVAL;
> > + }
> > + break;
> > + default:
> > + printf("Widget type not supported %d\n",
> > + widget->id);
> > + break;
> > + }
> > + /* load widget kcontrols */
> > + if (widget->num_kcontrols > 0)
> > + if (load_controls(sof, widget->num_kcontrols) < 0)
> > {
> > + printf("error: load buffer\n");
> > + return -EINVAL;
> > + }
> > + free(widget);
> > + return 0;
> > +}
> > +
> > +/* parse topology file and set up pipeline */
> > +int parse_topology(char *filename, struct sof *sof, int *fr_id,
> > int *fw_id,
> > + int *sched_id, char *bits_in, char *in_file,
> > + char *out_file, void *volume_library)
> > +{
> > + struct snd_soc_tplg_hdr *hdr;
> > +
> > + struct comp_info *temp_comp_list = NULL;
> > + struct sof_ipc_pipe_new pipeline;
> > + char message[DEBUG_MSG_LEN];
> > + int next_comp_id = 0, num_comps = 0;
> > + int i, ret = 0;
> > + size_t file_size, size;
> > +
> > + /* set volume library */
> > + volume_lib = volume_library;
> > +
> > + /* open topology file */
> > + file = fopen(filename, "rb");
> > + if (!file) {
> > + fprintf(stderr, "error: opening file %s",
> > filename);
> > + return -EINVAL;
> > + }
> > +
> > + /* set up fileread and filewrite file names */
> > + input_file = strdup(in_file);
> > + output_file = strdup(out_file);
> > +
> > + /* file size */
> > + fseek(file, 0, SEEK_END);
> > + file_size = ftell(file);
> > + fseek(file, 0, SEEK_SET);
> > +
> > + /* allocate memory */
> > + size = sizeof(struct snd_soc_tplg_hdr);
> > + hdr = (struct snd_soc_tplg_hdr *)malloc(size);
> > + if (!hdr) {
> > + printf("error: mem alloc\n");
> > + return -EINVAL;
> > + }
> > +
> > + debug_print("topology parsing start\n");
> > + while (1) {
> > + /* read topology header */
> > + ret = fread(hdr, sizeof(struct snd_soc_tplg_hdr),
> > 1, file);
> > + if (ret != 1)
> > + return -EINVAL;
> > +
> > + sprintf(message, "type: %x, size: 0x%x count: %d
> > index:
> > %d\n",
> > + hdr->type, hdr->payload_size, hdr->count,
> > hdr-
> > > index);
> >
> > + debug_print(message);
> > +
> > + /* parse header and load the next block based on
> > type */
> > + switch (hdr->type) {
> > + case SND_SOC_TPLG_TYPE_DAPM_WIDGET:
> > + /* load dapm widget */
> > + sprintf(message, "number of DAPM widgets
> > %d\n",
> > + hdr->count);
> > + debug_print(message);
> > + size = sizeof(struct comp_info) * hdr-
> > >count;
> > + temp_comp_list = (struct comp_info
> > *)malloc(size);
> > + num_comps = hdr->count;
> > +
> > + for (i = 0; i < hdr->count; i++)
> > + load_widget(sof, fr_id, fw_id,
> > sched_id,
> > + bits_in,
> > temp_comp_list,
> > + &pipeline,
> > next_comp_id++,
> > + i, hdr->index);
> > + break;
> > + case SND_SOC_TPLG_TYPE_DAPM_GRAPH:
> > + /* set up component connections from
> > pipeline graph
> > */
> > + if (load_graph(sof, temp_comp_list, hdr-
> > >count,
> > + num_comps, hdr->index) < 0)
> > {
> > + printf("error: pipeline graph\n");
> > + return -EINVAL;
> > + }
> > +
> > + if (ftell(file) == file_size)
> > + goto finish;
> > + break;
> > + default:
> > + fseek(file, hdr->payload_size, SEEK_CUR);
> > + if (ftell(file) == file_size)
> > + goto finish;
> > + break;
> > + }
> > + }
> > +finish:
> > + debug_print("topology parsing end\n");
> > + /* free all data */
> > + free(hdr);
> > + free(temp_comp_list);
> > + fclose(file);
> > + return 0;
> > +}
> > +
> > +/* parse vendor tokens in topology */
> > +int sof_parse_tokens(void *object, const struct sof_topology_token
> > *tokens,
> > + int count, struct snd_soc_tplg_vendor_array
> > *array,
> > + int priv_size)
> > +{
> > + int asize;
> > +
> > + while (priv_size > 0) {
> > + asize = array->size;
> > +
> > + /* validate asize */
> > + if (asize < 0) { /* FIXME: A zero-size array makes
> > no sense
> > */
> > + printf("error: invalid array size 0x%x\n",
> > asize);
> > + return -EINVAL;
> > + }
> > +
> > + /* make sure there is enough data before parsing
> > */
> > + priv_size -= asize;
> > +
> > + if (priv_size < 0) {
> > + printf("error: invalid array size 0x%x\n",
> > asize);
> > + return -EINVAL;
> > + }
> > +
> > + /* call correct parser depending on type */
> > + switch (array->type) {
> > + case SND_SOC_TPLG_TUPLE_TYPE_UUID:
> > + sof_parse_uuid_tokens(object, tokens,
> > count,
> > + array);
> > + break;
> > + case SND_SOC_TPLG_TUPLE_TYPE_STRING:
> > + sof_parse_string_tokens(object, tokens,
> > count,
> > + array);
> > + break;
> > + case SND_SOC_TPLG_TUPLE_TYPE_BOOL:
> > + case SND_SOC_TPLG_TUPLE_TYPE_BYTE:
> > + case SND_SOC_TPLG_TUPLE_TYPE_WORD:
> > + case SND_SOC_TPLG_TUPLE_TYPE_SHORT:
> > + sof_parse_word_tokens(object, tokens,
> > count,
> > + array);
> > + break;
> > + default:
> > + printf("error: unknown token type %d\n",
> > array-
> > > type);
> >
> > + return -EINVAL;
> > + }
> > +
> > + /* next array */
> > + array = (void *)array + asize;
> > + }
> > + return 0;
> > +}
> > +
> > +void sof_parse_word_tokens(void *object,
> > + const struct sof_topology_token
> > *tokens,
> > + int count,
> > + struct snd_soc_tplg_vendor_array
> > *array)
> > +{
> > + struct snd_soc_tplg_vendor_value_elem *elem;
> > + int i, j;
> > +
> > + /* parse element by element */
> > + for (i = 0; i < array->num_elems; i++) {
> > + elem = &array->value[i];
> > +
> > + /* search for token */
> > + for (j = 0; j < count; j++) {
> > + /* match token type */
> > + if (tokens[j].type !=
> > SND_SOC_TPLG_TUPLE_TYPE_WORD)
> > + continue;
> > +
> > + /* match token id */
> > + if (tokens[j].token != elem->token)
> > + continue;
> > +
> > + /* matched - now load token */
> > + tokens[j].get_token(elem, object,
> > tokens[j].offset,
> > + tokens[j].size);
> > + }
> > + }
> > +}
> > +
> > +void sof_parse_uuid_tokens(void *object,
> > + const struct sof_topology_token
> > *tokens,
> > + int count,
> > + struct snd_soc_tplg_vendor_array
> > *array)
> > +{
> > + struct snd_soc_tplg_vendor_uuid_elem *elem;
> > + int i, j;
> > +
> > + /* parse element by element */
> > + for (i = 0; i < array->num_elems; i++) {
> > + elem = &array->uuid[i];
> > +
> > + /* search for token */
> > + for (j = 0; j < count; j++) {
> > + /* match token type */
> > + if (tokens[j].type !=
> > SND_SOC_TPLG_TUPLE_TYPE_UUID)
> > + continue;
> > +
> > + /* match token id */
> > + if (tokens[j].token != elem->token)
> > + continue;
> > +
> > + /* matched - now load token */
> > + tokens[j].get_token(elem, object,
> > tokens[j].offset,
> > + tokens[j].size);
> > + }
> > + }
> > +}
> > +
> > +void sof_parse_string_tokens(void *object,
> > + const struct sof_topology_token
> > *tokens,
> > + int count,
> > + struct snd_soc_tplg_vendor_array
> > *array)
> > +{
> > + struct snd_soc_tplg_vendor_string_elem *elem;
> > + int i, j;
> > +
> > + /* parse element by element */
> > + for (i = 0; i < array->num_elems; i++) {
> > + elem = &array->string[i];
> > +
> > + /* search for token */
> > + for (j = 0; j < count; j++) {
> > + /* match token type */
> > + if (tokens[j].type !=
> > SND_SOC_TPLG_TUPLE_TYPE_STRING)
> > + continue;
> > +
> > + /* match token id */
> > + if (tokens[j].token != elem->token)
> > + continue;
> > +
> > + /* matched - now load token */
> > + tokens[j].get_token(elem, object,
> > tokens[j].offset,
> > + tokens[j].size);
> > + }
> > + }
> > +}
> > +
> > +enum sof_ipc_frame find_format(const char *name)
> > +{
> > + int i;
> > +
> > + for (i = 0; i < ARRAY_SIZE(sof_frames); i++) {
> > + if (strcmp(name, sof_frames[i].name) == 0)
> > + return sof_frames[i].frame;
> > + }
> > +
> > + /* use s32le if nothing is specified */
> > + return SOF_IPC_FRAME_S32_LE;
> > +}
> > +
> > +int get_token_uint32_t(void *elem, void *object, uint32_t offset,
> > + uint32_t size)
> > +{
> > + struct snd_soc_tplg_vendor_value_elem *velem = elem;
> > + uint32_t *val = object + offset;
> > +
> > + *val = velem->value;
> > + return 0;
> > +}
> > +
> > +int get_token_comp_format(void *elem, void *object, uint32_t
> > offset,
> > + uint32_t size)
> > +{
> > + struct snd_soc_tplg_vendor_string_elem *velem = elem;
> > + uint32_t *val = object + offset;
> > +
> > + *val = find_format(velem->string);
> > + return 0;
> > +}
> > diff --git a/tune/src/trace.c b/tune/src/trace.c
> > new file mode 100644
> > index 0000000..67580ca
> > --- /dev/null
> > +++ b/tune/src/trace.c
> > @@ -0,0 +1,150 @@
> > +/*
> > + * Copyright (c) 2018, Intel Corporation
> > + * All rights reserved.
> > + *
> > + * Redistribution and use in source and binary forms, with or
> > without
> > + * modification, are permitted provided that the following
> > conditions are
> > met:
> > + * * Redistributions of source code must retain the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer.
> > + * * Redistributions in binary form must reproduce the above
> > copyright
> > + * notice, this list of conditions and the following
> > disclaimer in the
> > + * documentation and/or other materials provided with the
> > distribution.
> > + * * Neither the name of the Intel Corporation nor the
> > + * names of its contributors may be used to endorse or promote
> > products
> > + * derived from this software without specific prior written
> > permission.
> > + *
> > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> > CONTRIBUTORS "AS
> > IS"
> > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> > LIMITED TO, THE
> > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
> > PARTICULAR PURPOSE
> > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
> > CONTRIBUTORS BE
> > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
> > EXEMPLARY, OR
> > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
> > PROCUREMENT OF
> > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> > BUSINESS
> > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
> > WHETHER IN
> > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> > OTHERWISE)
> > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
> > ADVISED OF THE
> > + * POSSIBILITY OF SUCH DAMAGE.
> > + *
> > + * Author: Seppo Ingalsuo <seppo.ingalsuo at linux.intel.com>
> > + * Liam Girdwood <liam.r.girdwood at linux.intel.com>
> > + * Keyon Jie <yang.jie at linux.intel.com>
> > + * Ranjani Sridharan <ranjani.sridharan at linux.intel.com>
> > + */
> > +
> > +#include <stdint.h>
> > +#include <stdio.h>
> > +#include <string.h>
> > +#include "common_test.h"
> > +
> > +/* testbench trace definition */
> > +
> > +/* enable trace by default in testbench */
> > +static int test_bench_trace = 1;
> > +
> > +/* TODO: include firmware trace.h to keep in sync with new types
> > */
> > +static char *get_trace_class(uint32_t trace_class)
> > +{
> > + switch (trace_class) {
> > + case 1:
> > + return "irq";
> > + case 2:
> > + return "ipc";
> > + case 3:
> > + return "pipe";
> > + case 4:
> > + return "host";
> > + case 5:
> > + return "dai";
> > + case 6:
> > + return "dma";
> > + case 7:
> > + return "ssp";
> > + case 8:
> > + return "comp";
> > + case 9:
> > + return "wait";
> > + case 10:
> > + return "lock";
> > + case 11:
> > + return "mem";
> > + case 12:
> > + return "mixer";
> > + case 13:
> > + return "buffer";
> > + case 14:
> > + return "volume";
> > + case 15:
> > + return "switch";
> > + case 16:
> > + return "mux";
> > + case 17:
> > + return "src";
> > + case 18:
> > + return "tone";
> > + case 19:
> > + return "eq_fir";
> > + case 20:
> > + return "eq_iir";
> > + case 21:
> > + return "sa";
> > + default:
> > + return "value";
> > + }
> > +}
> > +
> > +/* print trace event */
> > +void _trace_event(uint32_t event)
> > +{
> > + char a, b, c;
> > + char *trace_class;
> > +
> > + if (test_bench_trace > 0) {
> > + a = event & 0xff;
> > + b = (event >> 8) & 0xff;
> > + c = (event >> 16) & 0xff;
> > + trace_class = strdup(get_trace_class(event >>
> > 24));
> > + if (strcmp(trace_class, "value") == 0)
> > + fprintf(stderr, "Trace value %d\n",
> > event);
> > + else
> > + fprintf(stderr, "Trace %s %c%c%c\n",
> > trace_class,
> > + c, b, a);
> > + }
> > +}
> > +
> > +/* print trace error */
> > +void _trace_error(uint32_t event)
> > +{
> > + char a, b, c;
> > +
> > + if (test_bench_trace > 0) {
> > + a = event & 0xff;
> > + b = (event >> 8) & 0xff;
> > + c = (event >> 16) & 0xff;
> > + fprintf(stderr, "trace error: %s %c%c%c\n",
> > + get_trace_class(event >> 24), c, b, a);
> > + }
> > +}
> > +
> > +void _trace_error_atomic(uint32_t event)
> > +{
> > + _trace_error(event);
> > +}
> > +
> > +void _trace_event_mbox_atomic(uint32_t event)
> > +{
> > + _trace_event(event);
> > +}
> > +
> > +/* enable trace in testbench */
> > +void tb_enable_trace(void)
> > +{
> > + test_bench_trace = 1;
> > + debug_print("trace print enabled\n");
> > +}
> > +
> > +/* disable trace in testbench */
> > +void tb_disable_trace(void)
> > +{
> > + test_bench_trace = 0;
> > + debug_print("trace print disabled\n");
> > +}
More information about the Sound-open-firmware
mailing list