| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | #include <linux/init.h> | 
 | 2 | #include <linux/kernel.h> | 
 | 3 |  | 
 | 4 | #include <linux/string.h> | 
 | 5 | #include <linux/bitops.h> | 
 | 6 | #include <linux/smp.h> | 
 | 7 | #include <linux/thread_info.h> | 
| Nick Piggin | 53e86b9 | 2005-11-13 16:07:23 -0800 | [diff] [blame] | 8 | #include <linux/module.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 9 |  | 
 | 10 | #include <asm/processor.h> | 
| Sam Ravnborg | d72b1b4 | 2007-10-17 18:04:33 +0200 | [diff] [blame] | 11 | #include <asm/pgtable.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 12 | #include <asm/msr.h> | 
 | 13 | #include <asm/uaccess.h> | 
| Markus Metzger | eee3af4 | 2008-01-30 13:31:09 +0100 | [diff] [blame] | 14 | #include <asm/ptrace.h> | 
 | 15 | #include <asm/ds.h> | 
| Harvey Harrison | 73bdb73 | 2008-02-04 16:48:04 +0100 | [diff] [blame] | 16 | #include <asm/bugs.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 17 |  | 
 | 18 | #include "cpu.h" | 
 | 19 |  | 
 | 20 | #ifdef CONFIG_X86_LOCAL_APIC | 
 | 21 | #include <asm/mpspec.h> | 
 | 22 | #include <asm/apic.h> | 
 | 23 | #include <mach_apic.h> | 
 | 24 | #endif | 
 | 25 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 26 | #ifdef CONFIG_X86_INTEL_USERCOPY | 
 | 27 | /* | 
 | 28 |  * Alignment at which movsl is preferred for bulk memory copies. | 
 | 29 |  */ | 
| Christoph Lameter | 6c03652 | 2005-07-07 17:56:59 -0700 | [diff] [blame] | 30 | struct movsl_mask movsl_mask __read_mostly; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 31 | #endif | 
 | 32 |  | 
| Thomas Petazzoni | 03ae576 | 2008-02-15 12:00:23 +0100 | [diff] [blame] | 33 | static void __cpuinit early_init_intel(struct cpuinfo_x86 *c) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 34 | { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 35 | 	/* Netburst reports 64 bytes clflush size, but does IO in 128 bytes */ | 
 | 36 | 	if (c->x86 == 15 && c->x86_cache_alignment == 64) | 
 | 37 | 		c->x86_cache_alignment = 128; | 
| Andi Kleen | 2b16a23 | 2008-01-30 13:32:40 +0100 | [diff] [blame] | 38 | 	if ((c->x86 == 0xf && c->x86_model >= 0x03) || | 
 | 39 | 		(c->x86 == 0x6 && c->x86_model >= 0x0e)) | 
 | 40 | 		set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 41 | } | 
 | 42 |  | 
 | 43 | /* | 
 | 44 |  *	Early probe support logic for ppro memory erratum #50 | 
 | 45 |  * | 
 | 46 |  *	This is called before we do cpu ident work | 
 | 47 |  */ | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 48 |  | 
| Chuck Ebbert | 3bc9b76 | 2006-03-23 02:59:33 -0800 | [diff] [blame] | 49 | int __cpuinit ppro_with_ram_bug(void) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 50 | { | 
 | 51 | 	/* Uses data from early_cpu_detect now */ | 
 | 52 | 	if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && | 
 | 53 | 	    boot_cpu_data.x86 == 6 && | 
 | 54 | 	    boot_cpu_data.x86_model == 1 && | 
 | 55 | 	    boot_cpu_data.x86_mask < 8) { | 
 | 56 | 		printk(KERN_INFO "Pentium Pro with Errata#50 detected. Taking evasive action.\n"); | 
 | 57 | 		return 1; | 
 | 58 | 	} | 
 | 59 | 	return 0; | 
 | 60 | } | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 61 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 62 |  | 
 | 63 | /* | 
 | 64 |  * P4 Xeon errata 037 workaround. | 
 | 65 |  * Hardware prefetcher may cause stale data to be loaded into the cache. | 
 | 66 |  */ | 
