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

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2014-02-04 12:13:08 UTC
  • mfrom: (10.1.45 sid)
  • Revision ID: package-import@ubuntu.com-20140204121308-1xq92lrfs75agw2g
Tags: 1.7.0+dfsg-3ubuntu1~ppa1
* Merge 1.7.0+dfsg-3 from debian.  Remaining changes:
  - debian/patches/ubuntu:
    * expose-vmx_qemu64cpu.patch
    * linaro (omap3) and arm64 patches
    * ubuntu/target-ppc-add-stubs-for-kvm-breakpoints: fix FTBFS
      on ppc
    * ubuntu/CVE-2013-4377.patch: fix denial of service via virtio
  - debian/qemu-system-x86.modprobe: set kvm_intel nested=1 options
  - debian/control:
    * add arm64 to Architectures
    * add qemu-common and qemu-system-aarch64 packages
  - debian/qemu-system-common.install: add debian/tmp/usr/lib
  - debian/qemu-system-common.preinst: add kvm group
  - debian/qemu-system-common.postinst: remove acl placed by udev,
    and add udevadm trigger.
  - qemu-system-x86.links: add eepro100.rom, remove pxe-virtio,
    pxe-e1000 and pxe-rtl8139.
  - add qemu-system-x86.qemu-kvm.upstart and .default
  - qemu-user-static.postinst-in: remove arm64 binfmt
  - debian/rules:
    * allow parallel build
    * add aarch64 to system_targets and sys_systems
    * add qemu-kvm-spice links
    * install qemu-system-x86.modprobe
  - add debian/qemu-system-common.links for OVMF.fd link
* Remove kvm-img, kvm-nbd, kvm-ifup and kvm-ifdown symlinks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Arm PrimeCell PL181 MultiMedia Card Interface
 
3
 *
 
4
 * Copyright (c) 2007 CodeSourcery.
 
5
 * Written by Paul Brook
 
6
 *
 
7
 * This code is licensed under the GPL.
 
8
 */
 
9
 
 
10
#include "sysemu/blockdev.h"
 
11
#include "hw/sysbus.h"
 
12
#include "hw/sd.h"
 
13
 
 
14
//#define DEBUG_PL181 1
 
15
 
 
16
#ifdef DEBUG_PL181
 
17
#define DPRINTF(fmt, ...) \
 
