From 3d80bc21bb520fcf9e15b89d1e3d56018c937412 Mon Sep 17 00:00:00 2001 From: zjwang Date: Wed, 21 Aug 2024 15:40:17 +0800 Subject: [PATCH 1/2] shmem support --- arch/arm64/core/virtualization/trap_handler.c | 1 + auto_zvm.sh | 2 +- include/virtualization/vdev/shmem.h | 2 +- include/virtualization/vdev/shmem_rw.h | 43 ++++ samples/_zvm/boards/qemu_cortex_max_smp.conf | 2 + .../_zvm/boards/qemu_cortex_max_smp.overlay | 17 +- samples/_zvm/boards/roc_rk3568_pc_smp.conf | 3 +- samples/_zvm/boards/roc_rk3568_pc_smp.overlay | 11 + soc/arm64/rockchip/rk3568/mmu_regions.c | 5 + subsys/virtualization/CMakeLists.txt | 1 + subsys/virtualization/linuxdev.c | 91 ++++++++ subsys/virtualization/vdev/CMakeLists.txt | 11 +- subsys/virtualization/vdev/Kconfig | 16 +- subsys/virtualization/vdev/shmem.c | 38 +-- subsys/virtualization/vdev/shmem_rw.c | 219 ++++++++++++++++++ subsys/virtualization/vdev/virt_pci.c | 1 - subsys/virtualization/vm_device.c | 13 +- 17 files changed, 448 insertions(+), 28 deletions(-) create mode 100644 include/virtualization/vdev/shmem_rw.h create mode 100644 subsys/virtualization/linuxdev.c create mode 100644 subsys/virtualization/vdev/shmem_rw.c diff --git a/arch/arm64/core/virtualization/trap_handler.c b/arch/arm64/core/virtualization/trap_handler.c index f64cb8f50..65734bc95 100644 --- a/arch/arm64/core/virtualization/trap_handler.c +++ b/arch/arm64/core/virtualization/trap_handler.c @@ -14,6 +14,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(ZVM_MODULE_NAME); diff --git a/auto_zvm.sh b/auto_zvm.sh index 16a8cc52f..e2529739c 100755 --- a/auto_zvm.sh +++ b/auto_zvm.sh @@ -66,7 +66,7 @@ elif [ "$OPS" = "${ops_array[1]}" ]; then -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/zephyr.bin,addr=0xc8000000,force-raw=on \ -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/Image,addr=0xf0000000,force-raw=on \ -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/Image,addr=0xd8000000,force-raw=on \ - -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/linux-qemu-virt.dtb,addr=0xd0000000 \ + -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/linux-qemu-virtio.dtb,addr=0xd0000000 \ -kernel $(pwd)/build/zephyr/zvm_host.elf ### using gdb to connect it: # gdb-multiarch -q -ex 'file ./build/zephyr/zvm_host.elf' -ex 'target remote localhost:1234' diff --git a/include/virtualization/vdev/shmem.h b/include/virtualization/vdev/shmem.h index 9fa698215..68c430841 100644 --- a/include/virtualization/vdev/shmem.h +++ b/include/virtualization/vdev/shmem.h @@ -34,7 +34,7 @@ struct mem_vdevice { /** * @brief init vm mem device for the vm. */ -int vm_shmem_create(struct vm *vm); +int vm_mem_create(struct vm *vm); int memory_read(struct virt_dev *vdev, uint64_t addr, uint64_t *value); int memory_write(struct virt_dev *vdev, uint64_t addr, uint64_t *value); diff --git a/include/virtualization/vdev/shmem_rw.h b/include/virtualization/vdev/shmem_rw.h new file mode 100644 index 000000000..e17c82cdd --- /dev/null +++ b/include/virtualization/vdev/shmem_rw.h @@ -0,0 +1,43 @@ +/* + * Copyright 2023 HNU-ESNL + * Copyright 2023 openEuler SIG-Zephyr + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ZVM_VDEV_SHMEMRW_H_ +#define ZEPHYR_INCLUDE_ZVM_VDEV_SHMEMRW_H_ + +#include +#include +#include +#include +#include + +/** + * @brief shared memory devive config. + */ +struct shared_mem_rw_config +{ + uint64_t base; + uint64_t size; + // uint32_t hirq_num; +}; + +/** + * @brief virt memory device + */ +struct mem_rw_vdevice { + uint64_t mem_base; + uint64_t mem_size; +}; + +/** + * @brief init vm mem device for the vm. + */ +int vm_mem_rw_create(struct vm *vm); +int memory_rw_read(struct virt_dev *vdev, uint64_t addr, uint64_t *value); +int memory_rw_write(struct virt_dev *vdev, uint64_t addr, uint64_t *value); + + +#endif diff --git a/samples/_zvm/boards/qemu_cortex_max_smp.conf b/samples/_zvm/boards/qemu_cortex_max_smp.conf index 480796957..98d9e91c4 100644 --- a/samples/_zvm/boards/qemu_cortex_max_smp.conf +++ b/samples/_zvm/boards/qemu_cortex_max_smp.conf @@ -34,7 +34,9 @@ CONFIG_ZVM_LINUX_MAX_XLAT_TABLES=10240 CONFIG_VM_VIRTIO_MMIO=y CONFIG_VM_VIRTIO_BLOCK=y CONFIG_VM_SHMEM=y +CONFIG_VM_SHMEMRW=y CONFIG_MEM_INIT_PRIORITY=59 +CONFIG_MEMRW_INIT_PRIORITY=60 # enable pci bus support CONFIG_VM_PCI_BUS_CONTROLLER=y diff --git a/samples/_zvm/boards/qemu_cortex_max_smp.overlay b/samples/_zvm/boards/qemu_cortex_max_smp.overlay index 920395639..e742a0cc1 100644 --- a/samples/_zvm/boards/qemu_cortex_max_smp.overlay +++ b/samples/_zvm/boards/qemu_cortex_max_smp.overlay @@ -8,11 +8,12 @@ aliases { vmvirtio1 = "/soc/virtio_mmio@a000000"; vmvirtio2 = "/soc/virtio_mmio@a001000"; - vmvirtmem = "/soc/virtmem@c0000000"; linuxcpy = "/soc/linux_cpy@d8000000"; /*Passthrough device.*/ ptdevice1 = "/soc/pass_through_device/uart@9001000"; ptdevice2 = "/soc/pass_through_device/uart@9002000"; + vmvirtmem = "/soc/virtmem@bf000000"; + vmshmemrw = "/soc/shmem_rw@bd000000"; }; chosen { @@ -38,14 +39,24 @@ virtio_type = <2>; }; - virtmem@c0000000 { + virtmem@bf000000 { compatible = "arm,mem"; device_type = "memory"; - reg = <0x00 0xc0000000 0x00 0x1000>; + reg = <0x00 0xbf000000 0x00 0x1000>; + interrupts = ; label = "VM_SHMEM"; status = "okay"; }; + shmem_rw@bd000000 { + compatible = "shmem,rw"; + device_type = "memory"; + reg = <0x0 0xbd000000 0x0 0x10>; + interrupts = ; + label = "VM_SHMEMRW"; + status = "okay"; + }; + linux_cpy@d8000000 { reg = <0x0 0xd8000000 0x0 DT_SIZE_M(240)>; }; diff --git a/samples/_zvm/boards/roc_rk3568_pc_smp.conf b/samples/_zvm/boards/roc_rk3568_pc_smp.conf index 88254dbeb..d5c8bd5d2 100644 --- a/samples/_zvm/boards/roc_rk3568_pc_smp.conf +++ b/samples/_zvm/boards/roc_rk3568_pc_smp.conf @@ -32,6 +32,7 @@ CONFIG_ZVM_LINUX_MAX_XLAT_TABLES=10240 # CONFIG_VM_PCI_BUS_INIT_PRIORITY=68 CONFIG_VM_SHMEM=y +CONFIG_VM_SHMEMRW=y CONFIG_MEM_INIT_PRIORITY=59 - +CONFIG_MEMRW_INIT_PRIORITY=60 diff --git a/samples/_zvm/boards/roc_rk3568_pc_smp.overlay b/samples/_zvm/boards/roc_rk3568_pc_smp.overlay index 29870c276..585b495d0 100644 --- a/samples/_zvm/boards/roc_rk3568_pc_smp.overlay +++ b/samples/_zvm/boards/roc_rk3568_pc_smp.overlay @@ -18,6 +18,7 @@ ptdevice9 = "/soc/pass_through_device/serial@fe6c0000"; linuxdebugger = "/soc/fiq-debugger"; vmvirtmem = "/soc/virtmem@bf000000"; + vmshmemrw = "/soc/shmem_rw@bd000000"; }; chosen { @@ -149,10 +150,20 @@ compatible = "arm,mem"; device_type = "memory"; reg = <0x0 0xbf000000 0x0 0x1000>; + interrupts = ; label = "VM_SHMEM"; status = "okay"; }; + shmem_rw@bd000000 { + compatible = "shmem,rw"; + device_type = "memory"; + reg = <0x0 0xbd000000 0x0 0x1000>; + interrupts = ; + label = "VM_SHMEMRW"; + status = "okay"; + }; + }; /*TODO: The device that used by vm will be added below. */ diff --git a/soc/arm64/rockchip/rk3568/mmu_regions.c b/soc/arm64/rockchip/rk3568/mmu_regions.c index 5054501d4..a776a3449 100644 --- a/soc/arm64/rockchip/rk3568/mmu_regions.c +++ b/soc/arm64/rockchip/rk3568/mmu_regions.c @@ -51,6 +51,11 @@ static const struct arm_mmu_region mmu_regions[] = { DT_REG_ADDR(DT_ALIAS(vmvirtmem)), DT_REG_SIZE(DT_ALIAS(vmvirtmem)), MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE), + + MMU_REGION_FLAT_ENTRY("SHMEMRW", + DT_REG_ADDR(DT_ALIAS(vmshmemrw)), + DT_REG_SIZE(DT_ALIAS(vmshmemrw)), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE), #endif }; diff --git a/subsys/virtualization/CMakeLists.txt b/subsys/virtualization/CMakeLists.txt index a07afb625..bf3164dd0 100644 --- a/subsys/virtualization/CMakeLists.txt +++ b/subsys/virtualization/CMakeLists.txt @@ -16,4 +16,5 @@ zephyr_sources_ifdef( vm.c zvm_shell.c zvm.c + # linuxdev.c ) diff --git a/subsys/virtualization/linuxdev.c b/subsys/virtualization/linuxdev.c new file mode 100644 index 000000000..63fd8669d --- /dev/null +++ b/subsys/virtualization/linuxdev.c @@ -0,0 +1,91 @@ +/* + * Copyright 2023 HNU-ESNL + * Copyright 2023 openEuler SIG-Zephyr + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(ZVM_MODULE_NAME); + +#define DEV_CFG(dev) \ + ((const struct virt_device_config * const)(dev)->config) +#define DEV_DATA(dev) \ + ((struct virt_device_data *)(dev)->data) + +/** + * @brief init vm serial device for the vm. Including: + * 1. Allocating virt device to vm, and build map. + * 2. Setting the device's irq for binding virt interrupt with hardware interrupt. +*/ +static int vm_serial_init(const struct device *dev, struct vm *vm, struct virt_dev *vdev_desc) +{ + return 0; +} + +/** + * @brief set the callback function for serial which will be called + * when virt device is bind to vm. +*/ +static void virt_serial_irq_callback_set(const struct device *dev, + void *cb, void *user_data) +{ + /* Binding to the user's callback function and get the user data. */ + DEV_DATA(dev)->irq_cb = cb; + DEV_DATA(dev)->irq_cb_data = user_data; +} + +static const struct uart_driver_api serial_driver_api; + +static const struct virt_device_api virt_serial_api = { + .init_fn = vm_serial_init, + .device_driver_api = &serial_driver_api, +}; + +/** + * @brief The init function of serial, what will not init + * the hardware device, but get the device config for + * zvm system. +*/ +static int serial_init(const struct device *dev) +{ + dev->state->init_res = VM_DEVICE_INIT_RES; + ZVM_LOG_INFO("** Ready to init dev name is: %s. \n", dev->name); + return 0; +} + + +static struct virt_device_data virt_serial2_data_port = { + .device_data = NULL, +}; + +static struct virt_device_config virt_serial2_cfg = { + .reg_base = DT_REG_ADDR(DT_ALIAS(linuxdev)), + .reg_size = DT_REG_SIZE(DT_ALIAS(linuxdev)), + .hirq_num = DT_IRQN(DT_ALIAS(linuxdev)), + .device_config = NULL, +}; + +/** + * @brief Define the serial2 description for zvm. +*/ +DEVICE_DT_DEFINE(DT_ALIAS(linuxdev), + &serial_init, + NULL, + &virt_serial2_data_port, + &virt_serial2_cfg, POST_KERNEL, + CONFIG_SERIAL_INIT_PRIORITY, + &virt_serial_api); + diff --git a/subsys/virtualization/vdev/CMakeLists.txt b/subsys/virtualization/vdev/CMakeLists.txt index 0b58aa601..bce0188b6 100644 --- a/subsys/virtualization/vdev/CMakeLists.txt +++ b/subsys/virtualization/vdev/CMakeLists.txt @@ -5,7 +5,6 @@ zephyr_sources_ifdef( CONFIG_ZVM vgic_common.c vgic_v3.c - shmem.c ) # board specific configuration @@ -43,3 +42,13 @@ zephyr_sources_ifdef( CONFIG_VM_SYSCON_CONTROLLER virt_syscon.c ) + +zephyr_sources_ifdef( + CONFIG_VM_SHMEM + shmem.c +) + +zephyr_sources_ifdef( + CONFIG_VM_SHMEMRW + shmem_rw.c +) diff --git a/subsys/virtualization/vdev/Kconfig b/subsys/virtualization/vdev/Kconfig index bc234d076..7c627478a 100644 --- a/subsys/virtualization/vdev/Kconfig +++ b/subsys/virtualization/vdev/Kconfig @@ -138,7 +138,6 @@ endif config VM_SHMEM bool "VM MEM that get from vm." - default y help This option is used for building memory that get from overlay. @@ -151,3 +150,18 @@ config MEM_INIT_PRIORITY When virtmem is init, it judge the initialization priority in POST_KERNLE. endif + +config VM_SHMEMRW + bool "VM MEMRW that get from vm." + help + This option is used for building memory that get from overlay. + +if VM_SHMEMRW + +config MEMRW_INIT_PRIORITY + int "VM virt memrw init priority." + default 60 + help + When virtmem is init, it judge the initialization priority in POST_KERNLE. + +endif diff --git a/subsys/virtualization/vdev/shmem.c b/subsys/virtualization/vdev/shmem.c index 69280f207..55a1e97d5 100644 --- a/subsys/virtualization/vdev/shmem.c +++ b/subsys/virtualization/vdev/shmem.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -21,11 +22,21 @@ LOG_MODULE_DECLARE(ZVM_MODULE_NAME); +#define SHMEM_ADDR DT_REG_ADDR(DT_ALIAS(vmvirtmem)) +#define SHMEM_SIZE DT_REG_SIZE(DT_ALIAS(vmvirtmem)) + +#define SHMEM_VIRQ (DT_IRQN(DT_ALIAS(vmvirtmem)) + VM_LOCAL_VIRQ_NR) + #define DEV_CFG(dev) ((const struct virt_device_config *const)(dev)->config) #define DEV_DATA(dev) ((struct virt_device_data *)(dev)->data) -#define ZEPHYR_SHMEM_ADDR 0x20000000 -#define LINUX_SHMEM_ADDR 0x80000000 + +typedef struct shared_memory { + int sender; // sender ID + int receiver; // receiver ID + int length; // len of data + char *shm_value; // data +} SHMEM; static struct virtual_device_instance *mem_instance; @@ -38,7 +49,7 @@ static int vm_virt_mem_init(const struct device *dev, struct vm *vm, struct virt struct mem_vdevice *mem; struct zvm_dev_lists* vdev_list; struct _dnode *d_node, *ds_node; - struct virt_dev *vm_dev; + struct virt_dev *vm_dev, *chosen_dev = NULL; char *dev_name = "VM_SHMEM"; mem = (struct mem_vdevice *)k_malloc(sizeof(struct mem_vdevice)); if (!mem) { @@ -53,6 +64,7 @@ static int vm_virt_mem_init(const struct device *dev, struct vm *vm, struct virt ZVM_LOG_ERR("Allocate memory for mem_instance error \n"); return -ENODEV; } + mem_instance->data = DEV_DATA(dev); mem_instance->cfg = DEV_CFG(dev); mem_instance->api = dev->api; @@ -76,19 +88,14 @@ static int vm_virt_mem_init(const struct device *dev, struct vm *vm, struct virt DT_REG_ADDR(DT_ALIAS(vmvirtmem)), DT_REG_ADDR(DT_ALIAS(vmvirtmem)), vm_dev->vm_vdev_size, - VM_DEVICE_INVALID_VIRQ, VM_DEVICE_INVALID_VIRQ); + VM_DEVICE_INVALID_VIRQ, SHMEM_VIRQ - 32); if(!vdev){ ZVM_LOG_WARN("Init virt virt_mem device error\n"); return -ENODEV; } vdev->priv_data = mem_instance; vdev->priv_vdev = dev; - ; - if(vm->os->type == 1){ - sys_dlist_remove(&vdev->vdev_node); - sys_dlist_append(&vdev_list->dev_used_list, &vdev->vdev_node); - } - + vm_device_irq_init(vm, vdev); ZVM_LOG_INFO("** Add %s device to vm successful. \n", dev->name); return 0; @@ -101,12 +108,14 @@ static int vm_virt_mem_init(const struct device *dev, struct vm *vm, struct virt */ int memory_read(struct virt_dev *vdev, uint64_t addr, uint64_t *value) { + uint64_t *hva; uint64_t read_value; read_value = sys_read64(vdev->vm_vdev_paddr); - ZVM_LOG_INFO("vm_vdev_paddr: 0x%x, read_value: 0x%llx\n", vdev->vm_vdev_paddr, read_value); + printk("vm_vdev_paddr: 0x%x, read_value: 0x%x\n", vdev->vm_vdev_paddr, read_value); *(uint64_t *)value = read_value; return read_value; + } /** @@ -114,11 +123,6 @@ int memory_read(struct virt_dev *vdev, uint64_t addr, uint64_t *value) */ int memory_write(struct virt_dev *vdev, uint64_t addr, uint64_t *value) { - uint64_t value_w = *(uint64_t *)value; - - ZVM_LOG_INFO("vm_vdev_paddr: 0x%x, value: 0x%llx\n", vdev->vm_vdev_paddr, value_w); - sys_write64(value_w, vdev->vm_vdev_paddr); - return 0; } @@ -134,7 +138,7 @@ static int mem_init(const struct device *dev) return 0; } -int vm_shmem_create(struct vm *vm) +int vm_mem_create(struct vm *vm) { int ret = 0; const struct device *dev = DEVICE_DT_GET(DT_ALIAS(vmvirtmem)); diff --git a/subsys/virtualization/vdev/shmem_rw.c b/subsys/virtualization/vdev/shmem_rw.c new file mode 100644 index 000000000..b32854b0d --- /dev/null +++ b/subsys/virtualization/vdev/shmem_rw.c @@ -0,0 +1,219 @@ +/* + * Copyright 2023 HNU-ESNL + * Copyright 2023 openEuler SIG-Zephyr + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(ZVM_MODULE_NAME); + +#define SHMEM_VIRQ (DT_IRQN(DT_ALIAS(vmvirtmem)) + VM_LOCAL_VIRQ_NR) + +#define DEV_CFG(dev) ((const struct virt_device_config *const)(dev)->config) +#define DEV_DATA(dev) ((struct virt_device_data *)(dev)->data) + + +typedef struct shared_memory { + int sender; // sender ID + int receiver; // receiver ID + int length; // len of data + char *shm_value; // data +} SHMEM; + +static struct virtual_device_instance *mem_instance; + + +/** + * @brief Initialize virtual device's memory +*/ +static int vm_virt_mem_rw_init(const struct device *dev, struct vm *vm, struct virt_dev *vdev_desc) +{ + struct virt_dev *vdev; + struct mem_rw_vdevice *mem; + struct zvm_dev_lists* vdev_list; + struct _dnode *d_node, *ds_node; + struct virt_dev *vm_dev, *chosen_dev = NULL; + char *dev_name = "VM_SHMEMRW"; + mem = (struct mem_rw_vdevice *)k_malloc(sizeof(struct mem_rw_vdevice)); + if (!mem) { + ZVM_LOG_ERR("Allocate memory for mem error \n"); + return -ENODEV; + } + mem->mem_base = DT_REG_ADDR(DT_ALIAS(vmshmemrw)); + mem->mem_size = DT_REG_SIZE(DT_ALIAS(vmshmemrw)); + + mem_instance = (struct virtual_device_instance *)k_malloc(sizeof(struct virtual_device_instance)); + if(mem_instance == NULL){ + ZVM_LOG_ERR("Allocate memory for mem_instance error \n"); + return -ENODEV; + } + + mem_instance->data = DEV_DATA(dev); + mem_instance->cfg = DEV_CFG(dev); + mem_instance->api = dev->api; + mem_instance->name = dev->name; + DEV_DATA(mem_instance)->vdevice_type |= VM_DEVICE_PRE_KERNEL_1; + + bool chosen_flag=false; + vdev_list = get_zvm_dev_lists(); + SYS_DLIST_FOR_EACH_NODE_SAFE(&vdev_list->dev_idle_list, d_node, ds_node){ + vm_dev = CONTAINER_OF(d_node, struct virt_dev, vdev_node); + /* host uart device ? */ + if(!strcmp(dev_name, vm_dev->name)){ + chosen_flag = true; + break; + } + } + + if(chosen_flag) + { + vdev = vm_virt_dev_add(vm, dev->name, false, false, + DT_REG_ADDR(DT_ALIAS(vmshmemrw)), + DT_REG_ADDR(DT_ALIAS(vmshmemrw)), + vm_dev->vm_vdev_size, + VM_DEVICE_INVALID_VIRQ, SHMEM_VIRQ - 32); + if(!vdev){ + ZVM_LOG_WARN("Init virt virt_mem_rw device error\n"); + return -ENODEV; + } + vdev->priv_data = mem_instance; + vdev->priv_vdev = dev; + vm_device_irq_init(vm, vdev); + ZVM_LOG_INFO("** Add %s device to vm successful. \n", dev->name); + + return 0; + } + return -ENODEV; +} + +/** + * @brief shmem irq +*/ + + +/** + * @brief Memory read operation +*/ +int memory_rw_read(struct virt_dev *vdev, uint64_t addr, uint64_t *value) +{ + uint64_t *hva; + uint64_t read_value; + + read_value = sys_read64(vdev->vm_vdev_paddr); + printk("vm_vdev_paddr: 0x%x, read_value: 0x%x\n", vdev->vm_vdev_paddr, read_value); + *(uint64_t *)value = read_value; + return read_value; + +} + +/** + * @brief Memory write operation +*/ +int memory_rw_write(struct virt_dev *vdev, uint64_t addr, uint64_t *value) +{ + struct vm *vm; // VM-zephyr + char *char_value = (char *)value; + + // 打印 value 作为字符的内容 + printk("Value as characters: "); + for (int i = 0; i < sizeof(uint64_t); i++) { + printk("%c", char_value[i]); + } + printk("\n"); + /* + '1' : irq from linux + '2' : irq from linux (exit entry) + '3' : irq from zephyr + */ + if(char_value[0] == '1'){ + // linux sends irq to zephyr + vm = zvm_overall_info->vms[0]; + int ret = set_virq_to_vm(vm, SHMEM_VIRQ); + if (ret < 0) { + ZVM_LOG_WARN("Send virq to vm error!"); + } + // printk("send irq_to_zephyr success!\n"); + } else if (char_value[0] == '2') { + // linux send irq to zephyr + vm = zvm_overall_info->vms[0]; + int ret2 = set_virq_to_vm(vm, SHMEM_VIRQ); + // printk("send irq_to_linux success!\n"); + } else { + // zephyr sends irq to linux + vm = zvm_overall_info->vms[2]; + printk("vm_name : %s\n", vm->vm_name); + int ret3 = set_virq_to_vm(vm, SHMEM_VIRQ); + } + return 0; +} + +static const struct virt_device_api virt_mem_api = { + .init_fn = vm_virt_mem_rw_init, + .virt_device_write = memory_rw_write, + .virt_device_read = memory_rw_read, +}; + +static int mem_rw_init(const struct device *dev) +{ + dev->state->init_res = VM_DEVICE_INIT_RES; + return 0; +} + +int vm_mem_rw_create(struct vm *vm) +{ + int ret = 0; + const struct device *dev = DEVICE_DT_GET(DT_ALIAS(vmshmemrw)); + + if(((const struct virt_device_api * const)(dev->api))->init_fn){ + ((const struct virt_device_api * const)(dev->api))->init_fn(dev, vm, NULL); + }else{ + ZVM_LOG_ERR("No mem_rw device api! \n"); + return -ENODEV; + } + return ret; +} + + +#ifdef CONFIG_VM_SHMEMRW +static struct shared_mem_rw_config mem_data_port = { + .base = DT_REG_ADDR(DT_ALIAS(vmshmemrw)), + .size = DT_REG_SIZE(DT_ALIAS(vmshmemrw)), +}; + +static struct virt_device_data virt_mem_data_port = { + .device_data = &mem_data_port, +}; + +static struct virt_device_config virt_mem_cfg = { + .reg_base = DT_REG_ADDR(DT_ALIAS(vmshmemrw)), + .reg_size = DT_REG_SIZE(DT_ALIAS(vmshmemrw)), + .device_config = &virt_mem_data_port, +}; + +/** + * @brief Define the mem description for zvm. +*/ +DEVICE_DT_DEFINE(DT_ALIAS(vmshmemrw), + &mem_rw_init, + NULL, + &virt_mem_data_port, + &virt_mem_cfg, + POST_KERNEL, + CONFIG_MEMRW_INIT_PRIORITY, + &virt_mem_api); +#endif /* CONFIG_VM_SHMEMRW */ \ No newline at end of file diff --git a/subsys/virtualization/vdev/virt_pci.c b/subsys/virtualization/vdev/virt_pci.c index 3cd17bb8d..9a1b059c8 100644 --- a/subsys/virtualization/vdev/virt_pci.c +++ b/subsys/virtualization/vdev/virt_pci.c @@ -16,7 +16,6 @@ #include #include #include -#include #include LOG_MODULE_DECLARE(ZVM_MODULE_NAME); diff --git a/subsys/virtualization/vm_device.c b/subsys/virtualization/vm_device.c index e60c1ea86..941c6ac08 100644 --- a/subsys/virtualization/vm_device.c +++ b/subsys/virtualization/vm_device.c @@ -24,6 +24,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(ZVM_MODULE_NAME); @@ -48,9 +49,11 @@ static int vm_vdev_mem_add(struct vm *vm, struct virt_dev *vdev) attrs = MT_VM_DEVICE_MEM | MT_S2_ACCESS_OFF; } if(strcmp(vdev->name, "VM_SHMEM")==0){ - // attrs = MT_VM_DEVICE_MEM | MT_S2_ACCESS_OFF; attrs = MT_VM_DEVICE_MEM; } + if (strcmp(vdev->name, "VM_SHMEMRW") == 0){ + attrs = MT_VM_DEVICE_MEM | MT_S2_ACCESS_OFF; + } #ifdef CONFIG_SOC_QEMU_CORTEX_MAX if (vdev->vm_vdev_paddr == LINUX_VMCPY_BASE) { attrs = MT_VM_NORMAL_MEM; @@ -398,12 +401,18 @@ int vm_device_init(struct vm *vm) int ret, i; sys_dlist_init(&vm->vdev_list); - ret = vm_shmem_create(vm); + ret = vm_mem_create(vm); if (ret) { ZVM_LOG_WARN("Init vm mem error! \n"); return -EMMAO; } + ret = vm_mem_rw_create(vm); + if (ret) { + ZVM_LOG_WARN("Init vm mem_rw error! \n"); + return -EMMAO; + } + /* Assign ids to virtual devices. */ for (i = 0; i < zvm_virtual_devices_count_get(); i++) { const struct virtual_device_instance *virtual_device = zvm_virtual_device_get(i); -- Gitee From c4a6dc846d921adbd1ed9a9078255b22f7bbafd6 Mon Sep 17 00:00:00 2001 From: zjwang Date: Sun, 25 Aug 2024 23:08:13 +0800 Subject: [PATCH 2/2] share memory of ZVM --- samples/_zvm/boards/roc_rk3568_pc_smp.overlay | 26 +----- .../vdev/pt_device_roc_rk3568_pc.c | 88 +++---------------- subsys/virtualization/vdev/shmem.c | 27 ++---- subsys/virtualization/vdev/shmem_rw.c | 54 ++++-------- subsys/virtualization/vm_device.c | 2 +- 5 files changed, 45 insertions(+), 152 deletions(-) diff --git a/samples/_zvm/boards/roc_rk3568_pc_smp.overlay b/samples/_zvm/boards/roc_rk3568_pc_smp.overlay index 585b495d0..91ef2638a 100644 --- a/samples/_zvm/boards/roc_rk3568_pc_smp.overlay +++ b/samples/_zvm/boards/roc_rk3568_pc_smp.overlay @@ -10,12 +10,10 @@ ptdevice1 = "/soc/pass_through_device/serial@fe660000"; ptdevice2 = "/soc/pass_through_device/serial@fe670000"; ptdevice3 = "/soc/pass_through_device/gpio@fe760000"; - ptdevice4 = "/soc/pass_through_device/i2c@fe5b0000"; - ptdevice5 = "/soc/pass_through_device/i2c@fe5e0000"; - ptdevice6 = "/soc/pass_through_device/pwm@fe6f0000"; - ptdevice7 = "/soc/pass_through_device/i2c@fe5c0000"; - ptdevice8 = "/soc/pass_through_device/linuxdev@103000"; - ptdevice9 = "/soc/pass_through_device/serial@fe6c0000"; + ptdevice4 = "/soc/pass_through_device/i2c@fe5e0000"; + ptdevice5 = "/soc/pass_through_device/pwm@fe6f0000"; + ptdevice6 = "/soc/pass_through_device/linuxdev@103000"; + ptdevice7 = "/soc/pass_through_device/serial@fe6c0000"; linuxdebugger = "/soc/fiq-debugger"; vmvirtmem = "/soc/virtmem@bf000000"; vmshmemrw = "/soc/shmem_rw@bd000000"; @@ -88,22 +86,6 @@ status = "okay"; }; - i2c2: i2c@fe5b0000 { - compatible = "rockchip,rk3399-i2c"; - reg = <0x0 0xfe5b0000 0x0 0x1000>; - clock-frequency = <24000000>; - interrupts = ; - status = "okay"; - }; - - i2c3: i2c@fe5c0000 { - compatible = "rockchip,rk3399-i2c"; - reg = <0x0 0xfe5c0000 0x0 0x1000>; - clock-frequency = <24000000>; - interrupts = ; - status = "okay"; - }; - i2c5: i2c@fe5e0000 { compatible = "rockchip,rk3399-i2c"; reg = <0x0 0xfe5e0000 0x0 0x1000>; diff --git a/subsys/virtualization/vdev/pt_device_roc_rk3568_pc.c b/subsys/virtualization/vdev/pt_device_roc_rk3568_pc.c index fa8e9cb30..69091460b 100644 --- a/subsys/virtualization/vdev/pt_device_roc_rk3568_pc.c +++ b/subsys/virtualization/vdev/pt_device_roc_rk3568_pc.c @@ -93,79 +93,6 @@ static const struct virt_device_api virt_ptdevice_api = { /*---------------------Date for each pt device---------------------------*/ /*irq exist? set this configuration.*/ -// static void ptdevice_irq_config_func_9(const struct device *dev) -// { -// IRQ_CONNECT(DT_IRQN(DT_ALIAS(ptdevice9)), -// DT_IRQ(DT_ALIAS(ptdevice9), priority), -// pass_through_device_isr, -// DEVICE_DT_GET(DT_ALIAS(ptdevice9)), -// 0); -// } -/*irq exist? if not, set function NULL.*/ -static struct pass_through_device_config ptdevice_cfg_port_9 = { - .irq_config_func = NULL,//ptdevice_irq_config_func_9, - .ptdev_spec_init_func = NULL, - .ptdev_spec_irq_func = NULL, -}; - -static struct virt_device_config virt_ptdevice_cfg_9 = { - .reg_base = DT_REG_ADDR(DT_ALIAS(ptdevice9)), - .reg_size = DT_REG_SIZE(DT_ALIAS(ptdevice9)), - .hirq_num = DT_IRQN(DT_ALIAS(ptdevice9)), - .device_config = &ptdevice_cfg_port_9, -}; - -static struct virt_device_data virt_ptdevice_data_port_9 = { - .device_data = NULL, -}; - -DEVICE_DT_DEFINE(DT_ALIAS(ptdevice9), - &pass_through_device_init, - NULL, &virt_ptdevice_data_port_9, &virt_ptdevice_cfg_9, - POST_KERNEL, - CONFIG_SERIAL_INIT_PRIORITY, - &virt_ptdevice_api); -/*------------------------cut line---------------------------------------*/ - - -/*---------------------Date for each pt device---------------------------*/ -/*irq exist? set this configuration.*/ -static void ptdevice_irq_config_func_8(const struct device *dev) -{ - IRQ_CONNECT(DT_IRQN(DT_ALIAS(ptdevice8)), - DT_IRQ(DT_ALIAS(ptdevice8), priority), - pass_through_device_isr, - DEVICE_DT_GET(DT_ALIAS(ptdevice8)), - 0); -} -/*irq exist? if not, set function NULL.*/ -static struct pass_through_device_config ptdevice_cfg_port_8 = { - .irq_config_func = ptdevice_irq_config_func_8, - .ptdev_spec_init_func = NULL, - .ptdev_spec_irq_func = NULL, -}; - -static struct virt_device_config virt_ptdevice_cfg_8 = { - .reg_base = DT_REG_ADDR(DT_ALIAS(ptdevice8)), - .reg_size = DT_REG_SIZE(DT_ALIAS(ptdevice8)), - .hirq_num = DT_IRQN(DT_ALIAS(ptdevice8)), - .device_config = &ptdevice_cfg_port_8, -}; - -static struct virt_device_data virt_ptdevice_data_port_8 = { - .device_data = NULL, -}; - -DEVICE_DT_DEFINE(DT_ALIAS(ptdevice8), - &pass_through_device_init, - NULL, &virt_ptdevice_data_port_8, &virt_ptdevice_cfg_8, - POST_KERNEL, - CONFIG_SERIAL_INIT_PRIORITY, - &virt_ptdevice_api); -/*------------------------cut line---------------------------------------*/ - -/*---------------------Date for each pt device---------------------------*/ -/*irq exist? set this configuration.*/ static void ptdevice_irq_config_func_7(const struct device *dev) { IRQ_CONNECT(DT_IRQN(DT_ALIAS(ptdevice7)), @@ -201,9 +128,18 @@ DEVICE_DT_DEFINE(DT_ALIAS(ptdevice7), /*------------------------cut line---------------------------------------*/ /*---------------------Date for each pt device---------------------------*/ +/*irq exist? set this configuration.*/ +static void ptdevice_irq_config_func_6(const struct device *dev) +{ + IRQ_CONNECT(DT_IRQN(DT_ALIAS(ptdevice6)), + DT_IRQ(DT_ALIAS(ptdevice6), priority), + pass_through_device_isr, + DEVICE_DT_GET(DT_ALIAS(ptdevice6)), + 0); +} /*irq exist? if not, set function NULL.*/ static struct pass_through_device_config ptdevice_cfg_port_6 = { - .irq_config_func = NULL, + .irq_config_func = ptdevice_irq_config_func_6, .ptdev_spec_init_func = NULL, .ptdev_spec_irq_func = NULL, }; @@ -211,6 +147,7 @@ static struct pass_through_device_config ptdevice_cfg_port_6 = { static struct virt_device_config virt_ptdevice_cfg_6 = { .reg_base = DT_REG_ADDR(DT_ALIAS(ptdevice6)), .reg_size = DT_REG_SIZE(DT_ALIAS(ptdevice6)), + .hirq_num = DT_IRQN(DT_ALIAS(ptdevice6)), .device_config = &ptdevice_cfg_port_6, }; @@ -237,7 +174,6 @@ static struct pass_through_device_config ptdevice_cfg_port_5 = { static struct virt_device_config virt_ptdevice_cfg_5 = { .reg_base = DT_REG_ADDR(DT_ALIAS(ptdevice5)), .reg_size = DT_REG_SIZE(DT_ALIAS(ptdevice5)), - .hirq_num = DT_IRQN(DT_ALIAS(ptdevice5)), .device_config = &ptdevice_cfg_port_5, }; @@ -263,7 +199,7 @@ static void ptdevice_irq_config_func_4(const struct device *dev) DEVICE_DT_GET(DT_ALIAS(ptdevice4)), 0); } -/*irq exist? if not, set function NULL.*/ + static struct pass_through_device_config ptdevice_cfg_port_4 = { .irq_config_func = ptdevice_irq_config_func_4, .ptdev_spec_init_func = NULL, diff --git a/subsys/virtualization/vdev/shmem.c b/subsys/virtualization/vdev/shmem.c index 55a1e97d5..0af8aaba2 100644 --- a/subsys/virtualization/vdev/shmem.c +++ b/subsys/virtualization/vdev/shmem.c @@ -24,18 +24,17 @@ LOG_MODULE_DECLARE(ZVM_MODULE_NAME); #define SHMEM_ADDR DT_REG_ADDR(DT_ALIAS(vmvirtmem)) #define SHMEM_SIZE DT_REG_SIZE(DT_ALIAS(vmvirtmem)) - -#define SHMEM_VIRQ (DT_IRQN(DT_ALIAS(vmvirtmem)) + VM_LOCAL_VIRQ_NR) +#define SHMEM_VIRQ DT_IRQN(DT_ALIAS(vmvirtmem)) #define DEV_CFG(dev) ((const struct virt_device_config *const)(dev)->config) #define DEV_DATA(dev) ((struct virt_device_data *)(dev)->data) typedef struct shared_memory { - int sender; // sender ID - int receiver; // receiver ID - int length; // len of data - char *shm_value; // data + int sender; + int receiver; + int length; + char *shm_value; } SHMEM; static struct virtual_device_instance *mem_instance; @@ -82,14 +81,13 @@ static int vm_virt_mem_init(const struct device *dev, struct vm *vm, struct virt } } - if(chosen_flag) - { + if (chosen_flag) { vdev = vm_virt_dev_add(vm, dev->name, false, false, DT_REG_ADDR(DT_ALIAS(vmvirtmem)), DT_REG_ADDR(DT_ALIAS(vmvirtmem)), vm_dev->vm_vdev_size, - VM_DEVICE_INVALID_VIRQ, SHMEM_VIRQ - 32); - if(!vdev){ + VM_DEVICE_INVALID_VIRQ, SHMEM_VIRQ); + if (!vdev) { ZVM_LOG_WARN("Init virt virt_mem device error\n"); return -ENODEV; } @@ -108,14 +106,7 @@ static int vm_virt_mem_init(const struct device *dev, struct vm *vm, struct virt */ int memory_read(struct virt_dev *vdev, uint64_t addr, uint64_t *value) { - uint64_t *hva; - uint64_t read_value; - - read_value = sys_read64(vdev->vm_vdev_paddr); - printk("vm_vdev_paddr: 0x%x, read_value: 0x%x\n", vdev->vm_vdev_paddr, read_value); - *(uint64_t *)value = read_value; - return read_value; - + return 0; } /** diff --git a/subsys/virtualization/vdev/shmem_rw.c b/subsys/virtualization/vdev/shmem_rw.c index b32854b0d..f5a565414 100644 --- a/subsys/virtualization/vdev/shmem_rw.c +++ b/subsys/virtualization/vdev/shmem_rw.c @@ -22,17 +22,17 @@ LOG_MODULE_DECLARE(ZVM_MODULE_NAME); -#define SHMEM_VIRQ (DT_IRQN(DT_ALIAS(vmvirtmem)) + VM_LOCAL_VIRQ_NR) +#define SHMEM_VIRQ DT_IRQN(DT_ALIAS(vmvirtmem)) #define DEV_CFG(dev) ((const struct virt_device_config *const)(dev)->config) #define DEV_DATA(dev) ((struct virt_device_data *)(dev)->data) typedef struct shared_memory { - int sender; // sender ID - int receiver; // receiver ID - int length; // len of data - char *shm_value; // data + int sender; + int receiver; + int length; + char *shm_value; } SHMEM; static struct virtual_device_instance *mem_instance; @@ -86,7 +86,7 @@ static int vm_virt_mem_rw_init(const struct device *dev, struct vm *vm, struct v DT_REG_ADDR(DT_ALIAS(vmshmemrw)), DT_REG_ADDR(DT_ALIAS(vmshmemrw)), vm_dev->vm_vdev_size, - VM_DEVICE_INVALID_VIRQ, SHMEM_VIRQ - 32); + VM_DEVICE_INVALID_VIRQ, SHMEM_VIRQ); if(!vdev){ ZVM_LOG_WARN("Init virt virt_mem_rw device error\n"); return -ENODEV; @@ -101,24 +101,12 @@ static int vm_virt_mem_rw_init(const struct device *dev, struct vm *vm, struct v return -ENODEV; } -/** - * @brief shmem irq -*/ - - /** * @brief Memory read operation */ int memory_rw_read(struct virt_dev *vdev, uint64_t addr, uint64_t *value) { - uint64_t *hva; - uint64_t read_value; - - read_value = sys_read64(vdev->vm_vdev_paddr); - printk("vm_vdev_paddr: 0x%x, read_value: 0x%x\n", vdev->vm_vdev_paddr, read_value); - *(uint64_t *)value = read_value; - return read_value; - + return 0; } /** @@ -126,38 +114,34 @@ int memory_rw_read(struct virt_dev *vdev, uint64_t addr, uint64_t *value) */ int memory_rw_write(struct virt_dev *vdev, uint64_t addr, uint64_t *value) { - struct vm *vm; // VM-zephyr + struct vm *vm; char *char_value = (char *)value; - - // 打印 value 作为字符的内容 - printk("Value as characters: "); - for (int i = 0; i < sizeof(uint64_t); i++) { - printk("%c", char_value[i]); - } - printk("\n"); /* '1' : irq from linux '2' : irq from linux (exit entry) '3' : irq from zephyr */ - if(char_value[0] == '1'){ - // linux sends irq to zephyr + if (char_value[0] == '1') { + /* linux sends irq to zephyr */ vm = zvm_overall_info->vms[0]; int ret = set_virq_to_vm(vm, SHMEM_VIRQ); if (ret < 0) { ZVM_LOG_WARN("Send virq to vm error!"); } - // printk("send irq_to_zephyr success!\n"); - } else if (char_value[0] == '2') { - // linux send irq to zephyr + } else if (char_value[0] == '2'){ + /* linux send irq-2 to zephyr */ vm = zvm_overall_info->vms[0]; int ret2 = set_virq_to_vm(vm, SHMEM_VIRQ); - // printk("send irq_to_linux success!\n"); + if (ret2 < 0) { + ZVM_LOG_WARN("Send virq to vm error!"); + } } else { - // zephyr sends irq to linux + /* zephyr sends irq to linux */ vm = zvm_overall_info->vms[2]; - printk("vm_name : %s\n", vm->vm_name); int ret3 = set_virq_to_vm(vm, SHMEM_VIRQ); + if (ret3 < 0) { + ZVM_LOG_WARN("Send virq to vm error!"); + } } return 0; } diff --git a/subsys/virtualization/vm_device.c b/subsys/virtualization/vm_device.c index 941c6ac08..ff48daada 100644 --- a/subsys/virtualization/vm_device.c +++ b/subsys/virtualization/vm_device.c @@ -48,7 +48,7 @@ static int vm_vdev_mem_add(struct vm *vm, struct virt_dev *vdev) }else{ attrs = MT_VM_DEVICE_MEM | MT_S2_ACCESS_OFF; } - if(strcmp(vdev->name, "VM_SHMEM")==0){ + if(strcmp(vdev->name, "VM_SHMEM") == 0){ attrs = MT_VM_DEVICE_MEM; } if (strcmp(vdev->name, "VM_SHMEMRW") == 0){ -- Gitee