From patchwork Mon Jun 16 12:55:39 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Herring X-Patchwork-Id: 31961 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ie0-f199.google.com (mail-ie0-f199.google.com [209.85.223.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id AD2412107C for ; Mon, 16 Jun 2014 12:57:06 +0000 (UTC) Received: by mail-ie0-f199.google.com with SMTP id rd18sf32549512iec.6 for ; Mon, 16 Jun 2014 05:57:06 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:date :message-id:cc:subject:precedence:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:errors-to:sender :x-original-sender:x-original-authentication-results:mailing-list; bh=2XN8qVOAWnyBFeZQoNDibs+ODhdDaT0fG22+8YdB9pY=; b=GEJNdb5R0ZSIqerCftgltk2vkfdk1LzJG3/N9nsMc4CNWt58jTBX8+q/TvaQtJ/Oxl vAoutdg0MiEp4aDrY16e9ogNAK/uzK05YdHfGIENJu4YgBA7aECeWggTStC9mAlcGzg/ ZxCXX7phEDWsujIit59u1iCe/lS4AYO4kaVTJx8uhEgFiO13KZaZ1x+KVb5lNud+9KnV 1utc2GXZzUjoOLAuVT/+m5ffQZCEHn7PMWQjm5spxd6qNrxH1l7kEk9vGJZzX2LvhMY+ RXecWIUHQdPPKveFCBquWeZKMzWS2fcdCw68QjIEWmmJ2nPd64gACWHqP3CBYQWIbgcD iiKA== X-Gm-Message-State: ALoCoQmJWLjFMvnUytolfc7pbT/+0X/EINljLr1ueum8wFf/0HPKdTQutqXb4vAVqqfwL6rWFP3X X-Received: by 10.182.119.194 with SMTP id kw2mr980153obb.27.1402923425830; Mon, 16 Jun 2014 05:57:05 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.23.212 with SMTP id 78ls792969qgp.39.gmail; Mon, 16 Jun 2014 05:57:05 -0700 (PDT) X-Received: by 10.52.79.99 with SMTP id i3mr440922vdx.50.1402923425684; Mon, 16 Jun 2014 05:57:05 -0700 (PDT) Received: from mail-vc0-x232.google.com (mail-vc0-x232.google.com [2607:f8b0:400c:c03::232]) by mx.google.com with ESMTPS id dh1si4072329veb.23.2014.06.16.05.57.05 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 16 Jun 2014 05:57:05 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2607:f8b0:400c:c03::232 as permitted sender) client-ip=2607:f8b0:400c:c03::232; Received: by mail-vc0-f178.google.com with SMTP id ij19so4954699vcb.9 for ; Mon, 16 Jun 2014 05:57:05 -0700 (PDT) X-Received: by 10.220.174.137 with SMTP id t9mr16399262vcz.12.1402923425554; Mon, 16 Jun 2014 05:57:05 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.221.54.6 with SMTP id vs6csp133054vcb; Mon, 16 Jun 2014 05:57:05 -0700 (PDT) X-Received: by 10.224.38.4 with SMTP id z4mr4415585qad.94.1402923425159; Mon, 16 Jun 2014 05:57:05 -0700 (PDT) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id v3si13093212qab.62.2014.06.16.05.57.04 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 16 Jun 2014 05:57:05 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Received: from localhost ([::1]:43739 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WwWTA-0004AD-No for patch@linaro.org; Mon, 16 Jun 2014 08:57:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47262) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WwWSS-0003dB-7O for qemu-devel@nongnu.org; Mon, 16 Jun 2014 08:56:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WwWSM-0002IQ-Nb for qemu-devel@nongnu.org; Mon, 16 Jun 2014 08:56:20 -0400 Received: from mail-ob0-x22e.google.com ([2607:f8b0:4003:c01::22e]:38082) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WwWSM-0002IK-F0 for qemu-devel@nongnu.org; Mon, 16 Jun 2014 08:56:14 -0400 Received: by mail-ob0-f174.google.com with SMTP id va2so5611192obc.5 for ; Mon, 16 Jun 2014 05:56:13 -0700 (PDT) X-Received: by 10.60.134.175 with SMTP id pl15mr2020823oeb.81.1402923373421; Mon, 16 Jun 2014 05:56:13 -0700 (PDT) Received: from localhost.localdomain (66-90-144-10.dyn.grandenetworks.net. [66.90.144.10]) by mx.google.com with ESMTPSA id ub1sm50381478oeb.9.2014.06.16.05.56.12 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 16 Jun 2014 05:56:12 -0700 (PDT) From: Rob Herring To: Claudio Fontana , Peter Maydell Date: Mon, 16 Jun 2014 07:55:39 -0500 Message-Id: <1402923340-4950-1-git-send-email-robherring2@gmail.com> X-Mailer: git-send-email 1.9.1 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4003:c01::22e Cc: Rob Herring , qemu-devel@nongnu.org Subject: [Qemu-devel] [RFC PATCH 1/2] hw/pci-host: add a generic PCI host 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+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org X-Original-Sender: robherring2@gmail.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2607:f8b0:400c:c03::232 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org; dkim=fail header.i=@gmail.com; dmarc=fail (p=NONE dis=NONE) header.from=gmail.com Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 From: Rob Herring Add a generic PCI host controller for virtual platforms. This is for ARM virtual platforms at the moment, but has nothing ARM specific. This matches the generic PCI host driver added in the 3.16 kernel. Functioning with OHCI (usb disk), but not LSI SCSI which doesn't find a disk. TODO: - The memory region size and alias offset for the io and memory space are hardcoded and need to be set from the machine and must match the values in the DT ranges. Probably need to make these properties. - More space for PCI memory space needed? - MSI support - Needs GICv2M or GICv3 support. Signed-off-by: Rob Herring --- hw/pci-host/Makefile.objs | 2 +- hw/pci-host/generic-pci.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 hw/pci-host/generic-pci.c diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs index bb65f9c..8ef9fac 100644 --- a/hw/pci-host/Makefile.objs +++ b/hw/pci-host/Makefile.objs @@ -1,4 +1,4 @@ -common-obj-y += pam.o +common-obj-y += pam.o generic-pci.o # PPC devices common-obj-$(CONFIG_PREP_PCI) += prep.o diff --git a/hw/pci-host/generic-pci.c b/hw/pci-host/generic-pci.c new file mode 100644 index 0000000..1632e46 --- /dev/null +++ b/hw/pci-host/generic-pci.c @@ -0,0 +1,182 @@ +/* + * Generic PCI host controller + * + * Copyright (c) 2014 Linaro, Ltd. + * Author: Rob Herring + * + * Based on ARM Versatile PCI controller (hw/pci-host/versatile.c): + * Copyright (c) 2006-2009 CodeSourcery. + * Written by Paul Brook + * + * This code is licensed under the LGPL. + */ + +#include "hw/sysbus.h" +#include "hw/pci/pci.h" +#include "hw/pci/pci_bus.h" +#include "hw/pci/pci_host.h" +#include "exec/address-spaces.h" + +typedef struct { + PCIHostState parent_obj; + + qemu_irq irq[4]; + MemoryRegion mem_config; + /* Containers representing the PCI address spaces */ + MemoryRegion pci_io_space; + MemoryRegion pci_mem_space; + /* Alias regions into PCI address spaces which we expose as sysbus regions. + * The offsets into pci_mem_space are controlled by the imap registers. + */ + MemoryRegion pci_io_window; + MemoryRegion pci_mem_window; + PCIBus pci_bus; + PCIDevice pci_dev; +} PCIVPBState; + + +static const VMStateDescription pci_generic_host_vmstate = { + .name = "generic-host-pci", + .version_id = 1, + .minimum_version_id = 1, +}; + +#define TYPE_GENERIC_PCI "generic_pci" +#define PCI_GEN(obj) \ + OBJECT_CHECK(PCIVPBState, (obj), TYPE_GENERIC_PCI) + +#define TYPE_GENERIC_PCI_HOST "generic_pci_host" +#define PCI_GEN_HOST(obj) \ + OBJECT_CHECK(PCIDevice, (obj), TYPE_GENERIC_PCIHOST) + + +static void pci_cam_config_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) +{ + PCIVPBState *s = opaque; + pci_data_write(&s->pci_bus, addr, val, size); +} + +static uint64_t pci_cam_config_read(void *opaque, hwaddr addr, unsigned size) +{ + PCIVPBState *s = opaque; + uint32_t val; + val = pci_data_read(&s->pci_bus, addr, size); + return val; +} + +static const MemoryRegionOps pci_vpb_config_ops = { + .read = pci_cam_config_read, + .write = pci_cam_config_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + +static void pci_generic_set_irq(void *opaque, int irq_num, int level) +{ + qemu_irq *pic = opaque; + qemu_set_irq(pic[irq_num], level); +} + +static void pci_generic_host_init(Object *obj) +{ + PCIHostState *h = PCI_HOST_BRIDGE(obj); + PCIVPBState *s = PCI_GEN(obj); + + memory_region_init(&s->pci_io_space, OBJECT(s), "pci_io", 0x10000); + memory_region_init(&s->pci_mem_space, OBJECT(s), "pci_mem", 1ULL << 32); + + pci_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), "pci", + &s->pci_mem_space, &s->pci_io_space, + PCI_DEVFN(0, 0), TYPE_PCIE_BUS); + h->bus = &s->pci_bus; + + object_initialize(&s->pci_dev, sizeof(s->pci_dev), TYPE_GENERIC_PCI_HOST); + qdev_set_parent_bus(DEVICE(&s->pci_dev), BUS(&s->pci_bus)); +} + +static void pci_generic_host_realize(DeviceState *dev, Error **errp) +{ + PCIVPBState *s = PCI_GEN(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + int i; + + for (i = 0; i < 4; i++) { + sysbus_init_irq(sbd, &s->irq[i]); + } + + pci_bus_irqs(&s->pci_bus, pci_generic_set_irq, pci_swizzle_map_irq_fn, + s->irq, 4); + + /* Our memory regions are: + * 0 : PCI config window + * 1 : PCI IO window + * 2 : PCI memory windows + */ + memory_region_init_io(&s->mem_config, OBJECT(s), &pci_vpb_config_ops, s, + "pci-config", 0x1000000); + sysbus_init_mmio(sbd, &s->mem_config); + + /* The window into I/O space is always into a fixed base address; + * its size is the same for both realview and versatile. + */ + memory_region_init_alias(&s->pci_io_window, OBJECT(s), "pci-io-win", + &s->pci_io_space, 0, 0x10000); + sysbus_init_mmio(sbd, &s->pci_io_space); + + /* Create the alias regions corresponding to our three windows onto + * PCI memory space. The sizes vary from board to board; the base + * offsets are guest controllable via the IMAP registers. + */ + memory_region_init_alias(&s->pci_mem_window, OBJECT(s), "pci-mem-win", + &s->pci_mem_space, 0x12000000, 0x2e000000); + sysbus_init_mmio(sbd, &s->pci_mem_window); + + /* TODO Remove once realize propagates to child devices. */ + object_property_set_bool(OBJECT(&s->pci_dev), true, "realized", errp); +} + +static void pci_generic_host_class_init(ObjectClass *klass, void *data) +{ + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); + + k->vendor_id = PCI_VENDOR_ID_REDHAT; + k->device_id = 0x1234; + k->class_id = PCI_CLASS_PROCESSOR_CO; + /* + * PCI-facing part of the host bridge, not usable without the + * host-facing part, which can't be device_add'ed, yet. + */ + dc->cannot_instantiate_with_device_add_yet = true; +} + +static const TypeInfo pci_generic_host_info = { + .name = TYPE_GENERIC_PCI_HOST, + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(PCIDevice), + .class_init = pci_generic_host_class_init, +}; + +static void pci_generic_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = pci_generic_host_realize; + dc->vmsd = &pci_generic_host_vmstate; +} + +static const TypeInfo pci_generic_info = { + .name = TYPE_GENERIC_PCI, + .parent = TYPE_PCI_HOST_BRIDGE, + .instance_size = sizeof(PCIVPBState), + .instance_init = pci_generic_host_init, + .class_init = pci_generic_class_init, +}; + +static void generic_pci_host_register_types(void) +{ + type_register_static(&pci_generic_info); + type_register_static(&pci_generic_host_info); +} + +type_init(generic_pci_host_register_types)