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