From patchwork Wed Feb 11 16:22:03 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baptiste Reynal X-Patchwork-Id: 438879 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id CF6E514029D for ; Thu, 12 Feb 2015 03:27:04 +1100 (AEDT) Received: from localhost ([::1]:45812 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YLa7z-0004Ft-0y for incoming@patchwork.ozlabs.org; Wed, 11 Feb 2015 11:27:03 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58883) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YLa4O-00066i-HR for qemu-devel@nongnu.org; Wed, 11 Feb 2015 11:23:21 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YLa4J-0002rg-An for qemu-devel@nongnu.org; Wed, 11 Feb 2015 11:23:20 -0500 Received: from mail-we0-f178.google.com ([74.125.82.178]:38629) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YLa4J-0002rc-1t for qemu-devel@nongnu.org; Wed, 11 Feb 2015 11:23:15 -0500 Received: by mail-we0-f178.google.com with SMTP id w62so4471018wes.9 for ; Wed, 11 Feb 2015 08:23:14 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ALIxadFJY/hhmjyI19KnGIzB+3SrYgH5T9sdyjVpFaQ=; b=Ix/pPxFz74hCM5SVdcI3gt69pcyM94xnTKn/7UFdyd8SQk2ncLk4Ddq2/8mZ6qGKvr 8grbsPyG1+Crq4jyLEJ6BY4pifMnJn1/GZ8WXUpPoUoIs+yAyOcio9sxjdHugRrtxA/P BFbL2aabfonevw8q7xzTopnAhDUwxXljsfgatiZjd576Vzxt6ADK5At82p/uy5oxrM0i D3D0LLjOJdhI0h0eYa6F2Wh8wA8nLcY0eWeLvS2+OVkEabXyDI4W81jAaYWzPiN6e/qw PaE8R1Rl1T82skZTnD9DuPF4vX/jYP6XVt32DVT8wL9y+0EESL+HBija8HQ9EY9fV80z X2/g== X-Gm-Message-State: ALoCoQmb1jjmR/bd50CgNZ3ANFGyB4VHD6i9EcLcK3d7bSY7uOMWUSgjD04yA/vFwPpm7TG8yjWk X-Received: by 10.180.208.79 with SMTP id mc15mr56910842wic.23.1423671794569; Wed, 11 Feb 2015 08:23:14 -0800 (PST) Received: from localhost (LPuteaux-656-1-278-113.w80-15.abo.wanadoo.fr. [80.15.154.113]) by mx.google.com with ESMTPSA id qo10sm1882472wjc.38.2015.02.11.08.23.13 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 11 Feb 2015 08:23:13 -0800 (PST) From: Baptiste Reynal To: kvmarm@lists.cs.columbia.edu, qemu-devel@nongnu.org Date: Wed, 11 Feb 2015 17:22:03 +0100 Message-Id: <1423671724-13167-4-git-send-email-b.reynal@virtualopensystems.com> X-Mailer: git-send-email 2.3.0 In-Reply-To: <1423671724-13167-1-git-send-email-b.reynal@virtualopensystems.com> References: <1423671724-13167-1-git-send-email-b.reynal@virtualopensystems.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 74.125.82.178 Cc: Peter Maydell , Alex Williamson , tech@virtualopensystems.com, Baptiste Reynal Subject: [Qemu-devel] [RFC PATCH v3 3/3] hw/vfio: add pl330 device support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Create a meta-device for PL330 DMA. Add add_arm_pl330_fdt_node function, with multiple compatible string and clocks support. Signed-off-by: Baptiste Reynal --- v2 -> v3: got to fail in case of apb_pclk missing free nodename in fail case --- hw/arm/sysbus-fdt.c | 85 ++++++++++++++++++++++++++++++++++++++++++++ hw/vfio/Makefile.objs | 1 + hw/vfio/pl330.c | 41 +++++++++++++++++++++ include/hw/vfio/vfio-pl330.h | 26 ++++++++++++++ 4 files changed, 153 insertions(+) create mode 100644 hw/vfio/pl330.c create mode 100644 include/hw/vfio/vfio-pl330.h diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c index bc0944c..8d419de 100644 --- a/hw/arm/sysbus-fdt.c +++ b/hw/arm/sysbus-fdt.c @@ -28,6 +28,9 @@ #include "sysemu/sysemu.h" #include "hw/vfio/vfio-platform.h" #include "hw/vfio/vfio-calxeda-xgmac.h" +#include "hw/vfio/vfio-pl330.h" + +#include /* * internal struct that contains the information to create dynamic @@ -186,9 +189,91 @@ fail: return -1; } +/** + * add_arm_pl330_fdt_node + * + * Generates a very simple node with following properties: + * compatible string, regs, interrupts, clocks, clock-names + */ +static int add_arm_pl330_fdt_node(SysBusDevice *sbdev, void *opaque) +{ + PlatformBusFDTData *data = opaque; + void *fdt = data->fdt; + const char *parent_node = data->pbus_node_name; + int compat_str_len; + char *nodename; + int ret; + uint64_t mmio_base; + VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev); + VFIODevice *vbasedev = &vdev->vbasedev; + Object *obj = OBJECT(sbdev); + + mmio_base = object_property_get_int(obj, "mmio[0]", NULL); + + nodename = g_strdup_printf("%s/%s@%" PRIx64, parent_node, + vbasedev->name, + mmio_base); + + qemu_fdt_add_subnode(fdt, nodename); + + /* + * Process compatible string to deal with multiple strings + * (; is replaced by \0) + */ + char *compat = g_strdup(vdev->compat); + compat_str_len = strlen(compat) + 1; + + char *semicolon = compat; + while ((semicolon = strchr(semicolon, ';')) != NULL) { + *semicolon = '\0'; + } + + qemu_fdt_setprop(fdt, nodename, "compatible", + compat, compat_str_len); + + /* Setup clocks for AMBA device */ + /* Check clock existence */ + ret = fdt_path_offset(fdt, "/apb-pclk"); + + if (ret < 0) { + error_report("could not set clocks property of node %s", nodename); + goto fail; + } else { + qemu_fdt_setprop_cells(fdt, nodename, "clocks", + qemu_fdt_getprop_cell(fdt, "/apb-pclk", "phandle")); + char clock_names[] = "apb_pclk"; + qemu_fdt_setprop(fdt, nodename, "clock-names", clock_names, + sizeof(clock_names)); + } + + ret = set_regions_fdt_node(nodename, sbdev, opaque); + + if (ret < 0) { + error_report("could not set reg property of node %s", nodename); + goto fail; + } + + ret = set_interrupts_fdt_node(nodename, sbdev, opaque, 0, 0x4); + + if (ret < 0) { + error_report("could not set interrupts property of node %s", + nodename); + goto fail; + } + + g_free(nodename); + + return 0; + +fail: + g_free(nodename); + return -1; +} + /* list of supported dynamic sysbus devices */ static const NodeCreationPair add_fdt_node_functions[] = { {TYPE_VFIO_CALXEDA_XGMAC, add_calxeda_midway_xgmac_fdt_node}, + {TYPE_VFIO_PL330, add_arm_pl330_fdt_node}, {"", NULL}, /* last element */ }; diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs index d540c9d..4ed0fa0 100644 --- a/hw/vfio/Makefile.objs +++ b/hw/vfio/Makefile.objs @@ -3,4 +3,5 @@ obj-$(CONFIG_SOFTMMU) += common.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_SOFTMMU) += platform.o obj-$(CONFIG_SOFTMMU) += calxeda-xgmac.o +obj-$(CONFIG_SOFTMMU) += pl330.o endif diff --git a/hw/vfio/pl330.c b/hw/vfio/pl330.c new file mode 100644 index 0000000..a409024 --- /dev/null +++ b/hw/vfio/pl330.c @@ -0,0 +1,41 @@ +#include "hw/vfio/vfio-pl330.h" + +static void pl330_realize(DeviceState *dev, Error **errp) +{ + VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(dev); + VFIOPl330DeviceClass *k = VFIO_PL330_DEVICE_GET_CLASS(dev); + + vdev->compat = g_strdup("arm,pl330;arm,primecell"); + + k->parent_realize(dev, errp); +} + +static const VMStateDescription vfio_platform_vmstate = { + .name = TYPE_VFIO_PL330, + .unmigratable = 1, +}; + +static void vfio_pl330_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + VFIOPl330DeviceClass *vpc = + VFIO_PL330_DEVICE_CLASS(klass); + vpc->parent_realize = dc->realize; + dc->realize = pl330_realize; + dc->desc = "VFIO PL330"; +} + +static const TypeInfo vfio_pl330_dev_info = { + .name = TYPE_VFIO_PL330, + .parent = TYPE_VFIO_PLATFORM, + .instance_size = sizeof(VFIOPl330Device), + .class_init = vfio_pl330_class_init, + .class_size = sizeof(VFIOPl330DeviceClass), +}; + +static void register_pl330_dev_type(void) +{ + type_register_static(&vfio_pl330_dev_info); +} + +type_init(register_pl330_dev_type) diff --git a/include/hw/vfio/vfio-pl330.h b/include/hw/vfio/vfio-pl330.h new file mode 100644 index 0000000..1cdf039 --- /dev/null +++ b/include/hw/vfio/vfio-pl330.h @@ -0,0 +1,26 @@ +#ifndef HW_VFIO_VFIO_PL330 +#define HW_VFIO_VFIO_PL330 + +#include "hw/vfio/vfio-platform.h" + +#define TYPE_VFIO_PL330 "vfio-pl330" + +typedef struct VFIOPl330Device { + VFIOPlatformDevice vdev; +} VFIOPl330Device; + +typedef struct VFIOPl330DeviceClass { + VFIOPlatformDeviceClass parent_class; + DeviceRealize parent_realize; +} VFIOPl330DeviceClass; + +#define VFIO_PL330_DEVICE(obj) \ + OBJECT_CHECK(VFIOPl330Device, (obj), TYPE_VFIO_PL330) +#define VFIO_PL330_DEVICE_CLASS(klass) \ + OBJECT_CLASS_CHECK(VFIOPl330DeviceClass, (klass), \ + TYPE_VFIO_PL330) +#define VFIO_PL330_DEVICE_GET_CLASS(obj) \ + OBJECT_GET_CLASS(VFIOPl330DeviceClass, (obj), \ + TYPE_VFIO_PL330) + +#endif