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