2 #include "../port/lib.h"
8 static vcpu_time_info_t shadow[MAX_VIRT_CPUS]; // XXX should be in Mach
9 static ulong wallclock;
10 static ulong wallclocksystime;
13 * Return a consistent set of time parameters.
15 static vcpu_time_info_t *
18 vcpu_time_info_t *s, *t;
20 t = &HYPERVISOR_shared_info->vcpu_info[m->machno].time;
21 s = &shadow[m->machno]; // XXX place in mach struct
22 while(t->version != s->version) {
25 s->version = t->version;
26 s->tsc_timestamp = t->tsc_timestamp;
27 s->system_time = t->system_time;
28 s->tsc_to_system_mul = t->tsc_to_system_mul;
29 s->tsc_shift = t->tsc_shift;
35 /* just get it from the shared info */
37 guesscpuhz(int) // XXX no arg!
42 m->cpuhz = (1000000000LL << 32) / t->tsc_to_system_mul;
44 m->cpuhz <<= -t->tsc_shift;
46 m->cpuhz >>= t->tsc_shift;
47 m->cpumhz = m->cpuhz / 1000000L;
51 xentimerset(uvlong next)
55 soon = fastticks(0) + 100000;
58 HYPERVISOR_set_timer_op(next);
62 xentimerclock(Ureg* ureg, void*)
71 intrenable(VIRQ_TIMER, xentimerclock, nil, 0, "Xen Timer");
75 xentimerread(uvlong *hz)
83 delta = x - t->tsc_timestamp;
85 delta >>= -t->tsc_shift;
87 delta <<= t->tsc_shift;
88 mul64fract(&sdelta, delta, t->tsc_to_system_mul);
89 x = t->system_time + sdelta;
90 if (HYPERVISOR_shared_info->wc_sec != wallclock) {
91 wallclock = HYPERVISOR_shared_info->wc_sec;
104 elapsed = (ulong)((xentimerread(0) - wallclocksystime)/1000000000);
105 return wallclock + elapsed;
109 microdelay(int microsecs)
113 targ = xentimerread(&hz);
114 targ += microsecs * hz / 1000000;
115 while(xentimerread(0) < targ)
122 microdelay(millisecs * 1000);
126 * performance measurement ticks. must be low overhead.
127 * doesn't have to count over a second.