/*
 * Copyright (c) 2016, 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@linux.intel.com>
 *         Keyon Jie <yang.jie@linux.intel.com>
 *
 * IPC (InterProcessor Communication) provides a method of two way
 * communication between the host processor and the DSP. The IPC used here
 * utilises a shared mailbox and door bell between the host and DSP.
 *
 */

#include <stdbool.h>
#include <sof/debug.h>
#include <sof/timer.h>
#include <sof/interrupt.h>
#include <sof/ipc.h>
#include <sof/mailbox.h>
#include <sof/sof.h>
#include <sof/stream.h>
#include <sof/dai.h>
#include <sof/dma.h>
#include <sof/alloc.h>
#include <sof/wait.h>
#include <sof/trace.h>
#include <sof/ssp.h>
#include <platform/interrupt.h>
#include <platform/mailbox.h>
#include <platform/shim.h>
#include <platform/dma.h>
#include <platform/timer.h>
#include <sof/audio/component.h>
#include <sof/audio/pipeline.h>
#include <uapi/ipc.h>
#include <sof/intel-ipc.h>
#include <sof/dma-trace.h>
#include <sof/cpu.h>
#include <config.h>

#define iGS(x) ((x >> SOF_GLB_TYPE_SHIFT) & 0xf)
#define iCS(x) ((x >> SOF_CMD_TYPE_SHIFT) & 0xfff)

#define IPC_INVALID_SIZE(ipc) \
	(sizeof(*(ipc)) != ipc->hdr.size)

/* IPC context - shared with platform IPC driver */
struct ipc *_ipc;

static inline struct sof_ipc_hdr *mailbox_validate(void)
{
	struct sof_ipc_hdr *hdr = _ipc->comp_data;

	/* read component values from the inbox */
	mailbox_hostbox_read(hdr, 0, sizeof(*hdr));

	/* validate component header */
	if (hdr->size > SOF_IPC_MSG_MAX_SIZE) {
		trace_ipc_error("ebg");
		return NULL;
	}

	/* read rest of component data */
	mailbox_hostbox_read(hdr + 1, sizeof(*hdr), hdr->size - sizeof(*hdr));
	return hdr;
}

#ifdef CONFIG_HOST_PTABLE
/* check if a pipeline is hostless when walking downstream */
static bool is_hostless_downstream(struct comp_dev *current)
{
	struct list_item *clist;

	/* check if current is a HOST comp */
	if (current->comp.type == SOF_COMP_HOST ||
	    current->comp.type == SOF_COMP_SG_HOST)
		return false;

	/* check if the pipeline has a HOST comp downstream */
	list_for_item(clist, &current->bsink_list) {
		struct comp_buffer *buffer;

		buffer = container_of(clist, struct comp_buffer, source_list);

		/* don't go downstream if this component is not connected */
		if (!buffer->connected)
			continue;

		/* dont go downstream if this comp belongs to another pipe */
		if (buffer->sink->comp.pipeline_id != current->comp.pipeline_id)
			continue;

		/* return if there's a host comp downstream */
		if (!is_hostless_downstream(buffer->sink))
			return false;
	}

	return true;
}

/* check if a pipeline is hostless when walking upstream */
static bool is_hostless_upstream(struct comp_dev *current)
{
	struct list_item *clist;

	/* check if current is a HOST comp */
	if (current->comp.type == SOF_COMP_HOST ||
	    current->comp.type == SOF_COMP_SG_HOST)
		return false;

	/* check if the pipeline has a HOST comp upstream */
	list_for_item(clist, &current->bsource_list) {
		struct comp_buffer *buffer;

		buffer = container_of(clist, struct comp_buffer, sink_list);

		/* don't go upstream if this component is not connected */
		if (!buffer->connected)
			continue;

		/* dont go upstream if this comp belongs to another pipeline */
		if (buffer->source->comp.pipeline_id !=
		    current->comp.pipeline_id)
			continue;

		/* return if there is a host comp upstream */
		if (!is_hostless_upstream(buffer->source))
			return false;
	}

	return true;
}
#endif

/*
 * Stream IPC Operations.
 */

