static inline void strongarm_rtc_timer_update(StrongARMRTCState *s) { if ((s->rtsr & RTSR_HZE) && !(s->rtsr & RTSR_HZ)) { qemu_mod_timer(s->rtc_hz, s->last_hz + 1000); } else { qemu_del_timer(s->rtc_hz); } if ((s->rtsr & RTSR_ALE) && !(s->rtsr & RTSR_AL)) { qemu_mod_timer(s->rtc_alarm, s->last_hz + (((s->rtar - s->last_rcnr) * 1000 * ((s->rttr & 0xffff) + 1)) >> 15)); } else {
/* ACPI PM_TMR */ void acpi_pm_tmr_update(ACPIREGS *ar, bool enable) { int64_t expire_time; /* schedule a timer interruption if needed */ if (enable) { expire_time = muldiv64(ar->tmr.overflow_time, get_ticks_per_sec(), PM_TIMER_FREQUENCY); qemu_mod_timer(ar->tmr.timer, expire_time); } else { qemu_del_timer(ar->tmr.timer); } }
/* Set CPU Timer */ void HELPER(spt)(CPUS390XState *env, uint64_t a1) { uint64_t time = cpu_ldq_data(env, a1); if (time == -1ULL) { return; } /* nanoseconds */ time = (time * 125) >> 9; qemu_mod_timer(env->cpu_timer, qemu_get_clock_ns(vm_clock) + time); }
static void tusb6010_power(TUSBState *s, int on) { if (!on) { s->power = 0; } else if (!s->power && on) { s->power = 1; /* Pull the interrupt down after TUSB6010 comes up. */ s->intr_ok = 0; tusb_intr_update(s); qemu_mod_timer(s->pwr_timer, qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 2); } }
static int rtc_initfn(ISADevice *dev) { RTCState *s = DO_UPCAST(RTCState, dev, dev); int base = 0x70; s->cmos_data[RTC_REG_A] = 0x26; s->cmos_data[RTC_REG_B] = 0x02; s->cmos_data[RTC_REG_C] = 0x00; s->cmos_data[RTC_REG_D] = 0x80; rtc_set_date_from_host(dev); #ifdef TARGET_I386 switch (s->lost_tick_policy) { case LOST_TICK_SLEW: s->coalesced_timer = qemu_new_timer_ns(rtc_clock, rtc_coalesced_timer, s); break; case LOST_TICK_DISCARD: break; default: return -EINVAL; } #endif s->periodic_timer = qemu_new_timer_ns(rtc_clock, rtc_periodic_timer, s); s->second_timer = qemu_new_timer_ns(rtc_clock, rtc_update_second, s); s->second_timer2 = qemu_new_timer_ns(rtc_clock, rtc_update_second2, s); s->clock_reset_notifier.notify = rtc_notify_clock_reset; qemu_register_clock_reset_notifier(rtc_clock, &s->clock_reset_notifier); s->suspend_notifier.notify = rtc_notify_suspend; qemu_register_suspend_notifier(&s->suspend_notifier); s->next_second_time = qemu_get_clock_ns(rtc_clock) + (get_ticks_per_sec() * 99) / 100; qemu_mod_timer(s->second_timer2, s->next_second_time); memory_region_init_io(&s->io, &cmos_ops, s, "rtc", 2); isa_register_ioport(dev, &s->io, base); qdev_set_legacy_instance_id(&dev->qdev, base, 2); qemu_register_reset(rtc_reset, s); object_property_add(OBJECT(s), "date", "struct tm", rtc_get_date, NULL, NULL, s, NULL); return 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 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, 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 TARGET_I386 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 TARGET_I386 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); }
void tusb6010_power(struct tusb_s *s, int on) { if (!on) s->power = 0; else if (!s->power && on) { s->power = 1; /* Pull the interrupt down after TUSB6010 comes up. */ s->intr_ok = 0; tusb_intr_update(s); qemu_mod_timer(s->pwr_timer, qemu_get_clock(vm_clock) + ticks_per_sec / 2); } }
/* A write to this register enables the timer. */ static void ib700_write_enable_reg(void *vp, uint32_t addr, uint32_t data) { IB700State *s = vp; static int time_map[] = { 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0 }; int64_t timeout; ib700_debug("addr = %x, data = %x\n", addr, data); timeout = (int64_t) time_map[data & 0xF] * get_ticks_per_sec(); qemu_mod_timer(s->timer, qemu_get_clock_ns (vm_clock) + timeout); }
void enqueue_async_event(NVMEState *n, uint8_t event_type, uint8_t event_info, uint8_t log_page) { AsyncEvent *event = (AsyncEvent *)qemu_malloc(sizeof(AsyncEvent)); event->result.event_type = event_type; event->result.event_info = event_info; event->result.log_page = log_page; QSIMPLEQ_INSERT_TAIL(&(n->async_queue), event, entry); qemu_mod_timer(n->async_event_timer, qemu_get_clock_ns(vm_clock) + 20000); }
void qemu_clock_warp(QEMUClock *clock) { int64_t deadline; /* * 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. */ if (clock != vm_clock || !use_icount) { return; } /* * 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() || !qemu_clock_has_timers(vm_clock)) { qemu_del_timer(icount_warp_timer); return; } vm_clock_warp_start = qemu_get_clock_ns(rt_clock); deadline = qemu_clock_deadline(vm_clock); 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 continuously instead of every 100ms. */ qemu_mod_timer(icount_warp_timer, vm_clock_warp_start + deadline); } else { qemu_notify_event(); } }
static void set_next_tick(dp8393xState *s) { uint32_t ticks; int64_t delay; if (s->regs[SONIC_CR] & SONIC_CR_STP) { qemu_del_timer(s->watchdog); return; } ticks = s->regs[SONIC_WT1] << 16 | s->regs[SONIC_WT0]; s->wt_last_update = qemu_get_clock(vm_clock); delay = get_ticks_per_sec() * ticks / 5000000; qemu_mod_timer(s->watchdog, s->wt_last_update + delay); }
/* Set Clock Comparator */ void HELPER(sckc)(CPUS390XState *env, uint64_t a1) { uint64_t time = cpu_ldq_data(env, a1); if (time == -1ULL) { return; } /* difference between now and then */ time -= clock_value(env); /* nanoseconds */ time = (time * 125) >> 9; qemu_mod_timer(env->tod_timer, qemu_get_clock_ns(vm_clock) + time); }
static void rtc_notify_clock_reset(Notifier *notifier, void *data) { RTCState *s = container_of(notifier, RTCState, clock_reset_notifier); int64_t now = *(int64_t *)data; rtc_set_date_from_host(&s->dev); s->next_second_time = now + (get_ticks_per_sec() * 99) / 100; qemu_mod_timer(s->second_timer2, s->next_second_time); rtc_timer_update(s, now); #ifdef TARGET_I386 if (rtc_td_hack) { rtc_coalesced_timer_update(s); } #endif }
static void pl031_set_alarm(pl031_state *s) { uint32_t ticks; /* The timer wraps around. This subtraction also wraps in the same way, and gives correct results when alarm < now_ticks. */ ticks = s->mr - pl031_get_count(s); DPRINTF("Alarm set in %ud ticks\n", ticks); if (ticks == 0) { qemu_del_timer(s->timer); pl031_interrupt(s); } else { int64_t now = qemu_get_clock_ns(rtc_clock); qemu_mod_timer(s->timer, now + (int64_t)ticks * get_ticks_per_sec()); } }
void xtensa_rearm_ccompare_timer(CPUXtensaState *env) { int i; uint32_t wake_ccount = env->sregs[CCOUNT] - 1; for (i = 0; i < env->config->nccompare; ++i) { if (env->sregs[CCOMPARE + i] - env->sregs[CCOUNT] < wake_ccount - env->sregs[CCOUNT]) { wake_ccount = env->sregs[CCOMPARE + i]; } } env->wake_ccount = wake_ccount; qemu_mod_timer(env->ccompare_timer, env->halt_clock + muldiv64(wake_ccount - env->sregs[CCOUNT], 1000000, env->config->clock_freq_khz)); }
static void qemu_announce_self_once(void *opaque) { static int count = SELF_ANNOUNCE_ROUNDS; QEMUTimer *timer = *(QEMUTimer **)opaque; qemu_foreach_nic(qemu_announce_self_iter, NULL); if (--count) { /* delay 50ms, 150ms, 250ms, ... */ qemu_mod_timer(timer, qemu_get_clock(rt_clock) + 50 + (SELF_ANNOUNCE_ROUNDS - count - 1) * 100); } else { qemu_del_timer(timer); qemu_free_timer(timer); } }
static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu) { PXA2xxTimerInfo *s = (PXA2xxTimerInfo *) opaque; int i; uint32_t now_vm; uint64_t new_qemu; now_vm = s->clock + muldiv64(now_qemu - s->lastload, s->freq, get_ticks_per_sec()); for (i = 0; i < 4; i ++) { new_qemu = now_qemu + muldiv64((uint32_t) (s->timer[i].value - now_vm), get_ticks_per_sec(), s->freq); qemu_mod_timer(s->timer[i].qtimer, new_qemu); } }
static void virtio_net_handle_tx(VirtIODevice *vdev, VirtQueue *vq) { VirtIONet *n = to_virtio_net(vdev); if (n->tx_timer_active) { virtio_queue_set_notification(vq, 1); qemu_del_timer(n->tx_timer); n->tx_timer_active = 0; virtio_net_flush_tx(n, vq); } else { qemu_mod_timer(n->tx_timer, qemu_get_clock(vm_clock) + TX_TIMER_INTERVAL); n->tx_timer_active = 1; virtio_queue_set_notification(vq, 0); } }
static void mmc_send_command(S5pc1xxMMCState *s) { SDRequest request; uint8_t response[16]; int rlen; s->errintsts = 0; qemu_mod_timer(s->response_timer, qemu_get_clock(vm_clock)); if (!s->card) return; request.cmd = s->cmdreg >> 8; request.arg = s->cmdarg; DPRINTF("Command %d %08x\n", request.cmd, request.arg); rlen = sd_do_command(s->card, &request, response); if (rlen < 0) goto error; if ((s->cmdreg & CMD_RESPONSE) != 0) { #define RWORD(n) ((n >= 0 ? (response[n] << 24) : 0) \ | (response[n + 1] << 16) \ | (response[n + 2] << 8) \ | response[n + 3]) if (rlen == 0) goto error; if (rlen != 4 && rlen != 16) goto error; s->response[0] = RWORD(0); if (rlen == 4) { s->response[1] = s->response[2] = s->response[3] = 0; } else { s->response[0] = RWORD(11); s->response[1] = RWORD(7); s->response[2] = RWORD(3); s->response[3] = RWORD(-1); } DPRINTF("Response received\n"); #undef RWORD } else { DPRINTF("Command sent\n"); } return; error: DPRINTF("Timeout\n"); s->errintsts |= S5C_HSMMC_EIS_CMDTIMEOUT; }
QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state) { QEMUFileBuffered *s; s = g_malloc0(sizeof(*s)); s->migration_state = migration_state; s->xfer_limit = migration_state->bandwidth_limit / 10; s->file = qemu_fopen_ops(s, &buffered_file_ops); s->timer = qemu_new_timer_ms(rt_clock, buffered_rate_tick, s); qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 100); return s->file; }
static void iscsi_nop_timed_event(void *opaque) { IscsiLun *iscsilun = opaque; if (iscsi_get_nops_in_flight(iscsilun->iscsi) > MAX_NOP_FAILURES) { error_report("iSCSI: NOP timeout. Reconnecting..."); iscsi_reconnect(iscsilun->iscsi); } if (iscsi_nop_out_async(iscsilun->iscsi, NULL, NULL, 0, NULL) != 0) { error_report("iSCSI: failed to sent NOP-Out. Disabling NOP messages."); return; } qemu_mod_timer(iscsilun->nop_timer, qemu_get_clock_ms(rt_clock) + NOP_INTERVAL); iscsi_set_events(iscsilun); }
static void pm_update_sci(PIIX4PMState *s) { int sci_level, pmsts; int64_t expire_time; pmsts = get_pmsts(s); sci_level = (((pmsts & s->pmen) & (RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0); qemu_set_irq(s->irq, sci_level); /* schedule a timer interruption if needed */ if ((s->pmen & TMROF_EN) && !(pmsts & TMROF_EN)) { expire_time = muldiv64(s->tmr_overflow_time, get_ticks_per_sec(), PM_FREQ); qemu_mod_timer(s->tmr_timer, expire_time); } else { qemu_del_timer(s->tmr_timer); } }
/* 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); } }
static void buffered_rate_tick(void *opaque) { QEMUFileBuffered *s = opaque; if (qemu_file_get_error(s->file)) { buffered_close(s); return; } qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 100); if (s->freeze_output) return; s->bytes_xfer = 0; buffered_put_buffer(s, NULL, 0, 0); }
static uint32_t s5l8930_spi_mm_read(void *opaque, target_phys_addr_t offset) { S5L8930SPIState *s = (S5L8930SPIState *)opaque; // fprintf(stderr, "%s: base 0x%08x offset 0x%08x\n", __func__, s->base, offset); switch (offset) { case SPI_CONTROL: return s->ctrl; case SPI_SETUP: return s->setup; case SPI_STATUS: /* Strange that on fifo empty irq handler doesnt clear irq */ qemu_irq_lower(s->irq); return s->status; case SPI_PIN: return s->pin; case SPI_TXDATA: return s->tx_data[0]; case SPI_RXDATA: s->rx_data = pflash_cmd_parse(s->pflash); s->status |= pflash_cmd_len(s->pflash) << 11; //fprintf(stderr, "%s: rxBuf 0x%08x\n", __func__, s->rx_data); /* Queue fifo empty irq */ if(s->rxFifoCnt == 0x1e) { qemu_irq_lower(s->irq); qemu_mod_timer(s->timer, qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / 1000)); } else s->rxFifoCnt++; return s->rx_data; case SPI_CLKDIV: return s->clkdiv; case SPI_CNT: return s->cnt; case SPI_IDD: return s->idd; default: ; //fprintf(stderr, "%s: base 0x%08x offset 0x%08x\n", __func__, s->base, offset); //hw_error("s5l8930_spi: bad read offset 0x" TARGET_FMT_plx "\n", offset); } return 0; }
static void buffered_rate_tick(void *opaque) { QEMUFileBuffered *s = opaque; if (s->has_error) return; qemu_mod_timer(s->timer, qemu_get_clock(rt_clock) + 100); if (s->freeze_output) return; s->bytes_xfer = 0; buffered_flush(s); /* Add some checks around this */ s->put_ready(s->opaque); }
static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) { VirtIONet *n = opaque; if (version_id != 1) return -EINVAL; virtio_load(&n->vdev, f); qemu_get_buffer(f, n->mac, 6); n->tx_timer_active = qemu_get_be32(f); if (n->tx_timer_active) { qemu_mod_timer(n->tx_timer, qemu_get_clock(vm_clock) + TX_TIMER_INTERVAL); } return 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); } }
RTCState *rtc_init_sqw(int base, qemu_irq irq, qemu_irq sqw_irq, int base_year) { RTCState *s; s = qemu_mallocz(sizeof(RTCState)); s->irq = irq; s->sqw_irq = sqw_irq; s->cmos_data[RTC_REG_A] = 0x26; s->cmos_data[RTC_REG_B] = 0x02; s->cmos_data[RTC_REG_C] = 0x00; s->cmos_data[RTC_REG_D] = 0x80; s->base_year = base_year; rtc_set_date_from_host(s); s->periodic_timer = qemu_new_timer(vm_clock, rtc_periodic_timer, s); #ifdef TARGET_I386 if (rtc_td_hack) s->coalesced_timer = qemu_new_timer(vm_clock, rtc_coalesced_timer, s); #endif s->second_timer = qemu_new_timer(vm_clock, rtc_update_second, s); s->second_timer2 = qemu_new_timer(vm_clock, rtc_update_second2, s); s->next_second_time = qemu_get_clock(vm_clock) + (ticks_per_sec * 99) / 100; qemu_mod_timer(s->second_timer2, s->next_second_time); register_ioport_write(base, 2, 1, cmos_ioport_write, s); register_ioport_read(base, 2, 1, cmos_ioport_read, s); register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s); #ifdef TARGET_I386 if (rtc_td_hack) register_savevm("mc146818rtc-td", base, 1, rtc_save_td, rtc_load_td, s); #endif qemu_register_reset(rtc_reset, s); return s; }
static inline void csrhci_fifo_wake(struct csrhci_s *s) { if (!s->enable || !s->out_len) return; /* XXX: Should wait for s->modem_state & CHR_TIOCM_RTS? */ if (s->chr.chr_can_read && s->chr.chr_can_read(s->chr.handler_opaque) && s->chr.chr_read) { s->chr.chr_read(s->chr.handler_opaque, s->outfifo + s->out_start ++, 1); s->out_len --; if (s->out_start >= s->out_size) { s->out_start = 0; s->out_size = FIFO_LEN; } } if (s->out_len) qemu_mod_timer(s->out_tm, qemu_get_clock(vm_clock) + s->baud_delay); }