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