~fboudra/qemu-linaro/new-upstream-release-1.2.0-2012.09-0ubuntu1

« back to all changes in this revision

Viewing changes to hw/usb/hcd-musb.c

  • Committer: Fathi Boudra
  • Author(s): Fathi Boudra
  • Date: 2012-08-21 06:47:11 UTC
  • mfrom: (0.1.16)
  • Revision ID: fathi.boudra@linaro.org-20120821064711-7yxmubp2v8a44xce
Tags: 1.1.50-2012.08-0ubuntu1
* New upstream release.
  - support emulated systems with more than 2G of memory. (LP: #1030588)
* Drop powerpc-missing-include.patch - merged upstream.
* Update debian/control: 
  - drop perl build dependency.
  - add libfdt-dev build dependency.
* Update debian/qemu-keymaps.install file.
* Update debian/rules:
  - update QEMU_CPU for ARM architecture: armv4l -> armv7l.
  - update conf_audio_drv: default to PulseAudio since PA is the default on
    Ubuntu.
  - enable KVM on ARM architecture.
  - enable flat device tree support (--enable-fdt). (LP: #1030594)

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 "hw/usb.h"
 
26
#include "hw/irq.h"
 
27
#include "hw/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
#define MUSB_HDRC_ULPI_RAWDATA  0x77
 
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", __FUNCTION__, \
 
257
                               __LINE__, ##__VA_ARGS__)
 
258
#else
 
259
#define TRACE(...)
 
260
#endif
 
261
 
 
262
 
 
263
static void musb_attach(USBPort *port);
 
264
static void musb_detach(USBPort *port);
 
265
static void musb_child_detach(USBPort *port, USBDevice *child);
 
266
static void musb_schedule_cb(USBPort *port, USBPacket *p);
 
267
static void musb_async_cancel_device(MUSBState *s, USBDevice *dev);
 
268
 
 
269
static 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
 
 
276
static USBBusOps musb_bus_ops = {
 
277
};
 
278
 
 
279
typedef struct MUSBPacket MUSBPacket;
 
280
typedef struct MUSBEndPoint MUSBEndPoint;
 
281
 
 
282
struct MUSBPacket {
 
283
    USBPacket p;
 
284
    MUSBEndPoint *ep;
 
285
    int dir;
 
286
};
 
287
 
 
288
struct 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
 
 
317
struct 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
 
 
344
void 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
 
 
376
struct 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, &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
 
 
394
static 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
 
 
404
static 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
 
 
415
static 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
 
 
427
static 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
 
 
442
uint32_t musb_core_intr_get(MUSBState *s)
 
443
{
 
444
    return (s->rx_intr << 15) | s->tx_intr;
 
445
}
 
446
 
 
447
void 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
 
 
462
void 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
 
 
471
static 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.  */
 
506
static 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
 
 
514
static 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
 
 
524
static 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
 
 
531
static 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
 
 
538
static 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
 
 
547
static 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
        return musb_cb_tick(ep);
 
560
 
 
561
    if (!ep->intv_timer[dir])
 
562
        ep->intv_timer[dir] = qemu_new_timer_ns(vm_clock, musb_cb_tick, ep);
 
563
 
 
564
    qemu_mod_timer(ep->intv_timer[dir], qemu_get_clock_ns(vm_clock) +
 
565
                   muldiv64(timeout, get_ticks_per_sec(), 8000));
 
566
}
 
567
 
 
568
static int musb_timeout(int ttype, int speed, int val)
 
569
{
 
570
#if 1
 
571
    return val << 3;
 
572
#endif
 
573
 
 
574
    switch (ttype) {
 
575
    case USB_ENDPOINT_XFER_CONTROL:
 
576
        if (val < 2)
 
577
            return 0;
 
578
        else if (speed == USB_SPEED_HIGH)
 
579
            return 1 << (val - 1);
 
580
        else
 
581
            return 8 << (val - 1);
 
582
 
 
583
    case USB_ENDPOINT_XFER_INT:
 
584
        if (speed == USB_SPEED_HIGH)
 
585
            if (val < 2)
 
586
                return 0;
 
587
            else
 
588
                return 1 << (val - 1);
 
589
        else
 
590
            return val << 3;
 
591
 
 
592
    case USB_ENDPOINT_XFER_BULK:
 
593
    case USB_ENDPOINT_XFER_ISOC:
 
594
        if (val < 2)
 
595
            return 0;
 
596
        else if (speed == USB_SPEED_HIGH)
 
597
            return 1 << (val - 1);
 
598
        else
 
599
            return 8 << (val - 1);
 
600
        /* TODO: what with low-speed Bulk and Isochronous?  */
 
601
    }
 
602
 
 
603
    hw_error("bad interval\n");
 
604
}
 
605
 
 
606
static void musb_packet(MUSBState *s, MUSBEndPoint *ep,
 
607
                int epnum, int pid, int len, USBCallback cb, int dir)
 
608
{
 
609
    USBDevice *dev;
 
610
    USBEndpoint *uep;
 
611
    int ret;
 
612
    int idx = epnum && dir;
 
613
    int ttype;
 
614
 
 
615
    /* ep->type[0,1] contains:
 
616
     * in bits 7:6 the speed (0 - invalid, 1 - high, 2 - full, 3 - slow)
 
617
     * in bits 5:4 the transfer type (BULK / INT)
 
618
     * in bits 3:0 the EP num
 
619
     */
 
620
    ttype = epnum ? (ep->type[idx] >> 4) & 3 : 0;
 
621
 
 
622
    ep->timeout[dir] = musb_timeout(ttype,
 
623
                    ep->type[idx] >> 6, ep->interval[idx]);
 
624
    ep->interrupt[dir] = ttype == USB_ENDPOINT_XFER_INT;
 
625
    ep->delayed_cb[dir] = cb;
 
626
 
 
627
    /* A wild guess on the FADDR semantics... */
 
628
    dev = usb_find_device(&s->port, ep->faddr[idx]);
 
629
    uep = usb_ep_get(dev, pid, ep->type[idx] & 0xf);
 
630
    usb_packet_setup(&ep->packey[dir].p, pid, uep);
 
631
    usb_packet_addbuf(&ep->packey[dir].p, ep->buf[idx], len);
 
632
    ep->packey[dir].ep = ep;
 
633
    ep->packey[dir].dir = dir;
 
634
 
 
635
    ret = usb_handle_packet(dev, &ep->packey[dir].p);
 
636
 
 
637
    if (ret == USB_RET_ASYNC) {
 
638
        ep->status[dir] = len;
 
639
        return;
 
640
    }
 
641
 
 
642
    ep->status[dir] = ret;
 
643
    musb_schedule_cb(&s->port, &ep->packey[dir].p);
 
644
}
 
645
 
 
646
static void musb_tx_packet_complete(USBPacket *packey, void *opaque)
 
647
{
 
648
    /* Unfortunately we can't use packey->devep because that's the remote
 
649
     * endpoint number and may be different than our local.  */
 
650
    MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
 
651
    int epnum = ep->epnum;
 
652
    MUSBState *s = ep->musb;
 
653
 
 
654
    ep->fifostart[0] = 0;
 
655
    ep->fifolen[0] = 0;
 
656
#ifdef CLEAR_NAK
 
657
    if (ep->status[0] != USB_RET_NAK) {
 
658
#endif
 
659
        if (epnum)
 
660
            ep->csr[0] &= ~(MGC_M_TXCSR_FIFONOTEMPTY | MGC_M_TXCSR_TXPKTRDY);
 
661
        else
 
662
            ep->csr[0] &= ~MGC_M_CSR0_TXPKTRDY;
 
663
#ifdef CLEAR_NAK
 
664
    }
 
665
#endif
 
666
 
 
667
    /* Clear all of the error bits first */
 
668
    if (epnum)
 
669
        ep->csr[0] &= ~(MGC_M_TXCSR_H_ERROR | MGC_M_TXCSR_H_RXSTALL |
 
670
                        MGC_M_TXCSR_H_NAKTIMEOUT);
 
671
    else
 
672
        ep->csr[0] &= ~(MGC_M_CSR0_H_ERROR | MGC_M_CSR0_H_RXSTALL |
 
673
                        MGC_M_CSR0_H_NAKTIMEOUT | MGC_M_CSR0_H_NO_PING);
 
674
 
 
675
    if (ep->status[0] == USB_RET_STALL) {
 
676
        /* Command not supported by target! */
 
677
        ep->status[0] = 0;
 
678
 
 
679
        if (epnum)
 
680
            ep->csr[0] |= MGC_M_TXCSR_H_RXSTALL;
 
681
        else
 
682
            ep->csr[0] |= MGC_M_CSR0_H_RXSTALL;
 
683
    }
 
684
 
 
685
    if (ep->status[0] == USB_RET_NAK) {
 
686
        ep->status[0] = 0;
 
687
 
 
688
        /* NAK timeouts are only generated in Bulk transfers and
 
689
         * Data-errors in Isochronous.  */
 
690
        if (ep->interrupt[0]) {
 
691
            return;
 
692
        }
 
693
 
 
694
        if (epnum)
 
695
            ep->csr[0] |= MGC_M_TXCSR_H_NAKTIMEOUT;
 
696
        else
 
697
            ep->csr[0] |= MGC_M_CSR0_H_NAKTIMEOUT;
 
698
    }
 
699
 
 
700
    if (ep->status[0] < 0) {
 
701
        if (ep->status[0] == USB_RET_BABBLE)
 
702
            musb_intr_set(s, musb_irq_rst_babble, 1);
 
703
 
 
704
        /* Pretend we've tried three times already and failed (in
 
705
         * case of USB_TOKEN_SETUP).  */
 
706
        if (epnum)
 
707
            ep->csr[0] |= MGC_M_TXCSR_H_ERROR;
 
708
        else
 
709
            ep->csr[0] |= MGC_M_CSR0_H_ERROR;
 
710
 
 
711
        musb_tx_intr_set(s, epnum, 1);
 
712
        return;
 
713
    }
 
714
    /* TODO: check len for over/underruns of an OUT packet?  */
 
715
 
 
716
#ifdef SETUPLEN_HACK
 
717
    if (!epnum && ep->packey[0].pid == USB_TOKEN_SETUP)
 
718
        s->setup_len = ep->packey[0].data[6];
 
719
#endif
 
720
 
 
721
    /* In DMA mode: if no error, assert DMA request for this EP,
 
722
     * and skip the interrupt.  */
 
723
    musb_tx_intr_set(s, epnum, 1);
 
724
}
 
725
 
 
726
static void musb_rx_packet_complete(USBPacket *packey, void *opaque)
 
727
{
 
728
    /* Unfortunately we can't use packey->devep because that's the remote
 
729
     * endpoint number and may be different than our local.  */
 
730
    MUSBEndPoint *ep = (MUSBEndPoint *) opaque;
 
731
    int epnum = ep->epnum;
 
732
    MUSBState *s = ep->musb;
 
733
 
 
734
    ep->fifostart[1] = 0;
 
735
    ep->fifolen[1] = 0;
 
736
 
 
737
#ifdef CLEAR_NAK
 
738
    if (ep->status[1] != USB_RET_NAK) {
 
739
#endif
 
740
        ep->csr[1] &= ~MGC_M_RXCSR_H_REQPKT;
 
741
        if (!epnum)
 
742
            ep->csr[0] &= ~MGC_M_CSR0_H_REQPKT;
 
743
#ifdef CLEAR_NAK
 
744
    }
 
745
#endif
 
746
 
 
747
    /* Clear all of the imaginable error bits first */
 
748
    ep->csr[1] &= ~(MGC_M_RXCSR_H_ERROR | MGC_M_RXCSR_H_RXSTALL |
 
749
                    MGC_M_RXCSR_DATAERROR);
 
750
    if (!epnum)
 
751
        ep->csr[0] &= ~(MGC_M_CSR0_H_ERROR | MGC_M_CSR0_H_RXSTALL |
 
752
                        MGC_M_CSR0_H_NAKTIMEOUT | MGC_M_CSR0_H_NO_PING);
 
753
 
 
754
    if (ep->status[1] == USB_RET_STALL) {
 
755
        ep->status[1] = 0;
 
756
        packey->result = 0;
 
757
 
 
758
        ep->csr[1] |= MGC_M_RXCSR_H_RXSTALL;
 
759
        if (!epnum)
 
760
            ep->csr[0] |= MGC_M_CSR0_H_RXSTALL;
 
761
    }
 
762
 
 
763
    if (ep->status[1] == USB_RET_NAK) {
 
764
        ep->status[1] = 0;
 
765
 
 
766
        /* NAK timeouts are only generated in Bulk transfers and
 
767
         * Data-errors in Isochronous.  */
 
768
        if (ep->interrupt[1])
 
769
            return musb_packet(s, ep, epnum, USB_TOKEN_IN,
 
770
                            packey->iov.size, musb_rx_packet_complete, 1);
 
771
 
 
772
        ep->csr[1] |= MGC_M_RXCSR_DATAERROR;
 
773
        if (!epnum)
 
774
            ep->csr[0] |= MGC_M_CSR0_H_NAKTIMEOUT;
 
775
    }
 
776
 
 
777
    if (ep->status[1] < 0) {
 
778
        if (ep->status[1] == USB_RET_BABBLE) {
 
779
            musb_intr_set(s, musb_irq_rst_babble, 1);
 
780
            return;
 
781
        }
 
782
 
 
783
        /* Pretend we've tried three times already and failed (in
 
784
         * case of a control transfer).  */
 
785
        ep->csr[1] |= MGC_M_RXCSR_H_ERROR;
 
786
        if (!epnum)
 
787
            ep->csr[0] |= MGC_M_CSR0_H_ERROR;
 
788
 
 
789
        musb_rx_intr_set(s, epnum, 1);
 
790
        return;
 
791
    }
 
792
    /* TODO: check len for over/underruns of an OUT packet?  */
 
793
    /* TODO: perhaps make use of e->ext_size[1] here.  */
 
794
 
 
795
    packey->result = ep->status[1];
 
796
 
 
797
    if (!(ep->csr[1] & (MGC_M_RXCSR_H_RXSTALL | MGC_M_RXCSR_DATAERROR))) {
 
798
        ep->csr[1] |= MGC_M_RXCSR_FIFOFULL | MGC_M_RXCSR_RXPKTRDY;
 
799
        if (!epnum)
 
800
            ep->csr[0] |= MGC_M_CSR0_RXPKTRDY;
 
801
 
 
802
        ep->rxcount = packey->result; /* XXX: MIN(packey->len, ep->maxp[1]); */
 
803
        /* In DMA mode: assert DMA request for this EP */
 
804
    }
 
805
 
 
806
    /* Only if DMA has not been asserted */
 
807
    musb_rx_intr_set(s, epnum, 1);
 
808
}
 
809
 
 
810
static void musb_async_cancel_device(MUSBState *s, USBDevice *dev)
 
811
{
 
812
    int ep, dir;
 
813
 
 
814
    for (ep = 0; ep < 16; ep++) {
 
815
        for (dir = 0; dir < 2; dir++) {
 
816
            if (!usb_packet_is_inflight(&s->ep[ep].packey[dir].p) ||
 
817
                s->ep[ep].packey[dir].p.ep->dev != dev) {
 
818
                continue;
 
819
            }
 
820
            usb_cancel_packet(&s->ep[ep].packey[dir].p);
 
821
            /* status updates needed here? */
 
822
        }
 
823
    }
 
824
}
 
825
 
 
826
static void musb_tx_rdy(MUSBState *s, int epnum)
 
827
{
 
828
    MUSBEndPoint *ep = s->ep + epnum;
 
829
    int pid;
 
830
    int total, valid = 0;
 
831
    TRACE("start %d, len %d",  ep->fifostart[0], ep->fifolen[0] );
 
832
    ep->fifostart[0] += ep->fifolen[0];
 
833
    ep->fifolen[0] = 0;
 
834
 
 
835
    /* XXX: how's the total size of the packet retrieved exactly in
 
836
     * the generic case?  */
 
837
    total = ep->maxp[0] & 0x3ff;
 
838
 
 
839
    if (ep->ext_size[0]) {
 
840
        total = ep->ext_size[0];
 
841
        ep->ext_size[0] = 0;
 
842
        valid = 1;
 
843
    }
 
844
 
 
845
    /* If the packet is not fully ready yet, wait for a next segment.  */
 
846
    if (epnum && (ep->fifostart[0]) < total)
 
847
        return;
 
848
 
 
849
    if (!valid)
 
850
        total = ep->fifostart[0];
 
851
 
 
852
    pid = USB_TOKEN_OUT;
 
853
    if (!epnum && (ep->csr[0] & MGC_M_CSR0_H_SETUPPKT)) {
 
854
        pid = USB_TOKEN_SETUP;
 
855
        if (total != 8) {
 
856
            TRACE("illegal SETUPPKT length of %i bytes", total);
 
857
        }
 
858
        /* Controller should retry SETUP packets three times on errors
 
859
         * but it doesn't make sense for us to do that.  */
 
860
    }
 
861
 
 
862
    return musb_packet(s, ep, epnum, pid,
 
863
                    total, musb_tx_packet_complete, 0);
 
864
}
 
865
 
 
866
static void musb_rx_req(MUSBState *s, int epnum)
 
867
{
 
868
    MUSBEndPoint *ep = s->ep + epnum;
 
869
    int total;
 
870
 
 
871
    /* If we already have a packet, which didn't fit into the
 
872
     * 64 bytes of the FIFO, only move the FIFO start and return. (Obsolete) */
 
873
    if (ep->packey[1].p.pid == USB_TOKEN_IN && ep->status[1] >= 0 &&
 
874
                    (ep->fifostart[1]) + ep->rxcount <
 
875
                    ep->packey[1].p.iov.size) {
 
876
        TRACE("0x%08x, %d",  ep->fifostart[1], ep->rxcount );
 
877
        ep->fifostart[1] += ep->rxcount;
 
878
        ep->fifolen[1] = 0;
 
879
 
 
880
        ep->rxcount = MIN(ep->packey[0].p.iov.size - (ep->fifostart[1]),
 
881
                        ep->maxp[1]);
 
882
 
 
883
        ep->csr[1] &= ~MGC_M_RXCSR_H_REQPKT;
 
884
        if (!epnum)
 
885
            ep->csr[0] &= ~MGC_M_CSR0_H_REQPKT;
 
886
 
 
887
        /* Clear all of the error bits first */
 
888
        ep->csr[1] &= ~(MGC_M_RXCSR_H_ERROR | MGC_M_RXCSR_H_RXSTALL |
 
889
                        MGC_M_RXCSR_DATAERROR);
 
890
        if (!epnum)
 
891
            ep->csr[0] &= ~(MGC_M_CSR0_H_ERROR | MGC_M_CSR0_H_RXSTALL |
 
892
                            MGC_M_CSR0_H_NAKTIMEOUT | MGC_M_CSR0_H_NO_PING);
 
893
 
 
894
        ep->csr[1] |= MGC_M_RXCSR_FIFOFULL | MGC_M_RXCSR_RXPKTRDY;
 
895
        if (!epnum)
 
896
            ep->csr[0] |= MGC_M_CSR0_RXPKTRDY;
 
897
        musb_rx_intr_set(s, epnum, 1);
 
898
        return;
 
899
    }
 
900
 
 
901
    /* The driver sets maxp[1] to 64 or less because it knows the hardware
 
902
     * FIFO is this deep.  Bigger packets get split in
 
903
     * usb_generic_handle_packet but we can also do the splitting locally
 
904
     * for performance.  It turns out we can also have a bigger FIFO and
 
905
     * ignore the limit set in ep->maxp[1].  The Linux MUSB driver deals
 
906
     * OK with single packets of even 32KB and we avoid splitting, however
 
907
     * usb_msd.c sometimes sends a packet bigger than what Linux expects
 
908
     * (e.g. 8192 bytes instead of 4096) and we get an OVERRUN.  Splitting
 
909
     * hides this overrun from Linux.  Up to 4096 everything is fine
 
910
     * though.  Currently this is disabled.
 
911
     *
 
912
     * XXX: mind ep->fifosize.  */
 
913
    total = MIN(ep->maxp[1] & 0x3ff, sizeof(s->buf));
 
914
 
 
915
#ifdef SETUPLEN_HACK
 
916
    /* Why should *we* do that instead of Linux?  */
 
917
    if (!epnum) {
 
918
        if (ep->packey[0].p.devaddr == 2) {
 
919
            total = MIN(s->setup_len, 8);
 
920
        } else {
 
921
            total = MIN(s->setup_len, 64);
 
922
        }
 
923
        s->setup_len -= total;
 
924
    }
 
925
#endif
 
926
 
 
927
    return musb_packet(s, ep, epnum, USB_TOKEN_IN,
 
928
                    total, musb_rx_packet_complete, 1);
 
929
}
 
930
 
 
931
static uint8_t musb_read_fifo(MUSBEndPoint *ep)
 
932
{
 
933
    uint8_t value;
 
934
    if (ep->fifolen[1] >= 64) {
 
935
        /* We have a FIFO underrun */
 
936
        TRACE("EP%d FIFO is now empty, stop reading", ep->epnum);
 
937
        return 0x00000000;
 
938
    }
 
939
    /* In DMA mode clear RXPKTRDY and set REQPKT automatically
 
940
     * (if AUTOREQ is set) */
 
941
 
 
942
    ep->csr[1] &= ~MGC_M_RXCSR_FIFOFULL;
 
943
    value=ep->buf[1][ep->fifostart[1] + ep->fifolen[1] ++];
 
944
    TRACE("EP%d 0x%02x, %d", ep->epnum, value, ep->fifolen[1] );
 
945
    return value;
 
946
}
 
947
 
 
948
static void musb_write_fifo(MUSBEndPoint *ep, uint8_t value)
 
949
{
 
950
    TRACE("EP%d = %02x", ep->epnum, value);
 
951
    if (ep->fifolen[0] >= 64) {
 
952
        /* We have a FIFO overrun */
 
953
        TRACE("EP%d FIFO exceeded 64 bytes, stop feeding data", ep->epnum);
 
954
        return;
 
955
     }
 
956
 
 
957
     ep->buf[0][ep->fifostart[0] + ep->fifolen[0] ++] = value;
 
958
     ep->csr[0] |= MGC_M_TXCSR_FIFONOTEMPTY;
 
959
}
 
960
 
 
961
static void musb_ep_frame_cancel(MUSBEndPoint *ep, int dir)
 
962
{
 
963
    if (ep->intv_timer[dir])
 
964
        qemu_del_timer(ep->intv_timer[dir]);
 
965
}
 
966
 
 
967
/* Bus control */
 
968
static uint8_t musb_busctl_readb(void *opaque, int ep, int addr)
 
969
{
 
970
    MUSBState *s = (MUSBState *) opaque;
 
971
 
 
972
    switch (addr) {
 
973
    /* For USB2.0 HS hubs only */
 
974
    case MUSB_HDRC_TXHUBADDR:
 
975
        return s->ep[ep].haddr[0];
 
976
    case MUSB_HDRC_TXHUBPORT:
 
977
        return s->ep[ep].hport[0];
 
978
    case MUSB_HDRC_RXHUBADDR:
 
979
        return s->ep[ep].haddr[1];
 
980
    case MUSB_HDRC_RXHUBPORT:
 
981
        return s->ep[ep].hport[1];
 
982
 
 
983
    default:
 
984
        TRACE("unknown register 0x%02x", addr);
 
985
        return 0x00;
 
986
    };
 
987
}
 
988
 
 
989
static void musb_busctl_writeb(void *opaque, int ep, int addr, uint8_t value)
 
990
{
 
991
    MUSBState *s = (MUSBState *) opaque;
 
992
 
 
993
    switch (addr) {
 
994
    case MUSB_HDRC_TXFUNCADDR:
 
995
        s->ep[ep].faddr[0] = value;
 
996
        break;
 
997
    case MUSB_HDRC_RXFUNCADDR:
 
998
        s->ep[ep].faddr[1] = value;
 
999
        break;
 
1000
    case MUSB_HDRC_TXHUBADDR:
 
1001
        s->ep[ep].haddr[0] = value;
 
1002
        break;
 
1003
    case MUSB_HDRC_TXHUBPORT:
 
1004
        s->ep[ep].hport[0] = value;
 
1005
        break;
 
1006
    case MUSB_HDRC_RXHUBADDR:
 
1007
        s->ep[ep].haddr[1] = value;
 
1008
        break;
 
1009
    case MUSB_HDRC_RXHUBPORT:
 
1010
        s->ep[ep].hport[1] = value;
 
1011
        break;
 
1012
 
 
1013
    default:
 
1014
        TRACE("unknown register 0x%02x", addr);
 
1015
        break;
 
1016
    };
 
1017
}
 
1018
 
 
1019
static uint16_t musb_busctl_readh(void *opaque, int ep, int addr)
 
1020
{
 
1021
    MUSBState *s = (MUSBState *) opaque;
 
1022
 
 
1023
    switch (addr) {
 
1024
    case MUSB_HDRC_TXFUNCADDR:
 
1025
        return s->ep[ep].faddr[0];
 
1026
    case MUSB_HDRC_RXFUNCADDR:
 
1027
        return s->ep[ep].faddr[1];
 
1028
 
 
1029
    default:
 
1030
        return musb_busctl_readb(s, ep, addr) |
 
1031
                (musb_busctl_readb(s, ep, addr | 1) << 8);
 
1032
    };
 
1033
}
 
1034
 
 
1035
static void musb_busctl_writeh(void *opaque, int ep, int addr, uint16_t value)
 
1036
{
 
1037
    MUSBState *s = (MUSBState *) opaque;
 
1038
 
 
1039
    switch (addr) {
 
1040
    case MUSB_HDRC_TXFUNCADDR:
 
1041
        s->ep[ep].faddr[0] = value;
 
1042
        break;
 
1043
    case MUSB_HDRC_RXFUNCADDR:
 
1044
        s->ep[ep].faddr[1] = value;
 
1045
        break;
 
1046
 
 
1047
    default:
 
1048
        musb_busctl_writeb(s, ep, addr, value & 0xff);
 
1049
        musb_busctl_writeb(s, ep, addr | 1, value >> 8);
 
1050
    };
 
1051
}
 
1052
 
 
1053
/* Endpoint control */
 
1054
static uint8_t musb_ep_readb(void *opaque, int ep, int addr)
 
1055
{
 
1056
    MUSBState *s = (MUSBState *) opaque;
 
1057
 
 
1058
    switch (addr) {
 
1059
    case MUSB_HDRC_TXTYPE:
 
1060
        return s->ep[ep].type[0];
 
1061
    case MUSB_HDRC_TXINTERVAL:
 
1062
        return s->ep[ep].interval[0];
 
1063
    case MUSB_HDRC_RXTYPE:
 
1064
        return s->ep[ep].type[1];
 
1065
    case MUSB_HDRC_RXINTERVAL:
 
1066
        return s->ep[ep].interval[1];
 
1067
    case (MUSB_HDRC_FIFOSIZE & ~1):
 
1068
        return 0x00;
 
1069
    case MUSB_HDRC_FIFOSIZE:
 
1070
        return ep ? s->ep[ep].fifosize : s->ep[ep].config;
 
1071
    case MUSB_HDRC_RXCOUNT:
 
1072
        return s->ep[ep].rxcount;
 
1073
 
 
1074
    default:
 
1075
        TRACE("unknown register 0x%02x", addr);
 
1076
        return 0x00;
 
1077
    };
 
1078
}
 
1079
 
 
1080
static void musb_ep_writeb(void *opaque, int ep, int addr, uint8_t value)
 
1081
{
 
1082
    MUSBState *s = (MUSBState *) opaque;
 
1083
 
 
1084
    switch (addr) {
 
1085
    case MUSB_HDRC_TXTYPE:
 
1086
        s->ep[ep].type[0] = value;
 
1087
        break;
 
1088
    case MUSB_HDRC_TXINTERVAL:
 
1089
        s->ep[ep].interval[0] = value;
 
1090
        musb_ep_frame_cancel(&s->ep[ep], 0);
 
1091
        break;
 
1092
    case MUSB_HDRC_RXTYPE:
 
1093
        s->ep[ep].type[1] = value;
 
1094
        break;
 
1095
    case MUSB_HDRC_RXINTERVAL:
 
1096
        s->ep[ep].interval[1] = value;
 
1097
        musb_ep_frame_cancel(&s->ep[ep], 1);
 
1098
        break;
 
1099
    case (MUSB_HDRC_FIFOSIZE & ~1):
 
1100
        break;
 
1101
    case MUSB_HDRC_FIFOSIZE:
 
1102
        TRACE("somebody messes with fifosize (now %i bytes)", value);
 
1103
        s->ep[ep].fifosize = value;
 
1104
        break;
 
1105
    default:
 
1106
        TRACE("unknown register 0x%02x", addr);
 
1107
        break;
 
1108
    };
 
1109
}
 
1110
 
 
1111
static uint16_t musb_ep_readh(void *opaque, int ep, int addr)
 
1112
{
 
1113
    MUSBState *s = (MUSBState *) opaque;
 
1114
    uint16_t ret;
 
1115
 
 
1116
    switch (addr) {
 
1117
    case MUSB_HDRC_TXMAXP:
 
1118
        return s->ep[ep].maxp[0];
 
1119
    case MUSB_HDRC_TXCSR:
 
1120
        return s->ep[ep].csr[0];
 
1121
    case MUSB_HDRC_RXMAXP:
 
1122
        return s->ep[ep].maxp[1];
 
1123
    case MUSB_HDRC_RXCSR:
 
1124
        ret = s->ep[ep].csr[1];
 
1125
 
 
1126
        /* TODO: This and other bits probably depend on
 
1127
         * ep->csr[1] & MGC_M_RXCSR_AUTOCLEAR.  */
 
1128
        if (s->ep[ep].csr[1] & MGC_M_RXCSR_AUTOCLEAR)
 
1129
            s->ep[ep].csr[1] &= ~MGC_M_RXCSR_RXPKTRDY;
 
1130
 
 
1131
        return ret;
 
1132
    case MUSB_HDRC_RXCOUNT:
 
1133
        return s->ep[ep].rxcount;
 
1134
 
 
1135
    default:
 
1136
        return musb_ep_readb(s, ep, addr) |
 
1137
                (musb_ep_readb(s, ep, addr | 1) << 8);
 
1138
    };
 
1139
}
 
1140
 
 
1141
static void musb_ep_writeh(void *opaque, int ep, int addr, uint16_t value)
 
1142
{
 
1143
    MUSBState *s = (MUSBState *) opaque;
 
1144
 
 
1145
    switch (addr) {
 
1146
    case MUSB_HDRC_TXMAXP:
 
1147
        s->ep[ep].maxp[0] = value;
 
1148
        break;
 
1149
    case MUSB_HDRC_TXCSR:
 
1150
        if (ep) {
 
1151
            s->ep[ep].csr[0] &= value & 0xa6;
 
1152
            s->ep[ep].csr[0] |= value & 0xff59;
 
1153
        } else {
 
1154
            s->ep[ep].csr[0] &= value & 0x85;
 
1155
            s->ep[ep].csr[0] |= value & 0xf7a;
 
1156
        }
 
1157
 
 
1158
        musb_ep_frame_cancel(&s->ep[ep], 0);
 
1159
 
 
1160
        if ((ep && (value & MGC_M_TXCSR_FLUSHFIFO)) ||
 
1161
                        (!ep && (value & MGC_M_CSR0_FLUSHFIFO))) {
 
1162
            s->ep[ep].fifolen[0] = 0;
 
1163
            s->ep[ep].fifostart[0] = 0;
 
1164
            if (ep)
 
1165
                s->ep[ep].csr[0] &=
 
1166
                        ~(MGC_M_TXCSR_FIFONOTEMPTY | MGC_M_TXCSR_TXPKTRDY);
 
1167
            else
 
1168
                s->ep[ep].csr[0] &=
 
1169
                        ~(MGC_M_CSR0_TXPKTRDY | MGC_M_CSR0_RXPKTRDY);
 
1170
        }
 
1171
        if (
 
1172
                        (ep &&
 
1173
#ifdef CLEAR_NAK
 
1174
                         (value & MGC_M_TXCSR_TXPKTRDY) &&
 
1175
                         !(value & MGC_M_TXCSR_H_NAKTIMEOUT)) ||
 
1176
#else
 
1177
                         (value & MGC_M_TXCSR_TXPKTRDY)) ||
 
1178
#endif
 
1179
                        (!ep &&
 
1180
#ifdef CLEAR_NAK
 
1181
                         (value & MGC_M_CSR0_TXPKTRDY) &&
 
1182
                         !(value & MGC_M_CSR0_H_NAKTIMEOUT)))
 
1183
#else
 
1184
                         (value & MGC_M_CSR0_TXPKTRDY)))
 