18
do { printf("pl181: " fmt , ## __VA_ARGS__); } while (0)
 
19
#else
 
20
#define DPRINTF(fmt, ...) do {} while(0)
 
21
#endif
 
22
 
 
23
#define PL181_FIFO_LEN 16
 
24
 
 
25
#define TYPE_PL181 "pl181"
 
26
#define PL181(obj) OBJECT_CHECK(PL181State, (obj), TYPE_PL181)
 
27
 
 
28
typedef struct PL181State {
 
29
    SysBusDevice parent_obj;
 
30
 
 
31
    MemoryRegion iomem;
 
32
    SDState *card;
 
33
    uint32_t clock;
 
34
    uint32_t power;
 
35
    uint32_t cmdarg;
 
36
    uint32_t cmd;
 
37
    uint32_t datatimer;
 
38
    uint32_t datalength;
 
39
    uint32_t respcmd;
 
40
    uint32_t response[4];
 
41
    uint32_t datactrl;
 
42
    uint32_t datacnt;
 
43
    uint32_t status;
 
44
    uint32_t mask[2];
 
45
    int32_t fifo_pos;
 
46
    int32_t fifo_len;
 
47
    /* The linux 2.6.21 driver is buggy, and misbehaves if new data arrives
 
48
       while it is reading the FIFO.  We hack around this be defering
 
49
       subsequent transfers until after the driver polls the status word.
 
50
       http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=4446/1
 
51
     */
 
52
    int32_t linux_hack;
 
53
    uint32_t fifo[PL181_FIFO_LEN];
 
54
    qemu_irq irq[2];
 
55
    /* GPIO outputs for 'card is readonly' and 'card inserted' */
 
56
    qemu_irq cardstatus[2];
 
57
} PL181State;
 
58
 
 
59
static const VMStateDescription vmstate_pl181 = {
 
60
    .name = "pl181",
 
61
    .version_id = 1,
 
62
    .minimum_version_id = 1,
 
63
    .fields = (VMStateField[]) {
 
64
        VMSTATE_UINT32(clock, PL181State),
 
65
        VMSTATE_UINT32(power, PL181State),
 
66
        VMSTATE_UINT32(cmdarg, PL181State),
 
67
        VMSTATE_UINT32(cmd, PL181State),
 
68
        VMSTATE_UINT32(datatimer, PL181State),
 
69
        VMSTATE_UINT32(datalength, PL181State),
 
70
        VMSTATE_UINT32(respcmd, PL181State),
 
71
        VMSTATE_UINT32_ARRAY(response, PL181State, 4),
 
72
        VMSTATE_UINT32(datactrl, PL181State),
 
73
        VMSTATE_UINT32(datacnt, PL181State),
 
74
        VMSTATE_UINT32(status, PL181State),
 
75
        VMSTATE_UINT32_ARRAY(mask, PL181State, 2),
 
76
        VMSTATE_INT32(fifo_pos, PL181State),
 
77
        VMSTATE_INT32(fifo_len, PL181State),
 
78
        VMSTATE_INT32(linux_hack, PL181State),
 
79
        VMSTATE_UINT32_ARRAY(fifo, PL181State, PL181_FIFO_LEN),
 
80
        VMSTATE_END_OF_LIST()
 
81
    }
 
82
};
 
83
 
 
84
#define PL181_CMD_INDEX     0x3f
 
85
#define PL181_CMD_RESPONSE  (1 << 6)
 
86
#define PL181_CMD_LONGRESP  (1 << 7)
 
87
#define PL181_CMD_INTERRUPT (1 << 8)
 
88
#define PL181_CMD_PENDING   (1 << 9)
 
89
#define PL181_CMD_ENABLE    (1 << 10)
 
90
 
 
91
#define PL181_DATA_ENABLE             (1 << 0)
 
92
#define PL181_DATA_DIRECTION          (1 << 1)
 
93
#define PL181_DATA_MODE               (1 << 2)
 
94
#define PL181_DATA_DMAENABLE          (1 << 3)
 
95
 
 
96
#define PL181_STATUS_CMDCRCFAIL       (1 << 0)
 
97
#define PL181_STATUS_DATACRCFAIL      (1 << 1)
 
98
#define PL181_STATUS_CMDTIMEOUT       (1 << 2)
 
99
#define PL181_STATUS_DATATIMEOUT      (1 << 3)
 
100
#define PL181_STATUS_TXUNDERRUN       (1 << 4)
 
101
#define PL181_STATUS_RXOVERRUN        (1 << 5)
 
102
#define PL181_STATUS_CMDRESPEND       (1 << 6)
 
103
#define PL181_STATUS_CMDSENT          (1 << 7)
 
104
#define PL181_STATUS_DATAEND          (1 << 8)
 
105
#define PL181_STATUS_DATABLOCKEND     (1 << 10)
 
106
#define PL181_STATUS_CMDACTIVE        (1 << 11)
 
107
#define PL181_STATUS_TXACTIVE         (1 << 12)
 
108
#define PL181_STATUS_RXACTIVE         (1 << 13)
 
109
#define PL181_STATUS_TXFIFOHALFEMPTY  (1 << 14)
 
110
#define PL181_STATUS_RXFIFOHALFFULL   (1 << 15)
 
111
#define PL181_STATUS_TXFIFOFULL       (1 << 16)
 
112
#define PL181_STATUS_RXFIFOFULL       (1 << 17)
 
113
#define PL181_STATUS_TXFIFOEMPTY      (1 << 18)
 
114
#define PL181_STATUS_RXFIFOEMPTY      (1 << 19)
 
115
#define PL181_STATUS_TXDATAAVLBL      (1 << 20)
 
116
#define PL181_STATUS_RXDATAAVLBL      (1 << 21)
 
117
 
 
118
#define PL181_STATUS_TX_FIFO (PL181_STATUS_TXACTIVE \
 
119
                             |PL181_STATUS_TXFIFOHALFEMPTY \
 
120
                             |PL181_STATUS_TXFIFOFULL \
 
121
                             |PL181_STATUS_TXFIFOEMPTY \
 
122
                             |PL181_STATUS_TXDATAAVLBL)
 
123
#define PL181_STATUS_RX_FIFO (PL181_STATUS_RXACTIVE \
 
124
                             |PL181_STATUS_RXFIFOHALFFULL \
 
125
                             |PL181_STATUS_RXFIFOFULL \
 
126
                             |PL181_STATUS_RXFIFOEMPTY \
 
127
                             |PL181_STATUS_RXDATAAVLBL)
 
