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