diff --git a/mcs/CMakeLists.txt b/mcs/CMakeLists.txt index a23538dad6ef624a7496a0c0dcc0467ecbf6b972..bce56863132822dd926a0471a928b1f228f47fd4 100644 --- a/mcs/CMakeLists.txt +++ b/mcs/CMakeLists.txt @@ -3,6 +3,7 @@ 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}") diff --git a/mcs/README.md b/mcs/README.md index 128cbc22731fa3d024350c278897834f143645fa..c8feee30ab2d81a1e1af2837beb6670a074114d6 100644 --- a/mcs/README.md +++ b/mcs/README.md @@ -6,11 +6,15 @@ #### 软件架构 -kernel_cpu_handler: 提供OpenAMP所需内核模块,支持Client OS启动、专用中断收发等功能。 +mcs_km: 提供OpenAMP所需内核模块,支持Client OS启动、专用中断收发、管理保留内存等功能。 openamp_demo: 提供OpenAMP用户态程序Linux端样例,支持与指定Client OS进行通信。 -zephyr: 提供样例zephyr.bin镜像文件,该文件需要被加载至0x7a000000的起始地址,并在0x7a000ffc的地址进行启动。启动后会运行OpenAMP Client端的样例程序,并与Linux端进行交互。 +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端进行交互。 #### 原理简介 @@ -26,20 +30,20 @@ OpenAMP包括如下三大重要组件: -remoteproc:该组件用于主机上实现对远程处理器及相关软件环境的生命周期管理、及virtio和rpmsg设备的注册等。 -样例Demo通过提供cpu_handler_dev内核KO模块实现Linux内核启动从核的功能,并预留了OpenAMP通信所需的专用中断及其收发机制。用户可在用户态通过dev设备实现Client OS的启动,并通过rpmsg组件实现与Client OS的简单通信。 +样例Demo通过提供mcs_km内核KO模块实现Linux内核启动从核的功能,并预留了OpenAMP通信所需的专用中断及其收发机制。用户可在用户态通过dev设备实现Client OS的启动,并通过rpmsg组件实现与Client OS的简单通信。 #### 安装教程 1. 根据openEuler Embedded使用手册安装SDK并设置SDK环境变量。 -2. 编译内核模块cpu_handler_dev.ko,编译方式如下: +2. 编译内核模块mcs_km.ko,编译方式如下: ```` - cd kernel_cpu_handler + cd mcs_km make ```` -3. 编译用户态程序rpmsg_main,编译方式如下: +3. 编译openamp_demo用户态程序rpmsg_main,编译方式如下: ```` cmake -S . -B build -DDEMO_TARGET=openamp_demo @@ -48,14 +52,15 @@ OpenAMP包括如下三大重要组件: ```` 注意:此处定义OpenAMP通信设备共享内存起始地址为0x70000000,可根据实际内存分配进行修改。 +如果需要查看调试日志,可以给cmake增加-DDEBUG参数。 -4. 将编译好的KO模块、用户态程序,以及zephyr.bin镜像拷贝到openEuler Embedded系统的目录下。如何拷贝可以参考使用手册中共享文件系统场景。 +4. 将编译好的KO模块、用户态程序,以及zephyr_qemu.bin镜像拷贝到openEuler Embedded系统的目录下。如何拷贝可以参考使用手册中共享文件系统场景。 -5. 将OpenAMP的依赖库libmetal.so*,libopen_amp.so*,libsysfs.so*拷贝至文件系统/lib64目录。对应so可在sdk目录中找到,如何拷贝可以参考使用手册中共享文件系统场景。 +5. 将OpenAMP的依赖库libmetal.so*,libopen_amp.so*拷贝至文件系统/usr/lib64目录,libsysfs.so* 拷贝至文件系统/lib64目录。对应so可在sdk目录中找到,如何拷贝可以参考使用手册中共享文件系统场景。 #### 使用说明 -1. 通过QEMU启动openEuler Embedded镜像,如何启动可参考使用手册中QEMU使用与调试章节。 +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。 @@ -64,32 +69,86 @@ OpenAMP包括如下三大重要组件: 可参考如下命令进行启动: ```` - qemu-system-aarch64 -M virt,gic-version=3 -m 1G -cpu cortex-a57 -nographic -kernel zImage -initrd initrd -append 'mem=768M maxcpus=3' -smp 4 + 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模块cpu_handler_dev.ko。 +2. 在openEuler Embedded系统上插入内核KO模块mcs_km.ko。 ```` - insmod cpu_handler_dev.ko + insmod mcs_km.ko ```` 3. 运行rpmsg_main程序,使用方式如下: ```` - ./rpmsg_main -c [cpu_id] -b [boot_address] -t [target_binfile] -a [target_binaddress] + ./rpmsg_main -c [cpu_id] -t [target_binfile] -a [target_binaddress] eg: - ./rpmsg_main -c 3 -b 0x7a000ffc -t /tmp/zephyr.bin -a 0x7a000000 + ./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实现细节,接口定义在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); ```` -此处定义Client OS起始地址为0x7a000000,启动地址为0x7a000ffc,Client OS镜像路径为/tmp/zephyr.bin。 +#### 串口服务样例 +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 +```` -#### 用户开发 -参考demo实现流程,当前提供了多个API,包含在libopenamp.a中,供用户使用和二次开发,用户无需感知openamp实现细节。 +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 +```` -1. 调用openamp_init,初始化remoteproc、virtio、rpmsg,Linux端与Client OS建立配对的endpoint,供消息收发使用。 +树莓派可以通过设置printk在console上的打印优先级屏蔽内核打印。 +```` + cat /proc/sys/kernel/printk > /tmp/printk_bak + echo 1 4 1 7 > /proc/sys/kernel/printk +```` -2. 调用receive_message、send_message收发消息。 +3. 运行rpmsg_main程序时,把程序放在后台,然后通过screen打开shell。 +```` + ./rpmsg_main -c 3 -t zephyr_qemu.bin -a 0x7a000000 & + screen /dev/pts/0 +```` -3. 调用openamp_deinit,释放openamp资源。 \ No newline at end of file +4. 进入shell,输入help可以查看Client OS支持哪些命令,输入history可以查看历史命令,ctrl+d退出。 +```` + uart:~$ help + uart:~$ history +```` \ No newline at end of file diff --git a/mcs/dev_mcsmem/Makefile b/mcs/dev_mcsmem/Makefile deleted file mode 100644 index fe080afb1a590c8295b34e4ae271673f561fe754..0000000000000000000000000000000000000000 --- a/mcs/dev_mcsmem/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -KERNELDIR := ${KERNEL_SRC_DIR} -CURRENT_PATH := $(shell pwd) - -target := dev_mcsmem -obj-m := $(target).o - -build := kernel_modules - -kernel_modules: - $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules -clean: - $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean diff --git a/mcs/kernel_cpu_handler/Makefile b/mcs/kernel_cpu_handler/Makefile deleted file mode 100644 index 28b371086e6ff72f6131608d38bcf713be750859..0000000000000000000000000000000000000000 --- a/mcs/kernel_cpu_handler/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -KERNELDIR := ${KERNEL_SRC_DIR} -CURRENT_PATH := $(shell pwd) - -target := cpu_handler_dev -obj-m := $(target).o - -build := kernel_modules - -kernel_modules: - $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules -clean: - $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean diff --git a/mcs/kernel_cpu_handler/cpu_handler_dev.c b/mcs/kernel_cpu_handler/cpu_handler_dev.c deleted file mode 100644 index a646851a22aa386ef101dcff62acb226a27f63af..0000000000000000000000000000000000000000 --- a/mcs/kernel_cpu_handler/cpu_handler_dev.c +++ /dev/null @@ -1,211 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define CPU_HANDLER_DEVICE "cpu_handler" -#define CPU_ON_FUNCID 0xC4000003 -#define IRQ_SENDTO_CLIENTOS _IOW('A', 0, int) -#define OPENAMP_INIT_TRIGGER 0x0 -#define OPENAMP_CLIENTOS_TRIGGER 0x1 -#define OPENAMP_IRQ 8 - -static DEFINE_MUTEX(cpu_handler_mutex); -static struct class *cpu_handler_class; -static int cpu_handler_major; -static int cpu_state; - -static ssize_t dev_cpuhandler_write(struct file *file, const char __user *buf, - size_t datalen, loff_t *ppos) -{ - ssize_t result = -EINVAL; - int cpu_id; - phys_addr_t cpu_boot_addr; - char *data = NULL, *startp = NULL, *endp = NULL; - struct arm_smccc_res res; - - mutex_lock(&cpu_handler_mutex); - - if (cpu_state == 1) { - pr_info("cpu_handler: clientos os already boot\n"); - goto out; - } - - data = memdup_user_nul(buf, datalen); - if (!data) { - pr_err("cpu_handler: invalid input data\n"); - goto out; - } - - startp = data; - cpu_id = simple_strtol(startp, &endp, 0); - if (*endp != '@') { - pr_err("cpu_handler: invalid boot cpu format, str = %s\n", data); - goto out; - } - startp = endp + 1; - -#ifdef CONFIG_PHYS_ADDR_T_64BIT - cpu_boot_addr = simple_strtoull(startp, &endp, 0); -#else - cpu_boot_addr = simple_strtoul(startp, &endp, 0); -#endif - - if (startp == endp) { - pr_err("cpu_handler: invalid boot cpu format, str = %s\n", data); - goto out; - } - - if (cpu_state == 0) { - pr_info("cpu_handler: start booting clientos os on cpu(%d)\n", cpu_id); - arm_smccc_hvc(CPU_ON_FUNCID, cpu_id, cpu_boot_addr, 0, 0, 0, 0, 0, &res); - cpu_state = 1; - result = datalen; - } -out: - mutex_unlock(&cpu_handler_mutex); - return result; -} - -static DECLARE_WAIT_QUEUE_HEAD(openamp_trigger_wait); - -static int openamp_trigger; - -static irqreturn_t handle_clientos_ipi(int irq, void *data) -{ - pr_info("cpu_handler: received ipi from client os\n"); - openamp_trigger = OPENAMP_CLIENTOS_TRIGGER; - wake_up_interruptible(&openamp_trigger_wait); - return IRQ_HANDLED; -} - -static struct irq_desc *openamp_ipi_desc; - -void set_openamp_ipi(void) -{ - int err; - - err = request_percpu_irq(OPENAMP_IRQ, handle_clientos_ipi, "IPI", &cpu_number); - if (err) { - pr_err("cpu_handler: request openamp irq failed(%d)\n", err); - return; - } - - openamp_ipi_desc = irq_to_desc(OPENAMP_IRQ); - if (!openamp_ipi_desc) { - pr_err("cpu_handler: generate openamp irq descriptor failed\n"); - return; - } - - enable_percpu_irq(OPENAMP_IRQ, 0); - - return; -} - -static void send_clientos_ipi(const struct cpumask *target) -{ - ipi_send_mask(OPENAMP_IRQ, target); -} - -static ssize_t dev_cpuhandler_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) -{ - ssize_t len; - char res[32]; - - len = scnprintf(res, sizeof(res), "%d\n", cpu_state); - return simple_read_from_buffer(buf, count, ppos, res, len); -} - -static unsigned int dev_cpuhandler_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 dev_cpuhandler_ioctl(struct file *f, unsigned int cmd, unsigned long arg) -{ - int cpu_id = (int)arg; - switch (cmd) { - case IRQ_SENDTO_CLIENTOS: - pr_info("cpu_handler: received ioctl cmd to send ipi to cpu(%d)\n", cpu_id); - send_clientos_ipi(cpumask_of(cpu_id)); - return 0; - default: - return -EINVAL; - } -} - -static const struct file_operations dev_cpuhandler_fops = { - .read = dev_cpuhandler_read, - .write = dev_cpuhandler_write, - .poll = dev_cpuhandler_poll, - .unlocked_ioctl = dev_cpuhandler_ioctl, - .llseek = generic_file_llseek, -}; - -static __init int cpu_handler_dev_init(void) -{ - struct device *class_dev = NULL; - int ret = 0; - - cpu_handler_major = register_chrdev(0, CPU_HANDLER_DEVICE, &dev_cpuhandler_fops); - if (cpu_handler_major < 0) { - pr_err("cpu_handler: unable to get major %d for memory devs.\n", cpu_handler_major); - return -1; - } - - cpu_handler_class = class_create(THIS_MODULE, CPU_HANDLER_DEVICE); - if (IS_ERR(cpu_handler_class)) { - ret = PTR_ERR(cpu_handler_class); - goto error_class_create; - } - - class_dev = device_create(cpu_handler_class, NULL, MKDEV((unsigned int)cpu_handler_major, 1), - NULL, CPU_HANDLER_DEVICE); - if (unlikely(IS_ERR(class_dev))) { - ret = PTR_ERR(class_dev); - goto error_device_create; - } - - set_openamp_ipi(); - pr_info("cpu_handler: create major %d for cpu handler devs\n", cpu_handler_major); - return 0; - -error_device_create: - class_destroy(cpu_handler_class); -error_class_create: - unregister_chrdev(cpu_handler_major, CPU_HANDLER_DEVICE); - return ret; -} -module_init(cpu_handler_dev_init); - -static void __exit cpu_handler_dev_exit(void) -{ - device_destroy(cpu_handler_class, MKDEV((unsigned int)cpu_handler_major, 1)); - class_destroy(cpu_handler_class); - unregister_chrdev(cpu_handler_major, CPU_HANDLER_DEVICE); -} -module_exit(cpu_handler_dev_exit); - -MODULE_AUTHOR("OpenEuler Embedded"); -MODULE_DESCRIPTION("cpu_handler device"); -MODULE_LICENSE("Dual BSD/GPL"); diff --git a/mcs/mcs_km/Makefile b/mcs/mcs_km/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f9b3396cc9c7b44214201342c5f9e41320350e52 --- /dev/null +++ b/mcs/mcs_km/Makefile @@ -0,0 +1,6 @@ +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/dev_mcsmem/dev_mcsmem.c b/mcs/mcs_km/mcs_km.c similarity index 35% rename from mcs/dev_mcsmem/dev_mcsmem.c rename to mcs/mcs_km/mcs_km.c index e3204b1f28aed22a466ba2593a1962359e9ac48b..de1dd1607a1aa7e675a42b7ed2c797c62096d965 100644 --- a/mcs/dev_mcsmem/dev_mcsmem.c +++ b/mcs/mcs_km/mcs_km.c @@ -1,54 +1,139 @@ -/* - * A lite version of linux/drivers/char/mem.c - * Test with MMU for arm64 mcs functions - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include - +#include #include #include #include -#define DEVMEM_MINOR 1 +#define MCS_DEVICE_NAME "mcs" +#define CPU_ON_FUNCID 0xC4000003 + +#define MAGIC_NUMBER 'A' +#define IOC_SENDIPI _IOW(MAGIC_NUMBER, 0, int) +#define IOC_CPUON _IOW(MAGIC_NUMBER, 1, 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 +#define SIZE_INDEX 2 + +static struct class *mcs_class; +static int mcs_major; +static int cpu_state; + static u64 valid_start; static u64 valid_end; +static const char *smccc_method; -static ssize_t read_mem(struct file *file, char __user *buf, - size_t count, loff_t *ppos) +static DECLARE_WAIT_QUEUE_HEAD(openamp_trigger_wait); +static int openamp_trigger; + +static irqreturn_t handle_clientos_ipi(int irq, void *data) { - return -ENOSYS; + pr_info("mcs_km: received ipi from client os\n"); + openamp_trigger = OPENAMP_CLIENTOS_TRIGGER; + wake_up_interruptible(&openamp_trigger_wait); + return IRQ_HANDLED; } -static ssize_t write_mem(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) +void set_openamp_ipi(void) { - return -ENOSYS; + int err; + + 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; + } + + 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 ssize_t mcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +{ + ssize_t len; + char res[32]; + + len = scnprintf(res, sizeof(res), "%d\n", cpu_state); + return simple_read_from_buffer(buf, count, ppos, res, len); +} + +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)); + return 0; + case IOC_CPUON: + cpu_id = *(unsigned int*)arg; + cpu_boot_addr = *((unsigned int*)arg + 1); + + if (cpu_state == 1) { + pr_info("mcs_km: clientos already boot on cpu(%d)\n", cpu_id); + return 0; + } + + if (smccc_method == NULL) + smccc_method = "hvc"; + + if (cpu_state == 0) { + 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); + cpu_state = 1; + } + return 0; + default: + return -EINVAL; + } } #ifdef CONFIG_STRICT_DEVMEM @@ -105,7 +190,8 @@ static const struct vm_operations_struct mmap_mem_ops = { #endif }; -static int mmap_mem(struct file *file, struct vm_area_struct *vma) +/* 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; @@ -139,67 +225,22 @@ static int mmap_mem(struct file *file, struct vm_area_struct *vma) return 0; } -static loff_t memory_lseek(struct file *file, loff_t offset, int orig) -{ - return -ENOSYS; -} - -static int open_port(struct inode *inode, struct file *filp) +static int mcs_open(struct inode *inode, struct file *filp) { if (!capable(CAP_SYS_RAWIO)) return -EPERM; return 0; } -#define open_mem open_port -static const struct file_operations __maybe_unused mem_fops = { - .llseek = memory_lseek, - .read = read_mem, - .write = write_mem, - .mmap = mmap_mem, - .open = open_mem, -}; - -static const struct memdev { - const char *name; - umode_t mode; - const struct file_operations *fops; - fmode_t fmode; -} devlist[] = { - [DEVMEM_MINOR] = { "mcsmem", 0, &mem_fops, FMODE_UNSIGNED_OFFSET }, +static const struct file_operations mcs_fops = { + .open = mcs_open, + .mmap = mcs_mmap, + .read = mcs_read, + .poll = mcs_poll, + .unlocked_ioctl = mcs_ioctl, + .llseek = generic_file_llseek, }; -static int memory_open(struct inode *inode, struct file *filp) -{ - int minor; - const struct memdev *dev; - - minor = iminor(inode); - if (minor >= ARRAY_SIZE(devlist)) - return -ENXIO; - - dev = &devlist[minor]; - if (!dev->fops) - return -ENXIO; - - filp->f_op = dev->fops; - filp->f_mode |= dev->fmode; - - if (dev->fops->open) - return dev->fops->open(inode, filp); - - return 0; -} - -static const struct file_operations memory_fops = { - .open = memory_open, - .llseek = noop_llseek, -}; - -static struct class *mem_class; - -int mcsmem_major; - static int get_mcs_node_info(void) { int ret = 0; @@ -207,15 +248,15 @@ static int get_mcs_node_info(void) u8 datasize; u32 *val = NULL; - nd = of_find_node_by_path("/reserved-memory/mcs@70000000"); - if(nd == NULL) { - printk("invalid reserved-memory mcs node.\n"); + 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) { - printk("invalid reserved-memory mcs reg size.\n"); + pr_err("invalid reserved-memory mcs reg size.\n"); return -EINVAL; } @@ -230,36 +271,72 @@ static int get_mcs_node_info(void) 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 mcsmem_dev_init(void) +static int __init mcs_dev_init(void) { - int minor = 1; + 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) - printk("cat't get mcsmem dts node info. Allow page isn't ram mmap.\n"); + pr_info("there's no mcsmem dts node info. Allow page isn't ram mmap.\n"); else - printk("valid mcsmem node decated.\n"); + pr_info("valid mcsmem node detected.\n"); - mcsmem_major = register_chrdev(0, "mcsmem", &memory_fops); - if (mcsmem_major < 0) { - printk("unable to get major %d for memory devs\n", mcsmem_major); - return -1; - } + pr_info("mcs_km: create major %d for mcs dev.\n", mcs_major); + return 0; - mem_class = class_create(THIS_MODULE, "mcsmem"); - if (IS_ERR(mem_class)) - return PTR_ERR(mem_class); +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) +{ + preempt_disable(); + disable_percpu_irq(OPENAMP_IRQ); + preempt_enable(); + free_percpu_irq(OPENAMP_IRQ, &cpu_number); - device_create(mem_class, NULL, MKDEV((unsigned int)mcsmem_major, minor), - NULL, devlist[minor].name); + device_destroy(mcs_class, MKDEV((unsigned int)mcs_major, 1)); + class_destroy(mcs_class); + unregister_chrdev(mcs_major, MCS_DEVICE_NAME); - return 0; + pr_info("mcs_km: remove mcs dev.\n"); } +module_exit(mcs_dev_exit); -module_init(mcsmem_dev_init); -MODULE_DESCRIPTION("dev_mcsmem"); -MODULE_LICENSE("GPL v2"); +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 index 20ce22aed37c380b63a954c540ec8af14132e1fd..be788c19aa9f8f28bbb15be53a9417d00bec94ca 100644 --- a/mcs/modules/openamp_module.c +++ b/mcs/modules/openamp_module.c @@ -1,37 +1,56 @@ #include #include "openamp_module.h" -#define MAX_BIN_BUFLEN (10 * 1024 * 1024) +#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 load_bin(void) +static int memfd; +static void *binaddr; +static int binsize; +void *shmaddr; + +static int reserved_mem_init(void) { - int memfd = open("/dev/mem", O_RDWR); - int bin_fd = open(target_binfile, O_RDONLY); - void *access_address = NULL, *bin_buffer = NULL; - long bin_size; - long long int bin_addr = strtoll(target_binaddr, NULL, 0); - - if (bin_fd < 0 || memfd < 0) { - printf("invalid bin file fd\n"); - exit(-1); + 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; } - bin_buffer = (void *)malloc(MAX_BIN_BUFLEN); - if (!bin_buffer) { - printf("malloc bin_buffer failed\n"); - exit(-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; } - bin_size = read(bin_fd, bin_buffer, MAX_BIN_BUFLEN); - if (bin_size == 0) { - printf("read bin file failed\n"); - exit(-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; } - access_address = mmap((void *)bin_addr, MAX_BIN_BUFLEN, PROT_READ | PROT_WRITE, - MAP_SHARED, memfd, bin_addr); - memcpy(access_address, bin_buffer, bin_size); - free(bin_buffer); + /* load clientos */ + file_addr = mmap(NULL, binsize, PROT_READ, MAP_PRIVATE, binfd, 0); + memcpy(binaddr, file_addr, binsize); + return 0; } @@ -42,25 +61,25 @@ int openamp_init(void) unsigned char message[100]; int len; + 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 = load_bin(); - if (ret) { - printf("failed to load client os\n"); - return ret; - } - ret = remoteproc_start(rproc); if (ret) { printf("start processor failed\n"); return ret; } - sleep(5); /* wait for zephyr booting */ + sleep(5); /* wait for clientos booting */ virtio_init(); (void)receive_message(message, sizeof(message), &len); /* name service: endpoint matching */ @@ -68,14 +87,17 @@ int openamp_init(void) return 0; } -int openamp_deinit(void) +void openamp_deinit(void) { printf("\nOpenAMP demo ended.\n"); - if (io) - free(io); - remoteproc_stop(&rproc_inst); - rproc_inst.state = RPROC_OFFLINE; - remoteproc_remove(&rproc_inst); - return 0; + virtio_deinit(); + destory_remoteproc(); + + if (shmaddr) + munmap(shmaddr, VDEV_SIZE); + if (binaddr) + munmap(binaddr, binsize); + if (memfd) + close(memfd); } diff --git a/mcs/modules/openamp_module.h b/mcs/modules/openamp_module.h index 69abb2c93fdd6ebc397d0aacb0bd1e131e502479..90261620e30788c071b34fdffa99f3cf59409703 100644 --- a/mcs/modules/openamp_module.h +++ b/mcs/modules/openamp_module.h @@ -13,7 +13,7 @@ extern char *target_binaddr; int openamp_init(void); /* release openamp resource */ -int openamp_deinit(void); +void openamp_deinit(void); /* message standard receive interface */ int receive_message(unsigned char *message, int message_len, int *real_len); diff --git a/mcs/modules/remoteproc_module.c b/mcs/modules/remoteproc_module.c index f6efca0bec4944d2df53540c9d2b67a96c2aea94..7cb1f65e5d27bcba92e0a15cbcc321d18aba9d7a 100644 --- a/mcs/modules/remoteproc_module.c +++ b/mcs/modules/remoteproc_module.c @@ -1,9 +1,13 @@ #include #include #include +#include #include "remoteproc_module.h" -#define BOOTCMD_MAXSIZE 100 +#define MCS_DEVICE_NAME "/dev/mcs" +#define IOC_CPUON _IOW('A', 1, int) +#define STR_TO_HEX 16 +#define STR_TO_DEC 10 struct rproc_priv { struct remoteproc *rproc; /* pass a remoteproc instance pointer */ @@ -12,7 +16,7 @@ struct rproc_priv { unsigned int boot_address; /* related arg: boot address(in hex format) */ }; -struct remoteproc rproc_inst; +static struct remoteproc rproc_inst; static struct remoteproc *rproc_init(struct remoteproc *rproc, const struct remoteproc_ops *ops, void *args) @@ -42,30 +46,31 @@ static void rproc_remove(struct remoteproc *rproc) static int rproc_start(struct remoteproc *rproc) { - int cpu_handler_fd; int ret; - char on[BOOTCMD_MAXSIZE]; + unsigned int boot_args[2]; struct rproc_priv *args = (struct rproc_priv *)rproc->priv; - (void)snprintf(on, sizeof(on), "%d%s%d", args->cpu_id, "@", args->boot_address); + int fd = open(MCS_DEVICE_NAME, O_RDWR); + if (fd < 0) { + printf("failed to open %s device.\n", MCS_DEVICE_NAME); + return fd; + } - cpu_handler_fd = open(DEV_CLIENT_OS_AGENT, O_RDWR); - if (cpu_handler_fd < 0) { - printf("failed to open %s\n", DEV_CLIENT_OS_AGENT); - return cpu_handler_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; } - ret = write(cpu_handler_fd, on, sizeof(on)); + close(fd); return 0; } static int rproc_stop(struct remoteproc *rproc) { -#if 0 - /* send message to zephyr, zephyr shut itself down by PSCI */ - int ret = send_message("shutdown\r\n", 10); - sleep(3); -#endif + /* TODO: send message to clientos, clientos shut itself down by PSCI */ return 0; } @@ -83,11 +88,19 @@ struct remoteproc *create_remoteproc(void) args.rproc = &rproc_inst; args.idx = 1; - args.cpu_id = strtol(cpu_id, NULL, 10); - args.boot_address = strtol(boot_address, NULL, 16); + 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); +} diff --git a/mcs/modules/remoteproc_module.h b/mcs/modules/remoteproc_module.h index 7a54f471d7a11276856fd54d35293b7eb26075e9..7b1378bad81d0cdfeffc72657577bb3e274d084b 100644 --- a/mcs/modules/remoteproc_module.h +++ b/mcs/modules/remoteproc_module.h @@ -3,8 +3,6 @@ #include -#define DEV_CLIENT_OS_AGENT "/dev/cpu_handler" - /* create remoteproc */ struct remoteproc *create_remoteproc(void); @@ -23,8 +21,10 @@ struct remoteproc *create_remoteproc(void); int remoteproc_remove(struct remoteproc *rproc); */ +/* destory remoteproc */ +void destory_remoteproc(void); + extern char *cpu_id; -extern char *boot_address; -extern struct remoteproc rproc_inst; +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 index a97c34bb4625c261ddf3330f07761a1fac5de38d..56ffb52fb36434d3b6221c6ada6fdc0fe007d3c7 100644 --- a/mcs/modules/rpmsg_module.c +++ b/mcs/modules/rpmsg_module.c @@ -4,6 +4,8 @@ #include "virtio_module.h" #include "rpmsg_module.h" +#define MCS_DEVICE_NAME "/dev/mcs" + static unsigned char received_data[2048] = {0}; static unsigned int received_len = 0; struct rpmsg_endpoint ept_inst; @@ -37,9 +39,9 @@ int receive_message(unsigned char *message, int message_len, int *real_len) int cpu_handler_fd; struct pollfd fds; - cpu_handler_fd = open(DEV_CLIENT_OS_AGENT, O_RDWR); + cpu_handler_fd = open(MCS_DEVICE_NAME, O_RDWR); if (cpu_handler_fd < 0) { - printf("receive_message: open %s failed.\n", DEV_CLIENT_OS_AGENT); + printf("receive_message: open %s device failed.\n", MCS_DEVICE_NAME); return cpu_handler_fd; } @@ -51,6 +53,9 @@ int receive_message(unsigned char *message, int message_len, int *real_len) received_len = 0; while (1) { +#ifdef DEBUG + printf("master waiting for message....\n"); +#endif ret = poll(&fds, 1, 100); /* 100ms timeout */ if (ret < 0) { printf("receive_message: poll failed.\n"); @@ -59,10 +64,16 @@ int receive_message(unsigned char *message, int message_len, int *real_len) } if (ret == 0) { +#ifdef DEBUG + printf("master waiting for message timeout....\n"); +#endif break; } if (fds.revents & POLLIN) { +#ifdef DEBUG + printf("master receiving message....\n"); +#endif virtqueue_notification(vq[0]); /* will call endpoint_cb */ } } diff --git a/mcs/modules/rpmsg_module.h b/mcs/modules/rpmsg_module.h index cb700df2c41d9b8ce4344154eaaed7f4e2c3178e..9cba4780b2833785904ab83c7fccea2e9809b38b 100644 --- a/mcs/modules/rpmsg_module.h +++ b/mcs/modules/rpmsg_module.h @@ -3,8 +3,6 @@ #include -#define DEV_CLIENT_OS_AGENT "/dev/cpu_handler" - /* callback of ns */ void ns_bind_cb(struct rpmsg_device *rdev, const char *name, uint32_t dest); diff --git a/mcs/modules/virtio_module.c b/mcs/modules/virtio_module.c index 418aaedbbe8a8a9abdc101731e32e5e7adf6af95..892bd04689adb737b8e08cb46264b6f02b19419c 100644 --- a/mcs/modules/virtio_module.c +++ b/mcs/modules/virtio_module.c @@ -5,6 +5,10 @@ #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, @@ -14,12 +18,10 @@ static struct virtio_vring_info rvrings[2] = { }, }; -static int g_memfd; static struct virtio_device vdev; static struct rpmsg_virtio_device rvdev; -struct metal_io_region *io; +static struct metal_io_region *io; struct virtqueue *vq[2]; -static void *tx_addr, *rx_addr, *shm_start_addr; static metal_phys_addr_t shm_physmap[] = { SHM_START_ADDR }; static unsigned char virtio_get_status(struct virtio_device *vdev) @@ -29,9 +31,7 @@ static unsigned char virtio_get_status(struct virtio_device *vdev) static void virtio_set_status(struct virtio_device *vdev, unsigned char status) { - void *stat_addr = NULL; - stat_addr = mmap((void *)VDEV_STATUS_ADDR, VDEV_STATUS_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, g_memfd, VDEV_STATUS_ADDR); - *(volatile unsigned int *)stat_addr = (unsigned int)status; + *(volatile unsigned int *)VDEVADDR(shmaddr) = (unsigned int)status; } static uint32_t virtio_get_features(struct virtio_device *vdev) @@ -44,15 +44,14 @@ static void virtio_notify(struct virtqueue *vq) (void)vq; int cpu_handler_fd; int ret; - int cpu_num = strtol(cpu_id, NULL, 0); - cpu_handler_fd = open(DEV_CLIENT_OS_AGENT, O_RDWR); + cpu_handler_fd = open(MCS_DEVICE_NAME, O_RDWR); if (cpu_handler_fd < 0) { - printf("open %s failed\n", DEV_CLIENT_OS_AGENT); + printf("open %s device failed\n", MCS_DEVICE_NAME); return; } - ret = ioctl(cpu_handler_fd, IRQ_SENDTO_CLIENTOS, cpu_num); + ret = ioctl(cpu_handler_fd, IOC_SENDIPI, strtol(cpu_id, NULL, STR_TO_DEC)); if (ret) { printf("send ipi tp second os failed\n"); } @@ -76,17 +75,12 @@ void virtio_init(void) printf("\nInitialize the virtio, virtqueue and rpmsg device\n"); - g_memfd = open("/dev/mem", O_RDWR); - tx_addr = mmap((void *)VRING_TX_ADDRESS, VDEV_STATUS_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, g_memfd, VRING_TX_ADDRESS); - rx_addr = mmap((void *)VRING_RX_ADDRESS, VDEV_STATUS_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, g_memfd, VRING_RX_ADDRESS); - shm_start_addr = mmap((void *)SHM_START_ADDR, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, g_memfd, SHM_START_ADDR); - io = malloc(sizeof(struct metal_io_region)); if (!io) { printf("malloc io failed\n"); return; } - metal_io_init(io, shm_start_addr, shm_physmap, SHM_SIZE, -1, 0, NULL); + metal_io_init(io, SHMEMADDR(shmaddr), shm_physmap, SHM_SIZE, -1, 0, NULL); /* setup vdev */ vq[0] = virtqueue_allocate(VRING_SIZE); @@ -106,13 +100,13 @@ void virtio_init(void) vdev.vrings_num = VRING_COUNT; vdev.func = &dispatch; rvrings[0].io = io; - rvrings[0].info.vaddr = tx_addr; + 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 = rx_addr; + rvrings[1].info.vaddr = RXADDR(shmaddr); rvrings[1].info.num_descs = VRING_SIZE; rvrings[1].info.align = VRING_ALIGNMENT; rvrings[1].vq = vq[1]; @@ -120,7 +114,7 @@ void virtio_init(void) vdev.vrings_info = &rvrings[0]; /* setup rvdev */ - rpmsg_virtio_init_shm_pool(&shpool, shm_start_addr, SHM_SIZE); + 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); @@ -128,3 +122,14 @@ void virtio_init(void) return; } } + +void virtio_deinit(void) +{ + if (io) + free(io); + if (vq[0]) + virtqueue_free(vq[0]); + if (vq[1]) + virtqueue_free(vq[1]); + rpmsg_deinit_vdev(&rvdev); +} diff --git a/mcs/modules/virtio_module.h b/mcs/modules/virtio_module.h index 8914534436ac242731c2e22664f7801cb36adb98..c73cdcb3ff978c5d770ebfed9989a27af5c041b4 100644 --- a/mcs/modules/virtio_module.h +++ b/mcs/modules/virtio_module.h @@ -19,13 +19,16 @@ #define VRING_ALIGNMENT 4 #define VRING_SIZE 16 -#define IRQ_SENDTO_CLIENTOS _IOW('A', 0, int) -#define DEV_CLIENT_OS_AGENT "/dev/cpu_handler" +#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 metal_io_region *io; extern struct virtqueue *vq[2]; +extern void *shmaddr; #endif \ No newline at end of file diff --git a/mcs/openamp_demo/rpmsg_main.c b/mcs/openamp_demo/rpmsg_main.c index cd467e42f51447ea72f1dc6f1ceb0ef7c9996cc1..443894046e1ae4156152d0da2a88de0ec710caed 100644 --- a/mcs/openamp_demo/rpmsg_main.c +++ b/mcs/openamp_demo/rpmsg_main.c @@ -3,13 +3,14 @@ #include "openamp_module.h" char *cpu_id; -char *boot_address; char *target_binfile; char *target_binaddr; int rpmsg_app_master(void) { int ret; + int message = 0; + int len; printf("start processing OpenAMP demo...\n"); @@ -39,14 +40,11 @@ int main(int argc, char **argv) int ret; int opt; - while ((opt = getopt(argc, argv, "c:b:t:a:")) != -1) { + while ((opt = getopt(argc, argv, "c:t:a:")) != -1) { switch (opt) { case 'c': cpu_id = optarg; break; - case 'b': - boot_address = optarg; - break; case 't': target_binfile = optarg; break; @@ -61,20 +59,18 @@ int main(int argc, char **argv) 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; } - ret = openamp_deinit(); - if (ret) { - printf("openamp deinit failed: %d\n", ret); - return ret; - } + openamp_deinit(); return 0; } diff --git a/mcs/openamp_demo/zephyr.bin b/mcs/openamp_demo/zephyr_qemu.bin similarity index 100% rename from mcs/openamp_demo/zephyr.bin rename to mcs/openamp_demo/zephyr_qemu.bin diff --git a/mcs/openamp_demo/zephyr_rpi.bin b/mcs/openamp_demo/zephyr_rpi.bin new file mode 100644 index 0000000000000000000000000000000000000000..5240ed73c05a25fdb5c07a30c220c7ac3748e8f6 Binary files /dev/null and b/mcs/openamp_demo/zephyr_rpi.bin differ diff --git a/mcs/rpmsg_pty_demo/rpmsg_main.c b/mcs/rpmsg_pty_demo/rpmsg_main.c index 3bf642ed830df31d8fdad99bec765ae65b009b61..0e63e859f57ffc1a93869eb68004829fdd5ebfc7 100644 --- a/mcs/rpmsg_pty_demo/rpmsg_main.c +++ b/mcs/rpmsg_pty_demo/rpmsg_main.c @@ -5,7 +5,6 @@ #include "openamp_module.h" char *cpu_id; -char *boot_address; char *target_binfile; char *target_binaddr; @@ -41,14 +40,11 @@ int main(int argc, char **argv) int ret; int opt; - while ((opt = getopt(argc, argv, "c:b:t:a:")) != -1) { + while ((opt = getopt(argc, argv, "c:t:a:")) != -1) { switch (opt) { case 'c': cpu_id = optarg; break; - case 'b': - boot_address = optarg; - break; case 't': target_binfile = optarg; break; @@ -63,20 +59,18 @@ int main(int argc, char **argv) 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; } - ret = openamp_deinit(); - if (ret) { - printf("openamp deinit failed: %d\n", ret); - return ret; - } + openamp_deinit(); return 0; } diff --git a/mcs/rpmsg_pty_demo/rpmsg_pty.c b/mcs/rpmsg_pty_demo/rpmsg_pty.c index 900e634276c7e0cb3dc07a890bd0e4b1a1ef032c..c7a21c58bdfda9e44bf2136f3be7515fff32c33d 100644 --- a/mcs/rpmsg_pty_demo/rpmsg_pty.c +++ b/mcs/rpmsg_pty_demo/rpmsg_pty.c @@ -10,6 +10,7 @@ /* define the keys according to your terminfo */ #define KEY_CTRL_D 4 +#define FILE_MODE 0644 pthread_mutex_t mutex; @@ -126,7 +127,7 @@ void *log_user(void *arg) } /* write log into file */ - log_fd = open(log_file, O_RDWR | O_CREAT | O_APPEND, 0644); + 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; diff --git a/mcs/rpmsg_pty_demo/zephyr.bin b/mcs/rpmsg_pty_demo/zephyr_qemu.bin similarity index 100% rename from mcs/rpmsg_pty_demo/zephyr.bin rename to mcs/rpmsg_pty_demo/zephyr_qemu.bin diff --git a/mcs/rpmsg_pty_demo/zephyr_rpi.bin b/mcs/rpmsg_pty_demo/zephyr_rpi.bin new file mode 100644 index 0000000000000000000000000000000000000000..981f9b4fe71377a2c6d642b181fd40da449a40b7 Binary files /dev/null and b/mcs/rpmsg_pty_demo/zephyr_rpi.bin differ