Implemented Kernel Post-boot testing.
[akaros.git] / kern / src / tests_pb_kernel.c
1 /*
2  * Postboot kernel tests: Tests to be ran after boot in kernel mode.
3  * TODO: Some of the tests here may not necessarily be tests to be ran after
4  *       boot. If that is the case, change them in
5  */
6
7 #ifdef __SHARC__
8 #pragma nosharc
9 #endif
10
11 #include <arch/mmu.h>
12 #include <arch/arch.h>
13 #include <bitmask.h>
14 #include <smp.h>
15
16 #include <ros/memlayout.h>
17 #include <ros/common.h>
18 #include <ros/bcq.h>
19 #include <ros/ucq.h>
20
21 #include <atomic.h>
22 #include <stdio.h>
23 #include <assert.h>
24 #include <string.h>
25 #include <testing.h>
26 #include <trap.h>
27 #include <process.h>
28 #include <syscall.h>
29 #include <time.h>
30 #include <kfs.h>
31 #include <multiboot.h>
32 #include <pmap.h>
33 #include <page_alloc.h>
34 #include <pmap.h>
35 #include <slab.h>
36 #include <kmalloc.h>
37 #include <hashtable.h>
38 #include <radix.h>
39 #include <monitor.h>
40 #include <kthread.h>
41 #include <schedule.h>
42 #include <umem.h>
43 #include <ucq.h>
44 #include <setjmp.h>
45
46 #include <apipe.h>
47 #include <rwlock.h>
48 #include <rendez.h>
49
50 #define l1 (available_caches.l1)
51 #define l2 (available_caches.l2)
52 #define l3 (available_caches.l3)
53
54 #ifdef CONFIG_X86
55
56 // TODO: Do test if possible inside this function, and add assertions.
57 bool test_ipi_sending(void)
58 {
59         int8_t state = 0;
60
61         register_irq(I_TESTING, test_hello_world_handler, NULL,
62                      MKBUS(BusIPI, 0, 0, 0));
63         enable_irqsave(&state);
64         cprintf("\nCORE 0 sending broadcast\n");
65         send_broadcast_ipi(I_TESTING);
66         udelay(3000000);
67         cprintf("\nCORE 0 sending all others\n");
68         send_all_others_ipi(I_TESTING);
69         udelay(3000000);
70         cprintf("\nCORE 0 sending self\n");
71         send_self_ipi(I_TESTING);
72         udelay(3000000);
73         cprintf("\nCORE 0 sending ipi to physical 1\n");
74         send_ipi(0x01, I_TESTING);
75         udelay(3000000);
76         cprintf("\nCORE 0 sending ipi to physical 2\n");
77         send_ipi(0x02, I_TESTING);
78         udelay(3000000);
79         cprintf("\nCORE 0 sending ipi to physical 3\n");
80         send_ipi(0x03, I_TESTING);
81         udelay(3000000);
82         cprintf("\nCORE 0 sending ipi to physical 15\n");
83         send_ipi(0x0f, I_TESTING);
84         udelay(3000000);
85         cprintf("\nCORE 0 sending ipi to logical 2\n");
86         send_group_ipi(0x02, I_TESTING);
87         udelay(3000000);
88         cprintf("\nCORE 0 sending ipi to logical 1\n");
89         send_group_ipi(0x01, I_TESTING);
90         udelay(3000000);
91         cprintf("\nDone!\n");
92         disable_irqsave(&state);
93
94         return true;
95 }
96
97 // TODO: Refactor to make it return and add assertions.
98 // Note this never returns and will muck with any other timer work
99 bool test_pic_reception(void)
100 {
101         register_irq(IdtPIC + IrqCLOCK, test_hello_world_handler, NULL,
102                      MKBUS(BusISA, 0, 0, 0));
103         pit_set_timer(100,TIMER_RATEGEN); // totally arbitrary time
104         pic_unmask_irq(0, 0);
105         cprintf("PIC1 Mask = 0x%04x\n", inb(PIC1_DATA));
106         cprintf("PIC2 Mask = 0x%04x\n", inb(PIC2_DATA));
107         unmask_lapic_lvt(LAPIC_LVT_LINT0);
108         cprintf("Core %d's LINT0: 0x%08x\n", core_id(), read_mmreg32(LAPIC_LVT_LINT0));
109         enable_irq();
110         while(1);
111
112         return true;
113 }
114
115 // TODO: Add assertions.
116 bool test_ioapic_pit_reroute(void) 
117 {
118         register_irq(IdtPIC + IrqCLOCK, test_hello_world_handler, NULL,
119                      MKBUS(BusISA, 0, 0, 0));
120 #ifdef CONFIG_ENABLE_MPTABLES
121 #warning "not routing the irq"
122         //ioapic_route_irq(0, 3);       
123 #endif
124
125         cprintf("Starting pit on core 3....\n");
126         udelay(3000000);
127         pit_set_timer(0xFFFE,TIMER_RATEGEN); // totally arbitrary time
128         
129         udelay(3000000);
130 #ifdef CONFIG_ENABLE_MPTABLES
131 #warning "NOT unrouting the irq"
132         //ioapic_unroute_irq(0);
133 #endif
134         udelay(300000);
135         cprintf("Masked pit. Waiting before return...\n");
136         udelay(3000000);
137
138         return true;
139 }
140
141 #endif // CONFIG_X86
142
143 // TODO: Assert printed info follows the standard (or whatever we want to test).
144 bool test_print_info(void)
145 {
146         cprintf("\nCORE 0 asking all cores to print info:\n");
147         smp_call_function_all(test_print_info_handler, NULL, 0);
148         cprintf("\nDone!\n");
149         return true;
150 }
151
152 // TODO: Add assertions. Possibly the way to go is to extract relevant info 
153 //       from cache properties and make assertions on the colored pages lists 
154 //       based on those.
155 // TODO: The test was commented out. Figure out why was it like that and fix it.
156 bool test_page_coloring(void) 
157 {
158         /*
159         //Print the different cache properties of our machine
160         print_cache_properties("L1", l1);
161         cprintf("\n");
162         print_cache_properties("L2", l2);
163         cprintf("\n");
164         print_cache_properties("L3", l3);
165         cprintf("\n");
166
167         //Print some stats about our memory
168         cprintf("Max Address: %llu\n", MAX_VADDR);
169         cprintf("Num Pages: %u\n", npages);
170
171         //Declare a local variable for allocating pages 
172         page_t* page;
173
174         cprintf("Contents of the page free list:\n");
175         for(int i=0; i<llc_cache->num_colors; i++) {
176                 cprintf("  COLOR %d:\n", i);
177                 LIST_FOREACH(page, &colored_page_free_list[i], pg_link) {
178                         cprintf("    Page: %d\n", page2ppn(page));
179                 }
180         }
181
182         //Run through and allocate all pages through l1_page_alloc
183         cprintf("Allocating from L1 page colors:\n");
184         for(int i=0; i<get_cache_num_page_colors(l1); i++) {
185                 cprintf("  COLOR %d:\n", i);
186                 while(colored_page_alloc(l1, &page, i) != -ENOMEM)
187                         cprintf("    Page: %d\n", page2ppn(page));
188         }
189
190         //Put all the pages back by reinitializing
191         page_init();
192         
193         //Run through and allocate all pages through l2_page_alloc
194         cprintf("Allocating from L2 page colors:\n");
195         for(int i=0; i<get_cache_num_page_colors(l2); i++) {
196                 cprintf("  COLOR %d:\n", i);
197                 while(colored_page_alloc(l2, &page, i) != -ENOMEM)
198                         cprintf("    Page: %d\n", page2ppn(page));
199         }
200
201         //Put all the pages back by reinitializing
202         page_init();
203         
204         //Run through and allocate all pages through l3_page_alloc
205         cprintf("Allocating from L3 page colors:\n");
206         for(int i=0; i<get_cache_num_page_colors(l3); i++) {
207                 cprintf("  COLOR %d:\n", i);
208                 while(colored_page_alloc(l3, &page, i) != -ENOMEM)
209                         cprintf("    Page: %d\n", page2ppn(page));
210         }
211         
212         //Put all the pages back by reinitializing
213         page_init();
214         
215         //Run through and allocate all pages through page_alloc
216         cprintf("Allocating from global allocator:\n");
217         while(upage_alloc(&page) != -ENOMEM)
218                 cprintf("    Page: %d\n", page2ppn(page));
219         
220         if(colored_page_alloc(l2, &page, 0) != -ENOMEM)
221                 cprintf("Should not get here, all pages should already be gone!\n");
222         cprintf("All pages gone for sure...\n");
223         
224         //Now lets put a few pages back using page_free..
225         cprintf("Reinserting pages via page_free and reallocating them...\n");
226         page_free(&pages[0]);
227         page_free(&pages[15]);
228         page_free(&pages[7]);
229         page_free(&pages[6]);
230         page_free(&pages[4]);
231
232         while(upage_alloc(&page) != -ENOMEM)
233                 cprintf("Page: %d\n", page2ppn(page));  
234         
235         page_init();
236         */
237         return true;
238 }
239
240 // TODO: Add assertions.
241 bool test_color_alloc(void) {
242         size_t checkpoint = 0;
243         uint8_t* colors_map = kmalloc(BYTES_FOR_BITMASK(llc_cache->num_colors), 0);
244         cache_color_alloc(l2, colors_map);
245         cache_color_alloc(l3, colors_map);
246         cache_color_alloc(l3, colors_map);
247         cache_color_alloc(l2, colors_map);
248         cache_color_free(llc_cache, colors_map);
249         cache_color_free(llc_cache, colors_map);
250         cache_color_free(llc_cache, colors_map);
251         cache_color_free(llc_cache, colors_map);
252         cache_color_free(llc_cache, colors_map);
253         cache_color_free(llc_cache, colors_map);
254         cache_color_free(llc_cache, colors_map);
255         cache_color_free(llc_cache, colors_map);
256         cache_color_free(llc_cache, colors_map);
257         cache_color_free(llc_cache, colors_map);
258         cache_color_free(llc_cache, colors_map);
259         cache_color_free(llc_cache, colors_map);
260         cache_color_free(llc_cache, colors_map);
261         cache_color_free(llc_cache, colors_map);
262         cache_color_free(llc_cache, colors_map);
263         cache_color_free(llc_cache, colors_map);
264         cache_color_free(l2, colors_map);
265         cache_color_free(llc_cache, colors_map);
266         cache_color_free(llc_cache, colors_map);
267
268 print_cache_colors:
269         printk("L1 free colors, tot colors: %d\n", l1->num_colors);
270         PRINT_BITMASK(l1->free_colors_map, l1->num_colors);
271         printk("L2 free colors, tot colors: %d\n", l2->num_colors);
272         PRINT_BITMASK(l2->free_colors_map, l2->num_colors);
273         printk("L3 free colors, tot colors: %d\n", l3->num_colors);
274         PRINT_BITMASK(l3->free_colors_map, l3->num_colors);
275         printk("Process allocated colors\n");
276         PRINT_BITMASK(colors_map, llc_cache->num_colors);
277         printk("test_color_alloc() complete!\n");
278
279         return true;
280 }
281
282 barrier_t test_cpu_array;
283
284 // TODO: Add assertions, try to do everything from within this same function.
285 bool test_barrier(void)
286 {
287         cprintf("Core 0 initializing barrier\n");
288         init_barrier(&test_cpu_array, num_cpus);
289         cprintf("Core 0 asking all cores to print ids, barrier, rinse, repeat\n");
290         smp_call_function_all(test_barrier_handler, NULL, 0);
291
292         return true;
293 }
294
295 // TODO: Maybe remove all the printing statements and instead use the 
296 //       KT_ASSERT_M macro to include a message on assertions.
297 bool test_interrupts_irqsave(void)
298 {
299         int8_t state = 0;
300         printd("Testing Nesting Enabling first, turning ints off:\n");
301         disable_irq();
302         printd("Interrupts are: %x\n", irq_is_enabled());
303         KT_ASSERT(!irq_is_enabled());
304         printd("Enabling IRQSave\n");
305         enable_irqsave(&state);
306         printd("Interrupts are: %x\n", irq_is_enabled());
307         KT_ASSERT(irq_is_enabled());
308         printd("Enabling IRQSave Again\n");
309         enable_irqsave(&state);
310         printd("Interrupts are: %x\n", irq_is_enabled());
311         KT_ASSERT(irq_is_enabled());
312         printd("Disabling IRQSave Once\n");
313         disable_irqsave(&state);
314         printd("Interrupts are: %x\n", irq_is_enabled());
315         KT_ASSERT(irq_is_enabled());
316         printd("Disabling IRQSave Again\n");
317         disable_irqsave(&state);
318         printd("Interrupts are: %x\n", irq_is_enabled());
319         KT_ASSERT(!irq_is_enabled());
320         printd("Done.  Should have been 0, 200, 200, 200, 0\n");
321
322         printd("Testing Nesting Disabling first, turning ints on:\n");
323         state = 0;
324         enable_irq();
325         printd("Interrupts are: %x\n", irq_is_enabled());
326         KT_ASSERT(irq_is_enabled());
327         printd("Disabling IRQSave Once\n");
328         disable_irqsave(&state);
329         printd("Interrupts are: %x\n", irq_is_enabled());
330         KT_ASSERT(!irq_is_enabled());
331         printd("Disabling IRQSave Again\n");
332         disable_irqsave(&state);
333         printd("Interrupts are: %x\n", irq_is_enabled());
334         KT_ASSERT(!irq_is_enabled());
335         printd("Enabling IRQSave Once\n");
336         enable_irqsave(&state);
337         printd("Interrupts are: %x\n", irq_is_enabled());
338         KT_ASSERT(!irq_is_enabled());
339         printd("Enabling IRQSave Again\n");
340         enable_irqsave(&state);
341         printd("Interrupts are: %x\n", irq_is_enabled());
342         KT_ASSERT(irq_is_enabled());
343         printd("Done.  Should have been 200, 0, 0, 0, 200 \n");
344
345         state = 0;
346         disable_irq();
347         printd("Ints are off, enabling then disabling.\n");
348         enable_irqsave(&state);
349         printd("Interrupts are: %x\n", irq_is_enabled());
350         KT_ASSERT(irq_is_enabled());
351         disable_irqsave(&state);
352         printd("Interrupts are: %x\n", irq_is_enabled());
353         KT_ASSERT(!irq_is_enabled());
354         printd("Done.  Should have been 200, 0\n");
355
356         state = 0;
357         enable_irq();
358         printd("Ints are on, enabling then disabling.\n");
359         enable_irqsave(&state);
360         printd("Interrupts are: %x\n", irq_is_enabled());
361         KT_ASSERT(irq_is_enabled());
362         disable_irqsave(&state);
363         printd("Interrupts are: %x\n", irq_is_enabled());
364         KT_ASSERT(irq_is_enabled());
365         printd("Done.  Should have been 200, 200\n");
366
367         state = 0;
368         disable_irq();
369         printd("Ints are off, disabling then enabling.\n");
370         disable_irqsave(&state);
371         printd("Interrupts are: %x\n", irq_is_enabled());
372         KT_ASSERT(!irq_is_enabled());
373         enable_irqsave(&state);
374         printd("Interrupts are: %x\n", irq_is_enabled());
375         KT_ASSERT(!irq_is_enabled());
376         printd("Done.  Should have been 0, 0\n");
377
378         state = 0;
379         enable_irq();
380         printd("Ints are on, disabling then enabling.\n");
381         disable_irqsave(&state);
382         printd("Interrupts are: %x\n", irq_is_enabled());
383         KT_ASSERT(!irq_is_enabled());
384         enable_irqsave(&state);
385         printd("Interrupts are: %x\n", irq_is_enabled());
386         KT_ASSERT(irq_is_enabled());
387         printd("Done.  Should have been 0, 200\n");
388
389         disable_irq();
390         return true;
391 }
392
393 // TODO: Maybe remove PRINT_BITMASK statements and use KT_ASSERT_M instead
394 //       somehow.
395 bool test_bitmasks(void)
396 {
397 #define masksize 67
398         DECL_BITMASK(mask, masksize);
399         CLR_BITMASK(mask, masksize);
400 //      PRINT_BITMASK(mask, masksize);
401         SET_BITMASK_BIT(mask, 0);
402         SET_BITMASK_BIT(mask, 11);
403         SET_BITMASK_BIT(mask, 17);
404         SET_BITMASK_BIT(mask, masksize-1);
405 //      PRINT_BITMASK(mask, masksize);
406         DECL_BITMASK(mask2, masksize);
407         COPY_BITMASK(mask2, mask, masksize);
408 //      printk("copy of original mask, should be the same as the prev\n");
409 //      PRINT_BITMASK(mask2, masksize);
410         CLR_BITMASK_BIT(mask, 11);
411 //      PRINT_BITMASK(mask, masksize);
412         KT_ASSERT_M("Bit 17 should be 1", 1 == GET_BITMASK_BIT(mask, 17));
413         KT_ASSERT_M("Bit 11 should be 0", 0 == GET_BITMASK_BIT(mask, 11));
414         FILL_BITMASK(mask, masksize);
415 //      PRINT_BITMASK(mask, masksize);
416         KT_ASSERT_M("Bitmask should not be clear after calling FILL_BITMASK", 
417                     0 == BITMASK_IS_CLEAR(mask,masksize));
418         CLR_BITMASK(mask, masksize);
419 //      PRINT_BITMASK(mask, masksize);
420         KT_ASSERT_M("Bitmask should be clear after calling CLR_BITMASK", 
421                     1 == BITMASK_IS_CLEAR(mask,masksize));
422         return true;
423 }
424
425 checklist_t *RO the_global_list;
426
427 static void test_checklist_handler(struct hw_trapframe *hw_tf, void *data)
428 {
429         udelay(1000000);
430         cprintf("down_checklist(%x,%d)\n", the_global_list, core_id());
431         down_checklist(the_global_list);
432 }
433
434 // TODO: Add assertions
435 bool test_checklists(void)
436 {
437         INIT_CHECKLIST(a_list, MAX_NUM_CPUS);
438         the_global_list = &a_list;
439         printk("Checklist Build, mask size: %d\n", sizeof(a_list.mask.bits));
440         printk("mask\n");
441         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
442         SET_BITMASK_BIT(a_list.mask.bits, 11);
443         printk("Set bit 11\n");
444         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
445
446         CLR_BITMASK(a_list.mask.bits, a_list.mask.size);
447         INIT_CHECKLIST_MASK(a_mask, MAX_NUM_CPUS);
448         FILL_BITMASK(a_mask.bits, num_cpus);
449         //CLR_BITMASK_BIT(a_mask.bits, core_id());
450         //SET_BITMASK_BIT(a_mask.bits, 1);
451         //printk("New mask (1, 17, 25):\n");
452         printk("Created new mask, filled up to num_cpus\n");
453         PRINT_BITMASK(a_mask.bits, a_mask.size);
454         printk("committing new mask\n");
455         commit_checklist_wait(&a_list, &a_mask);
456         printk("Old mask (copied onto):\n");
457         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
458         //smp_call_function_single(1, test_checklist_handler, 0, 0);
459
460         smp_call_function_all(test_checklist_handler, NULL, 0);
461
462         printk("Waiting on checklist\n");
463         waiton_checklist(&a_list);
464         printk("Done Waiting!\n");
465
466         return true;
467 }
468
469 atomic_t a, b, c;
470
471 static void test_incrementer_handler(struct hw_trapframe *tf, void *data)
472 {
473         assert(data);
474         atomic_inc(data);
475 }
476
477 static void test_null_handler(struct hw_trapframe *tf, void *data)
478 {
479         asm volatile("nop");
480 }
481
482 // TODO: Add assertions.
483 bool test_smp_call_functions(void)
484 {
485         int i;
486         atomic_init(&a, 0);
487         atomic_init(&b, 0);
488         atomic_init(&c, 0);
489         handler_wrapper_t *waiter0 = 0, *waiter1 = 0, *waiter2 = 0, *waiter3 = 0,
490                           *waiter4 = 0, *waiter5 = 0;
491         uint8_t me = core_id();
492         printk("\nCore %d: SMP Call Self (nowait):\n", me);
493         printk("---------------------\n");
494         smp_call_function_self(test_hello_world_handler, NULL, 0);
495         printk("\nCore %d: SMP Call Self (wait):\n", me);
496         printk("---------------------\n");
497         smp_call_function_self(test_hello_world_handler, NULL, &waiter0);
498         smp_call_wait(waiter0);
499         printk("\nCore %d: SMP Call All (nowait):\n", me);
500         printk("---------------------\n");
501         smp_call_function_all(test_hello_world_handler, NULL, 0);
502         printk("\nCore %d: SMP Call All (wait):\n", me);
503         printk("---------------------\n");
504         smp_call_function_all(test_hello_world_handler, NULL, &waiter0);
505         smp_call_wait(waiter0);
506         printk("\nCore %d: SMP Call All-Else Individually, in order (nowait):\n", me);
507         printk("---------------------\n");
508         for(i = 1; i < num_cpus; i++)
509                 smp_call_function_single(i, test_hello_world_handler, NULL, 0);
510         printk("\nCore %d: SMP Call Self (wait):\n", me);
511         printk("---------------------\n");
512         smp_call_function_self(test_hello_world_handler, NULL, &waiter0);
513         smp_call_wait(waiter0);
514         printk("\nCore %d: SMP Call All-Else Individually, in order (wait):\n", me);
515         printk("---------------------\n");
516         for(i = 1; i < num_cpus; i++)
517         {
518                 smp_call_function_single(i, test_hello_world_handler, NULL, &waiter0);
519                 smp_call_wait(waiter0);
520         }
521         printk("\nTesting to see if any IPI-functions are dropped when not waiting:\n");
522         printk("A: %d, B: %d, C: %d (should be 0,0,0)\n", atomic_read(&a), atomic_read(&b), atomic_read(&c));
523         smp_call_function_all(test_incrementer_handler, &a, 0);
524         smp_call_function_all(test_incrementer_handler, &b, 0);
525         smp_call_function_all(test_incrementer_handler, &c, 0);
526         // if i can clobber a previous IPI, the interleaving might do it
527         smp_call_function_single(1 % num_cpus, test_incrementer_handler, &a, 0);
528         smp_call_function_single(2 % num_cpus, test_incrementer_handler, &b, 0);
529         smp_call_function_single(3 % num_cpus, test_incrementer_handler, &c, 0);
530         smp_call_function_single(4 % num_cpus, test_incrementer_handler, &a, 0);
531         smp_call_function_single(5 % num_cpus, test_incrementer_handler, &b, 0);
532         smp_call_function_single(6 % num_cpus, test_incrementer_handler, &c, 0);
533         smp_call_function_all(test_incrementer_handler, &a, 0);
534         smp_call_function_single(3 % num_cpus, test_incrementer_handler, &c, 0);
535         smp_call_function_all(test_incrementer_handler, &b, 0);
536         smp_call_function_single(1 % num_cpus, test_incrementer_handler, &a, 0);
537         smp_call_function_all(test_incrementer_handler, &c, 0);
538         smp_call_function_single(2 % num_cpus, test_incrementer_handler, &b, 0);
539         // wait, so we're sure the others finish before printing.
540         // without this, we could (and did) get 19,18,19, since the B_inc
541         // handler didn't finish yet
542         smp_call_function_self(test_null_handler, NULL, &waiter0);
543         // need to grab all 5 handlers (max), since the code moves to the next free.
544         smp_call_function_self(test_null_handler, NULL, &waiter1);
545         smp_call_function_self(test_null_handler, NULL, &waiter2);
546         smp_call_function_self(test_null_handler, NULL, &waiter3);
547         smp_call_function_self(test_null_handler, NULL, &waiter4);
548         smp_call_wait(waiter0);
549         smp_call_wait(waiter1);
550         smp_call_wait(waiter2);
551         smp_call_wait(waiter3);
552         smp_call_wait(waiter4);
553         printk("A: %d, B: %d, C: %d (should be 19,19,19)\n", atomic_read(&a), atomic_read(&b), atomic_read(&c));
554         printk("Attempting to deadlock by smp_calling with an outstanding wait:\n");
555         smp_call_function_self(test_null_handler, NULL, &waiter0);
556         printk("Sent one\n");
557         smp_call_function_self(test_null_handler, NULL, &waiter1);
558         printk("Sent two\n");
559         smp_call_wait(waiter0);
560         printk("Wait one\n");
561         smp_call_wait(waiter1);
562         printk("Wait two\n");
563         printk("\tMade it through!\n");
564         printk("Attempting to deadlock by smp_calling more than are available:\n");
565         printk("\tShould see an Insufficient message and a kernel warning.\n");
566         if (smp_call_function_self(test_null_handler, NULL, &waiter0))
567                 printk("\tInsufficient handlers to call function (0)\n");
568         if (smp_call_function_self(test_null_handler, NULL, &waiter1))
569                 printk("\tInsufficient handlers to call function (1)\n");
570         if (smp_call_function_self(test_null_handler, NULL, &waiter2))
571                 printk("\tInsufficient handlers to call function (2)\n");
572         if (smp_call_function_self(test_null_handler, NULL, &waiter3))
573                 printk("\tInsufficient handlers to call function (3)\n");
574         if (smp_call_function_self(test_null_handler, NULL, &waiter4))
575                 printk("\tInsufficient handlers to call function (4)\n");
576         if (smp_call_function_self(test_null_handler, NULL, &waiter5))
577                 printk("\tInsufficient handlers to call function (5)\n");
578         smp_call_wait(waiter0);
579         smp_call_wait(waiter1);
580         smp_call_wait(waiter2);
581         smp_call_wait(waiter3);
582         smp_call_wait(waiter4);
583         smp_call_wait(waiter5);
584         printk("\tMade it through!\n");
585
586         printk("Done\n");
587
588         return true;
589 }
590
591 #ifdef CONFIG_X86
592 // TODO: Fix the KT_ASSERTs
593 bool test_lapic_status_bit(void)
594 {
595         register_irq(I_TESTING, test_incrementer_handler, &a,
596                      MKBUS(BusIPI, 0, 0, 0));
597         #define NUM_IPI 100000
598         atomic_set(&a,0);
599         printk("IPIs received (should be 0): %d\n", a);
600         // KT_ASSERT_M("IPIs received should be 0", (0 == a));
601         for(int i = 0; i < NUM_IPI; i++) {
602                 send_ipi(7, I_TESTING);
603                 lapic_wait_to_send();
604         }
605         // need to wait a bit to let those IPIs get there
606         udelay(5000000);
607         printk("IPIs received (should be %d): %d\n", a, NUM_IPI);
608         // KT_ASSERT_M("IPIs received should be 100000", (NUM_IPI == a));
609         // hopefully that handler never fires again.  leaving it registered for now.
610
611         return true;
612 }
613 #endif // CONFIG_X86
614
615 /************************************************************/
616 /* ISR Handler Functions */
617
618 void test_hello_world_handler(struct hw_trapframe *hw_tf, void *data)
619 {
620         int trapno;
621         #if defined(CONFIG_X86)
622         trapno = hw_tf->tf_trapno;
623         #else
624         trapno = 0;
625         #endif
626
627         cprintf("Incoming IRQ, ISR: %d on core %d with tf at %p\n",
628                 trapno, core_id(), hw_tf);
629 }
630
631 spinlock_t print_info_lock = SPINLOCK_INITIALIZER_IRQSAVE;
632
633 void test_print_info_handler(struct hw_trapframe *hw_tf, void *data)
634 {
635         uint64_t tsc = read_tsc();
636
637         spin_lock_irqsave(&print_info_lock);
638         cprintf("----------------------------\n");
639         cprintf("This is Core %d\n", core_id());
640         cprintf("Timestamp = %lld\n", tsc);
641 #ifdef CONFIG_X86
642         cprintf("Hardware core %d\n", hw_core_id());
643         cprintf("MTRR_DEF_TYPE = 0x%08x\n", read_msr(IA32_MTRR_DEF_TYPE));
644         cprintf("MTRR Phys0 Base = 0x%016llx, Mask = 0x%016llx\n",
645                 read_msr(0x200), read_msr(0x201));
646         cprintf("MTRR Phys1 Base = 0x%016llx, Mask = 0x%016llx\n",
647                 read_msr(0x202), read_msr(0x203));
648         cprintf("MTRR Phys2 Base = 0x%016llx, Mask = 0x%016llx\n",
649                 read_msr(0x204), read_msr(0x205));
650         cprintf("MTRR Phys3 Base = 0x%016llx, Mask = 0x%016llx\n",
651                 read_msr(0x206), read_msr(0x207));
652         cprintf("MTRR Phys4 Base = 0x%016llx, Mask = 0x%016llx\n",
653                 read_msr(0x208), read_msr(0x209));
654         cprintf("MTRR Phys5 Base = 0x%016llx, Mask = 0x%016llx\n",
655                 read_msr(0x20a), read_msr(0x20b));
656         cprintf("MTRR Phys6 Base = 0x%016llx, Mask = 0x%016llx\n",
657                 read_msr(0x20c), read_msr(0x20d));
658         cprintf("MTRR Phys7 Base = 0x%016llx, Mask = 0x%016llx\n",
659                 read_msr(0x20e), read_msr(0x20f));
660 #endif // CONFIG_X86
661         cprintf("----------------------------\n");
662         spin_unlock_irqsave(&print_info_lock);
663 }
664
665 void test_barrier_handler(struct hw_trapframe *hw_tf, void *data)
666 {
667         cprintf("Round 1: Core %d\n", core_id());
668         waiton_barrier(&test_cpu_array);
669         waiton_barrier(&test_cpu_array);
670         waiton_barrier(&test_cpu_array);
671         waiton_barrier(&test_cpu_array);
672         waiton_barrier(&test_cpu_array);
673         waiton_barrier(&test_cpu_array);
674         cprintf("Round 2: Core %d\n", core_id());
675         waiton_barrier(&test_cpu_array);
676         cprintf("Round 3: Core %d\n", core_id());
677         // uncomment to see it fucked up
678         //cprintf("Round 4: Core %d\n", core_id());
679 }
680
681 static void test_waiting_handler(struct hw_trapframe *hw_tf, void *data)
682 {
683         atomic_dec(data);
684 }
685
686 #ifdef CONFIG_X86
687 // TODO: Add assertions.
688 bool test_pit(void)
689 {
690         cprintf("Starting test for PIT now (10s)\n");
691         udelay_pit(10000000);
692         cprintf("End now\n");
693         cprintf("Starting test for TSC (if stable) now (10s)\n");
694         udelay(10000000);
695         cprintf("End now\n");
696
697         cprintf("Starting test for LAPIC (if stable) now (10s)\n");
698         enable_irq();
699         lapic_set_timer(10000000, FALSE);
700
701         atomic_t waiting;
702         atomic_init(&waiting, 1);
703         register_irq(I_TESTING, test_waiting_handler, &waiting,
704                      MKBUS(BusIPI, 0, 0, 0));
705         while(atomic_read(&waiting))
706                 cpu_relax();
707         cprintf("End now\n");
708
709         return true;
710 }
711
712 // TODO: Add assertions.
713 bool test_circ_buffer(void)
714 {
715         int arr[5] = {0, 1, 2, 3, 4};
716
717         for (int i = 0; i < 5; i++) {
718                 FOR_CIRC_BUFFER(i, 5, j)
719                         printk("Starting with current = %d, each value = %d\n", i, j);
720         }
721         
722         return true;
723 }
724
725 static void test_km_handler(uint32_t srcid, long a0, long a1, long a2)
726 {
727         printk("Received KM on core %d from core %d: arg0= %p, arg1 = %p, "
728                "arg2 = %p\n", core_id(), srcid, a0, a1, a2);
729         return;
730 }
731
732 // TODO: Add assertions. Try to do everything inside this function.
733 bool test_kernel_messages(void)
734 {
735         printk("Testing Kernel Messages\n");
736         /* Testing sending multiples, sending different types, alternating, and
737          * precendence (the immediates should trump the others) */
738         printk("sending 5 IMMED to core 1, sending (#,deadbeef,0)\n");
739         for (int i = 0; i < 5; i++)
740                 send_kernel_message(1, test_km_handler, (long)i, 0xdeadbeef, 0,
741                                     KMSG_IMMEDIATE);
742         udelay(5000000);
743         printk("sending 5 routine to core 1, sending (#,cafebabe,0)\n");
744         for (int i = 0; i < 5; i++)
745                 send_kernel_message(1, test_km_handler, (long)i, 0xcafebabe, 0,
746                                     KMSG_ROUTINE);
747         udelay(5000000);
748         printk("sending 10 routine and 3 immediate to core 2\n");
749         for (int i = 0; i < 10; i++)
750                 send_kernel_message(2, test_km_handler, (long)i, 0xcafebabe, 0,
751                                     KMSG_ROUTINE);
752         for (int i = 0; i < 3; i++)
753                 send_kernel_message(2, test_km_handler, (long)i, 0xdeadbeef, 0,
754                                     KMSG_IMMEDIATE);
755         udelay(5000000);
756         printk("sending 5 ea alternating to core 2\n");
757         for (int i = 0; i < 5; i++) {
758                 send_kernel_message(2, test_km_handler, (long)i, 0xdeadbeef, 0,
759                                     KMSG_IMMEDIATE);
760                 send_kernel_message(2, test_km_handler, (long)i, 0xcafebabe, 0,
761                                     KMSG_ROUTINE);
762         }
763         udelay(5000000);
764         
765         return true;
766 }
767 #endif // CONFIG_X86
768 static void test_single_cache(int iters, size_t size, int align, int flags,
769                               void (*ctor)(void *, size_t),
770                               void (*dtor)(void *, size_t))
771 {
772         struct kmem_cache *test_cache;
773         void *objects[iters];
774         test_cache = kmem_cache_create("test_cache", size, align, flags, ctor, dtor);
775         printk("Testing Kmem Cache:\n");
776         print_kmem_cache(test_cache);
777         for (int i = 0; i < iters; i++) {
778                 objects[i] = kmem_cache_alloc(test_cache, 0);
779                 printk("Buffer %d addr = %p\n", i, objects[i]);
780         }
781         for (int i = 0; i < iters; i++) {
782                 kmem_cache_free(test_cache, objects[i]);
783         }
784         kmem_cache_destroy(test_cache);
785         printk("\n\n\n\n");
786 }
787
788 void a_ctor(void *buf, size_t size)
789 {
790         printk("constructin tests\n");
791 }
792 void a_dtor(void *buf, size_t size)
793 {
794         printk("destructin tests\n");
795 }
796
797 // TODO: Make test_single_cache return something, and then add assertions here.
798 bool test_slab(void)
799 {
800         test_single_cache(10, 128, 512, 0, 0, 0);
801         test_single_cache(10, 128, 4, 0, a_ctor, a_dtor);
802         test_single_cache(10, 1024, 16, 0, 0, 0);
803
804         return true;
805 }
806
807 // TODO: Add assertions.
808 bool test_kmalloc(void)
809 {
810         printk("Testing Kmalloc\n");
811         void *bufs[NUM_KMALLOC_CACHES + 1];     
812         size_t size;
813         for (int i = 0; i < NUM_KMALLOC_CACHES + 1; i++){
814                 size = (KMALLOC_SMALLEST << i) - sizeof(struct kmalloc_tag);
815                 bufs[i] = kmalloc(size, 0);
816                 printk("Size %d, Addr = %p\n", size, bufs[i]);
817         }
818         for (int i = 0; i < NUM_KMALLOC_CACHES; i++) {
819                 printk("Freeing buffer %d\n", i);
820                 kfree(bufs[i]);
821         }
822         printk("Testing a large kmalloc\n");
823         size = (KMALLOC_LARGEST << 2);
824         bufs[0] = kmalloc(size, 0);
825         printk("Size %d, Addr = %p\n", size, bufs[0]);
826         kfree(bufs[0]);
827
828         return true;
829 }
830
831 static size_t test_hash_fn_col(void *k)
832 {
833         return (size_t)k % 2; // collisions in slots 0 and 1
834 }
835
836 bool test_hashtable(void)
837 {
838         struct test {int x; int y;};
839         struct test tstruct[10];
840
841         struct hashtable *h;
842         uintptr_t k = 5;
843         struct test *v = &tstruct[0];
844
845         h = create_hashtable(32, __generic_hash, __generic_eq);
846         
847         // test inserting one item, then finding it again
848         KT_ASSERT_M("It should be possible to insert items to a hashtable", 
849                     hashtable_insert(h, (void*)k, v));
850         v = NULL;
851         KT_ASSERT_M("It should be possible to find inserted stuff in a hashtable", 
852                     (v = hashtable_search(h, (void*)k)));
853
854         KT_ASSERT_M("The extracted element should be the same we inserted", 
855                     (v == &tstruct[0]));
856
857         v = NULL;
858
859         KT_ASSERT_M("It should be possible to remove an existing element", 
860                     (v = hashtable_remove(h, (void*)k)));
861
862         KT_ASSERT_M("An element should not remain in a hashtable after deletion", 
863                     !(v = hashtable_search(h, (void*)k)));
864
865         /* Testing a bunch of items, insert, search, and removal */
866         for (int i = 0; i < 10; i++) {
867                 k = i; // vary the key, we don't do KEY collisions
868                 KT_ASSERT_M("It should be possible to insert elements to a hashtable", 
869                             (hashtable_insert(h, (void*)k, &tstruct[i])));
870         }
871         // read out the 10 items
872         for (int i = 0; i < 10; i++) {
873                 k = i;
874                 KT_ASSERT_M("It should be possible to find inserted stuff in a hashtable", 
875                             (v = hashtable_search(h, (void*)k)));
876                 KT_ASSERT_M("The extracted element should be the same we inserted", 
877                             (v == &tstruct[i]));
878         }
879
880         KT_ASSERT_M("The total count of number of elements should be 10", 
881                     (10 == hashtable_count(h)));
882
883         // remove the 10 items
884         for (int i = 0; i < 10; i++) {
885                 k = i;
886                 KT_ASSERT_M("It should be possible to remove an existing element", 
887                             (v = hashtable_remove(h, (void*)k)));
888
889         }
890         // make sure they are all gone
891         for (int i = 0; i < 10; i++) {
892                 k = i;
893                 KT_ASSERT_M("An element should not remain in a hashtable after deletion", 
894                             !(v = hashtable_search(h, (void*)k)));
895         }
896
897         KT_ASSERT_M("The hashtable should be empty", 
898                     (0 == hashtable_count(h)));
899
900         hashtable_destroy(h);
901
902         // same test of a bunch of items, but with collisions.
903         /* Testing a bunch of items with collisions, etc. */
904         h = create_hashtable(32, test_hash_fn_col, __generic_eq);
905         // insert 10 items
906         for (int i = 0; i < 10; i++) {
907                 k = i; // vary the key, we don't do KEY collisions
908
909                 KT_ASSERT_M("It should be possible to insert elements to a hashtable", 
910                             (hashtable_insert(h, (void*)k, &tstruct[i])));
911         }
912         // read out the 10 items
913         for (int i = 0; i < 10; i++) {
914                 k = i;
915                 KT_ASSERT_M("It should be possible to find inserted stuff in a hashtable", 
916                             (v = hashtable_search(h, (void*)k)));
917                 KT_ASSERT_M("The extracted element should be the same we inserted", 
918                             (v == &tstruct[i]));
919         }
920
921         KT_ASSERT_M("The total count of number of elements should be 10", 
922                     (10 == hashtable_count(h)));
923
924         // remove the 10 items
925         for (int i = 0; i < 10; i++) {
926                 k = i;
927                 KT_ASSERT_M("It should be possible to remove an existing element", 
928                             (v = hashtable_remove(h, (void*)k)));
929         }
930         // make sure they are all gone
931         for (int i = 0; i < 10; i++) {
932                 k = i;
933
934                 KT_ASSERT_M("An element should not remain in a hashtable after deletion", 
935                             !(v = hashtable_search(h, (void*)k)));
936         }
937
938         KT_ASSERT_M("The hashtable should be empty", 
939                     (0 == hashtable_count(h)));
940
941         hashtable_destroy(h);
942
943         return true;
944 }
945
946 /* Ghetto test, only tests one prod or consumer at a time */
947 // TODO: Un-guetto test, add assertions.
948 bool test_bcq(void)
949 {
950         /* Tests a basic struct */
951         struct my_struct {
952                 int x;
953                 int y;
954         };
955         struct my_struct in_struct, out_struct;
956         
957         DEFINE_BCQ_TYPES(test, struct my_struct, 16);
958         struct test_bcq t_bcq;
959         bcq_init(&t_bcq, struct my_struct, 16);
960         
961         in_struct.x = 4;
962         in_struct.y = 5;
963         out_struct.x = 1;
964         out_struct.y = 2;
965         
966         bcq_enqueue(&t_bcq, &in_struct, 16, 5);
967         bcq_dequeue(&t_bcq, &out_struct, 16);
968         printk("out x %d. out y %d\n", out_struct.x, out_struct.y);
969         
970         /* Tests the BCQ a bit more, esp with overflow */
971         #define NR_ELEM_A_BCQ 8 /* NOTE: this must be a power of 2! */
972         DEFINE_BCQ_TYPES(my, int, NR_ELEM_A_BCQ);
973         struct my_bcq a_bcq;
974         bcq_init(&a_bcq, int, NR_ELEM_A_BCQ);
975         
976         int y = 2;
977         int output[100];
978         int retval[100];
979
980         /* Helpful debugger */
981         void print_a_bcq(struct my_bcq *bcq)
982         {
983                 printk("A BCQ (made of ints): %p\n", bcq);
984                 printk("\tprod_idx: %p\n", bcq->hdr.prod_idx);
985                 printk("\tcons_pub_idx: %p\n", bcq->hdr.cons_pub_idx);
986                 printk("\tcons_pvt_idx: %p\n", bcq->hdr.cons_pvt_idx);
987                 for (int i = 0; i < NR_ELEM_A_BCQ; i++) {
988                         printk("Element %d, rdy_for_cons: %02p\n", i,
989                                bcq->wraps[i].rdy_for_cons);
990                 }
991         }
992
993         /* Put in more than it can take */
994         for (int i = 0; i < 15; i++) {
995                 y = i;
996                 retval[i] = bcq_enqueue(&a_bcq, &y, NR_ELEM_A_BCQ, 10);
997                 printk("enqueued: %d, had retval %d \n", y, retval[i]);
998         }
999         //print_a_bcq(&a_bcq);
1000         
1001         /* Try to dequeue more than we put in */
1002         for (int i = 0; i < 15; i++) {
1003                 retval[i] = bcq_dequeue(&a_bcq, &output[i], NR_ELEM_A_BCQ);
1004                 printk("dequeued: %d with retval %d\n", output[i], retval[i]);
1005         }
1006         //print_a_bcq(&a_bcq);
1007         
1008         /* Put in some it should be able to take */
1009         for (int i = 0; i < 3; i++) {
1010                 y = i;
1011                 retval[i] = bcq_enqueue(&a_bcq, &y, NR_ELEM_A_BCQ, 10);
1012                 printk("enqueued: %d, had retval %d \n", y, retval[i]);
1013         }
1014         
1015         /* Take those, and then a couple extra */
1016         for (int i = 0; i < 5; i++) {
1017                 retval[i] = bcq_dequeue(&a_bcq, &output[i], NR_ELEM_A_BCQ);
1018                 printk("dequeued: %d with retval %d\n", output[i], retval[i]);
1019         }
1020         
1021         /* Try some one-for-one */
1022         for (int i = 0; i < 5; i++) {
1023                 y = i;
1024                 retval[i] = bcq_enqueue(&a_bcq, &y, NR_ELEM_A_BCQ, 10);
1025                 printk("enqueued: %d, had retval %d \n", y, retval[i]);
1026                 retval[i] = bcq_dequeue(&a_bcq, &output[i], NR_ELEM_A_BCQ);
1027                 printk("dequeued: %d with retval %d\n", output[i], retval[i]);
1028         }
1029
1030         return true;
1031 }
1032
1033 /* Test a simple concurrent send and receive (one prod, one cons).  We spawn a
1034  * process that will go into _M mode on another core, and we'll do the test from
1035  * an alarm handler run on our core.  When we start up the process, we won't
1036  * return so we need to defer the work with an alarm. */
1037 // TODO: Check if we can add more assertions.
1038 bool test_ucq(void)
1039 {
1040         struct timer_chain *tchain = &per_cpu_info[core_id()].tchain;
1041         struct alarm_waiter *waiter = kmalloc(sizeof(struct alarm_waiter), 0);
1042
1043         /* Alarm handler: what we want to do after the process is up */
1044         void send_msgs(struct alarm_waiter *waiter)
1045         {
1046                 struct timer_chain *tchain;
1047                 struct proc *old_proc, *p = waiter->data;
1048                 struct ucq *ucq = (struct ucq*)USTACKTOP;
1049                 struct event_msg msg;
1050
1051                 printk("Running the alarm handler!\n");
1052                 printk("NR msg per page: %d\n", NR_MSG_PER_PAGE);
1053                 /* might not be mmaped yet, if not, abort.  We used to user_mem_check,
1054                  * but now we just touch it and PF. */
1055                 char touch = *(char*)ucq;
1056                 asm volatile ("" : : "r"(touch));
1057                 /* load their address space */
1058                 old_proc = switch_to(p);
1059                 /* So it's mmaped, see if it is ready (note that this is dangerous) */
1060                 if (!ucq->ucq_ready) {
1061                         printk("Not ready yet\n");
1062                         switch_back(p, old_proc);
1063                         goto abort;
1064                 }
1065                 /* So it's ready, time to finally do the tests... */
1066                 printk("[kernel] Finally starting the tests... \n");
1067                 /* 1: Send a simple message */
1068                 printk("[kernel] #1 Sending simple message (7, deadbeef)\n");
1069                 msg.ev_type = 7;
1070                 msg.ev_arg2 = 0xdeadbeef;
1071                 send_ucq_msg(ucq, p, &msg);
1072                 printk("nr_pages: %d\n", atomic_read(&ucq->nr_extra_pgs));
1073                 /* 2: Send a bunch.  In a VM, this causes one swap, and then a bunch of
1074                  * mmaps. */
1075                 printk("[kernel] #2 \n");
1076                 for (int i = 0; i < 5000; i++) {
1077                         msg.ev_type = i;
1078                         send_ucq_msg(ucq, p, &msg);
1079                 }
1080                 printk("nr_pages: %d\n", atomic_read(&ucq->nr_extra_pgs));
1081                 printk("[kernel] #3 \n");
1082                 /* 3: make sure we chained pages (assuming 1k is enough) */
1083                 for (int i = 0; i < 1000; i++) {
1084                         msg.ev_type = i;
1085                         send_ucq_msg(ucq, p, &msg);
1086                 }
1087                 printk("nr_pages: %d\n", atomic_read(&ucq->nr_extra_pgs));
1088                 /* other things we could do:
1089                  *  - concurrent producers / consumers...  ugh.
1090                  *  - would require a kmsg to another core, instead of a local alarm
1091                  */
1092                 /* done, switch back and free things */
1093                 switch_back(p, old_proc);
1094                 proc_decref(p);
1095                 kfree(waiter); /* since it was kmalloc()d */
1096                 return;
1097         abort:
1098                 tchain = &per_cpu_info[core_id()].tchain;
1099                 /* Set to run again */
1100                 set_awaiter_rel(waiter, 1000000);
1101                 set_alarm(tchain, waiter);
1102         }
1103         /* Set up a handler to run the real part of the test */
1104         init_awaiter(waiter, send_msgs);
1105         set_awaiter_rel(waiter, 1000000);       /* 1s should be long enough */
1106         set_alarm(tchain, waiter);
1107         /* Just spawn the program */
1108         struct file *program;
1109         program = do_file_open("/bin/ucq", 0, 0);
1110         
1111         KT_ASSERT_M("We should be able to find /bin/ucq", 
1112                     program);
1113
1114         char *p_envp[] = {"LD_LIBRARY_PATH=/lib", 0};
1115         struct proc *p = proc_create(program, 0, p_envp);
1116         proc_wakeup(p);
1117         /* instead of getting rid of the reference created in proc_create, we'll put
1118          * it in the awaiter */
1119         waiter->data = p;
1120         kref_put(&program->f_kref);
1121         /* Should never return from schedule (env_pop in there) also note you may
1122          * not get the process you created, in the event there are others floating
1123          * around that are runnable */
1124         run_scheduler();
1125         smp_idle();
1126         
1127         KT_ASSERT_M("We should never return from schedule",
1128                     false);
1129
1130         return true;
1131 }
1132
1133 /* rudimentary tests.  does the basics, create, merge, split, etc.  Feel free to
1134  * add more, esp for the error conditions and finding free slots.  This is also
1135  * a bit lazy with setting the caller's fields (perm, flags, etc). */
1136 // TODO: See if we could add more assertions, try to add more descriptive
1137 //       messages to assertions.
1138 bool test_vm_regions(void)
1139 {
1140         #define MAX_VMR_TESTS 10
1141         struct proc pr, *p = &pr;       /* too lazy to even create one */
1142         int n = 0;
1143         TAILQ_INIT(&p->vm_regions);
1144
1145         struct vmr_summary {
1146                 uintptr_t base; 
1147                 uintptr_t end; 
1148         };
1149         int check_vmrs(struct proc *p, struct vmr_summary *results, int len, int n)
1150         {
1151                 int count = 0;
1152                 struct vm_region *vmr;
1153                 TAILQ_FOREACH(vmr, &p->vm_regions, vm_link) {
1154                         if (count >= len) {
1155                                 printk("More vm_regions than expected\n");
1156                                 break;
1157                         }
1158                         if ((vmr->vm_base != results[count].base) ||
1159                             (vmr->vm_end != results[count].end)) {
1160                                 printk("VM test case %d failed!\n", n);
1161                                 print_vmrs(p);
1162                                 return -1;
1163                         }
1164                         count++;
1165                 }
1166                 return count;
1167         }
1168         struct vm_region *vmrs[MAX_VMR_TESTS];
1169         struct vmr_summary results[MAX_VMR_TESTS];
1170
1171         memset(results, 0, sizeof(results));
1172         /* Make one */
1173         vmrs[0] = create_vmr(p, 0x2000, 0x1000);
1174         results[0].base = 0x2000;
1175         results[0].end = 0x3000;
1176         check_vmrs(p, results, 1, n++);
1177         /* Grow it */
1178         grow_vmr(vmrs[0], 0x4000);
1179         results[0].base = 0x2000;
1180         results[0].end = 0x4000;
1181         check_vmrs(p, results, 1, n++);
1182         /* Grow it poorly */
1183         KT_ASSERT_M("It should pass bad grow test", 
1184                     (-1 == grow_vmr(vmrs[0], 0x3000)));
1185         check_vmrs(p, results, 1, n++);
1186         /* Make another right next to it */
1187         vmrs[1] = create_vmr(p, 0x4000, 0x1000);
1188         results[1].base = 0x4000;
1189         results[1].end = 0x5000;
1190         check_vmrs(p, results, 2, n++);
1191         /* try to grow through it */
1192         KT_ASSERT_M("It should pass bad grow test", 
1193                     (-1 == grow_vmr(vmrs[0], 0x5000)));
1194         check_vmrs(p, results, 2, n++);
1195         /* Merge them */
1196         merge_vmr(vmrs[0], vmrs[1]);
1197         results[0].end = 0x5000;
1198         results[1].base = 0;
1199         results[1].end = 0;
1200         check_vmrs(p, results, 1, n++);
1201         vmrs[1]= create_vmr(p, 0x6000, 0x4000);
1202         results[1].base = 0x6000;
1203         results[1].end = 0xa000;
1204         check_vmrs(p, results, 2, n++);
1205         /* try to merge unmergables (just testing ranges) */
1206         KT_ASSERT_M("It should pass bad merge test", 
1207                     (-1 == merge_vmr(vmrs[0], vmrs[1])));
1208         check_vmrs(p, results, 2, n++);
1209         vmrs[2] = split_vmr(vmrs[1], 0x8000);
1210         results[1].end = 0x8000;
1211         results[2].base = 0x8000;
1212         results[2].end = 0xa000;
1213         check_vmrs(p, results, 3, n++);
1214         /* destroy one */
1215         destroy_vmr(vmrs[1]);
1216         results[1].base = 0x8000;
1217         results[1].end = 0xa000;
1218         check_vmrs(p, results, 2, n++);
1219         /* shrink */
1220         shrink_vmr(vmrs[2], 0x9000);
1221         results[1].base = 0x8000;
1222         results[1].end = 0x9000;
1223         check_vmrs(p, results, 2, n++); /* 10 */
1224         KT_ASSERT_M("We should be able to find the right vmr", 
1225                     (vmrs[2] == find_vmr(p, 0x8500)));
1226         KT_ASSERT_M("We should be able to find the right vmr", 
1227                     (vmrs[2] == find_first_vmr(p, 0x8500)));
1228         KT_ASSERT_M("We should be able to find the right vmr", 
1229                     (vmrs[2] == find_first_vmr(p, 0x7500)));
1230         KT_ASSERT_M("We shouldn't be able to find a vmr", 
1231                     !(find_first_vmr(p, 0x9500)));
1232         /* grow up to another */
1233         grow_vmr(vmrs[0], 0x8000);
1234         results[0].end = 0x8000;
1235         check_vmrs(p, results, 2, n++);
1236         vmrs[0]->vm_prot = 88;
1237         vmrs[2]->vm_prot = 77;
1238         /* should be unmergeable due to perms */
1239         KT_ASSERT_M("It should pass bad merge test", 
1240                     -1 == merge_vmr(vmrs[0], vmrs[2]));
1241         check_vmrs(p, results, 2, n++);
1242         /* should merge now */
1243         vmrs[2]->vm_prot = 88;
1244         merge_vmr(vmrs[0], vmrs[2]);
1245         results[0].end = 0x9000;
1246         check_vmrs(p, results, 1, n++);
1247         destroy_vmr(vmrs[0]);
1248         check_vmrs(p, results, 0, n++);
1249         /* Check the automerge function */
1250         vmrs[0] = create_vmr(p, 0x2000, 0x1000);
1251         vmrs[1] = create_vmr(p, 0x3000, 0x1000);
1252         vmrs[2] = create_vmr(p, 0x4000, 0x1000);
1253         for (int i = 0; i < 3; i++) {
1254                 vmrs[i]->vm_prot = PROT_READ;
1255                 vmrs[i]->vm_flags = 0;
1256                 vmrs[i]->vm_file = 0; /* would like to test this, it's a pain for now */
1257         }
1258         vmrs[0] = merge_me(vmrs[1]);
1259         results[0].base = 0x2000;
1260         results[0].end = 0x5000;
1261         check_vmrs(p, results, 1, n++);
1262         destroy_vmr(vmrs[0]);
1263         check_vmrs(p, results, 0, n++);
1264         /* Check unfixed creation requests */
1265         vmrs[0] = create_vmr(p, 0x0000, 0x1000);
1266         vmrs[1] = create_vmr(p, 0x0000, 0x1000);
1267         vmrs[2] = create_vmr(p, 0x0000, 0x1000);
1268         results[0].base = 0x0000;
1269         results[0].end  = 0x1000;
1270         results[1].base = 0x1000;
1271         results[1].end  = 0x2000;
1272         results[2].base = 0x2000;
1273         results[2].end  = 0x3000;
1274         check_vmrs(p, results, 3, n++);
1275
1276         return true;
1277 }
1278
1279 bool test_radix_tree(void)
1280 {
1281         struct radix_tree real_tree = RADIX_INITIALIZER;
1282         struct radix_tree *tree = &real_tree;
1283         void *retval;
1284
1285         KT_ASSERT_M("It should be possible to insert at 0", 
1286                     !radix_insert(tree, 0, (void*)0xdeadbeef, 0));
1287         radix_delete(tree, 0);
1288         KT_ASSERT_M("It should be possible to re-insert at 0", 
1289                     !radix_insert(tree, 0, (void*)0xdeadbeef, 0));
1290
1291         KT_ASSERT_M("It should be possible to insert first", 
1292                     !radix_insert(tree, 3, (void*)0xdeadbeef, 0));
1293         radix_insert(tree, 4, (void*)0x04040404, 0);
1294         KT_ASSERT((void*)0xdeadbeef == radix_lookup(tree, 3));
1295         for (int i = 5; i < 100; i++)
1296                 if ((retval = radix_lookup(tree, i))) {
1297                         printk("Extra item %p at slot %d in tree %p\n", retval, i,
1298                                tree);
1299                         print_radix_tree(tree);
1300                         monitor(0);
1301                 }
1302         KT_ASSERT_M("It should be possible to insert a two-tier", 
1303                     !radix_insert(tree, 65, (void*)0xcafebabe, 0));
1304         KT_ASSERT_M("It should not be possible to reinsert", 
1305                     radix_insert(tree, 4, (void*)0x03030303, 0));
1306         KT_ASSERT_M("It should be possible to insert a two-tier boundary", 
1307                     !radix_insert(tree, 4095, (void*)0x4095, 0));
1308         KT_ASSERT_M("It should be possible to insert a three-tier", 
1309                     !radix_insert(tree, 4096, (void*)0x4096, 0));
1310         //print_radix_tree(tree);
1311         radix_delete(tree, 65);
1312         radix_delete(tree, 3);
1313         radix_delete(tree, 4);
1314         radix_delete(tree, 4095);
1315         radix_delete(tree, 4096);
1316         //print_radix_tree(tree);
1317
1318         return true;
1319 }
1320
1321 /* Assorted FS tests, which were hanging around in init.c */
1322 // TODO: remove all the print statements and try to convert most into assertions
1323 bool test_random_fs(void)
1324 {
1325         int retval = do_symlink("/dir1/sym", "/bin/hello", S_IRWXU);
1326         KT_ASSERT_M("symlink1 should be created successfully", 
1327                     (!retval));
1328         retval = do_symlink("/symdir", "/dir1/dir1-1", S_IRWXU);
1329         KT_ASSERT_M("symlink1 should be created successfully", 
1330                     (!retval));
1331         retval = do_symlink("/dir1/test.txt", "/dir2/test2.txt", S_IRWXU);
1332         KT_ASSERT_M("symlink2 should be created successfully", 
1333                     (!retval));
1334         retval = do_symlink("/dir1/dir1-1/up", "../../", S_IRWXU);
1335         KT_ASSERT_M("symlink3 should be created successfully", 
1336                     (!retval));
1337         retval = do_symlink("/bin/hello-sym", "hello", S_IRWXU);
1338         KT_ASSERT_M("symlink4 should be created successfully", 
1339                     (!retval));
1340
1341         struct dentry *dentry;
1342         struct nameidata nd_r = {0}, *nd = &nd_r;
1343         retval = path_lookup("/dir1/sym", 0, nd);
1344         KT_ASSERT_M("symlink lookup should work for an existing symlink", 
1345                     (!retval)); 
1346         char *symname = nd->dentry->d_inode->i_op->readlink(nd->dentry);
1347         printk("Pathlookup got %s (sym)\n", nd->dentry->d_name.name);
1348         if (!symname)
1349                 printk("symlink reading failed\n");
1350         else
1351                 printk("Symname: %s (/bin/hello)\n", symname);
1352         path_release(nd);
1353         /* try with follow */
1354         memset(nd, 0, sizeof(struct nameidata));
1355         retval = path_lookup("/dir1/sym", LOOKUP_FOLLOW, nd);
1356         
1357         KT_ASSERT_M("symlink lookup should work for an existing symlink", 
1358                     (!retval));
1359         printk("Pathlookup got %s (hello)\n", nd->dentry->d_name.name);
1360         path_release(nd);
1361         
1362         /* try with a directory */
1363         memset(nd, 0, sizeof(struct nameidata));
1364         retval = path_lookup("/symdir/f1-1.txt", 0, nd);
1365         KT_ASSERT_M("symlink lookup should work for an existing symlink", 
1366                     (!retval));
1367         printk("Pathlookup got %s (f1-1.txt)\n", nd->dentry->d_name.name);
1368         path_release(nd);
1369         
1370         /* try with a rel path */
1371         printk("Try with a rel path\n");
1372         memset(nd, 0, sizeof(struct nameidata));
1373         retval = path_lookup("/symdir/up/hello.txt", 0, nd);
1374         KT_ASSERT_M("symlink lookup should work for an existing symlink", 
1375                     (!retval));
1376         printk("Pathlookup got %s (hello.txt)\n", nd->dentry->d_name.name);
1377         path_release(nd);
1378         
1379         printk("Try for an ELOOP\n");
1380         memset(nd, 0, sizeof(struct nameidata));
1381         retval = path_lookup("/symdir/up/symdir/up/symdir/up/symdir/up/hello.txt", 0, nd);
1382         KT_ASSERT_M("symlink lookup should fail for a non existing symlink", 
1383                     (retval));
1384         path_release(nd);
1385
1386         return true;
1387 }
1388
1389 /* Kernel message to restart our kthread */
1390 static void __test_up_sem(uint32_t srcid, long a0, long a1, long a2)
1391 {
1392         struct semaphore *sem = (struct semaphore*)a0;
1393         printk("[kmsg] Upping the sem to start the kthread, stacktop is %p\n",
1394                    get_stack_top());
1395         if (!sem_up(sem)) {
1396                 printk("[kmsg] Crap, the sem didn't have a kthread waiting!\n");
1397                 return;
1398         }
1399         printk("Kthread will restart when we handle the __launch RKM\n");
1400 }
1401
1402 /* simple test - start one, do something else, and resume it.  For lack of a
1403  * better infrastructure, we send ourselves a kmsg to run the kthread, which
1404  * we'll handle in smp_idle (which you may have to manually call).  Note this
1405  * doesn't test things like memory being leaked, or dealing with processes. */
1406 // TODO: Add assertions.
1407 bool test_kthreads(void)
1408 {
1409         struct semaphore sem;
1410         sem_init(&sem, 1);              /* set to 1 to test the unwind */
1411         printk("We're a kthread!  Stacktop is %p.  Testing suspend, etc...\n",
1412                get_stack_top());
1413         /* So we have something that will wake us up.  Routine messages won't get
1414          * serviced in the kernel right away. */
1415         send_kernel_message(core_id(), __test_up_sem, (long)&sem, 0, 0,
1416                             KMSG_ROUTINE);
1417         /* Actually block (or try to) */
1418         /* This one shouldn't block - but will test the unwind (if 1 above) */
1419         printk("About to sleep, but should unwind (signal beat us)\n");
1420         sem_down(&sem);
1421         /* This one is for real, yo.  Run and tell that. */
1422         printk("About to sleep for real\n");
1423         sem_down(&sem);
1424         printk("Kthread restarted!, Stacktop is %p.\n", get_stack_top());
1425
1426         return true;
1427 }
1428
1429 /* Second player's kmsg */
1430 static void __test_kref_2(uint32_t srcid, long a0, long a1, long a2)
1431 {
1432         struct kref *kref = (struct kref*)a0;
1433         bool *done = (bool*)a1;
1434         enable_irq();
1435         for (int i = 0; i < 10000000; i++) {
1436                 kref_get(kref, 1);
1437                 set_core_timer(1, TRUE);
1438                 udelay(2);
1439                 kref_put(kref);
1440         }
1441         *done = TRUE;
1442 }
1443
1444 /* Runs a simple test between core 0 (caller) and core 2 */
1445 // TODO: I believe we need more assertions.
1446 bool test_kref(void)
1447 {
1448         struct kref local_kref;
1449         bool done = FALSE;
1450         
1451         kref_init(&local_kref, fake_release, 1);
1452         send_kernel_message(2, __test_kref_2, (long)&local_kref, (long)&done, 0,
1453                             KMSG_ROUTINE);
1454         for (int i = 0; i < 10000000; i++) {
1455                 kref_get(&local_kref, 1);
1456                 udelay(2);
1457                 kref_put(&local_kref);
1458         }
1459         while (!done)
1460                 cpu_relax();
1461         KT_ASSERT(kref_refcnt(&local_kref) == 1);
1462         printk("[TEST-KREF] Simple 2-core getting/putting passed.\n");
1463
1464         return true;
1465 }
1466
1467 // TODO: Add more descriptive assertion messages.
1468 bool test_atomics(void)
1469 {
1470         /* subtract_and_test */
1471         atomic_t num;
1472         /* Test subing to 0 */
1473         atomic_init(&num, 1);
1474         KT_ASSERT(atomic_sub_and_test(&num, 1) == 1);
1475         atomic_init(&num, 2);
1476         KT_ASSERT(atomic_sub_and_test(&num, 2) == 1);
1477         /* Test not getting to 0 */
1478         atomic_init(&num, 1);
1479         KT_ASSERT(atomic_sub_and_test(&num, 0) == 0);
1480         atomic_init(&num, 2);
1481         KT_ASSERT(atomic_sub_and_test(&num, 1) == 0);
1482         /* Test negatives */
1483         atomic_init(&num, -1);
1484         KT_ASSERT(atomic_sub_and_test(&num, 1) == 0);
1485         atomic_init(&num, -1);
1486         KT_ASSERT(atomic_sub_and_test(&num, -1) == 1);
1487         /* Test larger nums */
1488         atomic_init(&num, 265);
1489         KT_ASSERT(atomic_sub_and_test(&num, 265) == 1);
1490         atomic_init(&num, 265);
1491         KT_ASSERT(atomic_sub_and_test(&num, 2) == 0);
1492
1493         /* CAS */
1494         /* Simple test, make sure the bool retval of CAS handles failure */
1495         bool test_cas_val(long init_val)
1496         {
1497                 atomic_t actual_num;
1498                 long old_num;
1499                 int attempt;
1500                 atomic_init(&actual_num, init_val);
1501                 attempt = 0;
1502                 do {
1503                         old_num = atomic_read(&actual_num);
1504                         /* First time, try to fail */
1505                         if (attempt == 0) 
1506                                 old_num++;
1507                         attempt++;      
1508                 } while (!atomic_cas(&actual_num, old_num, old_num + 10));
1509                 if (atomic_read(&actual_num) != init_val + 10) {
1510                         return false;
1511                 } else {
1512                         return true;
1513                 }
1514         }
1515         KT_ASSERT_M("CAS test for 257 should be successful.",
1516                     test_cas_val(257));
1517         KT_ASSERT_M("CAS test for 1 should be successful.",
1518                     test_cas_val(1));
1519         return true;
1520 }
1521
1522 /* Helper KMSG for test_abort.  Core 1 does this, while core 0 sends an IRQ. */
1523 static void __test_try_halt(uint32_t srcid, long a0, long a1, long a2)
1524 {
1525         disable_irq();
1526         /* wait 10 sec.  should have a bunch of ints pending */
1527         udelay(10000000);
1528         printk("Core 1 is about to halt\n");
1529         cpu_halt();
1530         printk("Returned from halting on core 1\n");
1531 }
1532
1533 /* x86 test, making sure our cpu_halt() and handle_irq() work.  If you want to
1534  * see it fail, you'll probably need to put a nop in the asm for cpu_halt(), and
1535  * comment out abort_halt() in handle_irq(). */
1536 // TODO: Add assertions.
1537 bool test_abort_halt(void)
1538 {
1539 #ifdef CONFIG_X86
1540         send_kernel_message(1, __test_try_halt, 0, 0, 0, KMSG_ROUTINE);
1541         /* wait 1 sec, enough time to for core 1 to be in its KMSG */
1542         udelay(1000000);
1543         /* Send an IPI */
1544         send_ipi(0x01, I_TESTING);
1545         printk("Core 0 sent the IPI\n");
1546 #endif /* CONFIG_X86 */
1547         return true;
1548 }
1549
1550 /* Funcs and global vars for test_cv() */
1551 static struct cond_var local_cv;
1552 static atomic_t counter;
1553 static struct cond_var *cv = &local_cv;
1554 static volatile bool state = FALSE;             /* for test 3 */
1555
1556 void __test_cv_signal(uint32_t srcid, long a0, long a1, long a2)
1557 {
1558         if (atomic_read(&counter) % 4)
1559                 cv_signal(cv);
1560         else
1561                 cv_broadcast(cv);
1562         atomic_dec(&counter);
1563 }
1564
1565 void __test_cv_waiter(uint32_t srcid, long a0, long a1, long a2)
1566 {
1567         cv_lock(cv);
1568         /* check state, etc */
1569         cv_wait_and_unlock(cv);
1570         atomic_dec(&counter);
1571 }
1572
1573 void __test_cv_waiter_t3(uint32_t srcid, long a0, long a1, long a2)
1574 {
1575         udelay(a0);
1576         /* if state == false, we haven't seen the signal yet */
1577         cv_lock(cv);
1578         while (!state) {
1579                 cpu_relax();
1580                 cv_wait(cv);    /* unlocks and relocks */
1581         }
1582         cv_unlock(cv);
1583         /* Make sure we are done, tell the controller we are done */
1584         cmb();
1585         assert(state);
1586         atomic_dec(&counter);
1587 }
1588
1589 // TODO: Add more assertions.
1590 bool test_cv(void)
1591 {
1592         int nr_msgs;
1593
1594         cv_init(cv);
1595         /* Test 0: signal without waiting */
1596         cv_broadcast(cv);
1597         cv_signal(cv);
1598         kthread_yield();
1599         printk("test_cv: signal without waiting complete\n");
1600
1601         /* Test 1: single / minimal shit */
1602         nr_msgs = num_cpus - 1; /* not using cpu 0 */
1603         atomic_init(&counter, nr_msgs);
1604         for (int i = 1; i < num_cpus; i++)
1605                 send_kernel_message(i, __test_cv_waiter, 0, 0, 0, KMSG_ROUTINE);
1606         udelay(1000000);
1607         cv_signal(cv);
1608         kthread_yield();
1609         while (atomic_read(&counter) != nr_msgs - 1)
1610                 cpu_relax();
1611         printk("test_cv: single signal complete\n");
1612         cv_broadcast(cv);
1613         /* broadcast probably woke up the waiters on our core.  since we want to
1614          * spin on their completion, we need to yield for a bit. */
1615         kthread_yield();
1616         while (atomic_read(&counter))
1617                 cpu_relax();
1618         printk("test_cv: broadcast signal complete\n");
1619
1620         /* Test 2: shitloads of waiters and signalers */
1621         nr_msgs = 0x500;        /* any more than 0x20000 could go OOM */
1622         atomic_init(&counter, nr_msgs);
1623         for (int i = 0; i < nr_msgs; i++) {
1624                 int cpu = (i % (num_cpus - 1)) + 1;
1625                 if (atomic_read(&counter) % 5)
1626                         send_kernel_message(cpu, __test_cv_waiter, 0, 0, 0, KMSG_ROUTINE);
1627                 else
1628                         send_kernel_message(cpu, __test_cv_signal, 0, 0, 0, KMSG_ROUTINE);
1629         }
1630         kthread_yield();        /* run whatever messages we sent to ourselves */
1631         while (atomic_read(&counter)) {
1632                 cpu_relax();
1633                 cv_broadcast(cv);
1634                 udelay(1000000);
1635                 kthread_yield();        /* run whatever messages we sent to ourselves */
1636         }
1637         KT_ASSERT(!cv->nr_waiters);
1638         printk("test_cv: massive message storm complete\n");
1639
1640         /* Test 3: basic one signaller, one receiver.  we want to vary the amount of
1641          * time the sender and receiver delays, starting with (1ms, 0ms) and ending
1642          * with (0ms, 1ms).  At each extreme, such as with the sender waiting 1ms,
1643          * the receiver/waiter should hit the "check and wait" point well before the
1644          * sender/signaller hits the "change state and signal" point. */
1645         for (int i = 0; i < 1000; i++) {
1646                 for (int j = 0; j < 10; j++) {  /* some extra chances at each point */
1647                         state = FALSE;
1648                         atomic_init(&counter, 1);       /* signal that the client is done */
1649                         /* client waits for i usec */
1650                         send_kernel_message(2, __test_cv_waiter_t3, i, 0, 0, KMSG_ROUTINE);
1651                         cmb();
1652                         udelay(1000 - i);       /* senders wait time: 1000..0 */
1653                         state = TRUE;
1654                         cv_signal(cv);
1655                         /* signal might have unblocked a kthread, let it run */
1656                         kthread_yield();
1657                         /* they might not have run at all yet (in which case they lost the
1658                          * race and don't need the signal).  but we need to wait til they're
1659                          * done */
1660                         while (atomic_read(&counter))
1661                                 cpu_relax();
1662                         KT_ASSERT(!cv->nr_waiters);
1663                 }
1664         }
1665         printk("test_cv: single sender/receiver complete\n");
1666
1667         return true;
1668 }
1669
1670 /* Based on a bug I noticed.  TODO: actual memset test... */
1671 bool test_memset(void)
1672 {
1673         #define ARR_SZ 256
1674         
1675         void print_array(char *c, size_t len)
1676         {
1677                 for (int i = 0; i < len; i++)
1678                         printk("%04d: %02x\n", i, *c++);
1679         }
1680         
1681         bool check_array(char *c, char x, size_t len)
1682         {
1683                 for (int i = 0; i < len; i++) {
1684                         #define ASSRT_SIZE 64
1685                         char *assrt_msg = (char*) kmalloc(ASSRT_SIZE, 0);
1686                         snprintf(assrt_msg, ASSRT_SIZE, 
1687                                      "Char %d is %c (%02x), should be %c (%02x)", i, *c, *c,
1688                                      x, x);
1689                         KT_ASSERT_M(assrt_msg, (*c == x));
1690                         c++;
1691                 }
1692                 return true;
1693         }
1694         
1695         bool run_check(char *arr, int ch, size_t len)
1696         {
1697                 char *c = arr;
1698                 for (int i = 0; i < ARR_SZ; i++)
1699                         *c++ = 0x0;
1700                 memset(arr, ch, len - 4);
1701                 if (check_array(arr, ch, len - 4) &&
1702                     check_array(arr + len - 4, 0x0, 4)) {
1703                         return true;
1704                 } else {
1705                         return false;
1706                 }
1707         }
1708
1709         char bytes[ARR_SZ];
1710
1711         if (!run_check(bytes, 0xfe, 20) || !run_check(bytes, 0xc0fe, 20)) {
1712                 return false;
1713         }
1714
1715         return true;
1716 }
1717
1718 void __attribute__((noinline)) __longjmp_wrapper(struct jmpbuf* jb)
1719 {
1720         asm ("");
1721         printk("Starting: %s\n", __FUNCTION__);
1722         longjmp(jb, 1);
1723         // Should never get here
1724         printk("Exiting: %s\n", __FUNCTION__); 
1725 }
1726
1727 // TODO: Add assertions.
1728 bool test_setjmp()
1729 {
1730         struct jmpbuf jb;
1731         printk("Starting: %s\n", __FUNCTION__);
1732         if (setjmp(&jb)) {
1733           printk("After second setjmp return: %s\n", __FUNCTION__);
1734     }
1735     else {
1736           printk("After first setjmp return: %s\n", __FUNCTION__);
1737       __longjmp_wrapper(&jb);
1738     }
1739         printk("Exiting: %s\n", __FUNCTION__);
1740
1741         return true;
1742 }
1743
1744 // TODO: add assertions.
1745 bool test_apipe(void)
1746 {
1747         static struct atomic_pipe test_pipe;
1748
1749         struct some_struct {
1750                 long x;
1751                 int y;
1752         };
1753         /* Don't go too big, or you'll run off the stack */
1754         #define MAX_BATCH 100
1755
1756         void __test_apipe_writer(uint32_t srcid, long a0, long a1, long a2)
1757         {
1758                 int ret, count_todo;
1759                 int total = 0;
1760                 struct some_struct local_str[MAX_BATCH];
1761                 for (int i = 0; i < MAX_BATCH; i++) {
1762                         local_str[i].x = 0xf00;
1763                         local_str[i].y = 0xba5;
1764                 }
1765                 /* testing 0, and max out at 50. [0, ... 50] */
1766                 for (int i = 0; i < MAX_BATCH + 1; i++) {
1767                         count_todo = i;
1768                         while (count_todo) {
1769                                 ret = apipe_write(&test_pipe, &local_str, count_todo);
1770                                 /* Shouldn't break, based on the loop counters */
1771                                 if (!ret) {
1772                                         printk("Writer breaking with %d left\n", count_todo);
1773                                         break;
1774                                 }
1775                                 total += ret;
1776                                 count_todo -= ret;
1777                         }
1778                 }
1779                 printk("Writer done, added %d elems\n", total);
1780                 apipe_close_writer(&test_pipe);
1781         }
1782
1783         void __test_apipe_reader(uint32_t srcid, long a0, long a1, long a2)
1784         {
1785                 int ret, count_todo;
1786                 int total = 0;
1787                 struct some_struct local_str[MAX_BATCH] = {{0}};
1788                 /* reversed loop compared to the writer [50, ... 0] */
1789                 for (int i = MAX_BATCH; i >= 0; i--) {
1790                         count_todo = i;
1791                         while (count_todo) {
1792                                 ret = apipe_read(&test_pipe, &local_str, count_todo);
1793                                 if (!ret) {
1794                                         printk("Reader breaking with %d left\n", count_todo);
1795                                         break;
1796                                 }
1797                                 total += ret;
1798                                 count_todo -= ret;
1799                         }
1800                 }
1801                 printk("Reader done, took %d elems\n", total);
1802                 for (int i = 0; i < MAX_BATCH; i++) {
1803                         assert(local_str[i].x == 0xf00);
1804                         assert(local_str[i].y == 0xba5);
1805                 }
1806                 apipe_close_reader(&test_pipe);
1807         }
1808
1809         void *pipe_buf = kpage_alloc_addr();
1810         KT_ASSERT(pipe_buf);
1811         apipe_init(&test_pipe, pipe_buf, PGSIZE, sizeof(struct some_struct));
1812         printd("*ap_buf %p\n", test_pipe.ap_buf);
1813         printd("ap_ring_sz %p\n", test_pipe.ap_ring_sz);
1814         printd("ap_elem_sz %p\n", test_pipe.ap_elem_sz);
1815         printd("ap_rd_off %p\n", test_pipe.ap_rd_off);
1816         printd("ap_wr_off %p\n", test_pipe.ap_wr_off);
1817         printd("ap_nr_readers %p\n", test_pipe.ap_nr_readers);
1818         printd("ap_nr_writers %p\n", test_pipe.ap_nr_writers);
1819         send_kernel_message(0, __test_apipe_writer, 0, 0, 0, KMSG_ROUTINE);
1820         /* Once we start synchronizing with a kmsg / kthread that could be on a
1821          * different core, we run the chance of being migrated when we block. */
1822         __test_apipe_reader(0, 0, 0, 0);
1823         /* Wait til the first test is done */
1824         while (test_pipe.ap_nr_writers) {
1825                 kthread_yield();
1826                 cpu_relax();
1827         }
1828         /* Try cross core (though CV wake ups schedule on the waking core) */
1829         apipe_open_reader(&test_pipe);
1830         apipe_open_writer(&test_pipe);
1831         send_kernel_message(1, __test_apipe_writer, 0, 0, 0, KMSG_ROUTINE);
1832         __test_apipe_reader(0, 0, 0, 0);
1833         /* We could be on core 1 now.  If we were called from core0, our caller
1834          * might expect us to return while being on core 0 (like if we were kfunc'd
1835          * from the monitor.  Be careful if you copy this code. */
1836
1837         return true;
1838 }
1839
1840 static struct rwlock rwlock, *rwl = &rwlock;
1841 static atomic_t rwlock_counter;
1842 // TODO: Add assertions.
1843 bool test_rwlock(void)
1844 {
1845         bool ret;
1846         rwinit(rwl);
1847         /* Basic: can i lock twice, recursively? */
1848         rlock(rwl);
1849         ret = canrlock(rwl);
1850         KT_ASSERT(ret);
1851         runlock(rwl);
1852         runlock(rwl);
1853         /* Other simply tests */
1854         wlock(rwl);
1855         wunlock(rwl);
1856
1857         /* Just some half-assed different operations */
1858         void __test_rwlock(uint32_t srcid, long a0, long a1, long a2)
1859         {
1860                 int rand = read_tsc() & 0xff;
1861                 for (int i = 0; i < 10000; i++) {
1862                         switch ((rand * i) % 5) {
1863                                 case 0:
1864                                 case 1:
1865                                         rlock(rwl);
1866                                         runlock(rwl);
1867                                         break;
1868                                 case 2:
1869                                 case 3:
1870                                         if (canrlock(rwl))
1871                                                 runlock(rwl);
1872                                         break;
1873                                 case 4:
1874                                         wlock(rwl);
1875                                         wunlock(rwl);
1876                                         break;
1877                         }
1878                 }
1879                 /* signal to allow core 0 to finish */
1880                 atomic_dec(&rwlock_counter);
1881         }
1882                 
1883         /* send 4 messages to each non core 0 */
1884         atomic_init(&rwlock_counter, (num_cpus - 1) * 4);
1885         for (int i = 1; i < num_cpus; i++)
1886                 for (int j = 0; j < 4; j++)
1887                         send_kernel_message(i, __test_rwlock, 0, 0, 0, KMSG_ROUTINE);
1888         while (atomic_read(&rwlock_counter))
1889                 cpu_relax();
1890         printk("rwlock test complete\n");
1891
1892         return true;
1893 }
1894
1895 /* Funcs and global vars for test_rv() */
1896 static struct rendez local_rv;
1897 static struct rendez *rv = &local_rv;
1898 /* reusing state and counter from test_cv... */
1899
1900 static int __rendez_cond(void *arg)
1901 {
1902         return *(bool*)arg;
1903 }
1904
1905 void __test_rv_wakeup(uint32_t srcid, long a0, long a1, long a2)
1906 {
1907         if (atomic_read(&counter) % 4)
1908                 cv_signal(cv);
1909         else
1910                 cv_broadcast(cv);
1911         atomic_dec(&counter);
1912 }
1913
1914 void __test_rv_sleeper(uint32_t srcid, long a0, long a1, long a2)
1915 {
1916         rendez_sleep(rv, __rendez_cond, (void*)&state);
1917         atomic_dec(&counter);
1918 }
1919
1920 void __test_rv_sleeper_timeout(uint32_t srcid, long a0, long a1, long a2)
1921 {
1922         /* half-assed amount of time. */
1923         rendez_sleep_timeout(rv, __rendez_cond, (void*)&state, a0);
1924         atomic_dec(&counter);
1925 }
1926
1927 // TODO: Add more assertions.
1928 bool test_rv(void)
1929 {
1930         int nr_msgs;
1931
1932         rendez_init(rv);
1933         /* Test 0: signal without waiting */
1934         rendez_wakeup(rv);
1935         kthread_yield();
1936         printk("test_rv: wakeup without sleeping complete\n");
1937
1938         /* Test 1: a few sleepers */
1939         nr_msgs = num_cpus - 1; /* not using cpu 0 */
1940         atomic_init(&counter, nr_msgs);
1941         state = FALSE;
1942         for (int i = 1; i < num_cpus; i++)
1943                 send_kernel_message(i, __test_rv_sleeper, 0, 0, 0, KMSG_ROUTINE);
1944         udelay(1000000);
1945         cmb();
1946         state = TRUE;
1947         rendez_wakeup(rv);
1948         /* broadcast probably woke up the waiters on our core.  since we want to
1949          * spin on their completion, we need to yield for a bit. */
1950         kthread_yield();
1951         while (atomic_read(&counter))
1952                 cpu_relax();
1953         printk("test_rv: bulk wakeup complete\n");
1954
1955         /* Test 2: different types of sleepers / timeouts */
1956         state = FALSE;
1957         nr_msgs = 0x500;        /* any more than 0x20000 could go OOM */
1958         atomic_init(&counter, nr_msgs);
1959         for (int i = 0; i < nr_msgs; i++) {
1960                 int cpu = (i % (num_cpus - 1)) + 1;
1961                 /* timeouts from 0ms ..5000ms (enough that they should wake via cond */
1962                 if (atomic_read(&counter) % 5)
1963                         send_kernel_message(cpu, __test_rv_sleeper_timeout, i * 4, 0, 0,
1964                                             KMSG_ROUTINE);
1965                 else
1966                         send_kernel_message(cpu, __test_rv_sleeper, 0, 0, 0, KMSG_ROUTINE);
1967         }
1968         kthread_yield();        /* run whatever messages we sent to ourselves */
1969         state = TRUE;
1970         while (atomic_read(&counter)) {
1971                 cpu_relax();
1972                 rendez_wakeup(rv);
1973                 udelay(1000000);
1974                 kthread_yield();        /* run whatever messages we sent to ourselves */
1975         }
1976         KT_ASSERT(!rv->cv.nr_waiters);
1977         printk("test_rv: lots of sleepers/timeouts complete\n");
1978
1979         return true;
1980 }
1981
1982 /* Cheap test for the alarm internal management */
1983 // TODO: Add assertions.
1984 bool test_alarm(void)
1985 {
1986         uint64_t now = tsc2usec(read_tsc());
1987         struct alarm_waiter await1, await2;
1988         struct timer_chain *tchain = &per_cpu_info[0].tchain;
1989         void shouldnt_run(struct alarm_waiter *awaiter)
1990         {
1991                 printk("Crap, %p ran!\n", awaiter);
1992         }
1993         void empty_run(struct alarm_waiter *awaiter)
1994         {
1995                 printk("Yay, %p ran (hopefully twice)!\n", awaiter);
1996         }
1997         /* Test basic insert, move, remove */
1998         init_awaiter(&await1, shouldnt_run);
1999         set_awaiter_abs(&await1, now + 1000000000);
2000         set_alarm(tchain, &await1);
2001         reset_alarm_abs(tchain, &await1, now + 1000000000 - 50);
2002         reset_alarm_abs(tchain, &await1, now + 1000000000 + 50);
2003         unset_alarm(tchain, &await1);
2004         /* Test insert of one that fired already */
2005         init_awaiter(&await2, empty_run);
2006         set_awaiter_rel(&await2, 1);
2007         set_alarm(tchain, &await2);
2008         enable_irq();
2009         udelay(1000);
2010         reset_alarm_abs(tchain, &await2, now + 10);
2011         udelay(1000);
2012         unset_alarm(tchain, &await2);
2013
2014         printk("%s complete\n", __FUNCTION__);
2015
2016         return true;
2017 }
2018
2019 /* Linker function tests.  Keep them commented, etc. */
2020 #if 0
2021 linker_func_1(xme11)
2022 {
2023         printk("xme11\n");
2024 }
2025
2026 linker_func_1(xme12)
2027 {
2028         printk("xme12\n");
2029 }
2030
2031 linker_func_1(xme13)
2032 {
2033         printk("xme13\n");
2034 }
2035
2036 linker_func_1(xme14)
2037 {
2038         printk("xme14\n");
2039 }
2040
2041 linker_func_1(xme15)
2042 {
2043         printk("xme15\n");
2044 }
2045
2046 linker_func_2(xme21)
2047 {
2048         printk("xme21\n");
2049 }
2050
2051 linker_func_2(xme22)
2052 {
2053         printk("xme22\n");
2054 }
2055
2056 linker_func_2(xme23)
2057 {
2058         printk("xme23\n");
2059 }
2060
2061 linker_func_2(xme24)
2062 {
2063         printk("xme24\n");
2064 }
2065
2066 linker_func_2(xme25)
2067 {
2068         printk("xme25\n");
2069 }
2070
2071 linker_func_3(xme31)
2072 {
2073         printk("xme31\n");
2074 }
2075
2076 linker_func_3(xme32)
2077 {
2078         printk("xme32\n");
2079 }
2080
2081 linker_func_3(xme33)
2082 {
2083         printk("xme33\n");
2084 }
2085
2086 linker_func_3(xme34)
2087 {
2088         printk("xme34\n");
2089 }
2090
2091 linker_func_3(xme35)
2092 {
2093         printk("xme35\n");
2094 }
2095
2096 linker_func_4(xme41)
2097 {
2098         printk("xme41\n");
2099 }
2100
2101 linker_func_4(xme42)
2102 {
2103         printk("xme42\n");
2104 }
2105
2106 linker_func_4(xme43)
2107 {
2108         printk("xme43\n");
2109 }
2110
2111 linker_func_4(xme44)
2112 {
2113         printk("xme44\n");
2114 }
2115
2116 linker_func_4(xme45)
2117 {
2118         printk("xme45\n");
2119 }
2120 #endif /* linker func tests */