cachepc-qemu

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

pxa2xx_mmci.c (16259B)


      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 "qemu/osdep.h"
     14#include "qapi/error.h"
     15#include "hw/irq.h"
     16#include "hw/sysbus.h"
     17#include "migration/vmstate.h"
     18#include "hw/arm/pxa.h"
     19#include "hw/sd/sd.h"
     20#include "hw/qdev-properties.h"
     21#include "qemu/log.h"
     22#include "qemu/module.h"
     23#include "trace.h"
     24#include "qom/object.h"
     25
     26#define TYPE_PXA2XX_MMCI_BUS "pxa2xx-mmci-bus"
     27/* This is reusing the SDBus typedef from SD_BUS */
     28DECLARE_INSTANCE_CHECKER(SDBus, PXA2XX_MMCI_BUS,
     29                         TYPE_PXA2XX_MMCI_BUS)
     30
     31struct PXA2xxMMCIState {
     32    SysBusDevice parent_obj;
     33
     34    MemoryRegion iomem;
     35    qemu_irq irq;
     36    qemu_irq rx_dma;
     37    qemu_irq tx_dma;
     38    qemu_irq inserted;
     39    qemu_irq readonly;
     40
     41    BlockBackend *blk;
     42    SDBus sdbus;
     43
     44    uint32_t status;
     45    uint32_t clkrt;
     46    uint32_t spi;
     47    uint32_t cmdat;
     48    uint32_t resp_tout;
     49    uint32_t read_tout;
     50    int32_t blklen;
     51    int32_t numblk;
     52    uint32_t intmask;
     53    uint32_t intreq;
     54    int32_t cmd;
     55    uint32_t arg;
     56
     57    int32_t active;
     58    int32_t bytesleft;
     59    uint8_t tx_fifo[64];
     60    uint32_t tx_start;
     61    uint32_t tx_len;
     62    uint8_t rx_fifo[32];
     63    uint32_t rx_start;
     64    uint32_t rx_len;
     65    uint16_t resp_fifo[9];
     66    uint32_t resp_len;
     67
     68    int32_t cmdreq;
     69};
     70
     71static bool pxa2xx_mmci_vmstate_validate(void *opaque, int version_id)
     72{
     73    PXA2xxMMCIState *s = opaque;
     74
     75    return s->tx_start < ARRAY_SIZE(s->tx_fifo)
     76        && s->rx_start < ARRAY_SIZE(s->rx_fifo)
     77        && s->tx_len <= ARRAY_SIZE(s->tx_fifo)
     78        && s->rx_len <= ARRAY_SIZE(s->rx_fifo)
     79        && s->resp_len <= ARRAY_SIZE(s->resp_fifo);
     80}
     81
     82
     83static const VMStateDescription vmstate_pxa2xx_mmci = {
     84    .name = "pxa2xx-mmci",
     85    .version_id = 2,
     86    .minimum_version_id = 2,
     87    .fields = (VMStateField[]) {
     88        VMSTATE_UINT32(status, PXA2xxMMCIState),
     89        VMSTATE_UINT32(clkrt, PXA2xxMMCIState),
     90        VMSTATE_UINT32(spi, PXA2xxMMCIState),
     91        VMSTATE_UINT32(cmdat, PXA2xxMMCIState),
     92        VMSTATE_UINT32(resp_tout, PXA2xxMMCIState),
     93        VMSTATE_UINT32(read_tout, PXA2xxMMCIState),
     94        VMSTATE_INT32(blklen, PXA2xxMMCIState),
     95        VMSTATE_INT32(numblk, PXA2xxMMCIState),
     96        VMSTATE_UINT32(intmask, PXA2xxMMCIState),
     97        VMSTATE_UINT32(intreq, PXA2xxMMCIState),
     98        VMSTATE_INT32(cmd, PXA2xxMMCIState),
     99        VMSTATE_UINT32(arg, PXA2xxMMCIState),
    100        VMSTATE_INT32(cmdreq, PXA2xxMMCIState),
    101        VMSTATE_INT32(active, PXA2xxMMCIState),
    102        VMSTATE_INT32(bytesleft, PXA2xxMMCIState),
    103        VMSTATE_UINT32(tx_start, PXA2xxMMCIState),
    104        VMSTATE_UINT32(tx_len, PXA2xxMMCIState),
    105        VMSTATE_UINT32(rx_start, PXA2xxMMCIState),
    106        VMSTATE_UINT32(rx_len, PXA2xxMMCIState),
    107        VMSTATE_UINT32(resp_len, PXA2xxMMCIState),
    108        VMSTATE_VALIDATE("fifo size incorrect", pxa2xx_mmci_vmstate_validate),
    109        VMSTATE_UINT8_ARRAY(tx_fifo, PXA2xxMMCIState, 64),
    110        VMSTATE_UINT8_ARRAY(rx_fifo, PXA2xxMMCIState, 32),
    111        VMSTATE_UINT16_ARRAY(resp_fifo, PXA2xxMMCIState, 9),
    112        VMSTATE_END_OF_LIST()
    113    }
    114};
    115
    116#define MMC_STRPCL	0x00	/* MMC Clock Start/Stop register */
    117#define MMC_STAT	0x04	/* MMC Status register */
    118#define MMC_CLKRT	0x08	/* MMC Clock Rate register */
    119#define MMC_SPI		0x0c	/* MMC SPI Mode register */
    120#define MMC_CMDAT	0x10	/* MMC Command/Data register */
    121#define MMC_RESTO	0x14	/* MMC Response Time-Out register */
    122#define MMC_RDTO	0x18	/* MMC Read Time-Out register */
    123#define MMC_BLKLEN	0x1c	/* MMC Block Length register */
    124#define MMC_NUMBLK	0x20	/* MMC Number of Blocks register */
    125#define MMC_PRTBUF	0x24	/* MMC Buffer Partly Full register */
    126#define MMC_I_MASK	0x28	/* MMC Interrupt Mask register */
    127#define MMC_I_REG	0x2c	/* MMC Interrupt Request register */
    128#define MMC_CMD		0x30	/* MMC Command register */
    129#define MMC_ARGH	0x34	/* MMC Argument High register */
    130#define MMC_ARGL	0x38	/* MMC Argument Low register */
    131#define MMC_RES		0x3c	/* MMC Response FIFO */
    132#define MMC_RXFIFO	0x40	/* MMC Receive FIFO */
    133#define MMC_TXFIFO	0x44	/* MMC Transmit FIFO */
    134#define MMC_RDWAIT	0x48	/* MMC RD_WAIT register */
    135#define MMC_BLKS_REM	0x4c	/* MMC Blocks Remaining register */
    136
    137/* Bitfield masks */
    138#define STRPCL_STOP_CLK	(1 << 0)
    139#define STRPCL_STRT_CLK	(1 << 1)
    140#define STAT_TOUT_RES	(1 << 1)
    141#define STAT_CLK_EN	(1 << 8)
    142#define STAT_DATA_DONE	(1 << 11)
    143#define STAT_PRG_DONE	(1 << 12)
    144#define STAT_END_CMDRES	(1 << 13)
    145#define SPI_SPI_MODE	(1 << 0)
    146#define CMDAT_RES_TYPE	(3 << 0)
    147#define CMDAT_DATA_EN	(1 << 2)
    148#define CMDAT_WR_RD	(1 << 3)
    149#define CMDAT_DMA_EN	(1 << 7)
    150#define CMDAT_STOP_TRAN	(1 << 10)
    151#define INT_DATA_DONE	(1 << 0)
    152#define INT_PRG_DONE	(1 << 1)
    153#define INT_END_CMD	(1 << 2)
    154#define INT_STOP_CMD	(1 << 3)
    155#define INT_CLK_OFF	(1 << 4)
    156#define INT_RXFIFO_REQ	(1 << 5)
    157#define INT_TXFIFO_REQ	(1 << 6)
    158#define INT_TINT	(1 << 7)
    159#define INT_DAT_ERR	(1 << 8)
    160#define INT_RES_ERR	(1 << 9)
    161#define INT_RD_STALLED	(1 << 10)
    162#define INT_SDIO_INT	(1 << 11)
    163#define INT_SDIO_SACK	(1 << 12)
    164#define PRTBUF_PRT_BUF	(1 << 0)
    165
    166/* Route internal interrupt lines to the global IC and DMA */
    167static void pxa2xx_mmci_int_update(PXA2xxMMCIState *s)
    168{
    169    uint32_t mask = s->intmask;
    170    if (s->cmdat & CMDAT_DMA_EN) {
    171        mask |= INT_RXFIFO_REQ | INT_TXFIFO_REQ;
    172
    173        qemu_set_irq(s->rx_dma, !!(s->intreq & INT_RXFIFO_REQ));
    174        qemu_set_irq(s->tx_dma, !!(s->intreq & INT_TXFIFO_REQ));
    175    }
    176
    177    qemu_set_irq(s->irq, !!(s->intreq & ~mask));
    178}
    179
    180static void pxa2xx_mmci_fifo_update(PXA2xxMMCIState *s)
    181{
    182    if (!s->active)
    183        return;
    184
    185    if (s->cmdat & CMDAT_WR_RD) {
    186        while (s->bytesleft && s->tx_len) {
    187            sdbus_write_byte(&s->sdbus, s->tx_fifo[s->tx_start++]);
    188            s->tx_start &= 0x1f;
    189            s->tx_len --;
    190            s->bytesleft --;
    191        }
    192        if (s->bytesleft)
    193            s->intreq |= INT_TXFIFO_REQ;
    194    } else
    195        while (s->bytesleft && s->rx_len < 32) {
    196            s->rx_fifo[(s->rx_start + (s->rx_len ++)) & 0x1f] =
    197                sdbus_read_byte(&s->sdbus);
    198            s->bytesleft --;
    199            s->intreq |= INT_RXFIFO_REQ;
    200        }
    201
    202    if (!s->bytesleft) {
    203        s->active = 0;
    204        s->intreq |= INT_DATA_DONE;
    205        s->status |= STAT_DATA_DONE;
    206
    207        if (s->cmdat & CMDAT_WR_RD) {
    208            s->intreq |= INT_PRG_DONE;
    209            s->status |= STAT_PRG_DONE;
    210        }
    211    }
    212
    213    pxa2xx_mmci_int_update(s);
    214}
    215
    216static void pxa2xx_mmci_wakequeues(PXA2xxMMCIState *s)
    217{
    218    int rsplen, i;
    219    SDRequest request;
    220    uint8_t response[16];
    221
    222    s->active = 1;
    223    s->rx_len = 0;
    224    s->tx_len = 0;
    225    s->cmdreq = 0;
    226
    227    request.cmd = s->cmd;
    228    request.arg = s->arg;
    229    request.crc = 0;	/* FIXME */
    230
    231    rsplen = sdbus_do_command(&s->sdbus, &request, response);
    232    s->intreq |= INT_END_CMD;
    233
    234    memset(s->resp_fifo, 0, sizeof(s->resp_fifo));
    235    switch (s->cmdat & CMDAT_RES_TYPE) {
    236#define PXAMMCI_RESP(wd, value0, value1)	\
    237        s->resp_fifo[(wd) + 0] |= (value0);	\
    238        s->resp_fifo[(wd) + 1] |= (value1) << 8;
    239    case 0:	/* No response */
    240        goto complete;
    241
    242    case 1:	/* R1, R4, R5 or R6 */
    243        if (rsplen < 4)
    244            goto timeout;
    245        goto complete;
    246
    247    case 2:	/* R2 */
    248        if (rsplen < 16)
    249            goto timeout;
    250        goto complete;
    251
    252    case 3:	/* R3 */
    253        if (rsplen < 4)
    254            goto timeout;
    255        goto complete;
    256
    257    complete:
    258        for (i = 0; rsplen > 0; i ++, rsplen -= 2) {
    259            PXAMMCI_RESP(i, response[i * 2], response[i * 2 + 1]);
    260        }
    261        s->status |= STAT_END_CMDRES;
    262
    263        if (!(s->cmdat & CMDAT_DATA_EN))
    264            s->active = 0;
    265        else
    266            s->bytesleft = s->numblk * s->blklen;
    267
    268        s->resp_len = 0;
    269        break;
    270
    271    timeout:
    272        s->active = 0;
    273        s->status |= STAT_TOUT_RES;
    274        break;
    275    }
    276
    277    pxa2xx_mmci_fifo_update(s);
    278}
    279
    280static uint64_t pxa2xx_mmci_read(void *opaque, hwaddr offset, unsigned size)
    281{
    282    PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
    283    uint32_t ret = 0;
    284
    285    switch (offset) {
    286    case MMC_STRPCL:
    287        break;
    288    case MMC_STAT:
    289        ret = s->status;
    290        break;
    291    case MMC_CLKRT:
    292        ret = s->clkrt;
    293        break;
    294    case MMC_SPI:
    295        ret = s->spi;
    296        break;
    297    case MMC_CMDAT:
    298        ret = s->cmdat;
    299        break;
    300    case MMC_RESTO:
    301        ret = s->resp_tout;
    302        break;
    303    case MMC_RDTO:
    304        ret = s->read_tout;
    305        break;
    306    case MMC_BLKLEN:
    307        ret = s->blklen;
    308        break;
    309    case MMC_NUMBLK:
    310        ret = s->numblk;
    311        break;
    312    case MMC_PRTBUF:
    313        break;
    314    case MMC_I_MASK:
    315        ret = s->intmask;
    316        break;
    317    case MMC_I_REG:
    318        ret = s->intreq;
    319        break;
    320    case MMC_CMD:
    321        ret = s->cmd | 0x40;
    322        break;
    323    case MMC_ARGH:
    324        ret = s->arg >> 16;
    325        break;
    326    case MMC_ARGL:
    327        ret = s->arg & 0xffff;
    328        break;
    329    case MMC_RES:
    330        ret = (s->resp_len < 9) ? s->resp_fifo[s->resp_len++] : 0;
    331        break;
    332    case MMC_RXFIFO:
    333        while (size-- && s->rx_len) {
    334            ret |= s->rx_fifo[s->rx_start++] << (size << 3);
    335            s->rx_start &= 0x1f;
    336            s->rx_len --;
    337        }
    338        s->intreq &= ~INT_RXFIFO_REQ;
    339        pxa2xx_mmci_fifo_update(s);
    340        break;
    341    case MMC_RDWAIT:
    342        break;
    343    case MMC_BLKS_REM:
    344        ret = s->numblk;
    345        break;
    346    default:
    347        qemu_log_mask(LOG_GUEST_ERROR,
    348                      "%s: incorrect register 0x%02" HWADDR_PRIx "\n",
    349                      __func__, offset);
    350    }
    351    trace_pxa2xx_mmci_read(size, offset, ret);
    352
    353    return ret;
    354}
    355
    356static void pxa2xx_mmci_write(void *opaque,
    357                              hwaddr offset, uint64_t value, unsigned size)
    358{
    359    PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
    360
    361    trace_pxa2xx_mmci_write(size, offset, value);
    362    switch (offset) {
    363    case MMC_STRPCL:
    364        if (value & STRPCL_STRT_CLK) {
    365            s->status |= STAT_CLK_EN;
    366            s->intreq &= ~INT_CLK_OFF;
    367
    368            if (s->cmdreq && !(s->cmdat & CMDAT_STOP_TRAN)) {
    369                s->status &= STAT_CLK_EN;
    370                pxa2xx_mmci_wakequeues(s);
    371            }
    372        }
    373
    374        if (value & STRPCL_STOP_CLK) {
    375            s->status &= ~STAT_CLK_EN;
    376            s->intreq |= INT_CLK_OFF;
    377            s->active = 0;
    378        }
    379
    380        pxa2xx_mmci_int_update(s);
    381        break;
    382
    383    case MMC_CLKRT:
    384        s->clkrt = value & 7;
    385        break;
    386
    387    case MMC_SPI:
    388        s->spi = value & 0xf;
    389        if (value & SPI_SPI_MODE) {
    390            qemu_log_mask(LOG_GUEST_ERROR,
    391                          "%s: attempted to use card in SPI mode\n", __func__);
    392        }
    393        break;
    394
    395    case MMC_CMDAT:
    396        s->cmdat = value & 0x3dff;
    397        s->active = 0;
    398        s->cmdreq = 1;
    399        if (!(value & CMDAT_STOP_TRAN)) {
    400            s->status &= STAT_CLK_EN;
    401
    402            if (s->status & STAT_CLK_EN)
    403                pxa2xx_mmci_wakequeues(s);
    404        }
    405
    406        pxa2xx_mmci_int_update(s);
    407        break;
    408
    409    case MMC_RESTO:
    410        s->resp_tout = value & 0x7f;
    411        break;
    412
    413    case MMC_RDTO:
    414        s->read_tout = value & 0xffff;
    415        break;
    416
    417    case MMC_BLKLEN:
    418        s->blklen = value & 0xfff;
    419        break;
    420
    421    case MMC_NUMBLK:
    422        s->numblk = value & 0xffff;
    423        break;
    424
    425    case MMC_PRTBUF:
    426        if (value & PRTBUF_PRT_BUF) {
    427            s->tx_start ^= 32;
    428            s->tx_len = 0;
    429        }
    430        pxa2xx_mmci_fifo_update(s);
    431        break;
    432
    433    case MMC_I_MASK:
    434        s->intmask = value & 0x1fff;
    435        pxa2xx_mmci_int_update(s);
    436        break;
    437
    438    case MMC_CMD:
    439        s->cmd = value & 0x3f;
    440        break;
    441
    442    case MMC_ARGH:
    443        s->arg &= 0x0000ffff;
    444        s->arg |= value << 16;
    445        break;
    446
    447    case MMC_ARGL:
    448        s->arg &= 0xffff0000;
    449        s->arg |= value & 0x0000ffff;
    450        break;
    451
    452    case MMC_TXFIFO:
    453        while (size-- && s->tx_len < 0x20)
    454            s->tx_fifo[(s->tx_start + (s->tx_len ++)) & 0x1f] =
    455                    (value >> (size << 3)) & 0xff;
    456        s->intreq &= ~INT_TXFIFO_REQ;
    457        pxa2xx_mmci_fifo_update(s);
    458        break;
    459
    460    case MMC_RDWAIT:
    461    case MMC_BLKS_REM:
    462        break;
    463
    464    default:
    465        qemu_log_mask(LOG_GUEST_ERROR,
    466                      "%s: incorrect reg 0x%02" HWADDR_PRIx " "
    467                      "(value 0x%08" PRIx64 ")\n", __func__, offset, value);
    468    }
    469}
    470
    471static const MemoryRegionOps pxa2xx_mmci_ops = {
    472    .read = pxa2xx_mmci_read,
    473    .write = pxa2xx_mmci_write,
    474    .endianness = DEVICE_NATIVE_ENDIAN,
    475};
    476
    477PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
    478                hwaddr base,
    479                qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma)
    480{
    481    DeviceState *dev;
    482    SysBusDevice *sbd;
    483
    484    dev = qdev_new(TYPE_PXA2XX_MMCI);
    485    sbd = SYS_BUS_DEVICE(dev);
    486    sysbus_mmio_map(sbd, 0, base);
    487    sysbus_connect_irq(sbd, 0, irq);
    488    qdev_connect_gpio_out_named(dev, "rx-dma", 0, rx_dma);
    489    qdev_connect_gpio_out_named(dev, "tx-dma", 0, tx_dma);
    490    sysbus_realize_and_unref(sbd, &error_fatal);
    491
    492    return PXA2XX_MMCI(dev);
    493}
    494
    495static void pxa2xx_mmci_set_inserted(DeviceState *dev, bool inserted)
    496{
    497    PXA2xxMMCIState *s = PXA2XX_MMCI(dev);
    498
    499    qemu_set_irq(s->inserted, inserted);
    500}
    501
    502static void pxa2xx_mmci_set_readonly(DeviceState *dev, bool readonly)
    503{
    504    PXA2xxMMCIState *s = PXA2XX_MMCI(dev);
    505
    506    qemu_set_irq(s->readonly, readonly);
    507}
    508
    509void pxa2xx_mmci_handlers(PXA2xxMMCIState *s, qemu_irq readonly,
    510                          qemu_irq coverswitch)
    511{
    512    DeviceState *dev = DEVICE(s);
    513
    514    s->readonly = readonly;
    515    s->inserted = coverswitch;
    516
    517    pxa2xx_mmci_set_inserted(dev, sdbus_get_inserted(&s->sdbus));
    518    pxa2xx_mmci_set_readonly(dev, sdbus_get_readonly(&s->sdbus));
    519}
    520
    521static void pxa2xx_mmci_reset(DeviceState *d)
    522{
    523    PXA2xxMMCIState *s = PXA2XX_MMCI(d);
    524
    525    s->status = 0;
    526    s->clkrt = 0;
    527    s->spi = 0;
    528    s->cmdat = 0;
    529    s->resp_tout = 0;
    530    s->read_tout = 0;
    531    s->blklen = 0;
    532    s->numblk = 0;
    533    s->intmask = 0;
    534    s->intreq = 0;
    535    s->cmd = 0;
    536    s->arg = 0;
    537    s->active = 0;
    538    s->bytesleft = 0;
    539    s->tx_start = 0;
    540    s->tx_len = 0;
    541    s->rx_start = 0;
    542    s->rx_len = 0;
    543    s->resp_len = 0;
    544    s->cmdreq = 0;
    545    memset(s->tx_fifo, 0, sizeof(s->tx_fifo));
    546    memset(s->rx_fifo, 0, sizeof(s->rx_fifo));
    547    memset(s->resp_fifo, 0, sizeof(s->resp_fifo));
    548}
    549
    550static void pxa2xx_mmci_instance_init(Object *obj)
    551{
    552    PXA2xxMMCIState *s = PXA2XX_MMCI(obj);
    553    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    554    DeviceState *dev = DEVICE(obj);
    555
    556    memory_region_init_io(&s->iomem, obj, &pxa2xx_mmci_ops, s,
    557                          "pxa2xx-mmci", 0x00100000);
    558    sysbus_init_mmio(sbd, &s->iomem);
    559    sysbus_init_irq(sbd, &s->irq);
    560    qdev_init_gpio_out_named(dev, &s->rx_dma, "rx-dma", 1);
    561    qdev_init_gpio_out_named(dev, &s->tx_dma, "tx-dma", 1);
    562
    563    qbus_init(&s->sdbus, sizeof(s->sdbus),
    564              TYPE_PXA2XX_MMCI_BUS, DEVICE(obj), "sd-bus");
    565}
    566
    567static void pxa2xx_mmci_class_init(ObjectClass *klass, void *data)
    568{
    569    DeviceClass *dc = DEVICE_CLASS(klass);
    570
    571    dc->vmsd = &vmstate_pxa2xx_mmci;
    572    dc->reset = pxa2xx_mmci_reset;
    573}
    574
    575static void pxa2xx_mmci_bus_class_init(ObjectClass *klass, void *data)
    576{
    577    SDBusClass *sbc = SD_BUS_CLASS(klass);
    578
    579    sbc->set_inserted = pxa2xx_mmci_set_inserted;
    580    sbc->set_readonly = pxa2xx_mmci_set_readonly;
    581}
    582
    583static const TypeInfo pxa2xx_mmci_info = {
    584    .name = TYPE_PXA2XX_MMCI,
    585    .parent = TYPE_SYS_BUS_DEVICE,
    586    .instance_size = sizeof(PXA2xxMMCIState),
    587    .instance_init = pxa2xx_mmci_instance_init,
    588    .class_init = pxa2xx_mmci_class_init,
    589};
    590
    591static const TypeInfo pxa2xx_mmci_bus_info = {
    592    .name = TYPE_PXA2XX_MMCI_BUS,
    593    .parent = TYPE_SD_BUS,
    594    .instance_size = sizeof(SDBus),
    595    .class_init = pxa2xx_mmci_bus_class_init,
    596};
    597
    598static void pxa2xx_mmci_register_types(void)
    599{
    600    type_register_static(&pxa2xx_mmci_info);
    601    type_register_static(&pxa2xx_mmci_bus_info);
    602}
    603
    604type_init(pxa2xx_mmci_register_types)