1185
#endif
 
1186
            musb_tx_rdy(s, ep);
 
1187
        if (!ep &&
 
1188
                        (value & MGC_M_CSR0_H_REQPKT) &&
 
1189
#ifdef CLEAR_NAK
 
1190
                        !(value & (MGC_M_CSR0_H_NAKTIMEOUT |
 
1191
                                        MGC_M_CSR0_RXPKTRDY)))
 
1192
#else
 
1193
                        !(value & MGC_M_CSR0_RXPKTRDY))
 
1194
#endif
 
1195
            musb_rx_req(s, ep);
 
1196
        break;
 
1197
 
 
1198
    case MUSB_HDRC_RXMAXP:
 
1199
        s->ep[ep].maxp[1] = value;
 
1200
        break;
 
1201
    case MUSB_HDRC_RXCSR:
 
1202
        /* (DMA mode only) */
 
1203
        if (
 
1204
                (value & MGC_M_RXCSR_H_AUTOREQ) &&
 
1205
                !(value & MGC_M_RXCSR_RXPKTRDY) &&
 
1206
                (s->ep[ep].csr[1] & MGC_M_RXCSR_RXPKTRDY))
 
1207
            value |= MGC_M_RXCSR_H_REQPKT;
 
1208
 
 
1209
        s->ep[ep].csr[1] &= 0x102 | (value & 0x4d);
 
