qemu

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

avr_timer16.c (18079B)


      1 /*
      2  * AVR 16-bit timer
      3  *
      4  * Copyright (c) 2018 University of Kent
      5  * Author: Ed Robbins
      6  *
      7  * This library is free software; you can redistribute it and/or
      8  * modify it under the terms of the GNU Lesser General Public
      9  * License as published by the Free Software Foundation; either
     10  * version 2.1 of the License, or (at your option) any later version.
     11  *
     12  * This library is distributed in the hope that it will be useful,
     13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  * Lesser General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU Lesser General Public
     18  * License along with this library; if not, see
     19  * <http://www.gnu.org/licenses/lgpl-2.1.html>
     20  */
     21 
     22 /*
     23  * Driver for 16 bit timers on 8 bit AVR devices.
     24  * Note:
     25  * ATmega640/V-1280/V-1281/V-2560/V-2561/V timers 1, 3, 4 and 5 are 16 bit
     26  */
     27 
     28 /*
     29  * XXX TODO: Power Reduction Register support
     30  *           prescaler pause support
     31  *           PWM modes, GPIO, output capture pins, input compare pin
     32  */
     33 
     34 #include "qemu/osdep.h"
     35 #include "qapi/error.h"
     36 #include "qemu/log.h"
     37 #include "hw/irq.h"
     38 #include "hw/qdev-properties.h"
     39 #include "hw/timer/avr_timer16.h"
     40 #include "trace.h"
     41 
     42 /* Register offsets */
     43 #define T16_CRA     0x0
     44 #define T16_CRB     0x1
     45 #define T16_CRC     0x2
     46 #define T16_CNTL    0x4
     47 #define T16_CNTH    0x5
     48 #define T16_ICRL    0x6
     49 #define T16_ICRH    0x7
     50 #define T16_OCRAL   0x8
     51 #define T16_OCRAH   0x9
     52 #define T16_OCRBL   0xa
     53 #define T16_OCRBH   0xb
     54 #define T16_OCRCL   0xc
     55 #define T16_OCRCH   0xd
     56 
     57 /* Field masks */
     58 #define T16_CRA_WGM01   0x3
     59 #define T16_CRA_COMC    0xc
     60 #define T16_CRA_COMB    0x30
     61 #define T16_CRA_COMA    0xc0
     62 #define T16_CRA_OC_CONF \
     63     (T16_CRA_COMA | T16_CRA_COMB | T16_CRA_COMC)
     64 
     65 #define T16_CRB_CS      0x7
     66 #define T16_CRB_WGM23   0x18
     67 #define T16_CRB_ICES    0x40
     68 #define T16_CRB_ICNC    0x80
     69 
     70 #define T16_CRC_FOCC    0x20
     71 #define T16_CRC_FOCB    0x40
     72 #define T16_CRC_FOCA    0x80
     73 
     74 /* Fields masks both TIMSK and TIFR (interrupt mask/flag registers) */
     75 #define T16_INT_TOV    0x1 /* Timer overflow */
     76 #define T16_INT_OCA    0x2 /* Output compare A */
     77 #define T16_INT_OCB    0x4 /* Output compare B */
     78 #define T16_INT_OCC    0x8 /* Output compare C */
     79 #define T16_INT_IC     0x20 /* Input capture */
     80 
     81 /* Clock source values */
     82 #define T16_CLKSRC_STOPPED     0
     83 #define T16_CLKSRC_DIV1        1
     84 #define T16_CLKSRC_DIV8        2
     85 #define T16_CLKSRC_DIV64       3
     86 #define T16_CLKSRC_DIV256      4
     87 #define T16_CLKSRC_DIV1024     5
     88 #define T16_CLKSRC_EXT_FALLING 6
     89 #define T16_CLKSRC_EXT_RISING  7
     90 
     91 /* Timer mode values (not including PWM modes) */
     92 #define T16_MODE_NORMAL     0
     93 #define T16_MODE_CTC_OCRA   4
     94 #define T16_MODE_CTC_ICR    12
     95 
     96 /* Accessors */
     97 #define CLKSRC(t16) (t16->crb & T16_CRB_CS)
     98 #define MODE(t16)   (((t16->crb & T16_CRB_WGM23) >> 1) | \
     99                      (t16->cra & T16_CRA_WGM01))
    100 #define CNT(t16)    VAL16(t16->cntl, t16->cnth)
    101 #define OCRA(t16)   VAL16(t16->ocral, t16->ocrah)
    102 #define OCRB(t16)   VAL16(t16->ocrbl, t16->ocrbh)
    103 #define OCRC(t16)   VAL16(t16->ocrcl, t16->ocrch)
    104 #define ICR(t16)    VAL16(t16->icrl, t16->icrh)
    105 
    106 /* Helper macros */
    107 #define VAL16(l, h) ((h << 8) | l)
    108 #define DB_PRINT(fmt, args...) /* Nothing */
    109 
    110 static inline int64_t avr_timer16_ns_to_ticks(AVRTimer16State *t16, int64_t t)
    111 {
    112     if (t16->period_ns == 0) {
    113         return 0;
    114     }
    115     return t / t16->period_ns;
    116 }
    117 
    118 static void avr_timer16_update_cnt(AVRTimer16State *t16)
    119 {
    120     uint16_t cnt;
    121     cnt = avr_timer16_ns_to_ticks(t16, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
    122                                        t16->reset_time_ns);
    123     t16->cntl = (uint8_t)(cnt & 0xff);
    124     t16->cnth = (uint8_t)((cnt & 0xff00) >> 8);
    125 }
    126 
    127 static inline void avr_timer16_recalc_reset_time(AVRTimer16State *t16)
    128 {
    129     t16->reset_time_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
    130                          CNT(t16) * t16->period_ns;
    131 }
    132 
    133 static void avr_timer16_clock_reset(AVRTimer16State *t16)
    134 {
    135     t16->cntl = 0;
    136     t16->cnth = 0;
    137     t16->reset_time_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    138 }
    139 
    140 static void avr_timer16_clksrc_update(AVRTimer16State *t16)
    141 {
    142     uint16_t divider = 0;
    143     switch (CLKSRC(t16)) {
    144     case T16_CLKSRC_EXT_FALLING:
    145     case T16_CLKSRC_EXT_RISING:
    146         qemu_log_mask(LOG_UNIMP, "%s: external clock source unsupported\n",
    147                       __func__);
    148         break;
    149     case T16_CLKSRC_STOPPED:
    150         break;
    151     case T16_CLKSRC_DIV1:
    152         divider = 1;
    153         break;
    154     case T16_CLKSRC_DIV8:
    155         divider = 8;
    156         break;
    157     case T16_CLKSRC_DIV64:
    158         divider = 64;
    159         break;
    160     case T16_CLKSRC_DIV256:
    161         divider = 256;
    162         break;
    163     case T16_CLKSRC_DIV1024:
    164         divider = 1024;
    165         break;
    166     default:
    167         break;
    168     }
    169     if (divider) {
    170         t16->freq_hz = t16->cpu_freq_hz / divider;
    171         t16->period_ns = NANOSECONDS_PER_SECOND / t16->freq_hz;
    172         trace_avr_timer16_clksrc_update(t16->freq_hz, t16->period_ns,
    173                                         (uint64_t)(1e6 / t16->freq_hz));
    174     }
    175 }
    176 
    177 static void avr_timer16_set_alarm(AVRTimer16State *t16)
    178 {
    179     if (CLKSRC(t16) == T16_CLKSRC_EXT_FALLING ||
    180         CLKSRC(t16) == T16_CLKSRC_EXT_RISING ||
    181         CLKSRC(t16) == T16_CLKSRC_STOPPED) {
    182         /* Timer is disabled or set to external clock source (unsupported) */
    183         return;
    184     }
    185 
    186     uint64_t alarm_offset = 0xffff;
    187     enum NextInterrupt next_interrupt = OVERFLOW;
    188 
    189     switch (MODE(t16)) {
    190     case T16_MODE_NORMAL:
    191         /* Normal mode */
    192         if (OCRA(t16) < alarm_offset && OCRA(t16) > CNT(t16) &&
    193             (t16->imsk & T16_INT_OCA)) {
    194             alarm_offset = OCRA(t16);
    195             next_interrupt = COMPA;
    196         }
    197         break;
    198     case T16_MODE_CTC_OCRA:
    199         /* CTC mode, top = ocra */
    200         if (OCRA(t16) < alarm_offset && OCRA(t16) > CNT(t16)) {
    201             alarm_offset = OCRA(t16);
    202             next_interrupt = COMPA;
    203         }
    204        break;
    205     case T16_MODE_CTC_ICR:
    206         /* CTC mode, top = icr */
    207         if (ICR(t16) < alarm_offset && ICR(t16) > CNT(t16)) {
    208             alarm_offset = ICR(t16);
    209             next_interrupt = CAPT;
    210         }
    211         if (OCRA(t16) < alarm_offset && OCRA(t16) > CNT(t16) &&
    212             (t16->imsk & T16_INT_OCA)) {
    213             alarm_offset = OCRA(t16);
    214             next_interrupt = COMPA;
    215         }
    216         break;
    217     default:
    218         qemu_log_mask(LOG_UNIMP, "%s: pwm modes are unsupported\n",
    219                       __func__);
    220         return;
    221     }
    222     if (OCRB(t16) < alarm_offset && OCRB(t16) > CNT(t16) &&
    223         (t16->imsk & T16_INT_OCB)) {
    224         alarm_offset = OCRB(t16);
    225         next_interrupt = COMPB;
    226     }
    227     if (OCRC(t16) < alarm_offset && OCRB(t16) > CNT(t16) &&
    228         (t16->imsk & T16_INT_OCC)) {
    229         alarm_offset = OCRB(t16);
    230         next_interrupt = COMPC;
    231     }
    232     alarm_offset -= CNT(t16);
    233 
    234     t16->next_interrupt = next_interrupt;
    235     uint64_t alarm_ns =
    236         t16->reset_time_ns + ((CNT(t16) + alarm_offset) * t16->period_ns);
    237     timer_mod(t16->timer, alarm_ns);
    238 
    239     trace_avr_timer16_next_alarm(alarm_offset * t16->period_ns);
    240 }
    241 
    242 static void avr_timer16_interrupt(void *opaque)
    243 {
    244     AVRTimer16State *t16 = opaque;
    245     uint8_t mode = MODE(t16);
    246 
    247     avr_timer16_update_cnt(t16);
    248 
    249     if (CLKSRC(t16) == T16_CLKSRC_EXT_FALLING ||
    250         CLKSRC(t16) == T16_CLKSRC_EXT_RISING ||
    251         CLKSRC(t16) == T16_CLKSRC_STOPPED) {
    252         /* Timer is disabled or set to external clock source (unsupported) */
    253         return;
    254     }
    255 
    256     trace_avr_timer16_interrupt_count(CNT(t16));
    257 
    258     /* Counter overflow */
    259     if (t16->next_interrupt == OVERFLOW) {
    260         trace_avr_timer16_interrupt_overflow("counter 0xffff");
    261         avr_timer16_clock_reset(t16);
    262         if (t16->imsk & T16_INT_TOV) {
    263             t16->ifr |= T16_INT_TOV;
    264             qemu_set_irq(t16->ovf_irq, 1);
    265         }
    266     }
    267     /* Check for ocra overflow in CTC mode */
    268     if (mode == T16_MODE_CTC_OCRA && t16->next_interrupt == COMPA) {
    269         trace_avr_timer16_interrupt_overflow("CTC OCRA");
    270         avr_timer16_clock_reset(t16);
    271     }
    272     /* Check for icr overflow in CTC mode */
    273     if (mode == T16_MODE_CTC_ICR && t16->next_interrupt == CAPT) {
    274         trace_avr_timer16_interrupt_overflow("CTC ICR");
    275         avr_timer16_clock_reset(t16);
    276         if (t16->imsk & T16_INT_IC) {
    277             t16->ifr |= T16_INT_IC;
    278             qemu_set_irq(t16->capt_irq, 1);
    279         }
    280     }
    281     /* Check for output compare interrupts */
    282     if (t16->imsk & T16_INT_OCA && t16->next_interrupt == COMPA) {
    283         t16->ifr |= T16_INT_OCA;
    284         qemu_set_irq(t16->compa_irq, 1);
    285     }
    286     if (t16->imsk & T16_INT_OCB && t16->next_interrupt == COMPB) {
    287         t16->ifr |= T16_INT_OCB;
    288         qemu_set_irq(t16->compb_irq, 1);
    289     }
    290     if (t16->imsk & T16_INT_OCC && t16->next_interrupt == COMPC) {
    291         t16->ifr |= T16_INT_OCC;
    292         qemu_set_irq(t16->compc_irq, 1);
    293     }
    294     avr_timer16_set_alarm(t16);
    295 }
    296 
    297 static void avr_timer16_reset(DeviceState *dev)
    298 {
    299     AVRTimer16State *t16 = AVR_TIMER16(dev);
    300 
    301     avr_timer16_clock_reset(t16);
    302     avr_timer16_clksrc_update(t16);
    303     avr_timer16_set_alarm(t16);
    304 
    305     qemu_set_irq(t16->capt_irq, 0);
    306     qemu_set_irq(t16->compa_irq, 0);
    307     qemu_set_irq(t16->compb_irq, 0);
    308     qemu_set_irq(t16->compc_irq, 0);
    309     qemu_set_irq(t16->ovf_irq, 0);
    310 }
    311 
    312 static uint64_t avr_timer16_read(void *opaque, hwaddr offset, unsigned size)
    313 {
    314     assert(size == 1);
    315     AVRTimer16State *t16 = opaque;
    316     uint8_t retval = 0;
    317 
    318     switch (offset) {
    319     case T16_CRA:
    320         retval = t16->cra;
    321         break;
    322     case T16_CRB:
    323         retval = t16->crb;
    324         break;
    325     case T16_CRC:
    326         retval = t16->crc;
    327         break;
    328     case T16_CNTL:
    329         avr_timer16_update_cnt(t16);
    330         t16->rtmp = t16->cnth;
    331         retval = t16->cntl;
    332         break;
    333     case T16_CNTH:
    334         retval = t16->rtmp;
    335         break;
    336     case T16_ICRL:
    337         /*
    338          * The timer copies cnt to icr when the input capture pin changes
    339          * state or when the analog comparator has a match. We don't
    340          * emulate this behaviour. We do support it's use for defining a
    341          * TOP value in T16_MODE_CTC_ICR
    342          */
    343         t16->rtmp = t16->icrh;
    344         retval = t16->icrl;
    345         break;
    346     case T16_ICRH:
    347         retval = t16->rtmp;
    348         break;
    349     case T16_OCRAL:
    350         retval = t16->ocral;
    351         break;
    352     case T16_OCRAH:
    353         retval = t16->ocrah;
    354         break;
    355     case T16_OCRBL:
    356         retval = t16->ocrbl;
    357         break;
    358     case T16_OCRBH:
    359         retval = t16->ocrbh;
    360         break;
    361     case T16_OCRCL:
    362         retval = t16->ocrcl;
    363         break;
    364     case T16_OCRCH:
    365         retval = t16->ocrch;
    366         break;
    367     default:
    368         break;
    369     }
    370     trace_avr_timer16_read(offset, retval);
    371 
    372     return (uint64_t)retval;
    373 }
    374 
    375 static void avr_timer16_write(void *opaque, hwaddr offset,
    376                               uint64_t val64, unsigned size)
    377 {
    378     assert(size == 1);
    379     AVRTimer16State *t16 = opaque;
    380     uint8_t val8 = (uint8_t)val64;
    381     uint8_t prev_clk_src = CLKSRC(t16);
    382 
    383     trace_avr_timer16_write(offset, val8);
    384 
    385     switch (offset) {
    386     case T16_CRA:
    387         t16->cra = val8;
    388         if (t16->cra & T16_CRA_OC_CONF) {
    389             qemu_log_mask(LOG_UNIMP, "%s: output compare pins unsupported\n",
    390                           __func__);
    391         }
    392         break;
    393     case T16_CRB:
    394         t16->crb = val8;
    395         if (t16->crb & T16_CRB_ICNC) {
    396             qemu_log_mask(LOG_UNIMP,
    397                           "%s: input capture noise canceller unsupported\n",
    398                           __func__);
    399         }
    400         if (t16->crb & T16_CRB_ICES) {
    401             qemu_log_mask(LOG_UNIMP, "%s: input capture unsupported\n",
    402                           __func__);
    403         }
    404         if (CLKSRC(t16) != prev_clk_src) {
    405             avr_timer16_clksrc_update(t16);
    406             if (prev_clk_src == T16_CLKSRC_STOPPED) {
    407                 t16->reset_time_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
    408             }
    409         }
    410         break;
    411     case T16_CRC:
    412         t16->crc = val8;
    413         qemu_log_mask(LOG_UNIMP, "%s: output compare pins unsupported\n",
    414                       __func__);
    415         break;
    416     case T16_CNTL:
    417         /*
    418          * CNT is the 16-bit counter value, it must be read/written via
    419          * a temporary register (rtmp) to make the read/write atomic.
    420          */
    421         /* ICR also has this behaviour, and shares rtmp */
    422         /*
    423          * Writing CNT blocks compare matches for one clock cycle.
    424          * Writing CNT to TOP or to an OCR value (if in use) will
    425          * skip the relevant interrupt
    426          */
    427         t16->cntl = val8;
    428         t16->cnth = t16->rtmp;
    429         avr_timer16_recalc_reset_time(t16);
    430         break;
    431     case T16_CNTH:
    432         t16->rtmp = val8;
    433         break;
    434     case T16_ICRL:
    435         /* ICR can only be written in mode T16_MODE_CTC_ICR */
    436         if (MODE(t16) == T16_MODE_CTC_ICR) {
    437             t16->icrl = val8;
    438             t16->icrh = t16->rtmp;
    439         }
    440         break;
    441     case T16_ICRH:
    442         if (MODE(t16) == T16_MODE_CTC_ICR) {
    443             t16->rtmp = val8;
    444         }
    445         break;
    446     case T16_OCRAL:
    447         /*
    448          * OCRn cause the relevant output compare flag to be raised, and
    449          * trigger an interrupt, when CNT is equal to the value here
    450          */
    451         t16->ocral = val8;
    452         break;
    453     case T16_OCRAH:
    454         t16->ocrah = val8;
    455         break;
    456     case T16_OCRBL:
    457         t16->ocrbl = val8;
    458         break;
    459     case T16_OCRBH:
    460         t16->ocrbh = val8;
    461         break;
    462     case T16_OCRCL:
    463         t16->ocrcl = val8;
    464         break;
    465     case T16_OCRCH:
    466         t16->ocrch = val8;
    467         break;
    468     default:
    469         break;
    470     }
    471     avr_timer16_set_alarm(t16);
    472 }
    473 
    474 static uint64_t avr_timer16_imsk_read(void *opaque,
    475                                       hwaddr offset,
    476                                       unsigned size)
    477 {
    478     assert(size == 1);
    479     AVRTimer16State *t16 = opaque;
    480     trace_avr_timer16_read_imsk(offset ? 0 : t16->imsk);
    481     if (offset != 0) {
    482         return 0;
    483     }
    484     return t16->imsk;
    485 }
    486 
    487 static void avr_timer16_imsk_write(void *opaque, hwaddr offset,
    488                                    uint64_t val64, unsigned size)
    489 {
    490     assert(size == 1);
    491     AVRTimer16State *t16 = opaque;
    492     trace_avr_timer16_write_imsk(val64);
    493     if (offset != 0) {
    494         return;
    495     }
    496     t16->imsk = (uint8_t)val64;
    497 }
    498 
    499 static uint64_t avr_timer16_ifr_read(void *opaque,
    500                                      hwaddr offset,
    501                                      unsigned size)
    502 {
    503     assert(size == 1);
    504     AVRTimer16State *t16 = opaque;
    505     trace_avr_timer16_read_ifr(offset ? 0 : t16->ifr);
    506     if (offset != 0) {
    507         return 0;
    508     }
    509     return t16->ifr;
    510 }
    511 
    512 static void avr_timer16_ifr_write(void *opaque, hwaddr offset,
    513                                   uint64_t val64, unsigned size)
    514 {
    515     assert(size == 1);
    516     AVRTimer16State *t16 = opaque;
    517     trace_avr_timer16_write_imsk(val64);
    518     if (offset != 0) {
    519         return;
    520     }
    521     t16->ifr = (uint8_t)val64;
    522 }
    523 
    524 static const MemoryRegionOps avr_timer16_ops = {
    525     .read = avr_timer16_read,
    526     .write = avr_timer16_write,
    527     .endianness = DEVICE_NATIVE_ENDIAN,
    528     .impl = {.max_access_size = 1}
    529 };
    530 
    531 static const MemoryRegionOps avr_timer16_imsk_ops = {
    532     .read = avr_timer16_imsk_read,
    533     .write = avr_timer16_imsk_write,
    534     .endianness = DEVICE_NATIVE_ENDIAN,
    535     .impl = {.max_access_size = 1}
    536 };
    537 
    538 static const MemoryRegionOps avr_timer16_ifr_ops = {
    539     .read = avr_timer16_ifr_read,
    540     .write = avr_timer16_ifr_write,
    541     .endianness = DEVICE_NATIVE_ENDIAN,
    542     .impl = {.max_access_size = 1}
    543 };
    544 
    545 static Property avr_timer16_properties[] = {
    546     DEFINE_PROP_UINT8("id", struct AVRTimer16State, id, 0),
    547     DEFINE_PROP_UINT64("cpu-frequency-hz", struct AVRTimer16State,
    548                        cpu_freq_hz, 0),
    549     DEFINE_PROP_END_OF_LIST(),
    550 };
    551 
    552 static void avr_timer16_pr(void *opaque, int irq, int level)
    553 {
    554     AVRTimer16State *s = AVR_TIMER16(opaque);
    555 
    556     s->enabled = !level;
    557 
    558     if (!s->enabled) {
    559         avr_timer16_reset(DEVICE(s));
    560     }
    561 }
    562 
    563 static void avr_timer16_init(Object *obj)
    564 {
    565     AVRTimer16State *s = AVR_TIMER16(obj);
    566 
    567     sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->capt_irq);
    568     sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->compa_irq);
    569     sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->compb_irq);
    570     sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->compc_irq);
    571     sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->ovf_irq);
    572 
    573     memory_region_init_io(&s->iomem, obj, &avr_timer16_ops,
    574                           s, "avr-timer16", 0xe);
    575     memory_region_init_io(&s->imsk_iomem, obj, &avr_timer16_imsk_ops,
    576                           s, "avr-timer16-intmask", 0x1);
    577     memory_region_init_io(&s->ifr_iomem, obj, &avr_timer16_ifr_ops,
    578                           s, "avr-timer16-intflag", 0x1);
    579 
    580     sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
    581     sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->imsk_iomem);
    582     sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->ifr_iomem);
    583     qdev_init_gpio_in(DEVICE(s), avr_timer16_pr, 1);
    584 }
    585 
    586 static void avr_timer16_realize(DeviceState *dev, Error **errp)
    587 {
    588     AVRTimer16State *s = AVR_TIMER16(dev);
    589 
    590     if (s->cpu_freq_hz == 0) {
    591         error_setg(errp, "AVR timer16: cpu-frequency-hz property must be set");
    592         return;
    593     }
    594 
    595     s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, avr_timer16_interrupt, s);
    596     s->enabled = true;
    597 }
    598 
    599 static void avr_timer16_class_init(ObjectClass *klass, void *data)
    600 {
    601     DeviceClass *dc = DEVICE_CLASS(klass);
    602 
    603     dc->reset = avr_timer16_reset;
    604     dc->realize = avr_timer16_realize;
    605     device_class_set_props(dc, avr_timer16_properties);
    606 }
    607 
    608 static const TypeInfo avr_timer16_info = {
    609     .name          = TYPE_AVR_TIMER16,
    610     .parent        = TYPE_SYS_BUS_DEVICE,
    611     .instance_size = sizeof(AVRTimer16State),
    612     .instance_init = avr_timer16_init,
    613     .class_init    = avr_timer16_class_init,
    614 };
    615 
    616 static void avr_timer16_register_types(void)
    617 {
    618     type_register_static(&avr_timer16_info);
    619 }
    620 
    621 type_init(avr_timer16_register_types)