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