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