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 <rtos/alloc.h>
16 #include <sof/lib/memory.h>
17 #include <sof/list.h>
18 #include <sof/platform.h>
19 #include <rtos/task.h>
20 #include <rtos/sof.h>
21 #include <rtos/spinlock.h>
22 #include <sof/trace/trace.h>
23 #include <sof/ipc/common.h>
24 #include <ipc/trace.h>
25 
26 #include <stdbool.h>
27 #include <stdint.h>
28 
29 struct dai_config;
30 struct dma;
31 struct dma_sg_elem_array;
32 
33 struct ipc_msg {
34 	uint32_t header;	/* specific to platform */
35 	uint32_t extension;	/* extension specific to platform */
36 	uint32_t tx_size;	/* payload size in bytes */
37 	void *tx_data;		/* pointer to payload data */
38 	struct list_item list;
39 };
40 
41 /**
42  * \brief Initialize a new IPC message.
43  * @param header Message header metadata
44  * @param extension Message header extension metadata
45  * @param size Message data size in bytes.
46  * @return New IPC message.
47  */
ipc_msg_w_ext_init(uint32_t header,uint32_t extension,uint32_t size)48 static inline struct ipc_msg *ipc_msg_w_ext_init(uint32_t header, uint32_t extension,
49 						 uint32_t size)
50 {
51 	struct ipc_msg *msg;
52 
53 	msg = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, sizeof(*msg));
54 	if (!msg)
55 		return NULL;
56 
57 	if (size) {
58 		msg->tx_data = rzalloc(SOF_MEM_ZONE_RUNTIME_SHARED, 0, SOF_MEM_CAPS_RAM, size);
59 		if (!msg->tx_data) {
60 			rfree(msg);
61 			return NULL;
62 		}
63 	}
64 
65 	msg->header = header;
66 	msg->extension = extension;
67 	msg->tx_size = size;
68 	list_init(&msg->list);
69 
70 	return msg;
71 }
72 
73 /**
74  * \brief Initialise a new IPC message.
75  * @param header Message header metadata
76  * @param size Message data size in bytes.
77  * @return New IPC message.
78  */
ipc_msg_init(uint32_t header,uint32_t size)79 static inline struct ipc_msg *ipc_msg_init(uint32_t header, uint32_t size)
80 {
81 	return ipc_msg_w_ext_init(header, 0, size);
82 }
83 
84 /**
85  * \brief Frees IPC message header and data.
86  * @param msg The IPC message to be freed.
87  */
ipc_msg_free(struct ipc_msg * msg)88 static inline void ipc_msg_free(struct ipc_msg *msg)
89 {
90 	if (!msg)
91 		return;
92 
93 	struct ipc *ipc = ipc_get();
94 	k_spinlock_key_t key;
95 
96 	key = k_spin_lock(&ipc->lock);
97 
98 	list_item_del(&msg->list);
99 	rfree(msg->tx_data);
100 	rfree(msg);
101 
102 	k_spin_unlock(&ipc->lock, key);
103 }
104 
105 /**
106  * \brief Sends the next message in the IPC message queue.
107  */
108 void ipc_send_queued_msg(void);
109 
110 /**
111  * \brief Queues an IPC message for transmission.
112  * @param msg The IPC message to be freed.
113  * @param data The message data.
114  * @param high_priority True if a high priortity message.
115  */
116 void ipc_msg_send(struct ipc_msg *msg, void *data, bool high_priority);
117 
118 /**
119  * \brief Build stream position IPC message.
120  * @param[in,out] posn Stream position message
121  * @param[in] type Stream message type
122  * @param[in] id Stream ID.
123  */
124 void ipc_build_stream_posn(struct sof_ipc_stream_posn *posn, uint32_t type,
125 			   uint32_t id);
126 
127 /**
128  * \brief Build component event IPC message.
129  * @param[in,out] event Component event message
130  * @param[in] type Component event type
131  * @param[in] id Component ID.
132  */
133 void ipc_build_comp_event(struct sof_ipc_comp_event *event, uint32_t type,
134 			  uint32_t id);
135 
136 /**
137  * \brief Check if trace buffer is ready for transmission.
138  * @param[in,out] avail Data available in trace buffer
139  */
140 bool ipc_trigger_trace_xfer(uint32_t avail);
141 
142 /**
143  * \brief Build trace position IPC message.
144  * @param[in,out] posn Trace position message
145  */
146 void ipc_build_trace_posn(struct sof_ipc_dma_trace_posn *posn);
147 
148 #endif
149