diff options
author | rn@wyvis.camb.intel-research.net <rn@wyvis.camb.intel-research.net> | 2003-01-30 19:35:24 +0000 |
---|---|---|
committer | rn@wyvis.camb.intel-research.net <rn@wyvis.camb.intel-research.net> | 2003-01-30 19:35:24 +0000 |
commit | 9062553a0dc188eaf5f0fa001dbe92e64a7d64e9 (patch) | |
tree | 8a21d6af1b57302389695fc71fa61a01813dda5e /xenolinux-2.4.16-sparse | |
parent | 22a857bde9b89547d682aa92bb226096119b0223 (diff) | |
download | xen-9062553a0dc188eaf5f0fa001dbe92e64a7d64e9.tar.gz xen-9062553a0dc188eaf5f0fa001dbe92e64a7d64e9.tar.bz2 xen-9062553a0dc188eaf5f0fa001dbe92e64a7d64e9.zip |
bitkeeper revision 1.14.1.1 (3e397e7cPGmZK7y5LLOGYa43nTQMUw)
added time and accurate timer support
partially there for better scheduler (most of the infrastructure should be there)
Diffstat (limited to 'xenolinux-2.4.16-sparse')
4 files changed, 35 insertions, 67 deletions
diff --git a/xenolinux-2.4.16-sparse/arch/xeno/kernel/i386_ksyms.c b/xenolinux-2.4.16-sparse/arch/xeno/kernel/i386_ksyms.c index 12db77164b..a35ef1cc8a 100644 --- a/xenolinux-2.4.16-sparse/arch/xeno/kernel/i386_ksyms.c +++ b/xenolinux-2.4.16-sparse/arch/xeno/kernel/i386_ksyms.c @@ -42,7 +42,7 @@ extern struct drive_info_struct drive_info; EXPORT_SYMBOL(drive_info); #endif -extern unsigned long get_cmos_time(void); +//extern unsigned long get_cmos_time(void); /* platform dependent support */ EXPORT_SYMBOL(boot_cpu_data); @@ -58,7 +58,7 @@ EXPORT_SYMBOL(probe_irq_mask); EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(pm_idle); EXPORT_SYMBOL(pm_power_off); -EXPORT_SYMBOL(get_cmos_time); +//EXPORT_SYMBOL(get_cmos_time); EXPORT_SYMBOL(apm_info); #ifdef CONFIG_DEBUG_IOVIRT diff --git a/xenolinux-2.4.16-sparse/arch/xeno/kernel/process.c b/xenolinux-2.4.16-sparse/arch/xeno/kernel/process.c index 9e26f3d65a..608049ece0 100644 --- a/xenolinux-2.4.16-sparse/arch/xeno/kernel/process.c +++ b/xenolinux-2.4.16-sparse/arch/xeno/kernel/process.c @@ -86,7 +86,7 @@ void cpu_idle (void) while (1) { while (!current->need_resched) - HYPERVISOR_yield(); + HYPERVISOR_do_sched_op(NULL); schedule(); check_pgt_cache(); } diff --git a/xenolinux-2.4.16-sparse/arch/xeno/kernel/time.c b/xenolinux-2.4.16-sparse/arch/xeno/kernel/time.c index c728eb15e6..2557918c6d 100644 --- a/xenolinux-2.4.16-sparse/arch/xeno/kernel/time.c +++ b/xenolinux-2.4.16-sparse/arch/xeno/kernel/time.c @@ -102,47 +102,26 @@ static inline unsigned long ticks_to_us(unsigned long ticks) return(hi); } -static inline unsigned long do_gettimeoffset(void) +static long long get_s_time(void) { -#if 0 - register unsigned long eax, edx; - - /* Read the Time Stamp Counter */ - - rdtsc(eax,edx); - - /* .. relative to previous jiffy (32 bits is enough) */ - eax -= last_tsc_low; /* tsc_low delta */ - - /* - * Time offset = (tsc_low delta) * fast_gettimeoffset_quotient - * = (tsc_low delta) * (usecs_per_clock) - * = (tsc_low delta) * (usecs_per_jiffy / clocks_per_jiffy) - * - * Using a mull instead of a divl saves up to 31 clock cycles - * in the critical path. - */ - - edx = ticks_to_us(eax); - - /* our adjusted time offset in microseconds */ - return delay_at_last_interrupt + edx; -#else - /* - * We should keep a 'last_tsc_low' thing which incorporates - * delay_at_last_interrupt, adjusted in timer_interrupt after - * do_timer_interrupt. It would look at change in xtime, and - * make appropriate adjustment to a last_tsc variable. - * - * We'd be affected by rounding error in ticks_per_usec, and by - * processor clock drift (which should be no more than in an - * external interrupt source anyhow). - * - * Perhaps a bit rough and ready, but never mind! - */ - return 0; -#endif + u32 delta, low, pcc; + long long now; + long long incr; + + /* read two values (pcc, now) "atomically" */ +again: + pcc = HYPERVISOR_shared_info->st_timestamp; + now = HYPERVISOR_shared_info->system_time; + if (HYPERVISOR_shared_info->st_timestamp != pcc) goto again; + + /* only use bottom 32bits of TSC. This should be sufficient */ + rdtscl(low); + delta = low - pcc; + + incr = ((long long)(ticks_to_us(delta)*1000)); + return now + incr; } +#define NOW() ((long long)get_s_time()) /* * This version of gettimeofday has microsecond resolution @@ -151,15 +130,15 @@ static inline unsigned long do_gettimeoffset(void) void do_gettimeofday(struct timeval *tv) { unsigned long flags; - unsigned long usec, sec, lost; + unsigned long usec, sec; read_lock_irqsave(&xtime_lock, flags); - usec = do_gettimeoffset(); - lost = jiffies - wall_jiffies; - if ( lost != 0 ) usec += lost * (1000000 / HZ); - sec = xtime.tv_sec; - usec += xtime.tv_usec; - read_unlock_irqrestore(&xtime_lock, flags); + + usec = ((unsigned long)(NOW()-HYPERVISOR_shared_info->wc_timestamp))/1000; + sec = HYPERVISOR_shared_info->tv_sec; + usec += HYPERVISOR_shared_info->tv_usec; + + read_unlock_irqrestore(&xtime_lock, flags); while ( usec >= 1000000 ) { @@ -173,6 +152,8 @@ void do_gettimeofday(struct timeval *tv) void do_settimeofday(struct timeval *tv) { +/* XXX RN: shoudl do something special here for dom0 */ +#if 0 write_lock_irq(&xtime_lock); /* * This is revolting. We need to set "xtime" correctly. However, the @@ -195,6 +176,7 @@ void do_settimeofday(struct timeval *tv) time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; write_unlock_irq(&xtime_lock); +#endif } @@ -235,19 +217,6 @@ static struct irqaction irq_timer = { }; -unsigned long get_cmos_time(void) -{ - unsigned long secs = HYPERVISOR_shared_info->rtc_time; - unsigned long diff; - - rdtscl(diff); - diff -= (unsigned long)HYPERVISOR_shared_info->rtc_timestamp; - - secs += ticks_to_us(diff); - - return(secs + ticks_to_secs(diff)); -} - /* Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset(). */ static unsigned long __init calibrate_tsc(void) @@ -268,7 +237,6 @@ void __init time_init(void) unsigned long long alarm; fast_gettimeoffset_quotient = calibrate_tsc(); - do_get_fast_time = do_gettimeofday; /* report CPU clock rate in Hz. * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) = @@ -299,6 +267,5 @@ void __init time_init(void) HYPERVISOR_shared_info->domain_timeout = ~0ULL; clear_bit(_EVENT_TIMER, &HYPERVISOR_shared_info->events); - xtime.tv_sec = get_cmos_time(); - xtime.tv_usec = 0; + do_gettimeofday(&xtime); } diff --git a/xenolinux-2.4.16-sparse/include/asm-xeno/hypervisor.h b/xenolinux-2.4.16-sparse/include/asm-xeno/hypervisor.h index 839feed153..0d0940c9bb 100644 --- a/xenolinux-2.4.16-sparse/include/asm-xeno/hypervisor.h +++ b/xenolinux-2.4.16-sparse/include/asm-xeno/hypervisor.h @@ -203,12 +203,13 @@ static inline int HYPERVISOR_fpu_taskswitch(void) return ret; } -static inline int HYPERVISOR_yield(void) +static inline int HYPERVISOR_do_sched_op(void *sched_op) { int ret; __asm__ __volatile__ ( TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_yield) ); + : "=a" (ret) : "0" (__HYPERVISOR_sched_op), + "b" (sched_op) ); return ret; } |