1210
        s->ep[ep].csr[1] |= value & 0xfeb0;
 
1211
 
 
1212
        musb_ep_frame_cancel(&s->ep[ep], 1);
 
1213
 
 
1214
        if (value & MGC_M_RXCSR_FLUSHFIFO) {
 
1215
            s->ep[ep].fifolen[1] = 0;
 
1216
            s->ep[ep].fifostart[1] = 0;
 
1217
            s->ep[ep].csr[1] &= ~(MGC_M_RXCSR_FIFOFULL | MGC_M_RXCSR_RXPKTRDY);
 
1218
            /* If double buffering and we have two packets ready, flush
 
1219
             * only the first one and set up the fifo at the second packet.  */
 
1220
        }
 
1221
#ifdef CLEAR_NAK
 
1222
        if ((value & MGC_M_RXCSR_H_REQPKT) && !(value & MGC_M_RXCSR_DATAERROR))
 
1223
#else
 
1224
        if (value & MGC_M_RXCSR_H_REQPKT)
 
1225
#endif
 
1226
            musb_rx_req(s, ep);
 
1227
        break;
 
1228
    case MUSB_HDRC_RXCOUNT:
 
1229
        s->ep[ep].rxcount = value;
 
1230
        break;
 
1231
 
 
1232
    default:
 
