Skip to content

Commit 0a994ab

Browse files
committed
ipc: rework Zephyr IPC interface
This reworks the Zephyr IPC interface to utilize the generic IPC service and backend. So we no longer have to maintain a SoC specific IPC driver. Signed-off-by: Daniel Leung <daniel.leung@intel.com>
1 parent b3ce1f5 commit 0a994ab

File tree

4 files changed

+105
-25
lines changed

4 files changed

+105
-25
lines changed

app/prj.conf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,6 @@ CONFIG_SCHED_CPU_MASK=y
4949
CONFIG_SYS_CLOCK_TICKS_PER_SEC=15000
5050
CONFIG_DAI=y
5151
CONFIG_HEAP_MEM_POOL_SIZE=2048
52+
53+
# Use the new IPC message service in Zephyr
54+
CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE=n

src/include/sof/ipc/common.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,4 +250,12 @@ void ipc_complete_cmd(struct ipc *ipc);
250250
/* GDB stub: should enter GDB after completing the IPC processing */
251251
extern bool ipc_enter_gdb;
252252

253+
/**
254+
* \brief Send emergency IPC message.
255+
*
256+
* @param[in] data IPC data to be sent.
257+
* @param[in] ext_data Extended data to be sent.
258+
*/
259+
void ipc_send_message_emergency(uint32_t data, uint32_t ext_data);
260+
253261
#endif /* __SOF_DRIVERS_IPC_H__ */

src/ipc/ipc-zephyr.c

Lines changed: 93 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
#include <zephyr/kernel.h>
1515

16-
#include <intel_adsp_ipc.h>
1716
#include <sof/ipc/common.h>
1817

1918
#include <sof/ipc/schedule.h>
@@ -45,6 +44,11 @@
4544
#include <stddef.h>
4645
#include <stdint.h>
4746

47+
#ifdef CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE
48+
#include <intel_adsp_ipc.h>
49+
#endif
50+
#include <zephyr/ipc/backends/intel_adsp_host_ipc.h>
51+
4852
SOF_DEFINE_REG_UUID(zipc_task);
4953

5054
LOG_MODULE_DECLARE(ipc, CONFIG_SOF_LOG_LEVEL);
@@ -59,33 +63,88 @@ LOG_MODULE_DECLARE(ipc, CONFIG_SOF_LOG_LEVEL);
5963
*/
6064
static uint32_t g_last_data, g_last_ext_data;
6165

