~ubuntu-branches/ubuntu/trusty/qemu/trusty

« back to all changes in this revision

Viewing changes to .pc/linaro-patches/0003-sd-Allow-sd_init-callers-to-specify-whether-card-is-.patch/hw/sd/pxa2xx_mmci.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2013-10-22 22:47:07 UTC
  • mfrom: (1.8.3) (10.1.42 sid)
  • Revision ID: package-import@ubuntu.com-20131022224707-1lya34fw3k3f24tv
Tags: 1.6.0+dfsg-2ubuntu1
* Merge 1.6.0~rc0+dfsg-2exp from debian experimental.  Remaining changes:
  - debian/control
    * update maintainer
    * remove libiscsi, usb-redir, vde, vnc-jpeg, and libssh2-1-dev
      from build-deps
    * enable rbd
    * add qemu-system and qemu-common B/R to qemu-keymaps
    * add D:udev, R:qemu, R:qemu-common and B:qemu-common to
      qemu-system-common
    * qemu-system-arm, qemu-system-ppc, qemu-system-sparc:
      - add qemu-kvm to Provides
      - add qemu-common, qemu-kvm, kvm to B/R
      - remove openbios-sparc from qemu-system-sparc D
      - drop openbios-ppc and openhackware Depends to Suggests (for now)
    * qemu-system-x86:
      - add qemu-common to Breaks/Replaces.
      - add cpu-checker to Recommends.
    * qemu-user: add B/R:qemu-kvm
    * qemu-kvm:
      - add armhf armel powerpc sparc to Architecture
      - C/R/P: qemu-kvm-spice
    * add qemu-common package
    * drop qemu-slof which is not packaged in ubuntu
  - add qemu-system-common.links for tap ifup/down scripts and OVMF link.
  - qemu-system-x86.links:
    * remove pxe rom links which are in kvm-ipxe
    * add symlink for kvm.1 manpage
  - debian/rules
    * add kvm-spice symlink to qemu-kvm
    * call dh_installmodules for qemu-system-x86
    * update dh_installinit to install upstart script
    * run dh_installman (Closes: #709241) (cherrypicked from 1.5.0+dfsg-2)
  - Add qemu-utils.links for kvm-* symlinks.
  - Add qemu-system-x86.qemu-kvm.upstart and .default
  - Add qemu-system-x86.modprobe to set nesting=1
  - Add qemu-system-common.preinst to add kvm group
  - qemu-system-common.postinst: remove bad group acl if there, then have
    udev relabel /dev/kvm.
  - New linaro patches from qemu-linaro rebasing branch
  - Dropped patches:
    * xen-simplify-xen_enabled.patch
    * sparc-linux-user-fix-missing-symbols-in-.rel-.rela.plt-sections.patch
    * main_loop-do-not-set-nonblocking-if-xen_enabled.patch
    * xen_machine_pv-do-not-create-a-dummy-CPU-in-machine-.patch
    * virtio-rng-fix-crash
  - Kept patches:
    * expose_vms_qemu64cpu.patch - updated
    * linaro arm patches from qemu-linaro rebasing branch
  - New patches:
    * fix-pci-add: change CONFIG variable in ifdef to make sure that
      pci_add is defined.
* Add linaro patches
* Add experimental mach-virt patches for arm virtualization.
* qemu-system-common.install: add debian/tmp/usr/lib to install the
  qemu-bridge-helper

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Intel XScale PXA255/270 MultiMediaCard/SD/SDIO Controller emulation.
 
3
 *
 
4
 * Copyright (c) 2006 Openedhand Ltd.
 
5
 * Written by Andrzej Zaborowski <balrog@zabor.org>
 
6
 *
 
7
 * This code is licensed under the GPLv2.
 
8
 *
 
9
 * Contributions after 2012-01-13 are licensed under the terms of the
 
10
 * GNU GPL, version 2 or (at your option) any later version.
 
11
 */
 
12
 
 
13
#include "hw/hw.h"
 
14
#include "hw/arm/pxa.h"
 
15
#include "hw/sd.h"
 
16
#include "hw/qdev.h"
 
17
 
 
18
struct PXA2xxMMCIState {
 
19
    MemoryRegion iomem;
 
20
    qemu_irq irq;
 
21
    qemu_irq rx_dma;
 
22
    qemu_irq tx_dma;
 
23
 
 
24
    SDState *card;
 
25
 
 
26
    uint32_t status;
 
27
    uint32_t clkrt;
 
28
    uint32_t spi;
 
29
    uint32_t cmdat;
 
30
    uint32_t resp_tout;
 
31
    uint32_t read_tout;
 
32
    int blklen;
 
33
    int numblk;
 
34
    uint32_t intmask;
 
35
    uint32_t intreq;
 
36
    int cmd;
 
37
    uint32_t arg;
 
38
 
 
39
    int active;
 
40
    int bytesleft;
 
41
    uint8_t tx_fifo[64];
 
42
    int tx_start;
 
43
    int tx_len;
 
44
    uint8_t rx_fifo[32];
 
45
    int rx_start;
 
46
    int rx_len;
 
47
    uint16_t resp_fifo[9];
 
48
    int resp_len;
 
49
 
 
50
    int cmdreq;
 
51
    int ac_width;
 
52
};
 
53
 
 
54
#define MMC_STRPCL      0x00    /* MMC Clock Start/Stop register */
 
55
#define MMC_STAT        0x04    /* MMC Status register */
 
56
#define MMC_CLKRT       0x08    /* MMC Clock Rate register */
 
57
#define MMC_SPI         0x0c    /* MMC SPI Mode register */
 
58
#define MMC_CMDAT       0x10    /* MMC Command/Data register */
 
59
#define MMC_RESTO       0x14    /* MMC Response Time-Out register */
 
60
#define MMC_RDTO        0x18    /* MMC Read Time-Out register */
 
61
#define MMC_BLKLEN      0x1c    /* MMC Block Length register */
 
62
#define MMC_NUMBLK      0x20    /* MMC Number of Blocks register */
 
63
#define MMC_PRTBUF      0x24    /* MMC Buffer Partly Full register */
 
64
#define MMC_I_MASK      0x28    /* MMC Interrupt Mask register */
 
65
#define MMC_I_REG       0x2c    /* MMC Interrupt Request register */
 
66
#define MMC_CMD         0x30    /* MMC Command register */
 
67
#define MMC_ARGH        0x34    /* MMC Argument High register */
 
68
#define MMC_ARGL        0x38    /* MMC Argument Low register */
 
69
#define MMC_RES         0x3c    /* MMC Response FIFO */
 
70
#define MMC_RXFIFO      0x40    /* MMC Receive FIFO */
 
71
#define MMC_TXFIFO      0x44    /* MMC Transmit FIFO */
 
72
#define MMC_RDWAIT      0x48    /* MMC RD_WAIT register */
 
73
#define MMC_BLKS_REM    0x4c    /* MMC Blocks Remaining register */
 
74
 
 
75
/* Bitfield masks */
 
76
#define STRPCL_STOP_CLK (1 << 0)
 
77
#define STRPCL_STRT_CLK (1 << 1)
 
78
#define STAT_TOUT_RES   (1 << 1)
 
79
#define STAT_CLK_EN     (1 << 8)
 
80
#define STAT_DATA_DONE  (1 << 11)
 
81
#define STAT_PRG_DONE   (1 << 12)
 
82
#define STAT_END_CMDRES (1 << 13)
 
83
#define SPI_SPI_MODE    (1 << 0)
 
84
#define CMDAT_RES_TYPE  (3 << 0)
 
85
#define CMDAT_DATA_EN   (1 << 2)
 
86
#define CMDAT_WR_RD     (1 << 3)
 
87
#define CMDAT_DMA_EN    (1 << 7)
 
88
#define CMDAT_STOP_TRAN (1 << 10)
 
89
#define INT_DATA_DONE   (1 << 0)
 
90
#define INT_PRG_DONE    (1 << 1)
 
91
#define INT_END_CMD     (1 << 2)
 
92
#define INT_STOP_CMD    (1 << 3)
 
93
#define INT_CLK_OFF     (1 << 4)
 
94
#define INT_RXFIFO_REQ  (1 << 5)
 
95
#define INT_TXFIFO_REQ  (1 << 6)
 
96
#define INT_TINT        (1 << 7)
 
97
#define INT_DAT_ERR     (1 << 8)
 
98
#define INT_RES_ERR     (1 << 9)
 
99
#define INT_RD_STALLED  (1 << 10)
 
100
#define INT_SDIO_INT    (1 << 11)
 
101
#define INT_SDIO_SACK   (1 << 12)
 
102
#define PRTBUF_PRT_BUF  (1 << 0)
 
103
 
 
104
/* Route internal interrupt lines to the global IC and DMA */
 
105
static void pxa2xx_mmci_int_update(PXA2xxMMCIState *s)
 
106
{
 
107
    uint32_t mask = s->intmask;
 
108
    if (s->cmdat & CMDAT_DMA_EN) {
 
109
        mask |= INT_RXFIFO_REQ | INT_TXFIFO_REQ;
 
110
 
 
111
        qemu_set_irq(s->rx_dma, !!(s->intreq & INT_RXFIFO_REQ));
 
112
        qemu_set_irq(s->tx_dma, !!(s->intreq & INT_TXFIFO_REQ));
 
113
    }
 
114
 
 
115
    qemu_set_irq(s->irq, !!(s->intreq & ~mask));
 
116
}
 
117
 
 
118
static void pxa2xx_mmci_fifo_update(PXA2xxMMCIState *s)
 
119
{
 
120
    if (!s->active)
 
121
        return;
 
122
 
 
123
    if (s->cmdat & CMDAT_WR_RD) {
 
124
        while (s->bytesleft && s->tx_len) {
 
125
            sd_write_data(s->card, s->tx_fifo[s->tx_start ++]);
 
126
            s->tx_start &= 0x1f;
 
127
            s->tx_len --;
 
128
            s->bytesleft --;
 
129
        }
 
130
        if (s->bytesleft)
 
131
            s->intreq |= INT_TXFIFO_REQ;
 
132
    } else
 
133
        while (s->bytesleft && s->rx_len < 32) {
 
134
            s->rx_fifo[(s->rx_start + (s->rx_len ++)) & 0x1f] =
 
135
                sd_read_data(s->card);
 
136
            s->bytesleft --;
 
137
            s->intreq |= INT_RXFIFO_REQ;
 
138
        }
 
139
 
 
140
    if (!s->bytesleft) {
 
141
        s->active = 0;
 
142
        s->intreq |= INT_DATA_DONE;
 
143
        s->status |= STAT_DATA_DONE;
 
144
 
 
145
        if (s->cmdat & CMDAT_WR_RD) {
 
146
            s->intreq |= INT_PRG_DONE;
 
147
            s->status |= STAT_PRG_DONE;
 
148
        }
 
149
    }
 
150
 
 
151
    pxa2xx_mmci_int_update(s);
 
152
}
 
153
 
 
154
static void pxa2xx_mmci_wakequeues(PXA2xxMMCIState *s)
 
155
{
 
156
    int rsplen, i;
 
157
    SDRequest request;
 
158
    uint8_t response[16];
 
159
 
 
160
    s->active = 1;
 
161
    s->rx_len = 0;
 
162
    s->tx_len = 0;
 
163
    s->cmdreq = 0;
 
164
 
 
165
    request.cmd = s->cmd;
 
166
    request.arg = s->arg;
 
167
    request.crc = 0;    /* FIXME */
 
168
 
 
169
    rsplen = sd_do_command(s->card, &request, response);
 
170
    s->intreq |= INT_END_CMD;
 
171
 
 
172
    memset(s->resp_fifo, 0, sizeof(s->resp_fifo));
 
173
    switch (s->cmdat & CMDAT_RES_TYPE) {
 
174
#define PXAMMCI_RESP(wd, value0, value1)        \
 
175
        s->resp_fifo[(wd) + 0] |= (value0);     \
 
176
        s->resp_fifo[(wd) + 1] |= (value1) << 8;
 
177
    case 0:     /* No response */
 
178
        goto complete;
 
179
 
 
180
    case 1:     /* R1, R4, R5 or R6 */
 
181
        if (rsplen < 4)
 
182
            goto timeout;
 
183
        goto complete;
 
184
 
 
185
    case 2:     /* R2 */
 
186
        if (rsplen < 16)
 
187
            goto timeout;
 
188
        goto complete;
 
189
 
 
190
    case 3:     /* R3 */
 
191
        if (rsplen < 4)
 
192
            goto timeout;
 
193
        goto complete;
 
194
 
 
195
    complete:
 
196
        for (i = 0; rsplen > 0; i ++, rsplen -= 2) {
 
197
            PXAMMCI_RESP(i, response[i * 2], response[i * 2 + 1]);
 
198
        }
 
199
        s->status |= STAT_END_CMDRES;
 
200
 
 
201
        if (!(s->cmdat & CMDAT_DATA_EN))
 
202
            s->active = 0;
 
203
        else
 
204
            s->bytesleft = s->numblk * s->blklen;
 
205
 
 
206
        s->resp_len = 0;
 
207
        break;
 
208
 
 
209
    timeout:
 
210
        s->active = 0;
 
211
        s->status |= STAT_TOUT_RES;
 
212
        break;
 
213
    }
 
214
 
 
215
    pxa2xx_mmci_fifo_update(s);
 
216
}
 
217
 
 
218
static uint32_t pxa2xx_mmci_read(void *opaque, hwaddr offset)
 
219
{
 
220
    PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
 
221
    uint32_t ret;
 
222
 
 
223
    switch (offset) {
 
224
    case MMC_STRPCL:
 
225
        return 0;
 
226
    case MMC_STAT:
 
227
        return s->status;
 
228
    case MMC_CLKRT:
 
229
        return s->clkrt;
 
230
    case MMC_SPI:
 
231
        return s->spi;
 
232
    case MMC_CMDAT:
 
233
        return s->cmdat;
 
234
    case MMC_RESTO:
 
235
        return s->resp_tout;
 
236
    case MMC_RDTO:
 
237
        return s->read_tout;
 
238
    case MMC_BLKLEN:
 
239
        return s->blklen;
 
240
    case MMC_NUMBLK:
 
241
        return s->numblk;
 
242
    case MMC_PRTBUF:
 
243
        return 0;
 
244
    case MMC_I_MASK:
 
245
        return s->intmask;
 
246
    case MMC_I_REG:
 
247
        return s->intreq;
 
248
    case MMC_CMD:
 
249
        return s->cmd | 0x40;
 
250
    case MMC_ARGH:
 
251
        return s->arg >> 16;
 
252
    case MMC_ARGL:
 
253
        return s->arg & 0xffff;
 
254
    case MMC_RES:
 
255
        if (s->resp_len < 9)
 
256
            return s->resp_fifo[s->resp_len ++];
 
257
        return 0;
 
258
    case MMC_RXFIFO:
 
259
        ret = 0;
 
260
        while (s->ac_width -- && s->rx_len) {
 
261
            ret |= s->rx_fifo[s->rx_start ++] << (s->ac_width << 3);
 
262
            s->rx_start &= 0x1f;
 
263
            s->rx_len --;
 
264
        }
 
265
        s->intreq &= ~INT_RXFIFO_REQ;
 
266
        pxa2xx_mmci_fifo_update(s);
 
267
        return ret;
 
268
    case MMC_RDWAIT:
 
269
        return 0;
 
270
    case MMC_BLKS_REM:
 
271
        return s->numblk;
 
272
    default:
 
273
        hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
 
274
    }
 
275
 
 
276
    return 0;
 
277
}
 
278
 
 
279
static void pxa2xx_mmci_write(void *opaque,
 
280
                hwaddr offset, uint32_t value)
 
281
{
 
282
    PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
 
283
 
 
284
    switch (offset) {
 
285
    case MMC_STRPCL:
 
286
        if (value & STRPCL_STRT_CLK) {
 
287
            s->status |= STAT_CLK_EN;
 
288
            s->intreq &= ~INT_CLK_OFF;
 
289
 
 
290
            if (s->cmdreq && !(s->cmdat & CMDAT_STOP_TRAN)) {
 
291
                s->status &= STAT_CLK_EN;
 
292
                pxa2xx_mmci_wakequeues(s);
 
293
            }
 
294
        }
 
295
 
 
296
        if (value & STRPCL_STOP_CLK) {
 
297
            s->status &= ~STAT_CLK_EN;
 
298
            s->intreq |= INT_CLK_OFF;
 
299
            s->active = 0;
 
300
        }
 
301
 
 
302
        pxa2xx_mmci_int_update(s);
 
303
        break;
 
304
 
 
305
    case MMC_CLKRT:
 
306
        s->clkrt = value & 7;
 
307
        break;
 
308
 
 
309
    case MMC_SPI:
 
310
        s->spi = value & 0xf;
 
311
        if (value & SPI_SPI_MODE)
 
312
            printf("%s: attempted to use card in SPI mode\n", __FUNCTION__);
 
313
        break;
 
314
 
 
315
    case MMC_CMDAT:
 
316
        s->cmdat = value & 0x3dff;
 
317
        s->active = 0;
 
318
        s->cmdreq = 1;
 
319
        if (!(value & CMDAT_STOP_TRAN)) {
 
320
            s->status &= STAT_CLK_EN;
 
321
 
 
322
            if (s->status & STAT_CLK_EN)
 
323
                pxa2xx_mmci_wakequeues(s);
 
324
        }
 
325
 
 
326
        pxa2xx_mmci_int_update(s);
 
327
        break;
 
328
 
 
329
    case MMC_RESTO:
 
330
        s->resp_tout = value & 0x7f;
 
331
        break;
 
332
 
 
333
    case MMC_RDTO:
 
334
        s->read_tout = value & 0xffff;
 
335
        break;
 
336
 
 
337
    case MMC_BLKLEN:
 
338
        s->blklen = value & 0xfff;
 
339
        break;
 
340
 
 
341
    case MMC_NUMBLK:
 
342
        s->numblk = value & 0xffff;
 
343
        break;
 
344
 
 
345
    case MMC_PRTBUF:
 
346
        if (value & PRTBUF_PRT_BUF) {
 
347
            s->tx_start ^= 32;
 
348
            s->tx_len = 0;
 
349
        }
 
350
        pxa2xx_mmci_fifo_update(s);
 
351
        break;
 
352
 
 
353
    case MMC_I_MASK:
 
354
        s->intmask = value & 0x1fff;
 
355
        pxa2xx_mmci_int_update(s);
 
356
        break;
 
357
 
 
358
    case MMC_CMD:
 
359
        s->cmd = value & 0x3f;
 
360
        break;
 
361
 
 
362
    case MMC_ARGH:
 
363
        s->arg &= 0x0000ffff;
 
364
        s->arg |= value << 16;
 
365
        break;
 
366
 
 
367
    case MMC_ARGL:
 
368
        s->arg &= 0xffff0000;
 
369
        s->arg |= value & 0x0000ffff;
 
370
        break;
 
371
 
 
372
    case MMC_TXFIFO:
 
373
        while (s->ac_width -- && s->tx_len < 0x20)
 
374
            s->tx_fifo[(s->tx_start + (s->tx_len ++)) & 0x1f] =
 
375
                    (value >> (s->ac_width << 3)) & 0xff;
 
376
        s->intreq &= ~INT_TXFIFO_REQ;
 
377
        pxa2xx_mmci_fifo_update(s);
 
378
        break;
 
379
 
 
380
    case MMC_RDWAIT:
 
381
    case MMC_BLKS_REM:
 
382
        break;
 
383
 
 
384
    default:
 
385
        hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
 
386
    }
 
387
}
 
388
 
 
389
static uint32_t pxa2xx_mmci_readb(void *opaque, hwaddr offset)
 
390
{
 
391
    PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
 
392
    s->ac_width = 1;
 
393
    return pxa2xx_mmci_read(opaque, offset);
 
394
}
 
395
 
 
396
static uint32_t pxa2xx_mmci_readh(void *opaque, hwaddr offset)
 
397
{
 
398
    PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
 
399
    s->ac_width = 2;
 
400
    return pxa2xx_mmci_read(opaque, offset);
 
401
}
 
402
 
 
403
static uint32_t pxa2xx_mmci_readw(void *opaque, hwaddr offset)
 
404
{
 
405
    PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
 
406
    s->ac_width = 4;
 
407
    return pxa2xx_mmci_read(opaque, offset);
 
408
}
 
409
 
 
410
static void pxa2xx_mmci_writeb(void *opaque,
 
411
                hwaddr offset, uint32_t value)
 
412
{
 
413
    PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
 
414
    s->ac_width = 1;
 
415
    pxa2xx_mmci_write(opaque, offset, value);
 
416
}
 
417
 
 
418
static void pxa2xx_mmci_writeh(void *opaque,
 
419
                hwaddr offset, uint32_t value)
 
420
{
 
421
    PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
 
422
    s->ac_width = 2;
 
423
    pxa2xx_mmci_write(opaque, offset, value);
 
424
}
 
425
 
 
426
static void pxa2xx_mmci_writew(void *opaque,
 
427
                hwaddr offset, uint32_t value)
 
428
{
 
429
    PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
 
430
    s->ac_width = 4;
 
431
    pxa2xx_mmci_write(opaque, offset, value);
 
432
}
 
433
 
 
434
static const MemoryRegionOps pxa2xx_mmci_ops = {
 
435
    .old_mmio = {
 
436
        .read = { pxa2xx_mmci_readb,
 
437
                  pxa2xx_mmci_readh,
 
438
                  pxa2xx_mmci_readw, },
 
439
        .write = { pxa2xx_mmci_writeb,
 
440
                   pxa2xx_mmci_writeh,
 
441
                   pxa2xx_mmci_writew, },
 
442
    },
 
443
    .endianness = DEVICE_NATIVE_ENDIAN,
 
444
};
 
445
 
 
446
static void pxa2xx_mmci_save(QEMUFile *f, void *opaque)
 
447
{
 
448
    PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
 
449
    int i;
 
450
 
 
451
    qemu_put_be32s(f, &s->status);
 
452
    qemu_put_be32s(f, &s->clkrt);
 
453
    qemu_put_be32s(f, &s->spi);
 
454
    qemu_put_be32s(f, &s->cmdat);
 
455
    qemu_put_be32s(f, &s->resp_tout);
 
456
    qemu_put_be32s(f, &s->read_tout);
 
457
    qemu_put_be32(f, s->blklen);
 
458
    qemu_put_be32(f, s->numblk);
 
459
    qemu_put_be32s(f, &s->intmask);
 
460
    qemu_put_be32s(f, &s->intreq);
 
461
    qemu_put_be32(f, s->cmd);
 
462
    qemu_put_be32s(f, &s->arg);
 
463
    qemu_put_be32(f, s->cmdreq);
 
464
    qemu_put_be32(f, s->active);
 
465
    qemu_put_be32(f, s->bytesleft);
 
466
 
 
467
    qemu_put_byte(f, s->tx_len);
 
468
    for (i = 0; i < s->tx_len; i ++)
 
469
        qemu_put_byte(f, s->tx_fifo[(s->tx_start + i) & 63]);
 
470
 
 
471
    qemu_put_byte(f, s->rx_len);
 
472
    for (i = 0; i < s->rx_len; i ++)
 
473
        qemu_put_byte(f, s->rx_fifo[(s->rx_start + i) & 31]);
 
474
 
 
475
    qemu_put_byte(f, s->resp_len);
 
476
    for (i = s->resp_len; i < 9; i ++)
 
477
        qemu_put_be16s(f, &s->resp_fifo[i]);
 
478
}
 
479
 
 
480
static int pxa2xx_mmci_load(QEMUFile *f, void *opaque, int version_id)
 
481
{
 
482
    PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
 
483
    int i;
 
484
 
 
485
    qemu_get_be32s(f, &s->status);
 
486
    qemu_get_be32s(f, &s->clkrt);
 
487
    qemu_get_be32s(f, &s->spi);
 
488
    qemu_get_be32s(f, &s->cmdat);
 
489
    qemu_get_be32s(f, &s->resp_tout);
 
490
    qemu_get_be32s(f, &s->read_tout);
 
491
    s->blklen = qemu_get_be32(f);
 
492
    s->numblk = qemu_get_be32(f);
 
493
    qemu_get_be32s(f, &s->intmask);
 
494
    qemu_get_be32s(f, &s->intreq);
 
495
    s->cmd = qemu_get_be32(f);
 
496
    qemu_get_be32s(f, &s->arg);
 
497
    s->cmdreq = qemu_get_be32(f);
 
498
    s->active = qemu_get_be32(f);
 
499
    s->bytesleft = qemu_get_be32(f);
 
500
 
 
501
    s->tx_len = qemu_get_byte(f);
 
502
    s->tx_start = 0;
 
503
    if (s->tx_len >= sizeof(s->tx_fifo) || s->tx_len < 0)
 
504
        return -EINVAL;
 
505
    for (i = 0; i < s->tx_len; i ++)
 
506
        s->tx_fifo[i] = qemu_get_byte(f);
 
507
 
 
508
    s->rx_len = qemu_get_byte(f);
 
509
    s->rx_start = 0;
 
510
    if (s->rx_len >= sizeof(s->rx_fifo) || s->rx_len < 0)
 
511
        return -EINVAL;
 
512
    for (i = 0; i < s->rx_len; i ++)
 
513
        s->rx_fifo[i] = qemu_get_byte(f);
 
514
 
 
515
    s->resp_len = qemu_get_byte(f);
 
516
    if (s->resp_len > 9 || s->resp_len < 0)
 
517
        return -EINVAL;
 
518
    for (i = s->resp_len; i < 9; i ++)
 
519
         qemu_get_be16s(f, &s->resp_fifo[i]);
 
520
 
 
521
    return 0;
 
522
}
 
523
 
 
524
PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
 
525
                hwaddr base,
 
526
                BlockDriverState *bd, qemu_irq irq,
 
527
                qemu_irq rx_dma, qemu_irq tx_dma)
 
528
{
 
529
    PXA2xxMMCIState *s;
 
530
 
 
531
    s = (PXA2xxMMCIState *) g_malloc0(sizeof(PXA2xxMMCIState));
 
532
    s->irq = irq;
 
533
    s->rx_dma = rx_dma;
 
534
    s->tx_dma = tx_dma;
 
535
 
 
536
    memory_region_init_io(&s->iomem, NULL, &pxa2xx_mmci_ops, s,
 
537
                          "pxa2xx-mmci", 0x00100000);
 
538
    memory_region_add_subregion(sysmem, base, &s->iomem);
 
539
 
 
540
    /* Instantiate the actual storage */
 
541
    s->card = sd_init(bd, false);
 
542
 
 
543
    register_savevm(NULL, "pxa2xx_mmci", 0, 0,
 
544
                    pxa2xx_mmci_save, pxa2xx_mmci_load, s);
 
545
 
 
546
    return s;
 
547
}
 
548
 
 
549
void pxa2xx_mmci_handlers(PXA2xxMMCIState *s, qemu_irq readonly,
 
550
                qemu_irq coverswitch)
 
551
{
 
552
    sd_set_cb(s->card, readonly, coverswitch);
 
553
}