cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

hcd-musb.c (45120B)


      1/*
      2 * "Inventra" High-speed Dual-Role Controller (MUSB-HDRC), Mentor Graphics,
      3 * USB2.0 OTG compliant core used in various chips.
      4 *
      5 * Copyright (C) 2008 Nokia Corporation
      6 * Written by Andrzej Zaborowski <andrew@openedhand.com>
      7 *
      8 * This program is free software; you can redistribute it and/or
      9 * modify it under the terms of the GNU General Public License as
     10 * published by the Free Software Foundation; either version 2 or
     11 * (at your option) version 3 of the License.
     12 *
     13 * This program is distributed in the hope that it will be useful,
     14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 * GNU General Public License for more details.
     17 *
     18 * You should have received a copy of the GNU General Public License along
     19 * with this program; if not, see <http://www.gnu.org/licenses/>.
     20 *
     21 * Only host-mode and non-DMA accesses are currently supported.
     22 */
     23#include "qemu/osdep.h"
     24#include "qemu/timer.h"
     25#include "hw/usb.h"
     26#include "hw/usb/hcd-musb.h"
     27#include "hw/irq.h"
     28#include "hw/hw.h"
     29
     30/* Common USB registers */
     31#define MUSB_HDRC_FADDR		0x00	/* 8-bit */
     32#define MUSB_HDRC_POWER		0x01	/* 8-bit */
     33
     34#define MUSB_HDRC_INTRTX	0x02	/* 16-bit */
     35#define MUSB_HDRC_INTRRX	0x04
     36#define MUSB_HDRC_INTRTXE	0x06  
     37#define MUSB_HDRC_INTRRXE	0x08  
     38#define MUSB_HDRC_INTRUSB	0x0a	/* 8 bit */
     39#define MUSB_HDRC_INTRUSBE	0x0b	/* 8 bit */
     40#define MUSB_HDRC_FRAME		0x0c	/* 16-bit */
     41#define MUSB_HDRC_INDEX		0x0e	/* 8 bit */
     42#define MUSB_HDRC_TESTMODE	0x0f	/* 8 bit */
     43
     44/* Per-EP registers in indexed mode */
     45#define MUSB_HDRC_EP_IDX	0x10	/* 8-bit */
     46
     47/* EP FIFOs */
     48#define MUSB_HDRC_FIFO		0x20
     49
     50/* Additional Control Registers */
     51#define	MUSB_HDRC_DEVCTL	0x60	/* 8 bit */
     52
     53/* These are indexed */
     54#define MUSB_HDRC_TXFIFOSZ	0x62	/* 8 bit (see masks) */
     55#define MUSB_HDRC_RXFIFOSZ	0x63	/* 8 bit (see masks) */
     56#define MUSB_HDRC_TXFIFOADDR	0x64	/* 16 bit offset shifted right 3 */
     57#define MUSB_HDRC_RXFIFOADDR	0x66	/* 16 bit offset shifted right 3 */
     58
     59/* Some more registers */
     60#define MUSB_HDRC_VCTRL		0x68	/* 8 bit */
     61#define MUSB_HDRC_HWVERS	0x6c	/* 8 bit */
     62
     63/* Added in HDRC 1.9(?) & MHDRC 1.4 */
     64/* ULPI pass-through */
     65#define MUSB_HDRC_ULPI_VBUSCTL	0x70
     66#define MUSB_HDRC_ULPI_REGDATA	0x74
     67#define MUSB_HDRC_ULPI_REGADDR	0x75
     68#define MUSB_HDRC_ULPI_REGCTL	0x76
     69
     70/* Extended config & PHY control */
     71#define MUSB_HDRC_ENDCOUNT	0x78	/* 8 bit */
     72#define MUSB_HDRC_DMARAMCFG	0x79	/* 8 bit */
     73#define MUSB_HDRC_PHYWAIT	0x7a	/* 8 bit */
     74#define MUSB_HDRC_PHYVPLEN	0x7b	/* 8 bit */
     75#define MUSB_HDRC_HS_EOF1	0x7c	/* 8 bit, units of 546.1 us */
     76#define MUSB_HDRC_FS_EOF1	0x7d	/* 8 bit, units of 533.3 ns */
     77#define MUSB_HDRC_LS_EOF1	0x7e	/* 8 bit, units of 1.067 us */
     78
     79/* Per-EP BUSCTL registers */
     80#define MUSB_HDRC_BUSCTL	0x80
     81
     82/* Per-EP registers in flat mode */
     83#define MUSB_HDRC_EP		0x100
     84
     85/* offsets to registers in flat model */
     86#define MUSB_HDRC_TXMAXP	0x00	/* 16 bit apparently */
     87#define MUSB_HDRC_TXCSR		0x02	/* 16 bit apparently */
     88#define MUSB_HDRC_CSR0		MUSB_HDRC_TXCSR		/* re-used for EP0 */
     89#define MUSB_HDRC_RXMAXP	0x04	/* 16 bit apparently */
     90#define MUSB_HDRC_RXCSR		0x06	/* 16 bit apparently */
     91#define MUSB_HDRC_RXCOUNT	0x08	/* 16 bit apparently */
     92#define MUSB_HDRC_COUNT0	MUSB_HDRC_RXCOUNT	/* re-used for EP0 */
     93#define MUSB_HDRC_TXTYPE	0x0a	/* 8 bit apparently */
     94#define MUSB_HDRC_TYPE0		MUSB_HDRC_TXTYPE	/* re-used for EP0 */
     95#define MUSB_HDRC_TXINTERVAL	0x0b	/* 8 bit apparently */
     96#define MUSB_HDRC_NAKLIMIT0	MUSB_HDRC_TXINTERVAL	/* re-used for EP0 */
     97#define MUSB_HDRC_RXTYPE	0x0c	/* 8 bit apparently */
     98#define MUSB_HDRC_RXINTERVAL	0x0d	/* 8 bit apparently */
     99#define MUSB_HDRC_FIFOSIZE	0x0f	/* 8 bit apparently */
    100#define MUSB_HDRC_CONFIGDATA	MGC_O_HDRC_FIFOSIZE	/* re-used for EP0 */
    101
    102/* "Bus control" registers */
    103#define MUSB_HDRC_TXFUNCADDR	0x00
    104#define MUSB_HDRC_TXHUBADDR	0x02
    105#define MUSB_HDRC_TXHUBPORT	0x03
    106
    107#define MUSB_HDRC_RXFUNCADDR	0x04
    108#define MUSB_HDRC_RXHUBADDR	0x06
    109#define MUSB_HDRC_RXHUBPORT	0x07
    110
    111/*
    112 * MUSBHDRC Register bit masks
    113 */
    114
    115/* POWER */
    116#define MGC_M_POWER_ISOUPDATE		0x80 
    117#define	MGC_M_POWER_SOFTCONN		0x40
    118#define	MGC_M_POWER_HSENAB		0x20
    119#define	MGC_M_POWER_HSMODE		0x10
    120#define MGC_M_POWER_RESET		0x08
    121#define MGC_M_POWER_RESUME		0x04
    122#define MGC_M_POWER_SUSPENDM		0x02
    123#define MGC_M_POWER_ENSUSPEND		0x01
    124
    125/* INTRUSB */
    126#define MGC_M_INTR_SUSPEND		0x01
    127#define MGC_M_INTR_RESUME		0x02
    128#define MGC_M_INTR_RESET		0x04
    129#define MGC_M_INTR_BABBLE		0x04
    130#define MGC_M_INTR_SOF			0x08 
    131#define MGC_M_INTR_CONNECT		0x10
    132#define MGC_M_INTR_DISCONNECT		0x20
    133#define MGC_M_INTR_SESSREQ		0x40
    134#define MGC_M_INTR_VBUSERROR		0x80	/* FOR SESSION END */
    135#define MGC_M_INTR_EP0			0x01	/* FOR EP0 INTERRUPT */
    136
    137/* DEVCTL */
    138#define MGC_M_DEVCTL_BDEVICE		0x80   
    139#define MGC_M_DEVCTL_FSDEV		0x40
    140#define MGC_M_DEVCTL_LSDEV		0x20
    141#define MGC_M_DEVCTL_VBUS		0x18
    142#define MGC_S_DEVCTL_VBUS		3
    143#define MGC_M_DEVCTL_HM			0x04
    144#define MGC_M_DEVCTL_HR			0x02
    145#define MGC_M_DEVCTL_SESSION		0x01
    146
    147/* TESTMODE */
    148#define MGC_M_TEST_FORCE_HOST		0x80
    149#define MGC_M_TEST_FIFO_ACCESS		0x40
    150#define MGC_M_TEST_FORCE_FS		0x20
    151#define MGC_M_TEST_FORCE_HS		0x10
    152#define MGC_M_TEST_PACKET		0x08
    153#define MGC_M_TEST_K			0x04
    154#define MGC_M_TEST_J			0x02
    155#define MGC_M_TEST_SE0_NAK		0x01
    156
    157/* CSR0 */
    158#define	MGC_M_CSR0_FLUSHFIFO		0x0100
    159#define MGC_M_CSR0_TXPKTRDY		0x0002
    160#define MGC_M_CSR0_RXPKTRDY		0x0001
    161
    162/* CSR0 in Peripheral mode */
    163#define MGC_M_CSR0_P_SVDSETUPEND	0x0080
    164#define MGC_M_CSR0_P_SVDRXPKTRDY	0x0040
    165#define MGC_M_CSR0_P_SENDSTALL		0x0020
    166#define MGC_M_CSR0_P_SETUPEND		0x0010
    167#define MGC_M_CSR0_P_DATAEND		0x0008
    168#define MGC_M_CSR0_P_SENTSTALL		0x0004
    169
    170/* CSR0 in Host mode */
    171#define MGC_M_CSR0_H_NO_PING		0x0800
    172#define MGC_M_CSR0_H_WR_DATATOGGLE	0x0400	/* set to allow setting: */
    173#define MGC_M_CSR0_H_DATATOGGLE		0x0200	/* data toggle control */
    174#define	MGC_M_CSR0_H_NAKTIMEOUT		0x0080
    175#define MGC_M_CSR0_H_STATUSPKT		0x0040
    176#define MGC_M_CSR0_H_REQPKT		0x0020
    177#define MGC_M_CSR0_H_ERROR		0x0010
    178#define MGC_M_CSR0_H_SETUPPKT		0x0008
    179#define MGC_M_CSR0_H_RXSTALL		0x0004
    180
    181/* CONFIGDATA */
    182#define MGC_M_CONFIGDATA_MPRXE		0x80	/* auto bulk pkt combining */
    183#define MGC_M_CONFIGDATA_MPTXE		0x40	/* auto bulk pkt splitting */
    184#define MGC_M_CONFIGDATA_BIGENDIAN	0x20
    185#define MGC_M_CONFIGDATA_HBRXE		0x10	/* HB-ISO for RX */
    186#define MGC_M_CONFIGDATA_HBTXE		0x08	/* HB-ISO for TX */
    187#define MGC_M_CONFIGDATA_DYNFIFO	0x04	/* dynamic FIFO sizing */
    188#define MGC_M_CONFIGDATA_SOFTCONE	0x02	/* SoftConnect */
    189#define MGC_M_CONFIGDATA_UTMIDW		0x01	/* Width, 0 => 8b, 1 => 16b */
    190
    191/* TXCSR in Peripheral and Host mode */
    192#define MGC_M_TXCSR_AUTOSET		0x8000
    193#define MGC_M_TXCSR_ISO			0x4000
    194#define MGC_M_TXCSR_MODE		0x2000
    195#define MGC_M_TXCSR_DMAENAB		0x1000
    196#define MGC_M_TXCSR_FRCDATATOG		0x0800
    197#define MGC_M_TXCSR_DMAMODE		0x0400
    198#define MGC_M_TXCSR_CLRDATATOG		0x0040
    199#define MGC_M_TXCSR_FLUSHFIFO		0x0008
    200#define MGC_M_TXCSR_FIFONOTEMPTY	0x0002
    201#define MGC_M_TXCSR_TXPKTRDY		0x0001
    202
    203/* TXCSR in Peripheral mode */
    204#define MGC_M_TXCSR_P_INCOMPTX		0x0080
    205#define MGC_M_TXCSR_P_SENTSTALL		0x0020
    206#define MGC_M_TXCSR_P_SENDSTALL		0x0010
    207#define MGC_M_TXCSR_P_UNDERRUN		0x0004
    208
    209/* TXCSR in Host mode */
    210#define MGC_M_TXCSR_H_WR_DATATOGGLE	0x0200
    211#define MGC_M_TXCSR_H_DATATOGGLE	0x0100
    212#define MGC_M_TXCSR_H_NAKTIMEOUT	0x0080
    213#define MGC_M_TXCSR_H_RXSTALL		0x0020
    214#define MGC_M_TXCSR_H_ERROR		0x0004
    215
    216/* RXCSR in Peripheral and Host mode */
    217#define MGC_M_RXCSR_AUTOCLEAR		0x8000
    218#define MGC_M_RXCSR_DMAENAB		0x2000
    219#define MGC_M_RXCSR_DISNYET		0x1000
    220#define MGC_M_RXCSR_DMAMODE		0x0800
    221#define MGC_M_RXCSR_INCOMPRX		0x0100
    222#define MGC_M_RXCSR_CLRDATATOG		0x0080
    223#define MGC_M_RXCSR_FLUSHFIFO		0x0010
    224#define MGC_M_RXCSR_DATAERROR		0x0008
    225#define MGC_M_RXCSR_FIFOFULL		0x0002
    226#define MGC_M_RXCSR_RXPKTRDY		0x0001
    227
    228/* RXCSR in Peripheral mode */
    229#define MGC_M_RXCSR_P_ISO		0x4000
    230#define MGC_M_RXCSR_P_SENTSTALL		0x0040
    231#define MGC_M_RXCSR_P_SENDSTALL		0x0020
    232#define MGC_M_RXCSR_P_OVERRUN		0x0004
    233
    234/* RXCSR in Host mode */
    235#define MGC_M_RXCSR_H_AUTOREQ		0x4000
    236#define MGC_M_RXCSR_H_WR_DATATOGGLE	0x0400
    237#define MGC_M_RXCSR_H_DATATOGGLE	0x0200
    238#define MGC_M_RXCSR_H_RXSTALL		0x0040
    239#define MGC_M_RXCSR_H_REQPKT		0x0020
    240#define MGC_M_RXCSR_H_ERROR		0x0004
    241
    242/* HUBADDR */
    243#define MGC_M_HUBADDR_MULTI_TT		0x80
    244
    245/* ULPI: Added in HDRC 1.9(?) & MHDRC 1.4 */
    246#define MGC_M_ULPI_VBCTL_USEEXTVBUSIND	0x02
    247#define MGC_M_ULPI_VBCTL_USEEXTVBUS	0x01
    248#define MGC_M_ULPI_REGCTL_INT_ENABLE	0x08
    249#define MGC_M_ULPI_REGCTL_READNOTWRITE	0x04
    250#define MGC_M_ULPI_REGCTL_COMPLETE	0x02
    251#define MGC_M_ULPI_REGCTL_REG		0x01
    252
    253/* #define MUSB_DEBUG */
    254
    255#ifdef MUSB_DEBUG
    256#define TRACE(fmt, ...) fprintf(stderr, "%s@%d: " fmt "\n", __func__, \
    257                                __LINE__, ##__VA_ARGS__)
    258#else
    259#define TRACE(...)
    260#endif
    261
    262
    263static void musb_attach(USBPort *port);
    264static void musb_detach(USBPort *port);
    265static void musb_child_detach(USBPort *port, USBDevice *child);
    266static void musb_schedule_cb(USBPort *port, USBPacket *p);
    267static void musb_async_cancel_device(MUSBState *s, USBDevice *dev);
    268
    269static USBPortOps musb_port_ops = {
    270    .attach = musb_attach,
    271    .detach = musb_detach,
    272    .child_detach = musb_child_detach,
    273    .complete = musb_schedule_cb,
    274};
    275
    276static USBBusOps musb_bus_ops = {
    277};
    278
    279typedef struct MUSBPacket MUSBPacket;
    280typedef struct MUSBEndPoint MUSBEndPoint;
    281
    282struct MUSBPacket {
    283    USBPacket p;
    284    MUSBEndPoint *ep;
    285    int dir;
    286};
    287
    288struct MUSBEndPoint {
    289    uint16_t faddr[2];
    290    uint8_t haddr[2];
    291    uint8_t hport[2];
    292    uint16_t csr[2];
    293    uint16_t maxp[2];
    294    uint16_t rxcount;
    295    uint8_t type[2];
    296    uint8_t interval[2];
    297    uint8_t config;
    298    uint8_t fifosize;
    299    int timeout[2];	/* Always in microframes */
    300
    301    uint8_t *buf[2];
    302    int fifolen[2];
    303    int fifostart[2];
    304    int fifoaddr[2];
    305    MUSBPacket packey[2];
    306    int status[2];
    307    int ext_size[2];
    308
    309    /* For callbacks' use */
    310    int epnum;
    311    int interrupt[2];
    312    MUSBState *musb;
    313    USBCallback *delayed_cb[2];
    314    QEMUTimer *intv_timer[2];
    315};
    316
    317struct MUSBState {
    318    qemu_irq irqs[musb_irq_max];
    319    USBBus bus;
    320    USBPort port;
    321
    322    int idx;
    323    uint8_t devctl;
    324    uint8_t power;
    325    uint8_t faddr;
    326
    327    uint8_t intr;
    328    uint8_t mask;
    329    uint16_t tx_intr;
    330    uint16_t tx_mask;
    331    uint16_t rx_intr;
    332    uint16_t rx_mask;
    333
    334    int setup_len;
    335    int session;
    336
    337    uint8_t buf[0x8000];
    338
    339        /* Duplicating the world since 2008!...  probably we should have 32
    340         * logical, single endpoints instead.  */
    341    MUSBEndPoint ep[16];
    342};
    343
    344void musb_reset(MUSBState *s)
    345{
    346    int i;
    347
    348    s->faddr = 0x00;
    349    s->devctl = 0;
    350    s->power = MGC_M_POWER_HSENAB;
    351    s->tx_intr = 0x0000;
    352    s->rx_intr = 0x0000;
    353    s->tx_mask = 0xffff;
    354    s->rx_mask = 0xffff;
    355    s->intr = 0x00;
    356    s->mask = 0x06;
    357    s->idx = 0;
    358
    359    s->setup_len = 0;
    360    s->session = 0;
    361    memset(s->buf, 0, sizeof(s->buf));
    362
    363    /* TODO: _DW */
    364    s->ep[0].config = MGC_M_CONFIGDATA_SOFTCONE | MGC_M_CONFIGDATA_DYNFIFO;
    365    for (i = 0; i < 16; i ++) {
    366        s->ep[i].fifosize = 64;
    367        s->ep[i].maxp[0] = 0x40;
    368        s->ep[i].maxp[1] = 0x40;
    369        s->ep[i].musb = s;
    370        s->ep[i].epnum = i;
    371        usb_packet_init(&s->ep[i].packey[0].p);
    372        usb_packet_init(&s->ep[i].packey[1].p);
    373    }
    374}
    375
    376struct MUSBState *musb_init(DeviceState *parent_device, int gpio_base)
    377{
    378    MUSBState *s = g_malloc0(sizeof(*s));
    379    int i;
    380
    381    for (i = 0; i < musb_irq_max; i++) {
    382        s->irqs[i] = qdev_get_gpio_in(parent_device, gpio_base + i);
    383    }
    384
    385    musb_reset(s);
    386
    387    usb_bus_new(&s->bus, sizeof(s->bus), &musb_bus_ops, parent_device);
    388    usb_register_port(&s->bus, &s->port, s, 0, &musb_port_ops,
    389                      USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
    390
    391    return s;
    392}
    393
    394static void musb_vbus_set(MUSBState *s, int level)
    395{
    396    if (level)
    397        s->devctl |= 3 << MGC_S_DEVCTL_VBUS;
    398    else
    399        s->devctl &= ~MGC_M_DEVCTL_VBUS;
    400
    401    qemu_set_irq(s->irqs[musb_set_vbus], level);
    402}
    403
    404static void musb_intr_set(MUSBState *s, int line, int level)
    405{
    406    if (!level) {
    407        s->intr &= ~(1 << line);
    408        qemu_irq_lower(s->irqs[line]);
    409    } else if (s->mask & (1 << line)) {
    410        s->intr |= 1 << line;
    411        qemu_irq_raise(s->irqs[line]);
    412    }
    413}
    414
    415static void musb_tx_intr_set(MUSBState *s, int line, int level)
    416{
    417    if (!level) {
    418        s->tx_intr &= ~(1 << line);
    419        if (!s->tx_intr)
    420            qemu_irq_lower(s->irqs[musb_irq_tx]);
    421    } else if (s->tx_mask & (1 << line)) {
    422        s->tx_intr |= 1 << line;
    423        qemu_irq_raise(s->irqs[musb_irq_tx]);
    424    }
    425}
    426
    427static void musb_rx_intr_set(MUSBState *s, int line, int level)
    428{
    429    if (line) {
    430        if (!level) {
    431            s->rx_intr &= ~(1 << line);
    432            if (!s->rx_intr)
    433                qemu_irq_lower(s->irqs[musb_irq_rx]);
    434        } else if (s->rx_mask & (1 << line)) {
    435            s->rx_intr |= 1 << line;
    436            qemu_irq_raise(s->irqs[musb_irq_rx]);
    437        }
    438    } else
    439        musb_tx_intr_set(s, line, level);
    440}
    441
    442uint32_t musb_core_intr_get(MUSBState *s)
    443{
    444    return (s->rx_intr << 15) | s->tx_intr;
    445}
    446
    447void musb_core_intr_clear(MUSBState *s, uint32_t mask)
    448{
    449    if (s->rx_intr) {
    450        s->rx_intr &= mask >> 15;
    451        if (!s->rx_intr)
    452            qemu_irq_lower(s->irqs[musb_irq_rx]);
    453    }
    454
    455    if (s->tx_intr) {
    456        s->tx_intr &= mask & 0xffff;
    457        if (!s->tx_intr)
    458            qemu_irq_lower(s->irqs[musb_irq_tx]);
    459    }
    460}
    461
    462void musb_set_size(MUSBState *s, int epnum, int size, int is_tx)
    463{
    464    s->ep[epnum].ext_size[!is_tx] = size;
    465    s->ep[epnum].fifostart[0] = 0;
    466    s->ep[epnum].fifostart[1] = 0;
    467    s->ep[epnum].fifolen[0] = 0;
    468    s->ep[epnum].fifolen[1] = 0;
    469}
    470
    471static void musb_session_update(MUSBState *s, int prev_dev, int prev_sess)
    472{
    473    int detect_prev = prev_dev && prev_sess;
    474    int detect = !!s->port.dev && s->session;
    475
    476    if (detect && !detect_prev) {
    477        /* Let's skip the ID pin sense and VBUS sense formalities and
    478         * and signal a successful SRP directly.  This should work at least
    479         * for the Linux driver stack.  */
    480        musb_intr_set(s, musb_irq_connect, 1);
    481
    482        if (s->port.dev->speed == USB_SPEED_LOW) {
    483            s->devctl &= ~MGC_M_DEVCTL_FSDEV;
    484            s->devctl |= MGC_M_DEVCTL_LSDEV;
    485        } else {
    486            s->devctl |= MGC_M_DEVCTL_FSDEV;
    487            s->devctl &= ~MGC_M_DEVCTL_LSDEV;
    488        }
    489
    490        /* A-mode?  */
    491        s->devctl &= ~MGC_M_DEVCTL_BDEVICE;
    492
    493        /* Host-mode bit?  */
    494        s->devctl |= MGC_M_DEVCTL_HM;
    495#if 1
    496        musb_vbus_set(s, 1);
    497#endif
    498    } else if (!detect && detect_prev) {
    499#if 1
    500        musb_vbus_set(s, 0);
    501#endif
    502    }
    503}
    504
    505/* Attach or detach a device on our only port.  */
    506static void musb_attach(USBPort *port)
    507{
    508    MUSBState *s = (MUSBState *) port->opaque;
    509
    510    musb_intr_set(s, musb_irq_vbus_request, 1);
    511    musb_session_update(s, 0, s->session);
    512}
    513
    514static void musb_detach(USBPort *port)
    515{
    516    MUSBState *s = (MUSBState *) port->opaque;
    517
    518    musb_async_cancel_device(s, port->dev);
    519
    520    musb_intr_set(s, musb_irq_disconnect, 1);
    521    musb_session_update(s, 1, s->session);
    522}
    523
    524static void musb_child_detach(USBPort *port, USBDevice *child)
    525{
    526    MUSBState *s = (MUSBState *) port->opaque;
    527
    528    musb_async_cancel_device(s, child);
    529}
    530
    531static void musb_cb_tick0(void *opaque)
    532{
    533    MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
    534
    535    ep->delayed_cb[0](&ep->packey[0].p, opaque);
    536}
    537
    538static void musb_cb_tick1(void *opaque)
    539{
    540    MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
    541
    542    ep->delayed_cb[1](&ep->packey[1].p, opaque);
    543}
    544
    545#define musb_cb_tick	(dir ? musb_cb_tick1 : musb_cb_tick0)
    546
    547static void musb_schedule_cb(USBPort *port, USBPacket *packey)
    548{
    549    MUSBPacket *p = container_of(packey, MUSBPacket, p);
    550    MUSBEndPoint *ep = p->ep;
    551    int dir = p->dir;
    552    int timeout = 0;
    553
    554    if (ep->status[dir] == USB_RET_NAK)
    555        timeout = ep->timeout[dir];
    556    else if (ep->interrupt[dir])
    557        timeout = 8;
    558    else {
    559        musb_cb_tick(ep);
    560        return;
    561    }
    562
    563    if (!ep->intv_timer[dir])
    564        ep->intv_timer[dir] = timer_new_ns(QEMU_CLOCK_VIRTUAL, musb_cb_tick, ep);
    565
    566    timer_mod(ep->intv_timer[dir], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
    567                   muldiv64(timeout, NANOSECONDS_PER_SECOND, 8000));
    568}
    569
    570static int musb_timeout(int ttype, int speed, int val)
    571{
    572#if 1
    573    return val << 3;
    574#endif
    575
    576    switch (ttype) {
    577    case USB_ENDPOINT_XFER_CONTROL:
    578        if (val < 2)
    579            return 0;
    580        else if (speed == USB_SPEED_HIGH)
    581            return 1 << (val - 1);
    582        else
    583            return 8 << (val - 1);
    584
    585    case USB_ENDPOINT_XFER_INT:
    586        if (speed == USB_SPEED_HIGH)
    587            if (val < 2)
    588                return 0;
    589            else
    590                return 1 << (val - 1);
    591        else
    592            return val << 3;
    593
    594    case USB_ENDPOINT_XFER_BULK:
    595    case USB_ENDPOINT_XFER_ISOC:
    596        if (val < 2)
    597            return 0;
    598        else if (speed == USB_SPEED_HIGH)
    599            return 1 << (val - 1);
    600        else
    601            return 8 << (val - 1);
    602        /* TODO: what with low-speed Bulk and Isochronous?  */
    603    }
    604
    605    hw_error("bad interval\n");
    606}
    607
    608static void musb_packet(MUSBState *s, MUSBEndPoint *ep,
    609                int epnum, int pid, int len, USBCallback cb, int dir)
    610{
    611    USBDevice *dev;
    612    USBEndpoint *uep;
    613    int idx = epnum && dir;
    614    int id;
    615    int ttype;
    616
    617    /* ep->type[0,1] contains:
    618     * in bits 7:6 the speed (0 - invalid, 1 - high, 2 - full, 3 - slow)
    619     * in bits 5:4 the transfer type (BULK / INT)
    620     * in bits 3:0 the EP num
    621     */
    622    ttype = epnum ? (ep->type[idx] >> 4) & 3 : 0;
    623
    624    ep->timeout[dir] = musb_timeout(ttype,
    625                    ep->type[idx] >> 6, ep->interval[idx]);
    626    ep->interrupt[dir] = ttype == USB_ENDPOINT_XFER_INT;
    627    ep->delayed_cb[dir] = cb;
    628
    629    /* A wild guess on the FADDR semantics... */
    630    dev = usb_find_device(&s->port, ep->faddr[idx]);
    631    if (dev == NULL) {
    632        return;
    633    }
    634    uep = usb_ep_get(dev, pid, ep->type[idx] & 0xf);
    635    id = pid | (dev->addr << 16) | (uep->nr << 8);
    636    usb_packet_setup(&ep->packey[dir].p, pid, uep, 0, id, false, true);
    637    usb_packet_addbuf(&ep->packey[dir].p, ep->buf[idx], len);
    638    ep->packey[dir].ep = ep;
    639    ep->packey[dir].dir = dir;
    640
    641    usb_handle_packet(dev, &ep->packey[dir].p);
    642
    643    if (ep->packey[dir].p.status == USB_RET_ASYNC) {
    644        usb_device_flush_ep_queue(dev, uep);
    645        ep->status[dir] = len;
    646        return;
    647    }
    648
    649    if (ep->packey[dir].p.status == USB_RET_SUCCESS) {
    650        ep->status[dir] = ep->packey[dir].p.actual_length;
    651    } else {
    652        ep->status[dir] = ep->packey[dir].p.status;
    653    }
    654    musb_schedule_cb(&s->port, &ep->packey[dir].p);
    655}
    656
    657static void musb_tx_packet_complete(USBPacket *packey, void *opaque)
    658{
    659    /* Unfortunately we can't use packey->devep because that's the remote
    660     * endpoint number and may be different than our local.  */
    661    MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
    662    int epnum = ep->epnum;
    663    MUSBState *s = ep->musb;
    664
    665    ep->fifostart[0] = 0;
    666    ep->fifolen[0] = 0;
    667#ifdef CLEAR_NAK
    668    if (ep->status[0] != USB_RET_NAK) {
    669#endif
    670        if (epnum)
    671            ep->csr[0] &= ~(MGC_M_TXCSR_FIFONOTEMPTY | MGC_M_TXCSR_TXPKTRDY);
    672        else
    673            ep->csr[0] &= ~MGC_M_CSR0_TXPKTRDY;
    674#ifdef CLEAR_NAK
    675    }
    676#endif
    677
    678    /* Clear all of the error bits first */
    679    if (epnum)
    680        ep->csr[0] &= ~(MGC_M_TXCSR_H_ERROR | MGC_M_TXCSR_H_RXSTALL |
    681                        MGC_M_TXCSR_H_NAKTIMEOUT);
    682    else
    683        ep->csr[0] &= ~(MGC_M_CSR0_H_ERROR | MGC_M_CSR0_H_RXSTALL |
    684                        MGC_M_CSR0_H_NAKTIMEOUT | MGC_M_CSR0_H_NO_PING);
    685
    686    if (ep->status[0] == USB_RET_STALL) {
    687        /* Command not supported by target! */
    688        ep->status[0] = 0;
    689
    690        if (epnum)
    691            ep->csr[0] |= MGC_M_TXCSR_H_RXSTALL;
    692        else
    693            ep->csr[0] |= MGC_M_CSR0_H_RXSTALL;
    694    }
    695
    696    if (ep->status[0] == USB_RET_NAK) {
    697        ep->status[0] = 0;
    698
    699        /* NAK timeouts are only generated in Bulk transfers and
    700         * Data-errors in Isochronous.  */
    701        if (ep->interrupt[0]) {
    702            return;
    703        }
    704
    705        if (epnum)
    706            ep->csr[0] |= MGC_M_TXCSR_H_NAKTIMEOUT;
    707        else
    708            ep->csr[0] |= MGC_M_CSR0_H_NAKTIMEOUT;
    709    }
    710
    711    if (ep->status[0] < 0) {
    712        if (ep->status[0] == USB_RET_BABBLE)
    713            musb_intr_set(s, musb_irq_rst_babble, 1);
    714
    715        /* Pretend we've tried three times already and failed (in
    716         * case of USB_TOKEN_SETUP).  */
    717        if (epnum)
    718            ep->csr[0] |= MGC_M_TXCSR_H_ERROR;
    719        else
    720            ep->csr[0] |= MGC_M_CSR0_H_ERROR;
    721
    722        musb_tx_intr_set(s, epnum, 1);
    723        return;
    724    }
    725    /* TODO: check len for over/underruns of an OUT packet?  */
    726
    727#ifdef SETUPLEN_HACK
    728    if (!epnum && ep->packey[0].pid == USB_TOKEN_SETUP)
    729        s->setup_len = ep->packey[0].data[6];
    730#endif
    731
    732    /* In DMA mode: if no error, assert DMA request for this EP,
    733     * and skip the interrupt.  */
    734    musb_tx_intr_set(s, epnum, 1);
    735}
    736
    737static void musb_rx_packet_complete(USBPacket *packey, void *opaque)
    738{
    739    /* Unfortunately we can't use packey->devep because that's the remote
    740     * endpoint number and may be different than our local.  */
    741    MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
    742    int epnum = ep->epnum;
    743    MUSBState *s = ep->musb;
    744
    745    ep->fifostart[1] = 0;
    746    ep->fifolen[1] = 0;
    747
    748#ifdef CLEAR_NAK
    749    if (ep->status[1] != USB_RET_NAK) {
    750#endif
    751        ep->csr[1] &= ~MGC_M_RXCSR_H_REQPKT;
    752        if (!epnum)
    753            ep->csr[0] &= ~MGC_M_CSR0_H_REQPKT;
    754#ifdef CLEAR_NAK
    755    }
    756#endif
    757
    758    /* Clear all of the imaginable error bits first */
    759    ep->csr[1] &= ~(MGC_M_RXCSR_H_ERROR | MGC_M_RXCSR_H_RXSTALL |
    760                    MGC_M_RXCSR_DATAERROR);
    761    if (!epnum)
    762        ep->csr[0] &= ~(MGC_M_CSR0_H_ERROR | MGC_M_CSR0_H_RXSTALL |
    763                        MGC_M_CSR0_H_NAKTIMEOUT | MGC_M_CSR0_H_NO_PING);
    764
    765    if (ep->status[1] == USB_RET_STALL) {
    766        ep->status[1] = 0;
    767
    768        ep->csr[1] |= MGC_M_RXCSR_H_RXSTALL;
    769        if (!epnum)
    770            ep->csr[0] |= MGC_M_CSR0_H_RXSTALL;
    771    }
    772
    773    if (ep->status[1] == USB_RET_NAK) {
    774        ep->status[1] = 0;
    775
    776        /* NAK timeouts are only generated in Bulk transfers and
    777         * Data-errors in Isochronous.  */
    778        if (ep->interrupt[1]) {
    779            musb_packet(s, ep, epnum, USB_TOKEN_IN,
    780                        packey->iov.size, musb_rx_packet_complete, 1);
    781            return;
    782        }
    783
    784        ep->csr[1] |= MGC_M_RXCSR_DATAERROR;
    785        if (!epnum)
    786            ep->csr[0] |= MGC_M_CSR0_H_NAKTIMEOUT;
    787    }
    788
    789    if (ep->status[1] < 0) {
    790        if (ep->status[1] == USB_RET_BABBLE) {
    791            musb_intr_set(s, musb_irq_rst_babble, 1);
    792            return;
    793        }
    794
    795        /* Pretend we've tried three times already and failed (in
    796         * case of a control transfer).  */
    797        ep->csr[1] |= MGC_M_RXCSR_H_ERROR;
    798        if (!epnum)
    799            ep->csr[0] |= MGC_M_CSR0_H_ERROR;
    800
    801        musb_rx_intr_set(s, epnum, 1);
    802        return;
    803    }
    804    /* TODO: check len for over/underruns of an OUT packet?  */
    805    /* TODO: perhaps make use of e->ext_size[1] here.  */
    806
    807    if (!(ep->csr[1] & (MGC_M_RXCSR_H_RXSTALL | MGC_M_RXCSR_DATAERROR))) {
    808        ep->csr[1] |= MGC_M_RXCSR_FIFOFULL | MGC_M_RXCSR_RXPKTRDY;
    809        if (!epnum)
    810            ep->csr[0] |= MGC_M_CSR0_RXPKTRDY;
    811
    812        ep->rxcount = ep->status[1]; /* XXX: MIN(packey->len, ep->maxp[1]); */
    813        /* In DMA mode: assert DMA request for this EP */
    814    }
    815
    816    /* Only if DMA has not been asserted */
    817    musb_rx_intr_set(s, epnum, 1);
    818}
    819
    820static void musb_async_cancel_device(MUSBState *s, USBDevice *dev)
    821{
    822    int ep, dir;
    823
    824    for (ep = 0; ep < 16; ep++) {
    825        for (dir = 0; dir < 2; dir++) {
    826            if (!usb_packet_is_inflight(&s->ep[ep].packey[dir].p) ||
    827                s->ep[ep].packey[dir].p.ep->dev != dev) {
    828                continue;
    829            }
    830            usb_cancel_packet(&s->ep[ep].packey[dir].p);
    831            /* status updates needed here? */
    832        }
    833    }
    834}
    835
    836static void musb_tx_rdy(MUSBState *s, int epnum)
    837{
    838    MUSBEndPoint *ep = s->ep + epnum;
    839    int pid;
    840    int total, valid = 0;
    841    TRACE("start %d, len %d",  ep->fifostart[0], ep->fifolen[0] );
    842    ep->fifostart[0] += ep->fifolen[0];
    843    ep->fifolen[0] = 0;
    844
    845    /* XXX: how's the total size of the packet retrieved exactly in
    846     * the generic case?  */
    847    total = ep->maxp[0] & 0x3ff;
    848
    849    if (ep->ext_size[0]) {
    850        total = ep->ext_size[0];
    851        ep->ext_size[0] = 0;
    852        valid = 1;
    853    }
    854
    855    /* If the packet is not fully ready yet, wait for a next segment.  */
    856    if (epnum && (ep->fifostart[0]) < total)
    857        return;
    858
    859    if (!valid)
    860        total = ep->fifostart[0];
    861
    862    pid = USB_TOKEN_OUT;
    863    if (!epnum && (ep->csr[0] & MGC_M_CSR0_H_SETUPPKT)) {
    864        pid = USB_TOKEN_SETUP;
    865        if (total != 8) {
    866            TRACE("illegal SETUPPKT length of %i bytes", total);
    867        }
    868        /* Controller should retry SETUP packets three times on errors
    869         * but it doesn't make sense for us to do that.  */
    870    }
    871
    872    musb_packet(s, ep, epnum, pid, total, musb_tx_packet_complete, 0);
    873}
    874
    875static void musb_rx_req(MUSBState *s, int epnum)
    876{
    877    MUSBEndPoint *ep = s->ep + epnum;
    878    int total;
    879
    880    /* If we already have a packet, which didn't fit into the
    881     * 64 bytes of the FIFO, only move the FIFO start and return. (Obsolete) */
    882    if (ep->packey[1].p.pid == USB_TOKEN_IN && ep->status[1] >= 0 &&
    883                    (ep->fifostart[1]) + ep->rxcount <
    884                    ep->packey[1].p.iov.size) {
    885        TRACE("0x%08x, %d",  ep->fifostart[1], ep->rxcount );
    886        ep->fifostart[1] += ep->rxcount;
    887        ep->fifolen[1] = 0;
    888
    889        ep->rxcount = MIN(ep->packey[0].p.iov.size - (ep->fifostart[1]),
    890                        ep->maxp[1]);
    891
    892        ep->csr[1] &= ~MGC_M_RXCSR_H_REQPKT;
    893        if (!epnum)
    894            ep->csr[0] &= ~MGC_M_CSR0_H_REQPKT;
    895
    896        /* Clear all of the error bits first */
    897        ep->csr[1] &= ~(MGC_M_RXCSR_H_ERROR | MGC_M_RXCSR_H_RXSTALL |
    898                        MGC_M_RXCSR_DATAERROR);
    899        if (!epnum)
    900            ep->csr[0] &= ~(MGC_M_CSR0_H_ERROR | MGC_M_CSR0_H_RXSTALL |
    901                            MGC_M_CSR0_H_NAKTIMEOUT | MGC_M_CSR0_H_NO_PING);
    902
    903        ep->csr[1] |= MGC_M_RXCSR_FIFOFULL | MGC_M_RXCSR_RXPKTRDY;
    904        if (!epnum)
    905            ep->csr[0] |= MGC_M_CSR0_RXPKTRDY;
    906        musb_rx_intr_set(s, epnum, 1);
    907        return;
    908    }
    909
    910    /* The driver sets maxp[1] to 64 or less because it knows the hardware
    911     * FIFO is this deep.  Bigger packets get split in
    912     * usb_generic_handle_packet but we can also do the splitting locally
    913     * for performance.  It turns out we can also have a bigger FIFO and
    914     * ignore the limit set in ep->maxp[1].  The Linux MUSB driver deals
    915     * OK with single packets of even 32KB and we avoid splitting, however
    916     * usb_msd.c sometimes sends a packet bigger than what Linux expects
    917     * (e.g. 8192 bytes instead of 4096) and we get an OVERRUN.  Splitting
    918     * hides this overrun from Linux.  Up to 4096 everything is fine
    919     * though.  Currently this is disabled.
    920     *
    921     * XXX: mind ep->fifosize.  */
    922    total = MIN(ep->maxp[1] & 0x3ff, sizeof(s->buf));
    923
    924#ifdef SETUPLEN_HACK
    925    /* Why should *we* do that instead of Linux?  */
    926    if (!epnum) {
    927        if (ep->packey[0].p.devaddr == 2) {
    928            total = MIN(s->setup_len, 8);
    929        } else {
    930            total = MIN(s->setup_len, 64);
    931        }
    932        s->setup_len -= total;
    933    }
    934#endif
    935
    936    musb_packet(s, ep, epnum, USB_TOKEN_IN, total, musb_rx_packet_complete, 1);
    937}
    938
    939static uint8_t musb_read_fifo(MUSBEndPoint *ep)
    940{
    941    uint8_t value;
    942    if (ep->fifolen[1] >= 64) {
    943        /* We have a FIFO underrun */
    944        TRACE("EP%d FIFO is now empty, stop reading", ep->epnum);
    945        return 0x00000000;
    946    }
    947    /* In DMA mode clear RXPKTRDY and set REQPKT automatically
    948     * (if AUTOREQ is set) */
    949
    950    ep->csr[1] &= ~MGC_M_RXCSR_FIFOFULL;
    951    value=ep->buf[1][ep->fifostart[1] + ep->fifolen[1] ++];
    952    TRACE("EP%d 0x%02x, %d", ep->epnum, value, ep->fifolen[1] );
    953    return value;
    954}
    955
    956static void musb_write_fifo(MUSBEndPoint *ep, uint8_t value)
    957{
    958    TRACE("EP%d = %02x", ep->epnum, value);
    959    if (ep->fifolen[0] >= 64) {
    960        /* We have a FIFO overrun */
    961        TRACE("EP%d FIFO exceeded 64 bytes, stop feeding data", ep->epnum);
    962        return;
    963     }
    964
    965     ep->buf[0][ep->fifostart[0] + ep->fifolen[0] ++] = value;
    966     ep->csr[0] |= MGC_M_TXCSR_FIFONOTEMPTY;
    967}
    968
    969static void musb_ep_frame_cancel(MUSBEndPoint *ep, int dir)
    970{
    971    if (ep->intv_timer[dir])
    972        timer_del(ep->intv_timer[dir]);
    973}
    974
    975/* Bus control */
    976static uint8_t musb_busctl_readb(void *opaque, int ep, int addr)
    977{
    978    MUSBState *s = (MUSBState *) opaque;
    979
    980    switch (addr) {
    981    /* For USB2.0 HS hubs only */
    982    case MUSB_HDRC_TXHUBADDR:
    983        return s->ep[ep].haddr[0];
    984    case MUSB_HDRC_TXHUBPORT:
    985        return s->ep[ep].hport[0];
    986    case MUSB_HDRC_RXHUBADDR:
    987        return s->ep[ep].haddr[1];
    988    case MUSB_HDRC_RXHUBPORT:
    989        return s->ep[ep].hport[1];
    990
    991    default:
    992        TRACE("unknown register 0x%02x", addr);
    993        return 0x00;
    994    };
    995}
    996
    997static void musb_busctl_writeb(void *opaque, int ep, int addr, uint8_t value)
    998{
    999    MUSBState *s = (MUSBState *) opaque;
   1000
   1001    switch (addr) {
   1002    case MUSB_HDRC_TXFUNCADDR:
   1003        s->ep[ep].faddr[0] = value;
   1004        break;
   1005    case MUSB_HDRC_RXFUNCADDR:
   1006        s->ep[ep].faddr[1] = value;
   1007        break;
   1008    case MUSB_HDRC_TXHUBADDR:
   1009        s->ep[ep].haddr[0] = value;
   1010        break;
   1011    case MUSB_HDRC_TXHUBPORT:
   1012        s->ep[ep].hport[0] = value;
   1013        break;
   1014    case MUSB_HDRC_RXHUBADDR:
   1015        s->ep[ep].haddr[1] = value;
   1016        break;
   1017    case MUSB_HDRC_RXHUBPORT:
   1018        s->ep[ep].hport[1] = value;
   1019        break;
   1020
   1021    default:
   1022        TRACE("unknown register 0x%02x", addr);
   1023        break;
   1024    };
   1025}
   1026
   1027static uint16_t musb_busctl_readh(void *opaque, int ep, int addr)
   1028{
   1029    MUSBState *s = (MUSBState *) opaque;
   1030
   1031    switch (addr) {
   1032    case MUSB_HDRC_TXFUNCADDR:
   1033        return s->ep[ep].faddr[0];
   1034    case MUSB_HDRC_RXFUNCADDR:
   1035        return s->ep[ep].faddr[1];
   1036
   1037    default:
   1038        return musb_busctl_readb(s, ep, addr) |
   1039                (musb_busctl_readb(s, ep, addr | 1) << 8);
   1040    };
   1041}
   1042
   1043static void musb_busctl_writeh(void *opaque, int ep, int addr, uint16_t value)
   1044{
   1045    MUSBState *s = (MUSBState *) opaque;
   1046
   1047    switch (addr) {
   1048    case MUSB_HDRC_TXFUNCADDR:
   1049        s->ep[ep].faddr[0] = value;
   1050        break;
   1051    case MUSB_HDRC_RXFUNCADDR:
   1052        s->ep[ep].faddr[1] = value;
   1053        break;
   1054
   1055    default:
   1056        musb_busctl_writeb(s, ep, addr, value & 0xff);
   1057        musb_busctl_writeb(s, ep, addr | 1, value >> 8);
   1058    };
   1059}
   1060
   1061/* Endpoint control */
   1062static uint8_t musb_ep_readb(void *opaque, int ep, int addr)
   1063{
   1064    MUSBState *s = (MUSBState *) opaque;
   1065
   1066    switch (addr) {
   1067    case MUSB_HDRC_TXTYPE:
   1068        return s->ep[ep].type[0];
   1069    case MUSB_HDRC_TXINTERVAL:
   1070        return s->ep[ep].interval[0];
   1071    case MUSB_HDRC_RXTYPE:
   1072        return s->ep[ep].type[1];
   1073    case MUSB_HDRC_RXINTERVAL:
   1074        return s->ep[ep].interval[1];
   1075    case (MUSB_HDRC_FIFOSIZE & ~1):
   1076        return 0x00;
   1077    case MUSB_HDRC_FIFOSIZE:
   1078        return ep ? s->ep[ep].fifosize : s->ep[ep].config;
   1079    case MUSB_HDRC_RXCOUNT:
   1080        return s->ep[ep].rxcount;
   1081
   1082    default:
   1083        TRACE("unknown register 0x%02x", addr);
   1084        return 0x00;
   1085    };
   1086}
   1087
   1088static void musb_ep_writeb(void *opaque, int ep, int addr, uint8_t value)
   1089{
   1090    MUSBState *s = (MUSBState *) opaque;
   1091
   1092    switch (addr) {
   1093    case MUSB_HDRC_TXTYPE:
   1094        s->ep[ep].type[0] = value;
   1095        break;
   1096    case MUSB_HDRC_TXINTERVAL:
   1097        s->ep[ep].interval[0] = value;
   1098        musb_ep_frame_cancel(&s->ep[ep], 0);
   1099        break;
   1100    case MUSB_HDRC_RXTYPE:
   1101        s->ep[ep].type[1] = value;
   1102        break;
   1103    case MUSB_HDRC_RXINTERVAL:
   1104        s->ep[ep].interval[1] = value;
   1105        musb_ep_frame_cancel(&s->ep[ep], 1);
   1106        break;
   1107    case (MUSB_HDRC_FIFOSIZE & ~1):
   1108        break;
   1109    case MUSB_HDRC_FIFOSIZE:
   1110        TRACE("somebody messes with fifosize (now %i bytes)", value);
   1111        s->ep[ep].fifosize = value;
   1112        break;
   1113    default:
   1114        TRACE("unknown register 0x%02x", addr);
   1115        break;
   1116    };
   1117}
   1118
   1119static uint16_t musb_ep_readh(void *opaque, int ep, int addr)
   1120{
   1121    MUSBState *s = (MUSBState *) opaque;
   1122    uint16_t ret;
   1123
   1124    switch (addr) {
   1125    case MUSB_HDRC_TXMAXP:
   1126        return s->ep[ep].maxp[0];
   1127    case MUSB_HDRC_TXCSR:
   1128        return s->ep[ep].csr[0];
   1129    case MUSB_HDRC_RXMAXP:
   1130        return s->ep[ep].maxp[1];
   1131    case MUSB_HDRC_RXCSR:
   1132        ret = s->ep[ep].csr[1];
   1133
   1134        /* TODO: This and other bits probably depend on
   1135         * ep->csr[1] & MGC_M_RXCSR_AUTOCLEAR.  */
   1136        if (s->ep[ep].csr[1] & MGC_M_RXCSR_AUTOCLEAR)
   1137            s->ep[ep].csr[1] &= ~MGC_M_RXCSR_RXPKTRDY;
   1138
   1139        return ret;
   1140    case MUSB_HDRC_RXCOUNT:
   1141        return s->ep[ep].rxcount;
   1142
   1143    default:
   1144        return musb_ep_readb(s, ep, addr) |
   1145                (musb_ep_readb(s, ep, addr | 1) << 8);
   1146    };
   1147}
   1148
   1149static void musb_ep_writeh(void *opaque, int ep, int addr, uint16_t value)
   1150{
   1151    MUSBState *s = (MUSBState *) opaque;
   1152
   1153    switch (addr) {
   1154    case MUSB_HDRC_TXMAXP:
   1155        s->ep[ep].maxp[0] = value;
   1156        break;
   1157    case MUSB_HDRC_TXCSR:
   1158        if (ep) {
   1159            s->ep[ep].csr[0] &= value & 0xa6;
   1160            s->ep[ep].csr[0] |= value & 0xff59;
   1161        } else {
   1162            s->ep[ep].csr[0] &= value & 0x85;
   1163            s->ep[ep].csr[0] |= value & 0xf7a;
   1164        }
   1165
   1166        musb_ep_frame_cancel(&s->ep[ep], 0);
   1167
   1168        if ((ep && (value & MGC_M_TXCSR_FLUSHFIFO)) ||
   1169                        (!ep && (value & MGC_M_CSR0_FLUSHFIFO))) {
   1170            s->ep[ep].fifolen[0] = 0;
   1171            s->ep[ep].fifostart[0] = 0;
   1172            if (ep)
   1173                s->ep[ep].csr[0] &=
   1174                        ~(MGC_M_TXCSR_FIFONOTEMPTY | MGC_M_TXCSR_TXPKTRDY);
   1175            else
   1176                s->ep[ep].csr[0] &=
   1177                        ~(MGC_M_CSR0_TXPKTRDY | MGC_M_CSR0_RXPKTRDY);
   1178        }
   1179        if (
   1180                        (ep &&
   1181#ifdef CLEAR_NAK
   1182                         (value & MGC_M_TXCSR_TXPKTRDY) &&
   1183                         !(value & MGC_M_TXCSR_H_NAKTIMEOUT)) ||
   1184#else
   1185                         (value & MGC_M_TXCSR_TXPKTRDY)) ||
   1186#endif
   1187                        (!ep &&
   1188#ifdef CLEAR_NAK
   1189                         (value & MGC_M_CSR0_TXPKTRDY) &&
   1190                         !(value & MGC_M_CSR0_H_NAKTIMEOUT)))
   1191#else
   1192                         (value & MGC_M_CSR0_TXPKTRDY)))
   1193#endif
   1194            musb_tx_rdy(s, ep);
   1195        if (!ep &&
   1196                        (value & MGC_M_CSR0_H_REQPKT) &&
   1197#ifdef CLEAR_NAK
   1198                        !(value & (MGC_M_CSR0_H_NAKTIMEOUT |
   1199                                        MGC_M_CSR0_RXPKTRDY)))
   1200#else
   1201                        !(value & MGC_M_CSR0_RXPKTRDY))
   1202#endif
   1203            musb_rx_req(s, ep);
   1204        break;
   1205
   1206    case MUSB_HDRC_RXMAXP:
   1207        s->ep[ep].maxp[1] = value;
   1208        break;
   1209    case MUSB_HDRC_RXCSR:
   1210        /* (DMA mode only) */
   1211        if (
   1212                (value & MGC_M_RXCSR_H_AUTOREQ) &&
   1213                !(value & MGC_M_RXCSR_RXPKTRDY) &&
   1214                (s->ep[ep].csr[1] & MGC_M_RXCSR_RXPKTRDY))
   1215            value |= MGC_M_RXCSR_H_REQPKT;
   1216
   1217        s->ep[ep].csr[1] &= 0x102 | (value & 0x4d);
   1218        s->ep[ep].csr[1] |= value & 0xfeb0;
   1219
   1220        musb_ep_frame_cancel(&s->ep[ep], 1);
   1221
   1222        if (value & MGC_M_RXCSR_FLUSHFIFO) {
   1223            s->ep[ep].fifolen[1] = 0;
   1224            s->ep[ep].fifostart[1] = 0;
   1225            s->ep[ep].csr[1] &= ~(MGC_M_RXCSR_FIFOFULL | MGC_M_RXCSR_RXPKTRDY);
   1226            /* If double buffering and we have two packets ready, flush
   1227             * only the first one and set up the fifo at the second packet.  */
   1228        }
   1229#ifdef CLEAR_NAK
   1230        if ((value & MGC_M_RXCSR_H_REQPKT) && !(value & MGC_M_RXCSR_DATAERROR))
   1231#else
   1232        if (value & MGC_M_RXCSR_H_REQPKT)
   1233#endif
   1234            musb_rx_req(s, ep);
   1235        break;
   1236    case MUSB_HDRC_RXCOUNT:
   1237        s->ep[ep].rxcount = value;
   1238        break;
   1239
   1240    default:
   1241        musb_ep_writeb(s, ep, addr, value & 0xff);
   1242        musb_ep_writeb(s, ep, addr | 1, value >> 8);
   1243    };
   1244}
   1245
   1246/* Generic control */
   1247static uint32_t musb_readb(void *opaque, hwaddr addr)
   1248{
   1249    MUSBState *s = (MUSBState *) opaque;
   1250    int ep, i;
   1251    uint8_t ret;
   1252
   1253    switch (addr) {
   1254    case MUSB_HDRC_FADDR:
   1255        return s->faddr;
   1256    case MUSB_HDRC_POWER:
   1257        return s->power;
   1258    case MUSB_HDRC_INTRUSB:
   1259        ret = s->intr;
   1260        for (i = 0; i < sizeof(ret) * 8; i ++)
   1261            if (ret & (1 << i))
   1262                musb_intr_set(s, i, 0);
   1263        return ret;
   1264    case MUSB_HDRC_INTRUSBE:
   1265        return s->mask;
   1266    case MUSB_HDRC_INDEX:
   1267        return s->idx;
   1268    case MUSB_HDRC_TESTMODE:
   1269        return 0x00;
   1270
   1271    case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
   1272        return musb_ep_readb(s, s->idx, addr & 0xf);
   1273
   1274    case MUSB_HDRC_DEVCTL:
   1275        return s->devctl;
   1276
   1277    case MUSB_HDRC_TXFIFOSZ:
   1278    case MUSB_HDRC_RXFIFOSZ:
   1279    case MUSB_HDRC_VCTRL:
   1280        /* TODO */
   1281        return 0x00;
   1282
   1283    case MUSB_HDRC_HWVERS:
   1284        return (1 << 10) | 400;
   1285
   1286    case (MUSB_HDRC_VCTRL | 1):
   1287    case (MUSB_HDRC_HWVERS | 1):
   1288    case (MUSB_HDRC_DEVCTL | 1):
   1289        return 0x00;
   1290
   1291    case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
   1292        ep = (addr >> 3) & 0xf;
   1293        return musb_busctl_readb(s, ep, addr & 0x7);
   1294
   1295    case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
   1296        ep = (addr >> 4) & 0xf;
   1297        return musb_ep_readb(s, ep, addr & 0xf);
   1298
   1299    case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
   1300        ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
   1301        return musb_read_fifo(s->ep + ep);
   1302
   1303    default:
   1304        TRACE("unknown register 0x%02x", (int) addr);
   1305        return 0x00;
   1306    };
   1307}
   1308
   1309static void musb_writeb(void *opaque, hwaddr addr, uint32_t value)
   1310{
   1311    MUSBState *s = (MUSBState *) opaque;
   1312    int ep;
   1313
   1314    switch (addr) {
   1315    case MUSB_HDRC_FADDR:
   1316        s->faddr = value & 0x7f;
   1317        break;
   1318    case MUSB_HDRC_POWER:
   1319        s->power = (value & 0xef) | (s->power & 0x10);
   1320        /* MGC_M_POWER_RESET is also read-only in Peripheral Mode */
   1321        if ((value & MGC_M_POWER_RESET) && s->port.dev) {
   1322            usb_device_reset(s->port.dev);
   1323            /* Negotiate high-speed operation if MGC_M_POWER_HSENAB is set.  */
   1324            if ((value & MGC_M_POWER_HSENAB) &&
   1325                            s->port.dev->speed == USB_SPEED_HIGH)
   1326                s->power |= MGC_M_POWER_HSMODE;	/* Success */
   1327            /* Restart frame counting.  */
   1328        }
   1329        if (value & MGC_M_POWER_SUSPENDM) {
   1330            /* When all transfers finish, suspend and if MGC_M_POWER_ENSUSPEND
   1331             * is set, also go into low power mode.  Frame counting stops.  */
   1332            /* XXX: Cleared when the interrupt register is read */
   1333        }
   1334        if (value & MGC_M_POWER_RESUME) {
   1335            /* Wait 20ms and signal resuming on the bus.  Frame counting
   1336             * restarts.  */
   1337        }
   1338        break;
   1339    case MUSB_HDRC_INTRUSB:
   1340        break;
   1341    case MUSB_HDRC_INTRUSBE:
   1342        s->mask = value & 0xff;
   1343        break;
   1344    case MUSB_HDRC_INDEX:
   1345        s->idx = value & 0xf;
   1346        break;
   1347    case MUSB_HDRC_TESTMODE:
   1348        break;
   1349
   1350    case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
   1351        musb_ep_writeb(s, s->idx, addr & 0xf, value);
   1352        break;
   1353
   1354    case MUSB_HDRC_DEVCTL:
   1355        s->session = !!(value & MGC_M_DEVCTL_SESSION);
   1356        musb_session_update(s,
   1357                        !!s->port.dev,
   1358                        !!(s->devctl & MGC_M_DEVCTL_SESSION));
   1359
   1360        /* It seems this is the only R/W bit in this register?  */
   1361        s->devctl &= ~MGC_M_DEVCTL_SESSION;
   1362        s->devctl |= value & MGC_M_DEVCTL_SESSION;
   1363        break;
   1364
   1365    case MUSB_HDRC_TXFIFOSZ:
   1366    case MUSB_HDRC_RXFIFOSZ:
   1367    case MUSB_HDRC_VCTRL:
   1368        /* TODO */
   1369        break;
   1370
   1371    case (MUSB_HDRC_VCTRL | 1):
   1372    case (MUSB_HDRC_DEVCTL | 1):
   1373        break;
   1374
   1375    case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
   1376        ep = (addr >> 3) & 0xf;
   1377        musb_busctl_writeb(s, ep, addr & 0x7, value);
   1378        break;
   1379
   1380    case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
   1381        ep = (addr >> 4) & 0xf;
   1382        musb_ep_writeb(s, ep, addr & 0xf, value);
   1383        break;
   1384
   1385    case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
   1386        ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
   1387        musb_write_fifo(s->ep + ep, value & 0xff);
   1388        break;
   1389
   1390    default:
   1391        TRACE("unknown register 0x%02x", (int) addr);
   1392        break;
   1393    };
   1394}
   1395
   1396static uint32_t musb_readh(void *opaque, hwaddr addr)
   1397{
   1398    MUSBState *s = (MUSBState *) opaque;
   1399    int ep, i;
   1400    uint16_t ret;
   1401
   1402    switch (addr) {
   1403    case MUSB_HDRC_INTRTX:
   1404        ret = s->tx_intr;
   1405        /* Auto clear */
   1406        for (i = 0; i < sizeof(ret) * 8; i ++)
   1407            if (ret & (1 << i))
   1408                musb_tx_intr_set(s, i, 0);
   1409        return ret;
   1410    case MUSB_HDRC_INTRRX:
   1411        ret = s->rx_intr;
   1412        /* Auto clear */
   1413        for (i = 0; i < sizeof(ret) * 8; i ++)
   1414            if (ret & (1 << i))
   1415                musb_rx_intr_set(s, i, 0);
   1416        return ret;
   1417    case MUSB_HDRC_INTRTXE:
   1418        return s->tx_mask;
   1419    case MUSB_HDRC_INTRRXE:
   1420        return s->rx_mask;
   1421
   1422    case MUSB_HDRC_FRAME:
   1423        /* TODO */
   1424        return 0x0000;
   1425    case MUSB_HDRC_TXFIFOADDR:
   1426        return s->ep[s->idx].fifoaddr[0];
   1427    case MUSB_HDRC_RXFIFOADDR:
   1428        return s->ep[s->idx].fifoaddr[1];
   1429
   1430    case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
   1431        return musb_ep_readh(s, s->idx, addr & 0xf);
   1432
   1433    case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
   1434        ep = (addr >> 3) & 0xf;
   1435        return musb_busctl_readh(s, ep, addr & 0x7);
   1436
   1437    case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
   1438        ep = (addr >> 4) & 0xf;
   1439        return musb_ep_readh(s, ep, addr & 0xf);
   1440
   1441    case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
   1442        ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
   1443        return (musb_read_fifo(s->ep + ep) | musb_read_fifo(s->ep + ep) << 8);
   1444
   1445    default:
   1446        return musb_readb(s, addr) | (musb_readb(s, addr | 1) << 8);
   1447    };
   1448}
   1449
   1450static void musb_writeh(void *opaque, hwaddr addr, uint32_t value)
   1451{
   1452    MUSBState *s = (MUSBState *) opaque;
   1453    int ep;
   1454
   1455    switch (addr) {
   1456    case MUSB_HDRC_INTRTXE:
   1457        s->tx_mask = value;
   1458        /* XXX: the masks seem to apply on the raising edge like with
   1459         * edge-triggered interrupts, thus no need to update.  I may be
   1460         * wrong though.  */
   1461        break;
   1462    case MUSB_HDRC_INTRRXE:
   1463        s->rx_mask = value;
   1464        break;
   1465
   1466    case MUSB_HDRC_FRAME:
   1467        /* TODO */
   1468        break;
   1469    case MUSB_HDRC_TXFIFOADDR:
   1470        s->ep[s->idx].fifoaddr[0] = value;
   1471        s->ep[s->idx].buf[0] =
   1472                s->buf + ((value << 3) & 0x7ff );
   1473        break;
   1474    case MUSB_HDRC_RXFIFOADDR:
   1475        s->ep[s->idx].fifoaddr[1] = value;
   1476        s->ep[s->idx].buf[1] =
   1477                s->buf + ((value << 3) & 0x7ff);
   1478        break;
   1479
   1480    case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
   1481        musb_ep_writeh(s, s->idx, addr & 0xf, value);
   1482        break;
   1483
   1484    case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
   1485        ep = (addr >> 3) & 0xf;
   1486        musb_busctl_writeh(s, ep, addr & 0x7, value);
   1487        break;
   1488
   1489    case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
   1490        ep = (addr >> 4) & 0xf;
   1491        musb_ep_writeh(s, ep, addr & 0xf, value);
   1492        break;
   1493
   1494    case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
   1495        ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
   1496        musb_write_fifo(s->ep + ep, value & 0xff);
   1497        musb_write_fifo(s->ep + ep, (value >> 8) & 0xff);
   1498        break;
   1499
   1500    default:
   1501        musb_writeb(s, addr, value & 0xff);
   1502        musb_writeb(s, addr | 1, value >> 8);
   1503    };
   1504}
   1505
   1506static uint32_t musb_readw(void *opaque, hwaddr addr)
   1507{
   1508    MUSBState *s = (MUSBState *) opaque;
   1509    int ep;
   1510
   1511    switch (addr) {
   1512    case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
   1513        ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
   1514        return ( musb_read_fifo(s->ep + ep)       |
   1515                 musb_read_fifo(s->ep + ep) << 8  |
   1516                 musb_read_fifo(s->ep + ep) << 16 |
   1517                 musb_read_fifo(s->ep + ep) << 24 );
   1518    default:
   1519        TRACE("unknown register 0x%02x", (int) addr);
   1520        return 0x00000000;
   1521    };
   1522}
   1523
   1524static void musb_writew(void *opaque, hwaddr addr, uint32_t value)
   1525{
   1526    MUSBState *s = (MUSBState *) opaque;
   1527    int ep;
   1528
   1529    switch (addr) {
   1530    case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
   1531        ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
   1532        musb_write_fifo(s->ep + ep, value & 0xff);
   1533        musb_write_fifo(s->ep + ep, (value >> 8 ) & 0xff);
   1534        musb_write_fifo(s->ep + ep, (value >> 16) & 0xff);
   1535        musb_write_fifo(s->ep + ep, (value >> 24) & 0xff);
   1536            break;
   1537    default:
   1538        TRACE("unknown register 0x%02x", (int) addr);
   1539        break;
   1540    };
   1541}
   1542
   1543MUSBReadFunc * const musb_read[] = {
   1544    musb_readb,
   1545    musb_readh,
   1546    musb_readw,
   1547};
   1548
   1549MUSBWriteFunc * const musb_write[] = {
   1550    musb_writeb,
   1551    musb_writeh,
   1552    musb_writew,
   1553};