| Chuck Ebbert | 3bc9b76 | 2006-03-23 02:59:33 -0800 | [diff] [blame] | 67 | static void __cpuinit Intel_errata_workarounds(struct cpuinfo_x86 *c) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 68 | { | 
 | 69 | 	unsigned long lo, hi; | 
 | 70 |  | 
 | 71 | 	if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) { | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 72 | 		rdmsr(MSR_IA32_MISC_ENABLE, lo, hi); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 73 | 		if ((lo & (1<<9)) == 0) { | 
 | 74 | 			printk (KERN_INFO "CPU: C0 stepping P4 Xeon detected.\n"); | 
 | 75 | 			printk (KERN_INFO "CPU: Disabling hardware prefetching (Errata 037)\n"); | 
 | 76 | 			lo |= (1<<9);	/* Disable hw prefetching */ | 
 | 77 | 			wrmsr (MSR_IA32_MISC_ENABLE, lo, hi); | 
 | 78 | 		} | 
 | 79 | 	} | 
 | 80 | } | 
 | 81 |  | 
 | 82 |  | 
| Andi Kleen | 3dd9d51 | 2005-04-16 15:25:15 -0700 | [diff] [blame] | 83 | /* | 
 | 84 |  * find out the number of processor cores on the die | 
 | 85 |  */ | 
| Chuck Ebbert | 3bc9b76 | 2006-03-23 02:59:33 -0800 | [diff] [blame] | 86 | static int __cpuinit num_cpu_cores(struct cpuinfo_x86 *c) | 
| Andi Kleen | 3dd9d51 | 2005-04-16 15:25:15 -0700 | [diff] [blame] | 87 | { | 
| Zachary Amsden | f2ab446 | 2005-09-03 15:56:42 -0700 | [diff] [blame] | 88 | 	unsigned int eax, ebx, ecx, edx; | 
| Andi Kleen | 3dd9d51 | 2005-04-16 15:25:15 -0700 | [diff] [blame] | 89 |  | 
 | 90 | 	if (c->cpuid_level < 4) | 
 | 91 | 		return 1; | 
 | 92 |  | 
| Zachary Amsden | f2ab446 | 2005-09-03 15:56:42 -0700 | [diff] [blame] | 93 | 	/* Intel has a non-standard dependency on %ecx for this CPUID level. */ | 
 | 94 | 	cpuid_count(4, 0, &eax, &ebx, &ecx, &edx); | 
| Andi Kleen | 3dd9d51 | 2005-04-16 15:25:15 -0700 | [diff] [blame] | 95 | 	if (eax & 0x1f) | 
 | 96 | 		return ((eax >> 26) + 1); | 
 | 97 | 	else | 
 | 98 | 		return 1; | 
 | 99 | } | 
 | 100 |  | 
| Sam Ravnborg | d72b1b4 | 2007-10-17 18:04:33 +0200 | [diff] [blame] | 101 | #ifdef CONFIG_X86_F00F_BUG | 
 | 102 | static void __cpuinit trap_init_f00f_bug(void) | 
 | 103 | { | 
 | 104 | 	__set_fixmap(FIX_F00F_IDT, __pa(&idt_table), PAGE_KERNEL_RO); | 
 | 105 |  | 
 | 106 | 	/* | 
 | 107 | 	 * Update the IDT descriptor and reload the IDT so that | 
 | 108 | 	 * it uses the read-only mapped virtual address. | 
 | 109 | 	 */ | 
 | 110 | 	idt_descr.address = fix_to_virt(FIX_F00F_IDT); | 
 | 111 | 	load_idt(&idt_descr); | 
 | 112 | } | 
 | 113 | #endif | 
 | 114 |  | 