/* allocate a new stream */
static int ipc_stream_pcm_params(uint32_t stream)
{
#ifdef CONFIG_HOST_PTABLE
	struct intel_ipc_data *iipc = ipc_get_drvdata(_ipc);
	struct sof_ipc_comp_host *host = NULL;
	struct list_item elem_list;
	struct dma_sg_elem *elem;
	struct list_item *plist;
	uint32_t ring_size;
#endif
	struct sof_ipc_pcm_params *pcm_params = _ipc->comp_data;
	struct sof_ipc_pcm_params_reply reply;
	struct ipc_comp_dev *pcm_dev;
	struct comp_dev *cd;
	int err, posn_offset;

	trace_ipc("SAl");

	/* sanity check size */
	if (IPC_INVALID_SIZE(pcm_params)) {
		trace_ipc_error("eAS");
		return -EINVAL;
	}

	/* get the pcm_dev */
	pcm_dev = ipc_get_comp(_ipc, pcm_params->comp_id);
	if (pcm_dev == NULL) {
		trace_ipc_error("eAC");
		trace_error_value(pcm_params->comp_id);
		return -ENODEV;
	}

	/* sanity check comp */
	if (pcm_dev->cd->pipeline == NULL) {
		trace_ipc_error("eA1");
		trace_error_value(pcm_params->comp_id);
		return -EINVAL;
	}

	/* set params component params */
	cd = pcm_dev->cd;
	cd->params = pcm_params->params;

#ifdef CONFIG_HOST_PTABLE
	list_init(&elem_list);

	/*
	 * walk in both directions to check if the pipeline is hostless
	 * skip page table set up if it is
	 */
	if (is_hostless_downstream(cd) && is_hostless_upstream(cd))
		goto pipe_params;

	/* use DMA to read in compressed page table ringbuffer from host */
	err = ipc_get_page_descriptors(iipc->dmac, iipc->page_table,
				       &pcm_params->params.buffer);
	if (err < 0) {
		trace_ipc_error("eAp");
		goto error;
	}

	/* Parse host tables */
	host = (struct sof_ipc_comp_host *)&cd->comp;
	ring_size = pcm_params->params.buffer.size;

	err = ipc_parse_page_descriptors(iipc->page_table,
					 &pcm_params->params.buffer,
					 &elem_list, host->direction);
	if (err < 0) {
		trace_ipc_error("eAP");
		goto error;
	}

	list_for_item(plist, &elem_list) {
		elem = container_of(plist, struct dma_sg_elem, list);

		err = comp_host_buffer(cd, elem, ring_size);
		if (err < 0) {
			trace_ipc_error("ePb");
			goto error;
		}

		list_item_del(&elem->list);
		rfree(elem);
	}

pipe_params:
#endif

	/* configure pipeline audio params */
	err = pipeline_params(pcm_dev->cd->pipeline, pcm_dev->cd, pcm_params);
	if (err < 0) {
		trace_ipc_error("eAa");
		goto error;
	}

	/* prepare pipeline audio params */
	err = pipeline_prepare(pcm_dev->cd->pipeline, pcm_dev->cd);
	if (err < 0) {
		trace_ipc_error("eAr");
		goto error;
	}

	posn_offset = ipc_get_posn_offset(_ipc, pcm_dev->cd->pipeline);
	if (posn_offset < 0) {
		trace_ipc_error("eAo");
		goto error;
	}
	/* write component values to the outbox */
	reply.rhdr.hdr.size = sizeof(reply);
	reply.rhdr.hdr.cmd = stream;
	reply.rhdr.error = 0;
	reply.comp_id = pcm_params->comp_id;
	reply.posn_offset = posn_offset;
	mailbox_hostbox_write(0, &reply, sizeof(reply));
	return 1;

error:
#ifdef CONFIG_HOST_PTABLE
	list_for_item(plist, &elem_list) {
		elem = container_of(plist, struct dma_sg_elem, list);
		list_item_del(&elem->list);
		rfree(elem);
	}
#endif

	err = pipeline_reset(pcm_dev->cd->pipeline, pcm_dev->cd);
	if (err < 0)
		trace_ipc_error("eA!");
	return -EINVAL;
}

/* free stream resources */
static int ipc_stream_pcm_free(uint32_t header)
{
	struct sof_ipc_stream *free_req = _ipc->comp_data;
	struct ipc_comp_dev *pcm_dev;

	trace_ipc("SFr");

	/* sanity check size */
	if (IPC_INVALID_SIZE(free_req)) {
		trace_ipc_error("eFs");
		return -EINVAL;
	}

	/* get the pcm_dev */
	pcm_dev = ipc_get_comp(_ipc, free_req->comp_id);
	if (pcm_dev == NULL) {
		trace_ipc_error("eFr");
		return -ENODEV;
	}

	/* sanity check comp */
	if (pcm_dev->cd->pipeline == NULL) {
		trace_ipc_error("eF1");
		trace_error_value(free_req->comp_id);
		return -EINVAL;
	}

	/* reset the pipeline */
	return pipeline_reset(pcm_dev->cd->pipeline, pcm_dev->cd);
}

