ia64/xen-unstable

changeset 5902:01966dd718a8

Add IBM Cyclone support to Xen.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Jul 27 16:18:02 2005 +0000 (2005-07-27)
parents b7e975425dd6
children 2c67026ea29d
files xen/arch/x86/time.c xen/include/asm-x86/fixmap.h xen/include/asm-x86/mach-summit/mach_mpparse.h
line diff
     1.1 --- a/xen/arch/x86/time.c	Wed Jul 27 15:32:44 2005 +0000
     1.2 +++ b/xen/arch/x86/time.c	Wed Jul 27 16:18:02 2005 +0000
     1.3 @@ -199,13 +199,13 @@ void calibrate_tsc_bp(void)
     1.4      outb(CALIBRATE_LATCH >> 8, PIT_CH2);
     1.5  
     1.6      tsc_calibrate_status = 1;
     1.7 -	wmb();
     1.8 +    wmb();
     1.9  
    1.10      while ( (inb(0x61) & 0x20) == 0 )
    1.11          continue;
    1.12  
    1.13      tsc_calibrate_status = 2;
    1.14 -	wmb();
    1.15 +    wmb();
    1.16  
    1.17      while ( atomic_read(&tsc_calibrate_gang) != 0 )
    1.18          mb();
    1.19 @@ -233,7 +233,6 @@ void calibrate_tsc_ap(void)
    1.20      atomic_dec(&tsc_calibrate_gang);
    1.21  }
    1.22  
    1.23 -
    1.24  /************************************************************
    1.25   * PLATFORM TIMER 1: PROGRAMMABLE INTERVAL TIMER (LEGACY PIT)
    1.26   */
    1.27 @@ -280,6 +279,8 @@ static int init_pit(void)
    1.28      platform_timer_stamp = pit_counter64;
    1.29      set_time_scale(&platform_timer_scale, CLOCK_TICK_RATE);
    1.30  
    1.31 +    printk("Platform timer is PIT\n");
    1.32 +
    1.33      return 1;
    1.34  }
    1.35  
    1.36 @@ -318,12 +319,12 @@ static int init_hpet(void)
    1.37  
    1.38      if ( (hpet_address == 0) && opt_hpet_force )
    1.39      {
    1.40 -		printk(KERN_WARNING "WARNING: Enabling HPET base manually!\n");
    1.41 +        printk(KERN_WARNING "WARNING: Enabling HPET base manually!\n");
    1.42          outl(0x800038a0, 0xcf8);
    1.43          outl(0xff000001, 0xcfc);
    1.44          outl(0x800038a0, 0xcf8);
    1.45          hpet_address = inl(0xcfc) & 0xfffffffe;
    1.46 -		printk(KERN_WARNING "WARNING: Enabled HPET at %#lx.\n", hpet_address);
    1.47 +        printk(KERN_WARNING "WARNING: Enabled HPET at %#lx.\n", hpet_address);
    1.48      }
    1.49  
    1.50      if ( hpet_address == 0 )
    1.51 @@ -383,6 +384,89 @@ static int init_hpet(void)
    1.52      hpet_overflow(NULL);
    1.53      platform_timer_stamp = hpet_counter64;
    1.54  
    1.55 +    printk("Platform timer is HPET\n");
    1.56 +
    1.57 +    return 1;
    1.58 +}
    1.59 +
    1.60 +/************************************************************
    1.61 + * PLATFORM TIMER 3: IBM 'CYCLONE' TIMER
    1.62 + */
    1.63 +
    1.64 +int use_cyclone;
    1.65 +
    1.66 +/*
    1.67 + * Although the counter is read via a 64-bit register, I believe it is actually
    1.68 + * a 40-bit counter. Since this will wrap, I read only the low 32 bits and
    1.69 + * periodically fold into a 64-bit software counter, just as for PIT and HPET.
    1.70 + */
    1.71 +#define CYCLONE_CBAR_ADDR   0xFEB00CD0
    1.72 +#define CYCLONE_PMCC_OFFSET 0x51A0
    1.73 +#define CYCLONE_MPMC_OFFSET 0x51D0
    1.74 +#define CYCLONE_MPCS_OFFSET 0x51A8
    1.75 +#define CYCLONE_TIMER_FREQ  100000000
    1.76 +
    1.77 +/* Protected by platform_timer_lock. */
    1.78 +static u64 cyclone_counter64;
    1.79 +static u32 cyclone_stamp;
    1.80 +static struct ac_timer cyclone_overflow_timer;
    1.81 +static volatile u32 *cyclone_timer; /* Cyclone MPMC0 register */
    1.82 +
    1.83 +static void cyclone_overflow(void *unused)
    1.84 +{
    1.85 +    u32 counter;
    1.86 +
    1.87 +    spin_lock(&platform_timer_lock);
    1.88 +    counter = *cyclone_timer;
    1.89 +    cyclone_counter64 += (u32)(counter - cyclone_stamp);
    1.90 +    cyclone_stamp = counter;
    1.91 +    spin_unlock(&platform_timer_lock);
    1.92 +
    1.93 +    set_ac_timer(&cyclone_overflow_timer, NOW() + MILLISECS(20000));
    1.94 +}
    1.95 +
    1.96 +static u64 read_cyclone_count(void)
    1.97 +{
    1.98 +    return cyclone_counter64 + (u32)(*cyclone_timer - cyclone_stamp);
    1.99 +}
   1.100 +
   1.101 +static volatile u32 *map_cyclone_reg(unsigned long regaddr)
   1.102 +{
   1.103 +    unsigned long pageaddr = regaddr &  PAGE_MASK;
   1.104 +    unsigned long offset   = regaddr & ~PAGE_MASK;
   1.105 +    set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr);
   1.106 +    return (volatile u32 *)(fix_to_virt(FIX_CYCLONE_TIMER) + offset);
   1.107 +}
   1.108 +
   1.109 +static int init_cyclone(void)
   1.110 +{
   1.111 +    u32 base;
   1.112 +    
   1.113 +    if ( !use_cyclone )
   1.114 +        return 0;
   1.115 +
   1.116 +    /* Find base address. */
   1.117 +    base = *(map_cyclone_reg(CYCLONE_CBAR_ADDR));
   1.118 +    if ( base == 0 )
   1.119 +    {
   1.120 +        printk(KERN_ERR "Cyclone: Could not find valid CBAR value.\n");
   1.121 +        return 0;
   1.122 +    }
   1.123 + 
   1.124 +    /* Enable timer and map the counter register. */
   1.125 +    *(map_cyclone_reg(base + CYCLONE_PMCC_OFFSET)) = 1;
   1.126 +    *(map_cyclone_reg(base + CYCLONE_MPCS_OFFSET)) = 1;
   1.127 +    cyclone_timer = map_cyclone_reg(base + CYCLONE_MPMC_OFFSET);
   1.128 +
   1.129 +    read_platform_count = read_cyclone_count;
   1.130 +
   1.131 +    init_ac_timer(&cyclone_overflow_timer, cyclone_overflow, NULL, 0);
   1.132 +    cyclone_overflow(NULL);
   1.133 +    platform_timer_stamp = cyclone_counter64;
   1.134 +    set_time_scale(&platform_timer_scale, CYCLONE_TIMER_FREQ);
   1.135 +
   1.136 +    printk("Platform timer is IBM Cyclone\n");
   1.137 +
   1.138      return 1;
   1.139  }
   1.140  
   1.141 @@ -427,7 +511,7 @@ static void platform_time_calibration(vo
   1.142  
   1.143  static void init_platform_timer(void)
   1.144  {
   1.145 -    if ( !init_hpet() )
   1.146 +    if ( !init_cyclone() && !init_hpet() )
   1.147          BUG_ON(!init_pit());
   1.148  }
   1.149  
     2.1 --- a/xen/include/asm-x86/fixmap.h	Wed Jul 27 15:32:44 2005 +0000
     2.2 +++ b/xen/include/asm-x86/fixmap.h	Wed Jul 27 16:18:02 2005 +0000
     2.3 @@ -31,6 +31,7 @@ enum fixed_addresses {
     2.4      FIX_ACPI_BEGIN,
     2.5      FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
     2.6      FIX_HPET_BASE,
     2.7 +    FIX_CYCLONE_TIMER,
     2.8      __end_of_fixed_addresses
     2.9  };
    2.10  
     3.1 --- a/xen/include/asm-x86/mach-summit/mach_mpparse.h	Wed Jul 27 15:32:44 2005 +0000
     3.2 +++ b/xen/include/asm-x86/mach-summit/mach_mpparse.h	Wed Jul 27 16:18:02 2005 +0000
     3.3 @@ -30,7 +30,7 @@ static inline int mps_oem_check(struct m
     3.4  			(!strncmp(productid, "VIGIL SMP", 9) 
     3.5  			 || !strncmp(productid, "EXA", 3)
     3.6  			 || !strncmp(productid, "RUTHLESS SMP", 12))){
     3.7 -		/*use_cyclone = 1;*/ /*enable cyclone-timer*/
     3.8 +		use_cyclone = 1; /*enable cyclone-timer*/
     3.9  		setup_summit();
    3.10  		/*usb_early_handoff = 1;*/
    3.11  		return 1;
    3.12 @@ -44,7 +44,7 @@ static inline int acpi_madt_oem_check(ch
    3.13  	if (!strncmp(oem_id, "IBM", 3) &&
    3.14  	    (!strncmp(oem_table_id, "SERVIGIL", 8)
    3.15  	     || !strncmp(oem_table_id, "EXA", 3))){
    3.16 -		/*use_cyclone = 1;*/ /*enable cyclone-timer*/
    3.17 +		use_cyclone = 1; /*enable cyclone-timer*/
    3.18  		setup_summit();
    3.19  		/*usb_early_handoff = 1;*/
    3.20  		return 1;