| Chuck Ebbert | 3bc9b76 | 2006-03-23 02:59:33 -0800 | [diff] [blame] | 115 | static void __cpuinit init_intel(struct cpuinfo_x86 *c) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 116 | { | 
 | 117 | 	unsigned int l2 = 0; | 
 | 118 | 	char *p = NULL; | 
 | 119 |  | 
| Andi Kleen | 2b16a23 | 2008-01-30 13:32:40 +0100 | [diff] [blame] | 120 | 	early_init_intel(c); | 
 | 121 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 122 | #ifdef CONFIG_X86_F00F_BUG | 
 | 123 | 	/* | 
 | 124 | 	 * All current models of Pentium and Pentium with MMX technology CPUs | 
 | 125 | 	 * have the F0 0F bug, which lets nonprivileged users lock up the system. | 
 | 126 | 	 * Note that the workaround only should be initialized once... | 
 | 127 | 	 */ | 
 | 128 | 	c->f00f_bug = 0; | 
| Rusty Russell | 4f205fd | 2006-12-07 02:14:08 +0100 | [diff] [blame] | 129 | 	if (!paravirt_enabled() && c->x86 == 5) { | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 130 | 		static int f00f_workaround_enabled; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 131 |  | 
 | 132 | 		c->f00f_bug = 1; | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 133 | 		if (!f00f_workaround_enabled) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 134 | 			trap_init_f00f_bug(); | 
 | 135 | 			printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n"); | 
 | 136 | 			f00f_workaround_enabled = 1; | 
 | 137 | 		} | 
 | 138 | 	} | 
 | 139 | #endif | 
 | 140 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 141 | 	l2 = init_intel_cacheinfo(c); | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 142 | 	if (c->cpuid_level > 9) { | 
| Venkatesh Pallipadi | 0080e66 | 2006-06-26 13:59:59 +0200 | [diff] [blame] | 143 | 		unsigned eax = cpuid_eax(10); | 
 | 144 | 		/* Check for version and the number of counters */ | 
 | 145 | 		if ((eax & 0xff) && (((eax>>8) & 0xff) > 1)) | 
| Ingo Molnar | d0e95eb | 2008-02-26 08:52:33 +0100 | [diff] [blame] | 146 | 			set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON); | 
| Venkatesh Pallipadi | 0080e66 | 2006-06-26 13:59:59 +0200 | [diff] [blame] | 147 | 	} | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 148 |  | 
 | 149 | 	/* SEP CPUID bug: Pentium Pro reports SEP but doesn't have it until model 3 mask 3 */ | 
 | 150 | 	if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633) | 
| Ingo Molnar | d0e95eb | 2008-02-26 08:52:33 +0100 | [diff] [blame] | 151 | 		clear_cpu_cap(c, X86_FEATURE_SEP); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 152 |  | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 153 | 	/* | 
 | 154 | 	 * Names for the Pentium II/Celeron processors | 
 | 155 | 	 * detectable only by also checking the cache size. | 
 | 156 | 	 * Dixon is NOT a Celeron. | 
 | 157 | 	 */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 158 | 	if (c->x86 == 6) { | 
 | 159 | 		switch (c->x86_model) { | 
 | 160 | 		case 5: | 
 | 161 | 			if (c->x86_mask == 0) { | 
 | 162 | 				if (l2 == 0) | 
 | 163 | 					p = "Celeron (Covington)"; | 
 | 164 | 				else if (l2 == 256) | 
 | 165 | 					p = "Mobile Pentium II (Dixon)"; | 
 | 166 | 			} | 
 | 167 | 			break; | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 168 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 169 | 		case 6: | 
 | 170 | 			if (l2 == 128) | 
 | 171 | 				p = "Celeron (Mendocino)"; | 
 | 172 | 			else if (c->x86_mask == 0 || c->x86_mask == 5) | 
 | 173 | 				p = "Celeron-A"; | 
 | 174 | 			break; | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 175 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 176 | 		case 8: | 
 | 177 | 			if (l2 == 128) | 
 | 178 | 				p = "Celeron (Coppermine)"; | 
 | 179 | 			break; | 
 | 180 | 		} | 
 | 181 | 	} | 
 | 182 |  | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 183 | 	if (p) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 184 | 		strcpy(c->x86_model_id, p); | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 185 |  | 