128
 
 
129
static const unsigned char pl181_id[] =
 
130
{ 0x81, 0x11, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
 
131
 
 
132
static void pl181_update(PL181State *s)
 
133
{
 
134
    int i;
 
135
    for (i = 0; i < 2; i++) {
 
136
        qemu_set_irq(s->irq[i], (s->status & s->mask[i]) != 0);
 
137
    }
 
138
}
 
139
 
 
140
static void pl181_fifo_push(PL181State *s, uint32_t value)
 
141
{
 
142
    int n;
 
143
 
 
144
    if (s->fifo_len == PL181_FIFO_LEN) {
 
145
        fprintf(stderr, "pl181: FIFO overflow\n");
 
146
        return;
 
147
    }
 
148
    n = (s->fifo_pos + s->fifo_len) & (PL181_FIFO_LEN - 1);
 
149
    s->fifo_len++;
 
150
    s->fifo[n] = value;
 
151
    DPRINTF("FIFO push %08x\n", (int)value);
 
152
}
 
153
 
 
154
static uint32_t pl181_fifo_pop(PL181State *s)
 
155
{
 
156
    uint32_t value;
 
157
 
 
158
    if (s->fifo_len == 0) {
 
159
        fprintf(stderr, "pl181: FIFO underflow\n");
 
160
        return 0;
 
161
    }
 
162
    value = s->fifo[s->fifo_pos];
 
163
    s->fifo_len--;
 
164
    s->fifo_pos = (s->fifo_pos + 1) & (PL181_FIFO_LEN - 1);
 
165
    DPRINTF("FIFO pop %08x\n", (int)value);
 
166
    return value;
 
167
}
 
168
 
 
169
static void pl181_send_command(PL181State *s)
 
170
{
 
171
    SDRequest request;
 
172
    uint8_t response[16];
 
173
    int rlen;
 
174
 
 
175
    request.cmd = s->cmd & PL181_CMD_INDEX;
 
176
    request.arg = s->cmdarg;
 
177
    DPRINTF("Command %d %08x\n", request.cmd, request.arg);
 
178
    rlen = sd_do_command(s->card, &request, response);
 
179
    if (rlen < 0)
 
180
        goto error;
 
181
    if (s->cmd & PL181_CMD_RESPONSE) {
 
182
#define RWORD(n) (((uint32_t)response[n] << 24) | (response[n + 1] << 16) \
 
183
                  | (response[n + 2] << 8) | response[n + 3])
 
184
        if (rlen == 0 || (rlen == 4 && (s->cmd & PL181_CMD_LONGRESP)))
 
185
            goto error;
 
186
        if (rlen != 4 && rlen != 16)
 
187
            goto error;
 
188
        s->response[0] = RWORD(0);
 
189
        if (rlen == 4) {
 
190
            s->response[1] = s->response[2] = s->response[3] = 0;
 
191
        } else {
 
192
            s->response[1] = RWORD(4);
 
193
            s->response[2] = RWORD(8);
 
194
            s->response[3] = RWORD(12) & ~1;
 
195
        }
 
196
        DPRINTF("Response received\n");
 
197
        s->status |= PL181_STATUS_CMDRESPEND;
 
198
#undef RWORD
 
199
    } else {
 
200
        DPRINTF("Command sent\n");
 
201
        s->status |= PL181_STATUS_CMDSENT;
 
202
    }
 
203
    return;
 
204
 
 
205
error:
 
206
    DPRINTF("Timeout\n");
 
207
    s->status |= PL181_STATUS_CMDTIMEOUT;
 
208
}
 
209
 
 
210
/* Transfer data between the card and the FIFO.  This is complicated by
 
211
   the FIFO holding 32-bit words and the card taking data in single byte
 
212
   chunks.  FIFO bytes are transferred in little-endian order.  */
 
213
 
 
214
static void pl181_fifo_run(PL181State *s)
 
