From 6f986772aceedfcfced7a2f1549f5692070c522c Mon Sep 17 00:00:00 2001 From: Jerzy Kasenberg Date: Tue, 23 May 2023 09:23:34 +0200 Subject: [PATCH] hw/ipc_nrf5340: Support for flexible memory sharing This adds easy way to add application specific shared memory regions that will be defined on application core and can be easily found on network core. This is done so linker scripts for network and application core does not have to be carefully synchronized. Signed-off-by: Jerzy Kasenberg --- .../include/ipc_nrf5340/ipc_nrf5340.h | 68 +++++++++++++++++++ hw/drivers/ipc_nrf5340/pkg.yml | 3 + hw/drivers/ipc_nrf5340/src/ipc_nrf5340.c | 19 ++++++ 3 files changed, 90 insertions(+) diff --git a/hw/drivers/ipc_nrf5340/include/ipc_nrf5340/ipc_nrf5340.h b/hw/drivers/ipc_nrf5340/include/ipc_nrf5340/ipc_nrf5340.h index c68b3e7c04..214633fe57 100644 --- a/hw/drivers/ipc_nrf5340/include/ipc_nrf5340/ipc_nrf5340.h +++ b/hw/drivers/ipc_nrf5340/include/ipc_nrf5340/ipc_nrf5340.h @@ -213,6 +213,74 @@ const void *ipc_nrf5340_net_image_get(uint32_t *size); volatile struct hci_ipc_shm *ipc_nrf5340_hci_shm_get(void); #endif +struct shm_memory_region { + uint32_t region_id; + void *region_start; + uint32_t region_size; +}; + +#if MYNEWT_VAL(MCU_APP_CORE) + +#define __REGION_ID(id) shm_region_ ## id +/** + * Macro for shared memory region declaration + * + * It should be used on application core to specify memory region that should be accessible + * on the network core. + * example declaration form application core: + * \code + * struct application_shared_data { + * int anything; + * uint8_t buffer[1234] + * } shared_data; + * + * #define MY_REGION_ID 112233 + * SHM_REGION(MY_REGION_ID, &shared_data, sizeof(shared_data)); + * \endcode + * + * @param id number that will be used on netcore to locate this region by + * @param address start of shared memory region + * @param size size of shared memory region + */ +#define SHM_REGION(id, address, size) \ + static struct shm_memory_region __attribute__((section(".shm_descriptor"), used)) __REGION_ID(id) = { \ + .region_id = id, \ + .region_start = address, \ + .region_size = size, \ + } + +#else +/** + * Find shared memory region by it's ID. + * + * Region should be declared on application core with SHM_REGION macro. + * example declaration form application core: + * \code + * struct application_shared_data { + * int anything; + * uint8_t buffer[1234] + * } shared_data; + * + * SHM_REGION(112233, &shared_data, sizeof(shared_data)); + * \endcode + * access on netcode: + * \code + * ... + * const struct shm_memory_region *shared_region; + * region = ipc_nrf5340_find_region(122233); + * if (region) { + * struct application_shared_data *shared_data = region->region_start; + * shared_data->anything = 1; + * ... + * } + * \endcode + * @param region_id Region ID to find. + * + * @return Pointer to region, NULL if not present + */ +const struct shm_memory_region *ipc_nrf5340_find_region(uint32_t region_id); +#endif + #ifdef __cplusplus } #endif diff --git a/hw/drivers/ipc_nrf5340/pkg.yml b/hw/drivers/ipc_nrf5340/pkg.yml index 4ad4b9c139..ae875fa24b 100644 --- a/hw/drivers/ipc_nrf5340/pkg.yml +++ b/hw/drivers/ipc_nrf5340/pkg.yml @@ -32,3 +32,6 @@ pkg.deps: pkg.init: ipc_nrf5340_init: 'MYNEWT_VAL(IPC_NRF5340_SYSINIT_STAGE)' ipc_nrf5340_netcore_init: 'MYNEWT_VAL(IPC_NRF5340_NETCORE_SYSINIT_STAGE)' + +pkg.link_tables: + - shm_descriptor diff --git a/hw/drivers/ipc_nrf5340/src/ipc_nrf5340.c b/hw/drivers/ipc_nrf5340/src/ipc_nrf5340.c index 6d586799d2..8fb161fe16 100644 --- a/hw/drivers/ipc_nrf5340/src/ipc_nrf5340.c +++ b/hw/drivers/ipc_nrf5340/src/ipc_nrf5340.c @@ -54,6 +54,8 @@ struct ipc_shared { APP_AND_NET_RUNNING, NET_RESTARTED, } ipc_state; + struct shm_memory_region *region_descriptor_start; + struct shm_memory_region *region_descriptor_end; #if MYNEWT_PKG_apache_mynewt_nimble__nimble_transport_common_hci_ipc volatile struct hci_ipc_shm hci_shm; #endif @@ -96,6 +98,9 @@ static struct ipc_channel ipcs[IPC_MAX_CHANS]; __attribute__((section(".ipc"))) static struct ipc_shared ipc_shared[1]; #if MYNEWT_VAL(MCU_APP_CORE) +extern struct shm_memory_region __shm_descriptor_start__[]; +extern struct shm_memory_region __shm_descriptor_end__[]; + static struct ipc_shm shms[IPC_MAX_CHANS]; static uint8_t shms_bufs[IPC_MAX_CHANS][IPC_BUF_SIZE]; @@ -289,6 +294,8 @@ ipc_nrf5340_init(void) } } #endif + ipc_shared[0].region_descriptor_start = __shm_descriptor_start__; + ipc_shared[0].region_descriptor_end = __shm_descriptor_end__; for (i = 0; i < IPC_MAX_CHANS; ++i) { shms[i].buf = shms_bufs[i]; @@ -381,6 +388,18 @@ ipc_nrf5340_netcore_init(void) ipc_shared->ipc_state = APP_AND_NET_RUNNING; } } + +const struct shm_memory_region * +ipc_nrf5340_find_region(uint32_t region_id) +{ + const struct shm_memory_region *region; + for (region = ipc_shared->region_descriptor_start; region != ipc_shared->region_descriptor_end; ++region) { + if (region->region_id == region_id) { + return region; + } + } + return NULL; +} #endif #if MYNEWT_VAL(MCU_APP_CORE)