| Siddha, Suresh B | 94605ef | 2005-11-05 17:25:54 +0100 | [diff] [blame] | 186 | 	c->x86_max_cores = num_cpu_cores(c); | 
| Andi Kleen | 3dd9d51 | 2005-04-16 15:25:15 -0700 | [diff] [blame] | 187 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 188 | 	detect_ht(c); | 
 | 189 |  | 
 | 190 | 	/* Work around errata */ | 
 | 191 | 	Intel_errata_workarounds(c); | 
 | 192 |  | 
 | 193 | #ifdef CONFIG_X86_INTEL_USERCOPY | 
 | 194 | 	/* | 
 | 195 | 	 * Set up the preferred alignment for movsl bulk memory moves | 
 | 196 | 	 */ | 
 | 197 | 	switch (c->x86) { | 
 | 198 | 	case 4:		/* 486: untested */ | 
 | 199 | 		break; | 
 | 200 | 	case 5:		/* Old Pentia: untested */ | 
 | 201 | 		break; | 
 | 202 | 	case 6:		/* PII/PIII only like movsl with 8-byte alignment */ | 
 | 203 | 		movsl_mask.mask = 7; | 
 | 204 | 		break; | 
 | 205 | 	case 15:	/* P4 is OK down to 8-byte alignment */ | 
 | 206 | 		movsl_mask.mask = 7; | 
 | 207 | 		break; | 
 | 208 | 	} | 
 | 209 | #endif | 
 | 210 |  | 
| Ingo Molnar | 6d5f718 | 2008-01-30 13:32:38 +0100 | [diff] [blame] | 211 | 	if (cpu_has_xmm2) | 
| Ingo Molnar | d0e95eb | 2008-02-26 08:52:33 +0100 | [diff] [blame] | 212 | 		set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC); | 
| Andi Kleen | 3aefbe0 | 2007-05-02 19:27:20 +0200 | [diff] [blame] | 213 | 	if (c->x86 == 15) { | 
| Ingo Molnar | d0e95eb | 2008-02-26 08:52:33 +0100 | [diff] [blame] | 214 | 		set_cpu_cap(c, X86_FEATURE_P4); | 
| Andi Kleen | 3aefbe0 | 2007-05-02 19:27:20 +0200 | [diff] [blame] | 215 | 	} | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 216 | 	if (c->x86 == 6) | 
| Ingo Molnar | d0e95eb | 2008-02-26 08:52:33 +0100 | [diff] [blame] | 217 | 		set_cpu_cap(c, X86_FEATURE_P3); | 
| Stephane Eranian | 42ed458 | 2006-12-07 02:14:01 +0100 | [diff] [blame] | 218 | 	if (cpu_has_ds) { | 
 | 219 | 		unsigned int l1; | 
 | 220 | 		rdmsr(MSR_IA32_MISC_ENABLE, l1, l2); | 
| Stephane Eranian | 538f188 | 2006-12-07 02:14:11 +0100 | [diff] [blame] | 221 | 		if (!(l1 & (1<<11))) | 
| Ingo Molnar | d0e95eb | 2008-02-26 08:52:33 +0100 | [diff] [blame] | 222 | 			set_cpu_cap(c, X86_FEATURE_BTS); | 
| Stephane Eranian | 42ed458 | 2006-12-07 02:14:01 +0100 | [diff] [blame] | 223 | 		if (!(l1 & (1<<12))) | 
| Ingo Molnar | d0e95eb | 2008-02-26 08:52:33 +0100 | [diff] [blame] | 224 | 			set_cpu_cap(c, X86_FEATURE_PEBS); | 
| Stephane Eranian | 42ed458 | 2006-12-07 02:14:01 +0100 | [diff] [blame] | 225 | 	} | 
| Markus Metzger | eee3af4 | 2008-01-30 13:31:09 +0100 | [diff] [blame] | 226 |  | 
 | 227 | 	if (cpu_has_bts) | 
 | 228 | 		ds_init_intel(c); | 