66+
struct k_sem *wait_ack_sem;
67+
6268
/**
63-
* @brief cAVS IPC Message Handler Callback function.
69+
* @brief cAVS IPC Message Received Callback function.
6470
*
65-
* See @ref (*intel_adsp_ipc_handler_t) for function signature description.
66-
* @return false so BUSY on the other side will not be cleared immediately but
71+
* @return -1 so BUSY on the other side will not be cleared immediately but
6772
* will remain set until message would have been processed by scheduled task, i.e.
6873
* until ipc_platform_complete_cmd() call.
6974
*/
70-
static bool message_handler(const struct device *dev, void *arg, uint32_t data, uint32_t ext_data)
75+
static void ipc_receive_cb(const void *data, size_t len, void *priv)
7176
{
72-
struct ipc *ipc = (struct ipc *)arg;
77+
struct intel_adsp_ipc_ept_priv_data *priv_data = priv;
78+
79+
if (len == INTEL_ADSP_IPC_CB_MSG) {
80+
const struct intel_adsp_ipc_msg *msg = data;
7381

74-
k_spinlock_key_t key;
82+
struct ipc *ipc = priv_data->priv;
7583

76-
key = k_spin_lock(&ipc->lock);
84+
k_spinlock_key_t key;
7785

78-
g_last_data = data;
79-
g_last_ext_data = ext_data;
86+
key = k_spin_lock(&ipc->lock);
87+
88+
g_last_data = msg->data;
89+
g_last_ext_data = msg->ext_data;
8090

8191
#if CONFIG_DEBUG_IPC_COUNTERS
82-
increment_ipc_received_counter();
92+
increment_ipc_received_counter();
8393
#endif
84-
ipc_schedule_process(ipc);
94+
ipc_schedule_process(ipc);
8595

86-
k_spin_unlock(&ipc->lock, key);
96+
k_spin_unlock(&ipc->lock, key);
8797

88-
return false;
98+
priv_data->cb_ret = -1;
99+
} else if (len == INTEL_ADSP_IPC_CB_DONE) {
100+
if (wait_ack_sem)
101+
k_sem_give(wait_ack_sem);
102+
103+
priv_data->cb_ret = INTEL_ADSP_IPC_CB_RET_OKAY;
104+
}
105+
}
106+
107+
static struct ipc_ept ipc_ept;
108+
static struct intel_adsp_ipc_ept_priv_data ipc_ept_priv_data;
109+
static struct ipc_ept_cfg ipc_ept_cfg = {
110+
.name = "sof_ipc",
111+
.cb = {
112+
.received = ipc_receive_cb,
113+
},
114+
.priv = &ipc_ept_priv_data,
115+
};
116+
117+
static void ipc_ept_init(struct ipc *ipc)
118+
{
119+
const struct device *ipc_dev = INTEL_ADSP_IPC_HOST_DEV;
120+
121+
ipc_ept_priv_data.priv = ipc;
122+
123+
ipc_service_register_endpoint(ipc_dev, &ipc_ept, &ipc_ept_cfg);
124+
}
125+
126+
static void ipc_complete(void)
127+
{
128+
ipc_service_send(&ipc_ept, NULL, INTEL_ADSP_IPC_SEND_DONE);
129+
}
130+
131+
static bool ipc_is_complete(void)
132+
{
133+
return ipc_service_send(&ipc_ept, NULL, INTEL_ADSP_IPC_SEND_IS_COMPLETE) == 0;
134+
}
135+
136+
static int ipc_send_message(uint32_t data, uint32_t ext_data)
137+
{
138+
struct intel_adsp_ipc_msg msg = {.data = data, .ext_data = ext_data};
139+
140+
return ipc_service_send(&ipc_ept, &msg, INTEL_ADSP_IPC_SEND_MSG);
141+
}
142+
143+
void ipc_send_message_emergency(uint32_t data, uint32_t ext_data)
144+
{
145+
struct intel_adsp_ipc_msg msg = {.data = data, .ext_data = ext_data};
146+
147+
ipc_service_send(&ipc_ept, &msg, INTEL_ADSP_IPC_SEND_MSG_EMERGENCY);
89148
}
90149

91150
#ifdef CONFIG_PM_DEVICE
@@ -159,8 +218,8 @@ static int ipc_device_resume_handler(const struct device *dev, void *arg)
159218
ipc->task_mask = 0;
160219
ipc->pm_prepare_D3 = false;
161220

162-
/* attach handlers */
163-
intel_adsp_ipc_set_message_handler(INTEL_ADSP_IPC_HOST_DEV, message_handler, ipc);
221+
/* initialize IPC endpoint */
222+
ipc_ept_init(ipc);
164223

