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