215
{
 
216
    uint32_t bits;
 
217
    uint32_t value = 0;
 
218
    int n;
 
219
    int is_read;
 
220
 
 
221
    is_read = (s->datactrl & PL181_DATA_DIRECTION) != 0;
 
222
    if (s->datacnt != 0 && (!is_read || sd_data_ready(s->card))
 
223
            && !s->linux_hack) {
 
224
        if (is_read) {
 
225
            n = 0;
 
226
            while (s->datacnt && s->fifo_len < PL181_FIFO_LEN) {
 
227
                value |= (uint32_t)sd_read_data(s->card) << (n * 8);
 
228
                s->datacnt--;
 
229
                n++;
 
230
                if (n == 4) {
 
231
                    pl181_fifo_push(s, value);
 
232
                    n = 0;
 
233
                    value = 0;
 
234
                }
 
235
            }
 
236
            if (n != 0) {
 
237
                pl181_fifo_push(s, value);
 
238
            }
 
239
        } else { /* write */
 
240
            n = 0;
 
241
            while (s->datacnt > 0 && (s->fifo_len > 0 || n > 0)) {
 
242
                if (n == 0) {
 
243
                    value = pl181_fifo_pop(s);
 
244
                    n = 4;
 
245
                }
 
246
                n--;
 
247
                s->datacnt--;
 
248
                sd_write_data(s->card, value & 0xff);
 
249
                value >>= 8;
 
250
            }
 
251
        }
 
252
    }
 
253
    s->status &= ~(PL181_STATUS_RX_FIFO | PL181_STATUS_TX_FIFO);
 
254
    if (s->datacnt == 0) {
 
255
        s->status |= PL181_STATUS_DATAEND;
 
256
        /* HACK: */
 
257
        s->status |= PL181_STATUS_DATABLOCKEND;
 
258
        DPRINTF("Transfer Complete\n");
 
259
    }
 
260
    if (s->datacnt == 0 && s->fifo_len == 0) {
 
261
        s->datactrl &= ~PL181_DATA_ENABLE;
 
262
        DPRINTF("Data engine idle\n");
 
263
    } else {
 
264
        /* Update FIFO bits.  */
 
265
        bits = PL181_STATUS_TXACTIVE | PL181_STATUS_RXACTIVE;
 
266
        if (s->fifo_len == 0) {
 
267
            bits |= PL181_STATUS_TXFIFOEMPTY;
 
268
            bits |= PL181_STATUS_RXFIFOEMPTY;
 
269
        } else {
 
270
            bits |= PL181_STATUS_TXDATAAVLBL;
 
271
            bits |= PL181_STATUS_RXDATAAVLBL;
 
272
        }
 
273
        if (s->fifo_len == 16) {
 
274
            bits |= PL181_STATUS_TXFIFOFULL;
 
275
            bits |= PL181_STATUS_RXFIFOFULL;
 
276
        }
 
277
        if (s->fifo_len <= 8) {
 
278
            bits |= PL181_STATUS_TXFIFOHALFEMPTY;
 
279
        }
 
280
        if (s->fifo_len >= 8) {
 
281
            bits |= PL181_STATUS_RXFIFOHALFFULL;
 
282
        }
 
283
        if (s->datactrl & PL181_DATA_DIRECTION) {
 
284
            bits &= PL181_STATUS_RX_FIFO;
 
285
        } else {
 
286
            bits &= PL181_STATUS_TX_FIFO;
 
287
        }
 
288
        s->status |= bits;
 
289
    }
 
290
}
 
291
 
 
292
static uint64_t pl181_read(void *opaque, hwaddr offset,
 
293
                           unsigned size)
 
