X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/bd504ef0e0b883cdd7917b73b3574eb9ce669905..c18c124eaa464aaaa5549e99e5a70fc9cbb50944:/osfmk/i386/rtclock.c diff --git a/osfmk/i386/rtclock.c b/osfmk/i386/rtclock.c index 28354563c..d0a2ed840 100644 --- a/osfmk/i386/rtclock.c +++ b/osfmk/i386/rtclock.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2010 Apple Inc. All rights reserved. + * Copyright (c) 2000-2012 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -39,7 +39,6 @@ * the cpu clock counted by the timestamp MSR. */ -#include #include @@ -51,7 +50,7 @@ #include #include #include -#include +#include #include #include #include /* for kernel_map */ @@ -70,11 +69,8 @@ #include #include #include - #define UI_CPUFREQ_ROUNDING_FACTOR 10000000 -int rtclock_config(void); - int rtclock_init(void); uint64_t tsc_rebase_abs_time = 0; @@ -88,61 +84,27 @@ rtc_timer_start(void) /* * Force a complete re-evaluation of timer deadlines. */ - etimer_resync_deadlines(); + x86_lcpu()->rtcDeadline = EndOfAllTime; + timer_resync_deadlines(); } static inline uint32_t _absolutetime_to_microtime(uint64_t abstime, clock_sec_t *secs, clock_usec_t *microsecs) { uint32_t remain; -#if defined(__i386__) - asm volatile( - "divl %3" - : "=a" (*secs), "=d" (remain) - : "A" (abstime), "r" (NSEC_PER_SEC)); - asm volatile( - "divl %3" - : "=a" (*microsecs) - : "0" (remain), "d" (0), "r" (NSEC_PER_USEC)); -#elif defined(__x86_64__) *secs = abstime / (uint64_t)NSEC_PER_SEC; remain = (uint32_t)(abstime % (uint64_t)NSEC_PER_SEC); *microsecs = remain / NSEC_PER_USEC; -#else -#error Unsupported architecture -#endif return remain; } static inline void _absolutetime_to_nanotime(uint64_t abstime, clock_sec_t *secs, clock_usec_t *nanosecs) { -#if defined(__i386__) - asm volatile( - "divl %3" - : "=a" (*secs), "=d" (*nanosecs) - : "A" (abstime), "r" (NSEC_PER_SEC)); -#elif defined(__x86_64__) *secs = abstime / (uint64_t)NSEC_PER_SEC; *nanosecs = (clock_usec_t)(abstime % (uint64_t)NSEC_PER_SEC); -#else -#error Unsupported architecture -#endif } -/* - * Configure the real-time clock device. Return success (1) - * or failure (0). - */ - -int -rtclock_config(void) -{ - /* nothing to do */ - return (1); -} - - /* * Nanotime/mach_absolutime_time * ----------------------------- @@ -245,7 +207,6 @@ rtc_clock_napped(uint64_t base, uint64_t tsc_base) if (oldnsecs < newnsecs) { _pal_rtc_nanotime_store(tsc_base, base, rntp->scale, rntp->shift, rntp); rtc_nanotime_set_commpage(rntp); - trace_set_timebases(tsc_base, base); } } @@ -294,7 +255,7 @@ rtc_sleep_wakeup( uint64_t base) { /* Set fixed configuration for lapic timers */ - rtc_timer->config(); + rtc_timer->rtc_config(); /* * Reset nanotime. @@ -304,6 +265,17 @@ rtc_sleep_wakeup( rtc_nanotime_init(base); } +/* + * rtclock_early_init() is called very early at boot to + * establish mach_absolute_time() and set it to zero. + */ +void +rtclock_early_init(void) +{ + assert(tscFreq); + rtc_set_timescale(tscFreq); +} + /* * Initialize the real-time clock device. * In addition, various variables used to support the clock are initialized. @@ -318,7 +290,6 @@ rtclock_init(void) if (cpu_number() == master_cpu) { assert(tscFreq); - rtc_set_timescale(tscFreq); /* * Adjust and set the exported cpu speed. @@ -339,7 +310,7 @@ rtclock_init(void) } /* Set fixed configuration for lapic timers */ - rtc_timer->config(); + rtc_timer->rtc_config(); rtc_timer_start(); return (1); @@ -361,15 +332,19 @@ rtc_set_timescale(uint64_t cycles) cycles <<= 1; } - if ( shift != 0 ) - printf("Slow TSC, rtc_nanotime.shift == %d\n", shift); - rntp->scale = (uint32_t)(((uint64_t)NSEC_PER_SEC << 32) / cycles); rntp->shift = shift; + /* + * On some platforms, the TSC is not reset at warm boot. But the + * rebase time must be relative to the current boot so we can't use + * mach_absolute_time(). Instead, we convert the TSC delta since boot + * to nanoseconds. + */ if (tsc_rebase_abs_time == 0) - tsc_rebase_abs_time = mach_absolute_time(); + tsc_rebase_abs_time = _rtc_tsc_to_nanoseconds( + rdtsc64() - tsc_at_boot, rntp); rtc_nanotime_init(0); } @@ -377,8 +352,12 @@ rtc_set_timescale(uint64_t cycles) static uint64_t rtc_export_speed(uint64_t cyc_per_sec) { + pal_rtc_nanotime_t *rntp = &pal_rtc_nanotime_info; uint64_t cycles; + if (rntp->shift != 0 ) + printf("Slow TSC, rtc_nanotime.shift == %d\n", rntp->shift); + /* Round: */ cycles = ((cyc_per_sec + (UI_CPUFREQ_ROUNDING_FACTOR/2)) / UI_CPUFREQ_ROUNDING_FACTOR) @@ -475,7 +454,7 @@ rtclock_intr( } /* call the generic etimer */ - etimer_intr(user_mode, rip); + timer_intr(user_mode, rip); } @@ -484,8 +463,7 @@ rtclock_intr( */ uint64_t -setPop( - uint64_t time) +setPop(uint64_t time) { uint64_t now; uint64_t pop; @@ -494,10 +472,10 @@ setPop( if (time == 0 || time == EndOfAllTime ) { time = EndOfAllTime; now = 0; - pop = rtc_timer->set(0, 0); + pop = rtc_timer->rtc_set(0, 0); } else { now = rtc_nanotime_read(); /* The time in nanoseconds */ - pop = rtc_timer->set(time, now); + pop = rtc_timer->rtc_set(time, now); } /* Record requested and actual deadlines set */ @@ -531,15 +509,6 @@ absolutetime_to_microtime( _absolutetime_to_microtime(abstime, secs, microsecs); } -void -absolutetime_to_nanotime( - uint64_t abstime, - clock_sec_t *secs, - clock_nsec_t *nanosecs) -{ - _absolutetime_to_nanotime(abstime, secs, nanosecs); -} - void nanotime_to_absolutetime( clock_sec_t secs, @@ -567,11 +536,11 @@ nanoseconds_to_absolutetime( void machine_delay_until( - uint64_t interval, - uint64_t deadline) + uint64_t interval, + uint64_t deadline) { - (void)interval; - while (mach_absolute_time() < deadline) { - cpu_pause(); - } + (void)interval; + while (mach_absolute_time() < deadline) { + cpu_pause(); + } }