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