294
{
 
295
    PL181State *s = (PL181State *)opaque;
 
296
    uint32_t tmp;
 
297
 
 
298
    if (offset >= 0xfe0 && offset < 0x1000) {
 
299
        return pl181_id[(offset - 0xfe0) >> 2];
 
300
    }
 
301
    switch (offset) {
 
302
    case 0x00: /* Power */
 
303
        return s->power;
 
304
    case 0x04: /* Clock */
 
305
        return s->clock;
 
306
    case 0x08: /* Argument */
 
307
        return s->cmdarg;
 
308
    case 0x0c: /* Command */
 
309
        return s->cmd;
 
310
    case 0x10: /* RespCmd */
 
311
        return s->respcmd;
 
312
    case 0x14: /* Response0 */
 
313
        return s->response[0];
 
314
    case 0x18: /* Response1 */
 
315
        return s->response[1];
 
316
    case 0x1c: /* Response2 */
 
317
        return s->response[2];
 
318
    case 0x20: /* Response3 */
 
319
        return s->response[3];
 
320
    case 0x24: /* DataTimer */
 
321
        return s->datatimer;
 
322
    case 0x28: /* DataLength */
 
323
        return s->datalength;
 
324
    case 0x2c: /* DataCtrl */
 
325
        return s->datactrl;
 
326
    case 0x30: /* DataCnt */
 
327
        return s->datacnt;
 
328
    case 0x34: /* Status */
 
329
        tmp = s->status;
 
330
        if (s->linux_hack) {
 
331
            s->linux_hack = 0;
 
332
            pl181_fifo_run(s);
 
333
            pl181_update(s);
 
334
        }
 
335
        return tmp;
 
336
    case 0x3c: /* Mask0 */
 
337
        return s->mask[0];
 
338
    case 0x40: /* Mask1 */
 
339
        return s->mask[1];
 
340
    case 0x48: /* FifoCnt */
 
341
        /* The documentation is somewhat vague about exactly what FifoCnt
 
342
           does.  On real hardware it appears to be when decrememnted
 
343
           when a word is transferred between the FIFO and the serial
 
344
           data engine.  DataCnt is decremented after each byte is
 
345
           transferred between the serial engine and the card.
 
346
           We don't emulate this level of detail, so both can be the same.  */
 
347
        tmp = (s->datacnt + 3) >> 2;
 
348
        if (s->linux_hack) {
 
349
            s->linux_hack = 0;
 
350
            pl181_fifo_run(s);
 
351
            pl181_update(s);
 
352
        }
 
353
        return tmp;
 
354
    case 0x80: case 0x84: case 0x88: case 0x8c: /* FifoData */
 
355
    case 0x90: case 0x94: case 0x98: case 0x9c:
 
356
    case 0xa0: case 0xa4: case 0xa8: case 0xac:
 
357
    case 0xb0: case 0xb4: case 0xb8: case 0xbc:
 
358
        if (s->fifo_len == 0) {
 
359
            qemu_log_mask(LOG_GUEST_ERROR, "pl181: Unexpected FIFO read\n");
 
360
            return 0;
 
361
        } else {
 
362
            uint32_t value;
 
363
            value = pl181_fifo_pop(s);
 
364
            s->linux_hack = 1;
 
365
            pl181_fifo_run(s);
 
366
            pl181_update(s);
 
367
            return value;
 
368
        }
 
369
    default:
 
370
        qemu_log_mask(LOG_GUEST_ERROR,
 
371
                      "pl181_read: Bad offset %x\n", (int)offset);
 
372
        return 0;
 
373
    }
 
374
}
 
375
 
 
376
static void pl181_write(void *opaque, hwaddr offset,
 
377
                        uint64_t value, unsigned size)
 
378
{
 
379
    PL181State *s = (PL181State *)opaque;
 
380
 
 
381
    switch (offset) {
 
382
    case 0x00: /* Power */
 
383
        s->power = value & 0xff;
 
384
        break;
 
385
    case 0x04: /* Clock */
 
386
        s->clock = value & 0xff;
 
387
        break;
 
388
    case 0x08: /* Argument */
 
389
        s->cmdarg = value;
 
390
        break;
 
391
    case 0x0c: /* Command */
 
392
        s->cmd = value;
 
393
        if (s->cmd & PL181_CMD_ENABLE) {
 
394
            if (s->cmd & PL181_CMD_INTERRUPT) {
 
395
                qemu_log_mask(LOG_UNIMP,
 
396
                              "pl181: Interrupt mode not implemented\n");
 
397
            } if (s->cmd & PL181_CMD_PENDING) {
 
398
                qemu_log_mask(LOG_UNIMP,
 
399
                              "pl181: Pending commands not implemented\n");
 
400
            } else {
 
401
                pl181_send_command(s);
 
402
                pl181_fifo_run(s);
 
403
            }
 
404
            /* The command has completed one way or the other.  */
 
405
            s->cmd &= ~PL181_CMD_ENABLE;
 
406
        }
 
407
        break;
 
408
    case 0x24: /* DataTimer */
 
409
        s->datatimer = value;
 
410
        break;
 
411
    case 0x28: /* DataLength */
 
412
        s->datalength = value & 0xffff;
 
413
        break;
 
414
    case 0x2c: /* DataCtrl */
 
415
        s->datactrl = value & 0xff;
 
416
        if (value & PL181_DATA_ENABLE) {
 
417
            s->datacnt = s->datalength;
 
418
            pl181_fifo_run(s);
 
419
        }
 
420
        break;
 
421
    case 0x38: /* Clear */
 
422
        s->status &= ~(value & 0x7ff);
 
423
        break;
 
424
    case 0x3c: /* Mask0 */
 
425
        s->mask[0] = value;
 
426
        break;
 
427
    case 0x40: /* Mask1 */
 
428
        s->mask[1] = value;
 
429
        break;
 
430
    case 0x80: case 0x84: case 0x88: case 0x8c: /* FifoData */
 
431
    case 0x90: case 0x94: case 0x98: case 0x9c:
 
432
    case 0xa0: case 0xa4: case 0xa8: case 0xac:
 
433
    case 0xb0: case 0xb4: case 0xb8: case 0xbc:
 
434
        if (s->datacnt == 0) {
 
435
            qemu_log_mask(LOG_GUEST_ERROR, "pl181: Unexpected FIFO write\n");
 
436
        } else {
 
437
            pl181_fifo_push(s, value);
 
438
            pl181_fifo_run(s);
 
439
        }
 
440
        break;
 
441
    default:
 
442
        qemu_log_mask(LOG_GUEST_ERROR,
 
443
                      "pl181_write: Bad offset %x\n", (int)offset);
 
444
    }
 
445
    pl181_update(s);
 
446
}
 
