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