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