diff options
Diffstat (limited to 'hifi/xaf/hifi-dpf/core/xf-shmem.c')
-rw-r--r-- | hifi/xaf/hifi-dpf/core/xf-shmem.c | 350 |
1 files changed, 0 insertions, 350 deletions
diff --git a/hifi/xaf/hifi-dpf/core/xf-shmem.c b/hifi/xaf/hifi-dpf/core/xf-shmem.c deleted file mode 100644 index 15d3b1d9..00000000 --- a/hifi/xaf/hifi-dpf/core/xf-shmem.c +++ /dev/null @@ -1,350 +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-shmem.c - * - * DSP shared memory interface implementation - * - ******************************************************************************/ - -#define MODULE_TAG SHMEM - -/******************************************************************************* - * Includes - ******************************************************************************/ - -#include "xf.h" - -/******************************************************************************* - * Tracing tags - ******************************************************************************/ - -/* ...general initialization sequence */ -TRACE_TAG(INIT, 1); - -/* ...interface status change */ -TRACE_TAG(EXEC, 0); - -/* ...command reception */ -TRACE_TAG(CMD, 1); - -/* ...response generation */ -TRACE_TAG(RSP, 1); - -#ifdef XAF_PROFILE_DSP -#include "xa_profiler.h" -#endif -/******************************************************************************* - * Local constants definitions - ******************************************************************************/ - -/* ...local interface status change flag */ -#define XF_PROXY_STATUS_LOCAL (1 << 0) - -/* ...remote status change notification flag */ -#define XF_PROXY_STATUS_REMOTE (1 << 1) - -/******************************************************************************* - * Internal helpers - ******************************************************************************/ - -/* ...put message into proxy queue */ -static inline void xf_msg_proxy_put(xf_message_t *m) -{ - u32 dst = XF_MSG_DST_CORE(m->id); - u32 src = XF_MSG_SRC_CORE(m->id); - xf_core_rw_data_t *rw = XF_CORE_RW_DATA(dst); - int first; - - /* ...get an access to shared rw-memory (we are running on "source" core) */ - xf_mutex_lock(src); - - /* ...assure memory coherency if needed */ - if (XF_REMOTE_IPC_NON_COHERENT) - { - /* ...invalidate rw-shared memory region */ - XF_PROXY_INVALIDATE(rw, sizeof(*rw)); - - /* ...put message into shared queue */ - first = xf_msg_enqueue(&rw->remote, m); - - /* ...flush both message and shared queue data */ - XF_PROXY_FLUSH(rw, sizeof(*rw)), XF_PROXY_FLUSH(m, sizeof(*m)); - } - else - { - /* ...no memory coherency concerns; just place a message in the queue */ - first = xf_msg_enqueue(&rw->remote, m); - } - - /* ...release rw-memory region lock */ - xf_mutex_unlock(src); - - /* ...assert IPI interrupt on target ("destination") core if needed */ - if (first && (dst ^ src)) - { - xf_ipi_assert(dst); - } -} - -/* ...retrieve message from proxy queue */ -static inline xf_message_t * xf_msg_proxy_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); - - /* ...assure memory coherency if needed */ - if (XF_REMOTE_IPC_NON_COHERENT) - { - /* ...invalidate rw-memory */ - XF_PROXY_INVALIDATE(rw, sizeof(*rw)); - - /* ...dequeue message from response queue */ - m = xf_msg_dequeue(&rw->remote); - - /* ...flush rw memory */ - XF_PROXY_FLUSH(rw, sizeof(*rw)); - - /* ...invalidate message data if found */ - (m ? XF_PROXY_INVALIDATE(m, sizeof(*m)) : 0); - } - else - { - /* ...just dequeue message from response queue */ - m = xf_msg_dequeue(&rw->remote); - } - - /* ...release the rw-lock */ - xf_mutex_unlock(core); - - return m; -} - -/******************************************************************************* - * Internal functions definitions - ******************************************************************************/ - -/* ...retrieve all incoming commands from shared memory ring-buffer */ -static u32 xf_shmem_process_input(u32 core) -{ - xf_message_t *m; - u32 read_idx; - u32 write_idx; - u32 status = 0; - - /* ...get current value of write pointer */ - read_idx = XF_PROXY_READ(core, cmd_read_idx); - write_idx = XF_PROXY_READ(core, cmd_write_idx); - - TRACE(EXEC, _b("Command queue: write = %x / read = %x"), write_idx, read_idx); - - /* ...process all committed commands */ - while (!XF_QUEUE_EMPTY(read_idx, write_idx)) - { - xf_proxy_message_t *command; - - /* ...allocate message; the call should not fail */ - if ((m = xf_msg_pool_get(&XF_CORE_RO_DATA(core)->pool)) == NULL) - break; - - /* ...if queue was full, set global proxy update flag */ - if (XF_QUEUE_FULL(read_idx, write_idx)) - status |= XF_PROXY_STATUS_REMOTE | XF_PROXY_STATUS_LOCAL; - else - status |= XF_PROXY_STATUS_LOCAL; - - /* ...get oldest not processed command */ - command = XF_PROXY_COMMAND(core, XF_QUEUE_IDX(read_idx)); - - /* ...synchronize memory contents */ - XF_PROXY_INVALIDATE(command, sizeof(*command)); - - /* ...fill message parameters */ - m->id = command->session_id; - m->opcode = command->opcode; - m->length = command->length; - m->buffer = xf_ipc_a2b(core, command->address); - TRACE(CMD, _b("C[%x]:(%x,%u,%p)"), m->id, m->opcode, m->length, m->buffer); - - /* ...invalidate message buffer contents as required - not here - tbd */ - (XF_OPCODE_CDATA(m->opcode) ? XF_PROXY_INVALIDATE(m->buffer, m->length) : 0); - - /* ...advance local reading index copy */ - read_idx = XF_QUEUE_ADVANCE_IDX(read_idx); - - /* ...update shadow copy of reading index */ - XF_PROXY_WRITE(core, cmd_read_idx, read_idx); - - /* ...and schedule message execution on proper core */ - xf_msg_submit(m); - } - - return status; -} - -/* ...send out all pending outgoing responses to the shared memory ring-buffer */ -static u32 xf_shmem_process_output(u32 core) -{ - xf_message_t *m; - u32 read_idx; - u32 write_idx; - u32 status = 0; - - /* ...get current value of peer read pointer */ - write_idx = XF_PROXY_READ(core, rsp_write_idx); - read_idx = XF_PROXY_READ(core, rsp_read_idx); - - TRACE(EXEC, _b("Response queue: write = %08X / read = %08X"), write_idx, read_idx); - - /* ...while we have response messages and there's space to write out one */ - while (!XF_QUEUE_FULL(read_idx, write_idx)) - { - xf_proxy_message_t *response; - - /* ...remove message from internal queue */ - if ((m = xf_msg_proxy_get(core)) == NULL) - break; - - /* ...notify remote interface each time we send it a message (only if it was empty?) */ - status = XF_PROXY_STATUS_REMOTE | XF_PROXY_STATUS_LOCAL; - -#if 0 - /* ...need to decide on best strategy - tbd */ - if (XF_QUEUE_EMPTY(read_idx, write_idx)) - status |= XF_PROXY_STATUS_REMOTE | XF_PROXY_STATUS_LOCAL; - else - status |= XF_PROXY_STATUS_LOCAL; -#endif - - /* ...flush message buffer contents to main memory as required - too late - different core - tbd */ - (XF_OPCODE_RDATA(m->opcode) ? XF_PROXY_FLUSH(m->buffer, m->length) : 0); - - /* ...find place in a queue for next response */ - response = XF_PROXY_RESPONSE(core, XF_QUEUE_IDX(write_idx)); - - /* ...put the response message fields */ - response->session_id = m->id; - response->opcode = m->opcode; - response->length = m->length; - response->address = xf_ipc_b2a(core, m->buffer); - /* ...flush the content of the caches to main memory */ - XF_PROXY_FLUSH(response, sizeof(*response)); - -#ifdef XAF_PROFILE_DSP - if((m->opcode == XF_FILL_THIS_BUFFER)) - { - if((m->length != 0) && (m->length != 20)) - { - prof.g_output_bytes += (unsigned long)m->length; - } - else if (m->length == 20) - { - /* Profiler re-initialization */ - INIT_XA_PROFILER(prof,"DSP core"); - - /* update stream params on re-init */ - xf_start_msg_t *sm = (xf_start_msg_t *)m->buffer; - prof.sample_rate = sm->sample_rate; - prof.channels = sm->channels; - prof.pcm_width = sm->pcm_width; - } - } -#endif - TRACE(RSP, _b("R[%x]:(%x,%u,%p)"), m->id, m->opcode, m->length, m->buffer); - - /* ...return message back to the pool */ - xf_msg_pool_put(&XF_CORE_RO_DATA(core)->pool, m); - - /* ...advance local writing index copy */ - write_idx = XF_QUEUE_ADVANCE_IDX(write_idx); - - /* ...update shared copy of queue write pointer */ - XF_PROXY_WRITE(core, rsp_write_idx, write_idx); - } - - /* ...return interface status change flags */ - return status; -} - -/******************************************************************************* - * Entry points - ******************************************************************************/ - -/* ...process local/remote shared memory interface status change */ -void xf_shmem_process_queues(u32 core) -{ - u32 status; - - do - { - /* ...acknowledge/clear any pending incoming interrupt */ - XF_PROXY_SYNC_PEER(core); - - /* ...send out pending response messages (frees message buffers, so do it first) */ - status = xf_shmem_process_output(core); - - /* ...receive and forward incoming command messages (allocates message buffers) */ - status |= xf_shmem_process_input(core); - - /* ...assert remote mailbox interrupt if global update bit is set */ - if (status & XF_PROXY_STATUS_REMOTE) - { - XF_PROXY_NOTIFY_PEER(core); - } - } - while (status); -} - -/* ...completion callback for message originating from remote proxy */ -void xf_msg_proxy_complete(xf_message_t *m) -{ - /* ...place message into proxy response queue */ - xf_msg_proxy_put(m); -} - -/* ...initialize shared memory interface (DSP side) */ -int xf_shmem_init(u32 core) -{ - xf_core_rw_data_t *rw = XF_CORE_RW_DATA(core); - xf_core_ro_data_t *ro = XF_CORE_RO_DATA(core); - - /* ...initialize local/remote message queues */ - xf_msg_queue_init(&rw->local); - xf_msg_queue_init(&rw->remote); - - /* ...initialize global message list */ - XF_CHK_API(xf_msg_pool_init(&ro->pool, XF_CFG_MESSAGE_POOL_SIZE, core)); - - /* ...flush memory content as needed */ - (XF_REMOTE_IPC_NON_COHERENT ? XF_PROXY_FLUSH(rw, sizeof(*rw)) : 0); - - /* ...system-specific initialization of IPC layer */ - XF_CHK_API(xf_ipc_init(core)); - - TRACE(INIT, _b("SHMEM-%u subsystem initialized"), core); - - return 0; -} |