Merge with Linux 2.5.72.
[linux-2.6/linux-mips.git] / arch / ia64 / sn / kernel / misctest.c
blob974c95e6be175c489bd805d79ba570b9aa4be59e
1 /*
3 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive
5 * for more details.
7 * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
8 */
10 #include <linux/kernel.h>
11 #include <linux/init.h>
12 #include <linux/delay.h>
13 #include <linux/interrupt.h>
14 #include <asm/sn/sn_sal.h>
15 #include <asm/sn/sn_cpuid.h>
16 #include <asm/processor.h>
17 #include <asm/pgtable.h>
18 #include <asm/page.h>
19 #include <asm/timex.h>
20 #include <asm/io.h>
21 #include <asm/irq.h>
22 #include <asm/sn/intr.h>
23 #include <asm/hw_irq.h>
24 #include <asm/sn/leds.h>
26 extern int autotest_enabled;
27 long mcatest=0, debug0, debug1, debug2, debug3;
29 #define HDELAY(t) (IS_RUNNING_ON_SIMULATOR() ? udelay(1) : udelay(t))
31 /*
32 * mcatest
33 * mactest contains a decimal number (RPTT) where
34 * R - flag, if non zero, run forever
36 * P - identifies when to run the test
37 * 0 execute test at cpu 0 early init
38 * 1 execute test at cpu 0 idle
39 * 2 execute test at last (highest numbered) cpu idle
40 * 3 execute test on all cpus at idle
42 * TT- identifies test to run
43 * 01 = MCA via dup TLB dropin
44 * 02 = MCA via garbage address
45 * 03 = lfetch via garbage address
46 * 05 = INIT self
47 * 06 = INIT other cpu
48 * 07 = INIT non-existent cpu
49 * 10 = IPI stress test. Target cpu 0
50 * 11 = IPI stress test. Target all cpus
51 * 12 = TLB stress test
52 * 13 = Park cpu (spinloop)
53 * 14 = One shot TLB test with tlb spinlock
54 * 15 = One shot TLB test
55 * 16 = One shot TLB test sync'ed with RTC
56 * 20 = set led to the cpuid & spin.
57 * 21 = Try mixed cache/uncached refs & see what happens
58 * 22 = Call SAL reboot
59 * 23 = Call PAL halt
61 static int __init set_mcatest(char *str)
63 int val;
64 get_option(&str, &val);
65 mcatest = val;
66 return 1;
68 __setup("mcatest=", set_mcatest);
70 static int __init set_debug0(char *str)
72 int val;
73 get_option(&str, &val);
74 debug0 = val;
75 return 1;
77 __setup("debug0=", set_debug0);
79 static int __init set_debug1(char *str)
81 int val;
82 get_option(&str, &val);
83 debug1 = val;
84 return 1;
86 __setup("debug1=", set_debug1);
88 static int __init set_debug2(char *str)
90 int val;
91 get_option(&str, &val);
92 debug2 = val;
93 return 1;
95 __setup("debug2=", set_debug2);
97 static int __init set_debug3(char *str)
99 int val;
100 get_option(&str, &val);
101 debug3 = val;
102 return 1;
104 __setup("debug3=", set_debug3);
106 static volatile int go;
108 static void
109 do_sync(int pos) {
110 if (pos != 3)
111 return;
112 else if (smp_processor_id() == 0)
113 go = 1;
114 else
115 while (!go);
118 static void
119 sgi_mcatest_bkpt(void)
125 * Optional test
126 * pos - 0 called from early init
127 * pos - called when cpu about to go idle (fully initialized
129 void
130 sgi_mcatest(int pos)
132 long spos, test, repeat;
133 int cpu, curcpu, i, n;
135 //if (IS_RUNNING_ON_SIMULATOR()) mcatest=1323;
136 repeat = mcatest/1000;
137 spos = (mcatest/100)%10;
138 test = mcatest % 100;
139 curcpu = smp_processor_id();
141 if ( mcatest == 0 || !((pos == 0 && spos == 0) ||
142 (pos == 1 && spos == 3) ||
143 (pos == 1 && spos == 1 && curcpu == 0) ||
144 (pos == 1 && spos == 2 && curcpu == smp_num_cpus-1)))
145 return;
147 again:
148 if (test == 1 || test == 2 || test == 3) {
149 void zzzmca(int);
150 printk("CPU %d: About to cause unexpected MCA\n", curcpu);
151 HDELAY(100000);
152 sgi_mcatest_bkpt();
153 do_sync(spos);
155 zzzmca(test-1);
157 HDELAY(100000);
160 if (test == 4) {
161 long result, adrs[] = {0xe0021000009821e0UL, 0xc0003f3000000000UL, 0xc0000081101c0000UL, 0xc00000180e021004UL, 0xc00000180e022004UL, 0xc00000180e023004UL };
162 long size[] = {1,2,4,8};
163 int r, i, j, k;
165 for (k=0; k<2; k++) {
166 for (i=0; i<6; i++) {
167 for (j=0; j<4; j++) {
168 printk("Probing 0x%lx, size %ld\n", adrs[i], size[j]);
169 result = -1;
170 r = ia64_sn_probe_io_slot (adrs[i], size[j], &result);
171 printk(" status %d, val 0x%lx\n", r, result);
172 udelay(100000);
179 if (test == 5) {
180 cpu = curcpu;
181 printk("CPU %d: About to send INIT to self (cpu %d)\n", curcpu, cpu);
182 HDELAY(100000);
183 sgi_mcatest_bkpt();
184 do_sync(spos);
186 platform_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0);
188 HDELAY(100000);
189 printk("CPU %d: Returned from INIT\n", curcpu);
192 if (test == 6) {
193 cpu = curcpu ^ 1;
194 printk("CPU %d: About to send INIT to other cpu (cpu %d)\n", curcpu, cpu);
195 HDELAY(100000);
196 sgi_mcatest_bkpt();
197 do_sync(spos);
199 platform_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0);
201 HDELAY(100000);
202 printk("CPU %d: Done\n", curcpu);
205 if (test == 7) {
206 printk("CPU %d: About to send INIT to non-existent cpu\n", curcpu);
207 HDELAY(100000);
208 sgi_mcatest_bkpt();
209 do_sync(spos);
211 sn_send_IPI_phys(0xffff, 0, IA64_IPI_DM_INIT);
213 HDELAY(100000);
214 printk("CPU %d: Done\n", curcpu);
217 if (test == 10) {
218 n = IS_RUNNING_ON_SIMULATOR() ? 10 : 10000000;
219 cpu = 0;
220 printk("CPU %d: IPI stress test. Target cpu 0\n", curcpu);
221 HDELAY(100000);
222 sgi_mcatest_bkpt();
223 do_sync(spos);
225 for (i=0; i<n; i++)
226 platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0);
228 HDELAY(100000);
229 printk("CPU %d: Done\n", curcpu);
232 if (test == 11) {
233 n = IS_RUNNING_ON_SIMULATOR() ? 100 : 10000000;
234 printk("CPU %d: IPI stress test. Target all cpus\n", curcpu);
235 HDELAY(100000);
236 sgi_mcatest_bkpt();
237 do_sync(spos);
239 for (i=0; i<n; i++)
240 for (cpu=0; cpu<smp_num_cpus; cpu++)
241 if (smp_num_cpus > 2 && cpu != curcpu)
242 platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0);
244 HDELAY(100000);
245 printk("CPU %d: Done\n", curcpu);
248 if (test == 12) {
249 long adr = 0xe002200000000000UL;
250 n = IS_RUNNING_ON_SIMULATOR() ? 1000 : 100000;
251 printk("CPU %d: TLB flush stress test\n", curcpu);
252 HDELAY(100000);
253 sgi_mcatest_bkpt();
254 do_sync(spos);
256 for (i=0; i<n; i++)
257 platform_global_tlb_purge(adr, adr+25*PAGE_SIZE, 14);
259 HDELAY(100000);
260 printk("CPU %d: Done\n", curcpu);
263 if (test == 13) {
264 printk("CPU %d: Park cpu in spinloop\n", curcpu);
265 while(1);
267 if (test == 14 || test == 15 || test == 16 || test == 17) {
268 long adr = 0xe002200000000000UL;
269 static int inited=0;
270 if (inited == 0) {
271 if (debug0 == 0) debug0 = 1;
272 repeat = 1;
273 do_sync(spos);
274 if (curcpu >= smp_num_cpus-2) {
275 printk("Parking cpu %d\n", curcpu);
276 local_irq_disable();
277 while(1);
278 } else {
279 printk("Waiting cpu %d\n", curcpu);
280 HDELAY(1000000);
282 HDELAY(1000000);
283 inited = 1;
285 if (test == 16 || test == 17) {
286 unsigned long t, shift, mask;
287 mask = (smp_num_cpus > 16) ? 0x1f : 0xf;
288 shift = 25-debug1;
289 do {
290 t = get_cycles();
291 if (IS_RUNNING_ON_SIMULATOR())
292 t = (t>>8);
293 else
294 t = (t>>shift);
295 t = t & mask;
296 } while (t == curcpu);
297 do {
298 t = get_cycles();
299 if (IS_RUNNING_ON_SIMULATOR())
300 t = (t>>8);
301 else
302 t = (t>>shift);
303 t = t & mask;
304 } while (t != curcpu);
306 if(debug3) printk("CPU %d: One TLB start\n", curcpu);
307 if (test != 17) platform_global_tlb_purge(adr, adr+PAGE_SIZE*debug0, 14);
308 if(debug3) printk("CPU %d: One TLB flush done\n", curcpu);
310 if (test == 20) {
311 local_irq_disable();
312 set_led_bits(smp_processor_id(), 0xff);
313 while(1);
315 if (test == 21) {
316 extern long ia64_mca_stack[];
317 int i, n;
318 volatile long *p, *up;
319 p = (volatile long*)__imva(ia64_mca_stack);
320 up = (volatile long*)(__pa(p) | __IA64_UNCACHED_OFFSET);
322 if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ get data in cache\n");
323 for (n=0, i=0; i<100; i++)
324 n += *(p+i);
325 if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ Make uncached refs to same data\n");
326 for (n=0, i=0; i<100; i++)
327 n += *(up+i);
328 if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ dirty the data via cached refs\n");
329 for (n=0, i=0; i<100; i++)
330 *(p+i) = i;
331 if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ Make uncached refs to same data\n");
332 for (n=0, i=0; i<100; i++)
333 n += *(up+i);
334 if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ Flushing cache\n");
335 for (n=0, i=0; i<100; i++)
336 ia64_fc((void*)(p+i));
337 printk("ZZZ done\n");
339 if (test == 21) {
340 int i;
341 volatile long tb, t[10];
342 for (i=0; i<10; i++) {
343 tb = debug3+ia64_get_itc();
344 sgi_mcatest_bkpt();
345 t[i] = ia64_get_itc() - tb;
347 for (i=0; i<10; i++) {
348 printk("ZZZ NULL 0x%lx\n", t[i]);
350 for (i=0; i<10; i++) {
351 tb = debug3+ia64_get_itc();
352 ia64_pal_call_static(PAL_MC_DRAIN, 0, 0, 0, 0);
353 t[i] = ia64_get_itc() - tb;
355 for (i=0; i<10; i++) {
356 printk("ZZZ DRAIN 0x%lx\n", t[i]);
359 if (test == 22) {
360 extern void machine_restart(char*);
361 printk("ZZZ machine_restart\n");
362 machine_restart(0);
364 if (test == 23) {
365 printk("ZZZ ia64_pal_halt_light\n");
366 ia64_pal_halt_light();
368 if (repeat)
369 goto again;