static void pit_timer_start_cntr0(struct vatpit *vatpit) { struct channel *c; sbintime_t now, delta, precision; c = &vatpit->channel[0]; if (c->initial != 0) { delta = c->initial * vatpit->freq_sbt; precision = delta >> tc_precexp; c->callout_sbt = c->callout_sbt + delta; /* * Reset 'callout_sbt' if the time that the callout * was supposed to fire is more than 'c->initial' * ticks in the past. */ now = sbinuptime(); if (c->callout_sbt < now) c->callout_sbt = now + delta; callout_reset_sbt(&c->callout, c->callout_sbt, precision, vatpit_callout_handler, &c->callout_arg, C_ABSOLUTE); }
struct vpmtmr * vpmtmr_init(struct vm *vm) { struct vpmtmr *vpmtmr; struct bintime bt; vpmtmr = malloc(sizeof(struct vpmtmr), M_VPMTMR, M_WAITOK | M_ZERO); vpmtmr->baseuptime = sbinuptime(); vpmtmr->baseval = 0; FREQ2BT(PMTMR_FREQ, &bt); vpmtmr->freq_sbt = bttosbt(bt); return (vpmtmr); }
struct vpmtmr * vpmtmr_init(UNUSED struct vm *vm) { struct vpmtmr *vpmtmr; struct bintime bt; vpmtmr = malloc(sizeof(struct vpmtmr)); assert(vpmtmr); bzero(vpmtmr, sizeof(struct vpmtmr)); vpmtmr->baseuptime = sbinuptime(); vpmtmr->baseval = 0; FREQ2BT(PMTMR_FREQ, &bt); vpmtmr->freq_sbt = bttosbt(bt); return (vpmtmr); }
static int vatpit_get_out(struct vatpit *vatpit, int channel) { struct channel *c; sbintime_t delta_ticks; int out; c = &vatpit->channel[channel]; switch (c->mode) { case TIMER_INTTC: delta_ticks = (sbinuptime() - c->now_sbt) / vatpit->freq_sbt; out = ((c->initial - delta_ticks) <= 0); break; default: out = 0; break; } return (out); }
int vpmtmr_handler(struct vm *vm, UNUSED int vcpuid, bool in, UNUSED int port, int bytes, uint32_t *val) { struct vpmtmr *vpmtmr; sbintime_t now, delta; if (!in || bytes != 4) return (-1); vpmtmr = vm_pmtmr(vm); /* * No locking needed because 'baseuptime' and 'baseval' are * written only during initialization. */ now = sbinuptime(); delta = now - vpmtmr->baseuptime; KASSERT(delta >= 0, ("vpmtmr_handler: uptime went backwards: " "%#llx to %#llx", vpmtmr->baseuptime, now)); *val = (uint32_t) (vpmtmr->baseval + (delta / vpmtmr->freq_sbt)); return (0); }