/* get stream position */
static int ipc_stream_position(uint32_t header)
{
	struct sof_ipc_stream *stream = _ipc->comp_data;
	struct sof_ipc_stream_posn posn;
	struct ipc_comp_dev *pcm_dev;

	trace_ipc("pos");

	memset(&posn, 0, sizeof(posn));

	/* sanity check size */
	if (IPC_INVALID_SIZE(stream)) {
		trace_ipc_error("ePs");
		return -EINVAL;
	}

	/* get the pcm_dev */
	pcm_dev = ipc_get_comp(_ipc, stream->comp_id);
	if (pcm_dev == NULL) {
		trace_ipc_error("epo");
		return -ENODEV;
	}

	/* set message fields - TODO; get others */
	posn.rhdr.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_POSITION |
			    stream->comp_id;
	posn.rhdr.hdr.size = sizeof(posn);
	posn.comp_id = stream->comp_id;

	/* get the stream positions and timestamps */
	pipeline_get_timestamp(pcm_dev->cd->pipeline, pcm_dev->cd, &posn);

	/* copy positions to stream region */
	mailbox_stream_write(pcm_dev->cd->pipeline->posn_offset,
			     &posn, sizeof(posn));

	return 1;
}

/* send stream position */
int ipc_stream_send_position(struct comp_dev *cdev,
	struct sof_ipc_stream_posn *posn)
{
	struct sof_ipc_hdr hdr;

	tracev_ipc("Pos");
	posn->rhdr.hdr.cmd =  SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_POSITION |
			      cdev->comp.id;
	posn->rhdr.hdr.size = sizeof(*posn);
	posn->comp_id = cdev->comp.id;

	hdr.cmd = posn->rhdr.hdr.cmd;
	hdr.size = sizeof(hdr);

	mailbox_stream_write(cdev->pipeline->posn_offset, posn, sizeof(*posn));
	return ipc_queue_host_message(_ipc, posn->rhdr.hdr.cmd, &hdr,
				      sizeof(hdr), NULL, 0, NULL, NULL, 0);
}

/* send stream position TODO: send compound message  */
int ipc_stream_send_xrun(struct comp_dev *cdev,
	struct sof_ipc_stream_posn *posn)
{
	struct sof_ipc_hdr hdr;

	posn->rhdr.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_TRIG_XRUN;
	posn->rhdr.hdr.size = sizeof(*posn);
	posn->comp_id = cdev->comp.id;

	hdr.cmd = posn->rhdr.hdr.cmd;
	hdr.size = sizeof(hdr);

	mailbox_stream_write(cdev->pipeline->posn_offset, posn, sizeof(*posn));
	return ipc_queue_host_message(_ipc, posn->rhdr.hdr.cmd, &hdr,
				      sizeof(hdr), NULL, 0, NULL, NULL, 0);
}

static int ipc_stream_trigger(uint32_t header)
{
	struct ipc_comp_dev *pcm_dev;
	uint32_t cmd = COMP_TRIGGER_RELEASE;
	struct sof_ipc_stream *stream  = _ipc->comp_data;
	uint32_t ipc_cmd = (header & SOF_CMD_TYPE_MASK) >> SOF_CMD_TYPE_SHIFT;
	int ret;

	trace_ipc("tri");

	/* sanity check size */
	if (IPC_INVALID_SIZE(stream)) {
		trace_ipc_error("eRs");
		return -EINVAL;
	}

	/* get the pcm_dev */
	pcm_dev = ipc_get_comp(_ipc, stream->comp_id);
	if (pcm_dev == NULL) {
		trace_ipc_error("eRg");
		return -ENODEV;
	}

	switch (ipc_cmd) {
	case iCS(SOF_IPC_STREAM_TRIG_START):
		cmd = COMP_TRIGGER_START;
		break;
	case iCS(SOF_IPC_STREAM_TRIG_STOP):
		cmd = COMP_TRIGGER_STOP;
		break;
	case iCS(SOF_IPC_STREAM_TRIG_PAUSE):
		cmd = COMP_TRIGGER_PAUSE;
		break;
	case iCS(SOF_IPC_STREAM_TRIG_RELEASE):
		cmd = COMP_TRIGGER_RELEASE;
		break;
	/* XRUN is special case- TODO */
	case iCS(SOF_IPC_STREAM_TRIG_XRUN):
		return 0;
	}

	/* trigger the component */
	ret = pipeline_trigger(pcm_dev->cd->pipeline, pcm_dev->cd, cmd);
	if (ret < 0) {
		trace_ipc_error("eRc");
		trace_error_value(ipc_cmd);
	}

	return ret;
}

