Example #1
0
static void timerblock_write(void *opaque, hwaddr addr,
                             uint64_t value, unsigned size)
{
    TimerBlock *tb = (TimerBlock *)opaque;
    int64_t old;
    switch (addr) {
    case 0: /* Load */
        tb->load = value;
        /* Fall through.  */
    case 4: /* Counter.  */
        if ((tb->control & 1) && tb->count) {
            /* Cancel the previous timer.  */
            qemu_del_timer(tb->timer);
        }
        tb->count = value;
        if (tb->control & 1) {
            timerblock_reload(tb, 1);
        }
        break;
    case 8: /* Control.  */
        old = tb->control;
        tb->control = value;
        if (((old & 1) == 0) && (value & 1)) {
            if (tb->count == 0 && (tb->control & 2)) {
                tb->count = tb->load;
            }
            timerblock_reload(tb, 1);
        }
        break;
    case 12: /* Interrupt status.  */
        tb->status &= ~value;
        timerblock_update_irq(tb);
        break;
    }
}
static void qemu_announce_self_once(void *opaque)
{
    int i, len;
    VLANState *vlan;
    VLANClientState *vc;
    uint8_t buf[256];
    static int count = SELF_ANNOUNCE_ROUNDS;
    QEMUTimer *timer = *(QEMUTimer **)opaque;

    for (i = 0; i < MAX_NICS; i++) {
        if (!nd_table[i].used)
            continue;
        len = announce_self_create(buf, nd_table[i].macaddr);
        vlan = nd_table[i].vlan;
	for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
            qemu_send_packet_raw(vc, buf, len);
        }
    }
    if (count--) {
	    qemu_mod_timer(timer, qemu_get_clock(rt_clock) + 100);
    } else {
	    qemu_del_timer(timer);
	    qemu_free_timer(timer);
    }
}
static void goldfish_timer_write(void *opaque, target_phys_addr_t offset, uint32_t value_ns)
{
    struct timer_state *s = (struct timer_state *)opaque;
    int64_t alarm_tks, now_tks;
    switch(offset) {
        case TIMER_ALARM_LOW:
            s->alarm_low_ns = value_ns;
            alarm_tks = ns2tks(s->alarm_low_ns | (int64_t)s->alarm_high_ns << 32);
            now_tks   = qemu_get_clock(vm_clock);
            if (alarm_tks <= now_tks) {
                goldfish_device_set_irq(&s->dev, 0, 1);
            } else {
                qemu_mod_timer(s->timer, alarm_tks);
                s->armed = 1;
            }
            break;
        case TIMER_ALARM_HIGH:
            s->alarm_high_ns = value_ns;
            break;
        case TIMER_CLEAR_ALARM:
            qemu_del_timer(s->timer);
            s->armed = 0;
            /* fall through */
        case TIMER_CLEAR_INTERRUPT:
            goldfish_device_set_irq(&s->dev, 0, 0);
            break;
        default:
            cpu_abort (cpu_single_env, "goldfish_timer_write: Bad offset %x\n", offset);
    }
}
Example #4
0
/* modify the current timer so that it will be fired when current_time
   >= expire_time. The corresponding callback will be called. */
