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