| Stephane Eranian | 42ed458 | 2006-12-07 02:14:01 +0100 | [diff] [blame] | 229 | } | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 230 |  | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 231 | static unsigned int __cpuinit intel_size_cache(struct cpuinfo_x86 *c, unsigned int size) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 232 | { | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 233 | 	/* | 
 | 234 | 	 * Intel PIII Tualatin. This comes in two flavours. | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 235 | 	 * One has 256kb of cache, the other 512. We have no way | 
 | 236 | 	 * to determine which, so we use a boottime override | 
 | 237 | 	 * for the 512kb model, and assume 256 otherwise. | 
 | 238 | 	 */ | 
 | 239 | 	if ((c->x86 == 6) && (c->x86_model == 11) && (size == 0)) | 
 | 240 | 		size = 256; | 
 | 241 | 	return size; | 
 | 242 | } | 
 | 243 |  | 
| Chuck Ebbert | 3bc9b76 | 2006-03-23 02:59:33 -0800 | [diff] [blame] | 244 | static struct cpu_dev intel_cpu_dev __cpuinitdata = { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 245 | 	.c_vendor	= "Intel", | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 246 | 	.c_ident	= { "GenuineIntel" }, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 247 | 	.c_models = { | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 248 | 		{ .vendor = X86_VENDOR_INTEL, .family = 4, .model_names = | 
 | 249 | 		  { | 
 | 250 | 			  [0] = "486 DX-25/33", | 
 | 251 | 			  [1] = "486 DX-50", | 
 | 252 | 			  [2] = "486 SX", | 
 | 253 | 			  [3] = "486 DX/2", | 
 | 254 | 			  [4] = "486 SL", | 
 | 255 | 			  [5] = "486 SX/2", | 
 | 256 | 			  [7] = "486 DX/2-WB", | 
 | 257 | 			  [8] = "486 DX/4", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 258 | 			  [9] = "486 DX/4-WB" | 
 | 259 | 		  } | 
 | 260 | 		}, | 
 | 261 | 		{ .vendor = X86_VENDOR_INTEL, .family = 5, .model_names = | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 262 | 		  { | 
 | 263 | 			  [0] = "Pentium 60/66 A-step", | 
 | 264 | 			  [1] = "Pentium 60/66", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 265 | 			  [2] = "Pentium 75 - 200", | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 266 | 			  [3] = "OverDrive PODP5V83", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 267 | 			  [4] = "Pentium MMX", | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 268 | 			  [7] = "Mobile Pentium 75 - 200", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 269 | 			  [8] = "Mobile Pentium MMX" | 
 | 270 | 		  } | 
 | 271 | 		}, | 
 | 272 | 		{ .vendor = X86_VENDOR_INTEL, .family = 6, .model_names = | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 273 | 		  { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 274 | 			  [0] = "Pentium Pro A-step", | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 275 | 			  [1] = "Pentium Pro", | 
 | 276 | 			  [3] = "Pentium II (Klamath)", | 
 | 277 | 			  [4] = "Pentium II (Deschutes)", | 
 | 278 | 			  [5] = "Pentium II (Deschutes)", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 279 | 			  [6] = "Mobile Pentium II", | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 280 | 			  [7] = "Pentium III (Katmai)", | 
 | 281 | 			  [8] = "Pentium III (Coppermine)", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 282 | 			  [10] = "Pentium III (Cascades)", | 
 | 283 | 			  [11] = "Pentium III (Tualatin)", | 
 | 284 | 		  } | 
 | 285 | 		}, | 
 | 286 | 		{ .vendor = X86_VENDOR_INTEL, .family = 15, .model_names = | 
 | 287 | 		  { | 
 | 288 | 			  [0] = "Pentium 4 (Unknown)", | 
 | 289 | 			  [1] = "Pentium 4 (Willamette)", | 
 | 290 | 			  [2] = "Pentium 4 (Northwood)", | 
 | 291 | 			  [4] = "Pentium 4 (Foster)", | 
 | 292 | 			  [5] = "Pentium 4 (Foster)", | 
 | 293 | 		  } | 
 | 294 | 		}, | 
 | 295 | 	}, | 
| Thomas Petazzoni | 03ae576 | 2008-02-15 12:00:23 +0100 | [diff] [blame] | 296 | 	.c_early_init   = early_init_intel, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 297 | 	.c_init		= init_intel, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 298 | 	.c_size_cache	= intel_size_cache, | 
 | 299 | }; | 
 | 300 |  | 
