qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

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 
     59 static 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"
     70 OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxTimerInfo, PXA2XX_TIMER)
     71 
     72 
     73 typedef struct {
     74     uint32_t value;
     75     qemu_irq irq;
     76     QEMUTimer *qtimer;
     77     int num;
     78     PXA2xxTimerInfo *info;
     79 } PXA2xxTimer0;
     80 
     81 typedef 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 
     90 struct 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 
    112 static inline int pxa2xx_timer_has_tm4(PXA2xxTimerInfo *s)
    113 {
    114     return s->flags & (1 << PXA2XX_TIMER_HAVE_TM4);
    115 }
    116 
    117 static 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 
    134 static 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 
    162 static 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 
    272 static 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 
    401 static const MemoryRegionOps pxa2xx_timer_ops = {
    402     .read = pxa2xx_timer_read,
    403     .write = pxa2xx_timer_write,
    404     .endianness = DEVICE_NATIVE_ENDIAN,
    405 };
    406 
    407 static 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 
    424 static 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 
    438 static 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 
    454 static 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 
    470 static 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 
    500 static 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 
    510 static 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 
    526 static bool pxa2xx_timer_has_tm4_test(void *opaque, int version_id)
    527 {
    528     return pxa2xx_timer_has_tm4(opaque);
    529 }
    530 
    531 static 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 
    553 static 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 
    560 static 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 
    568 static 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 
    575 static 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 
    582 static 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 
    590 static 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 
    597 static 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 
    605 static 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 
    614 static 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 
    621 type_init(pxa2xx_timer_register_types)