Process running / destruction outline
[akaros.git] / kern / src / testing.c
1 #ifdef __DEPUTY__
2 #pragma nodeputy
3 #endif
4
5 #include <arch/mmu.h>
6 #include <arch/arch.h>
7 #include <smp.h>
8
9 #include <ros/memlayout.h>
10
11 #include <atomic.h>
12 #include <stdio.h>
13 #include <assert.h>
14 #include <string.h>
15 #include <testing.h>
16 #include <trap.h>
17 #include <process.h>
18 #include <syscall.h>
19 #include <timing.h>
20 #include <kfs.h>
21
22 #define test_vector 0xeb
23
24 #ifdef __i386__
25
26 void test_ipi_sending(void)
27 {
28         extern handler_t interrupt_handlers[];
29         int8_t state = 0;
30
31         register_interrupt_handler(interrupt_handlers, test_vector,
32                                    test_hello_world_handler, 0);
33         enable_irqsave(&state);
34         cprintf("\nCORE 0 sending broadcast\n");
35         send_broadcast_ipi(test_vector);
36         udelay(3000000);
37         cprintf("\nCORE 0 sending all others\n");
38         send_all_others_ipi(test_vector);
39         udelay(3000000);
40         cprintf("\nCORE 0 sending self\n");
41         send_self_ipi(test_vector);
42         udelay(3000000);
43         cprintf("\nCORE 0 sending ipi to physical 1\n");
44         send_ipi(0x01, 0, test_vector);
45         udelay(3000000);
46         cprintf("\nCORE 0 sending ipi to physical 2\n");
47         send_ipi(0x02, 0, test_vector);
48         udelay(3000000);
49         cprintf("\nCORE 0 sending ipi to physical 3\n");
50         send_ipi(0x03, 0, test_vector);
51         udelay(3000000);
52         cprintf("\nCORE 0 sending ipi to physical 15\n");
53         send_ipi(0x0f, 0, test_vector);
54         udelay(3000000);
55         cprintf("\nCORE 0 sending ipi to logical 2\n");
56         send_ipi(0x02, 1, test_vector);
57         udelay(3000000);
58         cprintf("\nCORE 0 sending ipi to logical 1\n");
59         send_ipi(0x01, 1, test_vector);
60         udelay(3000000);
61         cprintf("\nDone!\n");
62         disable_irqsave(&state);
63 }
64
65 // Note this never returns and will muck with any other timer work
66 void test_pic_reception(void)
67 {
68         register_interrupt_handler(interrupt_handlers, 0x20, test_hello_world_handler, 0);
69         pit_set_timer(100,TIMER_RATEGEN); // totally arbitrary time
70         pic_unmask_irq(0);
71         cprintf("PIC1 Mask = 0x%04x\n", inb(PIC1_DATA));
72         cprintf("PIC2 Mask = 0x%04x\n", inb(PIC2_DATA));
73         unmask_lapic_lvt(LAPIC_LVT_LINT0);
74         cprintf("Core %d's LINT0: 0x%08x\n", core_id(), read_mmreg32(LAPIC_LVT_LINT0));
75         enable_irq();
76         while(1);
77 }
78
79 #endif // __i386__
80
81 void test_print_info(void)
82 {
83         cprintf("\nCORE 0 asking all cores to print info:\n");
84         smp_call_function_all(test_print_info_handler, 0, 0);
85         cprintf("\nDone!\n");
86 }
87
88
89 extern uint8_t num_cpus;
90 barrier_t test_cpu_array;
91
92 void test_barrier(void)
93 {
94         cprintf("Core 0 initializing barrier\n");
95         init_barrier(&test_cpu_array, num_cpus);
96         cprintf("Core 0 asking all cores to print ids, barrier, rinse, repeat\n");
97         smp_call_function_all(test_barrier_handler, 0, 0);
98 }
99
100 void test_interrupts_irqsave(void)
101 {
102         int8_t state = 0;
103         printd("Testing Nesting Enabling first, turning ints off:\n");
104         disable_irq();
105         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
106         assert(!irq_is_enabled());
107         printd("Enabling IRQSave\n");
108         enable_irqsave(&state);
109         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
110         assert(irq_is_enabled());
111         printd("Enabling IRQSave Again\n");
112         enable_irqsave(&state);
113         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
114         assert(irq_is_enabled());
115         printd("Disabling IRQSave Once\n");
116         disable_irqsave(&state);
117         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
118         assert(irq_is_enabled());
119         printd("Disabling IRQSave Again\n");
120         disable_irqsave(&state);
121         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
122         assert(!irq_is_enabled());
123         printd("Done.  Should have been 0, 200, 200, 200, 0\n");
124
125         printd("Testing Nesting Disabling first, turning ints on:\n");
126         state = 0;
127         enable_irq();
128         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
129         assert(irq_is_enabled());
130         printd("Disabling IRQSave Once\n");
131         disable_irqsave(&state);
132         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
133         assert(!irq_is_enabled());
134         printd("Disabling IRQSave Again\n");
135         disable_irqsave(&state);
136         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
137         assert(!irq_is_enabled());
138         printd("Enabling IRQSave Once\n");
139         enable_irqsave(&state);
140         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
141         assert(!irq_is_enabled());
142         printd("Enabling IRQSave Again\n");
143         enable_irqsave(&state);
144         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
145         assert(irq_is_enabled());
146         printd("Done.  Should have been 200, 0, 0, 0, 200 \n");
147
148         state = 0;
149         disable_irq();
150         printd("Ints are off, enabling then disabling.\n");
151         enable_irqsave(&state);
152         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
153         assert(irq_is_enabled());
154         disable_irqsave(&state);
155         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
156         assert(!irq_is_enabled());
157         printd("Done.  Should have been 200, 0\n");
158
159         state = 0;
160         enable_irq();
161         printd("Ints are on, enabling then disabling.\n");
162         enable_irqsave(&state);
163         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
164         assert(irq_is_enabled());
165         disable_irqsave(&state);
166         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
167         assert(irq_is_enabled());
168         printd("Done.  Should have been 200, 200\n");
169
170         state = 0;
171         disable_irq();
172         printd("Ints are off, disabling then enabling.\n");
173         disable_irqsave(&state);
174         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
175         assert(!irq_is_enabled());
176         enable_irqsave(&state);
177         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
178         assert(!irq_is_enabled());
179         printd("Done.  Should have been 0, 0\n");
180
181         state = 0;
182         enable_irq();
183         printd("Ints are on, disabling then enabling.\n");
184         disable_irqsave(&state);
185         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
186         assert(!irq_is_enabled());
187         enable_irqsave(&state);
188         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
189         assert(irq_is_enabled());
190         printd("Done.  Should have been 0, 200\n");
191
192         disable_irq();
193         cprintf("Passed enable_irqsave tests\n");
194 }
195
196 void test_bitmasks(void)
197 {
198 #define masksize 67
199         DECL_BITMASK(mask, masksize);
200         printk("size of mask %d\n", sizeof(mask));
201         CLR_BITMASK(mask, masksize);
202         PRINT_BITMASK(mask, masksize);
203         printk("cleared\n");
204         SET_BITMASK_BIT(mask, 0);
205         SET_BITMASK_BIT(mask, 11);
206         SET_BITMASK_BIT(mask, 17);
207         SET_BITMASK_BIT(mask, masksize-1);
208         printk("bits set\n");
209         PRINT_BITMASK(mask, masksize);
210         DECL_BITMASK(mask2, masksize);
211         COPY_BITMASK(mask2, mask, masksize);
212         printk("copy of original mask, should be the same as the prev\n");
213         PRINT_BITMASK(mask2, masksize);
214         CLR_BITMASK_BIT(mask, 11);
215         printk("11 cleared\n");
216         PRINT_BITMASK(mask, masksize);
217         printk("bit 17 is %d (should be 1)\n", GET_BITMASK_BIT(mask, 17));
218         printk("bit 11 is %d (should be 0)\n", GET_BITMASK_BIT(mask, 11));
219         FILL_BITMASK(mask, masksize);
220         PRINT_BITMASK(mask, masksize);
221         printk("should be all 1's, except for a few at the end\n");
222         printk("Is Clear?: %d (should be 0)\n", BITMASK_IS_CLEAR(mask,masksize));
223         CLR_BITMASK(mask, masksize);
224         PRINT_BITMASK(mask, masksize);
225         printk("Is Clear?: %d (should be 1)\n", BITMASK_IS_CLEAR(mask,masksize));
226         printk("should be cleared\n");
227 }
228
229 checklist_t* the_global_list;
230
231 void test_checklist_handler(trapframe_t *tf, void* data)
232 {
233         udelay(1000000);
234         cprintf("down_checklist(%x,%d)\n", the_global_list, core_id());
235         down_checklist(the_global_list);
236 }
237
238 extern uint8_t num_cpus;
239
240 void test_checklists(void)
241 {
242         INIT_CHECKLIST(a_list, MAX_NUM_CPUS);
243         the_global_list = &a_list;
244         printk("Checklist Build, mask size: %d\n", sizeof(a_list.mask.bits));
245         printk("mask\n");
246         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
247         SET_BITMASK_BIT(a_list.mask.bits, 11);
248         printk("Set bit 11\n");
249         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
250
251         CLR_BITMASK(a_list.mask.bits, a_list.mask.size);
252         INIT_CHECKLIST_MASK(a_mask, MAX_NUM_CPUS);
253         FILL_BITMASK(a_mask.bits, num_cpus);
254         //CLR_BITMASK_BIT(a_mask.bits, core_id());
255         //SET_BITMASK_BIT(a_mask.bits, 1);
256         //printk("New mask (1, 17, 25):\n");
257         printk("Created new mask, filled up to num_cpus\n");
258         PRINT_BITMASK(a_mask.bits, a_mask.size);
259         printk("committing new mask\n");
260         commit_checklist_wait(&a_list, &a_mask);
261         printk("Old mask (copied onto):\n");
262         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
263         //smp_call_function_single(1, test_checklist_handler, 0, 0);
264
265         smp_call_function_all(test_checklist_handler, 0, 0);
266
267         printk("Waiting on checklist\n");
268         waiton_checklist(&a_list);
269         printk("Done Waiting!\n");
270
271 }
272
273 atomic_t a, b, c;
274
275 void test_incrementer_handler(trapframe_t *tf, void* data)
276 {
277         assert(data);
278         atomic_inc((atomic_t*)data);
279 }
280
281 void test_null_handler(trapframe_t *tf, void* data)
282 {
283         asm volatile("nop");
284 }
285
286 void test_smp_call_functions(void)
287 {
288         int i;
289         atomic_init(&a, 0);
290         atomic_init(&b, 0);
291         atomic_init(&c, 0);
292         handler_wrapper_t *waiter0 = 0, *waiter1 = 0, *waiter2 = 0, *waiter3 = 0,
293                           *waiter4 = 0, *waiter5 = 0;
294         uint8_t me = core_id();
295         printk("\nCore %d: SMP Call Self (nowait):\n", me);
296         printk("---------------------\n");
297         smp_call_function_self(test_hello_world_handler, 0, 0);
298         printk("\nCore %d: SMP Call Self (wait):\n", me);
299         printk("---------------------\n");
300         smp_call_function_self(test_hello_world_handler, 0, &waiter0);
301         smp_call_wait(waiter0);
302         printk("\nCore %d: SMP Call All (nowait):\n", me);
303         printk("---------------------\n");
304         smp_call_function_all(test_hello_world_handler, 0, 0);
305         printk("\nCore %d: SMP Call All (wait):\n", me);
306         printk("---------------------\n");
307         smp_call_function_all(test_hello_world_handler, 0, &waiter0);
308         smp_call_wait(waiter0);
309         printk("\nCore %d: SMP Call All-Else Individually, in order (nowait):\n", me);
310         printk("---------------------\n");
311         for(i = 1; i < num_cpus; i++)
312                 smp_call_function_single(i, test_hello_world_handler, 0, 0);
313         printk("\nCore %d: SMP Call Self (wait):\n", me);
314         printk("---------------------\n");
315         smp_call_function_self(test_hello_world_handler, 0, &waiter0);
316         smp_call_wait(waiter0);
317         printk("\nCore %d: SMP Call All-Else Individually, in order (wait):\n", me);
318         printk("---------------------\n");
319         for(i = 1; i < num_cpus; i++)
320         {
321                 smp_call_function_single(i, test_hello_world_handler, 0, &waiter0);
322                 smp_call_wait(waiter0);
323         }
324         printk("\nTesting to see if any IPI-functions are dropped when not waiting:\n");
325         printk("A: %d, B: %d, C: %d (should be 0,0,0)\n", atomic_read(&a), atomic_read(&b), atomic_read(&c));
326         smp_call_function_all(test_incrementer_handler, &a, 0);
327         smp_call_function_all(test_incrementer_handler, &b, 0);
328         smp_call_function_all(test_incrementer_handler, &c, 0);
329         // if i can clobber a previous IPI, the interleaving might do it
330         smp_call_function_single(1 % num_cpus, test_incrementer_handler, &a, 0);
331         smp_call_function_single(2 % num_cpus, test_incrementer_handler, &b, 0);
332         smp_call_function_single(3 % num_cpus, test_incrementer_handler, &c, 0);
333         smp_call_function_single(4 % num_cpus, test_incrementer_handler, &a, 0);
334         smp_call_function_single(5 % num_cpus, test_incrementer_handler, &b, 0);
335         smp_call_function_single(6 % num_cpus, test_incrementer_handler, &c, 0);
336         smp_call_function_all(test_incrementer_handler, &a, 0);
337         smp_call_function_single(3 % num_cpus, test_incrementer_handler, &c, 0);
338         smp_call_function_all(test_incrementer_handler, &b, 0);
339         smp_call_function_single(1 % num_cpus, test_incrementer_handler, &a, 0);
340         smp_call_function_all(test_incrementer_handler, &c, 0);
341         smp_call_function_single(2 % num_cpus, test_incrementer_handler, &b, 0);
342         // wait, so we're sure the others finish before printing.
343         // without this, we could (and did) get 19,18,19, since the B_inc
344         // handler didn't finish yet
345         smp_call_function_self(test_null_handler, 0, &waiter0);
346         // need to grab all 5 handlers (max), since the code moves to the next free.
347         smp_call_function_self(test_null_handler, 0, &waiter1);
348         smp_call_function_self(test_null_handler, 0, &waiter2);
349         smp_call_function_self(test_null_handler, 0, &waiter3);
350         smp_call_function_self(test_null_handler, 0, &waiter4);
351         smp_call_wait(waiter0);
352         smp_call_wait(waiter1);
353         smp_call_wait(waiter2);
354         smp_call_wait(waiter3);
355         smp_call_wait(waiter4);
356         printk("A: %d, B: %d, C: %d (should be 19,19,19)\n", atomic_read(&a), atomic_read(&b), atomic_read(&c));
357         printk("Attempting to deadlock by smp_calling with an outstanding wait:\n");
358         smp_call_function_self(test_null_handler, 0, &waiter0);
359         printk("Sent one\n");
360         smp_call_function_self(test_null_handler, 0, &waiter1);
361         printk("Sent two\n");
362         smp_call_wait(waiter0);
363         printk("Wait one\n");
364         smp_call_wait(waiter1);
365         printk("Wait two\n");
366         printk("\tMade it through!\n");
367         printk("Attempting to deadlock by smp_calling more than are available:\n");
368         printk("\tShould see an Insufficient message and a kernel warning.\n");
369         if (smp_call_function_self(test_null_handler, 0, &waiter0))
370                 printk("\tInsufficient handlers to call function (0)\n");
371         if (smp_call_function_self(test_null_handler, 0, &waiter1))
372                 printk("\tInsufficient handlers to call function (1)\n");
373         if (smp_call_function_self(test_null_handler, 0, &waiter2))
374                 printk("\tInsufficient handlers to call function (2)\n");
375         if (smp_call_function_self(test_null_handler, 0, &waiter3))
376                 printk("\tInsufficient handlers to call function (3)\n");
377         if (smp_call_function_self(test_null_handler, 0, &waiter4))
378                 printk("\tInsufficient handlers to call function (4)\n");
379         if (smp_call_function_self(test_null_handler, 0, &waiter5))
380                 printk("\tInsufficient handlers to call function (5)\n");
381         smp_call_wait(waiter0);
382         smp_call_wait(waiter1);
383         smp_call_wait(waiter2);
384         smp_call_wait(waiter3);
385         smp_call_wait(waiter4);
386         smp_call_wait(waiter5);
387         printk("\tMade it through!\n");
388
389         printk("Done\n");
390 }
391
392 #ifdef __i386__
393 void test_lapic_status_bit(void)
394 {
395         register_interrupt_handler(interrupt_handlers, test_vector,
396                                    test_incrementer_handler, &a);
397         #define NUM_IPI 100000
398         atomic_set(&a,0);
399         printk("IPIs received (should be 0): %d\n", a);
400         for(int i = 0; i < NUM_IPI; i++) {
401                 send_ipi(7, 0, test_vector);
402                 lapic_wait_to_send();
403         }
404         // need to wait a bit to let those IPIs get there
405         udelay(5000000);
406         printk("IPIs received (should be %d): %d\n", a, NUM_IPI);
407         // hopefully that handler never fires again.  leaving it registered for now.
408 }
409 #endif // __i386__
410
411 /******************************************************************************/
412 /*            Test Measurements: Couples with measurement.c                   */
413 // All user processes can R/W the UGDATA page
414 barrier_t* bar = (barrier_t*)UGDATA;
415 uint32_t* job_to_run = (uint32_t*)(UGDATA + sizeof(barrier_t));
416 env_t* env_batch[64]; // Fairly arbitrary, just the max I plan to use.
417
418 /* Helpers for test_run_measurements */
419 static void wait_for_all_envs_to_die(void)
420 {
421         while (atomic_read(&num_envs))
422                 cpu_relax();
423 }
424
425 // this never returns.
426 static void sync_tests(int start_core, int num_threads, int job_num)
427 {
428         assert(start_core + num_threads <= num_cpus);
429         wait_for_all_envs_to_die();
430         for (int i = start_core; i < start_core + num_threads; i++)
431                 env_batch[i] = kfs_proc_create(kfs_lookup_path("roslib_measurements"));
432         lcr3(env_batch[start_core]->env_cr3);
433         init_barrier(bar, num_threads);
434         *job_to_run = job_num;
435         for (int i = start_core; i < start_core + num_threads; i++)
436                 smp_call_function_single(i, run_env_handler, env_batch[i], 0);
437         process_workqueue();
438         // we want to fake a run, to reenter manager for the next case
439         env_t *env = kfs_proc_create(kfs_lookup_path("roslib_null"));
440         smp_call_function_single(0, run_env_handler, env, 0);
441         process_workqueue();
442         panic("whoops!\n");
443 }
444
445 static void async_tests(int start_core, int num_threads, int job_num)
446 {
447         int count;
448
449         assert(start_core + num_threads <= num_cpus);
450         wait_for_all_envs_to_die();
451         for (int i = start_core; i < start_core + num_threads; i++)
452                 env_batch[i] = kfs_proc_create(kfs_lookup_path("roslib_measurements"));
453         printk("async_tests: checkpoint 0\n");
454         lcr3(env_batch[start_core]->env_cr3);
455         init_barrier(bar, num_threads);
456         printk("async_tests: checkpoint 1\n");
457         *job_to_run = job_num;
458         for (int i = start_core; i < start_core + num_threads; i++)
459                 smp_call_function_single(i, run_env_handler, env_batch[i], 0);
460         count = 0;
461         while (count > -num_threads) {
462                 count = 0;
463                 for (int i = start_core; i < start_core + num_threads; i++) {
464                         count += process_generic_syscalls(env_batch[i], 1);
465                 }
466                 cpu_relax();
467         }
468         // we want to fake a run, to reenter manager for the next case
469         env_t *env = kfs_proc_create(kfs_lookup_path("roslib_null"));
470         smp_call_function_single(0, run_env_handler, env, 0);
471         process_workqueue();
472         // this all never returns
473         panic("whoops!\n");
474 }
475
476 void test_run_measurements(uint32_t job_num)
477 {
478         switch (job_num) {
479                 case 0: // Nulls
480                         printk("Case 0:\n");
481                         async_tests(2, 1, job_num);  // start core 2, 1 core total
482                         break;
483                 case 1: // Sync
484                         printk("Case 1:\n");
485                         sync_tests(2, 1, job_num);
486                         break;
487                 case 2:
488                         printk("Case 2:\n");
489                         sync_tests(2, 2, job_num);
490                         break;
491                 case 3:
492                         printk("Case 3:\n");
493                         sync_tests(0, 3, job_num);
494                         break;
495                 case 4:
496                         printk("Case 4:\n");
497                         sync_tests(0, 4, job_num);
498                         break;
499                 case 5:
500                         printk("Case 5:\n");
501                         sync_tests(0, 5, job_num);
502                         break;
503                 case 6:
504                         printk("Case 6:\n");
505                         sync_tests(0, 6, job_num);
506                         break;
507                 case 7:
508                         printk("Case 7:\n");
509                         sync_tests(0, 7, job_num);
510                         break;
511                 case 8:
512                         printk("Case 8:\n");
513                         sync_tests(0, 8, job_num);
514                         break;
515                 case 9:
516                         printk("Case 9:\n");
517                         async_tests(2, 1, job_num);
518                         break;
519                 case 10:
520                         printk("Case 10:\n");
521                         async_tests(2, 2, job_num);
522                         break;
523                 case 11:
524                         printk("Case 11:\n");
525                         async_tests(2, 3, job_num);
526                         break;
527                 case 12:
528                         printk("Case 12:\n");
529                         async_tests(2, 4, job_num);
530                         break;
531                 case 13:
532                         printk("Case 13:\n");
533                         async_tests(2, 5, job_num);
534                         break;
535                 case 14:
536                         printk("Case 14:\n");
537                         async_tests(2, 6, job_num);
538                         break;
539                 default:
540                         warn("Invalid test number!!");
541         }
542         panic("Error in test setup!!");
543 }
544
545 /************************************************************/
546 /* ISR Handler Functions */
547
548 void test_hello_world_handler(trapframe_t *tf, void* data)
549 {
550         int trapno;
551         #if defined(__i386__)
552         trapno = tf->tf_trapno;
553         #elif defined(__sparc_v8__)
554         trapno = (tf->tbr >> 4) & 0xFF;
555         #else
556         trapno = 0;
557         #endif
558
559         cprintf("Incoming IRQ, ISR: %d on core %d with tf at 0x%08x\n",
560                 trapno, core_id(), tf);
561 }
562
563 uint32_t print_info_lock = 0;
564
565 void test_print_info_handler(trapframe_t *tf, void* data)
566 {
567         spin_lock_irqsave(&print_info_lock);
568         cprintf("----------------------------\n");
569         cprintf("This is Core %d\n", core_id());
570 #ifdef __i386__
571         cprintf("MTRR_DEF_TYPE = 0x%08x\n", read_msr(IA32_MTRR_DEF_TYPE));
572         cprintf("MTRR Phys0 Base = 0x%016llx, Mask = 0x%016llx\n",
573                 read_msr(0x200), read_msr(0x201));
574         cprintf("MTRR Phys1 Base = 0x%016llx, Mask = 0x%016llx\n",
575                 read_msr(0x202), read_msr(0x203));
576         cprintf("MTRR Phys2 Base = 0x%016llx, Mask = 0x%016llx\n",
577                 read_msr(0x204), read_msr(0x205));
578         cprintf("MTRR Phys3 Base = 0x%016llx, Mask = 0x%016llx\n",
579                 read_msr(0x206), read_msr(0x207));
580         cprintf("MTRR Phys4 Base = 0x%016llx, Mask = 0x%016llx\n",
581                 read_msr(0x208), read_msr(0x209));
582         cprintf("MTRR Phys5 Base = 0x%016llx, Mask = 0x%016llx\n",
583                 read_msr(0x20a), read_msr(0x20b));
584         cprintf("MTRR Phys6 Base = 0x%016llx, Mask = 0x%016llx\n",
585                 read_msr(0x20c), read_msr(0x20d));
586         cprintf("MTRR Phys7 Base = 0x%016llx, Mask = 0x%016llx\n",
587                 read_msr(0x20e), read_msr(0x20f));
588 #endif // __i386__
589         cprintf("----------------------------\n");
590         spin_unlock_irqsave(&print_info_lock);
591 }
592
593 void test_barrier_handler(trapframe_t *tf, void* data)
594 {
595         cprintf("Round 1: Core %d\n", core_id());
596         waiton_barrier(&test_cpu_array);
597         waiton_barrier(&test_cpu_array);
598         waiton_barrier(&test_cpu_array);
599         waiton_barrier(&test_cpu_array);
600         waiton_barrier(&test_cpu_array);
601         waiton_barrier(&test_cpu_array);
602         cprintf("Round 2: Core %d\n", core_id());
603         waiton_barrier(&test_cpu_array);
604         cprintf("Round 3: Core %d\n", core_id());
605         // uncomment to see it fucked up
606         //cprintf("Round 4: Core %d\n", core_id());
607 }
608
609 static void test_waiting_handler(trapframe_t *tf, void* data)
610 {
611         {HANDLER_ATOMIC atomic_dec((atomic_t*)data);}
612 }
613
614 #ifdef __i386__
615 void test_pit(void)
616 {
617         cprintf("Starting test for PIT now (10s)\n");
618         udelay_pit(10000000);
619         cprintf("End now\n");
620         cprintf("Starting test for TSC (if stable) now (10s)\n");
621         udelay(10000000);
622         cprintf("End now\n");
623
624         cprintf("Starting test for LAPIC (if stable) now (10s)\n");
625         enable_irq();
626         lapic_set_timer(10000000, FALSE);
627
628         atomic_t waiting;
629         atomic_init(&waiting, 1);
630         register_interrupt_handler(interrupt_handlers, test_vector,
631                                    test_waiting_handler, &waiting);
632         while(atomic_read(&waiting))
633                 cpu_relax();
634         cprintf("End now\n");
635 }
636 #endif // __i386__