10 #include <linux/kernel.h>
19 #include <asm/xen/hypervisor.h>
20 #include <asm/xen/hypercall.h>
22 #include <xen/events.h>
30 #define TIMER_SLOP 100000
31 #define NS_PER_TICK (1000000000LL / HZ)
63 }
while (p32[1] != h);
65 ret = (((
u64)h) << 32) | l;
114 static void do_stolen_accounting(
void)
121 get_runstate_snapshot(&state);
158 static unsigned long xen_tsc_khz(
void)
183 static void xen_read_wallclock(
struct timespec *
ts)
194 static unsigned long xen_get_wallclock(
void)
198 xen_read_wallclock(&
ts);
202 static int xen_set_wallclock(
unsigned long now)
212 op.u.settime.secs = now;
213 op.u.settime.nsecs = 0;
216 rc = HYPERVISOR_dom0_op(&
op);
217 WARN(rc != 0,
"XENPF_settime failed: now=%ld\n", now);
225 .read = xen_clocksource_get_cycles,
261 static s64 get_abs_timeout(
unsigned long delta)
266 static void xen_timerop_set_mode(
enum clock_event_mode
mode,
267 struct clock_event_device *
evt)
270 case CLOCK_EVT_MODE_PERIODIC:
275 case CLOCK_EVT_MODE_ONESHOT:
276 case CLOCK_EVT_MODE_RESUME:
279 case CLOCK_EVT_MODE_UNUSED:
280 case CLOCK_EVT_MODE_SHUTDOWN:
281 HYPERVISOR_set_timer_op(0);
286 static int xen_timerop_set_next_event(
unsigned long delta,
287 struct clock_event_device *evt)
289 WARN_ON(evt->mode != CLOCK_EVT_MODE_ONESHOT);
291 if (HYPERVISOR_set_timer_op(get_abs_timeout(delta)) < 0)
301 static const struct clock_event_device xen_timerop_clockevent = {
303 .features = CLOCK_EVT_FEAT_ONESHOT,
305 .max_delta_ns = 0xffffffff,
312 .set_mode = xen_timerop_set_mode,
313 .set_next_event = xen_timerop_set_next_event,
318 static void xen_vcpuop_set_mode(
enum clock_event_mode mode,
319 struct clock_event_device *evt)
324 case CLOCK_EVT_MODE_PERIODIC:
328 case CLOCK_EVT_MODE_ONESHOT:
333 case CLOCK_EVT_MODE_UNUSED:
334 case CLOCK_EVT_MODE_SHUTDOWN:
339 case CLOCK_EVT_MODE_RESUME:
344 static int xen_vcpuop_set_next_event(
unsigned long delta,
345 struct clock_event_device *evt)
351 WARN_ON(evt->mode != CLOCK_EVT_MODE_ONESHOT);
353 single.timeout_abs_ns = get_abs_timeout(delta);
363 static const struct clock_event_device xen_vcpuop_clockevent = {
365 .features = CLOCK_EVT_FEAT_ONESHOT,
367 .max_delta_ns = 0xffffffff,
374 .set_mode = xen_vcpuop_set_mode,
375 .set_next_event = xen_vcpuop_set_next_event,
378 static const struct clock_event_device *xen_clockevent =
379 &xen_timerop_clockevent;
380 static DEFINE_PER_CPU(
struct clock_event_device, xen_clock_events);
384 struct clock_event_device *evt = &
__get_cpu_var(xen_clock_events);
388 if (evt->event_handler) {
389 evt->event_handler(evt);
393 do_stolen_accounting();
401 struct clock_event_device *
evt;
408 name =
"<timer kasprintf failed>";
416 evt = &
per_cpu(xen_clock_events, cpu);
417 memcpy(evt, xen_clockevent,
sizeof(*evt));
425 struct clock_event_device *
evt;
427 evt = &
per_cpu(xen_clock_events, cpu);
444 if (xen_clockevent != &xen_vcpuop_clockevent)
457 static void __init xen_time_init(
void)
462 clocksource_register_hz(&xen_clocksource,
NSEC_PER_SEC);
468 xen_clockevent = &xen_vcpuop_clockevent;
472 xen_read_wallclock(&tp);
486 x86_init.timers.timer_init = xen_time_init;
495 #ifdef CONFIG_XEN_PVHVM
496 static void xen_hvm_setup_cpu_clockevents(
void)
513 "disable pv timer\n");
518 x86_init.timers.setup_percpu_clockev = xen_time_init;
519 x86_cpuinit.setup_percpu_clockev = xen_hvm_setup_cpu_clockevents;