qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

hw/arm/sysbus-fdt: enable vfio-calxeda-xgmac dynamic instantiation

This patch allows the instantiation of the vfio-calxeda-xgmac device
from the QEMU command line (-device vfio-calxeda-xgmac,host="<device>").

A specialized device tree node is created for the guest, containing
compat, dma-coherent, reg and interrupts properties.

Signed-off-by: Eric Auger <eric.auger@linaro.org>
Acked-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1434455898-17895-1-git-send-email-eric.auger@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

authored by

Eric Auger and committed by
Peter Maydell
decf4f80 ba890a9b

+108 -11
+73
hw/arm/sysbus-fdt.c
··· 26 26 #include "sysemu/device_tree.h" 27 27 #include "hw/platform-bus.h" 28 28 #include "sysemu/sysemu.h" 29 + #include "hw/vfio/vfio-platform.h" 30 + #include "hw/vfio/vfio-calxeda-xgmac.h" 31 + #include "hw/arm/fdt.h" 29 32 30 33 /* 31 34 * internal struct that contains the information to create dynamic ··· 53 56 int (*add_fdt_node_fn)(SysBusDevice *sbdev, void *opaque); 54 57 } NodeCreationPair; 55 58 59 + /* Device Specific Code */ 60 + 61 + /** 62 + * add_calxeda_midway_xgmac_fdt_node 63 + * 64 + * Generates a simple node with following properties: 65 + * compatible string, regs, interrupts, dma-coherent 66 + */ 67 + static int add_calxeda_midway_xgmac_fdt_node(SysBusDevice *sbdev, void *opaque) 68 + { 69 + PlatformBusFDTData *data = opaque; 70 + PlatformBusDevice *pbus = data->pbus; 71 + void *fdt = data->fdt; 72 + const char *parent_node = data->pbus_node_name; 73 + int compat_str_len, i, ret = -1; 74 + char *nodename; 75 + uint32_t *irq_attr, *reg_attr; 76 + uint64_t mmio_base, irq_number; 77 + VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev); 78 + VFIODevice *vbasedev = &vdev->vbasedev; 79 + 80 + mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0); 81 + nodename = g_strdup_printf("%s/%s@%" PRIx64, parent_node, 82 + vbasedev->name, mmio_base); 83 + qemu_fdt_add_subnode(fdt, nodename); 84 + 85 + compat_str_len = strlen(vdev->compat) + 1; 86 + qemu_fdt_setprop(fdt, nodename, "compatible", 87 + vdev->compat, compat_str_len); 88 + 89 + qemu_fdt_setprop(fdt, nodename, "dma-coherent", "", 0); 90 + 91 + reg_attr = g_new(uint32_t, vbasedev->num_regions * 2); 92 + for (i = 0; i < vbasedev->num_regions; i++) { 93 + mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, i); 94 + reg_attr[2 * i] = cpu_to_be32(mmio_base); 95 + reg_attr[2 * i + 1] = cpu_to_be32( 96 + memory_region_size(&vdev->regions[i]->mem)); 97 + } 98 + ret = qemu_fdt_setprop(fdt, nodename, "reg", reg_attr, 99 + vbasedev->num_regions * 2 * sizeof(uint32_t)); 100 + if (ret) { 101 + error_report("could not set reg property of node %s", nodename); 102 + goto fail_reg; 103 + } 104 + 105 + irq_attr = g_new(uint32_t, vbasedev->num_irqs * 3); 106 + for (i = 0; i < vbasedev->num_irqs; i++) { 107 + irq_number = platform_bus_get_irqn(pbus, sbdev , i) 108 + + data->irq_start; 109 + irq_attr[3 * i] = cpu_to_be32(GIC_FDT_IRQ_TYPE_SPI); 110 + irq_attr[3 * i + 1] = cpu_to_be32(irq_number); 111 + irq_attr[3 * i + 2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_LEVEL_HI); 112 + } 113 + ret = qemu_fdt_setprop(fdt, nodename, "interrupts", 114 + irq_attr, vbasedev->num_irqs * 3 * sizeof(uint32_t)); 115 + if (ret) { 116 + error_report("could not set interrupts property of node %s", 117 + nodename); 118 + } 119 + g_free(irq_attr); 120 + fail_reg: 121 + g_free(reg_attr); 122 + g_free(nodename); 123 + return ret; 124 + } 125 + 56 126 /* list of supported dynamic sysbus devices */ 57 127 static const NodeCreationPair add_fdt_node_functions[] = { 128 + {TYPE_VFIO_CALXEDA_XGMAC, add_calxeda_midway_xgmac_fdt_node}, 58 129 {"", NULL}, /* last element */ 59 130 }; 131 + 132 + /* Generic Code */ 60 133 61 134 /** 62 135 * add_fdt_node - add the device tree node of a dynamic sysbus device
+1 -11
hw/arm/virt.c
··· 47 47 #include "hw/arm/virt-acpi-build.h" 48 48 #include "hw/arm/sysbus-fdt.h" 49 49 #include "hw/platform-bus.h" 50 + #include "hw/arm/fdt.h" 50 51 51 52 /* Number of external interrupt lines to configure the GIC with */ 52 53 #define NUM_IRQS 256 53 - 54 - #define GIC_FDT_IRQ_TYPE_SPI 0 55 - #define GIC_FDT_IRQ_TYPE_PPI 1 56 - 57 - #define GIC_FDT_IRQ_FLAGS_EDGE_LO_HI 1 58 - #define GIC_FDT_IRQ_FLAGS_EDGE_HI_LO 2 59 - #define GIC_FDT_IRQ_FLAGS_LEVEL_HI 4 60 - #define GIC_FDT_IRQ_FLAGS_LEVEL_LO 8 61 - 62 - #define GIC_FDT_IRQ_PPI_CPU_START 8 63 - #define GIC_FDT_IRQ_PPI_CPU_WIDTH 8 64 54 65 55 #define PLATFORM_BUS_NUM_IRQS 64 66 56
+34
include/hw/arm/fdt.h
··· 1 + /* 2 + * 3 + * Copyright (c) 2015 Linaro Limited 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms and conditions of the GNU General Public License, 7 + * version 2 or later, as published by the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program. If not, see <http://www.gnu.org/licenses/>. 16 + * 17 + * Define macros useful when building ARM device tree nodes 18 + */ 19 + 20 + #ifndef QEMU_ARM_FDT_H 21 + #define QEMU_ARM_FDT_H 22 + 23 + #define GIC_FDT_IRQ_TYPE_SPI 0 24 + #define GIC_FDT_IRQ_TYPE_PPI 1 25 + 26 + #define GIC_FDT_IRQ_FLAGS_EDGE_LO_HI 1 27 + #define GIC_FDT_IRQ_FLAGS_EDGE_HI_LO 2 28 + #define GIC_FDT_IRQ_FLAGS_LEVEL_HI 4 29 + #define GIC_FDT_IRQ_FLAGS_LEVEL_LO 8 30 + 31 + #define GIC_FDT_IRQ_PPI_CPU_START 8 32 + #define GIC_FDT_IRQ_PPI_CPU_WIDTH 8 33 + 34 + #endif