Commit f2ab4461249df85b20930a7a57b54f39c5ae291a

Authored by Zachary Amsden
Committed by Linus Torvalds
1 parent 4f0cb8d978

[PATCH] x86: more asm cleanups

Some more assembler cleanups I noticed along the way.

Signed-off-by: Zachary Amsden <zach@vmware.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 8 changed files with 35 additions and 50 deletions Inline Diff

arch/i386/kernel/cpu/intel.c
1 #include <linux/config.h> 1 #include <linux/config.h>
2 #include <linux/init.h> 2 #include <linux/init.h>
3 #include <linux/kernel.h> 3 #include <linux/kernel.h>
4 4
5 #include <linux/string.h> 5 #include <linux/string.h>
6 #include <linux/bitops.h> 6 #include <linux/bitops.h>
7 #include <linux/smp.h> 7 #include <linux/smp.h>
8 #include <linux/thread_info.h> 8 #include <linux/thread_info.h>
9 9
10 #include <asm/processor.h> 10 #include <asm/processor.h>
11 #include <asm/msr.h> 11 #include <asm/msr.h>
12 #include <asm/uaccess.h> 12 #include <asm/uaccess.h>
13 13
14 #include "cpu.h" 14 #include "cpu.h"
15 15
16 #ifdef CONFIG_X86_LOCAL_APIC 16 #ifdef CONFIG_X86_LOCAL_APIC
17 #include <asm/mpspec.h> 17 #include <asm/mpspec.h>
18 #include <asm/apic.h> 18 #include <asm/apic.h>
19 #include <mach_apic.h> 19 #include <mach_apic.h>
20 #endif 20 #endif
21 21
22 extern int trap_init_f00f_bug(void); 22 extern int trap_init_f00f_bug(void);
23 23
24 #ifdef CONFIG_X86_INTEL_USERCOPY 24 #ifdef CONFIG_X86_INTEL_USERCOPY
25 /* 25 /*
26 * Alignment at which movsl is preferred for bulk memory copies. 26 * Alignment at which movsl is preferred for bulk memory copies.
27 */ 27 */
28 struct movsl_mask movsl_mask __read_mostly; 28 struct movsl_mask movsl_mask __read_mostly;
29 #endif 29 #endif
30 30
31 void __devinit early_intel_workaround(struct cpuinfo_x86 *c) 31 void __devinit early_intel_workaround(struct cpuinfo_x86 *c)
32 { 32 {
33 if (c->x86_vendor != X86_VENDOR_INTEL) 33 if (c->x86_vendor != X86_VENDOR_INTEL)
34 return; 34 return;
35 /* Netburst reports 64 bytes clflush size, but does IO in 128 bytes */ 35 /* Netburst reports 64 bytes clflush size, but does IO in 128 bytes */
36 if (c->x86 == 15 && c->x86_cache_alignment == 64) 36 if (c->x86 == 15 && c->x86_cache_alignment == 64)
37 c->x86_cache_alignment = 128; 37 c->x86_cache_alignment = 128;
38 } 38 }
39 39
40 /* 40 /*
41 * Early probe support logic for ppro memory erratum #50 41 * Early probe support logic for ppro memory erratum #50
42 * 42 *
43 * This is called before we do cpu ident work 43 * This is called before we do cpu ident work
44 */ 44 */
45 45
46 int __devinit ppro_with_ram_bug(void) 46 int __devinit ppro_with_ram_bug(void)
47 { 47 {
48 /* Uses data from early_cpu_detect now */ 48 /* Uses data from early_cpu_detect now */
49 if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && 49 if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
50 boot_cpu_data.x86 == 6 && 50 boot_cpu_data.x86 == 6 &&
51 boot_cpu_data.x86_model == 1 && 51 boot_cpu_data.x86_model == 1 &&
52 boot_cpu_data.x86_mask < 8) { 52 boot_cpu_data.x86_mask < 8) {
53 printk(KERN_INFO "Pentium Pro with Errata#50 detected. Taking evasive action.\n"); 53 printk(KERN_INFO "Pentium Pro with Errata#50 detected. Taking evasive action.\n");
54 return 1; 54 return 1;
55 } 55 }
56 return 0; 56 return 0;
57 } 57 }
58 58
59 59
60 /* 60 /*
61 * P4 Xeon errata 037 workaround. 61 * P4 Xeon errata 037 workaround.
62 * Hardware prefetcher may cause stale data to be loaded into the cache. 62 * Hardware prefetcher may cause stale data to be loaded into the cache.
63 */ 63 */
64 static void __devinit Intel_errata_workarounds(struct cpuinfo_x86 *c) 64 static void __devinit Intel_errata_workarounds(struct cpuinfo_x86 *c)
65 { 65 {
66 unsigned long lo, hi; 66 unsigned long lo, hi;
67 67
68 if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) { 68 if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) {
69 rdmsr (MSR_IA32_MISC_ENABLE, lo, hi); 69 rdmsr (MSR_IA32_MISC_ENABLE, lo, hi);
70 if ((lo & (1<<9)) == 0) { 70 if ((lo & (1<<9)) == 0) {
71 printk (KERN_INFO "CPU: C0 stepping P4 Xeon detected.\n"); 71 printk (KERN_INFO "CPU: C0 stepping P4 Xeon detected.\n");
72 printk (KERN_INFO "CPU: Disabling hardware prefetching (Errata 037)\n"); 72 printk (KERN_INFO "CPU: Disabling hardware prefetching (Errata 037)\n");
73 lo |= (1<<9); /* Disable hw prefetching */ 73 lo |= (1<<9); /* Disable hw prefetching */
74 wrmsr (MSR_IA32_MISC_ENABLE, lo, hi); 74 wrmsr (MSR_IA32_MISC_ENABLE, lo, hi);
75 } 75 }
76 } 76 }
77 } 77 }
78 78
79 79
80 /* 80 /*
81 * find out the number of processor cores on the die 81 * find out the number of processor cores on the die
82 */ 82 */
83 static int __devinit num_cpu_cores(struct cpuinfo_x86 *c) 83 static int __devinit num_cpu_cores(struct cpuinfo_x86 *c)
84 { 84 {
85 unsigned int eax; 85 unsigned int eax, ebx, ecx, edx;
86 86
87 if (c->cpuid_level < 4) 87 if (c->cpuid_level < 4)
88 return 1; 88 return 1;
89 89
90 __asm__("cpuid" 90 /* Intel has a non-standard dependency on %ecx for this CPUID level. */
91 : "=a" (eax) 91 cpuid_count(4, 0, &eax, &ebx, &ecx, &edx);
92 : "0" (4), "c" (0)
93 : "bx", "dx");
94
95 if (eax & 0x1f) 92 if (eax & 0x1f)
96 return ((eax >> 26) + 1); 93 return ((eax >> 26) + 1);
97 else 94 else
98 return 1; 95 return 1;
99 } 96 }
100 97
101 static void __devinit init_intel(struct cpuinfo_x86 *c) 98 static void __devinit init_intel(struct cpuinfo_x86 *c)
102 { 99 {
103 unsigned int l2 = 0; 100 unsigned int l2 = 0;
104 char *p = NULL; 101 char *p = NULL;
105 102
106 #ifdef CONFIG_X86_F00F_BUG 103 #ifdef CONFIG_X86_F00F_BUG
107 /* 104 /*
108 * All current models of Pentium and Pentium with MMX technology CPUs 105 * All current models of Pentium and Pentium with MMX technology CPUs
109 * have the F0 0F bug, which lets nonprivileged users lock up the system. 106 * have the F0 0F bug, which lets nonprivileged users lock up the system.
110 * Note that the workaround only should be initialized once... 107 * Note that the workaround only should be initialized once...
111 */ 108 */
112 c->f00f_bug = 0; 109 c->f00f_bug = 0;
113 if ( c->x86 == 5 ) { 110 if ( c->x86 == 5 ) {
114 static int f00f_workaround_enabled = 0; 111 static int f00f_workaround_enabled = 0;
115 112
116 c->f00f_bug = 1; 113 c->f00f_bug = 1;
117 if ( !f00f_workaround_enabled ) { 114 if ( !f00f_workaround_enabled ) {
118 trap_init_f00f_bug(); 115 trap_init_f00f_bug();
119 printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n"); 116 printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n");
120 f00f_workaround_enabled = 1; 117 f00f_workaround_enabled = 1;
121 } 118 }
122 } 119 }
123 #endif 120 #endif
124 121
125 select_idle_routine(c); 122 select_idle_routine(c);
126 l2 = init_intel_cacheinfo(c); 123 l2 = init_intel_cacheinfo(c);
127 124
128 /* SEP CPUID bug: Pentium Pro reports SEP but doesn't have it until model 3 mask 3 */ 125 /* SEP CPUID bug: Pentium Pro reports SEP but doesn't have it until model 3 mask 3 */
129 if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633) 126 if ((c->x86<<8 | c->x86_model<<4 | c->x86_mask) < 0x633)
130 clear_bit(X86_FEATURE_SEP, c->x86_capability); 127 clear_bit(X86_FEATURE_SEP, c->x86_capability);
131 128
132 /* Names for the Pentium II/Celeron processors 129 /* Names for the Pentium II/Celeron processors
133 detectable only by also checking the cache size. 130 detectable only by also checking the cache size.
134 Dixon is NOT a Celeron. */ 131 Dixon is NOT a Celeron. */
135 if (c->x86 == 6) { 132 if (c->x86 == 6) {
136 switch (c->x86_model) { 133 switch (c->x86_model) {
137 case 5: 134 case 5:
138 if (c->x86_mask == 0) { 135 if (c->x86_mask == 0) {
139 if (l2 == 0) 136 if (l2 == 0)
140 p = "Celeron (Covington)"; 137 p = "Celeron (Covington)";
141 else if (l2 == 256) 138 else if (l2 == 256)
142 p = "Mobile Pentium II (Dixon)"; 139 p = "Mobile Pentium II (Dixon)";
143 } 140 }
144 break; 141 break;
145 142
146 case 6: 143 case 6:
147 if (l2 == 128) 144 if (l2 == 128)
148 p = "Celeron (Mendocino)"; 145 p = "Celeron (Mendocino)";
149 else if (c->x86_mask == 0 || c->x86_mask == 5) 146 else if (c->x86_mask == 0 || c->x86_mask == 5)
150 p = "Celeron-A"; 147 p = "Celeron-A";
151 break; 148 break;
152 149
153 case 8: 150 case 8:
154 if (l2 == 128) 151 if (l2 == 128)
155 p = "Celeron (Coppermine)"; 152 p = "Celeron (Coppermine)";
156 break; 153 break;
157 } 154 }
158 } 155 }
159 156
160 if ( p ) 157 if ( p )
161 strcpy(c->x86_model_id, p); 158 strcpy(c->x86_model_id, p);
162 159
163 c->x86_num_cores = num_cpu_cores(c); 160 c->x86_num_cores = num_cpu_cores(c);
164 161
165 detect_ht(c); 162 detect_ht(c);
166 163
167 /* Work around errata */ 164 /* Work around errata */
168 Intel_errata_workarounds(c); 165 Intel_errata_workarounds(c);
169 166
170 #ifdef CONFIG_X86_INTEL_USERCOPY 167 #ifdef CONFIG_X86_INTEL_USERCOPY
171 /* 168 /*
172 * Set up the preferred alignment for movsl bulk memory moves 169 * Set up the preferred alignment for movsl bulk memory moves
173 */ 170 */
174 switch (c->x86) { 171 switch (c->x86) {
175 case 4: /* 486: untested */ 172 case 4: /* 486: untested */
176 break; 173 break;
177 case 5: /* Old Pentia: untested */ 174 case 5: /* Old Pentia: untested */
178 break; 175 break;
179 case 6: /* PII/PIII only like movsl with 8-byte alignment */ 176 case 6: /* PII/PIII only like movsl with 8-byte alignment */
180 movsl_mask.mask = 7; 177 movsl_mask.mask = 7;
181 break; 178 break;
182 case 15: /* P4 is OK down to 8-byte alignment */ 179 case 15: /* P4 is OK down to 8-byte alignment */
183 movsl_mask.mask = 7; 180 movsl_mask.mask = 7;
184 break; 181 break;
185 } 182 }
186 #endif 183 #endif
187 184
188 if (c->x86 == 15) 185 if (c->x86 == 15)
189 set_bit(X86_FEATURE_P4, c->x86_capability); 186 set_bit(X86_FEATURE_P4, c->x86_capability);
190 if (c->x86 == 6) 187 if (c->x86 == 6)
191 set_bit(X86_FEATURE_P3, c->x86_capability); 188 set_bit(X86_FEATURE_P3, c->x86_capability);
192 } 189 }
193 190
194 191
195 static unsigned int intel_size_cache(struct cpuinfo_x86 * c, unsigned int size) 192 static unsigned int intel_size_cache(struct cpuinfo_x86 * c, unsigned int size)
196 { 193 {
197 /* Intel PIII Tualatin. This comes in two flavours. 194 /* Intel PIII Tualatin. This comes in two flavours.
198 * One has 256kb of cache, the other 512. We have no way 195 * One has 256kb of cache, the other 512. We have no way
199 * to determine which, so we use a boottime override 196 * to determine which, so we use a boottime override
200 * for the 512kb model, and assume 256 otherwise. 197 * for the 512kb model, and assume 256 otherwise.
201 */ 198 */
202 if ((c->x86 == 6) && (c->x86_model == 11) && (size == 0)) 199 if ((c->x86 == 6) && (c->x86_model == 11) && (size == 0))
203 size = 256; 200 size = 256;
204 return size; 201 return size;
205 } 202 }
206 203
207 static struct cpu_dev intel_cpu_dev __devinitdata = { 204 static struct cpu_dev intel_cpu_dev __devinitdata = {
208 .c_vendor = "Intel", 205 .c_vendor = "Intel",
209 .c_ident = { "GenuineIntel" }, 206 .c_ident = { "GenuineIntel" },
210 .c_models = { 207 .c_models = {
211 { .vendor = X86_VENDOR_INTEL, .family = 4, .model_names = 208 { .vendor = X86_VENDOR_INTEL, .family = 4, .model_names =
212 { 209 {
213 [0] = "486 DX-25/33", 210 [0] = "486 DX-25/33",
214 [1] = "486 DX-50", 211 [1] = "486 DX-50",
215 [2] = "486 SX", 212 [2] = "486 SX",
216 [3] = "486 DX/2", 213 [3] = "486 DX/2",
217 [4] = "486 SL", 214 [4] = "486 SL",
218 [5] = "486 SX/2", 215 [5] = "486 SX/2",
219 [7] = "486 DX/2-WB", 216 [7] = "486 DX/2-WB",
220 [8] = "486 DX/4", 217 [8] = "486 DX/4",
221 [9] = "486 DX/4-WB" 218 [9] = "486 DX/4-WB"
222 } 219 }
223 }, 220 },
224 { .vendor = X86_VENDOR_INTEL, .family = 5, .model_names = 221 { .vendor = X86_VENDOR_INTEL, .family = 5, .model_names =
225 { 222 {
226 [0] = "Pentium 60/66 A-step", 223 [0] = "Pentium 60/66 A-step",
227 [1] = "Pentium 60/66", 224 [1] = "Pentium 60/66",
228 [2] = "Pentium 75 - 200", 225 [2] = "Pentium 75 - 200",
229 [3] = "OverDrive PODP5V83", 226 [3] = "OverDrive PODP5V83",
230 [4] = "Pentium MMX", 227 [4] = "Pentium MMX",
231 [7] = "Mobile Pentium 75 - 200", 228 [7] = "Mobile Pentium 75 - 200",
232 [8] = "Mobile Pentium MMX" 229 [8] = "Mobile Pentium MMX"
233 } 230 }
234 }, 231 },
235 { .vendor = X86_VENDOR_INTEL, .family = 6, .model_names = 232 { .vendor = X86_VENDOR_INTEL, .family = 6, .model_names =
236 { 233 {
237 [0] = "Pentium Pro A-step", 234 [0] = "Pentium Pro A-step",
238 [1] = "Pentium Pro", 235 [1] = "Pentium Pro",
239 [3] = "Pentium II (Klamath)", 236 [3] = "Pentium II (Klamath)",
240 [4] = "Pentium II (Deschutes)", 237 [4] = "Pentium II (Deschutes)",
241 [5] = "Pentium II (Deschutes)", 238 [5] = "Pentium II (Deschutes)",
242 [6] = "Mobile Pentium II", 239 [6] = "Mobile Pentium II",
243 [7] = "Pentium III (Katmai)", 240 [7] = "Pentium III (Katmai)",
244 [8] = "Pentium III (Coppermine)", 241 [8] = "Pentium III (Coppermine)",
245 [10] = "Pentium III (Cascades)", 242 [10] = "Pentium III (Cascades)",
246 [11] = "Pentium III (Tualatin)", 243 [11] = "Pentium III (Tualatin)",
247 } 244 }
248 }, 245 },
249 { .vendor = X86_VENDOR_INTEL, .family = 15, .model_names = 246 { .vendor = X86_VENDOR_INTEL, .family = 15, .model_names =
250 { 247 {
251 [0] = "Pentium 4 (Unknown)", 248 [0] = "Pentium 4 (Unknown)",
252 [1] = "Pentium 4 (Willamette)", 249 [1] = "Pentium 4 (Willamette)",
253 [2] = "Pentium 4 (Northwood)", 250 [2] = "Pentium 4 (Northwood)",
254 [4] = "Pentium 4 (Foster)", 251 [4] = "Pentium 4 (Foster)",
255 [5] = "Pentium 4 (Foster)", 252 [5] = "Pentium 4 (Foster)",
256 } 253 }
257 }, 254 },
258 }, 255 },
259 .c_init = init_intel, 256 .c_init = init_intel,
260 .c_identify = generic_identify, 257 .c_identify = generic_identify,
261 .c_size_cache = intel_size_cache, 258 .c_size_cache = intel_size_cache,
262 }; 259 };
263 260
264 __init int intel_cpu_init(void) 261 __init int intel_cpu_init(void)
265 { 262 {
266 cpu_devs[X86_VENDOR_INTEL] = &intel_cpu_dev; 263 cpu_devs[X86_VENDOR_INTEL] = &intel_cpu_dev;
267 return 0; 264 return 0;
268 } 265 }
269 266
270 // arch_initcall(intel_cpu_init); 267 // arch_initcall(intel_cpu_init);
271 268
272 269
arch/i386/kernel/crash.c
1 /* 1 /*
2 * Architecture specific (i386) functions for kexec based crash dumps. 2 * Architecture specific (i386) functions for kexec based crash dumps.
3 * 3 *
4 * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) 4 * Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
5 * 5 *
6 * Copyright (C) IBM Corporation, 2004. All rights reserved. 6 * Copyright (C) IBM Corporation, 2004. All rights reserved.
7 * 7 *
8 */ 8 */
9 9
10 #include <linux/init.h> 10 #include <linux/init.h>
11 #include <linux/types.h> 11 #include <linux/types.h>
12 #include <linux/kernel.h> 12 #include <linux/kernel.h>
13 #include <linux/smp.h> 13 #include <linux/smp.h>
14 #include <linux/irq.h> 14 #include <linux/irq.h>
15 #include <linux/reboot.h> 15 #include <linux/reboot.h>
16 #include <linux/kexec.h> 16 #include <linux/kexec.h>
17 #include <linux/irq.h> 17 #include <linux/irq.h>
18 #include <linux/delay.h> 18 #include <linux/delay.h>
19 #include <linux/elf.h> 19 #include <linux/elf.h>
20 #include <linux/elfcore.h> 20 #include <linux/elfcore.h>
21 21
22 #include <asm/processor.h> 22 #include <asm/processor.h>
23 #include <asm/hardirq.h> 23 #include <asm/hardirq.h>
24 #include <asm/nmi.h> 24 #include <asm/nmi.h>
25 #include <asm/hw_irq.h> 25 #include <asm/hw_irq.h>
26 #include <asm/apic.h> 26 #include <asm/apic.h>
27 #include <mach_ipi.h> 27 #include <mach_ipi.h>
28 28
29 29
30 note_buf_t crash_notes[NR_CPUS]; 30 note_buf_t crash_notes[NR_CPUS];
31 /* This keeps a track of which one is crashing cpu. */ 31 /* This keeps a track of which one is crashing cpu. */
32 static int crashing_cpu; 32 static int crashing_cpu;
33 33
34 static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, 34 static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
35 size_t data_len) 35 size_t data_len)
36 { 36 {
37 struct elf_note note; 37 struct elf_note note;
38 38
39 note.n_namesz = strlen(name) + 1; 39 note.n_namesz = strlen(name) + 1;
40 note.n_descsz = data_len; 40 note.n_descsz = data_len;
41 note.n_type = type; 41 note.n_type = type;
42 memcpy(buf, &note, sizeof(note)); 42 memcpy(buf, &note, sizeof(note));
43 buf += (sizeof(note) +3)/4; 43 buf += (sizeof(note) +3)/4;
44 memcpy(buf, name, note.n_namesz); 44 memcpy(buf, name, note.n_namesz);
45 buf += (note.n_namesz + 3)/4; 45 buf += (note.n_namesz + 3)/4;
46 memcpy(buf, data, note.n_descsz); 46 memcpy(buf, data, note.n_descsz);
47 buf += (note.n_descsz + 3)/4; 47 buf += (note.n_descsz + 3)/4;
48 48
49 return buf; 49 return buf;
50 } 50 }
51 51
52 static void final_note(u32 *buf) 52 static void final_note(u32 *buf)
53 { 53 {
54 struct elf_note note; 54 struct elf_note note;
55 55
56 note.n_namesz = 0; 56 note.n_namesz = 0;
57 note.n_descsz = 0; 57 note.n_descsz = 0;
58 note.n_type = 0; 58 note.n_type = 0;
59 memcpy(buf, &note, sizeof(note)); 59 memcpy(buf, &note, sizeof(note));
60 } 60 }
61 61
62 static void crash_save_this_cpu(struct pt_regs *regs, int cpu) 62 static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
63 { 63 {
64 struct elf_prstatus prstatus; 64 struct elf_prstatus prstatus;
65 u32 *buf; 65 u32 *buf;
66 66
67 if ((cpu < 0) || (cpu >= NR_CPUS)) 67 if ((cpu < 0) || (cpu >= NR_CPUS))
68 return; 68 return;
69 69
70 /* Using ELF notes here is opportunistic. 70 /* Using ELF notes here is opportunistic.
71 * I need a well defined structure format 71 * I need a well defined structure format
72 * for the data I pass, and I need tags 72 * for the data I pass, and I need tags
73 * on the data to indicate what information I have 73 * on the data to indicate what information I have
74 * squirrelled away. ELF notes happen to provide 74 * squirrelled away. ELF notes happen to provide
75 * all of that that no need to invent something new. 75 * all of that that no need to invent something new.
76 */ 76 */
77 buf = &crash_notes[cpu][0]; 77 buf = &crash_notes[cpu][0];
78 memset(&prstatus, 0, sizeof(prstatus)); 78 memset(&prstatus, 0, sizeof(prstatus));
79 prstatus.pr_pid = current->pid; 79 prstatus.pr_pid = current->pid;
80 elf_core_copy_regs(&prstatus.pr_reg, regs); 80 elf_core_copy_regs(&prstatus.pr_reg, regs);
81 buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus, 81 buf = append_elf_note(buf, "CORE", NT_PRSTATUS, &prstatus,
82 sizeof(prstatus)); 82 sizeof(prstatus));
83 final_note(buf); 83 final_note(buf);
84 } 84 }
85 85
86 static void crash_get_current_regs(struct pt_regs *regs) 86 static void crash_get_current_regs(struct pt_regs *regs)
87 { 87 {
88 __asm__ __volatile__("movl %%ebx,%0" : "=m"(regs->ebx)); 88 __asm__ __volatile__("movl %%ebx,%0" : "=m"(regs->ebx));
89 __asm__ __volatile__("movl %%ecx,%0" : "=m"(regs->ecx)); 89 __asm__ __volatile__("movl %%ecx,%0" : "=m"(regs->ecx));
90 __asm__ __volatile__("movl %%edx,%0" : "=m"(regs->edx)); 90 __asm__ __volatile__("movl %%edx,%0" : "=m"(regs->edx));
91 __asm__ __volatile__("movl %%esi,%0" : "=m"(regs->esi)); 91 __asm__ __volatile__("movl %%esi,%0" : "=m"(regs->esi));
92 __asm__ __volatile__("movl %%edi,%0" : "=m"(regs->edi)); 92 __asm__ __volatile__("movl %%edi,%0" : "=m"(regs->edi));
93 __asm__ __volatile__("movl %%ebp,%0" : "=m"(regs->ebp)); 93 __asm__ __volatile__("movl %%ebp,%0" : "=m"(regs->ebp));
94 __asm__ __volatile__("movl %%eax,%0" : "=m"(regs->eax)); 94 __asm__ __volatile__("movl %%eax,%0" : "=m"(regs->eax));
95 __asm__ __volatile__("movl %%esp,%0" : "=m"(regs->esp)); 95 __asm__ __volatile__("movl %%esp,%0" : "=m"(regs->esp));
96 __asm__ __volatile__("movw %%ss, %%ax;" :"=a"(regs->xss)); 96 __asm__ __volatile__("movw %%ss, %%ax;" :"=a"(regs->xss));
97 __asm__ __volatile__("movw %%cs, %%ax;" :"=a"(regs->xcs)); 97 __asm__ __volatile__("movw %%cs, %%ax;" :"=a"(regs->xcs));
98 __asm__ __volatile__("movw %%ds, %%ax;" :"=a"(regs->xds)); 98 __asm__ __volatile__("movw %%ds, %%ax;" :"=a"(regs->xds));
99 __asm__ __volatile__("movw %%es, %%ax;" :"=a"(regs->xes)); 99 __asm__ __volatile__("movw %%es, %%ax;" :"=a"(regs->xes));
100 __asm__ __volatile__("pushfl; popl %0" :"=m"(regs->eflags)); 100 __asm__ __volatile__("pushfl; popl %0" :"=m"(regs->eflags));
101 101
102 regs->eip = (unsigned long)current_text_addr(); 102 regs->eip = (unsigned long)current_text_addr();
103 } 103 }
104 104
105 /* CPU does not save ss and esp on stack if execution is already 105 /* CPU does not save ss and esp on stack if execution is already
106 * running in kernel mode at the time of NMI occurrence. This code 106 * running in kernel mode at the time of NMI occurrence. This code
107 * fixes it. 107 * fixes it.
108 */ 108 */
109 static void crash_setup_regs(struct pt_regs *newregs, struct pt_regs *oldregs) 109 static void crash_setup_regs(struct pt_regs *newregs, struct pt_regs *oldregs)
110 { 110 {
111 memcpy(newregs, oldregs, sizeof(*newregs)); 111 memcpy(newregs, oldregs, sizeof(*newregs));
112 newregs->esp = (unsigned long)&(oldregs->esp); 112 newregs->esp = (unsigned long)&(oldregs->esp);
113 __asm__ __volatile__("xorl %eax, %eax;"); 113 __asm__ __volatile__("xorl %eax, %eax;");
114 __asm__ __volatile__ ("movw %%ss, %%ax;" :"=a"(newregs->xss)); 114 __asm__ __volatile__ ("movw %%ss, %%ax;" :"=a"(newregs->xss));
115 } 115 }
116 116
117 /* We may have saved_regs from where the error came from 117 /* We may have saved_regs from where the error came from
118 * or it is NULL if via a direct panic(). 118 * or it is NULL if via a direct panic().
119 */ 119 */
120 static void crash_save_self(struct pt_regs *saved_regs) 120 static void crash_save_self(struct pt_regs *saved_regs)
121 { 121 {
122 struct pt_regs regs; 122 struct pt_regs regs;
123 int cpu; 123 int cpu;
124 124
125 cpu = smp_processor_id(); 125 cpu = smp_processor_id();
126 if (saved_regs) 126 if (saved_regs)
127 crash_setup_regs(&regs, saved_regs); 127 crash_setup_regs(&regs, saved_regs);
128 else 128 else
129 crash_get_current_regs(&regs); 129 crash_get_current_regs(&regs);
130 crash_save_this_cpu(&regs, cpu); 130 crash_save_this_cpu(&regs, cpu);
131 } 131 }
132 132
133 #ifdef CONFIG_SMP 133 #ifdef CONFIG_SMP
134 static atomic_t waiting_for_crash_ipi; 134 static atomic_t waiting_for_crash_ipi;
135 135
136 static int crash_nmi_callback(struct pt_regs *regs, int cpu) 136 static int crash_nmi_callback(struct pt_regs *regs, int cpu)
137 { 137 {
138 struct pt_regs fixed_regs; 138 struct pt_regs fixed_regs;
139 139
140 /* Don't do anything if this handler is invoked on crashing cpu. 140 /* Don't do anything if this handler is invoked on crashing cpu.
141 * Otherwise, system will completely hang. Crashing cpu can get 141 * Otherwise, system will completely hang. Crashing cpu can get
142 * an NMI if system was initially booted with nmi_watchdog parameter. 142 * an NMI if system was initially booted with nmi_watchdog parameter.
143 */ 143 */
144 if (cpu == crashing_cpu) 144 if (cpu == crashing_cpu)
145 return 1; 145 return 1;
146 local_irq_disable(); 146 local_irq_disable();
147 147
148 if (!user_mode(regs)) { 148 if (!user_mode(regs)) {
149 crash_setup_regs(&fixed_regs, regs); 149 crash_setup_regs(&fixed_regs, regs);
150 regs = &fixed_regs; 150 regs = &fixed_regs;
151 } 151 }
152 crash_save_this_cpu(regs, cpu); 152 crash_save_this_cpu(regs, cpu);
153 disable_local_APIC(); 153 disable_local_APIC();
154 atomic_dec(&waiting_for_crash_ipi); 154 atomic_dec(&waiting_for_crash_ipi);
155 /* Assume hlt works */ 155 /* Assume hlt works */
156 __asm__("hlt"); 156 halt();
157 for(;;); 157 for(;;);
158 158
159 return 1; 159 return 1;
160 } 160 }
161 161
162 /* 162 /*
163 * By using the NMI code instead of a vector we just sneak thru the 163 * By using the NMI code instead of a vector we just sneak thru the
164 * word generator coming out with just what we want. AND it does 164 * word generator coming out with just what we want. AND it does
165 * not matter if clustered_apic_mode is set or not. 165 * not matter if clustered_apic_mode is set or not.
166 */ 166 */
167 static void smp_send_nmi_allbutself(void) 167 static void smp_send_nmi_allbutself(void)
168 { 168 {
169 send_IPI_allbutself(APIC_DM_NMI); 169 send_IPI_allbutself(APIC_DM_NMI);
170 } 170 }
171 171
172 static void nmi_shootdown_cpus(void) 172 static void nmi_shootdown_cpus(void)
173 { 173 {
174 unsigned long msecs; 174 unsigned long msecs;
175 175
176 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); 176 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
177 /* Would it be better to replace the trap vector here? */ 177 /* Would it be better to replace the trap vector here? */
178 set_nmi_callback(crash_nmi_callback); 178 set_nmi_callback(crash_nmi_callback);
179 /* Ensure the new callback function is set before sending 179 /* Ensure the new callback function is set before sending
180 * out the NMI 180 * out the NMI
181 */ 181 */
182 wmb(); 182 wmb();
183 183
184 smp_send_nmi_allbutself(); 184 smp_send_nmi_allbutself();
185 185
186 msecs = 1000; /* Wait at most a second for the other cpus to stop */ 186 msecs = 1000; /* Wait at most a second for the other cpus to stop */
187 while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) { 187 while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
188 mdelay(1); 188 mdelay(1);
189 msecs--; 189 msecs--;
190 } 190 }
191 191
192 /* Leave the nmi callback set */ 192 /* Leave the nmi callback set */
193 disable_local_APIC(); 193 disable_local_APIC();
194 } 194 }
195 #else 195 #else
196 static void nmi_shootdown_cpus(void) 196 static void nmi_shootdown_cpus(void)
197 { 197 {
198 /* There are no cpus to shootdown */ 198 /* There are no cpus to shootdown */
199 } 199 }
200 #endif 200 #endif
201 201
202 void machine_crash_shutdown(struct pt_regs *regs) 202 void machine_crash_shutdown(struct pt_regs *regs)
203 { 203 {
204 /* This function is only called after the system 204 /* This function is only called after the system
205 * has paniced or is otherwise in a critical state. 205 * has paniced or is otherwise in a critical state.
206 * The minimum amount of code to allow a kexec'd kernel 206 * The minimum amount of code to allow a kexec'd kernel
207 * to run successfully needs to happen here. 207 * to run successfully needs to happen here.
208 * 208 *
209 * In practice this means shooting down the other cpus in 209 * In practice this means shooting down the other cpus in
210 * an SMP system. 210 * an SMP system.
211 */ 211 */
212 /* The kernel is broken so disable interrupts */ 212 /* The kernel is broken so disable interrupts */
213 local_irq_disable(); 213 local_irq_disable();
214 214
215 /* Make a note of crashing cpu. Will be used in NMI callback.*/ 215 /* Make a note of crashing cpu. Will be used in NMI callback.*/
216 crashing_cpu = smp_processor_id(); 216 crashing_cpu = smp_processor_id();
217 nmi_shootdown_cpus(); 217 nmi_shootdown_cpus();
218 lapic_shutdown(); 218 lapic_shutdown();
219 #if defined(CONFIG_X86_IO_APIC) 219 #if defined(CONFIG_X86_IO_APIC)
220 disable_IO_APIC(); 220 disable_IO_APIC();
221 #endif 221 #endif
222 crash_save_self(regs); 222 crash_save_self(regs);
223 } 223 }
224 224
arch/i386/kernel/machine_kexec.c
1 /* 1 /*
2 * machine_kexec.c - handle transition of Linux booting another kernel 2 * machine_kexec.c - handle transition of Linux booting another kernel
3 * Copyright (C) 2002-2005 Eric Biederman <ebiederm@xmission.com> 3 * Copyright (C) 2002-2005 Eric Biederman <ebiederm@xmission.com>
4 * 4 *
5 * This source code is licensed under the GNU General Public License, 5 * This source code is licensed under the GNU General Public License,
6 * Version 2. See the file COPYING for more details. 6 * Version 2. See the file COPYING for more details.
7 */ 7 */
8 8
9 #include <linux/mm.h> 9 #include <linux/mm.h>
10 #include <linux/kexec.h> 10 #include <linux/kexec.h>
11 #include <linux/delay.h> 11 #include <linux/delay.h>
12 #include <asm/pgtable.h> 12 #include <asm/pgtable.h>
13 #include <asm/pgalloc.h> 13 #include <asm/pgalloc.h>
14 #include <asm/tlbflush.h> 14 #include <asm/tlbflush.h>
15 #include <asm/mmu_context.h> 15 #include <asm/mmu_context.h>
16 #include <asm/io.h> 16 #include <asm/io.h>
17 #include <asm/apic.h> 17 #include <asm/apic.h>
18 #include <asm/cpufeature.h> 18 #include <asm/cpufeature.h>
19 #include <asm/desc.h> 19 #include <asm/desc.h>
20 #include <asm/system.h> 20 #include <asm/system.h>
21 21
22 #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE))) 22 #define PAGE_ALIGNED __attribute__ ((__aligned__(PAGE_SIZE)))
23 23
24 #define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) 24 #define L0_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
25 #define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) 25 #define L1_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
26 #define L2_ATTR (_PAGE_PRESENT) 26 #define L2_ATTR (_PAGE_PRESENT)
27 27
28 #define LEVEL0_SIZE (1UL << 12UL) 28 #define LEVEL0_SIZE (1UL << 12UL)
29 29
30 #ifndef CONFIG_X86_PAE 30 #ifndef CONFIG_X86_PAE
31 #define LEVEL1_SIZE (1UL << 22UL) 31 #define LEVEL1_SIZE (1UL << 22UL)
32 static u32 pgtable_level1[1024] PAGE_ALIGNED; 32 static u32 pgtable_level1[1024] PAGE_ALIGNED;
33 33
34 static void identity_map_page(unsigned long address) 34 static void identity_map_page(unsigned long address)
35 { 35 {
36 unsigned long level1_index, level2_index; 36 unsigned long level1_index, level2_index;
37 u32 *pgtable_level2; 37 u32 *pgtable_level2;
38 38
39 /* Find the current page table */ 39 /* Find the current page table */
40 pgtable_level2 = __va(read_cr3()); 40 pgtable_level2 = __va(read_cr3());
41 41
42 /* Find the indexes of the physical address to identity map */ 42 /* Find the indexes of the physical address to identity map */
43 level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE; 43 level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
44 level2_index = address / LEVEL1_SIZE; 44 level2_index = address / LEVEL1_SIZE;
45 45
46 /* Identity map the page table entry */ 46 /* Identity map the page table entry */
47 pgtable_level1[level1_index] = address | L0_ATTR; 47 pgtable_level1[level1_index] = address | L0_ATTR;
48 pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR; 48 pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
49 49
50 /* Flush the tlb so the new mapping takes effect. 50 /* Flush the tlb so the new mapping takes effect.
51 * Global tlb entries are not flushed but that is not an issue. 51 * Global tlb entries are not flushed but that is not an issue.
52 */ 52 */
53 load_cr3(pgtable_level2); 53 load_cr3(pgtable_level2);
54 } 54 }
55 55
56 #else 56 #else
57 #define LEVEL1_SIZE (1UL << 21UL) 57 #define LEVEL1_SIZE (1UL << 21UL)
58 #define LEVEL2_SIZE (1UL << 30UL) 58 #define LEVEL2_SIZE (1UL << 30UL)
59 static u64 pgtable_level1[512] PAGE_ALIGNED; 59 static u64 pgtable_level1[512] PAGE_ALIGNED;
60 static u64 pgtable_level2[512] PAGE_ALIGNED; 60 static u64 pgtable_level2[512] PAGE_ALIGNED;
61 61
62 static void identity_map_page(unsigned long address) 62 static void identity_map_page(unsigned long address)
63 { 63 {
64 unsigned long level1_index, level2_index, level3_index; 64 unsigned long level1_index, level2_index, level3_index;
65 u64 *pgtable_level3; 65 u64 *pgtable_level3;
66 66
67 /* Find the current page table */ 67 /* Find the current page table */
68 pgtable_level3 = __va(read_cr3()); 68 pgtable_level3 = __va(read_cr3());
69 69
70 /* Find the indexes of the physical address to identity map */ 70 /* Find the indexes of the physical address to identity map */
71 level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE; 71 level1_index = (address % LEVEL1_SIZE)/LEVEL0_SIZE;
72 level2_index = (address % LEVEL2_SIZE)/LEVEL1_SIZE; 72 level2_index = (address % LEVEL2_SIZE)/LEVEL1_SIZE;
73 level3_index = address / LEVEL2_SIZE; 73 level3_index = address / LEVEL2_SIZE;
74 74
75 /* Identity map the page table entry */ 75 /* Identity map the page table entry */
76 pgtable_level1[level1_index] = address | L0_ATTR; 76 pgtable_level1[level1_index] = address | L0_ATTR;
77 pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR; 77 pgtable_level2[level2_index] = __pa(pgtable_level1) | L1_ATTR;
78 set_64bit(&pgtable_level3[level3_index], 78 set_64bit(&pgtable_level3[level3_index],
79 __pa(pgtable_level2) | L2_ATTR); 79 __pa(pgtable_level2) | L2_ATTR);
80 80
81 /* Flush the tlb so the new mapping takes effect. 81 /* Flush the tlb so the new mapping takes effect.
82 * Global tlb entries are not flushed but that is not an issue. 82 * Global tlb entries are not flushed but that is not an issue.
83 */ 83 */
84 load_cr3(pgtable_level3); 84 load_cr3(pgtable_level3);
85 } 85 }
86 #endif 86 #endif
87 87
88 static void set_idt(void *newidt, __u16 limit) 88 static void set_idt(void *newidt, __u16 limit)
89 { 89 {
90 struct Xgt_desc_struct curidt; 90 struct Xgt_desc_struct curidt;
91 91
92 /* ia32 supports unaliged loads & stores */ 92 /* ia32 supports unaliged loads & stores */
93 curidt.size = limit; 93 curidt.size = limit;
94 curidt.address = (unsigned long)newidt; 94 curidt.address = (unsigned long)newidt;
95 95
96 __asm__ __volatile__ ( 96 load_idt(&curidt);
97 "lidtl %0\n"
98 : : "m" (curidt)
99 );
100 }; 97 };
101 98
102 99
103 static void set_gdt(void *newgdt, __u16 limit) 100 static void set_gdt(void *newgdt, __u16 limit)
104 { 101 {
105 struct Xgt_desc_struct curgdt; 102 struct Xgt_desc_struct curgdt;
106 103
107 /* ia32 supports unaligned loads & stores */ 104 /* ia32 supports unaligned loads & stores */
108 curgdt.size = limit; 105 curgdt.size = limit;
109 curgdt.address = (unsigned long)newgdt; 106 curgdt.address = (unsigned long)newgdt;
110 107
111 __asm__ __volatile__ ( 108 load_gdt(&curgdt);
112 "lgdtl %0\n"
113 : : "m" (curgdt)
114 );
115 }; 109 };
116 110
117 static void load_segments(void) 111 static void load_segments(void)
118 { 112 {
119 #define __STR(X) #X 113 #define __STR(X) #X
120 #define STR(X) __STR(X) 114 #define STR(X) __STR(X)
121 115
122 __asm__ __volatile__ ( 116 __asm__ __volatile__ (
123 "\tljmp $"STR(__KERNEL_CS)",$1f\n" 117 "\tljmp $"STR(__KERNEL_CS)",$1f\n"
124 "\t1:\n" 118 "\t1:\n"
125 "\tmovl $"STR(__KERNEL_DS)",%eax\n" 119 "\tmovl $"STR(__KERNEL_DS)",%eax\n"
126 "\tmovl %eax,%ds\n" 120 "\tmovl %eax,%ds\n"
127 "\tmovl %eax,%es\n" 121 "\tmovl %eax,%es\n"
128 "\tmovl %eax,%fs\n" 122 "\tmovl %eax,%fs\n"
129 "\tmovl %eax,%gs\n" 123 "\tmovl %eax,%gs\n"
130 "\tmovl %eax,%ss\n" 124 "\tmovl %eax,%ss\n"
131 ); 125 );
132 #undef STR 126 #undef STR
133 #undef __STR 127 #undef __STR
134 } 128 }
135 129
136 typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)( 130 typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)(
137 unsigned long indirection_page, 131 unsigned long indirection_page,
138 unsigned long reboot_code_buffer, 132 unsigned long reboot_code_buffer,
139 unsigned long start_address, 133 unsigned long start_address,
140 unsigned int has_pae) ATTRIB_NORET; 134 unsigned int has_pae) ATTRIB_NORET;
141 135
142 const extern unsigned char relocate_new_kernel[]; 136 const extern unsigned char relocate_new_kernel[];
143 extern void relocate_new_kernel_end(void); 137 extern void relocate_new_kernel_end(void);
144 const extern unsigned int relocate_new_kernel_size; 138 const extern unsigned int relocate_new_kernel_size;
145 139
146 /* 140 /*
147 * A architecture hook called to validate the 141 * A architecture hook called to validate the
148 * proposed image and prepare the control pages 142 * proposed image and prepare the control pages
149 * as needed. The pages for KEXEC_CONTROL_CODE_SIZE 143 * as needed. The pages for KEXEC_CONTROL_CODE_SIZE
150 * have been allocated, but the segments have yet 144 * have been allocated, but the segments have yet
151 * been copied into the kernel. 145 * been copied into the kernel.
152 * 146 *
153 * Do what every setup is needed on image and the 147 * Do what every setup is needed on image and the
154 * reboot code buffer to allow us to avoid allocations 148 * reboot code buffer to allow us to avoid allocations
155 * later. 149 * later.
156 * 150 *
157 * Currently nothing. 151 * Currently nothing.
158 */ 152 */
159 int machine_kexec_prepare(struct kimage *image) 153 int machine_kexec_prepare(struct kimage *image)
160 { 154 {
161 return 0; 155 return 0;
162 } 156 }
163 157
164 /* 158 /*
165 * Undo anything leftover by machine_kexec_prepare 159 * Undo anything leftover by machine_kexec_prepare
166 * when an image is freed. 160 * when an image is freed.
167 */ 161 */
168 void machine_kexec_cleanup(struct kimage *image) 162 void machine_kexec_cleanup(struct kimage *image)
169 { 163 {
170 } 164 }
171 165
172 /* 166 /*
173 * Do not allocate memory (or fail in any way) in machine_kexec(). 167 * Do not allocate memory (or fail in any way) in machine_kexec().
174 * We are past the point of no return, committed to rebooting now. 168 * We are past the point of no return, committed to rebooting now.
175 */ 169 */
176 NORET_TYPE void machine_kexec(struct kimage *image) 170 NORET_TYPE void machine_kexec(struct kimage *image)
177 { 171 {
178 unsigned long page_list; 172 unsigned long page_list;
179 unsigned long reboot_code_buffer; 173 unsigned long reboot_code_buffer;
180 174
181 relocate_new_kernel_t rnk; 175 relocate_new_kernel_t rnk;
182 176
183 /* Interrupts aren't acceptable while we reboot */ 177 /* Interrupts aren't acceptable while we reboot */
184 local_irq_disable(); 178 local_irq_disable();
185 179
186 /* Compute some offsets */ 180 /* Compute some offsets */
187 reboot_code_buffer = page_to_pfn(image->control_code_page) 181 reboot_code_buffer = page_to_pfn(image->control_code_page)
188 << PAGE_SHIFT; 182 << PAGE_SHIFT;
189 page_list = image->head; 183 page_list = image->head;
190 184
191 /* Set up an identity mapping for the reboot_code_buffer */ 185 /* Set up an identity mapping for the reboot_code_buffer */
192 identity_map_page(reboot_code_buffer); 186 identity_map_page(reboot_code_buffer);
193 187
194 /* copy it out */ 188 /* copy it out */
195 memcpy((void *)reboot_code_buffer, relocate_new_kernel, 189 memcpy((void *)reboot_code_buffer, relocate_new_kernel,
196 relocate_new_kernel_size); 190 relocate_new_kernel_size);
197 191
198 /* The segment registers are funny things, they are 192 /* The segment registers are funny things, they are
199 * automatically loaded from a table, in memory wherever you 193 * automatically loaded from a table, in memory wherever you
200 * set them to a specific selector, but this table is never 194 * set them to a specific selector, but this table is never
201 * accessed again you set the segment to a different selector. 195 * accessed again you set the segment to a different selector.
202 * 196 *
203 * The more common model is are caches where the behide 197 * The more common model is are caches where the behide
204 * the scenes work is done, but is also dropped at arbitrary 198 * the scenes work is done, but is also dropped at arbitrary
205 * times. 199 * times.
206 * 200 *
207 * I take advantage of this here by force loading the 201 * I take advantage of this here by force loading the
208 * segments, before I zap the gdt with an invalid value. 202 * segments, before I zap the gdt with an invalid value.
209 */ 203 */
210 load_segments(); 204 load_segments();
211 /* The gdt & idt are now invalid. 205 /* The gdt & idt are now invalid.
212 * If you want to load them you must set up your own idt & gdt. 206 * If you want to load them you must set up your own idt & gdt.
213 */ 207 */
214 set_gdt(phys_to_virt(0),0); 208 set_gdt(phys_to_virt(0),0);
215 set_idt(phys_to_virt(0),0); 209 set_idt(phys_to_virt(0),0);
216 210
217 /* now call it */ 211 /* now call it */
218 rnk = (relocate_new_kernel_t) reboot_code_buffer; 212 rnk = (relocate_new_kernel_t) reboot_code_buffer;
219 (*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae); 213 (*rnk)(page_list, reboot_code_buffer, image->start, cpu_has_pae);
220 } 214 }
221 215
arch/i386/kernel/msr.c
1 /* ----------------------------------------------------------------------- * 1 /* ----------------------------------------------------------------------- *
2 * 2 *
3 * Copyright 2000 H. Peter Anvin - All Rights Reserved 3 * Copyright 2000 H. Peter Anvin - All Rights Reserved
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, 7 * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
8 * USA; either version 2 of the License, or (at your option) any later 8 * USA; either version 2 of the License, or (at your option) any later
9 * version; incorporated herein by reference. 9 * version; incorporated herein by reference.
10 * 10 *
11 * ----------------------------------------------------------------------- */ 11 * ----------------------------------------------------------------------- */
12 12
13 /* 13 /*
14 * msr.c 14 * msr.c
15 * 15 *
16 * x86 MSR access device 16 * x86 MSR access device
17 * 17 *
18 * This device is accessed by lseek() to the appropriate register number 18 * This device is accessed by lseek() to the appropriate register number
19 * and then read/write in chunks of 8 bytes. A larger size means multiple 19 * and then read/write in chunks of 8 bytes. A larger size means multiple
20 * reads or writes of the same register. 20 * reads or writes of the same register.
21 * 21 *
22 * This driver uses /dev/cpu/%d/msr where %d is the minor number, and on 22 * This driver uses /dev/cpu/%d/msr where %d is the minor number, and on
23 * an SMP box will direct the access to CPU %d. 23 * an SMP box will direct the access to CPU %d.
24 */ 24 */
25 25
26 #include <linux/module.h> 26 #include <linux/module.h>
27 #include <linux/config.h> 27 #include <linux/config.h>
28 28
29 #include <linux/types.h> 29 #include <linux/types.h>
30 #include <linux/errno.h> 30 #include <linux/errno.h>
31 #include <linux/fcntl.h> 31 #include <linux/fcntl.h>
32 #include <linux/init.h> 32 #include <linux/init.h>
33 #include <linux/poll.h> 33 #include <linux/poll.h>
34 #include <linux/smp.h> 34 #include <linux/smp.h>
35 #include <linux/smp_lock.h> 35 #include <linux/smp_lock.h>
36 #include <linux/major.h> 36 #include <linux/major.h>
37 #include <linux/fs.h> 37 #include <linux/fs.h>
38 #include <linux/device.h> 38 #include <linux/device.h>
39 #include <linux/cpu.h> 39 #include <linux/cpu.h>
40 #include <linux/notifier.h> 40 #include <linux/notifier.h>
41 41
42 #include <asm/processor.h> 42 #include <asm/processor.h>
43 #include <asm/msr.h> 43 #include <asm/msr.h>
44 #include <asm/uaccess.h> 44 #include <asm/uaccess.h>
45 #include <asm/system.h> 45 #include <asm/system.h>
46 46
47 static struct class *msr_class; 47 static struct class *msr_class;
48 48
49 /* Note: "err" is handled in a funny way below. Otherwise one version
50 of gcc or another breaks. */
51
52 static inline int wrmsr_eio(u32 reg, u32 eax, u32 edx) 49 static inline int wrmsr_eio(u32 reg, u32 eax, u32 edx)
53 { 50 {
54 int err; 51 int err;
55 52
56 asm volatile ("1: wrmsr\n" 53 err = wrmsr_safe(reg, eax, edx);
57 "2:\n" 54 if (err)
58 ".section .fixup,\"ax\"\n" 55 err = -EIO;
59 "3: movl %4,%0\n"
60 " jmp 2b\n"
61 ".previous\n"
62 ".section __ex_table,\"a\"\n"
63 " .align 4\n" " .long 1b,3b\n" ".previous":"=&bDS" (err)
64 :"a"(eax), "d"(edx), "c"(reg), "i"(-EIO), "0"(0));
65
66 return err; 56 return err;
67 } 57 }
68 58
69 static inline int rdmsr_eio(u32 reg, u32 *eax, u32 *edx) 59 static inline int rdmsr_eio(u32 reg, u32 *eax, u32 *edx)
70 { 60 {
71 int err; 61 int err;
72 62
73 asm volatile ("1: rdmsr\n" 63 err = rdmsr_safe(reg, eax, edx);
74 "2:\n" 64 if (err)
75 ".section .fixup,\"ax\"\n" 65 err = -EIO;
76 "3: movl %4,%0\n"
77 " jmp 2b\n"
78 ".previous\n"
79 ".section __ex_table,\"a\"\n"
80 " .align 4\n"
81 " .long 1b,3b\n"
82 ".previous":"=&bDS" (err), "=a"(*eax), "=d"(*edx)
83 :"c"(reg), "i"(-EIO), "0"(0));
84
85 return err; 66 return err;
86 } 67 }
87 68
88 #ifdef CONFIG_SMP 69 #ifdef CONFIG_SMP
89 70
90 struct msr_command { 71 struct msr_command {
91 int cpu; 72 int cpu;
92 int err; 73 int err;
93 u32 reg; 74 u32 reg;
94 u32 data[2]; 75 u32 data[2];
95 }; 76 };
96 77
97 static void msr_smp_wrmsr(void *cmd_block) 78 static void msr_smp_wrmsr(void *cmd_block)
98 { 79 {
99 struct msr_command *cmd = (struct msr_command *)cmd_block; 80 struct msr_command *cmd = (struct msr_command *)cmd_block;
100 81
101 if (cmd->cpu == smp_processor_id()) 82 if (cmd->cpu == smp_processor_id())
102 cmd->err = wrmsr_eio(cmd->reg, cmd->data[0], cmd->data[1]); 83 cmd->err = wrmsr_eio(cmd->reg, cmd->data[0], cmd->data[1]);
103 } 84 }
104 85
105 static void msr_smp_rdmsr(void *cmd_block) 86 static void msr_smp_rdmsr(void *cmd_block)
106 { 87 {
107 struct msr_command *cmd = (struct msr_command *)cmd_block; 88 struct msr_command *cmd = (struct msr_command *)cmd_block;
108 89
109 if (cmd->cpu == smp_processor_id()) 90 if (cmd->cpu == smp_processor_id())
110 cmd->err = rdmsr_eio(cmd->reg, &cmd->data[0], &cmd->data[1]); 91 cmd->err = rdmsr_eio(cmd->reg, &cmd->data[0], &cmd->data[1]);
111 } 92 }
112 93
113 static inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx) 94 static inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx)
114 { 95 {
115 struct msr_command cmd; 96 struct msr_command cmd;
116 int ret; 97 int ret;
117 98
118 preempt_disable(); 99 preempt_disable();
119 if (cpu == smp_processor_id()) { 100 if (cpu == smp_processor_id()) {
120 ret = wrmsr_eio(reg, eax, edx); 101 ret = wrmsr_eio(reg, eax, edx);
121 } else { 102 } else {
122 cmd.cpu = cpu; 103 cmd.cpu = cpu;
123 cmd.reg = reg; 104 cmd.reg = reg;
124 cmd.data[0] = eax; 105 cmd.data[0] = eax;
125 cmd.data[1] = edx; 106 cmd.data[1] = edx;
126 107
127 smp_call_function(msr_smp_wrmsr, &cmd, 1, 1); 108 smp_call_function(msr_smp_wrmsr, &cmd, 1, 1);
128 ret = cmd.err; 109 ret = cmd.err;
129 } 110 }
130 preempt_enable(); 111 preempt_enable();
131 return ret; 112 return ret;
132 } 113 }
133 114
134 static inline int do_rdmsr(int cpu, u32 reg, u32 * eax, u32 * edx) 115 static inline int do_rdmsr(int cpu, u32 reg, u32 * eax, u32 * edx)
135 { 116 {
136 struct msr_command cmd; 117 struct msr_command cmd;
137 int ret; 118 int ret;
138 119
139 preempt_disable(); 120 preempt_disable();
140 if (cpu == smp_processor_id()) { 121 if (cpu == smp_processor_id()) {
141 ret = rdmsr_eio(reg, eax, edx); 122 ret = rdmsr_eio(reg, eax, edx);
142 } else { 123 } else {
143 cmd.cpu = cpu; 124 cmd.cpu = cpu;
144 cmd.reg = reg; 125 cmd.reg = reg;
145 126
146 smp_call_function(msr_smp_rdmsr, &cmd, 1, 1); 127 smp_call_function(msr_smp_rdmsr, &cmd, 1, 1);
147 128
148 *eax = cmd.data[0]; 129 *eax = cmd.data[0];
149 *edx = cmd.data[1]; 130 *edx = cmd.data[1];
150 131
151 ret = cmd.err; 132 ret = cmd.err;
152 } 133 }
153 preempt_enable(); 134 preempt_enable();
154 return ret; 135 return ret;
155 } 136 }
156 137
157 #else /* ! CONFIG_SMP */ 138 #else /* ! CONFIG_SMP */
158 139
159 static inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx) 140 static inline int do_wrmsr(int cpu, u32 reg, u32 eax, u32 edx)
160 { 141 {
161 return wrmsr_eio(reg, eax, edx); 142 return wrmsr_eio(reg, eax, edx);
162 } 143 }
163 144
164 static inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx) 145 static inline int do_rdmsr(int cpu, u32 reg, u32 *eax, u32 *edx)
165 { 146 {
166 return rdmsr_eio(reg, eax, edx); 147 return rdmsr_eio(reg, eax, edx);
167 } 148 }
168 149
169 #endif /* ! CONFIG_SMP */ 150 #endif /* ! CONFIG_SMP */
170 151
171 static loff_t msr_seek(struct file *file, loff_t offset, int orig) 152 static loff_t msr_seek(struct file *file, loff_t offset, int orig)
172 { 153 {
173 loff_t ret = -EINVAL; 154 loff_t ret = -EINVAL;
174 155
175 lock_kernel(); 156 lock_kernel();
176 switch (orig) { 157 switch (orig) {
177 case 0: 158 case 0:
178 file->f_pos = offset; 159 file->f_pos = offset;
179 ret = file->f_pos; 160 ret = file->f_pos;
180 break; 161 break;
181 case 1: 162 case 1:
182 file->f_pos += offset; 163 file->f_pos += offset;
183 ret = file->f_pos; 164 ret = file->f_pos;
184 } 165 }
185 unlock_kernel(); 166 unlock_kernel();
186 return ret; 167 return ret;
187 } 168 }
188 169
189 static ssize_t msr_read(struct file *file, char __user * buf, 170 static ssize_t msr_read(struct file *file, char __user * buf,
190 size_t count, loff_t * ppos) 171 size_t count, loff_t * ppos)
191 { 172 {
192 u32 __user *tmp = (u32 __user *) buf; 173 u32 __user *tmp = (u32 __user *) buf;
193 u32 data[2]; 174 u32 data[2];
194 size_t rv; 175 size_t rv;
195 u32 reg = *ppos; 176 u32 reg = *ppos;
196 int cpu = iminor(file->f_dentry->d_inode); 177 int cpu = iminor(file->f_dentry->d_inode);
197 int err; 178 int err;
198 179
199 if (count % 8) 180 if (count % 8)
200 return -EINVAL; /* Invalid chunk size */ 181 return -EINVAL; /* Invalid chunk size */
201 182
202 for (rv = 0; count; count -= 8) { 183 for (rv = 0; count; count -= 8) {
203 err = do_rdmsr(cpu, reg, &data[0], &data[1]); 184 err = do_rdmsr(cpu, reg, &data[0], &data[1]);
204 if (err) 185 if (err)
205 return err; 186 return err;
206 if (copy_to_user(tmp, &data, 8)) 187 if (copy_to_user(tmp, &data, 8))
207 return -EFAULT; 188 return -EFAULT;
208 tmp += 2; 189 tmp += 2;
209 } 190 }
210 191
211 return ((char __user *)tmp) - buf; 192 return ((char __user *)tmp) - buf;
212 } 193 }
213 194
214 static ssize_t msr_write(struct file *file, const char __user *buf, 195 static ssize_t msr_write(struct file *file, const char __user *buf,
215 size_t count, loff_t *ppos) 196 size_t count, loff_t *ppos)
216 { 197 {
217 const u32 __user *tmp = (const u32 __user *)buf; 198 const u32 __user *tmp = (const u32 __user *)buf;
218 u32 data[2]; 199 u32 data[2];
219 size_t rv; 200 size_t rv;
220 u32 reg = *ppos; 201 u32 reg = *ppos;
221 int cpu = iminor(file->f_dentry->d_inode); 202 int cpu = iminor(file->f_dentry->d_inode);
222 int err; 203 int err;
223 204
224 if (count % 8) 205 if (count % 8)
225 return -EINVAL; /* Invalid chunk size */ 206 return -EINVAL; /* Invalid chunk size */
226 207
227 for (rv = 0; count; count -= 8) { 208 for (rv = 0; count; count -= 8) {
228 if (copy_from_user(&data, tmp, 8)) 209 if (copy_from_user(&data, tmp, 8))
229 return -EFAULT; 210 return -EFAULT;
230 err = do_wrmsr(cpu, reg, data[0], data[1]); 211 err = do_wrmsr(cpu, reg, data[0], data[1]);
231 if (err) 212 if (err)
232 return err; 213 return err;
233 tmp += 2; 214 tmp += 2;
234 } 215 }
235 216
236 return ((char __user *)tmp) - buf; 217 return ((char __user *)tmp) - buf;
237 } 218 }
238 219
239 static int msr_open(struct inode *inode, struct file *file) 220 static int msr_open(struct inode *inode, struct file *file)
240 { 221 {
241 unsigned int cpu = iminor(file->f_dentry->d_inode); 222 unsigned int cpu = iminor(file->f_dentry->d_inode);
242 struct cpuinfo_x86 *c = &(cpu_data)[cpu]; 223 struct cpuinfo_x86 *c = &(cpu_data)[cpu];
243 224
244 if (cpu >= NR_CPUS || !cpu_online(cpu)) 225 if (cpu >= NR_CPUS || !cpu_online(cpu))
245 return -ENXIO; /* No such CPU */ 226 return -ENXIO; /* No such CPU */
246 if (!cpu_has(c, X86_FEATURE_MSR)) 227 if (!cpu_has(c, X86_FEATURE_MSR))
247 return -EIO; /* MSR not supported */ 228 return -EIO; /* MSR not supported */
248 229
249 return 0; 230 return 0;
250 } 231 }
251 232
252 /* 233 /*
253 * File operations we support 234 * File operations we support
254 */ 235 */
255 static struct file_operations msr_fops = { 236 static struct file_operations msr_fops = {
256 .owner = THIS_MODULE, 237 .owner = THIS_MODULE,
257 .llseek = msr_seek, 238 .llseek = msr_seek,
258 .read = msr_read, 239 .read = msr_read,
259 .write = msr_write, 240 .write = msr_write,
260 .open = msr_open, 241 .open = msr_open,
261 }; 242 };
262 243
263 static int msr_class_device_create(int i) 244 static int msr_class_device_create(int i)
264 { 245 {
265 int err = 0; 246 int err = 0;
266 struct class_device *class_err; 247 struct class_device *class_err;
267 248
268 class_err = class_device_create(msr_class, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i); 249 class_err = class_device_create(msr_class, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i);
269 if (IS_ERR(class_err)) 250 if (IS_ERR(class_err))
270 err = PTR_ERR(class_err); 251 err = PTR_ERR(class_err);
271 return err; 252 return err;
272 } 253 }
273 254
274 static int __devinit msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) 255 static int __devinit msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
275 { 256 {
276 unsigned int cpu = (unsigned long)hcpu; 257 unsigned int cpu = (unsigned long)hcpu;
277 258
278 switch (action) { 259 switch (action) {
279 case CPU_ONLINE: 260 case CPU_ONLINE:
280 msr_class_device_create(cpu); 261 msr_class_device_create(cpu);
281 break; 262 break;
282 case CPU_DEAD: 263 case CPU_DEAD:
283 class_device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); 264 class_device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
284 break; 265 break;
285 } 266 }
286 return NOTIFY_OK; 267 return NOTIFY_OK;
287 } 268 }
288 269
289 static struct notifier_block msr_class_cpu_notifier = 270 static struct notifier_block msr_class_cpu_notifier =
290 { 271 {
291 .notifier_call = msr_class_cpu_callback, 272 .notifier_call = msr_class_cpu_callback,
292 }; 273 };
293 274
294 static int __init msr_init(void) 275 static int __init msr_init(void)
295 { 276 {
296 int i, err = 0; 277 int i, err = 0;
297 i = 0; 278 i = 0;
298 279
299 if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) { 280 if (register_chrdev(MSR_MAJOR, "cpu/msr", &msr_fops)) {
300 printk(KERN_ERR "msr: unable to get major %d for msr\n", 281 printk(KERN_ERR "msr: unable to get major %d for msr\n",
301 MSR_MAJOR); 282 MSR_MAJOR);
302 err = -EBUSY; 283 err = -EBUSY;
303 goto out; 284 goto out;
304 } 285 }
305 msr_class = class_create(THIS_MODULE, "msr"); 286 msr_class = class_create(THIS_MODULE, "msr");
306 if (IS_ERR(msr_class)) { 287 if (IS_ERR(msr_class)) {
307 err = PTR_ERR(msr_class); 288 err = PTR_ERR(msr_class);
308 goto out_chrdev; 289 goto out_chrdev;
309 } 290 }
310 for_each_online_cpu(i) { 291 for_each_online_cpu(i) {
311 err = msr_class_device_create(i); 292 err = msr_class_device_create(i);
312 if (err != 0) 293 if (err != 0)
313 goto out_class; 294 goto out_class;
314 } 295 }
315 register_cpu_notifier(&msr_class_cpu_notifier); 296 register_cpu_notifier(&msr_class_cpu_notifier);
316 297
317 err = 0; 298 err = 0;
318 goto out; 299 goto out;
319 300
320 out_class: 301 out_class:
321 i = 0; 302 i = 0;
322 for_each_online_cpu(i) 303 for_each_online_cpu(i)
323 class_device_destroy(msr_class, MKDEV(MSR_MAJOR, i)); 304 class_device_destroy(msr_class, MKDEV(MSR_MAJOR, i));
324 class_destroy(msr_class); 305 class_destroy(msr_class);
325 out_chrdev: 306 out_chrdev:
326 unregister_chrdev(MSR_MAJOR, "cpu/msr"); 307 unregister_chrdev(MSR_MAJOR, "cpu/msr");
327 out: 308 out:
328 return err; 309 return err;
329 } 310 }
330 311
331 static void __exit msr_exit(void) 312 static void __exit msr_exit(void)
332 { 313 {
333 int cpu = 0; 314 int cpu = 0;
334 for_each_online_cpu(cpu) 315 for_each_online_cpu(cpu)
335 class_device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); 316 class_device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu));
336 class_destroy(msr_class); 317 class_destroy(msr_class);
337 unregister_chrdev(MSR_MAJOR, "cpu/msr"); 318 unregister_chrdev(MSR_MAJOR, "cpu/msr");
338 unregister_cpu_notifier(&msr_class_cpu_notifier); 319 unregister_cpu_notifier(&msr_class_cpu_notifier);
339 } 320 }
340 321
341 module_init(msr_init); 322 module_init(msr_init);
342 module_exit(msr_exit) 323 module_exit(msr_exit)
343 324
344 MODULE_AUTHOR("H. Peter Anvin <hpa@zytor.com>"); 325 MODULE_AUTHOR("H. Peter Anvin <hpa@zytor.com>");
345 MODULE_DESCRIPTION("x86 generic MSR driver"); 326 MODULE_DESCRIPTION("x86 generic MSR driver");
346 MODULE_LICENSE("GPL"); 327 MODULE_LICENSE("GPL");
347 328
arch/i386/kernel/process.c
1 /* 1 /*
2 * linux/arch/i386/kernel/process.c 2 * linux/arch/i386/kernel/process.c
3 * 3 *
4 * Copyright (C) 1995 Linus Torvalds 4 * Copyright (C) 1995 Linus Torvalds
5 * 5 *
6 * Pentium III FXSR, SSE support 6 * Pentium III FXSR, SSE support
7 * Gareth Hughes <gareth@valinux.com>, May 2000 7 * Gareth Hughes <gareth@valinux.com>, May 2000
8 */ 8 */
9 9
10 /* 10 /*
11 * This file handles the architecture-dependent parts of process handling.. 11 * This file handles the architecture-dependent parts of process handling..
12 */ 12 */
13 13
14 #include <stdarg.h> 14 #include <stdarg.h>
15 15
16 #include <linux/cpu.h> 16 #include <linux/cpu.h>
17 #include <linux/errno.h> 17 #include <linux/errno.h>
18 #include <linux/sched.h> 18 #include <linux/sched.h>
19 #include <linux/fs.h> 19 #include <linux/fs.h>
20 #include <linux/kernel.h> 20 #include <linux/kernel.h>
21 #include <linux/mm.h> 21 #include <linux/mm.h>
22 #include <linux/elfcore.h> 22 #include <linux/elfcore.h>
23 #include <linux/smp.h> 23 #include <linux/smp.h>
24 #include <linux/smp_lock.h> 24 #include <linux/smp_lock.h>
25 #include <linux/stddef.h> 25 #include <linux/stddef.h>
26 #include <linux/slab.h> 26 #include <linux/slab.h>
27 #include <linux/vmalloc.h> 27 #include <linux/vmalloc.h>
28 #include <linux/user.h> 28 #include <linux/user.h>
29 #include <linux/a.out.h> 29 #include <linux/a.out.h>
30 #include <linux/interrupt.h> 30 #include <linux/interrupt.h>
31 #include <linux/config.h> 31 #include <linux/config.h>
32 #include <linux/utsname.h> 32 #include <linux/utsname.h>
33 #include <linux/delay.h> 33 #include <linux/delay.h>
34 #include <linux/reboot.h> 34 #include <linux/reboot.h>
35 #include <linux/init.h> 35 #include <linux/init.h>
36 #include <linux/mc146818rtc.h> 36 #include <linux/mc146818rtc.h>
37 #include <linux/module.h> 37 #include <linux/module.h>
38 #include <linux/kallsyms.h> 38 #include <linux/kallsyms.h>
39 #include <linux/ptrace.h> 39 #include <linux/ptrace.h>
40 #include <linux/random.h> 40 #include <linux/random.h>
41 #include <linux/kprobes.h> 41 #include <linux/kprobes.h>
42 42
43 #include <asm/uaccess.h> 43 #include <asm/uaccess.h>
44 #include <asm/pgtable.h> 44 #include <asm/pgtable.h>
45 #include <asm/system.h> 45 #include <asm/system.h>
46 #include <asm/io.h> 46 #include <asm/io.h>
47 #include <asm/ldt.h> 47 #include <asm/ldt.h>
48 #include <asm/processor.h> 48 #include <asm/processor.h>
49 #include <asm/i387.h> 49 #include <asm/i387.h>
50 #include <asm/irq.h> 50 #include <asm/irq.h>
51 #include <asm/desc.h> 51 #include <asm/desc.h>
52 #ifdef CONFIG_MATH_EMULATION 52 #ifdef CONFIG_MATH_EMULATION
53 #include <asm/math_emu.h> 53 #include <asm/math_emu.h>
54 #endif 54 #endif
55 55
56 #include <linux/irq.h> 56 #include <linux/irq.h>
57 #include <linux/err.h> 57 #include <linux/err.h>
58 58
59 #include <asm/tlbflush.h> 59 #include <asm/tlbflush.h>
60 #include <asm/cpu.h> 60 #include <asm/cpu.h>
61 61
62 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); 62 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
63 63
64 static int hlt_counter; 64 static int hlt_counter;
65 65
66 unsigned long boot_option_idle_override = 0; 66 unsigned long boot_option_idle_override = 0;
67 EXPORT_SYMBOL(boot_option_idle_override); 67 EXPORT_SYMBOL(boot_option_idle_override);
68 68
69 /* 69 /*
70 * Return saved PC of a blocked thread. 70 * Return saved PC of a blocked thread.
71 */ 71 */
72 unsigned long thread_saved_pc(struct task_struct *tsk) 72 unsigned long thread_saved_pc(struct task_struct *tsk)
73 { 73 {
74 return ((unsigned long *)tsk->thread.esp)[3]; 74 return ((unsigned long *)tsk->thread.esp)[3];
75 } 75 }
76 76
77 /* 77 /*
78 * Powermanagement idle function, if any.. 78 * Powermanagement idle function, if any..
79 */ 79 */
80 void (*pm_idle)(void); 80 void (*pm_idle)(void);
81 EXPORT_SYMBOL(pm_idle); 81 EXPORT_SYMBOL(pm_idle);
82 static DEFINE_PER_CPU(unsigned int, cpu_idle_state); 82 static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
83 83
84 void disable_hlt(void) 84 void disable_hlt(void)
85 { 85 {
86 hlt_counter++; 86 hlt_counter++;
87 } 87 }
88 88
89 EXPORT_SYMBOL(disable_hlt); 89 EXPORT_SYMBOL(disable_hlt);
90 90
91 void enable_hlt(void) 91 void enable_hlt(void)
92 { 92 {
93 hlt_counter--; 93 hlt_counter--;
94 } 94 }
95 95
96 EXPORT_SYMBOL(enable_hlt); 96 EXPORT_SYMBOL(enable_hlt);
97 97
98 /* 98 /*
99 * We use this if we don't have any better 99 * We use this if we don't have any better
100 * idle routine.. 100 * idle routine..
101 */ 101 */
102 void default_idle(void) 102 void default_idle(void)
103 { 103 {
104 if (!hlt_counter && boot_cpu_data.hlt_works_ok) { 104 if (!hlt_counter && boot_cpu_data.hlt_works_ok) {
105 local_irq_disable(); 105 local_irq_disable();
106 if (!need_resched()) 106 if (!need_resched())
107 safe_halt(); 107 safe_halt();
108 else 108 else
109 local_irq_enable(); 109 local_irq_enable();
110 } else { 110 } else {
111 cpu_relax(); 111 cpu_relax();
112 } 112 }
113 } 113 }
114 #ifdef CONFIG_APM_MODULE 114 #ifdef CONFIG_APM_MODULE
115 EXPORT_SYMBOL(default_idle); 115 EXPORT_SYMBOL(default_idle);
116 #endif 116 #endif
117 117
118 /* 118 /*
119 * On SMP it's slightly faster (but much more power-consuming!) 119 * On SMP it's slightly faster (but much more power-consuming!)
120 * to poll the ->work.need_resched flag instead of waiting for the 120 * to poll the ->work.need_resched flag instead of waiting for the
121 * cross-CPU IPI to arrive. Use this option with caution. 121 * cross-CPU IPI to arrive. Use this option with caution.
122 */ 122 */
123 static void poll_idle (void) 123 static void poll_idle (void)
124 { 124 {
125 int oldval; 125 int oldval;
126 126
127 local_irq_enable(); 127 local_irq_enable();
128 128
129 /* 129 /*
130 * Deal with another CPU just having chosen a thread to 130 * Deal with another CPU just having chosen a thread to
131 * run here: 131 * run here:
132 */ 132 */
133 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED); 133 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
134 134
135 if (!oldval) { 135 if (!oldval) {
136 set_thread_flag(TIF_POLLING_NRFLAG); 136 set_thread_flag(TIF_POLLING_NRFLAG);
137 asm volatile( 137 asm volatile(
138 "2:" 138 "2:"
139 "testl %0, %1;" 139 "testl %0, %1;"
140 "rep; nop;" 140 "rep; nop;"
141 "je 2b;" 141 "je 2b;"
142 : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags)); 142 : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags));
143 143
144 clear_thread_flag(TIF_POLLING_NRFLAG); 144 clear_thread_flag(TIF_POLLING_NRFLAG);
145 } else { 145 } else {
146 set_need_resched(); 146 set_need_resched();
147 } 147 }
148 } 148 }
149 149
150 #ifdef CONFIG_HOTPLUG_CPU 150 #ifdef CONFIG_HOTPLUG_CPU
151 #include <asm/nmi.h> 151 #include <asm/nmi.h>
152 /* We don't actually take CPU down, just spin without interrupts. */ 152 /* We don't actually take CPU down, just spin without interrupts. */
153 static inline void play_dead(void) 153 static inline void play_dead(void)
154 { 154 {
155 /* This must be done before dead CPU ack */ 155 /* This must be done before dead CPU ack */
156 cpu_exit_clear(); 156 cpu_exit_clear();
157 wbinvd(); 157 wbinvd();
158 mb(); 158 mb();
159 /* Ack it */ 159 /* Ack it */
160 __get_cpu_var(cpu_state) = CPU_DEAD; 160 __get_cpu_var(cpu_state) = CPU_DEAD;
161 161
162 /* 162 /*
163 * With physical CPU hotplug, we should halt the cpu 163 * With physical CPU hotplug, we should halt the cpu
164 */ 164 */
165 local_irq_disable(); 165 local_irq_disable();
166 while (1) 166 while (1)
167 __asm__ __volatile__("hlt":::"memory"); 167 halt();
168 } 168 }
169 #else 169 #else
170 static inline void play_dead(void) 170 static inline void play_dead(void)
171 { 171 {
172 BUG(); 172 BUG();
173 } 173 }
174 #endif /* CONFIG_HOTPLUG_CPU */ 174 #endif /* CONFIG_HOTPLUG_CPU */
175 175
176 /* 176 /*
177 * The idle thread. There's no useful work to be 177 * The idle thread. There's no useful work to be
178 * done, so just try to conserve power and have a 178 * done, so just try to conserve power and have a
179 * low exit latency (ie sit in a loop waiting for 179 * low exit latency (ie sit in a loop waiting for
180 * somebody to say that they'd like to reschedule) 180 * somebody to say that they'd like to reschedule)
181 */ 181 */
182 void cpu_idle(void) 182 void cpu_idle(void)
183 { 183 {
184 int cpu = raw_smp_processor_id(); 184 int cpu = raw_smp_processor_id();
185 185
186 /* endless idle loop with no priority at all */ 186 /* endless idle loop with no priority at all */
187 while (1) { 187 while (1) {
188 while (!need_resched()) { 188 while (!need_resched()) {
189 void (*idle)(void); 189 void (*idle)(void);
190 190
191 if (__get_cpu_var(cpu_idle_state)) 191 if (__get_cpu_var(cpu_idle_state))
192 __get_cpu_var(cpu_idle_state) = 0; 192 __get_cpu_var(cpu_idle_state) = 0;
193 193
194 rmb(); 194 rmb();
195 idle = pm_idle; 195 idle = pm_idle;
196 196
197 if (!idle) 197 if (!idle)
198 idle = default_idle; 198 idle = default_idle;
199 199
200 if (cpu_is_offline(cpu)) 200 if (cpu_is_offline(cpu))
201 play_dead(); 201 play_dead();
202 202
203 __get_cpu_var(irq_stat).idle_timestamp = jiffies; 203 __get_cpu_var(irq_stat).idle_timestamp = jiffies;
204 idle(); 204 idle();
205 } 205 }
206 schedule(); 206 schedule();
207 } 207 }
208 } 208 }
209 209
210 void cpu_idle_wait(void) 210 void cpu_idle_wait(void)
211 { 211 {
212 unsigned int cpu, this_cpu = get_cpu(); 212 unsigned int cpu, this_cpu = get_cpu();
213 cpumask_t map; 213 cpumask_t map;
214 214
215 set_cpus_allowed(current, cpumask_of_cpu(this_cpu)); 215 set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
216 put_cpu(); 216 put_cpu();
217 217
218 cpus_clear(map); 218 cpus_clear(map);
219 for_each_online_cpu(cpu) { 219 for_each_online_cpu(cpu) {
220 per_cpu(cpu_idle_state, cpu) = 1; 220 per_cpu(cpu_idle_state, cpu) = 1;
221 cpu_set(cpu, map); 221 cpu_set(cpu, map);
222 } 222 }
223 223
224 __get_cpu_var(cpu_idle_state) = 0; 224 __get_cpu_var(cpu_idle_state) = 0;
225 225
226 wmb(); 226 wmb();
227 do { 227 do {
228 ssleep(1); 228 ssleep(1);
229 for_each_online_cpu(cpu) { 229 for_each_online_cpu(cpu) {
230 if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu)) 230 if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
231 cpu_clear(cpu, map); 231 cpu_clear(cpu, map);
232 } 232 }
233 cpus_and(map, map, cpu_online_map); 233 cpus_and(map, map, cpu_online_map);
234 } while (!cpus_empty(map)); 234 } while (!cpus_empty(map));
235 } 235 }
236 EXPORT_SYMBOL_GPL(cpu_idle_wait); 236 EXPORT_SYMBOL_GPL(cpu_idle_wait);
237 237
238 /* 238 /*
239 * This uses new MONITOR/MWAIT instructions on P4 processors with PNI, 239 * This uses new MONITOR/MWAIT instructions on P4 processors with PNI,
240 * which can obviate IPI to trigger checking of need_resched. 240 * which can obviate IPI to trigger checking of need_resched.
241 * We execute MONITOR against need_resched and enter optimized wait state 241 * We execute MONITOR against need_resched and enter optimized wait state
242 * through MWAIT. Whenever someone changes need_resched, we would be woken 242 * through MWAIT. Whenever someone changes need_resched, we would be woken
243 * up from MWAIT (without an IPI). 243 * up from MWAIT (without an IPI).
244 */ 244 */
245 static void mwait_idle(void) 245 static void mwait_idle(void)
246 { 246 {
247 local_irq_enable(); 247 local_irq_enable();
248 248
249 if (!need_resched()) { 249 if (!need_resched()) {
250 set_thread_flag(TIF_POLLING_NRFLAG); 250 set_thread_flag(TIF_POLLING_NRFLAG);
251 do { 251 do {
252 __monitor((void *)&current_thread_info()->flags, 0, 0); 252 __monitor((void *)&current_thread_info()->flags, 0, 0);
253 if (need_resched()) 253 if (need_resched())
254 break; 254 break;
255 __mwait(0, 0); 255 __mwait(0, 0);
256 } while (!need_resched()); 256 } while (!need_resched());
257 clear_thread_flag(TIF_POLLING_NRFLAG); 257 clear_thread_flag(TIF_POLLING_NRFLAG);
258 } 258 }
259 } 259 }
260 260
261 void __devinit select_idle_routine(const struct cpuinfo_x86 *c) 261 void __devinit select_idle_routine(const struct cpuinfo_x86 *c)
262 { 262 {
263 if (cpu_has(c, X86_FEATURE_MWAIT)) { 263 if (cpu_has(c, X86_FEATURE_MWAIT)) {
264 printk("monitor/mwait feature present.\n"); 264 printk("monitor/mwait feature present.\n");
265 /* 265 /*
266 * Skip, if setup has overridden idle. 266 * Skip, if setup has overridden idle.
267 * One CPU supports mwait => All CPUs supports mwait 267 * One CPU supports mwait => All CPUs supports mwait
268 */ 268 */
269 if (!pm_idle) { 269 if (!pm_idle) {
270 printk("using mwait in idle threads.\n"); 270 printk("using mwait in idle threads.\n");
271 pm_idle = mwait_idle; 271 pm_idle = mwait_idle;
272 } 272 }
273 } 273 }
274 } 274 }
275 275
276 static int __init idle_setup (char *str) 276 static int __init idle_setup (char *str)
277 { 277 {
278 if (!strncmp(str, "poll", 4)) { 278 if (!strncmp(str, "poll", 4)) {
279 printk("using polling idle threads.\n"); 279 printk("using polling idle threads.\n");
280 pm_idle = poll_idle; 280 pm_idle = poll_idle;
281 #ifdef CONFIG_X86_SMP 281 #ifdef CONFIG_X86_SMP
282 if (smp_num_siblings > 1) 282 if (smp_num_siblings > 1)
283 printk("WARNING: polling idle and HT enabled, performance may degrade.\n"); 283 printk("WARNING: polling idle and HT enabled, performance may degrade.\n");
284 #endif 284 #endif
285 } else if (!strncmp(str, "halt", 4)) { 285 } else if (!strncmp(str, "halt", 4)) {
286 printk("using halt in idle threads.\n"); 286 printk("using halt in idle threads.\n");
287 pm_idle = default_idle; 287 pm_idle = default_idle;
288 } 288 }
289 289
290 boot_option_idle_override = 1; 290 boot_option_idle_override = 1;
291 return 1; 291 return 1;
292 } 292 }
293 293
294 __setup("idle=", idle_setup); 294 __setup("idle=", idle_setup);
295 295
296 void show_regs(struct pt_regs * regs) 296 void show_regs(struct pt_regs * regs)
297 { 297 {
298 unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L; 298 unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
299 299
300 printk("\n"); 300 printk("\n");
301 printk("Pid: %d, comm: %20s\n", current->pid, current->comm); 301 printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
302 printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id()); 302 printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
303 print_symbol("EIP is at %s\n", regs->eip); 303 print_symbol("EIP is at %s\n", regs->eip);
304 304
305 if (user_mode(regs)) 305 if (user_mode(regs))
306 printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); 306 printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
307 printk(" EFLAGS: %08lx %s (%s)\n", 307 printk(" EFLAGS: %08lx %s (%s)\n",
308 regs->eflags, print_tainted(), system_utsname.release); 308 regs->eflags, print_tainted(), system_utsname.release);
309 printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", 309 printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
310 regs->eax,regs->ebx,regs->ecx,regs->edx); 310 regs->eax,regs->ebx,regs->ecx,regs->edx);
311 printk("ESI: %08lx EDI: %08lx EBP: %08lx", 311 printk("ESI: %08lx EDI: %08lx EBP: %08lx",
312 regs->esi, regs->edi, regs->ebp); 312 regs->esi, regs->edi, regs->ebp);
313 printk(" DS: %04x ES: %04x\n", 313 printk(" DS: %04x ES: %04x\n",
314 0xffff & regs->xds,0xffff & regs->xes); 314 0xffff & regs->xds,0xffff & regs->xes);
315 315
316 cr0 = read_cr0(); 316 cr0 = read_cr0();
317 cr2 = read_cr2(); 317 cr2 = read_cr2();
318 cr3 = read_cr3(); 318 cr3 = read_cr3();
319 if (current_cpu_data.x86 > 4) { 319 if (current_cpu_data.x86 > 4) {
320 cr4 = read_cr4(); 320 cr4 = read_cr4();
321 } 321 }
322 printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4); 322 printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
323 show_trace(NULL, &regs->esp); 323 show_trace(NULL, &regs->esp);
324 } 324 }
325 325
326 /* 326 /*
327 * This gets run with %ebx containing the 327 * This gets run with %ebx containing the
328 * function to call, and %edx containing 328 * function to call, and %edx containing
329 * the "args". 329 * the "args".
330 */ 330 */
331 extern void kernel_thread_helper(void); 331 extern void kernel_thread_helper(void);
332 __asm__(".section .text\n" 332 __asm__(".section .text\n"
333 ".align 4\n" 333 ".align 4\n"
334 "kernel_thread_helper:\n\t" 334 "kernel_thread_helper:\n\t"
335 "movl %edx,%eax\n\t" 335 "movl %edx,%eax\n\t"
336 "pushl %edx\n\t" 336 "pushl %edx\n\t"
337 "call *%ebx\n\t" 337 "call *%ebx\n\t"
338 "pushl %eax\n\t" 338 "pushl %eax\n\t"
339 "call do_exit\n" 339 "call do_exit\n"
340 ".previous"); 340 ".previous");
341 341
342 /* 342 /*
343 * Create a kernel thread 343 * Create a kernel thread
344 */ 344 */
345 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) 345 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
346 { 346 {
347 struct pt_regs regs; 347 struct pt_regs regs;
348 348
349 memset(&regs, 0, sizeof(regs)); 349 memset(&regs, 0, sizeof(regs));
350 350
351 regs.ebx = (unsigned long) fn; 351 regs.ebx = (unsigned long) fn;
352 regs.edx = (unsigned long) arg; 352 regs.edx = (unsigned long) arg;
353 353
354 regs.xds = __USER_DS; 354 regs.xds = __USER_DS;
355 regs.xes = __USER_DS; 355 regs.xes = __USER_DS;
356 regs.orig_eax = -1; 356 regs.orig_eax = -1;
357 regs.eip = (unsigned long) kernel_thread_helper; 357 regs.eip = (unsigned long) kernel_thread_helper;
358 regs.xcs = __KERNEL_CS; 358 regs.xcs = __KERNEL_CS;
359 regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; 359 regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
360 360
361 /* Ok, create the new process.. */ 361 /* Ok, create the new process.. */
362 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL); 362 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
363 } 363 }
364 EXPORT_SYMBOL(kernel_thread); 364 EXPORT_SYMBOL(kernel_thread);
365 365
366 /* 366 /*
367 * Free current thread data structures etc.. 367 * Free current thread data structures etc..
368 */ 368 */
369 void exit_thread(void) 369 void exit_thread(void)
370 { 370 {
371 struct task_struct *tsk = current; 371 struct task_struct *tsk = current;
372 struct thread_struct *t = &tsk->thread; 372 struct thread_struct *t = &tsk->thread;
373 373
374 /* 374 /*
375 * Remove function-return probe instances associated with this task 375 * Remove function-return probe instances associated with this task
376 * and put them back on the free list. Do not insert an exit probe for 376 * and put them back on the free list. Do not insert an exit probe for
377 * this function, it will be disabled by kprobe_flush_task if you do. 377 * this function, it will be disabled by kprobe_flush_task if you do.
378 */ 378 */
379 kprobe_flush_task(tsk); 379 kprobe_flush_task(tsk);
380 380
381 /* The process may have allocated an io port bitmap... nuke it. */ 381 /* The process may have allocated an io port bitmap... nuke it. */
382 if (unlikely(NULL != t->io_bitmap_ptr)) { 382 if (unlikely(NULL != t->io_bitmap_ptr)) {
383 int cpu = get_cpu(); 383 int cpu = get_cpu();
384 struct tss_struct *tss = &per_cpu(init_tss, cpu); 384 struct tss_struct *tss = &per_cpu(init_tss, cpu);
385 385
386 kfree(t->io_bitmap_ptr); 386 kfree(t->io_bitmap_ptr);
387 t->io_bitmap_ptr = NULL; 387 t->io_bitmap_ptr = NULL;
388 /* 388 /*
389 * Careful, clear this in the TSS too: 389 * Careful, clear this in the TSS too:
390 */ 390 */
391 memset(tss->io_bitmap, 0xff, tss->io_bitmap_max); 391 memset(tss->io_bitmap, 0xff, tss->io_bitmap_max);
392 t->io_bitmap_max = 0; 392 t->io_bitmap_max = 0;
393 tss->io_bitmap_owner = NULL; 393 tss->io_bitmap_owner = NULL;
394 tss->io_bitmap_max = 0; 394 tss->io_bitmap_max = 0;
395 tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET; 395 tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
396 put_cpu(); 396 put_cpu();
397 } 397 }
398 } 398 }
399 399
400 void flush_thread(void) 400 void flush_thread(void)
401 { 401 {
402 struct task_struct *tsk = current; 402 struct task_struct *tsk = current;
403 403
404 /* 404 /*
405 * Remove function-return probe instances associated with this task 405 * Remove function-return probe instances associated with this task
406 * and put them back on the free list. Do not insert an exit probe for 406 * and put them back on the free list. Do not insert an exit probe for
407 * this function, it will be disabled by kprobe_flush_task if you do. 407 * this function, it will be disabled by kprobe_flush_task if you do.
408 */ 408 */
409 kprobe_flush_task(tsk); 409 kprobe_flush_task(tsk);
410 410
411 memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8); 411 memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
412 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array)); 412 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
413 /* 413 /*
414 * Forget coprocessor state.. 414 * Forget coprocessor state..
415 */ 415 */
416 clear_fpu(tsk); 416 clear_fpu(tsk);
417 clear_used_math(); 417 clear_used_math();
418 } 418 }
419 419
420 void release_thread(struct task_struct *dead_task) 420 void release_thread(struct task_struct *dead_task)
421 { 421 {
422 if (dead_task->mm) { 422 if (dead_task->mm) {
423 // temporary debugging check 423 // temporary debugging check
424 if (dead_task->mm->context.size) { 424 if (dead_task->mm->context.size) {
425 printk("WARNING: dead process %8s still has LDT? <%p/%d>\n", 425 printk("WARNING: dead process %8s still has LDT? <%p/%d>\n",
426 dead_task->comm, 426 dead_task->comm,
427 dead_task->mm->context.ldt, 427 dead_task->mm->context.ldt,
428 dead_task->mm->context.size); 428 dead_task->mm->context.size);
429 BUG(); 429 BUG();
430 } 430 }
431 } 431 }
432 432
433 release_vm86_irqs(dead_task); 433 release_vm86_irqs(dead_task);
434 } 434 }
435 435
436 /* 436 /*
437 * This gets called before we allocate a new thread and copy 437 * This gets called before we allocate a new thread and copy
438 * the current task into it. 438 * the current task into it.
439 */ 439 */
440 void prepare_to_copy(struct task_struct *tsk) 440 void prepare_to_copy(struct task_struct *tsk)
441 { 441 {
442 unlazy_fpu(tsk); 442 unlazy_fpu(tsk);
443 } 443 }
444 444
445 int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, 445 int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
446 unsigned long unused, 446 unsigned long unused,
447 struct task_struct * p, struct pt_regs * regs) 447 struct task_struct * p, struct pt_regs * regs)
448 { 448 {
449 struct pt_regs * childregs; 449 struct pt_regs * childregs;
450 struct task_struct *tsk; 450 struct task_struct *tsk;
451 int err; 451 int err;
452 452
453 childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; 453 childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
454 /* 454 /*
455 * The below -8 is to reserve 8 bytes on top of the ring0 stack. 455 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
456 * This is necessary to guarantee that the entire "struct pt_regs" 456 * This is necessary to guarantee that the entire "struct pt_regs"
457 * is accessable even if the CPU haven't stored the SS/ESP registers 457 * is accessable even if the CPU haven't stored the SS/ESP registers
458 * on the stack (interrupt gate does not save these registers 458 * on the stack (interrupt gate does not save these registers
459 * when switching to the same priv ring). 459 * when switching to the same priv ring).
460 * Therefore beware: accessing the xss/esp fields of the 460 * Therefore beware: accessing the xss/esp fields of the
461 * "struct pt_regs" is possible, but they may contain the 461 * "struct pt_regs" is possible, but they may contain the
462 * completely wrong values. 462 * completely wrong values.
463 */ 463 */
464 childregs = (struct pt_regs *) ((unsigned long) childregs - 8); 464 childregs = (struct pt_regs *) ((unsigned long) childregs - 8);
465 *childregs = *regs; 465 *childregs = *regs;
466 childregs->eax = 0; 466 childregs->eax = 0;
467 childregs->esp = esp; 467 childregs->esp = esp;
468 468
469 p->thread.esp = (unsigned long) childregs; 469 p->thread.esp = (unsigned long) childregs;
470 p->thread.esp0 = (unsigned long) (childregs+1); 470 p->thread.esp0 = (unsigned long) (childregs+1);
471 471
472 p->thread.eip = (unsigned long) ret_from_fork; 472 p->thread.eip = (unsigned long) ret_from_fork;
473 473
474 savesegment(fs,p->thread.fs); 474 savesegment(fs,p->thread.fs);
475 savesegment(gs,p->thread.gs); 475 savesegment(gs,p->thread.gs);
476 476
477 tsk = current; 477 tsk = current;
478 if (unlikely(NULL != tsk->thread.io_bitmap_ptr)) { 478 if (unlikely(NULL != tsk->thread.io_bitmap_ptr)) {
479 p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL); 479 p->thread.io_bitmap_ptr = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
480 if (!p->thread.io_bitmap_ptr) { 480 if (!p->thread.io_bitmap_ptr) {
481 p->thread.io_bitmap_max = 0; 481 p->thread.io_bitmap_max = 0;
482 return -ENOMEM; 482 return -ENOMEM;
483 } 483 }
484 memcpy(p->thread.io_bitmap_ptr, tsk->thread.io_bitmap_ptr, 484 memcpy(p->thread.io_bitmap_ptr, tsk->thread.io_bitmap_ptr,
485 IO_BITMAP_BYTES); 485 IO_BITMAP_BYTES);
486 } 486 }
487 487
488 /* 488 /*
489 * Set a new TLS for the child thread? 489 * Set a new TLS for the child thread?
490 */ 490 */
491 if (clone_flags & CLONE_SETTLS) { 491 if (clone_flags & CLONE_SETTLS) {
492 struct desc_struct *desc; 492 struct desc_struct *desc;
493 struct user_desc info; 493 struct user_desc info;
494 int idx; 494 int idx;
495 495
496 err = -EFAULT; 496 err = -EFAULT;
497 if (copy_from_user(&info, (void __user *)childregs->esi, sizeof(info))) 497 if (copy_from_user(&info, (void __user *)childregs->esi, sizeof(info)))
498 goto out; 498 goto out;
499 err = -EINVAL; 499 err = -EINVAL;
500 if (LDT_empty(&info)) 500 if (LDT_empty(&info))
501 goto out; 501 goto out;
502 502
503 idx = info.entry_number; 503 idx = info.entry_number;
504 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) 504 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
505 goto out; 505 goto out;
506 506
507 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; 507 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
508 desc->a = LDT_entry_a(&info); 508 desc->a = LDT_entry_a(&info);
509 desc->b = LDT_entry_b(&info); 509 desc->b = LDT_entry_b(&info);
510 } 510 }
511 511
512 err = 0; 512 err = 0;
513 out: 513 out:
514 if (err && p->thread.io_bitmap_ptr) { 514 if (err && p->thread.io_bitmap_ptr) {
515 kfree(p->thread.io_bitmap_ptr); 515 kfree(p->thread.io_bitmap_ptr);
516 p->thread.io_bitmap_max = 0; 516 p->thread.io_bitmap_max = 0;
517 } 517 }
518 return err; 518 return err;
519 } 519 }
520 520
521 /* 521 /*
522 * fill in the user structure for a core dump.. 522 * fill in the user structure for a core dump..
523 */ 523 */
524 void dump_thread(struct pt_regs * regs, struct user * dump) 524 void dump_thread(struct pt_regs * regs, struct user * dump)
525 { 525 {
526 int i; 526 int i;
527 527
528 /* changed the size calculations - should hopefully work better. lbt */ 528 /* changed the size calculations - should hopefully work better. lbt */
529 dump->magic = CMAGIC; 529 dump->magic = CMAGIC;
530 dump->start_code = 0; 530 dump->start_code = 0;
531 dump->start_stack = regs->esp & ~(PAGE_SIZE - 1); 531 dump->start_stack = regs->esp & ~(PAGE_SIZE - 1);
532 dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT; 532 dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
533 dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT; 533 dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
534 dump->u_dsize -= dump->u_tsize; 534 dump->u_dsize -= dump->u_tsize;
535 dump->u_ssize = 0; 535 dump->u_ssize = 0;
536 for (i = 0; i < 8; i++) 536 for (i = 0; i < 8; i++)
537 dump->u_debugreg[i] = current->thread.debugreg[i]; 537 dump->u_debugreg[i] = current->thread.debugreg[i];
538 538
539 if (dump->start_stack < TASK_SIZE) 539 if (dump->start_stack < TASK_SIZE)
540 dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT; 540 dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
541 541
542 dump->regs.ebx = regs->ebx; 542 dump->regs.ebx = regs->ebx;
543 dump->regs.ecx = regs->ecx; 543 dump->regs.ecx = regs->ecx;
544 dump->regs.edx = regs->edx; 544 dump->regs.edx = regs->edx;
545 dump->regs.esi = regs->esi; 545 dump->regs.esi = regs->esi;
546 dump->regs.edi = regs->edi; 546 dump->regs.edi = regs->edi;
547 dump->regs.ebp = regs->ebp; 547 dump->regs.ebp = regs->ebp;
548 dump->regs.eax = regs->eax; 548 dump->regs.eax = regs->eax;
549 dump->regs.ds = regs->xds; 549 dump->regs.ds = regs->xds;
550 dump->regs.es = regs->xes; 550 dump->regs.es = regs->xes;
551 savesegment(fs,dump->regs.fs); 551 savesegment(fs,dump->regs.fs);
552 savesegment(gs,dump->regs.gs); 552 savesegment(gs,dump->regs.gs);
553 dump->regs.orig_eax = regs->orig_eax; 553 dump->regs.orig_eax = regs->orig_eax;
554 dump->regs.eip = regs->eip; 554 dump->regs.eip = regs->eip;
555 dump->regs.cs = regs->xcs; 555 dump->regs.cs = regs->xcs;
556 dump->regs.eflags = regs->eflags; 556 dump->regs.eflags = regs->eflags;
557 dump->regs.esp = regs->esp; 557 dump->regs.esp = regs->esp;
558 dump->regs.ss = regs->xss; 558 dump->regs.ss = regs->xss;
559 559
560 dump->u_fpvalid = dump_fpu (regs, &dump->i387); 560 dump->u_fpvalid = dump_fpu (regs, &dump->i387);
561 } 561 }
562 EXPORT_SYMBOL(dump_thread); 562 EXPORT_SYMBOL(dump_thread);
563 563
564 /* 564 /*
565 * Capture the user space registers if the task is not running (in user space) 565 * Capture the user space registers if the task is not running (in user space)
566 */ 566 */
567 int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) 567 int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
568 { 568 {
569 struct pt_regs ptregs; 569 struct pt_regs ptregs;
570 570
571 ptregs = *(struct pt_regs *) 571 ptregs = *(struct pt_regs *)
572 ((unsigned long)tsk->thread_info+THREAD_SIZE - sizeof(ptregs)); 572 ((unsigned long)tsk->thread_info+THREAD_SIZE - sizeof(ptregs));
573 ptregs.xcs &= 0xffff; 573 ptregs.xcs &= 0xffff;
574 ptregs.xds &= 0xffff; 574 ptregs.xds &= 0xffff;
575 ptregs.xes &= 0xffff; 575 ptregs.xes &= 0xffff;
576 ptregs.xss &= 0xffff; 576 ptregs.xss &= 0xffff;
577 577
578 elf_core_copy_regs(regs, &ptregs); 578 elf_core_copy_regs(regs, &ptregs);
579 579
580 return 1; 580 return 1;
581 } 581 }
582 582
583 static inline void 583 static inline void
584 handle_io_bitmap(struct thread_struct *next, struct tss_struct *tss) 584 handle_io_bitmap(struct thread_struct *next, struct tss_struct *tss)
585 { 585 {
586 if (!next->io_bitmap_ptr) { 586 if (!next->io_bitmap_ptr) {
587 /* 587 /*
588 * Disable the bitmap via an invalid offset. We still cache 588 * Disable the bitmap via an invalid offset. We still cache
589 * the previous bitmap owner and the IO bitmap contents: 589 * the previous bitmap owner and the IO bitmap contents:
590 */ 590 */
591 tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET; 591 tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
592 return; 592 return;
593 } 593 }
594 if (likely(next == tss->io_bitmap_owner)) { 594 if (likely(next == tss->io_bitmap_owner)) {
595 /* 595 /*
596 * Previous owner of the bitmap (hence the bitmap content) 596 * Previous owner of the bitmap (hence the bitmap content)
597 * matches the next task, we dont have to do anything but 597 * matches the next task, we dont have to do anything but
598 * to set a valid offset in the TSS: 598 * to set a valid offset in the TSS:
599 */ 599 */
600 tss->io_bitmap_base = IO_BITMAP_OFFSET; 600 tss->io_bitmap_base = IO_BITMAP_OFFSET;
601 return; 601 return;
602 } 602 }
603 /* 603 /*
604 * Lazy TSS's I/O bitmap copy. We set an invalid offset here 604 * Lazy TSS's I/O bitmap copy. We set an invalid offset here
605 * and we let the task to get a GPF in case an I/O instruction 605 * and we let the task to get a GPF in case an I/O instruction
606 * is performed. The handler of the GPF will verify that the 606 * is performed. The handler of the GPF will verify that the
607 * faulting task has a valid I/O bitmap and, it true, does the 607 * faulting task has a valid I/O bitmap and, it true, does the
608 * real copy and restart the instruction. This will save us 608 * real copy and restart the instruction. This will save us
609 * redundant copies when the currently switched task does not 609 * redundant copies when the currently switched task does not
610 * perform any I/O during its timeslice. 610 * perform any I/O during its timeslice.
611 */ 611 */
612 tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY; 612 tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
613 } 613 }
614 614
615 /* 615 /*
616 * This function selects if the context switch from prev to next 616 * This function selects if the context switch from prev to next
617 * has to tweak the TSC disable bit in the cr4. 617 * has to tweak the TSC disable bit in the cr4.
618 */ 618 */
619 static inline void disable_tsc(struct task_struct *prev_p, 619 static inline void disable_tsc(struct task_struct *prev_p,
620 struct task_struct *next_p) 620 struct task_struct *next_p)
621 { 621 {
622 struct thread_info *prev, *next; 622 struct thread_info *prev, *next;
623 623
624 /* 624 /*
625 * gcc should eliminate the ->thread_info dereference if 625 * gcc should eliminate the ->thread_info dereference if
626 * has_secure_computing returns 0 at compile time (SECCOMP=n). 626 * has_secure_computing returns 0 at compile time (SECCOMP=n).
627 */ 627 */
628 prev = prev_p->thread_info; 628 prev = prev_p->thread_info;
629 next = next_p->thread_info; 629 next = next_p->thread_info;
630 630
631 if (has_secure_computing(prev) || has_secure_computing(next)) { 631 if (has_secure_computing(prev) || has_secure_computing(next)) {
632 /* slow path here */ 632 /* slow path here */
633 if (has_secure_computing(prev) && 633 if (has_secure_computing(prev) &&
634 !has_secure_computing(next)) { 634 !has_secure_computing(next)) {
635 write_cr4(read_cr4() & ~X86_CR4_TSD); 635 write_cr4(read_cr4() & ~X86_CR4_TSD);
636 } else if (!has_secure_computing(prev) && 636 } else if (!has_secure_computing(prev) &&
637 has_secure_computing(next)) 637 has_secure_computing(next))
638 write_cr4(read_cr4() | X86_CR4_TSD); 638 write_cr4(read_cr4() | X86_CR4_TSD);
639 } 639 }
640 } 640 }
641 641
642 /* 642 /*
643 * switch_to(x,yn) should switch tasks from x to y. 643 * switch_to(x,yn) should switch tasks from x to y.
644 * 644 *
645 * We fsave/fwait so that an exception goes off at the right time 645 * We fsave/fwait so that an exception goes off at the right time
646 * (as a call from the fsave or fwait in effect) rather than to 646 * (as a call from the fsave or fwait in effect) rather than to
647 * the wrong process. Lazy FP saving no longer makes any sense 647 * the wrong process. Lazy FP saving no longer makes any sense
648 * with modern CPU's, and this simplifies a lot of things (SMP 648 * with modern CPU's, and this simplifies a lot of things (SMP
649 * and UP become the same). 649 * and UP become the same).
650 * 650 *
651 * NOTE! We used to use the x86 hardware context switching. The 651 * NOTE! We used to use the x86 hardware context switching. The
652 * reason for not using it any more becomes apparent when you 652 * reason for not using it any more becomes apparent when you
653 * try to recover gracefully from saved state that is no longer 653 * try to recover gracefully from saved state that is no longer
654 * valid (stale segment register values in particular). With the 654 * valid (stale segment register values in particular). With the
655 * hardware task-switch, there is no way to fix up bad state in 655 * hardware task-switch, there is no way to fix up bad state in
656 * a reasonable manner. 656 * a reasonable manner.
657 * 657 *
658 * The fact that Intel documents the hardware task-switching to 658 * The fact that Intel documents the hardware task-switching to
659 * be slow is a fairly red herring - this code is not noticeably 659 * be slow is a fairly red herring - this code is not noticeably
660 * faster. However, there _is_ some room for improvement here, 660 * faster. However, there _is_ some room for improvement here,
661 * so the performance issues may eventually be a valid point. 661 * so the performance issues may eventually be a valid point.
662 * More important, however, is the fact that this allows us much 662 * More important, however, is the fact that this allows us much
663 * more flexibility. 663 * more flexibility.
664 * 664 *
665 * The return value (in %eax) will be the "prev" task after 665 * The return value (in %eax) will be the "prev" task after
666 * the task-switch, and shows up in ret_from_fork in entry.S, 666 * the task-switch, and shows up in ret_from_fork in entry.S,
667 * for example. 667 * for example.
668 */ 668 */
669 struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct task_struct *next_p) 669 struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
670 { 670 {
671 struct thread_struct *prev = &prev_p->thread, 671 struct thread_struct *prev = &prev_p->thread,
672 *next = &next_p->thread; 672 *next = &next_p->thread;
673 int cpu = smp_processor_id(); 673 int cpu = smp_processor_id();
674 struct tss_struct *tss = &per_cpu(init_tss, cpu); 674 struct tss_struct *tss = &per_cpu(init_tss, cpu);
675 675
676 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */ 676 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
677 677
678 __unlazy_fpu(prev_p); 678 __unlazy_fpu(prev_p);
679 679
680 /* 680 /*
681 * Reload esp0. 681 * Reload esp0.
682 */ 682 */
683 load_esp0(tss, next); 683 load_esp0(tss, next);
684 684
685 /* 685 /*
686 * Save away %fs and %gs. No need to save %es and %ds, as 686 * Save away %fs and %gs. No need to save %es and %ds, as
687 * those are always kernel segments while inside the kernel. 687 * those are always kernel segments while inside the kernel.
688 * Doing this before setting the new TLS descriptors avoids 688 * Doing this before setting the new TLS descriptors avoids
689 * the situation where we temporarily have non-reloadable 689 * the situation where we temporarily have non-reloadable
690 * segments in %fs and %gs. This could be an issue if the 690 * segments in %fs and %gs. This could be an issue if the
691 * NMI handler ever used %fs or %gs (it does not today), or 691 * NMI handler ever used %fs or %gs (it does not today), or
692 * if the kernel is running inside of a hypervisor layer. 692 * if the kernel is running inside of a hypervisor layer.
693 */ 693 */
694 savesegment(fs, prev->fs); 694 savesegment(fs, prev->fs);
695 savesegment(gs, prev->gs); 695 savesegment(gs, prev->gs);
696 696
697 /* 697 /*
698 * Load the per-thread Thread-Local Storage descriptor. 698 * Load the per-thread Thread-Local Storage descriptor.
699 */ 699 */
700 load_TLS(next, cpu); 700 load_TLS(next, cpu);
701 701
702 /* 702 /*
703 * Restore %fs and %gs if needed. 703 * Restore %fs and %gs if needed.
704 * 704 *
705 * Glibc normally makes %fs be zero, and %gs is one of 705 * Glibc normally makes %fs be zero, and %gs is one of
706 * the TLS segments. 706 * the TLS segments.
707 */ 707 */
708 if (unlikely(prev->fs | next->fs)) 708 if (unlikely(prev->fs | next->fs))
709 loadsegment(fs, next->fs); 709 loadsegment(fs, next->fs);
710 710
711 if (prev->gs | next->gs) 711 if (prev->gs | next->gs)
712 loadsegment(gs, next->gs); 712 loadsegment(gs, next->gs);
713 713
714 /* 714 /*
715 * Now maybe reload the debug registers 715 * Now maybe reload the debug registers
716 */ 716 */
717 if (unlikely(next->debugreg[7])) { 717 if (unlikely(next->debugreg[7])) {
718 set_debugreg(next->debugreg[0], 0); 718 set_debugreg(next->debugreg[0], 0);
719 set_debugreg(next->debugreg[1], 1); 719 set_debugreg(next->debugreg[1], 1);
720 set_debugreg(next->debugreg[2], 2); 720 set_debugreg(next->debugreg[2], 2);
721 set_debugreg(next->debugreg[3], 3); 721 set_debugreg(next->debugreg[3], 3);
722 /* no 4 and 5 */ 722 /* no 4 and 5 */
723 set_debugreg(next->debugreg[6], 6); 723 set_debugreg(next->debugreg[6], 6);
724 set_debugreg(next->debugreg[7], 7); 724 set_debugreg(next->debugreg[7], 7);
725 } 725 }
726 726
727 if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr)) 727 if (unlikely(prev->io_bitmap_ptr || next->io_bitmap_ptr))
728 handle_io_bitmap(next, tss); 728 handle_io_bitmap(next, tss);
729 729
730 disable_tsc(prev_p, next_p); 730 disable_tsc(prev_p, next_p);
731 731
732 return prev_p; 732 return prev_p;
733 } 733 }
734 734
735 asmlinkage int sys_fork(struct pt_regs regs) 735 asmlinkage int sys_fork(struct pt_regs regs)
736 { 736 {
737 return do_fork(SIGCHLD, regs.esp, &regs, 0, NULL, NULL); 737 return do_fork(SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
738 } 738 }
739 739
740 asmlinkage int sys_clone(struct pt_regs regs) 740 asmlinkage int sys_clone(struct pt_regs regs)
741 { 741 {
742 unsigned long clone_flags; 742 unsigned long clone_flags;
743 unsigned long newsp; 743 unsigned long newsp;
744 int __user *parent_tidptr, *child_tidptr; 744 int __user *parent_tidptr, *child_tidptr;
745 745
746 clone_flags = regs.ebx; 746 clone_flags = regs.ebx;
747 newsp = regs.ecx; 747 newsp = regs.ecx;
748 parent_tidptr = (int __user *)regs.edx; 748 parent_tidptr = (int __user *)regs.edx;
749 child_tidptr = (int __user *)regs.edi; 749 child_tidptr = (int __user *)regs.edi;
750 if (!newsp) 750 if (!newsp)
751 newsp = regs.esp; 751 newsp = regs.esp;
752 return do_fork(clone_flags, newsp, &regs, 0, parent_tidptr, child_tidptr); 752 return do_fork(clone_flags, newsp, &regs, 0, parent_tidptr, child_tidptr);
753 } 753 }
754 754
755 /* 755 /*
756 * This is trivial, and on the face of it looks like it 756 * This is trivial, and on the face of it looks like it
757 * could equally well be done in user mode. 757 * could equally well be done in user mode.
758 * 758 *
759 * Not so, for quite unobvious reasons - register pressure. 759 * Not so, for quite unobvious reasons - register pressure.
760 * In user mode vfork() cannot have a stack frame, and if 760 * In user mode vfork() cannot have a stack frame, and if
761 * done by calling the "clone()" system call directly, you 761 * done by calling the "clone()" system call directly, you
762 * do not have enough call-clobbered registers to hold all 762 * do not have enough call-clobbered registers to hold all
763 * the information you need. 763 * the information you need.
764 */ 764 */
765 asmlinkage int sys_vfork(struct pt_regs regs) 765 asmlinkage int sys_vfork(struct pt_regs regs)
766 { 766 {
767 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs, 0, NULL, NULL); 767 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
768 } 768 }
769 769
770 /* 770 /*
771 * sys_execve() executes a new program. 771 * sys_execve() executes a new program.
772 */ 772 */
773 asmlinkage int sys_execve(struct pt_regs regs) 773 asmlinkage int sys_execve(struct pt_regs regs)
774 { 774 {
775 int error; 775 int error;
776 char * filename; 776 char * filename;
777 777
778 filename = getname((char __user *) regs.ebx); 778 filename = getname((char __user *) regs.ebx);
779 error = PTR_ERR(filename); 779 error = PTR_ERR(filename);
780 if (IS_ERR(filename)) 780 if (IS_ERR(filename))
781 goto out; 781 goto out;
782 error = do_execve(filename, 782 error = do_execve(filename,
783 (char __user * __user *) regs.ecx, 783 (char __user * __user *) regs.ecx,
784 (char __user * __user *) regs.edx, 784 (char __user * __user *) regs.edx,
785 &regs); 785 &regs);
786 if (error == 0) { 786 if (error == 0) {
787 task_lock(current); 787 task_lock(current);
788 current->ptrace &= ~PT_DTRACE; 788 current->ptrace &= ~PT_DTRACE;
789 task_unlock(current); 789 task_unlock(current);
790 /* Make sure we don't return using sysenter.. */ 790 /* Make sure we don't return using sysenter.. */
791 set_thread_flag(TIF_IRET); 791 set_thread_flag(TIF_IRET);
792 } 792 }
793 putname(filename); 793 putname(filename);
794 out: 794 out:
795 return error; 795 return error;
796 } 796 }
797 797
798 #define top_esp (THREAD_SIZE - sizeof(unsigned long)) 798 #define top_esp (THREAD_SIZE - sizeof(unsigned long))
799 #define top_ebp (THREAD_SIZE - 2*sizeof(unsigned long)) 799 #define top_ebp (THREAD_SIZE - 2*sizeof(unsigned long))
800 800
801 unsigned long get_wchan(struct task_struct *p) 801 unsigned long get_wchan(struct task_struct *p)
802 { 802 {
803 unsigned long ebp, esp, eip; 803 unsigned long ebp, esp, eip;
804 unsigned long stack_page; 804 unsigned long stack_page;
805 int count = 0; 805 int count = 0;
806 if (!p || p == current || p->state == TASK_RUNNING) 806 if (!p || p == current || p->state == TASK_RUNNING)
807 return 0; 807 return 0;
808 stack_page = (unsigned long)p->thread_info; 808 stack_page = (unsigned long)p->thread_info;
809 esp = p->thread.esp; 809 esp = p->thread.esp;
810 if (!stack_page || esp < stack_page || esp > top_esp+stack_page) 810 if (!stack_page || esp < stack_page || esp > top_esp+stack_page)
811 return 0; 811 return 0;
812 /* include/asm-i386/system.h:switch_to() pushes ebp last. */ 812 /* include/asm-i386/system.h:switch_to() pushes ebp last. */
813 ebp = *(unsigned long *) esp; 813 ebp = *(unsigned long *) esp;
814 do { 814 do {
815 if (ebp < stack_page || ebp > top_ebp+stack_page) 815 if (ebp < stack_page || ebp > top_ebp+stack_page)
816 return 0; 816 return 0;
817 eip = *(unsigned long *) (ebp+4); 817 eip = *(unsigned long *) (ebp+4);
818 if (!in_sched_functions(eip)) 818 if (!in_sched_functions(eip))
819 return eip; 819 return eip;
820 ebp = *(unsigned long *) ebp; 820 ebp = *(unsigned long *) ebp;
821 } while (count++ < 16); 821 } while (count++ < 16);
822 return 0; 822 return 0;
823 } 823 }
824 EXPORT_SYMBOL(get_wchan); 824 EXPORT_SYMBOL(get_wchan);
825 825
826 /* 826 /*
827 * sys_alloc_thread_area: get a yet unused TLS descriptor index. 827 * sys_alloc_thread_area: get a yet unused TLS descriptor index.
828 */ 828 */
829 static int get_free_idx(void) 829 static int get_free_idx(void)
830 { 830 {
831 struct thread_struct *t = &current->thread; 831 struct thread_struct *t = &current->thread;
832 int idx; 832 int idx;
833 833
834 for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++) 834 for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
835 if (desc_empty(t->tls_array + idx)) 835 if (desc_empty(t->tls_array + idx))
836 return idx + GDT_ENTRY_TLS_MIN; 836 return idx + GDT_ENTRY_TLS_MIN;
837 return -ESRCH; 837 return -ESRCH;
838 } 838 }
839 839
840 /* 840 /*
841 * Set a given TLS descriptor: 841 * Set a given TLS descriptor:
842 */ 842 */
843 asmlinkage int sys_set_thread_area(struct user_desc __user *u_info) 843 asmlinkage int sys_set_thread_area(struct user_desc __user *u_info)
844 { 844 {
845 struct thread_struct *t = &current->thread; 845 struct thread_struct *t = &current->thread;
846 struct user_desc info; 846 struct user_desc info;
847 struct desc_struct *desc; 847 struct desc_struct *desc;
848 int cpu, idx; 848 int cpu, idx;
849 849
850 if (copy_from_user(&info, u_info, sizeof(info))) 850 if (copy_from_user(&info, u_info, sizeof(info)))
851 return -EFAULT; 851 return -EFAULT;
852 idx = info.entry_number; 852 idx = info.entry_number;
853 853
854 /* 854 /*
855 * index -1 means the kernel should try to find and 855 * index -1 means the kernel should try to find and
856 * allocate an empty descriptor: 856 * allocate an empty descriptor:
857 */ 857 */
858 if (idx == -1) { 858 if (idx == -1) {
859 idx = get_free_idx(); 859 idx = get_free_idx();
860 if (idx < 0) 860 if (idx < 0)
861 return idx; 861 return idx;
862 if (put_user(idx, &u_info->entry_number)) 862 if (put_user(idx, &u_info->entry_number))
863 return -EFAULT; 863 return -EFAULT;
864 } 864 }
865 865
866 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) 866 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
867 return -EINVAL; 867 return -EINVAL;
868 868
869 desc = t->tls_array + idx - GDT_ENTRY_TLS_MIN; 869 desc = t->tls_array + idx - GDT_ENTRY_TLS_MIN;
870 870
871 /* 871 /*
872 * We must not get preempted while modifying the TLS. 872 * We must not get preempted while modifying the TLS.
873 */ 873 */
874 cpu = get_cpu(); 874 cpu = get_cpu();
875 875
876 if (LDT_empty(&info)) { 876 if (LDT_empty(&info)) {
877 desc->a = 0; 877 desc->a = 0;
878 desc->b = 0; 878 desc->b = 0;
879 } else { 879 } else {
880 desc->a = LDT_entry_a(&info); 880 desc->a = LDT_entry_a(&info);
881 desc->b = LDT_entry_b(&info); 881 desc->b = LDT_entry_b(&info);
882 } 882 }
883 load_TLS(t, cpu); 883 load_TLS(t, cpu);
884 884
885 put_cpu(); 885 put_cpu();
886 886
887 return 0; 887 return 0;
888 } 888 }
889 889
890 /* 890 /*
891 * Get the current Thread-Local Storage area: 891 * Get the current Thread-Local Storage area:
892 */ 892 */
893 893
894 #define GET_BASE(desc) ( \ 894 #define GET_BASE(desc) ( \
895 (((desc)->a >> 16) & 0x0000ffff) | \ 895 (((desc)->a >> 16) & 0x0000ffff) | \
896 (((desc)->b << 16) & 0x00ff0000) | \ 896 (((desc)->b << 16) & 0x00ff0000) | \
897 ( (desc)->b & 0xff000000) ) 897 ( (desc)->b & 0xff000000) )
898 898
899 #define GET_LIMIT(desc) ( \ 899 #define GET_LIMIT(desc) ( \
900 ((desc)->a & 0x0ffff) | \ 900 ((desc)->a & 0x0ffff) | \
901 ((desc)->b & 0xf0000) ) 901 ((desc)->b & 0xf0000) )
902 902
903 #define GET_32BIT(desc) (((desc)->b >> 22) & 1) 903 #define GET_32BIT(desc) (((desc)->b >> 22) & 1)
904 #define GET_CONTENTS(desc) (((desc)->b >> 10) & 3) 904 #define GET_CONTENTS(desc) (((desc)->b >> 10) & 3)
905 #define GET_WRITABLE(desc) (((desc)->b >> 9) & 1) 905 #define GET_WRITABLE(desc) (((desc)->b >> 9) & 1)
906 #define GET_LIMIT_PAGES(desc) (((desc)->b >> 23) & 1) 906 #define GET_LIMIT_PAGES(desc) (((desc)->b >> 23) & 1)
907 #define GET_PRESENT(desc) (((desc)->b >> 15) & 1) 907 #define GET_PRESENT(desc) (((desc)->b >> 15) & 1)
908 #define GET_USEABLE(desc) (((desc)->b >> 20) & 1) 908 #define GET_USEABLE(desc) (((desc)->b >> 20) & 1)
909 909
910 asmlinkage int sys_get_thread_area(struct user_desc __user *u_info) 910 asmlinkage int sys_get_thread_area(struct user_desc __user *u_info)
911 { 911 {
912 struct user_desc info; 912 struct user_desc info;
913 struct desc_struct *desc; 913 struct desc_struct *desc;
914 int idx; 914 int idx;
915 915
916 if (get_user(idx, &u_info->entry_number)) 916 if (get_user(idx, &u_info->entry_number))
917 return -EFAULT; 917 return -EFAULT;
918 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX) 918 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
919 return -EINVAL; 919 return -EINVAL;
920 920
921 memset(&info, 0, sizeof(info)); 921 memset(&info, 0, sizeof(info));
922 922
923 desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN; 923 desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
924 924
925 info.entry_number = idx; 925 info.entry_number = idx;
926 info.base_addr = GET_BASE(desc); 926 info.base_addr = GET_BASE(desc);
927 info.limit = GET_LIMIT(desc); 927 info.limit = GET_LIMIT(desc);
928 info.seg_32bit = GET_32BIT(desc); 928 info.seg_32bit = GET_32BIT(desc);
929 info.contents = GET_CONTENTS(desc); 929 info.contents = GET_CONTENTS(desc);
930 info.read_exec_only = !GET_WRITABLE(desc); 930 info.read_exec_only = !GET_WRITABLE(desc);
931 info.limit_in_pages = GET_LIMIT_PAGES(desc); 931 info.limit_in_pages = GET_LIMIT_PAGES(desc);
932 info.seg_not_present = !GET_PRESENT(desc); 932 info.seg_not_present = !GET_PRESENT(desc);
933 info.useable = GET_USEABLE(desc); 933 info.useable = GET_USEABLE(desc);
934 934
935 if (copy_to_user(u_info, &info, sizeof(info))) 935 if (copy_to_user(u_info, &info, sizeof(info)))
936 return -EFAULT; 936 return -EFAULT;
937 return 0; 937 return 0;
938 } 938 }
939 939
940 unsigned long arch_align_stack(unsigned long sp) 940 unsigned long arch_align_stack(unsigned long sp)
941 { 941 {
942 if (randomize_va_space) 942 if (randomize_va_space)
943 sp -= get_random_int() % 8192; 943 sp -= get_random_int() % 8192;
944 return sp & ~0xf; 944 return sp & ~0xf;
945 } 945 }
946 946
arch/i386/mach-voyager/voyager_basic.c
1 /* Copyright (C) 1999,2001 1 /* Copyright (C) 1999,2001
2 * 2 *
3 * Author: J.E.J.Bottomley@HansenPartnership.com 3 * Author: J.E.J.Bottomley@HansenPartnership.com
4 * 4 *
5 * linux/arch/i386/kernel/voyager.c 5 * linux/arch/i386/kernel/voyager.c
6 * 6 *
7 * This file contains all the voyager specific routines for getting 7 * This file contains all the voyager specific routines for getting
8 * initialisation of the architecture to function. For additional 8 * initialisation of the architecture to function. For additional
9 * features see: 9 * features see:
10 * 10 *
11 * voyager_cat.c - Voyager CAT bus interface 11 * voyager_cat.c - Voyager CAT bus interface
12 * voyager_smp.c - Voyager SMP hal (emulates linux smp.c) 12 * voyager_smp.c - Voyager SMP hal (emulates linux smp.c)
13 */ 13 */
14 14
15 #include <linux/config.h> 15 #include <linux/config.h>
16 #include <linux/module.h> 16 #include <linux/module.h>
17 #include <linux/types.h> 17 #include <linux/types.h>
18 #include <linux/sched.h> 18 #include <linux/sched.h>
19 #include <linux/ptrace.h> 19 #include <linux/ptrace.h>
20 #include <linux/ioport.h> 20 #include <linux/ioport.h>
21 #include <linux/interrupt.h> 21 #include <linux/interrupt.h>
22 #include <linux/init.h> 22 #include <linux/init.h>
23 #include <linux/delay.h> 23 #include <linux/delay.h>
24 #include <linux/reboot.h> 24 #include <linux/reboot.h>
25 #include <linux/sysrq.h> 25 #include <linux/sysrq.h>
26 #include <asm/io.h> 26 #include <asm/io.h>
27 #include <asm/voyager.h> 27 #include <asm/voyager.h>
28 #include <asm/vic.h> 28 #include <asm/vic.h>
29 #include <linux/pm.h> 29 #include <linux/pm.h>
30 #include <linux/irq.h> 30 #include <linux/irq.h>
31 #include <asm/tlbflush.h> 31 #include <asm/tlbflush.h>
32 #include <asm/arch_hooks.h> 32 #include <asm/arch_hooks.h>
33 #include <asm/i8253.h> 33 #include <asm/i8253.h>
34 34
35 /* 35 /*
36 * Power off function, if any 36 * Power off function, if any
37 */ 37 */
38 void (*pm_power_off)(void); 38 void (*pm_power_off)(void);
39 EXPORT_SYMBOL(pm_power_off); 39 EXPORT_SYMBOL(pm_power_off);
40 40
41 int voyager_level = 0; 41 int voyager_level = 0;
42 42
43 struct voyager_SUS *voyager_SUS = NULL; 43 struct voyager_SUS *voyager_SUS = NULL;
44 44
45 #ifdef CONFIG_SMP 45 #ifdef CONFIG_SMP
46 static void 46 static void
47 voyager_dump(int dummy1, struct pt_regs *dummy2, struct tty_struct *dummy3) 47 voyager_dump(int dummy1, struct pt_regs *dummy2, struct tty_struct *dummy3)
48 { 48 {
49 /* get here via a sysrq */ 49 /* get here via a sysrq */
50 voyager_smp_dump(); 50 voyager_smp_dump();
51 } 51 }
52 52
53 static struct sysrq_key_op sysrq_voyager_dump_op = { 53 static struct sysrq_key_op sysrq_voyager_dump_op = {
54 .handler = voyager_dump, 54 .handler = voyager_dump,
55 .help_msg = "Voyager", 55 .help_msg = "Voyager",
56 .action_msg = "Dump Voyager Status", 56 .action_msg = "Dump Voyager Status",
57 }; 57 };
58 #endif 58 #endif
59 59
60 void 60 void
61 voyager_detect(struct voyager_bios_info *bios) 61 voyager_detect(struct voyager_bios_info *bios)
62 { 62 {
63 if(bios->len != 0xff) { 63 if(bios->len != 0xff) {
64 int class = (bios->class_1 << 8) 64 int class = (bios->class_1 << 8)
65 | (bios->class_2 & 0xff); 65 | (bios->class_2 & 0xff);
66 66
67 printk("Voyager System detected.\n" 67 printk("Voyager System detected.\n"
68 " Class %x, Revision %d.%d\n", 68 " Class %x, Revision %d.%d\n",
69 class, bios->major, bios->minor); 69 class, bios->major, bios->minor);
70 if(class == VOYAGER_LEVEL4) 70 if(class == VOYAGER_LEVEL4)
71 voyager_level = 4; 71 voyager_level = 4;
72 else if(class < VOYAGER_LEVEL5_AND_ABOVE) 72 else if(class < VOYAGER_LEVEL5_AND_ABOVE)
73 voyager_level = 3; 73 voyager_level = 3;
74 else 74 else
75 voyager_level = 5; 75 voyager_level = 5;
76 printk(" Architecture Level %d\n", voyager_level); 76 printk(" Architecture Level %d\n", voyager_level);
77 if(voyager_level < 4) 77 if(voyager_level < 4)
78 printk("\n**WARNING**: Voyager HAL only supports Levels 4 and 5 Architectures at the moment\n\n"); 78 printk("\n**WARNING**: Voyager HAL only supports Levels 4 and 5 Architectures at the moment\n\n");
79 /* install the power off handler */ 79 /* install the power off handler */
80 pm_power_off = voyager_power_off; 80 pm_power_off = voyager_power_off;
81 #ifdef CONFIG_SMP 81 #ifdef CONFIG_SMP
82 register_sysrq_key('v', &sysrq_voyager_dump_op); 82 register_sysrq_key('v', &sysrq_voyager_dump_op);
83 #endif 83 #endif
84 } else { 84 } else {
85 printk("\n\n**WARNING**: No Voyager Subsystem Found\n"); 85 printk("\n\n**WARNING**: No Voyager Subsystem Found\n");
86 } 86 }
87 } 87 }
88 88
89 void 89 void
90 voyager_system_interrupt(int cpl, void *dev_id, struct pt_regs *regs) 90 voyager_system_interrupt(int cpl, void *dev_id, struct pt_regs *regs)
91 { 91 {
92 printk("Voyager: detected system interrupt\n"); 92 printk("Voyager: detected system interrupt\n");
93 } 93 }
94 94
95 /* Routine to read information from the extended CMOS area */ 95 /* Routine to read information from the extended CMOS area */
96 __u8 96 __u8
97 voyager_extended_cmos_read(__u16 addr) 97 voyager_extended_cmos_read(__u16 addr)
98 { 98 {
99 outb(addr & 0xff, 0x74); 99 outb(addr & 0xff, 0x74);
100 outb((addr >> 8) & 0xff, 0x75); 100 outb((addr >> 8) & 0xff, 0x75);
101 return inb(0x76); 101 return inb(0x76);
102 } 102 }
103 103
104 /* internal definitions for the SUS Click Map of memory */ 104 /* internal definitions for the SUS Click Map of memory */
105 105
106 #define CLICK_ENTRIES 16 106 #define CLICK_ENTRIES 16
107 #define CLICK_SIZE 4096 /* click to byte conversion for Length */ 107 #define CLICK_SIZE 4096 /* click to byte conversion for Length */
108 108
109 typedef struct ClickMap { 109 typedef struct ClickMap {
110 struct Entry { 110 struct Entry {
111 __u32 Address; 111 __u32 Address;
112 __u32 Length; 112 __u32 Length;
113 } Entry[CLICK_ENTRIES]; 113 } Entry[CLICK_ENTRIES];
114 } ClickMap_t; 114 } ClickMap_t;
115 115
116 116
117 /* This routine is pretty much an awful hack to read the bios clickmap by 117 /* This routine is pretty much an awful hack to read the bios clickmap by
118 * mapping it into page 0. There are usually three regions in the map: 118 * mapping it into page 0. There are usually three regions in the map:
119 * Base Memory 119 * Base Memory
120 * Extended Memory 120 * Extended Memory
121 * zero length marker for end of map 121 * zero length marker for end of map
122 * 122 *
123 * Returns are 0 for failure and 1 for success on extracting region. 123 * Returns are 0 for failure and 1 for success on extracting region.
124 */ 124 */
125 int __init 125 int __init
126 voyager_memory_detect(int region, __u32 *start, __u32 *length) 126 voyager_memory_detect(int region, __u32 *start, __u32 *length)
127 { 127 {
128 int i; 128 int i;
129 int retval = 0; 129 int retval = 0;
130 __u8 cmos[4]; 130 __u8 cmos[4];
131 ClickMap_t *map; 131 ClickMap_t *map;
132 unsigned long map_addr; 132 unsigned long map_addr;
133 unsigned long old; 133 unsigned long old;
134 134
135 if(region >= CLICK_ENTRIES) { 135 if(region >= CLICK_ENTRIES) {
136 printk("Voyager: Illegal ClickMap region %d\n", region); 136 printk("Voyager: Illegal ClickMap region %d\n", region);
137 return 0; 137 return 0;
138 } 138 }
139 139
140 for(i = 0; i < sizeof(cmos); i++) 140 for(i = 0; i < sizeof(cmos); i++)
141 cmos[i] = voyager_extended_cmos_read(VOYAGER_MEMORY_CLICKMAP + i); 141 cmos[i] = voyager_extended_cmos_read(VOYAGER_MEMORY_CLICKMAP + i);
142 142
143 map_addr = *(unsigned long *)cmos; 143 map_addr = *(unsigned long *)cmos;
144 144
145 /* steal page 0 for this */ 145 /* steal page 0 for this */
146 old = pg0[0]; 146 old = pg0[0];
147 pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT); 147 pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
148 local_flush_tlb(); 148 local_flush_tlb();
149 /* now clear everything out but page 0 */ 149 /* now clear everything out but page 0 */
150 map = (ClickMap_t *)(map_addr & (~PAGE_MASK)); 150 map = (ClickMap_t *)(map_addr & (~PAGE_MASK));
151 151
152 /* zero length is the end of the clickmap */ 152 /* zero length is the end of the clickmap */
153 if(map->Entry[region].Length != 0) { 153 if(map->Entry[region].Length != 0) {
154 *length = map->Entry[region].Length * CLICK_SIZE; 154 *length = map->Entry[region].Length * CLICK_SIZE;
155 *start = map->Entry[region].Address; 155 *start = map->Entry[region].Address;
156 retval = 1; 156 retval = 1;
157 } 157 }
158 158
159 /* replace the mapping */ 159 /* replace the mapping */
160 pg0[0] = old; 160 pg0[0] = old;
161 local_flush_tlb(); 161 local_flush_tlb();
162 return retval; 162 return retval;
163 } 163 }
164 164
165 /* voyager specific handling code for timer interrupts. Used to hand 165 /* voyager specific handling code for timer interrupts. Used to hand
166 * off the timer tick to the SMP code, since the VIC doesn't have an 166 * off the timer tick to the SMP code, since the VIC doesn't have an
167 * internal timer (The QIC does, but that's another story). */ 167 * internal timer (The QIC does, but that's another story). */
168 void 168 void
169 voyager_timer_interrupt(struct pt_regs *regs) 169 voyager_timer_interrupt(struct pt_regs *regs)
170 { 170 {
171 if((jiffies & 0x3ff) == 0) { 171 if((jiffies & 0x3ff) == 0) {
172 172
173 /* There seems to be something flaky in either 173 /* There seems to be something flaky in either
174 * hardware or software that is resetting the timer 0 174 * hardware or software that is resetting the timer 0
175 * count to something much higher than it should be 175 * count to something much higher than it should be
176 * This seems to occur in the boot sequence, just 176 * This seems to occur in the boot sequence, just
177 * before root is mounted. Therefore, every 10 177 * before root is mounted. Therefore, every 10
178 * seconds or so, we sanity check the timer zero count 178 * seconds or so, we sanity check the timer zero count
179 * and kick it back to where it should be. 179 * and kick it back to where it should be.
180 * 180 *
181 * FIXME: This is the most awful hack yet seen. I 181 * FIXME: This is the most awful hack yet seen. I
182 * should work out exactly what is interfering with 182 * should work out exactly what is interfering with
183 * the timer count settings early in the boot sequence 183 * the timer count settings early in the boot sequence
184 * and swiftly introduce it to something sharp and 184 * and swiftly introduce it to something sharp and
185 * pointy. */ 185 * pointy. */
186 __u16 val; 186 __u16 val;
187 187
188 spin_lock(&i8253_lock); 188 spin_lock(&i8253_lock);
189 189
190 outb_p(0x00, 0x43); 190 outb_p(0x00, 0x43);
191 val = inb_p(0x40); 191 val = inb_p(0x40);
192 val |= inb(0x40) << 8; 192 val |= inb(0x40) << 8;
193 spin_unlock(&i8253_lock); 193 spin_unlock(&i8253_lock);
194 194
195 if(val > LATCH) { 195 if(val > LATCH) {
196 printk("\nVOYAGER: countdown timer value too high (%d), resetting\n\n", val); 196 printk("\nVOYAGER: countdown timer value too high (%d), resetting\n\n", val);
197 spin_lock(&i8253_lock); 197 spin_lock(&i8253_lock);
198 outb(0x34,0x43); 198 outb(0x34,0x43);
199 outb_p(LATCH & 0xff , 0x40); /* LSB */ 199 outb_p(LATCH & 0xff , 0x40); /* LSB */
200 outb(LATCH >> 8 , 0x40); /* MSB */ 200 outb(LATCH >> 8 , 0x40); /* MSB */
201 spin_unlock(&i8253_lock); 201 spin_unlock(&i8253_lock);
202 } 202 }
203 } 203 }
204 #ifdef CONFIG_SMP 204 #ifdef CONFIG_SMP
205 smp_vic_timer_interrupt(regs); 205 smp_vic_timer_interrupt(regs);
206 #endif 206 #endif
207 } 207 }
208 208
209 void 209 void
210 voyager_power_off(void) 210 voyager_power_off(void)
211 { 211 {
212 printk("VOYAGER Power Off\n"); 212 printk("VOYAGER Power Off\n");
213 213
214 if(voyager_level == 5) { 214 if(voyager_level == 5) {
215 voyager_cat_power_off(); 215 voyager_cat_power_off();
216 } else if(voyager_level == 4) { 216 } else if(voyager_level == 4) {
217 /* This doesn't apparently work on most L4 machines, 217 /* This doesn't apparently work on most L4 machines,
218 * but the specs say to do this to get automatic power 218 * but the specs say to do this to get automatic power
219 * off. Unfortunately, if it doesn't power off the 219 * off. Unfortunately, if it doesn't power off the
220 * machine, it ends up doing a cold restart, which 220 * machine, it ends up doing a cold restart, which
221 * isn't really intended, so comment out the code */ 221 * isn't really intended, so comment out the code */
222 #if 0 222 #if 0
223 int port; 223 int port;
224 224
225 225
226 /* enable the voyager Configuration Space */ 226 /* enable the voyager Configuration Space */
227 outb((inb(VOYAGER_MC_SETUP) & 0xf0) | 0x8, 227 outb((inb(VOYAGER_MC_SETUP) & 0xf0) | 0x8,
228 VOYAGER_MC_SETUP); 228 VOYAGER_MC_SETUP);
229 /* the port for the power off flag is an offset from the 229 /* the port for the power off flag is an offset from the
230 floating base */ 230 floating base */
231 port = (inb(VOYAGER_SSPB_RELOCATION_PORT) << 8) + 0x21; 231 port = (inb(VOYAGER_SSPB_RELOCATION_PORT) << 8) + 0x21;
232 /* set the power off flag */ 232 /* set the power off flag */
233 outb(inb(port) | 0x1, port); 233 outb(inb(port) | 0x1, port);
234 #endif 234 #endif
235 } 235 }
236 /* and wait for it to happen */ 236 /* and wait for it to happen */
237 for(;;) { 237 local_irq_disable();
238 __asm("cli"); 238 for(;;)
239 __asm("hlt"); 239 halt();
240 }
241 } 240 }
242 241
243 /* copied from process.c */ 242 /* copied from process.c */
244 static inline void 243 static inline void
245 kb_wait(void) 244 kb_wait(void)
246 { 245 {
247 int i; 246 int i;
248 247
249 for (i=0; i<0x10000; i++) 248 for (i=0; i<0x10000; i++)
250 if ((inb_p(0x64) & 0x02) == 0) 249 if ((inb_p(0x64) & 0x02) == 0)
251 break; 250 break;
252 } 251 }
253 252
254 void 253 void
255 machine_shutdown(void) 254 machine_shutdown(void)
256 { 255 {
257 /* Architecture specific shutdown needed before a kexec */ 256 /* Architecture specific shutdown needed before a kexec */
258 } 257 }
259 258
260 void 259 void
261 machine_restart(char *cmd) 260 machine_restart(char *cmd)
262 { 261 {
263 printk("Voyager Warm Restart\n"); 262 printk("Voyager Warm Restart\n");
264 kb_wait(); 263 kb_wait();
265 264
266 if(voyager_level == 5) { 265 if(voyager_level == 5) {
267 /* write magic values to the RTC to inform system that 266 /* write magic values to the RTC to inform system that
268 * shutdown is beginning */ 267 * shutdown is beginning */
269 outb(0x8f, 0x70); 268 outb(0x8f, 0x70);
270 outb(0x5 , 0x71); 269 outb(0x5 , 0x71);
271 270
272 udelay(50); 271 udelay(50);
273 outb(0xfe,0x64); /* pull reset low */ 272 outb(0xfe,0x64); /* pull reset low */
274 } else if(voyager_level == 4) { 273 } else if(voyager_level == 4) {
275 __u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT)<<8; 274 __u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT)<<8;
276 __u8 basebd = inb(VOYAGER_MC_SETUP); 275 __u8 basebd = inb(VOYAGER_MC_SETUP);
277 276
278 outb(basebd | 0x08, VOYAGER_MC_SETUP); 277 outb(basebd | 0x08, VOYAGER_MC_SETUP);
279 outb(0x02, catbase + 0x21); 278 outb(0x02, catbase + 0x21);
280 } 279 }
281 for(;;) { 280 local_irq_disable();
282 asm("cli"); 281 for(;;)
283 asm("hlt"); 282 halt();
284 }
285 } 283 }
286 284
287 void 285 void
288 machine_emergency_restart(void) 286 machine_emergency_restart(void)
289 { 287 {
290 /*for now, just hook this to a warm restart */ 288 /*for now, just hook this to a warm restart */
291 machine_restart(NULL); 289 machine_restart(NULL);
292 } 290 }
293 291
294 void 292 void
295 mca_nmi_hook(void) 293 mca_nmi_hook(void)
296 { 294 {
297 __u8 dumpval __attribute__((unused)) = inb(0xf823); 295 __u8 dumpval __attribute__((unused)) = inb(0xf823);
298 __u8 swnmi __attribute__((unused)) = inb(0xf813); 296 __u8 swnmi __attribute__((unused)) = inb(0xf813);
299 297
300 /* FIXME: assume dump switch pressed */ 298 /* FIXME: assume dump switch pressed */
301 /* check to see if the dump switch was pressed */ 299 /* check to see if the dump switch was pressed */
302 VDEBUG(("VOYAGER: dumpval = 0x%x, swnmi = 0x%x\n", dumpval, swnmi)); 300 VDEBUG(("VOYAGER: dumpval = 0x%x, swnmi = 0x%x\n", dumpval, swnmi));
303 /* clear swnmi */ 301 /* clear swnmi */
304 outb(0xff, 0xf813); 302 outb(0xff, 0xf813);
305 /* tell SUS to ignore dump */ 303 /* tell SUS to ignore dump */
306 if(voyager_level == 5 && voyager_SUS != NULL) { 304 if(voyager_level == 5 && voyager_SUS != NULL) {
307 if(voyager_SUS->SUS_mbox == VOYAGER_DUMP_BUTTON_NMI) { 305 if(voyager_SUS->SUS_mbox == VOYAGER_DUMP_BUTTON_NMI) {
308 voyager_SUS->kernel_mbox = VOYAGER_NO_COMMAND; 306 voyager_SUS->kernel_mbox = VOYAGER_NO_COMMAND;
309 voyager_SUS->kernel_flags |= VOYAGER_OS_IN_PROGRESS; 307 voyager_SUS->kernel_flags |= VOYAGER_OS_IN_PROGRESS;
310 udelay(1000); 308 udelay(1000);
311 voyager_SUS->kernel_mbox = VOYAGER_IGNORE_DUMP; 309 voyager_SUS->kernel_mbox = VOYAGER_IGNORE_DUMP;
312 voyager_SUS->kernel_flags &= ~VOYAGER_OS_IN_PROGRESS; 310 voyager_SUS->kernel_flags &= ~VOYAGER_OS_IN_PROGRESS;
313 } 311 }
314 } 312 }
315 printk(KERN_ERR "VOYAGER: Dump switch pressed, printing CPU%d tracebacks\n", smp_processor_id()); 313 printk(KERN_ERR "VOYAGER: Dump switch pressed, printing CPU%d tracebacks\n", smp_processor_id());
316 show_stack(NULL, NULL); 314 show_stack(NULL, NULL);
317 show_state(); 315 show_state();
318 } 316 }
319 317
320 318
321 319
322 void 320 void
323 machine_halt(void) 321 machine_halt(void)
324 { 322 {
325 /* treat a halt like a power off */ 323 /* treat a halt like a power off */
326 machine_power_off(); 324 machine_power_off();
327 } 325 }
328 326
329 void machine_power_off(void) 327 void machine_power_off(void)
330 { 328 {
331 if (pm_power_off) 329 if (pm_power_off)
332 pm_power_off(); 330 pm_power_off();
333 } 331 }
334 332
335 333
arch/i386/mach-voyager/voyager_smp.c
1 /* -*- mode: c; c-basic-offset: 8 -*- */ 1 /* -*- mode: c; c-basic-offset: 8 -*- */
2 2
3 /* Copyright (C) 1999,2001 3 /* Copyright (C) 1999,2001
4 * 4 *
5 * Author: J.E.J.Bottomley@HansenPartnership.com 5 * Author: J.E.J.Bottomley@HansenPartnership.com
6 * 6 *
7 * linux/arch/i386/kernel/voyager_smp.c 7 * linux/arch/i386/kernel/voyager_smp.c
8 * 8 *
9 * This file provides all the same external entries as smp.c but uses 9 * This file provides all the same external entries as smp.c but uses
10 * the voyager hal to provide the functionality 10 * the voyager hal to provide the functionality
11 */ 11 */
12 #include <linux/config.h> 12 #include <linux/config.h>
13 #include <linux/module.h> 13 #include <linux/module.h>
14 #include <linux/mm.h> 14 #include <linux/mm.h>
15 #include <linux/kernel_stat.h> 15 #include <linux/kernel_stat.h>
16 #include <linux/delay.h> 16 #include <linux/delay.h>
17 #include <linux/mc146818rtc.h> 17 #include <linux/mc146818rtc.h>
18 #include <linux/cache.h> 18 #include <linux/cache.h>
19 #include <linux/interrupt.h> 19 #include <linux/interrupt.h>
20 #include <linux/smp_lock.h> 20 #include <linux/smp_lock.h>
21 #include <linux/init.h> 21 #include <linux/init.h>
22 #include <linux/kernel.h> 22 #include <linux/kernel.h>
23 #include <linux/bootmem.h> 23 #include <linux/bootmem.h>
24 #include <linux/completion.h> 24 #include <linux/completion.h>
25 #include <asm/desc.h> 25 #include <asm/desc.h>
26 #include <asm/voyager.h> 26 #include <asm/voyager.h>
27 #include <asm/vic.h> 27 #include <asm/vic.h>
28 #include <asm/mtrr.h> 28 #include <asm/mtrr.h>
29 #include <asm/pgalloc.h> 29 #include <asm/pgalloc.h>
30 #include <asm/tlbflush.h> 30 #include <asm/tlbflush.h>
31 #include <asm/arch_hooks.h> 31 #include <asm/arch_hooks.h>
32 32
33 #include <linux/irq.h> 33 #include <linux/irq.h>
34 34
35 /* TLB state -- visible externally, indexed physically */ 35 /* TLB state -- visible externally, indexed physically */
36 DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0 }; 36 DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0 };
37 37
38 /* CPU IRQ affinity -- set to all ones initially */ 38 /* CPU IRQ affinity -- set to all ones initially */
39 static unsigned long cpu_irq_affinity[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1] = ~0UL }; 39 static unsigned long cpu_irq_affinity[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1] = ~0UL };
40 40
41 /* per CPU data structure (for /proc/cpuinfo et al), visible externally 41 /* per CPU data structure (for /proc/cpuinfo et al), visible externally
42 * indexed physically */ 42 * indexed physically */
43 struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; 43 struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;
44 EXPORT_SYMBOL(cpu_data); 44 EXPORT_SYMBOL(cpu_data);
45 45
46 /* physical ID of the CPU used to boot the system */ 46 /* physical ID of the CPU used to boot the system */
47 unsigned char boot_cpu_id; 47 unsigned char boot_cpu_id;
48 48
49 /* The memory line addresses for the Quad CPIs */ 49 /* The memory line addresses for the Quad CPIs */
50 struct voyager_qic_cpi *voyager_quad_cpi_addr[NR_CPUS] __cacheline_aligned; 50 struct voyager_qic_cpi *voyager_quad_cpi_addr[NR_CPUS] __cacheline_aligned;
51 51
52 /* The masks for the Extended VIC processors, filled in by cat_init */ 52 /* The masks for the Extended VIC processors, filled in by cat_init */
53 __u32 voyager_extended_vic_processors = 0; 53 __u32 voyager_extended_vic_processors = 0;
54 54
55 /* Masks for the extended Quad processors which cannot be VIC booted */ 55 /* Masks for the extended Quad processors which cannot be VIC booted */
56 __u32 voyager_allowed_boot_processors = 0; 56 __u32 voyager_allowed_boot_processors = 0;
57 57
58 /* The mask for the Quad Processors (both extended and non-extended) */ 58 /* The mask for the Quad Processors (both extended and non-extended) */
59 __u32 voyager_quad_processors = 0; 59 __u32 voyager_quad_processors = 0;
60 60
61 /* Total count of live CPUs, used in process.c to display 61 /* Total count of live CPUs, used in process.c to display
62 * the CPU information and in irq.c for the per CPU irq 62 * the CPU information and in irq.c for the per CPU irq
63 * activity count. Finally exported by i386_ksyms.c */ 63 * activity count. Finally exported by i386_ksyms.c */
64 static int voyager_extended_cpus = 1; 64 static int voyager_extended_cpus = 1;
65 65
66 /* Have we found an SMP box - used by time.c to do the profiling 66 /* Have we found an SMP box - used by time.c to do the profiling
67 interrupt for timeslicing; do not set to 1 until the per CPU timer 67 interrupt for timeslicing; do not set to 1 until the per CPU timer
68 interrupt is active */ 68 interrupt is active */
69 int smp_found_config = 0; 69 int smp_found_config = 0;
70 70
71 /* Used for the invalidate map that's also checked in the spinlock */ 71 /* Used for the invalidate map that's also checked in the spinlock */
72 static volatile unsigned long smp_invalidate_needed; 72 static volatile unsigned long smp_invalidate_needed;
73 73
74 /* Bitmask of currently online CPUs - used by setup.c for 74 /* Bitmask of currently online CPUs - used by setup.c for
75 /proc/cpuinfo, visible externally but still physical */ 75 /proc/cpuinfo, visible externally but still physical */
76 cpumask_t cpu_online_map = CPU_MASK_NONE; 76 cpumask_t cpu_online_map = CPU_MASK_NONE;
77 EXPORT_SYMBOL(cpu_online_map); 77 EXPORT_SYMBOL(cpu_online_map);
78 78
79 /* Bitmask of CPUs present in the system - exported by i386_syms.c, used 79 /* Bitmask of CPUs present in the system - exported by i386_syms.c, used
80 * by scheduler but indexed physically */ 80 * by scheduler but indexed physically */
81 cpumask_t phys_cpu_present_map = CPU_MASK_NONE; 81 cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
82 82
83 83
84 /* The internal functions */ 84 /* The internal functions */
85 static void send_CPI(__u32 cpuset, __u8 cpi); 85 static void send_CPI(__u32 cpuset, __u8 cpi);
86 static void ack_CPI(__u8 cpi); 86 static void ack_CPI(__u8 cpi);
87 static int ack_QIC_CPI(__u8 cpi); 87 static int ack_QIC_CPI(__u8 cpi);
88 static void ack_special_QIC_CPI(__u8 cpi); 88 static void ack_special_QIC_CPI(__u8 cpi);
89 static void ack_VIC_CPI(__u8 cpi); 89 static void ack_VIC_CPI(__u8 cpi);
90 static void send_CPI_allbutself(__u8 cpi); 90 static void send_CPI_allbutself(__u8 cpi);
91 static void enable_vic_irq(unsigned int irq); 91 static void enable_vic_irq(unsigned int irq);
92 static void disable_vic_irq(unsigned int irq); 92 static void disable_vic_irq(unsigned int irq);
93 static unsigned int startup_vic_irq(unsigned int irq); 93 static unsigned int startup_vic_irq(unsigned int irq);
94 static void enable_local_vic_irq(unsigned int irq); 94 static void enable_local_vic_irq(unsigned int irq);
95 static void disable_local_vic_irq(unsigned int irq); 95 static void disable_local_vic_irq(unsigned int irq);
96 static void before_handle_vic_irq(unsigned int irq); 96 static void before_handle_vic_irq(unsigned int irq);
97 static void after_handle_vic_irq(unsigned int irq); 97 static void after_handle_vic_irq(unsigned int irq);
98 static void set_vic_irq_affinity(unsigned int irq, cpumask_t mask); 98 static void set_vic_irq_affinity(unsigned int irq, cpumask_t mask);
99 static void ack_vic_irq(unsigned int irq); 99 static void ack_vic_irq(unsigned int irq);
100 static void vic_enable_cpi(void); 100 static void vic_enable_cpi(void);
101 static void do_boot_cpu(__u8 cpuid); 101 static void do_boot_cpu(__u8 cpuid);
102 static void do_quad_bootstrap(void); 102 static void do_quad_bootstrap(void);
103 103
104 int hard_smp_processor_id(void); 104 int hard_smp_processor_id(void);
105 105
106 /* Inline functions */ 106 /* Inline functions */
107 static inline void 107 static inline void
108 send_one_QIC_CPI(__u8 cpu, __u8 cpi) 108 send_one_QIC_CPI(__u8 cpu, __u8 cpi)
109 { 109 {
110 voyager_quad_cpi_addr[cpu]->qic_cpi[cpi].cpi = 110 voyager_quad_cpi_addr[cpu]->qic_cpi[cpi].cpi =
111 (smp_processor_id() << 16) + cpi; 111 (smp_processor_id() << 16) + cpi;
112 } 112 }
113 113
114 static inline void 114 static inline void
115 send_QIC_CPI(__u32 cpuset, __u8 cpi) 115 send_QIC_CPI(__u32 cpuset, __u8 cpi)
116 { 116 {
117 int cpu; 117 int cpu;
118 118
119 for_each_online_cpu(cpu) { 119 for_each_online_cpu(cpu) {
120 if(cpuset & (1<<cpu)) { 120 if(cpuset & (1<<cpu)) {
121 #ifdef VOYAGER_DEBUG 121 #ifdef VOYAGER_DEBUG
122 if(!cpu_isset(cpu, cpu_online_map)) 122 if(!cpu_isset(cpu, cpu_online_map))
123 VDEBUG(("CPU%d sending cpi %d to CPU%d not in cpu_online_map\n", hard_smp_processor_id(), cpi, cpu)); 123 VDEBUG(("CPU%d sending cpi %d to CPU%d not in cpu_online_map\n", hard_smp_processor_id(), cpi, cpu));
124 #endif 124 #endif
125 send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET); 125 send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET);
126 } 126 }
127 } 127 }
128 } 128 }
129 129
130 static inline void 130 static inline void
131 wrapper_smp_local_timer_interrupt(struct pt_regs *regs) 131 wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
132 { 132 {
133 irq_enter(); 133 irq_enter();
134 smp_local_timer_interrupt(regs); 134 smp_local_timer_interrupt(regs);
135 irq_exit(); 135 irq_exit();
136 } 136 }
137 137
138 static inline void 138 static inline void
139 send_one_CPI(__u8 cpu, __u8 cpi) 139 send_one_CPI(__u8 cpu, __u8 cpi)
140 { 140 {
141 if(voyager_quad_processors & (1<<cpu)) 141 if(voyager_quad_processors & (1<<cpu))
142 send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET); 142 send_one_QIC_CPI(cpu, cpi - QIC_CPI_OFFSET);
143 else 143 else
144 send_CPI(1<<cpu, cpi); 144 send_CPI(1<<cpu, cpi);
145 } 145 }
146 146
147 static inline void 147 static inline void
148 send_CPI_allbutself(__u8 cpi) 148 send_CPI_allbutself(__u8 cpi)
149 { 149 {
150 __u8 cpu = smp_processor_id(); 150 __u8 cpu = smp_processor_id();
151 __u32 mask = cpus_addr(cpu_online_map)[0] & ~(1 << cpu); 151 __u32 mask = cpus_addr(cpu_online_map)[0] & ~(1 << cpu);
152 send_CPI(mask, cpi); 152 send_CPI(mask, cpi);
153 } 153 }
154 154
155 static inline int 155 static inline int
156 is_cpu_quad(void) 156 is_cpu_quad(void)
157 { 157 {
158 __u8 cpumask = inb(VIC_PROC_WHO_AM_I); 158 __u8 cpumask = inb(VIC_PROC_WHO_AM_I);
159 return ((cpumask & QUAD_IDENTIFIER) == QUAD_IDENTIFIER); 159 return ((cpumask & QUAD_IDENTIFIER) == QUAD_IDENTIFIER);
160 } 160 }
161 161
162 static inline int 162 static inline int
163 is_cpu_extended(void) 163 is_cpu_extended(void)
164 { 164 {
165 __u8 cpu = hard_smp_processor_id(); 165 __u8 cpu = hard_smp_processor_id();
166 166
167 return(voyager_extended_vic_processors & (1<<cpu)); 167 return(voyager_extended_vic_processors & (1<<cpu));
168 } 168 }
169 169
170 static inline int 170 static inline int
171 is_cpu_vic_boot(void) 171 is_cpu_vic_boot(void)
172 { 172 {
173 __u8 cpu = hard_smp_processor_id(); 173 __u8 cpu = hard_smp_processor_id();
174 174
175 return(voyager_extended_vic_processors 175 return(voyager_extended_vic_processors
176 & voyager_allowed_boot_processors & (1<<cpu)); 176 & voyager_allowed_boot_processors & (1<<cpu));
177 } 177 }
178 178
179 179
180 static inline void 180 static inline void
181 ack_CPI(__u8 cpi) 181 ack_CPI(__u8 cpi)
182 { 182 {
183 switch(cpi) { 183 switch(cpi) {
184 case VIC_CPU_BOOT_CPI: 184 case VIC_CPU_BOOT_CPI:
185 if(is_cpu_quad() && !is_cpu_vic_boot()) 185 if(is_cpu_quad() && !is_cpu_vic_boot())
186 ack_QIC_CPI(cpi); 186 ack_QIC_CPI(cpi);
187 else 187 else
188 ack_VIC_CPI(cpi); 188 ack_VIC_CPI(cpi);
189 break; 189 break;
190 case VIC_SYS_INT: 190 case VIC_SYS_INT:
191 case VIC_CMN_INT: 191 case VIC_CMN_INT:
192 /* These are slightly strange. Even on the Quad card, 192 /* These are slightly strange. Even on the Quad card,
193 * They are vectored as VIC CPIs */ 193 * They are vectored as VIC CPIs */
194 if(is_cpu_quad()) 194 if(is_cpu_quad())
195 ack_special_QIC_CPI(cpi); 195 ack_special_QIC_CPI(cpi);
196 else 196 else
197 ack_VIC_CPI(cpi); 197 ack_VIC_CPI(cpi);
198 break; 198 break;
199 default: 199 default:
200 printk("VOYAGER ERROR: CPI%d is in common CPI code\n", cpi); 200 printk("VOYAGER ERROR: CPI%d is in common CPI code\n", cpi);
201 break; 201 break;
202 } 202 }
203 } 203 }
204 204
205 /* local variables */ 205 /* local variables */
206 206
207 /* The VIC IRQ descriptors -- these look almost identical to the 207 /* The VIC IRQ descriptors -- these look almost identical to the
208 * 8259 IRQs except that masks and things must be kept per processor 208 * 8259 IRQs except that masks and things must be kept per processor
209 */ 209 */
210 static struct hw_interrupt_type vic_irq_type = { 210 static struct hw_interrupt_type vic_irq_type = {
211 .typename = "VIC-level", 211 .typename = "VIC-level",
212 .startup = startup_vic_irq, 212 .startup = startup_vic_irq,
213 .shutdown = disable_vic_irq, 213 .shutdown = disable_vic_irq,
214 .enable = enable_vic_irq, 214 .enable = enable_vic_irq,
215 .disable = disable_vic_irq, 215 .disable = disable_vic_irq,
216 .ack = before_handle_vic_irq, 216 .ack = before_handle_vic_irq,
217 .end = after_handle_vic_irq, 217 .end = after_handle_vic_irq,
218 .set_affinity = set_vic_irq_affinity, 218 .set_affinity = set_vic_irq_affinity,
219 }; 219 };
220 220
221 /* used to count up as CPUs are brought on line (starts at 0) */ 221 /* used to count up as CPUs are brought on line (starts at 0) */
222 static int cpucount = 0; 222 static int cpucount = 0;
223 223
224 /* steal a page from the bottom of memory for the trampoline and 224 /* steal a page from the bottom of memory for the trampoline and
225 * squirrel its address away here. This will be in kernel virtual 225 * squirrel its address away here. This will be in kernel virtual
226 * space */ 226 * space */
227 static __u32 trampoline_base; 227 static __u32 trampoline_base;
228 228
229 /* The per cpu profile stuff - used in smp_local_timer_interrupt */ 229 /* The per cpu profile stuff - used in smp_local_timer_interrupt */
230 static DEFINE_PER_CPU(int, prof_multiplier) = 1; 230 static DEFINE_PER_CPU(int, prof_multiplier) = 1;
231 static DEFINE_PER_CPU(int, prof_old_multiplier) = 1; 231 static DEFINE_PER_CPU(int, prof_old_multiplier) = 1;
232 static DEFINE_PER_CPU(int, prof_counter) = 1; 232 static DEFINE_PER_CPU(int, prof_counter) = 1;
233 233
234 /* the map used to check if a CPU has booted */ 234 /* the map used to check if a CPU has booted */
235 static __u32 cpu_booted_map; 235 static __u32 cpu_booted_map;
236 236
237 /* the synchronize flag used to hold all secondary CPUs spinning in 237 /* the synchronize flag used to hold all secondary CPUs spinning in
238 * a tight loop until the boot sequence is ready for them */ 238 * a tight loop until the boot sequence is ready for them */
239 static cpumask_t smp_commenced_mask = CPU_MASK_NONE; 239 static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
240 240
241 /* This is for the new dynamic CPU boot code */ 241 /* This is for the new dynamic CPU boot code */
242 cpumask_t cpu_callin_map = CPU_MASK_NONE; 242 cpumask_t cpu_callin_map = CPU_MASK_NONE;
243 cpumask_t cpu_callout_map = CPU_MASK_NONE; 243 cpumask_t cpu_callout_map = CPU_MASK_NONE;
244 EXPORT_SYMBOL(cpu_callout_map); 244 EXPORT_SYMBOL(cpu_callout_map);
245 245
246 /* The per processor IRQ masks (these are usually kept in sync) */ 246 /* The per processor IRQ masks (these are usually kept in sync) */
247 static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned; 247 static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned;
248 248
249 /* the list of IRQs to be enabled by the VIC_ENABLE_IRQ_CPI */ 249 /* the list of IRQs to be enabled by the VIC_ENABLE_IRQ_CPI */
250 static __u16 vic_irq_enable_mask[NR_CPUS] __cacheline_aligned = { 0 }; 250 static __u16 vic_irq_enable_mask[NR_CPUS] __cacheline_aligned = { 0 };
251 251
252 /* Lock for enable/disable of VIC interrupts */ 252 /* Lock for enable/disable of VIC interrupts */
253 static __cacheline_aligned DEFINE_SPINLOCK(vic_irq_lock); 253 static __cacheline_aligned DEFINE_SPINLOCK(vic_irq_lock);
254 254
255 /* The boot processor is correctly set up in PC mode when it 255 /* The boot processor is correctly set up in PC mode when it
256 * comes up, but the secondaries need their master/slave 8259 256 * comes up, but the secondaries need their master/slave 8259
257 * pairs initializing correctly */ 257 * pairs initializing correctly */
258 258
259 /* Interrupt counters (per cpu) and total - used to try to 259 /* Interrupt counters (per cpu) and total - used to try to
260 * even up the interrupt handling routines */ 260 * even up the interrupt handling routines */
261 static long vic_intr_total = 0; 261 static long vic_intr_total = 0;
262 static long vic_intr_count[NR_CPUS] __cacheline_aligned = { 0 }; 262 static long vic_intr_count[NR_CPUS] __cacheline_aligned = { 0 };
263 static unsigned long vic_tick[NR_CPUS] __cacheline_aligned = { 0 }; 263 static unsigned long vic_tick[NR_CPUS] __cacheline_aligned = { 0 };
264 264
265 /* Since we can only use CPI0, we fake all the other CPIs */ 265 /* Since we can only use CPI0, we fake all the other CPIs */
266 static unsigned long vic_cpi_mailbox[NR_CPUS] __cacheline_aligned; 266 static unsigned long vic_cpi_mailbox[NR_CPUS] __cacheline_aligned;
267 267
268 /* debugging routine to read the isr of the cpu's pic */ 268 /* debugging routine to read the isr of the cpu's pic */
269 static inline __u16 269 static inline __u16
270 vic_read_isr(void) 270 vic_read_isr(void)
271 { 271 {
272 __u16 isr; 272 __u16 isr;
273 273
274 outb(0x0b, 0xa0); 274 outb(0x0b, 0xa0);
275 isr = inb(0xa0) << 8; 275 isr = inb(0xa0) << 8;
276 outb(0x0b, 0x20); 276 outb(0x0b, 0x20);
277 isr |= inb(0x20); 277 isr |= inb(0x20);
278 278
279 return isr; 279 return isr;
280 } 280 }
281 281
282 static __init void 282 static __init void
283 qic_setup(void) 283 qic_setup(void)
284 { 284 {
285 if(!is_cpu_quad()) { 285 if(!is_cpu_quad()) {
286 /* not a quad, no setup */ 286 /* not a quad, no setup */
287 return; 287 return;
288 } 288 }
289 outb(QIC_DEFAULT_MASK0, QIC_MASK_REGISTER0); 289 outb(QIC_DEFAULT_MASK0, QIC_MASK_REGISTER0);
290 outb(QIC_CPI_ENABLE, QIC_MASK_REGISTER1); 290 outb(QIC_CPI_ENABLE, QIC_MASK_REGISTER1);
291 291
292 if(is_cpu_extended()) { 292 if(is_cpu_extended()) {
293 /* the QIC duplicate of the VIC base register */ 293 /* the QIC duplicate of the VIC base register */
294 outb(VIC_DEFAULT_CPI_BASE, QIC_VIC_CPI_BASE_REGISTER); 294 outb(VIC_DEFAULT_CPI_BASE, QIC_VIC_CPI_BASE_REGISTER);
295 outb(QIC_DEFAULT_CPI_BASE, QIC_CPI_BASE_REGISTER); 295 outb(QIC_DEFAULT_CPI_BASE, QIC_CPI_BASE_REGISTER);
296 296
297 /* FIXME: should set up the QIC timer and memory parity 297 /* FIXME: should set up the QIC timer and memory parity
298 * error vectors here */ 298 * error vectors here */
299 } 299 }
300 } 300 }
301 301
302 static __init void 302 static __init void
303 vic_setup_pic(void) 303 vic_setup_pic(void)
304 { 304 {
305 outb(1, VIC_REDIRECT_REGISTER_1); 305 outb(1, VIC_REDIRECT_REGISTER_1);
306 /* clear the claim registers for dynamic routing */ 306 /* clear the claim registers for dynamic routing */
307 outb(0, VIC_CLAIM_REGISTER_0); 307 outb(0, VIC_CLAIM_REGISTER_0);
308 outb(0, VIC_CLAIM_REGISTER_1); 308 outb(0, VIC_CLAIM_REGISTER_1);
309 309
310 outb(0, VIC_PRIORITY_REGISTER); 310 outb(0, VIC_PRIORITY_REGISTER);
311 /* Set the Primary and Secondary Microchannel vector 311 /* Set the Primary and Secondary Microchannel vector
312 * bases to be the same as the ordinary interrupts 312 * bases to be the same as the ordinary interrupts
313 * 313 *
314 * FIXME: This would be more efficient using separate 314 * FIXME: This would be more efficient using separate
315 * vectors. */ 315 * vectors. */
316 outb(FIRST_EXTERNAL_VECTOR, VIC_PRIMARY_MC_BASE); 316 outb(FIRST_EXTERNAL_VECTOR, VIC_PRIMARY_MC_BASE);
317 outb(FIRST_EXTERNAL_VECTOR, VIC_SECONDARY_MC_BASE); 317 outb(FIRST_EXTERNAL_VECTOR, VIC_SECONDARY_MC_BASE);
318 /* Now initiallise the master PIC belonging to this CPU by 318 /* Now initiallise the master PIC belonging to this CPU by
319 * sending the four ICWs */ 319 * sending the four ICWs */
320 320
321 /* ICW1: level triggered, ICW4 needed */ 321 /* ICW1: level triggered, ICW4 needed */
322 outb(0x19, 0x20); 322 outb(0x19, 0x20);
323 323
324 /* ICW2: vector base */ 324 /* ICW2: vector base */
325 outb(FIRST_EXTERNAL_VECTOR, 0x21); 325 outb(FIRST_EXTERNAL_VECTOR, 0x21);
326 326
327 /* ICW3: slave at line 2 */ 327 /* ICW3: slave at line 2 */
328 outb(0x04, 0x21); 328 outb(0x04, 0x21);
329 329
330 /* ICW4: 8086 mode */ 330 /* ICW4: 8086 mode */
331 outb(0x01, 0x21); 331 outb(0x01, 0x21);
332 332
333 /* now the same for the slave PIC */ 333 /* now the same for the slave PIC */
334 334
335 /* ICW1: level trigger, ICW4 needed */ 335 /* ICW1: level trigger, ICW4 needed */
336 outb(0x19, 0xA0); 336 outb(0x19, 0xA0);
337 337
338 /* ICW2: slave vector base */ 338 /* ICW2: slave vector base */
339 outb(FIRST_EXTERNAL_VECTOR + 8, 0xA1); 339 outb(FIRST_EXTERNAL_VECTOR + 8, 0xA1);
340 340
341 /* ICW3: slave ID */ 341 /* ICW3: slave ID */
342 outb(0x02, 0xA1); 342 outb(0x02, 0xA1);
343 343
344 /* ICW4: 8086 mode */ 344 /* ICW4: 8086 mode */
345 outb(0x01, 0xA1); 345 outb(0x01, 0xA1);
346 } 346 }
347 347
348 static void 348 static void
349 do_quad_bootstrap(void) 349 do_quad_bootstrap(void)
350 { 350 {
351 if(is_cpu_quad() && is_cpu_vic_boot()) { 351 if(is_cpu_quad() && is_cpu_vic_boot()) {
352 int i; 352 int i;
353 unsigned long flags; 353 unsigned long flags;
354 __u8 cpuid = hard_smp_processor_id(); 354 __u8 cpuid = hard_smp_processor_id();
355 355
356 local_irq_save(flags); 356 local_irq_save(flags);
357 357
358 for(i = 0; i<4; i++) { 358 for(i = 0; i<4; i++) {
359 /* FIXME: this would be >>3 &0x7 on the 32 way */ 359 /* FIXME: this would be >>3 &0x7 on the 32 way */
360 if(((cpuid >> 2) & 0x03) == i) 360 if(((cpuid >> 2) & 0x03) == i)
361 /* don't lower our own mask! */ 361 /* don't lower our own mask! */
362 continue; 362 continue;
363 363
364 /* masquerade as local Quad CPU */ 364 /* masquerade as local Quad CPU */
365 outb(QIC_CPUID_ENABLE | i, QIC_PROCESSOR_ID); 365 outb(QIC_CPUID_ENABLE | i, QIC_PROCESSOR_ID);
366 /* enable the startup CPI */ 366 /* enable the startup CPI */
367 outb(QIC_BOOT_CPI_MASK, QIC_MASK_REGISTER1); 367 outb(QIC_BOOT_CPI_MASK, QIC_MASK_REGISTER1);
368 /* restore cpu id */ 368 /* restore cpu id */
369 outb(0, QIC_PROCESSOR_ID); 369 outb(0, QIC_PROCESSOR_ID);
370 } 370 }
371 local_irq_restore(flags); 371 local_irq_restore(flags);
372 } 372 }
373 } 373 }
374 374
375 375
376 /* Set up all the basic stuff: read the SMP config and make all the 376 /* Set up all the basic stuff: read the SMP config and make all the
377 * SMP information reflect only the boot cpu. All others will be 377 * SMP information reflect only the boot cpu. All others will be
378 * brought on-line later. */ 378 * brought on-line later. */
379 void __init 379 void __init
380 find_smp_config(void) 380 find_smp_config(void)
381 { 381 {
382 int i; 382 int i;
383 383
384 boot_cpu_id = hard_smp_processor_id(); 384 boot_cpu_id = hard_smp_processor_id();
385 385
386 printk("VOYAGER SMP: Boot cpu is %d\n", boot_cpu_id); 386 printk("VOYAGER SMP: Boot cpu is %d\n", boot_cpu_id);
387 387
388 /* initialize the CPU structures (moved from smp_boot_cpus) */ 388 /* initialize the CPU structures (moved from smp_boot_cpus) */
389 for(i=0; i<NR_CPUS; i++) { 389 for(i=0; i<NR_CPUS; i++) {
390 cpu_irq_affinity[i] = ~0; 390 cpu_irq_affinity[i] = ~0;
391 } 391 }
392 cpu_online_map = cpumask_of_cpu(boot_cpu_id); 392 cpu_online_map = cpumask_of_cpu(boot_cpu_id);
393 393
394 /* The boot CPU must be extended */ 394 /* The boot CPU must be extended */
395 voyager_extended_vic_processors = 1<<boot_cpu_id; 395 voyager_extended_vic_processors = 1<<boot_cpu_id;
396 /* initially, all of the first 8 cpu's can boot */ 396 /* initially, all of the first 8 cpu's can boot */
397 voyager_allowed_boot_processors = 0xff; 397 voyager_allowed_boot_processors = 0xff;
398 /* set up everything for just this CPU, we can alter 398 /* set up everything for just this CPU, we can alter
399 * this as we start the other CPUs later */ 399 * this as we start the other CPUs later */
400 /* now get the CPU disposition from the extended CMOS */ 400 /* now get the CPU disposition from the extended CMOS */
401 cpus_addr(phys_cpu_present_map)[0] = voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK); 401 cpus_addr(phys_cpu_present_map)[0] = voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK);
402 cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8; 402 cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 1) << 8;
403 cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16; 403 cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 2) << 16;
404 cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24; 404 cpus_addr(phys_cpu_present_map)[0] |= voyager_extended_cmos_read(VOYAGER_PROCESSOR_PRESENT_MASK + 3) << 24;
405 printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", cpus_addr(phys_cpu_present_map)[0]); 405 printk("VOYAGER SMP: phys_cpu_present_map = 0x%lx\n", cpus_addr(phys_cpu_present_map)[0]);
406 /* Here we set up the VIC to enable SMP */ 406 /* Here we set up the VIC to enable SMP */
407 /* enable the CPIs by writing the base vector to their register */ 407 /* enable the CPIs by writing the base vector to their register */
408 outb(VIC_DEFAULT_CPI_BASE, VIC_CPI_BASE_REGISTER); 408 outb(VIC_DEFAULT_CPI_BASE, VIC_CPI_BASE_REGISTER);
409 outb(1, VIC_REDIRECT_REGISTER_1); 409 outb(1, VIC_REDIRECT_REGISTER_1);
410 /* set the claim registers for static routing --- Boot CPU gets 410 /* set the claim registers for static routing --- Boot CPU gets
411 * all interrupts untill all other CPUs started */ 411 * all interrupts untill all other CPUs started */
412 outb(0xff, VIC_CLAIM_REGISTER_0); 412 outb(0xff, VIC_CLAIM_REGISTER_0);
413 outb(0xff, VIC_CLAIM_REGISTER_1); 413 outb(0xff, VIC_CLAIM_REGISTER_1);
414 /* Set the Primary and Secondary Microchannel vector 414 /* Set the Primary and Secondary Microchannel vector
415 * bases to be the same as the ordinary interrupts 415 * bases to be the same as the ordinary interrupts
416 * 416 *
417 * FIXME: This would be more efficient using separate 417 * FIXME: This would be more efficient using separate
418 * vectors. */ 418 * vectors. */
419 outb(FIRST_EXTERNAL_VECTOR, VIC_PRIMARY_MC_BASE); 419 outb(FIRST_EXTERNAL_VECTOR, VIC_PRIMARY_MC_BASE);
420 outb(FIRST_EXTERNAL_VECTOR, VIC_SECONDARY_MC_BASE); 420 outb(FIRST_EXTERNAL_VECTOR, VIC_SECONDARY_MC_BASE);
421 421
422 /* Finally tell the firmware that we're driving */ 422 /* Finally tell the firmware that we're driving */
423 outb(inb(VOYAGER_SUS_IN_CONTROL_PORT) | VOYAGER_IN_CONTROL_FLAG, 423 outb(inb(VOYAGER_SUS_IN_CONTROL_PORT) | VOYAGER_IN_CONTROL_FLAG,
424 VOYAGER_SUS_IN_CONTROL_PORT); 424 VOYAGER_SUS_IN_CONTROL_PORT);
425 425
426 current_thread_info()->cpu = boot_cpu_id; 426 current_thread_info()->cpu = boot_cpu_id;
427 } 427 }
428 428
429 /* 429 /*
430 * The bootstrap kernel entry code has set these up. Save them 430 * The bootstrap kernel entry code has set these up. Save them
431 * for a given CPU, id is physical */ 431 * for a given CPU, id is physical */
432 void __init 432 void __init
433 smp_store_cpu_info(int id) 433 smp_store_cpu_info(int id)
434 { 434 {
435 struct cpuinfo_x86 *c=&cpu_data[id]; 435 struct cpuinfo_x86 *c=&cpu_data[id];
436 436
437 *c = boot_cpu_data; 437 *c = boot_cpu_data;
438 438
439 identify_cpu(c); 439 identify_cpu(c);
440 } 440 }
441 441
442 /* set up the trampoline and return the physical address of the code */ 442 /* set up the trampoline and return the physical address of the code */
443 static __u32 __init 443 static __u32 __init
444 setup_trampoline(void) 444 setup_trampoline(void)
445 { 445 {
446 /* these two are global symbols in trampoline.S */ 446 /* these two are global symbols in trampoline.S */
447 extern __u8 trampoline_end[]; 447 extern __u8 trampoline_end[];
448 extern __u8 trampoline_data[]; 448 extern __u8 trampoline_data[];
449 449
450 memcpy((__u8 *)trampoline_base, trampoline_data, 450 memcpy((__u8 *)trampoline_base, trampoline_data,
451 trampoline_end - trampoline_data); 451 trampoline_end - trampoline_data);
452 return virt_to_phys((__u8 *)trampoline_base); 452 return virt_to_phys((__u8 *)trampoline_base);
453 } 453 }
454 454
455 /* Routine initially called when a non-boot CPU is brought online */ 455 /* Routine initially called when a non-boot CPU is brought online */
456 static void __init 456 static void __init
457 start_secondary(void *unused) 457 start_secondary(void *unused)
458 { 458 {
459 __u8 cpuid = hard_smp_processor_id(); 459 __u8 cpuid = hard_smp_processor_id();
460 /* external functions not defined in the headers */ 460 /* external functions not defined in the headers */
461 extern void calibrate_delay(void); 461 extern void calibrate_delay(void);
462 462
463 cpu_init(); 463 cpu_init();
464 464
465 /* OK, we're in the routine */ 465 /* OK, we're in the routine */
466 ack_CPI(VIC_CPU_BOOT_CPI); 466 ack_CPI(VIC_CPU_BOOT_CPI);
467 467
468 /* setup the 8259 master slave pair belonging to this CPU --- 468 /* setup the 8259 master slave pair belonging to this CPU ---
469 * we won't actually receive any until the boot CPU 469 * we won't actually receive any until the boot CPU
470 * relinquishes it's static routing mask */ 470 * relinquishes it's static routing mask */
471 vic_setup_pic(); 471 vic_setup_pic();
472 472
473 qic_setup(); 473 qic_setup();
474 474
475 if(is_cpu_quad() && !is_cpu_vic_boot()) { 475 if(is_cpu_quad() && !is_cpu_vic_boot()) {
476 /* clear the boot CPI */ 476 /* clear the boot CPI */
477 __u8 dummy; 477 __u8 dummy;
478 478
479 dummy = voyager_quad_cpi_addr[cpuid]->qic_cpi[VIC_CPU_BOOT_CPI].cpi; 479 dummy = voyager_quad_cpi_addr[cpuid]->qic_cpi[VIC_CPU_BOOT_CPI].cpi;
480 printk("read dummy %d\n", dummy); 480 printk("read dummy %d\n", dummy);
481 } 481 }
482 482
483 /* lower the mask to receive CPIs */ 483 /* lower the mask to receive CPIs */
484 vic_enable_cpi(); 484 vic_enable_cpi();
485 485
486 VDEBUG(("VOYAGER SMP: CPU%d, stack at about %p\n", cpuid, &cpuid)); 486 VDEBUG(("VOYAGER SMP: CPU%d, stack at about %p\n", cpuid, &cpuid));
487 487
488 /* enable interrupts */ 488 /* enable interrupts */
489 local_irq_enable(); 489 local_irq_enable();
490 490
491 /* get our bogomips */ 491 /* get our bogomips */
492 calibrate_delay(); 492 calibrate_delay();
493 493
494 /* save our processor parameters */ 494 /* save our processor parameters */
495 smp_store_cpu_info(cpuid); 495 smp_store_cpu_info(cpuid);
496 496
497 /* if we're a quad, we may need to bootstrap other CPUs */ 497 /* if we're a quad, we may need to bootstrap other CPUs */
498 do_quad_bootstrap(); 498 do_quad_bootstrap();
499 499
500 /* FIXME: this is rather a poor hack to prevent the CPU 500 /* FIXME: this is rather a poor hack to prevent the CPU
501 * activating softirqs while it's supposed to be waiting for 501 * activating softirqs while it's supposed to be waiting for
502 * permission to proceed. Without this, the new per CPU stuff 502 * permission to proceed. Without this, the new per CPU stuff
503 * in the softirqs will fail */ 503 * in the softirqs will fail */
504 local_irq_disable(); 504 local_irq_disable();
505 cpu_set(cpuid, cpu_callin_map); 505 cpu_set(cpuid, cpu_callin_map);
506 506
507 /* signal that we're done */ 507 /* signal that we're done */
508 cpu_booted_map = 1; 508 cpu_booted_map = 1;
509 509
510 while (!cpu_isset(cpuid, smp_commenced_mask)) 510 while (!cpu_isset(cpuid, smp_commenced_mask))
511 rep_nop(); 511 rep_nop();
512 local_irq_enable(); 512 local_irq_enable();
513 513
514 local_flush_tlb(); 514 local_flush_tlb();
515 515
516 cpu_set(cpuid, cpu_online_map); 516 cpu_set(cpuid, cpu_online_map);
517 wmb(); 517 wmb();
518 cpu_idle(); 518 cpu_idle();
519 } 519 }
520 520
521 521
522 /* Routine to kick start the given CPU and wait for it to report ready 522 /* Routine to kick start the given CPU and wait for it to report ready
523 * (or timeout in startup). When this routine returns, the requested 523 * (or timeout in startup). When this routine returns, the requested
524 * CPU is either fully running and configured or known to be dead. 524 * CPU is either fully running and configured or known to be dead.
525 * 525 *
526 * We call this routine sequentially 1 CPU at a time, so no need for 526 * We call this routine sequentially 1 CPU at a time, so no need for
527 * locking */ 527 * locking */
528 528
529 static void __init 529 static void __init
530 do_boot_cpu(__u8 cpu) 530 do_boot_cpu(__u8 cpu)
531 { 531 {
532 struct task_struct *idle; 532 struct task_struct *idle;
533 int timeout; 533 int timeout;
534 unsigned long flags; 534 unsigned long flags;
535 int quad_boot = (1<<cpu) & voyager_quad_processors 535 int quad_boot = (1<<cpu) & voyager_quad_processors
536 & ~( voyager_extended_vic_processors 536 & ~( voyager_extended_vic_processors
537 & voyager_allowed_boot_processors); 537 & voyager_allowed_boot_processors);
538 538
539 /* For the 486, we can't use the 4Mb page table trick, so 539 /* For the 486, we can't use the 4Mb page table trick, so
540 * must map a region of memory */ 540 * must map a region of memory */
541 #ifdef CONFIG_M486 541 #ifdef CONFIG_M486
542 int i; 542 int i;
543 unsigned long *page_table_copies = (unsigned long *) 543 unsigned long *page_table_copies = (unsigned long *)
544 __get_free_page(GFP_KERNEL); 544 __get_free_page(GFP_KERNEL);
545 #endif 545 #endif
546 pgd_t orig_swapper_pg_dir0; 546 pgd_t orig_swapper_pg_dir0;
547 547
548 /* This is an area in head.S which was used to set up the 548 /* This is an area in head.S which was used to set up the
549 * initial kernel stack. We need to alter this to give the 549 * initial kernel stack. We need to alter this to give the
550 * booting CPU a new stack (taken from its idle process) */ 550 * booting CPU a new stack (taken from its idle process) */
551 extern struct { 551 extern struct {
552 __u8 *esp; 552 __u8 *esp;
553 unsigned short ss; 553 unsigned short ss;
554 } stack_start; 554 } stack_start;
555 /* This is the format of the CPI IDT gate (in real mode) which 555 /* This is the format of the CPI IDT gate (in real mode) which
556 * we're hijacking to boot the CPU */ 556 * we're hijacking to boot the CPU */
557 union IDTFormat { 557 union IDTFormat {
558 struct seg { 558 struct seg {
559 __u16 Offset; 559 __u16 Offset;
560 __u16 Segment; 560 __u16 Segment;
561 } idt; 561 } idt;
562 __u32 val; 562 __u32 val;
563 } hijack_source; 563 } hijack_source;
564 564
565 __u32 *hijack_vector; 565 __u32 *hijack_vector;
566 __u32 start_phys_address = setup_trampoline(); 566 __u32 start_phys_address = setup_trampoline();
567 567
568 /* There's a clever trick to this: The linux trampoline is 568 /* There's a clever trick to this: The linux trampoline is
569 * compiled to begin at absolute location zero, so make the 569 * compiled to begin at absolute location zero, so make the
570 * address zero but have the data segment selector compensate 570 * address zero but have the data segment selector compensate
571 * for the actual address */ 571 * for the actual address */
572 hijack_source.idt.Offset = start_phys_address & 0x000F; 572 hijack_source.idt.Offset = start_phys_address & 0x000F;
573 hijack_source.idt.Segment = (start_phys_address >> 4) & 0xFFFF; 573 hijack_source.idt.Segment = (start_phys_address >> 4) & 0xFFFF;
574 574
575 cpucount++; 575 cpucount++;
576 idle = fork_idle(cpu); 576 idle = fork_idle(cpu);
577 if(IS_ERR(idle)) 577 if(IS_ERR(idle))
578 panic("failed fork for CPU%d", cpu); 578 panic("failed fork for CPU%d", cpu);
579 idle->thread.eip = (unsigned long) start_secondary; 579 idle->thread.eip = (unsigned long) start_secondary;
580 /* init_tasks (in sched.c) is indexed logically */ 580 /* init_tasks (in sched.c) is indexed logically */
581 stack_start.esp = (void *) idle->thread.esp; 581 stack_start.esp = (void *) idle->thread.esp;
582 582
583 irq_ctx_init(cpu); 583 irq_ctx_init(cpu);
584 584
585 /* Note: Don't modify initial ss override */ 585 /* Note: Don't modify initial ss override */
586 VDEBUG(("VOYAGER SMP: Booting CPU%d at 0x%lx[%x:%x], stack %p\n", cpu, 586 VDEBUG(("VOYAGER SMP: Booting CPU%d at 0x%lx[%x:%x], stack %p\n", cpu,
587 (unsigned long)hijack_source.val, hijack_source.idt.Segment, 587 (unsigned long)hijack_source.val, hijack_source.idt.Segment,
588 hijack_source.idt.Offset, stack_start.esp)); 588 hijack_source.idt.Offset, stack_start.esp));
589 /* set the original swapper_pg_dir[0] to map 0 to 4Mb transparently 589 /* set the original swapper_pg_dir[0] to map 0 to 4Mb transparently
590 * (so that the booting CPU can find start_32 */ 590 * (so that the booting CPU can find start_32 */
591 orig_swapper_pg_dir0 = swapper_pg_dir[0]; 591 orig_swapper_pg_dir0 = swapper_pg_dir[0];
592 #ifdef CONFIG_M486 592 #ifdef CONFIG_M486
593 if(page_table_copies == NULL) 593 if(page_table_copies == NULL)
594 panic("No free memory for 486 page tables\n"); 594 panic("No free memory for 486 page tables\n");
595 for(i = 0; i < PAGE_SIZE/sizeof(unsigned long); i++) 595 for(i = 0; i < PAGE_SIZE/sizeof(unsigned long); i++)
596 page_table_copies[i] = (i * PAGE_SIZE) 596 page_table_copies[i] = (i * PAGE_SIZE)
597 | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT; 597 | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT;
598 598
599 ((unsigned long *)swapper_pg_dir)[0] = 599 ((unsigned long *)swapper_pg_dir)[0] =
600 ((virt_to_phys(page_table_copies)) & PAGE_MASK) 600 ((virt_to_phys(page_table_copies)) & PAGE_MASK)
601 | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT; 601 | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT;
602 #else 602 #else
603 ((unsigned long *)swapper_pg_dir)[0] = 603 ((unsigned long *)swapper_pg_dir)[0] =
604 (virt_to_phys(pg0) & PAGE_MASK) 604 (virt_to_phys(pg0) & PAGE_MASK)
605 | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT; 605 | _PAGE_RW | _PAGE_USER | _PAGE_PRESENT;
606 #endif 606 #endif
607 607
608 if(quad_boot) { 608 if(quad_boot) {
609 printk("CPU %d: non extended Quad boot\n", cpu); 609 printk("CPU %d: non extended Quad boot\n", cpu);
610 hijack_vector = (__u32 *)phys_to_virt((VIC_CPU_BOOT_CPI + QIC_DEFAULT_CPI_BASE)*4); 610 hijack_vector = (__u32 *)phys_to_virt((VIC_CPU_BOOT_CPI + QIC_DEFAULT_CPI_BASE)*4);
611 *hijack_vector = hijack_source.val; 611 *hijack_vector = hijack_source.val;
612 } else { 612 } else {
613 printk("CPU%d: extended VIC boot\n", cpu); 613 printk("CPU%d: extended VIC boot\n", cpu);
614 hijack_vector = (__u32 *)phys_to_virt((VIC_CPU_BOOT_CPI + VIC_DEFAULT_CPI_BASE)*4); 614 hijack_vector = (__u32 *)phys_to_virt((VIC_CPU_BOOT_CPI + VIC_DEFAULT_CPI_BASE)*4);
615 *hijack_vector = hijack_source.val; 615 *hijack_vector = hijack_source.val;
616 /* VIC errata, may also receive interrupt at this address */ 616 /* VIC errata, may also receive interrupt at this address */
617 hijack_vector = (__u32 *)phys_to_virt((VIC_CPU_BOOT_ERRATA_CPI + VIC_DEFAULT_CPI_BASE)*4); 617 hijack_vector = (__u32 *)phys_to_virt((VIC_CPU_BOOT_ERRATA_CPI + VIC_DEFAULT_CPI_BASE)*4);
618 *hijack_vector = hijack_source.val; 618 *hijack_vector = hijack_source.val;
619 } 619 }
620 /* All non-boot CPUs start with interrupts fully masked. Need 620 /* All non-boot CPUs start with interrupts fully masked. Need
621 * to lower the mask of the CPI we're about to send. We do 621 * to lower the mask of the CPI we're about to send. We do
622 * this in the VIC by masquerading as the processor we're 622 * this in the VIC by masquerading as the processor we're
623 * about to boot and lowering its interrupt mask */ 623 * about to boot and lowering its interrupt mask */
624 local_irq_save(flags); 624 local_irq_save(flags);
625 if(quad_boot) { 625 if(quad_boot) {
626 send_one_QIC_CPI(cpu, VIC_CPU_BOOT_CPI); 626 send_one_QIC_CPI(cpu, VIC_CPU_BOOT_CPI);
627 } else { 627 } else {
628 outb(VIC_CPU_MASQUERADE_ENABLE | cpu, VIC_PROCESSOR_ID); 628 outb(VIC_CPU_MASQUERADE_ENABLE | cpu, VIC_PROCESSOR_ID);
629 /* here we're altering registers belonging to `cpu' */ 629 /* here we're altering registers belonging to `cpu' */
630 630
631 outb(VIC_BOOT_INTERRUPT_MASK, 0x21); 631 outb(VIC_BOOT_INTERRUPT_MASK, 0x21);
632 /* now go back to our original identity */ 632 /* now go back to our original identity */
633 outb(boot_cpu_id, VIC_PROCESSOR_ID); 633 outb(boot_cpu_id, VIC_PROCESSOR_ID);
634 634
635 /* and boot the CPU */ 635 /* and boot the CPU */
636 636
637 send_CPI((1<<cpu), VIC_CPU_BOOT_CPI); 637 send_CPI((1<<cpu), VIC_CPU_BOOT_CPI);
638 } 638 }
639 cpu_booted_map = 0; 639 cpu_booted_map = 0;
640 local_irq_restore(flags); 640 local_irq_restore(flags);
641 641
642 /* now wait for it to become ready (or timeout) */ 642 /* now wait for it to become ready (or timeout) */
643 for(timeout = 0; timeout < 50000; timeout++) { 643 for(timeout = 0; timeout < 50000; timeout++) {
644 if(cpu_booted_map) 644 if(cpu_booted_map)
645 break; 645 break;
646 udelay(100); 646 udelay(100);
647 } 647 }
648 /* reset the page table */ 648 /* reset the page table */
649 swapper_pg_dir[0] = orig_swapper_pg_dir0; 649 swapper_pg_dir[0] = orig_swapper_pg_dir0;
650 local_flush_tlb(); 650 local_flush_tlb();
651 #ifdef CONFIG_M486 651 #ifdef CONFIG_M486
652 free_page((unsigned long)page_table_copies); 652 free_page((unsigned long)page_table_copies);
653 #endif 653 #endif
654 654
655 if (cpu_booted_map) { 655 if (cpu_booted_map) {
656 VDEBUG(("CPU%d: Booted successfully, back in CPU %d\n", 656 VDEBUG(("CPU%d: Booted successfully, back in CPU %d\n",
657 cpu, smp_processor_id())); 657 cpu, smp_processor_id()));
658 658
659 printk("CPU%d: ", cpu); 659 printk("CPU%d: ", cpu);
660 print_cpu_info(&cpu_data[cpu]); 660 print_cpu_info(&cpu_data[cpu]);
661 wmb(); 661 wmb();
662 cpu_set(cpu, cpu_callout_map); 662 cpu_set(cpu, cpu_callout_map);
663 } 663 }
664 else { 664 else {
665 printk("CPU%d FAILED TO BOOT: ", cpu); 665 printk("CPU%d FAILED TO BOOT: ", cpu);
666 if (*((volatile unsigned char *)phys_to_virt(start_phys_address))==0xA5) 666 if (*((volatile unsigned char *)phys_to_virt(start_phys_address))==0xA5)
667 printk("Stuck.\n"); 667 printk("Stuck.\n");
668 else 668 else
669 printk("Not responding.\n"); 669 printk("Not responding.\n");
670 670
671 cpucount--; 671 cpucount--;
672 } 672 }
673 } 673 }
674 674
675 void __init 675 void __init
676 smp_boot_cpus(void) 676 smp_boot_cpus(void)
677 { 677 {
678 int i; 678 int i;
679 679
680 /* CAT BUS initialisation must be done after the memory */ 680 /* CAT BUS initialisation must be done after the memory */
681 /* FIXME: The L4 has a catbus too, it just needs to be 681 /* FIXME: The L4 has a catbus too, it just needs to be
682 * accessed in a totally different way */ 682 * accessed in a totally different way */
683 if(voyager_level == 5) { 683 if(voyager_level == 5) {
684 voyager_cat_init(); 684 voyager_cat_init();
685 685
686 /* now that the cat has probed the Voyager System Bus, sanity 686 /* now that the cat has probed the Voyager System Bus, sanity
687 * check the cpu map */ 687 * check the cpu map */
688 if( ((voyager_quad_processors | voyager_extended_vic_processors) 688 if( ((voyager_quad_processors | voyager_extended_vic_processors)
689 & cpus_addr(phys_cpu_present_map)[0]) != cpus_addr(phys_cpu_present_map)[0]) { 689 & cpus_addr(phys_cpu_present_map)[0]) != cpus_addr(phys_cpu_present_map)[0]) {
690 /* should panic */ 690 /* should panic */
691 printk("\n\n***WARNING*** Sanity check of CPU present map FAILED\n"); 691 printk("\n\n***WARNING*** Sanity check of CPU present map FAILED\n");
692 } 692 }
693 } else if(voyager_level == 4) 693 } else if(voyager_level == 4)
694 voyager_extended_vic_processors = cpus_addr(phys_cpu_present_map)[0]; 694 voyager_extended_vic_processors = cpus_addr(phys_cpu_present_map)[0];
695 695
696 /* this sets up the idle task to run on the current cpu */ 696 /* this sets up the idle task to run on the current cpu */
697 voyager_extended_cpus = 1; 697 voyager_extended_cpus = 1;
698 /* Remove the global_irq_holder setting, it triggers a BUG() on 698 /* Remove the global_irq_holder setting, it triggers a BUG() on
699 * schedule at the moment */ 699 * schedule at the moment */
700 //global_irq_holder = boot_cpu_id; 700 //global_irq_holder = boot_cpu_id;
701 701
702 /* FIXME: Need to do something about this but currently only works 702 /* FIXME: Need to do something about this but currently only works
703 * on CPUs with a tsc which none of mine have. 703 * on CPUs with a tsc which none of mine have.
704 smp_tune_scheduling(); 704 smp_tune_scheduling();
705 */ 705 */
706 smp_store_cpu_info(boot_cpu_id); 706 smp_store_cpu_info(boot_cpu_id);
707 printk("CPU%d: ", boot_cpu_id); 707 printk("CPU%d: ", boot_cpu_id);
708 print_cpu_info(&cpu_data[boot_cpu_id]); 708 print_cpu_info(&cpu_data[boot_cpu_id]);
709 709
710 if(is_cpu_quad()) { 710 if(is_cpu_quad()) {
711 /* booting on a Quad CPU */ 711 /* booting on a Quad CPU */
712 printk("VOYAGER SMP: Boot CPU is Quad\n"); 712 printk("VOYAGER SMP: Boot CPU is Quad\n");
713 qic_setup(); 713 qic_setup();
714 do_quad_bootstrap(); 714 do_quad_bootstrap();
715 } 715 }
716 716
717 /* enable our own CPIs */ 717 /* enable our own CPIs */
718 vic_enable_cpi(); 718 vic_enable_cpi();
719 719
720 cpu_set(boot_cpu_id, cpu_online_map); 720 cpu_set(boot_cpu_id, cpu_online_map);
721 cpu_set(boot_cpu_id, cpu_callout_map); 721 cpu_set(boot_cpu_id, cpu_callout_map);
722 722
723 /* loop over all the extended VIC CPUs and boot them. The 723 /* loop over all the extended VIC CPUs and boot them. The
724 * Quad CPUs must be bootstrapped by their extended VIC cpu */ 724 * Quad CPUs must be bootstrapped by their extended VIC cpu */
725 for(i = 0; i < NR_CPUS; i++) { 725 for(i = 0; i < NR_CPUS; i++) {
726 if(i == boot_cpu_id || !cpu_isset(i, phys_cpu_present_map)) 726 if(i == boot_cpu_id || !cpu_isset(i, phys_cpu_present_map))
727 continue; 727 continue;
728 do_boot_cpu(i); 728 do_boot_cpu(i);
729 /* This udelay seems to be needed for the Quad boots 729 /* This udelay seems to be needed for the Quad boots
730 * don't remove unless you know what you're doing */ 730 * don't remove unless you know what you're doing */
731 udelay(1000); 731 udelay(1000);
732 } 732 }
733 /* we could compute the total bogomips here, but why bother?, 733 /* we could compute the total bogomips here, but why bother?,
734 * Code added from smpboot.c */ 734 * Code added from smpboot.c */
735 { 735 {
736 unsigned long bogosum = 0; 736 unsigned long bogosum = 0;
737 for (i = 0; i < NR_CPUS; i++) 737 for (i = 0; i < NR_CPUS; i++)
738 if (cpu_isset(i, cpu_online_map)) 738 if (cpu_isset(i, cpu_online_map))
739 bogosum += cpu_data[i].loops_per_jiffy; 739 bogosum += cpu_data[i].loops_per_jiffy;
740 printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n", 740 printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
741 cpucount+1, 741 cpucount+1,
742 bogosum/(500000/HZ), 742 bogosum/(500000/HZ),
743 (bogosum/(5000/HZ))%100); 743 (bogosum/(5000/HZ))%100);
744 } 744 }
745 voyager_extended_cpus = hweight32(voyager_extended_vic_processors); 745 voyager_extended_cpus = hweight32(voyager_extended_vic_processors);
746 printk("VOYAGER: Extended (interrupt handling CPUs): %d, non-extended: %d\n", voyager_extended_cpus, num_booting_cpus() - voyager_extended_cpus); 746 printk("VOYAGER: Extended (interrupt handling CPUs): %d, non-extended: %d\n", voyager_extended_cpus, num_booting_cpus() - voyager_extended_cpus);
747 /* that's it, switch to symmetric mode */ 747 /* that's it, switch to symmetric mode */
748 outb(0, VIC_PRIORITY_REGISTER); 748 outb(0, VIC_PRIORITY_REGISTER);
749 outb(0, VIC_CLAIM_REGISTER_0); 749 outb(0, VIC_CLAIM_REGISTER_0);
750 outb(0, VIC_CLAIM_REGISTER_1); 750 outb(0, VIC_CLAIM_REGISTER_1);
751 751
752 VDEBUG(("VOYAGER SMP: Booted with %d CPUs\n", num_booting_cpus())); 752 VDEBUG(("VOYAGER SMP: Booted with %d CPUs\n", num_booting_cpus()));
753 } 753 }
754 754
755 /* Reload the secondary CPUs task structure (this function does not 755 /* Reload the secondary CPUs task structure (this function does not
756 * return ) */ 756 * return ) */
757 void __init 757 void __init
758 initialize_secondary(void) 758 initialize_secondary(void)
759 { 759 {
760 #if 0 760 #if 0
761 // AC kernels only 761 // AC kernels only
762 set_current(hard_get_current()); 762 set_current(hard_get_current());
763 #endif 763 #endif
764 764
765 /* 765 /*
766 * We don't actually need to load the full TSS, 766 * We don't actually need to load the full TSS,
767 * basically just the stack pointer and the eip. 767 * basically just the stack pointer and the eip.
768 */ 768 */
769 769
770 asm volatile( 770 asm volatile(
771 "movl %0,%%esp\n\t" 771 "movl %0,%%esp\n\t"
772 "jmp *%1" 772 "jmp *%1"
773 : 773 :
774 :"r" (current->thread.esp),"r" (current->thread.eip)); 774 :"r" (current->thread.esp),"r" (current->thread.eip));
775 } 775 }
776 776
777 /* handle a Voyager SYS_INT -- If we don't, the base board will 777 /* handle a Voyager SYS_INT -- If we don't, the base board will
778 * panic the system. 778 * panic the system.
779 * 779 *
780 * System interrupts occur because some problem was detected on the 780 * System interrupts occur because some problem was detected on the
781 * various busses. To find out what you have to probe all the 781 * various busses. To find out what you have to probe all the
782 * hardware via the CAT bus. FIXME: At the moment we do nothing. */ 782 * hardware via the CAT bus. FIXME: At the moment we do nothing. */
783 fastcall void 783 fastcall void
784 smp_vic_sys_interrupt(struct pt_regs *regs) 784 smp_vic_sys_interrupt(struct pt_regs *regs)
785 { 785 {
786 ack_CPI(VIC_SYS_INT); 786 ack_CPI(VIC_SYS_INT);
787 printk("Voyager SYSTEM INTERRUPT\n"); 787 printk("Voyager SYSTEM INTERRUPT\n");
788 } 788 }
789 789
790 /* Handle a voyager CMN_INT; These interrupts occur either because of 790 /* Handle a voyager CMN_INT; These interrupts occur either because of
791 * a system status change or because a single bit memory error 791 * a system status change or because a single bit memory error
792 * occurred. FIXME: At the moment, ignore all this. */ 792 * occurred. FIXME: At the moment, ignore all this. */
793 fastcall void 793 fastcall void
794 smp_vic_cmn_interrupt(struct pt_regs *regs) 794 smp_vic_cmn_interrupt(struct pt_regs *regs)
795 { 795 {
796 static __u8 in_cmn_int = 0; 796 static __u8 in_cmn_int = 0;
797 static DEFINE_SPINLOCK(cmn_int_lock); 797 static DEFINE_SPINLOCK(cmn_int_lock);
798 798
799 /* common ints are broadcast, so make sure we only do this once */ 799 /* common ints are broadcast, so make sure we only do this once */
800 _raw_spin_lock(&cmn_int_lock); 800 _raw_spin_lock(&cmn_int_lock);
801 if(in_cmn_int) 801 if(in_cmn_int)
802 goto unlock_end; 802 goto unlock_end;
803 803
804 in_cmn_int++; 804 in_cmn_int++;
805 _raw_spin_unlock(&cmn_int_lock); 805 _raw_spin_unlock(&cmn_int_lock);
806 806
807 VDEBUG(("Voyager COMMON INTERRUPT\n")); 807 VDEBUG(("Voyager COMMON INTERRUPT\n"));
808 808
809 if(voyager_level == 5) 809 if(voyager_level == 5)
810 voyager_cat_do_common_interrupt(); 810 voyager_cat_do_common_interrupt();
811 811
812 _raw_spin_lock(&cmn_int_lock); 812 _raw_spin_lock(&cmn_int_lock);
813 in_cmn_int = 0; 813 in_cmn_int = 0;
814 unlock_end: 814 unlock_end:
815 _raw_spin_unlock(&cmn_int_lock); 815 _raw_spin_unlock(&cmn_int_lock);
816 ack_CPI(VIC_CMN_INT); 816 ack_CPI(VIC_CMN_INT);
817 } 817 }
818 818
819 /* 819 /*
820 * Reschedule call back. Nothing to do, all the work is done 820 * Reschedule call back. Nothing to do, all the work is done
821 * automatically when we return from the interrupt. */ 821 * automatically when we return from the interrupt. */
822 static void 822 static void
823 smp_reschedule_interrupt(void) 823 smp_reschedule_interrupt(void)
824 { 824 {
825 /* do nothing */ 825 /* do nothing */
826 } 826 }
827 827
828 static struct mm_struct * flush_mm; 828 static struct mm_struct * flush_mm;
829 static unsigned long flush_va; 829 static unsigned long flush_va;
830 static DEFINE_SPINLOCK(tlbstate_lock); 830 static DEFINE_SPINLOCK(tlbstate_lock);
831 #define FLUSH_ALL 0xffffffff 831 #define FLUSH_ALL 0xffffffff
832 832
833 /* 833 /*
834 * We cannot call mmdrop() because we are in interrupt context, 834 * We cannot call mmdrop() because we are in interrupt context,
835 * instead update mm->cpu_vm_mask. 835 * instead update mm->cpu_vm_mask.
836 * 836 *
837 * We need to reload %cr3 since the page tables may be going 837 * We need to reload %cr3 since the page tables may be going
838 * away from under us.. 838 * away from under us..
839 */ 839 */
840 static inline void 840 static inline void
841 leave_mm (unsigned long cpu) 841 leave_mm (unsigned long cpu)
842 { 842 {
843 if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) 843 if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK)
844 BUG(); 844 BUG();
845 cpu_clear(cpu, per_cpu(cpu_tlbstate, cpu).active_mm->cpu_vm_mask); 845 cpu_clear(cpu, per_cpu(cpu_tlbstate, cpu).active_mm->cpu_vm_mask);
846 load_cr3(swapper_pg_dir); 846 load_cr3(swapper_pg_dir);
847 } 847 }
848 848
849 849
850 /* 850 /*
851 * Invalidate call-back 851 * Invalidate call-back
852 */ 852 */
853 static void 853 static void
854 smp_invalidate_interrupt(void) 854 smp_invalidate_interrupt(void)
855 { 855 {
856 __u8 cpu = smp_processor_id(); 856 __u8 cpu = smp_processor_id();
857 857
858 if (!test_bit(cpu, &smp_invalidate_needed)) 858 if (!test_bit(cpu, &smp_invalidate_needed))
859 return; 859 return;
860 /* This will flood messages. Don't uncomment unless you see 860 /* This will flood messages. Don't uncomment unless you see
861 * Problems with cross cpu invalidation 861 * Problems with cross cpu invalidation
862 VDEBUG(("VOYAGER SMP: CPU%d received INVALIDATE_CPI\n", 862 VDEBUG(("VOYAGER SMP: CPU%d received INVALIDATE_CPI\n",
863 smp_processor_id())); 863 smp_processor_id()));
864 */ 864 */
865 865
866 if (flush_mm == per_cpu(cpu_tlbstate, cpu).active_mm) { 866 if (flush_mm == per_cpu(cpu_tlbstate, cpu).active_mm) {
867 if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) { 867 if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) {
868 if (flush_va == FLUSH_ALL) 868 if (flush_va == FLUSH_ALL)
869 local_flush_tlb(); 869 local_flush_tlb();
870 else 870 else
871 __flush_tlb_one(flush_va); 871 __flush_tlb_one(flush_va);
872 } else 872 } else
873 leave_mm(cpu); 873 leave_mm(cpu);
874 } 874 }
875 smp_mb__before_clear_bit(); 875 smp_mb__before_clear_bit();
876 clear_bit(cpu, &smp_invalidate_needed); 876 clear_bit(cpu, &smp_invalidate_needed);
877 smp_mb__after_clear_bit(); 877 smp_mb__after_clear_bit();
878 } 878 }
879 879
880 /* All the new flush operations for 2.4 */ 880 /* All the new flush operations for 2.4 */
881 881
882 882
883 /* This routine is called with a physical cpu mask */ 883 /* This routine is called with a physical cpu mask */
884 static void 884 static void
885 flush_tlb_others (unsigned long cpumask, struct mm_struct *mm, 885 flush_tlb_others (unsigned long cpumask, struct mm_struct *mm,
886 unsigned long va) 886 unsigned long va)
887 { 887 {
888 int stuck = 50000; 888 int stuck = 50000;
889 889
890 if (!cpumask) 890 if (!cpumask)
891 BUG(); 891 BUG();
892 if ((cpumask & cpus_addr(cpu_online_map)[0]) != cpumask) 892 if ((cpumask & cpus_addr(cpu_online_map)[0]) != cpumask)
893 BUG(); 893 BUG();
894 if (cpumask & (1 << smp_processor_id())) 894 if (cpumask & (1 << smp_processor_id()))
895 BUG(); 895 BUG();
896 if (!mm) 896 if (!mm)
897 BUG(); 897 BUG();
898 898
899 spin_lock(&tlbstate_lock); 899 spin_lock(&tlbstate_lock);
900 900
901 flush_mm = mm; 901 flush_mm = mm;
902 flush_va = va; 902 flush_va = va;
903 atomic_set_mask(cpumask, &smp_invalidate_needed); 903 atomic_set_mask(cpumask, &smp_invalidate_needed);
904 /* 904 /*
905 * We have to send the CPI only to 905 * We have to send the CPI only to
906 * CPUs affected. 906 * CPUs affected.
907 */ 907 */
908 send_CPI(cpumask, VIC_INVALIDATE_CPI); 908 send_CPI(cpumask, VIC_INVALIDATE_CPI);
909 909
910 while (smp_invalidate_needed) { 910 while (smp_invalidate_needed) {
911 mb(); 911 mb();
912 if(--stuck == 0) { 912 if(--stuck == 0) {
913 printk("***WARNING*** Stuck doing invalidate CPI (CPU%d)\n", smp_processor_id()); 913 printk("***WARNING*** Stuck doing invalidate CPI (CPU%d)\n", smp_processor_id());
914 break; 914 break;
915 } 915 }
916 } 916 }
917 917
918 /* Uncomment only to debug invalidation problems 918 /* Uncomment only to debug invalidation problems
919 VDEBUG(("VOYAGER SMP: Completed invalidate CPI (CPU%d)\n", cpu)); 919 VDEBUG(("VOYAGER SMP: Completed invalidate CPI (CPU%d)\n", cpu));
920 */ 920 */
921 921
922 flush_mm = NULL; 922 flush_mm = NULL;
923 flush_va = 0; 923 flush_va = 0;
924 spin_unlock(&tlbstate_lock); 924 spin_unlock(&tlbstate_lock);
925 } 925 }
926 926
927 void 927 void
928 flush_tlb_current_task(void) 928 flush_tlb_current_task(void)
929 { 929 {
930 struct mm_struct *mm = current->mm; 930 struct mm_struct *mm = current->mm;
931 unsigned long cpu_mask; 931 unsigned long cpu_mask;
932 932
933 preempt_disable(); 933 preempt_disable();
934 934
935 cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); 935 cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id());
936 local_flush_tlb(); 936 local_flush_tlb();
937 if (cpu_mask) 937 if (cpu_mask)
938 flush_tlb_others(cpu_mask, mm, FLUSH_ALL); 938 flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
939 939
940 preempt_enable(); 940 preempt_enable();
941 } 941 }
942 942
943 943
944 void 944 void
945 flush_tlb_mm (struct mm_struct * mm) 945 flush_tlb_mm (struct mm_struct * mm)
946 { 946 {
947 unsigned long cpu_mask; 947 unsigned long cpu_mask;
948 948
949 preempt_disable(); 949 preempt_disable();
950 950
951 cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); 951 cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id());
952 952
953 if (current->active_mm == mm) { 953 if (current->active_mm == mm) {
954 if (current->mm) 954 if (current->mm)
955 local_flush_tlb(); 955 local_flush_tlb();
956 else 956 else
957 leave_mm(smp_processor_id()); 957 leave_mm(smp_processor_id());
958 } 958 }
959 if (cpu_mask) 959 if (cpu_mask)
960 flush_tlb_others(cpu_mask, mm, FLUSH_ALL); 960 flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
961 961
962 preempt_enable(); 962 preempt_enable();
963 } 963 }
964 964
965 void flush_tlb_page(struct vm_area_struct * vma, unsigned long va) 965 void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
966 { 966 {
967 struct mm_struct *mm = vma->vm_mm; 967 struct mm_struct *mm = vma->vm_mm;
968 unsigned long cpu_mask; 968 unsigned long cpu_mask;
969 969
970 preempt_disable(); 970 preempt_disable();
971 971
972 cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id()); 972 cpu_mask = cpus_addr(mm->cpu_vm_mask)[0] & ~(1 << smp_processor_id());
973 if (current->active_mm == mm) { 973 if (current->active_mm == mm) {
974 if(current->mm) 974 if(current->mm)
975 __flush_tlb_one(va); 975 __flush_tlb_one(va);
976 else 976 else
977 leave_mm(smp_processor_id()); 977 leave_mm(smp_processor_id());
978 } 978 }
979 979
980 if (cpu_mask) 980 if (cpu_mask)
981 flush_tlb_others(cpu_mask, mm, va); 981 flush_tlb_others(cpu_mask, mm, va);
982 982
983 preempt_enable(); 983 preempt_enable();
984 } 984 }
985 EXPORT_SYMBOL(flush_tlb_page); 985 EXPORT_SYMBOL(flush_tlb_page);
986 986
987 /* enable the requested IRQs */ 987 /* enable the requested IRQs */
988 static void 988 static void
989 smp_enable_irq_interrupt(void) 989 smp_enable_irq_interrupt(void)
990 { 990 {
991 __u8 irq; 991 __u8 irq;
992 __u8 cpu = get_cpu(); 992 __u8 cpu = get_cpu();
993 993
994 VDEBUG(("VOYAGER SMP: CPU%d enabling irq mask 0x%x\n", cpu, 994 VDEBUG(("VOYAGER SMP: CPU%d enabling irq mask 0x%x\n", cpu,
995 vic_irq_enable_mask[cpu])); 995 vic_irq_enable_mask[cpu]));
996 996
997 spin_lock(&vic_irq_lock); 997 spin_lock(&vic_irq_lock);
998 for(irq = 0; irq < 16; irq++) { 998 for(irq = 0; irq < 16; irq++) {
999 if(vic_irq_enable_mask[cpu] & (1<<irq)) 999 if(vic_irq_enable_mask[cpu] & (1<<irq))
1000 enable_local_vic_irq(irq); 1000 enable_local_vic_irq(irq);
1001 } 1001 }
1002 vic_irq_enable_mask[cpu] = 0; 1002 vic_irq_enable_mask[cpu] = 0;
1003 spin_unlock(&vic_irq_lock); 1003 spin_unlock(&vic_irq_lock);
1004 1004
1005 put_cpu_no_resched(); 1005 put_cpu_no_resched();
1006 } 1006 }
1007 1007
1008 /* 1008 /*
1009 * CPU halt call-back 1009 * CPU halt call-back
1010 */ 1010 */
1011 static void 1011 static void
1012 smp_stop_cpu_function(void *dummy) 1012 smp_stop_cpu_function(void *dummy)
1013 { 1013 {
1014 VDEBUG(("VOYAGER SMP: CPU%d is STOPPING\n", smp_processor_id())); 1014 VDEBUG(("VOYAGER SMP: CPU%d is STOPPING\n", smp_processor_id()));
1015 cpu_clear(smp_processor_id(), cpu_online_map); 1015 cpu_clear(smp_processor_id(), cpu_online_map);
1016 local_irq_disable(); 1016 local_irq_disable();
1017 for(;;) 1017 for(;;)
1018 __asm__("hlt"); 1018 halt();
1019 } 1019 }
1020 1020
1021 static DEFINE_SPINLOCK(call_lock); 1021 static DEFINE_SPINLOCK(call_lock);
1022 1022
1023 struct call_data_struct { 1023 struct call_data_struct {
1024 void (*func) (void *info); 1024 void (*func) (void *info);
1025 void *info; 1025 void *info;
1026 volatile unsigned long started; 1026 volatile unsigned long started;
1027 volatile unsigned long finished; 1027 volatile unsigned long finished;
1028 int wait; 1028 int wait;
1029 }; 1029 };
1030 1030
1031 static struct call_data_struct * call_data; 1031 static struct call_data_struct * call_data;
1032 1032
1033 /* execute a thread on a new CPU. The function to be called must be 1033 /* execute a thread on a new CPU. The function to be called must be
1034 * previously set up. This is used to schedule a function for 1034 * previously set up. This is used to schedule a function for
1035 * execution on all CPU's - set up the function then broadcast a 1035 * execution on all CPU's - set up the function then broadcast a
1036 * function_interrupt CPI to come here on each CPU */ 1036 * function_interrupt CPI to come here on each CPU */
1037 static void 1037 static void
1038 smp_call_function_interrupt(void) 1038 smp_call_function_interrupt(void)
1039 { 1039 {
1040 void (*func) (void *info) = call_data->func; 1040 void (*func) (void *info) = call_data->func;
1041 void *info = call_data->info; 1041 void *info = call_data->info;
1042 /* must take copy of wait because call_data may be replaced 1042 /* must take copy of wait because call_data may be replaced
1043 * unless the function is waiting for us to finish */ 1043 * unless the function is waiting for us to finish */
1044 int wait = call_data->wait; 1044 int wait = call_data->wait;
1045 __u8 cpu = smp_processor_id(); 1045 __u8 cpu = smp_processor_id();
1046 1046
1047 /* 1047 /*
1048 * Notify initiating CPU that I've grabbed the data and am 1048 * Notify initiating CPU that I've grabbed the data and am
1049 * about to execute the function 1049 * about to execute the function
1050 */ 1050 */
1051 mb(); 1051 mb();
1052 if(!test_and_clear_bit(cpu, &call_data->started)) { 1052 if(!test_and_clear_bit(cpu, &call_data->started)) {
1053 /* If the bit wasn't set, this could be a replay */ 1053 /* If the bit wasn't set, this could be a replay */
1054 printk(KERN_WARNING "VOYAGER SMP: CPU %d received call funtion with no call pending\n", cpu); 1054 printk(KERN_WARNING "VOYAGER SMP: CPU %d received call funtion with no call pending\n", cpu);
1055 return; 1055 return;
1056 } 1056 }
1057 /* 1057 /*
1058 * At this point the info structure may be out of scope unless wait==1 1058 * At this point the info structure may be out of scope unless wait==1
1059 */ 1059 */
1060 irq_enter(); 1060 irq_enter();
1061 (*func)(info); 1061 (*func)(info);
1062 irq_exit(); 1062 irq_exit();
1063 if (wait) { 1063 if (wait) {
1064 mb(); 1064 mb();
1065 clear_bit(cpu, &call_data->finished); 1065 clear_bit(cpu, &call_data->finished);
1066 } 1066 }
1067 } 1067 }
1068 1068
1069 /* Call this function on all CPUs using the function_interrupt above 1069 /* Call this function on all CPUs using the function_interrupt above
1070 <func> The function to run. This must be fast and non-blocking. 1070 <func> The function to run. This must be fast and non-blocking.
1071 <info> An arbitrary pointer to pass to the function. 1071 <info> An arbitrary pointer to pass to the function.
1072 <retry> If true, keep retrying until ready. 1072 <retry> If true, keep retrying until ready.
1073 <wait> If true, wait until function has completed on other CPUs. 1073 <wait> If true, wait until function has completed on other CPUs.
1074 [RETURNS] 0 on success, else a negative status code. Does not return until 1074 [RETURNS] 0 on success, else a negative status code. Does not return until
1075 remote CPUs are nearly ready to execute <<func>> or are or have executed. 1075 remote CPUs are nearly ready to execute <<func>> or are or have executed.
1076 */ 1076 */
1077 int 1077 int
1078 smp_call_function (void (*func) (void *info), void *info, int retry, 1078 smp_call_function (void (*func) (void *info), void *info, int retry,
1079 int wait) 1079 int wait)
1080 { 1080 {
1081 struct call_data_struct data; 1081 struct call_data_struct data;
1082 __u32 mask = cpus_addr(cpu_online_map)[0]; 1082 __u32 mask = cpus_addr(cpu_online_map)[0];
1083 1083
1084 mask &= ~(1<<smp_processor_id()); 1084 mask &= ~(1<<smp_processor_id());
1085 1085
1086 if (!mask) 1086 if (!mask)
1087 return 0; 1087 return 0;
1088 1088
1089 /* Can deadlock when called with interrupts disabled */ 1089 /* Can deadlock when called with interrupts disabled */
1090 WARN_ON(irqs_disabled()); 1090 WARN_ON(irqs_disabled());
1091 1091
1092 data.func = func; 1092 data.func = func;
1093 data.info = info; 1093 data.info = info;
1094 data.started = mask; 1094 data.started = mask;
1095 data.wait = wait; 1095 data.wait = wait;
1096 if (wait) 1096 if (wait)
1097 data.finished = mask; 1097 data.finished = mask;
1098 1098
1099 spin_lock(&call_lock); 1099 spin_lock(&call_lock);
1100 call_data = &data; 1100 call_data = &data;
1101 wmb(); 1101 wmb();
1102 /* Send a message to all other CPUs and wait for them to respond */ 1102 /* Send a message to all other CPUs and wait for them to respond */
1103 send_CPI_allbutself(VIC_CALL_FUNCTION_CPI); 1103 send_CPI_allbutself(VIC_CALL_FUNCTION_CPI);
1104 1104
1105 /* Wait for response */ 1105 /* Wait for response */
1106 while (data.started) 1106 while (data.started)
1107 barrier(); 1107 barrier();
1108 1108
1109 if (wait) 1109 if (wait)
1110 while (data.finished) 1110 while (data.finished)
1111 barrier(); 1111 barrier();
1112 1112
1113 spin_unlock(&call_lock); 1113 spin_unlock(&call_lock);
1114 1114
1115 return 0; 1115 return 0;
1116 } 1116 }
1117 EXPORT_SYMBOL(smp_call_function); 1117 EXPORT_SYMBOL(smp_call_function);
1118 1118
1119 /* Sorry about the name. In an APIC based system, the APICs 1119 /* Sorry about the name. In an APIC based system, the APICs
1120 * themselves are programmed to send a timer interrupt. This is used 1120 * themselves are programmed to send a timer interrupt. This is used
1121 * by linux to reschedule the processor. Voyager doesn't have this, 1121 * by linux to reschedule the processor. Voyager doesn't have this,
1122 * so we use the system clock to interrupt one processor, which in 1122 * so we use the system clock to interrupt one processor, which in
1123 * turn, broadcasts a timer CPI to all the others --- we receive that 1123 * turn, broadcasts a timer CPI to all the others --- we receive that
1124 * CPI here. We don't use this actually for counting so losing 1124 * CPI here. We don't use this actually for counting so losing
1125 * ticks doesn't matter 1125 * ticks doesn't matter
1126 * 1126 *
1127 * FIXME: For those CPU's which actually have a local APIC, we could 1127 * FIXME: For those CPU's which actually have a local APIC, we could
1128 * try to use it to trigger this interrupt instead of having to 1128 * try to use it to trigger this interrupt instead of having to
1129 * broadcast the timer tick. Unfortunately, all my pentium DYADs have 1129 * broadcast the timer tick. Unfortunately, all my pentium DYADs have
1130 * no local APIC, so I can't do this 1130 * no local APIC, so I can't do this
1131 * 1131 *
1132 * This function is currently a placeholder and is unused in the code */ 1132 * This function is currently a placeholder and is unused in the code */
1133 fastcall void 1133 fastcall void
1134 smp_apic_timer_interrupt(struct pt_regs *regs) 1134 smp_apic_timer_interrupt(struct pt_regs *regs)
1135 { 1135 {
1136 wrapper_smp_local_timer_interrupt(regs); 1136 wrapper_smp_local_timer_interrupt(regs);
1137 } 1137 }
1138 1138
1139 /* All of the QUAD interrupt GATES */ 1139 /* All of the QUAD interrupt GATES */
1140 fastcall void 1140 fastcall void
1141 smp_qic_timer_interrupt(struct pt_regs *regs) 1141 smp_qic_timer_interrupt(struct pt_regs *regs)
1142 { 1142 {
1143 ack_QIC_CPI(QIC_TIMER_CPI); 1143 ack_QIC_CPI(QIC_TIMER_CPI);
1144 wrapper_smp_local_timer_interrupt(regs); 1144 wrapper_smp_local_timer_interrupt(regs);
1145 } 1145 }
1146 1146
1147 fastcall void 1147 fastcall void
1148 smp_qic_invalidate_interrupt(struct pt_regs *regs) 1148 smp_qic_invalidate_interrupt(struct pt_regs *regs)
1149 { 1149 {
1150 ack_QIC_CPI(QIC_INVALIDATE_CPI); 1150 ack_QIC_CPI(QIC_INVALIDATE_CPI);
1151 smp_invalidate_interrupt(); 1151 smp_invalidate_interrupt();
1152 } 1152 }
1153 1153
1154 fastcall void 1154 fastcall void
1155 smp_qic_reschedule_interrupt(struct pt_regs *regs) 1155 smp_qic_reschedule_interrupt(struct pt_regs *regs)
1156 { 1156 {
1157 ack_QIC_CPI(QIC_RESCHEDULE_CPI); 1157 ack_QIC_CPI(QIC_RESCHEDULE_CPI);
1158 smp_reschedule_interrupt(); 1158 smp_reschedule_interrupt();
1159 } 1159 }
1160 1160
1161 fastcall void 1161 fastcall void
1162 smp_qic_enable_irq_interrupt(struct pt_regs *regs) 1162 smp_qic_enable_irq_interrupt(struct pt_regs *regs)
1163 { 1163 {
1164 ack_QIC_CPI(QIC_ENABLE_IRQ_CPI); 1164 ack_QIC_CPI(QIC_ENABLE_IRQ_CPI);
1165 smp_enable_irq_interrupt(); 1165 smp_enable_irq_interrupt();
1166 } 1166 }
1167 1167
1168 fastcall void 1168 fastcall void
1169 smp_qic_call_function_interrupt(struct pt_regs *regs) 1169 smp_qic_call_function_interrupt(struct pt_regs *regs)
1170 { 1170 {
1171 ack_QIC_CPI(QIC_CALL_FUNCTION_CPI); 1171 ack_QIC_CPI(QIC_CALL_FUNCTION_CPI);
1172 smp_call_function_interrupt(); 1172 smp_call_function_interrupt();
1173 } 1173 }
1174 1174
1175 fastcall void 1175 fastcall void
1176 smp_vic_cpi_interrupt(struct pt_regs *regs) 1176 smp_vic_cpi_interrupt(struct pt_regs *regs)
1177 { 1177 {
1178 __u8 cpu = smp_processor_id(); 1178 __u8 cpu = smp_processor_id();
1179 1179
1180 if(is_cpu_quad()) 1180 if(is_cpu_quad())
1181 ack_QIC_CPI(VIC_CPI_LEVEL0); 1181 ack_QIC_CPI(VIC_CPI_LEVEL0);
1182 else 1182 else
1183 ack_VIC_CPI(VIC_CPI_LEVEL0); 1183 ack_VIC_CPI(VIC_CPI_LEVEL0);
1184 1184
1185 if(test_and_clear_bit(VIC_TIMER_CPI, &vic_cpi_mailbox[cpu])) 1185 if(test_and_clear_bit(VIC_TIMER_CPI, &vic_cpi_mailbox[cpu]))
1186 wrapper_smp_local_timer_interrupt(regs); 1186 wrapper_smp_local_timer_interrupt(regs);
1187 if(test_and_clear_bit(VIC_INVALIDATE_CPI, &vic_cpi_mailbox[cpu])) 1187 if(test_and_clear_bit(VIC_INVALIDATE_CPI, &vic_cpi_mailbox[cpu]))
1188 smp_invalidate_interrupt(); 1188 smp_invalidate_interrupt();
1189 if(test_and_clear_bit(VIC_RESCHEDULE_CPI, &vic_cpi_mailbox[cpu])) 1189 if(test_and_clear_bit(VIC_RESCHEDULE_CPI, &vic_cpi_mailbox[cpu]))
1190 smp_reschedule_interrupt(); 1190 smp_reschedule_interrupt();
1191 if(test_and_clear_bit(VIC_ENABLE_IRQ_CPI, &vic_cpi_mailbox[cpu])) 1191 if(test_and_clear_bit(VIC_ENABLE_IRQ_CPI, &vic_cpi_mailbox[cpu]))
1192 smp_enable_irq_interrupt(); 1192 smp_enable_irq_interrupt();
1193 if(test_and_clear_bit(VIC_CALL_FUNCTION_CPI, &vic_cpi_mailbox[cpu])) 1193 if(test_and_clear_bit(VIC_CALL_FUNCTION_CPI, &vic_cpi_mailbox[cpu]))
1194 smp_call_function_interrupt(); 1194 smp_call_function_interrupt();
1195 } 1195 }
1196 1196
1197 static void 1197 static void
1198 do_flush_tlb_all(void* info) 1198 do_flush_tlb_all(void* info)
1199 { 1199 {
1200 unsigned long cpu = smp_processor_id(); 1200 unsigned long cpu = smp_processor_id();
1201 1201
1202 __flush_tlb_all(); 1202 __flush_tlb_all();
1203 if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_LAZY) 1203 if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_LAZY)
1204 leave_mm(cpu); 1204 leave_mm(cpu);
1205 } 1205 }
1206 1206
1207 1207
1208 /* flush the TLB of every active CPU in the system */ 1208 /* flush the TLB of every active CPU in the system */
1209 void 1209 void
1210 flush_tlb_all(void) 1210 flush_tlb_all(void)
1211 { 1211 {
1212 on_each_cpu(do_flush_tlb_all, 0, 1, 1); 1212 on_each_cpu(do_flush_tlb_all, 0, 1, 1);
1213 } 1213 }
1214 1214
1215 /* used to set up the trampoline for other CPUs when the memory manager 1215 /* used to set up the trampoline for other CPUs when the memory manager
1216 * is sorted out */ 1216 * is sorted out */
1217 void __init 1217 void __init
1218 smp_alloc_memory(void) 1218 smp_alloc_memory(void)
1219 { 1219 {
1220 trampoline_base = (__u32)alloc_bootmem_low_pages(PAGE_SIZE); 1220 trampoline_base = (__u32)alloc_bootmem_low_pages(PAGE_SIZE);
1221 if(__pa(trampoline_base) >= 0x93000) 1221 if(__pa(trampoline_base) >= 0x93000)
1222 BUG(); 1222 BUG();
1223 } 1223 }
1224 1224
1225 /* send a reschedule CPI to one CPU by physical CPU number*/ 1225 /* send a reschedule CPI to one CPU by physical CPU number*/
1226 void 1226 void
1227 smp_send_reschedule(int cpu) 1227 smp_send_reschedule(int cpu)
1228 { 1228 {
1229 send_one_CPI(cpu, VIC_RESCHEDULE_CPI); 1229 send_one_CPI(cpu, VIC_RESCHEDULE_CPI);
1230 } 1230 }
1231 1231
1232 1232
1233 int 1233 int
1234 hard_smp_processor_id(void) 1234 hard_smp_processor_id(void)
1235 { 1235 {
1236 __u8 i; 1236 __u8 i;
1237 __u8 cpumask = inb(VIC_PROC_WHO_AM_I); 1237 __u8 cpumask = inb(VIC_PROC_WHO_AM_I);
1238 if((cpumask & QUAD_IDENTIFIER) == QUAD_IDENTIFIER) 1238 if((cpumask & QUAD_IDENTIFIER) == QUAD_IDENTIFIER)
1239 return cpumask & 0x1F; 1239 return cpumask & 0x1F;
1240 1240
1241 for(i = 0; i < 8; i++) { 1241 for(i = 0; i < 8; i++) {
1242 if(cpumask & (1<<i)) 1242 if(cpumask & (1<<i))
1243 return i; 1243 return i;
1244 } 1244 }
1245 printk("** WARNING ** Illegal cpuid returned by VIC: %d", cpumask); 1245 printk("** WARNING ** Illegal cpuid returned by VIC: %d", cpumask);
1246 return 0; 1246 return 0;
1247 } 1247 }
1248 1248
1249 /* broadcast a halt to all other CPUs */ 1249 /* broadcast a halt to all other CPUs */
1250 void 1250 void
1251 smp_send_stop(void) 1251 smp_send_stop(void)
1252 { 1252 {
1253 smp_call_function(smp_stop_cpu_function, NULL, 1, 1); 1253 smp_call_function(smp_stop_cpu_function, NULL, 1, 1);
1254 } 1254 }
1255 1255
1256 /* this function is triggered in time.c when a clock tick fires 1256 /* this function is triggered in time.c when a clock tick fires
1257 * we need to re-broadcast the tick to all CPUs */ 1257 * we need to re-broadcast the tick to all CPUs */
1258 void 1258 void
1259 smp_vic_timer_interrupt(struct pt_regs *regs) 1259 smp_vic_timer_interrupt(struct pt_regs *regs)
1260 { 1260 {
1261 send_CPI_allbutself(VIC_TIMER_CPI); 1261 send_CPI_allbutself(VIC_TIMER_CPI);
1262 smp_local_timer_interrupt(regs); 1262 smp_local_timer_interrupt(regs);
1263 } 1263 }
1264 1264
1265 /* local (per CPU) timer interrupt. It does both profiling and 1265 /* local (per CPU) timer interrupt. It does both profiling and
1266 * process statistics/rescheduling. 1266 * process statistics/rescheduling.
1267 * 1267 *
1268 * We do profiling in every local tick, statistics/rescheduling 1268 * We do profiling in every local tick, statistics/rescheduling
1269 * happen only every 'profiling multiplier' ticks. The default 1269 * happen only every 'profiling multiplier' ticks. The default
1270 * multiplier is 1 and it can be changed by writing the new multiplier 1270 * multiplier is 1 and it can be changed by writing the new multiplier
1271 * value into /proc/profile. 1271 * value into /proc/profile.
1272 */ 1272 */
1273 void 1273 void
1274 smp_local_timer_interrupt(struct pt_regs * regs) 1274 smp_local_timer_interrupt(struct pt_regs * regs)
1275 { 1275 {
1276 int cpu = smp_processor_id(); 1276 int cpu = smp_processor_id();
1277 long weight; 1277 long weight;
1278 1278
1279 profile_tick(CPU_PROFILING, regs); 1279 profile_tick(CPU_PROFILING, regs);
1280 if (--per_cpu(prof_counter, cpu) <= 0) { 1280 if (--per_cpu(prof_counter, cpu) <= 0) {
1281 /* 1281 /*
1282 * The multiplier may have changed since the last time we got 1282 * The multiplier may have changed since the last time we got
1283 * to this point as a result of the user writing to 1283 * to this point as a result of the user writing to
1284 * /proc/profile. In this case we need to adjust the APIC 1284 * /proc/profile. In this case we need to adjust the APIC
1285 * timer accordingly. 1285 * timer accordingly.
1286 * 1286 *
1287 * Interrupts are already masked off at this point. 1287 * Interrupts are already masked off at this point.
1288 */ 1288 */
1289 per_cpu(prof_counter,cpu) = per_cpu(prof_multiplier, cpu); 1289 per_cpu(prof_counter,cpu) = per_cpu(prof_multiplier, cpu);
1290 if (per_cpu(prof_counter, cpu) != 1290 if (per_cpu(prof_counter, cpu) !=
1291 per_cpu(prof_old_multiplier, cpu)) { 1291 per_cpu(prof_old_multiplier, cpu)) {
1292 /* FIXME: need to update the vic timer tick here */ 1292 /* FIXME: need to update the vic timer tick here */
1293 per_cpu(prof_old_multiplier, cpu) = 1293 per_cpu(prof_old_multiplier, cpu) =
1294 per_cpu(prof_counter, cpu); 1294 per_cpu(prof_counter, cpu);
1295 } 1295 }
1296 1296
1297 update_process_times(user_mode_vm(regs)); 1297 update_process_times(user_mode_vm(regs));
1298 } 1298 }
1299 1299
1300 if( ((1<<cpu) & voyager_extended_vic_processors) == 0) 1300 if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
1301 /* only extended VIC processors participate in 1301 /* only extended VIC processors participate in
1302 * interrupt distribution */ 1302 * interrupt distribution */
1303 return; 1303 return;
1304 1304
1305 /* 1305 /*
1306 * We take the 'long' return path, and there every subsystem 1306 * We take the 'long' return path, and there every subsystem
1307 * grabs the apropriate locks (kernel lock/ irq lock). 1307 * grabs the apropriate locks (kernel lock/ irq lock).
1308 * 1308 *
1309 * we might want to decouple profiling from the 'long path', 1309 * we might want to decouple profiling from the 'long path',
1310 * and do the profiling totally in assembly. 1310 * and do the profiling totally in assembly.
1311 * 1311 *
1312 * Currently this isn't too much of an issue (performance wise), 1312 * Currently this isn't too much of an issue (performance wise),
1313 * we can take more than 100K local irqs per second on a 100 MHz P5. 1313 * we can take more than 100K local irqs per second on a 100 MHz P5.
1314 */ 1314 */
1315 1315
1316 if((++vic_tick[cpu] & 0x7) != 0) 1316 if((++vic_tick[cpu] & 0x7) != 0)
1317 return; 1317 return;
1318 /* get here every 16 ticks (about every 1/6 of a second) */ 1318 /* get here every 16 ticks (about every 1/6 of a second) */
1319 1319
1320 /* Change our priority to give someone else a chance at getting 1320 /* Change our priority to give someone else a chance at getting
1321 * the IRQ. The algorithm goes like this: 1321 * the IRQ. The algorithm goes like this:
1322 * 1322 *
1323 * In the VIC, the dynamically routed interrupt is always 1323 * In the VIC, the dynamically routed interrupt is always
1324 * handled by the lowest priority eligible (i.e. receiving 1324 * handled by the lowest priority eligible (i.e. receiving
1325 * interrupts) CPU. If >1 eligible CPUs are equal lowest, the 1325 * interrupts) CPU. If >1 eligible CPUs are equal lowest, the
1326 * lowest processor number gets it. 1326 * lowest processor number gets it.
1327 * 1327 *
1328 * The priority of a CPU is controlled by a special per-CPU 1328 * The priority of a CPU is controlled by a special per-CPU
1329 * VIC priority register which is 3 bits wide 0 being lowest 1329 * VIC priority register which is 3 bits wide 0 being lowest
1330 * and 7 highest priority.. 1330 * and 7 highest priority..
1331 * 1331 *
1332 * Therefore we subtract the average number of interrupts from 1332 * Therefore we subtract the average number of interrupts from
1333 * the number we've fielded. If this number is negative, we 1333 * the number we've fielded. If this number is negative, we
1334 * lower the activity count and if it is positive, we raise 1334 * lower the activity count and if it is positive, we raise
1335 * it. 1335 * it.
1336 * 1336 *
1337 * I'm afraid this still leads to odd looking interrupt counts: 1337 * I'm afraid this still leads to odd looking interrupt counts:
1338 * the totals are all roughly equal, but the individual ones 1338 * the totals are all roughly equal, but the individual ones
1339 * look rather skewed. 1339 * look rather skewed.
1340 * 1340 *
1341 * FIXME: This algorithm is total crap when mixed with SMP 1341 * FIXME: This algorithm is total crap when mixed with SMP
1342 * affinity code since we now try to even up the interrupt 1342 * affinity code since we now try to even up the interrupt
1343 * counts when an affinity binding is keeping them on a 1343 * counts when an affinity binding is keeping them on a
1344 * particular CPU*/ 1344 * particular CPU*/
1345 weight = (vic_intr_count[cpu]*voyager_extended_cpus 1345 weight = (vic_intr_count[cpu]*voyager_extended_cpus
1346 - vic_intr_total) >> 4; 1346 - vic_intr_total) >> 4;
1347 weight += 4; 1347 weight += 4;
1348 if(weight > 7) 1348 if(weight > 7)
1349 weight = 7; 1349 weight = 7;
1350 if(weight < 0) 1350 if(weight < 0)
1351 weight = 0; 1351 weight = 0;
1352 1352
1353 outb((__u8)weight, VIC_PRIORITY_REGISTER); 1353 outb((__u8)weight, VIC_PRIORITY_REGISTER);
1354 1354
1355 #ifdef VOYAGER_DEBUG 1355 #ifdef VOYAGER_DEBUG
1356 if((vic_tick[cpu] & 0xFFF) == 0) { 1356 if((vic_tick[cpu] & 0xFFF) == 0) {
1357 /* print this message roughly every 25 secs */ 1357 /* print this message roughly every 25 secs */
1358 printk("VOYAGER SMP: vic_tick[%d] = %lu, weight = %ld\n", 1358 printk("VOYAGER SMP: vic_tick[%d] = %lu, weight = %ld\n",
1359 cpu, vic_tick[cpu], weight); 1359 cpu, vic_tick[cpu], weight);
1360 } 1360 }
1361 #endif 1361 #endif
1362 } 1362 }
1363 1363
1364 /* setup the profiling timer */ 1364 /* setup the profiling timer */
1365 int 1365 int
1366 setup_profiling_timer(unsigned int multiplier) 1366 setup_profiling_timer(unsigned int multiplier)
1367 { 1367 {
1368 int i; 1368 int i;
1369 1369
1370 if ( (!multiplier)) 1370 if ( (!multiplier))
1371 return -EINVAL; 1371 return -EINVAL;
1372 1372
1373 /* 1373 /*
1374 * Set the new multiplier for each CPU. CPUs don't start using the 1374 * Set the new multiplier for each CPU. CPUs don't start using the
1375 * new values until the next timer interrupt in which they do process 1375 * new values until the next timer interrupt in which they do process
1376 * accounting. 1376 * accounting.
1377 */ 1377 */
1378 for (i = 0; i < NR_CPUS; ++i) 1378 for (i = 0; i < NR_CPUS; ++i)
1379 per_cpu(prof_multiplier, i) = multiplier; 1379 per_cpu(prof_multiplier, i) = multiplier;
1380 1380
1381 return 0; 1381 return 0;
1382 } 1382 }
1383 1383
1384 1384
1385 /* The CPIs are handled in the per cpu 8259s, so they must be 1385 /* The CPIs are handled in the per cpu 8259s, so they must be
1386 * enabled to be received: FIX: enabling the CPIs in the early 1386 * enabled to be received: FIX: enabling the CPIs in the early
1387 * boot sequence interferes with bug checking; enable them later 1387 * boot sequence interferes with bug checking; enable them later
1388 * on in smp_init */ 1388 * on in smp_init */
1389 #define VIC_SET_GATE(cpi, vector) \ 1389 #define VIC_SET_GATE(cpi, vector) \
1390 set_intr_gate((cpi) + VIC_DEFAULT_CPI_BASE, (vector)) 1390 set_intr_gate((cpi) + VIC_DEFAULT_CPI_BASE, (vector))
1391 #define QIC_SET_GATE(cpi, vector) \ 1391 #define QIC_SET_GATE(cpi, vector) \
1392 set_intr_gate((cpi) + QIC_DEFAULT_CPI_BASE, (vector)) 1392 set_intr_gate((cpi) + QIC_DEFAULT_CPI_BASE, (vector))
1393 1393
1394 void __init 1394 void __init
1395 smp_intr_init(void) 1395 smp_intr_init(void)
1396 { 1396 {
1397 int i; 1397 int i;
1398 1398
1399 /* initialize the per cpu irq mask to all disabled */ 1399 /* initialize the per cpu irq mask to all disabled */
1400 for(i = 0; i < NR_CPUS; i++) 1400 for(i = 0; i < NR_CPUS; i++)
1401 vic_irq_mask[i] = 0xFFFF; 1401 vic_irq_mask[i] = 0xFFFF;
1402 1402
1403 VIC_SET_GATE(VIC_CPI_LEVEL0, vic_cpi_interrupt); 1403 VIC_SET_GATE(VIC_CPI_LEVEL0, vic_cpi_interrupt);
1404 1404
1405 VIC_SET_GATE(VIC_SYS_INT, vic_sys_interrupt); 1405 VIC_SET_GATE(VIC_SYS_INT, vic_sys_interrupt);
1406 VIC_SET_GATE(VIC_CMN_INT, vic_cmn_interrupt); 1406 VIC_SET_GATE(VIC_CMN_INT, vic_cmn_interrupt);
1407 1407
1408 QIC_SET_GATE(QIC_TIMER_CPI, qic_timer_interrupt); 1408 QIC_SET_GATE(QIC_TIMER_CPI, qic_timer_interrupt);
1409 QIC_SET_GATE(QIC_INVALIDATE_CPI, qic_invalidate_interrupt); 1409 QIC_SET_GATE(QIC_INVALIDATE_CPI, qic_invalidate_interrupt);
1410 QIC_SET_GATE(QIC_RESCHEDULE_CPI, qic_reschedule_interrupt); 1410 QIC_SET_GATE(QIC_RESCHEDULE_CPI, qic_reschedule_interrupt);
1411 QIC_SET_GATE(QIC_ENABLE_IRQ_CPI, qic_enable_irq_interrupt); 1411 QIC_SET_GATE(QIC_ENABLE_IRQ_CPI, qic_enable_irq_interrupt);
1412 QIC_SET_GATE(QIC_CALL_FUNCTION_CPI, qic_call_function_interrupt); 1412 QIC_SET_GATE(QIC_CALL_FUNCTION_CPI, qic_call_function_interrupt);
1413 1413
1414 1414
1415 /* now put the VIC descriptor into the first 48 IRQs 1415 /* now put the VIC descriptor into the first 48 IRQs
1416 * 1416 *
1417 * This is for later: first 16 correspond to PC IRQs; next 16 1417 * This is for later: first 16 correspond to PC IRQs; next 16
1418 * are Primary MC IRQs and final 16 are Secondary MC IRQs */ 1418 * are Primary MC IRQs and final 16 are Secondary MC IRQs */
1419 for(i = 0; i < 48; i++) 1419 for(i = 0; i < 48; i++)
1420 irq_desc[i].handler = &vic_irq_type; 1420 irq_desc[i].handler = &vic_irq_type;
1421 } 1421 }
1422 1422
1423 /* send a CPI at level cpi to a set of cpus in cpuset (set 1 bit per 1423 /* send a CPI at level cpi to a set of cpus in cpuset (set 1 bit per
1424 * processor to receive CPI */ 1424 * processor to receive CPI */
1425 static void 1425 static void
1426 send_CPI(__u32 cpuset, __u8 cpi) 1426 send_CPI(__u32 cpuset, __u8 cpi)
1427 { 1427 {
1428 int cpu; 1428 int cpu;
1429 __u32 quad_cpuset = (cpuset & voyager_quad_processors); 1429 __u32 quad_cpuset = (cpuset & voyager_quad_processors);
1430 1430
1431 if(cpi < VIC_START_FAKE_CPI) { 1431 if(cpi < VIC_START_FAKE_CPI) {
1432 /* fake CPI are only used for booting, so send to the 1432 /* fake CPI are only used for booting, so send to the
1433 * extended quads as well---Quads must be VIC booted */ 1433 * extended quads as well---Quads must be VIC booted */
1434 outb((__u8)(cpuset), VIC_CPI_Registers[cpi]); 1434 outb((__u8)(cpuset), VIC_CPI_Registers[cpi]);
1435 return; 1435 return;
1436 } 1436 }
1437 if(quad_cpuset) 1437 if(quad_cpuset)
1438 send_QIC_CPI(quad_cpuset, cpi); 1438 send_QIC_CPI(quad_cpuset, cpi);
1439 cpuset &= ~quad_cpuset; 1439 cpuset &= ~quad_cpuset;
1440 cpuset &= 0xff; /* only first 8 CPUs vaild for VIC CPI */ 1440 cpuset &= 0xff; /* only first 8 CPUs vaild for VIC CPI */
1441 if(cpuset == 0) 1441 if(cpuset == 0)
1442 return; 1442 return;
1443 for_each_online_cpu(cpu) { 1443 for_each_online_cpu(cpu) {
1444 if(cpuset & (1<<cpu)) 1444 if(cpuset & (1<<cpu))
1445 set_bit(cpi, &vic_cpi_mailbox[cpu]); 1445 set_bit(cpi, &vic_cpi_mailbox[cpu]);
1446 } 1446 }
1447 if(cpuset) 1447 if(cpuset)
1448 outb((__u8)cpuset, VIC_CPI_Registers[VIC_CPI_LEVEL0]); 1448 outb((__u8)cpuset, VIC_CPI_Registers[VIC_CPI_LEVEL0]);
1449 } 1449 }
1450 1450
1451 /* Acknowledge receipt of CPI in the QIC, clear in QIC hardware and 1451 /* Acknowledge receipt of CPI in the QIC, clear in QIC hardware and
1452 * set the cache line to shared by reading it. 1452 * set the cache line to shared by reading it.
1453 * 1453 *
1454 * DON'T make this inline otherwise the cache line read will be 1454 * DON'T make this inline otherwise the cache line read will be
1455 * optimised away 1455 * optimised away
1456 * */ 1456 * */
1457 static int 1457 static int
1458 ack_QIC_CPI(__u8 cpi) { 1458 ack_QIC_CPI(__u8 cpi) {
1459 __u8 cpu = hard_smp_processor_id(); 1459 __u8 cpu = hard_smp_processor_id();
1460 1460
1461 cpi &= 7; 1461 cpi &= 7;
1462 1462
1463 outb(1<<cpi, QIC_INTERRUPT_CLEAR1); 1463 outb(1<<cpi, QIC_INTERRUPT_CLEAR1);
1464 return voyager_quad_cpi_addr[cpu]->qic_cpi[cpi].cpi; 1464 return voyager_quad_cpi_addr[cpu]->qic_cpi[cpi].cpi;
1465 } 1465 }
1466 1466
1467 static void 1467 static void
1468 ack_special_QIC_CPI(__u8 cpi) 1468 ack_special_QIC_CPI(__u8 cpi)
1469 { 1469 {
1470 switch(cpi) { 1470 switch(cpi) {
1471 case VIC_CMN_INT: 1471 case VIC_CMN_INT:
1472 outb(QIC_CMN_INT, QIC_INTERRUPT_CLEAR0); 1472 outb(QIC_CMN_INT, QIC_INTERRUPT_CLEAR0);
1473 break; 1473 break;
1474 case VIC_SYS_INT: 1474 case VIC_SYS_INT:
1475 outb(QIC_SYS_INT, QIC_INTERRUPT_CLEAR0); 1475 outb(QIC_SYS_INT, QIC_INTERRUPT_CLEAR0);
1476 break; 1476 break;
1477 } 1477 }
1478 /* also clear at the VIC, just in case (nop for non-extended proc) */ 1478 /* also clear at the VIC, just in case (nop for non-extended proc) */
1479 ack_VIC_CPI(cpi); 1479 ack_VIC_CPI(cpi);
1480 } 1480 }
1481 1481
1482 /* Acknowledge receipt of CPI in the VIC (essentially an EOI) */ 1482 /* Acknowledge receipt of CPI in the VIC (essentially an EOI) */
1483 static void 1483 static void
1484 ack_VIC_CPI(__u8 cpi) 1484 ack_VIC_CPI(__u8 cpi)
1485 { 1485 {
1486 #ifdef VOYAGER_DEBUG 1486 #ifdef VOYAGER_DEBUG
1487 unsigned long flags; 1487 unsigned long flags;
1488 __u16 isr; 1488 __u16 isr;
1489 __u8 cpu = smp_processor_id(); 1489 __u8 cpu = smp_processor_id();
1490 1490
1491 local_irq_save(flags); 1491 local_irq_save(flags);
1492 isr = vic_read_isr(); 1492 isr = vic_read_isr();
1493 if((isr & (1<<(cpi &7))) == 0) { 1493 if((isr & (1<<(cpi &7))) == 0) {
1494 printk("VOYAGER SMP: CPU%d lost CPI%d\n", cpu, cpi); 1494 printk("VOYAGER SMP: CPU%d lost CPI%d\n", cpu, cpi);
1495 } 1495 }
1496 #endif 1496 #endif
1497 /* send specific EOI; the two system interrupts have 1497 /* send specific EOI; the two system interrupts have
1498 * bit 4 set for a separate vector but behave as the 1498 * bit 4 set for a separate vector but behave as the
1499 * corresponding 3 bit intr */ 1499 * corresponding 3 bit intr */
1500 outb_p(0x60|(cpi & 7),0x20); 1500 outb_p(0x60|(cpi & 7),0x20);
1501 1501
1502 #ifdef VOYAGER_DEBUG 1502 #ifdef VOYAGER_DEBUG
1503 if((vic_read_isr() & (1<<(cpi &7))) != 0) { 1503 if((vic_read_isr() & (1<<(cpi &7))) != 0) {
1504 printk("VOYAGER SMP: CPU%d still asserting CPI%d\n", cpu, cpi); 1504 printk("VOYAGER SMP: CPU%d still asserting CPI%d\n", cpu, cpi);
1505 } 1505 }
1506 local_irq_restore(flags); 1506 local_irq_restore(flags);
1507 #endif 1507 #endif
1508 } 1508 }
1509 1509
1510 /* cribbed with thanks from irq.c */ 1510 /* cribbed with thanks from irq.c */
1511 #define __byte(x,y) (((unsigned char *)&(y))[x]) 1511 #define __byte(x,y) (((unsigned char *)&(y))[x])
1512 #define cached_21(cpu) (__byte(0,vic_irq_mask[cpu])) 1512 #define cached_21(cpu) (__byte(0,vic_irq_mask[cpu]))
1513 #define cached_A1(cpu) (__byte(1,vic_irq_mask[cpu])) 1513 #define cached_A1(cpu) (__byte(1,vic_irq_mask[cpu]))
1514 1514
1515 static unsigned int 1515 static unsigned int
1516 startup_vic_irq(unsigned int irq) 1516 startup_vic_irq(unsigned int irq)
1517 { 1517 {
1518 enable_vic_irq(irq); 1518 enable_vic_irq(irq);
1519 1519
1520 return 0; 1520 return 0;
1521 } 1521 }
1522 1522
1523 /* The enable and disable routines. This is where we run into 1523 /* The enable and disable routines. This is where we run into
1524 * conflicting architectural philosophy. Fundamentally, the voyager 1524 * conflicting architectural philosophy. Fundamentally, the voyager
1525 * architecture does not expect to have to disable interrupts globally 1525 * architecture does not expect to have to disable interrupts globally
1526 * (the IRQ controllers belong to each CPU). The processor masquerade 1526 * (the IRQ controllers belong to each CPU). The processor masquerade
1527 * which is used to start the system shouldn't be used in a running OS 1527 * which is used to start the system shouldn't be used in a running OS
1528 * since it will cause great confusion if two separate CPUs drive to 1528 * since it will cause great confusion if two separate CPUs drive to
1529 * the same IRQ controller (I know, I've tried it). 1529 * the same IRQ controller (I know, I've tried it).
1530 * 1530 *
1531 * The solution is a variant on the NCR lazy SPL design: 1531 * The solution is a variant on the NCR lazy SPL design:
1532 * 1532 *
1533 * 1) To disable an interrupt, do nothing (other than set the 1533 * 1) To disable an interrupt, do nothing (other than set the
1534 * IRQ_DISABLED flag). This dares the interrupt actually to arrive. 1534 * IRQ_DISABLED flag). This dares the interrupt actually to arrive.
1535 * 1535 *
1536 * 2) If the interrupt dares to come in, raise the local mask against 1536 * 2) If the interrupt dares to come in, raise the local mask against
1537 * it (this will result in all the CPU masks being raised 1537 * it (this will result in all the CPU masks being raised
1538 * eventually). 1538 * eventually).
1539 * 1539 *
1540 * 3) To enable the interrupt, lower the mask on the local CPU and 1540 * 3) To enable the interrupt, lower the mask on the local CPU and
1541 * broadcast an Interrupt enable CPI which causes all other CPUs to 1541 * broadcast an Interrupt enable CPI which causes all other CPUs to
1542 * adjust their masks accordingly. */ 1542 * adjust their masks accordingly. */
1543 1543
1544 static void 1544 static void
1545 enable_vic_irq(unsigned int irq) 1545 enable_vic_irq(unsigned int irq)
1546 { 1546 {
1547 /* linux doesn't to processor-irq affinity, so enable on 1547 /* linux doesn't to processor-irq affinity, so enable on
1548 * all CPUs we know about */ 1548 * all CPUs we know about */
1549 int cpu = smp_processor_id(), real_cpu; 1549 int cpu = smp_processor_id(), real_cpu;
1550 __u16 mask = (1<<irq); 1550 __u16 mask = (1<<irq);
1551 __u32 processorList = 0; 1551 __u32 processorList = 0;
1552 unsigned long flags; 1552 unsigned long flags;
1553 1553
1554 VDEBUG(("VOYAGER: enable_vic_irq(%d) CPU%d affinity 0x%lx\n", 1554 VDEBUG(("VOYAGER: enable_vic_irq(%d) CPU%d affinity 0x%lx\n",
1555 irq, cpu, cpu_irq_affinity[cpu])); 1555 irq, cpu, cpu_irq_affinity[cpu]));
1556 spin_lock_irqsave(&vic_irq_lock, flags); 1556 spin_lock_irqsave(&vic_irq_lock, flags);
1557 for_each_online_cpu(real_cpu) { 1557 for_each_online_cpu(real_cpu) {
1558 if(!(voyager_extended_vic_processors & (1<<real_cpu))) 1558 if(!(voyager_extended_vic_processors & (1<<real_cpu)))
1559 continue; 1559 continue;
1560 if(!(cpu_irq_affinity[real_cpu] & mask)) { 1560 if(!(cpu_irq_affinity[real_cpu] & mask)) {
1561 /* irq has no affinity for this CPU, ignore */ 1561 /* irq has no affinity for this CPU, ignore */
1562 continue; 1562 continue;
1563 } 1563 }
1564 if(real_cpu == cpu) { 1564 if(real_cpu == cpu) {
1565 enable_local_vic_irq(irq); 1565 enable_local_vic_irq(irq);
1566 } 1566 }
1567 else if(vic_irq_mask[real_cpu] & mask) { 1567 else if(vic_irq_mask[real_cpu] & mask) {
1568 vic_irq_enable_mask[real_cpu] |= mask; 1568 vic_irq_enable_mask[real_cpu] |= mask;
1569 processorList |= (1<<real_cpu); 1569 processorList |= (1<<real_cpu);
1570 } 1570 }
1571 } 1571 }
1572 spin_unlock_irqrestore(&vic_irq_lock, flags); 1572 spin_unlock_irqrestore(&vic_irq_lock, flags);
1573 if(processorList) 1573 if(processorList)
1574 send_CPI(processorList, VIC_ENABLE_IRQ_CPI); 1574 send_CPI(processorList, VIC_ENABLE_IRQ_CPI);
1575 } 1575 }
1576 1576
1577 static void 1577 static void
1578 disable_vic_irq(unsigned int irq) 1578 disable_vic_irq(unsigned int irq)
1579 { 1579 {
1580 /* lazy disable, do nothing */ 1580 /* lazy disable, do nothing */
1581 } 1581 }
1582 1582
1583 static void 1583 static void
1584 enable_local_vic_irq(unsigned int irq) 1584 enable_local_vic_irq(unsigned int irq)
1585 { 1585 {
1586 __u8 cpu = smp_processor_id(); 1586 __u8 cpu = smp_processor_id();
1587 __u16 mask = ~(1 << irq); 1587 __u16 mask = ~(1 << irq);
1588 __u16 old_mask = vic_irq_mask[cpu]; 1588 __u16 old_mask = vic_irq_mask[cpu];
1589 1589
1590 vic_irq_mask[cpu] &= mask; 1590 vic_irq_mask[cpu] &= mask;
1591 if(vic_irq_mask[cpu] == old_mask) 1591 if(vic_irq_mask[cpu] == old_mask)
1592 return; 1592 return;
1593 1593
1594 VDEBUG(("VOYAGER DEBUG: Enabling irq %d in hardware on CPU %d\n", 1594 VDEBUG(("VOYAGER DEBUG: Enabling irq %d in hardware on CPU %d\n",
1595 irq, cpu)); 1595 irq, cpu));
1596 1596
1597 if (irq & 8) { 1597 if (irq & 8) {
1598 outb_p(cached_A1(cpu),0xA1); 1598 outb_p(cached_A1(cpu),0xA1);
1599 (void)inb_p(0xA1); 1599 (void)inb_p(0xA1);
1600 } 1600 }
1601 else { 1601 else {
1602 outb_p(cached_21(cpu),0x21); 1602 outb_p(cached_21(cpu),0x21);
1603 (void)inb_p(0x21); 1603 (void)inb_p(0x21);
1604 } 1604 }
1605 } 1605 }
1606 1606
1607 static void 1607 static void
1608 disable_local_vic_irq(unsigned int irq) 1608 disable_local_vic_irq(unsigned int irq)
1609 { 1609 {
1610 __u8 cpu = smp_processor_id(); 1610 __u8 cpu = smp_processor_id();
1611 __u16 mask = (1 << irq); 1611 __u16 mask = (1 << irq);
1612 __u16 old_mask = vic_irq_mask[cpu]; 1612 __u16 old_mask = vic_irq_mask[cpu];
1613 1613
1614 if(irq == 7) 1614 if(irq == 7)
1615 return; 1615 return;
1616 1616
1617 vic_irq_mask[cpu] |= mask; 1617 vic_irq_mask[cpu] |= mask;
1618 if(old_mask == vic_irq_mask[cpu]) 1618 if(old_mask == vic_irq_mask[cpu])
1619 return; 1619 return;
1620 1620
1621 VDEBUG(("VOYAGER DEBUG: Disabling irq %d in hardware on CPU %d\n", 1621 VDEBUG(("VOYAGER DEBUG: Disabling irq %d in hardware on CPU %d\n",
1622 irq, cpu)); 1622 irq, cpu));
1623 1623
1624 if (irq & 8) { 1624 if (irq & 8) {
1625 outb_p(cached_A1(cpu),0xA1); 1625 outb_p(cached_A1(cpu),0xA1);
1626 (void)inb_p(0xA1); 1626 (void)inb_p(0xA1);
1627 } 1627 }
1628 else { 1628 else {
1629 outb_p(cached_21(cpu),0x21); 1629 outb_p(cached_21(cpu),0x21);
1630 (void)inb_p(0x21); 1630 (void)inb_p(0x21);
1631 } 1631 }
1632 } 1632 }
1633 1633
1634 /* The VIC is level triggered, so the ack can only be issued after the 1634 /* The VIC is level triggered, so the ack can only be issued after the
1635 * interrupt completes. However, we do Voyager lazy interrupt 1635 * interrupt completes. However, we do Voyager lazy interrupt
1636 * handling here: It is an extremely expensive operation to mask an 1636 * handling here: It is an extremely expensive operation to mask an
1637 * interrupt in the vic, so we merely set a flag (IRQ_DISABLED). If 1637 * interrupt in the vic, so we merely set a flag (IRQ_DISABLED). If
1638 * this interrupt actually comes in, then we mask and ack here to push 1638 * this interrupt actually comes in, then we mask and ack here to push
1639 * the interrupt off to another CPU */ 1639 * the interrupt off to another CPU */
1640 static void 1640 static void
1641 before_handle_vic_irq(unsigned int irq) 1641 before_handle_vic_irq(unsigned int irq)
1642 { 1642 {
1643 irq_desc_t *desc = irq_desc + irq; 1643 irq_desc_t *desc = irq_desc + irq;
1644 __u8 cpu = smp_processor_id(); 1644 __u8 cpu = smp_processor_id();
1645 1645
1646 _raw_spin_lock(&vic_irq_lock); 1646 _raw_spin_lock(&vic_irq_lock);
1647 vic_intr_total++; 1647 vic_intr_total++;
1648 vic_intr_count[cpu]++; 1648 vic_intr_count[cpu]++;
1649 1649
1650 if(!(cpu_irq_affinity[cpu] & (1<<irq))) { 1650 if(!(cpu_irq_affinity[cpu] & (1<<irq))) {
1651 /* The irq is not in our affinity mask, push it off 1651 /* The irq is not in our affinity mask, push it off
1652 * onto another CPU */ 1652 * onto another CPU */
1653 VDEBUG(("VOYAGER DEBUG: affinity triggered disable of irq %d on cpu %d\n", 1653 VDEBUG(("VOYAGER DEBUG: affinity triggered disable of irq %d on cpu %d\n",
1654 irq, cpu)); 1654 irq, cpu));
1655 disable_local_vic_irq(irq); 1655 disable_local_vic_irq(irq);
1656 /* set IRQ_INPROGRESS to prevent the handler in irq.c from 1656 /* set IRQ_INPROGRESS to prevent the handler in irq.c from
1657 * actually calling the interrupt routine */ 1657 * actually calling the interrupt routine */
1658 desc->status |= IRQ_REPLAY | IRQ_INPROGRESS; 1658 desc->status |= IRQ_REPLAY | IRQ_INPROGRESS;
1659 } else if(desc->status & IRQ_DISABLED) { 1659 } else if(desc->status & IRQ_DISABLED) {
1660 /* Damn, the interrupt actually arrived, do the lazy 1660 /* Damn, the interrupt actually arrived, do the lazy
1661 * disable thing. The interrupt routine in irq.c will 1661 * disable thing. The interrupt routine in irq.c will
1662 * not handle a IRQ_DISABLED interrupt, so nothing more 1662 * not handle a IRQ_DISABLED interrupt, so nothing more
1663 * need be done here */ 1663 * need be done here */
1664 VDEBUG(("VOYAGER DEBUG: lazy disable of irq %d on CPU %d\n", 1664 VDEBUG(("VOYAGER DEBUG: lazy disable of irq %d on CPU %d\n",
1665 irq, cpu)); 1665 irq, cpu));
1666 disable_local_vic_irq(irq); 1666 disable_local_vic_irq(irq);
1667 desc->status |= IRQ_REPLAY; 1667 desc->status |= IRQ_REPLAY;
1668 } else { 1668 } else {
1669 desc->status &= ~IRQ_REPLAY; 1669 desc->status &= ~IRQ_REPLAY;
1670 } 1670 }
1671 1671
1672 _raw_spin_unlock(&vic_irq_lock); 1672 _raw_spin_unlock(&vic_irq_lock);
1673 } 1673 }
1674 1674
1675 /* Finish the VIC interrupt: basically mask */ 1675 /* Finish the VIC interrupt: basically mask */
1676 static void 1676 static void
1677 after_handle_vic_irq(unsigned int irq) 1677 after_handle_vic_irq(unsigned int irq)
1678 { 1678 {
1679 irq_desc_t *desc = irq_desc + irq; 1679 irq_desc_t *desc = irq_desc + irq;
1680 1680
1681 _raw_spin_lock(&vic_irq_lock); 1681 _raw_spin_lock(&vic_irq_lock);
1682 { 1682 {
1683 unsigned int status = desc->status & ~IRQ_INPROGRESS; 1683 unsigned int status = desc->status & ~IRQ_INPROGRESS;
1684 #ifdef VOYAGER_DEBUG 1684 #ifdef VOYAGER_DEBUG
1685 __u16 isr; 1685 __u16 isr;
1686 #endif 1686 #endif
1687 1687
1688 desc->status = status; 1688 desc->status = status;
1689 if ((status & IRQ_DISABLED)) 1689 if ((status & IRQ_DISABLED))
1690 disable_local_vic_irq(irq); 1690 disable_local_vic_irq(irq);
1691 #ifdef VOYAGER_DEBUG 1691 #ifdef VOYAGER_DEBUG
1692 /* DEBUG: before we ack, check what's in progress */ 1692 /* DEBUG: before we ack, check what's in progress */
1693 isr = vic_read_isr(); 1693 isr = vic_read_isr();
1694 if((isr & (1<<irq) && !(status & IRQ_REPLAY)) == 0) { 1694 if((isr & (1<<irq) && !(status & IRQ_REPLAY)) == 0) {
1695 int i; 1695 int i;
1696 __u8 cpu = smp_processor_id(); 1696 __u8 cpu = smp_processor_id();
1697 __u8 real_cpu; 1697 __u8 real_cpu;
1698 int mask; /* Um... initialize me??? --RR */ 1698 int mask; /* Um... initialize me??? --RR */
1699 1699
1700 printk("VOYAGER SMP: CPU%d lost interrupt %d\n", 1700 printk("VOYAGER SMP: CPU%d lost interrupt %d\n",
1701 cpu, irq); 1701 cpu, irq);
1702 for_each_cpu(real_cpu, mask) { 1702 for_each_cpu(real_cpu, mask) {
1703 1703
1704 outb(VIC_CPU_MASQUERADE_ENABLE | real_cpu, 1704 outb(VIC_CPU_MASQUERADE_ENABLE | real_cpu,
1705 VIC_PROCESSOR_ID); 1705 VIC_PROCESSOR_ID);
1706 isr = vic_read_isr(); 1706 isr = vic_read_isr();
1707 if(isr & (1<<irq)) { 1707 if(isr & (1<<irq)) {
1708 printk("VOYAGER SMP: CPU%d ack irq %d\n", 1708 printk("VOYAGER SMP: CPU%d ack irq %d\n",
1709 real_cpu, irq); 1709 real_cpu, irq);
1710 ack_vic_irq(irq); 1710 ack_vic_irq(irq);
1711 } 1711 }
1712 outb(cpu, VIC_PROCESSOR_ID); 1712 outb(cpu, VIC_PROCESSOR_ID);
1713 } 1713 }
1714 } 1714 }
1715 #endif /* VOYAGER_DEBUG */ 1715 #endif /* VOYAGER_DEBUG */
1716 /* as soon as we ack, the interrupt is eligible for 1716 /* as soon as we ack, the interrupt is eligible for
1717 * receipt by another CPU so everything must be in 1717 * receipt by another CPU so everything must be in
1718 * order here */ 1718 * order here */
1719 ack_vic_irq(irq); 1719 ack_vic_irq(irq);
1720 if(status & IRQ_REPLAY) { 1720 if(status & IRQ_REPLAY) {
1721 /* replay is set if we disable the interrupt 1721 /* replay is set if we disable the interrupt
1722 * in the before_handle_vic_irq() routine, so 1722 * in the before_handle_vic_irq() routine, so
1723 * clear the in progress bit here to allow the 1723 * clear the in progress bit here to allow the
1724 * next CPU to handle this correctly */ 1724 * next CPU to handle this correctly */
1725 desc->status &= ~(IRQ_REPLAY | IRQ_INPROGRESS); 1725 desc->status &= ~(IRQ_REPLAY | IRQ_INPROGRESS);
1726 } 1726 }
1727 #ifdef VOYAGER_DEBUG 1727 #ifdef VOYAGER_DEBUG
1728 isr = vic_read_isr(); 1728 isr = vic_read_isr();
1729 if((isr & (1<<irq)) != 0) 1729 if((isr & (1<<irq)) != 0)
1730 printk("VOYAGER SMP: after_handle_vic_irq() after ack irq=%d, isr=0x%x\n", 1730 printk("VOYAGER SMP: after_handle_vic_irq() after ack irq=%d, isr=0x%x\n",
1731 irq, isr); 1731 irq, isr);
1732 #endif /* VOYAGER_DEBUG */ 1732 #endif /* VOYAGER_DEBUG */
1733 } 1733 }
1734 _raw_spin_unlock(&vic_irq_lock); 1734 _raw_spin_unlock(&vic_irq_lock);
1735 1735
1736 /* All code after this point is out of the main path - the IRQ 1736 /* All code after this point is out of the main path - the IRQ
1737 * may be intercepted by another CPU if reasserted */ 1737 * may be intercepted by another CPU if reasserted */
1738 } 1738 }
1739 1739
1740 1740
1741 /* Linux processor - interrupt affinity manipulations. 1741 /* Linux processor - interrupt affinity manipulations.
1742 * 1742 *
1743 * For each processor, we maintain a 32 bit irq affinity mask. 1743 * For each processor, we maintain a 32 bit irq affinity mask.
1744 * Initially it is set to all 1's so every processor accepts every 1744 * Initially it is set to all 1's so every processor accepts every
1745 * interrupt. In this call, we change the processor's affinity mask: 1745 * interrupt. In this call, we change the processor's affinity mask:
1746 * 1746 *
1747 * Change from enable to disable: 1747 * Change from enable to disable:
1748 * 1748 *
1749 * If the interrupt ever comes in to the processor, we will disable it 1749 * If the interrupt ever comes in to the processor, we will disable it
1750 * and ack it to push it off to another CPU, so just accept the mask here. 1750 * and ack it to push it off to another CPU, so just accept the mask here.
1751 * 1751 *
1752 * Change from disable to enable: 1752 * Change from disable to enable:
1753 * 1753 *
1754 * change the mask and then do an interrupt enable CPI to re-enable on 1754 * change the mask and then do an interrupt enable CPI to re-enable on
1755 * the selected processors */ 1755 * the selected processors */
1756 1756
1757 void 1757 void
1758 set_vic_irq_affinity(unsigned int irq, cpumask_t mask) 1758 set_vic_irq_affinity(unsigned int irq, cpumask_t mask)
1759 { 1759 {
1760 /* Only extended processors handle interrupts */ 1760 /* Only extended processors handle interrupts */
1761 unsigned long real_mask; 1761 unsigned long real_mask;
1762 unsigned long irq_mask = 1 << irq; 1762 unsigned long irq_mask = 1 << irq;
1763 int cpu; 1763 int cpu;
1764 1764
1765 real_mask = cpus_addr(mask)[0] & voyager_extended_vic_processors; 1765 real_mask = cpus_addr(mask)[0] & voyager_extended_vic_processors;
1766 1766
1767 if(cpus_addr(mask)[0] == 0) 1767 if(cpus_addr(mask)[0] == 0)
1768 /* can't have no cpu's to accept the interrupt -- extremely 1768 /* can't have no cpu's to accept the interrupt -- extremely
1769 * bad things will happen */ 1769 * bad things will happen */
1770 return; 1770 return;
1771 1771
1772 if(irq == 0) 1772 if(irq == 0)
1773 /* can't change the affinity of the timer IRQ. This 1773 /* can't change the affinity of the timer IRQ. This
1774 * is due to the constraint in the voyager 1774 * is due to the constraint in the voyager
1775 * architecture that the CPI also comes in on and IRQ 1775 * architecture that the CPI also comes in on and IRQ
1776 * line and we have chosen IRQ0 for this. If you 1776 * line and we have chosen IRQ0 for this. If you
1777 * raise the mask on this interrupt, the processor 1777 * raise the mask on this interrupt, the processor
1778 * will no-longer be able to accept VIC CPIs */ 1778 * will no-longer be able to accept VIC CPIs */
1779 return; 1779 return;
1780 1780
1781 if(irq >= 32) 1781 if(irq >= 32)
1782 /* You can only have 32 interrupts in a voyager system 1782 /* You can only have 32 interrupts in a voyager system
1783 * (and 32 only if you have a secondary microchannel 1783 * (and 32 only if you have a secondary microchannel
1784 * bus) */ 1784 * bus) */
1785 return; 1785 return;
1786 1786
1787 for_each_online_cpu(cpu) { 1787 for_each_online_cpu(cpu) {
1788 unsigned long cpu_mask = 1 << cpu; 1788 unsigned long cpu_mask = 1 << cpu;
1789 1789
1790 if(cpu_mask & real_mask) { 1790 if(cpu_mask & real_mask) {
1791 /* enable the interrupt for this cpu */ 1791 /* enable the interrupt for this cpu */
1792 cpu_irq_affinity[cpu] |= irq_mask; 1792 cpu_irq_affinity[cpu] |= irq_mask;
1793 } else { 1793 } else {
1794 /* disable the interrupt for this cpu */ 1794 /* disable the interrupt for this cpu */
1795 cpu_irq_affinity[cpu] &= ~irq_mask; 1795 cpu_irq_affinity[cpu] &= ~irq_mask;
1796 } 1796 }
1797 } 1797 }
1798 /* this is magic, we now have the correct affinity maps, so 1798 /* this is magic, we now have the correct affinity maps, so
1799 * enable the interrupt. This will send an enable CPI to 1799 * enable the interrupt. This will send an enable CPI to
1800 * those cpu's who need to enable it in their local masks, 1800 * those cpu's who need to enable it in their local masks,
1801 * causing them to correct for the new affinity . If the 1801 * causing them to correct for the new affinity . If the
1802 * interrupt is currently globally disabled, it will simply be 1802 * interrupt is currently globally disabled, it will simply be
1803 * disabled again as it comes in (voyager lazy disable). If 1803 * disabled again as it comes in (voyager lazy disable). If
1804 * the affinity map is tightened to disable the interrupt on a 1804 * the affinity map is tightened to disable the interrupt on a
1805 * cpu, it will be pushed off when it comes in */ 1805 * cpu, it will be pushed off when it comes in */
1806 enable_vic_irq(irq); 1806 enable_vic_irq(irq);
1807 } 1807 }
1808 1808
1809 static void 1809 static void
1810 ack_vic_irq(unsigned int irq) 1810 ack_vic_irq(unsigned int irq)
1811 { 1811 {
1812 if (irq & 8) { 1812 if (irq & 8) {
1813 outb(0x62,0x20); /* Specific EOI to cascade */ 1813 outb(0x62,0x20); /* Specific EOI to cascade */
1814 outb(0x60|(irq & 7),0xA0); 1814 outb(0x60|(irq & 7),0xA0);
1815 } else { 1815 } else {
1816 outb(0x60 | (irq & 7),0x20); 1816 outb(0x60 | (irq & 7),0x20);
1817 } 1817 }
1818 } 1818 }
1819 1819
1820 /* enable the CPIs. In the VIC, the CPIs are delivered by the 8259 1820 /* enable the CPIs. In the VIC, the CPIs are delivered by the 8259
1821 * but are not vectored by it. This means that the 8259 mask must be 1821 * but are not vectored by it. This means that the 8259 mask must be
1822 * lowered to receive them */ 1822 * lowered to receive them */
1823 static __init void 1823 static __init void
1824 vic_enable_cpi(void) 1824 vic_enable_cpi(void)
1825 { 1825 {
1826 __u8 cpu = smp_processor_id(); 1826 __u8 cpu = smp_processor_id();
1827 1827
1828 /* just take a copy of the current mask (nop for boot cpu) */ 1828 /* just take a copy of the current mask (nop for boot cpu) */
1829 vic_irq_mask[cpu] = vic_irq_mask[boot_cpu_id]; 1829 vic_irq_mask[cpu] = vic_irq_mask[boot_cpu_id];
1830 1830
1831 enable_local_vic_irq(VIC_CPI_LEVEL0); 1831 enable_local_vic_irq(VIC_CPI_LEVEL0);
1832 enable_local_vic_irq(VIC_CPI_LEVEL1); 1832 enable_local_vic_irq(VIC_CPI_LEVEL1);
1833 /* for sys int and cmn int */ 1833 /* for sys int and cmn int */
1834 enable_local_vic_irq(7); 1834 enable_local_vic_irq(7);
1835 1835
1836 if(is_cpu_quad()) { 1836 if(is_cpu_quad()) {
1837 outb(QIC_DEFAULT_MASK0, QIC_MASK_REGISTER0); 1837 outb(QIC_DEFAULT_MASK0, QIC_MASK_REGISTER0);
1838 outb(QIC_CPI_ENABLE, QIC_MASK_REGISTER1); 1838 outb(QIC_CPI_ENABLE, QIC_MASK_REGISTER1);
1839 VDEBUG(("VOYAGER SMP: QIC ENABLE CPI: CPU%d: MASK 0x%x\n", 1839 VDEBUG(("VOYAGER SMP: QIC ENABLE CPI: CPU%d: MASK 0x%x\n",
1840 cpu, QIC_CPI_ENABLE)); 1840 cpu, QIC_CPI_ENABLE));
1841 } 1841 }
1842 1842
1843 VDEBUG(("VOYAGER SMP: ENABLE CPI: CPU%d: MASK 0x%x\n", 1843 VDEBUG(("VOYAGER SMP: ENABLE CPI: CPU%d: MASK 0x%x\n",
1844 cpu, vic_irq_mask[cpu])); 1844 cpu, vic_irq_mask[cpu]));
1845 } 1845 }
1846 1846
1847 void 1847 void
1848 voyager_smp_dump() 1848 voyager_smp_dump()
1849 { 1849 {
1850 int old_cpu = smp_processor_id(), cpu; 1850 int old_cpu = smp_processor_id(), cpu;
1851 1851
1852 /* dump the interrupt masks of each processor */ 1852 /* dump the interrupt masks of each processor */
1853 for_each_online_cpu(cpu) { 1853 for_each_online_cpu(cpu) {
1854 __u16 imr, isr, irr; 1854 __u16 imr, isr, irr;
1855 unsigned long flags; 1855 unsigned long flags;
1856 1856
1857 local_irq_save(flags); 1857 local_irq_save(flags);
1858 outb(VIC_CPU_MASQUERADE_ENABLE | cpu, VIC_PROCESSOR_ID); 1858 outb(VIC_CPU_MASQUERADE_ENABLE | cpu, VIC_PROCESSOR_ID);
1859 imr = (inb(0xa1) << 8) | inb(0x21); 1859 imr = (inb(0xa1) << 8) | inb(0x21);
1860 outb(0x0a, 0xa0); 1860 outb(0x0a, 0xa0);
1861 irr = inb(0xa0) << 8; 1861 irr = inb(0xa0) << 8;
1862 outb(0x0a, 0x20); 1862 outb(0x0a, 0x20);
1863 irr |= inb(0x20); 1863 irr |= inb(0x20);
1864 outb(0x0b, 0xa0); 1864 outb(0x0b, 0xa0);
1865 isr = inb(0xa0) << 8; 1865 isr = inb(0xa0) << 8;
1866 outb(0x0b, 0x20); 1866 outb(0x0b, 0x20);
1867 isr |= inb(0x20); 1867 isr |= inb(0x20);
1868 outb(old_cpu, VIC_PROCESSOR_ID); 1868 outb(old_cpu, VIC_PROCESSOR_ID);
1869 local_irq_restore(flags); 1869 local_irq_restore(flags);
1870 printk("\tCPU%d: mask=0x%x, IMR=0x%x, IRR=0x%x, ISR=0x%x\n", 1870 printk("\tCPU%d: mask=0x%x, IMR=0x%x, IRR=0x%x, ISR=0x%x\n",
1871 cpu, vic_irq_mask[cpu], imr, irr, isr); 1871 cpu, vic_irq_mask[cpu], imr, irr, isr);
1872 #if 0 1872 #if 0
1873 /* These lines are put in to try to unstick an un ack'd irq */ 1873 /* These lines are put in to try to unstick an un ack'd irq */
1874 if(isr != 0) { 1874 if(isr != 0) {
1875 int irq; 1875 int irq;
1876 for(irq=0; irq<16; irq++) { 1876 for(irq=0; irq<16; irq++) {
1877 if(isr & (1<<irq)) { 1877 if(isr & (1<<irq)) {
1878 printk("\tCPU%d: ack irq %d\n", 1878 printk("\tCPU%d: ack irq %d\n",
1879 cpu, irq); 1879 cpu, irq);
1880 local_irq_save(flags); 1880 local_irq_save(flags);
1881 outb(VIC_CPU_MASQUERADE_ENABLE | cpu, 1881 outb(VIC_CPU_MASQUERADE_ENABLE | cpu,
1882 VIC_PROCESSOR_ID); 1882 VIC_PROCESSOR_ID);
1883 ack_vic_irq(irq); 1883 ack_vic_irq(irq);
1884 outb(old_cpu, VIC_PROCESSOR_ID); 1884 outb(old_cpu, VIC_PROCESSOR_ID);
1885 local_irq_restore(flags); 1885 local_irq_restore(flags);
1886 } 1886 }
1887 } 1887 }
1888 } 1888 }
1889 #endif 1889 #endif
1890 } 1890 }
1891 } 1891 }
1892 1892
1893 void 1893 void
1894 smp_voyager_power_off(void *dummy) 1894 smp_voyager_power_off(void *dummy)
1895 { 1895 {
1896 if(smp_processor_id() == boot_cpu_id) 1896 if(smp_processor_id() == boot_cpu_id)
1897 voyager_power_off(); 1897 voyager_power_off();
1898 else 1898 else
1899 smp_stop_cpu_function(NULL); 1899 smp_stop_cpu_function(NULL);
1900 } 1900 }
1901 1901
1902 void __init 1902 void __init
1903 smp_prepare_cpus(unsigned int max_cpus) 1903 smp_prepare_cpus(unsigned int max_cpus)
1904 { 1904 {
1905 /* FIXME: ignore max_cpus for now */ 1905 /* FIXME: ignore max_cpus for now */
1906 smp_boot_cpus(); 1906 smp_boot_cpus();
1907 } 1907 }
1908 1908
1909 void __devinit smp_prepare_boot_cpu(void) 1909 void __devinit smp_prepare_boot_cpu(void)
1910 { 1910 {
1911 cpu_set(smp_processor_id(), cpu_online_map); 1911 cpu_set(smp_processor_id(), cpu_online_map);
1912 cpu_set(smp_processor_id(), cpu_callout_map); 1912 cpu_set(smp_processor_id(), cpu_callout_map);
1913 } 1913 }
1914 1914
1915 int __devinit 1915 int __devinit
1916 __cpu_up(unsigned int cpu) 1916 __cpu_up(unsigned int cpu)
1917 { 1917 {
1918 /* This only works at boot for x86. See "rewrite" above. */ 1918 /* This only works at boot for x86. See "rewrite" above. */
1919 if (cpu_isset(cpu, smp_commenced_mask)) 1919 if (cpu_isset(cpu, smp_commenced_mask))
1920 return -ENOSYS; 1920 return -ENOSYS;
1921 1921
1922 /* In case one didn't come up */ 1922 /* In case one didn't come up */
1923 if (!cpu_isset(cpu, cpu_callin_map)) 1923 if (!cpu_isset(cpu, cpu_callin_map))
1924 return -EIO; 1924 return -EIO;
1925 /* Unleash the CPU! */ 1925 /* Unleash the CPU! */
1926 cpu_set(cpu, smp_commenced_mask); 1926 cpu_set(cpu, smp_commenced_mask);
1927 while (!cpu_isset(cpu, cpu_online_map)) 1927 while (!cpu_isset(cpu, cpu_online_map))
1928 mb(); 1928 mb();
1929 return 0; 1929 return 0;
1930 } 1930 }
1931 1931
1932 void __init 1932 void __init
1933 smp_cpus_done(unsigned int max_cpus) 1933 smp_cpus_done(unsigned int max_cpus)
1934 { 1934 {
1935 zap_low_mappings(); 1935 zap_low_mappings();
1936 } 1936 }
1937 1937
include/asm-i386/msr.h
1 #ifndef __ASM_MSR_H 1 #ifndef __ASM_MSR_H
2 #define __ASM_MSR_H 2 #define __ASM_MSR_H
3 3
4 /* 4 /*
5 * Access to machine-specific registers (available on 586 and better only) 5 * Access to machine-specific registers (available on 586 and better only)
6 * Note: the rd* operations modify the parameters directly (without using 6 * Note: the rd* operations modify the parameters directly (without using
7 * pointer indirection), this allows gcc to optimize better 7 * pointer indirection), this allows gcc to optimize better
8 */ 8 */
9 9
10 #define rdmsr(msr,val1,val2) \ 10 #define rdmsr(msr,val1,val2) \
11 __asm__ __volatile__("rdmsr" \ 11 __asm__ __volatile__("rdmsr" \
12 : "=a" (val1), "=d" (val2) \ 12 : "=a" (val1), "=d" (val2) \
13 : "c" (msr)) 13 : "c" (msr))
14 14
15 #define wrmsr(msr,val1,val2) \ 15 #define wrmsr(msr,val1,val2) \
16 __asm__ __volatile__("wrmsr" \ 16 __asm__ __volatile__("wrmsr" \
17 : /* no outputs */ \ 17 : /* no outputs */ \
18 : "c" (msr), "a" (val1), "d" (val2)) 18 : "c" (msr), "a" (val1), "d" (val2))
19 19
20 #define rdmsrl(msr,val) do { \ 20 #define rdmsrl(msr,val) do { \
21 unsigned long l__,h__; \ 21 unsigned long l__,h__; \
22 rdmsr (msr, l__, h__); \ 22 rdmsr (msr, l__, h__); \
23 val = l__; \ 23 val = l__; \
24 val |= ((u64)h__<<32); \ 24 val |= ((u64)h__<<32); \
25 } while(0) 25 } while(0)
26 26
27 static inline void wrmsrl (unsigned long msr, unsigned long long val) 27 static inline void wrmsrl (unsigned long msr, unsigned long long val)
28 { 28 {
29 unsigned long lo, hi; 29 unsigned long lo, hi;
30 lo = (unsigned long) val; 30 lo = (unsigned long) val;
31 hi = val >> 32; 31 hi = val >> 32;
32 wrmsr (msr, lo, hi); 32 wrmsr (msr, lo, hi);
33 } 33 }
34 34
35 /* wrmsr with exception handling */ 35 /* wrmsr with exception handling */
36 #define wrmsr_safe(msr,a,b) ({ int ret__; \ 36 #define wrmsr_safe(msr,a,b) ({ int ret__; \
37 asm volatile("2: wrmsr ; xorl %0,%0\n" \ 37 asm volatile("2: wrmsr ; xorl %0,%0\n" \
38 "1:\n\t" \ 38 "1:\n\t" \
39 ".section .fixup,\"ax\"\n\t" \ 39 ".section .fixup,\"ax\"\n\t" \
40 "3: movl %4,%0 ; jmp 1b\n\t" \ 40 "3: movl %4,%0 ; jmp 1b\n\t" \
41 ".previous\n\t" \ 41 ".previous\n\t" \
42 ".section __ex_table,\"a\"\n" \ 42 ".section __ex_table,\"a\"\n" \
43 " .align 4\n\t" \ 43 " .align 4\n\t" \
44 " .long 2b,3b\n\t" \ 44 " .long 2b,3b\n\t" \
45 ".previous" \ 45 ".previous" \
46 : "=a" (ret__) \ 46 : "=a" (ret__) \
47 : "c" (msr), "0" (a), "d" (b), "i" (-EFAULT));\ 47 : "c" (msr), "0" (a), "d" (b), "i" (-EFAULT));\
48 ret__; }) 48 ret__; })
49 49
50 /* rdmsr with exception handling */
51 #define rdmsr_safe(msr,a,b) ({ int ret__; \
52 asm volatile("2: rdmsr ; xorl %0,%0\n" \
53 "1:\n\t" \
54 ".section .fixup,\"ax\"\n\t" \
55 "3: movl %4,%0 ; jmp 1b\n\t" \
56 ".previous\n\t" \
57 ".section __ex_table,\"a\"\n" \
58 " .align 4\n\t" \
59 " .long 2b,3b\n\t" \
60 ".previous" \
61 : "=r" (ret__), "=a" (*(a)), "=d" (*(b)) \
62 : "c" (msr), "i" (-EFAULT));\
63 ret__; })
64
50 #define rdtsc(low,high) \ 65 #define rdtsc(low,high) \
51 __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high)) 66 __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
52 67
53 #define rdtscl(low) \ 68 #define rdtscl(low) \
54 __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx") 69 __asm__ __volatile__("rdtsc" : "=a" (low) : : "edx")
55 70
56 #define rdtscll(val) \ 71 #define rdtscll(val) \
57 __asm__ __volatile__("rdtsc" : "=A" (val)) 72 __asm__ __volatile__("rdtsc" : "=A" (val))
58 73
59 #define write_tsc(val1,val2) wrmsr(0x10, val1, val2) 74 #define write_tsc(val1,val2) wrmsr(0x10, val1, val2)
60 75
61 #define rdpmc(counter,low,high) \ 76 #define rdpmc(counter,low,high) \
62 __asm__ __volatile__("rdpmc" \ 77 __asm__ __volatile__("rdpmc" \
63 : "=a" (low), "=d" (high) \ 78 : "=a" (low), "=d" (high) \
64 : "c" (counter)) 79 : "c" (counter))
65 80
66 /* symbolic names for some interesting MSRs */ 81 /* symbolic names for some interesting MSRs */
67 /* Intel defined MSRs. */ 82 /* Intel defined MSRs. */
68 #define MSR_IA32_P5_MC_ADDR 0 83 #define MSR_IA32_P5_MC_ADDR 0
69 #define MSR_IA32_P5_MC_TYPE 1 84 #define MSR_IA32_P5_MC_TYPE 1
70 #define MSR_IA32_PLATFORM_ID 0x17 85 #define MSR_IA32_PLATFORM_ID 0x17
71 #define MSR_IA32_EBL_CR_POWERON 0x2a 86 #define MSR_IA32_EBL_CR_POWERON 0x2a
72 87
73 #define MSR_IA32_APICBASE 0x1b 88 #define MSR_IA32_APICBASE 0x1b
74 #define MSR_IA32_APICBASE_BSP (1<<8) 89 #define MSR_IA32_APICBASE_BSP (1<<8)
75 #define MSR_IA32_APICBASE_ENABLE (1<<11) 90 #define MSR_IA32_APICBASE_ENABLE (1<<11)
76 #define MSR_IA32_APICBASE_BASE (0xfffff<<12) 91 #define MSR_IA32_APICBASE_BASE (0xfffff<<12)
77 92
78 #define MSR_IA32_UCODE_WRITE 0x79 93 #define MSR_IA32_UCODE_WRITE 0x79
79 #define MSR_IA32_UCODE_REV 0x8b 94 #define MSR_IA32_UCODE_REV 0x8b
80 95
81 #define MSR_P6_PERFCTR0 0xc1 96 #define MSR_P6_PERFCTR0 0xc1
82 #define MSR_P6_PERFCTR1 0xc2 97 #define MSR_P6_PERFCTR1 0xc2
83 98
84 #define MSR_IA32_BBL_CR_CTL 0x119 99 #define MSR_IA32_BBL_CR_CTL 0x119
85 100
86 #define MSR_IA32_SYSENTER_CS 0x174 101 #define MSR_IA32_SYSENTER_CS 0x174
87 #define MSR_IA32_SYSENTER_ESP 0x175 102 #define MSR_IA32_SYSENTER_ESP 0x175
88 #define MSR_IA32_SYSENTER_EIP 0x176 103 #define MSR_IA32_SYSENTER_EIP 0x176
89 104
90 #define MSR_IA32_MCG_CAP 0x179 105 #define MSR_IA32_MCG_CAP 0x179
91 #define MSR_IA32_MCG_STATUS 0x17a 106 #define MSR_IA32_MCG_STATUS 0x17a
92 #define MSR_IA32_MCG_CTL 0x17b 107 #define MSR_IA32_MCG_CTL 0x17b
93 108
94 /* P4/Xeon+ specific */ 109 /* P4/Xeon+ specific */
95 #define MSR_IA32_MCG_EAX 0x180 110 #define MSR_IA32_MCG_EAX 0x180
96 #define MSR_IA32_MCG_EBX 0x181 111 #define MSR_IA32_MCG_EBX 0x181
97 #define MSR_IA32_MCG_ECX 0x182 112 #define MSR_IA32_MCG_ECX 0x182
98 #define MSR_IA32_MCG_EDX 0x183 113 #define MSR_IA32_MCG_EDX 0x183
99 #define MSR_IA32_MCG_ESI 0x184 114 #define MSR_IA32_MCG_ESI 0x184
100 #define MSR_IA32_MCG_EDI 0x185 115 #define MSR_IA32_MCG_EDI 0x185
101 #define MSR_IA32_MCG_EBP 0x186 116 #define MSR_IA32_MCG_EBP 0x186
102 #define MSR_IA32_MCG_ESP 0x187 117 #define MSR_IA32_MCG_ESP 0x187
103 #define MSR_IA32_MCG_EFLAGS 0x188 118 #define MSR_IA32_MCG_EFLAGS 0x188
104 #define MSR_IA32_MCG_EIP 0x189 119 #define MSR_IA32_MCG_EIP 0x189
105 #define MSR_IA32_MCG_RESERVED 0x18A 120 #define MSR_IA32_MCG_RESERVED 0x18A
106 121
107 #define MSR_P6_EVNTSEL0 0x186 122 #define MSR_P6_EVNTSEL0 0x186
108 #define MSR_P6_EVNTSEL1 0x187 123 #define MSR_P6_EVNTSEL1 0x187
109 124
110 #define MSR_IA32_PERF_STATUS 0x198 125 #define MSR_IA32_PERF_STATUS 0x198
111 #define MSR_IA32_PERF_CTL 0x199 126 #define MSR_IA32_PERF_CTL 0x199
112 127
113 #define MSR_IA32_THERM_CONTROL 0x19a 128 #define MSR_IA32_THERM_CONTROL 0x19a
114 #define MSR_IA32_THERM_INTERRUPT 0x19b 129 #define MSR_IA32_THERM_INTERRUPT 0x19b
115 #define MSR_IA32_THERM_STATUS 0x19c 130 #define MSR_IA32_THERM_STATUS 0x19c
116 #define MSR_IA32_MISC_ENABLE 0x1a0 131 #define MSR_IA32_MISC_ENABLE 0x1a0
117 132
118 #define MSR_IA32_DEBUGCTLMSR 0x1d9 133 #define MSR_IA32_DEBUGCTLMSR 0x1d9
119 #define MSR_IA32_LASTBRANCHFROMIP 0x1db 134 #define MSR_IA32_LASTBRANCHFROMIP 0x1db
120 #define MSR_IA32_LASTBRANCHTOIP 0x1dc 135 #define MSR_IA32_LASTBRANCHTOIP 0x1dc
121 #define MSR_IA32_LASTINTFROMIP 0x1dd 136 #define MSR_IA32_LASTINTFROMIP 0x1dd
122 #define MSR_IA32_LASTINTTOIP 0x1de 137 #define MSR_IA32_LASTINTTOIP 0x1de
123 138
124 #define MSR_IA32_MC0_CTL 0x400 139 #define MSR_IA32_MC0_CTL 0x400
125 #define MSR_IA32_MC0_STATUS 0x401 140 #define MSR_IA32_MC0_STATUS 0x401
126 #define MSR_IA32_MC0_ADDR 0x402 141 #define MSR_IA32_MC0_ADDR 0x402
127 #define MSR_IA32_MC0_MISC 0x403 142 #define MSR_IA32_MC0_MISC 0x403
128 143
129 /* Pentium IV performance counter MSRs */ 144 /* Pentium IV performance counter MSRs */
130 #define MSR_P4_BPU_PERFCTR0 0x300 145 #define MSR_P4_BPU_PERFCTR0 0x300
131 #define MSR_P4_BPU_PERFCTR1 0x301 146 #define MSR_P4_BPU_PERFCTR1 0x301
132 #define MSR_P4_BPU_PERFCTR2 0x302 147 #define MSR_P4_BPU_PERFCTR2 0x302
133 #define MSR_P4_BPU_PERFCTR3 0x303 148 #define MSR_P4_BPU_PERFCTR3 0x303
134 #define MSR_P4_MS_PERFCTR0 0x304 149 #define MSR_P4_MS_PERFCTR0 0x304
135 #define MSR_P4_MS_PERFCTR1 0x305 150 #define MSR_P4_MS_PERFCTR1 0x305
136 #define MSR_P4_MS_PERFCTR2 0x306 151 #define MSR_P4_MS_PERFCTR2 0x306
137 #define MSR_P4_MS_PERFCTR3 0x307 152 #define MSR_P4_MS_PERFCTR3 0x307
138 #define MSR_P4_FLAME_PERFCTR0 0x308 153 #define MSR_P4_FLAME_PERFCTR0 0x308
139 #define MSR_P4_FLAME_PERFCTR1 0x309 154 #define MSR_P4_FLAME_PERFCTR1 0x309
140 #define MSR_P4_FLAME_PERFCTR2 0x30a 155 #define MSR_P4_FLAME_PERFCTR2 0x30a
141 #define MSR_P4_FLAME_PERFCTR3 0x30b 156 #define MSR_P4_FLAME_PERFCTR3 0x30b
142 #define MSR_P4_IQ_PERFCTR0 0x30c 157 #define MSR_P4_IQ_PERFCTR0 0x30c
143 #define MSR_P4_IQ_PERFCTR1 0x30d 158 #define MSR_P4_IQ_PERFCTR1 0x30d
144 #define MSR_P4_IQ_PERFCTR2 0x30e 159 #define MSR_P4_IQ_PERFCTR2 0x30e
145 #define MSR_P4_IQ_PERFCTR3 0x30f 160 #define MSR_P4_IQ_PERFCTR3 0x30f
146 #define MSR_P4_IQ_PERFCTR4 0x310 161 #define MSR_P4_IQ_PERFCTR4 0x310
147 #define MSR_P4_IQ_PERFCTR5 0x311 162 #define MSR_P4_IQ_PERFCTR5 0x311
148 #define MSR_P4_BPU_CCCR0 0x360 163 #define MSR_P4_BPU_CCCR0 0x360
149 #define MSR_P4_BPU_CCCR1 0x361 164 #define MSR_P4_BPU_CCCR1 0x361
150 #define MSR_P4_BPU_CCCR2 0x362 165 #define MSR_P4_BPU_CCCR2 0x362
151 #define MSR_P4_BPU_CCCR3 0x363 166 #define MSR_P4_BPU_CCCR3 0x363
152 #define MSR_P4_MS_CCCR0 0x364 167 #define MSR_P4_MS_CCCR0 0x364
153 #define MSR_P4_MS_CCCR1 0x365 168 #define MSR_P4_MS_CCCR1 0x365
154 #define MSR_P4_MS_CCCR2 0x366 169 #define MSR_P4_MS_CCCR2 0x366
155 #define MSR_P4_MS_CCCR3 0x367 170 #define MSR_P4_MS_CCCR3 0x367
156 #define MSR_P4_FLAME_CCCR0 0x368 171 #define MSR_P4_FLAME_CCCR0 0x368
157 #define MSR_P4_FLAME_CCCR1 0x369 172 #define MSR_P4_FLAME_CCCR1 0x369
158 #define MSR_P4_FLAME_CCCR2 0x36a 173 #define MSR_P4_FLAME_CCCR2 0x36a
159 #define MSR_P4_FLAME_CCCR3 0x36b 174 #define MSR_P4_FLAME_CCCR3 0x36b
160 #define MSR_P4_IQ_CCCR0 0x36c 175 #define MSR_P4_IQ_CCCR0 0x36c
161 #define MSR_P4_IQ_CCCR1 0x36d 176 #define MSR_P4_IQ_CCCR1 0x36d
162 #define MSR_P4_IQ_CCCR2 0x36e 177 #define MSR_P4_IQ_CCCR2 0x36e
163 #define MSR_P4_IQ_CCCR3 0x36f 178 #define MSR_P4_IQ_CCCR3 0x36f
164 #define MSR_P4_IQ_CCCR4 0x370 179 #define MSR_P4_IQ_CCCR4 0x370
165 #define MSR_P4_IQ_CCCR5 0x371 180 #define MSR_P4_IQ_CCCR5 0x371
166 #define MSR_P4_ALF_ESCR0 0x3ca 181 #define MSR_P4_ALF_ESCR0 0x3ca
167 #define MSR_P4_ALF_ESCR1 0x3cb 182 #define MSR_P4_ALF_ESCR1 0x3cb
168 #define MSR_P4_BPU_ESCR0 0x3b2 183 #define MSR_P4_BPU_ESCR0 0x3b2
169 #define MSR_P4_BPU_ESCR1 0x3b3 184 #define MSR_P4_BPU_ESCR1 0x3b3
170 #define MSR_P4_BSU_ESCR0 0x3a0 185 #define MSR_P4_BSU_ESCR0 0x3a0
171 #define MSR_P4_BSU_ESCR1 0x3a1 186 #define MSR_P4_BSU_ESCR1 0x3a1
172 #define MSR_P4_CRU_ESCR0 0x3b8 187 #define MSR_P4_CRU_ESCR0 0x3b8
173 #define MSR_P4_CRU_ESCR1 0x3b9 188 #define MSR_P4_CRU_ESCR1 0x3b9
174 #define MSR_P4_CRU_ESCR2 0x3cc 189 #define MSR_P4_CRU_ESCR2 0x3cc
175 #define MSR_P4_CRU_ESCR3 0x3cd 190 #define MSR_P4_CRU_ESCR3 0x3cd
176 #define MSR_P4_CRU_ESCR4 0x3e0 191 #define MSR_P4_CRU_ESCR4 0x3e0
177 #define MSR_P4_CRU_ESCR5 0x3e1 192 #define MSR_P4_CRU_ESCR5 0x3e1
178 #define MSR_P4_DAC_ESCR0 0x3a8 193 #define MSR_P4_DAC_ESCR0 0x3a8
179 #define MSR_P4_DAC_ESCR1 0x3a9 194 #define MSR_P4_DAC_ESCR1 0x3a9
180 #define MSR_P4_FIRM_ESCR0 0x3a4 195 #define MSR_P4_FIRM_ESCR0 0x3a4
181 #define MSR_P4_FIRM_ESCR1 0x3a5 196 #define MSR_P4_FIRM_ESCR1 0x3a5
182 #define MSR_P4_FLAME_ESCR0 0x3a6 197 #define MSR_P4_FLAME_ESCR0 0x3a6
183 #define MSR_P4_FLAME_ESCR1 0x3a7 198 #define MSR_P4_FLAME_ESCR1 0x3a7
184 #define MSR_P4_FSB_ESCR0 0x3a2 199 #define MSR_P4_FSB_ESCR0 0x3a2
185 #define MSR_P4_FSB_ESCR1 0x3a3 200 #define MSR_P4_FSB_ESCR1 0x3a3
186 #define MSR_P4_IQ_ESCR0 0x3ba 201 #define MSR_P4_IQ_ESCR0 0x3ba
187 #define MSR_P4_IQ_ESCR1 0x3bb 202 #define MSR_P4_IQ_ESCR1 0x3bb
188 #define MSR_P4_IS_ESCR0 0x3b4 203 #define MSR_P4_IS_ESCR0 0x3b4
189 #define MSR_P4_IS_ESCR1 0x3b5 204 #define MSR_P4_IS_ESCR1 0x3b5
190 #define MSR_P4_ITLB_ESCR0 0x3b6 205 #define MSR_P4_ITLB_ESCR0 0x3b6
191 #define MSR_P4_ITLB_ESCR1 0x3b7 206 #define MSR_P4_ITLB_ESCR1 0x3b7
192 #define MSR_P4_IX_ESCR0 0x3c8 207 #define MSR_P4_IX_ESCR0 0x3c8
193 #define MSR_P4_IX_ESCR1 0x3c9 208 #define MSR_P4_IX_ESCR1 0x3c9
194 #define MSR_P4_MOB_ESCR0 0x3aa 209 #define MSR_P4_MOB_ESCR0 0x3aa
195 #define MSR_P4_MOB_ESCR1 0x3ab 210 #define MSR_P4_MOB_ESCR1 0x3ab
196 #define MSR_P4_MS_ESCR0 0x3c0 211 #define MSR_P4_MS_ESCR0 0x3c0
197 #define MSR_P4_MS_ESCR1 0x3c1 212 #define MSR_P4_MS_ESCR1 0x3c1
198 #define MSR_P4_PMH_ESCR0 0x3ac 213 #define MSR_P4_PMH_ESCR0 0x3ac
199 #define MSR_P4_PMH_ESCR1 0x3ad 214 #define MSR_P4_PMH_ESCR1 0x3ad
200 #define MSR_P4_RAT_ESCR0 0x3bc 215 #define MSR_P4_RAT_ESCR0 0x3bc
201 #define MSR_P4_RAT_ESCR1 0x3bd 216 #define MSR_P4_RAT_ESCR1 0x3bd
202 #define MSR_P4_SAAT_ESCR0 0x3ae 217 #define MSR_P4_SAAT_ESCR0 0x3ae
203 #define MSR_P4_SAAT_ESCR1 0x3af 218 #define MSR_P4_SAAT_ESCR1 0x3af
204 #define MSR_P4_SSU_ESCR0 0x3be 219 #define MSR_P4_SSU_ESCR0 0x3be
205 #define MSR_P4_SSU_ESCR1 0x3bf /* guess: not defined in manual */ 220 #define MSR_P4_SSU_ESCR1 0x3bf /* guess: not defined in manual */
206 #define MSR_P4_TBPU_ESCR0 0x3c2 221 #define MSR_P4_TBPU_ESCR0 0x3c2
207 #define MSR_P4_TBPU_ESCR1 0x3c3 222 #define MSR_P4_TBPU_ESCR1 0x3c3
208 #define MSR_P4_TC_ESCR0 0x3c4 223 #define MSR_P4_TC_ESCR0 0x3c4
209 #define MSR_P4_TC_ESCR1 0x3c5 224 #define MSR_P4_TC_ESCR1 0x3c5
210 #define MSR_P4_U2L_ESCR0 0x3b0 225 #define MSR_P4_U2L_ESCR0 0x3b0
211 #define MSR_P4_U2L_ESCR1 0x3b1 226 #define MSR_P4_U2L_ESCR1 0x3b1
212 227
213 /* AMD Defined MSRs */ 228 /* AMD Defined MSRs */
214 #define MSR_K6_EFER 0xC0000080 229 #define MSR_K6_EFER 0xC0000080
215 #define MSR_K6_STAR 0xC0000081 230 #define MSR_K6_STAR 0xC0000081
216 #define MSR_K6_WHCR 0xC0000082 231 #define MSR_K6_WHCR 0xC0000082
217 #define MSR_K6_UWCCR 0xC0000085 232 #define MSR_K6_UWCCR 0xC0000085
218 #define MSR_K6_EPMR 0xC0000086 233 #define MSR_K6_EPMR 0xC0000086
219 #define MSR_K6_PSOR 0xC0000087 234 #define MSR_K6_PSOR 0xC0000087
220 #define MSR_K6_PFIR 0xC0000088 235 #define MSR_K6_PFIR 0xC0000088
221 236
222 #define MSR_K7_EVNTSEL0 0xC0010000 237 #define MSR_K7_EVNTSEL0 0xC0010000
223 #define MSR_K7_EVNTSEL1 0xC0010001 238 #define MSR_K7_EVNTSEL1 0xC0010001
224 #define MSR_K7_EVNTSEL2 0xC0010002 239 #define MSR_K7_EVNTSEL2 0xC0010002
225 #define MSR_K7_EVNTSEL3 0xC0010003 240 #define MSR_K7_EVNTSEL3 0xC0010003
226 #define MSR_K7_PERFCTR0 0xC0010004 241 #define MSR_K7_PERFCTR0 0xC0010004
227 #define MSR_K7_PERFCTR1 0xC0010005 242 #define MSR_K7_PERFCTR1 0xC0010005
228 #define MSR_K7_PERFCTR2 0xC0010006 243 #define MSR_K7_PERFCTR2 0xC0010006
229 #define MSR_K7_PERFCTR3 0xC0010007 244 #define MSR_K7_PERFCTR3 0xC0010007
230 #define MSR_K7_HWCR 0xC0010015 245 #define MSR_K7_HWCR 0xC0010015
231 #define MSR_K7_CLK_CTL 0xC001001b 246 #define MSR_K7_CLK_CTL 0xC001001b
232 #define MSR_K7_FID_VID_CTL 0xC0010041 247 #define MSR_K7_FID_VID_CTL 0xC0010041
233 #define MSR_K7_FID_VID_STATUS 0xC0010042 248 #define MSR_K7_FID_VID_STATUS 0xC0010042
234 249
235 /* extended feature register */ 250 /* extended feature register */
236 #define MSR_EFER 0xc0000080 251 #define MSR_EFER 0xc0000080
237 252
238 /* EFER bits: */ 253 /* EFER bits: */
239 254
240 /* Execute Disable enable */ 255 /* Execute Disable enable */
241 #define _EFER_NX 11 256 #define _EFER_NX 11
242 #define EFER_NX (1<<_EFER_NX) 257 #define EFER_NX (1<<_EFER_NX)
243 258
244 /* Centaur-Hauls/IDT defined MSRs. */ 259 /* Centaur-Hauls/IDT defined MSRs. */
245 #define MSR_IDT_FCR1 0x107 260 #define MSR_IDT_FCR1 0x107
246 #define MSR_IDT_FCR2 0x108 261 #define MSR_IDT_FCR2 0x108
247 #define MSR_IDT_FCR3 0x109 262 #define MSR_IDT_FCR3 0x109
248 #define MSR_IDT_FCR4 0x10a 263 #define MSR_IDT_FCR4 0x10a
249 264
250 #define MSR_IDT_MCR0 0x110 265 #define MSR_IDT_MCR0 0x110
251 #define MSR_IDT_MCR1 0x111 266 #define MSR_IDT_MCR1 0x111
252 #define MSR_IDT_MCR2 0x112 267 #define MSR_IDT_MCR2 0x112
253 #define MSR_IDT_MCR3 0x113 268 #define MSR_IDT_MCR3 0x113
254 #define MSR_IDT_MCR4 0x114 269 #define MSR_IDT_MCR4 0x114
255 #define MSR_IDT_MCR5 0x115 270 #define MSR_IDT_MCR5 0x115
256 #define MSR_IDT_MCR6 0x116 271 #define MSR_IDT_MCR6 0x116
257 #define MSR_IDT_MCR7 0x117 272 #define MSR_IDT_MCR7 0x117
258 #define MSR_IDT_MCR_CTRL 0x120 273 #define MSR_IDT_MCR_CTRL 0x120
259 274
260 /* VIA Cyrix defined MSRs*/ 275 /* VIA Cyrix defined MSRs*/
261 #define MSR_VIA_FCR 0x1107 276 #define MSR_VIA_FCR 0x1107
262 #define MSR_VIA_LONGHAUL 0x110a 277 #define MSR_VIA_LONGHAUL 0x110a
263 #define MSR_VIA_RNG 0x110b 278 #define MSR_VIA_RNG 0x110b
264 #define MSR_VIA_BCR2 0x1147 279 #define MSR_VIA_BCR2 0x1147
265 280
266 /* Transmeta defined MSRs */ 281 /* Transmeta defined MSRs */
267 #define MSR_TMTA_LONGRUN_CTRL 0x80868010 282 #define MSR_TMTA_LONGRUN_CTRL 0x80868010
268 #define MSR_TMTA_LONGRUN_FLAGS 0x80868011 283 #define MSR_TMTA_LONGRUN_FLAGS 0x80868011
269 #define MSR_TMTA_LRTI_READOUT 0x80868018 284 #define MSR_TMTA_LRTI_READOUT 0x80868018
270 #define MSR_TMTA_LRTI_VOLT_MHZ 0x8086801a 285 #define MSR_TMTA_LRTI_VOLT_MHZ 0x8086801a
271 286
272 #endif /* __ASM_MSR_H */ 287 #endif /* __ASM_MSR_H */
273 288