Kernel message parameters are now longs
[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
15 #include <atomic.h>
16 #include <stdio.h>
17 #include <assert.h>
18 #include <string.h>
19 #include <testing.h>
20 #include <trap.h>
21 #include <arch/trap.h>
22 #include <process.h>
23 #include <syscall.h>
24 #include <timing.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
37 #define l1 (available_caches.l1)
38 #define l2 (available_caches.l2)
39 #define l3 (available_caches.l3)
40
41 #ifdef __i386__
42
43 void test_ipi_sending(void)
44 {
45         extern handler_t (CT(NUM_INTERRUPT_HANDLERS) RO interrupt_handlers)[];
46         int8_t state = 0;
47
48         register_interrupt_handler(interrupt_handlers, I_TESTING,
49                                    test_hello_world_handler, NULL);
50         enable_irqsave(&state);
51         cprintf("\nCORE 0 sending broadcast\n");
52         send_broadcast_ipi(I_TESTING);
53         udelay(3000000);
54         cprintf("\nCORE 0 sending all others\n");
55         send_all_others_ipi(I_TESTING);
56         udelay(3000000);
57         cprintf("\nCORE 0 sending self\n");
58         send_self_ipi(I_TESTING);
59         udelay(3000000);
60         cprintf("\nCORE 0 sending ipi to physical 1\n");
61         send_ipi(get_hw_coreid(0x01), I_TESTING);
62         udelay(3000000);
63         cprintf("\nCORE 0 sending ipi to physical 2\n");
64         send_ipi(get_hw_coreid(0x02), I_TESTING);
65         udelay(3000000);
66         cprintf("\nCORE 0 sending ipi to physical 3\n");
67         send_ipi(get_hw_coreid(0x03), I_TESTING);
68         udelay(3000000);
69         cprintf("\nCORE 0 sending ipi to physical 15\n");
70         send_ipi(get_hw_coreid(0x0f), I_TESTING);
71         udelay(3000000);
72         cprintf("\nCORE 0 sending ipi to logical 2\n");
73         send_group_ipi(0x02, I_TESTING);
74         udelay(3000000);
75         cprintf("\nCORE 0 sending ipi to logical 1\n");
76         send_group_ipi(0x01, I_TESTING);
77         udelay(3000000);
78         cprintf("\nDone!\n");
79         disable_irqsave(&state);
80 }
81
82 // Note this never returns and will muck with any other timer work
83 void test_pic_reception(void)
84 {
85         register_interrupt_handler(interrupt_handlers, 0x20, test_hello_world_handler, NULL);
86         pit_set_timer(100,TIMER_RATEGEN); // totally arbitrary time
87         pic_unmask_irq(0);
88         cprintf("PIC1 Mask = 0x%04x\n", inb(PIC1_DATA));
89         cprintf("PIC2 Mask = 0x%04x\n", inb(PIC2_DATA));
90         unmask_lapic_lvt(LAPIC_LVT_LINT0);
91         cprintf("Core %d's LINT0: 0x%08x\n", core_id(), read_mmreg32(LAPIC_LVT_LINT0));
92         enable_irq();
93         while(1);
94 }
95
96 void test_ioapic_pit_reroute(void) 
97 {
98         register_interrupt_handler(interrupt_handlers, 0x20, test_hello_world_handler, NULL);
99         ioapic_route_irq(0, 3); 
100
101         cprintf("Starting pit on core 3....\n");
102         udelay(3000000);
103         pit_set_timer(0xFFFE,TIMER_RATEGEN); // totally arbitrary time
104         
105         udelay(3000000);
106         ioapic_unroute_irq(0);
107         udelay(300000);
108         cprintf("Masked pit. Waiting before return...\n");
109         udelay(3000000);
110 }
111
112 #endif // __i386__
113
114
115 void test_print_info(void)
116 {
117         cprintf("\nCORE 0 asking all cores to print info:\n");
118         smp_call_function_all(test_print_info_handler, NULL, 0);
119         cprintf("\nDone!\n");
120 }
121
122 void test_page_coloring(void) 
123 {
124 /*
125         //Print the different cache properties of our machine
126         print_cache_properties("L1", l1);
127         cprintf("\n");
128         print_cache_properties("L2", l2);
129         cprintf("\n");
130         print_cache_properties("L3", l3);
131         cprintf("\n");
132
133         //Print some stats about our memory
134         cprintf("Max Address: %llu\n", MAX_VADDR);
135         cprintf("Num Pages: %u\n", npages);
136
137         //Declare a local variable for allocating pages 
138         page_t* page;
139
140         cprintf("Contents of the page free list:\n");
141         for(int i=0; i<llc_cache->num_colors; i++) {
142                 cprintf("  COLOR %d:\n", i);
143                 LIST_FOREACH(page, &colored_page_free_list[i], pg_link) {
144                         cprintf("    Page: %d\n", page2ppn(page));
145                 }
146         }
147
148         //Run through and allocate all pages through l1_page_alloc
149         cprintf("Allocating from L1 page colors:\n");
150         for(int i=0; i<get_cache_num_page_colors(l1); i++) {
151                 cprintf("  COLOR %d:\n", i);
152                 while(colored_page_alloc(l1, &page, i) != -ENOMEM)
153                         cprintf("    Page: %d\n", page2ppn(page));
154         }
155
156         //Put all the pages back by reinitializing
157         page_init();
158         
159         //Run through and allocate all pages through l2_page_alloc
160         cprintf("Allocating from L2 page colors:\n");
161         for(int i=0; i<get_cache_num_page_colors(l2); i++) {
162                 cprintf("  COLOR %d:\n", i);
163                 while(colored_page_alloc(l2, &page, i) != -ENOMEM)
164                         cprintf("    Page: %d\n", page2ppn(page));
165         }
166
167         //Put all the pages back by reinitializing
168         page_init();
169         
170         //Run through and allocate all pages through l3_page_alloc
171         cprintf("Allocating from L3 page colors:\n");
172         for(int i=0; i<get_cache_num_page_colors(l3); i++) {
173                 cprintf("  COLOR %d:\n", i);
174                 while(colored_page_alloc(l3, &page, i) != -ENOMEM)
175                         cprintf("    Page: %d\n", page2ppn(page));
176         }
177         
178         //Put all the pages back by reinitializing
179         page_init();
180         
181         //Run through and allocate all pages through page_alloc
182         cprintf("Allocating from global allocator:\n");
183         while(upage_alloc(&page) != -ENOMEM)
184                 cprintf("    Page: %d\n", page2ppn(page));
185         
186         if(colored_page_alloc(l2, &page, 0) != -ENOMEM)
187                 cprintf("Should not get here, all pages should already be gone!\n");
188         cprintf("All pages gone for sure...\n");
189         
190         //Now lets put a few pages back using page_free..
191         cprintf("Reinserting pages via page_free and reallocating them...\n");
192         page_free(&pages[0]);
193         page_free(&pages[15]);
194         page_free(&pages[7]);
195         page_free(&pages[6]);
196         page_free(&pages[4]);
197
198         while(upage_alloc(&page) != -ENOMEM)
199                 cprintf("Page: %d\n", page2ppn(page));  
200         
201         page_init();
202 */
203 }
204
205 void test_color_alloc() {
206         size_t checkpoint = 0;
207         uint8_t* colors_map = kmalloc(BYTES_FOR_BITMASK(llc_cache->num_colors), 0);
208         cache_color_alloc(l2, colors_map);
209         cache_color_alloc(l3, colors_map);
210         cache_color_alloc(l3, colors_map);
211         cache_color_alloc(l2, colors_map);
212         cache_color_free(llc_cache, colors_map);
213         cache_color_free(llc_cache, colors_map);
214         cache_color_free(llc_cache, colors_map);
215         cache_color_free(llc_cache, colors_map);
216         cache_color_free(llc_cache, colors_map);
217         cache_color_free(llc_cache, colors_map);
218         cache_color_free(llc_cache, colors_map);
219         cache_color_free(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(l2, colors_map);
229         cache_color_free(llc_cache, colors_map);
230         cache_color_free(llc_cache, colors_map);
231
232 print_cache_colors:
233         printk("L1 free colors, tot colors: %d\n", l1->num_colors);
234         PRINT_BITMASK(l1->free_colors_map, l1->num_colors);
235         printk("L2 free colors, tot colors: %d\n", l2->num_colors);
236         PRINT_BITMASK(l2->free_colors_map, l2->num_colors);
237         printk("L3 free colors, tot colors: %d\n", l3->num_colors);
238         PRINT_BITMASK(l3->free_colors_map, l3->num_colors);
239         printk("Process allocated colors\n");
240         PRINT_BITMASK(colors_map, llc_cache->num_colors);
241         printk("test_color_alloc() complete!\n");
242 }
243
244 barrier_t test_cpu_array;
245
246 void test_barrier(void)
247 {
248         cprintf("Core 0 initializing barrier\n");
249         init_barrier(&test_cpu_array, num_cpus);
250         cprintf("Core 0 asking all cores to print ids, barrier, rinse, repeat\n");
251         smp_call_function_all(test_barrier_handler, NULL, 0);
252 }
253
254 void test_interrupts_irqsave(void)
255 {
256         int8_t state = 0;
257         printd("Testing Nesting Enabling first, turning ints off:\n");
258         disable_irq();
259         printd("Interrupts are: %x\n", irq_is_enabled());
260         assert(!irq_is_enabled());
261         printd("Enabling IRQSave\n");
262         enable_irqsave(&state);
263         printd("Interrupts are: %x\n", irq_is_enabled());
264         assert(irq_is_enabled());
265         printd("Enabling IRQSave Again\n");
266         enable_irqsave(&state);
267         printd("Interrupts are: %x\n", irq_is_enabled());
268         assert(irq_is_enabled());
269         printd("Disabling IRQSave Once\n");
270         disable_irqsave(&state);
271         printd("Interrupts are: %x\n", irq_is_enabled());
272         assert(irq_is_enabled());
273         printd("Disabling IRQSave Again\n");
274         disable_irqsave(&state);
275         printd("Interrupts are: %x\n", irq_is_enabled());
276         assert(!irq_is_enabled());
277         printd("Done.  Should have been 0, 200, 200, 200, 0\n");
278
279         printd("Testing Nesting Disabling first, turning ints on:\n");
280         state = 0;
281         enable_irq();
282         printd("Interrupts are: %x\n", irq_is_enabled());
283         assert(irq_is_enabled());
284         printd("Disabling IRQSave Once\n");
285         disable_irqsave(&state);
286         printd("Interrupts are: %x\n", irq_is_enabled());
287         assert(!irq_is_enabled());
288         printd("Disabling IRQSave Again\n");
289         disable_irqsave(&state);
290         printd("Interrupts are: %x\n", irq_is_enabled());
291         assert(!irq_is_enabled());
292         printd("Enabling IRQSave Once\n");
293         enable_irqsave(&state);
294         printd("Interrupts are: %x\n", irq_is_enabled());
295         assert(!irq_is_enabled());
296         printd("Enabling IRQSave Again\n");
297         enable_irqsave(&state);
298         printd("Interrupts are: %x\n", irq_is_enabled());
299         assert(irq_is_enabled());
300         printd("Done.  Should have been 200, 0, 0, 0, 200 \n");
301
302         state = 0;
303         disable_irq();
304         printd("Ints are off, enabling then disabling.\n");
305         enable_irqsave(&state);
306         printd("Interrupts are: %x\n", irq_is_enabled());
307         assert(irq_is_enabled());
308         disable_irqsave(&state);
309         printd("Interrupts are: %x\n", irq_is_enabled());
310         assert(!irq_is_enabled());
311         printd("Done.  Should have been 200, 0\n");
312
313         state = 0;
314         enable_irq();
315         printd("Ints are on, enabling then disabling.\n");
316         enable_irqsave(&state);
317         printd("Interrupts are: %x\n", irq_is_enabled());
318         assert(irq_is_enabled());
319         disable_irqsave(&state);
320         printd("Interrupts are: %x\n", irq_is_enabled());
321         assert(irq_is_enabled());
322         printd("Done.  Should have been 200, 200\n");
323
324         state = 0;
325         disable_irq();
326         printd("Ints are off, disabling then enabling.\n");
327         disable_irqsave(&state);
328         printd("Interrupts are: %x\n", irq_is_enabled());
329         assert(!irq_is_enabled());
330         enable_irqsave(&state);
331         printd("Interrupts are: %x\n", irq_is_enabled());
332         assert(!irq_is_enabled());
333         printd("Done.  Should have been 0, 0\n");
334
335         state = 0;
336         enable_irq();
337         printd("Ints are on, disabling then enabling.\n");
338         disable_irqsave(&state);
339         printd("Interrupts are: %x\n", irq_is_enabled());
340         assert(!irq_is_enabled());
341         enable_irqsave(&state);
342         printd("Interrupts are: %x\n", irq_is_enabled());
343         assert(irq_is_enabled());
344         printd("Done.  Should have been 0, 200\n");
345
346         disable_irq();
347         cprintf("Passed enable_irqsave tests\n");
348 }
349
350 void test_bitmasks(void)
351 {
352 #define masksize 67
353         DECL_BITMASK(mask, masksize);
354         printk("size of mask %d\n", sizeof(mask));
355         CLR_BITMASK(mask, masksize);
356         PRINT_BITMASK(mask, masksize);
357         printk("cleared\n");
358         SET_BITMASK_BIT(mask, 0);
359         SET_BITMASK_BIT(mask, 11);
360         SET_BITMASK_BIT(mask, 17);
361         SET_BITMASK_BIT(mask, masksize-1);
362         printk("bits set\n");
363         PRINT_BITMASK(mask, masksize);
364         DECL_BITMASK(mask2, masksize);
365         COPY_BITMASK(mask2, mask, masksize);
366         printk("copy of original mask, should be the same as the prev\n");
367         PRINT_BITMASK(mask2, masksize);
368         CLR_BITMASK_BIT(mask, 11);
369         printk("11 cleared\n");
370         PRINT_BITMASK(mask, masksize);
371         printk("bit 17 is %d (should be 1)\n", GET_BITMASK_BIT(mask, 17));
372         printk("bit 11 is %d (should be 0)\n", GET_BITMASK_BIT(mask, 11));
373         FILL_BITMASK(mask, masksize);
374         PRINT_BITMASK(mask, masksize);
375         printk("should be all 1's, except for a few at the end\n");
376         printk("Is Clear?: %d (should be 0)\n", BITMASK_IS_CLEAR(mask,masksize));
377         CLR_BITMASK(mask, masksize);
378         PRINT_BITMASK(mask, masksize);
379         printk("Is Clear?: %d (should be 1)\n", BITMASK_IS_CLEAR(mask,masksize));
380         printk("should be cleared\n");
381 }
382
383 checklist_t *RO the_global_list;
384
385 void test_checklist_handler(trapframe_t *tf, void* data)
386 {
387         udelay(1000000);
388         cprintf("down_checklist(%x,%d)\n", the_global_list, core_id());
389         down_checklist(the_global_list);
390 }
391
392 void test_checklists(void)
393 {
394         INIT_CHECKLIST(a_list, MAX_NUM_CPUS);
395         the_global_list = &a_list;
396         printk("Checklist Build, mask size: %d\n", sizeof(a_list.mask.bits));
397         printk("mask\n");
398         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
399         SET_BITMASK_BIT(a_list.mask.bits, 11);
400         printk("Set bit 11\n");
401         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
402
403         CLR_BITMASK(a_list.mask.bits, a_list.mask.size);
404         INIT_CHECKLIST_MASK(a_mask, MAX_NUM_CPUS);
405         FILL_BITMASK(a_mask.bits, num_cpus);
406         //CLR_BITMASK_BIT(a_mask.bits, core_id());
407         //SET_BITMASK_BIT(a_mask.bits, 1);
408         //printk("New mask (1, 17, 25):\n");
409         printk("Created new mask, filled up to num_cpus\n");
410         PRINT_BITMASK(a_mask.bits, a_mask.size);
411         printk("committing new mask\n");
412         commit_checklist_wait(&a_list, &a_mask);
413         printk("Old mask (copied onto):\n");
414         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
415         //smp_call_function_single(1, test_checklist_handler, 0, 0);
416
417         smp_call_function_all(test_checklist_handler, NULL, 0);
418
419         printk("Waiting on checklist\n");
420         waiton_checklist(&a_list);
421         printk("Done Waiting!\n");
422
423 }
424
425 atomic_t a, b, c;
426
427 #ifdef __IVY__
428 void test_incrementer_handler(trapframe_t *tf, atomic_t *data)
429 #else
430 void test_incrementer_handler(trapframe_t *tf, void *data)
431 #endif
432 {
433         assert(data);
434         atomic_inc(data);
435 }
436
437 void test_null_handler(trapframe_t *tf, void* data)
438 {
439         asm volatile("nop");
440 }
441
442 void test_smp_call_functions(void)
443 {
444         int i;
445         atomic_init(&a, 0);
446         atomic_init(&b, 0);
447         atomic_init(&c, 0);
448         handler_wrapper_t *waiter0 = 0, *waiter1 = 0, *waiter2 = 0, *waiter3 = 0,
449                           *waiter4 = 0, *waiter5 = 0;
450         uint8_t me = core_id();
451         printk("\nCore %d: SMP Call Self (nowait):\n", me);
452         printk("---------------------\n");
453         smp_call_function_self(test_hello_world_handler, NULL, 0);
454         printk("\nCore %d: SMP Call Self (wait):\n", me);
455         printk("---------------------\n");
456         smp_call_function_self(test_hello_world_handler, NULL, &waiter0);
457         smp_call_wait(waiter0);
458         printk("\nCore %d: SMP Call All (nowait):\n", me);
459         printk("---------------------\n");
460         smp_call_function_all(test_hello_world_handler, NULL, 0);
461         printk("\nCore %d: SMP Call All (wait):\n", me);
462         printk("---------------------\n");
463         smp_call_function_all(test_hello_world_handler, NULL, &waiter0);
464         smp_call_wait(waiter0);
465         printk("\nCore %d: SMP Call All-Else Individually, in order (nowait):\n", me);
466         printk("---------------------\n");
467         for(i = 1; i < num_cpus; i++)
468                 smp_call_function_single(i, test_hello_world_handler, NULL, 0);
469         printk("\nCore %d: SMP Call Self (wait):\n", me);
470         printk("---------------------\n");
471         smp_call_function_self(test_hello_world_handler, NULL, &waiter0);
472         smp_call_wait(waiter0);
473         printk("\nCore %d: SMP Call All-Else Individually, in order (wait):\n", me);
474         printk("---------------------\n");
475         for(i = 1; i < num_cpus; i++)
476         {
477                 smp_call_function_single(i, test_hello_world_handler, NULL, &waiter0);
478                 smp_call_wait(waiter0);
479         }
480         printk("\nTesting to see if any IPI-functions are dropped when not waiting:\n");
481         printk("A: %d, B: %d, C: %d (should be 0,0,0)\n", atomic_read(&a), atomic_read(&b), atomic_read(&c));
482         smp_call_function_all(test_incrementer_handler, &a, 0);
483         smp_call_function_all(test_incrementer_handler, &b, 0);
484         smp_call_function_all(test_incrementer_handler, &c, 0);
485         // if i can clobber a previous IPI, the interleaving might do it
486         smp_call_function_single(1 % num_cpus, test_incrementer_handler, &a, 0);
487         smp_call_function_single(2 % num_cpus, test_incrementer_handler, &b, 0);
488         smp_call_function_single(3 % num_cpus, test_incrementer_handler, &c, 0);
489         smp_call_function_single(4 % num_cpus, test_incrementer_handler, &a, 0);
490         smp_call_function_single(5 % num_cpus, test_incrementer_handler, &b, 0);
491         smp_call_function_single(6 % num_cpus, test_incrementer_handler, &c, 0);
492         smp_call_function_all(test_incrementer_handler, &a, 0);
493         smp_call_function_single(3 % num_cpus, test_incrementer_handler, &c, 0);
494         smp_call_function_all(test_incrementer_handler, &b, 0);
495         smp_call_function_single(1 % num_cpus, test_incrementer_handler, &a, 0);
496         smp_call_function_all(test_incrementer_handler, &c, 0);
497         smp_call_function_single(2 % num_cpus, test_incrementer_handler, &b, 0);
498         // wait, so we're sure the others finish before printing.
499         // without this, we could (and did) get 19,18,19, since the B_inc
500         // handler didn't finish yet
501         smp_call_function_self(test_null_handler, NULL, &waiter0);
502         // need to grab all 5 handlers (max), since the code moves to the next free.
503         smp_call_function_self(test_null_handler, NULL, &waiter1);
504         smp_call_function_self(test_null_handler, NULL, &waiter2);
505         smp_call_function_self(test_null_handler, NULL, &waiter3);
506         smp_call_function_self(test_null_handler, NULL, &waiter4);
507         smp_call_wait(waiter0);
508         smp_call_wait(waiter1);
509         smp_call_wait(waiter2);
510         smp_call_wait(waiter3);
511         smp_call_wait(waiter4);
512         printk("A: %d, B: %d, C: %d (should be 19,19,19)\n", atomic_read(&a), atomic_read(&b), atomic_read(&c));
513         printk("Attempting to deadlock by smp_calling with an outstanding wait:\n");
514         smp_call_function_self(test_null_handler, NULL, &waiter0);
515         printk("Sent one\n");
516         smp_call_function_self(test_null_handler, NULL, &waiter1);
517         printk("Sent two\n");
518         smp_call_wait(waiter0);
519         printk("Wait one\n");
520         smp_call_wait(waiter1);
521         printk("Wait two\n");
522         printk("\tMade it through!\n");
523         printk("Attempting to deadlock by smp_calling more than are available:\n");
524         printk("\tShould see an Insufficient message and a kernel warning.\n");
525         if (smp_call_function_self(test_null_handler, NULL, &waiter0))
526                 printk("\tInsufficient handlers to call function (0)\n");
527         if (smp_call_function_self(test_null_handler, NULL, &waiter1))
528                 printk("\tInsufficient handlers to call function (1)\n");
529         if (smp_call_function_self(test_null_handler, NULL, &waiter2))
530                 printk("\tInsufficient handlers to call function (2)\n");
531         if (smp_call_function_self(test_null_handler, NULL, &waiter3))
532                 printk("\tInsufficient handlers to call function (3)\n");
533         if (smp_call_function_self(test_null_handler, NULL, &waiter4))
534                 printk("\tInsufficient handlers to call function (4)\n");
535         if (smp_call_function_self(test_null_handler, NULL, &waiter5))
536                 printk("\tInsufficient handlers to call function (5)\n");
537         smp_call_wait(waiter0);
538         smp_call_wait(waiter1);
539         smp_call_wait(waiter2);
540         smp_call_wait(waiter3);
541         smp_call_wait(waiter4);
542         smp_call_wait(waiter5);
543         printk("\tMade it through!\n");
544
545         printk("Done\n");
546 }
547
548 #ifdef __i386__
549 void test_lapic_status_bit(void)
550 {
551         register_interrupt_handler(interrupt_handlers, I_TESTING,
552                                    test_incrementer_handler, &a);
553         #define NUM_IPI 100000
554         atomic_set(&a,0);
555         printk("IPIs received (should be 0): %d\n", a);
556         for(int i = 0; i < NUM_IPI; i++) {
557                 send_ipi(get_hw_coreid(7), I_TESTING);
558                 lapic_wait_to_send();
559         }
560         // need to wait a bit to let those IPIs get there
561         udelay(5000000);
562         printk("IPIs received (should be %d): %d\n", a, NUM_IPI);
563         // hopefully that handler never fires again.  leaving it registered for now.
564 }
565 #endif // __i386__
566
567 /************************************************************/
568 /* ISR Handler Functions */
569
570 void test_hello_world_handler(trapframe_t *tf, void* data)
571 {
572         int trapno;
573         #if defined(__i386__)
574         trapno = tf->tf_trapno;
575         #elif defined(__sparc_v8__)
576         trapno = (tf->tbr >> 4) & 0xFF;
577         #else
578         trapno = 0;
579         #endif
580
581         cprintf("Incoming IRQ, ISR: %d on core %d with tf at 0x%08x\n",
582                 trapno, core_id(), tf);
583 }
584
585 spinlock_t print_info_lock = SPINLOCK_INITIALIZER;
586
587 void test_print_info_handler(trapframe_t *tf, void* data)
588 {
589         uint64_t tsc = read_tsc();
590
591         spin_lock_irqsave(&print_info_lock);
592         cprintf("----------------------------\n");
593         cprintf("This is Core %d\n", core_id());
594         cprintf("Timestamp = %lld\n", tsc);
595 #ifdef __i386__
596         cprintf("Hardware core %d\n", hw_core_id());
597         cprintf("MTRR_DEF_TYPE = 0x%08x\n", read_msr(IA32_MTRR_DEF_TYPE));
598         cprintf("MTRR Phys0 Base = 0x%016llx, Mask = 0x%016llx\n",
599                 read_msr(0x200), read_msr(0x201));
600         cprintf("MTRR Phys1 Base = 0x%016llx, Mask = 0x%016llx\n",
601                 read_msr(0x202), read_msr(0x203));
602         cprintf("MTRR Phys2 Base = 0x%016llx, Mask = 0x%016llx\n",
603                 read_msr(0x204), read_msr(0x205));
604         cprintf("MTRR Phys3 Base = 0x%016llx, Mask = 0x%016llx\n",
605                 read_msr(0x206), read_msr(0x207));
606         cprintf("MTRR Phys4 Base = 0x%016llx, Mask = 0x%016llx\n",
607                 read_msr(0x208), read_msr(0x209));
608         cprintf("MTRR Phys5 Base = 0x%016llx, Mask = 0x%016llx\n",
609                 read_msr(0x20a), read_msr(0x20b));
610         cprintf("MTRR Phys6 Base = 0x%016llx, Mask = 0x%016llx\n",
611                 read_msr(0x20c), read_msr(0x20d));
612         cprintf("MTRR Phys7 Base = 0x%016llx, Mask = 0x%016llx\n",
613                 read_msr(0x20e), read_msr(0x20f));
614 #endif // __i386__
615         cprintf("----------------------------\n");
616         spin_unlock_irqsave(&print_info_lock);
617 }
618
619 void test_barrier_handler(trapframe_t *tf, void* data)
620 {
621         cprintf("Round 1: Core %d\n", core_id());
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         waiton_barrier(&test_cpu_array);
628         cprintf("Round 2: Core %d\n", core_id());
629         waiton_barrier(&test_cpu_array);
630         cprintf("Round 3: Core %d\n", core_id());
631         // uncomment to see it fucked up
632         //cprintf("Round 4: Core %d\n", core_id());
633 }
634
635 #ifdef __IVY__
636 static void test_waiting_handler(trapframe_t *tf, atomic_t *data)
637 #else
638 static void test_waiting_handler(trapframe_t *tf, void *data)
639 #endif
640 {
641         atomic_dec(data);
642 }
643
644 #ifdef __i386__
645 void test_pit(void)
646 {
647         cprintf("Starting test for PIT now (10s)\n");
648         udelay_pit(10000000);
649         cprintf("End now\n");
650         cprintf("Starting test for TSC (if stable) now (10s)\n");
651         udelay(10000000);
652         cprintf("End now\n");
653
654         cprintf("Starting test for LAPIC (if stable) now (10s)\n");
655         enable_irq();
656         lapic_set_timer(10000000, FALSE);
657
658         atomic_t waiting;
659         atomic_init(&waiting, 1);
660         register_interrupt_handler(interrupt_handlers, I_TESTING,
661                                    test_waiting_handler, &waiting);
662         while(atomic_read(&waiting))
663                 cpu_relax();
664         cprintf("End now\n");
665 }
666
667 void test_circ_buffer(void)
668 {
669         int arr[5] = {0, 1, 2, 3, 4};
670
671         for (int i = 0; i < 5; i++) {
672                 FOR_CIRC_BUFFER(i, 5, j)
673                         printk("Starting with current = %d, each value = %d\n", i, j);
674         }
675         return;
676 }
677
678 void test_km_handler(struct trapframe *tf, uint32_t srcid, long a0, long a1,
679                      long a2)
680 {
681         printk("Received KM on core %d from core %d: arg0= 0x%08x, arg1 = "
682                "0x%08x, arg2 = 0x%08x\n", core_id(), srcid, a0, a1, a2);
683         return;
684 }
685
686 void test_kernel_messages(void)
687 {
688         printk("Testing Kernel Messages\n");
689         /* Testing sending multiples, sending different types, alternating, and
690          * precendence (the immediates should trump the others) */
691         printk("sending 5 IMMED to core 1, sending (#,deadbeef,0)\n");
692         for (int i = 0; i < 5; i++)
693                 send_kernel_message(1, test_km_handler, (long)i, 0xdeadbeef, 0,
694                                     KMSG_IMMEDIATE);
695         udelay(5000000);
696         printk("sending 5 routine to core 1, sending (#,cafebabe,0)\n");
697         for (int i = 0; i < 5; i++)
698                 send_kernel_message(1, test_km_handler, (long)i, 0xcafebabe, 0,
699                                     KMSG_ROUTINE);
700         udelay(5000000);
701         printk("sending 10 routine and 3 immediate to core 2\n");
702         for (int i = 0; i < 10; i++)
703                 send_kernel_message(2, test_km_handler, (long)i, 0xcafebabe, 0,
704                                     KMSG_ROUTINE);
705         for (int i = 0; i < 3; i++)
706                 send_kernel_message(2, test_km_handler, (long)i, 0xdeadbeef, 0,
707                                     KMSG_IMMEDIATE);
708         udelay(5000000);
709         printk("sending 5 ea alternating to core 2\n");
710         for (int i = 0; i < 5; i++) {
711                 send_kernel_message(2, test_km_handler, (long)i, 0xdeadbeef, 0,
712                                     KMSG_IMMEDIATE);
713                 send_kernel_message(2, test_km_handler, (long)i, 0xcafebabe, 0,
714                                     KMSG_ROUTINE);
715         }
716         udelay(5000000);
717         return;
718 }
719 #endif // __i386__
720
721 static void test_single_cache(int iters, size_t size, int align, int flags,
722                               void (*ctor)(void *, size_t),
723                               void (*dtor)(void *, size_t))
724 {
725         struct kmem_cache *test_cache;
726         void *objects[iters];
727         test_cache = kmem_cache_create("test_cache", size, align, flags, ctor, dtor);
728         printk("Testing Kmem Cache:\n");
729         print_kmem_cache(test_cache);
730         for (int i = 0; i < iters; i++) {
731                 objects[i] = kmem_cache_alloc(test_cache, 0);
732                 printk("Buffer %d addr = %p\n", i, objects[i]);
733         }
734         for (int i = 0; i < iters; i++) {
735                 kmem_cache_free(test_cache, objects[i]);
736         }
737         kmem_cache_destroy(test_cache);
738         printk("\n\n\n\n");
739 }
740
741 void a_ctor(void *buf, size_t size)
742 {
743         printk("constructin tests\n");
744 }
745 void a_dtor(void *buf, size_t size)
746 {
747         printk("destructin tests\n");
748 }
749
750 void test_slab(void)
751 {
752         test_single_cache(10, 128, 512, 0, 0, 0);
753         test_single_cache(10, 128, 4, 0, a_ctor, a_dtor);
754         test_single_cache(10, 1024, 16, 0, 0, 0);
755 }
756
757 void test_kmalloc(void)
758 {
759         printk("Testing Kmalloc\n");
760         void *bufs[NUM_KMALLOC_CACHES + 1];     
761         size_t size;
762         for (int i = 0; i < NUM_KMALLOC_CACHES + 1; i++){
763                 size = (KMALLOC_SMALLEST << i) - KMALLOC_OFFSET;
764                 bufs[i] = kmalloc(size, 0);
765                 printk("Size %d, Addr = %p\n", size, bufs[i]);
766         }
767         for (int i = 0; i < NUM_KMALLOC_CACHES; i++) {
768                 printk("Freeing buffer %d\n", i);
769                 kfree(bufs[i]);
770         }
771         printk("Testing a large kmalloc\n");
772         size = (KMALLOC_LARGEST << 2);
773         bufs[0] = kmalloc(size, 0);
774         printk("Size %d, Addr = %p\n", size, bufs[0]);
775         kfree(bufs[0]);
776 }
777
778 static size_t test_hash_fn_col(void *k)
779 {
780         return (size_t)k % 2; // collisions in slots 0 and 1
781 }
782
783 void test_hashtable(void)
784 {
785         struct test {int x; int y;};
786         struct test tstruct[10];
787
788         struct hashtable *h;
789         uintptr_t k = 5;
790         struct test *v = &tstruct[0];
791
792         h = create_hashtable(32, __generic_hash, __generic_eq);
793         
794         // test inserting one item, then finding it again
795         printk("Tesing one item, insert, search, and removal\n");
796         if(!hashtable_insert(h, (void*)k, v))
797                 printk("Failed to insert to hashtable!\n");
798         v = NULL;
799         if (!(v = hashtable_search(h, (void*)k)))
800                 printk("Failed to find in hashtable!\n");
801         if (v != &tstruct[0])
802                 printk("Got the wrong item! (got %p, wanted %p)\n", v, &tstruct[0]);
803         v = NULL;
804         if (!(v = hashtable_remove(h, (void*)k)))
805                 printk("Failed to remove from hashtable!\n");
806         // shouldn't be able to find it again
807         if ((v = hashtable_search(h, (void*)k)))
808                 printk("Should not have been able to find in hashtable!\n");
809         
810         printk("Tesing a bunch of items, insert, search, and removal\n");
811         for (int i = 0; i < 10; i++) {
812                 k = i; // vary the key, we don't do KEY collisions
813                 if(!hashtable_insert(h, (void*)k, &tstruct[i]))
814                         printk("Failed to insert iter %d to hashtable!\n", i);
815         }
816         // read out the 10 items
817         for (int i = 0; i < 10; i++) {
818                 k = i;
819                 if (!(v = hashtable_search(h, (void*)k)))
820                         printk("Failed to find in hashtable!\n");
821                 if (v != &tstruct[i])
822                         printk("Got the wrong item! (got %p, wanted %p)\n", v, &tstruct[i]);
823         }
824         if (hashtable_count(h) != 10)
825                 printk("Wrong accounting of number of elements!\n");
826         // remove the 10 items
827         for (int i = 0; i < 10; i++) {
828                 k = i;
829                 if (!(v = hashtable_remove(h, (void*)k)))
830                         printk("Failed to remove from hashtable!\n");
831         }
832         // make sure they are all gone
833         for (int i = 0; i < 10; i++) {
834                 k = i;
835                 if ((v = hashtable_search(h, (void*)k)))
836                         printk("Should not have been able to find in hashtable!\n");
837         }
838         if (hashtable_count(h))
839                 printk("Wrong accounting of number of elements!\n");
840         hashtable_destroy(h);
841
842         // same test of a bunch of items, but with collisions.
843         printk("Tesing a bunch of items with collisions, etc.\n");
844         h = create_hashtable(32, test_hash_fn_col, __generic_eq);
845         // insert 10 items
846         for (int i = 0; i < 10; i++) {
847                 k = i; // vary the key, we don't do KEY collisions
848                 if(!hashtable_insert(h, (void*)k, &tstruct[i]))
849                         printk("Failed to insert iter %d to hashtable!\n", i);
850         }
851         // read out the 10 items
852         for (int i = 0; i < 10; i++) {
853                 k = i;
854                 if (!(v = hashtable_search(h, (void*)k)))
855                         printk("Failed to find in hashtable!\n");
856                 if (v != &tstruct[i])
857                         printk("Got the wrong item! (got %p, wanted %p)\n", v, &tstruct[i]);
858         }
859         if (hashtable_count(h) != 10)
860                 printk("Wrong accounting of number of elements!\n");
861         // remove the 10 items
862         for (int i = 0; i < 10; i++) {
863                 k = i;
864                 if (!(v = hashtable_remove(h, (void*)k)))
865                         printk("Failed to remove from hashtable!\n");
866         }
867         // make sure they are all gone
868         for (int i = 0; i < 10; i++) {
869                 k = i;
870                 if ((v = hashtable_search(h, (void*)k)))
871                         printk("Should not have been able to find in hashtable!\n");
872         }
873         if (hashtable_count(h))
874                 printk("Wrong accounting of number of elements!\n");
875         hashtable_destroy(h);
876 }
877
878 /* Ghetto test, only tests one prod or consumer at a time */
879 void test_bcq(void)
880 {
881         /* Tests a basic struct */
882         struct my_struct {
883                 int x;
884                 int y;
885         };
886         struct my_struct in_struct, out_struct;
887         
888         DEFINE_BCQ_TYPES(test, struct my_struct, 16);
889         struct test_bcq t_bcq;
890         bcq_init(&t_bcq, struct my_struct, 16);
891         
892         in_struct.x = 4;
893         in_struct.y = 5;
894         out_struct.x = 1;
895         out_struct.y = 2;
896         
897         bcq_enqueue(&t_bcq, &in_struct, 16, 5);
898         bcq_dequeue(&t_bcq, &out_struct, 16);
899         printk("out x %d. out y %d\n", out_struct.x, out_struct.y);
900         
901         /* Tests the BCQ a bit more, esp with overflow */
902         #define NR_ELEM_A_BCQ 8 /* NOTE: this must be a power of 2! */
903         DEFINE_BCQ_TYPES(my, int, NR_ELEM_A_BCQ);
904         struct my_bcq a_bcq;
905         bcq_init(&a_bcq, int, NR_ELEM_A_BCQ);
906         
907         int y = 2;
908         int output[100];
909         int retval[100];
910
911         /* Helpful debugger */
912         void print_a_bcq(struct my_bcq *bcq)
913         {
914                 printk("A BCQ (made of ints): %08p\n", bcq);
915                 printk("\tprod_idx: %08p\n", bcq->hdr.prod_idx);
916                 printk("\tcons_pub_idx: %08p\n", bcq->hdr.cons_pub_idx);
917                 printk("\tcons_pvt_idx: %08p\n", bcq->hdr.cons_pvt_idx);
918                 for (int i = 0; i < NR_ELEM_A_BCQ; i++) {
919                         printk("Element %d, rdy_for_cons: %02p\n", i,
920                                bcq->wraps[i].rdy_for_cons);
921                 }
922         }
923
924         /* Put in more than it can take */
925         for (int i = 0; i < 15; i++) {
926                 y = i;
927                 retval[i] = bcq_enqueue(&a_bcq, &y, NR_ELEM_A_BCQ, 10);
928                 printk("enqueued: %d, had retval %d \n", y, retval[i]);
929         }
930         //print_a_bcq(&a_bcq);
931         
932         /* Try to dequeue more than we put in */
933         for (int i = 0; i < 15; i++) {
934                 retval[i] = bcq_dequeue(&a_bcq, &output[i], NR_ELEM_A_BCQ);
935                 printk("dequeued: %d with retval %d\n", output[i], retval[i]);
936         }
937         //print_a_bcq(&a_bcq);
938         
939         /* Put in some it should be able to take */
940         for (int i = 0; i < 3; i++) {
941                 y = i;
942                 retval[i] = bcq_enqueue(&a_bcq, &y, NR_ELEM_A_BCQ, 10);
943                 printk("enqueued: %d, had retval %d \n", y, retval[i]);
944         }
945         
946         /* Take those, and then a couple extra */
947         for (int i = 0; i < 5; i++) {
948                 retval[i] = bcq_dequeue(&a_bcq, &output[i], NR_ELEM_A_BCQ);
949                 printk("dequeued: %d with retval %d\n", output[i], retval[i]);
950         }
951         
952         /* Try some one-for-one */
953         for (int i = 0; i < 5; i++) {
954                 y = i;
955                 retval[i] = bcq_enqueue(&a_bcq, &y, NR_ELEM_A_BCQ, 10);
956                 printk("enqueued: %d, had retval %d \n", y, retval[i]);
957                 retval[i] = bcq_dequeue(&a_bcq, &output[i], NR_ELEM_A_BCQ);
958                 printk("dequeued: %d with retval %d\n", output[i], retval[i]);
959         }
960 }
961
962 /* rudimentary tests.  does the basics, create, merge, split, etc.  Feel free to
963  * add more, esp for the error conditions and finding free slots.  This is also
964  * a bit lazy with setting the caller's fields (perm, flags, etc). */
965 void test_vm_regions(void)
966 {
967         #define MAX_VMR_TESTS 10
968         struct proc pr, *p = &pr;       /* too lazy to even create one */
969         int n = 0;
970         TAILQ_INIT(&p->vm_regions);
971
972         struct vmr_summary {
973                 uintptr_t base; 
974                 uintptr_t end; 
975         };
976         int check_vmrs(struct proc *p, struct vmr_summary *results, int len, int n)
977         {
978                 int count = 0;
979                 struct vm_region *vmr;
980                 TAILQ_FOREACH(vmr, &p->vm_regions, vm_link) {
981                         if (count >= len) {
982                                 printk("More vm_regions than expected\n");
983                                 break;
984                         }
985                         if ((vmr->vm_base != results[count].base) ||
986                             (vmr->vm_end != results[count].end)) {
987                                 printk("VM test case %d failed!\n", n);
988                                 print_vmrs(p);
989                                 return -1;
990                         }
991                         count++;
992                 }
993                 return count;
994         }
995         struct vm_region *vmrs[MAX_VMR_TESTS];
996         struct vmr_summary results[MAX_VMR_TESTS];
997
998         memset(results, 0, sizeof(results));
999         /* Make one */
1000         vmrs[0] = create_vmr(p, 0x2000, 0x1000);
1001         results[0].base = 0x2000;
1002         results[0].end = 0x3000;
1003         check_vmrs(p, results, 1, n++);
1004         /* Grow it */
1005         grow_vmr(vmrs[0], 0x4000);
1006         results[0].base = 0x2000;
1007         results[0].end = 0x4000;
1008         check_vmrs(p, results, 1, n++);
1009         /* Grow it poorly */
1010         if (-1 != grow_vmr(vmrs[0], 0x3000))
1011                 printk("Bad grow test failed\n");
1012         check_vmrs(p, results, 1, n++);
1013         /* Make another right next to it */
1014         vmrs[1] = create_vmr(p, 0x4000, 0x1000);
1015         results[1].base = 0x4000;
1016         results[1].end = 0x5000;
1017         check_vmrs(p, results, 2, n++);
1018         /* try to grow through it */
1019         if (-1 != grow_vmr(vmrs[0], 0x5000))
1020                 printk("Bad grow test failed\n");
1021         check_vmrs(p, results, 2, n++);
1022         /* Merge them */
1023         merge_vmr(vmrs[0], vmrs[1]);
1024         results[0].end = 0x5000;
1025         results[1].base = 0;
1026         results[1].end = 0;
1027         check_vmrs(p, results, 1, n++);
1028         vmrs[1]= create_vmr(p, 0x6000, 0x4000);
1029         results[1].base = 0x6000;
1030         results[1].end = 0xa000;
1031         check_vmrs(p, results, 2, n++);
1032         /* try to merge unmergables (just testing ranges) */
1033         if (-1 != merge_vmr(vmrs[0], vmrs[1]))
1034                 printk("Bad merge test failed\n");
1035         check_vmrs(p, results, 2, n++);
1036         vmrs[2] = split_vmr(vmrs[1], 0x8000);
1037         results[1].end = 0x8000;
1038         results[2].base = 0x8000;
1039         results[2].end = 0xa000;
1040         check_vmrs(p, results, 3, n++);
1041         /* destroy one */
1042         destroy_vmr(vmrs[1]);
1043         results[1].base = 0x8000;
1044         results[1].end = 0xa000;
1045         check_vmrs(p, results, 2, n++);
1046         /* shrink */
1047         shrink_vmr(vmrs[2], 0x9000);
1048         results[1].base = 0x8000;
1049         results[1].end = 0x9000;
1050         check_vmrs(p, results, 2, n++); /* 10 */
1051         if (vmrs[2] != find_vmr(p, 0x8500))
1052                 printk("Failed to find the right vmr!\n");
1053         if (vmrs[2] != find_first_vmr(p, 0x8500))
1054                 printk("Failed to find the right vmr!\n");
1055         if (vmrs[2] != find_first_vmr(p, 0x7500))
1056                 printk("Failed to find the right vmr!\n");
1057         if (find_first_vmr(p, 0x9500))
1058                 printk("Found a vmr when we shouldn't!\n");
1059         /* grow up to another */
1060         grow_vmr(vmrs[0], 0x8000);
1061         results[0].end = 0x8000;
1062         check_vmrs(p, results, 2, n++);
1063         vmrs[0]->vm_prot = 88;
1064         vmrs[2]->vm_prot = 77;
1065         /* should be unmergeable due to perms */
1066         if (-1 != merge_vmr(vmrs[0], vmrs[2]))
1067                 printk("Bad merge test failed\n");
1068         check_vmrs(p, results, 2, n++);
1069         /* should merge now */
1070         vmrs[2]->vm_prot = 88;
1071         merge_vmr(vmrs[0], vmrs[2]);
1072         results[0].end = 0x9000;
1073         check_vmrs(p, results, 1, n++);
1074         destroy_vmr(vmrs[0]);
1075         check_vmrs(p, results, 0, n++);
1076         /* Check the automerge function */
1077         vmrs[0] = create_vmr(p, 0x2000, 0x1000);
1078         vmrs[1] = create_vmr(p, 0x3000, 0x1000);
1079         vmrs[2] = create_vmr(p, 0x4000, 0x1000);
1080         for (int i = 0; i < 3; i++) {
1081                 vmrs[i]->vm_prot = PROT_READ;
1082                 vmrs[i]->vm_flags = 0;
1083                 vmrs[i]->vm_file = 0; /* would like to test this, it's a pain for now */
1084         }
1085         vmrs[0] = merge_me(vmrs[1]);
1086         results[0].base = 0x2000;
1087         results[0].end = 0x5000;
1088         check_vmrs(p, results, 1, n++);
1089         destroy_vmr(vmrs[0]);
1090         check_vmrs(p, results, 0, n++);
1091         /* Check unfixed creation requests */
1092         vmrs[0] = create_vmr(p, 0x0000, 0x1000);
1093         vmrs[1] = create_vmr(p, 0x0000, 0x1000);
1094         vmrs[2] = create_vmr(p, 0x0000, 0x1000);
1095         results[0].base = 0x0000;
1096         results[0].end  = 0x1000;
1097         results[1].base = 0x1000;
1098         results[1].end  = 0x2000;
1099         results[2].base = 0x2000;
1100         results[2].end  = 0x3000;
1101         check_vmrs(p, results, 3, n++);
1102
1103         printk("Finished vm_regions test!\n");
1104 }
1105
1106 void test_radix_tree(void)
1107 {
1108         struct radix_tree real_tree = RADIX_INITIALIZER;
1109         struct radix_tree *tree = &real_tree;
1110         void *retval;
1111
1112         if (radix_insert(tree, 0, (void*)0xdeadbeef))
1113                 printk("Failed to insert at 0!\n");
1114         radix_delete(tree, 0);
1115         if (radix_insert(tree, 0, (void*)0xdeadbeef))
1116                 printk("Failed to re-insert at 0!\n");
1117
1118         if (radix_insert(tree, 3, (void*)0xdeadbeef))
1119                 printk("Failed to insert first!\n");
1120         radix_insert(tree, 4, (void*)0x04040404);
1121         assert((void*)0xdeadbeef == radix_lookup(tree, 3));
1122         for (int i = 5; i < 100; i++)
1123                 if ((retval = radix_lookup(tree, i))) {
1124                         printk("Extra item %08p at slot %d in tree %08p\n", retval, i,
1125                                tree);
1126                         print_radix_tree(tree);
1127                         monitor(0);
1128                 }
1129         if (radix_insert(tree, 65, (void*)0xcafebabe))
1130                 printk("Failed to insert a two-tier!\n");
1131         if (!radix_insert(tree, 4, (void*)0x03030303))
1132                 printk("Should not let us reinsert\n");
1133         if (radix_insert(tree, 4095, (void*)0x4095))
1134                 printk("Failed to insert a two-tier boundary!\n");
1135         if (radix_insert(tree, 4096, (void*)0x4096))
1136                 printk("Failed to insert a three-tier!\n");
1137         //print_radix_tree(tree);
1138         radix_delete(tree, 65);
1139         radix_delete(tree, 3);
1140         radix_delete(tree, 4);
1141         radix_delete(tree, 4095);
1142         radix_delete(tree, 4096);
1143         //print_radix_tree(tree);
1144         printk("Finished radix tree tests!\n");
1145 }
1146
1147 /* Assorted FS tests, which were hanging around in init.c */
1148 void test_random_fs(void)
1149 {
1150         int retval = do_symlink("/dir1/sym", "/bin/hello", S_IRWXU);
1151         if (retval)
1152                 printk("symlink1 creation failed\n");
1153         retval = do_symlink("/symdir", "/dir1/dir1-1", S_IRWXU);
1154         if (retval)
1155                 printk("symlink1 creation failed\n");
1156         retval = do_symlink("/dir1/test.txt", "/dir2/test2.txt", S_IRWXU);
1157         if (retval)
1158                 printk("symlink2 creation failed\n");
1159         retval = do_symlink("/dir1/dir1-1/up", "../../", S_IRWXU);
1160         if (retval)
1161                 printk("symlink3 creation failed\n");
1162         retval = do_symlink("/bin/hello-sym", "hello", S_IRWXU);
1163         if (retval)
1164                 printk("symlink4 creation failed\n");
1165         
1166         struct dentry *dentry;
1167         struct nameidata nd_r = {0}, *nd = &nd_r;
1168         retval = path_lookup("/dir1/sym", 0, nd);
1169         if (retval)
1170                 printk("symlink lookup failed: %d\n", retval);
1171         char *symname = nd->dentry->d_inode->i_op->readlink(nd->dentry);
1172         printk("Pathlookup got %s (sym)\n", nd->dentry->d_name.name);
1173         if (!symname)
1174                 printk("symlink reading failed\n");
1175         else
1176                 printk("Symname: %s (/bin/hello)\n", symname);
1177         path_release(nd);
1178         /* try with follow */
1179         memset(nd, 0, sizeof(struct nameidata));
1180         retval = path_lookup("/dir1/sym", LOOKUP_FOLLOW, nd);
1181         if (retval)
1182                 printk("symlink lookup failed: %d\n", retval);
1183         printk("Pathlookup got %s (hello)\n", nd->dentry->d_name.name);
1184         path_release(nd);
1185         
1186         /* try with a directory */
1187         memset(nd, 0, sizeof(struct nameidata));
1188         retval = path_lookup("/symdir/f1-1.txt", 0, nd);
1189         if (retval)
1190                 printk("symlink lookup failed: %d\n", retval);
1191         printk("Pathlookup got %s (f1-1.txt)\n", nd->dentry->d_name.name);
1192         path_release(nd);
1193         
1194         /* try with a rel path */
1195         printk("Try with a rel path\n");
1196         memset(nd, 0, sizeof(struct nameidata));
1197         retval = path_lookup("/symdir/up/hello.txt", 0, nd);
1198         if (retval)
1199                 printk("symlink lookup failed: %d\n", retval);
1200         printk("Pathlookup got %s (hello.txt)\n", nd->dentry->d_name.name);
1201         path_release(nd);
1202         
1203         printk("Try for an ELOOP\n");
1204         memset(nd, 0, sizeof(struct nameidata));
1205         retval = path_lookup("/symdir/up/symdir/up/symdir/up/symdir/up/hello.txt", 0, nd);
1206         if (retval)
1207                 printk("Symlink lookup failed (it should): %d (-40)\n", retval);
1208         path_release(nd);
1209 }
1210
1211 /* simple test - start one, do something else, and resume it.  For lack of a
1212  * better infrastructure, we send ourselves a kmsg to run the kthread, which
1213  * we'll handle in smp_idle (which you may have to manually call).  Note this
1214  * doesn't test things like memory being leaked, or dealing with processes. */
1215 void test_kthreads(void)
1216 {
1217         /* Kernel message to restart our kthread */
1218         void test_up_sem(struct trapframe *tf, uint32_t srcid, long a0, long a1,
1219                          long a2)
1220         {
1221                 struct semaphore *sem = (struct semaphore*)a0;
1222                 struct kthread *kthread;
1223                 printk("[kmsg] Upping the sem to start the kthread, stacktop is %08p\n",
1224                        get_stack_top());
1225                 kthread = __up_sem(sem, FALSE);
1226                 if (!kthread) {
1227                         printk("[kmsg] Crap, the sem didn't have a kthread waiting!\n");
1228                         return;
1229                 }
1230                 printk("[kmsg] Restarting the kthread...\n");
1231                 restart_kthread(kthread);
1232                 panic("[kmsg] Damnit...");
1233         }
1234         struct semaphore sem;
1235         init_sem(&sem, 1);              /* set to 1 to test the unwind */
1236         printk("We're a kthread!  Stacktop is %08p.  Testing suspend, etc...\n",
1237                get_stack_top());
1238         /* So we have something that will wake us up.  Routine messages won't get
1239          * serviced in the kernel right away. */
1240         send_kernel_message(core_id(), test_up_sem, (long)&sem, 0, 0,
1241                             KMSG_ROUTINE);
1242         /* Actually block (or try to) */
1243         /* This one shouldn't block - but will test the unwind (if 1 above) */
1244         printk("About to sleep, but should unwind (signal beat us)\n");
1245         sleep_on(&sem);
1246         /* This one is for real, yo.  Run and tell that. */
1247         printk("About to sleep for real\n");
1248         sleep_on(&sem);
1249         printk("Kthread restarted!, Stacktop is %08p.\n", get_stack_top());
1250 }
1251
1252 /* Runs a simple test between core 0 (caller) and core 2 */
1253 void test_kref(void)
1254 {
1255         struct kref local_kref;
1256         bool done = FALSE;
1257         /* Second player's kmsg */
1258         void test_kref_2(struct trapframe *tf, uint32_t srcid, long a0, long a1,
1259                          long a2)
1260         {
1261                 struct kref *kref = (struct kref*)a0;
1262                 bool *done = (bool*)a1;
1263                 enable_irq();
1264                 for (int i = 0; i < 10000000; i++) {
1265                         kref_get(kref, 1);
1266                         set_core_timer(1, TRUE);
1267                         udelay(2);
1268                         kref_put(kref);
1269                 }
1270                 *done = TRUE;
1271         }
1272         
1273         kref_init(&local_kref, fake_release, 1);
1274         send_kernel_message(2, test_kref_2, (long)&local_kref, (long)&done, 0,
1275                             KMSG_ROUTINE);
1276         for (int i = 0; i < 10000000; i++) {
1277                 kref_get(&local_kref, 1);
1278                 udelay(2);
1279                 kref_put(&local_kref);
1280         }
1281         while (!done)
1282                 cpu_relax();
1283         assert(kref_refcnt(&local_kref) == 1);
1284         printk("[TEST-KREF] Simple 2-core getting/putting passed.\n");
1285 }
1286
1287 void test_atomics(void)
1288 {
1289         /* subtract_and_test */
1290         atomic_t num;
1291         /* Test subing to 0 */
1292         atomic_init(&num, 1);
1293         assert(atomic_sub_and_test(&num, 1) == 1);
1294         atomic_init(&num, 2);
1295         assert(atomic_sub_and_test(&num, 2) == 1);
1296         /* Test not getting to 0 */
1297         atomic_init(&num, 1);
1298         assert(atomic_sub_and_test(&num, 0) == 0);
1299         atomic_init(&num, 2);
1300         assert(atomic_sub_and_test(&num, 1) == 0);
1301         /* Test negatives */
1302         atomic_init(&num, -1);
1303         assert(atomic_sub_and_test(&num, 1) == 0);
1304         atomic_init(&num, -1);
1305         assert(atomic_sub_and_test(&num, -1) == 1);
1306         /* Test larger nums */
1307         atomic_init(&num, 265);
1308         assert(atomic_sub_and_test(&num, 265) == 1);
1309         atomic_init(&num, 265);
1310         assert(atomic_sub_and_test(&num, 2) == 0);
1311
1312         /* CAS */
1313         /* Simple test, make sure the bool retval of CAS handles failure */
1314         void test_cas_val(long init_val)
1315         {
1316                 atomic_t actual_num;
1317                 long old_num;
1318                 int attempt;
1319                 atomic_init(&actual_num, init_val);
1320                 attempt = 0;
1321                 do {
1322                         old_num = atomic_read(&actual_num);
1323                         /* First time, try to fail */
1324                         if (attempt == 0) 
1325                                 old_num++;
1326                         attempt++;      
1327                 } while (!atomic_cas(&actual_num, old_num, old_num + 10));
1328                 if (atomic_read(&actual_num) != init_val + 10)
1329                         printk("FUCK, CAS test failed for %d\n", init_val);
1330         }
1331         test_cas_val(257);
1332         test_cas_val(1);
1333 }