Skip to content

Commit f3f8816

Browse files
committed
Add unbound DTS option and adjust pbuf for session handshake
1 parent 6ac5c2b commit f3f8816

File tree

8 files changed

+85
-25
lines changed

8 files changed

+85
-25
lines changed

dts/bindings/ipc/zephyr,ipc-icmsg.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,21 @@ properties:
2121
required: true
2222
type: phandle
2323

24+
unbound:
25+
type: string
26+
enum:
27+
- disable
28+
- enable
29+
- compatibility
30+
default: disable
31+
description: |
32+
Select unbound() callback mode. The callback can be enabled or disabled with the
33+
"enable" and "disable" option respectively. This functionality requires session
34+
number handshake procedure on both sides, so you cannot set "enable" on one side
35+
and "disable" on the other. The "compatibility" mode detects if the remote side
36+
supports handshake procedure and adjusts its behavior accordingly. The
37+
"compatibility" mode is possible only if "dcache-alignment" is at least 8 bytes.
38+
2439
dcache-alignment:
2540
type: int
2641
description: |

include/zephyr/ipc/icmsg.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ enum icmsg_state {
3232
ICMSG_STATE_READY,
3333
};
3434

35+
enum icmsg_unbound_mode {
36+
ICMSG_UNBOUND_MODE_DISABLE,
37+
ICMSG_UNBOUND_MODE_ENABLE,
38+
ICMSG_UNBOUND_MODE_COMPATIBILITY,
39+
};
40+
3541
struct icmsg_config_t {
3642
struct mbox_dt_spec mbox_tx;
3743
struct mbox_dt_spec mbox_rx;

include/zephyr/ipc/pbuf.h

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,23 @@ extern "C" {
4747
* The structure contains configuration data.
4848
*/
4949
struct pbuf_cfg {
50-
volatile uint32_t *rd_idx_loc; /* Address of the variable holding
51-
* index value of the first valid byte
52-
* in data[].
53-
*/
54-
volatile uint32_t *wr_idx_loc; /* Address of the variable holding
55-
* index value of the first free byte
56-
* in data[].
57-
*/
58-
uint32_t dcache_alignment; /* CPU data cache line size in bytes.
59-
* Used for validation - TODO: To be
60-
* replaced by flags.
61-
*/
62-
uint32_t len; /* Length of data[] in bytes. */
63-
uint8_t *data_loc; /* Location of the data[]. */
50+
volatile uint32_t *rd_idx_loc; /* Address of the variable holding
51+
* index value of the first valid byte
52+
* in data[].
53+
*/
54+
volatile uint32_t *handshake_loc;/* Address of the variable holding
55+
* handshake information.
56+
*/
57+
volatile uint32_t *wr_idx_loc; /* Address of the variable holding
58+
* index value of the first free byte
59+
* in data[].
60+
*/
61+
uint32_t dcache_alignment; /* CPU data cache line size in bytes.
62+
* Used for validation - TODO: To be
63+
* replaced by flags.
64+
*/
65+
uint32_t len; /* Length of data[] in bytes. */
66+
uint8_t *data_loc; /* Location of the data[]. */
6467
};
6568

6669
/**
@@ -112,14 +115,16 @@ struct pbuf {
112115
* @param size Size of the memory.
113116
* @param dcache_align Data cache alignment.
114117
*/
115-
#define PBUF_CFG_INIT(mem_addr, size, dcache_align) \
118+
#define PBUF_CFG_INIT(mem_addr, size, dcache_align, use_handshake) \
116119
{ \
117120
.rd_idx_loc = (uint32_t *)(mem_addr), \
118-
.wr_idx_loc = (uint32_t *)((uint8_t *)(mem_addr) + \
119-
MAX(dcache_align, _PBUF_IDX_SIZE)), \
121+
.handshake_loc = use_handshake ? (uint32_t *)((uint8_t *)(mem_addr) + \
122+
_PBUF_IDX_SIZE) : NULL, \
123+
.wr_idx_loc = (uint32_t *)((uint8_t *)(mem_addr) + MAX(dcache_align, \
124+
(use_handshake ? 2 : 1) * _PBUF_IDX_SIZE)), \
120125
.data_loc = (uint8_t *)((uint8_t *)(mem_addr) + \
121-
MAX(dcache_align, _PBUF_IDX_SIZE) + _PBUF_IDX_SIZE), \
122-
.len = (uint32_t)((uint32_t)(size) - MAX(dcache_align, _PBUF_IDX_SIZE) - \
126+
MAX(dcache_align, (use_handshake ? 2 : 1) * _PBUF_IDX_SIZE) + _PBUF_IDX_SIZE), \
127+
.len = (uint32_t)((uint32_t)(size) - MAX(dcache_align, (use_handshake ? 2 : 1) * _PBUF_IDX_SIZE) - \
123128
_PBUF_IDX_SIZE), \
124129
.dcache_alignment = (dcache_align), \
125130
}
@@ -142,7 +147,7 @@ struct pbuf {
142147
* @param size Size of the memory.
143148
* @param dcache_align Data cache line size.
144149
*/
145-
#define PBUF_DEFINE(name, mem_addr, size, dcache_align) \
150+
#define PBUF_DEFINE(name, mem_addr, size, dcache_align, use_handshake, compatibility) \
146151
BUILD_ASSERT(dcache_align >= 0, \
147152
"Cache line size must be non negative."); \
148153
BUILD_ASSERT((size) > 0 && IS_PTR_ALIGNED_BYTES(size, _PBUF_IDX_SIZE), \
@@ -151,8 +156,10 @@ struct pbuf {
151156
"Misaligned memory."); \
152157
BUILD_ASSERT(size >= (MAX(dcache_align, _PBUF_IDX_SIZE) + _PBUF_IDX_SIZE + \
153158
_PBUF_MIN_DATA_LEN), "Insufficient size."); \
159+
BUILD_ASSERT(!(compatibility) || (dcache_align) >= 8, \
160+
"Data cache alignment must be at least 8 if compatibility is enabled.");\
154161
static PBUF_MAYBE_CONST struct pbuf_cfg cfg_##name = \
155-
PBUF_CFG_INIT(mem_addr, size, dcache_align); \
162+
PBUF_CFG_INIT(mem_addr, size, dcache_align, use_handshake); \
156163
static struct pbuf name = { \
157164
.cfg = &cfg_##name, \
158165
}
@@ -223,6 +230,9 @@ int pbuf_write(struct pbuf *pb, const char *buf, uint16_t len);
223230
*/
224231
int pbuf_read(struct pbuf *pb, char *buf, uint16_t len);
225232

233+
uint32_t pbuf_handshake_read(struct pbuf *pb);
234+
void pbuf_handshake_write(struct pbuf *pb, uint32_t value);
235+
226236
/**
227237
* @}
228238
*/

samples/subsys/ipc/ipc_service/icmsg/boards/nrf5340dk_nrf5340_cpuapp.overlay

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
ipc0: ipc0 {
2828
compatible = "zephyr,ipc-icmsg";
29+
unbound = "enable";
2930
tx-region = <&sram_tx>;
3031
rx-region = <&sram_rx>;
3132
mboxes = <&mbox 0>, <&mbox 1>;

samples/subsys/ipc/ipc_service/icmsg/remote/boards/nrf5340dk_nrf5340_cpunet.overlay

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
ipc0: ipc0 {
2828
compatible = "zephyr,ipc-icmsg";
29+
unbound = "enable";
2930
tx-region = <&sram_tx>;
3031
rx-region = <&sram_rx>;
3132
mboxes = <&mbox 0>, <&mbox 1>;

subsys/ipc/ipc_service/backends/ipc_icmsg.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ static int backend_init(const struct device *instance)
5454
return 0;
5555
}
5656

57+
#define UNBOUND_MODE(i) CONCAT(ICMSG_UNBOUND_MODE_, DT_INST_STRING_UPPER_TOKEN(i, unbound))
58+
5759
#define DEFINE_BACKEND_DEVICE(i) \
5860
static const struct icmsg_config_t backend_config_##i = { \
5961
.mbox_tx = MBOX_DT_SPEC_INST_GET(i, tx), \
@@ -63,11 +65,15 @@ static int backend_init(const struct device *instance)
6365
PBUF_DEFINE(tx_pb_##i, \
6466
DT_REG_ADDR(DT_INST_PHANDLE(i, tx_region)), \
6567
DT_REG_SIZE(DT_INST_PHANDLE(i, tx_region)), \
66-
DT_INST_PROP_OR(i, dcache_alignment, 0)); \
68+
DT_INST_PROP_OR(i, dcache_alignment, 0), \
69+
UNBOUND_MODE(i) != ICMSG_UNBOUND_MODE_DISABLE, \
70+
UNBOUND_MODE(i) == ICMSG_UNBOUND_MODE_COMPATIBILITY); \
6771
PBUF_DEFINE(rx_pb_##i, \
6872
DT_REG_ADDR(DT_INST_PHANDLE(i, rx_region)), \
6973
DT_REG_SIZE(DT_INST_PHANDLE(i, rx_region)), \
70-
DT_INST_PROP_OR(i, dcache_alignment, 0)); \
74+
DT_INST_PROP_OR(i, dcache_alignment, 0), \
75+
UNBOUND_MODE(i) != ICMSG_UNBOUND_MODE_DISABLE, \
76+
UNBOUND_MODE(i) == ICMSG_UNBOUND_MODE_COMPATIBILITY); \
7177
\
7278
static struct icmsg_data_t backend_data_##i = { \
7379
.tx_pb = &tx_pb_##i, \

subsys/ipc/ipc_service/lib/icmsg.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
#define BOND_NOTIFY_REPEAT_TO K_MSEC(CONFIG_IPC_SERVICE_ICMSG_BOND_NOTIFY_REPEAT_TO_MS)
1616
#define SHMEM_ACCESS_TO K_MSEC(CONFIG_IPC_SERVICE_ICMSG_SHMEM_ACCESS_TO_MS)
1717

18-
static const uint8_t magic[] = {0x45, 0x6d, 0x31, 0x6c, 0x31, 0x4b,
19-
0x30, 0x72, 0x6e, 0x33, 0x6c, 0x69, 0x34};
18+
static const uint8_t magic[] = {0x45, 0x6d, 0x31, 0x6c, 0x31, 0x4b, 0x30,
19+
0x72, 0x6e, 0x33, 0x6c, 0x69, 0x34, 0x01 };
20+
21+
#define OLD_MAGIC_LENGTH (sizeof(magic) - 1)
2022

2123
#ifdef CONFIG_MULTITHREADING
2224
#if defined(CONFIG_IPC_SERVICE_BACKEND_ICMSG_WQ_ENABLE)

subsys/ipc/ipc_service/lib/pbuf.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ static int validate_cfg(const struct pbuf_cfg *cfg)
3838
/* Validate pointer alignment. */
3939
if (!IS_PTR_ALIGNED_BYTES(cfg->rd_idx_loc, MAX(cfg->dcache_alignment, _PBUF_IDX_SIZE)) ||
4040
!IS_PTR_ALIGNED_BYTES(cfg->wr_idx_loc, MAX(cfg->dcache_alignment, _PBUF_IDX_SIZE)) ||
41+
!IS_PTR_ALIGNED_BYTES(cfg->handshake_loc, _PBUF_IDX_SIZE) ||
4142
!IS_PTR_ALIGNED_BYTES(cfg->data_loc, _PBUF_IDX_SIZE)) {
4243
return -EINVAL;
4344
}
@@ -49,6 +50,8 @@ static int validate_cfg(const struct pbuf_cfg *cfg)
4950

5051
/* Validate pointer values. */
5152
if (!(cfg->rd_idx_loc < cfg->wr_idx_loc) ||
53+
(cfg->handshake_loc && !(cfg->rd_idx_loc < cfg->handshake_loc)) ||
54+
!(cfg->handshake_loc < cfg->wr_idx_loc) ||
5255
!((uint8_t *)cfg->wr_idx_loc < cfg->data_loc) ||
5356
!(((uint8_t *)cfg->rd_idx_loc + MAX(_PBUF_IDX_SIZE, cfg->dcache_alignment)) ==
5457
(uint8_t *)cfg->wr_idx_loc)) {
@@ -253,3 +256,19 @@ int pbuf_read(struct pbuf *pb, char *buf, uint16_t len)
253256

254257
return len;
255258
}
259+
260+
uint32_t pbuf_handshake_read(struct pbuf *pb)
261+
{
262+
volatile uint32_t *ptr = pb->cfg->handshake_loc;
263+
sys_cache_data_invd_range((void *)ptr, sizeof(*ptr));
264+
__sync_synchronize();
265+
return *ptr;
266+
}
267+
268+
void pbuf_handshake_write(struct pbuf *pb, uint32_t value)
269+
{
270+
volatile uint32_t *ptr = pb->cfg->handshake_loc;
271+
*ptr = value;
272+
__sync_synchronize();
273+
sys_cache_data_flush_range((void *)ptr, sizeof(*ptr));
274+
}

0 commit comments

Comments
 (0)