From 00edcacf1e2fe1723a4cc9e6d4a749fe9038d12d Mon Sep 17 00:00:00 2001 From: Charlie Xiong <1981639884@qq.com> Date: Sat, 23 Mar 2024 14:29:06 +0800 Subject: [PATCH 1/4] driver: modified pcie_ecam Moving data struct from pcie_ecam.c to pcie_ecam.h, and adding some dts items. Signed-off-by: Charlie Xiong <1981639884@qq.com> --- drivers/pcie/host/pcie_ecam.c | 26 +--------- .../pcie/host/pci-host-ecam-generic.yaml | 9 ++++ include/drivers/pcie/pcie_ecam.h | 47 +++++++++++++++++++ 3 files changed, 57 insertions(+), 25 deletions(-) create mode 100644 include/drivers/pcie/pcie_ecam.h diff --git a/drivers/pcie/host/pcie_ecam.c b/drivers/pcie/host/pcie_ecam.c index fc4599fe7..a1120ab5c 100644 --- a/drivers/pcie/host/pcie_ecam.c +++ b/drivers/pcie/host/pcie_ecam.c @@ -10,35 +10,11 @@ LOG_MODULE_REGISTER(pcie_ecam, LOG_LEVEL_ERR); #include #include #include +#include #include #define DT_DRV_COMPAT pci_host_ecam_generic -/* - * PCIe Controllers Regions - * - * TOFIX: - * - handle prefetchable regions - */ -enum pcie_region_type { - PCIE_REGION_IO = 0, - PCIE_REGION_MEM, - PCIE_REGION_MEM64, - PCIE_REGION_MAX, -}; - -struct pcie_ecam_data { - uintptr_t cfg_phys_addr; - mm_reg_t cfg_addr; - size_t cfg_size; - struct { - uintptr_t phys_start; - uintptr_t bus_start; - size_t size; - size_t allocation_offset; - } regions[PCIE_REGION_MAX]; -}; - static int pcie_ecam_init(const struct device *dev) { const struct pcie_ctrl_config *cfg = (const struct pcie_ctrl_config *)dev->config; diff --git a/dts/bindings/pcie/host/pci-host-ecam-generic.yaml b/dts/bindings/pcie/host/pci-host-ecam-generic.yaml index 111bceef8..3d46325a8 100644 --- a/dts/bindings/pcie/host/pci-host-ecam-generic.yaml +++ b/dts/bindings/pcie/host/pci-host-ecam-generic.yaml @@ -21,3 +21,12 @@ properties: As described in IEEE Std 1275-1994, but must provide at least a definition of non-prefetchable memory. One or both of prefetchable Memory and IO Space may also be provided. + + interrupt-map-mask: + type: array + + interrupt-map: + type: compound + + bus-range: + type: array diff --git a/include/drivers/pcie/pcie_ecam.h b/include/drivers/pcie/pcie_ecam.h new file mode 100644 index 000000000..138955d2c --- /dev/null +++ b/include/drivers/pcie/pcie_ecam.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_PCIE_PCIE_ECAM_H_ +#define ZEPHYR_INCLUDE_DRIVERS_PCIE_PCIE_ECAM_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * PCIe Controllers Regions + * + * TOFIX: + * - handle prefetchable regions + */ +enum pcie_region_type { + PCIE_REGION_IO = 0, + PCIE_REGION_MEM, + PCIE_REGION_MEM64, + PCIE_REGION_MAX, +}; + +struct pcie_ecam_data { + uintptr_t cfg_phys_addr; + mm_reg_t cfg_addr; + size_t cfg_size; + struct { + uintptr_t phys_start; + uintptr_t bus_start; + size_t size; + size_t allocation_offset; + } regions[PCIE_REGION_MAX]; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_PCIE_PCIE_ECAM_H_ */ -- Gitee From b5f685a59b9013420fca2702f8e04b654f030cbd Mon Sep 17 00:00:00 2001 From: Charlie Xiong <1981639884@qq.com> Date: Sat, 23 Mar 2024 14:31:24 +0800 Subject: [PATCH 2/4] virt: device: Add virt pci bus device PCIE bus in the host is not enabled in zephyr on rk3568, and it can not support virt pcie device. So, virt_pcie emualte a pcie bus for vm. Signed-off-by: Charlie Xiong <1981639884@qq.com> --- arch/arm64/core/virtualization/trap_handler.c | 11 +- auto_zvm.sh | 6 +- include/virtualization/vdev/virt_device.h | 4 +- include/virtualization/vdev/virt_pci.h | 75 ++++++ include/virtualization/vm_dev.h | 17 +- samples/_zvm/boards/qemu_cortex_max.overlay | 6 +- samples/_zvm/boards/qemu_cortex_max_smp.conf | 8 + .../_zvm/boards/qemu_cortex_max_smp.overlay | 55 ++++- samples/_zvm/dts/bindings/virt,pci.yaml | 75 ++++++ samples/_zvm/dts/bindings/vm-dram.yaml | 3 - subsys/virtualization/vdev/CMakeLists.txt | 5 + subsys/virtualization/vdev/Kconfig | 15 ++ subsys/virtualization/vdev/virt_pci.c | 232 ++++++++++++++++++ subsys/virtualization/vm_dev.c | 47 +++- subsys/virtualization/vm_manager.c | 1 - 15 files changed, 532 insertions(+), 28 deletions(-) create mode 100644 include/virtualization/vdev/virt_pci.h create mode 100644 samples/_zvm/dts/bindings/virt,pci.yaml create mode 100644 subsys/virtualization/vdev/virt_pci.c diff --git a/arch/arm64/core/virtualization/trap_handler.c b/arch/arm64/core/virtualization/trap_handler.c index 6f3ca2014..d247543c5 100644 --- a/arch/arm64/core/virtualization/trap_handler.c +++ b/arch/arm64/core/virtualization/trap_handler.c @@ -45,10 +45,19 @@ static int handle_ftrans_desc(int iss_dfsc, uint64_t pa_addr, #else uint16_t reg_index = dabt->srt; uint64_t *reg_value; + reg_value = find_index_reg(reg_index, regs); + if (reg_value == NULL) { + reg_value = &wzr_reg; + } /* check that if it is a device memory fault */ - ret = handle_vm_device_emulate(vcpu->vm, pa_addr); + ret = handle_vm_device_emulate(vcpu->vm, pa_addr, dabt->wnr, reg_value); if(ret){ + /* pci initial sucessful. */ + if(ret > 0){ + return 0; + } + reg_value = find_index_reg(reg_index, regs); *reg_value = 0xfefefefefefefefe; ZVM_LOG_WARN("VM's mem abort addr: 0x%llx ! \n", pa_addr); diff --git a/auto_zvm.sh b/auto_zvm.sh index 3c12b5b71..accb561fd 100755 --- a/auto_zvm.sh +++ b/auto_zvm.sh @@ -44,9 +44,9 @@ elif [ "$OPS" = "$ops_debug" ]; then -net none -pidfile qemu.pid -chardev stdio,id=con,mux=on \ -serial chardev:con -mon chardev=con,mode=readline -serial pty -serial pty -smp cpus=4 \ -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/zephyr.bin,addr=0xf2000000,force-raw=on \ - -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/Image,addr=0xf3000000,force-raw=on \ - -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/linux-qemu-virtio.dtb,addr=0xf2a00000 \ - -kernel $(pwd)/build/zephyr/zvm_host.elf + -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/Image_oee,addr=0xf3000000,force-raw=on \ + -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/linux-qemu-virt-pcie.dtb,addr=0xf2a00000 \ + -kernel $(pwd)/build/zephyr/zvm_host.elf -s -S ### 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/virt_device.h b/include/virtualization/vdev/virt_device.h index cda0aa8b3..db05fff64 100644 --- a/include/virtualization/vdev/virt_device.h +++ b/include/virtualization/vdev/virt_device.h @@ -46,8 +46,8 @@ struct virt_device_data { */ struct virt_device_config { /* Regisiter base and size from dts*/ - uint32_t reg_base; - uint32_t reg_size; + uint64_t reg_base; + uint64_t reg_size; uint32_t hirq_num; char device_type[VIRT_DEV_TYPE_LENGTH]; /* Address of device instance config information */ diff --git a/include/virtualization/vdev/virt_pci.h b/include/virtualization/vdev/virt_pci.h new file mode 100644 index 000000000..ea6327641 --- /dev/null +++ b/include/virtualization/vdev/virt_pci.h @@ -0,0 +1,75 @@ +/* + * Copyright 2024 HNU-ESNL + * Copyright 2024 openEuler SIG-Zephyr + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_VIRTUALIZATION_VDEV_VIRT_PCI_H_ +#define ZEPHYR_INCLUDE_VIRTUALIZATION_VDEV_VIRT_PCI_H_ + +#include +#include +#include +#include + +/* PCI device type. */ +#define VM_PCI_BRIDGE (0x01) +#define VM_PCI_DEVICE (0x02) +#define VM_PCI_IVSHMEM (0x03) + +/* PCI shmem protocol type. */ +#define VM_PCI_SHMEM_PROTO_UNDEFINED (0x0000) +#define VM_PCI_SHMEM_PROTO_VETH (0x0001) +#define VM_PCI_SHMEM_PROTO_CUSTOM (0x4000) /* 0x4000..0x7fff */ +#define VM_PCI_SHMEM_PROTO_VIRTIO_FRONT (0x8000) /* 0x8000..0xbfff */ +#define VM_PCI_SHMEM_PROTO_VIRTIO_BACK (0xc000) /* 0xc000..0xffff */ + +#define VM_PCI_RANGES_NUM (5) + +#define PCI_TRANSUCESS (6) + +/*Description of virtual pci bus device. */ +struct virt_pci_bus_config { + bool pci_is_virtual; + uint16_t pci_domain; + uint16_t pci_config_end_bus; + + /*cpu addree space for pci device.*/ + uint32_t pci_range_base[VM_PCI_RANGES_NUM]; + uint32_t pci_range_size[VM_PCI_RANGES_NUM]; + +}; + +/*Description of virtual pci private device. */ +struct virt_pci_bus_data { + /* host access pci bus's base address. */ + uint64_t pci_hva_base; +}; + +/* Description of virtual pci device. */ +struct virt_pci_device { + + uint8_t type; + uint8_t shmem_dev_id; + uint8_t shmem_peers; + uint8_t num_msi_vector; + + uint16_t domain; + uint16_t bdf; + uint16_t bar_mask[6]; + uint16_t caps_start; + uint16_t num_caps; + uint16_t shmem_protocol; + + uint32_t shmem_region_start; +}; + +/** + * @brief Translation vm's access to physical memory. + * + * @return 0 is success, other value is wrong. +*/ +int virt_pci_emulation(struct vm *vm, uint64_t pdev_addr, int write, uint64_t *value); + +#endif /*ZEPHYR_INCLUDE_VIRTUALIZATION_VDEV_VIRT_PCI_H_*/ \ No newline at end of file diff --git a/include/virtualization/vm_dev.h b/include/virtualization/vm_dev.h index 204436475..27b47ef2f 100644 --- a/include/virtualization/vm_dev.h +++ b/include/virtualization/vm_dev.h @@ -36,8 +36,8 @@ struct virt_dev { uint32_t hirq; uint32_t virq; - uint32_t vm_vdev_paddr; - uint32_t vm_vdev_vaddr; + uint64_t vm_vdev_paddr; + uint64_t vm_vdev_vaddr; uint32_t vm_vdev_size; struct _dnode vdev_node; @@ -69,11 +69,20 @@ struct zvm_dev_lists { /*TODO: Add smp lock here*/ }; +/** + * @brief Creating a vm device for the @vm, and there is no memory map build. + * + * @param +*/ +struct virt_dev *vm_virt_dev_add_no_memmap(struct vm *vm, const char *dev_name, bool pt_flag, + bool shareable, uint64_t dev_pbase, uint64_t dev_hva, + uint32_t dev_size, uint32_t dev_hirq, uint32_t dev_virq); + /** * @brief According to the device info, create a vm device for the para @vm. */ struct virt_dev *vm_virt_dev_add(struct vm *vm, const char *dev_name, bool pt_flag, - bool shareable, uint32_t dev_pbase, uint32_t dev_vbase, + bool shareable, uint64_t dev_pbase, uint64_t dev_vbase, uint32_t dev_size, uint32_t dev_hirq, uint32_t dev_virq); /** @@ -96,7 +105,7 @@ int vm_vdev_pause(struct vcpu *vcpu); * can directly access this memory later. * 2. Rerun the fault code and access the physical device memory. */ -int handle_vm_device_emulate(struct vm *vm, uint64_t pa_addr); +int handle_vm_device_emulate(struct vm *vm, uint64_t pa_addr, int write, uint64_t *value); int vm_device_init(struct vm *vm); diff --git a/samples/_zvm/boards/qemu_cortex_max.overlay b/samples/_zvm/boards/qemu_cortex_max.overlay index a03920a30..79b429145 100644 --- a/samples/_zvm/boards/qemu_cortex_max.overlay +++ b/samples/_zvm/boards/qemu_cortex_max.overlay @@ -21,7 +21,7 @@ vmvirtio9 = "/soc/virtio_mmio@a001000"; vmvirtio10 = "/soc/virtio_mmio@a001200"; vmgpioctrl = "/soc/pl061@9030000"; -// vmpcie = "/soc/pcie@10000000"; + vmpcie = "/soc/pcie@10000000"; vmrtc = "/soc/pl031@9010000"; vmpmu = "/soc/pmu"; vmflash = "/soc/flash@0"; @@ -159,7 +159,7 @@ compatible = "arm,pl061\0arm,primecell"; reg = <0x00 0x9030000 0x00 0x1000>; }; -/* + pcie@10000000 { interrupt-map-mask = <0x1800 0x00 0x00 0x07>; interrupt-map = <0x00 0x00 0x00 0x01 0x8005 0x00 0x00 0x00 0x03 0x04 0x00 0x00 0x00 0x02 0x8005 0x00 0x00 0x00 0x04 0x04 0x00 0x00 0x00 0x03 0x8005 0x00 0x00 0x00 0x05 0x04 0x00 0x00 0x00 0x04 0x8005 0x00 0x00 0x00 0x06 0x04 0x800 0x00 0x00 0x01 0x8005 0x00 0x00 0x00 0x04 0x04 0x800 0x00 0x00 0x02 0x8005 0x00 0x00 0x00 0x05 0x04 0x800 0x00 0x00 0x03 0x8005 0x00 0x00 0x00 0x06 0x04 0x800 0x00 0x00 0x04 0x8005 0x00 0x00 0x00 0x03 0x04 0x1000 0x00 0x00 0x01 0x8005 0x00 0x00 0x00 0x05 0x04 0x1000 0x00 0x00 0x02 0x8005 0x00 0x00 0x00 0x06 0x04 0x1000 0x00 0x00 0x03 0x8005 0x00 0x00 0x00 0x03 0x04 0x1000 0x00 0x00 0x04 0x8005 0x00 0x00 0x00 0x04 0x04 0x1800 0x00 0x00 0x01 0x8005 0x00 0x00 0x00 0x06 0x04 0x1800 0x00 0x00 0x02 0x8005 0x00 0x00 0x00 0x03 0x04 0x1800 0x00 0x00 0x03 0x8005 0x00 0x00 0x00 0x04 0x04 0x1800 0x00 0x00 0x04 0x8005 0x00 0x00 0x00 0x05 0x04>; @@ -175,7 +175,7 @@ device_type = "pci"; compatible = "pci-host-ecam-generic"; }; -*/ + pl031@9010000 { clock-names = "apb_pclk"; clocks = <0x8000>; diff --git a/samples/_zvm/boards/qemu_cortex_max_smp.conf b/samples/_zvm/boards/qemu_cortex_max_smp.conf index adac4b289..e96e176ed 100644 --- a/samples/_zvm/boards/qemu_cortex_max_smp.conf +++ b/samples/_zvm/boards/qemu_cortex_max_smp.conf @@ -12,6 +12,11 @@ CONFIG_KERNEL_VM_SIZE=0x20000000 # uart CONFIG_UART_PL011_PORT1=n +# pci controller +CONFIG_PCIE=y +CONFIG_PCIE_CONTROLLER=y +CONFIG_PCIE_ECAM=y + # vgic device. CONFIG_VM_VGICV3=y @@ -30,3 +35,6 @@ CONFIG_ZVM_LINUX_MAX_XLAT_TABLES=8192 CONFIG_VM_VIRTIO_MMIO=y CONFIG_VM_VIRTIO_BLOCK=y +# enable pci bus support +CONFIG_VM_PCI_BUS_CONTROLLER=y +CONFIG_VM_PCI_BUS_INIT_PRIORITY=68 diff --git a/samples/_zvm/boards/qemu_cortex_max_smp.overlay b/samples/_zvm/boards/qemu_cortex_max_smp.overlay index b2fe94b70..0d61a93eb 100644 --- a/samples/_zvm/boards/qemu_cortex_max_smp.overlay +++ b/samples/_zvm/boards/qemu_cortex_max_smp.overlay @@ -21,14 +21,16 @@ vmvirtio9 = "/soc/virtio_mmio@a001000"; vmvirtio10 = "/soc/virtio_mmio@a001200"; vmgpioctrl = "/soc/pl061@9030000"; -// vmpcie = "/soc/pcie@10000000"; + vmpcie = "/soc/pcie@10000000"; vmrtc = "/soc/pl031@9010000"; vmpmu = "/soc/pmu"; vmflash = "/soc/flash@0"; + vmivshmem0 = "/vm_linux_space/linux_ivshmem"; }; chosen { vm,console = &uart0; + zephyr_pcie_controller = "/soc/pcie@10000000"; }; soc { @@ -158,23 +160,38 @@ compatible = "arm,pl061\0arm,primecell"; reg = <0x00 0x9030000 0x00 0x1000>; }; -/* + pcie@10000000 { + compatible = "pci-host-ecam-generic"; interrupt-map-mask = <0x1800 0x00 0x00 0x07>; - interrupt-map = <0x00 0x00 0x00 0x01 0x8005 0x00 0x00 0x00 0x03 0x04 0x00 0x00 0x00 0x02 0x8005 0x00 0x00 0x00 0x04 0x04 0x00 0x00 0x00 0x03 0x8005 0x00 0x00 0x00 0x05 0x04 0x00 0x00 0x00 0x04 0x8005 0x00 0x00 0x00 0x06 0x04 0x800 0x00 0x00 0x01 0x8005 0x00 0x00 0x00 0x04 0x04 0x800 0x00 0x00 0x02 0x8005 0x00 0x00 0x00 0x05 0x04 0x800 0x00 0x00 0x03 0x8005 0x00 0x00 0x00 0x06 0x04 0x800 0x00 0x00 0x04 0x8005 0x00 0x00 0x00 0x03 0x04 0x1000 0x00 0x00 0x01 0x8005 0x00 0x00 0x00 0x05 0x04 0x1000 0x00 0x00 0x02 0x8005 0x00 0x00 0x00 0x06 0x04 0x1000 0x00 0x00 0x03 0x8005 0x00 0x00 0x00 0x03 0x04 0x1000 0x00 0x00 0x04 0x8005 0x00 0x00 0x00 0x04 0x04 0x1800 0x00 0x00 0x01 0x8005 0x00 0x00 0x00 0x06 0x04 0x1800 0x00 0x00 0x02 0x8005 0x00 0x00 0x00 0x03 0x04 0x1800 0x00 0x00 0x03 0x8005 0x00 0x00 0x00 0x04 0x04 0x1800 0x00 0x00 0x04 0x8005 0x00 0x00 0x00 0x05 0x04>; + interrupt-map = <0x00 0x00 0x00 0x01 0x8005 0x00 0x00 0x00 0x03 0x04 + 0x00 0x00 0x00 0x02 0x8005 0x00 0x00 0x00 0x04 0x04 + 0x00 0x00 0x00 0x03 0x8005 0x00 0x00 0x00 0x05 0x04 + 0x00 0x00 0x00 0x04 0x8005 0x00 0x00 0x00 0x06 0x04 + 0x800 0x00 0x00 0x01 0x8005 0x00 0x00 0x00 0x04 0x04 + 0x800 0x00 0x00 0x02 0x8005 0x00 0x00 0x00 0x05 0x04 + 0x800 0x00 0x00 0x03 0x8005 0x00 0x00 0x00 0x06 0x04 + 0x800 0x00 0x00 0x04 0x8005 0x00 0x00 0x00 0x03 0x04 + 0x1000 0x00 0x00 0x01 0x8005 0x00 0x00 0x00 0x05 0x04 + 0x1000 0x00 0x00 0x02 0x8005 0x00 0x00 0x00 0x06 0x04 + 0x1000 0x00 0x00 0x03 0x8005 0x00 0x00 0x00 0x03 0x04 + 0x1000 0x00 0x00 0x04 0x8005 0x00 0x00 0x00 0x04 0x04 + 0x1800 0x00 0x00 0x01 0x8005 0x00 0x00 0x00 0x06 0x04 + 0x1800 0x00 0x00 0x02 0x8005 0x00 0x00 0x00 0x03 0x04 + 0x1800 0x00 0x00 0x03 0x8005 0x00 0x00 0x00 0x04 0x04 + 0x1800 0x00 0x00 0x04 0x8005 0x00 0x00 0x00 0x05 0x04>; #interrupt-cells = <0x01>; - ranges = <0x1000000 0x00 0x00 0x00 0x3eff0000 0x00 0x10000 0x2000000 0x00 0x10000000 0x00 0x10000000 0x00 0x2eff0000 0x3000000 0x80 0x00 0x80 0x00 0x80 0x00>; + ranges = <0x1000000 0x00 0x00 0x00 0x3eff0000 0x00 0x10000>, + <0x2000000 0x00 0x10000000 0x00 0x10000000 0x00>, + <0x2eff0000 0x3000000 0x80 0x00 0x80 0x00 0x80 0x00>; reg = <0x40 0x10000000 0x00 0x10000000>; msi-parent = <&gic_ist>; - dma-coherent; bus-range = <0x00 0xff>; - linux,pci-domain = <0x00>; #size-cells = <0x02>; #address-cells = <0x03>; device_type = "pci"; - compatible = "pci-host-ecam-generic"; }; -*/ + pl031@9010000 { clock-names = "apb_pclk"; clocks = <0x8000>; @@ -224,5 +241,27 @@ reg = <0x0 0xf3000000 0x0 DT_SIZE_M(240)>; label = "VM1_MEM"; }; + + /* Define a pci device instance for vm. */ + linux_ivshmem { + compatible = "virt,pci"; + /* ivshmem device */ + type = <0x03>; + domain = <0x01>; + bdf = <0x00>; + /* little endian bar_mask */ + bar_mask0 = <0xfffff000>; + bar_mask1 = <0x00000000>; + bar_mask2 = <0x00000000>; + bar_mask3 = <0x00000000>; + bar_mask4 = <0x00000000>; + bar_mask5 = <0x00000000>; + shmem_region_start = <0x0>; + shmem_dev_id = <0x0>; + shmem_peers = <0x2>; + shmem_protocol = <0x0>; + status = "okay"; + }; + }; }; diff --git a/samples/_zvm/dts/bindings/virt,pci.yaml b/samples/_zvm/dts/bindings/virt,pci.yaml new file mode 100644 index 000000000..2c5510741 --- /dev/null +++ b/samples/_zvm/dts/bindings/virt,pci.yaml @@ -0,0 +1,75 @@ +description: Virtual Machine virtual pci devices. + +compatible: "virt,pci" + +include: base.yaml + +properties: + reg: + required: false + + label: + type: string + + type: + type: int + required: true + description: | + VM's pci device type, including ivshmem, + bridge and common device. See 'virt_pci.h'. + + domain: + type: int + required: true + description: | + PCI device domain. + + bdf: + type: int + required: true + description: | + PCI device address, including bus-device-function. + + bar_mask0: + type: int + required: true + description: | + PCI device base address mask value. + + bar_mask1: + type: int + required: true + + bar_mask2: + type: int + required: true + + bar_mask3: + type: int + required: true + + bar_mask4: + type: int + required: true + + bar_mask5: + type: int + required: true + + shmem_region_start: + type: int + required: true + description: | + shared memory region start. + + shmem_dev_id: + type: int + + shmem_peers: + type: int + + shmem_protocol: + type: int + + status: + type: string diff --git a/samples/_zvm/dts/bindings/vm-dram.yaml b/samples/_zvm/dts/bindings/vm-dram.yaml index 53521ff19..c9c0bd6dc 100644 --- a/samples/_zvm/dts/bindings/vm-dram.yaml +++ b/samples/_zvm/dts/bindings/vm-dram.yaml @@ -7,9 +7,6 @@ properties: type: array required: true - label: - type: string - label: type: string required: true diff --git a/subsys/virtualization/vdev/CMakeLists.txt b/subsys/virtualization/vdev/CMakeLists.txt index 7800e37bb..ce142ea81 100644 --- a/subsys/virtualization/vdev/CMakeLists.txt +++ b/subsys/virtualization/vdev/CMakeLists.txt @@ -29,3 +29,8 @@ zephyr_sources_ifdef( CONFIG_VM_CLOCK_SYSTEM_CONTROLLER virt_clock_syscon.c ) + +zephyr_sources_ifdef( + CONFIG_VM_PCI_BUS_CONTROLLER + virt_pci.c +) \ No newline at end of file diff --git a/subsys/virtualization/vdev/Kconfig b/subsys/virtualization/vdev/Kconfig index 28718a48e..317613840 100644 --- a/subsys/virtualization/vdev/Kconfig +++ b/subsys/virtualization/vdev/Kconfig @@ -103,3 +103,18 @@ config VM_CLOCK_SYSTEM_CONTROLLER_INIT_PRIORITY When virt system clock is init, it judge the initialization priority in POST_KERNLE. endif + +config VM_PCI_BUS_CONTROLLER + bool "VM pci bus controller." + help + PCI bus controller is a bus device that can support mutiple pci device. + +if VM_PCI_BUS_CONTROLLER + +config VM_PCI_BUS_INIT_PRIORITY + int "VM pci bus init priority." + default 68 + help + PCI bus can be initialized in lowest priority of POST_KERNLE. + +endif diff --git a/subsys/virtualization/vdev/virt_pci.c b/subsys/virtualization/vdev/virt_pci.c new file mode 100644 index 000000000..690c149d2 --- /dev/null +++ b/subsys/virtualization/vdev/virt_pci.c @@ -0,0 +1,232 @@ +/* + * Copyright 2024 HNU-ESNL + * Copyright 2024 openEuler SIG-Zephyr + * + * SPDX-License-Identifier: Apache-2.0 + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(ZVM_MODULE_NAME); + +#define VM_PCI_NAME vm_pci_bus + +#define PCIE_BUS_DEVICE DEVICE_DT_GET(DT_ALIAS(vmpcie)) +#define PCIE_ECAM_CONFIG(dev) \ + ((struct pcie_ctrl_config *)(dev)->config) +#define PCIE_ECAM_DATA(dev) \ + ((struct pcie_ecam_data *)(dev)->data) + +#define DEV_DATA(dev) \ + ((struct virt_device_data *)(dev)->data) +#define DEV_CFG(dev) \ + ((struct virt_device_config *)(dev)->cfg) + +#define PCI_CFG(dev) \ + ((struct virt_pci_bus_config *)(DEV_CFG(dev))->device_config) +#define PCI_DATA(dev) \ + ((struct virt_pci_bus_data *)(DEV_DATA(dev))->device_data) + +#define DEFINE_VPCI_DEVICE(node_id) { .type = DT_PROP(node_id, type), \ + .domain = DT_PROP(node_id, domain), \ + .bdf = DT_PROP(node_id, bdf), \ + .bar_mask[0] = DT_PROP(node_id, bar_mask0), \ + .bar_mask[1] = DT_PROP(node_id, bar_mask1), \ + .bar_mask[2] = DT_PROP(node_id, bar_mask2), \ + .bar_mask[3] = DT_PROP(node_id, bar_mask3), \ + .bar_mask[4] = DT_PROP(node_id, bar_mask4), \ + .bar_mask[5] = DT_PROP(node_id, bar_mask5), \ + .shmem_region_start = DT_PROP(node_id, shmem_region_start), \ + .shmem_dev_id = DT_PROP(node_id, shmem_dev_id), \ + .shmem_peers = DT_PROP(node_id, shmem_peers), \ + .shmem_protocol = DT_PROP(node_id, shmem_protocol), \ + }, + +static const struct virtual_device_instance *pci_virtual_device_instance; + +static struct virt_pci_device pci_devices[] = { + DT_FOREACH_STATUS_OKAY(virt_pci, DEFINE_VPCI_DEVICE) +}; + + +int virt_pci_emulation(struct vm *vm, uint64_t pdev_addr, int write, uint64_t *value) +{ + uint32_t wvalue, rvalue; + uint64_t cfg_base, cfg_size, hdev_base; + + wvalue = *(uint32_t *)value; + + cfg_base = DEV_CFG(pci_virtual_device_instance)->reg_base; + cfg_size = DEV_CFG(pci_virtual_device_instance)->reg_size; + hdev_base = PCI_DATA(pci_virtual_device_instance)->pci_hva_base; + + /*configuration space?*/ + if(pdev_addr >= cfg_base && pdev_addr < cfg_base+cfg_size){ + if(write) { + sys_write32(wvalue, pdev_addr-cfg_base + hdev_base); + }else { + rvalue = sys_read32(pdev_addr-cfg_base + hdev_base); + *(uint32_t *)value = rvalue; + } + return 0; + } + + /*pci device space?*/ + return -ENODEV; +} + +/** + * @brief: Get the virtual virtual pci device. +*/ +static int virt_pci_bus_init(const struct device *dev) +{ + ARG_UNUSED(dev); + int i; + + for (i = 0; i < zvm_virtual_devices_count_get(); i++) { + const struct virtual_device_instance *virtual_device = zvm_virtual_device_get(i); + if(strcmp(virtual_device->name, TOSTRING(VM_PCI_NAME))){ + continue; + } + /*Get device info from pcie physical device.*/ + DEV_CFG(virtual_device)->reg_base = PCIE_ECAM_DATA(PCIE_BUS_DEVICE)->cfg_phys_addr; + DEV_CFG(virtual_device)->reg_size = PCIE_ECAM_DATA(PCIE_BUS_DEVICE)->cfg_size; + PCI_DATA(virtual_device)->pci_hva_base = PCIE_ECAM_DATA(PCIE_BUS_DEVICE)->cfg_addr; + printk("cfg_phys_addr: %llx \n", PCIE_ECAM_DATA(PCIE_BUS_DEVICE)->cfg_phys_addr); + printk("cfg_size: %llx \n", PCIE_ECAM_DATA(PCIE_BUS_DEVICE)->cfg_size); + printk("reg_base: %llx \n", DEV_CFG(virtual_device)->reg_base); + + if(!DEV_CFG(virtual_device)->reg_base && !PCI_CFG(virtual_device)->pci_is_virtual){ + ZVM_LOG_ERR("Do not support hardware pci device now.\n"); + return -ENODEV; + } + + DEV_DATA(virtual_device)->vdevice_type |= VM_DEVICE_PRE_KERNEL_1; + pci_virtual_device_instance = virtual_device; + break; + } + return 0; +} + +static struct virt_pci_bus_config pci_bus_priv_cfg = { + .pci_is_virtual = true, + .pci_domain = 1, + .pci_config_end_bus = 0, +}; + +static struct virt_device_config virt_pci_bus_cfg = { + + /*TODO: Irq is unknown.*/ + .hirq_num = VM_DEVICE_INVALID_VIRQ, + + .device_config = &pci_bus_priv_cfg, +}; + +static struct virt_pci_bus_data pci_privdate; + +static struct virt_device_data virt_pci_bus_data_port = { + .device_data = &pci_privdate, +}; + +/** + * @brief init vm clock syscon device for each vm. +*/ +static int vm_pci_bus_init(const struct device *dev, struct vm *vm, struct virt_dev *vdev_desc) +{ + ARG_UNUSED(dev); + int i; + struct virt_dev *vm_dev; + struct virt_pci_device *pci_device; + + /* Is there any pci device exist? */ + switch (vm->os->type) { + case OS_TYPE_LINUX: +#if DT_NODE_EXISTS(DT_ALIAS(vmivshmem0)) + break; +#endif + return 0; + break; + case OS_TYPE_ZEPHYR: +#if DT_NODE_EXISTS(DT_ALIAS(vmivshmem1)) + break; +#endif + return 0; + default: + return 0; + } + + vm_dev = vm_virt_dev_add_no_memmap(vm, pci_virtual_device_instance->name, false, false, + DEV_CFG(pci_virtual_device_instance)->reg_base, PCI_DATA(pci_virtual_device_instance)->pci_hva_base, + DEV_CFG(pci_virtual_device_instance)->reg_size, VM_DEVICE_INVALID_VIRQ, + VM_DEVICE_INVALID_VIRQ); + if(!vm_dev){ + return -ENODEV; + } + + vm_dev->priv_data = pci_virtual_device_instance; + + /* scan the pci devices for getting device info */ +/* + for(i=0; itype == VM_PCI_IVSHMEM){ + ivshmem_init(); + } else{ + printk("Not a ivshmem pci device, not support!"); + } + } +*/ + return 0; +} + +int pci_bus_vdev_mem_read(struct virt_dev *vdev, uint64_t addr, uint64_t *value) +{ + uint32_t read_value; + read_value = sys_read32(addr); + *(uint32_t *)value = read_value; + + printk("Device-%s Read:addr is %llx, value is %x\n", vdev->name, addr, read_value); + + return 0; +} + +int pci_bus_vdev_mem_write(struct virt_dev *vdev, uint64_t addr, uint64_t *value) +{ + uint32_t be_write_value, write_value, af_write_value; + + write_value = *(uint32_t *)value; + be_write_value = sys_read32(addr); + sys_write32(write_value, addr); + af_write_value = sys_read32(addr); + + printk("Device-%s Write:addr is %llx, be_value is %x, ne_value is %x, af_value is %x\n", + vdev->name, addr, be_write_value, write_value, af_write_value); + + return 0; +} + +static const struct virt_device_api virt_pci_bus_api = { + .init_fn = vm_pci_bus_init, + .virt_device_read = pci_bus_vdev_mem_read, + .virt_device_write = pci_bus_vdev_mem_write, +}; + +/* Init virtual pci device. */ +ZVM_VIRTUAL_DEVICE_DEFINE(virt_pci_bus_init, + POST_KERNEL, CONFIG_VM_PCI_BUS_INIT_PRIORITY, + VM_PCI_NAME, + virt_pci_bus_data_port, + virt_pci_bus_cfg, + virt_pci_bus_api); \ No newline at end of file diff --git a/subsys/virtualization/vm_dev.c b/subsys/virtualization/vm_dev.c index 8309f9884..e408791d8 100644 --- a/subsys/virtualization/vm_dev.c +++ b/subsys/virtualization/vm_dev.c @@ -20,6 +20,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(ZVM_MODULE_NAME); @@ -44,8 +45,44 @@ static int vm_vdev_mem_add(struct vm *vm, struct virt_dev *vdev) } +struct virt_dev *vm_virt_dev_add_no_memmap(struct vm *vm, const char *dev_name, bool pt_flag, + bool shareable, uint64_t dev_pbase, uint64_t dev_hva, + uint32_t dev_size, uint32_t dev_hirq, uint32_t dev_virq) +{ + uint16_t name_len; + int ret; + struct virt_dev *vm_dev; + + vm_dev = (struct virt_dev *)k_malloc(sizeof(struct virt_dev)); + if (!vm_dev) { + return NULL; + } + + name_len = strlen(dev_name); + name_len = name_len > VIRT_DEV_NAME_LENGTH ? VIRT_DEV_NAME_LENGTH : name_len; + strncpy(vm_dev->name, dev_name, name_len); + vm_dev->name[name_len] = '\0'; + + vm_dev->dev_pt_flag = pt_flag; + vm_dev->shareable = shareable; + vm_dev->vm_vdev_paddr = dev_pbase; + vm_dev->vm_vdev_vaddr = dev_hva; + vm_dev->vm_vdev_size = dev_size; + vm_dev->virq = dev_virq; + vm_dev->hirq = dev_hirq; + vm_dev->vm = vm; + + /*Init private data and vdev*/ + vm_dev->priv_data = NULL; + vm_dev->priv_vdev = NULL; + + sys_dlist_append(&vm->vdev_list, &vm_dev->vdev_node); + + return vm_dev; +} + struct virt_dev *vm_virt_dev_add(struct vm *vm, const char *dev_name, bool pt_flag, - bool shareable, uint32_t dev_pbase, uint32_t dev_vbase, + bool shareable, uint64_t dev_pbase, uint64_t dev_vbase, uint32_t dev_size, uint32_t dev_hirq, uint32_t dev_virq) { uint16_t name_len; @@ -162,7 +199,7 @@ int vm_vdev_pause(struct vcpu *vcpu) return 0; } -int handle_vm_device_emulate(struct vm *vm, uint64_t pa_addr) +int handle_vm_device_emulate(struct vm *vm, uint64_t pa_addr, int write, uint64_t *value) { bool chosen_flag = false; int ret; @@ -171,6 +208,11 @@ int handle_vm_device_emulate(struct vm *vm, uint64_t pa_addr) struct _dnode *d_node, *ds_node; const struct device *dev; + /* Check whether it is a pci bus device or pci device */ + if(!virt_pci_emulation(vm, pa_addr, write, value)){ + return PCI_TRANSUCESS; + } + 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); @@ -203,7 +245,6 @@ int handle_vm_device_emulate(struct vm *vm, uint64_t pa_addr) ZVM_LOG_WARN(" Init device error! \n"); return -EFAULT; } - return 0; } diff --git a/subsys/virtualization/vm_manager.c b/subsys/virtualization/vm_manager.c index c890d6c6c..3fbf1f07d 100644 --- a/subsys/virtualization/vm_manager.c +++ b/subsys/virtualization/vm_manager.c @@ -8,7 +8,6 @@ #include #include #include - #include #include #include -- Gitee From 0a9dcfe880e1d850d8ef90d49fee5360cb575d49 Mon Sep 17 00:00:00 2001 From: Charlie Xiong <1981639884@qq.com> Date: Sat, 23 Mar 2024 23:53:33 +0800 Subject: [PATCH 3/4] virt:device: add ivshmem pci device Using qemu's command to enable virt board pci device, and adding pci device support for linux vm. bug: only 32 bits address is supported now. Signed-off-by: Charlie Xiong <1981639884@qq.com> --- auto_zvm.sh | 6 +- include/virtualization/vdev/virt_pci.h | 4 + .../_zvm/boards/qemu_cortex_max_smp.overlay | 4 +- subsys/virtualization/vdev/virt_pci.c | 43 +- subsys/virtualization/vm_dev.c | 6 +- .../qemu_platform/hub/linux-qemu-virt.dtb | Bin 2936 -> 2955 bytes zvm_config/qemu_platform/linux-qemu-virt.dts | 92 ++--- .../qemu_platform/linux-qemu-virtio.dts | 106 ----- zvm_config/qemu_platform/qemu.dts | 389 ++++++++++++++++++ 9 files changed, 464 insertions(+), 186 deletions(-) delete mode 100644 zvm_config/qemu_platform/linux-qemu-virtio.dts create mode 100644 zvm_config/qemu_platform/qemu.dts diff --git a/auto_zvm.sh b/auto_zvm.sh index accb561fd..df6dd75a9 100755 --- a/auto_zvm.sh +++ b/auto_zvm.sh @@ -45,8 +45,10 @@ elif [ "$OPS" = "$ops_debug" ]; then -serial chardev:con -mon chardev=con,mode=readline -serial pty -serial pty -smp cpus=4 \ -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/zephyr.bin,addr=0xf2000000,force-raw=on \ -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/Image_oee,addr=0xf3000000,force-raw=on \ - -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/linux-qemu-virt-pcie.dtb,addr=0xf2a00000 \ - -kernel $(pwd)/build/zephyr/zvm_host.elf -s -S + -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/linux-qemu-virt.dtb,addr=0xf2a00000 \ + -object memory-backend-file,id=my_shmem0,size=4M,mem-path=/dev/shm/ivshmem,share=on \ + -device ivshmem-plain,memdev=my_shmem0,id=my_shmem0,addr=0x03,master=on \ + -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/virt_pci.h b/include/virtualization/vdev/virt_pci.h index ea6327641..ae8247e59 100644 --- a/include/virtualization/vdev/virt_pci.h +++ b/include/virtualization/vdev/virt_pci.h @@ -25,8 +25,12 @@ #define VM_PCI_SHMEM_PROTO_VIRTIO_FRONT (0x8000) /* 0x8000..0xbfff */ #define VM_PCI_SHMEM_PROTO_VIRTIO_BACK (0xc000) /* 0xc000..0xffff */ +/* Default is 4MB. */ +#define VM_DEFAULT_PCIDEVICE_SIZE (0x400000) + #define VM_PCI_RANGES_NUM (5) +#define PCI_DEVICE_INIT (1) #define PCI_TRANSUCESS (6) /*Description of virtual pci bus device. */ diff --git a/samples/_zvm/boards/qemu_cortex_max_smp.overlay b/samples/_zvm/boards/qemu_cortex_max_smp.overlay index 0d61a93eb..c1f01f4c6 100644 --- a/samples/_zvm/boards/qemu_cortex_max_smp.overlay +++ b/samples/_zvm/boards/qemu_cortex_max_smp.overlay @@ -182,8 +182,8 @@ 0x1800 0x00 0x00 0x04 0x8005 0x00 0x00 0x00 0x05 0x04>; #interrupt-cells = <0x01>; ranges = <0x1000000 0x00 0x00 0x00 0x3eff0000 0x00 0x10000>, - <0x2000000 0x00 0x10000000 0x00 0x10000000 0x00>, - <0x2eff0000 0x3000000 0x80 0x00 0x80 0x00 0x80 0x00>; + <0x2000000 0x00 0x10000000 0x00 0x10000000 0x00 0x10000000>, + <0x3000000 0x00 0x20000000 0x00 0x20000000 0x00 0x1eff0000>; reg = <0x40 0x10000000 0x00 0x10000000>; msi-parent = <&gic_ist>; bus-range = <0x00 0xff>; diff --git a/subsys/virtualization/vdev/virt_pci.c b/subsys/virtualization/vdev/virt_pci.c index 690c149d2..0bcad81bd 100644 --- a/subsys/virtualization/vdev/virt_pci.c +++ b/subsys/virtualization/vdev/virt_pci.c @@ -60,19 +60,20 @@ static struct virt_pci_device pci_devices[] = { DT_FOREACH_STATUS_OKAY(virt_pci, DEFINE_VPCI_DEVICE) }; - int virt_pci_emulation(struct vm *vm, uint64_t pdev_addr, int write, uint64_t *value) { + int i; uint32_t wvalue, rvalue; uint64_t cfg_base, cfg_size, hdev_base; + uint64_t range_base, range_size; + struct virt_dev *vdev; wvalue = *(uint32_t *)value; - cfg_base = DEV_CFG(pci_virtual_device_instance)->reg_base; cfg_size = DEV_CFG(pci_virtual_device_instance)->reg_size; hdev_base = PCI_DATA(pci_virtual_device_instance)->pci_hva_base; - /*configuration space?*/ + /*pci bus configuration space?*/ if(pdev_addr >= cfg_base && pdev_addr < cfg_base+cfg_size){ if(write) { sys_write32(wvalue, pdev_addr-cfg_base + hdev_base); @@ -84,6 +85,23 @@ int virt_pci_emulation(struct vm *vm, uint64_t pdev_addr, int write, uint64_t *v } /*pci device space?*/ + for(i=0; iregions[i].phys_start; + range_size = PCIE_ECAM_DATA(PCIE_BUS_DEVICE)->regions[i].size; + if(pdev_addr >= range_base && pdev_addr < range_base+range_size){ + vdev = vm_virt_dev_add(vm, "vm_pci", true, false, pdev_addr, + pdev_addr, VM_DEFAULT_PCIDEVICE_SIZE, + VM_DEVICE_INVALID_VIRQ, VM_DEVICE_INVALID_VIRQ); + if(!vdev){ + ZVM_LOG_WARN("VM pci device init error!"); + return -ENODEV; + } + ZVM_LOG_INFO("Mapping pci device, address: %llx \n", pdev_addr); + return PCI_DEVICE_INIT; + /*@TODO:pci passthrough interrupt is not consider now.*/ + } + } + return -ENODEV; } @@ -178,16 +196,15 @@ static int vm_pci_bus_init(const struct device *dev, struct vm *vm, struct virt_ vm_dev->priv_data = pci_virtual_device_instance; /* scan the pci devices for getting device info */ -/* - for(i=0; itype == VM_PCI_IVSHMEM){ - ivshmem_init(); - } else{ - printk("Not a ivshmem pci device, not support!"); - } - } -*/ + // for(i=0; itype == VM_PCI_IVSHMEM){ + // ivshmem_init(); + // } else{ + // printk("Not a ivshmem pci device, not support!"); + // } + // } + return 0; } diff --git a/subsys/virtualization/vm_dev.c b/subsys/virtualization/vm_dev.c index e408791d8..a9bda18bf 100644 --- a/subsys/virtualization/vm_dev.c +++ b/subsys/virtualization/vm_dev.c @@ -209,8 +209,12 @@ int handle_vm_device_emulate(struct vm *vm, uint64_t pa_addr, int write, uint64_ const struct device *dev; /* Check whether it is a pci bus device or pci device */ - if(!virt_pci_emulation(vm, pa_addr, write, value)){ + ret = virt_pci_emulation(vm, pa_addr, write, value); + if(!ret){ return PCI_TRANSUCESS; + } else if(ret > 0){ + /*Add pci device, but no passthrough interrupt.*/ + return 0; } vdev_list = get_zvm_dev_lists(); diff --git a/zvm_config/qemu_platform/hub/linux-qemu-virt.dtb b/zvm_config/qemu_platform/hub/linux-qemu-virt.dtb index 6010ff28c2d6ee3fce309279fbb29f1537ee4996..3d4b934cd117c8569f12f95465e9a545ada1d240 100644 GIT binary patch literal 2955 zcmZuzJ#Qs76!nA!HZ03RgAfuZQW}b9Hdz)Dn&pWCQ6MTRnkQ$*$s1+9*7k&Cg-{9# z5G557zkt864MMa?bnp{s=nz6eS~$lZ&+{Z>>5hG`ukSg&zV>^+-hT3@5VyV&LL3UQ z{SW##ATL2)grH^L!v3QlPCwb8K85~97+-Fok2+(d`fG{KxkXhr{rRHk>-s{TmBzuw zmUT8S!*Gms@Usw4!xm$|2c6@nfAHlL>toE5U!4Ec);U8`e;Kk+rd|+7?!9?WM1>w9 zPFCx>H5beKd!fA!yNSqybp=Z)NZ#(kCTs;gsh9f+^G&R;g?J@|314zXtgTD*-v`t9MgA`1 z8Al^=$t`Wbyyi!rtA1E}&5vh#)erhLzh{Eq%@lWz-+(*uo8vd&PW0b})IZby3S*GitM=n319yyMo;+c&vW z7^Sn=mfsjmV=V58^OQ07H{|&d z&fqI+)p0JfZGNiVo*(B`Z=E(?@qVq*gEGX(9)LSz5Hl6VTuy!c*~L6FX9~i`SmS>3 z);N7G)!PT-9DOz7(GW2*hoUpy#jht6e?uAnHaf21_=RMQvmNcIgs~Rs`aVA7u>(o! zGNAA;0_*fZj;Q33;hxDW_l&qaPjo&W>N5KXSMlEcdi{t-w3xe9*1VJI{zrV6=e=1R zm*={Wd4(gPpU2GcIOv9|kAu8rpWp4SJqpA?1!Z47S$(+myZUYgJ?3s3_e&eocTRT7 z=*Ed%TRzf~ci4(uRTM^BJE(bEcgmGVl@@h*VwBSYN3m*~&>bK9-uAZBO(AOS)@>n- zJ`sgJD|5Ya7o8SGtz_P=wFeu~tr&+aKZre@n#AtLBd{~7Inh?swv615dMmwEguj%0 zK#R6kB^WYuvQafw_^}n;S~UgsvTJlvT4&0m-nB-8aM?B~p}cLJX{!oFMzBO>C93K( sbzvp5;4#|Xb-hcWHCIetd3jX1+tBfq{Y1<0t$ODC4;q!Vb{uo*Va_9R&nfF`H-~= zphb@1fZE)xCz0XqCjS6%=J40Me>7c`K_FW9Q@xtn!RgCx2i)%s6NA z7PcTJh9#3Z*n{{O4guAH5)>#tuTRckmj}vsuxl|fyqLU&y^o3E`(zgmZJ<~I$1Em> z-;;Sby)EZ3Ff;&FgSBx2(-muSPPUOrZblVI5D1{gF-kDznIZEvCQslrmo?Qd$T2W9 zbg%>_P9T8m07fmN; - reg = <0x00 0xa000000 0x00 0x200>; + interrupts = <0x00 0x10 0x04>; + reg = <0x00 0xa000000 0x00 0x1000>; compatible = "virtio,mmio"; }; - virtio_mmio@a000200 { + pcie@10000000 { + interrupt-map-mask = <0x1800 0x00 0x00 0x07>; + interrupt-map = <0x00 0x00 0x00 0x01 0x8001 0x00 0x00 0x00 0x03 0x04 + 0x00 0x00 0x00 0x02 0x8001 0x00 0x00 0x00 0x04 0x04 + 0x00 0x00 0x00 0x03 0x8001 0x00 0x00 0x00 0x05 0x04 + 0x00 0x00 0x00 0x04 0x8001 0x00 0x00 0x00 0x06 0x04 + 0x800 0x00 0x00 0x01 0x8001 0x00 0x00 0x00 0x04 0x04 + 0x800 0x00 0x00 0x02 0x8001 0x00 0x00 0x00 0x05 0x04 + 0x800 0x00 0x00 0x03 0x8001 0x00 0x00 0x00 0x06 0x04 + 0x800 0x00 0x00 0x04 0x8001 0x00 0x00 0x00 0x03 0x04 + 0x1000 0x00 0x00 0x01 0x8001 0x00 0x00 0x00 0x05 0x04 + 0x1000 0x00 0x00 0x02 0x8001 0x00 0x00 0x00 0x06 0x04 + 0x1000 0x00 0x00 0x03 0x8001 0x00 0x00 0x00 0x03 0x04 + 0x1000 0x00 0x00 0x04 0x8001 0x00 0x00 0x00 0x04 0x04 + 0x1800 0x00 0x00 0x01 0x8001 0x00 0x00 0x00 0x06 0x04 + 0x1800 0x00 0x00 0x02 0x8001 0x00 0x00 0x00 0x03 0x04 + 0x1800 0x00 0x00 0x03 0x8001 0x00 0x00 0x00 0x04 0x04 + 0x1800 0x00 0x00 0x04 0x8001 0x00 0x00 0x00 0x05 0x04>; + #interrupt-cells = <0x01>; + ranges = <0x1000000 0x00 0x00 0x00 0x3eff0000 0x00 0x10000 0x2000000 0x00 0x10000000 0x00 0x10000000 0x00 0x10000000 0x3000000 0x00 0x20000000 0x00 0x20000000 0x00 0x1eff0000>; + reg = <0x40 0x10000000 0x00 0x10000000>; + msi-parent = <0x8003>; dma-coherent; - interrupts = <0x00 0x11 0x01>; - reg = <0x00 0xa000200 0x00 0x200>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@a000400 { - dma-coherent; - interrupts = <0x00 0x12 0x01>; - reg = <0x00 0xa000400 0x00 0x200>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@a000600 { - dma-coherent; - interrupts = <0x00 0x13 0x01>; - reg = <0x00 0xa000600 0x00 0x200>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@a000800 { - dma-coherent; - interrupts = <0x00 0x14 0x01>; - reg = <0x00 0xa000800 0x00 0x200>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@a000a00 { - dma-coherent; - interrupts = <0x00 0x15 0x01>; - reg = <0x00 0xa000a00 0x00 0x200>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@a000c00 { - dma-coherent; - interrupts = <0x00 0x16 0x01>; - reg = <0x00 0xa000c00 0x00 0x200>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@a000e00 { - dma-coherent; - interrupts = <0x00 0x17 0x01>; - reg = <0x00 0xa000e00 0x00 0x200>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@a001000 { - dma-coherent; - interrupts = <0x00 0x18 0x01>; - reg = <0x00 0xa001000 0x00 0x200>; - compatible = "virtio,mmio"; - }; - - virtio_mmio@a001200 { - dma-coherent; - interrupts = <0x00 0x19 0x01>; - reg = <0x00 0xa001200 0x00 0x200>; - compatible = "virtio,mmio"; + bus-range = <0x00 0xff>; + linux,pci-domain = <0x00>; + #size-cells = <0x02>; + #address-cells = <0x03>; + device_type = "pci"; + compatible = "pci-host-ecam-generic"; }; pl011@9000000 { diff --git a/zvm_config/qemu_platform/linux-qemu-virtio.dts b/zvm_config/qemu_platform/linux-qemu-virtio.dts deleted file mode 100644 index 33502b4a1..000000000 --- a/zvm_config/qemu_platform/linux-qemu-virtio.dts +++ /dev/null @@ -1,106 +0,0 @@ -/dts-v1/; - -/ { - interrupt-parent = <0x8002>; - #size-cells = <0x2>; - #address-cells = <0x2>; - compatible = "linux,dummy-virt"; - - psci { - migrate = <0xc4000005>; - cpu_on = <0xc4000003>; - cpu_off = <0x84000002>; - cpu_suspend = <0xc4000001>; - method = "smc"; - compatible = "arm,psci-0.2", "arm,psci"; - }; - - memory@40000000 { - reg = <0x0 0x40000000 0x0 0x40000000>; - device_type = "memory"; - }; - - virtio_mmio@a000000 { - dma-coherent; - interrupts = <0x00 0x10 0x04>; - reg = <0x00 0xa000000 0x00 0x1000>; - compatible = "virtio,mmio"; - }; - - pl011@9000000 { - clock-names = "uartclk", "apb_pclk"; - clocks = <0x8000 0x8000>; - interrupts = <0x0 0x1 0x4>; - reg = <0x0 0x09000000 0x0 0x1000>; - compatible = "arm,pl011", "arm,primecell"; - }; - - pmu { - interrupts = <0x1 0x7 0x104>; - compatible = "arm,armv8-pmuv3"; - }; - - intc@8000000 { - phandle = <0x8002>; - interrupts = <0x1 0x9 0x4>; - reg = <0x0 0x8000000 0x0 0x10000 0x0 0x80a0000 0x0 0xf60000>; - #redistributor-regions = <0x1>; - compatible = "arm,gic-v3"; - ranges; - #size-cells = <0x2>; - #address-cells = <0x2>; - interrupt-controller; - #interrupt-cells = <0x3>; - - its@8080000 { - phandle = <0x8003>; - reg = <0x0 0x8080000 0x0 0x20000>; - msi-controller; - compatible = "arm,gic-v3-its"; - }; - }; - - cpus { - #size-cells = <0x0>; - #address-cells = <0x1>; - - cpu-map { - - socket0 { - - cluster0 { - - core0 { - cpu = <0x8001>; - }; - }; - }; - }; - - cpu@0 { - phandle = <0x8001>; - reg = <0x0>; - compatible = "arm,cortex-a57"; - device_type = "cpu"; - }; - }; - - timer { - interrupts = <0x1 0xd 0x104 0x1 0xe 0x104 0x1 0xb 0x104 0x1 0xa 0x104>; - always-on; - compatible = "arm,armv8-timer", "arm,armv7-timer"; - }; - - apb-pclk { - phandle = <0x8000>; - clock-output-names = "clk24mhz"; - clock-frequency = <0x16e3600>; - #clock-cells = <0x0>; - compatible = "fixed-clock"; - }; - - chosen { - stdout-path = "/pl011@9000000"; - kaslr-seed = <0xfe5f4802 0xd861995f>; - }; -}; diff --git a/zvm_config/qemu_platform/qemu.dts b/zvm_config/qemu_platform/qemu.dts new file mode 100644 index 000000000..4d5307b84 --- /dev/null +++ b/zvm_config/qemu_platform/qemu.dts @@ -0,0 +1,389 @@ +/dts-v1/; + +/ { + interrupt-parent = <0x8001>; + #size-cells = <0x02>; + #address-cells = <0x02>; + compatible = "linux,dummy-virt"; + + psci { + migrate = <0xc4000005>; + cpu_on = <0xc4000003>; + cpu_off = <0x84000002>; + cpu_suspend = <0xc4000001>; + method = "hvc"; + compatible = "arm,psci-0.2\0arm,psci"; + }; + + memory@40000000 { + reg = <0x00 0x40000000 0x00 0x40000000>; + device_type = "memory"; + }; + + platform@c000000 { + interrupt-parent = <0x8001>; + ranges = <0x00 0x00 0xc000000 0x2000000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + compatible = "qemu,platform\0simple-bus"; + }; + + fw-cfg@9020000 { + dma-coherent; + reg = <0x00 0x9020000 0x00 0x18>; + compatible = "qemu,fw-cfg-mmio"; + }; + + virtio_mmio@a000000 { + dma-coherent; + interrupts = <0x00 0x10 0x01>; + reg = <0x00 0xa000000 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a000200 { + dma-coherent; + interrupts = <0x00 0x11 0x01>; + reg = <0x00 0xa000200 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a000400 { + dma-coherent; + interrupts = <0x00 0x12 0x01>; + reg = <0x00 0xa000400 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a000600 { + dma-coherent; + interrupts = <0x00 0x13 0x01>; + reg = <0x00 0xa000600 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a000800 { + dma-coherent; + interrupts = <0x00 0x14 0x01>; + reg = <0x00 0xa000800 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a000a00 { + dma-coherent; + interrupts = <0x00 0x15 0x01>; + reg = <0x00 0xa000a00 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a000c00 { + dma-coherent; + interrupts = <0x00 0x16 0x01>; + reg = <0x00 0xa000c00 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a000e00 { + dma-coherent; + interrupts = <0x00 0x17 0x01>; + reg = <0x00 0xa000e00 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a001000 { + dma-coherent; + interrupts = <0x00 0x18 0x01>; + reg = <0x00 0xa001000 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a001200 { + dma-coherent; + interrupts = <0x00 0x19 0x01>; + reg = <0x00 0xa001200 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a001400 { + dma-coherent; + interrupts = <0x00 0x1a 0x01>; + reg = <0x00 0xa001400 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a001600 { + dma-coherent; + interrupts = <0x00 0x1b 0x01>; + reg = <0x00 0xa001600 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a001800 { + dma-coherent; + interrupts = <0x00 0x1c 0x01>; + reg = <0x00 0xa001800 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a001a00 { + dma-coherent; + interrupts = <0x00 0x1d 0x01>; + reg = <0x00 0xa001a00 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a001c00 { + dma-coherent; + interrupts = <0x00 0x1e 0x01>; + reg = <0x00 0xa001c00 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a001e00 { + dma-coherent; + interrupts = <0x00 0x1f 0x01>; + reg = <0x00 0xa001e00 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a002000 { + dma-coherent; + interrupts = <0x00 0x20 0x01>; + reg = <0x00 0xa002000 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a002200 { + dma-coherent; + interrupts = <0x00 0x21 0x01>; + reg = <0x00 0xa002200 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a002400 { + dma-coherent; + interrupts = <0x00 0x22 0x01>; + reg = <0x00 0xa002400 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a002600 { + dma-coherent; + interrupts = <0x00 0x23 0x01>; + reg = <0x00 0xa002600 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a002800 { + dma-coherent; + interrupts = <0x00 0x24 0x01>; + reg = <0x00 0xa002800 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a002a00 { + dma-coherent; + interrupts = <0x00 0x25 0x01>; + reg = <0x00 0xa002a00 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a002c00 { + dma-coherent; + interrupts = <0x00 0x26 0x01>; + reg = <0x00 0xa002c00 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a002e00 { + dma-coherent; + interrupts = <0x00 0x27 0x01>; + reg = <0x00 0xa002e00 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a003000 { + dma-coherent; + interrupts = <0x00 0x28 0x01>; + reg = <0x00 0xa003000 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a003200 { + dma-coherent; + interrupts = <0x00 0x29 0x01>; + reg = <0x00 0xa003200 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a003400 { + dma-coherent; + interrupts = <0x00 0x2a 0x01>; + reg = <0x00 0xa003400 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a003600 { + dma-coherent; + interrupts = <0x00 0x2b 0x01>; + reg = <0x00 0xa003600 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a003800 { + dma-coherent; + interrupts = <0x00 0x2c 0x01>; + reg = <0x00 0xa003800 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a003a00 { + dma-coherent; + interrupts = <0x00 0x2d 0x01>; + reg = <0x00 0xa003a00 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a003c00 { + dma-coherent; + interrupts = <0x00 0x2e 0x01>; + reg = <0x00 0xa003c00 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + virtio_mmio@a003e00 { + dma-coherent; + interrupts = <0x00 0x2f 0x01>; + reg = <0x00 0xa003e00 0x00 0x200>; + compatible = "virtio,mmio"; + }; + + gpio-keys { + #address-cells = <0x01>; + #size-cells = <0x00>; + compatible = "gpio-keys"; + + poweroff { + gpios = <0x8003 0x03 0x00>; + linux,code = <0x74>; + label = "GPIO Key Poweroff"; + }; + }; + + pl061@9030000 { + phandle = <0x8003>; + clock-names = "apb_pclk"; + clocks = <0x8000>; + interrupts = <0x00 0x07 0x04>; + gpio-controller; + #gpio-cells = <0x02>; + compatible = "arm,pl061\0arm,primecell"; + reg = <0x00 0x9030000 0x00 0x1000>; + }; + + pcie@10000000 { + interrupt-map-mask = <0x1800 0x00 0x00 0x07>; + interrupt-map = <0x00 0x00 0x00 0x01 0x8001 0x00 0x00 0x00 0x03 0x04 + 0x00 0x00 0x00 0x02 0x8001 0x00 0x00 0x00 0x04 0x04 + 0x00 0x00 0x00 0x03 0x8001 0x00 0x00 0x00 0x05 0x04 + 0x00 0x00 0x00 0x04 0x8001 0x00 0x00 0x00 0x06 0x04 + 0x800 0x00 0x00 0x01 0x8001 0x00 0x00 0x00 0x04 0x04 + 0x800 0x00 0x00 0x02 0x8001 0x00 0x00 0x00 0x05 0x04 + 0x800 0x00 0x00 0x03 0x8001 0x00 0x00 0x00 0x06 0x04 + 0x800 0x00 0x00 0x04 0x8001 0x00 0x00 0x00 0x03 0x04 + 0x1000 0x00 0x00 0x01 0x8001 0x00 0x00 0x00 0x05 0x04 + 0x1000 0x00 0x00 0x02 0x8001 0x00 0x00 0x00 0x06 0x04 + 0x1000 0x00 0x00 0x03 0x8001 0x00 0x00 0x00 0x03 0x04 + 0x1000 0x00 0x00 0x04 0x8001 0x00 0x00 0x00 0x04 0x04 + 0x1800 0x00 0x00 0x01 0x8001 0x00 0x00 0x00 0x06 0x04 + 0x1800 0x00 0x00 0x02 0x8001 0x00 0x00 0x00 0x03 0x04 + 0x1800 0x00 0x00 0x03 0x8001 0x00 0x00 0x00 0x04 0x04 + 0x1800 0x00 0x00 0x04 0x8001 0x00 0x00 0x00 0x05 0x04>; + #interrupt-cells = <0x01>; + ranges = <0x1000000 0x00 0x00 0x00 0x3eff0000 0x00 0x10000 0x2000000 0x00 0x10000000 0x00 0x10000000 0x00 0x2eff0000 0x3000000 0x80 0x00 0x80 0x00 0x80 0x00>; + reg = <0x40 0x10000000 0x00 0x10000000>; + msi-parent = <0x8002>; + dma-coherent; + bus-range = <0x00 0xff>; + linux,pci-domain = <0x00>; + #size-cells = <0x02>; + #address-cells = <0x03>; + device_type = "pci"; + compatible = "pci-host-ecam-generic"; + }; + + pl031@9010000 { + clock-names = "apb_pclk"; + clocks = <0x8000>; + interrupts = <0x00 0x02 0x04>; + reg = <0x00 0x9010000 0x00 0x1000>; + compatible = "arm,pl031\0arm,primecell"; + }; + + pl011@9000000 { + clock-names = "uartclk\0apb_pclk"; + clocks = <0x8000 0x8000>; + interrupts = <0x00 0x01 0x04>; + reg = <0x00 0x9000000 0x00 0x1000>; + compatible = "arm,pl011\0arm,primecell"; + }; + + pmu { + interrupts = <0x01 0x07 0x104>; + compatible = "arm,armv8-pmuv3"; + }; + + intc@8000000 { + phandle = <0x8001>; + reg = <0x00 0x8000000 0x00 0x10000 0x00 0x8010000 0x00 0x10000>; + compatible = "arm,cortex-a15-gic"; + ranges; + #size-cells = <0x02>; + #address-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x03>; + + v2m@8020000 { + phandle = <0x8002>; + reg = <0x00 0x8020000 0x00 0x1000>; + msi-controller; + compatible = "arm,gic-v2m-frame"; + }; + }; + + flash@0 { + bank-width = <0x04>; + reg = <0x00 0x00 0x00 0x4000000 0x00 0x4000000 0x00 0x4000000>; + compatible = "cfi-flash"; + }; + + cpus { + #size-cells = <0x00>; + #address-cells = <0x01>; + + cpu@0 { + reg = <0x00>; + compatible = "arm,cortex-a57"; + device_type = "cpu"; + }; + }; + + timer { + interrupts = <0x01 0x0d 0x104 0x01 0x0e 0x104 0x01 0x0b 0x104 0x01 0x0a 0x104>; + always-on; + compatible = "arm,armv8-timer\0arm,armv7-timer"; + }; + + apb-pclk { + phandle = <0x8000>; + clock-output-names = "clk24mhz"; + clock-frequency = <0x16e3600>; + #clock-cells = <0x00>; + compatible = "fixed-clock"; + }; + + chosen { + stdout-path = "/pl011@9000000"; + kaslr-seed = <0x62527fe1 0x768290b5>; + }; +}; -- Gitee From 710d7be937e4fc06f7f65059897e9932d127777b Mon Sep 17 00:00:00 2001 From: zjwang <13435138+zjwangzj@user.noreply.gitee.com> Date: Mon, 15 Apr 2024 17:43:43 +0800 Subject: [PATCH 4/4] Shared memory: Provides a shared memory to support communication between two virtual machines. Signed-off-by: zjwang <13435138+zjwangzj@user.noreply.gitee.com> --- arch/arm64/core/virtualization/trap_handler.c | 2 +- include/virtualization/vdev/shmem.h | 42 +++++ samples/_zvm/boards/qemu_cortex_max_smp.conf | 1 + .../_zvm/boards/qemu_cortex_max_smp.overlay | 10 +- samples/_zvm/src/main.c | 6 + soc/arm64/qemu_cortex_max/mmu_regions.c | 4 + subsys/virtualization/vdev/CMakeLists.txt | 5 + subsys/virtualization/vdev/Kconfig | 14 ++ subsys/virtualization/vdev/shmem.c | 176 ++++++++++++++++++ subsys/virtualization/vdev/virt_pci.c | 35 ++-- subsys/virtualization/vm_dev.c | 26 ++- subsys/virtualization/vm_mm.c | 2 +- .../qemu_platform/hub/linux-qemu-virt.dtb | Bin 2955 -> 2955 bytes zvm_config/qemu_platform/linux-qemu-virt.dtb | Bin 0 -> 2955 bytes zvm_config/qemu_platform/linux-qemu-virt.dts | 4 +- 15 files changed, 296 insertions(+), 31 deletions(-) create mode 100644 include/virtualization/vdev/shmem.h create mode 100644 subsys/virtualization/vdev/shmem.c create mode 100644 zvm_config/qemu_platform/linux-qemu-virt.dtb diff --git a/arch/arm64/core/virtualization/trap_handler.c b/arch/arm64/core/virtualization/trap_handler.c index d247543c5..ad74ad9cd 100644 --- a/arch/arm64/core/virtualization/trap_handler.c +++ b/arch/arm64/core/virtualization/trap_handler.c @@ -118,7 +118,7 @@ static int handle_faccess_desc(int iss_dfsc, uint64_t pa_addr, ZVM_LOG_WARN("Handle mmio read/write failed! The addr: %llx \n", addr); return -ENODEV; } - return 0; + return ret; } static int cpu_unknwn_sync(arch_commom_regs_t *arch_ctxt, uint64_t esr_elx) diff --git a/include/virtualization/vdev/shmem.h b/include/virtualization/vdev/shmem.h new file mode 100644 index 000000000..aadc15d6c --- /dev/null +++ b/include/virtualization/vdev/shmem.h @@ -0,0 +1,42 @@ +/* + * Copyright 2023 HNU-ESNL + * Copyright 2023 openEuler SIG-Zephyr + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ZVM_VDEV_SHMEM_H_ +#define ZEPHYR_INCLUDE_ZVM_VDEV_SHMEM_H_ + +#include +#include +#include +#include +#include + +/** + * @brief shared memory devive config. + */ +struct shared_mem_config +{ + uint64_t base; + uint64_t size; +}; + +/** + * @brief virt memory device + */ +struct mem_vdevice { + uint64_t mem_base; + uint64_t mem_size; +}; + +/** + * @brief init vm mem device for the 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); + + +#endif diff --git a/samples/_zvm/boards/qemu_cortex_max_smp.conf b/samples/_zvm/boards/qemu_cortex_max_smp.conf index e96e176ed..26582c292 100644 --- a/samples/_zvm/boards/qemu_cortex_max_smp.conf +++ b/samples/_zvm/boards/qemu_cortex_max_smp.conf @@ -34,6 +34,7 @@ CONFIG_ZVM_LINUX_MAX_XLAT_TABLES=8192 # enable vm device below: CONFIG_VM_VIRTIO_MMIO=y CONFIG_VM_VIRTIO_BLOCK=y +CONFIG_VM_MEM=y # 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 c1f01f4c6..a1c202f4d 100644 --- a/samples/_zvm/boards/qemu_cortex_max_smp.overlay +++ b/samples/_zvm/boards/qemu_cortex_max_smp.overlay @@ -26,6 +26,7 @@ vmpmu = "/soc/pmu"; vmflash = "/soc/flash@0"; vmivshmem0 = "/vm_linux_space/linux_ivshmem"; + vmvirtmem = "/soc/virtmem@10000000"; }; chosen { @@ -205,6 +206,13 @@ compatible = "arm,armv8-pmuv3"; }; + virtmem@10000000 { + compatible = "arm,mem"; + device_type = "memory"; + reg = <0x00 0x10000000 0x00 0x1000>; + label = "VM_MEM"; + }; + }; vm_zephyr_space { @@ -236,7 +244,7 @@ compatible = "vm-dram"; memmap_type = "direct"; address_type = "normal_memory"; - vm_reg_base = <0x40000000>; + vm_reg_base = <0x50000000>; vm_reg_size = ; reg = <0x0 0xf3000000 0x0 DT_SIZE_M(240)>; label = "VM1_MEM"; diff --git a/samples/_zvm/src/main.c b/samples/_zvm/src/main.c index 0e42864b7..0e3a3ac9c 100644 --- a/samples/_zvm/src/main.c +++ b/samples/_zvm/src/main.c @@ -14,6 +14,12 @@ #include #include #include +#include +#include +#include + +#define DEV_CFG(dev) ((const struct virt_device_config *const)(dev)->config) +#define DEV_DATA(dev) ((struct virt_device_data *)(dev)->data) /* For test time slice vm change */ int main(int argc, char **argv) diff --git a/soc/arm64/qemu_cortex_max/mmu_regions.c b/soc/arm64/qemu_cortex_max/mmu_regions.c index a7cd789ce..400b15367 100644 --- a/soc/arm64/qemu_cortex_max/mmu_regions.c +++ b/soc/arm64/qemu_cortex_max/mmu_regions.c @@ -25,6 +25,10 @@ static const struct arm_mmu_region mmu_regions[] = { DT_REG_ADDR(DT_INST(0, arm_pl011)), DT_REG_SIZE(DT_INST(0, arm_pl011)), MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE), + MMU_REGION_FLAT_ENTRY("PCI_MEM", + 0x10000000, + 0x4000000, + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE), #if defined(CONFIG_ZVM) MMU_REGION_FLAT_ENTRY("UART1", diff --git a/subsys/virtualization/vdev/CMakeLists.txt b/subsys/virtualization/vdev/CMakeLists.txt index ce142ea81..afac5742e 100644 --- a/subsys/virtualization/vdev/CMakeLists.txt +++ b/subsys/virtualization/vdev/CMakeLists.txt @@ -33,4 +33,9 @@ zephyr_sources_ifdef( zephyr_sources_ifdef( CONFIG_VM_PCI_BUS_CONTROLLER virt_pci.c +) + +zephyr_sources_ifdef( + CONFIG_VM_MEM + shmem.c ) \ No newline at end of file diff --git a/subsys/virtualization/vdev/Kconfig b/subsys/virtualization/vdev/Kconfig index 317613840..85f55d662 100644 --- a/subsys/virtualization/vdev/Kconfig +++ b/subsys/virtualization/vdev/Kconfig @@ -118,3 +118,17 @@ config VM_PCI_BUS_INIT_PRIORITY PCI bus can be initialized in lowest priority of POST_KERNLE. endif + +config VM_MEM + bool "VM MEM that get from vm." + help + This option is used for building memory that get from overlay. + +if VM_MEM +config MEM_INIT_PRIORITY + int "VM virt mem init priority." + default 59 + 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 new file mode 100644 index 000000000..0275de63a --- /dev/null +++ b/subsys/virtualization/vdev/shmem.c @@ -0,0 +1,176 @@ +/* + * 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 +#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) + +#define ZEPHYR_SHMEM_ADDR 0x40300000 + + +static struct virtual_device_instance *mem_instance; + +/** + * @brief Initialize virtual memory device +*/ +static int vm_virt_mem_init(const struct device *dev, struct vm *vm, struct virt_dev *vdev_desc) +{ + struct virt_dev *vdev; + struct mem_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_MEM"; + mem = (struct mem_vdevice *)k_malloc(sizeof(struct mem_vdevice)); + if (!mem) { + ZVM_LOG_ERR("Allocate memory for mem error \n"); + return -ENODEV; + } + mem->mem_base = DT_REG_ADDR(DT_ALIAS(vmvirtmem)); + mem->mem_size = DT_REG_SIZE(DT_ALIAS(vmvirtmem)); + + 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(vmvirtmem)), + ZEPHYR_SHMEM_ADDR, + vm_dev->vm_vdev_size, + VM_DEVICE_INVALID_VIRQ, VM_DEVICE_INVALID_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); + ZVM_LOG_INFO("** Add %s device to vm successful. \n", dev->name); + + return 0; + } + return -ENODEV; +} + +/** + * @brief Memory read operation +*/ +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); + *(uint64_t *)value = read_value; + return read_value; +} + +/** + * @brief Memory write operation +*/ +int memory_write(struct virt_dev *vdev, uint64_t addr, uint64_t *value) +{ + uint64_t *hva; + uint64_t value_w = *(uint64_t *)value; + + sys_write64(value_w, vdev->vm_vdev_paddr); + return 0; +} + +static const struct virt_device_api virt_mem_api = { + .init_fn = vm_virt_mem_init, + .virt_device_write = memory_write, + .virt_device_read = memory_read, +}; + +static int mem_init(const struct device *dev) +{ + dev->state->init_res = VM_DEVICE_INIT_RES; + return 0; +} + +int vm_mem_create(struct vm *vm) +{ + int ret = 0; + const struct device *dev = DEVICE_DT_GET(DT_ALIAS(vmvirtmem)); + + 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 device api! \n"); + return -ENODEV; + } + return ret; +} + +#ifdef CONFIG_VM_MEM +static struct shared_mem_config mem_data_port = { + .base = DT_REG_ADDR(DT_ALIAS(vmvirtmem)), + .size = DT_REG_SIZE(DT_ALIAS(vmvirtmem)), +}; + +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(vmvirtmem)), + .reg_size = DT_REG_SIZE(DT_ALIAS(vmvirtmem)), + .device_config = &virt_mem_data_port, +}; +/** + * @brief Define the mem description for zvm. +*/ +DEVICE_DT_DEFINE(DT_ALIAS(vmvirtmem), + &mem_init, + NULL, + &virt_mem_data_port, + &virt_mem_cfg, POST_KERNEL, + CONFIG_MEM_INIT_PRIORITY, + &virt_mem_api); +#endif /* CONFIG_VM_MEM */ \ No newline at end of file diff --git a/subsys/virtualization/vdev/virt_pci.c b/subsys/virtualization/vdev/virt_pci.c index 0bcad81bd..86a08bb5b 100644 --- a/subsys/virtualization/vdev/virt_pci.c +++ b/subsys/virtualization/vdev/virt_pci.c @@ -63,12 +63,12 @@ static struct virt_pci_device pci_devices[] = { int virt_pci_emulation(struct vm *vm, uint64_t pdev_addr, int write, uint64_t *value) { int i; - uint32_t wvalue, rvalue; + uint64_t wvalue, rvalue; uint64_t cfg_base, cfg_size, hdev_base; uint64_t range_base, range_size; struct virt_dev *vdev; - wvalue = *(uint32_t *)value; + wvalue = *(uint64_t *)value; cfg_base = DEV_CFG(pci_virtual_device_instance)->reg_base; cfg_size = DEV_CFG(pci_virtual_device_instance)->reg_size; hdev_base = PCI_DATA(pci_virtual_device_instance)->pci_hva_base; @@ -76,10 +76,10 @@ int virt_pci_emulation(struct vm *vm, uint64_t pdev_addr, int write, uint64_t *v /*pci bus configuration space?*/ if(pdev_addr >= cfg_base && pdev_addr < cfg_base+cfg_size){ if(write) { - sys_write32(wvalue, pdev_addr-cfg_base + hdev_base); + sys_write64(wvalue, pdev_addr-cfg_base + hdev_base); }else { - rvalue = sys_read32(pdev_addr-cfg_base + hdev_base); - *(uint32_t *)value = rvalue; + rvalue = sys_read64(pdev_addr-cfg_base + hdev_base); + *(uint64_t *)value = rvalue; } return 0; } @@ -89,15 +89,14 @@ int virt_pci_emulation(struct vm *vm, uint64_t pdev_addr, int write, uint64_t *v range_base = PCIE_ECAM_DATA(PCIE_BUS_DEVICE)->regions[i].phys_start; range_size = PCIE_ECAM_DATA(PCIE_BUS_DEVICE)->regions[i].size; if(pdev_addr >= range_base && pdev_addr < range_base+range_size){ - vdev = vm_virt_dev_add(vm, "vm_pci", true, false, pdev_addr, - pdev_addr, VM_DEFAULT_PCIDEVICE_SIZE, - VM_DEVICE_INVALID_VIRQ, VM_DEVICE_INVALID_VIRQ); - if(!vdev){ - ZVM_LOG_WARN("VM pci device init error!"); - return -ENODEV; + if(write) { + sys_write64(wvalue, pdev_addr); + }else { + rvalue = sys_read64(pdev_addr); + *(uint64_t *)value = rvalue; } - ZVM_LOG_INFO("Mapping pci device, address: %llx \n", pdev_addr); - return PCI_DEVICE_INIT; + + return 0; /*@TODO:pci passthrough interrupt is not consider now.*/ } } @@ -195,16 +194,6 @@ static int vm_pci_bus_init(const struct device *dev, struct vm *vm, struct virt_ vm_dev->priv_data = pci_virtual_device_instance; - /* scan the pci devices for getting device info */ - // for(i=0; itype == VM_PCI_IVSHMEM){ - // ivshmem_init(); - // } else{ - // printk("Not a ivshmem pci device, not support!"); - // } - // } - return 0; } diff --git a/subsys/virtualization/vm_dev.c b/subsys/virtualization/vm_dev.c index a9bda18bf..5c4f58ff9 100644 --- a/subsys/virtualization/vm_dev.c +++ b/subsys/virtualization/vm_dev.c @@ -21,6 +21,7 @@ #include #include #include +#include LOG_MODULE_DECLARE(ZVM_MODULE_NAME); @@ -39,6 +40,9 @@ 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_MEM")==0){ + attrs = MT_VM_DEVICE_MEM | MT_S2_ACCESS_OFF; + } return vm_vdev_mem_create(vm->vmem_domain, vdev->vm_vdev_paddr, vdev->vm_vdev_vaddr, vdev->vm_vdev_size, attrs); @@ -146,15 +150,24 @@ int vdev_mmio_abort(arch_commom_regs_t *regs, int write, uint64_t addr, dev = (const struct device* const)vdev->priv_data; if (write) { return ((struct virtio_mmio_driver_api *)((struct virt_device_api \ - *)dev->api)->device_driver_api)->write(vdev, addr - vdev->vm_vdev_vaddr, 0, (uint32_t)*reg_value, size); + *)dev->api)->device_driver_api)->write(vdev, addr - vdev->vm_vdev_vaddr, 0, (uint64_t)*reg_value, size); } else { return ((struct virtio_mmio_driver_api *)((struct virt_device_api \ - *)dev->api)->device_driver_api)->read(vdev, addr - vdev->vm_vdev_vaddr, (uint32_t *)reg_value, size); + *)dev->api)->device_driver_api)->read(vdev, addr - vdev->vm_vdev_vaddr, (uint64_t *)reg_value, size); } } }else if(vdevice_instance != NULL){ if(DEV_DATA(vdevice_instance)->vdevice_type & VM_DEVICE_PRE_KERNEL_1){ - if ((addr >= vdev->vm_vdev_paddr) && (addr < vdev->vm_vdev_paddr + vdev->vm_vdev_size)) { + if(addr == 0x40300000){ + if (write) { + return ((const struct virt_device_api * \ + const)(vdevice_instance->api))->virt_device_write(vdev, addr, reg_value); + }else{ + return ((const struct virt_device_api * \ + const)(vdevice_instance->api))->virt_device_read(vdev, addr, reg_value); + } + } + else if ((addr >= vdev->vm_vdev_paddr) && (addr < vdev->vm_vdev_paddr + vdev->vm_vdev_size)) { if (write) { return ((const struct virt_device_api * \ const)(vdevice_instance->api))->virt_device_write(vdev, addr, reg_value); @@ -275,6 +288,13 @@ int vm_device_init(struct vm *vm) return -EMMAO; } + ret = vm_mem_create(vm); + if (ret) { + ZVM_LOG_WARN("Init vm mem 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); diff --git a/subsys/virtualization/vm_mm.c b/subsys/virtualization/vm_mm.c index 9d73ad5da..d5a92aa30 100644 --- a/subsys/virtualization/vm_mm.c +++ b/subsys/virtualization/vm_mm.c @@ -680,7 +680,7 @@ void vm_host_memory_read(uint64_t hpa, void *dst, size_t len) } void vm_host_memory_write(uint64_t hpa, void *src, size_t len) -{ +{ size_t len_actual = len; uint64_t *hva; if (len == 1) { diff --git a/zvm_config/qemu_platform/hub/linux-qemu-virt.dtb b/zvm_config/qemu_platform/hub/linux-qemu-virt.dtb index 3d4b934cd117c8569f12f95465e9a545ada1d240..d75ed0bf550ef7041077d621d1276af883aa949c 100644 GIT binary patch delta 20 bcmeAc?-t)6&&X&xS%Fc4F<`SLV-ObrHm?M+ delta 20 bcmeAc?-t)6&&X&pS%Fc4(P6VCV-ObrHbVrU diff --git a/zvm_config/qemu_platform/linux-qemu-virt.dtb b/zvm_config/qemu_platform/linux-qemu-virt.dtb new file mode 100644 index 0000000000000000000000000000000000000000..d75ed0bf550ef7041077d621d1276af883aa949c GIT binary patch literal 2955 zcmZuzJ#Qs76!nA!HZ03WgAfuZQW}b9Hd$B_n&pWCQ6NM?Mf2p$IC-PY*V>+ttPn~; z0ivWr;ur82wn2y%i4J}O4IM&ANDJrK<9VKBEZwp1_4Pf+*VlgU*V~W(6ynx5LWn~l zw*Nu@I^;#j3lOyITiAc}!|5j*)F;s22;<8w^igMwRDU(mIk%|Fraxa4eO+J3v(h-& z*s{*%Wf+dJ4t^HmN!ViSccF6}_4mJ=Vts^p@{9AI+B#=Q>MubS%G3+u$h|l2im1>d z#K~%1x8`DbZ!a|3xt2LmR6gbhZRx*$?r98lSm%x0d&Yg0?W(TJcB!VZ==1=>xX(hq zfUptc24sTw3}<}v#}d~pLi`2ebJk;ad8wEC3G+>?uZ4Iygb81AMy#z%^xp^5_(lFM z;~7UIamg)hz`W*1pR0aYd(Dq$desm5HNU5V-^~-S%$|bbFHN4($F-v0jboy}_!))MEB zUKy8Hr$Ti{tB!-v7@K_m!d}o(JYM?lFva9U-4!^gq%dv++X;_OYX@$1XR<;%l#i#`_D{tN!}xf+{PW9%J_ zd8U5T?0q#+j}PhJ-pUwQld&g1_O~FO*GZYnK*`%-7LOpq8vh#^c@Q`KeS@04lK8To zJx1v)w&gbl(-@0;;yh){{muA15hcu_%kB*0=g}uTB|^gz^5=7ycYUyIa9AU3aS!Co zeP{5Mwdy#R*)~7bZqJYNs<%!XuXw-K=s_7`WcR_HF^HK8V=kw@{_J9&nKK1pW2|vM zd25_Lm+IcZI7eTNcr-+e%%SLvck$~9#otiIzm1M-IDRe}<7`JeDq*Zey1s`GdF()v zx(q1%i@-WPkRvL2WVmPY$~_}4&l8=Ghq}x@#8tfeR=s{mBU;SeDr??Ob^jwi%=6wX zj>~gh$h^Xl(9dJ$cpP*?)yF~Jvd`~y*B%98pn|fm98231cI&nf zMxTg6pOv{@xr;0*F^El!oKjI>%8;(zS`T{Qpz literal 0 HcmV?d00001 diff --git a/zvm_config/qemu_platform/linux-qemu-virt.dts b/zvm_config/qemu_platform/linux-qemu-virt.dts index 94e3cac34..ff867c1df 100644 --- a/zvm_config/qemu_platform/linux-qemu-virt.dts +++ b/zvm_config/qemu_platform/linux-qemu-virt.dts @@ -15,8 +15,8 @@ compatible = "arm,psci-0.2", "arm,psci"; }; - memory@40000000 { - reg = <0x0 0x40000000 0x0 0x40000000>; + memory@50000000 { + reg = <0x0 0x50000000 0x0 0x40000000>; device_type = "memory"; }; -- Gitee