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

[Xen-changelog] [xen-unstable] [HVM] Save/restore: save pmtimer count register



# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
# Date 1170942169 0
# Node ID 6e74932c9a64298ef31af28ad0b53c0e7d2e6781
# Parent  3fbe12560ffe84359e2bc7bce12b0cc34a1e398c
[HVM] Save/restore: save pmtimer count register
Also remove the repeating timer from pmtimer.c because it doesn't do anything.
Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
---
 xen/arch/x86/hvm/hvm.c        |    2 -
 xen/arch/x86/hvm/pmtimer.c    |   75 +++++++++++++++++++++++-------------------
 xen/include/asm-x86/hvm/vpt.h |   14 ++-----
 xen/include/public/hvm/save.h |   12 ++++++
 4 files changed, 58 insertions(+), 45 deletions(-)

diff -r 3fbe12560ffe -r 6e74932c9a64 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Thu Feb 08 10:44:53 2007 +0000
+++ b/xen/arch/x86/hvm/hvm.c    Thu Feb 08 13:42:49 2007 +0000
@@ -106,7 +106,6 @@ void hvm_migrate_timers(struct vcpu *v)
     pit_migrate_timers(v);
     rtc_migrate_timers(v);
     hpet_migrate_timers(v);
-    pmtimer_migrate_timers(v);
     if ( vcpu_vlapic(v)->pt.enabled )
         migrate_timer(&vcpu_vlapic(v)->pt.timer, v->processor);
 }
