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