From patchwork Fri Sep 27 02:31:22 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?w4Frb3MgS292w6Fjcw==?= X-Patchwork-Id: 278413 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)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 009A32C0340 for ; Fri, 27 Sep 2013 12:45:30 +1000 (EST) Received: from localhost ([::1]:60896 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VPO3b-000114-5E for incoming@patchwork.ozlabs.org; Thu, 26 Sep 2013 22:45:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54654) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VPNrI-0007w4-LC for qemu-devel@nongnu.org; Thu, 26 Sep 2013 22:32:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VPNrD-0007Pm-CQ for qemu-devel@nongnu.org; Thu, 26 Sep 2013 22:32:44 -0400 Received: from mail-ea0-x230.google.com ([2a00:1450:4013:c01::230]:60594) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VPNrD-0007PU-15 for qemu-devel@nongnu.org; Thu, 26 Sep 2013 22:32:39 -0400 Received: by mail-ea0-f176.google.com with SMTP id q16so912914ead.35 for ; Thu, 26 Sep 2013 19:32:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; bh=ql6fjRbRWdnevaRl1xJx0LJce3crh6pLoiZrRW7sqQo=; b=Gu8f9pDye6kVay8JUXn32PinCbQBzFA5CrhIOR9EpkXVtgc5L7iz0o0S7po9hjDTC5 K0t4qt8dXeGrJJJCxmFiSRIrhbIGe+gECdmJfgXKdI3jZyhCddj4sDovbMNeGXRLOHxt ZZDZ1JoT72s7MKjmAQmxZy6sxhF+vsgoS1zqqflfCH5qtN1qNh4C/v1bczm8TOOcPMis V+Tk2GKLbVuySMvnHtZWRwQ9Br9szDiI8Ql1l7vroGSilr9NjzQOhvzLaqqZy0So/LU8 IHHThyCiu52V74hAJjfK1onRYta9g5VKsW7CNfY+hXsRCXRU2aS3MxOUTrC3dw88j2II z7Vw== X-Received: by 10.15.64.1 with SMTP id n1mr6452765eex.15.1380249158190; Thu, 26 Sep 2013 19:32:38 -0700 (PDT) Received: from zion.teteny.elte.hu (zion.teteny.elte.hu. [157.181.96.43]) by mx.google.com with ESMTPSA id f49sm10573304eec.7.1969.12.31.16.00.00 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 26 Sep 2013 19:32:37 -0700 (PDT) From: =?UTF-8?q?=C3=81kos=20Kov=C3=A1cs?= To: qemu-devel@nongnu.org Date: Fri, 27 Sep 2013 04:31:22 +0200 Message-Id: <1380249092-4775-62-git-send-email-akoskovacs@gmx.com> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1380249092-4775-1-git-send-email-akoskovacs@gmx.com> References: <1380249092-4775-1-git-send-email-akoskovacs@gmx.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:4013:c01::230 Cc: =?UTF-8?q?=C3=81kos=20Kov=C3=A1cs?= Subject: [Qemu-devel] [v2 61/71] hw/usb/hcd-ohci.c: Move sysbus and PCI code to new files 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 Move the existing sysbus and PCI logic to hcd-ohci-sysbus.c and hcd-ohci-pci.c from hcd-ohci.c. Create a new hcd-ohci.h header for the shared declarations and macros. Signed-off-by: Ákos Kovács --- hw/usb/hcd-ohci-pci.c | 96 +++++++++++++++ hw/usb/hcd-ohci-sysbus.c | 84 +++++++++++++ hw/usb/hcd-ohci.h | 311 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 491 insertions(+) create mode 100644 hw/usb/hcd-ohci-pci.c create mode 100644 hw/usb/hcd-ohci-sysbus.c create mode 100644 hw/usb/hcd-ohci.h diff --git a/hw/usb/hcd-ohci-pci.c b/hw/usb/hcd-ohci-pci.c new file mode 100644 index 0000000..ac50951 --- /dev/null +++ b/hw/usb/hcd-ohci-pci.c @@ -0,0 +1,96 @@ +/* + * QEMU USB OHCI Emulation + * Copyright (c) 2004 Gianni Tedesco + * Copyright (c) 2006 CodeSourcery + * Copyright (c) 2006 Openedhand Ltd. + * + * 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 Lesser General Public + * License along with this library; if not, see . + * + * TODO: + * o Isochronous transfers + * o Allocate bandwidth in frames properly + * o Disable timers when nothing needs to be done, or remove timer usage + * all together. + * o BIOS work to boot from USB storage +*/ + +#include "hw/usb/hcd-ohci.h" + +#define TYPE_PCI_OHCI "pci-ohci" +#define PCI_OHCI(obj) OBJECT_CHECK(OHCIPCIState, (obj), TYPE_PCI_OHCI) + +typedef struct { + /*< private >*/ + PCIDevice parent_obj; + /*< public >*/ + + OHCIState state; + char *masterbus; + uint32_t num_ports; + uint32_t firstport; +} OHCIPCIState; + +static Property ohci_pci_properties[] = { + DEFINE_PROP_STRING("masterbus", OHCIPCIState, masterbus), + DEFINE_PROP_UINT32("num-ports", OHCIPCIState, num_ports, 3), + DEFINE_PROP_UINT32("firstport", OHCIPCIState, firstport, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static int usb_ohci_initfn_pci(PCIDevice *dev) +{ + OHCIPCIState *ohci = PCI_OHCI(dev); + + dev->config[PCI_CLASS_PROG] = 0x10; /* OHCI */ + dev->config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin A */ + + if (usb_ohci_init(&ohci->state, DEVICE(dev), ohci->num_ports, 0, + ohci->masterbus, ohci->firstport, + pci_get_address_space(dev)) != 0) { + return -1; + } + ohci->state.irq = dev->irq[0]; + + pci_register_bar(dev, 0, 0, &ohci->state.mem); + return 0; +} + +static void ohci_pci_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->init = usb_ohci_initfn_pci; + k->vendor_id = PCI_VENDOR_ID_APPLE; + k->device_id = PCI_DEVICE_ID_APPLE_IPID_USB; + k->class_id = PCI_CLASS_SERIAL_USB; + k->no_hotplug = 1; + set_bit(DEVICE_CATEGORY_USB, dc->categories); + dc->desc = "Apple USB Controller"; + dc->props = ohci_pci_properties; +} + +static const TypeInfo ohci_pci_info = { + .name = TYPE_PCI_OHCI, + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(OHCIPCIState), + .class_init = ohci_pci_class_init, +}; + +static void ohci_pci_register_type(void) +{ + type_register_static(&ohci_pci_info); +} + +type_init(ohci_pci_register_type) diff --git a/hw/usb/hcd-ohci-sysbus.c b/hw/usb/hcd-ohci-sysbus.c new file mode 100644 index 0000000..b9d15db --- /dev/null +++ b/hw/usb/hcd-ohci-sysbus.c @@ -0,0 +1,84 @@ +/* + * QEMU USB OHCI Emulation + * Copyright (c) 2004 Gianni Tedesco + * Copyright (c) 2006 CodeSourcery + * Copyright (c) 2006 Openedhand Ltd. + * + * 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 Lesser General Public + * License along with this library; if not, see . + * + * TODO: + * o Isochronous transfers + * o Allocate bandwidth in frames properly + * o Disable timers when nothing needs to be done, or remove timer usage + * all together. + * o BIOS work to boot from USB storage +*/ + +#include "hw/sysbus.h" +#include "hw/usb/hcd-ohci.h" + +#define TYPE_SYSBUS_OHCI "sysbus-ohci" +#define SYSBUS_OHCI(obj) OBJECT_CHECK(OHCISysBusState, (obj), TYPE_SYSBUS_OHCI) + +typedef struct { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + OHCIState ohci; + uint32_t num_ports; + dma_addr_t dma_offset; +} OHCISysBusState; + +static Property ohci_sysbus_properties[] = { + DEFINE_PROP_UINT32("num-ports", OHCISysBusState, num_ports, 3), + DEFINE_PROP_DMAADDR("dma-offset", OHCISysBusState, dma_offset, 3), + DEFINE_PROP_END_OF_LIST(), +}; + +static void ohci_realize_pxa(DeviceState *dev, Error **errp) +{ + OHCISysBusState *s = SYSBUS_OHCI(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + + /* Cannot fail as we pass NULL for masterbus */ + usb_ohci_init(&s->ohci, dev, s->num_ports, s->dma_offset, NULL, 0, + &address_space_memory); + sysbus_init_irq(sbd, &s->ohci.irq); + sysbus_init_mmio(sbd, &s->ohci.mem); +} + +static void ohci_sysbus_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = ohci_realize_pxa; + set_bit(DEVICE_CATEGORY_USB, dc->categories); + dc->desc = "OHCI USB Controller"; + dc->props = ohci_sysbus_properties; +} + +static const TypeInfo ohci_sysbus_info = { + .name = TYPE_SYSBUS_OHCI, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(OHCISysBusState), + .class_init = ohci_sysbus_class_init, +}; + +static void ohci_sysbus_register_type(void) +{ + type_register_static(&ohci_sysbus_info); +} + +type_init(ohci_sysbus_register_type) diff --git a/hw/usb/hcd-ohci.h b/hw/usb/hcd-ohci.h new file mode 100644 index 0000000..8be00f2 --- /dev/null +++ b/hw/usb/hcd-ohci.h @@ -0,0 +1,311 @@ +/* + * QEMU USB OHCI Emulation + * Copyright (c) 2004 Gianni Tedesco + * Copyright (c) 2006 CodeSourcery + * Copyright (c) 2006 Openedhand Ltd. + * + * 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 Lesser General Public + * License along with this library; if not, see . + * + * TODO: + * o Isochronous transfers + * o Allocate bandwidth in frames properly + * o Disable timers when nothing needs to be done, or remove timer usage + * all together. + * o BIOS work to boot from USB storage +*/ + +#ifndef HW_USB_OHCI_H +#define HW_USB_OHCI_H 1 + +#include "hw/hw.h" +#include "qemu/timer.h" +#include "hw/usb.h" +#include "hw/qdev-dma.h" +#include "hw/pci/pci.h" + +//#define DEBUG_OHCI +/* Dump packet contents. */ +//#define DEBUG_PACKET +//#define DEBUG_ISOCH +/* This causes frames to occur 1000x slower */ +//#define OHCI_TIME_WARP 1 + +#ifdef DEBUG_OHCI +#define DPRINTF printf +#else +#define DPRINTF(...) +#endif + +/* Number of Downstream Ports on the root hub. */ + +#define OHCI_MAX_PORTS 15 + +typedef struct OHCIPort { + USBPort port; + uint32_t ctrl; +} OHCIPort; + +typedef struct { + USBBus bus; + qemu_irq irq; + MemoryRegion mem; + AddressSpace *as; + int num_ports; + const char *name; + + QEMUTimer *eof_timer; + int64_t sof_time; + + /* OHCI state */ + /* Control partition */ + uint32_t ctl, status; + uint32_t intr_status; + uint32_t intr; + + /* memory pointer partition */ + uint32_t hcca; + uint32_t ctrl_head, ctrl_cur; + uint32_t bulk_head, bulk_cur; + uint32_t per_cur; + uint32_t done; + int done_count; + + /* Frame counter partition */ + uint32_t fsmps:15; + uint32_t fit:1; + uint32_t fi:14; + uint32_t frt:1; + uint16_t frame_number; + uint16_t padding; + uint32_t pstart; + uint32_t lst; + + /* Root Hub partition */ + uint32_t rhdesc_a, rhdesc_b; + uint32_t rhstatus; + OHCIPort rhport[OHCI_MAX_PORTS]; + + /* PXA27x Non-OHCI events */ + uint32_t hstatus; + uint32_t hmask; + uint32_t hreset; + uint32_t htest; + + /* SM501 local memory offset */ + dma_addr_t localmem_base; + + /* Active packets. */ + uint32_t old_ctl; + USBPacket usb_packet; + uint8_t usb_buf[8192]; + uint32_t async_td; + int async_complete; + +} OHCIState; + +/* Host Controller Communications Area */ +struct ohci_hcca { + uint32_t intr[32]; + uint16_t frame, pad; + uint32_t done; +}; +#define HCCA_WRITEBACK_OFFSET offsetof(struct ohci_hcca, frame) +#define HCCA_WRITEBACK_SIZE 8 /* frame, pad, done */ + +#define ED_WBACK_OFFSET offsetof(struct ohci_ed, head) +#define ED_WBACK_SIZE 4 + +/* Bitfields for the first word of an Endpoint Desciptor. */ +#define OHCI_ED_FA_SHIFT 0 +#define OHCI_ED_FA_MASK (0x7f<> OHCI_##field##_SHIFT) + +#define OHCI_SET_BM(val, field, newval) do { \ + val &= ~OHCI_##field##_MASK; \ + val |= ((newval) << OHCI_##field##_SHIFT) & OHCI_##field##_MASK; \ + } while(0) + +/* endpoint descriptor */ +struct ohci_ed { + uint32_t flags; + uint32_t tail; + uint32_t head; + uint32_t next; +}; + +/* General transfer descriptor */ +struct ohci_td { + uint32_t flags; + uint32_t cbp; + uint32_t next; + uint32_t be; +}; + +/* Isochronous transfer descriptor */ +struct ohci_iso_td { + uint32_t flags; + uint32_t bp; + uint32_t next; + uint32_t be; + uint16_t offset[8]; +}; + +#define USB_HZ 12000000 + +/* OHCI Local stuff */ +#define OHCI_CTL_CBSR ((1<<0)|(1<<1)) +#define OHCI_CTL_PLE (1<<2) +#define OHCI_CTL_IE (1<<3) +#define OHCI_CTL_CLE (1<<4) +#define OHCI_CTL_BLE (1<<5) +#define OHCI_CTL_HCFS ((1<<6)|(1<<7)) +#define OHCI_USB_RESET 0x00 +#define OHCI_USB_RESUME 0x40 +#define OHCI_USB_OPERATIONAL 0x80 +#define OHCI_USB_SUSPEND 0xc0 +#define OHCI_CTL_IR (1<<8) +#define OHCI_CTL_RWC (1<<9) +#define OHCI_CTL_RWE (1<<10) + +#define OHCI_STATUS_HCR (1<<0) +#define OHCI_STATUS_CLF (1<<1) +#define OHCI_STATUS_BLF (1<<2) +#define OHCI_STATUS_OCR (1<<3) +#define OHCI_STATUS_SOC ((1<<6)|(1<<7)) + +#define OHCI_INTR_SO (1<<0) /* Scheduling overrun */ +#define OHCI_INTR_WD (1<<1) /* HcDoneHead writeback */ +#define OHCI_INTR_SF (1<<2) /* Start of frame */ +#define OHCI_INTR_RD (1<<3) /* Resume detect */ +#define OHCI_INTR_UE (1<<4) /* Unrecoverable error */ +#define OHCI_INTR_FNO (1<<5) /* Frame number overflow */ +#define OHCI_INTR_RHSC (1<<6) /* Root hub status change */ +#define OHCI_INTR_OC (1<<30) /* Ownership change */ +#define OHCI_INTR_MIE (1<<31) /* Master Interrupt Enable */ + +#define OHCI_HCCA_SIZE 0x100 +#define OHCI_HCCA_MASK 0xffffff00 + +#define OHCI_EDPTR_MASK 0xfffffff0 + +#define OHCI_FMI_FI 0x00003fff +#define OHCI_FMI_FSMPS 0xffff0000 +#define OHCI_FMI_FIT 0x80000000 + +#define OHCI_FR_RT (1<<31) + +#define OHCI_LS_THRESH 0x628 + +#define OHCI_RHA_RW_MASK 0x00000000 /* Mask of supported features. */ +#define OHCI_RHA_PSM (1<<8) +#define OHCI_RHA_NPS (1<<9) +#define OHCI_RHA_DT (1<<10) +#define OHCI_RHA_OCPM (1<<11) +#define OHCI_RHA_NOCP (1<<12) +#define OHCI_RHA_POTPGT_MASK 0xff000000 + +#define OHCI_RHS_LPS (1<<0) +#define OHCI_RHS_OCI (1<<1) +#define OHCI_RHS_DRWE (1<<15) +#define OHCI_RHS_LPSC (1<<16) +#define OHCI_RHS_OCIC (1<<17) +#define OHCI_RHS_CRWE (1<<31) + +#define OHCI_PORT_CCS (1<<0) +#define OHCI_PORT_PES (1<<1) +#define OHCI_PORT_PSS (1<<2) +#define OHCI_PORT_POCI (1<<3) +#define OHCI_PORT_PRS (1<<4) +#define OHCI_PORT_PPS (1<<8) +#define OHCI_PORT_LSDA (1<<9) +#define OHCI_PORT_CSC (1<<16) +#define OHCI_PORT_PESC (1<<17) +#define OHCI_PORT_PSSC (1<<18) +#define OHCI_PORT_OCIC (1<<19) +#define OHCI_PORT_PRSC (1<<20) +#define OHCI_PORT_WTC (OHCI_PORT_CSC|OHCI_PORT_PESC|OHCI_PORT_PSSC \ + |OHCI_PORT_OCIC|OHCI_PORT_PRSC) + +#define OHCI_TD_DIR_SETUP 0x0 +#define OHCI_TD_DIR_OUT 0x1 +#define OHCI_TD_DIR_IN 0x2 +#define OHCI_TD_DIR_RESERVED 0x3 + +#define OHCI_CC_NOERROR 0x0 +#define OHCI_CC_CRC 0x1 +#define OHCI_CC_BITSTUFFING 0x2 +#define OHCI_CC_DATATOGGLEMISMATCH 0x3 +#define OHCI_CC_STALL 0x4 +#define OHCI_CC_DEVICENOTRESPONDING 0x5 +#define OHCI_CC_PIDCHECKFAILURE 0x6 +#define OHCI_CC_UNDEXPETEDPID 0x7 +#define OHCI_CC_DATAOVERRUN 0x8 +#define OHCI_CC_DATAUNDERRUN 0x9 +#define OHCI_CC_BUFFEROVERRUN 0xc +#define OHCI_CC_BUFFERUNDERRUN 0xd + +#define OHCI_HRESET_FSBIR (1 << 0) + +int usb_ohci_init(OHCIState *ohci, DeviceState *dev, + int num_ports, dma_addr_t localmem_base, + char *masterbus, uint32_t firstport, + AddressSpace *as); + +#endif /* HW_USB_OHCI_H */