[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] RTC: use offset to caculate rtc clock



# HG changeset patch
# User Yang Zhang <yang.z.zhang@xxxxxxxxx>
# Date 1331105660 0
# Node ID 6deb0b626f3f5fba073da01035e3b5864e54938c
# Parent  50a70b652b43aacbf923007ba8f645c5024ab698
RTC: use offset to caculate rtc clock

There has no need to run two periodic timer to update RTC time.
Use the offset instead.

Signed-off-by: Yang Zhang <yang.z.zhang@xxxxxxxxx>
Committed-by: Keir Fraser <keir@xxxxxxx>
---


diff -r 50a70b652b43 -r 6deb0b626f3f xen/arch/x86/hvm/rtc.c
--- a/xen/arch/x86/hvm/rtc.c    Wed Mar 07 07:30:30 2012 +0000
+++ b/xen/arch/x86/hvm/rtc.c    Wed Mar 07 07:34:20 2012 +0000
@@ -36,6 +36,8 @@
 #define epoch_year     1900
 #define get_year(x)    (x + epoch_year)
 
+static void rtc_copy_date(RTCState *s);
+
 static void rtc_periodic_cb(struct vcpu *v, void *opaque)
 {
     RTCState *s = opaque;
@@ -75,6 +77,7 @@
 static int rtc_ioport_write(void *opaque, uint32_t addr, uint32_t data)
 {
     RTCState *s = opaque;
+    struct domain *d = vrtc_domain(s);
 
     spin_lock(&s->lock);
 
@@ -122,6 +125,12 @@
         {
             /* set mode: reset UIP mode */
             s->hw.cmos_data[RTC_REG_A] &= ~RTC_UIP;
+            /* adjust cmos before stopping */
+            if (!(s->hw.cmos_data[RTC_REG_B] & RTC_SET))
+            {
+                s->current_tm = gmtime(get_localtime(d));
+                rtc_copy_date(s);
+            }
         }
         else
         {
@@ -218,156 +227,10 @@
     s->hw.cmos_data[RTC_YEAR] = to_bcd(s, tm->tm_year % 100);
 }
 
-/* month is between 0 and 11. */
-static int get_days_in_month(int month, int year)
-{
-    static const int days_tab[12] = { 
-        31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 
-    };
-    int d;
-    if ( (unsigned)month >= 12 )
-        return 31;
-    d = days_tab[month];
-    if ( month == 1 )
-        if ( (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0) )
-            d++;
-    return d;
-}
-
-/* update 'tm' to the next second */
-static void rtc_next_second(RTCState *s)
-{
-    struct tm *tm = &s->current_tm;
-    int days_in_month;
-
-    ASSERT(spin_is_locked(&s->lock));
-
-    tm->tm_sec++;
-    if ( (unsigned)tm->tm_sec >= 60 )
-    {
-        tm->tm_sec = 0;
-        tm->tm_min++;
-        if ( (unsigned)tm->tm_min >= 60 )
-        {
-            tm->tm_min = 0;
-            tm->tm_hour++;
-            if ( (unsigned)tm->tm_hour >= 24 )
-            {
-                tm->tm_hour = 0;
-                /* next day */
-                tm->tm_wday++;
-                if ( (unsigned)tm->tm_wday >= 7 )
-                    tm->tm_wday = 0;
-                days_in_month = get_days_in_month(tm->tm_mon, 
-                                                  get_year(tm->tm_year));
-                tm->tm_mday++;
-                if ( tm->tm_mday < 1 )
-                {
-                    tm->tm_mday = 1;
-                }
-                else if ( tm->tm_mday > days_in_month )
-                {
-                    tm->tm_mday = 1;
-                    tm->tm_mon++;
-                    if ( tm->tm_mon >= 12 )
-                    {
-                        tm->tm_mon = 0;
-                        tm->tm_year++;
-                    }
-                }
-            }
-        }
-    }
-}
-
-static void rtc_update_second(void *opaque)
-{
-    RTCState *s = opaque;
-    s_time_t now = NOW();
-
-    spin_lock(&s->lock);
-
-    /* If we somehow get way out of sync (say, Xen time leaps forward), 
-     * don't livelock the system trying to emulate every second.  Time 
-     * is already in bad trouble, so just skip forward rather than 
-     * trying to sync the RTC registers */
-    if ( unlikely(now - s->next_second_time > SECONDS(86400)) )
-    {
-        dprintk(XENLOG_WARNING, "HVM RTC: dom %u skipping %"PRId64" seconds\n",
-                vrtc_domain(s)->domain_id, 
-                (int64_t)((now - s->next_second_time) / SYSTEM_TIME_HZ));
-        s->next_second_time = now;
-    }
-
-    /* if the oscillator is not in normal operation, we do not update */
-    if ( (s->hw.cmos_data[RTC_REG_A] & RTC_DIV_CTL) != RTC_REF_CLCK_32KHZ )
-    {
-        s->next_second_time += 1000000000ULL;
-        set_timer(&s->second_timer, s->next_second_time);
-    }
-    else
-    {
-        rtc_next_second(s);
-        
-        if ( !(s->hw.cmos_data[RTC_REG_B] & RTC_SET) )
-            s->hw.cmos_data[RTC_REG_A] |= RTC_UIP;
-
-        /* Delay time before update cycle */
-        set_timer(&s->second_timer2, s->next_second_time + 244000);
-    }
-
-    spin_unlock(&s->lock);
-}
-
-static void rtc_update_second2(void *opaque)
-{
-    RTCState *s = opaque;
-    struct domain *d = vrtc_domain(s);
-
-    spin_lock(&s->lock);
-
-    if ( !(s->hw.cmos_data[RTC_REG_B] & RTC_SET) )
-        rtc_copy_date(s);
-
-    /* check alarm */
-    if ( s->hw.cmos_data[RTC_REG_B] & RTC_AIE )
-    {
-        if ( ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0 ||
-              from_bcd(s, s->hw.cmos_data[RTC_SECONDS_ALARM]) ==
-              s->current_tm.tm_sec) &&
-             ((s->hw.cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0 ||
-              from_bcd(s, s->hw.cmos_data[RTC_MINUTES_ALARM]) ==
-              s->current_tm.tm_min) &&
-             ((s->hw.cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0 ||
-              from_bcd(s, s->hw.cmos_data[RTC_HOURS_ALARM]) ==
-              s->current_tm.tm_hour) )
-        {
-            s->hw.cmos_data[RTC_REG_C] |= 0xa0; 
-            hvm_isa_irq_deassert(d, RTC_IRQ);
-            hvm_isa_irq_assert(d, RTC_IRQ);
-        }
-    }
-
-    /* update ended interrupt */
-    if ( (s->hw.cmos_data[RTC_REG_B] & (RTC_UIE|RTC_SET)) == RTC_UIE )
-    {
-        s->hw.cmos_data[RTC_REG_C] |= 0x90; 
-        hvm_isa_irq_deassert(d, RTC_IRQ);
-        hvm_isa_irq_assert(d, RTC_IRQ);
-    }
-
-    /* clear update in progress bit */
-    s->hw.cmos_data[RTC_REG_A] &= ~RTC_UIP;
-
-    s->next_second_time += 1000000000ULL;
-    set_timer(&s->second_timer, s->next_second_time);
-
-    spin_unlock(&s->lock);
-}
-
 static uint32_t rtc_ioport_read(RTCState *s, uint32_t addr)
 {
     int ret;
+    struct domain *d = vrtc_domain(s);
 
     if ( (addr & 1) == 0 )
         return 0xff;
@@ -383,6 +246,12 @@
     case RTC_DAY_OF_MONTH:
     case RTC_MONTH:
     case RTC_YEAR:
+        /* if not in set mode, adjust cmos before reading*/
+        if (!(s->hw.cmos_data[RTC_REG_B] & RTC_SET))
+        {
+            s->current_tm = gmtime(get_localtime(d));
+            rtc_copy_date(s);
+        }
         ret = s->hw.cmos_data[s->hw.cmos_index];
         break;
     case RTC_REG_A:
@@ -430,12 +299,9 @@
 
 void rtc_migrate_timers(struct vcpu *v)
 {
-    RTCState *s = vcpu_vrtc(v);
-
     if ( v->vcpu_id == 0 )
     {
-        migrate_timer(&s->second_timer, v->processor);
-        migrate_timer(&s->second_timer2, v->processor);
+        ;
     }
 }
 
@@ -468,9 +334,6 @@
      * time, so let's keep doing that. */
     s->current_tm = gmtime(get_localtime(d));
     rtc_copy_date(s);
-    s->next_second_time = NOW() + 1000000000ULL;
-    stop_timer(&s->second_timer);
-    set_timer(&s->second_timer2, s->next_second_time);
 
     /* Reset the periodic interrupt timer based on the registers */
     rtc_timer_update(s);
@@ -496,9 +359,6 @@
 
     spin_lock_init(&s->lock);
 
-    init_timer(&s->second_timer, rtc_update_second, s, smp_processor_id());
-    init_timer(&s->second_timer2, rtc_update_second2, s, smp_processor_id());
-
     register_portio_handler(d, RTC_PORT(0), 2, handle_rtc_io);
 
     rtc_reset(d);
@@ -514,10 +374,6 @@
 
     rtc_copy_date(s);
 
-    s->next_second_time = NOW() + 1000000000ULL;
-    stop_timer(&s->second_timer);
-    set_timer(&s->second_timer2, s->next_second_time);
-
     spin_unlock(&s->lock);
 }
 
@@ -528,8 +384,6 @@
     spin_barrier(&s->lock);
 
     destroy_periodic_time(&s->pt);
-    kill_timer(&s->second_timer);
-    kill_timer(&s->second_timer2);
 }
 
 void rtc_update_clock(struct domain *d)
diff -r 50a70b652b43 -r 6deb0b626f3f xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h     Wed Mar 07 07:30:30 2012 +0000
+++ b/xen/include/asm-x86/hvm/vpt.h     Wed Mar 07 07:34:20 2012 +0000
@@ -106,8 +106,6 @@
     struct tm current_tm;
     /* second update */
     int64_t next_second_time;
-    struct timer second_timer;
-    struct timer second_timer2;
     struct periodic_time pt;
     spinlock_t lock;
 } RTCState;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.