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