[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Add IBM Cyclone support to Xen.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 01966dd718a84c35c5baa1e16cd7db7c904f810e # Parent b7e975425dd677520c630f92e2a2d6d2668cb1d5 Add IBM Cyclone support to Xen. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r b7e975425dd6 -r 01966dd718a8 xen/arch/x86/time.c --- a/xen/arch/x86/time.c Wed Jul 27 15:32:44 2005 +++ b/xen/arch/x86/time.c Wed Jul 27 16:18:02 2005 @@ -199,13 +199,13 @@ outb(CALIBRATE_LATCH >> 8, PIT_CH2); tsc_calibrate_status = 1; - wmb(); + wmb(); while ( (inb(0x61) & 0x20) == 0 ) continue; tsc_calibrate_status = 2; - wmb(); + wmb(); while ( atomic_read(&tsc_calibrate_gang) != 0 ) mb(); @@ -232,7 +232,6 @@ atomic_dec(&tsc_calibrate_gang); } - /************************************************************ * PLATFORM TIMER 1: PROGRAMMABLE INTERVAL TIMER (LEGACY PIT) @@ -280,6 +279,8 @@ platform_timer_stamp = pit_counter64; set_time_scale(&platform_timer_scale, CLOCK_TICK_RATE); + printk("Platform timer is PIT\n"); + return 1; } @@ -318,12 +319,12 @@ if ( (hpet_address == 0) && opt_hpet_force ) { - printk(KERN_WARNING "WARNING: Enabling HPET base manually!\n"); + printk(KERN_WARNING "WARNING: Enabling HPET base manually!\n"); outl(0x800038a0, 0xcf8); outl(0xff000001, 0xcfc); outl(0x800038a0, 0xcf8); hpet_address = inl(0xcfc) & 0xfffffffe; - printk(KERN_WARNING "WARNING: Enabled HPET at %#lx.\n", hpet_address); + printk(KERN_WARNING "WARNING: Enabled HPET at %#lx.\n", hpet_address); } if ( hpet_address == 0 ) @@ -382,6 +383,89 @@ init_ac_timer(&hpet_overflow_timer, hpet_overflow, NULL, 0); hpet_overflow(NULL); platform_timer_stamp = hpet_counter64; + + printk("Platform timer is HPET\n"); + + return 1; +} + +/************************************************************ + * PLATFORM TIMER 3: IBM 'CYCLONE' TIMER + */ + +int use_cyclone; + +/* + * Although the counter is read via a 64-bit register, I believe it is actually + * a 40-bit counter. Since this will wrap, I read only the low 32 bits and + * periodically fold into a 64-bit software counter, just as for PIT and HPET. + */ +#define CYCLONE_CBAR_ADDR 0xFEB00CD0 +#define CYCLONE_PMCC_OFFSET 0x51A0 +#define CYCLONE_MPMC_OFFSET 0x51D0 +#define CYCLONE_MPCS_OFFSET 0x51A8 +#define CYCLONE_TIMER_FREQ 100000000 + +/* Protected by platform_timer_lock. */ +static u64 cyclone_counter64; +static u32 cyclone_stamp; +static struct ac_timer cyclone_overflow_timer; +static volatile u32 *cyclone_timer; /* Cyclone MPMC0 register */ + +static void cyclone_overflow(void *unused) +{ + u32 counter; + + spin_lock(&platform_timer_lock); + counter = *cyclone_timer; + cyclone_counter64 += (u32)(counter - cyclone_stamp); + cyclone_stamp = counter; + spin_unlock(&platform_timer_lock); + + set_ac_timer(&cyclone_overflow_timer, NOW() + MILLISECS(20000)); +} + +static u64 read_cyclone_count(void) +{ + return cyclone_counter64 + (u32)(*cyclone_timer - cyclone_stamp); +} + +static volatile u32 *map_cyclone_reg(unsigned long regaddr) +{ + unsigned long pageaddr = regaddr & PAGE_MASK; + unsigned long offset = regaddr & ~PAGE_MASK; + set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr); + return (volatile u32 *)(fix_to_virt(FIX_CYCLONE_TIMER) + offset); +} + +static int init_cyclone(void) +{ + u32 base; + + if ( !use_cyclone ) + return 0; + + /* Find base address. */ + base = *(map_cyclone_reg(CYCLONE_CBAR_ADDR)); + if ( base == 0 ) + { + printk(KERN_ERR "Cyclone: Could not find valid CBAR value.\n"); + return 0; + } + + /* Enable timer and map the counter register. */ + *(map_cyclone_reg(base + CYCLONE_PMCC_OFFSET)) = 1; + *(map_cyclone_reg(base + CYCLONE_MPCS_OFFSET)) = 1; + cyclone_timer = map_cyclone_reg(base + CYCLONE_MPMC_OFFSET); + + read_platform_count = read_cyclone_count; + + init_ac_timer(&cyclone_overflow_timer, cyclone_overflow, NULL, 0); + cyclone_overflow(NULL); + platform_timer_stamp = cyclone_counter64; + set_time_scale(&platform_timer_scale, CYCLONE_TIMER_FREQ); + + printk("Platform timer is IBM Cyclone\n"); return 1; } @@ -427,7 +511,7 @@ static void init_platform_timer(void) { - if ( !init_hpet() ) + if ( !init_cyclone() && !init_hpet() ) BUG_ON(!init_pit()); } diff -r b7e975425dd6 -r 01966dd718a8 xen/include/asm-x86/fixmap.h --- a/xen/include/asm-x86/fixmap.h Wed Jul 27 15:32:44 2005 +++ b/xen/include/asm-x86/fixmap.h Wed Jul 27 16:18:02 2005 @@ -31,6 +31,7 @@ FIX_ACPI_BEGIN, FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1, FIX_HPET_BASE, + FIX_CYCLONE_TIMER, __end_of_fixed_addresses }; diff -r b7e975425dd6 -r 01966dd718a8 xen/include/asm-x86/mach-summit/mach_mpparse.h --- a/xen/include/asm-x86/mach-summit/mach_mpparse.h Wed Jul 27 15:32:44 2005 +++ b/xen/include/asm-x86/mach-summit/mach_mpparse.h Wed Jul 27 16:18:02 2005 @@ -30,7 +30,7 @@ (!strncmp(productid, "VIGIL SMP", 9) || !strncmp(productid, "EXA", 3) || !strncmp(productid, "RUTHLESS SMP", 12))){ - /*use_cyclone = 1;*/ /*enable cyclone-timer*/ + use_cyclone = 1; /*enable cyclone-timer*/ setup_summit(); /*usb_early_handoff = 1;*/ return 1; @@ -44,7 +44,7 @@ if (!strncmp(oem_id, "IBM", 3) && (!strncmp(oem_table_id, "SERVIGIL", 8) || !strncmp(oem_table_id, "EXA", 3))){ - /*use_cyclone = 1;*/ /*enable cyclone-timer*/ + use_cyclone = 1; /*enable cyclone-timer*/ setup_summit(); /*usb_early_handoff = 1;*/ return 1; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |