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_timer.c (17750B)


      1/*
      2 * Intel XScale PXA255/270 OS Timers.
      3 *
      4 * Copyright (c) 2006 Openedhand Ltd.
      5 * Copyright (c) 2006 Thorsten Zitterell
      6 *
      7 * This code is licensed under the GPL.
      8 */
      9
     10#include "qemu/osdep.h"
     11#include "hw/irq.h"
     12#include "hw/qdev-properties.h"
     13#include "qemu/timer.h"
     14#include "sysemu/runstate.h"
     15#include "hw/arm/pxa.h"
     16#include "hw/sysbus.h"
     17#include "migration/vmstate.h"
     18#include "qemu/log.h"
     19#include "qemu/module.h"
     20#include "qom/object.h"
     21
     22#define OSMR0	0x00
     23#define OSMR1	0x04
     24#define OSMR2	0x08
     25#define OSMR3	0x0c
     26#define OSMR4	0x80
     27#define OSMR5	0x84
     28#define OSMR6	0x88
     29#define OSMR7	0x8c
     30#define OSMR8	0x90
     31#define OSMR9	0x94
     32#define OSMR10	0x98
     33#define OSMR11	0x9c
     34#define OSCR	0x10	/* OS Timer Count */
     35#define OSCR4	0x40
     36#define OSCR5	0x44
     37#define OSCR6	0x48
     38#define OSCR7	0x4c
     39#define OSCR8	0x50
     40#define OSCR9	0x54
     41#define OSCR10	0x58
     42#define OSCR11	0x5c
     43#define OSSR	0x14	/* Timer status register */
     44#define OWER	0x18
     45#define OIER	0x1c	/* Interrupt enable register  3-0 to E3-E0 */
     46#define OMCR4	0xc0	/* OS Match Control registers */
     47#define OMCR5	0xc4
     48#define OMCR6	0xc8
     49#define OMCR7	0xcc
     50#define OMCR8	0xd0
     51#define OMCR9	0xd4
     52#define OMCR10	0xd8
     53#define OMCR11	0xdc
     54#define OSNR	0x20
     55
     56#define PXA25X_FREQ	3686400	/* 3.6864 MHz */
     57#define PXA27X_FREQ	3250000	/* 3.25 MHz */
     58
     59static int pxa2xx_timer4_freq[8] = {
     60    [0] = 0,
     61    [1] = 32768,
     62    [2] = 1000,
     63    [3] = 1,
     64    [4] = 1000000,
     65    /* [5] is the "Externally supplied clock".  Assign if necessary.  */
     66    [5 ... 7] = 0,
     67};
     68
     69#define TYPE_PXA2XX_TIMER "pxa2xx-timer"
     70OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxTimerInfo, PXA2XX_TIMER)
     71
     72
     73typedef struct {
     74    uint32_t value;
     75    qemu_irq irq;
     76    QEMUTimer *qtimer;
     77    int num;
     78    PXA2xxTimerInfo *info;
     79} PXA2xxTimer0;
     80
     81typedef struct {
     82    PXA2xxTimer0 tm;
     83    int32_t oldclock;
     84    int32_t clock;
     85    uint64_t lastload;
     86    uint32_t freq;
     87    uint32_t control;
     88} PXA2xxTimer4;
     89
     90struct PXA2xxTimerInfo {
     91    SysBusDevice parent_obj;
     92
     93    MemoryRegion iomem;
     94    uint32_t flags;
     95
     96    int32_t clock;
     97    int32_t oldclock;
     98    uint64_t lastload;
     99    uint32_t freq;
    100    PXA2xxTimer0 timer[4];
    101    uint32_t events;
    102    uint32_t irq_enabled;
    103    uint32_t reset3;
    104    uint32_t snapshot;
    105
    106    qemu_irq irq4;
    107    PXA2xxTimer4 tm4[8];
    108};
    109
    110#define PXA2XX_TIMER_HAVE_TM4	0
    111
    112static inline int pxa2xx_timer_has_tm4(PXA2xxTimerInfo *s)
    113{
    114    return s->flags & (1 << PXA2XX_TIMER_HAVE_TM4);
    115}
    116
    117static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu)
    118{
    119    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
    120    int i;
    121    uint32_t now_vm;
    122    uint64_t new_qemu;
    123
    124    now_vm = s->clock +
    125            muldiv64(now_qemu - s->lastload, s->freq, NANOSECONDS_PER_SECOND);
    126
    127    for (i = 0; i < 4; i ++) {
    128        new_qemu = now_qemu + muldiv64((uint32_t) (s->timer[i].value - now_vm),
    129                        NANOSECONDS_PER_SECOND, s->freq);
    130        timer_mod(s->timer[i].qtimer, new_qemu);
    131    }
    132}
    133
    134static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n)
    135{
    136    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
    137    uint32_t now_vm;
    138    uint64_t new_qemu;
    139    static const int counters[8] = { 0, 0, 0, 0, 4, 4, 6, 6 };
    140    int counter;
    141
    142    assert(n < ARRAY_SIZE(counters));
    143    if (s->tm4[n].control & (1 << 7))
    144        counter = n;
    145    else
    146        counter = counters[n];
    147
    148    if (!s->tm4[counter].freq) {
    149        timer_del(s->tm4[n].tm.qtimer);
    150        return;
    151    }
    152
    153    now_vm = s->tm4[counter].clock + muldiv64(now_qemu -
    154                    s->tm4[counter].lastload,
    155                    s->tm4[counter].freq, NANOSECONDS_PER_SECOND);
    156
    157    new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm),
    158                    NANOSECONDS_PER_SECOND, s->tm4[counter].freq);
    159    timer_mod(s->tm4[n].tm.qtimer, new_qemu);
    160}
    161
    162static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset,
    163                                  unsigned size)
    164{
    165    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
    166    int tm = 0;
    167
    168    switch (offset) {
    169    case OSMR3:  tm ++;
    170        /* fall through */
    171    case OSMR2:  tm ++;
    172        /* fall through */
    173    case OSMR1:  tm ++;
    174        /* fall through */
    175    case OSMR0:
    176        return s->timer[tm].value;
    177    case OSMR11: tm ++;
    178        /* fall through */
    179    case OSMR10: tm ++;
    180        /* fall through */
    181    case OSMR9:  tm ++;
    182        /* fall through */
    183    case OSMR8:  tm ++;
    184        /* fall through */
    185    case OSMR7:  tm ++;
    186        /* fall through */
    187    case OSMR6:  tm ++;
    188        /* fall through */
    189    case OSMR5:  tm ++;
    190        /* fall through */
    191    case OSMR4:
    192        if (!pxa2xx_timer_has_tm4(s))
    193            goto badreg;
    194        return s->tm4[tm].tm.value;
    195    case OSCR:
    196        return s->clock + muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
    197                        s->lastload, s->freq, NANOSECONDS_PER_SECOND);
    198    case OSCR11: tm ++;
    199        /* fall through */
    200    case OSCR10: tm ++;
    201        /* fall through */
    202    case OSCR9:  tm ++;
    203        /* fall through */
    204    case OSCR8:  tm ++;
    205        /* fall through */
    206    case OSCR7:  tm ++;
    207        /* fall through */
    208    case OSCR6:  tm ++;
    209        /* fall through */
    210    case OSCR5:  tm ++;
    211        /* fall through */
    212    case OSCR4:
    213        if (!pxa2xx_timer_has_tm4(s))
    214            goto badreg;
    215
    216        if ((tm == 9 - 4 || tm == 11 - 4) && (s->tm4[tm].control & (1 << 9))) {
    217            if (s->tm4[tm - 1].freq)
    218                s->snapshot = s->tm4[tm - 1].clock + muldiv64(
    219                                qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
    220                                s->tm4[tm - 1].lastload,
    221                                s->tm4[tm - 1].freq, NANOSECONDS_PER_SECOND);
    222            else
    223                s->snapshot = s->tm4[tm - 1].clock;
    224        }
    225
    226        if (!s->tm4[tm].freq)
    227            return s->tm4[tm].clock;
    228        return s->tm4[tm].clock +
    229            muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
    230                     s->tm4[tm].lastload, s->tm4[tm].freq,
    231                     NANOSECONDS_PER_SECOND);
    232    case OIER:
    233        return s->irq_enabled;
    234    case OSSR:	/* Status register */
    235        return s->events;
    236    case OWER:
    237        return s->reset3;
    238    case OMCR11: tm ++;
    239        /* fall through */
    240    case OMCR10: tm ++;
    241        /* fall through */
    242    case OMCR9:  tm ++;
    243        /* fall through */
    244    case OMCR8:  tm ++;
    245        /* fall through */
    246    case OMCR7:  tm ++;
    247        /* fall through */
    248    case OMCR6:  tm ++;
    249        /* fall through */
    250    case OMCR5:  tm ++;
    251        /* fall through */
    252    case OMCR4:
    253        if (!pxa2xx_timer_has_tm4(s))
    254            goto badreg;
    255        return s->tm4[tm].control;
    256    case OSNR:
    257        return s->snapshot;
    258    default:
    259        qemu_log_mask(LOG_UNIMP,
    260                      "%s: unknown register 0x%02" HWADDR_PRIx "\n",
    261                      __func__, offset);
    262        break;
    263    badreg:
    264        qemu_log_mask(LOG_GUEST_ERROR,
    265                      "%s: incorrect register 0x%02" HWADDR_PRIx "\n",
    266                      __func__, offset);
    267    }
    268
    269    return 0;
    270}
    271
    272static void pxa2xx_timer_write(void *opaque, hwaddr offset,
    273                               uint64_t value, unsigned size)
    274{
    275    int i, tm = 0;
    276    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
    277
    278    switch (offset) {
    279    case OSMR3:  tm ++;
    280        /* fall through */
    281    case OSMR2:  tm ++;
    282        /* fall through */
    283    case OSMR1:  tm ++;
    284        /* fall through */
    285    case OSMR0:
    286        s->timer[tm].value = value;
    287        pxa2xx_timer_update(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
    288        break;
    289    case OSMR11: tm ++;
    290        /* fall through */
    291    case OSMR10: tm ++;
    292        /* fall through */
    293    case OSMR9:  tm ++;
    294        /* fall through */
    295    case OSMR8:  tm ++;
    296        /* fall through */
    297    case OSMR7:  tm ++;
    298        /* fall through */
    299    case OSMR6:  tm ++;
    300        /* fall through */
    301    case OSMR5:  tm ++;
    302        /* fall through */
    303    case OSMR4:
    304        if (!pxa2xx_timer_has_tm4(s))
    305            goto badreg;
    306        s->tm4[tm].tm.value = value;
    307        pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm);
    308        break;
    309    case OSCR:
    310        s->oldclock = s->clock;
    311        s->lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    312        s->clock = value;
    313        pxa2xx_timer_update(s, s->lastload);
    314        break;
    315    case OSCR11: tm ++;
    316        /* fall through */
    317    case OSCR10: tm ++;
    318        /* fall through */
    319    case OSCR9:  tm ++;
    320        /* fall through */
    321    case OSCR8:  tm ++;
    322        /* fall through */
    323    case OSCR7:  tm ++;
    324        /* fall through */
    325    case OSCR6:  tm ++;
    326        /* fall through */
    327    case OSCR5:  tm ++;
    328        /* fall through */
    329    case OSCR4:
    330        if (!pxa2xx_timer_has_tm4(s))
    331            goto badreg;
    332        s->tm4[tm].oldclock = s->tm4[tm].clock;
    333        s->tm4[tm].lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    334        s->tm4[tm].clock = value;
    335        pxa2xx_timer_update4(s, s->tm4[tm].lastload, tm);
    336        break;
    337    case OIER:
    338        s->irq_enabled = value & 0xfff;
    339        break;
    340    case OSSR:	/* Status register */
    341        value &= s->events;
    342        s->events &= ~value;
    343        for (i = 0; i < 4; i ++, value >>= 1)
    344            if (value & 1)
    345                qemu_irq_lower(s->timer[i].irq);
    346        if (pxa2xx_timer_has_tm4(s) && !(s->events & 0xff0) && value)
    347            qemu_irq_lower(s->irq4);
    348        break;
    349    case OWER:	/* XXX: Reset on OSMR3 match? */
    350        s->reset3 = value;
    351        break;
    352    case OMCR7:  tm ++;
    353        /* fall through */
    354    case OMCR6:  tm ++;
    355        /* fall through */
    356    case OMCR5:  tm ++;
    357        /* fall through */
    358    case OMCR4:
    359        if (!pxa2xx_timer_has_tm4(s))
    360            goto badreg;
    361        s->tm4[tm].control = value & 0x0ff;
    362        /* XXX Stop if running (shouldn't happen) */
    363        if ((value & (1 << 7)) || tm == 0)
    364            s->tm4[tm].freq = pxa2xx_timer4_freq[value & 7];
    365        else {
    366            s->tm4[tm].freq = 0;
    367            pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm);
    368        }
    369        break;
    370    case OMCR11: tm ++;
    371        /* fall through */
    372    case OMCR10: tm ++;
    373        /* fall through */
    374    case OMCR9:  tm ++;
    375        /* fall through */
    376    case OMCR8:  tm += 4;
    377        if (!pxa2xx_timer_has_tm4(s))
    378            goto badreg;
    379        s->tm4[tm].control = value & 0x3ff;
    380        /* XXX Stop if running (shouldn't happen) */
    381        if ((value & (1 << 7)) || !(tm & 1))
    382            s->tm4[tm].freq =
    383                    pxa2xx_timer4_freq[(value & (1 << 8)) ?  0 : (value & 7)];
    384        else {
    385            s->tm4[tm].freq = 0;
    386            pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm);
    387        }
    388        break;
    389    default:
    390        qemu_log_mask(LOG_UNIMP,
    391                      "%s: unknown register 0x%02" HWADDR_PRIx " "
    392                      "(value 0x%08" PRIx64 ")\n",  __func__, offset, value);
    393        break;
    394    badreg:
    395        qemu_log_mask(LOG_GUEST_ERROR,
    396                      "%s: incorrect register 0x%02" HWADDR_PRIx " "
    397                      "(value 0x%08" PRIx64 ")\n", __func__, offset, value);
    398    }
    399}
    400
    401static const MemoryRegionOps pxa2xx_timer_ops = {
    402    .read = pxa2xx_timer_read,
    403    .write = pxa2xx_timer_write,
    404    .endianness = DEVICE_NATIVE_ENDIAN,
    405};
    406
    407static void pxa2xx_timer_tick(void *opaque)
    408{
    409    PXA2xxTimer0 *t = (PXA2xxTimer0 *) opaque;
    410    PXA2xxTimerInfo *i = t->info;
    411
    412    if (i->irq_enabled & (1 << t->num)) {
    413        i->events |= 1 << t->num;
    414        qemu_irq_raise(t->irq);
    415    }
    416
    417    if (t->num == 3)
    418        if (i->reset3 & 1) {
    419            i->reset3 = 0;
    420            qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
    421        }
    422}
    423
    424static void pxa2xx_timer_tick4(void *opaque)
    425{
    426    PXA2xxTimer4 *t = (PXA2xxTimer4 *) opaque;
    427    PXA2xxTimerInfo *i = (PXA2xxTimerInfo *) t->tm.info;
    428
    429    pxa2xx_timer_tick(&t->tm);
    430    if (t->control & (1 << 3))
    431        t->clock = 0;
    432    if (t->control & (1 << 6))
    433        pxa2xx_timer_update4(i, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), t->tm.num - 4);
    434    if (i->events & 0xff0)
    435        qemu_irq_raise(i->irq4);
    436}
    437
    438static int pxa25x_timer_post_load(void *opaque, int version_id)
    439{
    440    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
    441    int64_t now;
    442    int i;
    443
    444    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    445    pxa2xx_timer_update(s, now);
    446
    447    if (pxa2xx_timer_has_tm4(s))
    448        for (i = 0; i < 8; i ++)
    449            pxa2xx_timer_update4(s, now, i);
    450
    451    return 0;
    452}
    453
    454static void pxa2xx_timer_init(Object *obj)
    455{
    456    PXA2xxTimerInfo *s = PXA2XX_TIMER(obj);
    457    SysBusDevice *dev = SYS_BUS_DEVICE(obj);
    458
    459    s->irq_enabled = 0;
    460    s->oldclock = 0;
    461    s->clock = 0;
    462    s->lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    463    s->reset3 = 0;
    464
    465    memory_region_init_io(&s->iomem, obj, &pxa2xx_timer_ops, s,
    466                          "pxa2xx-timer", 0x00001000);
    467    sysbus_init_mmio(dev, &s->iomem);
    468}
    469
    470static void pxa2xx_timer_realize(DeviceState *dev, Error **errp)
    471{
    472    PXA2xxTimerInfo *s = PXA2XX_TIMER(dev);
    473    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    474    int i;
    475
    476    for (i = 0; i < 4; i ++) {
    477        s->timer[i].value = 0;
    478        sysbus_init_irq(sbd, &s->timer[i].irq);
    479        s->timer[i].info = s;
    480        s->timer[i].num = i;
    481        s->timer[i].qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
    482                                          pxa2xx_timer_tick, &s->timer[i]);
    483    }
    484
    485    if (s->flags & (1 << PXA2XX_TIMER_HAVE_TM4)) {
    486        sysbus_init_irq(sbd, &s->irq4);
    487
    488        for (i = 0; i < 8; i ++) {
    489            s->tm4[i].tm.value = 0;
    490            s->tm4[i].tm.info = s;
    491            s->tm4[i].tm.num = i + 4;
    492            s->tm4[i].freq = 0;
    493            s->tm4[i].control = 0x0;
    494            s->tm4[i].tm.qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
    495                                               pxa2xx_timer_tick4, &s->tm4[i]);
    496        }
    497    }
    498}
    499
    500static const VMStateDescription vmstate_pxa2xx_timer0_regs = {
    501    .name = "pxa2xx_timer0",
    502    .version_id = 2,
    503    .minimum_version_id = 2,
    504    .fields = (VMStateField[]) {
    505        VMSTATE_UINT32(value, PXA2xxTimer0),
    506        VMSTATE_END_OF_LIST(),
    507    },
    508};
    509
    510static const VMStateDescription vmstate_pxa2xx_timer4_regs = {
    511    .name = "pxa2xx_timer4",
    512    .version_id = 1,
    513    .minimum_version_id = 1,
    514    .fields = (VMStateField[]) {
    515        VMSTATE_STRUCT(tm, PXA2xxTimer4, 1,
    516                        vmstate_pxa2xx_timer0_regs, PXA2xxTimer0),
    517        VMSTATE_INT32(oldclock, PXA2xxTimer4),
    518        VMSTATE_INT32(clock, PXA2xxTimer4),
    519        VMSTATE_UINT64(lastload, PXA2xxTimer4),
    520        VMSTATE_UINT32(freq, PXA2xxTimer4),
    521        VMSTATE_UINT32(control, PXA2xxTimer4),
    522        VMSTATE_END_OF_LIST(),
    523    },
    524};
    525
    526static bool pxa2xx_timer_has_tm4_test(void *opaque, int version_id)
    527{
    528    return pxa2xx_timer_has_tm4(opaque);
    529}
    530
    531static const VMStateDescription vmstate_pxa2xx_timer_regs = {
    532    .name = "pxa2xx_timer",
    533    .version_id = 1,
    534    .minimum_version_id = 1,
    535    .post_load = pxa25x_timer_post_load,
    536    .fields = (VMStateField[]) {
    537        VMSTATE_INT32(clock, PXA2xxTimerInfo),
    538        VMSTATE_INT32(oldclock, PXA2xxTimerInfo),
    539        VMSTATE_UINT64(lastload, PXA2xxTimerInfo),
    540        VMSTATE_STRUCT_ARRAY(timer, PXA2xxTimerInfo, 4, 1,
    541                        vmstate_pxa2xx_timer0_regs, PXA2xxTimer0),
    542        VMSTATE_UINT32(events, PXA2xxTimerInfo),
    543        VMSTATE_UINT32(irq_enabled, PXA2xxTimerInfo),
    544        VMSTATE_UINT32(reset3, PXA2xxTimerInfo),
    545        VMSTATE_UINT32(snapshot, PXA2xxTimerInfo),
    546        VMSTATE_STRUCT_ARRAY_TEST(tm4, PXA2xxTimerInfo, 8,
    547                        pxa2xx_timer_has_tm4_test, 0,
    548                        vmstate_pxa2xx_timer4_regs, PXA2xxTimer4),
    549        VMSTATE_END_OF_LIST(),
    550    }
    551};
    552
    553static Property pxa25x_timer_dev_properties[] = {
    554    DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA25X_FREQ),
    555    DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
    556                    PXA2XX_TIMER_HAVE_TM4, false),
    557    DEFINE_PROP_END_OF_LIST(),
    558};
    559
    560static void pxa25x_timer_dev_class_init(ObjectClass *klass, void *data)
    561{
    562    DeviceClass *dc = DEVICE_CLASS(klass);
    563
    564    dc->desc = "PXA25x timer";
    565    device_class_set_props(dc, pxa25x_timer_dev_properties);
    566}
    567
    568static const TypeInfo pxa25x_timer_dev_info = {
    569    .name          = "pxa25x-timer",
    570    .parent        = TYPE_PXA2XX_TIMER,
    571    .instance_size = sizeof(PXA2xxTimerInfo),
    572    .class_init    = pxa25x_timer_dev_class_init,
    573};
    574
    575static Property pxa27x_timer_dev_properties[] = {
    576    DEFINE_PROP_UINT32("freq", PXA2xxTimerInfo, freq, PXA27X_FREQ),
    577    DEFINE_PROP_BIT("tm4", PXA2xxTimerInfo, flags,
    578                    PXA2XX_TIMER_HAVE_TM4, true),
    579    DEFINE_PROP_END_OF_LIST(),
    580};
    581
    582static void pxa27x_timer_dev_class_init(ObjectClass *klass, void *data)
    583{
    584    DeviceClass *dc = DEVICE_CLASS(klass);
    585
    586    dc->desc = "PXA27x timer";
    587    device_class_set_props(dc, pxa27x_timer_dev_properties);
    588}
    589
    590static const TypeInfo pxa27x_timer_dev_info = {
    591    .name          = "pxa27x-timer",
    592    .parent        = TYPE_PXA2XX_TIMER,
    593    .instance_size = sizeof(PXA2xxTimerInfo),
    594    .class_init    = pxa27x_timer_dev_class_init,
    595};
    596
    597static void pxa2xx_timer_class_init(ObjectClass *oc, void *data)
    598{
    599    DeviceClass *dc = DEVICE_CLASS(oc);
    600
    601    dc->realize  = pxa2xx_timer_realize;
    602    dc->vmsd = &vmstate_pxa2xx_timer_regs;
    603}
    604
    605static const TypeInfo pxa2xx_timer_type_info = {
    606    .name          = TYPE_PXA2XX_TIMER,
    607    .parent        = TYPE_SYS_BUS_DEVICE,
    608    .instance_size = sizeof(PXA2xxTimerInfo),
    609    .instance_init = pxa2xx_timer_init,
    610    .abstract      = true,
    611    .class_init    = pxa2xx_timer_class_init,
    612};
    613
    614static void pxa2xx_timer_register_types(void)
    615{
    616    type_register_static(&pxa2xx_timer_type_info);
    617    type_register_static(&pxa25x_timer_dev_info);
    618    type_register_static(&pxa27x_timer_dev_info);
    619}
    620
    621type_init(pxa2xx_timer_register_types)