]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/i386/rtclock.c
xnu-3789.70.16.tar.gz
[apple/xnu.git] / osfmk / i386 / rtclock.c
index 9935839d90269cb8079553cd2fb46429a5b6adb5..6ed44cc7357b52b2e899081369c1caeeb7280390 100644 (file)
@@ -39,7 +39,6 @@
  *                     the cpu clock counted by the timestamp MSR.
  */
 
  *                     the cpu clock counted by the timestamp MSR.
  */
 
-#include <platforms.h>
 
 #include <mach/mach_types.h>
 
 
 #include <mach/mach_types.h>
 
@@ -72,8 +71,6 @@
 #include <i386/rtclock_protos.h>
 #define UI_CPUFREQ_ROUNDING_FACTOR     10000000
 
 #include <i386/rtclock_protos.h>
 #define UI_CPUFREQ_ROUNDING_FACTOR     10000000
 
-int            rtclock_config(void);
-
 int            rtclock_init(void);
 
 uint64_t       tsc_rebase_abs_time = 0;
 int            rtclock_init(void);
 
 uint64_t       tsc_rebase_abs_time = 0;
@@ -108,19 +105,6 @@ _absolutetime_to_nanotime(uint64_t abstime, clock_sec_t *secs, clock_usec_t *nan
        *nanosecs = (clock_usec_t)(abstime % (uint64_t)NSEC_PER_SEC);
 }
 
        *nanosecs = (clock_usec_t)(abstime % (uint64_t)NSEC_PER_SEC);
 }
 
-/*
- * 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
  * -----------------------------
 /*
  * Nanotime/mach_absolutime_time
  * -----------------------------
@@ -161,7 +145,7 @@ _rtc_nanotime_init(pal_rtc_nanotime_t *rntp, uint64_t base)
        _pal_rtc_nanotime_store(tsc, base, rntp->scale, rntp->shift, rntp);
 }
 
        _pal_rtc_nanotime_store(tsc, base, rntp->scale, rntp->shift, rntp);
 }
 
-static void
+void
 rtc_nanotime_init(uint64_t base)
 {
        _rtc_nanotime_init(&pal_rtc_nanotime_info, base);
 rtc_nanotime_init(uint64_t base)
 {
        _rtc_nanotime_init(&pal_rtc_nanotime_info, base);
@@ -271,7 +255,7 @@ rtc_sleep_wakeup(
        uint64_t                base)
 {
        /* Set fixed configuration for lapic timers */
        uint64_t                base)
 {
        /* Set fixed configuration for lapic timers */
-       rtc_timer->config();
+       rtc_timer->rtc_config();
 
        /*
         * Reset nanotime.
 
        /*
         * Reset nanotime.
@@ -281,6 +265,21 @@ rtc_sleep_wakeup(
        rtc_nanotime_init(base);
 }
 
        rtc_nanotime_init(base);
 }
 
+void
+rtc_decrementer_configure(void) {
+       rtc_timer->rtc_config();
+}
+/*
+ * 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.
 /*
  * Initialize the real-time clock device.
  * In addition, various variables used to support the clock are initialized.
@@ -295,7 +294,6 @@ rtclock_init(void)
        if (cpu_number() == master_cpu) {
 
                assert(tscFreq);
        if (cpu_number() == master_cpu) {
 
                assert(tscFreq);
-               rtc_set_timescale(tscFreq);
 
                /*
                 * Adjust and set the exported cpu speed.
 
                /*
                 * Adjust and set the exported cpu speed.
@@ -316,7 +314,7 @@ rtclock_init(void)
        }
 
        /* Set fixed configuration for lapic timers */
        }
 
        /* Set fixed configuration for lapic timers */
-       rtc_timer->config();
+       rtc_timer->rtc_config();
        rtc_timer_start();
 
        return (1);
        rtc_timer_start();
 
        return (1);
@@ -338,15 +336,19 @@ rtc_set_timescale(uint64_t cycles)
                cycles <<= 1;
        }
        
                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;
 
        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)
        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);
 }
 
        rtc_nanotime_init(0);
 }
@@ -354,8 +356,12 @@ rtc_set_timescale(uint64_t cycles)
 static uint64_t
 rtc_export_speed(uint64_t cyc_per_sec)
 {
 static uint64_t
 rtc_export_speed(uint64_t cyc_per_sec)
 {
+       pal_rtc_nanotime_t      *rntp = &pal_rtc_nanotime_info;
        uint64_t        cycles;
 
        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)
        /* Round: */
         cycles = ((cyc_per_sec + (UI_CPUFREQ_ROUNDING_FACTOR/2))
                        / UI_CPUFREQ_ROUNDING_FACTOR)
@@ -461,8 +467,7 @@ rtclock_intr(
  */
 
 uint64_t
  */
 
 uint64_t
-setPop(
-       uint64_t time)
+setPop(uint64_t time)
 {
        uint64_t        now;
        uint64_t        pop;
 {
        uint64_t        now;
        uint64_t        pop;
@@ -471,10 +476,10 @@ setPop(
        if (time == 0 || time == EndOfAllTime ) {
                time = EndOfAllTime;
                now = 0;
        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 */
        } 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 */
        }
 
        /* Record requested and actual deadlines set */
@@ -490,6 +495,12 @@ mach_absolute_time(void)
        return rtc_nanotime_read();
 }
 
        return rtc_nanotime_read();
 }
 
+uint64_t
+mach_approximate_time(void)
+{
+       return rtc_nanotime_read();
+}
+
 void
 clock_interval_to_absolutetime_interval(
        uint32_t                interval,
 void
 clock_interval_to_absolutetime_interval(
        uint32_t                interval,
@@ -508,15 +519,6 @@ absolutetime_to_microtime(
        _absolutetime_to_microtime(abstime, secs, microsecs);
 }
 
        _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,
 void
 nanotime_to_absolutetime(
        clock_sec_t                     secs,