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