1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2016 Intel Corporation. All rights reserved.
4  *
5  * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
6  *         Keyon Jie <yang.jie@linux.intel.com>
7  */
8 
9 #ifndef __SOF_IPC_MSG_H__
10 #define __SOF_IPC_MSG_H__
11 
12 #include <sof/audio/buffer.h>
13 #include <sof/audio/component.h>
14 #include <sof/audio/pipeline.h>
15 #include <sof/lib/alloc.h>
16 #include <sof/lib/memory.h>
17 #include <sof/list.h>
18 #include <sof/platform.h>
19 #include <sof/schedule/task.h>
20 #include <sof/sof.h>
21 #include <sof/spinlock.h>
22 #include <sof/trace/trace.h>
23 #include <sof/ipc/common.h>
24 #include <stdbool.h>
25 #include <stdint.h>
26 
27 struct dai_config;
28 struct dma;
29 struct dma_sg_elem_array;
30 
31 struct ipc_msg {
32 	uint32_t header;	/* specific to platform */
33 	uint32_t tx_size;	/* payload size in bytes */
34 	void *tx_data;		/* pointer to payload data */
35 	struct list_item list;
36 };
37 
38 /**
39  * \brief Initialise a new IPC message.
40  * @param header Message header metadata
41  * @param size Message size in bytes.
42  * @return New IPC message.
43  */
ipc_msg_init(uint32_t header,uint32_t size)44 static inline struct ipc_msg *ipc_msg_init(uint32_t header, uint32_t size)
45 {
46 	struct ipc_msg *msg;
47 
48 	msg = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*msg));
49 	if (!msg)
50 		return NULL;
51 
52 	msg->tx_data = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, size);
53 	if (!msg->tx_data) {
54 		rfree(msg);
55 		return NULL;
56 	}
57 
58 	msg->header = header;
59 	msg->tx_size = size;
60 	list_init(&msg->list);
61 
62 	return msg;
63 }
64 
65 /**
66  * \brief Frees IPC message header and data.
67  * @param msg The IPC message to be freed.
68  */
ipc_msg_free(struct ipc_msg * msg)69 static inline void ipc_msg_free(struct ipc_msg *msg)
70 {
71 	if (!msg)
72 		return;
73 
74 	struct ipc *ipc = ipc_get();
75 	uint32_t flags;
76 
77 	spin_lock_irq(&ipc->lock, flags);
78 
79 	list_item_del(&msg->list);
80 	rfree(msg->tx_data);
81 	rfree(msg);
82 
83 	spin_unlock_irq(&ipc->lock, flags);
84 }
85 
86 /**
87  * \brief Sends the next message in the IPC message queue.
88  */
89 void ipc_send_queued_msg(void);
90 
91 /**
92  * \brief Queues an IPC message for transmission.
93  * @param msg The IPC message to be freed.
94  * @param data The message data.
95  * @param high_priority True if a high priortity message.
96  */
97 void ipc_msg_send(struct ipc_msg *msg, void *data, bool high_priority);
98 
99 /**
100  * \brief Build stream position IPC message.
101  * @param[in,out] posn Stream position message
102  * @param[in] type Stream message type
103  * @param[in] id Stream ID.
104  */
105 void ipc_build_stream_posn(struct sof_ipc_stream_posn *posn, uint32_t type,
106 			   uint32_t id);
107 
108 /**
109  * \brief Build component event IPC message.
110  * @param[in,out] event Component event message
111  * @param[in] type Component event type
112  * @param[in] id Component ID.
113  */
114 void ipc_build_comp_event(struct sof_ipc_comp_event *event, uint32_t type,
115 			  uint32_t id);
116 
117 /**
118  * \brief Build trace position IPC message.
119  * @param[in,out] posn Trace position message
120  */
121 void ipc_build_trace_posn(struct sof_ipc_dma_trace_posn *posn);
122 
123 #endif
124