Пример #1
0
static int xilinx_timer_init(SysBusDevice *dev)
{
    struct timerblock *t = FROM_SYSBUS(typeof (*t), dev);
    unsigned int i;

    /* All timers share a single irq line.  */
    sysbus_init_irq(dev, &t->irq);

    /* Init all the ptimers.  */
    t->timers = g_malloc0(sizeof t->timers[0] * num_timers(t));
    for (i = 0; i < num_timers(t); i++) {
        struct xlx_timer *xt = &t->timers[i];

        xt->parent = t;
        xt->nr = i;
        xt->bh = qemu_bh_new(timer_hit, xt);
        xt->ptimer = ptimer_init(xt->bh);
        ptimer_set_freq(xt->ptimer, t->freq_hz);
    }

    memory_region_init_io(&t->mmio, &timer_ops, t, "xlnx.xps-timer",
                          R_MAX * 4 * num_timers(t));
    sysbus_init_mmio(dev, &t->mmio);
    return 0;
}
Пример #2
0
static void grlib_gptimer_reset(DeviceState *d)
{
    GPTimerUnit *unit = container_of(d, GPTimerUnit, busdev.qdev);
    int          i    = 0;

    assert(unit != NULL);

    unit->scaler = 0;
    unit->reload = 0;
    unit->config = 0;

    unit->config  = unit->nr_timers;
    unit->config |= unit->irq_line << 3;
    unit->config |= 1 << 8;     /* separate interrupt */
    unit->config |= 1 << 9;     /* Disable timer freeze */


    for (i = 0; i < unit->nr_timers; i++) {
        GPTimer *timer = &unit->timers[i];

        timer->counter = 0;
        timer->reload = 0;
        timer->config = 0;
        ptimer_stop(timer->ptimer);
        ptimer_set_count(timer->ptimer, 0);
        ptimer_set_freq(timer->ptimer, unit->freq_hz);
    }
}
Пример #3
0
static int grlib_gptimer_init(SysBusDevice *dev)
{
    GPTimerUnit  *unit = FROM_SYSBUS(typeof(*unit), dev);
    unsigned int  i;

    assert(unit->nr_timers > 0);
    assert(unit->nr_timers <= GPTIMER_MAX_TIMERS);

    unit->timers = g_malloc0(sizeof unit->timers[0] * unit->nr_timers);

    for (i = 0; i < unit->nr_timers; i++) {
        GPTimer *timer = &unit->timers[i];

        timer->unit   = unit;
        timer->bh     = qemu_bh_new(grlib_gptimer_hit, timer);
        timer->ptimer = ptimer_init(timer->bh);
        timer->id     = i;

        /* One IRQ line for each timer */
        sysbus_init_irq(dev, &timer->irq);

        ptimer_set_freq(timer->ptimer, unit->freq_hz);
    }

    memory_region_init_io(&unit->iomem, &grlib_gptimer_ops, unit, "gptimer",
                          UNIT_REG_SIZE + GPTIMER_REG_SIZE * unit->nr_timers);

    sysbus_init_mmio(dev, &unit->iomem);
    return 0;
}
Пример #4
0
static inline void timer_watchdog_update(struct etrax_timer *t, uint32_t value)
{
    unsigned int wd_en = t->rw_wd_ctrl & (1 << 8);
    unsigned int wd_key = t->rw_wd_ctrl >> 9;
    unsigned int wd_cnt = t->rw_wd_ctrl & 511;
    unsigned int new_key = value >> 9 & ((1 << 7) - 1);
    unsigned int new_cmd = (value >> 8) & 1;

    /* If the watchdog is enabled, they written key must match the
       complement of the previous.  */
    wd_key = ~wd_key & ((1 << 7) - 1);

    if (wd_en && wd_key != new_key)
        return;

    D(printf("en=%d new_key=%x oldkey=%x cmd=%d cnt=%d\n", 
         wd_en, new_key, wd_key, new_cmd, wd_cnt));

    if (t->wd_hits)
        qemu_irq_lower(t->nmi);

    t->wd_hits = 0;

    ptimer_set_freq(t->ptimer_wd, 760);
    if (wd_cnt == 0)
        wd_cnt = 256;
    ptimer_set_count(t->ptimer_wd, wd_cnt);
    if (new_cmd)
        ptimer_run(t->ptimer_wd, 1);
    else
        ptimer_stop(t->ptimer_wd);

    t->rw_wd_ctrl = value;
}
Пример #5
0
static void imx_epit_set_freq(IMXEPITState *s)
{
    uint32_t clksrc;
    uint32_t prescaler;
    uint32_t freq;

    clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, 2);
    prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, 12);

    freq = imx_clock_frequency(s->ccm, imx_epit_clocks[clksrc]) / prescaler;

    s->freq = freq;

    DPRINTF("Setting ptimer frequency to %u\n", freq);

    if (freq) {
        ptimer_set_freq(s->timer_reload, freq);
        ptimer_set_freq(s->timer_cmp, freq);
    }
}
Пример #6
0
static int marin_timer_init(SysBusDevice *dev)
{
    MarinTimerState *s = MARIN_TIMER(dev);

    sysbus_init_irq(dev, &s->irq);

    s->bh = qemu_bh_new(marin_timer_tick, s);
    s->ptimer = ptimer_init(s->bh);
    ptimer_set_freq(s->ptimer, 50 * 1000 * 1000);

    return 0;
}
Пример #7
0
static int milkymist_sysctl_init(SysBusDevice *dev)
{
    MilkymistSysctlState *s = FROM_SYSBUS(typeof(*s), dev);

    sysbus_init_irq(dev, &s->gpio_irq);
    sysbus_init_irq(dev, &s->timer0_irq);
    sysbus_init_irq(dev, &s->timer1_irq);

    s->bh0 = qemu_bh_new(timer0_hit, s);
    s->bh1 = qemu_bh_new(timer1_hit, s);
    s->ptimer0 = ptimer_init(s->bh0);
    s->ptimer1 = ptimer_init(s->bh1);
    ptimer_set_freq(s->ptimer0, s->freq_hz);
    ptimer_set_freq(s->ptimer1, s->freq_hz);

    memory_region_init_io(&s->regs_region, &sysctl_mmio_ops, s,
                          "milkymist-sysctl", R_MAX * 4);
    sysbus_init_mmio(dev, &s->regs_region);

    return 0;
}
Пример #8
0
static void imx_gpt_set_freq(IMXGPTState *s)
{
    uint32_t clksrc = extract32(s->cr, GPT_CR_CLKSRC_SHIFT, 3);
    uint32_t freq = imx_clock_frequency(s->ccm, imx_gpt_clocks[clksrc])
                    / (1 + s->pr);
    s->freq = freq;

    DPRINTF("Setting clksrc %d to frequency %d\n", clksrc, freq);

    if (freq) {
        ptimer_set_freq(s->timer, freq);
    }
}
Пример #9
0
static void etsec_realize(DeviceState *dev, Error **errp)
{
    eTSEC        *etsec = ETSEC_COMMON(dev);

    etsec->nic = qemu_new_nic(&net_etsec_info, &etsec->conf,
                              object_get_typename(OBJECT(dev)), dev->id, etsec);
    qemu_format_nic_info_str(qemu_get_queue(etsec->nic), etsec->conf.macaddr.a);


    etsec->bh     = qemu_bh_new(etsec_timer_hit, etsec);
    etsec->ptimer = ptimer_init(etsec->bh, PTIMER_POLICY_DEFAULT);
    ptimer_set_freq(etsec->ptimer, 100);
}
Пример #10
0
static void arm_timer_write(void *opaque, hwaddr offset,
                            uint32_t value)
{
    arm_timer_state *s = (arm_timer_state *)opaque;
    int freq;

    switch (offset >> 2) {
    case 0: /* TimerLoad */
        s->limit = value;
        arm_timer_recalibrate(s, 1);
        break;
    case 1: /* TimerValue */
        /* ??? Linux seems to want to write to this readonly register.
           Ignore it.  */
        break;
    case 2: /* TimerControl */
        if (s->control & TIMER_CTRL_ENABLE) {
            /* Pause the timer if it is running.  This may cause some
               inaccuracy dure to rounding, but avoids a whole lot of other
               messyness.  */
            ptimer_stop(s->timer);
        }
        s->control = value;
        freq = s->freq;
        /* ??? Need to recalculate expiry time after changing divisor.  */
        switch ((value >> 2) & 3) {
        case 1: freq >>= 4; break;
        case 2: freq >>= 8; break;
        }
        arm_timer_recalibrate(s, s->control & TIMER_CTRL_ENABLE);
        ptimer_set_freq(s->timer, freq);
        if (s->control & TIMER_CTRL_ENABLE) {
            /* Restart the timer if still enabled.  */
            ptimer_run(s->timer, (s->control & TIMER_CTRL_ONESHOT) != 0);
        }
        break;
    case 3: /* TimerIntClr */
        s->int_level = 0;
        break;
    case 6: /* TimerBGLoad */
        s->limit = value;
        arm_timer_recalibrate(s, 0);
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Bad offset %x\n", __func__, (int)offset);
    }
    arm_timer_update(s);
}
Пример #11
0
static int lm32_timer_init(SysBusDevice *dev)
{
    LM32TimerState *s = FROM_SYSBUS(typeof(*s), dev);

    sysbus_init_irq(dev, &s->irq);

    s->bh = qemu_bh_new(timer_hit, s);
    s->ptimer = ptimer_init(s->bh);
    ptimer_set_freq(s->ptimer, s->freq_hz);

    memory_region_init_io(&s->iomem, &timer_ops, s, "timer", R_MAX * 4);
    sysbus_init_mmio(dev, &s->iomem);

    return 0;
}
Пример #12
0
static void a10_pit_set_freq(AwA10PITState *s, int index)
{
    uint32_t prescaler, source, source_freq;

    prescaler = 1 << extract32(s->control[index], 4, 3);
    source = extract32(s->control[index], 2, 2);
    source_freq = s->clk_freq[source];

    if (source_freq) {
        ptimer_set_freq(s->timer[index], source_freq / prescaler);
    } else {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid clock source %u\n",
                      __func__, source);
    }
}
Пример #13
0
static void digic_timer_init(Object *obj)
{
    DigicTimerState *s = DIGIC_TIMER(obj);

    s->ptimer = ptimer_init(NULL, PTIMER_POLICY_DEFAULT);

    /*
     * FIXME: there is no documentation on Digic timer
     * frequency setup so let it always run at 1 MHz
     */
    ptimer_set_freq(s->ptimer, 1 * 1000 * 1000);

    memory_region_init_io(&s->iomem, OBJECT(s), &digic_timer_ops, s,
                          TYPE_DIGIC_TIMER, 0x100);
    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
}
Пример #14
0
static void xlx_iom_realize(DeviceState *dev, Error **errp)
{
    XilinxPIT *s = XILINX_IO_MODULE_PIT(dev);
    unsigned int i;

    s->prefix = object_get_canonical_path(OBJECT(dev));

    for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
        RegisterInfo *r = &s->regs_info[i];

        *r = (RegisterInfo) {
            .data = (uint8_t *)&s->regs[i],
            .data_size = sizeof(uint32_t),
            .access = &pit_regs_info[i],
            .debug = XILINX_IO_MODULE_PIT_ERR_DEBUG,
            .prefix = s->prefix,
            .opaque = s,
        };
        memory_region_init_io(&r->mem, OBJECT(dev), &iom_pit_ops, r,
                              r->access->name, 4);
        memory_region_add_subregion(&s->iomem, i * 4, &r->mem);
    }

    if (s->cfg.use) {
        s->bh = qemu_bh_new(pit_timer_hit, s);
        s->ptimer = ptimer_init(s->bh);
        ptimer_set_freq(s->ptimer, s->frequency);
        /* IRQ out to pulse when present timer expires/reloads */
        qdev_init_gpio_out(dev, &s->hit_out, 1);
        /* IRQ in to enable pre-scalar mode. Routed from gpo1 */
        qdev_init_gpio_in_named(dev, iom_pit_ps_config, "ps_config", 1);
        /* hit_out of neighbouring PIT is received as hit_in */
        qdev_init_gpio_in_named(dev, iom_pit_ps_hit_in, "ps_hit_in", 1);
    }
}

