hikey960: HiFi3 host side XAF framework

Xtensa Audio Framework in user space to offload audio tasks to HiFi3 DSP.
It provides few API's to invoke DSP and to perform ogg audio decoding,
post processing (PCM Gain) as well it provides adb shell-based
"xaf-dec-test" and "xaf-dec-mix-test" binaries to perform pcm and ogg
file playback

Change-Id: I77ac3b56d4141f41e06f0d0eac4ac3a8ee567e8d
Signed-off-by: Niranjan Yadla <nyadla@cadence.com>
diff --git a/hifi/xaf/host-apf/proxy/xaf-api.c b/hifi/xaf/host-apf/proxy/xaf-api.c
new file mode 100644
index 0000000..6b5862d
--- /dev/null
+++ b/hifi/xaf/host-apf/proxy/xaf-api.c
@@ -0,0 +1,597 @@
+/*******************************************************************************
+* 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.
+
+******************************************************************************/
+#include "xf.h"
+#include "xaf-api.h"
+#include "xaf-structs.h"
+
+#ifdef XAF_HOSTLESS
+#include "xos-msgq-if.h"
+#endif
+#define MODULE_TAG                      DEVAPI
+
+/*******************************************************************************
+ * Tracing configuration
+ ******************************************************************************/
+
+TRACE_TAG(INIT, 1);
+TRACE_TAG(DEBUG, 1);
+TRACE_TAG(INFO, 1);
+
+#define XAF_4BYTE_ALIGN    4
+#define XAF_8BYTE_ALIGN    8
+#define XAF_32BYTE_ALIGN   32
+
+
+static void xaf_comp_response(xf_handle_t *h, xf_user_msg_t *msg)
+{
+    if (msg->opcode == XF_UNREGISTER)
+    {
+        /* ...component execution failed unexpectedly; die */
+        BUG(1, _x("[%p] Abnormal termination"), h);
+    }
+    else
+    {
+        /* ...submit response to asynchronous delivery queue */
+        xf_response_put(h, msg);
+    }
+}
+
+static XAF_ERR_CODE xaf_comp_add(xaf_comp_t **pp_comp_chain, xaf_comp_t *p_comp)
+{
+    XAF_CHK_PTR(pp_comp_chain);
+    XAF_CHK_PTR(p_comp);
+
+    p_comp->next   = *pp_comp_chain;
+    *pp_comp_chain = p_comp;
+
+    return XAF_NO_ERROR;
+}
+
+static XAF_ERR_CODE xaf_comp_post_init_config(xaf_adev_t *p_adev, xaf_comp_t *p_comp, void *p_msg)
+{
+    xf_proxy_t *p_proxy = &p_adev->proxy; 
+    xf_start_msg_t *smsg = p_msg;
+
+    p_comp->out_format.sample_rate   = smsg->sample_rate;
+    p_comp->out_format.channels      = smsg->channels;
+    p_comp->out_format.pcm_width     = smsg->pcm_width;
+    p_comp->out_format.input_length  = smsg->input_length;
+    p_comp->out_format.output_length = smsg->output_length;
+
+    TRACE(INFO, _b("Component[%x] Params: f=%d, c=%d, w=%d i=%d o=%d"), p_comp->handle.id, smsg->sample_rate, smsg->channels, smsg->pcm_width, smsg->input_length, smsg->output_length);
+
+    if (p_comp->noutbuf)
+    { 
+        XF_CHK_API(xf_pool_alloc(p_proxy, p_comp->noutbuf, smsg->output_length, XF_POOL_OUTPUT, &p_comp->outpool, XAF_MEM_ID_COMP,
+				p_adev->pxf_mem_malloc_fxn, p_adev->pxf_mem_free_fxn));
+    }
+
+    p_comp->init_done   = 1;
+    p_comp->comp_status = XAF_INIT_DONE;
+
+    return XAF_NO_ERROR;
+}
+
+#ifdef XAF_HOSTLESS
+XAF_ERR_CODE xaf_xos_start()
+{
+#if defined BOARD
+    xos_set_clock_freq(xtbsp_clock_freq_hz());
+#else
+    xos_set_clock_freq(XOS_CLOCK_FREQ);
+#endif
+
+    xos_start("main", 7, 0);
+#if XCHAL_NUM_TIMERS > 0
+    xos_start_system_timer(0, TICK_CYCLES);
+#endif
+
+    return XAF_NO_ERROR;
+}
+#endif
+
+XAF_ERR_CODE xaf_adev_open(void** pp_adev, s32 audio_frmwk_buf_size, s32 audio_comp_buf_size, xaf_mem_malloc_fxn_t mem_malloc, xaf_mem_free_fxn_t mem_free)
+{
+    int size;
+    void * pTmp;
+    xaf_adev_t *p_adev;
+    xf_proxy_t *p_proxy; 
+
+    XAF_CHK_PTR(pp_adev);
+    XAF_CHK_PTR(mem_malloc);
+    XAF_CHK_PTR(mem_free);
+
+    /* ...unused arg */
+    (void) audio_comp_buf_size;
+
+    //Memory allocation for adev struct pointer
+    size = (sizeof(xaf_adev_t) +(XAF_4BYTE_ALIGN-1));
+    pTmp = mem_malloc(size, XAF_MEM_ID_DEV);
+    XAF_CHK_PTR(pTmp);
+    memset(pTmp, 0, size);
+    
+    p_adev = (xaf_adev_t *) (((unsigned long)pTmp + (XAF_4BYTE_ALIGN-1))& ~(XAF_4BYTE_ALIGN-1));
+    p_adev->adev_ptr = pTmp;
+    *pp_adev = (void *)p_adev;
+
+    p_proxy = &p_adev->proxy;    
+
+    // Host side Memory allocation (BSS)
+    p_adev->pxf_mem_malloc_fxn = mem_malloc;
+    p_adev->pxf_mem_free_fxn  = mem_free;
+
+    size = sizeof(xaf_ap_utils_t)+(XAF_8BYTE_ALIGN-1);
+    p_adev->p_ap_utils = mem_malloc(size, XAF_MEM_ID_DEV);
+    XAF_CHK_PTR(p_adev->p_ap_utils);
+    //reset memory size stats
+    memset(p_adev->p_ap_utils, 0, sizeof(xaf_ap_utils_t));
+
+    // shmmem Memory allocation
+    p_adev->p_ap_utils->xf_cfg_remote_ipc_pool_size = audio_frmwk_buf_size; //minimum size 256 KB, mmap multiple is 0x1000
+
+    //DSP localbuf allocation is done in the DSP core; nothing to be done here
+
+    /* ...open DSP proxy - specify "DSP#0" */
+    XF_CHK_API(xf_proxy_init(p_proxy, 0, (void *)&p_adev->p_ap_utils->xf_cfg_remote_ipc_pool_size));
+
+    /* ...create auxiliary buffers pool for control commands */
+    XF_CHK_API(xf_pool_alloc(p_proxy, XAF_AUX_POOL_SIZE, XAF_AUX_POOL_MSG_LENGTH, XF_POOL_AUX, &p_proxy->aux, XAF_MEM_ID_DEV,
+				p_adev->pxf_mem_malloc_fxn, p_adev->pxf_mem_free_fxn));
+
+    return XAF_NO_ERROR;
+}
+
+XAF_ERR_CODE xaf_adev_close(void* adev_ptr, xaf_comp_flag flag)
+{
+    xaf_adev_t *p_adev;
+    xf_proxy_t *p_proxy;
+
+    XAF_CHK_PTR(adev_ptr);
+    p_adev = (xaf_adev_t *)adev_ptr;
+
+    /* ...unused arg */
+    (void) flag;
+
+    p_proxy = &p_adev->proxy;
+    if(p_proxy->aux != NULL)
+    {
+        xf_pool_free(p_proxy->aux, XAF_MEM_ID_DEV, p_adev->pxf_mem_free_fxn);
+    }
+
+    xf_proxy_close(p_proxy);
+
+    p_adev->pxf_mem_free_fxn(p_adev->p_ap_utils, XAF_MEM_ID_DEV);
+    p_adev->p_ap_utils = NULL;
+    p_adev->pxf_mem_free_fxn(p_adev->adev_ptr, XAF_MEM_ID_DEV);
+    p_adev->adev_ptr = NULL;
+
+    p_adev->pxf_mem_malloc_fxn = NULL;
+    p_adev->pxf_mem_free_fxn  = NULL;
+
+    return XAF_NO_ERROR;
+}
+
+XAF_ERR_CODE xaf_comp_create(void *adev_ptr, void **pp_comp, xf_id_t comp_id, u32 ninbuf, u32 noutbuf, void *pp_inbuf[], xaf_comp_type comp_type)
+{
+    xf_handle_t *p_handle;
+    void * pTmp;
+    int size;
+
+    xaf_adev_t *p_adev;
+    p_adev = (xaf_adev_t *)adev_ptr;
+    xaf_comp_t *p_comp;
+
+    XAF_CHK_PTR(p_adev);
+    XAF_CHK_PTR(pp_comp);
+    XAF_CHK_PTR(comp_id);
+    if (ninbuf) XAF_CHK_PTR(pp_inbuf);
+
+    XAF_CHK_RANGE(ninbuf, 0, XAF_MAX_INBUFS);
+    XAF_CHK_RANGE(noutbuf, 0, 1);
+    XAF_CHK_RANGE(comp_type, XAF_DECODER, XAF_POST_PROC); 
+
+    //Memory allocation for component struct pointer
+    size = (sizeof(xaf_comp_t) + (XAF_4BYTE_ALIGN-1));
+    pTmp = p_adev->pxf_mem_malloc_fxn(size, XAF_MEM_ID_COMP);
+    XAF_CHK_PTR(pTmp);
+    memset(pTmp, 0, size);
+    p_comp = (xaf_comp_t *) (((unsigned long)pTmp + (XAF_4BYTE_ALIGN-1))& ~(XAF_4BYTE_ALIGN-1));
+
+    p_comp->comp_ptr = pTmp;
+    *pp_comp = (void*)p_comp;
+
+    memset(p_comp, 0, sizeof(xaf_comp_t));
+    p_handle = &p_comp->handle;
+
+    /* ...create component instance (select core-0) */
+    XF_CHK_API(xf_open(&p_adev->proxy, p_handle, comp_id, 0, xaf_comp_response));
+
+    xaf_comp_add(&p_adev->comp_chain, p_comp);
+    
+    // Temporary solution in place of component chain handling
+    p_comp->p_adev = p_adev;
+    p_adev->n_comp += 1;
+    p_comp->ninbuf = ninbuf;
+
+    /* ...allocate input buffer */
+    if (ninbuf) 
+    {
+        xf_buffer_t *buf;
+        u32 i;
+        XF_CHK_API(xf_pool_alloc(&p_adev->proxy, ninbuf, XAF_INBUF_SIZE, XF_POOL_INPUT, &p_comp->inpool, XAF_MEM_ID_COMP,
+				p_adev->pxf_mem_malloc_fxn, p_adev->pxf_mem_free_fxn));
+        
+        for (i=0; i<ninbuf; i++)
+        {
+            buf         = xf_buffer_get(p_comp->inpool);
+            pp_inbuf[i] = xf_buffer_data(buf); 
+        }
+
+    }
+    p_comp->noutbuf = noutbuf;
+
+    p_comp->comp_type   = comp_type;
+    p_comp->comp_status = XAF_STARTING;
+
+    switch (comp_type)
+    {
+    case XAF_DECODER:
+    case XAF_ENCODER:
+    case XAF_PRE_PROC:
+    case XAF_POST_PROC:
+        p_comp->inp_ports = 1; p_comp->out_ports = 1;
+        break;
+    case XAF_MIXER:
+        p_comp->inp_ports = 4; p_comp->out_ports = 1;
+        break;
+    }
+
+    return XAF_NO_ERROR;
+}
+
+XAF_ERR_CODE xaf_comp_delete(void *comp_ptr)
+{
+    xaf_adev_t *p_adev;
+
+    xaf_comp_t *p_comp;
+    p_comp = (xaf_comp_t *)comp_ptr;
+
+    XAF_CHK_PTR(p_comp);
+
+    // Temporary solution in place of component chain handling
+    p_adev = (xaf_adev_t *)(p_comp->p_adev);
+    XF_CHK_ERR((p_adev->n_comp > 0), XAF_API_ERR);
+    p_adev->n_comp -= 1;
+
+
+    if (p_comp->inpool)  xf_pool_free(p_comp->inpool, XAF_MEM_ID_COMP, p_adev->pxf_mem_free_fxn);
+    if (p_comp->outpool) xf_pool_free(p_comp->outpool, XAF_MEM_ID_COMP, p_adev->pxf_mem_free_fxn);
+
+    xf_close(&p_comp->handle);
+   
+    /* ...tbd - remove from chain */
+    p_adev->pxf_mem_free_fxn(p_comp->comp_ptr, XAF_MEM_ID_COMP);
+    p_comp->comp_ptr = NULL;
+     
+    return XAF_NO_ERROR;
+}
+
+XAF_ERR_CODE xaf_comp_set_config(void *comp_ptr, s32 num_param, s32 *p_param)
+{
+    xaf_comp_t              *p_comp;
+    xf_user_msg_t           rmsg;
+    xf_set_param_msg_t     *smsg;
+    xf_handle_t            *p_handle;
+    s32                     i, j;
+
+    p_comp = (xaf_comp_t *)comp_ptr;
+
+    XAF_CHK_PTR(p_comp);
+    XAF_CHK_PTR(p_param);
+    XAF_CHK_RANGE(num_param, 1, XAF_MAX_CONFIG_PARAMS); 
+    
+    p_handle = &p_comp->handle;
+    XAF_CHK_PTR(p_handle);
+
+    /* ...set persistent stream characteristics */
+    smsg = xf_buffer_data(p_handle->aux);
+
+    j = 0;
+    for (i=0; i<num_param; i++)
+    {
+        smsg->item[i].id    = p_param[j++];
+        smsg->item[i].value = p_param[j++];
+    }
+    
+    /* ...pass command to the component */
+    /* ...tbd - command goes port 0 always, check if okay */
+    XF_CHK_API(xf_command(p_handle, 0, XF_SET_PARAM, smsg, sizeof(xf_set_param_item_t)*num_param));
+
+    /* ...wait until result is delivered */
+    XF_CHK_API(xf_response_get(p_handle, &rmsg));
+
+    /* ...make sure response is expected */
+    XF_CHK_ERR(rmsg.opcode == (u32) XF_SET_PARAM && rmsg.buffer == smsg, XAF_API_ERR);
+
+    return XAF_NO_ERROR;
+}
+
+XAF_ERR_CODE xaf_comp_get_config(void *comp_ptr, s32 num_param, s32 *p_param)
+{
+    xaf_comp_t             *p_comp;
+    xf_user_msg_t           rmsg;
+    xf_get_param_msg_t     *smsg;
+    xf_handle_t            *p_handle;
+    s32                     i;
+
+    p_comp = (xaf_comp_t *)comp_ptr;
+
+    XAF_CHK_PTR(p_comp);
+    XAF_CHK_PTR(p_param);
+    XAF_CHK_RANGE(num_param, 1, XAF_MAX_CONFIG_PARAMS); 
+    
+    p_handle = &p_comp->handle;
+    XAF_CHK_PTR(p_handle);
+
+    /* ...set persistent stream characteristics */
+    smsg = xf_buffer_data(p_handle->aux);
+
+    for (i=0; i<num_param; i++)
+    {
+        smsg->c.id[i] = p_param[i];
+    }
+    
+    /* ...pass command to the component */
+    /* ...tbd - command goes port 0 always, check if okay */
+    XF_CHK_API(xf_command(p_handle, 0, XF_GET_PARAM, smsg, XF_GET_PARAM_CMD_LEN(num_param)));
+
+    /* ...wait until result is delivered */
+    XF_CHK_API(xf_response_get(p_handle, &rmsg));
+
+    /* ...make sure response is expected */
+    XF_CHK_ERR(rmsg.opcode == (u32) XF_GET_PARAM && rmsg.buffer == smsg, XAF_API_ERR);
+
+    for (i=0; i<num_param; i++)
+    {
+        p_param[i] = smsg->r.value[i];
+    }
+
+    return XAF_NO_ERROR;
+}
+#ifdef XAF_HOSTLESS
+XAF_ERR_CODE xaf_comp_get_status(xaf_adev_t *p_adev, xaf_comp_t *p_comp, xaf_comp_status *p_status, void *p_info)
+#else
+XAF_ERR_CODE xaf_comp_get_status(void *adev_ptr, void *comp_ptr, xaf_comp_status *p_status, xaf_info_t *p_info)
+#endif
+{
+    xaf_adev_t *p_adev;
+    xaf_comp_t *p_comp;
+    xf_handle_t *p_handle;
+
+    p_adev = (xaf_adev_t *)adev_ptr;
+    p_comp = (xaf_comp_t *)comp_ptr;
+
+    XAF_CHK_PTR(p_comp);
+    XAF_CHK_PTR(p_status);
+    XAF_CHK_PTR(p_info);
+    if (!p_comp->init_done) XAF_CHK_PTR(p_adev);
+
+    p_handle = &p_comp->handle;
+
+    if (p_comp->pending_resp)
+    {
+        xf_user_msg_t rmsg;
+        /* ...wait until result is delivered */
+        XF_CHK_API(xf_response_get(p_handle, &rmsg)); 
+
+        if (rmsg.opcode == XF_FILL_THIS_BUFFER) 
+        {
+            if (rmsg.buffer == p_comp->start_buf)
+            {
+                XF_CHK_API(xaf_comp_post_init_config(p_adev, p_comp, p_comp->start_buf));
+            }
+            else 
+            {
+#ifdef XAF_HOSTLESS
+				s32 *p_buf = (s32 *) p_info;
+                p_buf[0] = (s32) rmsg.buffer;
+                p_buf[1] = (s32) rmsg.length;
+#else
+                p_info->buf = (void*) rmsg.buffer;
+                p_info->length = (s32) rmsg.length;
+#endif				
+                if (!p_comp->inpool && p_comp->outpool) p_comp->pending_resp--;
+
+                if (!rmsg.length) p_comp->comp_status = XAF_EXEC_DONE;
+                else
+                {
+                    p_comp->comp_status = XAF_OUTPUT_READY;
+                    p_comp->expect_out_cmd++;
+                }
+            }
+        }
+        else
+        {
+            /* ...make sure response is expected */
+            XF_CHK_ERR(rmsg.opcode == (u32) XF_EMPTY_THIS_BUFFER, XAF_API_ERR);            
+#ifdef XAF_HOSTLESS
+			s32 *p_buf = (s32 *) p_info;
+            p_buf[0] = (s32) rmsg.buffer;
+            p_buf[1] = (s32) rmsg.length;
+#else
+            p_info->buf = (void*) rmsg.buffer;
+			p_info->length = (s32) rmsg.length;
+#endif            
+            p_comp->pending_resp--;
+            
+            if (p_comp->input_over && rmsg.buffer == NULL) p_comp->comp_status = XAF_EXEC_DONE;
+            else p_comp->comp_status = XAF_NEED_INPUT;
+        }
+    }
+    else if ((p_comp->comp_status == XAF_STARTING && p_comp->start_cmd_issued) ||
+             (p_comp->comp_status == XAF_INIT_DONE && p_comp->exec_cmd_issued))
+    {
+        if (p_comp->inpool) p_comp->comp_status = XAF_NEED_INPUT;
+    }
+    
+    *p_status = p_comp->comp_status;
+    
+    return XAF_NO_ERROR;
+}
+
+XAF_ERR_CODE xaf_comp_process(void *adev_ptr, void *comp_ptr, void *p_buf, u32 length, xaf_comp_flag flag)
+{
+    xaf_adev_t *p_adev;
+    xaf_comp_t *p_comp;
+    xf_handle_t *p_handle;
+
+    p_adev = (xaf_adev_t *)adev_ptr;
+    p_comp = (xaf_comp_t *)comp_ptr;
+
+    XAF_CHK_PTR(p_comp);
+    if (!p_comp->init_done) XAF_CHK_PTR(p_adev);
+    XAF_CHK_RANGE(flag, XAF_START_FLAG, XAF_NEED_OUTPUT_FLAG);
+    if (flag == XAF_INPUT_READY_FLAG) XAF_CHK_RANGE(length, 0, XAF_INBUF_SIZE);
+
+    p_handle = &p_comp->handle;
+    
+    switch (flag)
+    {
+    case XAF_START_FLAG:
+        if (p_comp->start_cmd_issued)
+            break;
+        else
+        {
+            p_comp->start_buf = xf_buffer_data(p_handle->aux);
+            XF_CHK_API(xf_command(p_handle, (p_comp->inp_ports), XF_FILL_THIS_BUFFER, p_comp->start_buf, 0));
+            p_comp->start_cmd_issued = 1;
+
+            if(p_comp->comp_type != XAF_DECODER) 
+            {
+                xf_user_msg_t rmsg;
+                /* ...wait until result is delivered */
+                XF_CHK_API(xf_response_get(p_handle, &rmsg)); 
+            
+                /* ...make sure response is expected */
+                XF_CHK_ERR(rmsg.opcode == XF_FILL_THIS_BUFFER && rmsg.buffer == p_comp->start_buf, XAF_API_ERR);
+
+                XF_CHK_API(xaf_comp_post_init_config(p_adev, p_comp, p_comp->start_buf));
+            }            
+        }
+        break;
+    
+    case XAF_EXEC_FLAG:
+        if (!p_comp->init_done || p_comp->exec_cmd_issued)
+            break;
+        p_comp->exec_cmd_issued = 1;
+        if (p_comp->outpool)
+        {
+            u32 i;
+            xf_buffer_t *p_buf;
+            void *p_data;
+
+            for (i=0; i<p_comp->noutbuf; i++)
+            {
+                p_buf = xf_buffer_get(p_comp->outpool);
+                p_data = xf_buffer_data(p_buf);
+
+                XF_CHK_API(xf_command(&p_comp->handle, (p_comp->inp_ports), XF_FILL_THIS_BUFFER, p_data, p_comp->out_format.output_length));
+            }
+            
+            if (!p_comp->inpool) p_comp->pending_resp = p_comp->noutbuf;
+        }
+        break;
+ 
+    case XAF_INPUT_OVER_FLAG:
+        if (!p_comp->input_over)
+        {
+            XF_CHK_API(xf_command(p_handle, 0, XF_EMPTY_THIS_BUFFER, NULL, 0));
+            p_comp->input_over = 1;
+            p_comp->pending_resp++;
+        }
+        break;
+
+    case XAF_INPUT_READY_FLAG:
+        if (!p_comp->input_over)
+        {
+            XAF_CHK_PTR(p_buf);
+            XF_CHK_API(xf_command(p_handle, 0, XF_EMPTY_THIS_BUFFER, p_buf, length));
+            p_comp->pending_resp++;
+        }
+        break;
+
+    case XAF_NEED_OUTPUT_FLAG:
+        if (p_comp->expect_out_cmd)
+        {
+            XAF_CHK_PTR(p_buf);
+            XF_CHK_API(xf_command(p_handle, (p_comp->inp_ports), XF_FILL_THIS_BUFFER, p_buf, length));
+            p_comp->expect_out_cmd--;
+
+            if (!p_comp->inpool && p_comp->outpool) p_comp->pending_resp++;
+        }
+        break;
+    }
+    
+    return XAF_NO_ERROR;
+}
+
+XAF_ERR_CODE xaf_connect(void *src_ptr, void *dest_ptr, s32 num_buf)
+{
+    xaf_comp_t *p_src;
+    xaf_comp_t *p_dest;
+
+    p_src = (xaf_comp_t *)src_ptr;
+    p_dest = (xaf_comp_t *)dest_ptr;
+
+    XAF_CHK_PTR(p_src);
+    XAF_CHK_PTR(p_dest);
+    XAF_CHK_RANGE(num_buf, 2, 4);    
+
+    if (!p_src->init_done || p_src->out_routed == p_src->out_ports || p_dest->inp_routed == p_dest->inp_ports)
+        return XAF_ROUTING_ERROR;
+                   
+    XF_CHK_API(xf_route(&p_src->handle, (p_src->inp_ports + p_src->out_routed), &p_dest->handle, (p_dest->inp_routed), num_buf, p_src->out_format.output_length, 8));
+    
+    p_src->out_routed++;
+    p_dest->inp_routed++;
+
+    return XAF_NO_ERROR;
+}
+
+XAF_ERR_CODE xaf_disconnect(xaf_comp_t *p_comp)
+{
+    XAF_CHK_PTR(p_comp);
+    
+    /* ...tbd - support for multiple output ports */
+    if (!p_comp->init_done || p_comp->out_routed != p_comp->out_ports)
+        return XAF_ROUTING_ERROR;
+
+    XF_CHK_API(xf_unroute(&p_comp->handle, (p_comp->inp_ports)));
+
+    return XAF_NO_ERROR;
+}
+
+
+
+
+
+
diff --git a/hifi/xaf/host-apf/proxy/xf-fio.c b/hifi/xaf/host-apf/proxy/xf-fio.c
new file mode 100644
index 0000000..5c3c3db
--- /dev/null
+++ b/hifi/xaf/host-apf/proxy/xf-fio.c
@@ -0,0 +1,193 @@
+/*******************************************************************************
+* 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.
+
+******************************************************************************/
+
+#define MODULE_TAG                      FIO
+
+/*******************************************************************************
+ * Includes
+ ******************************************************************************/
+
+#include "xf.h"
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+/*******************************************************************************
+ * Tracing configuration
+ ******************************************************************************/
+
+TRACE_TAG(INIT, 1);
+TRACE_TAG(CMD, 1);
+TRACE_TAG(RSP, 1);
+
+/*******************************************************************************
+ * Local constants - tbd
+ ******************************************************************************/
+
+/* ...proxy setup ioctl */
+#define XF_PROXY_SETUP_IOCTL            _IO('P', 0x0)
+
+/* ...proxy close ioctl */
+#define XF_PROXY_CLOSE_IOCTL            _IO('P', 0x1)
+
+#define HIFI_DSP_MISC_DRIVER "/dev/hifi_misc"
+#ifndef GJB_COMMENT
+#define HIFI_MISC_IOCTL_XAF_IPC_MSG_SEND _IOW('A',  0x7c, xf_proxy_message_driv_t)
+#define HIFI_MISC_IOCTL_XAF_IPC_MSG_RECV _IOR('A', 0x7d, xf_proxy_message_driv_t)
+#define HIFI_MISC_IOCTL_XAF_IPC_VMSG_PTR _IOR('A', 0x7e, xf_proxy_message_driv_t)
+#endif
+//u8 remote_ipc_pool[XF_CFG_REMOTE_IPC_POOL_SIZE];
+/*******************************************************************************
+ * Internal IPC API implementation
+ ******************************************************************************/
+
+/* ...pass command to remote DSP */
+int xf_ipc_send(xf_proxy_ipc_data_t *ipc, xf_proxy_msg_t *msg, void *b)
+{
+    /* ...unused arg */
+    (void) b;
+
+    int     fd = ipc->fd;
+    int ret;
+#ifdef GJB_COMMENT
+    TRACE(CMD, _b("C[%08x]:(%x,%08x,%u)"), msg->id, msg->opcode, msg->address, msg->length);    
+
+    /* ...pass message to kernel driver */
+    XF_CHK_ERR(write(fd, msg, sizeof(*msg)) == sizeof(*msg), -errno);
+#else
+	ret = ioctl(fd, HIFI_MISC_IOCTL_XAF_IPC_MSG_SEND, msg);// GJB:-Verify th return value with driver implementation.
+#endif
+
+    /* ...communication mutex is still locked! */
+    return 0;
+}
+
+/* ...wait for response availability */
+int xf_ipc_wait(xf_proxy_ipc_data_t *ipc, u32 timeout)
+{
+    int             fd = ipc->fd;
+    fd_set          rfds;
+    struct timeval  tv;
+    
+    /* ...specify waiting set */
+    FD_ZERO(&rfds);
+    FD_SET(fd, &rfds);
+    
+    /* ...set timeout value if given */
+    (timeout ? tv.tv_sec = timeout / 1000, tv.tv_usec = (timeout % 1000) * 1000 : 0);
+    
+    /* ...wait until there is a data in file */
+//    XF_CHK_ERR(select(fd + 1, &rfds, NULL, NULL, (timeout ? &tv : NULL)) >= 0, -errno);
+	select(fd+1,&rfds,NULL,NULL,(timeout? &tv: NULL));
+    
+    /* ...check if descriptor is set */
+    return (FD_ISSET(fd, &rfds) ? 0 : -ETIMEDOUT);
+}
+
+/* ...read response from proxy */
+int xf_ipc_recv(xf_proxy_ipc_data_t *ipc, xf_proxy_msg_t *msg, void **buffer)
+{
+    int     fd = ipc->fd;
+    int     r;
+    xf_proxy_msg_t temp;
+#ifdef GJB_COMMENT
+    /* ...get message header from file */
+    if ((r = read(fd, msg, sizeof(*msg))) == sizeof(*msg))
+    {
+        TRACE(RSP, _b("R[%08x]:(%x,%u,%08x)"), msg->id, msg->opcode, msg->length, msg->address);
+
+        /* ...translate shared address into local pointer */
+        XF_CHK_ERR((*buffer = xf_ipc_a2b(ipc, msg->address)) != (void *)-1, -EBADFD);
+
+        /* ...return positive result indicating the message has been received */
+        return sizeof(*msg);
+    }
+#else
+    if ((r = ioctl(fd, HIFI_MISC_IOCTL_XAF_IPC_MSG_RECV, &temp)) == sizeof(temp))
+    {
+        msg->id = temp.id;
+        msg->opcode = temp.opcode;
+        msg->length = temp.length;
+        *buffer = xf_ipc_a2b(ipc, temp.address);
+        /* ...translate shared address into local pointer */
+        XF_CHK_ERR((*buffer = xf_ipc_a2b(ipc, temp.address)) != (void *)-1, -EBADFD);
+        msg->address = temp.address;
+        return sizeof(*msg);
+    }
+#endif
+    else
+    {
+        /* ...if no response is available, return 0 result */
+        return XF_CHK_API(errno == EAGAIN ? 0 : -errno);
+    }
+}
+
+/*******************************************************************************
+ * Internal API functions implementation
+ ******************************************************************************/
+
+/* ...open proxy interface on proper DSP partition */
+int xf_ipc_open(xf_proxy_ipc_data_t *ipc, u32 core, void *p_shmem)
+{
+    //XF_CHK_ERR((p_shmem != NULL), -errno);
+    //size_t xf_cfg_remote_ipc_pool_size = *(size_t *)p_shmem;//user configured shmem pool size: minimum 256 KB
+    /* ...unused arg */
+    (void) p_shmem;
+#ifdef GJB_COMMENT	
+    /* ...open file handle */
+    XF_CHK_ERR((ipc->fd = open("/dev/xtensa-proxy", O_RDWR)) >= 0, -errno);
+
+    /* ...pass shread memory core for this proxy instance */
+    XF_CHK_ERR(ioctl(ipc->fd, XF_PROXY_SETUP_IOCTL, core) >= 0, -errno);    
+#else
+	XF_CHK_ERR((ipc->fd = open(HIFI_DSP_MISC_DRIVER, O_RDWR,0)) >= 0, -errno);
+#endif
+    /* ...create pipe for asynchronous response delivery */
+    XF_CHK_ERR(pipe(ipc->pipe) == 0, -errno);
+
+    /* ...map entire shared memory region (not too good - tbd) */
+//	ipc->shmem = remote_ipc_pool;
+//	ioctl(ipc->fd, HIFI_MISC_IOCTL_XAF_IPC_VMSG_PTR, ipc->shmem);
+#if 1
+    //allocate 256 KB constant size
+    XF_CHK_ERR((ipc->shmem = mmap(NULL, XF_CFG_REMOTE_IPC_POOL_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, ipc->fd, 0)) != MAP_FAILED, -errno);
+#else
+    XF_CHK_ERR((ipc->shmem = mmap(NULL, xf_cfg_remote_ipc_pool_size, PROT_READ | PROT_WRITE, MAP_SHARED, ipc->fd, 0)) != MAP_FAILED, -errno);
+#endif
+    TRACE(INIT, _b("proxy-%u interface opened"), core); 
+    return 0;
+}
+
+/* ...close proxy handle */
+void xf_ipc_close(xf_proxy_ipc_data_t *ipc, u32 core)
+{
+    /* ...unmap shared memory region */
+//    (void)munmap(ipc->shmem, XF_CFG_REMOTE_IPC_POOL_SIZE);
+
+    /* ...close asynchronous response delivery pipe */
+    close(ipc->pipe[0]), close(ipc->pipe[1]);
+    
+    /* ...close proxy file handle */
+    close(ipc->fd);
+
+    TRACE(INIT, _b("proxy-%u interface closed"), core);
+}
+
diff --git a/hifi/xaf/host-apf/proxy/xf-proxy.c b/hifi/xaf/host-apf/proxy/xf-proxy.c
new file mode 100644
index 0000000..9487f4e
--- /dev/null
+++ b/hifi/xaf/host-apf/proxy/xf-proxy.c
@@ -0,0 +1,686 @@
+/*******************************************************************************
+* 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.
+
+******************************************************************************/
+
+#define MODULE_TAG                      PROXY
+
+/*******************************************************************************
+ * Includes
+ ******************************************************************************/
+
+#include "xf.h"
+
+/*******************************************************************************
+ * Tracing configuration
+ ******************************************************************************/
+
+TRACE_TAG(INIT, 1);
+TRACE_TAG(CMD, 1);
+TRACE_TAG(EXEC, 1);
+TRACE_TAG(RSP, 1);
+TRACE_TAG(REG, 1);
+TRACE_TAG(MEM, 1);
+TRACE_TAG(GRAPH, 1);
+TRACE_TAG(BUFFER, 1);
+
+/*******************************************************************************
+ * Internal functions definitions
+ ******************************************************************************/
+
+/* ...execute proxy command synchronously */
+static inline int xf_proxy_cmd_exec(xf_proxy_t *proxy, xf_user_msg_t *msg)
+{
+    xf_proxy_msg_t  m;
+    
+    /* ...send command to remote proxy */
+    m.id = msg->id, m.opcode = msg->opcode, m.length = msg->length;
+
+    /* ...translate address */
+    XF_CHK_ERR((m.address = xf_proxy_b2a(proxy, msg->buffer)) != XF_PROXY_BADADDR, -EINVAL);
+
+    /* ...pass command to remote proxy */
+    XF_CHK_API(xf_ipc_send(&proxy->ipc, &m, msg->buffer));
+
+    /* ...wait for response reception indication from proxy thread */
+    XF_CHK_API(xf_proxy_response_get(proxy, &m));
+    
+    /* ...copy parameters */
+    msg->id = m.id, msg->opcode = m.opcode, msg->length = m.length;
+
+    /* ...translate address back to virtual space */
+    XF_CHK_ERR((msg->buffer = xf_proxy_a2b(proxy, m.address)) != (void *)-1, -EBADFD);
+    
+    TRACE(EXEC, _b("proxy[%p]: command done: [%08x:%p:%u]"), proxy, msg->opcode, msg->buffer, msg->length);
+
+    return 0;
+}
+
+#if 0
+/* ...pass command to remote DSP */
+static inline int xf_proxy_cmd(xf_proxy_t *proxy, xf_handle_t *handle, xf_user_msg_t *m)
+{
+    xf_proxy_msg_t  msg;
+
+    /* ...set session-id of the message */
+    msg.id = __XF_MSG_ID(__XF_AP_CLIENT(proxy->core, handle->client), m->id);
+    msg.opcode = m->opcode;
+    msg.length = m->length;
+
+    /* ...translate buffer pointer to shared address */
+    XF_CHK_ERR((msg.address = xf_proxy_b2a(proxy, m->buffer)) != XF_PROXY_BADADDR, -EINVAL);
+
+    /* ...submit command message to IPC layer */
+    return XF_CHK_API(xf_ipc_send(&proxy->ipc, &msg, m->buffer));
+}
+#endif /* 0 */
+
+/* ...allocate local client-id number */
+static inline u32 xf_client_alloc(xf_proxy_t *proxy, xf_handle_t *handle)
+{
+    u32     client;
+    
+    if ((client = proxy->cmap[0].next) != 0)
+    {
+        /* ...pop client from free clients list */
+        proxy->cmap[0].next = proxy->cmap[client].next;
+
+        /* ...put client handle into association map */
+        handle->client = client, proxy->cmap[client].handle = handle;
+    }
+
+    return client;
+}
+
+/* ...recycle local client-id number */
+static inline void xf_client_free(xf_proxy_t *proxy, xf_handle_t *handle)
+{
+    u32     client = handle->client;
+    
+    /* ...push client into head of the free clients list */
+    proxy->cmap[client].next = proxy->cmap[0].next;
+    
+    /* ...adjust head of free clients */
+    proxy->cmap[0].next = client;
+}
+
+/* ...lookup client basing on its local id */
+static inline xf_handle_t * xf_client_lookup(xf_proxy_t *proxy, u32 client)
+{
+    /* ...client index must be in proper range */
+    BUG(client >= XF_CFG_PROXY_MAX_CLIENTS, _x("Invalid client index: %u"), client);
+    
+    /* ...check if client index is small */
+    if (proxy->cmap[client].next < XF_CFG_PROXY_MAX_CLIENTS)
+        return NULL;
+    else
+        return proxy->cmap[client].handle;
+}
+
+/* ...create new client on remote core */
+static inline int xf_client_register(xf_proxy_t *proxy, xf_handle_t *handle, xf_id_t id, u32 core)
+{
+    void           *b = xf_handle_aux(handle);
+    xf_user_msg_t   msg;
+    
+    /* ...set session-id: source is local proxy, destination is remote proxy */
+    msg.id = __XF_MSG_ID(__XF_AP_PROXY(proxy->core), __XF_DSP_PROXY(core));
+    msg.opcode = XF_REGISTER;
+    msg.buffer = b;
+    msg.length = strlen(id) + 1;
+
+    /* ...copy component identifier */
+    strncpy(b, id, xf_buffer_length(handle->aux));
+
+    /* ...execute command synchronously */
+    XF_CHK_API(xf_proxy_cmd_exec(proxy, &msg));
+    
+    /* ...check operation is successfull */
+    XF_CHK_ERR(msg.opcode == (u32) XF_REGISTER, -EFAULT);
+    
+    /* ...save received component global client-id */
+    handle->id = XF_MSG_SRC(msg.id);  
+
+    TRACE(REG, _b("[%p]=[%s:%u:%u]"), handle, id, XF_PORT_CORE(handle->id), XF_PORT_CLIENT(handle->id));
+
+    return 0;
+}
+
+/* ...unregister client from remote proxy */
+static inline int xf_client_unregister(xf_proxy_t *proxy, xf_handle_t *handle)
+{
+    xf_user_msg_t   msg;
+
+    /* ...make sure the client is consistent */
+    BUG(proxy->cmap[handle->client].handle != handle, _x("Invalid handle: %p"), handle);
+    
+    /* ...set message parameters */
+    msg.id = __XF_MSG_ID(__XF_AP_PROXY(proxy->core), handle->id);
+    msg.opcode = XF_UNREGISTER;
+    msg.buffer = NULL;
+    msg.length = 0;
+
+    /* ...synchronously execute command on remote proxy */
+    XF_CHK_API(xf_proxy_cmd_exec(proxy, &msg));
+    
+    /* ...opcode must be XF_UNREGISTER - tbd */
+    BUG(msg.opcode != XF_UNREGISTER, _x("Invalid opcode: %X"), msg.opcode);
+    
+    TRACE(REG, _b("%p[%u:%u] unregistered"), handle, XF_PORT_CORE(handle->id), XF_PORT_CLIENT(handle->id));
+
+    return 0;
+}
+
+/* ...allocate shared buffer */
+static inline int xf_proxy_buffer_alloc(xf_proxy_t *proxy, u32 length, void **buffer)
+{
+    u32             core = proxy->core;
+    xf_user_msg_t   msg;
+    
+    /* ...prepare command parameters */
+    msg.id = __XF_MSG_ID(__XF_AP_PROXY(core), __XF_DSP_PROXY(core));
+    msg.opcode = XF_ALLOC;
+    msg.length = length;
+    msg.buffer = NULL;
+
+    /* ...synchronously execute command on remote proxy */
+    XF_CHK_API(xf_proxy_cmd_exec(proxy, &msg));
+
+    /* ...check if response is valid */
+    XF_CHK_ERR(msg.opcode == XF_ALLOC, -EBADFD);
+
+    /* ...check if allocation is successful */
+    XF_CHK_ERR(msg.buffer != NULL, -ENOMEM);
+
+    /* ...save output parameter */
+    *buffer = msg.buffer;
+    
+    TRACE(MEM, _b("proxy-%u: allocated [%p:%u]"), core, *buffer, length);
+
+    return 0;
+}
+
+/* ...free shared AP-DSP memory */
+static inline int xf_proxy_buffer_free(xf_proxy_t *proxy, void *buffer, u32 length)
+{
+    u32             core = proxy->core;
+    xf_user_msg_t   msg;
+
+    /* ...prepare command parameters */
+    msg.id = __XF_MSG_ID(__XF_AP_PROXY(core), __XF_DSP_PROXY(core));
+    msg.opcode = XF_FREE;
+    msg.length = length;
+    msg.buffer = buffer;
+    
+    /* ...synchronously execute command on remote proxy */
+    XF_CHK_API(xf_proxy_cmd_exec(proxy, &msg));
+
+    /* ...check if response is valid */
+    XF_CHK_ERR(msg.opcode == XF_FREE, -EBADFD);
+
+    TRACE(MEM, _b("proxy-%u: free [%p:%u]"), core, buffer, length);
+
+    return 0;
+}
+
+/*******************************************************************************
+ * Proxy interface asynchronous receiving thread
+ ******************************************************************************/
+
+static void * xf_proxy_thread(void *arg)
+{
+    xf_proxy_t     *proxy = arg;
+    xf_handle_t    *client;
+    int             r;
+    
+    /* ...start polling thread */
+    while (1)
+    {
+        xf_proxy_msg_t  m;
+        xf_user_msg_t   msg;
+        
+        /* ...wait for response from remote proxy (infinite timeout) */
+        if ((r = xf_ipc_wait(&proxy->ipc, 0)) < 0)
+            break;
+
+        /* ...retrieve all responses received */
+        while ((r = xf_ipc_recv(&proxy->ipc, &m, &msg.buffer)) == sizeof(m))
+        {
+            /* ...make sure we have proper core identifier of SHMEM interface */
+            BUG(XF_MSG_DST_CORE(m.id) != proxy->core, _x("Invalid session-id: %X (core=%u)"), m.id, proxy->core);
+
+            /* ...make sure translation is successful */
+            BUG(msg.buffer == (void *)-1, _x("Invalid buffer address: %08x"), m.address);        
+
+            /* ...retrieve information fields */
+            msg.id = XF_MSG_SRC(m.id), msg.opcode = m.opcode, msg.length = m.length;           
+        
+            TRACE(RSP, _b("R[%08x]:(%08x,%u,%08x)"), m.id, m.opcode, m.length, m.address);
+
+            /* ...lookup component basing on destination port specification */
+            if (XF_AP_CLIENT(m.id) == 0)
+            {
+                /* ...put proxy response to local IPC queue */
+                xf_proxy_response_put(proxy, &m);
+            }
+            else if ((client = xf_client_lookup(proxy, XF_AP_CLIENT(m.id))) != NULL)
+            {
+                /* ...client is found; invoke its response callback (must be non-blocking) */
+                client->response(client, &msg);
+            }
+            else
+            {
+                /* ...client has been disconnected already; drop message */
+                TRACE(RSP, _b("Client look-up failed - drop message"));
+            }
+        }
+
+        /* ...if result code is negative; terminate thread operation */
+        if (r < 0)
+        {
+            TRACE(ERROR, _x("abnormal proxy[%p] thread termination: %d"), proxy, r);
+            break;
+        }
+    }
+    
+    TRACE(INIT, _b("IPC proxy[%p] thread terminated: %d"), proxy, r);
+    
+    return (void *)(intptr_t)r;
+}
+
+/*******************************************************************************
+ * HiFi proxy API
+ ******************************************************************************/
+
+/* ...open HiFi proxy */
+int xf_proxy_init(xf_proxy_t *proxy, u32 core, void *p_shmem)
+{
+    u32             i;
+    int             r;
+    
+    /* ...initialize proxy lock */
+    __xf_lock_init(&proxy->lock);
+   
+    /* ...open proxy IPC interface */
+    XF_CHK_API(xf_ipc_open(&proxy->ipc, core, p_shmem));
+
+    /* ...save proxy core - hmm, too much core identifiers - tbd */
+    proxy->core = core;
+    
+    /* ...line-up all clients into single-linked list */
+    for (i = 0; i < XF_CFG_PROXY_MAX_CLIENTS - 1; i++)
+    {
+        proxy->cmap[i].next = i + 1;
+    }
+    
+    /* ...tail of the list points back to head (list terminator) */
+    proxy->cmap[i].next = 0;
+
+    /* ...initialize thread attributes (joinable, with minimal stack) */
+    if ((r = __xf_thread_create(&proxy->thread, xf_proxy_thread, proxy)) < 0)
+    {
+        TRACE(ERROR, _x("Failed to create polling thread: %d"), r);
+        xf_ipc_close(&proxy->ipc, core);
+        return r;
+    }
+        
+    TRACE(INIT, _b("proxy-%u[%p] opened"), core, proxy);
+    
+    return 0;
+}
+
+/* ...close proxy handle */
+void xf_proxy_close(xf_proxy_t *proxy)
+{
+    u32     core = proxy->core;
+    
+    /* ...terminate proxy thread */
+    __xf_thread_destroy(&proxy->thread);
+
+    /* ...close proxy IPC interface */
+    xf_ipc_close(&proxy->ipc, core);
+    
+    TRACE(INIT, _b("proxy-%u[%p] closed"), core, proxy);
+}
+
+/*******************************************************************************
+ * HiFi component API
+ ******************************************************************************/
+
+/* ...open component handle */
+int xf_open(xf_proxy_t *proxy, xf_handle_t *handle, xf_id_t id, u32 core, xf_response_cb response)
+{
+    int     r;
+    
+    /* ...retrieve auxiliary control buffer from proxy - need I */
+    XF_CHK_ERR(handle->aux = xf_buffer_get(proxy->aux), -EBUSY);
+
+    /* ...initialize IPC data */
+    XF_CHK_API(xf_ipc_data_init(&handle->ipc));    
+
+    /* ...register client in interlocked fashion */
+    xf_proxy_lock(proxy);
+
+    /* ...allocate local client */
+    if (xf_client_alloc(proxy, handle) == 0)
+    {
+        TRACE(ERROR, _x("client allocation failed"));
+        r = -EBUSY;
+    }
+    else if ((r = xf_client_register(proxy, handle, id, core)) < 0)
+    {
+        TRACE(ERROR, _x("client registering failed"));
+        xf_client_free(proxy, handle);
+    }
+    
+    xf_proxy_unlock(proxy);
+
+    /* ...if failed, release buffer handle */
+    if (r < 0)
+    {
+        /* ...operation failed; return buffer back to proxy pool */
+        xf_buffer_put(handle->aux), handle->aux = NULL;
+    }
+    else
+    {
+        /* ...operation completed successfully; assign handle data */
+        handle->response = response;
+        handle->proxy = proxy;
+
+        TRACE(INIT, _b("component[%p]:(id=%s,core=%u) created"), handle, id, core);
+    }
+    
+    return XF_CHK_API(r);
+}
+
+/* ...close component handle */
+void xf_close(xf_handle_t *handle)
+{
+    xf_proxy_t *proxy = handle->proxy;
+
+    /* ...do I need to take component lock here? guess no - tbd */
+
+    /* ...buffers and stuff? - tbd */
+
+    /* ...acquire global proxy lock */
+    xf_proxy_lock(proxy);
+    
+    /* ...unregister component from remote DSP proxy (ignore result code) */
+    (void) xf_client_unregister(proxy, handle);
+    
+    /* ...recycle client-id afterwards */
+    xf_client_free(proxy, handle);
+
+    /* ...release global proxy lock */
+    xf_proxy_unlock(proxy);
+
+    /* ...destroy IPC data */
+    xf_ipc_data_destroy(&handle->ipc);
+    
+    /* ...clear handle data */
+    xf_buffer_put(handle->aux), handle->aux = NULL;
+    
+    /* ...wipe out proxy pointer */
+    handle->proxy = NULL;
+
+    TRACE(INIT, _b("component[%p] destroyed"), handle);
+}
+
+/* ...port binding function */
+int xf_route(xf_handle_t *src, u32 src_port, xf_handle_t *dst, u32 dst_port, u32 num, u32 size, u32 align)
+{
+    xf_proxy_t             *proxy = src->proxy;
+    xf_buffer_t            *b;
+    xf_route_port_msg_t    *m;
+    xf_user_msg_t           msg;
+    
+    /* ...sanity checks - proxy pointers are same */
+    XF_CHK_ERR(proxy == dst->proxy, -EINVAL);
+    
+    /* ...buffer data is sane */
+    XF_CHK_ERR(num && size && xf_is_power_of_two(align), -EINVAL);
+    
+    /* ...get control buffer */
+    XF_CHK_ERR(b = xf_buffer_get(proxy->aux), -EBUSY);
+
+    /* ...get message buffer */
+    m = xf_buffer_data(b);
+    
+    /* ...fill-in message parameters */
+    //m->src = __XF_PORT_SPEC2(src->id, src_port);
+    m->dst = __XF_PORT_SPEC2(dst->id, dst_port);
+    m->alloc_number = num;
+    m->alloc_size = size;
+    m->alloc_align = align;
+
+    /* ...set command parameters */
+    msg.id = __XF_MSG_ID(__XF_AP_PROXY(proxy->core), __XF_PORT_SPEC2(src->id, src_port));
+    msg.opcode = XF_ROUTE;
+    msg.length = sizeof(*m);
+    msg.buffer = m;
+
+    /* ...synchronously execute command on remote DSP */    
+    XF_CHK_API(xf_proxy_cmd_exec(proxy, &msg));
+
+    /* ...return buffer to proxy */
+    xf_buffer_put(b);
+
+    /* ...check result is successfull */
+    XF_CHK_ERR(msg.opcode == (u32) XF_ROUTE, -ENOMEM);
+    
+    /* ...port binding completed */
+    TRACE(GRAPH, _b("[%p]:%u bound to [%p]:%u"), src, src_port, dst, dst_port);
+    
+    return 0;
+}
+
+/* ...port unbinding function */
+int xf_unroute(xf_handle_t *src, u32 src_port)
+{
+    xf_proxy_t             *proxy = src->proxy;
+    xf_buffer_t            *b;
+    xf_unroute_port_msg_t  *m;
+    xf_user_msg_t           msg;
+    int                     r;
+    
+    /* ...get control buffer */
+    XF_CHK_ERR(b = xf_buffer_get(proxy->aux), -EBUSY);
+
+    /* ...get message buffer */
+    m = xf_buffer_data(b);
+    
+    /* ...fill-in message parameters */
+    //m->src = __XF_PORT_SPEC2(src->id, src_port);
+
+    /* ...set command parameters */
+    msg.id = __XF_MSG_ID(__XF_AP_PROXY(proxy->core), __XF_PORT_SPEC2(src->id, src_port));
+    msg.opcode = XF_UNROUTE;
+    msg.length = sizeof(*m);
+    msg.buffer = m;
+
+    /* ...synchronously execute command on remote DSP */    
+    if ((r = xf_proxy_cmd_exec(proxy, &msg)) != 0)
+    {
+        TRACE(ERROR, _x("Command failed: %d"), r);
+        goto out;
+    }
+    else if (msg.opcode != (u32) XF_UNROUTE)
+    {
+        TRACE(ERROR, _x("Port unbinding failed"));
+        r = -EBADFD;
+        goto out;
+    }
+    
+    /* ...port binding completed */
+    TRACE(GRAPH, _b("[%p]:%u unbound"), src, src_port);
+    
+out:
+    /* ...return buffer to proxy */
+    xf_buffer_put(b);
+    
+    return r;
+}
+
+/* ...send a command message to component */
+int xf_command(xf_handle_t *handle, u32 port, u32 opcode, void *buffer, u32 length)
+{
+    xf_proxy_t     *proxy = handle->proxy;
+    xf_proxy_msg_t  msg;
+    
+    /* ...fill-in message parameters */
+    msg.id = __XF_MSG_ID(__XF_AP_CLIENT(proxy->core, handle->client), __XF_PORT_SPEC2(handle->id, port));
+    msg.opcode = opcode;
+    msg.length = length;
+    XF_CHK_ERR((msg.address = xf_proxy_b2a(proxy, buffer)) != XF_PROXY_BADADDR, -EINVAL);
+
+    TRACE(CMD, _b("[%p]:[%08x]:(%08x,%u,%p)"), handle, msg.id, opcode, length, buffer);
+
+    /* ...pass command to IPC layer */
+    return XF_CHK_API(xf_ipc_send(&proxy->ipc, &msg, buffer));
+}
+
+/*******************************************************************************
+ * Buffer pool API
+ ******************************************************************************/
+
+/* ...allocate buffer pool */
+int xf_pool_alloc(xf_proxy_t *proxy, u32 number, u32 length, xf_pool_type_t type, xf_pool_t **pool, s32 id, 
+                  xaf_mem_malloc_fxn_t xaf_malloc, xaf_mem_free_fxn_t xaf_free)
+{
+    xf_pool_t      *p;
+    xf_buffer_t    *b;
+    void           *data;
+    int             r;
+ 
+    /* ...unused arg */
+    (void) type;
+
+    /* ...basic sanity checks; number of buffers is positive */
+    XF_CHK_ERR(number > 0, -EINVAL);
+
+    /* ...get properly aligned buffer length */
+    length = (length + XF_PROXY_ALIGNMENT - 1) & ~(XF_PROXY_ALIGNMENT - 1);
+
+    /* ...allocate data structure */
+    p = xaf_malloc(offset_of(xf_pool_t, buffer) + number * sizeof(xf_buffer_t), id);
+    XF_CHK_ERR(p, -ENOMEM);
+
+    /* ...issue memory pool allocation request to remote DSP */
+    xf_proxy_lock(proxy);
+    r = xf_proxy_buffer_alloc(proxy, number * length, &p->p);
+    xf_proxy_unlock(proxy);
+    
+    /* ...if operation is failed, do cleanup */
+    if (r < 0)
+    {
+        TRACE(ERROR, _x("failed to allocate buffer: %d"), r);
+        xaf_free(p, id);
+        return r;
+    }
+    else
+    {
+        /* ...set pool parameters */
+        p->number = number, p->length = length;
+        p->proxy = proxy;
+    }
+ 
+    /* ...create individual buffers and link them into free list */
+    for (p->free = b = &p->buffer[0], data = p->p; number > 0; number--, b++)
+    {
+        /* ...set address of the buffer (no length there) */
+        b->address = data;
+            
+        /* ...file buffer into the free list */
+        b->link.next = b + 1;
+
+        /* ...advance data pointer in contiguous buffer */
+        data = (unsigned char *) data + length;
+    }
+
+    /* ...terminate list of buffers (not too good - tbd) */
+    b[-1].link.next = NULL;
+
+    TRACE(BUFFER, _b("[%p]: pool[%p] created: %u * %u"), proxy, p, p->number, p->length);
+    
+    /* ...return buffer pointer */
+    *pool = p;
+    
+    return 0;
+}
+
+/* ...buffer pool destruction */
+void xf_pool_free(xf_pool_t *pool, s32 id, xaf_mem_free_fxn_t xaf_free)
+{
+    xf_proxy_t     *proxy = pool->proxy;
+
+    /* ...check buffers are all freed - tbd */
+
+    /* ...use global proxy lock for pool operations protection */
+    xf_proxy_lock(proxy);
+    
+    /* ...release allocated buffer on remote DSP */
+    xf_proxy_buffer_free(proxy, pool->p, pool->length * pool->number);
+
+    /* ...release global proxy lock */
+    xf_proxy_unlock(proxy);
+    
+    /* ...deallocate pool structure itself */
+    xaf_free(pool, id);
+
+    TRACE(BUFFER, _b("[%p]::pool[%p] destroyed"), proxy, pool);
+}
+
+/* ...get new buffer from a pool */
+xf_buffer_t * xf_buffer_get(xf_pool_t *pool)
+{
+    xf_buffer_t    *b;
+
+    /* ...use global proxy lock for pool operations protection */
+    xf_proxy_lock(pool->proxy);
+    
+    /* ...take buffer from a head of the free list */
+    if ((b = pool->free) != NULL)
+    {
+        /* ...advance free list head */
+        pool->free = b->link.next, b->link.pool = pool;
+
+        TRACE(BUFFER, _b("pool[%p]::get[%p]"), pool, b);
+    }
+
+    xf_proxy_unlock(pool->proxy);
+    
+    return b;
+}
+
+/* ...return buffer back to pool */
+void xf_buffer_put(xf_buffer_t *buffer)
+{
+    xf_pool_t  *pool = buffer->link.pool;
+    
+    /* ...use global proxy lock for pool operations protection */
+    xf_proxy_lock(pool->proxy);
+    
+    /* ...put buffer back to a pool */
+    buffer->link.next = pool->free, pool->free = buffer;
+    
+    TRACE(BUFFER, _b("pool[%p]::put[%p]"), pool, buffer);
+
+    xf_proxy_unlock(pool->proxy);
+}
diff --git a/hifi/xaf/host-apf/proxy/xf-trace.c b/hifi/xaf/host-apf/proxy/xf-trace.c
new file mode 100644
index 0000000..fb90267
--- /dev/null
+++ b/hifi/xaf/host-apf/proxy/xf-trace.c
@@ -0,0 +1,90 @@
+/*******************************************************************************
+* 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.
+
+******************************************************************************/
+
+#include "xf.h"
+#include <sys/time.h>
+
+#if XF_TRACE
+/*******************************************************************************
+ * Local data definitions
+ ******************************************************************************/
+
+/* ...tracing lock */
+static pthread_mutex_t  xf_trace_mutex;
+
+/*******************************************************************************
+ * Tracing facility
+ ******************************************************************************/
+
+/* ...timestamp function */
+static u32 xf_timenow(void)
+{
+    struct timeval          tv;
+
+    /* ...get current time value */
+    gettimeofday(&tv, NULL);
+
+    /* ...wrap over every 100 seconds */
+    return (u32)((tv.tv_sec % 100) * 1000000 + tv.tv_usec);
+}
+
+/* ...tracing initialization */
+void xf_trace_init(const char *banner)
+{
+    /* ...initialize tracing lock */
+    pthread_mutex_init(&xf_trace_mutex, NULL);
+
+    /* ...output banner */
+    xf_trace(banner);
+}
+
+/* ...tracing primitive */
+int xf_trace(const char *format, ...)
+{
+    va_list     args;
+    static char buf[256];
+    char       *b = buf;
+    
+    /* ...get global tracing lock */
+    pthread_mutex_lock(&xf_trace_mutex);
+
+    /* ...output timestamp */
+    b += sprintf(b, "[%08u] ", xf_timenow());
+
+    /* ...output format string */
+    va_start(args, format);
+    b += vsprintf(b, format, args);
+    va_end(args);
+
+    /* ...put terminator */
+    *b = '\0';
+
+    /* ...output prepared string */
+    __xf_puts(buf);
+    
+    /* ...release tracing lock */
+    pthread_mutex_unlock(&xf_trace_mutex);
+
+    return 0;
+}
+
+#endif  /* XF_TRACE */