diff --git a/arch/arm64/core/virtualization/trap_handler.c b/arch/arm64/core/virtualization/trap_handler.c index f64cb8f50b678d8b4723cbbaddda2bd12d3b302c..65734bc95d23b3ab73fb443f6d6a537edd367d1f 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 16a8cc52fd64645f3950c81670cb928ad219c7b5..e2529739c8c71870127e7832b479714aaefffc5b 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 9fa6982150164bbe306ef65cdeb1789c0f70243c..68c4308416c8b4742368491b29ded45a819957f2 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 0000000000000000000000000000000000000000..e17c82cdd07c99453c5fc41fc12b2612bfb7ea30 --- /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 480796957fe52bc840d8e121e3133bf3faab8323..98d9e91c44fdf0a092c79bed1c24deede93df048 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 920395639f4e88b1866284ecebf8ed0e02b0d663..e742a0cc1ff066e3b3bbb5bbfb93a27381fe2c56 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 88254dbeb1e5a75bbc176aa016d38b518c255037..d5c8bd5d20989a0469a581671d5842fa117d856d 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 29870c276d6a99c472caca80c2906d8f386db089..91ef2638a4c54f66930fdc911f8561ad1a3ca7bd 100644 --- a/samples/_zvm/boards/roc_rk3568_pc_smp.overlay +++ b/samples/_zvm/boards/roc_rk3568_pc_smp.overlay @@ -10,14 +10,13 @@ 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"; }; chosen { @@ -87,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>; @@ -149,10 +132,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 5054501d4864a6502ae83224ab6703a027d4fdfa..a776a3449243a6601b091707ef5e35f82ab1accb 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 a07afb6251d9e42bfb74e57c8345e3b69ee430f8..bf3164dd0f4d8322cd19548ae1af75001d6287fe 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 0000000000000000000000000000000000000000..63fd8669d72afc6225038abd05b2a4988d32435f --- /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 0b58aa6014d4eb01e5c4ec667fad439f2ea69ca2..bce0188b6d62d4d45f3dead98e87c8f44e357f86 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 bc234d0766f26c841d5d34c6beb7047be4690628..7c627478ad8fa8edd93e214600e06c94cb34916e 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/pt_device_roc_rk3568_pc.c b/subsys/virtualization/vdev/pt_device_roc_rk3568_pc.c index fa8e9cb304846491decd6c4bec4314c34a64e568..69091460ba2eb561e6e5459ec59952c0d12e8067 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 69280f2072fb2badb3d7c302cde00f03b6edf611..0af8aaba2f90a811651d4d28d1081fd70dd66dd0 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,20 @@ 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)) + #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; + int receiver; + int length; + char *shm_value; +} SHMEM; static struct virtual_device_instance *mem_instance; @@ -38,7 +48,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 +63,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; @@ -70,25 +81,19 @@ 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, VM_DEVICE_INVALID_VIRQ); - if(!vdev){ + VM_DEVICE_INVALID_VIRQ, SHMEM_VIRQ); + 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 +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 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); - *(uint64_t *)value = read_value; - return read_value; + return 0; } /** @@ -114,11 +114,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 +129,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 0000000000000000000000000000000000000000..f5a565414b77c2e2806b46100a429f5c146ddb1b --- /dev/null +++ b/subsys/virtualization/vdev/shmem_rw.c @@ -0,0 +1,203 @@ +/* + * 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)) + +#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; + int receiver; + int length; + char *shm_value; +} 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); + 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 Memory read operation +*/ +int memory_rw_read(struct virt_dev *vdev, uint64_t addr, uint64_t *value) +{ + return 0; +} + +/** + * @brief Memory write operation +*/ +int memory_rw_write(struct virt_dev *vdev, uint64_t addr, uint64_t *value) +{ + struct vm *vm; + char *char_value = (char *)value; + /* + '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!"); + } + } 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); + if (ret2 < 0) { + ZVM_LOG_WARN("Send virq to vm error!"); + } + } else { + /* zephyr sends irq to linux */ + vm = zvm_overall_info->vms[2]; + int ret3 = set_virq_to_vm(vm, SHMEM_VIRQ); + if (ret3 < 0) { + ZVM_LOG_WARN("Send virq to vm error!"); + } + } + 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 3cd17bb8d02613a096e093ecc6770eea679d27ac..9a1b059c81af25023d957f7a5721b3c85a2f2cc2 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 e60c1ea868df78f201effe614ebfd0e809b09269..ff48daada7b1ea58584b1923d4577e1870bed474 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); @@ -47,10 +48,12 @@ 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){ - // attrs = MT_VM_DEVICE_MEM | MT_S2_ACCESS_OFF; + if(strcmp(vdev->name, "VM_SHMEM") == 0){ 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);