static void xlx_iom_pit_init(Object *obj)
{
    XilinxPIT *s = XILINX_IO_MODULE_PIT(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    memory_region_init_io(&s->iomem, obj, &iom_pit_ops, s,
                          TYPE_XILINX_IO_MODULE_PIT,
                          R_MAX * 4);
    sysbus_init_mmio(sbd, &s->iomem);
    sysbus_init_irq(sbd, &s->irq);
}
Пример #15
0
static int lm32_timer_init(SysBusDevice *dev)
{
    LM32TimerState *s = FROM_SYSBUS(typeof(*s), dev);
    int timer_regs;

    sysbus_init_irq(dev, &s->irq);

    s->bh = qemu_bh_new(timer_hit, s);
    s->ptimer = ptimer_init(s->bh);
    ptimer_set_freq(s->ptimer, s->freq_hz);

    timer_regs = cpu_register_io_memory(timer_read_fn, timer_write_fn, s,
                                        DEVICE_NATIVE_ENDIAN);
    sysbus_init_mmio(dev, R_MAX * 4, timer_regs);

    return 0;
}
Пример #16
0
static void grlib_gptimer_set_scaler(GPTimerUnit *unit, uint32_t scaler)
{
    int i = 0;
    uint32_t value = 0;

    assert(unit != NULL);

    if (scaler > 0) {
        value = unit->freq_hz / (scaler + 1);
    } else {
        value = unit->freq_hz;
    }

    trace_grlib_gptimer_set_scaler(scaler, value);

    for (i = 0; i < unit->nr_timers; i++) {
        ptimer_set_freq(unit->timers[i].ptimer, value);
    }
}
Пример #17
0
static void mss_timer_init(Object *obj)
{
    MSSTimerState *t = MSS_TIMER(obj);
    int i;

    /* Init all the ptimers.  */
    for (i = 0; i < NUM_TIMERS; i++) {
        struct Msf2Timer *st = &t->timers[i];

        st->bh = qemu_bh_new(timer_hit, st);
        st->ptimer = ptimer_init(st->bh, PTIMER_POLICY_DEFAULT);
        ptimer_set_freq(st->ptimer, t->freq_hz);
        sysbus_init_irq(SYS_BUS_DEVICE(obj), &st->irq);
    }

    memory_region_init_io(&t->mmio, OBJECT(t), &timer_ops, t, TYPE_MSS_TIMER,
                          NUM_TIMERS * R_TIM1_MAX * 4);
    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &t->mmio);
}
Пример #18
0
static int puv3_ost_init(SysBusDevice *dev)
{
    PUV3OSTState *s = FROM_SYSBUS(PUV3OSTState, dev);

    s->reg_OIER = 0;
    s->reg_OSSR = 0;
    s->reg_OSMR0 = 0;
    s->reg_OSCR = 0;

    sysbus_init_irq(dev, &s->irq);

    s->bh = qemu_bh_new(puv3_ost_tick, s);
    s->ptimer = ptimer_init(s->bh);
    ptimer_set_freq(s->ptimer, 50 * 1000 * 1000);

    memory_region_init_io(&s->iomem, &puv3_ost_ops, s, "puv3_ost",
            PUV3_REGS_OFFSET);
    sysbus_init_mmio(dev, &s->iomem);

    return 0;
}
Пример #19
0
static void xilinx_timer_realize(DeviceState *dev, Error **errp)
{
    struct timerblock *t = XILINX_TIMER(dev);
    unsigned int i;

    /* Init all the ptimers.  */
    t->timers = g_malloc0(sizeof t->timers[0] * num_timers(t));
    for (i = 0; i < num_timers(t); i++) {
        struct xlx_timer *xt = &t->timers[i];

        xt->parent = t;
        xt->nr = i;
        xt->bh = qemu_bh_new(timer_hit, xt);
        xt->ptimer = ptimer_init(xt->bh);
        ptimer_set_freq(xt->ptimer, t->freq_hz);
    }

    memory_region_init_io(&t->mmio, OBJECT(t), &timer_ops, t, "xlnx.xps-timer",
                          R_MAX * 4 * num_timers(t));
    sysbus_init_mmio(SYS_BUS_DEVICE(dev), &t->mmio);
}
Пример #20
0
static int rtt_init(SysBusDevice *dev)
{
    rtt_state *s = FROM_SYSBUS(rtt_state, dev);
    QEMUBH *bh;

    memory_region_init_io(&s->iomem, OBJECT(s), &rtt_ops, s, "rtt", 0x20);
    sysbus_init_mmio(dev, &s->iomem);
    sysbus_init_irq(dev, &s->irq);
    //s->ssi = ssi_create_bus(&dev->qdev, "ssi");
    //rtt_reset(s);
    //vmstate_register(&dev->qdev, -1, &vmstate_rtt, s);
    bh = qemu_bh_new(rtt_tick, s);
    s->timer = ptimer_init(bh);

    ptimer_set_freq(s->timer, 10);
    ptimer_set_limit(s->timer, 1, 1);
    ptimer_run(s->timer, 0);

    return 0;

}
Пример #21
0
static int puv3_ost_init(SysBusDevice *dev)
{
    PUV3OSTState *s = PUV3_OST(dev);

    s->reg_OIER = 0;
    s->reg_OSSR = 0;
    s->reg_OSMR0 = 0;
    s->reg_OSCR = 0;

    sysbus_init_irq(dev, &s->irq);

    s->bh = qemu_bh_new(puv3_ost_tick, s);
    s->ptimer = ptimer_init(s->bh, PTIMER_POLICY_DEFAULT);
    ptimer_set_freq(s->ptimer, 50 * 1000 * 1000);

    memory_region_init_io(&s->iomem, OBJECT(s), &puv3_ost_ops, s, "puv3_ost",
            PUV3_REGS_OFFSET);
    sysbus_init_mmio(dev, &s->iomem);

    return 0;
}
Пример #22
0
static int grlib_gptimer_init(SysBusDevice *dev)
{
    GPTimerUnit  *unit = FROM_SYSBUS(typeof(*unit), dev);
    unsigned int  i;
    int           timer_regs;

    assert(unit->nr_timers > 0);
    assert(unit->nr_timers <= GPTIMER_MAX_TIMERS);

    unit->timers = qemu_mallocz(sizeof unit->timers[0] * unit->nr_timers);

    for (i = 0; i < unit->nr_timers; i++) {
        GPTimer *timer = &unit->timers[i];

        timer->unit   = unit;
        timer->bh     = qemu_bh_new(grlib_gptimer_hit, timer);
        timer->ptimer = ptimer_init(timer->bh);
        timer->id     = i;

        /* One IRQ line for each timer */
        sysbus_init_irq(dev, &timer->irq);

        ptimer_set_freq(timer->ptimer, unit->freq_hz);
    }

    timer_regs = cpu_register_io_memory(grlib_gptimer_read,
                                        grlib_gptimer_write,
                                        unit, DEVICE_NATIVE_ENDIAN);
    if (timer_regs < 0) {
        return -1;
    }

    sysbus_init_mmio(dev, UNIT_REG_SIZE + GPTIMER_REG_SIZE * unit->nr_timers,
                     timer_regs);
    return 0;
}
Пример #23
0
static void update_ctrl(struct etrax_timer *t, int tnum)
{
    unsigned int op;
    unsigned int freq;
    unsigned int freq_hz;
    unsigned int div;
    uint32_t ctrl;

    ptimer_state *timer;

    if (tnum == 0) {
        ctrl = t->rw_tmr0_ctrl;
        div = t->rw_tmr0_div;
        timer = t->ptimer_t0;
    } else {
        ctrl = t->rw_tmr1_ctrl;
        div = t->rw_tmr1_div;
        timer = t->ptimer_t1;
    }


    op = ctrl & 3;
    freq = ctrl >> 2;
    freq_hz = 32000000;

    switch (freq)
    {
    case 0:
    case 1:
        D(printf ("extern or disabled timer clock?\n"));
        break;
    case 4: freq_hz =  29493000; break;
    case 5: freq_hz =  32000000; break;
    case 6: freq_hz =  32768000; break;
    case 7: freq_hz = 100000000; break;
    default:
        abort();
        break;
    }

    D(printf ("freq_hz=%d div=%d\n", freq_hz, div));
    ptimer_set_freq(timer, freq_hz);
    ptimer_set_limit(timer, div, 0);

    switch (op)
    {
        case 0:
            /* Load.  */
            ptimer_set_limit(timer, div, 1);
            break;
        case 1:
            /* Hold.  */
            ptimer_stop(timer);
            break;
        case 2:
            /* Run.  */
            ptimer_run(timer, 0);
            break;
        default:
            abort();
            break;
    }
}
Пример #24
0
static void sh_timer_write(void *opaque, target_phys_addr_t offset,
                            uint32_t value)
{
    sh_timer_state *s = (sh_timer_state *)opaque;
    int freq;

    switch (offset >> 2) {
    case OFFSET_TCOR:
        s->tcor = value;
        ptimer_set_limit(s->timer, s->tcor, 0);
        break;
    case OFFSET_TCNT:
        s->tcnt = value;
        ptimer_set_count(s->timer, s->tcnt);
        break;
    case OFFSET_TCR:
        if (s->enabled) {
            /* Pause the timer if it is running.  This may cause some
               inaccuracy dure to rounding, but avoids a whole lot of other
               messyness.  */
            ptimer_stop(s->timer);
        }
        freq = s->freq;
        /* ??? Need to recalculate expiry time after changing divisor.  */
        switch (value & TIMER_TCR_TPSC) {
        case 0: freq >>= 2; break;
        case 1: freq >>= 4; break;
        case 2: freq >>= 6; break;
        case 3: freq >>= 8; break;
        case 4: freq >>= 10; break;
	case 6:
	case 7: if (s->feat & TIMER_FEAT_EXTCLK) break;
	default: hw_error("sh_timer_write: Reserved TPSC value\n"); break;
        }
        switch ((value & TIMER_TCR_CKEG) >> 3) {
	case 0: break;
        case 1:
        case 2:
        case 3: if (s->feat & TIMER_FEAT_EXTCLK) break;
	default: hw_error("sh_timer_write: Reserved CKEG value\n"); break;
        }
        switch ((value & TIMER_TCR_ICPE) >> 6) {
	case 0: break;
        case 2:
        case 3: if (s->feat & TIMER_FEAT_CAPT) break;
	default: hw_error("sh_timer_write: Reserved ICPE value\n"); break;
        }
	if ((value & TIMER_TCR_UNF) == 0)
            s->int_level = 0;

	value &= ~TIMER_TCR_UNF;

	if ((value & TIMER_TCR_ICPF) && (!(s->feat & TIMER_FEAT_CAPT)))
            hw_error("sh_timer_write: Reserved ICPF value\n");

	value &= ~TIMER_TCR_ICPF; /* capture not supported */

	if (value & TIMER_TCR_RESERVED)
            hw_error("sh_timer_write: Reserved TCR bits set\n");
        s->tcr = value;
        ptimer_set_limit(s->timer, s->tcor, 0);
        ptimer_set_freq(s->timer, freq);
        if (s->enabled) {
            /* Restart the timer if still enabled.  */
            ptimer_run(s->timer, 0);
        }
        break;
    case OFFSET_TCPR:
        if (s->feat & TIMER_FEAT_CAPT) {
            s->tcpr = value;
	    break;
	}
    default:
        hw_error("sh_timer_write: Bad offset %x\n", (int)offset);
    }
    sh_timer_update(s);
}