[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: Remove (most) Centaur CPU support. Only VIA C7 can work, as it
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Date 1188394800 -3600 # Node ID 79053138b35c8e77ef828f920ce0c68543c6a932 # Parent 86a02b7148fabe25f374b5dbe69579a9d249c821 x86: Remove (most) Centaur CPU support. Only VIA C7 can work, as it has CMOV support. Leave a small amount of centaur.c around to support that. MTRR code goes entirely, as 686-class Centaur CPUs have generic MTRR support. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- xen/arch/x86/cpu/mtrr/centaur.c | 223 ----------------------- xen/arch/x86/cpu/centaur.c | 380 ---------------------------------------- xen/arch/x86/cpu/mtrr/Makefile | 1 xen/arch/x86/cpu/mtrr/main.c | 9 xen/include/asm-x86/spinlock.h | 8 xen/include/asm-x86/system.h | 28 -- 6 files changed, 3 insertions(+), 646 deletions(-) diff -r 86a02b7148fa -r 79053138b35c xen/arch/x86/cpu/centaur.c --- a/xen/arch/x86/cpu/centaur.c Wed Aug 29 11:34:01 2007 +0100 +++ b/xen/arch/x86/cpu/centaur.c Wed Aug 29 14:40:00 2007 +0100 @@ -6,248 +6,6 @@ #include <asm/msr.h> #include <asm/e820.h> #include "cpu.h" - -#ifdef CONFIG_X86_OOSTORE - -static u32 __init power2(u32 x) -{ - u32 s=1; - while(s<=x) - s<<=1; - return s>>=1; -} - - -/* - * Set up an actual MCR - */ - -static void __init centaur_mcr_insert(int reg, u32 base, u32 size, int key) -{ - u32 lo, hi; - - hi = base & ~0xFFF; - lo = ~(size-1); /* Size is a power of 2 so this makes a mask */ - lo &= ~0xFFF; /* Remove the ctrl value bits */ - lo |= key; /* Attribute we wish to set */ - wrmsr(reg+MSR_IDT_MCR0, lo, hi); - mtrr_centaur_report_mcr(reg, lo, hi); /* Tell the mtrr driver */ -} - -/* - * Figure what we can cover with MCR's - * - * Shortcut: We know you can't put 4Gig of RAM on a winchip - */ - -static u32 __init ramtop(void) /* 16388 */ -{ - int i; - u32 top = 0; - u32 clip = 0xFFFFFFFFUL; - - for (i = 0; i < e820.nr_map; i++) { - unsigned long start, end; - - if (e820.map[i].addr > 0xFFFFFFFFUL) - continue; - /* - * Don't MCR over reserved space. Ignore the ISA hole - * we frob around that catastrophy already - */ - - if (e820.map[i].type == E820_RESERVED) - { - if(e820.map[i].addr >= 0x100000UL && e820.map[i].addr < clip) - clip = e820.map[i].addr; - continue; - } - start = e820.map[i].addr; - end = e820.map[i].addr + e820.map[i].size; - if (start >= end) - continue; - if (end > top) - top = end; - } - /* Everything below 'top' should be RAM except for the ISA hole. - Because of the limited MCR's we want to map NV/ACPI into our - MCR range for gunk in RAM - - Clip might cause us to MCR insufficient RAM but that is an - acceptable failure mode and should only bite obscure boxes with - a VESA hole at 15Mb - - The second case Clip sometimes kicks in is when the EBDA is marked - as reserved. Again we fail safe with reasonable results - */ - - if(top>clip) - top=clip; - - return top; -} - -/* - * Compute a set of MCR's to give maximum coverage - */ - -static int __init centaur_mcr_compute(int nr, int key) -{ - u32 mem = ramtop(); - u32 root = power2(mem); - u32 base = root; - u32 top = root; - u32 floor = 0; - int ct = 0; - - while(ct<nr) - { - u32 fspace = 0; - - /* - * Find the largest block we will fill going upwards - */ - - u32 high = power2(mem-top); - - /* - * Find the largest block we will fill going downwards - */ - - u32 low = base/2; - - /* - * Don't fill below 1Mb going downwards as there - * is an ISA hole in the way. - */ - - if(base <= 1024*1024) - low = 0; - - /* - * See how much space we could cover by filling below - * the ISA hole - */ - - if(floor == 0) - fspace = 512*1024; - else if(floor ==512*1024) - fspace = 128*1024; - - /* And forget ROM space */ - - /* - * Now install the largest coverage we get - */ - - if(fspace > high && fspace > low) - { - centaur_mcr_insert(ct, floor, fspace, key); - floor += fspace; - } - else if(high > low) - { - centaur_mcr_insert(ct, top, high, key); - top += high; - } - else if(low > 0) - { - base -= low; - centaur_mcr_insert(ct, base, low, key); - } - else break; - ct++; - } - /* - * We loaded ct values. We now need to set the mask. The caller - * must do this bit. - */ - - return ct; -} - -static void __init centaur_create_optimal_mcr(void) -{ - int i; - /* - * Allocate up to 6 mcrs to mark as much of ram as possible - * as write combining and weak write ordered. - * - * To experiment with: Linux never uses stack operations for - * mmio spaces so we could globally enable stack operation wc - * - * Load the registers with type 31 - full write combining, all - * writes weakly ordered. - */ - int used = centaur_mcr_compute(6, 31); - - /* - * Wipe unused MCRs - */ - - for(i=used;i<8;i++) - wrmsr(MSR_IDT_MCR0+i, 0, 0); -} - -static void __init winchip2_create_optimal_mcr(void) -{ - u32 lo, hi; - int i; - - /* - * Allocate up to 6 mcrs to mark as much of ram as possible - * as write combining, weak store ordered. - * - * Load the registers with type 25 - * 8 - weak write ordering - * 16 - weak read ordering - * 1 - write combining - */ - - int used = centaur_mcr_compute(6, 25); - - /* - * Mark the registers we are using. - */ - - rdmsr(MSR_IDT_MCR_CTRL, lo, hi); - for(i=0;i<used;i++) - lo|=1<<(9+i); - wrmsr(MSR_IDT_MCR_CTRL, lo, hi); - - /* - * Wipe unused MCRs - */ - - for(i=used;i<8;i++) - wrmsr(MSR_IDT_MCR0+i, 0, 0); -} - -/* - * Handle the MCR key on the Winchip 2. - */ - -static void __init winchip2_unprotect_mcr(void) -{ - u32 lo, hi; - u32 key; - - rdmsr(MSR_IDT_MCR_CTRL, lo, hi); - lo&=~0x1C0; /* blank bits 8-6 */ - key = (lo>>17) & 7; - lo |= key<<6; /* replace with unlock key */ - wrmsr(MSR_IDT_MCR_CTRL, lo, hi); -} - -static void __init winchip2_protect_mcr(void) -{ - u32 lo, hi; - - rdmsr(MSR_IDT_MCR_CTRL, lo, hi); - lo&=~0x1C0; /* blank bits 8-6 */ - wrmsr(MSR_IDT_MCR_CTRL, lo, hi); -} -#endif /* CONFIG_X86_OOSTORE */ #define ACE_PRESENT (1 << 6) #define ACE_ENABLED (1 << 7) @@ -305,146 +63,12 @@ static void __init init_c3(struct cpuinf static void __init init_centaur(struct cpuinfo_x86 *c) { - enum { - ECX8=1<<1, - EIERRINT=1<<2, - DPM=1<<3, - DMCE=1<<4, - DSTPCLK=1<<5, - ELINEAR=1<<6, - DSMC=1<<7, - DTLOCK=1<<8, - EDCTLB=1<<8, - EMMX=1<<9, - DPDC=1<<11, - EBRPRED=1<<12, - DIC=1<<13, - DDC=1<<14, - DNA=1<<15, - ERETSTK=1<<16, - E2MMX=1<<19, - EAMD3D=1<<20, - }; - - char *name; - u32 fcr_set=0; - u32 fcr_clr=0; - u32 lo,hi,newlo; - u32 aa,bb,cc,dd; - /* Bit 31 in normal CPUID used for nonstandard 3DNow ID; 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */ clear_bit(0*32+31, c->x86_capability); - switch (c->x86) { - - case 5: - switch(c->x86_model) { - case 4: - name="C6"; - fcr_set=ECX8|DSMC|EDCTLB|EMMX|ERETSTK; - fcr_clr=DPDC; - printk(KERN_NOTICE "Disabling bugged TSC.\n"); - clear_bit(X86_FEATURE_TSC, c->x86_capability); -#ifdef CONFIG_X86_OOSTORE - centaur_create_optimal_mcr(); - /* Enable - write combining on non-stack, non-string - write combining on string, all types - weak write ordering - - The C6 original lacks weak read order - - Note 0x120 is write only on Winchip 1 */ - - wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0); -#endif - break; - case 8: - switch(c->x86_mask) { - default: - name="2"; - break; - case 7 ... 9: - name="2A"; - break; - case 10 ... 15: - name="2B"; - break; - } - fcr_set=ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|E2MMX|EAMD3D; - fcr_clr=DPDC; -#ifdef CONFIG_X86_OOSTORE - winchip2_unprotect_mcr(); - winchip2_create_optimal_mcr(); - rdmsr(MSR_IDT_MCR_CTRL, lo, hi); - /* Enable - write combining on non-stack, non-string - write combining on string, all types - weak write ordering - */ - lo|=31; - wrmsr(MSR_IDT_MCR_CTRL, lo, hi); - winchip2_protect_mcr(); -#endif - break; - case 9: - name="3"; - fcr_set=ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|E2MMX|EAMD3D; - fcr_clr=DPDC; -#ifdef CONFIG_X86_OOSTORE - winchip2_unprotect_mcr(); - winchip2_create_optimal_mcr(); - rdmsr(MSR_IDT_MCR_CTRL, lo, hi); - /* Enable - write combining on non-stack, non-string - write combining on string, all types - weak write ordering - */ - lo|=31; - wrmsr(MSR_IDT_MCR_CTRL, lo, hi); - winchip2_protect_mcr(); -#endif - break; - case 10: - name="4"; - /* no info on the WC4 yet */ - break; - default: - name="??"; - } - - rdmsr(MSR_IDT_FCR1, lo, hi); - newlo=(lo|fcr_set) & (~fcr_clr); - - if (newlo!=lo) { - printk(KERN_INFO "Centaur FCR was 0x%X now 0x%X\n", lo, newlo ); - wrmsr(MSR_IDT_FCR1, newlo, hi ); - } else { - printk(KERN_INFO "Centaur FCR is 0x%X\n",lo); - } - /* Emulate MTRRs using Centaur's MCR. */ - set_bit(X86_FEATURE_CENTAUR_MCR, c->x86_capability); - /* Report CX8 */ - set_bit(X86_FEATURE_CX8, c->x86_capability); - /* Set 3DNow! on Winchip 2 and above. */ - if (c->x86_model >=8) - set_bit(X86_FEATURE_3DNOW, c->x86_capability); - /* See if we can find out some more. */ - if ( cpuid_eax(0x80000000) >= 0x80000005 ) { - /* Yes, we can. */ - cpuid(0x80000005,&aa,&bb,&cc,&dd); - /* Add L1 data and code cache sizes. */ - c->x86_cache_size = (cc>>24)+(dd>>24); - } - snprintf( c->x86_model_id, sizeof(c->x86_model_id), - "WinChip %s", name ); - break; - - case 6: - init_c3(c); - break; - } + if (c->x86 == 6) + init_c3(c); } static unsigned int centaur_size_cache(struct cpuinfo_x86 * c, unsigned int size) diff -r 86a02b7148fa -r 79053138b35c xen/arch/x86/cpu/mtrr/Makefile --- a/xen/arch/x86/cpu/mtrr/Makefile Wed Aug 29 11:34:01 2007 +0100 +++ b/xen/arch/x86/cpu/mtrr/Makefile Wed Aug 29 14:40:00 2007 +0100 @@ -1,5 +1,4 @@ obj-$(x86_32) += amd.o obj-$(x86_32) += amd.o -obj-$(x86_32) += centaur.o obj-$(x86_32) += cyrix.o obj-y += generic.o obj-y += main.o diff -r 86a02b7148fa -r 79053138b35c xen/arch/x86/cpu/mtrr/centaur.c --- a/xen/arch/x86/cpu/mtrr/centaur.c Wed Aug 29 11:34:01 2007 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,223 +0,0 @@ -#include <xen/init.h> -#include <xen/mm.h> -#include <asm/mtrr.h> -#include <asm/msr.h> -#include "mtrr.h" - -static struct { - unsigned long high; - unsigned long low; -} centaur_mcr[8]; - -static u8 centaur_mcr_reserved; -static u8 centaur_mcr_type; /* 0 for winchip, 1 for winchip2 */ - -/* - * Report boot time MCR setups - */ - -static int -centaur_get_free_region(unsigned long base, unsigned long size) -/* [SUMMARY] Get a free MTRR. - <base> The starting (base) address of the region. - <size> The size (in bytes) of the region. - [RETURNS] The index of the region on success, else -1 on error. -*/ -{ - int i, max; - mtrr_type ltype; - unsigned long lbase; - unsigned int lsize; - - max = num_var_ranges; - for (i = 0; i < max; ++i) { - if (centaur_mcr_reserved & (1 << i)) - continue; - mtrr_if->get(i, &lbase, &lsize, <ype); - if (lsize == 0) - return i; - } - return -ENOSPC; -} - -void -mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi) -{ - centaur_mcr[mcr].low = lo; - centaur_mcr[mcr].high = hi; -} - -static void -centaur_get_mcr(unsigned int reg, unsigned long *base, - unsigned int *size, mtrr_type * type) -{ - *base = centaur_mcr[reg].high >> PAGE_SHIFT; - *size = -(centaur_mcr[reg].low & 0xfffff000) >> PAGE_SHIFT; - *type = MTRR_TYPE_WRCOMB; /* If it is there, it is write-combining */ - if (centaur_mcr_type == 1 && ((centaur_mcr[reg].low & 31) & 2)) - *type = MTRR_TYPE_UNCACHABLE; - if (centaur_mcr_type == 1 && (centaur_mcr[reg].low & 31) == 25) - *type = MTRR_TYPE_WRBACK; - if (centaur_mcr_type == 0 && (centaur_mcr[reg].low & 31) == 31) - *type = MTRR_TYPE_WRBACK; - -} - -static void centaur_set_mcr(unsigned int reg, unsigned long base, - unsigned long size, mtrr_type type) -{ - unsigned long low, high; - - if (size == 0) { - /* Disable */ - high = low = 0; - } else { - high = base << PAGE_SHIFT; - if (centaur_mcr_type == 0) - low = -size << PAGE_SHIFT | 0x1f; /* only support write-combining... */ - else { - if (type == MTRR_TYPE_UNCACHABLE) - low = -size << PAGE_SHIFT | 0x02; /* NC */ - else - low = -size << PAGE_SHIFT | 0x09; /* WWO,WC */ - } - } - centaur_mcr[reg].high = high; - centaur_mcr[reg].low = low; - wrmsr(MSR_IDT_MCR0 + reg, low, high); -} - -#if 0 -/* - * Initialise the later (saner) Winchip MCR variant. In this version - * the BIOS can pass us the registers it has used (but not their values) - * and the control register is read/write - */ - -static void __init -centaur_mcr1_init(void) -{ - unsigned i; - u32 lo, hi; - - /* Unfortunately, MCR's are read-only, so there is no way to - * find out what the bios might have done. - */ - - rdmsr(MSR_IDT_MCR_CTRL, lo, hi); - if (((lo >> 17) & 7) == 1) { /* Type 1 Winchip2 MCR */ - lo &= ~0x1C0; /* clear key */ - lo |= 0x040; /* set key to 1 */ - wrmsr(MSR_IDT_MCR_CTRL, lo, hi); /* unlock MCR */ - } - - centaur_mcr_type = 1; - - /* - * Clear any unconfigured MCR's. - */ - - for (i = 0; i < 8; ++i) { - if (centaur_mcr[i].high == 0 && centaur_mcr[i].low == 0) { - if (!(lo & (1 << (9 + i)))) - wrmsr(MSR_IDT_MCR0 + i, 0, 0); - else - /* - * If the BIOS set up an MCR we cannot see it - * but we don't wish to obliterate it - */ - centaur_mcr_reserved |= (1 << i); - } - } - /* - * Throw the main write-combining switch... - * However if OOSTORE is enabled then people have already done far - * cleverer things and we should behave. - */ - - lo |= 15; /* Write combine enables */ - wrmsr(MSR_IDT_MCR_CTRL, lo, hi); -} - -/* - * Initialise the original winchip with read only MCR registers - * no used bitmask for the BIOS to pass on and write only control - */ - -static void __init -centaur_mcr0_init(void) -{ - unsigned i; - - /* Unfortunately, MCR's are read-only, so there is no way to - * find out what the bios might have done. - */ - - /* Clear any unconfigured MCR's. - * This way we are sure that the centaur_mcr array contains the actual - * values. The disadvantage is that any BIOS tweaks are thus undone. - * - */ - for (i = 0; i < 8; ++i) { - if (centaur_mcr[i].high == 0 && centaur_mcr[i].low == 0) - wrmsr(MSR_IDT_MCR0 + i, 0, 0); - } - - wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0); /* Write only */ -} - -/* - * Initialise Winchip series MCR registers - */ - -static void __init -centaur_mcr_init(void) -{ - struct set_mtrr_context ctxt; - - set_mtrr_prepare_save(&ctxt); - set_mtrr_cache_disable(&ctxt); - - if (boot_cpu_data.x86_model == 4) - centaur_mcr0_init(); - else if (boot_cpu_data.x86_model == 8 || boot_cpu_data.x86_model == 9) - centaur_mcr1_init(); - - set_mtrr_done(&ctxt); -} -#endif - -static int centaur_validate_add_page(unsigned long base, - unsigned long size, unsigned int type) -{ - /* - * FIXME: Winchip2 supports uncached - */ - if (type != MTRR_TYPE_WRCOMB && - (centaur_mcr_type == 0 || type != MTRR_TYPE_UNCACHABLE)) { - printk(KERN_WARNING - "mtrr: only write-combining%s supported\n", - centaur_mcr_type ? " and uncacheable are" - : " is"); - return -EINVAL; - } - return 0; -} - -static struct mtrr_ops centaur_mtrr_ops = { - .vendor = X86_VENDOR_CENTAUR, -// .init = centaur_mcr_init, - .set = centaur_set_mcr, - .get = centaur_get_mcr, - .get_free_region = centaur_get_free_region, - .validate_add_page = centaur_validate_add_page, - .have_wrcomb = positive_have_wrcomb, -}; - -int __init centaur_init_mtrr(void) -{ - set_mtrr_ops(¢aur_mtrr_ops); - return 0; -} - -//arch_initcall(centaur_init_mtrr); diff -r 86a02b7148fa -r 79053138b35c xen/arch/x86/cpu/mtrr/main.c --- a/xen/arch/x86/cpu/mtrr/main.c Wed Aug 29 11:34:01 2007 +0100 +++ b/xen/arch/x86/cpu/mtrr/main.c Wed Aug 29 14:40:00 2007 +0100 @@ -539,14 +539,12 @@ EXPORT_SYMBOL(mtrr_del); */ extern void amd_init_mtrr(void); extern void cyrix_init_mtrr(void); -extern void centaur_init_mtrr(void); static void __init init_ifs(void) { #ifndef CONFIG_X86_64 amd_init_mtrr(); cyrix_init_mtrr(); - centaur_init_mtrr(); #endif } @@ -609,13 +607,6 @@ void __init mtrr_bp_init(void) size_and_mask = 0; } break; - case X86_VENDOR_CENTAUR: - if (cpu_has_centaur_mcr) { - mtrr_if = mtrr_ops[X86_VENDOR_CENTAUR]; - size_or_mask = 0xfff00000; /* 32 bits */ - size_and_mask = 0; - } - break; case X86_VENDOR_CYRIX: if (cpu_has_cyrix_arr) { mtrr_if = mtrr_ops[X86_VENDOR_CYRIX]; diff -r 86a02b7148fa -r 79053138b35c xen/include/asm-x86/spinlock.h --- a/xen/include/asm-x86/spinlock.h Wed Aug 29 11:34:01 2007 +0100 +++ b/xen/include/asm-x86/spinlock.h Wed Aug 29 14:40:00 2007 +0100 @@ -33,18 +33,10 @@ static inline void _raw_spin_lock(spinlo static inline void _raw_spin_unlock(spinlock_t *lock) { -#if !defined(CONFIG_X86_OOSTORE) ASSERT(spin_is_locked(lock)); __asm__ __volatile__ ( "movb $1,%0" : "=m" (lock->lock) : : "memory" ); -#else - char oldval = 1; - ASSERT(spin_is_locked(lock)); - __asm__ __volatile__ ( - "xchgb %b0, %1" - : "=q" (oldval), "=m" (lock->lock) : "0" (oldval) : "memory" ); -#endif } static inline int _raw_spin_trylock(spinlock_t *lock) diff -r 86a02b7148fa -r 79053138b35c xen/include/asm-x86/system.h --- a/xen/include/asm-x86/system.h Wed Aug 29 11:34:01 2007 +0100 +++ b/xen/include/asm-x86/system.h Wed Aug 29 14:40:00 2007 +0100 @@ -253,40 +253,14 @@ static always_inline unsigned long long }) #endif -/* - * Force strict CPU ordering. - * And yes, this is required on UP too when we're talking - * to devices. - * - * For now, "wmb()" doesn't actually do anything, as all - * Intel CPU's follow what Intel calls a *Processor Order*, - * in which all writes are seen in the program order even - * outside the CPU. - * - * I expect future Intel CPU's to have a weaker ordering, - * but I'd also expect them to finally get their act together - * and add some real memory barriers if so. - * - * Some non intel clones support out of order store. wmb() ceases to be a - * nop for these. - */ #if defined(__i386__) #define mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory") #define rmb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory") -#ifdef CONFIG_X86_OOSTORE -#define wmb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory") -#endif #elif defined(__x86_64__) #define mb() __asm__ __volatile__ ("mfence":::"memory") #define rmb() __asm__ __volatile__ ("lfence":::"memory") -#ifdef CONFIG_X86_OOSTORE -#define wmb() __asm__ __volatile__ ("sfence":::"memory") -#endif -#endif - -#ifndef CONFIG_X86_OOSTORE +#endif #define wmb() __asm__ __volatile__ ("": : :"memory") -#endif #ifdef CONFIG_SMP #define smp_mb() mb() _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |