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