1233
        musb_ep_writeb(s, ep, addr, value & 0xff);
 
1234
        musb_ep_writeb(s, ep, addr | 1, value >> 8);
 
1235
    };
 
1236
}
 
1237
 
 
1238
/* Generic control */
 
1239
static uint32_t musb_readb(void *opaque, target_phys_addr_t addr)
 
1240
{
 
1241
    MUSBState *s = (MUSBState *) opaque;
 
1242
    int ep, i;
 
1243
    uint8_t ret;
 
1244
 
 
1245
    switch (addr) {
 
1246
    case MUSB_HDRC_FADDR:
 
1247
        return s->faddr;
 
1248
    case MUSB_HDRC_POWER:
 
1249
        return s->power;
 
1250
    case MUSB_HDRC_INTRUSB:
 
1251
        ret = s->intr;
 
1252
        for (i = 0; i < sizeof(ret) * 8; i ++)
 
1253
            if (ret & (1 << i))
 
1254
                musb_intr_set(s, i, 0);
 
1255
        return ret;
 
1256
    case MUSB_HDRC_INTRUSBE:
 
1257
        return s->mask;
 
1258
    case MUSB_HDRC_INDEX:
 
1259
        return s->idx;
 
1260
    case MUSB_HDRC_TESTMODE:
 
1261
        return 0x00;
 
1262
 
 
1263
    case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
 
1264
        return musb_ep_readb(s, s->idx, addr & 0xf);
 
1265
 
 
1266
    case MUSB_HDRC_DEVCTL:
 
1267
        return s->devctl;
 
1268
 
 
1269
    case MUSB_HDRC_TXFIFOSZ:
 
1270
    case MUSB_HDRC_RXFIFOSZ:
 
1271
    case MUSB_HDRC_VCTRL:
 
1272
        /* TODO */
 
1273
        return 0x00;
 
1274
 
 
1275
    case MUSB_HDRC_HWVERS:
 
1276
        return (1 << 10) | 400;
 
1277
 
 
1278
    case (MUSB_HDRC_VCTRL | 1):
 
1279
    case (MUSB_HDRC_HWVERS | 1):
 
1280
    case (MUSB_HDRC_DEVCTL | 1):
 
1281
        return 0x00;
 
1282
 
 
1283
    case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
 
1284
        ep = (addr >> 3) & 0xf;
 
1285
        return musb_busctl_readb(s, ep, addr & 0x7);
 
1286
 
 
1287
    case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
 
1288
        ep = (addr >> 4) & 0xf;
 
1289
        return musb_ep_readb(s, ep, addr & 0xf);
 
1290
 
 
1291
    case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
 
1292
        ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
 
1293
        return musb_read_fifo(s->ep + ep);
 
1294
 
 
1295
    case MUSB_HDRC_ULPI_REGADDR:
 
1296
    case MUSB_HDRC_ULPI_REGDATA:
 
1297
    case MUSB_HDRC_ULPI_RAWDATA:
 
1298
        /* TODO */
 
1299
        return 0x00;
 
1300
 
 
1301
    case MUSB_HDRC_ULPI_REGCTL:
 
1302
        /* TODO */
 
1303
        return 0x02;
 
1304
 
 
1305
    default:
 
1306
        TRACE("unknown register 0x%02x", (int) addr);
 
1307
        return 0x00;
 
1308
    };
 
1309
}
 
