summaryrefslogtreecommitdiff
path: root/hifi/xaf/hifi-dpf/core/xf-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'hifi/xaf/hifi-dpf/core/xf-core.c')
-rw-r--r--hifi/xaf/hifi-dpf/core/xf-core.c709
1 files changed, 0 insertions, 709 deletions
diff --git a/hifi/xaf/hifi-dpf/core/xf-core.c b/hifi/xaf/hifi-dpf/core/xf-core.c
deleted file mode 100644
index 95bca129..00000000
--- a/hifi/xaf/hifi-dpf/core/xf-core.c
+++ /dev/null
@@ -1,709 +0,0 @@
-/*******************************************************************************
-* Copyright (C) 2018 Cadence Design Systems, Inc.
-*
-* Permission is hereby granted, free of charge, to any person obtaining
-* a copy of this software and associated documentation files (the
-* "Software"), to use this Software with Cadence processor cores only and
-* not with any other processors and platforms, subject to
-* the following conditions:
-*
-* The above copyright notice and this permission notice shall be included
-* in all copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-******************************************************************************/
-
-/*******************************************************************************
- * xf-core.c
- *
- * DSP processing framework core
- *
- ******************************************************************************/
-
-#define MODULE_TAG CORE
-
-/*******************************************************************************
- * Includes
- ******************************************************************************/
-
-#include "xf.h"
-
-/*******************************************************************************
- * Tracing tags
- ******************************************************************************/
-
-/* ...general initialization sequence */
-TRACE_TAG(INIT, 1);
-
-/* ...message dispatching */
-TRACE_TAG(DISP, 1);
-
-/* ...client registration procedures */
-TRACE_TAG(REG, 1);
-
-/* ...ports routing/unrouting */
-TRACE_TAG(ROUTE, 1);
-
-#ifdef XAF_PROFILE_DSP
-/* ... MCPS/profile info */
-#include "xa_profiler.h"
-#endif
-/*******************************************************************************
- * Internal helpers
- ******************************************************************************/
-
-/* ...translate client-id into component handle */
-static inline xf_component_t * xf_client_lookup(xf_core_data_t *cd, u32 client)
-{
- xf_cmap_link_t *link = &cd->cmap[client];
-
- /* ...if link pointer is less than XF_CFG_MAX_CLIENTS, it is a free descriptor */
- return (link->next > XF_CFG_MAX_CLIENTS ? link->c : NULL);
-}
-
-/* ...allocate client-id */
-static inline u32 xf_client_alloc(xf_core_data_t *cd)
-{
- u32 client = cd->free;
-
- /* ...advance list head to next free id */
- (client < XF_CFG_MAX_CLIENTS ? cd->free = cd->cmap[client].next : 0);
-
- return client;
-}
-
-/* ...recycle client-id */
-static inline void xf_client_free(xf_core_data_t *cd, u32 client)
-{
- /* ...put client into the head of the free id list */
- cd->cmap[client].next = cd->free, cd->free = client;
-}
-
-/*******************************************************************************
- * Process commands to a proxy
- ******************************************************************************/
-
-/* ...register new client */
-static int xf_proxy_register(u32 core, xf_message_t *m)
-{
- xf_core_data_t *cd = XF_CORE_DATA(core);
- u32 src = XF_MSG_SRC(m->id);
- u32 client;
- xf_component_t *component;
-
- /* ...allocate new client-id */
- XF_CHK_ERR((client = xf_client_alloc(cd)) != XF_CFG_MAX_CLIENTS, -EBUSY);
-
- /* ...create component via class factory */
- if ((component = xf_component_factory(core, m->buffer, m->length)) == NULL)
- {
- TRACE(ERROR, _x("Component creation failed"));
-
- /* ...recycle client-id */
- xf_client_free(cd, client);
-
- /* ...return generic out-of-memory code always (tbd) */
- return -ENOMEM;
- }
-
- /* ...register component in a map */
- cd->cmap[client].c = component;
-
- /* ...set component "default" port specification ("destination") */
- component->id = __XF_PORT_SPEC(core, client, 0);
-
- /* ...adjust session-id to include newly created component-id */
- m->id = __XF_MSG_ID(src, component->id);
-
- /* ...do system-specific registration of component within IPC layer */
- xf_ipc_component_addref(m->id);
-
- TRACE(REG, _b("registered client: %u:%u (%s)"), core, client, (xf_id_t)m->buffer);
-
- /* ...and return success to remote proxy (zero-length output) */
- xf_response_ok(m);
-
- return 0;
-}
-
-/* ...shared buffer allocation request */
-static int xf_proxy_alloc(u32 core, xf_message_t *m)
-{
- /* ...command is valid only if shared memory interface for core is specified */
- XF_CHK_ERR(xf_shmem_enabled(core), -EPERM);
-
- /* ...allocate shared memory buffer (system-specific function; may fail) */
- xf_shmem_alloc(core, m);
-
- /* ...pass result to remote proxy (on success buffer is non-null) */
- xf_response(m);
-
- return 0;
-}
-
-/* ...shared buffer freeing request */
-static int xf_proxy_free(u32 core, xf_message_t *m)
-{
- /* ...command is valid only if shared memory interface for core is specified */
- XF_CHK_ERR(xf_shmem_enabled(core), -EPERM);
-
- /* ...pass buffer freeing request to system-specific function */
- xf_shmem_free(core, m);
-
- /* ...return success to remote proxy (function never fails) */
- xf_response(m);
-
- return 0;
-}
-
-#if 0
-/* ...port routing command processing */
-static int xf_proxy_route(u32 core, xf_message_t *m)
-{
- xf_route_port_msg_t *cmd = m->buffer;
- u32 src = cmd->src;
- u32 dst = cmd->dst;
- xf_component_t *component;
- xf_output_port_t *port;
-
- /* ...source component must reside on the local core */
- XF_CHK_ERR(XF_MSG_SRC_CORE(src) == core, -EINVAL);
-
- /* ...make sure the "src" component is valid ("dst" may reside on other core) */
- if ((component = xf_client_lookup(XF_CORE_DATA(core), XF_PORT_CLIENT(src))) == NULL)
- {
- TRACE(ERROR, _x("Source port lookup failed: %x"), src);
- return -ENOENT;
- }
- else if (!component->port || !(port = component->port(component, XF_PORT_ID(src))))
- {
- TRACE(ERROR, _b("Source port doesn't exist: %x"), src);
- return -ENOENT;
- }
- else if (xf_output_port_routed(port))
- {
- TRACE(ERROR, _b("Source port is already routed: %x"), src);
- return -EBUSY;
- }
-
- /* ...route output port with source port set as destination */
- XF_CHK_API(xf_output_port_route(port, __XF_MSG_ID(dst, src), cmd->alloc_number, cmd->alloc_size, cmd->alloc_align));
-
- TRACE(ROUTE, _b("Ports routed: %03x -> %03x"), src, dst);
-
- /* ...invoke component data-processing function directly (ignore errors? - tbd) */
- component->entry(component, NULL);
-
- /* ...return success result code (no output attached) */
- xf_response_ok(m);
-
- return 0;
-}
-
-/* ...disconnect ports */
-static int xf_proxy_unroute(u32 core, xf_message_t *m)
-{
- xf_unroute_port_msg_t *cmd = m->buffer;
- u32 src = cmd->src;
- xf_component_t *component;
- xf_output_port_t *port;
-
- /* ...source component must reside on the local core */
- XF_CHK_ERR(XF_MSG_SRC_CORE(src) == core, -EINVAL);
-
- /* ...lookup source (output) port */
- if ((component = xf_client_lookup(XF_CORE_DATA(core), XF_PORT_CLIENT(src))) == NULL)
- {
- TRACE(ERROR, _b("Source port lookup failed: %x"), src);
- return -ENOENT;
- }
- else if (!component->port || !(port = component->port(component, XF_PORT_ID(src))))
- {
- TRACE(ERROR, _b("Source port doesn't exist: %x"), src);
- return -ENOENT;
- }
- else if (!xf_output_port_routed(port))
- {
- /* ...port is not routed; satisfy immediately */
- goto done;
- }
- else if (!xf_output_port_idle(port))
- {
- TRACE(ERROR, _b("Source port is not idle: %x"), src);
- return -EBUSY;
- }
-
- /* ...unroute port (call must succeed) */
- xf_output_port_unroute(port);
-
- /* ...we cannot satisfy the command now, and need to propagate it to a sink - tbd */
- //return 0;
-
-done:
- /* ...pass success result code to caller */
- xf_response_ok(m);
-
- return 0;
-}
-#endif
-
-/* ...fill-this-buffer command processing */
-static int xf_proxy_output(u32 core, xf_message_t *m)
-{
- /* ...determine destination "client" */
- switch (XF_MSG_SRC_CLIENT(m->id))
- {
-#if XF_TRACE_REMOTE
- case 0:
- /* ...destination is a tracer facility; submit buffer to tracer */
- xf_trace_submit(core, m);
- return 0;
-#endif
-
- default:
- /* ...unrecognized destination; return general failure response */
- return XF_CHK_ERR(0, -EINVAL);
- }
-}
-
-/* ...flush command processing */
-static int xf_proxy_flush(u32 core, xf_message_t *m)
-{
- /* ...determine destination "client" */
- switch (XF_MSG_SRC_CLIENT(m->id))
- {
-#if XF_TRACE_REMOTE
- case 0:
- /* ...destination is a tracer facility; flush current buffer */
- xf_trace_flush(core, m);
- return 0;
-#endif
-
- default:
- /* ...unrecognized destination; return general failure response */
- return XF_CHK_ERR(0, -EINVAL);
- }
-}
-
-/* ...proxy command processing table */
-static int (* const xf_proxy_cmd[])(u32, xf_message_t *) =
-{
- [XF_OPCODE_TYPE(XF_REGISTER)] = xf_proxy_register,
- [XF_OPCODE_TYPE(XF_ALLOC)] = xf_proxy_alloc,
- [XF_OPCODE_TYPE(XF_FREE)] = xf_proxy_free,
-#if 0
- [XF_OPCODE_TYPE(XF_ROUTE)] = xf_proxy_route,
- [XF_OPCODE_TYPE(XF_UNROUTE)] = xf_proxy_unroute,
-#endif
- [XF_OPCODE_TYPE(XF_FILL_THIS_BUFFER)] = xf_proxy_output,
- [XF_OPCODE_TYPE(XF_FLUSH)] = xf_proxy_flush,
-};
-
-/* ...total number of commands supported */
-#define XF_PROXY_CMD_NUM (sizeof(xf_proxy_cmd) / sizeof(xf_proxy_cmd[0]))
-
-/* ...process commands to a proxy */
-static void xf_proxy_command(u32 core, xf_message_t *m)
-{
- u32 opcode = m->opcode;
- int res;
-
- /* ...dispatch command to proper hook */
- if (XF_OPCODE_TYPE(opcode) < XF_PROXY_CMD_NUM)
- {
- if ((res = xf_proxy_cmd[XF_OPCODE_TYPE(opcode)](core, m)) >= 0)
- {
- /* ...command processed successfully; do nothing */
- return;
- }
- }
- else
- {
- TRACE(ERROR, _x("invalid opcode: %x"), opcode);
- }
-
- /* ...command processing failed; return generic failure response */
- xf_response_err(m);
-}
-
-/*******************************************************************************
- * Message completion helper
- ******************************************************************************/
-
-/* ...put message into local IPC command queue on remote core (src != dst) */
-static inline void xf_msg_local_ipc_put(u32 src, u32 dst, xf_message_t *m)
-{
- xf_core_rw_data_t *rw = XF_CORE_RW_DATA(dst);
- int first;
-
- /* ...flush message payload if needed */
- if (XF_LOCAL_IPC_NON_COHERENT)
- {
- /* ...it may be a command with output payload only - tbd */
- XF_PROXY_FLUSH(m->buffer, m->length);
- }
-
- /* ...acquire mutex to target rw-data (running on source core) */
- xf_mutex_lock(src);
-
- /* ...assure memory coherency as needed */
- if (XF_LOCAL_IPC_NON_COHERENT)
- {
- /* ...invalidate local queue data */
- XF_PROXY_INVALIDATE(&rw->local, sizeof(rw->local));
-
- /* ...place message into queue */
- first = xf_msg_enqueue(&rw->local, m);
-
- /* ...flush both queue and message data */
- XF_PROXY_FLUSH(&rw->local, sizeof(rw->local)), XF_PROXY_FLUSH(m, sizeof(*m));
- }
- else
- {
- /* ...just enqueue the message */
- first = xf_msg_enqueue(&rw->local, m);
- }
-
- /* ...release global rw-memory access lock */
- xf_mutex_unlock(src);
-
- /* ...signal IPI interrupt on destination core as needed */
- (first ? xf_ipi_assert(dst), 1 : 0);
-}
-
-/* ...dequeue message from core-specific dispatch queue */
-static inline xf_message_t * xf_msg_local_ipc_get(u32 core)
-{
- xf_core_rw_data_t *rw = XF_CORE_RW_DATA(core);
- xf_message_t *m;
-
- /* ...retrieve message from queue in atomic fashion */
- xf_mutex_lock(core);
-
- /* ...process memory coherency as required */
- if (XF_LOCAL_IPC_NON_COHERENT)
- {
- /* ...inavlidate local rw-data */
- XF_PROXY_INVALIDATE(&rw->local, sizeof(rw->local));
-
- /* ...get message from the queue */
- if ((m = xf_msg_dequeue(&rw->local)) != NULL)
- {
- /* ...flush rw-queue data */
- XF_PROXY_FLUSH(&rw->local, sizeof(rw->local));
- }
- }
- else
- {
- /* ...just dequeue message from the queue */
- m = xf_msg_dequeue(&rw->local);
- }
-
- /* ...release rw-memory access lock */
- xf_mutex_unlock(core);
-
- /* ...invalidate message header and data as needed */
- if (XF_LOCAL_IPC_NON_COHERENT && m != NULL)
- {
- /* ...invalidate message header */
- XF_PROXY_INVALIDATE(m, sizeof(*m));
-
- /* ...and data if needed (it may not be always needed - tbd) */
- (m->length ? XF_PROXY_INVALIDATE(m->buffer, m->length) : 0);
- }
-
- /* ...return message */
- return m;
-}
-
-/* ...retrieve message from local queue (protected from ISR) */
-static inline int xf_msg_local_put(u32 core, xf_message_t *m)
-{
- xf_core_data_t *cd = XF_CORE_DATA(core);
- int first;
- u32 status;
-
- /* ...use interrupt masking protocol to protect message queue */
- status = xf_isr_disable(core);
- first = xf_msg_enqueue(&cd->queue, m);
- xf_isr_restore(core, status);
-
- return first;
-}
-
-/* ...retrieve message from local queue (protected from ISR) */
-static inline xf_message_t * xf_msg_local_get(u32 core)
-{
- xf_core_data_t *cd = XF_CORE_DATA(core);
- xf_message_t *m;
- u32 status;
-
- /* ...use interrupt masking protocol to protect message queue */
- status = xf_isr_disable(core);
- m = xf_msg_dequeue(&cd->queue);
- xf_isr_restore(core, status);
-
- return m;
-}
-
-/* ...retrieve message from local queue (protected from ISR) */
-static inline xf_message_t * xf_msg_local_response_get(u32 core)
-{
- xf_core_data_t *cd = XF_CORE_DATA(core);
- xf_message_t *m;
- u32 status;
-
- /* ...use interrupt masking protocol to protect message queue */
- status = xf_isr_disable(core);
- m = xf_msg_dequeue(&cd->response);
- xf_isr_restore(core, status);
-
- return m;
-}
-
-/* ...call component data processing function */
-static inline void xf_core_process(xf_component_t *component)
-{
- u32 id = component->id;
-
- /* ...client look-up successfull */
- TRACE(DISP, _b("core[%u]::client[%u]::process"), XF_PORT_CORE(id), XF_PORT_CLIENT(id));
-
- /* ...call data-processing interface */
- if (component->entry(component, NULL) < 0)
- {
- TRACE(ERROR, _b("execution error (ignored)"));
- }
-}
-
-/* ...dispatch message queue execution */
-static inline void xf_core_dispatch(xf_core_data_t *cd, u32 core, xf_message_t *m)
-{
- u32 client;
- xf_component_t *component;
-
- /* ...do client-id/component lookup */
- if (XF_MSG_DST_PROXY(m->id))
- {
- TRACE(DISP, _b("core[%u]::proxy-cmd(id=%x, opcode=%x)"), core, m->id, m->opcode);
-
- /* ...process message addressed to proxy */
- xf_proxy_command(core, m);
-
- /* ...do not like this return statement... - tbd */
- return;
- }
-
- /* ...message goes to local component */
- client = XF_MSG_DST_CLIENT(m->id);
-
- /* ...check if client is alive */
- if ((component = xf_client_lookup(cd, client)) != NULL)
- {
- /* ...client look-up successfull */
- TRACE(DISP, _b("core[%u]::client[%u]::cmd(id=%x, opcode=%x)"), core, client, m->id, m->opcode);
-
- /* ...pass message to component entry point */
- if (component->entry(component, m) < 0)
- {
- /* ...call component destructor */
- if (component->exit(component, m) == 0)
- {
- /* ...component cleanup completed; recycle component-id */
- xf_client_free(cd, client);
-
- /* ...do system-specific deregistration of component within IPC layer */
- xf_ipc_component_rmref(__XF_PORT_SPEC(core, client, 0));
- }
- }
- }
- else
- {
- TRACE(DISP, _b("Discard message id=%x - client %u:%u not registered"), m->id, core, client);
-
- /* ...complete message with general failure response */
- xf_response_err(m);
- }
-}
-
-/*******************************************************************************
- * Entry points
- ******************************************************************************/
-
-/* ...submit message for instant execution on some core */
-void xf_msg_submit(xf_message_t *m)
-{
- u32 src = XF_MSG_SRC_CORE(m->id);
- u32 dst = XF_MSG_DST_CORE(m->id);
-
- /* ...check if message shall go through local IPC layer */
- if (src ^ dst)
- {
- /* ...put message into local IPC queue */
- xf_msg_local_ipc_put(src, dst, m);
- }
- else
- {
- /* ...message is addressed to same core */
- xf_msg_local_put(src, m);
- }
-}
-
-/* ...complete message and pass response to a caller */
-void xf_msg_complete(xf_message_t *m)
-{
- u32 src = XF_MSG_SRC(m->id);
- u32 dst = XF_MSG_DST(m->id);
-
- /* ...swap src/dst specifiers */
- m->id = __XF_MSG_ID(dst, src);
-
- /* ...check if message goes to remote IPC layer */
- if (XF_MSG_DST_PROXY(m->id))
- {
- /* ...return message to proxy */
- xf_msg_proxy_complete(m);
- }
- else
- {
- /* ...destination is within DSP cluster; check if that is a data buffer */
- switch (m->opcode)
- {
- case XF_EMPTY_THIS_BUFFER:
- /* ...emptied buffer goes back to the output port */
- m->opcode = XF_FILL_THIS_BUFFER;
- break;
-
- case XF_FILL_THIS_BUFFER:
- /* ...filled buffer is passed to the input port */
- m->opcode = XF_EMPTY_THIS_BUFFER;
- break;
- }
-
- /* ...submit message for execution */
- xf_msg_submit(m);
- }
-}
-
-/* ...initialize per-core framework data */
-int xf_core_init(u32 core)
-{
- xf_core_data_t *cd = XF_CORE_DATA(core);
- xf_cmap_link_t *link;
- u32 i;
-
- /* ...create list of free client descriptors */
- for (link = &cd->cmap[i = 0]; i < XF_CFG_MAX_CLIENTS; i++, link++)
- {
- link->next = i + 1;
- }
-
- /* ...set head of free clients list */
- cd->free = 0;
-
- /* ...initialize local queue scheduler */
- xf_sched_init(&cd->sched);
-
- /* ...initialize IPI subsystem */
- XF_CHK_API(xf_ipi_init(core));
-
- /* ...initialize shared read-write memory */
- XF_CHK_API(xf_shmem_enabled(core) ? xf_shmem_init(core) : 0);
-
- /* ...initialize scratch memory */
- XF_CHK_ERR(cd->scratch = xf_scratch_mem_init(core), -ENOMEM);
-
- /* ...okay... it's all good */
- TRACE(INIT, _b("core-%u initialized"), core);
-
- return 0;
-}
-
-/* ...core executive loop function */
-void xf_core_service(u32 core)
-{
- xf_core_data_t *cd = &xf_core_data[core];
- u32 status;
- xf_message_t *m;
- xf_task_t *t;
-
-#ifdef XAF_PROFILE_DSP
- START_TIME_XA_PROFILER(prof);
-#endif
- do
- {
- /* ...clear local status change */
- status = 0;
-
- /* ...if core is servicing shared memory with AP, do it first - actually, they all need to support it */
- if (xf_shmem_enabled(core))
- {
- /* ...process all commands */
- xf_shmem_process_queues(core);
- }
-
- /* ...check if we have a backlog message placed into interim queue */
- while ((m = xf_msg_local_ipc_get(core)) || (m = xf_msg_local_get(core)))
- {
- /* ...dispatch message execution */
- xf_core_dispatch(cd, core, m);
-
- /* ...set local status change */
- status = 1;
- }
-
- /* ...check if we have pending responses (submitted from ISR) we need to process */
- while ((m = xf_msg_local_response_get(core)) != NULL)
- {
- /* ...call completion handler on current stack */
- xf_msg_complete(m);
-
- /* ...set local status change */
- status = 1;
-
- }
-
- /* ...if scheduler queue is empty, break the loop and pause the core */
- if ((t = xf_sched_get(&cd->sched)) != NULL)
- {
- /* ...data-processing execution (ignore internal errors) */
- xf_core_process((xf_component_t *)t);
-
- /* ...set local status change */
- status = 1;
- }
- }
- while (status);
-
-#ifdef XAF_PROFILE_DSP
- STOP_TIME_XA_PROFILER(prof);
-
- if(prof.g_output_bytes)
- {
- unsigned long output_samples = prof.g_output_bytes;
- output_samples >>= (prof.channels == 2 ? 1 : 0);
- output_samples >>= (prof.pcm_width == 24 ? 2 : 1);
-
- COMPUTE_MHZ_XA_PROFILER(prof, output_samples, prof.sample_rate, 0);
-
- prof.g_output_bytes = prof.cycles = 0; /* reset counters */
- }
-#endif
-
-}
-
-/* ...global data initialization function */
-int xf_global_init(void)
-{
- /* ...what global data we have to initialize? - tbd */
- TRACE(INIT, _b("Global data initialized"));
-
- return 0;
-}