447
 
 
448
static const MemoryRegionOps pl181_ops = {
 
449
    .read = pl181_read,
 
450
    .write = pl181_write,
 
451
    .endianness = DEVICE_NATIVE_ENDIAN,
 
452
};
 
453
 
 
454
static void pl181_reset(DeviceState *d)
 
455
{
 
456
    PL181State *s = PL181(d);
 
457
 
 
458
    s->power = 0;
 
459
    s->cmdarg = 0;
 
460
    s->cmd = 0;
 
461
    s->datatimer = 0;
 
462
    s->datalength = 0;
 
463
    s->respcmd = 0;
 
464
    s->response[0] = 0;
 
465
    s->response[1] = 0;
 
466
    s->response[2] = 0;
 
467
    s->response[3] = 0;
 
468
    s->datatimer = 0;
 
469
    s->datalength = 0;
 
470
    s->datactrl = 0;
 
471
    s->datacnt = 0;
 
472
    s->status = 0;
 
473
    s->linux_hack = 0;
 
474
    s->mask[0] = 0;
 
475
    s->mask[1] = 0;
 
476
 
 
477
    /* We can assume our GPIO outputs have been wired up now */
 
478
    sd_set_cb(s->card, s->cardstatus[0], s->cardstatus[1]);
 
479
}
 
480
 
 
481
static int pl181_init(SysBusDevice *sbd)
 
482
{
 
483
    DeviceState *dev = DEVICE(sbd);
 
484
    PL181State *s = PL181(dev);
 
485
    DriveInfo *dinfo;
 
486
 
 
487
    memory_region_init_io(&s->iomem, OBJECT(s), &pl181_ops, s, "pl181", 0x1000);
 
488
    sysbus_init_mmio(sbd, &s->iomem);
 
489
    sysbus_init_irq(sbd, &s->irq[0]);
 
490
    sysbus_init_irq(sbd, &s->irq[1]);
 
491
    qdev_init_gpio_out(dev, s->cardstatus, 2);
 
492
    dinfo = drive_get_next(IF_SD);
 
493
    s->card = sd_init(dinfo ? dinfo->bdrv : NULL, false);
 
494
    if (s->card == NULL) {
 
495
        return -1;
 
496
    }
 
497
 
 
498
    return 0;
 
499
}
 
500
 
 
501
static void pl181_class_init(ObjectClass *klass, void *data)
 
502
{
 
503
    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
 
504
    DeviceClass *k = DEVICE_CLASS(klass);
 
505
 
 
506
    sdc->init = pl181_init;
 
507
    k->vmsd = &vmstate_pl181;
 
508
    k->reset = pl181_reset;
 
509
    k->no_user = 1;
 
510
}
 
511
 
 
512
static const TypeInfo pl181_info = {
 
513
    .name          = TYPE_PL181,
 
514
    .parent        = TYPE_SYS_BUS_DEVICE,
 
515
    .instance_size = sizeof(PL181State),
 
516
    .class_init    = pl181_class_init,
 
517
};
 
518
 
 
519
static void pl181_register_types(void)
 
520
{
 
521
    type_register_static(&pl181_info);
 
522
}
 
523
 
 
524
type_init(pl181_register_types)