1310
 
 
1311
static void musb_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
 
1312
{
 
1313
    MUSBState *s = (MUSBState *) opaque;
 
1314
    int ep;
 
1315
 
 
1316
    switch (addr) {
 
1317
    case MUSB_HDRC_FADDR:
 
1318
        s->faddr = value & 0x7f;
 
1319
        break;
 
1320
    case MUSB_HDRC_POWER:
 
1321
        s->power = (value & 0xef) | (s->power & 0x10);
 
1322
        /* MGC_M_POWER_RESET is also read-only in Peripheral Mode */
 
1323
        if ((value & MGC_M_POWER_RESET) && s->port.dev) {
 
1324
            usb_device_reset(s->port.dev);
 
1325
            /* Negotiate high-speed operation if MGC_M_POWER_HSENAB is set.  */
 
1326
            if ((value & MGC_M_POWER_HSENAB) &&
 
1327
                            s->port.dev->speed == USB_SPEED_HIGH)
 
1328
                s->power |= MGC_M_POWER_HSMODE; /* Success */
 
1329
            /* Restart frame counting.  */
 
1330
        }
 
1331
        if (value & MGC_M_POWER_SUSPENDM) {
 
1332
            /* When all transfers finish, suspend and if MGC_M_POWER_ENSUSPEND
 
1333
             * is set, also go into low power mode.  Frame counting stops.  */
 
1334
            /* XXX: Cleared when the interrupt register is read */
 
1335
        }
 
1336
        if (value & MGC_M_POWER_RESUME) {
 
1337
            /* Wait 20ms and signal resuming on the bus.  Frame counting
 
1338
             * restarts.  */
 
1339
        }
 
1340
        break;
 
1341
    case MUSB_HDRC_INTRUSB:
 
1342
        break;
 
1343
    case MUSB_HDRC_INTRUSBE:
 
1344
        s->mask = value & 0xff;
 
1345
        break;
 
1346
    case MUSB_HDRC_INDEX:
 
1347
        s->idx = value & 0xf;
 
1348
        break;
 
1349
    case MUSB_HDRC_TESTMODE:
 
1350
        break;
 
1351
 
 
1352
    case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
 
1353
        musb_ep_writeb(s, s->idx, addr & 0xf, value);
 
1354
        break;
 
1355
 
 
1356
    case MUSB_HDRC_DEVCTL:
 
1357
        s->session = !!(value & MGC_M_DEVCTL_SESSION);
 
1358
        musb_session_update(s,
 
1359
                        !!s->port.dev,
 
1360
                        !!(s->devctl & MGC_M_DEVCTL_SESSION));
 
1361
 
 
1362
        /* It seems this is the only R/W bit in this register?  */
 
1363
        s->devctl &= ~MGC_M_DEVCTL_SESSION;
 
1364
        s->devctl |= value & MGC_M_DEVCTL_SESSION;
 
1365
        break;
 
1366
 
 
1367
    case MUSB_HDRC_TXFIFOSZ:
 
1368
    case MUSB_HDRC_RXFIFOSZ:
 
1369
    case MUSB_HDRC_VCTRL:
 
1370
        /* TODO */
 
1371
        break;
 
1372
 
 
1373
    case (MUSB_HDRC_VCTRL | 1):
 
1374
    case (MUSB_HDRC_DEVCTL | 1):
 
1375
        break;
 
1376
 
 
1377
    case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
 
1378
        ep = (addr >> 3) & 0xf;
 
1379
        musb_busctl_writeb(s, ep, addr & 0x7, value);
 
1380
        break;
 
1381
 
 
1382
    case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
 
1383
        ep = (addr >> 4) & 0xf;
 
1384
        musb_ep_writeb(s, ep, addr & 0xf, value);
 
1385
        break;
 
1386
 
 
1387
    case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
 
1388
        ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
 
1389
        musb_write_fifo(s->ep + ep, value & 0xff);
 
1390
        break;
 
1391
 
 
1392
    case MUSB_HDRC_ULPI_REGADDR:
 
1393
    case MUSB_HDRC_ULPI_REGCTL:
 
1394
    case MUSB_HDRC_ULPI_REGDATA:
 
1395
    case MUSB_HDRC_ULPI_RAWDATA:
 
1396
        /* TODO */
 
1397
        break;
 
1398
 
 
1399
    default:
 
1400
        TRACE("unknown register 0x%02x", (int) addr);
 
1401
        break;
 
1402
    };
 
1403
}
 
