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