Compiles with GCC
[akaros.git] / kern / src / testing.c
1
2 #ifdef __SHARC__
3 #pragma nosharc
4 #endif
5
6 #ifdef __IVY__
7 #pragma nodeputy
8 #endif
9
10 #include <arch/mmu.h>
11 #include <arch/arch.h>
12 #include <smp.h>
13
14 #include <ros/memlayout.h>
15 #include <ros/common.h>
16
17 #include <atomic.h>
18 #include <stdio.h>
19 #include <assert.h>
20 #include <string.h>
21 #include <testing.h>
22 #include <trap.h>
23 #include <arch/trap.h>
24 #include <process.h>
25 #include <syscall.h>
26 #include <timing.h>
27 #include <kfs.h>
28 #include <multiboot.h>
29 #include <pmap.h>
30 #include <page_alloc.h>
31
32 #ifdef __i386__
33
34 void test_ipi_sending(void)
35 {
36         extern handler_t (COUNT(NUM_INTERRUPT_HANDLERS) interrupt_handlers)[];
37         int8_t state = 0;
38
39         register_interrupt_handler(interrupt_handlers, I_TESTING,
40                                    test_hello_world_handler, NULL);
41         enable_irqsave(&state);
42         cprintf("\nCORE 0 sending broadcast\n");
43         send_broadcast_ipi(I_TESTING);
44         udelay(3000000);
45         cprintf("\nCORE 0 sending all others\n");
46         send_all_others_ipi(I_TESTING);
47         udelay(3000000);
48         cprintf("\nCORE 0 sending self\n");
49         send_self_ipi(I_TESTING);
50         udelay(3000000);
51         cprintf("\nCORE 0 sending ipi to physical 1\n");
52         send_ipi(0x01, 0, I_TESTING);
53         udelay(3000000);
54         cprintf("\nCORE 0 sending ipi to physical 2\n");
55         send_ipi(0x02, 0, I_TESTING);
56         udelay(3000000);
57         cprintf("\nCORE 0 sending ipi to physical 3\n");
58         send_ipi(0x03, 0, I_TESTING);
59         udelay(3000000);
60         cprintf("\nCORE 0 sending ipi to physical 15\n");
61         send_ipi(0x0f, 0, I_TESTING);
62         udelay(3000000);
63         cprintf("\nCORE 0 sending ipi to logical 2\n");
64         send_ipi(0x02, 1, I_TESTING);
65         udelay(3000000);
66         cprintf("\nCORE 0 sending ipi to logical 1\n");
67         send_ipi(0x01, 1, I_TESTING);
68         udelay(3000000);
69         cprintf("\nDone!\n");
70         disable_irqsave(&state);
71 }
72
73 // Note this never returns and will muck with any other timer work
74 void test_pic_reception(void)
75 {
76         register_interrupt_handler(interrupt_handlers, 0x20, test_hello_world_handler, NULL);
77         pit_set_timer(100,TIMER_RATEGEN); // totally arbitrary time
78         pic_unmask_irq(0);
79         cprintf("PIC1 Mask = 0x%04x\n", inb(PIC1_DATA));
80         cprintf("PIC2 Mask = 0x%04x\n", inb(PIC2_DATA));
81         unmask_lapic_lvt(LAPIC_LVT_LINT0);
82         cprintf("Core %d's LINT0: 0x%08x\n", core_id(), read_mmreg32(LAPIC_LVT_LINT0));
83         enable_irq();
84         while(1);
85 }
86
87 #endif // __i386__
88
89 void test_print_info(void)
90 {
91         cprintf("\nCORE 0 asking all cores to print info:\n");
92         smp_call_function_all(test_print_info_handler, NULL, 0);
93         cprintf("\nDone!\n");
94 }
95
96 void test_page_coloring(void) 
97 {
98         //Print the different cache properties of our machine
99         print_cache_properties("L1", &l1);
100         cprintf("\n");
101         print_cache_properties("L2", &l2);
102         cprintf("\n");
103         print_cache_properties("L3", &l3);
104         cprintf("\n");
105
106         //Print some stats about our memory
107         cprintf("Max Address: %llu\n", MAX_VADDR);
108         cprintf("Num Pages: %u\n", npages);
109
110         //Declare a local variable for allocating pages 
111         page_t* page;
112
113         //Run through and allocate all pages through l1_page_alloc
114         cprintf("Allocating from L1 page colors:\n");
115         for(int i=0; i<get_cache_num_page_colors(&l1); i++) {
116                 cprintf("  COLOR %d:\n", i);
117                 while(l1_page_alloc(&page, i) != -ENOMEM)
118                         cprintf("    Page: %d\n", page2ppn(page));
119         }
120
121         //Put all the pages back by reinitializing
122         page_init();
123         
124         //Run through and allocate all pages through l2_page_alloc
125         cprintf("Allocating from L2 page colors:\n");
126         for(int i=0; i<get_cache_num_page_colors(&l2); i++) {
127                 cprintf("  COLOR %d:\n", i);
128                 while(l2_page_alloc(&page, i) != -ENOMEM)
129                         cprintf("    Page: %d\n", page2ppn(page));
130         }
131
132         //Put all the pages back by reinitializing
133         page_init();
134         
135         //Run through and allocate all pages through l3_page_alloc
136         cprintf("Allocating from L3 page colors:\n");
137         for(int i=0; i<get_cache_num_page_colors(&l3); i++) {
138                 cprintf("  COLOR %d:\n", i);
139                 while(l3_page_alloc(&page, i) != -ENOMEM)
140                         cprintf("    Page: %d\n", page2ppn(page));
141         }
142         
143         //Put all the pages back by reinitializing
144         page_init();
145         
146         //Run through and allocate all pages through page_alloc
147         cprintf("Allocating from global allocator:\n");
148         while(page_alloc(&page) != -ENOMEM)
149                 cprintf("    Page: %d\n", page2ppn(page));
150         
151         if(l2_page_alloc(&page, 0) != -ENOMEM)
152                 cprintf("Should not get here, all pages should already be gone!\n");
153         cprintf("All pages gone for sure...\n");
154         
155         //Now lets put a few pages back using page_free..
156         cprintf("Reinserting pages via page_free and reallocating them...\n");
157         page_free(&pages[0]);
158         page_free(&pages[15]);
159         page_free(&pages[7]);
160         page_free(&pages[6]);
161         page_free(&pages[4]);
162
163         while(page_alloc(&page) != -ENOMEM)
164                 cprintf("Page: %d\n", page2ppn(page));  
165 }
166
167 barrier_t test_cpu_array;
168
169 void test_barrier(void)
170 {
171         cprintf("Core 0 initializing barrier\n");
172         init_barrier(&test_cpu_array, num_cpus);
173         cprintf("Core 0 asking all cores to print ids, barrier, rinse, repeat\n");
174         smp_call_function_all(test_barrier_handler, NULL, 0);
175 }
176
177 void test_interrupts_irqsave(void)
178 {
179         int8_t state = 0;
180         printd("Testing Nesting Enabling first, turning ints off:\n");
181         disable_irq();
182         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
183         assert(!irq_is_enabled());
184         printd("Enabling IRQSave\n");
185         enable_irqsave(&state);
186         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
187         assert(irq_is_enabled());
188         printd("Enabling IRQSave Again\n");
189         enable_irqsave(&state);
190         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
191         assert(irq_is_enabled());
192         printd("Disabling IRQSave Once\n");
193         disable_irqsave(&state);
194         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
195         assert(irq_is_enabled());
196         printd("Disabling IRQSave Again\n");
197         disable_irqsave(&state);
198         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
199         assert(!irq_is_enabled());
200         printd("Done.  Should have been 0, 200, 200, 200, 0\n");
201
202         printd("Testing Nesting Disabling first, turning ints on:\n");
203         state = 0;
204         enable_irq();
205         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
206         assert(irq_is_enabled());
207         printd("Disabling IRQSave Once\n");
208         disable_irqsave(&state);
209         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
210         assert(!irq_is_enabled());
211         printd("Disabling IRQSave Again\n");
212         disable_irqsave(&state);
213         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
214         assert(!irq_is_enabled());
215         printd("Enabling IRQSave Once\n");
216         enable_irqsave(&state);
217         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
218         assert(!irq_is_enabled());
219         printd("Enabling IRQSave Again\n");
220         enable_irqsave(&state);
221         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
222         assert(irq_is_enabled());
223         printd("Done.  Should have been 200, 0, 0, 0, 200 \n");
224
225         state = 0;
226         disable_irq();
227         printd("Ints are off, enabling then disabling.\n");
228         enable_irqsave(&state);
229         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
230         assert(irq_is_enabled());
231         disable_irqsave(&state);
232         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
233         assert(!irq_is_enabled());
234         printd("Done.  Should have been 200, 0\n");
235
236         state = 0;
237         enable_irq();
238         printd("Ints are on, enabling then disabling.\n");
239         enable_irqsave(&state);
240         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
241         assert(irq_is_enabled());
242         disable_irqsave(&state);
243         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
244         assert(irq_is_enabled());
245         printd("Done.  Should have been 200, 200\n");
246
247         state = 0;
248         disable_irq();
249         printd("Ints are off, disabling then enabling.\n");
250         disable_irqsave(&state);
251         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
252         assert(!irq_is_enabled());
253         enable_irqsave(&state);
254         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
255         assert(!irq_is_enabled());
256         printd("Done.  Should have been 0, 0\n");
257
258         state = 0;
259         enable_irq();
260         printd("Ints are on, disabling then enabling.\n");
261         disable_irqsave(&state);
262         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
263         assert(!irq_is_enabled());
264         enable_irqsave(&state);
265         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
266         assert(irq_is_enabled());
267         printd("Done.  Should have been 0, 200\n");
268
269         disable_irq();
270         cprintf("Passed enable_irqsave tests\n");
271 }
272
273 void test_bitmasks(void)
274 {
275 #define masksize 67
276         DECL_BITMASK(mask, masksize);
277         printk("size of mask %d\n", sizeof(mask));
278         CLR_BITMASK(mask, masksize);
279         PRINT_BITMASK(mask, masksize);
280         printk("cleared\n");
281         SET_BITMASK_BIT(mask, 0);
282         SET_BITMASK_BIT(mask, 11);
283         SET_BITMASK_BIT(mask, 17);
284         SET_BITMASK_BIT(mask, masksize-1);
285         printk("bits set\n");
286         PRINT_BITMASK(mask, masksize);
287         DECL_BITMASK(mask2, masksize);
288         COPY_BITMASK(mask2, mask, masksize);
289         printk("copy of original mask, should be the same as the prev\n");
290         PRINT_BITMASK(mask2, masksize);
291         CLR_BITMASK_BIT(mask, 11);
292         printk("11 cleared\n");
293         PRINT_BITMASK(mask, masksize);
294         printk("bit 17 is %d (should be 1)\n", GET_BITMASK_BIT(mask, 17));
295         printk("bit 11 is %d (should be 0)\n", GET_BITMASK_BIT(mask, 11));
296         FILL_BITMASK(mask, masksize);
297         PRINT_BITMASK(mask, masksize);
298         printk("should be all 1's, except for a few at the end\n");
299         printk("Is Clear?: %d (should be 0)\n", BITMASK_IS_CLEAR(mask,masksize));
300         CLR_BITMASK(mask, masksize);
301         PRINT_BITMASK(mask, masksize);
302         printk("Is Clear?: %d (should be 1)\n", BITMASK_IS_CLEAR(mask,masksize));
303         printk("should be cleared\n");
304 }
305
306 checklist_t* the_global_list;
307
308 void test_checklist_handler(trapframe_t *tf, void* data)
309 {
310         udelay(1000000);
311         cprintf("down_checklist(%x,%d)\n", the_global_list, core_id());
312         down_checklist(the_global_list);
313 }
314
315 void test_checklists(void)
316 {
317         INIT_CHECKLIST(a_list, MAX_NUM_CPUS);
318         the_global_list = &a_list;
319         printk("Checklist Build, mask size: %d\n", sizeof(a_list.mask.bits));
320         printk("mask\n");
321         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
322         SET_BITMASK_BIT(a_list.mask.bits, 11);
323         printk("Set bit 11\n");
324         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
325
326         CLR_BITMASK(a_list.mask.bits, a_list.mask.size);
327         INIT_CHECKLIST_MASK(a_mask, MAX_NUM_CPUS);
328         FILL_BITMASK(a_mask.bits, num_cpus);
329         //CLR_BITMASK_BIT(a_mask.bits, core_id());
330         //SET_BITMASK_BIT(a_mask.bits, 1);
331         //printk("New mask (1, 17, 25):\n");
332         printk("Created new mask, filled up to num_cpus\n");
333         PRINT_BITMASK(a_mask.bits, a_mask.size);
334         printk("committing new mask\n");
335         commit_checklist_wait(&a_list, &a_mask);
336         printk("Old mask (copied onto):\n");
337         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
338         //smp_call_function_single(1, test_checklist_handler, 0, 0);
339
340         smp_call_function_all(test_checklist_handler, NULL, 0);
341
342         printk("Waiting on checklist\n");
343         waiton_checklist(&a_list);
344         printk("Done Waiting!\n");
345
346 }
347
348 atomic_t a, b, c;
349
350 void test_incrementer_handler(trapframe_t *tf, void *data)
351 {
352         assert(data);
353         atomic_inc(data);
354 }
355
356 void test_null_handler(trapframe_t *tf, void* data)
357 {
358         asm volatile("nop");
359 }
360
361 void test_smp_call_functions(void)
362 {
363         int i;
364         atomic_init(&a, 0);
365         atomic_init(&b, 0);
366         atomic_init(&c, 0);
367         handler_wrapper_t *waiter0 = 0, *waiter1 = 0, *waiter2 = 0, *waiter3 = 0,
368                           *waiter4 = 0, *waiter5 = 0;
369         uint8_t me = core_id();
370         printk("\nCore %d: SMP Call Self (nowait):\n", me);
371         printk("---------------------\n");
372         smp_call_function_self(test_hello_world_handler, NULL, 0);
373         printk("\nCore %d: SMP Call Self (wait):\n", me);
374         printk("---------------------\n");
375         smp_call_function_self(test_hello_world_handler, NULL, &waiter0);
376         smp_call_wait(waiter0);
377         printk("\nCore %d: SMP Call All (nowait):\n", me);
378         printk("---------------------\n");
379         smp_call_function_all(test_hello_world_handler, NULL, 0);
380         printk("\nCore %d: SMP Call All (wait):\n", me);
381         printk("---------------------\n");
382         smp_call_function_all(test_hello_world_handler, NULL, &waiter0);
383         smp_call_wait(waiter0);
384         printk("\nCore %d: SMP Call All-Else Individually, in order (nowait):\n", me);
385         printk("---------------------\n");
386         for(i = 1; i < num_cpus; i++)
387                 smp_call_function_single(i, test_hello_world_handler, NULL, 0);
388         printk("\nCore %d: SMP Call Self (wait):\n", me);
389         printk("---------------------\n");
390         smp_call_function_self(test_hello_world_handler, NULL, &waiter0);
391         smp_call_wait(waiter0);
392         printk("\nCore %d: SMP Call All-Else Individually, in order (wait):\n", me);
393         printk("---------------------\n");
394         for(i = 1; i < num_cpus; i++)
395         {
396                 smp_call_function_single(i, test_hello_world_handler, NULL, &waiter0);
397                 smp_call_wait(waiter0);
398         }
399         printk("\nTesting to see if any IPI-functions are dropped when not waiting:\n");
400         printk("A: %d, B: %d, C: %d (should be 0,0,0)\n", atomic_read(&a), atomic_read(&b), atomic_read(&c));
401         smp_call_function_all(test_incrementer_handler, &a, 0);
402         smp_call_function_all(test_incrementer_handler, &b, 0);
403         smp_call_function_all(test_incrementer_handler, &c, 0);
404         // if i can clobber a previous IPI, the interleaving might do it
405         smp_call_function_single(1 % num_cpus, test_incrementer_handler, &a, 0);
406         smp_call_function_single(2 % num_cpus, test_incrementer_handler, &b, 0);
407         smp_call_function_single(3 % num_cpus, test_incrementer_handler, &c, 0);
408         smp_call_function_single(4 % num_cpus, test_incrementer_handler, &a, 0);
409         smp_call_function_single(5 % num_cpus, test_incrementer_handler, &b, 0);
410         smp_call_function_single(6 % num_cpus, test_incrementer_handler, &c, 0);
411         smp_call_function_all(test_incrementer_handler, &a, 0);
412         smp_call_function_single(3 % num_cpus, test_incrementer_handler, &c, 0);
413         smp_call_function_all(test_incrementer_handler, &b, 0);
414         smp_call_function_single(1 % num_cpus, test_incrementer_handler, &a, 0);
415         smp_call_function_all(test_incrementer_handler, &c, 0);
416         smp_call_function_single(2 % num_cpus, test_incrementer_handler, &b, 0);
417         // wait, so we're sure the others finish before printing.
418         // without this, we could (and did) get 19,18,19, since the B_inc
419         // handler didn't finish yet
420         smp_call_function_self(test_null_handler, NULL, &waiter0);
421         // need to grab all 5 handlers (max), since the code moves to the next free.
422         smp_call_function_self(test_null_handler, NULL, &waiter1);
423         smp_call_function_self(test_null_handler, NULL, &waiter2);
424         smp_call_function_self(test_null_handler, NULL, &waiter3);
425         smp_call_function_self(test_null_handler, NULL, &waiter4);
426         smp_call_wait(waiter0);
427         smp_call_wait(waiter1);
428         smp_call_wait(waiter2);
429         smp_call_wait(waiter3);
430         smp_call_wait(waiter4);
431         printk("A: %d, B: %d, C: %d (should be 19,19,19)\n", atomic_read(&a), atomic_read(&b), atomic_read(&c));
432         printk("Attempting to deadlock by smp_calling with an outstanding wait:\n");
433         smp_call_function_self(test_null_handler, NULL, &waiter0);
434         printk("Sent one\n");
435         smp_call_function_self(test_null_handler, NULL, &waiter1);
436         printk("Sent two\n");
437         smp_call_wait(waiter0);
438         printk("Wait one\n");
439         smp_call_wait(waiter1);
440         printk("Wait two\n");
441         printk("\tMade it through!\n");
442         printk("Attempting to deadlock by smp_calling more than are available:\n");
443         printk("\tShould see an Insufficient message and a kernel warning.\n");
444         if (smp_call_function_self(test_null_handler, NULL, &waiter0))
445                 printk("\tInsufficient handlers to call function (0)\n");
446         if (smp_call_function_self(test_null_handler, NULL, &waiter1))
447                 printk("\tInsufficient handlers to call function (1)\n");
448         if (smp_call_function_self(test_null_handler, NULL, &waiter2))
449                 printk("\tInsufficient handlers to call function (2)\n");
450         if (smp_call_function_self(test_null_handler, NULL, &waiter3))
451                 printk("\tInsufficient handlers to call function (3)\n");
452         if (smp_call_function_self(test_null_handler, NULL, &waiter4))
453                 printk("\tInsufficient handlers to call function (4)\n");
454         if (smp_call_function_self(test_null_handler, NULL, &waiter5))
455                 printk("\tInsufficient handlers to call function (5)\n");
456         smp_call_wait(waiter0);
457         smp_call_wait(waiter1);
458         smp_call_wait(waiter2);
459         smp_call_wait(waiter3);
460         smp_call_wait(waiter4);
461         smp_call_wait(waiter5);
462         printk("\tMade it through!\n");
463
464         printk("Done\n");
465 }
466
467 #ifdef __i386__
468 void test_lapic_status_bit(void)
469 {
470         register_interrupt_handler(interrupt_handlers, I_TESTING,
471                                    test_incrementer_handler, &a);
472         #define NUM_IPI 100000
473         atomic_set(&a,0);
474         printk("IPIs received (should be 0): %d\n", a);
475         for(int i = 0; i < NUM_IPI; i++) {
476                 send_ipi(7, 0, I_TESTING);
477                 lapic_wait_to_send();
478         }
479         // need to wait a bit to let those IPIs get there
480         udelay(5000000);
481         printk("IPIs received (should be %d): %d\n", a, NUM_IPI);
482         // hopefully that handler never fires again.  leaving it registered for now.
483 }
484 #endif // __i386__
485
486 /******************************************************************************/
487 /*            Test Measurements: Couples with measurement.c                   */
488 // All user processes can R/W the UGDATA page
489 barrier_t*COUNT(1) bar = (barrier_t*COUNT(1))TC(UGDATA);
490 uint32_t*COUNT(1) job_to_run = (uint32_t*COUNT(1))TC(UGDATA + sizeof(barrier_t));
491 env_t* env_batch[64]; // Fairly arbitrary, just the max I plan to use.
492
493 /* Helpers for test_run_measurements */
494 static void wait_for_all_envs_to_die(void)
495 {
496         while (atomic_read(&num_envs))
497                 cpu_relax();
498 }
499
500 // this never returns.
501 static void sync_tests(int start_core, int num_threads, int job_num)
502 {
503         assert(start_core + num_threads <= num_cpus);
504         wait_for_all_envs_to_die();
505         for (int i = start_core; i < start_core + num_threads; i++)
506                 env_batch[i] = kfs_proc_create(kfs_lookup_path("roslib_measurements"));
507         lcr3(env_batch[start_core]->env_cr3);
508         init_barrier(bar, num_threads);
509         *job_to_run = job_num;
510         for (int i = start_core; i < start_core + num_threads; i++)
511                 smp_call_function_single(i, run_env_handler, env_batch[i], 0);
512         process_workqueue();
513         // we want to fake a run, to reenter manager for the next case
514         env_t *env = kfs_proc_create(kfs_lookup_path("roslib_null"));
515         smp_call_function_single(0, run_env_handler, env, 0);
516         process_workqueue();
517         panic("whoops!\n");
518 }
519
520 static void async_tests(int start_core, int num_threads, int job_num)
521 {
522         int count;
523
524         assert(start_core + num_threads <= num_cpus);
525         wait_for_all_envs_to_die();
526         for (int i = start_core; i < start_core + num_threads; i++)
527                 env_batch[i] = kfs_proc_create(kfs_lookup_path("roslib_measurements"));
528         printk("async_tests: checkpoint 0\n");
529         lcr3(env_batch[start_core]->env_cr3);
530         init_barrier(bar, num_threads);
531         printk("async_tests: checkpoint 1\n");
532         *job_to_run = job_num;
533         for (int i = start_core; i < start_core + num_threads; i++)
534                 smp_call_function_single(i, run_env_handler, env_batch[i], 0);
535         count = 0;
536         while (count > -num_threads) {
537                 count = 0;
538                 for (int i = start_core; i < start_core + num_threads; i++) {
539                         count += process_generic_syscalls(env_batch[i], 1);
540                 }
541                 cpu_relax();
542         }
543         // we want to fake a run, to reenter manager for the next case
544         env_t *env = kfs_proc_create(kfs_lookup_path("roslib_null"));
545         smp_call_function_single(0, run_env_handler, env, 0);
546         process_workqueue();
547         // this all never returns
548         panic("whoops!\n");
549 }
550
551 void test_run_measurements(uint32_t job_num)
552 {
553         switch (job_num) {
554                 case 0: // Nulls
555                         printk("Case 0:\n");
556                         async_tests(2, 1, job_num);  // start core 2, 1 core total
557                         break;
558                 case 1: // Sync
559                         printk("Case 1:\n");
560                         sync_tests(2, 1, job_num);
561                         break;
562                 case 2:
563                         printk("Case 2:\n");
564                         sync_tests(2, 2, job_num);
565                         break;
566                 case 3:
567                         printk("Case 3:\n");
568                         sync_tests(0, 3, job_num);
569                         break;
570                 case 4:
571                         printk("Case 4:\n");
572                         sync_tests(0, 4, job_num);
573                         break;
574                 case 5:
575                         printk("Case 5:\n");
576                         sync_tests(0, 5, job_num);
577                         break;
578                 case 6:
579                         printk("Case 6:\n");
580                         sync_tests(0, 6, job_num);
581                         break;
582                 case 7:
583                         printk("Case 7:\n");
584                         sync_tests(0, 7, job_num);
585                         break;
586                 case 8:
587                         printk("Case 8:\n");
588                         sync_tests(0, 8, job_num);
589                         break;
590                 case 9:
591                         printk("Case 9:\n");
592                         async_tests(2, 1, job_num);
593                         break;
594                 case 10:
595                         printk("Case 10:\n");
596                         async_tests(2, 2, job_num);
597                         break;
598                 case 11:
599                         printk("Case 11:\n");
600                         async_tests(2, 3, job_num);
601                         break;
602                 case 12:
603                         printk("Case 12:\n");
604                         async_tests(2, 4, job_num);
605                         break;
606                 case 13:
607                         printk("Case 13:\n");
608                         async_tests(2, 5, job_num);
609                         break;
610                 case 14:
611                         printk("Case 14:\n");
612                         async_tests(2, 6, job_num);
613                         break;
614                 default:
615                         warn("Invalid test number!!");
616         }
617         panic("Error in test setup!!");
618 }
619
620 /************************************************************/
621 /* ISR Handler Functions */
622
623 void test_hello_world_handler(trapframe_t *tf, void* data)
624 {
625         int trapno;
626         #if defined(__i386__)
627         trapno = tf->tf_trapno;
628         #elif defined(__sparc_v8__)
629         trapno = (tf->tbr >> 4) & 0xFF;
630         #else
631         trapno = 0;
632         #endif
633
634         cprintf("Incoming IRQ, ISR: %d on core %d with tf at 0x%08x\n",
635                 trapno, core_id(), tf);
636 }
637
638 uint32_t print_info_lock = 0;
639
640 void test_print_info_handler(trapframe_t *tf, void* data)
641 {
642         spin_lock_irqsave(&print_info_lock);
643         cprintf("----------------------------\n");
644         cprintf("This is Core %d\n", core_id());
645 #ifdef __i386__
646         cprintf("MTRR_DEF_TYPE = 0x%08x\n", read_msr(IA32_MTRR_DEF_TYPE));
647         cprintf("MTRR Phys0 Base = 0x%016llx, Mask = 0x%016llx\n",
648                 read_msr(0x200), read_msr(0x201));
649         cprintf("MTRR Phys1 Base = 0x%016llx, Mask = 0x%016llx\n",
650                 read_msr(0x202), read_msr(0x203));
651         cprintf("MTRR Phys2 Base = 0x%016llx, Mask = 0x%016llx\n",
652                 read_msr(0x204), read_msr(0x205));
653         cprintf("MTRR Phys3 Base = 0x%016llx, Mask = 0x%016llx\n",
654                 read_msr(0x206), read_msr(0x207));
655         cprintf("MTRR Phys4 Base = 0x%016llx, Mask = 0x%016llx\n",
656                 read_msr(0x208), read_msr(0x209));
657         cprintf("MTRR Phys5 Base = 0x%016llx, Mask = 0x%016llx\n",
658                 read_msr(0x20a), read_msr(0x20b));
659         cprintf("MTRR Phys6 Base = 0x%016llx, Mask = 0x%016llx\n",
660                 read_msr(0x20c), read_msr(0x20d));
661         cprintf("MTRR Phys7 Base = 0x%016llx, Mask = 0x%016llx\n",
662                 read_msr(0x20e), read_msr(0x20f));
663 #endif // __i386__
664         cprintf("----------------------------\n");
665         spin_unlock_irqsave(&print_info_lock);
666 }
667
668 void test_barrier_handler(trapframe_t *tf, void* data)
669 {
670         cprintf("Round 1: Core %d\n", core_id());
671         waiton_barrier(&test_cpu_array);
672         waiton_barrier(&test_cpu_array);
673         waiton_barrier(&test_cpu_array);
674         waiton_barrier(&test_cpu_array);
675         waiton_barrier(&test_cpu_array);
676         waiton_barrier(&test_cpu_array);
677         cprintf("Round 2: Core %d\n", core_id());
678         waiton_barrier(&test_cpu_array);
679         cprintf("Round 3: Core %d\n", core_id());
680         // uncomment to see it fucked up
681         //cprintf("Round 4: Core %d\n", core_id());
682 }
683
684 static void test_waiting_handler(trapframe_t *tf, void *data)
685 {
686         {HANDLER_ATOMIC atomic_dec(data);}
687 }
688
689 #ifdef __i386__
690 void test_pit(void)
691 {
692         cprintf("Starting test for PIT now (10s)\n");
693         udelay_pit(10000000);
694         cprintf("End now\n");
695         cprintf("Starting test for TSC (if stable) now (10s)\n");
696         udelay(10000000);
697         cprintf("End now\n");
698
699         cprintf("Starting test for LAPIC (if stable) now (10s)\n");
700         enable_irq();
701         lapic_set_timer(10000000, FALSE);
702
703         atomic_t waiting;
704         atomic_init(&waiting, 1);
705         register_interrupt_handler(interrupt_handlers, I_TESTING,
706                                    test_waiting_handler, &waiting);
707         while(atomic_read(&waiting))
708                 cpu_relax();
709         cprintf("End now\n");
710 }
711
712 void test_circ_buffer(void)
713 {
714         int arr[5] = {0, 1, 2, 3, 4};
715
716         for (int i = 0; i < 5; i++) {
717                 FOR_CIRC_BUFFER(i, 5, j)
718                         printk("Starting with current = %d, each value = %d\n", i, j);
719         }
720         return;
721 }
722
723 void test_am_handler(trapframe_t* tf, uint32_t srcid, uint32_t a0, uint32_t a1,
724                      uint32_t a2)
725 {
726         printk("Received AM on core %d from core %d: arg0= 0x%08x, arg1 = "
727                "0x%08x, arg2 = 0x%08x\n", core_id(), srcid, a0, a1, a2);
728         return;
729 }
730
731 void test_active_messages(void)
732 {
733         // basic tests, make sure we can handle a wraparound and that the error
734         // messages work.
735         printk("sending NUM_ACTIVE_MESSAGES to core 1, sending (#,deadbeef,0)\n");
736         for (int i = 0; i < NUM_ACTIVE_MESSAGES; i++)
737                 while (send_active_message(1, test_am_handler, i, 0xdeadbeef, 0))
738                         cpu_relax();
739         udelay(5000000);
740         printk("sending 2*NUM_ACTIVE_MESSAGES to core 1, sending (#,cafebabe,0)\n");
741         for (int i = 0; i < 2*NUM_ACTIVE_MESSAGES; i++)
742                 while (send_active_message(1, test_am_handler, i, 0xcafebabe, 0))
743                         cpu_relax();
744         udelay(5000000);
745         return;
746 }
747 #endif // __i386__