1404
 
 
1405
static uint32_t musb_readh(void *opaque, target_phys_addr_t addr)
 
1406
{
 
1407
    MUSBState *s = (MUSBState *) opaque;
 
1408
    int ep, i;
 
1409
    uint16_t ret;
 
1410
 
 
1411
    switch (addr) {
 
1412
    case MUSB_HDRC_INTRTX:
 
1413
        ret = s->tx_intr;
 
1414
        /* Auto clear */
 
1415
        for (i = 0; i < sizeof(ret) * 8; i ++)
 
1416
            if (ret & (1 << i))
 
1417
                musb_tx_intr_set(s, i, 0);
 
1418
        return ret;
 
1419
    case MUSB_HDRC_INTRRX:
 
1420
        ret = s->rx_intr;
 
1421
        /* Auto clear */
 
1422
        for (i = 0; i < sizeof(ret) * 8; i ++)
 
1423
            if (ret & (1 << i))
 
1424
                musb_rx_intr_set(s, i, 0);
 
1425
        return ret;
 
1426
    case MUSB_HDRC_INTRTXE:
 
1427
        return s->tx_mask;
 
1428
    case MUSB_HDRC_INTRRXE:
 
1429
        return s->rx_mask;
 
1430
 
 
1431
    case MUSB_HDRC_FRAME:
 
1432
        /* TODO */
 
1433
        return 0x0000;
 
1434
    case MUSB_HDRC_TXFIFOADDR:
 
1435
        return s->ep[s->idx].fifoaddr[0];
 
1436
    case MUSB_HDRC_RXFIFOADDR:
 
1437
        return s->ep[s->idx].fifoaddr[1];
 
1438
 
 
1439
    case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
 
1440
        return musb_ep_readh(s, s->idx, addr & 0xf);
 
1441
 
 
1442
    case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
 
1443
        ep = (addr >> 3) & 0xf;
 
1444
        return musb_busctl_readh(s, ep, addr & 0x7);
 
1445
 
 
1446
    case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
 
1447
        ep = (addr >> 4) & 0xf;
 
1448
        return musb_ep_readh(s, ep, addr & 0xf);
 
1449
 
 
1450
    case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
 
1451
        ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
 
1452
        return (musb_read_fifo(s->ep + ep) | musb_read_fifo(s->ep + ep) << 8);
 
1453
 
 
1454
    default:
 
1455
        return musb_readb(s, addr) | (musb_readb(s, addr | 1) << 8);
 
1456
    };
 
1457
}
 
