From 531cd570acb21a8438360cb7e61312a68af2c327 Mon Sep 17 00:00:00 2001 From: Arnaud Pouliquen Date: Fri, 20 Sep 2019 11:41:38 +0200 Subject: [PATCH 1/4] lib: open-amp: add helper to add resource table in project The resource table is needed by the Linux kernel OS for a rpmsg generic support, but is also recognised by OpenAMP. This table allows to add trace based on the RAM console and to support rpmsg protocol. Signed-off-by: Arnaud Pouliquen --- CODEOWNERS | 1 + lib/CMakeLists.txt | 1 + lib/Kconfig | 2 + lib/open-amp/CMakeLists.txt | 8 ++++ lib/open-amp/Kconfig | 20 +++++++++ lib/open-amp/resource_table.c | 82 +++++++++++++++++++++++++++++++++++ lib/open-amp/resource_table.h | 72 ++++++++++++++++++++++++++++++ 7 files changed, 186 insertions(+) create mode 100644 lib/open-amp/CMakeLists.txt create mode 100644 lib/open-amp/Kconfig create mode 100644 lib/open-amp/resource_table.c create mode 100644 lib/open-amp/resource_table.h diff --git a/CODEOWNERS b/CODEOWNERS index 92db3a68b588c..a7bd3a93f5c76 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -350,6 +350,7 @@ /kernel/ @andrewboie @andyross /lib/fnmatch/ @carlescufi /lib/gui/ @vanwinkeljan +/lib/open-amp/ @arnopo /lib/os/ @andrewboie @andyross /lib/posix/ @pfalcon /lib/cmsis_rtos_v2/ @nashif diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index e28df122ee091..9626d1bfc3870 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -10,3 +10,4 @@ add_subdirectory_ifdef(CONFIG_FNMATCH fnmatch) add_subdirectory(gui) add_subdirectory(os) add_subdirectory_ifdef(CONFIG_UPDATEHUB updatehub) +add_subdirectory_ifdef(CONFIG_OPENAMP open-amp) diff --git a/lib/Kconfig b/lib/Kconfig index 189229277065d..5b8e8d95136f0 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -19,4 +19,6 @@ source "lib/posix/Kconfig" source "lib/updatehub/Kconfig" +source "lib/open-amp/Kconfig" + endmenu diff --git a/lib/open-amp/CMakeLists.txt b/lib/open-amp/CMakeLists.txt new file mode 100644 index 0000000000000..5d7fb289a76f4 --- /dev/null +++ b/lib/open-amp/CMakeLists.txt @@ -0,0 +1,8 @@ +# +# Copyright (c) 2020, STMicroelectronics +# +# SPDX-License-Identifier: Apache-2.0 +# + +zephyr_include_directories_ifdef(CONFIG_OPENAMP_RSC_TABLE .) +zephyr_sources_ifdef(CONFIG_OPENAMP_RSC_TABLE resource_table.c) diff --git a/lib/open-amp/Kconfig b/lib/open-amp/Kconfig new file mode 100644 index 0000000000000..c37ee967fce3b --- /dev/null +++ b/lib/open-amp/Kconfig @@ -0,0 +1,20 @@ +# +# Copyright (c) 2020, STMicroelectronics +# +# SPDX-License-Identifier: Apache-2.0 +# + +config OPENAMP_RSC_TABLE + bool "coprocessor resource table" + imply OPENAMP + help + add the resource table in the generated binary. This table is + compatible with linux remote proc framework and OpenAMP library. + +config OPENAMP_RSC_TABLE_NUM_RPMSG_BUFF + int "Resource table number of rpmsg buffers" + default 0 + depends on OPENAMP_RSC_TABLE + help + This option specifies the number of buffer used in a Vring for + interprocessor communication diff --git a/lib/open-amp/resource_table.c b/lib/open-amp/resource_table.c new file mode 100644 index 0000000000000..9c976cf5bc877 --- /dev/null +++ b/lib/open-amp/resource_table.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2020 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * In addition to the standard ELF segments, most remote processors would + * also include a special section which we call "the resource table". + * + * The resource table contains system resources that the remote processor + * requires before it should be powered on, such as allocation of physically + * contiguous memory, or iommu mapping of certain on-chip peripherals. + + * In addition to system resources, the resource table may also contain + * resource entries that publish the existence of supported features + * or configurations by the remote processor, such as trace buffers and + * supported virtio devices (and their configurations). + + * Dependencies: + * to be compliant with Linux kernel OS the resource table must be linked in a + * specific section named ".resource_table". + + * Related documentation: + * https://www.kernel.org/doc/Documentation/remoteproc.txt + * https://github.com/OpenAMP/open-amp/wiki/OpenAMP-Life-Cycle-Management + */ + +#include +#include + +extern char ram_console[]; + +#define __resource Z_GENERIC_SECTION(.resource_table) + +#if (CONFIG_OPENAMP_RSC_TABLE_NUM_RPMSG_BUFF > 0) || defined(CONFIG_RAM_CONSOLE) + +static struct fw_resource_table __resource resource_table = { + .ver = 1, + .num = RSC_TABLE_NUM_ENTRY, + .offset = { + +#if (CONFIG_OPENAMP_RSC_TABLE_NUM_RPMSG_BUFF > 0) + offsetof(struct fw_resource_table, vdev), +#endif + +#if defined(CONFIG_RAM_CONSOLE) + offsetof(struct fw_resource_table, cm_trace), +#endif + }, + +#if (CONFIG_OPENAMP_RSC_TABLE_NUM_RPMSG_BUFF > 0) + /* Virtio device entry */ + .vdev = { + RSC_VDEV, VIRTIO_ID_RPMSG, 0, RPMSG_IPU_C0_FEATURES, 0, 0, 0, + VRING_COUNT, {0, 0}, + }, + + /* Vring rsc entry - part of vdev rsc entry */ + .vring0 = {VRING_TX_ADDRESS, VRING_ALIGNMENT, + CONFIG_OPENAMP_RSC_TABLE_NUM_RPMSG_BUFF, + VRING0_ID, 0}, + .vring1 = {VRING_RX_ADDRESS, VRING_ALIGNMENT, + CONFIG_OPENAMP_RSC_TABLE_NUM_RPMSG_BUFF, + VRING1_ID, 0}, +#endif + +#if defined(CONFIG_RAM_CONSOLE) + .cm_trace = { + RSC_TRACE, + (uint32_t)ram_console, CONFIG_RAM_CONSOLE_BUFFER_SIZE + 1, 0, + "Zephyr_log", + }, +#endif +}; + +void rsc_table_get(void **table_ptr, int *length) +{ + *table_ptr = (void *)&resource_table; + *length = sizeof(resource_table); +} +#endif diff --git a/lib/open-amp/resource_table.h b/lib/open-amp/resource_table.h new file mode 100644 index 0000000000000..76e57cf4b2023 --- /dev/null +++ b/lib/open-amp/resource_table.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2020 STMicroelectronics + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef RESOURCE_TABLE_H__ +#define RESOURCE_TABLE_H__ + +#include +#include + +#if (CONFIG_OPENAMP_RSC_TABLE_NUM_RPMSG_BUFF > 0) + +#define VDEV_ID 0xFF +#define VRING0_ID 0 /* (master to remote) fixed to 0 for Linux compatibility */ +#define VRING1_ID 1 /* (remote to master) fixed to 1 for Linux compatibility */ + +#define VRING_COUNT 2 +#define RPMSG_IPU_C0_FEATURES 1 + +#define VRING_RX_ADDRESS -1 /* allocated by Master processor */ +#define VRING_TX_ADDRESS -1 /* allocated by Master processor */ +#define VRING_BUFF_ADDRESS -1 /* allocated by Master processor */ +#define VRING_ALIGNMENT 16 /* fixed to match with Linux constraint */ + +#endif + +enum rsc_table_entries { +#if (CONFIG_OPENAMP_RSC_TABLE_NUM_RPMSG_BUFF > 0) + RSC_TABLE_VDEV_ENTRY, +#endif +#if defined(CONFIG_RAM_CONSOLE) + RSC_TABLE_TRACE_ENTRY, +#endif + RSC_TABLE_NUM_ENTRY +}; + +struct fw_resource_table { + unsigned int ver; + unsigned int num; + unsigned int reserved[2]; + unsigned int offset[RSC_TABLE_NUM_ENTRY]; + + struct fw_rsc_vdev vdev; + struct fw_rsc_vdev_vring vring0; + struct fw_rsc_vdev_vring vring1; + +#if defined(CONFIG_RAM_CONSOLE) + /* rpmsg trace entry */ + struct fw_rsc_trace cm_trace; +#endif +} METAL_PACKED_END; + +void rsc_table_get(void **table_ptr, int *length); + +inline struct fw_rsc_vdev *rsc_table_to_vdev(void *rsc_table) +{ + return &((struct fw_resource_table *)rsc_table)->vdev; +} + +inline struct fw_rsc_vdev_vring *rsc_table_get_vring0(void *rsc_table) +{ + return &((struct fw_resource_table *)rsc_table)->vring0; +} + +inline struct fw_rsc_vdev_vring *rsc_table_get_vring1(void *rsc_table) +{ + return &((struct fw_resource_table *)rsc_table)->vring1; +} + +#endif From cb41aa7e560e090e0e0808a35422580ec9c0feff Mon Sep 17 00:00:00 2001 From: Arnaud Pouliquen Date: Fri, 29 Mar 2019 17:11:13 +0100 Subject: [PATCH 2/4] stm32mp1: update resource table management Rebase the resource table management to the new implementation in open-amp module Signed-off-by: Arnaud Pouliquen --- soc/arm/st_stm32/stm32mp1/CMakeLists.txt | 1 - soc/arm/st_stm32/stm32mp1/Kconfig.series | 1 + soc/arm/st_stm32/stm32mp1/Kconfig.soc | 7 --- soc/arm/st_stm32/stm32mp1/linker.ld | 2 +- soc/arm/st_stm32/stm32mp1/resource_table.c | 34 ---------- soc/arm/st_stm32/stm32mp1/resource_table.h | 73 ---------------------- 6 files changed, 2 insertions(+), 116 deletions(-) delete mode 100644 soc/arm/st_stm32/stm32mp1/resource_table.c delete mode 100644 soc/arm/st_stm32/stm32mp1/resource_table.h diff --git a/soc/arm/st_stm32/stm32mp1/CMakeLists.txt b/soc/arm/st_stm32/stm32mp1/CMakeLists.txt index 6f3e25a5b7e50..4a1dfd3050377 100644 --- a/soc/arm/st_stm32/stm32mp1/CMakeLists.txt +++ b/soc/arm/st_stm32/stm32mp1/CMakeLists.txt @@ -6,4 +6,3 @@ zephyr_include_directories(${ZEPHYR_BASE}/drivers) zephyr_sources( soc.c ) -zephyr_sources_ifdef(CONFIG_RPROC_RSC_TABLE resource_table.c) diff --git a/soc/arm/st_stm32/stm32mp1/Kconfig.series b/soc/arm/st_stm32/stm32mp1/Kconfig.series index f93f48dd73cf8..0c6580e84cce5 100644 --- a/soc/arm/st_stm32/stm32mp1/Kconfig.series +++ b/soc/arm/st_stm32/stm32mp1/Kconfig.series @@ -11,5 +11,6 @@ config SOC_SERIES_STM32MP1X select SOC_FAMILY_STM32 select HAS_STM32CUBE select CPU_HAS_ARM_MPU + select OPENAMP_RSC_TABLE if RAM_CONSOLE help Enable support for STM32MP1 MPU series diff --git a/soc/arm/st_stm32/stm32mp1/Kconfig.soc b/soc/arm/st_stm32/stm32mp1/Kconfig.soc index be9816f4d30a9..18e4202ae5f4f 100644 --- a/soc/arm/st_stm32/stm32mp1/Kconfig.soc +++ b/soc/arm/st_stm32/stm32mp1/Kconfig.soc @@ -11,10 +11,3 @@ config SOC_STM32MP15_M4 bool "STM32MP15_M4" endchoice - -config RPROC_RSC_TABLE - bool "coprocessor resource table" - default y if RAM_CONSOLE || OPENAMP - help - add the resource table in the generated binary. This table is - compatible with linux remote proc framework and OpenAMP library. diff --git a/soc/arm/st_stm32/stm32mp1/linker.ld b/soc/arm/st_stm32/stm32mp1/linker.ld index 63a58ccf38d7c..932eba0394d3a 100644 --- a/soc/arm/st_stm32/stm32mp1/linker.ld +++ b/soc/arm/st_stm32/stm32mp1/linker.ld @@ -13,7 +13,7 @@ SECTIONS { #include -#ifdef CONFIG_RPROC_RSC_TABLE +#ifdef CONFIG_OPENAMP_RSC_TABLE SECTION_PROLOGUE(.resource_table,, SUBALIGN(4)) { diff --git a/soc/arm/st_stm32/stm32mp1/resource_table.c b/soc/arm/st_stm32/stm32mp1/resource_table.c deleted file mode 100644 index 87950f3822246..0000000000000 --- a/soc/arm/st_stm32/stm32mp1/resource_table.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2019 STMicroelectronics - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include "resource_table.h" - -extern char ram_console[]; - -#define __section_t(S) __attribute__((__section__(#S))) -#define __resource __section_t(.resource_table) - -#ifdef CONFIG_RAM_CONSOLE -static volatile struct stm32_resource_table __resource resource_table = { - .ver = 1, - .num = 1, - .offset = { - offsetof(struct stm32_resource_table, cm_trace), - }, - .cm_trace = { - RSC_TRACE, - (uint32_t)ram_console, CONFIG_RAM_CONSOLE_BUFFER_SIZE + 1, 0, - "cm4_log", - }, -}; -#endif - -void resource_table_init(volatile void **table_ptr, int *length) -{ - *table_ptr = &resource_table; - *length = sizeof(resource_table); -} diff --git a/soc/arm/st_stm32/stm32mp1/resource_table.h b/soc/arm/st_stm32/stm32mp1/resource_table.h deleted file mode 100644 index 4dd0bdc633d77..0000000000000 --- a/soc/arm/st_stm32/stm32mp1/resource_table.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2018 Nordic Semiconductor ASA - * Copyright (c) 2019 STMicroelectronics - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef RESOURCE_TABLE_H__ -#define RESOURCE_TABLE_H__ - -#ifndef OPENAMP_PACKED_BEGIN -#define OPENAMP_PACKED_BEGIN -#endif - -#ifndef OPENAMP_PACKED_END -#define OPENAMP_PACKED_END __attribute__((__packed__)) -#endif - -/* beginning of section: copied from OpenAMP */ -/** - * struct fw_rsc_trace - trace buffer declaration - * @da: device address - * @len: length (in bytes) - * @reserved: reserved (must be zero) - * @name: human-readable name of the trace buffer - * - * This resource entry provides the host information about a trace buffer - * into which the remote remote_proc will write log messages. - * - * @da specifies the device address of the buffer, @len specifies - * its size, and @name may contain a human readable name of the trace buffer. - * - * After booting the remote remote_proc, the trace buffers are exposed to the - * user via debugfs entries (called trace0, trace1, etc..). - */ -OPENAMP_PACKED_BEGIN -struct fw_rsc_trace { - u32_t type; - u32_t da; - u32_t len; - u32_t reserved; - u8_t name[32]; -} OPENAMP_PACKED_END; - -OPENAMP_PACKED_BEGIN - -enum fw_resource_type { - RSC_CARVEOUT = 0, - RSC_DEVMEM = 1, - RSC_TRACE = 2, - RSC_VDEV = 3, - RSC_RPROC_MEM = 4, - RSC_FW_CHKSUM = 5, - RSC_LAST = 6, - RSC_VENDOR_START = 128, - RSC_VENDOR_END = 512, -}; - -/* end of section: copied from OpenAMP */ - -struct stm32_resource_table { - unsigned int ver; - unsigned int num; - unsigned int reserved[2]; - unsigned int offset[1]; - - /* rpmsg trace entry */ - struct fw_rsc_trace cm_trace; -} OPENAMP_PACKED_END; - -void resource_table_init(volatile void **table_ptr, int *length); - -#endif From 09bac32e8b0ef1734327ef03682feedf18549b47 Mon Sep 17 00:00:00 2001 From: Arnaud Pouliquen Date: Thu, 25 Jul 2019 16:02:34 +0200 Subject: [PATCH 3/4] dts: extend stm32mp1 sram declaration to 300 kB by default 64 kB of memory is reserved for the inter-processor communication. this makes sense only if RPMsg is used. Allow to use this memory for firmware data by default. Signed-off-by: Arnaud Pouliquen --- dts/arm/st/mp1/stm32mp157.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dts/arm/st/mp1/stm32mp157.dtsi b/dts/arm/st/mp1/stm32mp157.dtsi index 35b6890fcebed..0452b157d4c0f 100644 --- a/dts/arm/st/mp1/stm32mp157.dtsi +++ b/dts/arm/st/mp1/stm32mp157.dtsi @@ -31,7 +31,7 @@ mcusram: memory1@10000000 { device_type = "memory"; compatible = "mmio-sram"; - reg = <0x10000000 DT_SIZE_K(256)>; + reg = <0x10000000 DT_SIZE_K(320)>; }; soc { From 6d2865ebb618919529935f873a68973c55188aa8 Mon Sep 17 00:00:00 2001 From: Arnaud Pouliquen Date: Tue, 30 Jul 2019 14:21:09 +0200 Subject: [PATCH 4/4] samples: add openamp sample relying on resource table This sample is designed to respond to the Linux rpmsg sample client. It should be platform independent and based on the the integration of a resource table in the elf file. Signed-off-by: Arnaud Pouliquen --- .../ipc/openamp_rsc_table/CMakeLists.txt | 19 ++ samples/subsys/ipc/openamp_rsc_table/Kconfig | 15 + .../subsys/ipc/openamp_rsc_table/README.rst | 72 +++++ .../boards/stm32mp157c_dk2.overlay | 24 ++ samples/subsys/ipc/openamp_rsc_table/prj.conf | 11 + .../subsys/ipc/openamp_rsc_table/sample.yaml | 9 + .../ipc/openamp_rsc_table/src/main_remote.c | 293 ++++++++++++++++++ 7 files changed, 443 insertions(+) create mode 100644 samples/subsys/ipc/openamp_rsc_table/CMakeLists.txt create mode 100644 samples/subsys/ipc/openamp_rsc_table/Kconfig create mode 100644 samples/subsys/ipc/openamp_rsc_table/README.rst create mode 100644 samples/subsys/ipc/openamp_rsc_table/boards/stm32mp157c_dk2.overlay create mode 100644 samples/subsys/ipc/openamp_rsc_table/prj.conf create mode 100644 samples/subsys/ipc/openamp_rsc_table/sample.yaml create mode 100644 samples/subsys/ipc/openamp_rsc_table/src/main_remote.c diff --git a/samples/subsys/ipc/openamp_rsc_table/CMakeLists.txt b/samples/subsys/ipc/openamp_rsc_table/CMakeLists.txt new file mode 100644 index 0000000000000..1469c25080e75 --- /dev/null +++ b/samples/subsys/ipc/openamp_rsc_table/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.13.1) +# Copyright (c) 2020 STMicroelectronics +# +# SPDX-License-Identifier: Apache-2.0 +# + +find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) + +project(openamp_rsc_table_remote) + +# METAL_MAX_DEVICE_REGIONS is used to give the number of memory regions shared +# between processors. By default only one region is defined for the vrings +# and rpmsg buffers. The METAL_MAX_DEVICE_REGIONS has to be redifined to add a +# second region for the resource table. +zephyr_compile_definitions(METAL_MAX_DEVICE_REGIONS=2) + +target_include_directories(app PRIVATE ${LIBMETAL_INCLUDE_DIR} ${OPENAMP_INCLUDE_DIR} ${PLATFORM_DIR}) + +target_sources(app PRIVATE src/main_remote.c) diff --git a/samples/subsys/ipc/openamp_rsc_table/Kconfig b/samples/subsys/ipc/openamp_rsc_table/Kconfig new file mode 100644 index 0000000000000..52cc946db2f6d --- /dev/null +++ b/samples/subsys/ipc/openamp_rsc_table/Kconfig @@ -0,0 +1,15 @@ +# Private config options for openamp sample app + +# Copyright (c) 2020 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +# Workaround for not being able to have commas in macro arguments +DT_CHOSEN_Z_IPC := zephyr,ipc + +config OPENAMP_IPC_DEV_NAME + string + default "$(dt_chosen_label,$(DT_CHOSEN_Z_IPC))" + help + This option specifies the device name for the IPC device to be used + +source "Kconfig.zephyr" diff --git a/samples/subsys/ipc/openamp_rsc_table/README.rst b/samples/subsys/ipc/openamp_rsc_table/README.rst new file mode 100644 index 0000000000000..40695466fd393 --- /dev/null +++ b/samples/subsys/ipc/openamp_rsc_table/README.rst @@ -0,0 +1,72 @@ +.. _openAMP_rsc_table_sample: + +OpenAMP Sample Application using resource table +############################################### + +Overview +******** + +This application demonstrates how to use OpenAMP with Zephyr based on a resource +table. It is designed to respond to the `Linux rpmsg client sample `_. +This sample implementation is compatible with platforms that embed +a Linux kernel OS on the main processor and a Zephyr application on +the co-processor. + +Building the application +************************* + +Zephyr +------- + +.. zephyr-app-commands:: + :zephyr-app: samples/subsys/ipc/openamp_rsc_table + :goals: test + +Linux +------ + +Enable SAMPLE_RPMSG_CLIENT configuration to build and install +the rpmsg_client_sample.ko module on the target. + +Running the sample +******************* + +Zephyr console +--------------- + +Open a serial terminal (minicom, putty, etc.) and connect the board with the +following settings: + +- Speed: 115200 +- Data: 8 bits +- Parity: None +- Stop bits: 1 + +Reset the board. + +Linux console +--------------- + +Open a Linux shell (minicom, ssh, etc.) and insert a module into the Linux Kernel + +.. code-block:: console + + root@linuxshell: insmod rpmsg_client_sample.ko + +Result on Zephyr console +------------------------- + +The following message will appear on the corresponding Zephyr console: + +.. code-block:: console + + ***** Booting Zephyr OS v#.##.#-####-g########## ***** + Starting application thread! + + OpenAMP demo started + Remote core received message 1: hello world! + Remote core received message 2: hello world! + Remote core received message 3: hello world! + ... + Remote core received message 100: hello world! + OpenAMP demo ended. diff --git a/samples/subsys/ipc/openamp_rsc_table/boards/stm32mp157c_dk2.overlay b/samples/subsys/ipc/openamp_rsc_table/boards/stm32mp157c_dk2.overlay new file mode 100644 index 0000000000000..b843b81083a6c --- /dev/null +++ b/samples/subsys/ipc/openamp_rsc_table/boards/stm32mp157c_dk2.overlay @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2020, STMICROLECTRONICS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + /* + * shared memory reserved for the inter-processor communication + */ + zephyr,ipc_shm = &mcusram3; + zephyr,ipc = &mailbox; + }; + + mcusram3: memory1@10040000 { + compatible = "mmio-sram"; + reg = <0x10040000 DT_SIZE_K(64)>; + }; +}; + +&mcusram { + reg = <0x10000000 DT_SIZE_K(256)>; +}; diff --git a/samples/subsys/ipc/openamp_rsc_table/prj.conf b/samples/subsys/ipc/openamp_rsc_table/prj.conf new file mode 100644 index 0000000000000..1dd836773262c --- /dev/null +++ b/samples/subsys/ipc/openamp_rsc_table/prj.conf @@ -0,0 +1,11 @@ +CONFIG_KERNEL_BIN_NAME="zephyr_openamp_rsc_table" +CONFIG_PRINTK=n +CONFIG_IPM=y +CONFIG_IPM_MCUX=y +CONFIG_PLATFORM_SPECIFIC_INIT=n +CONFIG_MAIN_STACK_SIZE=1024 +CONFIG_HEAP_MEM_POOL_SIZE=1024 +CONFIG_OPENAMP=y +CONFIG_OPENAMP_RSC_TABLE_NUM_RPMSG_BUFF=8 +CONFIG_OPENAMP_RSC_TABLE=y +CONFIG_OPENAMP_MASTER=n diff --git a/samples/subsys/ipc/openamp_rsc_table/sample.yaml b/samples/subsys/ipc/openamp_rsc_table/sample.yaml new file mode 100644 index 0000000000000..aec9b5322a601 --- /dev/null +++ b/samples/subsys/ipc/openamp_rsc_table/sample.yaml @@ -0,0 +1,9 @@ +sample: + description: This app provides an example of how to integrate OpenAMP + with Zephyr in cluding a esource table. + name: OpenAMP with resource table example integration +tests: + sample.subsys.ipc.openamp_rs_table: + build_only: true + platform_whitelist: stm32mp157c_dk2 + tags: ipm diff --git a/samples/subsys/ipc/openamp_rsc_table/src/main_remote.c b/samples/subsys/ipc/openamp_rsc_table/src/main_remote.c new file mode 100644 index 0000000000000..5462456cb9142 --- /dev/null +++ b/samples/subsys/ipc/openamp_rsc_table/src/main_remote.c @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2020, STMICROLECTRONICS + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +LOG_MODULE_REGISTER(openamp_rsc_table, LOG_LEVEL_DBG); + +#define RPMSG_CHAN_NAME "rpmsg-client-sample" +#define SHM_DEVICE_NAME "shm" + +/* constant derivated from linker symbols */ +#define SHM_START_ADDR DT_IPC_SHM_BASE_ADDRESS +#define SHM_SIZE (DT_IPC_SHM_SIZE * 1024) + +#define APP_TASK_STACK_SIZE (512) +K_THREAD_STACK_DEFINE(thread_stack, APP_TASK_STACK_SIZE); +static struct k_thread thread_data; + +static struct device *ipm_handle; + +static metal_phys_addr_t shm_physmap = SHM_START_ADDR; + +struct metal_device shm_device = { + .name = SHM_DEVICE_NAME, + .num_regions = 2, + .regions = { + {.virt = NULL}, /* shared memory */ + {.virt = NULL}, /* rsc_table memory */ + }, + .node = { NULL }, + .irq_num = 0, + .irq_info = NULL +}; + +static struct metal_io_region *shm_io; +static struct rpmsg_virtio_shm_pool shpool; + +static struct metal_io_region *rsc_io; +static struct rpmsg_virtio_device rvdev; + +static void *rsc_table; + +static char rcv_msg[20]; /* should receive "Hello world!" */ +static unsigned int rcv_len; +static struct rpmsg_endpoint rcv_ept; + +static K_SEM_DEFINE(data_sem, 0, 1); +static K_SEM_DEFINE(data_rx_sem, 0, 1); + +static void platform_ipm_callback(void *context, u32_t id, volatile void *data) +{ + LOG_DBG("%s: msg received from mb %d\n", __func__, id); + k_sem_give(&data_sem); +} + +static int rpmsg_recv_callback(struct rpmsg_endpoint *ept, void *data, + size_t len, uint32_t src, void *priv) +{ + memcpy(rcv_msg, data, len); + rcv_len = len; + k_sem_give(&data_rx_sem); + + return RPMSG_SUCCESS; +} + +static void receive_message(unsigned char **msg, unsigned int *len) +{ + while (k_sem_take(&data_rx_sem, K_NO_WAIT) != 0) { + int status = k_sem_take(&data_sem, K_FOREVER); + + if (status == 0) { + rproc_virtio_notified(rvdev.vdev, VRING1_ID); + } + } + *len = rcv_len; + *msg = rcv_msg; +} + +static void new_service_cb(struct rpmsg_device *rdev, const char *name, + uint32_t src) +{ + LOG_ERR("%s: unexpected ns service receive for name %s\n", + __func__, name); +} + +int mailbox_notify(void *priv, uint32_t id) +{ + ARG_UNUSED(priv); + + LOG_DBG("%s: msg received\n", __func__); + ipm_send(ipm_handle, 0, id, NULL, 0); + + return 0; +} + +int platform_init(void) +{ + void *rsc_tab_addr; + int rsc_size; + struct metal_device *device; + struct metal_init_params metal_params = METAL_INIT_DEFAULTS; + int status; + + status = metal_init(&metal_params); + if (status) { + LOG_DBG("metal_init: failed: %d\n", status); + return -1; + } + + status = metal_register_generic_device(&shm_device); + if (status) { + LOG_DBG("Couldn't register shared memory: %d\n", status); + return -1; + } + + status = metal_device_open("generic", SHM_DEVICE_NAME, &device); + if (status) { + LOG_DBG("metal_device_open failed: %d\n", status); + return -1; + } + + /* declare shared memory region */ + metal_io_init(&device->regions[0], (void *)SHM_START_ADDR, &shm_physmap, + SHM_SIZE, -1, 0, NULL); + + shm_io = metal_device_io_region(device, 0); + if (!shm_io) { + LOG_DBG("Failed to get shm_io region\n"); + return -1; + } + + /* declare resource table region */ + rsc_table_get(&rsc_tab_addr, &rsc_size); + rsc_table = (struct st_resource_table *)rsc_tab_addr; + + metal_io_init(&device->regions[1], rsc_table, + (metal_phys_addr_t *)rsc_table, rsc_size, -1, 0, NULL); + + rsc_io = metal_device_io_region(device, 1); + if (!rsc_io) { + LOG_DBG("Failed to get rsc_io region\n"); + return -1; + } + + /* setup IPM */ + ipm_handle = device_get_binding(CONFIG_OPENAMP_IPC_DEV_NAME); + if (!ipm_handle) { + LOG_DBG("Failed to find ipm device\n"); + return -1; + } + + ipm_register_callback(ipm_handle, platform_ipm_callback, NULL); + + status = ipm_set_enabled(ipm_handle, 1); + if (status) { + LOG_DBG("ipm_set_enabled failed\n"); + return -1; + } + + return 0; +} + +static void cleanup_system(void) +{ + ipm_set_enabled(ipm_handle, 0); + rpmsg_deinit_vdev(&rvdev); + metal_finish(); +} + +struct rpmsg_device * +platform_create_rpmsg_vdev(unsigned int vdev_index, + unsigned int role, + void (*rst_cb)(struct virtio_device *vdev), + rpmsg_ns_bind_cb ns_cb) +{ + struct fw_rsc_vdev_vring *vring_rsc; + struct virtio_device *vdev; + int ret; + + vdev = rproc_virtio_create_vdev(VIRTIO_DEV_SLAVE, VDEV_ID, + rsc_table_to_vdev(rsc_table), + rsc_io, NULL, mailbox_notify, NULL); + + if (!vdev) { + LOG_DBG("failed to create vdev\r\n"); + return NULL; + } + + /* wait master rpmsg init completion */ + rproc_virtio_wait_remote_ready(vdev); + + vring_rsc = rsc_table_get_vring0(rsc_table); + ret = rproc_virtio_init_vring(vdev, 0, vring_rsc->notifyid, + (void *)vring_rsc->da, rsc_io, + vring_rsc->num, vring_rsc->align); + if (ret) { + LOG_DBG("failed to init vring 0\r\n"); + goto failed; + } + + vring_rsc = rsc_table_get_vring1(rsc_table); + ret = rproc_virtio_init_vring(vdev, 1, vring_rsc->notifyid, + (void *)vring_rsc->da, rsc_io, + vring_rsc->num, vring_rsc->align); + if (ret) { + LOG_DBG("failed to init vring 1\r\n"); + goto failed; + } + + rpmsg_virtio_init_shm_pool(&shpool, NULL, SHM_SIZE); + ret = rpmsg_init_vdev(&rvdev, vdev, ns_cb, shm_io, &shpool); + + if (ret) { + LOG_DBG("failed rpmsg_init_vdev\r\n"); + goto failed; + } + + return rpmsg_virtio_get_rpmsg_device(&rvdev); + +failed: + rproc_virtio_remove_vdev(vdev); + + return NULL; +} + +void app_task(void *arg1, void *arg2, void *arg3) +{ + ARG_UNUSED(arg1); + ARG_UNUSED(arg2); + ARG_UNUSED(arg3); + struct rpmsg_device *rpdev; + unsigned char *msg; + unsigned int len, msg_cnt = 0; + int ret = 0; + + printk("\r\nOpenAMP[remote] linux responder demo started\r\n"); + + /* Initialize platform */ + ret = platform_init(); + if (ret) { + LOG_ERR("Failed to initialize platform\n"); + ret = -1; + goto task_end; + } + + rpdev = platform_create_rpmsg_vdev(0, VIRTIO_DEV_SLAVE, NULL, + new_service_cb); + if (!rpdev) { + LOG_ERR("Failed to create rpmsg virtio device\n"); + ret = -1; + goto task_end; + } + + ret = rpmsg_create_ept(&rcv_ept, rpdev, RPMSG_CHAN_NAME, + RPMSG_ADDR_ANY, RPMSG_ADDR_ANY, + rpmsg_recv_callback, NULL); + if (ret != 0) + LOG_ERR("error while creating endpoint(%d)\n", ret); + + while (msg_cnt < 100) { + receive_message(&msg, &len); + msg_cnt++; + rpmsg_send(&rcv_ept, msg, len); + } + rpmsg_destroy_ept(&rcv_ept); + +task_end: + cleanup_system(); + + printk("OpenAMP demo ended\n"); +} + +void main(void) +{ + printk("Starting application thread!\n"); + k_thread_create(&thread_data, thread_stack, APP_TASK_STACK_SIZE, + (k_thread_entry_t)app_task, + NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); +}