static void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
{
    QEMUTimer **pt, *t;

    qemu_del_timer(ts);

    /* add the timer in the sorted list */
    /* NOTE: this code must be signal safe because
       qemu_timer_expired() can be called from a signal. */
    pt = &active_timers[ts->clock->type];
    for(;;) {
        t = *pt;
        if (!qemu_timer_expired_ns(t, expire_time)) {
            break;
        }
        pt = &t->next;
    }
    ts->expire_time = expire_time;
    ts->next = *pt;
    *pt = ts;

    /* Rearm if necessary  */
    if (pt == &active_timers[ts->clock->type]) {
        if (!alarm_timer->pending) {
            qemu_rearm_alarm_timer(alarm_timer);
        }
        /* Interrupt execution to force deadline recalculation.  */
        qemu_clock_warp(ts->clock);
        if (use_icount) {
            qemu_notify_event();
        }
    }
}
Example #5
0
static void
_hwSensorClient_free( HwSensorClient*  cl )
{
    /* remove from sensors's list */
    if (cl->sensors) {
        HwSensorClient**  pnode = &cl->sensors->clients;
        for (;;) {
            HwSensorClient*  node = *pnode;
            if (node == NULL)
                break;
            if (node == cl) {
                *pnode = cl->next;
                break;
            }
            pnode = &node->next;
        }
        cl->next    = NULL;
        cl->sensors = NULL;
    }

    /* close QEMUD client, if any */
    if (cl->client) {
        qemud_client_close(cl->client);
        cl->client = NULL;
    }
    /* remove timer, if any */
    if (cl->timer) {
        qemu_del_timer(cl->timer);
        qemu_free_timer(cl->timer);
        cl->timer = NULL;
    }
    AFREE(cl);
}
Example #6
0
static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n)
{
    PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque;
    uint32_t now_vm;
    uint64_t new_qemu;
    static const int counters[8] = { 0, 0, 0, 0, 4, 4, 6, 6 };
    int counter;

    if (s->tm4[n].control & (1 << 7))
        counter = n;
    else
        counter = counters[n];

    if (!s->tm4[counter].freq) {
        qemu_del_timer(s->tm4[n].tm.qtimer);
        return;
    }

    now_vm = s->tm4[counter].clock + muldiv64(now_qemu -
                    s->tm4[counter].lastload,
                    s->tm4[counter].freq, get_ticks_per_sec());

    new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm),
                    get_ticks_per_sec(), s->tm4[counter].freq);
    qemu_mod_timer(s->tm4[n].tm.qtimer, new_qemu);
}
Example #7
0
/* handle periodic timer */
static void periodic_timer_update(RTCState *s, int64_t current_time)
{
    int period_code, period;
    int64_t cur_clock, next_irq_clock;

    period_code = s->cmos_data[RTC_REG_A] & 0x0f;
    if (period_code != 0
        && ((s->cmos_data[RTC_REG_B] & REG_B_PIE)
            || ((s->cmos_data[RTC_REG_B] & REG_B_SQWE) && s->sqw_irq))) {
        if (period_code <= 2)
            period_code += 7;
        /* period in 32 Khz cycles */
        period = 1 << (period_code - 1);
#ifdef TARGET_I386
        if (period != s->period) {
            s->irq_coalesced = (s->irq_coalesced * s->period) / period;
            DPRINTF_C("cmos: coalesced irqs scaled to %d\n", s->irq_coalesced);
        }
        s->period = period;
#endif
        /* compute 32 khz clock */
        cur_clock = muldiv64(current_time, RTC_CLOCK_RATE, get_ticks_per_sec());
        next_irq_clock = (cur_clock & ~(period - 1)) + period;
        s->next_periodic_time =
            muldiv64(next_irq_clock, get_ticks_per_sec(), RTC_CLOCK_RATE) + 1;
        qemu_mod_timer(s->periodic_timer, s->next_periodic_time);
    } else {
#ifdef TARGET_I386
        s->irq_coalesced = 0;
#endif
        qemu_del_timer(s->periodic_timer);
    }
}
Example #8
0
static void wdt_ib700_reset(DeviceState *dev)
{
    IB700State *s = IB700(dev);

    ib700_debug("watchdog reset\n");

    qemu_del_timer(s->timer);
}
Example #9
0
/* A write (of any value) to this register disables the timer. */
static void ib700_write_disable_reg(void *vp, uint32_t addr, uint32_t data)
{
    IB700State *s = vp;

    ib700_debug("addr = %x, data = %x\n", addr, data);

    qemu_del_timer(s->timer);
}
Example #10
0
/* handle update-ended timer */
static void check_update_timer(RTCState *s)
{
    uint64_t next_update_time;
    uint64_t guest_nsec;
    int next_alarm_sec;

    /* From the data sheet: "Holding the dividers in reset prevents
     * interrupts from operating, while setting the SET bit allows"
     * them to occur.  However, it will prevent an alarm interrupt
     * from occurring, because the time of day is not updated.
     */
    if ((s->cmos_data[RTC_REG_A] & 0x60) == 0x60) {
        qemu_del_timer(s->update_timer);
        return;
    }
    if ((s->cmos_data[RTC_REG_C] & REG_C_UF) &&
        (s->cmos_data[RTC_REG_B] & REG_B_SET)) {
        qemu_del_timer(s->update_timer);
        return;
    }
    if ((s->cmos_data[RTC_REG_C] & REG_C_UF) &&
        (s->cmos_data[RTC_REG_C] & REG_C_AF)) {
        qemu_del_timer(s->update_timer);
        return;
    }

    guest_nsec = get_guest_rtc_ns(s) % NSEC_PER_SEC;
    /* if UF is clear, reprogram to next second */
    next_update_time = qemu_get_clock_ns(rtc_clock)
        + NSEC_PER_SEC - guest_nsec;

    /* Compute time of next alarm.  One second is already accounted
     * for in next_update_time.
     */
    next_alarm_sec = get_next_alarm(s);
    s->next_alarm_time = next_update_time + (next_alarm_sec - 1) * NSEC_PER_SEC;

    if (s->cmos_data[RTC_REG_C] & REG_C_UF) {
        /* UF is set, but AF is clear.  Program the timer to target
         * the alarm time.  */
        next_update_time = s->next_alarm_time;
    }
    if (next_update_time != qemu_timer_expire_time_ns(s->update_timer)) {
        qemu_mod_timer(s->update_timer, next_update_time);
    }
}
Example #11
0
static void
qlooptimer_startAbsolute(void* impl, Duration deadline_ms)
{
    QEMUTimer* tt = impl;
    if (deadline_ms == DURATION_INFINITE)
        qemu_del_timer(tt);
    else
        qemu_mod_timer(tt, deadline_ms*1000000);
}
Example #12
0
static void
qlooptimer_startRelative(void* impl, Duration timeout_ms)
{
    QEMUTimer* tt = impl;
    if (timeout_ms == DURATION_INFINITE)
        qemu_del_timer(tt);
    else
        qemu_mod_timer(tt, qemu_get_clock_ms(host_clock) + timeout_ms);
}
Example #13
0
/* This is called when the watchdog expires. */
static void ib700_timer_expired(void *vp)
{
    IB700State *s = vp;

    ib700_debug("watchdog expired\n");

    watchdog_perform_action();
    qemu_del_timer(s->timer);
}
Example #14
0
/* timer for waiting the semaphore for sem_retry times try */
static void onedram_wait_semaphore(void *opaque)
{
    S5pc1xxOneDRAMState *s = (S5pc1xxOneDRAMState *)opaque;
    int64_t timeout;

    if(sem_retry <= 0) {
        fprintf(stderr, "time out to wait semaphore from AP\n");
        qemu_del_timer(s->sem_timer);
        sem_retry = 100;
    } else if(onedram_read_sem(s)) {
        sem_retry--;
        timeout = get_ticks_per_sec();
        qemu_mod_timer(s->sem_timer, qemu_get_clock(vm_clock) + TICK_COUNTDOWN);
    } else {
        sem_retry = 100;
        qemu_del_timer(s->sem_timer);
        onedram_fmt_send_cmd(s);
    }
}
Example #15
0
void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
{
    uint64_t expire_time;

    expire_time = qemu_get_be64(f);
    if (expire_time != -1) {
        qemu_mod_timer_ns(ts, expire_time);
    } else {
        qemu_del_timer(ts);
    }
}
Example #16
0
static void timerblock_reset(TimerBlock *tb)
{
    tb->count = 0;
    tb->load = 0;
    tb->control = 0;
    tb->status = 0;
    tb->tick = 0;
    if (tb->timer) {
        qemu_del_timer(tb->timer);
    }
}
Example #17
0
static void rtc_coalesced_timer_update(RTCState *s)
{
    if (s->irq_coalesced == 0) {
        qemu_del_timer(s->coalesced_timer);
    } else {
        /* divide each RTC interval to 2 - 8 smaller intervals */
        int c = MIN(s->irq_coalesced, 7) + 1; 
        int64_t next_clock = qemu_get_clock(rtc_clock) +
            muldiv64(s->period / c, get_ticks_per_sec(), 32768);
        qemu_mod_timer(s->coalesced_timer, next_clock);
    }
}
Example #18
0
void qemu_clock_warp(QEMUClock *clock)
{
    int64_t deadline;

    if (!clock->warp_timer) {
        return;
    }

    /*
     * There are too many global variables to make the "warp" behavior
     * applicable to other clocks.  But a clock argument removes the
     * need for if statements all over the place.
     */
    assert(clock == vm_clock);

    /*
     * If the CPUs have been sleeping, advance the vm_clock timer now.  This
     * ensures that the deadline for the timer is computed correctly below.
     * This also makes sure that the insn counter is synchronized before the
     * CPU starts running, in case the CPU is woken by an event other than
     * the earliest vm_clock timer.
     */
    icount_warp_rt(NULL);
    if (!all_cpu_threads_idle() || !active_timers[clock->type]) {
        qemu_del_timer(clock->warp_timer);
        return;
    }

    vm_clock_warp_start = qemu_get_clock_ns(rt_clock);
    deadline = qemu_next_icount_deadline();
    if (deadline > 0) {
        /*
         * Ensure the vm_clock proceeds even when the virtual CPU goes to
         * sleep.  Otherwise, the CPU might be waiting for a future timer
         * interrupt to wake it up, but the interrupt never comes because
         * the vCPU isn't running any insns and thus doesn't advance the
         * vm_clock.
         *
         * An extreme solution for this problem would be to never let VCPUs
         * sleep in icount mode if there is a pending vm_clock timer; rather
         * time could just advance to the next vm_clock event.  Instead, we
         * do stop VCPUs and only advance vm_clock after some "real" time,
         * (related to the time left until the next event) has passed.  This
         * rt_clock timer will do this.  This avoids that the warps are too
         * visible externally---for example, you will not be sending network
         * packets continously instead of every 100ms.
         */
        qemu_mod_timer(clock->warp_timer, vm_clock_warp_start + deadline);
    } else {
        qemu_notify_event();
    }
}
Example #19
0
static void iscsi_close(BlockDriverState *bs)
{
    IscsiLun *iscsilun = bs->opaque;
    struct iscsi_context *iscsi = iscsilun->iscsi;

    if (iscsilun->nop_timer) {
        qemu_del_timer(iscsilun->nop_timer);
        qemu_free_timer(iscsilun->nop_timer);
    }
    qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL, NULL);
    iscsi_destroy_context(iscsi);
    memset(iscsilun, 0, sizeof(IscsiLun));
}
Example #20
0
static void rtc_timer_update(RTCState *s, int64_t current_time)
{
    int period_code, period;
    int64_t cur_clock, next_irq_clock;

    period_code = s->cmos_data[RTC_REG_A] & 0x0f;
#if defined TARGET_I386 || defined TARGET_X86_64
    /* disable periodic timer if hpet is in legacy mode, since interrupts are
     * disabled anyway.
     */
    if (period_code != 0 && (s->cmos_data[RTC_REG_B] & REG_B_PIE) && !hpet_in_legacy_mode()) {
#else
    if (period_code != 0 && (s->cmos_data[RTC_REG_B] & REG_B_PIE)) {
#endif
        if (period_code <= 2)
            period_code += 7;
        /* period in 32 Khz cycles */
        period = 1 << (period_code - 1);
#ifdef IRQ_COALESCE_HACK
        if(period != s->period)
            s->irq_coalesced = (s->irq_coalesced * s->period) / period;
        s->period = period;
#endif
        /* compute 32 khz clock */
        cur_clock = muldiv64(current_time, 32768, ticks_per_sec);
        next_irq_clock = (cur_clock & ~(period - 1)) + period;
        s->next_periodic_time = muldiv64(next_irq_clock, ticks_per_sec, 32768) + 1;
        qemu_mod_timer(s->periodic_timer, s->next_periodic_time);
    } else {
#ifdef IRQ_COALESCE_HACK
        s->irq_coalesced = 0;
#endif
        qemu_del_timer(s->periodic_timer);
    }
}

static void rtc_periodic_timer(void *opaque)
{
    RTCState *s = opaque;

    rtc_timer_update(s, s->next_periodic_time);
#ifdef IRQ_COALESCE_HACK
    if ((s->cmos_data[RTC_REG_C] & 0xc0) && rtc_td_hack) {
        s->irq_coalesced++;
        return;
    }
#endif
    s->cmos_data[RTC_REG_C] |= 0xc0;
    rtc_irq_raise(s->irq);
}
Example #21
0
static int iscsi_create(const char *filename, QEMUOptionParameter *options)
{
    int ret = 0;
    int64_t total_size = 0;
    BlockDriverState bs;
    IscsiLun *iscsilun = NULL;

    memset(&bs, 0, sizeof(BlockDriverState));

    /* Read out options */
    while (options && options->name) {
        if (!strcmp(options->name, "size")) {
            total_size = options->value.n / BDRV_SECTOR_SIZE;
        }
        options++;
    }

    bs.opaque = g_malloc0(sizeof(struct IscsiLun));
    iscsilun = bs.opaque;

    ret = iscsi_open(&bs, filename, 0);
    if (ret != 0) {
        goto out;
    }
    if (iscsilun->nop_timer) {
        qemu_del_timer(iscsilun->nop_timer);
        qemu_free_timer(iscsilun->nop_timer);
    }
    if (iscsilun->type != TYPE_DISK) {
        ret = -ENODEV;
        goto out;
    }
    if (bs.total_sectors < total_size) {
        ret = -ENOSPC;
    }

    ret = 0;
out:
    if (iscsilun->iscsi != NULL) {
        iscsi_destroy_context(iscsilun->iscsi);
    }
    g_free(bs.opaque);
    return ret;
}
Example #22
0
static void pl031_set_alarm(pl031_state *s)
{
    int64_t now;
    uint32_t ticks;

    now = qemu_get_clock(vm_clock);
    ticks = s->tick_offset + now / ticks_per_sec;

    /* The timer wraps around.  This subtraction also wraps in the same way,
       and gives correct results when alarm < now_ticks.  */
    ticks = s->mr - ticks;
    DPRINTF("Alarm set in %ud ticks\n", ticks);
    if (ticks == 0) {
        qemu_del_timer(s->timer);
        pl031_interrupt(s);
    } else {
        qemu_mod_timer(s->timer, now + (int64_t)ticks * ticks_per_sec);
    }
}
Example #23
0
static void rtc_timer_update(RTCState *s, int64_t current_time)
{
    int period_code, period;
    int64_t cur_clock, next_irq_clock;
    int enable_pie;

    period_code = s->cmos_data[RTC_REG_A] & 0x0f;
#if defined TARGET_I386
    /* disable periodic timer if hpet is in legacy mode, since interrupts are
     * disabled anyway.
     */
    enable_pie = !hpet_in_legacy_mode();
#else
    enable_pie = 1;
#endif
    if (period_code != 0
        && (((s->cmos_data[RTC_REG_B] & REG_B_PIE) && enable_pie)
            || ((s->cmos_data[RTC_REG_B] & REG_B_SQWE) && s->sqw_irq))) {
        if (period_code <= 2)
            period_code += 7;
        /* period in 32 Khz cycles */
        period = 1 << (period_code - 1);
#ifdef TARGET_I386
        if(period != s->period)
            s->irq_coalesced = (s->irq_coalesced * s->period) / period;
        s->period = period;
#endif
        /* compute 32 khz clock */
        cur_clock = muldiv64(current_time, 32768, get_ticks_per_sec());
        next_irq_clock = (cur_clock & ~(period - 1)) + period;
        s->next_periodic_time =
            muldiv64(next_irq_clock, get_ticks_per_sec(), 32768) + 1;
        qemu_mod_timer(s->periodic_timer, s->next_periodic_time);
    } else {
#ifdef TARGET_I386
        s->irq_coalesced = 0;
#endif
        qemu_del_timer(s->periodic_timer);
    }
}
Example #24
0
/* Boot up timer */
static void onedram_bootup(void *opaque)
{
    uint16_t cmd;

    S5pc1xxOneDRAMState *s = (S5pc1xxOneDRAMState *)opaque;
    if(!s->vmodem_bootup) {
        onedram_io_writel(s, ONEDRAM_MBX_AB, IPC_CP_READY_FOR_LOADING);
        s->vmodem_bootup = 1;

    } else {
        /* Init the in/out head/tail */
        onedram_write_inhead(s, 0);
        onedram_write_intail(s, 0);
        onedram_write_outhead(s, 0);
        onedram_write_outtail(s, 0);
        /* put the authority to AP to let it access to shared memory */
        onedram_put_authority(s);
        cmd = INT_COMMAND(INT_MASK_CMD_PHONE_START|CP_CHIP_INFINEON);
        onedram_send_cmd_to_pda(s, cmd);
        qemu_del_timer(s->bootup_timer);
    }
}
Example #25
0
void soc_dma_set_request(struct soc_dma_ch_s *ch, int level)
{
    struct dma_s *dma = (struct dma_s *) ch->dma;

    dma->enabled_count += level - ch->enable;

    if (level)
        dma->ch_enable_mask |= 1 << ch->num;
    else
        dma->ch_enable_mask &= ~(1 << ch->num);

    if (level != ch->enable) {
        soc_dma_ch_freq_update(dma);
        ch->enable = level;

        if (!ch->enable)
            qemu_del_timer(ch->timer);
        else if (!ch->running)
            soc_dma_ch_run(ch);
        else
            soc_dma_ch_schedule(ch, 1);
    }
}
Example #26
0
static void
qlooptimer_stop(void* impl)
{
    QEMUTimer* tt = impl;
    qemu_del_timer(tt);
}
Example #27
0
/* This is called when the guest disables the watchdog. */
static void i6300esb_disable_timer(I6300State *d)
{
    i6300esb_debug("timer disabled\n");

    qemu_del_timer(d->timer);
}
Example #28
0
/* Stop sending SOF tokens on the bus */
static void ohci_bus_stop(OHCIState *ohci)
{
    if (ohci->eof_timer)
        qemu_del_timer(ohci->eof_timer);
    ohci->eof_timer = NULL;
}