165224
/* schedule task */
166225
#if CONFIG_TWB_IPC_TASK
@@ -254,7 +313,7 @@ enum task_state ipc_platform_do_cmd(struct ipc *ipc)
254313
void ipc_platform_complete_cmd(struct ipc *ipc)
255314
{
256315
ARG_UNUSED(ipc);
257-
intel_adsp_ipc_complete(INTEL_ADSP_IPC_HOST_DEV);
316+
ipc_complete();
258317

259318
#if CONFIG_DEBUG_IPC_COUNTERS
260319
increment_ipc_processed_counter();
@@ -263,26 +322,26 @@ void ipc_platform_complete_cmd(struct ipc *ipc)
263322

264323
int ipc_platform_send_msg(const struct ipc_msg *msg)
265324
{
266-
if (!intel_adsp_ipc_is_complete(INTEL_ADSP_IPC_HOST_DEV))
325+
if (!ipc_is_complete())
267326
return -EBUSY;
268327

269328
/* prepare the message and copy to mailbox */
270329
struct ipc_cmd_hdr *hdr = ipc_prepare_to_send(msg);
271330

272-
return intel_adsp_ipc_send_message(INTEL_ADSP_IPC_HOST_DEV, hdr->pri, hdr->ext);
331+
return ipc_send_message(hdr->pri, hdr->ext);
273332
}
274333

275334
void ipc_platform_send_msg_direct(const struct ipc_msg *msg)
276335
{
277336
/* prepare the message and copy to mailbox */
278337
struct ipc_cmd_hdr *hdr = ipc_prepare_to_send(msg);
279338

280-
intel_adsp_ipc_send_message_emergency(INTEL_ADSP_IPC_HOST_DEV, hdr->pri, hdr->ext);
339+
ipc_send_message_emergency(hdr->pri, hdr->ext);
281340
}
282341

283342
int ipc_platform_poll_is_host_ready(void)
284343
{
285-
return intel_adsp_ipc_is_complete(INTEL_ADSP_IPC_HOST_DEV);
344+
return ipc_is_complete();
286345
}
287346

288347
int platform_ipc_init(struct ipc *ipc)
@@ -300,8 +359,9 @@ int platform_ipc_init(struct ipc *ipc)
300359
#endif
301360
/* configure interrupt - work is done internally by Zephyr API */
302361

303-
/* attach handlers */
304-
intel_adsp_ipc_set_message_handler(INTEL_ADSP_IPC_HOST_DEV, message_handler, ipc);
362+
/* initialize IPC endpoint */
363+
ipc_ept_init(ipc);
364+
305365
#ifdef CONFIG_PM
306366
intel_adsp_ipc_set_suspend_handler(INTEL_ADSP_IPC_HOST_DEV,
307367
ipc_device_suspend_handler, ipc);
@@ -312,22 +372,32 @@ int platform_ipc_init(struct ipc *ipc)
312372
return 0;
313373
}
314374

375+
#ifdef CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE
315376
static bool ipc_wait_complete(const struct device *dev, void *arg)
316377
{
317378
k_sem_give(arg);
318379
return false;
319380
}
381+
#endif
320382

321383
void ipc_platform_wait_ack(struct ipc *ipc)
322384
{
323385
static struct k_sem ipc_wait_sem;
324386

325387
k_sem_init(&ipc_wait_sem, 0, 1);
326388

389+
#ifdef CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE
327390
intel_adsp_ipc_set_done_handler(INTEL_ADSP_IPC_HOST_DEV, ipc_wait_complete, &ipc_wait_sem);
391+
#else
392+
wait_ack_sem = &ipc_wait_sem;
393+
#endif
328394

329395
if (k_sem_take(&ipc_wait_sem, Z_TIMEOUT_MS(10)) == -EAGAIN)
330396
tr_err(&ipc_tr, "Timeout waiting for host ack!");
331397

398+
#ifdef CONFIG_INTEL_ADSP_IPC_OLD_INTERFACE
332399
intel_adsp_ipc_set_done_handler(INTEL_ADSP_IPC_HOST_DEV, NULL, NULL);
400+
#else
401+
wait_ack_sem = NULL;
402+
#endif
333403
}

src/platform/intel/ace/lib/watchdog.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ static void watchdog_primary_core_action_on_timeout(void)
3434

3535
/* Send Watchdog Timeout IPC notification */
3636
ipc4_notification_watchdog_init(&notif, cpu_get_id(), true);
37-
intel_adsp_ipc_send_message_emergency(INTEL_ADSP_IPC_HOST_DEV,
38-
notif.primary.dat, notif.extension.dat);
37+
(void)ipc_send_message_emergency(notif.primary.dat, notif.extension.dat);
3938
}
4039

4140
static void watchdog_secondary_core_action_on_timeout(void)

0 commit comments

Comments
 (0)