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