static int ipc_glb_stream_message(uint32_t header)
{
	uint32_t cmd = (header & SOF_CMD_TYPE_MASK) >> SOF_CMD_TYPE_SHIFT;

	switch (cmd) {
	case iCS(SOF_IPC_STREAM_PCM_PARAMS):
		return ipc_stream_pcm_params(header);
	case iCS(SOF_IPC_STREAM_PCM_FREE):
		return ipc_stream_pcm_free(header);
	case iCS(SOF_IPC_STREAM_TRIG_START):
	case iCS(SOF_IPC_STREAM_TRIG_STOP):
	case iCS(SOF_IPC_STREAM_TRIG_PAUSE):
	case iCS(SOF_IPC_STREAM_TRIG_RELEASE):
	case iCS(SOF_IPC_STREAM_TRIG_DRAIN):
	case iCS(SOF_IPC_STREAM_TRIG_XRUN):
		return ipc_stream_trigger(header);
	case iCS(SOF_IPC_STREAM_POSITION):
		return ipc_stream_position(header);
	default:
		trace_ipc_error("es1");
		return -EINVAL;
	}
}

/*
 * DAI IPC Operations.
 */

static int ipc_dai_config(uint32_t header)
{
	struct sof_ipc_dai_config *config = _ipc->comp_data;
	struct dai *dai;
	int ret;

	trace_ipc("DsF");

	/* get DAI */
	dai = dai_get(config->type, config->dai_index);
	if (dai == NULL) {
		trace_ipc_error("eDi");
		trace_error_value(config->type);
		trace_error_value(config->dai_index);
		return -ENODEV;
	}

	/* configure DAI */
	ret = dai_set_config(dai, config);
	if (ret < 0) {
		trace_ipc_error("eDC");
		return ret;
	}

	/* now send params to all DAI components who use that physical DAI */
	return ipc_comp_dai_config(_ipc, config);
}

static int ipc_glb_dai_message(uint32_t header)
{
	uint32_t cmd = (header & SOF_CMD_TYPE_MASK) >> SOF_CMD_TYPE_SHIFT;

	switch (cmd) {
	case iCS(SOF_IPC_DAI_CONFIG):
		return ipc_dai_config(header);
	case iCS(SOF_IPC_DAI_LOOPBACK):
		//return ipc_comp_set_value(header, COMP_CMD_LOOPBACK);
	default:
		trace_ipc_error("eDc");
		trace_error_value(header);
		return -EINVAL;
	}
}

/*
 * PM IPC Operations.
 */

static int ipc_pm_context_size(uint32_t header)
{
	struct sof_ipc_pm_ctx pm_ctx;

	trace_ipc("PMs");

	bzero(&pm_ctx, sizeof(pm_ctx));

	/* TODO: calculate the context and size of host buffers required */

	/* write the context to the host driver */
	mailbox_hostbox_write(0, &pm_ctx, sizeof(pm_ctx));
	return 1;
}

static int ipc_pm_context_save(uint32_t header)
{
	struct sof_ipc_pm_ctx *pm_ctx = _ipc->comp_data;
	struct intel_ipc_data *iipc = ipc_get_drvdata(_ipc);

	trace_ipc("PMs");

	/* TODO: check we are inactive - all streams are suspended */

	/* TODO: mask ALL platform interrupts except DMA */

	/* TODO now save the context - create SG buffer config using */
	//mm_pm_context_save(struct dma_sg_config *sg);

	/* mask all DSP interrupts */
	arch_interrupt_disable_mask(0xffff);

	/* TODO: mask ALL platform interrupts inc DMA */

	/* TODO: clear any outstanding platform IRQs - TODO refine */

	/* TODO: stop ALL timers */
	platform_timer_stop(platform_timer);

	/* TODO: disable SSP and DMA HW */

	/* TODO: save the context */
	//reply.entries_no = 0;

	/* write the context to the host driver */
	mailbox_hostbox_write(0, pm_ctx, sizeof(*pm_ctx));

	iipc->pm_prepare_D3 = 1;

	return 1;
}

static int ipc_pm_context_restore(uint32_t header)
{
	struct sof_ipc_pm_ctx *pm_ctx = _ipc->comp_data;

	trace_ipc("PMr");

	/* restore context placeholder */
	mailbox_hostbox_write(0, pm_ctx, sizeof(*pm_ctx));

	return 1;
}

