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

[Xen-devel] [PATCH RESEND 1/5] RTC: use offset to caculate rtc clock


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
  • From: "Zhang, Yang Z" <yang.z.zhang@xxxxxxxxx>
  • Date: Thu, 8 Mar 2012 00:43:00 +0000
  • Accept-language: en-US
  • Delivery-date: Thu, 08 Mar 2012 00:44:31 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xen.org>
  • Thread-index: Acz8xGj3+TErrFj/SWmRhpTXXgHyRw==
  • Thread-topic: [PATCH RESEND 1/5] 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>

diff -r 33659563f589 -r f2e4c1af3759 xen/arch/x86/hvm/rtc.c
--- a/xen/arch/x86/hvm/rtc.c    Fri Mar 02 12:33:25 2012 +0000
+++ b/xen/arch/x86/hvm/rtc.c    Mon Mar 05 14:38:20 2012 +0800
@@ -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 void rtc_set_time(RTCState *s);  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 @@ static int rtc_ioport_write(void *opaque
         {
             /* 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 @@ static void rtc_copy_date(RTCState *s)
     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 @@ static uint32_t rtc_ioport_read(RTCState
     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 @@ static int handle_rtc_io(

 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 @@ static int rtc_load(struct domain *d, hv
      * 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 @@ void rtc_init(struct domain *d)

     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 @@ void rtc_init(struct domain *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);
-
     spin_unlock(&s->lock);
 }

@@ -528,8 +384,6 @@ void rtc_deinit(struct domain *d)
     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 33659563f589 -r f2e4c1af3759 
xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h     Fri Mar 02 12:33:25 2012 +0000
+++ b/xen/include/asm-x86/hvm/vpt.h     Mon Mar 05 14:38:20 2012 +0800
@@ -106,8 +106,6 @@ typedef struct RTCState {
     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-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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