@@ -170,7 +169,6 @@ void hvm_domain_destroy(struct domain *d
 {
     pit_deinit(d);
     rtc_deinit(d);
-    pmtimer_deinit(d);
     hpet_deinit(d);
 
     if ( d->arch.hvm_domain.shared_page_va )
diff -r 3fbe12560ffe -r 6e74932c9a64 xen/arch/x86/hvm/pmtimer.c
--- a/xen/arch/x86/hvm/pmtimer.c        Thu Feb 08 10:44:53 2007 +0000
+++ b/xen/arch/x86/hvm/pmtimer.c        Thu Feb 08 13:42:49 2007 +0000
@@ -1,17 +1,6 @@
 #include <asm/hvm/vpt.h>
 #include <asm/hvm/io.h>
 #include <asm/hvm/support.h>
-
-#define TMR_STS (1 << 0)
-static void pmt_update_status(void *opaque)
-{
-   PMTState *s = opaque;
-   s->pm1_status |= TMR_STS;
-
-   /* TODO: When TMR_EN == 1, generate a SCI event */
-
-   set_timer(&s->timer, NOW() + (1000000000ULL << 31) / FREQUENCE_PMTIMER);
-}
 
 static int handle_pmt_io(ioreq_t *p)
 {
@@ -30,42 +19,62 @@ static int handle_pmt_io(ioreq_t *p)
         /* PM_TMR_BLK is read-only */
         return 1;
     } else if (p->dir == 1) { /* read */
+        /* Set the correct value in the timer, accounting for time
+         * elapsed since the last time we did that. */
         curr_gtime = hvm_get_guest_time(s->vcpu);
-        s->pm1_timer += ((curr_gtime - s->last_gtime) * s->scale) >> 32;
-        p->data = s->pm1_timer;
+        s->pm.timer += ((curr_gtime - s->last_gtime) * s->scale) >> 32;
+        p->data = s->pm.timer;
         s->last_gtime = curr_gtime;
         return 1;
     }
     return 0;
 }
 
+static int pmtimer_save(struct domain *d, hvm_domain_context_t *h)
+{
+    PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
+    uint32_t x;
+
+    /* Update the counter to the guest's current time.  We always save
+     * with the domain paused, so the saved time should be after the
+     * last_gtime, but just in case, make sure we only go forwards */
+    x = ((s->vcpu->arch.hvm_vcpu.guest_time - s->last_gtime) * s->scale) >> 32;
+    if ( x < 1UL<<31 )
+        s->pm.timer += x;
+    return hvm_save_entry(PMTIMER, 0, h, &s->pm);
+}
+
+static int pmtimer_load(struct domain *d, hvm_domain_context_t *h)
+{
+    PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
+
+    /* Reload the counter */
+    if ( hvm_load_entry(PMTIMER, h, &s->pm) )
+        return -EINVAL;
+
+    /* Calculate future counter values from now. */
+    s->last_gtime = hvm_get_guest_time(s->vcpu);
+    
+    return 0;
+}
+
+HVM_REGISTER_SAVE_RESTORE(PMTIMER, pmtimer_save, pmtimer_load, 
+                          1, HVMSR_PER_DOM);
+
+
 void pmtimer_init(struct vcpu *v, int base)
 {
     PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt;
 
-    s->pm1_timer = 0;
-    s->pm1_status = 0;
+    s->pm.timer = 0;
     s->scale = ((uint64_t)FREQUENCE_PMTIMER << 32) / ticks_per_sec(v);
     s->vcpu = v;
 
-    init_timer(&s->timer, pmt_update_status, s, v->processor);
-    /* ACPI supports a 32-bit power management timer */
-    set_timer(&s->timer, NOW() + (1000000000ULL << 31) / FREQUENCE_PMTIMER);
-    
+    /* Not implemented: we should set TMR_STS (bit 0 of PM1a_STS) every
+     * time the timer's top bit flips, and generate an SCI if TMR_EN
+     * (bit 0 of PM1a_EN) is set.  For now, those registers are in
+     * qemu-dm, and we just calculate the timer's value on demand. */  
+
     register_portio_handler(v->domain, base, 4, handle_pmt_io);
 }
 
-void pmtimer_migrate_timers(struct vcpu *v)
-{
-    struct PMTState *vpmt = &v->domain->arch.hvm_domain.pl_time.vpmt;
-
-    if (vpmt->vcpu == v)
-        migrate_timer(&vpmt->timer, v->processor);
-}
-
-void pmtimer_deinit(struct domain *d)
-{
-    PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
-
-    kill_timer(&s->timer);
-}
diff -r 3fbe12560ffe -r 6e74932c9a64 xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h     Thu Feb 08 10:44:53 2007 +0000
+++ b/xen/include/asm-x86/hvm/vpt.h     Thu Feb 08 13:42:49 2007 +0000
@@ -94,14 +94,12 @@ typedef struct RTCState {
     struct periodic_time pt;
 } RTCState;
 
-#define FREQUENCE_PMTIMER  3579545
+#define FREQUENCE_PMTIMER  3579545  /* Timer should run at 3.579545 MHz */
 typedef struct PMTState {
-    uint32_t pm1_timer;
-    uint32_t pm1_status;
-    uint64_t last_gtime;
-    struct timer timer;
-    uint64_t scale;
-    struct vcpu *vcpu;
+    struct hvm_hw_pmtimer pm;   /* 32bit timer value */
+    struct vcpu *vcpu;          /* Keeps sync with this vcpu's guest-time */
+    uint64_t last_gtime;        /* Last (guest) time we updated the timer */
+    uint64_t scale;             /* Multiplier to get from tsc to timer ticks */
 } PMTState;
 
 struct pl_time {    /* platform time */
@@ -134,8 +132,6 @@ void rtc_deinit(struct domain *d);
 void rtc_deinit(struct domain *d);
 int is_rtc_periodic_irq(void *opaque);
 void pmtimer_init(struct vcpu *v, int base);
-void pmtimer_migrate_timers(struct vcpu *v);
-void pmtimer_deinit(struct domain *d);
 
 void hpet_migrate_timers(struct vcpu *v);
 void hpet_init(struct vcpu *v);
diff -r 3fbe12560ffe -r 6e74932c9a64 xen/include/public/hvm/save.h
--- a/xen/include/public/hvm/save.h     Thu Feb 08 10:44:53 2007 +0000
+++ b/xen/include/public/hvm/save.h     Thu Feb 08 13:42:49 2007 +0000
@@ -382,10 +382,20 @@ DECLARE_HVM_SAVE_TYPE(HPET, 12, struct h
 DECLARE_HVM_SAVE_TYPE(HPET, 12, struct hvm_hw_hpet);
 
 
+/*
+ * PM timer
+ */
+
+struct hvm_hw_pmtimer {
+    uint32_t timer;
+};
+
+DECLARE_HVM_SAVE_TYPE(PMTIMER, 13, struct hvm_hw_pmtimer);
+
 /* 
  * Largest type-code in use
  */
-#define HVM_SAVE_CODE_MAX 12
+#define HVM_SAVE_CODE_MAX 13
 
 
 /* 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
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®.