static int ipc_pm_core_enable(uint32_t header)
{
	struct sof_ipc_pm_core_config *pm_core_config = _ipc->comp_data;
	int i = 0;

	trace_ipc("PMc");

	for (i = 0; i < PLATFORM_CORE_COUNT; i++) {
		if (i != PLATFORM_MASTER_CORE_ID) {
			if (pm_core_config->enable_mask & (1 << i))
				cpu_enable_core(i);
			else
				cpu_disable_core(i);
		}
	}

	return 0;
}

static int ipc_glb_pm_message(uint32_t header)
{
	uint32_t cmd = (header & SOF_CMD_TYPE_MASK) >> SOF_CMD_TYPE_SHIFT;

	switch (cmd) {
	case iCS(SOF_IPC_PM_CTX_SAVE):
		return ipc_pm_context_save(header);
	case iCS(SOF_IPC_PM_CTX_RESTORE):
		return ipc_pm_context_restore(header);
	case iCS(SOF_IPC_PM_CTX_SIZE):
		return ipc_pm_context_size(header);
	case iCS(SOF_IPC_PM_CORE_ENABLE):
		return ipc_pm_core_enable(header);
	case iCS(SOF_IPC_PM_CLK_SET):
	case iCS(SOF_IPC_PM_CLK_GET):
	case iCS(SOF_IPC_PM_CLK_REQ):
	default:
		return -EINVAL;
	}
}

/*
 * Debug IPC Operations.
 */

static int ipc_dma_trace_config(uint32_t header)
{
#ifdef CONFIG_HOST_PTABLE
	struct intel_ipc_data *iipc = ipc_get_drvdata(_ipc);
	struct list_item elem_list;
	struct dma_sg_elem *elem;
	struct list_item *plist;
	uint32_t ring_size;
#endif
	struct sof_ipc_dma_trace_params *params = _ipc->comp_data;
	struct sof_ipc_reply reply;
	int err;

	trace_ipc("DA1");

	/* sanity check size */
	if (IPC_INVALID_SIZE(params)) {
		trace_ipc_error("DAs");
		return -EINVAL;
	}

#ifdef CONFIG_HOST_PTABLE

	list_init(&elem_list);

	/* use DMA to read in compressed page table ringbuffer from host */
	err = ipc_get_page_descriptors(iipc->dmac, iipc->page_table,
				       &params->buffer);
	if (err < 0) {
		trace_ipc_error("eCp");
		goto error;
	}

	trace_ipc("DAg");

	/* Parse host tables */
	ring_size = params->buffer.size;

	err = ipc_parse_page_descriptors(iipc->page_table, &params->buffer,
					 &elem_list, SOF_IPC_STREAM_CAPTURE);
	if (err < 0) {
		trace_ipc_error("ePP");
		goto error;
	}

	list_for_item(plist, &elem_list) {
		elem = container_of(plist, struct dma_sg_elem, list);

		err = dma_trace_host_buffer(_ipc->dmat, elem, ring_size);
		if (err < 0) {
			trace_ipc_error("ePb");
			goto error;
		}

		list_item_del(&elem->list);
		rfree(elem);
	}
#else
	/* stream tag of capture stream for DMA trace */
	_ipc->dmat->stream_tag = params->stream_tag;

	/* host buffer size for DMA trace */
	_ipc->dmat->host_size = params->buffer.size;
#endif
	trace_ipc("DAp");

	err = dma_trace_enable(_ipc->dmat);
	if (err < 0)
		goto error;

	/* write component values to the outbox */
	reply.hdr.size = sizeof(reply);
	reply.hdr.cmd = header;
	reply.error = 0;
	mailbox_hostbox_write(0, &reply, sizeof(reply));
	return 0;

error:
#ifdef CONFIG_HOST_PTABLE
	list_for_item(plist, &elem_list) {
		elem = container_of(plist, struct dma_sg_elem, list);
		list_item_del(&elem->list);
		rfree(elem);
	}
#endif

	if (err < 0)
		trace_ipc_error("eA!");
	return -EINVAL;
}

/* send DMA trace host buffer position to host */
int ipc_dma_trace_send_position(void)
{
	struct sof_ipc_dma_trace_posn posn;

	posn.rhdr.hdr.cmd =  SOF_IPC_GLB_TRACE_MSG | SOF_IPC_TRACE_DMA_POSITION;
	posn.host_offset = _ipc->dmat->host_offset;
	posn.overflow = _ipc->dmat->overflow;
	posn.messages = _ipc->dmat->messages;
	posn.rhdr.hdr.size = sizeof(posn);

	return ipc_queue_host_message(_ipc, posn.rhdr.hdr.cmd, &posn,
		sizeof(posn), NULL, 0, NULL, NULL, 1);
}

