From c64dd2d399177d88cdfecb0c334825533580a425 Mon Sep 17 00:00:00 2001 From: Wayne Ren Date: Thu, 1 Dec 2022 21:06:44 +0800 Subject: [PATCH] mcs: remove mcs codes mcs codes move to https://gitee.com/openeuler/mcs Signed-off-by: Wayne Ren --- mcs/CMakeLists.txt | 46 --- mcs/README.md | 158 -------- mcs/latency_demo/rpmsg_main.c | 87 ----- mcs/latency_demo/zephyr_rpi.bin | Bin 174016 -> 0 bytes mcs/mcs_km/Makefile | 6 - mcs/mcs_km/mcs_km.c | 341 ------------------ mcs/modules/openamp_module.c | 113 ------ mcs/modules/openamp_module.h | 25 -- mcs/modules/remoteproc_module.c | 133 ------- mcs/modules/remoteproc_module.h | 37 -- mcs/modules/rpmsg_module.c | 173 --------- mcs/modules/rpmsg_module.h | 19 - mcs/modules/virtio_module.c | 134 ------- mcs/modules/virtio_module.h | 35 -- mcs/openamp_demo/rpmsg_main.c | 85 ----- mcs/openamp_demo/zephyr_qemu.bin | Bin 109608 -> 0 bytes mcs/openamp_demo/zephyr_rpi.bin | Bin 136832 -> 0 bytes mcs/openamp_demo_proc_ptyshell/Makefile | 14 - .../rpmsg-internal.h | 55 --- .../rpmsg_linux_endpoint.c | 332 ----------------- mcs/openamp_demo_proc_ptyshell/rpmsg_main.c | 76 ---- .../rpmsg_rtos_endpoint.c | 272 -------------- mcs/openamp_demo_proc_rsctbl/Makefile | 14 - mcs/openamp_demo_proc_rsctbl/rpmsg-internal.h | 54 --- .../rpmsg_linux_endpoint.c | 296 --------------- mcs/openamp_demo_proc_rsctbl/rpmsg_main.c | 76 ---- .../rpmsg_rtos_endpoint.c | 277 -------------- mcs/rpmsg_pty_demo/rpmsg_main.c | 87 ----- mcs/rpmsg_pty_demo/rpmsg_pty.c | 153 -------- mcs/rpmsg_pty_demo/rpmsg_pty.h | 10 - mcs/rpmsg_pty_demo/zephyr_qemu.bin | Bin 167456 -> 0 bytes mcs/rpmsg_pty_demo/zephyr_rpi.bin | Bin 179752 -> 0 bytes 32 files changed, 3108 deletions(-) delete mode 100644 mcs/CMakeLists.txt delete mode 100644 mcs/README.md delete mode 100644 mcs/latency_demo/rpmsg_main.c delete mode 100644 mcs/latency_demo/zephyr_rpi.bin delete mode 100644 mcs/mcs_km/Makefile delete mode 100644 mcs/mcs_km/mcs_km.c delete mode 100644 mcs/modules/openamp_module.c delete mode 100644 mcs/modules/openamp_module.h delete mode 100644 mcs/modules/remoteproc_module.c delete mode 100644 mcs/modules/remoteproc_module.h delete mode 100644 mcs/modules/rpmsg_module.c delete mode 100644 mcs/modules/rpmsg_module.h delete mode 100644 mcs/modules/virtio_module.c delete mode 100644 mcs/modules/virtio_module.h delete mode 100644 mcs/openamp_demo/rpmsg_main.c delete mode 100644 mcs/openamp_demo/zephyr_qemu.bin delete mode 100644 mcs/openamp_demo/zephyr_rpi.bin delete mode 100644 mcs/openamp_demo_proc_ptyshell/Makefile delete mode 100644 mcs/openamp_demo_proc_ptyshell/rpmsg-internal.h delete mode 100644 mcs/openamp_demo_proc_ptyshell/rpmsg_linux_endpoint.c delete mode 100644 mcs/openamp_demo_proc_ptyshell/rpmsg_main.c delete mode 100644 mcs/openamp_demo_proc_ptyshell/rpmsg_rtos_endpoint.c delete mode 100644 mcs/openamp_demo_proc_rsctbl/Makefile delete mode 100644 mcs/openamp_demo_proc_rsctbl/rpmsg-internal.h delete mode 100644 mcs/openamp_demo_proc_rsctbl/rpmsg_linux_endpoint.c delete mode 100644 mcs/openamp_demo_proc_rsctbl/rpmsg_main.c delete mode 100644 mcs/openamp_demo_proc_rsctbl/rpmsg_rtos_endpoint.c delete mode 100644 mcs/rpmsg_pty_demo/rpmsg_main.c delete mode 100644 mcs/rpmsg_pty_demo/rpmsg_pty.c delete mode 100644 mcs/rpmsg_pty_demo/rpmsg_pty.h delete mode 100644 mcs/rpmsg_pty_demo/zephyr_qemu.bin delete mode 100644 mcs/rpmsg_pty_demo/zephyr_rpi.bin diff --git a/mcs/CMakeLists.txt b/mcs/CMakeLists.txt deleted file mode 100644 index 3f80ebb9..00000000 --- a/mcs/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ -cmake_minimum_required(VERSION 3.19) - -project(openamp_demo) - -set(CMAKE_C_COMPILER ${CC}) -set(CMAKE_CXX_COMPILER ${CXX}) - -message(STATUS "SDKTARGETSYSROOT=$ENV{SDKTARGETSYSROOT}") -message(STATUS "DEMO_TARGET=${DEMO_TARGET}") - -set(SHARED_LINK_LIBS - $ENV{SDKTARGETSYSROOT}/usr/lib64/libopen_amp.so - $ENV{SDKTARGETSYSROOT}/usr/lib64/libmetal.so - $ENV{SDKTARGETSYSROOT}/lib64/libsysfs.so -) - -add_library(openamp STATIC - ./modules/openamp_module.c - ./modules/remoteproc_module.c - ./modules/virtio_module.c - ./modules/rpmsg_module.c -) -target_link_libraries(openamp - ${SHARED_LINK_LIBS} -) - -set(SRC_FILE - ./${DEMO_TARGET}/rpmsg_main.c -) - -if(DEMO_TARGET MATCHES "openamp_demo") -elseif(DEMO_TARGET MATCHES "latency_demo") -elseif(DEMO_TARGET MATCHES "rpmsg_pty_demo") - list(APPEND SRC_FILE "./${DEMO_TARGET}/rpmsg_pty.c") -else() - message(FATAL_ERROR "DEMO_TARGET: choose a target to build. - [openamp_demo|rpmsg_pty_demo]") #rsc_table_demo|cyclitest_demo|rpmsg_service_demo|gdb_demo -endif() - -include_directories( - $ENV{SDKTARGETSYSROOT}/usr/include - ./modules - ./${DEMO_TARGET} -) -add_executable(rpmsg_main ${SRC_FILE}) -target_link_libraries(rpmsg_main openamp) \ No newline at end of file diff --git a/mcs/README.md b/mcs/README.md deleted file mode 100644 index dbee180d..00000000 --- a/mcs/README.md +++ /dev/null @@ -1,158 +0,0 @@ -# mcs - -#### 介绍 - -该模块用于提供OpenAMP样例的内核态与用户态支持。 - -#### 软件架构 - -mcs_km: 提供OpenAMP所需内核模块,支持Client OS启动、专用中断收发、管理保留内存等功能。 - -openamp_demo: 提供OpenAMP用户态程序Linux端样例,支持与指定Client OS进行通信。 - -rpmsg_pty_demo: 提供OpenAMP用户态程序Linux端样例,支持通过shell命令行访问Client OS。 - -modules: 提供OpenAMP样例必需的模块remoteproc、virtio、rpmsg、openamp,这些模块静态编译成libopenamp.a。 - -zephyr: 提供样例镜像文件,在每个demo中,zephyr_qemu.bin运行在qemu上,zephyr_rpi.bin运行在树莓派上,该文件需要被加载至设定的0x7a000000起始地址。启动后会运行OpenAMP Client端的样例程序,并与Linux端进行交互。 - -#### 原理简介 - -OpenAMP旨在通过非对称多处理器的开源解决方案来标准化异构嵌入式系统中操作环境之间的交互。 - -OpenAMP是一个软件框架,提供了为AMP系统开发软件应用程序所需的软件组件,允许操作系统在复杂的同构和异构体系结构中交互。 - -OpenAMP包括如下三大重要组件: - --virtio:该组件是rpmsg组件的实现基础。 - --rpmsg:实现多核处理器通信的通道,基于virtio组件实现。 - --remoteproc:该组件用于主机上实现对远程处理器及相关软件环境的生命周期管理、及virtio和rpmsg设备的注册等。 - -样例Demo通过提供mcs_km内核KO模块实现Linux内核启动从核的功能,并预留了OpenAMP通信所需的专用中断及其收发机制。用户可在用户态通过dev设备实现Client OS的启动,并通过rpmsg组件实现与Client OS的简单通信。 - -#### 安装教程 - -1. qemu使用openeuler-image镜像运行混合部署。 - -树莓派使用openeuler-image-uefi镜像运行混合部署,该镜像对齐tiny镜像的软件包配置,并集成openssh支持网络登录、混合部署依赖库、混合部署保留内存mcsmem dtoverlay、以及第三方UEFI固件支持PSCI功能。openeuler-image-uefi镜像的构建、烧录和启动,请参考openEuler Embedded在线文档章节:树莓派的UEFI支持和网络启动。 - -2. 根据openEuler Embedded使用手册安装SDK并设置SDK环境变量。 - -3. 编译内核模块mcs_km.ko,编译方式如下: - -```` - cd mcs_km - make -```` - -4. 编译openamp_demo用户态程序rpmsg_main,编译方式如下: - -```` - cmake -S . -B build -DDEMO_TARGET=openamp_demo - cd build - make -```` - -注意:此处定义OpenAMP通信设备保留内存起始地址为0x70000000,可根据实际内存分配进行修改。 -如果需要查看调试日志,可以给cmake增加-DDEBUG参数。 - -5. 将编译好的KO模块、用户态程序,以及zephyr_qemu.bin镜像拷贝到openEuler Embedded系统的目录下。如何拷贝可以参考使用手册中共享文件系统场景。 - -6. 将OpenAMP的依赖库libmetal.so\*,libopen_amp.so\*拷贝至文件系统/usr/lib64目录,libsysfs.so\*拷贝至文件系统/lib64目录。对应so可在sdk目录中找到,如何拷贝可以参考使用手册中共享文件系统场景。 - -#### 使用说明 - -1. 通过QEMU启动openEuler Embedded镜像,如何启动可参考使用手册中QEMU使用与调试章节。树莓派跳过这一步。 - --以上述demo为例,需要预留出地址0x70000000为起始的内存用于OpenAMP demo和Client OS启动。通过QEMU启动时,当指定-m 1G时默认使用0x40000000-0x80000000的系统内存。添加内核启动参数mem=768M,可预留地址为0x70000000-0x80000000的256M保留内存。 --在样例中在cpu 3启动Client OS,需要预留出3号cpu。 --样例中zephyr镜像默认gic版本为3,需要在QEMU中设置。 - -可参考如下命令进行启动: - -```` - qemu-system-aarch64 -M virt,gic-version=3 -m 1G -cpu cortex-a57 -nographic -kernel zImage -initrd *.rootfs.cpio.gz -append 'mem=768M maxcpus=3' -smp 4 -```` - -当使用的QEMU版本过老时可能会由于内存分布不一致导致段错误,可升级QEMU版本或手动修改DTB空出对应内存。 - -2. 在openEuler Embedded系统上插入内核KO模块mcs_km.ko。 - -```` - insmod mcs_km.ko -```` - -3. 运行rpmsg_main程序,使用方式如下: - -```` - ./rpmsg_main -c [cpu_id] -t [target_binfile] -a [target_binaddress] - eg: - ./rpmsg_main -c 3 -t zephyr_qemu.bin -a 0x7a000000 -```` - -此处定义Client OS起始地址为0x7a000000,Client OS镜像名为zephyr_qemu.bin,Client OS从3号cpu启动。树莓派换成zephyr_rpi.bin。 - -#### 用户样例开发 -mcs提供了4个API,供用户做样例开发,用户无需感知OpenAMP实现细节,接口定义在modules/openamp_module.h。 - -1. openamp_init: 初始化保留内存,加载zephyr镜像文件,初始化remoteproc、virtio、rpmsg,建立Linux与Client OS两端配对的endpoint,供消息收发使用。 -```` - int openamp_init(void); -```` - -2. receive_message: Linux端接收消息。 -```` - int receive_message(unsigned char *message, int message_len, int *real_len); -```` - message: 用户传入的消息接收buffer - message_len: 接收buffer的长度 - real_len: 实际接收到的消息长度 - -3. send_message: Linux端发送消息。 -```` - int send_message(unsigned char *message, int len); -```` - message: 用户传入的消息发送buffer - len: 发送buffer的长度 - -4. openamp_deinit: 释放openamp资源。 -```` - void openamp_deinit(void); -```` - -#### 串口服务样例 -rpmsg_pty_demo包含2个源文件,实现通过Linux shell命令行访问Client OS的功能,样例支持多用户多线程场景。 - -rpmsg_main.c: 初始化OpenAMP,用户创建线程,在线程中运行shell程序。 - -rpmsg_pty.c: 用户创建PTY虚拟串口设备,将PTY的slave端作为shell,PTY的master端与OpenAMP Endpint节点通信。 - -1. 安装教程,其他步骤与openamp_demo相同,把DEMO_TARGET换成rpmsg_pty_demo编译。 -```` - cmake -S . -B build -DDEMO_TARGET=rpmsg_pty_demo -```` - -2. 使用说明,为了不影响shell的使用,建议启动qemu时加上console=ttyAMA1内核参数,将内核打印屏蔽。 -```` - qemu-system-aarch64 -M virt,gic-version=3 -m 1G -cpu cortex-a57 -nographic -kernel zImage -initrd *.rootfs.cpio.gz -append 'mem=768M maxcpus=3 console=ttyAMA1' -smp 4 -```` - -树莓派可以通过设置printk在console上的打印优先级屏蔽内核打印。 -```` - cat /proc/sys/kernel/printk > /tmp/printk_bak - echo 1 4 1 7 > /proc/sys/kernel/printk -```` - -3. 运行rpmsg_main程序时,把程序放在后台,然后通过screen打开shell。 -```` - ./rpmsg_main -c 3 -t zephyr_qemu.bin -a 0x7a000000 & - screen /dev/pts/0 -```` - -4. 进入shell,输入help可以查看Client OS支持哪些命令,输入history可以查看历史命令,ctrl+d退出。 -```` - uart:~$ help - uart:~$ history -```` \ No newline at end of file diff --git a/mcs/latency_demo/rpmsg_main.c b/mcs/latency_demo/rpmsg_main.c deleted file mode 100644 index 2632ee0d..00000000 --- a/mcs/latency_demo/rpmsg_main.c +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include -#include "openamp_module.h" - -char *cpu_id; -char *target_binfile; -char *target_binaddr; - -static void cleanup(int sig) -{ - openamp_deinit(); - exit(0); -} - -int rpmsg_app_master(void) -{ - int ret; - char buf[2048] = {0}; - int len; - int i; - - printf("start latency measure demo...\n"); - - /* linux send messsage to clientos first */ - ret = send_message("latency_demo\n", sizeof("latency_demo\n")); - if (ret < 0) { - printf("send_message failed with status %d\n", ret); - return ret; - } - - while (1) { - ret = receive_message(buf, sizeof(buf), &len); - if (ret < 0) { - printf("receive_message failed with status %d\n", ret); - return ret; - } - - /* show message */ - for (i = 0; i < len; i++) - printf("%c", buf[i]); - } - - return 0; -} - -int main(int argc, char **argv) -{ - int ret; - int opt; - - /* ctrl+c signal, do cleanup before program exit */ - signal(SIGINT, cleanup); - - while ((opt = getopt(argc, argv, "c:t:a:")) != -1) { - switch (opt) { - case 'c': - cpu_id = optarg; - break; - case 't': - target_binfile = optarg; - break; - case 'a': - target_binaddr = optarg; - break; - default: - break; - } - } - - ret = openamp_init(); - if (ret) { - printf("openamp init failed: %d\n", ret); - openamp_deinit(); - return ret; - } - - ret = rpmsg_app_master(); - if (ret) { - printf("rpmsg app master failed: %d\n", ret); - openamp_deinit(); - return ret; - } - - openamp_deinit(); - - return 0; -} diff --git a/mcs/latency_demo/zephyr_rpi.bin b/mcs/latency_demo/zephyr_rpi.bin deleted file mode 100644 index 2f3b03354f2e30aa6cb0e72b828b9866ac6d5cbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174016 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 diff --git a/mcs/mcs_km/Makefile b/mcs/mcs_km/Makefile deleted file mode 100644 index f9b3396c..00000000 --- a/mcs/mcs_km/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -obj-m := mcs_km.o - -all: - $(MAKE) -C $(KERNEL_SRC_DIR) M=$(PWD) modules -clean: - $(MAKE) -C $(KERNEL_SRC_DIR) M=$(PWD) clean diff --git a/mcs/mcs_km/mcs_km.c b/mcs/mcs_km/mcs_km.c deleted file mode 100644 index 0445be1f..00000000 --- a/mcs/mcs_km/mcs_km.c +++ /dev/null @@ -1,341 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MCS_DEVICE_NAME "mcs" -#define CPU_ON_FUNCID 0xC4000003 -#define AFFINITY_INFO_FUNCID 0xC4000004 - -#define MAGIC_NUMBER 'A' -#define IOC_SENDIPI _IOW(MAGIC_NUMBER, 0, int) -#define IOC_CPUON _IOW(MAGIC_NUMBER, 1, int) -#define IOC_AFFINITY_INFO _IOW(MAGIC_NUMBER, 2, int) -#define IOC_MAXNR 2 - -#define OPENAMP_INIT_TRIGGER 0x0 -#define OPENAMP_CLIENTOS_TRIGGER 0x1 -#define OPENAMP_IRQ 8 - -#define START_INDEX 1 -#define SIZE_INDEX 2 - -static struct class *mcs_class; -static int mcs_major; - -static u64 valid_start; -static u64 valid_end; -static const char *smccc_method = "hvc"; - -static DECLARE_WAIT_QUEUE_HEAD(openamp_trigger_wait); -static int openamp_trigger; - -static irqreturn_t handle_clientos_ipi(int irq, void *data) -{ - pr_info("mcs_km: received ipi from client os\n"); - openamp_trigger = OPENAMP_CLIENTOS_TRIGGER; - wake_up_interruptible(&openamp_trigger_wait); - return IRQ_HANDLED; -} - -void set_openamp_ipi(void) -{ - int err; - struct irq_desc *desc; - - /* use IRQ8 as IPI7, init irq resource once */ - desc = irq_to_desc(OPENAMP_IRQ); - if (!desc->action) { - err = request_percpu_irq(OPENAMP_IRQ, handle_clientos_ipi, "IPI", &cpu_number); - if (err) { - pr_err("mcs_km: request openamp irq failed(%d)\n", err); - return; - } - } - - /* In SMP, all the cores run Linux should be enabled */ - if (!irq_percpu_is_enabled(OPENAMP_IRQ)) { - preempt_disable(); /* fix kernel err message: using smp_processor_id() in preemptible */ - enable_percpu_irq(OPENAMP_IRQ, 0); - preempt_enable(); - } - - return; -} - -static void send_clientos_ipi(const struct cpumask *target) -{ - ipi_send_mask(OPENAMP_IRQ, target); -} - -static unsigned int mcs_poll(struct file *file, poll_table *wait) -{ - unsigned int mask; - - poll_wait(file, &openamp_trigger_wait, wait); - mask = 0; - if (openamp_trigger == OPENAMP_CLIENTOS_TRIGGER) - mask |= POLLIN | POLLRDNORM; - - openamp_trigger = OPENAMP_INIT_TRIGGER; - return mask; -} - -static long mcs_ioctl(struct file *f, unsigned int cmd, unsigned long arg) -{ - int err; - int cpu_id, cpu_boot_addr; - struct arm_smccc_res res; - - if (_IOC_TYPE(cmd) != MAGIC_NUMBER) - return -EINVAL; - if (_IOC_NR(cmd) > IOC_MAXNR) - return -EINVAL; - err = !access_ok((void*)arg, _IOC_SIZE(cmd)); - if (err) - return -EINVAL; - - switch (cmd) { - case IOC_SENDIPI: - cpu_id = (int)arg; - pr_info("mcs_km: received ioctl cmd to send ipi to cpu(%d)\n", cpu_id); - send_clientos_ipi(cpumask_of(cpu_id)); - break; - case IOC_CPUON: - cpu_id = *(unsigned int*)arg; - cpu_boot_addr = *((unsigned int*)arg + 1); - - pr_info("mcs_km: start booting clientos on cpu(%d) addr(0x%x) smccc(%s)\n", cpu_id, cpu_boot_addr, smccc_method); - if (strcmp(smccc_method, "smc") == 0) - arm_smccc_smc(CPU_ON_FUNCID, cpu_id, cpu_boot_addr, 0, 0, 0, 0, 0, &res); - else - arm_smccc_hvc(CPU_ON_FUNCID, cpu_id, cpu_boot_addr, 0, 0, 0, 0, 0, &res); - if (res.a0) { - pr_err("mcs_km: boot clientos failed(%ld)\n", res.a0); - return -EINVAL; - } - break; - case IOC_AFFINITY_INFO: - cpu_id = *(unsigned int*)arg; - - if (strcmp(smccc_method, "smc") == 0) - arm_smccc_smc(AFFINITY_INFO_FUNCID, cpu_id, 0, 0, 0, 0, 0, 0, &res); - else - arm_smccc_hvc(AFFINITY_INFO_FUNCID, cpu_id, 0, 0, 0, 0, 0, 0, &res); - *(unsigned int*)arg = res.a0; - break; - default: - pr_err("mcs_km: IOC param invalid(0x%x)\n", cmd); - return -EINVAL; - } - - return 0; -} - -#ifdef CONFIG_STRICT_DEVMEM -static inline int range_is_allowed(unsigned long pfn, unsigned long size) -{ - u64 from = ((u64)pfn) << PAGE_SHIFT; - u64 to = from + size; - u64 cursor = from; - - while (cursor < to) { - if (page_is_ram(pfn)) - return 0; - cursor += PAGE_SIZE; - pfn++; - } - return 1; -} -#else -static inline int range_is_allowed(unsigned long pfn, unsigned long size) -{ - return 1; -} -#endif - -int mcs_phys_mem_access_prot_allowed(struct file *file, - unsigned long pfn, unsigned long size, pgprot_t *vma_prot) -{ - u64 start, end; - start = ((u64)pfn) << PAGE_SHIFT; - end = start + size; - - if (valid_start == 0 && valid_end == 0) { - if (!range_is_allowed(pfn, size)) - return 0; - return 1; - } - - if (start < valid_start || end > valid_end) { - return 0; - } - - return 1; -} - -static pgprot_t mcs_phys_mem_access_prot(struct file *file, unsigned long pfn, - unsigned long size, pgprot_t vma_prot) -{ - return __pgprot_modify(vma_prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN); -} - -static const struct vm_operations_struct mmap_mem_ops = { -#ifdef CONFIG_HAVE_IOREMAP_PROT - .access = generic_access_phys -#endif -}; - -/* A lite version of linux/drivers/char/mem.c, Test with MMU for arm64 mcs functions */ -static int mcs_mmap(struct file *file, struct vm_area_struct *vma) -{ - size_t size = vma->vm_end - vma->vm_start; - phys_addr_t offset = (phys_addr_t)vma->vm_pgoff << PAGE_SHIFT; - - /* Does it even fit in phys_addr_t? */ - if (offset >> PAGE_SHIFT != vma->vm_pgoff) - return -EINVAL; - - /* It's illegal to wrap around the end of the physical address space. */ - if (offset + (phys_addr_t)size - 1 < offset) - return -EINVAL; - - if (!mcs_phys_mem_access_prot_allowed(file, vma->vm_pgoff, size, - &vma->vm_page_prot)) - return -EINVAL; - - vma->vm_page_prot = mcs_phys_mem_access_prot(file, vma->vm_pgoff, - size, - vma->vm_page_prot); - - vma->vm_ops = &mmap_mem_ops; - - /* Remap-pfn-range will mark the range VM_IO */ - if (remap_pfn_range(vma, - vma->vm_start, - vma->vm_pgoff, - size, - vma->vm_page_prot)) { - return -EAGAIN; - } - return 0; -} - -static int mcs_open(struct inode *inode, struct file *filp) -{ - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - return 0; -} - -static const struct file_operations mcs_fops = { - .open = mcs_open, - .mmap = mcs_mmap, - .poll = mcs_poll, - .unlocked_ioctl = mcs_ioctl, - .llseek = generic_file_llseek, -}; - -static int get_mcs_node_info(void) -{ - int ret = 0; - struct device_node *nd = NULL; - u8 datasize; - u32 *val = NULL; - - nd = of_find_compatible_node(NULL, NULL, "mcs_mem"); - if (nd == NULL) { - pr_info("no reserved-memory mcs node.\n"); - return -EINVAL; - } - - datasize = of_property_count_elems_of_size(nd, "reg", sizeof(u32)); - if (datasize != 3) { - pr_err("invalid reserved-memory mcs reg size.\n"); - return -EINVAL; - } - - val = kmalloc(datasize * sizeof(u32), GFP_KERNEL); - if (val == NULL) - return -ENOMEM; - - ret = of_property_read_u32_array(nd, "reg", val, datasize); - if (ret < 0) - goto out; - - valid_start = (u64)(*(val + START_INDEX)); - valid_end = valid_start + (u64)(*(val + SIZE_INDEX)); - - ret = of_property_read_string(nd, "smccc", &smccc_method); - if (ret < 0) - goto out; - -out: - kfree(val); - return ret; -} - -static int __init mcs_dev_init(void) -{ - struct device *class_dev = NULL; - int ret = 0; - - mcs_major = register_chrdev(0, MCS_DEVICE_NAME, &mcs_fops); - if (mcs_major < 0) { - pr_err("mcs_km: unable to get major %d for memory devs.\n", mcs_major); - return -1; - } - - mcs_class = class_create(THIS_MODULE, MCS_DEVICE_NAME); - if (IS_ERR(mcs_class)) { - ret = PTR_ERR(mcs_class); - goto error_class_create; - } - - class_dev = device_create(mcs_class, NULL, MKDEV((unsigned int)mcs_major, 1), - NULL, MCS_DEVICE_NAME); - if (unlikely(IS_ERR(class_dev))) { - ret = PTR_ERR(class_dev); - goto error_device_create; - } - - set_openamp_ipi(); - - if (get_mcs_node_info() < 0) - pr_info("there's no mcsmem dts node info. Allow page isn't ram mmap.\n"); - else - pr_info("valid mcsmem node detected.\n"); - - pr_info("mcs_km: create major %d for mcs dev.\n", mcs_major); - return 0; - -error_device_create: - class_destroy(mcs_class); -error_class_create: - unregister_chrdev(mcs_major, MCS_DEVICE_NAME); - return ret; -} -module_init(mcs_dev_init); - -static void __exit mcs_dev_exit(void) -{ - device_destroy(mcs_class, MKDEV((unsigned int)mcs_major, 1)); - class_destroy(mcs_class); - unregister_chrdev(mcs_major, MCS_DEVICE_NAME); - - pr_info("mcs_km: remove mcs dev.\n"); -} -module_exit(mcs_dev_exit); - -MODULE_AUTHOR("OpenEuler Embedded"); -MODULE_DESCRIPTION("mcs device"); -MODULE_LICENSE("Dual BSD/GPL"); diff --git a/mcs/modules/openamp_module.c b/mcs/modules/openamp_module.c deleted file mode 100644 index 89ba609a..00000000 --- a/mcs/modules/openamp_module.c +++ /dev/null @@ -1,113 +0,0 @@ -#include -#include "openamp_module.h" - -#define MCS_DEVICE_NAME "/dev/mcs" -#define STR_TO_HEX 16 -#define PAGE_SIZE 4096 -#define PAGE_MASK (~(PAGE_SIZE - 1)) -#define PAGE_ALIGN(addr) ((addr & PAGE_MASK) + PAGE_SIZE) - -static int memfd; -static void *binaddr; -static int binsize; -void *shmaddr; - -static int reserved_mem_init(void) -{ - int binfd; - struct stat buf; - void *file_addr; - - /* open memfd */ - memfd = open(MCS_DEVICE_NAME, O_RDWR | O_SYNC); - if (memfd < 0) { - printf("mcsmem open failed: %d\n", memfd); - return -1; - } - - /* open clientos bin file */ - binfd = open(target_binfile, O_RDONLY); - if (binfd < 0) { - printf("open %s failed, binfd:%d\n", target_binfile, binfd); - return -1; - } - - /* shared memory for virtio */ - shmaddr = mmap(NULL, VDEV_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, VDEV_START_ADDR); - memset(shmaddr, 0, VDEV_SIZE); - - /* memory for loading clientos bin file */ - fstat(binfd, &buf); - binsize = PAGE_ALIGN(buf.st_size); - binaddr = mmap(NULL, binsize, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, strtol(target_binaddr, NULL, STR_TO_HEX)); - memset(binaddr, 0, binsize); - - if (shmaddr < 0 || binaddr < 0) { - printf("mmap reserved mem failed: shmaddr:%p, binaddr:%p\n", shmaddr, binaddr); - return -1; - } - - /* load clientos */ - file_addr = mmap(NULL, binsize, PROT_READ, MAP_PRIVATE, binfd, 0); - memcpy(binaddr, file_addr, binsize); - - close(binfd); - - return 0; -} - -static void reserved_mem_release(void) -{ - if (shmaddr) - munmap(shmaddr, VDEV_SIZE); - if (binaddr) - munmap(binaddr, binsize); - if (memfd) - close(memfd); -} - -int openamp_init(void) -{ - int ret; - struct remoteproc *rproc; - int cpu_state; - - /* secondary core power state must be CPU_STATE_OFF, avoid initialize repeatedly */ - cpu_state = acquire_cpu_state(); - if (cpu_state != CPU_STATE_OFF) { - printf("cpu(%s) is already on(%d).\n", cpu_id, cpu_state); - return -1; - } - - ret = reserved_mem_init(); - if (ret) { - printf("failed to init reserved mem\n"); - return ret; - } - - rproc = create_remoteproc(); - if (!rproc) { - printf("create remoteproc failed\n"); - return -1; - } - - ret = remoteproc_start(rproc); - if (ret) { - printf("start processor failed\n"); - return ret; - } - - virtio_init(); - rpmsg_module_init(); - - return 0; -} - -void openamp_deinit(void) -{ - printf("\nOpenAMP demo ended.\n"); - - destory_remoteproc(); /* shutdown clientos first */ - virtio_deinit(); - reserved_mem_release(); -} diff --git a/mcs/modules/openamp_module.h b/mcs/modules/openamp_module.h deleted file mode 100644 index bc4237ab..00000000 --- a/mcs/modules/openamp_module.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef OPENAMP_MODULE_H -#define OPENAMP_MODULE_H - -#include -#include "remoteproc_module.h" -#include "virtio_module.h" -#include "rpmsg_module.h" - -extern char *target_binfile; -extern char *target_binaddr; -extern char *cpu_id; - -/* initialize openamp module, including remoteproc, virtio, rpmsg */ -int openamp_init(void); - -/* release openamp resource */ -void openamp_deinit(void); - -/* message standard receive interface */ -int receive_message(unsigned char *message, int message_len, int *real_len); - -/* message standard send interface */ -int send_message(unsigned char *message, int len); - -#endif \ No newline at end of file diff --git a/mcs/modules/remoteproc_module.c b/mcs/modules/remoteproc_module.c deleted file mode 100644 index 8965040b..00000000 --- a/mcs/modules/remoteproc_module.c +++ /dev/null @@ -1,133 +0,0 @@ -#include -#include -#include -#include -#include "remoteproc_module.h" -#include "openamp_module.h" - -#define MCS_DEVICE_NAME "/dev/mcs" -#define IOC_CPUON _IOW('A', 1, int) -#define IOC_AFFINITY_INFO _IOW('A', 2, int) -#define STR_TO_HEX 16 -#define STR_TO_DEC 10 - -struct rproc_priv { - struct remoteproc *rproc; /* pass a remoteproc instance pointer */ - unsigned int idx; /* remoteproc instance idx */ - unsigned int cpu_id; /* related arg: cpu id */ - unsigned int boot_address; /* related arg: boot address(in hex format) */ -}; - -static struct remoteproc rproc_inst; - -static struct remoteproc *rproc_init(struct remoteproc *rproc, - const struct remoteproc_ops *ops, void *args) -{ - struct rproc_priv *priv; - - (void)rproc; - priv = metal_allocate_memory(sizeof(*priv)); - if (!priv) - return NULL; - - memcpy(priv, (struct rproc_priv *)args, sizeof(*priv)); - priv->rproc->ops = ops; - metal_list_init(&priv->rproc->mems); - priv->rproc->priv = priv; - rproc->state = RPROC_READY; - return priv->rproc; -} - -static void rproc_remove(struct remoteproc *rproc) -{ - struct rproc_priv *priv; - - priv = (struct rproc_priv *)rproc->priv; - metal_free_memory(priv); -} - -static int rproc_start(struct remoteproc *rproc) -{ - int ret; - unsigned int boot_args[2]; - struct rproc_priv *args = (struct rproc_priv *)rproc->priv; - - int fd = open(MCS_DEVICE_NAME, O_RDWR); - if (fd < 0) { - printf("failed to open %s device.\n", MCS_DEVICE_NAME); - return fd; - } - - boot_args[0] = args->cpu_id; - boot_args[1] = args->boot_address; - ret = ioctl(fd, IOC_CPUON, boot_args); - if (ret) { - printf("boot clientos failed\n"); - return ret; - } - - close(fd); - return 0; -} - -static int rproc_stop(struct remoteproc *rproc) -{ - /* TODO: send order to clientos by RPC service, clientos shut itself down by PSCI */ - send_message("shutdown", sizeof("shutdown")); - - return 0; -} - -const struct remoteproc_ops rproc_ops = { - .init = rproc_init, - .remove = rproc_remove, - .start = rproc_start, - .stop = rproc_stop, -}; - -struct remoteproc *create_remoteproc(void) -{ - struct remoteproc *rproc; - struct rproc_priv args; - - args.rproc = &rproc_inst; - args.idx = 1; - args.cpu_id = strtol(cpu_id, NULL, STR_TO_DEC); - args.boot_address = strtol(target_binaddr, NULL, STR_TO_HEX); - rproc = remoteproc_init(&rproc_inst, &rproc_ops, &args); - if (!rproc) - return NULL; - - return rproc; -} - -void destory_remoteproc(void) -{ - remoteproc_stop(&rproc_inst); - rproc_inst.state = RPROC_OFFLINE; - if (rproc_inst.priv) - remoteproc_remove(&rproc_inst); -} - -int acquire_cpu_state(void) -{ - int ret; - int fd; - unsigned int state_arg; - - fd = open(MCS_DEVICE_NAME, O_RDWR); - if (fd < 0) { - printf("open %s device failed\n", MCS_DEVICE_NAME); - return fd; - } - - state_arg = strtol(cpu_id, NULL, STR_TO_DEC); - ret = ioctl(fd, IOC_AFFINITY_INFO, &state_arg); - if (ret) { - printf("acquire cpu state failed\n"); - return ret; - } - - close(fd); - return state_arg; /* secondary core power state */ -} diff --git a/mcs/modules/remoteproc_module.h b/mcs/modules/remoteproc_module.h deleted file mode 100644 index 6b0a6ae2..00000000 --- a/mcs/modules/remoteproc_module.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef REMOTEPROC_MODULE_H -#define REMOTEPROC_MODULE_H - -#include - -#define CPU_STATE_ON 0 -#define CPU_STATE_OFF 1 -#define CPU_STATE_ON_PENDING 2 - -/* create remoteproc */ -struct remoteproc *create_remoteproc(void); - -/* - start remoteproc: refet to - int remoteproc_start(struct remoteproc *rproc); -*/ - -/* - stop remoteproc: refet to - int remoteproc_stop(struct remoteproc *rproc); -*/ - -/* - remove remoteproc: refet to - int remoteproc_remove(struct remoteproc *rproc); -*/ - -/* destory remoteproc */ -void destory_remoteproc(void); - -/* acquire cpu power state */ -int acquire_cpu_state(void); - -extern char *cpu_id; -extern char *target_binaddr; - -#endif \ No newline at end of file diff --git a/mcs/modules/rpmsg_module.c b/mcs/modules/rpmsg_module.c deleted file mode 100644 index 9b1a78b2..00000000 --- a/mcs/modules/rpmsg_module.c +++ /dev/null @@ -1,173 +0,0 @@ -#include -#include -#include -#include -#include "virtio_module.h" -#include "rpmsg_module.h" - -#define MCS_DEVICE_NAME "/dev/mcs" - -/* endpoint state */ -#define ENDPOINT_BOUND 0 -#define ENDPOINT_NOT_FOUND -1 -#define ENDPOINT_UNKNOWN_STATE -2 - -struct endpoint_priv { - unsigned char received_data[2048]; - unsigned int received_len; -}; - -/* TODO: endpoint ability negotiation */ -char ept_name[RPMSG_NAME_SIZE]; - -/* add more parameters such as dest_addr, when there are several clientos */ -static struct rpmsg_endpoint* obtain_endpoint(const char *name) -{ - struct metal_list *node; - struct rpmsg_endpoint *ept; - - metal_list_for_each(&rdev->endpoints, node) { - ept = metal_container_of(node, struct rpmsg_endpoint, node); - if (!strncmp(ept->name, name, sizeof(ept->name))) - return ept; - } - - return NULL; -} - -static int check_endpoint(const char *name) -{ - struct rpmsg_endpoint *ept = obtain_endpoint(name); - if (!ept) { - return ENDPOINT_NOT_FOUND; - } - - if ((ept->addr != RPMSG_ADDR_ANY) && (ept->dest_addr != RPMSG_ADDR_ANY)) - return ENDPOINT_BOUND; - - return ENDPOINT_UNKNOWN_STATE; -} - -static int endpoint_cb(struct rpmsg_endpoint *ept, void *data, - size_t len, uint32_t src, void *priv) -{ - /* put data into endpoint's priv buffer, do not cover. - user call receive_message of this endpoint will read and clear the buffer */ - struct endpoint_priv *p = priv; - - memcpy(p->received_data + p->received_len, data, len); - p->received_len += len; - - return RPMSG_SUCCESS; -} - -static void rpmsg_service_unbind(struct rpmsg_endpoint *ept) -{ - rpmsg_destroy_ept(ept); -} - -void destroy_endpoint(const char *name) -{ - struct rpmsg_endpoint *ept = obtain_endpoint(name); - rpmsg_destroy_ept(ept); - free(ept->priv); - free(ept); -} - -void ns_bind_cb(struct rpmsg_device *rdev, const char *name, uint32_t dest) -{ - strncpy(ept_name, name ? name : "", RPMSG_NAME_SIZE); - - /* endpoint_cb can be defined by user */ - struct rpmsg_endpoint *ept = malloc(sizeof(struct rpmsg_endpoint)); - ept->priv = malloc(sizeof(struct endpoint_priv)); - (void)rpmsg_create_ept(ept, rdev, ept_name, RPMSG_ADDR_ANY, dest, endpoint_cb, rpmsg_service_unbind); -} - -static void *rpmsg_receive_message(void *arg) -{ - int ret; - int dev_fd; - struct pollfd fds; - - dev_fd = open(MCS_DEVICE_NAME, O_RDWR); - if (dev_fd < 0) { - printf("rpmsg_receive_message: open %s device failed.\n", MCS_DEVICE_NAME); - return (void*)-1; - } - - fds.fd = dev_fd; - fds.events = POLLIN; - - while (1) { -#ifdef DEBUG - printf("master waiting for message....\n"); -#endif - ret = poll(&fds, 1, -1); - if (ret < 0) { - printf("rpmsg_receive_message: poll failed.\n"); - goto _cleanup; - } - - if (fds.revents & POLLIN) { -#ifdef DEBUG - printf("master receiving message....\n"); -#endif - virtqueue_notification(vq[0]); /* will call endpoint_cb or ns_bind_cb */ - } - } - -_cleanup: - close(dev_fd); - return (void*)0; -} - -int receive_message(unsigned char *message, int message_len, int *real_len) -{ - struct rpmsg_endpoint *ept = obtain_endpoint(ept_name); - if (!ept) { - printf("receive_message: no endpoint to receive message.\n"); - return -1; - } - - struct endpoint_priv *data = ept->priv; - if (data->received_len > message_len) { - printf("receive_message: buffer is too small. received_len:%d\n", data->received_len); - return -1; - } - if (!message) - return -1; - - /* copy buffer to message */ - memset(message, 0, message_len); - memcpy(message, data->received_data, data->received_len); - *real_len = data->received_len; - - /* clear buffer */ - memset(data->received_data, 0, sizeof(data->received_data)); - data->received_len = 0; - - return 0; -} - -int send_message(unsigned char *message, int len) -{ - /* ensure endpoint is bound, sleep to wait */ - while (check_endpoint(ept_name) != ENDPOINT_BOUND) - usleep(1000); - - struct rpmsg_endpoint *ept = obtain_endpoint(ept_name); - return rpmsg_send(ept, message, len); -} - -void rpmsg_module_init(void) -{ - pthread_t tid; - - /* deal with messages received from clientos */ - if (pthread_create(&tid, NULL, rpmsg_receive_message, NULL) < 0) { - perror("rpmsg_receive_message pthread_create"); - return; - } - pthread_detach(tid); -} diff --git a/mcs/modules/rpmsg_module.h b/mcs/modules/rpmsg_module.h deleted file mode 100644 index 93fb5c85..00000000 --- a/mcs/modules/rpmsg_module.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef RPMSG_MODULE_H -#define RPMSG_MODULE_H - -#include - -/* endpoint name */ -#define CONSOLE_ENDPOINT "console_ept" -#define LOG_ENDPOINT "log_ept" -#define SHELL_ENDPOINT "shell_ept" - -/* name service callback: create matching endpoint */ -void ns_bind_cb(struct rpmsg_device *rdev, const char *name, uint32_t dest); - -/* destroy endpoint and inform clientos to destroy */ -void destroy_endpoint(const char *name); - -void rpmsg_module_init(void); - -#endif \ No newline at end of file diff --git a/mcs/modules/virtio_module.c b/mcs/modules/virtio_module.c deleted file mode 100644 index 4e5d5811..00000000 --- a/mcs/modules/virtio_module.c +++ /dev/null @@ -1,134 +0,0 @@ -#include -#include -#include -#include -#include "rpmsg_module.h" -#include "virtio_module.h" - -#define IOC_SENDIPI _IOW('A', 0, int) -#define MCS_DEVICE_NAME "/dev/mcs" -#define STR_TO_DEC 10 - -static struct virtio_vring_info rvrings[2] = { - [0] = { - .info.align = VRING_ALIGNMENT, - }, - [1] = { - .info.align = VRING_ALIGNMENT, - }, -}; - -static struct virtio_device vdev; -static struct rpmsg_virtio_device rvdev; -static struct metal_io_region *io; -struct virtqueue *vq[2]; -static metal_phys_addr_t shm_physmap[] = { SHM_START_ADDR }; -struct rpmsg_device *rdev; - -static unsigned char virtio_get_status(struct virtio_device *vdev) -{ - return VIRTIO_CONFIG_STATUS_DRIVER_OK; -} - -static void virtio_set_status(struct virtio_device *vdev, unsigned char status) -{ - *(volatile unsigned int *)VDEVADDR(shmaddr) = (unsigned int)status; -} - -static uint32_t virtio_get_features(struct virtio_device *vdev) -{ - return 1 << VIRTIO_RPMSG_F_NS; -} - -static void virtio_notify(struct virtqueue *vq) -{ - (void)vq; - int cpu_handler_fd; - int ret; - - cpu_handler_fd = open(MCS_DEVICE_NAME, O_RDWR); - if (cpu_handler_fd < 0) { - printf("open %s device failed\n", MCS_DEVICE_NAME); - return; - } - - ret = ioctl(cpu_handler_fd, IOC_SENDIPI, strtol(cpu_id, NULL, STR_TO_DEC)); - if (ret) { - printf("send ipi tp second os failed\n"); - } - - close(cpu_handler_fd); - return; -} - -struct virtio_dispatch dispatch = { - .get_status = virtio_get_status, - .set_status = virtio_set_status, - .get_features = virtio_get_features, - .notify = virtio_notify, -}; - -static struct rpmsg_virtio_shm_pool shpool; - -void virtio_init(void) -{ - int status = 0; - - printf("\nInitialize the virtio, virtqueue and rpmsg device\n"); - - io = malloc(sizeof(struct metal_io_region)); - if (!io) { - printf("malloc io failed\n"); - return; - } - metal_io_init(io, SHMEMADDR(shmaddr), shm_physmap, SHM_SIZE, -1, 0, NULL); - - /* setup vdev */ - vq[0] = virtqueue_allocate(VRING_SIZE); - if (vq[0] == NULL) { - printf("virtqueue_allocate failed to alloc vq[0]\n"); - free(io); - return; - } - vq[1] = virtqueue_allocate(VRING_SIZE); - if (vq[1] == NULL) { - printf("virtqueue_allocate failed to alloc vq[1]\n"); - free(io); - return; - } - - vdev.role = RPMSG_HOST; - vdev.vrings_num = VRING_COUNT; - vdev.func = &dispatch; - rvrings[0].io = io; - rvrings[0].info.vaddr = TXADDR(shmaddr); - rvrings[0].info.num_descs = VRING_SIZE; - rvrings[0].info.align = VRING_ALIGNMENT; - rvrings[0].vq = vq[0]; - - rvrings[1].io = io; - rvrings[1].info.vaddr = RXADDR(shmaddr); - rvrings[1].info.num_descs = VRING_SIZE; - rvrings[1].info.align = VRING_ALIGNMENT; - rvrings[1].vq = vq[1]; - - vdev.vrings_info = &rvrings[0]; - - /* setup rvdev */ - rpmsg_virtio_init_shm_pool(&shpool, SHMEMADDR(shmaddr), SHM_SIZE); - status = rpmsg_init_vdev(&rvdev, &vdev, ns_bind_cb, io, &shpool); - if (status != 0) { - printf("rpmsg_init_vdev failed %d\n", status); - free(io); - return; - } - - rdev = rpmsg_virtio_get_rpmsg_device(&rvdev); -} - -void virtio_deinit(void) -{ - rpmsg_deinit_vdev(&rvdev); - if (io) - free(io); -} diff --git a/mcs/modules/virtio_module.h b/mcs/modules/virtio_module.h deleted file mode 100644 index e8db4572..00000000 --- a/mcs/modules/virtio_module.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef VIRTIO_MODULE_H -#define VIRTIO_MODULE_H - -#include -#include - -#define VDEV_START_ADDR 0x70000000 -#define VDEV_SIZE 0x30000 - -#define VDEV_STATUS_ADDR VDEV_START_ADDR -#define VDEV_STATUS_SIZE 0x4000 - -#define SHM_START_ADDR (VDEV_START_ADDR + VDEV_STATUS_SIZE) -#define SHM_SIZE (VDEV_SIZE - VDEV_STATUS_SIZE) - -#define VRING_COUNT 2 -#define VRING_RX_ADDRESS (VDEV_START_ADDR + SHM_SIZE - VDEV_STATUS_SIZE) -#define VRING_TX_ADDRESS (VDEV_START_ADDR + SHM_SIZE) -#define VRING_ALIGNMENT 4 -#define VRING_SIZE 16 - -#define TXADDR(SHMADDR) (SHMADDR + VRING_TX_ADDRESS - VDEV_START_ADDR) -#define RXADDR(SHMADDR) (SHMADDR + VRING_RX_ADDRESS - VDEV_START_ADDR) -#define VDEVADDR(SHMADDR) (SHMADDR + VDEV_STATUS_ADDR - VDEV_START_ADDR) -#define SHMEMADDR(SHMADDR) (SHMADDR + SHM_START_ADDR - VDEV_START_ADDR) - -void virtio_init(void); -void virtio_deinit(void); - -extern char *cpu_id; -extern struct virtqueue *vq[2]; -extern void *shmaddr; -extern struct rpmsg_device *rdev; - -#endif \ No newline at end of file diff --git a/mcs/openamp_demo/rpmsg_main.c b/mcs/openamp_demo/rpmsg_main.c deleted file mode 100644 index 59d0258f..00000000 --- a/mcs/openamp_demo/rpmsg_main.c +++ /dev/null @@ -1,85 +0,0 @@ -#include -#include -#include "openamp_module.h" - -char *cpu_id; -char *target_binfile; -char *target_binaddr; - -static void cleanup(int sig) -{ - openamp_deinit(); - exit(0); -} - -int rpmsg_app_master(void) -{ - int ret; - int message = 10; - int len; - - printf("start processing OpenAMP demo...\n"); - - while (message < 99) { - ret = send_message((unsigned char*)&message, sizeof(message)); - if (ret < 0) { - printf("send_message(%u) failed with status %d\n", message, ret); - return ret; - } - sleep(1); - - ret = receive_message((unsigned char*)&message, sizeof(message), &len); - if (ret < 0) { - printf("receive_message failed with status %d\n", ret); - return ret; - } - printf("Master core received a message: %u\n", message); - message++; - sleep(1); - } - - return 0; -} - -int main(int argc, char **argv) -{ - int ret; - int opt; - - /* ctrl+c signal, do cleanup before program exit */ - signal(SIGINT, cleanup); - - while ((opt = getopt(argc, argv, "c:t:a:")) != -1) { - switch (opt) { - case 'c': - cpu_id = optarg; - break; - case 't': - target_binfile = optarg; - break; - case 'a': - target_binaddr = optarg; - break; - default: - break; - } - } - - ret = openamp_init(); - if (ret) { - printf("openamp init failed: %d\n", ret); - openamp_deinit(); - return ret; - } - - ret = rpmsg_app_master(); - if (ret) { - printf("rpmsg app master failed: %d\n", ret); - openamp_deinit(); - return ret; - } - - openamp_deinit(); - - return 0; -} diff --git a/mcs/openamp_demo/zephyr_qemu.bin b/mcs/openamp_demo/zephyr_qemu.bin deleted file mode 100644 index 457b597f7230ab5f7ebec7ca1e0d2d2dec25fc30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 109608 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 diff --git a/mcs/openamp_demo/zephyr_rpi.bin b/mcs/openamp_demo/zephyr_rpi.bin deleted file mode 100644 index 5dcb9d9d185945fbb78cecaac70cfb103dc3f445..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 136832 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%0D^qsf{8vtGD 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 -#include -#include - -#define SHM_START_ADDR 0x70000000 -#define SHM_SIZE 0x30000 - -#define VRING_ADDR_SIZE 0x4000 -#define VRING_RX_ADDRESS (SHM_START_ADDR + SHM_SIZE) -#define VRING_TX_ADDRESS (VRING_RX_ADDRESS + VRING_ADDR_SIZE) -#define RTOS_VRING_RX_ADDRESS VRING_TX_ADDRESS -#define RTOS_VRING_TX_ADDRESS VRING_RX_ADDRESS - -#define VRING_COUNT 2 -#define VRING_ALIGNMENT 4 -#define VRING_SIZE 16 - -#define RSC_TABLE_ADDR 0x71000000 - -#define VDEV_NOTIFY_ID 0 -#define VRING_RX_NOTIFY_ID 1 -#define VRING_TX_NOTIFY_ID 2 - -struct rproc_priv { - struct remoteproc *rproc; - unsigned int id; -}; - -#define NO_RESOURCE_ENTRIES 8 - -/* Resource table for the given remote */ -struct remote_resource_table { - unsigned int version; - unsigned int num; - unsigned int reserved[2]; - unsigned int offset[NO_RESOURCE_ENTRIES]; - - /* 1. rpmsg buffer mem entry */ - struct fw_rsc_carveout rpmsg_mem; - - /* 2. rpmsg vdev entry */ - struct fw_rsc_vdev rpmsg_vdev; - struct fw_rsc_vdev_vring rpmsg_vring0; - struct fw_rsc_vdev_vring rpmsg_vring1; -} __attribute__((__packed__)); - -extern int pipefd1[2]; -extern int pipefd2[2]; - -void *get_resource_table(int *len); - -#endif diff --git a/mcs/openamp_demo_proc_ptyshell/rpmsg_linux_endpoint.c b/mcs/openamp_demo_proc_ptyshell/rpmsg_linux_endpoint.c deleted file mode 100644 index 7d56db46..00000000 --- a/mcs/openamp_demo_proc_ptyshell/rpmsg_linux_endpoint.c +++ /dev/null @@ -1,332 +0,0 @@ -/* Linux Endpoint run in parent process, isolate with child process */ - -#include -#define __USE_XOPEN_EXTENDED -#define __USE_XOPEN2KXSI -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rpmsg-internal.h" - -static volatile unsigned int received_data; -static struct rpmsg_virtio_shm_pool shpool; //tmp, must be global var -static struct rpmsg_endpoint linux_ept; //tmp, must be global var - -static struct remoteproc *rproc_init(struct remoteproc *rproc, - struct remoteproc_ops *ops, void *arg) -{ - struct rproc_priv *priv; - unsigned int id = *((unsigned int *)arg); - - priv = metal_allocate_memory(sizeof(*priv)); - if (!priv) - return NULL; - - memset(priv, 0, sizeof(*priv)); - priv->rproc = rproc; - priv->id = id; - priv->rproc->ops = ops; - metal_list_init(&priv->rproc->mems); - priv->rproc->priv = priv; - rproc->state = RPROC_READY; - return priv->rproc; -} - -static void rproc_remove(struct remoteproc *rproc) -{ - struct rproc_priv *priv; - - priv = (struct rproc_priv *)rproc->priv; - metal_free_memory(priv); -} - -static void *rproc_mmap(struct remoteproc *rproc, - metal_phys_addr_t *pa, metal_phys_addr_t *da, - size_t size, unsigned int attribute, - struct metal_io_region **io) -{ - struct remoteproc_mem *mem; - struct metal_io_region *tmpio; - - if (*pa == METAL_BAD_PHYS && *da == METAL_BAD_PHYS) - return NULL; - if (*pa == METAL_BAD_PHYS) - *pa = *da; - if (*da == METAL_BAD_PHYS) - *da = *pa; - - mem = metal_allocate_memory(sizeof(*mem)); - if (!mem) - return NULL; - tmpio = metal_allocate_memory(sizeof(*tmpio)); - if (!tmpio) { - metal_free_memory(mem); - return NULL; - } - - /* mmap pa to va */ - int memfd; - void *va; - memfd = open("/dev/mem", O_RDWR); - va = mmap((void*)pa, size, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, *pa); - - remoteproc_init_mem(mem, NULL, *pa, *da, size, tmpio); - metal_io_init(tmpio, va, &mem->pa, size, -1, attribute, NULL); /* metal io manage va and pa */ - remoteproc_add_mem(rproc, mem); - if (io) - *io = tmpio; - - printf("master mmap pa=0x%lx, da=0x%lx, size=0x%lx, attribute=0x%x va=%p\n", *pa, *da, size, attribute, va); - - return metal_io_phys_to_virt(tmpio, mem->pa); -} - -//master tmp -static int rproc_notify_tmp(struct remoteproc *rproc, uint32_t id) -{ - return 0; -} - -static int rproc_notify(struct remoteproc *rproc, uint32_t id) -{ - int ret; - - printf("master notify start\n"); - - /* notify RTOS Endpoint using IPC */ - ret = write(pipefd1[1], "Linux: notify ipi\n", strlen("Linux: notify ipi\n")); - if (ret == -1) - perror("master write pipefd1[1]"); - - return 0; -} - -static struct remoteproc_ops rproc_ops = { - .init = rproc_init, - .remove = rproc_remove, - .mmap = rproc_mmap, - .notify = rproc_notify_tmp, //master tmp -}; - -static unsigned int receive_message(struct remoteproc *rproc) -{ - char buf[50] = {0}; - int ret; - - /* 1. poll and wait for IPI(IPC) from RTOS Endpoint */ - while (read(pipefd2[0], buf, sizeof(buf)) > 0) { - printf("master poll:%s", buf); - if (strcmp(buf, "RTOS: notify ipi\n") == 0) - break; - } - - /* 2. receive data */ - ret = remoteproc_get_notification(rproc, VRING_RX_NOTIFY_ID); - if (ret) - printf("remoteproc_get_notification failed: 0x%x\n", ret); - return received_data; -} - -static int endpoint_cb(struct rpmsg_endpoint *ept, void *data, - size_t len, uint32_t src, void *priv) -{ - received_data = *((unsigned int *) data); - return RPMSG_SUCCESS; -} - -static void rpmsg_service_unbind(struct rpmsg_endpoint *ept) -{ - rpmsg_destroy_ept(ept); -} - -static void ns_bind_cb(struct rpmsg_device *rdev, const char *name, uint32_t dest) -{ - (void)rpmsg_create_ept(&linux_ept, rdev, name, - RPMSG_ADDR_ANY, dest, - endpoint_cb, - rpmsg_service_unbind); -} - -static int send_message(unsigned int message, struct rpmsg_endpoint *ept) -{ - return rpmsg_send(ept, &message, sizeof(message)); -} - -static struct remoteproc *platform_create_proc(unsigned int id) -{ - struct remoteproc *rproc; - struct remoteproc rproc_inst; - void *va; - void *rsc; - int ret; - metal_phys_addr_t pa = RSC_TABLE_ADDR; - int rsc_size; - - /* Initialize remoteproc instance */ - rproc = remoteproc_init(&rproc_inst, &rproc_ops, &id); - if (!rproc) - return NULL; - - /* mmap resource table */ - rsc = get_resource_table(&rsc_size); - va = remoteproc_mmap(rproc, &pa, NULL, rsc_size, 0, NULL); - memcpy(va, rsc, rsc_size); - - /* parse resource table to remoteproc */ - ret = remoteproc_set_rsc_table(rproc, va, rsc_size); - if (ret) { - printf("Failed to initialize remoteproc, ret:0x%x\n", ret); - remoteproc_remove(rproc); - return NULL; - } - - //tmp - struct remote_resource_table *va_tmp = va; - struct remote_resource_table *rsc_tmp = rsc; - va_tmp->rpmsg_vdev.notifyid = rsc_tmp->rpmsg_vdev.notifyid; - va_tmp->rpmsg_vdev.vring[0].notifyid = rsc_tmp->rpmsg_vdev.vring[0].notifyid; - va_tmp->rpmsg_vdev.vring[1].notifyid = rsc_tmp->rpmsg_vdev.vring[1].notifyid; - - printf("(1)master platform_create_proc success\n"); - - return rproc; -} - -static struct rpmsg_device *platform_create_rpmsg_vdev(struct remoteproc *rproc) -{ - struct rpmsg_virtio_device rpmsg_vdev; - struct virtio_device *vdev; - void *shbuf; - struct metal_io_region *shbuf_io; - int ret; - - shbuf_io = remoteproc_get_io_with_pa(rproc, SHM_START_ADDR); - if (!shbuf_io) - return NULL; - shbuf = metal_io_phys_to_virt(shbuf_io, SHM_START_ADDR); - - printf("(2)master creating remoteproc virtio\n"); - vdev = remoteproc_create_virtio(rproc, 0, RPMSG_MASTER, NULL); - if (!vdev) { - printf("failed remoteproc_create_virtio\n"); - return NULL; - } - - printf("(3)master initializing rpmsg shared buffer pool\n"); - /* Only RPMsg virtio master needs to initialize the shared buffers pool */ - rpmsg_virtio_init_shm_pool(&shpool, shbuf, SHM_SIZE); - - printf("(4)master initializing rpmsg vdev\n"); - /* RPMsg virtio slave can set shared buffers pool argument to NULL */ - ret = rpmsg_init_vdev(&rpmsg_vdev, vdev, ns_bind_cb, shbuf_io, &shpool); - if (ret) { - printf("failed rpmsg_init_vdev\n"); - remoteproc_remove_virtio(rproc, vdev); - return NULL; - } - - //printf("master vq[0].callback:%p, vq[1].callback:%p\n", vdev->vrings_info[0].vq->callback, vdev->vrings_info[1].vq->callback); - - printf("(5)master returning rdev\n"); - return rpmsg_virtio_get_rpmsg_device(&rpmsg_vdev); -} - -static void rpmsg_app_master(struct remoteproc *rproc, int fdm) -{ - int status = 0; - unsigned int message; - - //tmp - /* register notify function */ - rproc->ops->notify = rproc_notify; - - /* 1.2 master receive NS Announcement, and process it */ - receive_message(rproc); - - printf("1.2 master receive_message succeed\n"); - printf("1.2 master Endpoint: name:%s, addr:0x%x, dest_addr:0x%x\n", linux_ept.name, linux_ept.addr, linux_ept.dest_addr); - - char buffer[256] = {0}; - while (read(fdm, buffer, sizeof(buffer)) > 0) { - message = atoi(buffer); - /* 2. master send message */ - status = send_message(message, &linux_ept); - if (status < 0) - printf("send_message(%u) failed with status %d\n", message, status); - printf("2. master send_message succeed\n"); - - /* 5. master receive message */ - message = receive_message(rproc); - printf("5. Master core received a message: %u\n\n", message); - snprintf(buffer, sizeof(buffer), "%d\n", message); - status = write(fdm, buffer, strlen(buffer)); - if (status == -1) - perror("master write fdm"); - } -} - -void open_pty(int *pfdm, int *pfds) -{ - int ret, fdm, fds; - struct termios tty = {0}; - - /* Open the master side of the PTY */ - fdm = posix_openpt(O_RDWR | O_NOCTTY); - if (fdm < 0) - printf("Error %d on posix_openpt()\n", errno); - - ret = grantpt(fdm); - if (ret != 0) - printf("Error %d on grantpt()\n", errno); - - ret = unlockpt(fdm); - if (ret != 0) - printf("Error %d on unlockpt()\n", errno); - - /* Open the slave side of the PTY */ - fds = open(ptsname(fdm), O_RDWR | O_NOCTTY); - - /* Set the state of fds to TERMIOS_P */ - tty.c_cflag = CS8; - tcsetattr(fds, TCSAFLUSH, &tty); - - *pfdm = fdm; - *pfds = fds; -} - -int rpmsg_linux_endpoint() -{ - struct remoteproc *rproc = NULL; - unsigned int id = 1; - struct rpmsg_device *rdev = NULL; - int fdm, fds; - - open_pty(&fdm, &fds); - - /* create remoteproc */ - rproc = platform_create_proc(id); - if (!rproc) { - printf("create rproc failed\n"); - return -1; - } - - rdev = platform_create_rpmsg_vdev(rproc); - if (!rdev) - printf("master create rpmsg vdev failed\n"); - - rpmsg_app_master(rproc, fdm); - //remoteproc_remove(rproc); - - return 0; -} diff --git a/mcs/openamp_demo_proc_ptyshell/rpmsg_main.c b/mcs/openamp_demo_proc_ptyshell/rpmsg_main.c deleted file mode 100644 index ac08fba1..00000000 --- a/mcs/openamp_demo_proc_ptyshell/rpmsg_main.c +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include -#include - -#include "rpmsg-internal.h" - -int pipefd1[2]; -int pipefd2[2]; - -/* Place resource table in special ELF section */ -#define __section_t(S) __attribute__((__section__(#S))) -#define __resource __section_t(.resource_table) - -#define NUM_TABLE_ENTRIES 2 -#define DFEATURE_SUPPORT_NS 1 - -struct remote_resource_table __resource resources = { - /* Version */ - RSC_TAB_SUPPORTED_VERSION, - /* NUmber of table entries */ - NUM_TABLE_ENTRIES, - /* reserved fields */ - { 0, 0 }, - /* Offsets of rsc entries */ - { - offsetof(struct remote_resource_table, rpmsg_mem), - offsetof(struct remote_resource_table, rpmsg_vdev), - }, - - /* 1. Rpmsg buffer memory entry including vring TX/RX memory */ - { RSC_CARVEOUT, SHM_START_ADDR, SHM_START_ADDR, SHM_SIZE, 0 }, - - /* 2. Virtio device entry */ - { RSC_VDEV, VIRTIO_ID_RPMSG, VDEV_NOTIFY_ID, DFEATURE_SUPPORT_NS, 0, 0, 0, VRING_COUNT, { 0, 0 } }, - /* Vring rsc entry - part of vdev rsc entry */ - { VRING_RX_ADDRESS, VRING_ALIGNMENT, VRING_SIZE, VRING_RX_NOTIFY_ID, 0 }, /* VRING_RX */ - { VRING_TX_ADDRESS, VRING_ALIGNMENT, VRING_SIZE, VRING_TX_NOTIFY_ID, 0 }, /* VRING_TX */ -}; - -void *get_resource_table(int *len) -{ - *len = sizeof(resources); - return &resources; -} - -extern int rpmsg_linux_endpoint(); -extern int rpmsg_rtos_endpoint(); - -int main(int argc, char **argv) -{ - pid_t pid; - - /* Create unamed pipe */ - if (pipe(pipefd1) < 0) { - perror("pipe1"); - return -1; - } - if (pipe(pipefd2) < 0) { - perror("pipe2"); - return -1; - } - - if ((pid = fork()) < 0) { - perror("fork"); - return -1; - } else if (pid > 0) { - /* parent: Linux Endpoint */ - rpmsg_linux_endpoint(); - } else { - /* child: RTOS Endpoint */ - rpmsg_rtos_endpoint(); - } - - return 0; -} diff --git a/mcs/openamp_demo_proc_ptyshell/rpmsg_rtos_endpoint.c b/mcs/openamp_demo_proc_ptyshell/rpmsg_rtos_endpoint.c deleted file mode 100644 index 7094b436..00000000 --- a/mcs/openamp_demo_proc_ptyshell/rpmsg_rtos_endpoint.c +++ /dev/null @@ -1,272 +0,0 @@ -/* RTOS Endpoint run in child process, isolate with parent process */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rpmsg-internal.h" - -static volatile unsigned int rtos_received_data; - -static struct remoteproc *rtos_rproc_init(struct remoteproc *rproc, - struct remoteproc_ops *ops, void *arg) -{ - struct rproc_priv *priv; - unsigned int id = *((unsigned int *)arg); - - priv = metal_allocate_memory(sizeof(*priv)); - if (!priv) - return NULL; - - memset(priv, 0, sizeof(*priv)); - priv->rproc = rproc; - priv->id = id; - priv->rproc->ops = ops; - metal_list_init(&priv->rproc->mems); - priv->rproc->priv = priv; - rproc->state = RPROC_READY; - return priv->rproc; -} - -static void rtos_rproc_remove(struct remoteproc *rproc) -{ - struct rproc_priv *priv; - - priv = (struct rproc_priv *)rproc->priv; - metal_free_memory(priv); -} - -static void *rtos_rproc_mmap(struct remoteproc *rproc, - metal_phys_addr_t *pa, metal_phys_addr_t *da, - size_t size, unsigned int attribute, - struct metal_io_region **io) -{ - struct remoteproc_mem *mem; - struct metal_io_region *tmpio; - - if (*pa == METAL_BAD_PHYS && *da == METAL_BAD_PHYS) - return NULL; - if (*pa == METAL_BAD_PHYS) - *pa = *da; - if (*da == METAL_BAD_PHYS) - *da = *pa; - - mem = metal_allocate_memory(sizeof(*mem)); - if (!mem) - return NULL; - tmpio = metal_allocate_memory(sizeof(*tmpio)); - if (!tmpio) { - metal_free_memory(mem); - return NULL; - } - - /* mmap pa to va */ - int memfd; - void *va; - memfd = open("/dev/mem", O_RDWR); - va = mmap((void*)pa, size, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, *pa); - - remoteproc_init_mem(mem, NULL, *pa, *da, size, tmpio); - metal_io_init(tmpio, va, &mem->pa, size, -1, attribute, NULL); /* metal io manage va and pa */ - remoteproc_add_mem(rproc, mem); - if (io) - *io = tmpio; - - printf("slave mmap pa=0x%lx, da=0x%lx, size=0x%lx, attribute=0x%x va=%p\n", *pa, *da, size, attribute, va); - - return metal_io_phys_to_virt(tmpio, mem->pa); -} - -static int rtos_rproc_notify(struct remoteproc *rproc, uint32_t id) -{ - int ret; - - printf("slave notify start\n"); - - /* notify RTOS Endpoint using IPC */ - ret = write(pipefd2[1], "RTOS: notify ipi\n", strlen("RTOS: notify ipi\n")); - if (ret == -1) - perror("slave write pipefd2[1]"); - - return 0; -} - -static struct remoteproc_ops rtos_rproc_ops = { - .init = rtos_rproc_init, - .remove = rtos_rproc_remove, - .mmap = rtos_rproc_mmap, - .notify = rtos_rproc_notify, -}; - -static unsigned int rtos_receive_message(struct remoteproc *rproc) -{ - char buf[50] = {0}; - int ret; - - /* 1. poll and wait for IPI(IPC) from RTOS Endpoint */ - while (read(pipefd1[0], buf, sizeof(buf)) > 0) { - printf("slave poll:%s", buf); - if (strcmp(buf, "Linux: notify ipi\n") == 0) - break; - } - - /* 2. receive data */ - ret = remoteproc_get_notification(rproc, VRING_TX_NOTIFY_ID); - if (ret) - printf("remoteproc_get_notification failed: 0x%x\n", ret); - return rtos_received_data; -} - -static int rtos_endpoint_cb(struct rpmsg_endpoint *ept, void *data, - size_t len, uint32_t src, void *priv) -{ - rtos_received_data = *((unsigned int *) data); - return RPMSG_SUCCESS; -} - -static void rtos_rpmsg_service_unbind(struct rpmsg_endpoint *ept) -{ - rpmsg_destroy_ept(ept); -} - -static int rtos_send_message(unsigned int message, struct rpmsg_endpoint *ept) -{ - return rpmsg_send(ept, &message, sizeof(message)); -} - -static struct remoteproc *rtos_platform_create_proc(unsigned int id) -{ - struct remoteproc *rproc; - struct remoteproc rproc_inst; - void *va; - void *rsc; - int ret; - metal_phys_addr_t pa = RSC_TABLE_ADDR; - int rsc_size; - - /* Initialize remoteproc instance */ - rproc = remoteproc_init(&rproc_inst, &rtos_rproc_ops, &id); - if (!rproc) - return NULL; - - /* mmap resource table */ - rsc = get_resource_table(&rsc_size); - va = remoteproc_mmap(rproc, &pa, NULL, rsc_size, 0, NULL); - memcpy(va, rsc, rsc_size); - - /* parse resource table to remoteproc */ - ret = remoteproc_set_rsc_table(rproc, va, rsc_size); - if (ret) { - printf("Failed to initialize remoteproc, ret:0x%x\n", ret); - remoteproc_remove(rproc); - return NULL; - } - - //tmp - struct remote_resource_table *va_tmp = va; - struct remote_resource_table *rsc_tmp = rsc; - va_tmp->rpmsg_vdev.notifyid = rsc_tmp->rpmsg_vdev.notifyid; - va_tmp->rpmsg_vdev.vring[0].notifyid = rsc_tmp->rpmsg_vdev.vring[0].notifyid; - va_tmp->rpmsg_vdev.vring[1].notifyid = rsc_tmp->rpmsg_vdev.vring[1].notifyid; - - printf("(1)slave platform_create_proc success\n"); - - return rproc; -} - -static struct rpmsg_device *rtos_platform_create_rpmsg_vdev(struct remoteproc *rproc) -{ - struct rpmsg_virtio_device rpmsg_vdev; - struct virtio_device *vdev; - void *shbuf; - struct metal_io_region *shbuf_io; - int ret; - - shbuf_io = remoteproc_get_io_with_pa(rproc, SHM_START_ADDR); - if (!shbuf_io) - return NULL; - shbuf = metal_io_phys_to_virt(shbuf_io, SHM_START_ADDR); - - printf("(2)slave creating remoteproc virtio\n"); - vdev = remoteproc_create_virtio(rproc, 0, RPMSG_REMOTE, NULL); - if (!vdev) { - printf("failed remoteproc_create_virtio\n"); - return NULL; - } - - printf("(3)slave initializing rpmsg vdev\n"); - /* RPMsg virtio slave can set shared buffers pool argument to NULL */ - ret = rpmsg_init_vdev(&rpmsg_vdev, vdev, NULL, shbuf_io, NULL); - if (ret) { - printf("failed rpmsg_init_vdev\n"); - remoteproc_remove_virtio(rproc, vdev); - return NULL; - } - - //printf("slave vq[0].callback:%p, vq[1].callback:%p\n", vdev->vrings_info[0].vq->callback, vdev->vrings_info[1].vq->callback); - - printf("(4)slave returning rdev\n"); - return rpmsg_virtio_get_rpmsg_device(&rpmsg_vdev); -} - -static void rtos_rpmsg_app_master(struct remoteproc *rproc, struct rpmsg_device *rdev) -{ - int status = 0; - unsigned int message; - struct rpmsg_endpoint ept; - - /* 1.1 slave create endpoint, and send an NS Announcement */ - status = rpmsg_create_ept(&ept, rdev, "k", RPMSG_ADDR_ANY, RPMSG_ADDR_ANY, rtos_endpoint_cb, rtos_rpmsg_service_unbind); - if (status < 0) - printf("slave rpmsg_create_ept failed:%d\n", status); - - printf("1.1 slave rpmsg_create_ept succeed\n"); - printf("1.1 slave Endpoint: name:%s, addr:0x%x, dest_addr:0x%x\n", ept.name, ept.addr, ept.dest_addr); - - while (1) { - /* 3. slave receive message */ - message = rtos_receive_message(rproc); - printf("3. Slave core received a message: %u\n", message); - message++; - printf("3. slave Endpoint: name:%s, addr:0x%x, dest_addr:0x%x\n", ept.name, ept.addr, ept.dest_addr); - - /* 4. slave send message */ - status = rtos_send_message(message, &ept); - if (status < 0) - printf("rtos_send_message(%u) failed with status %d\n", message, status); - printf("4. slave rtos_send_message succeed\n"); - } -} - -int rpmsg_rtos_endpoint() -{ - struct remoteproc *rproc = NULL; - unsigned int id = 1; - struct rpmsg_device *rdev = NULL; - - /* create remoteproc */ - rproc = rtos_platform_create_proc(id); - if (!rproc) { - printf("create rproc failed\n"); - return -1; - } - - rdev = rtos_platform_create_rpmsg_vdev(rproc); - if (!rdev) - printf("slave create rpmsg vdev failed\n"); - - rtos_rpmsg_app_master(rproc, rdev); - //remoteproc_remove(rproc); - - return 0; -} diff --git a/mcs/openamp_demo_proc_rsctbl/Makefile b/mcs/openamp_demo_proc_rsctbl/Makefile deleted file mode 100644 index 5907eef3..00000000 --- a/mcs/openamp_demo_proc_rsctbl/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -rpmsg_main: rpmsg_main.o rpmsg_linux_endpoint.o rpmsg_rtos_endpoint.o - $(CC) rpmsg_main.o rpmsg_linux_endpoint.o rpmsg_rtos_endpoint.o -g $(SDKTARGETSYSROOT)/usr/lib64/libmetal.so $(SDKTARGETSYSROOT)/usr/lib64/libopen_amp.so $(SDKTARGETSYSROOT)/lib64/libsysfs.so -o rpmsg_main - -rpmsg_main.o: rpmsg_main.c rpmsg-internal.h - $(CC) -g -I$(SDKTARGETSYSROOT)/usr/include -c rpmsg_main.c -o rpmsg_main.o - -rpmsg_linux_endpoint.o: rpmsg_linux_endpoint.c rpmsg-internal.h - $(CC) -g -I$(SDKTARGETSYSROOT)/usr/include -c rpmsg_linux_endpoint.c -o rpmsg_linux_endpoint.o - -rpmsg_rtos_endpoint.o: rpmsg_rtos_endpoint.c - $(CC) -g -I$(SDKTARGETSYSROOT)/usr/include -c rpmsg_rtos_endpoint.c -o rpmsg_rtos_endpoint.o - -clean: - rm -rf *.o rpmsg_main diff --git a/mcs/openamp_demo_proc_rsctbl/rpmsg-internal.h b/mcs/openamp_demo_proc_rsctbl/rpmsg-internal.h deleted file mode 100644 index 9caea599..00000000 --- a/mcs/openamp_demo_proc_rsctbl/rpmsg-internal.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef RPMSG_INTERNAL_H_ -#define RPMSG_INTERNAL_H_ - -#include -#include -#include - -#define SHM_START_ADDR 0x70000000 -#define SHM_SIZE 0x30000 - -#define VRING_ADDR_SIZE 0x4000 -#define VRING_RX_ADDRESS (SHM_START_ADDR + SHM_SIZE) -#define VRING_TX_ADDRESS (VRING_RX_ADDRESS + VRING_ADDR_SIZE) -#define RTOS_VRING_RX_ADDRESS VRING_TX_ADDRESS -#define RTOS_VRING_TX_ADDRESS VRING_RX_ADDRESS - -#define VRING_COUNT 2 -#define VRING_ALIGNMENT 4 -#define VRING_SIZE 16 - -#define RSC_TABLE_ADDR 0x71000000 - -#define VDEV_NOTIFY_ID 0 -#define VRING_RX_NOTIFY_ID 1 -#define VRING_TX_NOTIFY_ID 2 - -struct rproc_priv { - struct remoteproc *rproc; - unsigned int id; -}; - -#define NO_RESOURCE_ENTRIES 8 - -/* Resource table for the given remote */ -struct remote_resource_table { - unsigned int version; - unsigned int num; - unsigned int reserved[2]; - unsigned int offset[NO_RESOURCE_ENTRIES]; - - /* 1. rpmsg buffer mem entry */ - struct fw_rsc_carveout rpmsg_mem; - - /* 2. rpmsg vdev entry */ - struct fw_rsc_vdev rpmsg_vdev; - struct fw_rsc_vdev_vring rpmsg_vring0; - struct fw_rsc_vdev_vring rpmsg_vring1; -} __attribute__((__packed__)); - -extern int pipefd[2]; - -void *get_resource_table(int *len); - -#endif diff --git a/mcs/openamp_demo_proc_rsctbl/rpmsg_linux_endpoint.c b/mcs/openamp_demo_proc_rsctbl/rpmsg_linux_endpoint.c deleted file mode 100644 index f4463f93..00000000 --- a/mcs/openamp_demo_proc_rsctbl/rpmsg_linux_endpoint.c +++ /dev/null @@ -1,296 +0,0 @@ -/* Linux Endpoint run in parent process, isolate with child process */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rpmsg-internal.h" - -static volatile unsigned int received_data; -static struct rpmsg_virtio_shm_pool shpool; //tmp, must be global var -static struct rpmsg_endpoint linux_ept; //tmp, must be global var - -static struct remoteproc *rproc_init(struct remoteproc *rproc, - struct remoteproc_ops *ops, void *arg) -{ - struct rproc_priv *priv; - unsigned int id = *((unsigned int *)arg); - - priv = metal_allocate_memory(sizeof(*priv)); - if (!priv) - return NULL; - - memset(priv, 0, sizeof(*priv)); - priv->rproc = rproc; - priv->id = id; - priv->rproc->ops = ops; - metal_list_init(&priv->rproc->mems); - priv->rproc->priv = priv; - rproc->state = RPROC_READY; - return priv->rproc; -} - -static void rproc_remove(struct remoteproc *rproc) -{ - struct rproc_priv *priv; - - priv = (struct rproc_priv *)rproc->priv; - metal_free_memory(priv); -} - -static void *rproc_mmap(struct remoteproc *rproc, - metal_phys_addr_t *pa, metal_phys_addr_t *da, - size_t size, unsigned int attribute, - struct metal_io_region **io) -{ - struct remoteproc_mem *mem; - struct metal_io_region *tmpio; - - if (*pa == METAL_BAD_PHYS && *da == METAL_BAD_PHYS) - return NULL; - if (*pa == METAL_BAD_PHYS) - *pa = *da; - if (*da == METAL_BAD_PHYS) - *da = *pa; - - mem = metal_allocate_memory(sizeof(*mem)); - if (!mem) - return NULL; - tmpio = metal_allocate_memory(sizeof(*tmpio)); - if (!tmpio) { - metal_free_memory(mem); - return NULL; - } - - /* mmap pa to va */ - int memfd; - void *va; - memfd = open("/dev/mem", O_RDWR); - va = mmap((void*)pa, size, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, *pa); - - remoteproc_init_mem(mem, NULL, *pa, *da, size, tmpio); - metal_io_init(tmpio, va, &mem->pa, size, -1, attribute, NULL); /* metal io manage va and pa */ - remoteproc_add_mem(rproc, mem); - if (io) - *io = tmpio; - - printf("master mmap pa=0x%lx, da=0x%lx, size=0x%lx, attribute=0x%x va=%p\n", *pa, *da, size, attribute, va); - - return metal_io_phys_to_virt(tmpio, mem->pa); -} - -//master tmp -static int rproc_notify_tmp(struct remoteproc *rproc, uint32_t id) -{ - return 0; -} - -static int rproc_notify(struct remoteproc *rproc, uint32_t id) -{ - int ret; - - printf("master notify start\n"); - - /* notify RTOS Endpoint using IPC */ - ret = write(pipefd1[1], "Linux: notify ipi\n", strlen("Linux: notify ipi\n")); - if (ret == -1) - perror("master write pipefd1[1]"); - - return 0; -} - -static struct remoteproc_ops rproc_ops = { - .init = rproc_init, - .remove = rproc_remove, - .mmap = rproc_mmap, - .notify = rproc_notify_tmp, //master tmp -}; - -static unsigned int receive_message(struct remoteproc *rproc) -{ - char buf[50] = {0}; - int ret; - - /* 1. poll and wait for IPI(IPC) from RTOS Endpoint */ - while (read(pipefd2[0], buf, sizeof(buf)) > 0) { - printf("master poll:%s", buf); - if (strcmp(buf, "RTOS: notify ipi\n") == 0) - break; - } - - /* 2. receive data */ - ret = remoteproc_get_notification(rproc, VRING_RX_NOTIFY_ID); - if (ret) - printf("remoteproc_get_notification failed: 0x%x\n", ret); - return received_data; -} - -static int endpoint_cb(struct rpmsg_endpoint *ept, void *data, - size_t len, uint32_t src, void *priv) -{ - received_data = *((unsigned int *) data); - return RPMSG_SUCCESS; -} - -static void rpmsg_service_unbind(struct rpmsg_endpoint *ept) -{ - rpmsg_destroy_ept(ept); -} - -static void ns_bind_cb(struct rpmsg_device *rdev, const char *name, uint32_t dest) -{ - (void)rpmsg_create_ept(&linux_ept, rdev, name, - RPMSG_ADDR_ANY, dest, - endpoint_cb, - rpmsg_service_unbind); -} - -static int send_message(unsigned int message, struct rpmsg_endpoint *ept) -{ - return rpmsg_send(ept, &message, sizeof(message)); -} - -static struct remoteproc *platform_create_proc(unsigned int id) -{ - struct remoteproc *rproc; - struct remoteproc rproc_inst; - void *va; - void *rsc; - int ret; - metal_phys_addr_t pa = RSC_TABLE_ADDR; - int rsc_size; - - /* Initialize remoteproc instance */ - rproc = remoteproc_init(&rproc_inst, &rproc_ops, &id); - if (!rproc) - return NULL; - - /* mmap resource table */ - rsc = get_resource_table(&rsc_size); - va = remoteproc_mmap(rproc, &pa, NULL, rsc_size, 0, NULL); - memcpy(va, rsc, rsc_size); - - /* parse resource table to remoteproc */ - ret = remoteproc_set_rsc_table(rproc, va, rsc_size); - if (ret) { - printf("Failed to initialize remoteproc, ret:0x%x\n", ret); - remoteproc_remove(rproc); - return NULL; - } - - //tmp - struct remote_resource_table *va_tmp = va; - struct remote_resource_table *rsc_tmp = rsc; - va_tmp->rpmsg_vdev.notifyid = rsc_tmp->rpmsg_vdev.notifyid; - va_tmp->rpmsg_vdev.vring[0].notifyid = rsc_tmp->rpmsg_vdev.vring[0].notifyid; - va_tmp->rpmsg_vdev.vring[1].notifyid = rsc_tmp->rpmsg_vdev.vring[1].notifyid; - - printf("(1)master platform_create_proc success\n"); - - return rproc; -} - -static struct rpmsg_device *platform_create_rpmsg_vdev(struct remoteproc *rproc) -{ - struct rpmsg_virtio_device rpmsg_vdev; - struct virtio_device *vdev; - void *shbuf; - struct metal_io_region *shbuf_io; - int ret; - - shbuf_io = remoteproc_get_io_with_pa(rproc, SHM_START_ADDR); - if (!shbuf_io) - return NULL; - shbuf = metal_io_phys_to_virt(shbuf_io, SHM_START_ADDR); - - printf("(2)master creating remoteproc virtio\n"); - vdev = remoteproc_create_virtio(rproc, 0, RPMSG_MASTER, NULL); - if (!vdev) { - printf("failed remoteproc_create_virtio\n"); - return NULL; - } - - printf("(3)master initializing rpmsg shared buffer pool\n"); - /* Only RPMsg virtio master needs to initialize the shared buffers pool */ - rpmsg_virtio_init_shm_pool(&shpool, shbuf, SHM_SIZE); - - printf("(4)master initializing rpmsg vdev\n"); - /* RPMsg virtio slave can set shared buffers pool argument to NULL */ - ret = rpmsg_init_vdev(&rpmsg_vdev, vdev, ns_bind_cb, shbuf_io, &shpool); - if (ret) { - printf("failed rpmsg_init_vdev\n"); - remoteproc_remove_virtio(rproc, vdev); - return NULL; - } - - //printf("master vq[0].callback:%p, vq[1].callback:%p\n", vdev->vrings_info[0].vq->callback, vdev->vrings_info[1].vq->callback); - - printf("(5)master returning rdev\n"); - return rpmsg_virtio_get_rpmsg_device(&rpmsg_vdev); -} - -static void rpmsg_app_master(struct remoteproc *rproc) -{ - int status = 0; - unsigned int message = 2; - - //tmp - /* register notify function */ - rproc->ops->notify = rproc_notify; - - /* 1.2 master receive NS Announcement, and process it */ - receive_message(rproc); - - printf("1.2 master receive_message succeed\n"); - printf("1.2 master Endpoint: name:%s, addr:0x%x, dest_addr:0x%x\n", linux_ept.name, linux_ept.addr, linux_ept.dest_addr); - - while (message < 99) { - /* 2. master send message */ - status = send_message(message, &linux_ept); - if (status < 0) - printf("send_message(%u) failed with status %d\n", message, status); - - printf("2. master send_message succeed\n"); - - sleep(1); - /* 5. master receive message */ - message = receive_message(rproc); - printf("5. Master core received a message: %u\n\n", message); - - message++; - sleep(1); - } -} - -int rpmsg_linux_endpoint() -{ - struct remoteproc *rproc = NULL; - unsigned int id = 1; - struct rpmsg_device *rdev = NULL; - - /* create remoteproc */ - rproc = platform_create_proc(id); - if (!rproc) { - printf("create rproc failed\n"); - return -1; - } - - rdev = platform_create_rpmsg_vdev(rproc); - if (!rdev) - printf("master create rpmsg vdev failed\n"); - - rpmsg_app_master(rproc); - //remoteproc_remove(rproc); - - return 0; -} diff --git a/mcs/openamp_demo_proc_rsctbl/rpmsg_main.c b/mcs/openamp_demo_proc_rsctbl/rpmsg_main.c deleted file mode 100644 index 611636ae..00000000 --- a/mcs/openamp_demo_proc_rsctbl/rpmsg_main.c +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include -#include - -#include "rpmsg-internal.h" - -int pipefd1[2]; -int pipefd2[2]; - -/* Place resource table in special ELF section */ -#define __section_t(S) __attribute__((__section__(#S))) -#define __resource __section_t(.resource_table) - -#define NUM_TABLE_ENTRIES 2 -#define DFEATURE_SUPPORT_NS 1 - -struct remote_resource_table __resource resources = { - /* Version */ - RSC_TAB_SUPPORTED_VERSION, - /* NUmber of table entries */ - NUM_TABLE_ENTRIES, - /* reserved fields */ - { 0, 0 }, - /* Offsets of rsc entries */ - { - offsetof(struct remote_resource_table, rpmsg_mem), - offsetof(struct remote_resource_table, rpmsg_vdev), - }, - - /* 1. Rpmsg buffer memory entry */ - { RSC_CARVEOUT, SHM_START_ADDR, SHM_START_ADDR, SHM_SIZE, 0 }, - - /* 2. Virtio device entry */ - { RSC_VDEV, VIRTIO_ID_RPMSG, VDEV_NOTIFY_ID, DFEATURE_SUPPORT_NS, 0, 0, 0, VRING_COUNT, { 0, 0 } }, - /* Vring rsc entry - part of vdev rsc entry */ - { VRING_RX_ADDRESS, VRING_ALIGNMENT, VRING_SIZE, VRING_RX_NOTIFY_ID, 0 }, /* VRING_RX */ - { VRING_TX_ADDRESS, VRING_ALIGNMENT, VRING_SIZE, VRING_TX_NOTIFY_ID, 0 }, /* VRING_TX */ -}; - -void *get_resource_table(int *len) -{ - *len = sizeof(resources); - return &resources; -} - -extern int rpmsg_linux_endpoint(); -extern int rpmsg_rtos_endpoint(); - -int main(int argc, char **argv) -{ - pid_t pid; - - /* Create unamed pipe */ - if (pipe(pipefd1) < 0) { - perror("pipe1"); - return -1; - } - if (pipe(pipefd2) < 0) { - perror("pipe2"); - return -1; - } - - if ((pid = fork()) < 0) { - perror("fork"); - return -1; - } else if (pid > 0) { - /* parent: Linux Endpoint */ - rpmsg_linux_endpoint(); - } else { - /* child: RTOS Endpoint */ - rpmsg_rtos_endpoint(); - } - - return 0; -} diff --git a/mcs/openamp_demo_proc_rsctbl/rpmsg_rtos_endpoint.c b/mcs/openamp_demo_proc_rsctbl/rpmsg_rtos_endpoint.c deleted file mode 100644 index a0ad2872..00000000 --- a/mcs/openamp_demo_proc_rsctbl/rpmsg_rtos_endpoint.c +++ /dev/null @@ -1,277 +0,0 @@ -/* RTOS Endpoint run in child process, isolate with parent process */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rpmsg-internal.h" - -static volatile unsigned int rtos_received_data; - -static struct remoteproc *rtos_rproc_init(struct remoteproc *rproc, - struct remoteproc_ops *ops, void *arg) -{ - struct rproc_priv *priv; - unsigned int id = *((unsigned int *)arg); - - priv = metal_allocate_memory(sizeof(*priv)); - if (!priv) - return NULL; - - memset(priv, 0, sizeof(*priv)); - priv->rproc = rproc; - priv->id = id; - priv->rproc->ops = ops; - metal_list_init(&priv->rproc->mems); - priv->rproc->priv = priv; - rproc->state = RPROC_READY; - return priv->rproc; -} - -static void rtos_rproc_remove(struct remoteproc *rproc) -{ - struct rproc_priv *priv; - - priv = (struct rproc_priv *)rproc->priv; - metal_free_memory(priv); -} - -static void *rtos_rproc_mmap(struct remoteproc *rproc, - metal_phys_addr_t *pa, metal_phys_addr_t *da, - size_t size, unsigned int attribute, - struct metal_io_region **io) -{ - struct remoteproc_mem *mem; - struct metal_io_region *tmpio; - - if (*pa == METAL_BAD_PHYS && *da == METAL_BAD_PHYS) - return NULL; - if (*pa == METAL_BAD_PHYS) - *pa = *da; - if (*da == METAL_BAD_PHYS) - *da = *pa; - - mem = metal_allocate_memory(sizeof(*mem)); - if (!mem) - return NULL; - tmpio = metal_allocate_memory(sizeof(*tmpio)); - if (!tmpio) { - metal_free_memory(mem); - return NULL; - } - - /* mmap pa to va */ - int memfd; - void *va; - memfd = open("/dev/mem", O_RDWR); - va = mmap((void*)pa, size, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, *pa); - - remoteproc_init_mem(mem, NULL, *pa, *da, size, tmpio); - metal_io_init(tmpio, va, &mem->pa, size, -1, attribute, NULL); /* metal io manage va and pa */ - remoteproc_add_mem(rproc, mem); - if (io) - *io = tmpio; - - printf("slave mmap pa=0x%lx, da=0x%lx, size=0x%lx, attribute=0x%x va=%p\n", *pa, *da, size, attribute, va); - - return metal_io_phys_to_virt(tmpio, mem->pa); -} - -static int rtos_rproc_notify(struct remoteproc *rproc, uint32_t id) -{ - int ret; - - printf("slave notify start\n"); - - /* notify RTOS Endpoint using IPC */ - ret = write(pipefd2[1], "RTOS: notify ipi\n", strlen("RTOS: notify ipi\n")); - if (ret == -1) - perror("slave write pipefd2[1]"); - - return 0; -} - -static struct remoteproc_ops rtos_rproc_ops = { - .init = rtos_rproc_init, - .remove = rtos_rproc_remove, - .mmap = rtos_rproc_mmap, - .notify = rtos_rproc_notify, -}; - -static unsigned int rtos_receive_message(struct remoteproc *rproc) -{ - char buf[50] = {0}; - int ret; - - /* 1. poll and wait for IPI(IPC) from RTOS Endpoint */ - while (read(pipefd1[0], buf, sizeof(buf)) > 0) { - printf("slave poll:%s", buf); - if (strcmp(buf, "Linux: notify ipi\n") == 0) - break; - } - - /* 2. receive data */ - ret = remoteproc_get_notification(rproc, VRING_TX_NOTIFY_ID); - if (ret) - printf("remoteproc_get_notification failed: 0x%x\n", ret); - return rtos_received_data; -} - -static int rtos_endpoint_cb(struct rpmsg_endpoint *ept, void *data, - size_t len, uint32_t src, void *priv) -{ - rtos_received_data = *((unsigned int *) data); - return RPMSG_SUCCESS; -} - -static void rtos_rpmsg_service_unbind(struct rpmsg_endpoint *ept) -{ - rpmsg_destroy_ept(ept); -} - -static int rtos_send_message(unsigned int message, struct rpmsg_endpoint *ept) -{ - return rpmsg_send(ept, &message, sizeof(message)); -} - -static struct remoteproc *rtos_platform_create_proc(unsigned int id) -{ - struct remoteproc *rproc; - struct remoteproc rproc_inst; - void *va; - void *rsc; - int ret; - metal_phys_addr_t pa = RSC_TABLE_ADDR; - int rsc_size; - - /* Initialize remoteproc instance */ - rproc = remoteproc_init(&rproc_inst, &rtos_rproc_ops, &id); - if (!rproc) - return NULL; - - /* mmap resource table */ - rsc = get_resource_table(&rsc_size); - va = remoteproc_mmap(rproc, &pa, NULL, rsc_size, 0, NULL); - memcpy(va, rsc, rsc_size); - - /* parse resource table to remoteproc */ - ret = remoteproc_set_rsc_table(rproc, va, rsc_size); - if (ret) { - printf("Failed to initialize remoteproc, ret:0x%x\n", ret); - remoteproc_remove(rproc); - return NULL; - } - - //tmp - struct remote_resource_table *va_tmp = va; - struct remote_resource_table *rsc_tmp = rsc; - va_tmp->rpmsg_vdev.notifyid = rsc_tmp->rpmsg_vdev.notifyid; - va_tmp->rpmsg_vdev.vring[0].notifyid = rsc_tmp->rpmsg_vdev.vring[0].notifyid; - va_tmp->rpmsg_vdev.vring[1].notifyid = rsc_tmp->rpmsg_vdev.vring[1].notifyid; - - printf("(1)slave platform_create_proc success\n"); - - return rproc; -} - -static struct rpmsg_device *rtos_platform_create_rpmsg_vdev(struct remoteproc *rproc) -{ - struct rpmsg_virtio_device rpmsg_vdev; - struct virtio_device *vdev; - void *shbuf; - struct metal_io_region *shbuf_io; - int ret; - - shbuf_io = remoteproc_get_io_with_pa(rproc, SHM_START_ADDR); - if (!shbuf_io) - return NULL; - shbuf = metal_io_phys_to_virt(shbuf_io, SHM_START_ADDR); - - printf("(2)slave creating remoteproc virtio\n"); - vdev = remoteproc_create_virtio(rproc, 0, RPMSG_REMOTE, NULL); - if (!vdev) { - printf("failed remoteproc_create_virtio\n"); - return NULL; - } - - printf("(3)slave initializing rpmsg vdev\n"); - /* RPMsg virtio slave can set shared buffers pool argument to NULL */ - ret = rpmsg_init_vdev(&rpmsg_vdev, vdev, NULL, shbuf_io, NULL); - if (ret) { - printf("failed rpmsg_init_vdev\n"); - remoteproc_remove_virtio(rproc, vdev); - return NULL; - } - - //printf("slave vq[0].callback:%p, vq[1].callback:%p\n", vdev->vrings_info[0].vq->callback, vdev->vrings_info[1].vq->callback); - - printf("(4)slave returning rdev\n"); - return rpmsg_virtio_get_rpmsg_device(&rpmsg_vdev); -} - -static void rtos_rpmsg_app_master(struct remoteproc *rproc, struct rpmsg_device *rdev) -{ - int status = 0; - unsigned int message; - struct rpmsg_endpoint ept; - - /* 1.1 slave create endpoint, and send an NS Announcement */ - status = rpmsg_create_ept(&ept, rdev, "k", RPMSG_ADDR_ANY, RPMSG_ADDR_ANY, rtos_endpoint_cb, rtos_rpmsg_service_unbind); - if (status < 0) - printf("slave rpmsg_create_ept failed:%d\n", status); - - printf("1.1 slave rpmsg_create_ept succeed\n"); - printf("1.1 slave Endpoint: name:%s, addr:0x%x, dest_addr:0x%x\n", ept.name, ept.addr, ept.dest_addr); - - while (message < 99) { - /* 3. slave receive message */ - message = rtos_receive_message(rproc); - printf("3. Slave core received a message: %u\n", message); - message++; - sleep(1); - - printf("3. slave Endpoint: name:%s, addr:0x%x, dest_addr:0x%x\n", ept.name, ept.addr, ept.dest_addr); - - /* 4. slave send message */ - status = rtos_send_message(message, &ept); - if (status < 0) - printf("rtos_send_message(%u) failed with status %d\n", message, status); - - printf("4. slave rtos_send_message succeed\n"); - - sleep(1); - } -} - -int rpmsg_rtos_endpoint() -{ - struct remoteproc *rproc = NULL; - unsigned int id = 1; - struct rpmsg_device *rdev = NULL; - - /* create remoteproc */ - rproc = rtos_platform_create_proc(id); - if (!rproc) { - printf("create rproc failed\n"); - return -1; - } - - rdev = rtos_platform_create_rpmsg_vdev(rproc); - if (!rdev) - printf("slave create rpmsg vdev failed\n"); - - rtos_rpmsg_app_master(rproc, rdev); - //remoteproc_remove(rproc); - - return 0; -} diff --git a/mcs/rpmsg_pty_demo/rpmsg_main.c b/mcs/rpmsg_pty_demo/rpmsg_main.c deleted file mode 100644 index 74fa2f49..00000000 --- a/mcs/rpmsg_pty_demo/rpmsg_main.c +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include -#include -#include "rpmsg_pty.h" -#include "openamp_module.h" - -char *cpu_id; -char *target_binfile; -char *target_binaddr; - -static void cleanup(int sig) -{ - openamp_deinit(); - pthread_mutex_destroy(&mutex); - exit(0); -} - -int rpmsg_app_master(void) -{ - pthread_t tida, tidb, tidc; - - printf("Multi-thread processing user requests...\n"); - - /* init mutex as thread lock */ - pthread_mutex_init(&mutex, NULL); - - /* userA, zephyr shell, open with screen */ - if (pthread_create(&tida, NULL, shell_user, NULL) < 0) { - perror("userA pthread_create"); - return -1; - } - pthread_detach(tida); - - /* userB, zephyr shell, open with screen */ - if (pthread_create(&tidb, NULL, shell_user, NULL) < 0) { - perror("userB pthread_create"); - return -1; - } - pthread_detach(tidb); - - while (1); - - return 0; -} - -int main(int argc, char **argv) -{ - int ret; - int opt; - - /* ctrl+c signal, do cleanup before program exit */ - signal(SIGINT, cleanup); - - while ((opt = getopt(argc, argv, "c:t:a:")) != -1) { - switch (opt) { - case 'c': - cpu_id = optarg; - break; - case 't': - target_binfile = optarg; - break; - case 'a': - target_binaddr = optarg; - break; - default: - break; - } - } - - ret = openamp_init(); - if (ret) { - printf("openamp init failed: %d\n", ret); - openamp_deinit(); - return ret; - } - - ret = rpmsg_app_master(); - if (ret) { - printf("rpmsg app master failed: %d\n", ret); - openamp_deinit(); - return ret; - } - - openamp_deinit(); - - return 0; -} diff --git a/mcs/rpmsg_pty_demo/rpmsg_pty.c b/mcs/rpmsg_pty_demo/rpmsg_pty.c deleted file mode 100644 index f95b80c5..00000000 --- a/mcs/rpmsg_pty_demo/rpmsg_pty.c +++ /dev/null @@ -1,153 +0,0 @@ -#define _XOPEN_SOURCE 600 -#include -#include -#include -#include -#include -#include -#include -#include "openamp_module.h" - -/* define the keys according to your terminfo */ -#define KEY_CTRL_D 4 -#define FILE_MODE 0644 -#define PTSNAME_LEN 20 - -pthread_mutex_t mutex; - -void open_pty(int *pfdm, int *pfds, const char *pty_name) -{ - int ret; - int fdm, fds; - char pts_name[PTSNAME_LEN] = {0}; - - /* Open the master side of the PTY */ - fdm = posix_openpt(O_RDWR | O_NOCTTY); - if (fdm < 0) - printf("Error %d on posix_openpt()\n", errno); - - ret = grantpt(fdm); - if (ret != 0) - printf("Error %d on grantpt()\n", errno); - - ret = unlockpt(fdm); - if (ret != 0) - printf("Error %d on unlockpt()\n", errno); - - /* Open the slave side of the PTY */ - ret = ptsname_r(fdm, pts_name, sizeof(pts_name)); - if (ret != 0) - printf("Error %d on ptsname_r()\n", errno); - - fds = open(pts_name, O_RDWR | O_NOCTTY); - if (ret != 0) - printf("Error %d on open()\n", errno); - - printf("open a new terminal, zephyr %s: screen %s\n", pty_name, pts_name); - - *pfdm = fdm; - *pfds = fds; -} - -void *shell_user(void *arg) -{ - int ret; - int fdm, fds; - unsigned char cmd[1]; - unsigned char reply[2048]; - int reply_len; - - open_pty(&fdm, &fds, "shell"); - - while (1) { - ret = read(fdm, cmd, 1); /* get command from ptmx */ - if (ret < 0) { - printf("shell_user: get from ptmx failed: %d\n", ret); - return (void*)-1; - } - - if (cmd[0] == KEY_CTRL_D) { /* special key: ctrl+d */ - close(fds); - close(fdm); - return (void*)0; /* exit this thread, the same as pthread_exit */ - } - - pthread_mutex_lock(&mutex); - - ret = send_message(cmd, 1); /* send command to rtos */ - usleep(100 * 1000); /* wait 100ms, some messages may be seperated */ - ret |= receive_message(reply, sizeof(reply), &reply_len); /* receive reply from rtos */ - - pthread_mutex_unlock(&mutex); - - if (ret < 0) { - printf("shell_user: send(%s)/receive(%s) message failed: %d\n", cmd, reply, ret); - return (void*)-1; - } - - ret = write(fdm, reply, reply_len); /* send reply to ptmx */ - if (ret < 0) { - printf("shell_user: write to ptmx(%s) failed: %d\n", reply, ret); - return (void*)-1; - } - } - - return (void*)0; -} - -void *console_user(void *arg) -{ - int ret; - int fdm, fds; - unsigned char reply[2048]; - int reply_len; - - /* open PTY, pts binds to terminal, using screen to open pts */ - open_pty(&fdm, &fds, "console"); - - while (1) { - ret = receive_message(reply, sizeof(reply), &reply_len); /* receive reply from rtos */ - if (ret < 0) { - printf("shell_user: receive_message failed: %d\n", ret); - return (void*)-1; - } - - ret = write(fdm, reply, reply_len); /* send reply to ptmx */ - if (ret < 0) { - printf("shell_user: write to ptmx(%s) failed: %d\n", reply, ret); - return (void*)-1; - } - } - - return (void*)0; -} - -void *log_user(void *arg) -{ - int ret; - int log_fd; - unsigned char log[2048] = {0}; - int log_len; - const char *log_file = "/tmp/zephyr_log.txt"; - - ret = receive_message(log, sizeof(log), &log_len); /* receive log from rtos */ - if (ret < 0) { - printf("log_user: receive_message(%s) failed: %d\n", log, ret); - return (void*)-1; - } - - /* write log into file */ - log_fd = open(log_file, O_RDWR | O_CREAT | O_APPEND, FILE_MODE); - if (log_fd < 0) { - printf("log_user: open (%s) failed: %d\n", log_file, log_fd); - return (void*)-1; - } - ret = write(log_fd, log, log_len); - if (ret < 0) { - printf("log_user: write to file(%s) failed: %d\n", log_file, ret); - return (void*)-1; - } - close(log_fd); - - return (void*)0; -} diff --git a/mcs/rpmsg_pty_demo/rpmsg_pty.h b/mcs/rpmsg_pty_demo/rpmsg_pty.h deleted file mode 100644 index 3668849d..00000000 --- a/mcs/rpmsg_pty_demo/rpmsg_pty.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef RPMSG_PTY_H -#define RPMSG_PTY_H - -void *shell_user(void *arg); -void *console_user(void *arg); -void *log_user(void *arg); - -extern pthread_mutex_t mutex; - -#endif \ No newline at end of file diff --git a/mcs/rpmsg_pty_demo/zephyr_qemu.bin b/mcs/rpmsg_pty_demo/zephyr_qemu.bin deleted file mode 100644 index ebf342c54a341d7e2cec636e321e07725ea3c368..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 167456 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 JcxPn#zX6A$83q6V diff --git a/mcs/rpmsg_pty_demo/zephyr_rpi.bin b/mcs/rpmsg_pty_demo/zephyr_rpi.bin deleted file mode 100644 index 57d2c401ce021aa9230ca319000d312c1c829603..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 179752 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