ia64/xen-unstable

changeset 16689:66db23ecd562

hvm: hpet: Fix per-timer enable/disable.

The enable/disable per timer interrupt bit is wrongly used as per
timer enable/disable. According to spec, comparator value should
constantly increasing when HPET is globally enabled, no matter
whether the timer interrupt is enabled or not.

From: Haitao Shan <haitao.shan@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Jan 08 13:57:45 2008 +0000 (2008-01-08)
parents 4fcc8b64c2b5
children 01adaec882d4
files xen/arch/x86/hvm/hpet.c
line diff
     1.1 --- a/xen/arch/x86/hvm/hpet.c	Tue Jan 08 10:13:11 2008 +0000
     1.2 +++ b/xen/arch/x86/hvm/hpet.c	Tue Jan 08 13:57:45 2008 +0000
     1.3 @@ -75,7 +75,6 @@
     1.4                                    (S_TO_NS*TSC_PER_HPET_TICK)/h->tsc_freq)
     1.5  
     1.6  #define timer_config(h, n)       (h->hpet.timers[n].config)
     1.7 -#define timer_enabled(h, n)      (timer_config(h, n) & HPET_TN_ENABLE)
     1.8  #define timer_is_periodic(h, n)  (timer_config(h, n) & HPET_TN_PERIODIC)
     1.9  #define timer_is_32bit(h, n)     (timer_config(h, n) & HPET_TN_32BIT)
    1.10  #define hpet_enabled(h)          (h->hpet.config & HPET_CFG_ENABLE)
    1.11 @@ -195,9 +194,6 @@ static void hpet_set_timer(HPETState *h,
    1.12      ASSERT(tn < HPET_TIMER_NUM);
    1.13      ASSERT(spin_is_locked(&h->lock));
    1.14  
    1.15 -    if ( !hpet_enabled(h) || !timer_enabled(h, tn) )
    1.16 -        return;
    1.17 -
    1.18      if ( (tn == 0) && (h->hpet.config & HPET_CFG_LEGACY) )
    1.19      {
    1.20          /* HPET specification requires PIT shouldn't generate
    1.21 @@ -308,10 +304,6 @@ static void hpet_write(
    1.22          if ( new_val & HPET_TN_32BIT )
    1.23              h->hpet.timers[tn].cmp = (uint32_t)h->hpet.timers[tn].cmp;
    1.24  
    1.25 -        if ( !(old_val & HPET_TN_ENABLE) && (new_val & HPET_TN_ENABLE) )
    1.26 -            hpet_set_timer(h, tn);
    1.27 -        else if ( (old_val & HPET_TN_ENABLE) && !(new_val & HPET_TN_ENABLE) )
    1.28 -            hpet_stop_timer(h, tn);
    1.29          break;
    1.30  
    1.31      case HPET_T0_CMP:
    1.32 @@ -326,7 +318,7 @@ static void hpet_write(
    1.33          else
    1.34              h->hpet.period[tn] = new_val;
    1.35          h->hpet.timers[tn].config &= ~HPET_TN_SETVAL;
    1.36 -        if ( hpet_enabled(h) && timer_enabled(h, tn) )
    1.37 +        if ( hpet_enabled(h) )
    1.38              hpet_set_timer(h, tn);
    1.39          break;
    1.40  
    1.41 @@ -397,13 +389,14 @@ static void hpet_timer_fn(void *opaque)
    1.42  
    1.43      spin_lock(&h->lock);
    1.44  
    1.45 -    if ( !hpet_enabled(h) || !timer_enabled(h, tn) )
    1.46 +    if ( !hpet_enabled(h) )
    1.47      {
    1.48          spin_unlock(&h->lock);
    1.49          return;
    1.50      }
    1.51  
    1.52 -    hpet_route_interrupt(h, tn);
    1.53 +    if ( timer_config(h, tn) & HPET_TN_ENABLE )
    1.54 +        hpet_route_interrupt(h, tn);
    1.55  
    1.56      if ( timer_is_periodic(h, tn) && (h->hpet.period[tn] != 0) )
    1.57      {
    1.58 @@ -522,7 +515,8 @@ static int hpet_load(struct domain *d, h
    1.59                  
    1.60      /* Restart the timers */
    1.61      for ( i = 0; i < HPET_TIMER_NUM; i++ )
    1.62 -        hpet_set_timer(hp, i);
    1.63 +        if ( hpet_enabled(hp) )
    1.64 +            hpet_set_timer(hp, i);
    1.65  
    1.66      spin_unlock(&hp->lock);
    1.67