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