static int ipc_glb_debug_message(uint32_t header)
{
	uint32_t cmd = (header & SOF_CMD_TYPE_MASK) >> SOF_CMD_TYPE_SHIFT;

	trace_ipc("Idn");

	switch (cmd) {
	case iCS(SOF_IPC_TRACE_DMA_PARAMS):
		return ipc_dma_trace_config(header);
	default:
		trace_ipc_error("eDc");
		trace_error_value(header);
		return -EINVAL;
	}
}

/*
 * Topology IPC Operations.
 */

/* get/set component values or runtime data */
static int ipc_comp_value(uint32_t header, uint32_t cmd)
{
	struct ipc_comp_dev *comp_dev;
	struct sof_ipc_ctrl_data *data = _ipc->comp_data;
	int ret;

	trace_ipc("VoG");

	/* get the component */
	comp_dev = ipc_get_comp(_ipc, data->comp_id);
	if (comp_dev == NULL){
		trace_ipc_error("eVg");
		trace_error_value(data->comp_id);
		return -ENODEV;
	}
	
	/* get component values */
	ret = comp_cmd(comp_dev->cd, cmd, data);
	if (ret < 0) {
		trace_ipc_error("eVG");
		return ret;
	}

	/* write component values to the outbox */
	mailbox_hostbox_write(0, data, data->rhdr.hdr.size);
	return 1;
}

static int ipc_glb_comp_message(uint32_t header)
{
	uint32_t cmd = (header & SOF_CMD_TYPE_MASK) >> SOF_CMD_TYPE_SHIFT;

	switch (cmd) {
	case iCS(SOF_IPC_COMP_SET_VALUE):
		return ipc_comp_value(header, COMP_CMD_SET_VALUE);
	case iCS(SOF_IPC_COMP_GET_VALUE):
		return ipc_comp_value(header, COMP_CMD_GET_VALUE);
	case iCS(SOF_IPC_COMP_SET_DATA):
		return ipc_comp_value(header, COMP_CMD_SET_DATA);
	case iCS(SOF_IPC_COMP_GET_DATA):
		return ipc_comp_value(header, COMP_CMD_GET_DATA);
	default:
		trace_ipc_error("eCc");
		trace_error_value(header);
		return -EINVAL;
	}
}

static int ipc_glb_tplg_comp_new(uint32_t header)
{
	struct sof_ipc_comp *comp = _ipc->comp_data;
	struct sof_ipc_comp_reply reply;
	int ret;

	trace_ipc("tcn");

	/* register component */
	ret = ipc_comp_new(_ipc, comp);
	if (ret < 0) {
		trace_ipc_error("cn1");
		return ret;
	}

	/* write component values to the outbox */
	reply.rhdr.hdr.size = sizeof(reply);
	reply.rhdr.hdr.cmd = header;
	reply.rhdr.error = 0;
	reply.offset = 0; /* TODO: set this up for mmaped components */
	mailbox_hostbox_write(0, &reply, sizeof(reply));
	return 1;
}

static int ipc_glb_tplg_buffer_new(uint32_t header)
{
	struct sof_ipc_buffer *ipc_buffer = _ipc->comp_data;
	struct sof_ipc_comp_reply reply;
	int ret;

	trace_ipc("Ibn");

	ret = ipc_buffer_new(_ipc, ipc_buffer);
	if (ret < 0) {
		trace_ipc_error("bn1");
		return ret;
	}

	/* write component values to the outbox */
	reply.rhdr.hdr.size = sizeof(reply);
	reply.rhdr.hdr.cmd = header;
	reply.rhdr.error = 0;
	reply.offset = 0; /* TODO: set this up for mmaped components */
	mailbox_hostbox_write(0, &reply, sizeof(reply));
	return 1;
}

static int ipc_glb_tplg_pipe_new(uint32_t header)
{
	struct sof_ipc_pipe_new *ipc_pipeline = _ipc->comp_data;
	struct sof_ipc_comp_reply reply;
	int ret;

	trace_ipc("Ipn");

	/* sanity check size */
	if (IPC_INVALID_SIZE(ipc_pipeline)) {
		trace_ipc_error("Ips");
		return -EINVAL;
	}

	ret = ipc_pipeline_new(_ipc, ipc_pipeline);
	if (ret < 0) {
		trace_ipc_error("pn1");
		return ret;
	}

	/* write component values to the outbox */
	reply.rhdr.hdr.size = sizeof(reply);
	reply.rhdr.hdr.cmd = header;
	reply.rhdr.error = 0;
	reply.offset = 0; /* TODO: set this up for mmaped components */
	mailbox_hostbox_write(0, &reply, sizeof(reply));
	return 1;
}

