|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RESEND 3/5] RTC: Add UIP(update in progress) check logic
The UIP(update in progress) is set when RTC is in updating. And the update
cycle begins 244us later after UIP is set.
Signed-off-by: Yang Zhang <yang.z.zhang@xxxxxxxxx>
diff -r 47cb862a07c2 -r edc35b026509 xen/arch/x86/hvm/rtc.c
--- a/xen/arch/x86/hvm/rtc.c Mon Mar 05 14:39:07 2012 +0800
+++ b/xen/arch/x86/hvm/rtc.c Mon Mar 05 14:39:41 2012 +0800
@@ -28,6 +28,8 @@
#include <asm/hvm/support.h>
#include <asm/current.h>
+#define USEC_PER_SEC 1000000UL
+
#define domain_vrtc(x) (&(x)->arch.hvm_domain.pl_time.vrtc)
#define vcpu_vrtc(x) (domain_vrtc((x)->domain))
#define vrtc_domain(x) (container_of((x), struct domain, \ @@ -239,6 +241,22
@@ static void rtc_copy_date(RTCState *s)
s->hw.cmos_data[RTC_YEAR] = to_bcd(s, tm->tm_year % 100); }
+static int update_in_progress(RTCState *s) {
+ uint64_t guest_usec;
+ struct domain *d = vrtc_domain(s);
+
+ if (s->hw.cmos_data[RTC_REG_B] & RTC_SET)
+ return 0;
+
+ guest_usec = get_localtime_us(d);
+ /* UIP bit will be set at last 244us of every second. */
+ if ((guest_usec % USEC_PER_SEC) >= (USEC_PER_SEC - 244))
+ return 1;
+
+ return 0;
+}
+
static uint32_t rtc_ioport_read(RTCState *s, uint32_t addr) {
int ret;
@@ -268,6 +286,8 @@ static uint32_t rtc_ioport_read(RTCState
break;
case RTC_REG_A:
ret = s->hw.cmos_data[s->hw.cmos_index];
+ if (update_in_progress(s))
+ ret |= RTC_UIP;
break;
case RTC_REG_C:
ret = s->hw.cmos_data[s->hw.cmos_index];
diff -r 47cb862a07c2 -r edc35b026509 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c Mon Mar 05 14:39:07 2012 +0800
+++ b/xen/arch/x86/time.c Mon Mar 05 14:39:41 2012 +0800
@@ -1601,6 +1601,13 @@ unsigned long get_localtime(struct domai
+ d->time_offset_seconds;
}
+/* Return microsecs after 00:00:00 localtime, 1 January, 1970. */
+uint64_t get_localtime_us(struct domain *d) {
+ return ((wc_sec + d->time_offset_seconds) * 1000000000ULL
+ + wc_nsec + NOW()) / 1000UL;
+}
+
unsigned long get_sec(void)
{
return wc_sec + (wc_nsec + NOW()) / 1000000000ULL;
diff -r 47cb862a07c2 -r edc35b026509 xen/include/xen/time.h
--- a/xen/include/xen/time.h Mon Mar 05 14:39:07 2012 +0800
+++ b/xen/include/xen/time.h Mon Mar 05 14:39:41 2012 +0800
@@ -34,6 +34,7 @@ typedef s64 s_time_t;
s_time_t get_s_time(void);
unsigned long get_localtime(struct domain *d);
+uint64_t get_localtime_us(struct domain *d);
struct tm {
int tm_sec; /* seconds */
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |