1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2023 Intel Corporation. All rights reserved.
4  */
5 
6 /*
7  * This file contains structures that are exact copies of an existing ABI used
8  * by IOT middleware. They are Intel specific and will be used by one middleware.
9  *
10  * Some of the structures may contain programming implementations that makes them
11  * unsuitable for generic use and general usage.
12  *
13  * This code is mostly copied "as-is" from existing C++ interface files hence the use of
14  * different style in places. The intention is to keep the interface as close as possible to
15  * original so it's easier to track changes with IPC host code.
16  */
17 
18 /**
19  * \file include/ipc4/notification.h
20  * \brief IPC4 notification definitions
21  */
22 
23 #ifndef __IPC4_NOTIFICATION_H__
24 #define __IPC4_NOTIFICATION_H__
25 
26 #include <stdint.h>
27 #include <ipc/header.h>
28 
29 /* ipc4 notification msg */
30 enum sof_ipc4_notification_type {
31 	SOF_IPC4_NOTIFY_PHRASE_DETECTED		= 4,
32 	SOF_IPC4_NOTIFY_RESOURCE_EVENT		= 5,
33 	SOF_IPC4_NOTIFY_LOG_BUFFER_STATUS	= 6,
34 	SOF_IPC4_NOTIFY_TIMESTAMP_CAPTURED	= 7,
35 	SOF_IPC4_NOTIFY_FW_READY		= 8,
36 	SOF_IPC4_FW_AUD_CLASS_RESULT		= 9,
37 	SOF_IPC4_EXCEPTION_CAUGHT		= 10,
38 	SOF_IPC4_MODULE_NOTIFICATION		= 12,
39 	SOF_IPC4_UAOL_RSVD_		= 13,
40 	SOF_IPC4_PROBE_DATA_AVAILABLE		= 14,
41 	SOF_IPC4_WATCHDOG_TIMEOUT		= 15,
42 	SOF_IPC4_MANAGEMENT_SERVICE		= 16,
43 };
44 
45 /**
46  * \brief Resource Event Notification provides unified structure for events that may be raised by
47  * identifiable entity from inside the FW.
48  */
49 enum sof_ipc4_resource_event_type {
50 	/* MCPS budget for the module exceeded */
51 	SOF_IPC4_BUDGET_VIOLATION		= 0,
52 	/* Underrun detected by the Mixer */
53 	SOF_IPC4_MIXER_UNDERRUN_DETECTED	= 1,
54 	/* Stream data segment completed by the gateway */
55 	SOF_IPC4_STREAM_DATA_SEGMENT		= 2,
56 	/* Error caught during data processing */
57 	SOF_IPC4_PROCESS_DATA_ERROR		= 3,
58 	/* Stack overflow in a module instance */
59 	SOF_IPC4_STACK_OVERFLOW			= 4,
60 	/* KPB changed buffering mode */
61 	SOF_IPC4_BUFFERING_MODE_CHANGED		= 5,
62 	/* Underrun detected by gateway. */
63 	SOF_IPC4_GATEWAY_UNDERRUN_DETECTED	= 6,
64 	/* Overrun detected by gateway */
65 	SOF_IPC4_GATEWAY_OVERRUN_DETECTED	= 7,
66 	/* DP task missing the deadline */
67 	SOF_IPC4_EDF_DOMAIN_UNSTABLE		= 8,
68 	/* Watchdog notification */
69 	SOF_IPC4_WATCHDOG_EVENT			= 9,
70 	/* IPC gateway reached high threshold */
71 	SOF_IPC4_GATEWAY_HIGH_THRES		= 10,
72 	/* IPC gateway reached low threshold */
73 	SOF_IPC4_GATEWAY_LOW_THRES		= 11,
74 	/* Bit Count Error detected on I2S port */
75 	SOF_IPC4_I2S_BCE_DETECTED		= 12,
76 	/* Clock detected/loss on I2S port */
77 	SOF_IPC4_I2S_CLK_STATE_CHANGED		= 13,
78 	/* I2S Sink started/stopped dropping data in non-blk mode */
79 	SOF_IPC4_I2S_SINK_MODE_CHANGED		= 14,
80 	/* I2S Source started/stopped generating 0's in non-blk mode */
81 	SOF_IPC4_I2S_SOURCE_MODE_CHANGED	= 15,
82 	/* Frequency drift exceeded limit in SRE */
83 	SOF_IPC4_SRE_DRIFT_TOO_HIGH		= 16,
84 	/* The notification should be sent only once after exceeding threshold or aging timer. */
85 	SOF_IPC4_TELEMETRY_DATA_STATUS		= 17,
86 	/* SNDW debug notification e.g. external VAD detected */
87 	SOF_IPC4_SNDW_DEBUG_INFO		= 18,
88 	/* Invalid type */
89 	SOF_IPC4_INVALID_RESORUCE_EVENT_TYPE	= 19,
90 };
91 
92 /* Resource Type - source of the event */
93 enum sof_ipc4_resource_type {
94 	/* Module instance */
95 	SOF_IPC4_MODULE_INSTANCE		= 0,
96 	/* Pipeline */
97 	SOF_IPC4_PIPELINE			= 1,
98 	/* Gateway */
99 	SOF_IPC4_GATEWAY			= 2,
100 	/* EDF Task*/
101 	SOF_IPC4_EDF_TASK			= 3,
102 	/* Invalid type */
103 	SOF_IPC4_INVALID_RESOURCE_TYPE		= 4,
104 };
105 
106 #define SOF_IPC4_GLB_NOTIFY_DIR_MASK		BIT(29)
107 #define SOF_IPC4_REPLY_STATUS_MASK		0xFFFFFF
108 #define SOF_IPC4_GLB_NOTIFY_TYPE_SHIFT		16
109 #define SOF_IPC4_GLB_NOTIFY_MSG_TYPE_SHIFT	24
110 
111 #define SOF_IPC4_FW_READY \
112 		(((SOF_IPC4_NOTIFY_FW_READY) << (SOF_IPC4_GLB_NOTIFY_TYPE_SHIFT)) |\
113 		((SOF_IPC4_GLB_NOTIFICATION) << (SOF_IPC4_GLB_NOTIFY_MSG_TYPE_SHIFT)))
114 
115 #define SOF_IPC4_NOTIF_HEADER(notif_type) \
116 		((notif_type) << (SOF_IPC4_GLB_NOTIFY_TYPE_SHIFT) | \
117 		((SOF_IPC4_GLB_NOTIFICATION) << (SOF_IPC4_GLB_NOTIFY_MSG_TYPE_SHIFT)))
118 
119 #endif
120 
121 /**
122  * \brief IPC MAJOR 4 notification header. All IPC4 notifications use this header.
123  */
124 union ipc4_notification_header {
125 	uint32_t dat;
126 
127 	struct {
128 		uint32_t rsvd0 : 16;
129 
130 		/**< Notification::MODULE_EVENT */
131 		uint32_t notif_type : 8;
132 
133 		/**< One of Global::Type */
134 		uint32_t type : 5;
135 
136 		/**< Msg::MSG_REQUEST */
137 		uint32_t rsp : 1;
138 
139 		/**< Msg::FW_GEN_MSG */
140 		uint32_t msg_tgt : 1;
141 
142 		uint32_t _reserved_0 : 1;
143 	} r;
144 } __packed __aligned(4);
145 
146 /**
147  * \brief This notification is reported by the Detector module upon key phrase detection.
148  */
149 struct ipc4_voice_cmd_notification {
150 	union {
151 		uint32_t dat;
152 
153 		struct {
154 			/**< ID of detected keyword */
155 			uint32_t word_id : 16;
156 			/**< Notification::PHRASE_DETECTED */
157 			uint32_t notif_type : 8;
158 			/**< Global::NOTIFICATION */
159 			uint32_t type : 5;
160 			/**< Msg::MSG_NOTIFICATION */
161 			uint32_t rsp : 1;
162 			/**< Msg::FW_GEN_MSG */
163 			uint32_t msg_tgt : 1;
164 			uint32_t _reserved_0 : 1;
165 		} r;
166 	} primary;
167 
168 	union {
169 		uint32_t dat;
170 
171 		struct {
172 			/**< Final speaker verification score in range of 0..8192 */
173 			uint32_t sv_score : 16;
174 			uint32_t rsvd1 : 14;
175 			uint32_t _reserved_2 : 2;
176 		} r;
177 	} extension;
178 } __packed __aligned(4);
179 
180 /**
181  * \brief This notification is reported by the Base FW when DSP core receive WDT timeout interrupt.
182  */
183 struct ipc4_watchdog_timeout_notification {
184 	union {
185 		uint32_t dat;
186 
187 		struct {
188 			/* ID of a core that timeouted. */
189 			uint32_t core_id : 4;
190 			/* Indicates that it was first timeout and crash dump was done */
191 			uint32_t first_timeout : 1;
192 			uint32_t rsvd : 11;
193 			/* Notification::WATCHDOG_TIMEOUT */
194 			uint32_t notif_type : 8;
195 			/* Global::NOTIFICATION */
196 			uint32_t type : 5;
197 			/* Msg::MSG_NOTIFICATION (0) */
198 			uint32_t rsp : 1;
199 			/* Msg::FW_GEN_MSG */
200 			uint32_t msg_tgt : 1;
201 			uint32_t _hw_rsvd_0 : 1;
202 		} r;
203 	} primary;
204 
205 	union {
206 		uint32_t dat;
207 
208 		struct {
209 			uint32_t rsvd1 : 30;
210 			uint32_t _hw_rsvd_2 : 2;
211 		} r;
212 	} extension;
213 } __packed __aligned(4);
214 
ipc4_notification_watchdog_init(struct ipc4_watchdog_timeout_notification * notif,uint32_t core_id,bool first_timeout)215 static inline void ipc4_notification_watchdog_init(struct ipc4_watchdog_timeout_notification *notif,
216 						   uint32_t core_id, bool first_timeout)
217 {
218 	notif->primary.dat = 0;
219 	notif->extension.dat = 0;
220 
221 	/* ID of a core that timeouted. */
222 	notif->primary.r.core_id = core_id;
223 
224 	/* Indicates that it was first timeout and crash dump was done */
225 	notif->primary.r.first_timeout = first_timeout;
226 
227 	notif->primary.r.notif_type = SOF_IPC4_WATCHDOG_TIMEOUT;
228 	notif->primary.r.type = SOF_IPC4_GLB_NOTIFICATION;
229 	notif->primary.r.rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST;
230 	notif->primary.r.msg_tgt = SOF_IPC4_MESSAGE_TARGET_FW_GEN_MSG;
231 }
232 
233 /**
234  * \brief Input data payload is reserved field in parent technical spec which can be easily
235  * extendable if needed by specific resource event types in the future. For backward compatibility
236  * the size of this structure is 6 dw.
237  */
238 union ipc4_resource_event_data {
239 	/* Raw data */
240 	uint32_t dws[6];
241 };
242 
243 struct ipc4_resource_event_data_notification {
244 	/* Type of originator (see sof_ipc4_resource_type) */
245 	uint32_t resource_type;
246 	/* ID of resource firing event */
247 	uint32_t resource_id;
248 	/* Type of fired event (see sof_ipc4_resource_event_type enum) */
249 	uint32_t event_type;
250 	/* Explicit alignment as ipc4_resource_event_data contains 64bit fields and needs
251 	 * alignment
252 	 */
253 	uint32_t reserved0;
254 	/* Detailed event data */
255 	union ipc4_resource_event_data event_data;
256 } __packed __aligned(8);
257