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

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
    110static 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
    118static 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
    127static 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
    133static 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
    140static 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
    177static 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
    242static 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
    297static 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
    312static 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
    375static 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
    474static 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
    487static 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
    499static 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
    512static 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
    524static 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
    531static 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
    538static 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
    545static 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
    552static 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
    563static 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
    586static 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
    599static 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
    608static 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
    616static void avr_timer16_register_types(void)
    617{
    618    type_register_static(&avr_timer16_info);
    619}
    620
    621type_init(avr_timer16_register_types)