static int ipc_glb_tplg_pipe_complete(uint32_t header)
{
	struct sof_ipc_pipe_ready *ipc_pipeline = _ipc->comp_data;

	trace_ipc("Ipc");

	return ipc_pipeline_complete(_ipc, ipc_pipeline->comp_id);
}

static int ipc_glb_tplg_comp_connect(uint32_t header)
{
	struct sof_ipc_pipe_comp_connect *connect = _ipc->comp_data;

	trace_ipc("Icn");

	/* sanity check size */
	if (IPC_INVALID_SIZE(connect)) {
		trace_ipc_error("Ics");
		return -EINVAL;
	}

	return ipc_comp_connect(_ipc, connect);
}

static int ipc_glb_tplg_free(uint32_t header,
		int (*free_func)(struct ipc *ipc, uint32_t id))
{
	struct sof_ipc_free *ipc_free = _ipc->comp_data;

	trace_ipc("Tcf");

	/* sanity check size */
	if (IPC_INVALID_SIZE(ipc_free)) {
		trace_ipc_error("Tcs");
		return -EINVAL;
	}

	/* free the object */
	free_func(_ipc, ipc_free->id);

	return 0;
}

static int ipc_glb_tplg_message(uint32_t header)
{
	uint32_t cmd = (header & SOF_CMD_TYPE_MASK) >> SOF_CMD_TYPE_SHIFT;

	switch (cmd) {
	case iCS(SOF_IPC_TPLG_COMP_NEW):
		return ipc_glb_tplg_comp_new(header);
	case iCS(SOF_IPC_TPLG_COMP_FREE):
		return ipc_glb_tplg_free(header, ipc_comp_free);
	case iCS(SOF_IPC_TPLG_COMP_CONNECT):
		return ipc_glb_tplg_comp_connect(header);
	case iCS(SOF_IPC_TPLG_PIPE_NEW):
		return ipc_glb_tplg_pipe_new(header);
	case iCS(SOF_IPC_TPLG_PIPE_COMPLETE):
		return ipc_glb_tplg_pipe_complete(header);
	case iCS(SOF_IPC_TPLG_PIPE_FREE):
		return ipc_glb_tplg_free(header, ipc_pipeline_free);
	case iCS(SOF_IPC_TPLG_BUFFER_NEW):
		return ipc_glb_tplg_buffer_new(header);
	case iCS(SOF_IPC_TPLG_BUFFER_FREE):
		return ipc_glb_tplg_free(header, ipc_buffer_free);
	default:
		trace_ipc_error("eTc");
		trace_error_value(header);
		return -EINVAL;
	}
}

/*
 * Global IPC Operations.
 */

int ipc_cmd(void)
{
	struct sof_ipc_hdr *hdr;
	uint32_t type;

	hdr = mailbox_validate();
	if (hdr == NULL) {
		trace_ipc_error("hdr");
		return -EINVAL;
	}

	type = (hdr->cmd & SOF_GLB_TYPE_MASK) >> SOF_GLB_TYPE_SHIFT;

	switch (type) {
	case iGS(SOF_IPC_GLB_REPLY):
		return 0;
	case iGS(SOF_IPC_GLB_COMPOUND):
		return -EINVAL;	/* TODO */
	case iGS(SOF_IPC_GLB_TPLG_MSG):
		return ipc_glb_tplg_message(hdr->cmd);
	case iGS(SOF_IPC_GLB_PM_MSG):
		return ipc_glb_pm_message(hdr->cmd);
	case iGS(SOF_IPC_GLB_COMP_MSG):
		return ipc_glb_comp_message(hdr->cmd);
	case iGS(SOF_IPC_GLB_STREAM_MSG):
		return ipc_glb_stream_message(hdr->cmd);
	case iGS(SOF_IPC_GLB_DAI_MSG):
		return ipc_glb_dai_message(hdr->cmd);
	case iGS(SOF_IPC_GLB_TRACE_MSG):
		return ipc_glb_debug_message(hdr->cmd);
	default:
		trace_ipc_error("eGc");
		trace_error_value(type);
		return -EINVAL;
	}
}

/* locks held by caller */
static inline struct ipc_msg *msg_get_empty(struct ipc *ipc)
{
	struct ipc_msg *msg = NULL;

	if (!list_is_empty(&ipc->empty_list)) {
		msg = list_first_item(&ipc->empty_list, struct ipc_msg, list);
		list_item_del(&msg->list);
	}

	return msg;
}

