974c95e6be175c489bd805d79ba570b9aa4be59e
[linux-flexiantxendom0-3.2.10.git] / arch / ia64 / sn / kernel / misctest.c
1 /* 
2  *
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.
6  *
7  * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
8  */
9
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>
25
26 extern  int autotest_enabled;
27 long    mcatest=0, debug0, debug1, debug2, debug3;
28
29 #define HDELAY(t)       (IS_RUNNING_ON_SIMULATOR() ? udelay(1) : udelay(t))
30
31 /* 
32  * mcatest
33  *      mactest contains a decimal number (RPTT) where
34  *              R - flag, if non zero, run forever
35  *
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
41  *
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
60  */
61 static int __init set_mcatest(char *str)
62 {
63         int     val;
64         get_option(&str, &val);
65         mcatest = val;
66         return 1;
67 }
68 __setup("mcatest=", set_mcatest);
69
70 static int __init set_debug0(char *str)
71 {
72         int     val;
73         get_option(&str, &val);
74         debug0 = val;
75         return 1;
76 }
77 __setup("debug0=", set_debug0);
78
79 static int __init set_debug1(char *str)
80 {
81         int     val;
82         get_option(&str, &val);
83         debug1 = val;
84         return 1;
85 }
86 __setup("debug1=", set_debug1);
87
88 static int __init set_debug2(char *str)
89 {
90         int     val;
91         get_option(&str, &val);
92         debug2 = val;
93         return 1;
94 }
95 __setup("debug2=", set_debug2);
96
97 static int __init set_debug3(char *str)
98 {
99         int     val;
100         get_option(&str, &val);
101         debug3 = val;
102         return 1;
103 }
104 __setup("debug3=", set_debug3);
105
106 static volatile int     go;
107
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);
116 }
117
118 static void
119 sgi_mcatest_bkpt(void)
120 {
121 }
122
123
124 /*
125  * Optional test
126  *      pos - 0 called from early init
127  *      pos - called when cpu about to go idle (fully initialized
128  */
129 void
130 sgi_mcatest(int pos)
131 {
132         long    spos, test, repeat;
133         int     cpu, curcpu, i, n;
134
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();
140
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;
146              
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);
154
155                 zzzmca(test-1);
156         
157                 HDELAY(100000);
158         }
159
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;
164
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);
173                                 }
174                         }
175                 }
176
177         }
178
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);
185
186                 platform_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0);
187                 
188                 HDELAY(100000);
189                 printk("CPU %d: Returned from INIT\n", curcpu);
190         }
191
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);
198
199                 platform_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0);
200
201                 HDELAY(100000);
202                 printk("CPU %d: Done\n", curcpu);
203         }
204
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);
210
211                 sn_send_IPI_phys(0xffff, 0, IA64_IPI_DM_INIT);
212
213                 HDELAY(100000);
214                 printk("CPU %d: Done\n", curcpu);
215         }
216
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);
224
225                 for (i=0; i<n; i++)
226                         platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0);
227
228                 HDELAY(100000);
229                 printk("CPU %d: Done\n", curcpu);
230         }
231
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);
238
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);
243
244                 HDELAY(100000);
245                 printk("CPU %d: Done\n", curcpu);
246         }
247
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);
255
256                 for (i=0; i<n; i++)
257                         platform_global_tlb_purge(adr, adr+25*PAGE_SIZE, 14);
258
259                 HDELAY(100000);
260                 printk("CPU %d: Done\n", curcpu);
261         }
262         
263         if (test == 13) {
264                 printk("CPU %d: Park cpu in spinloop\n", curcpu);
265                 while(1);
266         }
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);
281                         }
282                         HDELAY(1000000);
283                         inited = 1;
284                 }
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);
305                 }
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);
309         }
310         if (test == 20) {
311                 local_irq_disable();
312                 set_led_bits(smp_processor_id(), 0xff);
313                 while(1);
314         }
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);
321
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");
338         }
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;
346                 }
347                 for (i=0; i<10; i++) {
348                         printk("ZZZ NULL  0x%lx\n", t[i]);
349                 }
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;
354                 }
355                 for (i=0; i<10; i++) {
356                         printk("ZZZ DRAIN 0x%lx\n", t[i]);
357                 }
358         }
359         if (test == 22) {
360                 extern void machine_restart(char*);
361                 printk("ZZZ machine_restart\n");
362                 machine_restart(0);
363         }
364         if (test == 23) {
365                 printk("ZZZ ia64_pal_halt_light\n");
366                 ia64_pal_halt_light();
367         }
368         if (repeat)
369                 goto again;
370
371 }