1458
 
 
1459
static void musb_writeh(void *opaque, target_phys_addr_t addr, uint32_t value)
 
1460
{
 
1461
    MUSBState *s = (MUSBState *) opaque;
 
1462
    int ep;
 
1463
 
 
1464
    switch (addr) {
 
1465
    case MUSB_HDRC_INTRTXE:
 
1466
        s->tx_mask = value;
 
1467
        /* XXX: the masks seem to apply on the raising edge like with
 
1468
         * edge-triggered interrupts, thus no need to update.  I may be
 
1469
         * wrong though.  */
 
1470
        break;
 
1471
    case MUSB_HDRC_INTRRXE:
 
1472
        s->rx_mask = value;
 
1473
        break;
 
1474
 
 
1475
    case MUSB_HDRC_FRAME:
 
1476
        /* TODO */
 
1477
        break;
 
1478
    case MUSB_HDRC_TXFIFOADDR:
 
1479
        s->ep[s->idx].fifoaddr[0] = value;
 
1480
        s->ep[s->idx].buf[0] =
 
1481
                s->buf + ((value << 3) & 0x7ff );
 
1482
        break;
 
1483
    case MUSB_HDRC_RXFIFOADDR:
 
1484
        s->ep[s->idx].fifoaddr[1] = value;
 
1485
        s->ep[s->idx].buf[1] =
 
1486
                s->buf + ((value << 3) & 0x7ff);
 
1487
        break;
 
1488
 
 
1489
    case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
 
1490
        musb_ep_writeh(s, s->idx, addr & 0xf, value);
 
1491
        break;
 
1492
 
 
1493
    case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
 
1494
        ep = (addr >> 3) & 0xf;
 
1495
        musb_busctl_writeh(s, ep, addr & 0x7, value);
 
1496
        break;
 
1497
 
 
1498
    case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
 
1499
        ep = (addr >> 4) & 0xf;
 
1500
        musb_ep_writeh(s, ep, addr & 0xf, value);
 
1501
        break;
 
1502
 
 
1503
    case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
 
1504
        ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
 
1505
        musb_write_fifo(s->ep + ep, value & 0xff);
 
1506
        musb_write_fifo(s->ep + ep, (value >> 8) & 0xff);
 
1507
        break;
 
1508
 
 
1509
    default:
 
1510
        musb_writeb(s, addr, value & 0xff);
 
1511
        musb_writeb(s, addr | 1, value >> 8);
 
1512
    };
 
1513
}
 
