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>
This commit is contained in:
parent
ba890a9b25
commit
decf4f807b
@ -26,6 +26,9 @@
|
||||
#include "sysemu/device_tree.h"
|
||||
#include "hw/platform-bus.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "hw/vfio/vfio-platform.h"
|
||||
#include "hw/vfio/vfio-calxeda-xgmac.h"
|
||||
#include "hw/arm/fdt.h"
|
||||
|
||||
/*
|
||||
* internal struct that contains the information to create dynamic
|
||||
@ -53,11 +56,81 @@ typedef struct NodeCreationPair {
|
||||
int (*add_fdt_node_fn)(SysBusDevice *sbdev, void *opaque);
|
||||
} NodeCreationPair;
|
||||
|
||||
/* Device Specific Code */
|
||||
|
||||
/**
|
||||
* add_calxeda_midway_xgmac_fdt_node
|
||||
*
|
||||
* Generates a simple node with following properties:
|
||||
* compatible string, regs, interrupts, dma-coherent
|
||||
*/
|
||||
static int add_calxeda_midway_xgmac_fdt_node(SysBusDevice *sbdev, void *opaque)
|
||||
{
|
||||
PlatformBusFDTData *data = opaque;
|
||||
PlatformBusDevice *pbus = data->pbus;
|
||||
void *fdt = data->fdt;
|
||||
const char *parent_node = data->pbus_node_name;
|
||||
int compat_str_len, i, ret = -1;
|
||||
char *nodename;
|
||||
uint32_t *irq_attr, *reg_attr;
|
||||
uint64_t mmio_base, irq_number;
|
||||
VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
|
||||
VFIODevice *vbasedev = &vdev->vbasedev;
|
||||
|
||||
mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
|
||||
nodename = g_strdup_printf("%s/%s@%" PRIx64, parent_node,
|
||||
vbasedev->name, mmio_base);
|
||||
qemu_fdt_add_subnode(fdt, nodename);
|
||||
|
||||
compat_str_len = strlen(vdev->compat) + 1;
|
||||
qemu_fdt_setprop(fdt, nodename, "compatible",
|
||||
vdev->compat, compat_str_len);
|
||||
|
||||
qemu_fdt_setprop(fdt, nodename, "dma-coherent", "", 0);
|
||||
|
||||
reg_attr = g_new(uint32_t, vbasedev->num_regions * 2);
|
||||
for (i = 0; i < vbasedev->num_regions; i++) {
|
||||
mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, i);
|
||||
reg_attr[2 * i] = cpu_to_be32(mmio_base);
|
||||
reg_attr[2 * i + 1] = cpu_to_be32(
|
||||
memory_region_size(&vdev->regions[i]->mem));
|
||||
}
|
||||
ret = qemu_fdt_setprop(fdt, nodename, "reg", reg_attr,
|
||||
vbasedev->num_regions * 2 * sizeof(uint32_t));
|
||||
if (ret) {
|
||||
error_report("could not set reg property of node %s", nodename);
|
||||
goto fail_reg;
|
||||
}
|
||||
|
||||
irq_attr = g_new(uint32_t, vbasedev->num_irqs * 3);
|
||||
for (i = 0; i < vbasedev->num_irqs; i++) {
|
||||
irq_number = platform_bus_get_irqn(pbus, sbdev , i)
|
||||
+ data->irq_start;
|
||||
irq_attr[3 * i] = cpu_to_be32(GIC_FDT_IRQ_TYPE_SPI);
|
||||
irq_attr[3 * i + 1] = cpu_to_be32(irq_number);
|
||||
irq_attr[3 * i + 2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_LEVEL_HI);
|
||||
}
|
||||
ret = qemu_fdt_setprop(fdt, nodename, "interrupts",
|
||||
irq_attr, vbasedev->num_irqs * 3 * sizeof(uint32_t));
|
||||
if (ret) {
|
||||
error_report("could not set interrupts property of node %s",
|
||||
nodename);
|
||||
}
|
||||
g_free(irq_attr);
|
||||
fail_reg:
|
||||
g_free(reg_attr);
|
||||
g_free(nodename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* list of supported dynamic sysbus devices */
|
||||
static const NodeCreationPair add_fdt_node_functions[] = {
|
||||
{TYPE_VFIO_CALXEDA_XGMAC, add_calxeda_midway_xgmac_fdt_node},
|
||||
{"", NULL}, /* last element */
|
||||
};
|
||||
|
||||
/* Generic Code */
|
||||
|
||||
/**
|
||||
* add_fdt_node - add the device tree node of a dynamic sysbus device
|
||||
*
|
||||
|
@ -47,21 +47,11 @@
|
||||
#include "hw/arm/virt-acpi-build.h"
|
||||
#include "hw/arm/sysbus-fdt.h"
|
||||
#include "hw/platform-bus.h"
|
||||
#include "hw/arm/fdt.h"
|
||||
|
||||
/* Number of external interrupt lines to configure the GIC with */
|
||||
#define NUM_IRQS 256
|
||||
|
||||
#define GIC_FDT_IRQ_TYPE_SPI 0
|
||||
#define GIC_FDT_IRQ_TYPE_PPI 1
|
||||
|
||||
#define GIC_FDT_IRQ_FLAGS_EDGE_LO_HI 1
|
||||
#define GIC_FDT_IRQ_FLAGS_EDGE_HI_LO 2
|
||||
#define GIC_FDT_IRQ_FLAGS_LEVEL_HI 4
|
||||
#define GIC_FDT_IRQ_FLAGS_LEVEL_LO 8
|
||||
|
||||
#define GIC_FDT_IRQ_PPI_CPU_START 8
|
||||
#define GIC_FDT_IRQ_PPI_CPU_WIDTH 8
|
||||
|
||||
#define PLATFORM_BUS_NUM_IRQS 64
|
||||
|
||||
static ARMPlatformBusSystemParams platform_bus_params;
|
||||
|
34
include/hw/arm/fdt.h
Normal file
34
include/hw/arm/fdt.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2015 Linaro Limited
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2 or later, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Define macros useful when building ARM device tree nodes
|
||||
*/
|
||||
|
||||
#ifndef QEMU_ARM_FDT_H
|
||||
#define QEMU_ARM_FDT_H
|
||||
|
||||
#define GIC_FDT_IRQ_TYPE_SPI 0
|
||||
#define GIC_FDT_IRQ_TYPE_PPI 1
|
||||
|
||||
#define GIC_FDT_IRQ_FLAGS_EDGE_LO_HI 1
|
||||
#define GIC_FDT_IRQ_FLAGS_EDGE_HI_LO 2
|
||||
#define GIC_FDT_IRQ_FLAGS_LEVEL_HI 4
|
||||
#define GIC_FDT_IRQ_FLAGS_LEVEL_LO 8
|
||||
|
||||
#define GIC_FDT_IRQ_PPI_CPU_START 8
|
||||
#define GIC_FDT_IRQ_PPI_CPU_WIDTH 8
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user