static inline struct ipc_msg *ipc_glb_stream_message_find(struct ipc *ipc,
	struct sof_ipc_stream_posn *posn)
{
	struct list_item *plist;
	struct ipc_msg *msg = NULL;
	struct sof_ipc_stream_posn *old_posn = NULL;
	uint32_t cmd;

	/* Check whether the command is expected */
	cmd = (posn->rhdr.hdr.cmd & SOF_CMD_TYPE_MASK) >> SOF_CMD_TYPE_SHIFT;

	switch (cmd) {
	case iCS(SOF_IPC_STREAM_TRIG_XRUN):
	case iCS(SOF_IPC_STREAM_POSITION):

		/* iterate host message list for searching */
		list_for_item(plist, &ipc->msg_list) {
			msg = container_of(plist, struct ipc_msg, list);
			if (msg->header == posn->rhdr.hdr.cmd) {
				old_posn = (struct sof_ipc_stream_posn *)msg->tx_data;
				if (old_posn->comp_id == posn->comp_id)
					return msg;
			}
		}
		break;
	default:
		break;
	}

	/* no match */
	return NULL;
}

static inline struct ipc_msg *ipc_glb_trace_message_find(struct ipc *ipc,
	struct sof_ipc_dma_trace_posn *posn)
{
	struct list_item *plist;
	struct ipc_msg *msg = NULL;
	uint32_t cmd;

	/* Check whether the command is expected */
	cmd = (posn->rhdr.hdr.cmd & SOF_CMD_TYPE_MASK) >> SOF_CMD_TYPE_SHIFT;

	switch (cmd) {
	case iCS(SOF_IPC_TRACE_DMA_POSITION):
		/* iterate host message list for searching */
		list_for_item(plist, &ipc->msg_list) {
			msg = container_of(plist, struct ipc_msg, list);
			if (msg->header == posn->rhdr.hdr.cmd)
				return msg;
		}
		break;
	default:
		break;
	}

	/* no match */
	return NULL;
}

static inline struct ipc_msg *msg_find(struct ipc *ipc, uint32_t header,
	void *tx_data)
{
	uint32_t type;

	/* use different sub function for different global message type */
	type = (header & SOF_GLB_TYPE_MASK) >> SOF_GLB_TYPE_SHIFT;

	switch (type) {
	case iGS(SOF_IPC_GLB_STREAM_MSG):
		return ipc_glb_stream_message_find(ipc,
			(struct sof_ipc_stream_posn *)tx_data);
	case iGS(SOF_IPC_GLB_TRACE_MSG):
		return ipc_glb_trace_message_find(ipc,
			(struct sof_ipc_dma_trace_posn *)tx_data);
	default:
		/* not found */
		return NULL;
	}
}

int ipc_queue_host_message(struct ipc *ipc, uint32_t header,
	void *tx_data, size_t tx_bytes, void *rx_data,
	size_t rx_bytes, void (*cb)(void*, void*), void *cb_data, uint32_t replace)
{
	struct ipc_msg *msg = NULL;
	uint32_t flags, found = 0;
	int ret = 0;

	spin_lock_irq(&ipc->lock, flags);

	/* do we need to replace an existing message? */
	if (replace)
		msg = msg_find(ipc, header, tx_data);

	/* do we need to use a new empty message? */
	if (msg)
		found = 1;
	else
		msg = msg_get_empty(ipc);

	if (msg == NULL) {
		trace_ipc_error("eQb");
		ret = -EBUSY;
		goto out;
	}

	/* prepare the message */
	msg->header = header;
	msg->tx_size = tx_bytes;
	msg->rx_size = rx_bytes;
	msg->cb_data = cb_data;
	msg->cb = cb;

	/* copy mailbox data to message */
	if (tx_bytes > 0 && tx_bytes < SOF_IPC_MSG_MAX_SIZE)
		rmemcpy(msg->tx_data, tx_data, tx_bytes);

	if (!found) {
		/* now queue the message */
		ipc->dsp_pending = 1;
		list_item_append(&msg->list, &ipc->msg_list);
	}

out:
	spin_unlock_irq(&ipc->lock, flags);
	return ret;
}

/* process current message */
int ipc_process_msg_queue(void)
{
	if (_ipc->host_pending)
		ipc_platform_do_cmd(_ipc);
	if (_ipc->dsp_pending)
		ipc_platform_send_msg(_ipc);
	return 0;
}