1514
 
 
1515
static uint32_t musb_readw(void *opaque, target_phys_addr_t addr)
 
1516
{
 
1517
    MUSBState *s = (MUSBState *) opaque;
 
1518
    int ep;
 
1519
 
 
1520
    switch (addr) {
 
1521
    case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
 
1522
        ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
 
1523
        return ( musb_read_fifo(s->ep + ep)       |
 
1524
                 musb_read_fifo(s->ep + ep) << 8  |
 
1525
                 musb_read_fifo(s->ep + ep) << 16 |
 
1526
                 musb_read_fifo(s->ep + ep) << 24 );
 
1527
    default:
 
1528
        TRACE("unknown register 0x%02x", (int) addr);
 
1529
        return 0x00000000;
 
1530
    };
 
1531
}
 
1532
 
 
1533
static void musb_writew(void *opaque, target_phys_addr_t addr, uint32_t value)
 
1534
{
 
1535
    MUSBState *s = (MUSBState *) opaque;
 
1536
    int ep;
 
1537
 
 
1538
    switch (addr) {
 
1539
    case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
 
1540
        ep = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
 
1541
        musb_write_fifo(s->ep + ep, value & 0xff);
 
1542
        musb_write_fifo(s->ep + ep, (value >> 8 ) & 0xff);
 
1543
        musb_write_fifo(s->ep + ep, (value >> 16) & 0xff);
 
1544
        musb_write_fifo(s->ep + ep, (value >> 24) & 0xff);
 
1545
            break;
 
1546
    default:
 
1547
        TRACE("unknown register 0x%02x", (int) addr);
 
1548
        break;
 
1549
    };
 
1550
}
 
1551
 
 
1552
CPUReadMemoryFunc * const musb_read[] = {
 
1553
    musb_readb,
 
1554
    musb_readh,
 
1555
    musb_readw,
 
1556
};
 
1557
 
 
1558
CPUWriteMemoryFunc * const musb_write[] = {
 
1559
    musb_writeb,
 
1560
    musb_writeh,
 
1561
    musb_writew,
 
1562
};