[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: Reintroduce clocksource=tsc.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1216633155 -3600 # Node ID 85a83b919653378db803882286fa156079c7cd69 # Parent a0ce4b04011493286a18d7f0b3d62ad5aff6412d x86: Reintroduce clocksource=tsc. Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/time.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 70 insertions(+), 8 deletions(-) diff -r a0ce4b040114 -r 85a83b919653 xen/arch/x86/time.c --- a/xen/arch/x86/time.c Mon Jul 21 10:00:18 2008 +0100 +++ b/xen/arch/x86/time.c Mon Jul 21 10:39:15 2008 +0100 @@ -481,6 +481,35 @@ static int init_pmtimer(struct platform_ } /************************************************************ + * PLATFORM TIMER 5: TSC + */ + +static const char plt_tsc_name[] = "TSC"; +#define platform_timer_is_tsc() (plt_src.name == plt_tsc_name) + +static int init_tsctimer(struct platform_timesource *pts) +{ + if ( !tsc_invariant ) + return 0; + + pts->name = (char *)plt_tsc_name; + return 1; +} + +static void make_tsctimer_record(void) +{ + struct cpu_time *t = &this_cpu(cpu_time); + s_time_t now; + u64 tsc; + + rdtscll(tsc); + now = scale_delta(tsc, &t->tsc_scale); + + t->local_tsc_stamp = tsc; + t->stime_local_stamp = t->stime_master_stamp = now; +} + +/************************************************************ * GENERIC PLATFORM TIMER INFRASTRUCTURE */ @@ -545,6 +574,12 @@ static void platform_time_calibration(vo static void resume_platform_timer(void) { + if ( platform_timer_is_tsc() ) + { + /* TODO: Save/restore TSC values. */ + return; + } + /* No change in platform_stime across suspend/resume. */ platform_timer_stamp = plt_stamp64; plt_stamp = plt_src.read_counter(); @@ -565,6 +600,8 @@ static void init_platform_timer(void) rc = init_cyclone(pts); else if ( !strcmp(opt_clocksource, "acpi") ) rc = init_pmtimer(pts); + else if ( !strcmp(opt_clocksource, "tsc") ) + rc = init_tsctimer(pts); if ( rc <= 0 ) printk("WARNING: %s clocksource '%s'.\n", @@ -577,6 +614,12 @@ static void init_platform_timer(void) !init_hpet(pts) && !init_pmtimer(pts) ) init_pit(pts); + + if ( platform_timer_is_tsc() ) + { + printk("Platform timer is TSC\n"); + return; + } plt_mask = (u64)~0ull >> (64 - pts->counter_bits); @@ -780,6 +823,10 @@ int cpu_frequency_change(u64 freq) struct cpu_time *t = &this_cpu(cpu_time); u64 curr_tsc; + /* Nothing to do if TSC is platform timer. Assume it is constant-rate. */ + if ( platform_timer_is_tsc() ) + return 0; + /* Sanity check: CPU frequency allegedly dropping below 1MHz? */ if ( freq < 1000000u ) { @@ -861,6 +908,14 @@ static void local_time_calibration(void /* The overall calibration scale multiplier. */ u32 calibration_mul_frac; + if ( platform_timer_is_tsc() ) + { + make_tsctimer_record(); + update_vcpu_system_time(current); + set_timer(&t->calibration_timer, NOW() + MILLISECS(10*1000)); + return; + } + prev_tsc = t->local_tsc_stamp; prev_local_stime = t->stime_local_stamp; prev_master_stime = t->stime_master_stamp; @@ -978,6 +1033,12 @@ void init_percpu_time(void) unsigned long flags; s_time_t now; + if ( platform_timer_is_tsc() ) + { + make_tsctimer_record(); + goto out; + } + local_irq_save(flags); rdtscll(t->local_tsc_stamp); now = !plt_src.read_counter ? 0 : read_platform_stime(); @@ -986,6 +1047,7 @@ void init_percpu_time(void) t->stime_master_stamp = now; t->stime_local_stamp = now; + out: init_timer(&t->calibration_timer, local_time_calibration, NULL, smp_processor_id()); set_timer(&t->calibration_timer, NOW() + EPOCH); @@ -994,19 +1056,19 @@ void init_percpu_time(void) /* Late init function (after all CPUs are booted). */ int __init init_xen_time(void) { - wc_sec = get_cmos_time(); - local_irq_disable(); + + /* check if TSC is invariant during deep C state + this is a new feature introduced by Nehalem*/ + if ( cpuid_edx(0x80000007) & (1u<<8) ) + tsc_invariant = 1; init_percpu_time(); stime_platform_stamp = 0; init_platform_timer(); - /* check if TSC is invariant during deep C state - this is a new feature introduced by Nehalem*/ - if ( cpuid_edx(0x80000007) & (1U<<8) ) - tsc_invariant = 1; + do_settime(get_cmos_time(), 0, NOW()); local_irq_enable(); @@ -1120,9 +1182,9 @@ int time_resume(void) resume_platform_timer(); - do_settime(get_cmos_time() + cmos_utc_offset, 0, read_platform_stime()); - init_percpu_time(); + + do_settime(get_cmos_time() + cmos_utc_offset, 0, NOW()); if ( !is_idle_vcpu(current) ) update_vcpu_system_time(current); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |