Patchwork [14/22] usb/ehci: add sysbus variant

login
register
mail settings
Submitter Peter A. G. Crosthwaite
Date Oct. 31, 2012, 5:57 a.m.
Message ID <1351663031.24283.14.camel@PetaLogix-ws2>
Download mbox | patch
Permalink /patch/195745/
State New
Headers show

Comments

Peter A. G. Crosthwaite - Oct. 31, 2012, 5:57 a.m.
All good,

Needs a hack to get around the dma_memory_foo segfault (attached), but
that will come out in the wash with the memory API refactorings.

Regards,
Peter

On Tue, 2012-10-30 at 15:26 +0100, Gerd Hoffmann wrote:
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Tested-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>

> ---
>  hw/usb/Makefile.objs     |    2 +-
>  hw/usb/hcd-ehci-sysbus.c |   77 ++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 78 insertions(+), 1 deletions(-)
>  create mode 100644 hw/usb/hcd-ehci-sysbus.c
> 
> diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
> index 5c7b024..7669938 100644
> --- a/hw/usb/Makefile.objs
> +++ b/hw/usb/Makefile.objs
> @@ -1,6 +1,6 @@
>  common-obj-$(CONFIG_USB_UHCI) += hcd-uhci.o
>  common-obj-$(CONFIG_USB_OHCI) += hcd-ohci.o
> -common-obj-$(CONFIG_USB_EHCI) += hcd-ehci.o hcd-ehci-pci.o
> +common-obj-$(CONFIG_USB_EHCI) += hcd-ehci.o hcd-ehci-pci.o hcd-ehci-sysbus.o
>  common-obj-$(CONFIG_USB_XHCI) += hcd-xhci.o
>  common-obj-y += libhw.o
>  
> diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c
> new file mode 100644
> index 0000000..1584079
> --- /dev/null
> +++ b/hw/usb/hcd-ehci-sysbus.c
> @@ -0,0 +1,77 @@
> +/*
> + * QEMU USB EHCI Emulation
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or(at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser 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/>.
> + */
> +
> +#include "hw/usb/hcd-ehci.h"
> +#include "hw/sysbus.h"
> +
> +typedef struct EHCISysBusState {
> +    SysBusDevice busdev;
> +    EHCIState ehci;
> +} EHCISysBusState;
> +
> +static const VMStateDescription vmstate_ehci_sysbus = {
> +    .name        = "ehci-sysbus",
> +    .version_id  = 2,
> +    .minimum_version_id  = 1,
> +    .fields      = (VMStateField[]) {
> +        VMSTATE_STRUCT(ehci, EHCISysBusState, 2, vmstate_ehci, EHCIState),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
> +static Property ehci_sysbus_properties[] = {
> +    DEFINE_PROP_UINT32("maxframes", EHCISysBusState, ehci.maxframes, 128),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static int usb_ehci_sysbus_initfn(SysBusDevice *dev)
> +{
> +    EHCISysBusState *i = FROM_SYSBUS(EHCISysBusState, dev);
> +    EHCIState *s = &i->ehci;
> +
> +    s->capsbase = 0x100;
> +    s->opregbase = 0x140;
> +
> +    usb_ehci_initfn(s, DEVICE(dev));
> +    sysbus_init_irq(dev, &s->irq);
> +    sysbus_init_mmio(dev, &s->mem);
> +    return 0;
> +}
> +
> +static void ehci_sysbus_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
> +
> +    k->init = usb_ehci_sysbus_initfn;
> +    dc->vmsd = &vmstate_ehci_sysbus;
> +    dc->props = ehci_sysbus_properties;
> +}
> +
> +TypeInfo ehci_xlnx_type_info = {
> +    .name          = "xlnx,ps7-usb",
> +    .parent        = TYPE_SYS_BUS_DEVICE,
> +    .instance_size = sizeof(EHCISysBusState),
> +    .class_init    = ehci_sysbus_class_init,
> +};
> +
> +static void ehci_sysbus_register_types(void)
> +{
> +    type_register_static(&ehci_xlnx_type_info);
> +}
> +
> +type_init(ehci_sysbus_register_types)

Patch

From b3dc8992bbea0358752efdd8ca8803c8f150f083 Mon Sep 17 00:00:00 2001
From: Peter Maydell <peter.maydell@linaro.org>
Date: Tue, 23 Oct 2012 18:26:51 +0100
Subject: [PATCH] dma: Define dma_context_memory and use by default

Define a new global dma_context_memory which is a DMAContext corresponding
to the global address_space_memory AddressSpace. This can be used by
sysbus peripherals like sysbus-ohci which need to do DMA.

[PC] Use this dma context by default if NULL is passed to the dma API for
DMAContext *dma

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
 dma.h  |   17 +++++++++++++++++
 exec.c |    5 +++++
 2 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/dma.h b/dma.h
index 91ccdb5..defed50 100644
--- a/dma.h
+++ b/dma.h
@@ -68,6 +68,11 @@  struct DMAContext {
     DMAUnmapFunc *unmap;
 };
 
+/* A global DMA context corresponding to the address_space_memory
+ * AddressSpace, for sysbus devices which do DMA.
+ */
+extern DMAContext dma_context_memory;
+
 static inline void dma_barrier(DMAContext *dma, DMADirection dir)
 {
     /*
@@ -107,6 +112,9 @@  static inline bool dma_memory_valid(DMAContext *dma,
                                     dma_addr_t addr, dma_addr_t len,
                                     DMADirection dir)
 {
+    if (!dma) {
+        dma = &dma_context_memory;
+    }
     if (!dma_has_iommu(dma)) {
         return true;
     } else {
@@ -120,6 +128,9 @@  static inline int dma_memory_rw_relaxed(DMAContext *dma, dma_addr_t addr,
                                         void *buf, dma_addr_t len,
                                         DMADirection dir)
 {
+    if (!dma) {
+        dma = &dma_context_memory;
+    }
     if (!dma_has_iommu(dma)) {
         /* Fast-path for no IOMMU */
         address_space_rw(dma->as, addr, buf, len, dir == DMA_DIRECTION_FROM_DEVICE);
@@ -176,6 +187,9 @@  static inline void *dma_memory_map(DMAContext *dma,
                                    dma_addr_t addr, dma_addr_t *len,
                                    DMADirection dir)
 {
+    if (!dma) {
+        dma = &dma_context_memory;
+    }
     if (!dma_has_iommu(dma)) {
         hwaddr xlen = *len;
         void *p;
@@ -195,6 +209,9 @@  static inline void dma_memory_unmap(DMAContext *dma,
                                     void *buffer, dma_addr_t len,
                                     DMADirection dir, dma_addr_t access_len)
 {
+    if (!dma) {
+        dma = &dma_context_memory;
+    }
     if (!dma_has_iommu(dma)) {
         address_space_unmap(dma->as, buffer, (hwaddr)len,
                             dir == DMA_DIRECTION_FROM_DEVICE, access_len);
diff --git a/exec.c b/exec.c
index b0ed593..d2f6e79 100644
--- a/exec.c
+++ b/exec.c
@@ -34,6 +34,7 @@ 
 #include "hw/xen.h"
 #include "qemu-timer.h"
 #include "memory.h"
+#include "dma.h"
 #include "exec-memory.h"
 #if defined(CONFIG_USER_ONLY)
 #include <qemu.h>
@@ -103,6 +104,7 @@  static MemoryRegion *system_io;
 
 AddressSpace address_space_io;
 AddressSpace address_space_memory;
+DMAContext dma_context_memory;
 
 MemoryRegion io_mem_ram, io_mem_rom, io_mem_unassigned, io_mem_notdirty;
 static MemoryRegion io_mem_subpage_ram;
@@ -3276,6 +3278,9 @@  static void memory_map_init(void)
     memory_listener_register(&core_memory_listener, &address_space_memory);
     memory_listener_register(&io_memory_listener, &address_space_io);
     memory_listener_register(&tcg_memory_listener, &address_space_memory);
+
+    dma_context_init(&dma_context_memory, &address_space_memory,
+                     NULL, NULL, NULL);
 }
 
 MemoryRegion *get_system_memory(void)
-- 
1.7.0.4