diff --git a/arch/arm64/core/virtualization/trap_handler.c b/arch/arm64/core/virtualization/trap_handler.c index 6f3ca20149fabca0ed6ad9cca9f01b5a991b7698..ad74ad9cd36ed4d0ceb9a63331e7a3bf436425b0 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); @@ -109,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/auto_zvm.sh b/auto_zvm.sh index 3c12b5b71b3623ea676b4e4af6f750aa7a0b382f..df6dd75a97bb0ce1572b2f89739a8a2d47fab72a 100755 --- a/auto_zvm.sh +++ b/auto_zvm.sh @@ -44,8 +44,10 @@ 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 \ + -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.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: diff --git a/drivers/pcie/host/pcie_ecam.c b/drivers/pcie/host/pcie_ecam.c index fc4599fe71c11003608dc0135b9cf5c9d9b7cd29..a1120ab5c260cb12b665ac14b2591d7acb27462a 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 111bceef849a34e8390452e88caf653dd4efda08..3d46325a897ae45eda21491854e93673463b5cfe 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 0000000000000000000000000000000000000000..138955d2c8c36072a6f56a626a388e35afcea167 --- /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_ */ diff --git a/include/virtualization/vdev/shmem.h b/include/virtualization/vdev/shmem.h new file mode 100644 index 0000000000000000000000000000000000000000..aadc15d6c77b1566cfe7153091ae1746674e3159 --- /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/include/virtualization/vdev/virt_device.h b/include/virtualization/vdev/virt_device.h index cda0aa8b3ad99b5e0a7c140abb864b308a510d3a..db05fff641c0d05b2fef886eb5b453e3bc78839b 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 0000000000000000000000000000000000000000..ae8247e599675f57486f498d7819134982ef95b1 --- /dev/null +++ b/include/virtualization/vdev/virt_pci.h @@ -0,0 +1,79 @@ +/* + * 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 */ + +/* 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. */ +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 2044364750f15229284e80f0ae54524f8b7e99d4..27b47ef2fe26144b2b16394b2b7bec3b0f06e386 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 a03920a30fdec599b9cf5c4121dea39ce7082b7b..79b429145683c14d74c53e327025c4d1c777e4d4 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 adac4b289f1b82d95354fc38a224aed65cb0931b..26582c2924eee916e6e00ccd39451caf8f60bbe4 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 @@ -29,4 +34,8 @@ 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 +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 b2fe94b703185c9a79ab4a36ad1a2f1e5dada11d..a1c202f4d5cb635de59b39c821419136b511bc0a 100644 --- a/samples/_zvm/boards/qemu_cortex_max_smp.overlay +++ b/samples/_zvm/boards/qemu_cortex_max_smp.overlay @@ -21,14 +21,17 @@ 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"; + vmvirtmem = "/soc/virtmem@10000000"; }; chosen { vm,console = &uart0; + zephyr_pcie_controller = "/soc/pcie@10000000"; }; soc { @@ -158,23 +161,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 0x10000000>, + <0x3000000 0x00 0x20000000 0x00 0x20000000 0x00 0x1eff0000>; 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>; @@ -188,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 { @@ -219,10 +244,32 @@ 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"; }; + + /* 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 0000000000000000000000000000000000000000..2c55107414c7c4e2aa72a009b35322493c3faa89 --- /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 53521ff19582e18d5d2d06b32d328379df9fe638..c9c0bd6dca0a3240ae2cfa2da6c6611b06ceb55a 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/samples/_zvm/src/main.c b/samples/_zvm/src/main.c index 0e42864b7f0fcba8eb83b1a721d669f67015e659..0e3a3ac9c6ecf365286d6e14c038184942e23080 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 a7cd789cedf3f43cf9a3f40840a4b7a2d9938d53..400b1536741377f4711184fb00c597372f661e6f 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 7800e37bb98622e60d3982545b936986969089e7..afac5742e36caa3d7f156339a8642d3f77c9f503 100644 --- a/subsys/virtualization/vdev/CMakeLists.txt +++ b/subsys/virtualization/vdev/CMakeLists.txt @@ -29,3 +29,13 @@ zephyr_sources_ifdef( CONFIG_VM_CLOCK_SYSTEM_CONTROLLER virt_clock_syscon.c ) + +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 28718a48e6ef390cf8c5f3d35add2025e395b702..85f55d6628cabec5a3fe242895ea46329349a180 100644 --- a/subsys/virtualization/vdev/Kconfig +++ b/subsys/virtualization/vdev/Kconfig @@ -103,3 +103,32 @@ 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 + +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 0000000000000000000000000000000000000000..0275de63a71bb1ad27421b13da591383ea3d83ad --- /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 new file mode 100644 index 0000000000000000000000000000000000000000..86a08bb5b7bada59f0c657b7395d0837ff2887b3 --- /dev/null +++ b/subsys/virtualization/vdev/virt_pci.c @@ -0,0 +1,238 @@ +/* + * 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) +{ + int i; + uint64_t wvalue, rvalue; + uint64_t cfg_base, cfg_size, hdev_base; + uint64_t range_base, range_size; + struct virt_dev *vdev; + + 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; + + /*pci bus configuration space?*/ + if(pdev_addr >= cfg_base && pdev_addr < cfg_base+cfg_size){ + if(write) { + sys_write64(wvalue, pdev_addr-cfg_base + hdev_base); + }else { + rvalue = sys_read64(pdev_addr-cfg_base + hdev_base); + *(uint64_t *)value = rvalue; + } + return 0; + } + + /*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){ + if(write) { + sys_write64(wvalue, pdev_addr); + }else { + rvalue = sys_read64(pdev_addr); + *(uint64_t *)value = rvalue; + } + + return 0; + /*@TODO:pci passthrough interrupt is not consider now.*/ + } + } + + 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; + + 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 8309f98846763a210387a06046af948586f21d90..5c4f58ff90ce70eba90732d7e15449a17e7572d1 100644 --- a/subsys/virtualization/vm_dev.c +++ b/subsys/virtualization/vm_dev.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include LOG_MODULE_DECLARE(ZVM_MODULE_NAME); @@ -38,14 +40,53 @@ 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); } +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; @@ -109,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); @@ -162,7 +212,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 +221,15 @@ 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 */ + 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(); 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 +262,6 @@ int handle_vm_device_emulate(struct vm *vm, uint64_t pa_addr) ZVM_LOG_WARN(" Init device error! \n"); return -EFAULT; } - return 0; } @@ -230,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_manager.c b/subsys/virtualization/vm_manager.c index c890d6c6cdd0e505a85e79abd2e52b7db80b7506..3fbf1f07da072f59a14674797779f0301fe32f64 100644 --- a/subsys/virtualization/vm_manager.c +++ b/subsys/virtualization/vm_manager.c @@ -8,7 +8,6 @@ #include #include #include - #include #include #include diff --git a/subsys/virtualization/vm_mm.c b/subsys/virtualization/vm_mm.c index 9d73ad5da0941a52b97b47cc66aaada505e93028..d5a92aa30b4015bcf77c342735f7b0ae517d0109 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 6010ff28c2d6ee3fce309279fbb29f1537ee4996..d75ed0bf550ef7041077d621d1276af883aa949c 100644 Binary files a/zvm_config/qemu_platform/hub/linux-qemu-virt.dtb and b/zvm_config/qemu_platform/hub/linux-qemu-virt.dtb differ 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 Binary files /dev/null and b/zvm_config/qemu_platform/linux-qemu-virt.dtb differ diff --git a/zvm_config/qemu_platform/linux-qemu-virt.dts b/zvm_config/qemu_platform/linux-qemu-virt.dts index 85fe65dc058641da53cf64409b4efc81a0a481bc..ff867c1df3a5d41f4e4e9b38f5cfd3b2f76a8757 100644 --- a/zvm_config/qemu_platform/linux-qemu-virt.dts +++ b/zvm_config/qemu_platform/linux-qemu-virt.dts @@ -15,79 +15,47 @@ compatible = "arm,psci-0.2", "arm,psci"; }; - memory@40000000 { - reg = <0x0 0x40000000 0x0 0x40000000>; + memory@50000000 { + reg = <0x0 0x50000000 0x0 0x40000000>; device_type = "memory"; }; virtio_mmio@a000000 { dma-coherent; - interrupts = <0x00 0x10 0x01>; - 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 33502b4a1726c458800e9fbf8bfb406f6979e656..0000000000000000000000000000000000000000 --- 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 0000000000000000000000000000000000000000..4d5307b8482c08c161efeee9e23092e99f28b8f0 --- /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>; + }; +};