~ubuntu-branches/ubuntu/wily/qemu-kvm-spice/wily

« back to all changes in this revision

Viewing changes to hw/usb-musb.c

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2011-10-19 10:44:56 UTC
  • Revision ID: james.westby@ubuntu.com-20111019104456-xgvskumk3sxi97f4
Tags: upstream-0.15.0+noroms
ImportĀ upstreamĀ versionĀ 0.15.0+noroms

Show diffs side-by-side

added added

removed removed

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