Skip to content

Commit e764edc

Browse files
committed
ipc: move IPC payload handling to IPC driver
Move responsibility to write and read the IPC message payload to the Zephyr IPC driver. This change allows to use SOF IPC client code with multiple hardware backends and there's no assumption payload transport is a memory mapped payload buffer is exposed via mailbox.h. This depends on Zephyr commit TBD ("foo bar") that adds message payload to the interface. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
1 parent 4550361 commit e764edc

File tree

1 file changed

+34
-32
lines changed

1 file changed

+34
-32
lines changed

src/ipc/ipc-zephyr.c

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
#include <sof/ipc/common.h>
1717

1818
#include <sof/ipc/schedule.h>
19-
#include <sof/lib/mailbox.h>
20-
#include <sof/lib/memory.h>
19+
#include <sof/lib/mailbox.h> /* for sw_regs with CONFIG_DEBUG_IPC_COUNTERS */
20+
#include <sof/lib/memory.h> /* for sw_regs with CONFIG_DEBUG_IPC_COUNTERS */
2121
#if defined(CONFIG_PM)
2222
#include <sof/lib/cpu.h>
2323
#include <zephyr/pm/device.h>
@@ -61,7 +61,9 @@ LOG_MODULE_DECLARE(ipc, CONFIG_SOF_LOG_LEVEL);
6161
* Filled with content of TDR and TDD registers.
6262
* When IPC message is read fills ipc_cmd_hdr.
6363
*/
64-
static uint32_t g_last_data, g_last_ext_data;
64+
static uint32_t g_last_data, g_last_ext_data, g_last_payload_length;
65+
66+
static uint32_t *g_last_payload;
6567

6668
struct k_sem *wait_ack_sem;
6769

@@ -87,6 +89,8 @@ static void ipc_receive_cb(const void *data, size_t cb_type, void *priv)
8789

8890
g_last_data = msg->data;
8991
g_last_ext_data = msg->ext_data;
92+
g_last_payload = msg->payload;
93+
g_last_payload_length = msg->payload_length;
9094

9195
#if CONFIG_DEBUG_IPC_COUNTERS
9296
increment_ipc_received_counter();
@@ -133,11 +137,9 @@ static bool ipc_is_complete(void)
133137
return ipc_service_send(&ipc_ept, NULL, INTEL_ADSP_IPC_SEND_IS_COMPLETE) == 0;
134138
}
135139

136-
static int ipc_send_message(uint32_t data, uint32_t ext_data)
140+
static int ipc_send_message(struct intel_adsp_ipc_msg *msg)
137141
{
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);
142+
return ipc_service_send(&ipc_ept, msg, INTEL_ADSP_IPC_SEND_MSG);
141143
}
142144

143145
void ipc_send_message_emergency(uint32_t data, uint32_t ext_data)
@@ -147,6 +149,11 @@ void ipc_send_message_emergency(uint32_t data, uint32_t ext_data)
147149
ipc_service_send(&ipc_ept, &msg, INTEL_ADSP_IPC_SEND_MSG_EMERGENCY);
148150
}
149151

152+
static void ipc_send_message_emergency_with_payload(struct intel_adsp_ipc_msg *msg)
153+
{
154+
ipc_service_send(&ipc_ept, msg, INTEL_ADSP_IPC_SEND_MSG_EMERGENCY);
155+
}
156+
150157
#ifdef CONFIG_PM_DEVICE
151158
/**
152159
* @brief IPC device suspend handler callback function.
@@ -325,43 +332,38 @@ int ipc_platform_send_msg(const struct ipc_msg *msg)
325332
if (!ipc_is_complete())
326333
return -EBUSY;
327334

328-
/* prepare the message and copy to mailbox */
329335
struct ipc_cmd_hdr *hdr = ipc_prepare_to_send(msg);
330-
331-
if (msg->tx_size)
332-
mailbox_dspbox_write(0, (uint32_t *)msg->tx_data, msg->tx_size);
333-
334-
return ipc_send_message(hdr->pri, hdr->ext);
336+
struct intel_adsp_ipc_msg ipc_drv_msg = {
337+
.data = hdr->pri,
338+
.ext_data = hdr->ext,
339+
.payload = (uintptr_t)msg->tx_data,
340+
.payload_length = msg->tx_size
341+
};
342+
343+
return ipc_send_message(&ipc_drv_msg);
335344
}
336345

337346
void ipc_platform_send_msg_direct(const struct ipc_msg *msg)
338347
{
339348
/* prepare the message and copy to mailbox */
340349
struct ipc_cmd_hdr *hdr = ipc_prepare_to_send(msg);
341-
342-
if (msg->tx_size)
343-
mailbox_dspbox_write(0, (uint32_t *)msg->tx_data, msg->tx_size);
344-
345-
ipc_send_message_emergency(hdr->pri, hdr->ext);
350+
struct intel_adsp_ipc_msg ipc_drv_msg = {
351+
.data = hdr->pri,
352+
.ext_data = hdr->ext,
353+
.payload = (uintptr_t)msg->tx_data,
354+
.payload_length = msg->tx_size
355+
};
356+
357+
ipc_send_message_emergency_with_payload(&ipc_drv_msg);
346358
}
347359

348-
uint32_t *ipc_access_msg_payload(size_t bytes)
360+
uint32_t *ipc_access_msg_payload(size_t __unused bytes)
349361
{
350362
/*
351-
* TODO: intermediate step to put MAILBOX access here,
352-
* this should be moved to Zephyr IPC driver
363+
* The IPC driver has flushed the
364+
* cache on payload buffer, so no action needed here.
353365
*/
354-
uint32_t *hostbox = (uint32_t*)MAILBOX_HOSTBOX_BASE;
355-
356-
/*
357-
* TODO: can we invalidate whole hostbox upon IPC reception
358-
* and skip these calls doen when incrementally
359-
* parsing the message until full length of payload
360-
* is known
361-
*/
362-
dcache_invalidate_region((__sparse_force void __sparse_cache *)hostbox, bytes);
363-
364-
return hostbox;
366+
return g_last_payload;
365367
}
366368

367369
int ipc_platform_poll_is_host_ready(void)

0 commit comments

Comments
 (0)