direct-io.hg

changeset 13760:6db6b5df4f6f

[HVM] Save/restore: save HPET registers
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
author Tim Deegan <Tim.Deegan@xensource.com>
date Wed Jan 31 18:15:00 2007 +0000 (2007-01-31)
parents 5d09e6098f93
children b998ae45c076
files xen/arch/x86/hvm/hpet.c xen/include/asm-x86/hvm/vpt.h xen/include/public/hvm/save.h
line diff
     1.1 --- a/xen/arch/x86/hvm/hpet.c	Wed Jan 31 17:22:17 2007 +0000
     1.2 +++ b/xen/arch/x86/hvm/hpet.c	Wed Jan 31 18:15:00 2007 +0000
     1.3 @@ -279,7 +279,7 @@ static void hpet_write(
     1.4               (h->hpet.timers[tn].config & HPET_TN_SETVAL) )
     1.5              h->hpet.timers[tn].cmp = new_val;
     1.6          else
     1.7 -            h->period[tn] = new_val;
     1.8 +            h->hpet.period[tn] = new_val;
     1.9          h->hpet.timers[tn].config &= ~HPET_TN_SETVAL;
    1.10          if ( hpet_enabled(h) && timer_enabled(h, tn) )
    1.11              hpet_set_timer(h, tn);
    1.12 @@ -289,7 +289,7 @@ static void hpet_write(
    1.13      case HPET_T1_ROUTE:
    1.14      case HPET_T2_ROUTE:
    1.15          tn = (addr - HPET_T0_ROUTE) >> 5;
    1.16 -        h->hpet.timers[tn].hpet_fsb[0] = new_val;
    1.17 +        h->hpet.timers[tn].fsb = new_val;
    1.18          break;
    1.19  
    1.20      default:
    1.21 @@ -351,21 +351,22 @@ static void hpet_timer_fn(void *opaque)
    1.22  
    1.23      hpet_route_interrupt(h, tn);
    1.24  
    1.25 -    if ( timer_is_periodic(h, tn) && (h->period[tn] != 0) )
    1.26 +    if ( timer_is_periodic(h, tn) && (h->hpet.period[tn] != 0) )
    1.27      {
    1.28          uint64_t mc = hpet_read_maincounter(h);
    1.29          if ( timer_is_32bit(h, tn) )
    1.30          {
    1.31              while ( hpet_time_after(mc, h->hpet.timers[tn].cmp) )
    1.32                  h->hpet.timers[tn].cmp = (uint32_t)(
    1.33 -                    h->hpet.timers[tn].cmp + h->period[tn]);
    1.34 +                    h->hpet.timers[tn].cmp + h->hpet.period[tn]);
    1.35          }
    1.36          else
    1.37          {
    1.38              while ( hpet_time_after64(mc, h->hpet.timers[tn].cmp) )
    1.39 -                h->hpet.timers[tn].cmp += h->period[tn];
    1.40 +                h->hpet.timers[tn].cmp += h->hpet.period[tn];
    1.41          }
    1.42 -        set_timer(&h->timers[tn], NOW() + hpet_tick_to_ns(h, h->period[tn]));
    1.43 +        set_timer(&h->timers[tn], 
    1.44 +                  NOW() + hpet_tick_to_ns(h, h->hpet.period[tn]));
    1.45      }
    1.46  }
    1.47  
    1.48 @@ -378,6 +379,35 @@ void hpet_migrate_timers(struct vcpu *v)
    1.49          migrate_timer(&h->timers[i], v->processor);
    1.50  }
    1.51  
    1.52 +static int hpet_save(struct domain *d, hvm_domain_context_t *h)
    1.53 +{
    1.54 +    HPETState *hp = &d->arch.hvm_domain.pl_time.vhpet;
    1.55 +
    1.56 +    /* Save the HPET registers */
    1.57 +    return hvm_save_entry(HPET, 0, h, &hp->hpet);
    1.58 +}
    1.59 +
    1.60 +static int hpet_load(struct domain *d, hvm_domain_context_t *h)
    1.61 +{
    1.62 +    HPETState *hp = &d->arch.hvm_domain.pl_time.vhpet;
    1.63 +    int i;
    1.64 +
    1.65 +    /* Reload the HPET registers */
    1.66 +    if ( hvm_load_entry(HPET, h, &hp->hpet) )
    1.67 +        return -EINVAL;
    1.68 +    
    1.69 +    /* Recalculate the offset between the main counter and guest time */
    1.70 +    hp->mc_offset = hp->hpet.mc64 - hvm_get_guest_time(hp->vcpu);
    1.71 +                
    1.72 +    /* Restart the timers */
    1.73 +    for ( i = 0; i < HPET_TIMER_NUM; i++ )
    1.74 +        hpet_set_timer(hp, i);
    1.75 +
    1.76 +    return 0;
    1.77 +}
    1.78 +
    1.79 +HVM_REGISTER_SAVE_RESTORE(HPET, hpet_save, hpet_load);
    1.80 +
    1.81  void hpet_init(struct vcpu *v)
    1.82  {
    1.83      HPETState *h = &v->domain->arch.hvm_domain.pl_time.vhpet;
     2.1 --- a/xen/include/asm-x86/hvm/vpt.h	Wed Jan 31 17:22:17 2007 +0000
     2.2 +++ b/xen/include/asm-x86/hvm/vpt.h	Wed Jan 31 18:15:00 2007 +0000
     2.3 @@ -31,22 +31,6 @@
     2.4  #include <asm/hvm/vpic.h>
     2.5  #include <public/hvm/save.h>
     2.6  
     2.7 -#define HPET_TIMER_NUM     3    /* 3 timers supported now */
     2.8 -struct HPET {
     2.9 -    uint64_t capability;        /* capabilities */
    2.10 -    uint64_t res0;              /* reserved */
    2.11 -    uint64_t config;            /* configuration */
    2.12 -    uint64_t res1;              /* reserved */
    2.13 -    uint64_t isr;               /* interrupt status reg */
    2.14 -    uint64_t res2[25];          /* reserved */
    2.15 -    uint64_t mc64;              /* main counter */
    2.16 -    uint64_t res3;              /* reserved */
    2.17 -    struct {                    /* timers */
    2.18 -        uint64_t config;        /* configuration/cap */
    2.19 -        uint64_t cmp;           /* comparator */
    2.20 -        uint64_t hpet_fsb[2];   /* FSB route, not supported now */
    2.21 -    } timers[HPET_TIMER_NUM];
    2.22 -};
    2.23  
    2.24  struct HPETState;
    2.25  struct HPET_timer_fn_info {
    2.26 @@ -55,11 +39,10 @@ struct HPET_timer_fn_info {
    2.27  };
    2.28  
    2.29  typedef struct HPETState {
    2.30 -    struct HPET     hpet;
    2.31 -    struct vcpu     *vcpu;
    2.32 -    uint64_t        tsc_freq;
    2.33 -    uint64_t        mc_offset;
    2.34 -    uint64_t        period[HPET_TIMER_NUM];
    2.35 +    struct hvm_hw_hpet hpet;
    2.36 +    struct vcpu *vcpu;
    2.37 +    uint64_t tsc_freq;
    2.38 +    uint64_t mc_offset;
    2.39      struct timer timers[HPET_TIMER_NUM];
    2.40      struct HPET_timer_fn_info timer_fn_info[HPET_TIMER_NUM]; 
    2.41  } HPETState;
     3.1 --- a/xen/include/public/hvm/save.h	Wed Jan 31 17:22:17 2007 +0000
     3.2 +++ b/xen/include/public/hvm/save.h	Wed Jan 31 18:15:00 2007 +0000
     3.3 @@ -381,10 +381,40 @@ struct hvm_hw_rtc {
     3.4  DECLARE_HVM_SAVE_TYPE(RTC, 9, struct hvm_hw_rtc);
     3.5  
     3.6  
     3.7 +/*
     3.8 + * HPET
     3.9 + */
    3.10 +
    3.11 +#define HPET_TIMER_NUM     3    /* 3 timers supported now */
    3.12 +struct hvm_hw_hpet {
    3.13 +    /* Memory-mapped, software visible registers */
    3.14 +    uint64_t capability;        /* capabilities */
    3.15 +    uint64_t res0;              /* reserved */
    3.16 +    uint64_t config;            /* configuration */
    3.17 +    uint64_t res1;              /* reserved */
    3.18 +    uint64_t isr;               /* interrupt status reg */
    3.19 +    uint64_t res2[25];          /* reserved */
    3.20 +    uint64_t mc64;              /* main counter */
    3.21 +    uint64_t res3;              /* reserved */
    3.22 +    struct {                    /* timers */
    3.23 +        uint64_t config;        /* configuration/cap */
    3.24 +        uint64_t cmp;           /* comparator */
    3.25 +        uint64_t fsb;           /* FSB route, not supported now */
    3.26 +        uint64_t res4;          /* reserved */
    3.27 +    } timers[HPET_TIMER_NUM];
    3.28 +    uint64_t res5[4*(24-HPET_TIMER_NUM)];  /* reserved, up to 0x3ff */
    3.29 +
    3.30 +    /* Hidden register state */
    3.31 +    uint64_t period[HPET_TIMER_NUM]; /* Last value written to comparator */
    3.32 +};
    3.33 +
    3.34 +DECLARE_HVM_SAVE_TYPE(HPET, 10, struct hvm_hw_hpet);
    3.35 +
    3.36 +
    3.37  /* 
    3.38   * Largest type-code in use
    3.39   */
    3.40 -#define HVM_SAVE_CODE_MAX 9
    3.41 +#define HVM_SAVE_CODE_MAX 10
    3.42  
    3.43  
    3.44  /*