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