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