ia64/xen-unstable

changeset 13879:6e74932c9a64

[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@xensource.com>
author Tim Deegan <Tim.Deegan@xensource.com>
date Thu Feb 08 13:42:49 2007 +0000 (2007-02-08)
parents 3fbe12560ffe
children 9c88b5f3b4eb
files xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/pmtimer.c xen/include/asm-x86/hvm/vpt.h xen/include/public/hvm/save.h
line diff
     1.1 --- a/xen/arch/x86/hvm/hvm.c	Thu Feb 08 10:44:53 2007 +0000
     1.2 +++ b/xen/arch/x86/hvm/hvm.c	Thu Feb 08 13:42:49 2007 +0000
     1.3 @@ -106,7 +106,6 @@ void hvm_migrate_timers(struct vcpu *v)
     1.4      pit_migrate_timers(v);
     1.5      rtc_migrate_timers(v);
     1.6      hpet_migrate_timers(v);
     1.7 -    pmtimer_migrate_timers(v);
     1.8      if ( vcpu_vlapic(v)->pt.enabled )
     1.9          migrate_timer(&vcpu_vlapic(v)->pt.timer, v->processor);
    1.10  }
    1.11 @@ -170,7 +169,6 @@ void hvm_domain_destroy(struct domain *d
    1.12  {
    1.13      pit_deinit(d);
    1.14      rtc_deinit(d);
    1.15 -    pmtimer_deinit(d);
    1.16      hpet_deinit(d);
    1.17  
    1.18      if ( d->arch.hvm_domain.shared_page_va )
     2.1 --- a/xen/arch/x86/hvm/pmtimer.c	Thu Feb 08 10:44:53 2007 +0000
     2.2 +++ b/xen/arch/x86/hvm/pmtimer.c	Thu Feb 08 13:42:49 2007 +0000
     2.3 @@ -2,17 +2,6 @@
     2.4  #include <asm/hvm/io.h>
     2.5  #include <asm/hvm/support.h>
     2.6  
     2.7 -#define TMR_STS (1 << 0)
     2.8 -static void pmt_update_status(void *opaque)
     2.9 -{
    2.10 -   PMTState *s = opaque;
    2.11 -   s->pm1_status |= TMR_STS;
    2.12 -
    2.13 -   /* TODO: When TMR_EN == 1, generate a SCI event */
    2.14 -
    2.15 -   set_timer(&s->timer, NOW() + (1000000000ULL << 31) / FREQUENCE_PMTIMER);
    2.16 -}
    2.17 -
    2.18  static int handle_pmt_io(ioreq_t *p)
    2.19  {
    2.20      struct vcpu *v = current;
    2.21 @@ -30,42 +19,62 @@ static int handle_pmt_io(ioreq_t *p)
    2.22          /* PM_TMR_BLK is read-only */
    2.23          return 1;
    2.24      } else if (p->dir == 1) { /* read */
    2.25 +        /* Set the correct value in the timer, accounting for time
    2.26 +         * elapsed since the last time we did that. */
    2.27          curr_gtime = hvm_get_guest_time(s->vcpu);
    2.28 -        s->pm1_timer += ((curr_gtime - s->last_gtime) * s->scale) >> 32;
    2.29 -        p->data = s->pm1_timer;
    2.30 +        s->pm.timer += ((curr_gtime - s->last_gtime) * s->scale) >> 32;
    2.31 +        p->data = s->pm.timer;
    2.32          s->last_gtime = curr_gtime;
    2.33          return 1;
    2.34      }
    2.35      return 0;
    2.36  }
    2.37  
    2.38 +static int pmtimer_save(struct domain *d, hvm_domain_context_t *h)
    2.39 +{
    2.40 +    PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
    2.41 +    uint32_t x;
    2.42 +
    2.43 +    /* Update the counter to the guest's current time.  We always save
    2.44 +     * with the domain paused, so the saved time should be after the
    2.45 +     * last_gtime, but just in case, make sure we only go forwards */
    2.46 +    x = ((s->vcpu->arch.hvm_vcpu.guest_time - s->last_gtime) * s->scale) >> 32;
    2.47 +    if ( x < 1UL<<31 )
    2.48 +        s->pm.timer += x;
    2.49 +    return hvm_save_entry(PMTIMER, 0, h, &s->pm);
    2.50 +}
    2.51 +
    2.52 +static int pmtimer_load(struct domain *d, hvm_domain_context_t *h)
    2.53 +{
    2.54 +    PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
    2.55 +
    2.56 +    /* Reload the counter */
    2.57 +    if ( hvm_load_entry(PMTIMER, h, &s->pm) )
    2.58 +        return -EINVAL;
    2.59 +
    2.60 +    /* Calculate future counter values from now. */
    2.61 +    s->last_gtime = hvm_get_guest_time(s->vcpu);
    2.62 +    
    2.63 +    return 0;
    2.64 +}
    2.65 +
    2.66 +HVM_REGISTER_SAVE_RESTORE(PMTIMER, pmtimer_save, pmtimer_load, 
    2.67 +                          1, HVMSR_PER_DOM);
    2.68 +
    2.69 +
    2.70  void pmtimer_init(struct vcpu *v, int base)
    2.71  {
    2.72      PMTState *s = &v->domain->arch.hvm_domain.pl_time.vpmt;
    2.73  
    2.74 -    s->pm1_timer = 0;
    2.75 -    s->pm1_status = 0;
    2.76 +    s->pm.timer = 0;
    2.77      s->scale = ((uint64_t)FREQUENCE_PMTIMER << 32) / ticks_per_sec(v);
    2.78      s->vcpu = v;
    2.79  
    2.80 -    init_timer(&s->timer, pmt_update_status, s, v->processor);
    2.81 -    /* ACPI supports a 32-bit power management timer */
    2.82 -    set_timer(&s->timer, NOW() + (1000000000ULL << 31) / FREQUENCE_PMTIMER);
    2.83 -    
    2.84 +    /* Not implemented: we should set TMR_STS (bit 0 of PM1a_STS) every
    2.85 +     * time the timer's top bit flips, and generate an SCI if TMR_EN
    2.86 +     * (bit 0 of PM1a_EN) is set.  For now, those registers are in
    2.87 +     * qemu-dm, and we just calculate the timer's value on demand. */  
    2.88 +
    2.89      register_portio_handler(v->domain, base, 4, handle_pmt_io);
    2.90  }
    2.91  
    2.92 -void pmtimer_migrate_timers(struct vcpu *v)
    2.93 -{
    2.94 -    struct PMTState *vpmt = &v->domain->arch.hvm_domain.pl_time.vpmt;
    2.95 -
    2.96 -    if (vpmt->vcpu == v)
    2.97 -        migrate_timer(&vpmt->timer, v->processor);
    2.98 -}
    2.99 -
   2.100 -void pmtimer_deinit(struct domain *d)
   2.101 -{
   2.102 -    PMTState *s = &d->arch.hvm_domain.pl_time.vpmt;
   2.103 -
   2.104 -    kill_timer(&s->timer);
   2.105 -}
     3.1 --- a/xen/include/asm-x86/hvm/vpt.h	Thu Feb 08 10:44:53 2007 +0000
     3.2 +++ b/xen/include/asm-x86/hvm/vpt.h	Thu Feb 08 13:42:49 2007 +0000
     3.3 @@ -94,14 +94,12 @@ typedef struct RTCState {
     3.4      struct periodic_time pt;
     3.5  } RTCState;
     3.6  
     3.7 -#define FREQUENCE_PMTIMER  3579545
     3.8 +#define FREQUENCE_PMTIMER  3579545  /* Timer should run at 3.579545 MHz */
     3.9  typedef struct PMTState {
    3.10 -    uint32_t pm1_timer;
    3.11 -    uint32_t pm1_status;
    3.12 -    uint64_t last_gtime;
    3.13 -    struct timer timer;
    3.14 -    uint64_t scale;
    3.15 -    struct vcpu *vcpu;
    3.16 +    struct hvm_hw_pmtimer pm;   /* 32bit timer value */
    3.17 +    struct vcpu *vcpu;          /* Keeps sync with this vcpu's guest-time */
    3.18 +    uint64_t last_gtime;        /* Last (guest) time we updated the timer */
    3.19 +    uint64_t scale;             /* Multiplier to get from tsc to timer ticks */
    3.20  } PMTState;
    3.21  
    3.22  struct pl_time {    /* platform time */
    3.23 @@ -134,8 +132,6 @@ void rtc_migrate_timers(struct vcpu *v);
    3.24  void rtc_deinit(struct domain *d);
    3.25  int is_rtc_periodic_irq(void *opaque);
    3.26  void pmtimer_init(struct vcpu *v, int base);
    3.27 -void pmtimer_migrate_timers(struct vcpu *v);
    3.28 -void pmtimer_deinit(struct domain *d);
    3.29  
    3.30  void hpet_migrate_timers(struct vcpu *v);
    3.31  void hpet_init(struct vcpu *v);
     4.1 --- a/xen/include/public/hvm/save.h	Thu Feb 08 10:44:53 2007 +0000
     4.2 +++ b/xen/include/public/hvm/save.h	Thu Feb 08 13:42:49 2007 +0000
     4.3 @@ -382,10 +382,20 @@ struct hvm_hw_hpet {
     4.4  DECLARE_HVM_SAVE_TYPE(HPET, 12, struct hvm_hw_hpet);
     4.5  
     4.6  
     4.7 +/*
     4.8 + * PM timer
     4.9 + */
    4.10 +
    4.11 +struct hvm_hw_pmtimer {
    4.12 +    uint32_t timer;
    4.13 +};
    4.14 +
    4.15 +DECLARE_HVM_SAVE_TYPE(PMTIMER, 13, struct hvm_hw_pmtimer);
    4.16 +
    4.17  /* 
    4.18   * Largest type-code in use
    4.19   */
    4.20 -#define HVM_SAVE_CODE_MAX 12
    4.21 +#define HVM_SAVE_CODE_MAX 13
    4.22  
    4.23  
    4.24  /*