| Thomas Petazzoni | 03ae576 | 2008-02-15 12:00:23 +0100 | [diff] [blame] | 301 | cpu_vendor_dev_register(X86_VENDOR_INTEL, &intel_cpu_dev); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 302 |  | 
| Nick Piggin | 53e86b9 | 2005-11-13 16:07:23 -0800 | [diff] [blame] | 303 | #ifndef CONFIG_X86_CMPXCHG | 
 | 304 | unsigned long cmpxchg_386_u8(volatile void *ptr, u8 old, u8 new) | 
 | 305 | { | 
 | 306 | 	u8 prev; | 
 | 307 | 	unsigned long flags; | 
 | 308 |  | 
 | 309 | 	/* Poor man's cmpxchg for 386. Unsuitable for SMP */ | 
 | 310 | 	local_irq_save(flags); | 
 | 311 | 	prev = *(u8 *)ptr; | 
 | 312 | 	if (prev == old) | 
 | 313 | 		*(u8 *)ptr = new; | 
 | 314 | 	local_irq_restore(flags); | 
 | 315 | 	return prev; | 
 | 316 | } | 
 | 317 | EXPORT_SYMBOL(cmpxchg_386_u8); | 
 | 318 |  | 
 | 319 | unsigned long cmpxchg_386_u16(volatile void *ptr, u16 old, u16 new) | 
 | 320 | { | 
 | 321 | 	u16 prev; | 
 | 322 | 	unsigned long flags; | 
 | 323 |  | 
 | 324 | 	/* Poor man's cmpxchg for 386. Unsuitable for SMP */ | 
 | 325 | 	local_irq_save(flags); | 
 | 326 | 	prev = *(u16 *)ptr; | 
 | 327 | 	if (prev == old) | 
 | 328 | 		*(u16 *)ptr = new; | 
 | 329 | 	local_irq_restore(flags); | 
 | 330 | 	return prev; | 
 | 331 | } | 
 | 332 | EXPORT_SYMBOL(cmpxchg_386_u16); | 
 | 333 |  | 
 | 334 | unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new) | 
 | 335 | { | 
 | 336 | 	u32 prev; | 
 | 337 | 	unsigned long flags; | 
 | 338 |  | 
 | 339 | 	/* Poor man's cmpxchg for 386. Unsuitable for SMP */ | 
 | 340 | 	local_irq_save(flags); | 
 | 341 | 	prev = *(u32 *)ptr; | 
 | 342 | 	if (prev == old) | 
 | 343 | 		*(u32 *)ptr = new; | 
 | 344 | 	local_irq_restore(flags); | 
 | 345 | 	return prev; | 
 | 346 | } | 
 | 347 | EXPORT_SYMBOL(cmpxchg_386_u32); | 
 | 348 | #endif | 
 | 349 |  | 
| Mathieu Desnoyers | 2c0b8a7 | 2008-01-30 13:30:47 +0100 | [diff] [blame] | 350 | #ifndef CONFIG_X86_CMPXCHG64 | 
 | 351 | unsigned long long cmpxchg_486_u64(volatile void *ptr, u64 old, u64 new) | 
 | 352 | { | 
 | 353 | 	u64 prev; | 
 | 354 | 	unsigned long flags; | 
 | 355 |  | 
 | 356 | 	/* Poor man's cmpxchg8b for 386 and 486. Unsuitable for SMP */ | 
 | 357 | 	local_irq_save(flags); | 
 | 358 | 	prev = *(u64 *)ptr; | 
 | 359 | 	if (prev == old) | 
 | 360 | 		*(u64 *)ptr = new; | 
 | 361 | 	local_irq_restore(flags); | 
 | 362 | 	return prev; | 
 | 363 | } | 
 | 364 | EXPORT_SYMBOL(cmpxchg_486_u64); | 
 | 365 | #endif | 
 | 366 |  | 
| Paolo Ciarrocchi | 65eb6b4 | 2008-02-22 23:09:42 +0100 | [diff] [blame] | 367 | /* arch_initcall(intel_cpu_init); */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 368 |  |