VM regions: management functions and structs
[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 <arch/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
34 #define l1 (available_caches.l1)
35 #define l2 (available_caches.l2)
36 #define l3 (available_caches.l3)
37
38 #ifdef __i386__
39
40 void test_ipi_sending(void)
41 {
42         extern handler_t (CT(NUM_INTERRUPT_HANDLERS) RO interrupt_handlers)[];
43         int8_t state = 0;
44
45         register_interrupt_handler(interrupt_handlers, I_TESTING,
46                                    test_hello_world_handler, NULL);
47         enable_irqsave(&state);
48         cprintf("\nCORE 0 sending broadcast\n");
49         send_broadcast_ipi(I_TESTING);
50         udelay(3000000);
51         cprintf("\nCORE 0 sending all others\n");
52         send_all_others_ipi(I_TESTING);
53         udelay(3000000);
54         cprintf("\nCORE 0 sending self\n");
55         send_self_ipi(I_TESTING);
56         udelay(3000000);
57         cprintf("\nCORE 0 sending ipi to physical 1\n");
58         send_ipi(get_hw_coreid(0x01), I_TESTING);
59         udelay(3000000);
60         cprintf("\nCORE 0 sending ipi to physical 2\n");
61         send_ipi(get_hw_coreid(0x02), I_TESTING);
62         udelay(3000000);
63         cprintf("\nCORE 0 sending ipi to physical 3\n");
64         send_ipi(get_hw_coreid(0x03), I_TESTING);
65         udelay(3000000);
66         cprintf("\nCORE 0 sending ipi to physical 15\n");
67         send_ipi(get_hw_coreid(0x0f), I_TESTING);
68         udelay(3000000);
69         cprintf("\nCORE 0 sending ipi to logical 2\n");
70         send_group_ipi(0x02, I_TESTING);
71         udelay(3000000);
72         cprintf("\nCORE 0 sending ipi to logical 1\n");
73         send_group_ipi(0x01, I_TESTING);
74         udelay(3000000);
75         cprintf("\nDone!\n");
76         disable_irqsave(&state);
77 }
78
79 // Note this never returns and will muck with any other timer work
80 void test_pic_reception(void)
81 {
82         register_interrupt_handler(interrupt_handlers, 0x20, test_hello_world_handler, NULL);
83         pit_set_timer(100,TIMER_RATEGEN); // totally arbitrary time
84         pic_unmask_irq(0);
85         cprintf("PIC1 Mask = 0x%04x\n", inb(PIC1_DATA));
86         cprintf("PIC2 Mask = 0x%04x\n", inb(PIC2_DATA));
87         unmask_lapic_lvt(LAPIC_LVT_LINT0);
88         cprintf("Core %d's LINT0: 0x%08x\n", core_id(), read_mmreg32(LAPIC_LVT_LINT0));
89         enable_irq();
90         while(1);
91 }
92
93 void test_ioapic_pit_reroute(void) 
94 {
95         register_interrupt_handler(interrupt_handlers, 0x20, test_hello_world_handler, NULL);
96         ioapic_route_irq(0, 3); 
97
98         cprintf("Starting pit on core 3....\n");
99         udelay(3000000);
100         pit_set_timer(0xFFFE,TIMER_RATEGEN); // totally arbitrary time
101         
102         udelay(3000000);
103         ioapic_unroute_irq(0);
104         udelay(300000);
105         cprintf("Masked pit. Waiting before return...\n");
106         udelay(3000000);
107 }
108
109 #endif // __i386__
110
111
112 void test_print_info(void)
113 {
114         cprintf("\nCORE 0 asking all cores to print info:\n");
115         smp_call_function_all(test_print_info_handler, NULL, 0);
116         cprintf("\nDone!\n");
117 }
118
119 void test_page_coloring(void) 
120 {
121 /*
122         //Print the different cache properties of our machine
123         print_cache_properties("L1", l1);
124         cprintf("\n");
125         print_cache_properties("L2", l2);
126         cprintf("\n");
127         print_cache_properties("L3", l3);
128         cprintf("\n");
129
130         //Print some stats about our memory
131         cprintf("Max Address: %llu\n", MAX_VADDR);
132         cprintf("Num Pages: %u\n", npages);
133
134         //Declare a local variable for allocating pages 
135         page_t* page;
136
137         cprintf("Contents of the page free list:\n");
138         for(int i=0; i<llc_cache->num_colors; i++) {
139                 cprintf("  COLOR %d:\n", i);
140                 LIST_FOREACH(page, &colored_page_free_list[i], page_link) {
141                         cprintf("    Page: %d\n", page2ppn(page));
142                 }
143         }
144
145         //Run through and allocate all pages through l1_page_alloc
146         cprintf("Allocating from L1 page colors:\n");
147         for(int i=0; i<get_cache_num_page_colors(l1); i++) {
148                 cprintf("  COLOR %d:\n", i);
149                 while(colored_page_alloc(l1, &page, i) != -ENOMEM)
150                         cprintf("    Page: %d\n", page2ppn(page));
151         }
152
153         //Put all the pages back by reinitializing
154         page_init();
155         
156         //Run through and allocate all pages through l2_page_alloc
157         cprintf("Allocating from L2 page colors:\n");
158         for(int i=0; i<get_cache_num_page_colors(l2); i++) {
159                 cprintf("  COLOR %d:\n", i);
160                 while(colored_page_alloc(l2, &page, i) != -ENOMEM)
161                         cprintf("    Page: %d\n", page2ppn(page));
162         }
163
164         //Put all the pages back by reinitializing
165         page_init();
166         
167         //Run through and allocate all pages through l3_page_alloc
168         cprintf("Allocating from L3 page colors:\n");
169         for(int i=0; i<get_cache_num_page_colors(l3); i++) {
170                 cprintf("  COLOR %d:\n", i);
171                 while(colored_page_alloc(l3, &page, i) != -ENOMEM)
172                         cprintf("    Page: %d\n", page2ppn(page));
173         }
174         
175         //Put all the pages back by reinitializing
176         page_init();
177         
178         //Run through and allocate all pages through page_alloc
179         cprintf("Allocating from global allocator:\n");
180         while(upage_alloc(&page) != -ENOMEM)
181                 cprintf("    Page: %d\n", page2ppn(page));
182         
183         if(colored_page_alloc(l2, &page, 0) != -ENOMEM)
184                 cprintf("Should not get here, all pages should already be gone!\n");
185         cprintf("All pages gone for sure...\n");
186         
187         //Now lets put a few pages back using page_free..
188         cprintf("Reinserting pages via page_free and reallocating them...\n");
189         page_free(&pages[0]);
190         page_free(&pages[15]);
191         page_free(&pages[7]);
192         page_free(&pages[6]);
193         page_free(&pages[4]);
194
195         while(upage_alloc(&page) != -ENOMEM)
196                 cprintf("Page: %d\n", page2ppn(page));  
197         
198         page_init();
199 */
200 }
201
202 void test_color_alloc() {
203         size_t checkpoint = 0;
204         uint8_t* colors_map = kmalloc(BYTES_FOR_BITMASK(llc_cache->num_colors), 0);
205         cache_color_alloc(l2, colors_map);
206         cache_color_alloc(l3, colors_map);
207         cache_color_alloc(l3, colors_map);
208         cache_color_alloc(l2, colors_map);
209         cache_color_free(llc_cache, colors_map);
210         cache_color_free(llc_cache, colors_map);
211         cache_color_free(llc_cache, colors_map);
212         cache_color_free(llc_cache, colors_map);
213         cache_color_free(llc_cache, colors_map);
214         cache_color_free(llc_cache, colors_map);
215         cache_color_free(llc_cache, colors_map);
216         cache_color_free(llc_cache, colors_map);
217         cache_color_free(llc_cache, colors_map);
218         cache_color_free(llc_cache, colors_map);
219         cache_color_free(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(l2, colors_map);
226         cache_color_free(llc_cache, colors_map);
227         cache_color_free(llc_cache, colors_map);
228
229 print_cache_colors:
230         printk("L1 free colors, tot colors: %d\n", l1->num_colors);
231         PRINT_BITMASK(l1->free_colors_map, l1->num_colors);
232         printk("L2 free colors, tot colors: %d\n", l2->num_colors);
233         PRINT_BITMASK(l2->free_colors_map, l2->num_colors);
234         printk("L3 free colors, tot colors: %d\n", l3->num_colors);
235         PRINT_BITMASK(l3->free_colors_map, l3->num_colors);
236         printk("Process allocated colors\n");
237         PRINT_BITMASK(colors_map, llc_cache->num_colors);
238         printk("test_color_alloc() complete!\n");
239 }
240
241 barrier_t test_cpu_array;
242
243 void test_barrier(void)
244 {
245         cprintf("Core 0 initializing barrier\n");
246         init_barrier(&test_cpu_array, num_cpus);
247         cprintf("Core 0 asking all cores to print ids, barrier, rinse, repeat\n");
248         smp_call_function_all(test_barrier_handler, NULL, 0);
249 }
250
251 void test_interrupts_irqsave(void)
252 {
253         int8_t state = 0;
254         printd("Testing Nesting Enabling first, turning ints off:\n");
255         disable_irq();
256         printd("Interrupts are: %x\n", irq_is_enabled());
257         assert(!irq_is_enabled());
258         printd("Enabling IRQSave\n");
259         enable_irqsave(&state);
260         printd("Interrupts are: %x\n", irq_is_enabled());
261         assert(irq_is_enabled());
262         printd("Enabling IRQSave Again\n");
263         enable_irqsave(&state);
264         printd("Interrupts are: %x\n", irq_is_enabled());
265         assert(irq_is_enabled());
266         printd("Disabling IRQSave Once\n");
267         disable_irqsave(&state);
268         printd("Interrupts are: %x\n", irq_is_enabled());
269         assert(irq_is_enabled());
270         printd("Disabling IRQSave Again\n");
271         disable_irqsave(&state);
272         printd("Interrupts are: %x\n", irq_is_enabled());
273         assert(!irq_is_enabled());
274         printd("Done.  Should have been 0, 200, 200, 200, 0\n");
275
276         printd("Testing Nesting Disabling first, turning ints on:\n");
277         state = 0;
278         enable_irq();
279         printd("Interrupts are: %x\n", irq_is_enabled());
280         assert(irq_is_enabled());
281         printd("Disabling IRQSave Once\n");
282         disable_irqsave(&state);
283         printd("Interrupts are: %x\n", irq_is_enabled());
284         assert(!irq_is_enabled());
285         printd("Disabling IRQSave Again\n");
286         disable_irqsave(&state);
287         printd("Interrupts are: %x\n", irq_is_enabled());
288         assert(!irq_is_enabled());
289         printd("Enabling IRQSave Once\n");
290         enable_irqsave(&state);
291         printd("Interrupts are: %x\n", irq_is_enabled());
292         assert(!irq_is_enabled());
293         printd("Enabling IRQSave Again\n");
294         enable_irqsave(&state);
295         printd("Interrupts are: %x\n", irq_is_enabled());
296         assert(irq_is_enabled());
297         printd("Done.  Should have been 200, 0, 0, 0, 200 \n");
298
299         state = 0;
300         disable_irq();
301         printd("Ints are off, enabling then disabling.\n");
302         enable_irqsave(&state);
303         printd("Interrupts are: %x\n", irq_is_enabled());
304         assert(irq_is_enabled());
305         disable_irqsave(&state);
306         printd("Interrupts are: %x\n", irq_is_enabled());
307         assert(!irq_is_enabled());
308         printd("Done.  Should have been 200, 0\n");
309
310         state = 0;
311         enable_irq();
312         printd("Ints are on, enabling then disabling.\n");
313         enable_irqsave(&state);
314         printd("Interrupts are: %x\n", irq_is_enabled());
315         assert(irq_is_enabled());
316         disable_irqsave(&state);
317         printd("Interrupts are: %x\n", irq_is_enabled());
318         assert(irq_is_enabled());
319         printd("Done.  Should have been 200, 200\n");
320
321         state = 0;
322         disable_irq();
323         printd("Ints are off, disabling then enabling.\n");
324         disable_irqsave(&state);
325         printd("Interrupts are: %x\n", irq_is_enabled());
326         assert(!irq_is_enabled());
327         enable_irqsave(&state);
328         printd("Interrupts are: %x\n", irq_is_enabled());
329         assert(!irq_is_enabled());
330         printd("Done.  Should have been 0, 0\n");
331
332         state = 0;
333         enable_irq();
334         printd("Ints are on, disabling then enabling.\n");
335         disable_irqsave(&state);
336         printd("Interrupts are: %x\n", irq_is_enabled());
337         assert(!irq_is_enabled());
338         enable_irqsave(&state);
339         printd("Interrupts are: %x\n", irq_is_enabled());
340         assert(irq_is_enabled());
341         printd("Done.  Should have been 0, 200\n");
342
343         disable_irq();
344         cprintf("Passed enable_irqsave tests\n");
345 }
346
347 void test_bitmasks(void)
348 {
349 #define masksize 67
350         DECL_BITMASK(mask, masksize);
351         printk("size of mask %d\n", sizeof(mask));
352         CLR_BITMASK(mask, masksize);
353         PRINT_BITMASK(mask, masksize);
354         printk("cleared\n");
355         SET_BITMASK_BIT(mask, 0);
356         SET_BITMASK_BIT(mask, 11);
357         SET_BITMASK_BIT(mask, 17);
358         SET_BITMASK_BIT(mask, masksize-1);
359         printk("bits set\n");
360         PRINT_BITMASK(mask, masksize);
361         DECL_BITMASK(mask2, masksize);
362         COPY_BITMASK(mask2, mask, masksize);
363         printk("copy of original mask, should be the same as the prev\n");
364         PRINT_BITMASK(mask2, masksize);
365         CLR_BITMASK_BIT(mask, 11);
366         printk("11 cleared\n");
367         PRINT_BITMASK(mask, masksize);
368         printk("bit 17 is %d (should be 1)\n", GET_BITMASK_BIT(mask, 17));
369         printk("bit 11 is %d (should be 0)\n", GET_BITMASK_BIT(mask, 11));
370         FILL_BITMASK(mask, masksize);
371         PRINT_BITMASK(mask, masksize);
372         printk("should be all 1's, except for a few at the end\n");
373         printk("Is Clear?: %d (should be 0)\n", BITMASK_IS_CLEAR(mask,masksize));
374         CLR_BITMASK(mask, masksize);
375         PRINT_BITMASK(mask, masksize);
376         printk("Is Clear?: %d (should be 1)\n", BITMASK_IS_CLEAR(mask,masksize));
377         printk("should be cleared\n");
378 }
379
380 checklist_t *RO the_global_list;
381
382 void test_checklist_handler(trapframe_t *tf, void* data)
383 {
384         udelay(1000000);
385         cprintf("down_checklist(%x,%d)\n", the_global_list, core_id());
386         down_checklist(the_global_list);
387 }
388
389 void test_checklists(void)
390 {
391         INIT_CHECKLIST(a_list, MAX_NUM_CPUS);
392         the_global_list = &a_list;
393         printk("Checklist Build, mask size: %d\n", sizeof(a_list.mask.bits));
394         printk("mask\n");
395         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
396         SET_BITMASK_BIT(a_list.mask.bits, 11);
397         printk("Set bit 11\n");
398         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
399
400         CLR_BITMASK(a_list.mask.bits, a_list.mask.size);
401         INIT_CHECKLIST_MASK(a_mask, MAX_NUM_CPUS);
402         FILL_BITMASK(a_mask.bits, num_cpus);
403         //CLR_BITMASK_BIT(a_mask.bits, core_id());
404         //SET_BITMASK_BIT(a_mask.bits, 1);
405         //printk("New mask (1, 17, 25):\n");
406         printk("Created new mask, filled up to num_cpus\n");
407         PRINT_BITMASK(a_mask.bits, a_mask.size);
408         printk("committing new mask\n");
409         commit_checklist_wait(&a_list, &a_mask);
410         printk("Old mask (copied onto):\n");
411         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
412         //smp_call_function_single(1, test_checklist_handler, 0, 0);
413
414         smp_call_function_all(test_checklist_handler, NULL, 0);
415
416         printk("Waiting on checklist\n");
417         waiton_checklist(&a_list);
418         printk("Done Waiting!\n");
419
420 }
421
422 atomic_t a, b, c;
423
424 #ifdef __IVY__
425 void test_incrementer_handler(trapframe_t *tf, atomic_t *data)
426 #else
427 void test_incrementer_handler(trapframe_t *tf, void *data)
428 #endif
429 {
430         assert(data);
431         atomic_inc(data);
432 }
433
434 void test_null_handler(trapframe_t *tf, void* data)
435 {
436         asm volatile("nop");
437 }
438
439 void test_smp_call_functions(void)
440 {
441         int i;
442         atomic_init(&a, 0);
443         atomic_init(&b, 0);
444         atomic_init(&c, 0);
445         handler_wrapper_t *waiter0 = 0, *waiter1 = 0, *waiter2 = 0, *waiter3 = 0,
446                           *waiter4 = 0, *waiter5 = 0;
447         uint8_t me = core_id();
448         printk("\nCore %d: SMP Call Self (nowait):\n", me);
449         printk("---------------------\n");
450         smp_call_function_self(test_hello_world_handler, NULL, 0);
451         printk("\nCore %d: SMP Call Self (wait):\n", me);
452         printk("---------------------\n");
453         smp_call_function_self(test_hello_world_handler, NULL, &waiter0);
454         smp_call_wait(waiter0);
455         printk("\nCore %d: SMP Call All (nowait):\n", me);
456         printk("---------------------\n");
457         smp_call_function_all(test_hello_world_handler, NULL, 0);
458         printk("\nCore %d: SMP Call All (wait):\n", me);
459         printk("---------------------\n");
460         smp_call_function_all(test_hello_world_handler, NULL, &waiter0);
461         smp_call_wait(waiter0);
462         printk("\nCore %d: SMP Call All-Else Individually, in order (nowait):\n", me);
463         printk("---------------------\n");
464         for(i = 1; i < num_cpus; i++)
465                 smp_call_function_single(i, test_hello_world_handler, NULL, 0);
466         printk("\nCore %d: SMP Call Self (wait):\n", me);
467         printk("---------------------\n");
468         smp_call_function_self(test_hello_world_handler, NULL, &waiter0);
469         smp_call_wait(waiter0);
470         printk("\nCore %d: SMP Call All-Else Individually, in order (wait):\n", me);
471         printk("---------------------\n");
472         for(i = 1; i < num_cpus; i++)
473         {
474                 smp_call_function_single(i, test_hello_world_handler, NULL, &waiter0);
475                 smp_call_wait(waiter0);
476         }
477         printk("\nTesting to see if any IPI-functions are dropped when not waiting:\n");
478         printk("A: %d, B: %d, C: %d (should be 0,0,0)\n", atomic_read(&a), atomic_read(&b), atomic_read(&c));
479         smp_call_function_all(test_incrementer_handler, &a, 0);
480         smp_call_function_all(test_incrementer_handler, &b, 0);
481         smp_call_function_all(test_incrementer_handler, &c, 0);
482         // if i can clobber a previous IPI, the interleaving might do it
483         smp_call_function_single(1 % num_cpus, test_incrementer_handler, &a, 0);
484         smp_call_function_single(2 % num_cpus, test_incrementer_handler, &b, 0);
485         smp_call_function_single(3 % num_cpus, test_incrementer_handler, &c, 0);
486         smp_call_function_single(4 % num_cpus, test_incrementer_handler, &a, 0);
487         smp_call_function_single(5 % num_cpus, test_incrementer_handler, &b, 0);
488         smp_call_function_single(6 % num_cpus, test_incrementer_handler, &c, 0);
489         smp_call_function_all(test_incrementer_handler, &a, 0);
490         smp_call_function_single(3 % num_cpus, test_incrementer_handler, &c, 0);
491         smp_call_function_all(test_incrementer_handler, &b, 0);
492         smp_call_function_single(1 % num_cpus, test_incrementer_handler, &a, 0);
493         smp_call_function_all(test_incrementer_handler, &c, 0);
494         smp_call_function_single(2 % num_cpus, test_incrementer_handler, &b, 0);
495         // wait, so we're sure the others finish before printing.
496         // without this, we could (and did) get 19,18,19, since the B_inc
497         // handler didn't finish yet
498         smp_call_function_self(test_null_handler, NULL, &waiter0);
499         // need to grab all 5 handlers (max), since the code moves to the next free.
500         smp_call_function_self(test_null_handler, NULL, &waiter1);
501         smp_call_function_self(test_null_handler, NULL, &waiter2);
502         smp_call_function_self(test_null_handler, NULL, &waiter3);
503         smp_call_function_self(test_null_handler, NULL, &waiter4);
504         smp_call_wait(waiter0);
505         smp_call_wait(waiter1);
506         smp_call_wait(waiter2);
507         smp_call_wait(waiter3);
508         smp_call_wait(waiter4);
509         printk("A: %d, B: %d, C: %d (should be 19,19,19)\n", atomic_read(&a), atomic_read(&b), atomic_read(&c));
510         printk("Attempting to deadlock by smp_calling with an outstanding wait:\n");
511         smp_call_function_self(test_null_handler, NULL, &waiter0);
512         printk("Sent one\n");
513         smp_call_function_self(test_null_handler, NULL, &waiter1);
514         printk("Sent two\n");
515         smp_call_wait(waiter0);
516         printk("Wait one\n");
517         smp_call_wait(waiter1);
518         printk("Wait two\n");
519         printk("\tMade it through!\n");
520         printk("Attempting to deadlock by smp_calling more than are available:\n");
521         printk("\tShould see an Insufficient message and a kernel warning.\n");
522         if (smp_call_function_self(test_null_handler, NULL, &waiter0))
523                 printk("\tInsufficient handlers to call function (0)\n");
524         if (smp_call_function_self(test_null_handler, NULL, &waiter1))
525                 printk("\tInsufficient handlers to call function (1)\n");
526         if (smp_call_function_self(test_null_handler, NULL, &waiter2))
527                 printk("\tInsufficient handlers to call function (2)\n");
528         if (smp_call_function_self(test_null_handler, NULL, &waiter3))
529                 printk("\tInsufficient handlers to call function (3)\n");
530         if (smp_call_function_self(test_null_handler, NULL, &waiter4))
531                 printk("\tInsufficient handlers to call function (4)\n");
532         if (smp_call_function_self(test_null_handler, NULL, &waiter5))
533                 printk("\tInsufficient handlers to call function (5)\n");
534         smp_call_wait(waiter0);
535         smp_call_wait(waiter1);
536         smp_call_wait(waiter2);
537         smp_call_wait(waiter3);
538         smp_call_wait(waiter4);
539         smp_call_wait(waiter5);
540         printk("\tMade it through!\n");
541
542         printk("Done\n");
543 }
544
545 #ifdef __i386__
546 void test_lapic_status_bit(void)
547 {
548         register_interrupt_handler(interrupt_handlers, I_TESTING,
549                                    test_incrementer_handler, &a);
550         #define NUM_IPI 100000
551         atomic_set(&a,0);
552         printk("IPIs received (should be 0): %d\n", a);
553         for(int i = 0; i < NUM_IPI; i++) {
554                 send_ipi(get_hw_coreid(7), I_TESTING);
555                 lapic_wait_to_send();
556         }
557         // need to wait a bit to let those IPIs get there
558         udelay(5000000);
559         printk("IPIs received (should be %d): %d\n", a, NUM_IPI);
560         // hopefully that handler never fires again.  leaving it registered for now.
561 }
562 #endif // __i386__
563
564 /************************************************************/
565 /* ISR Handler Functions */
566
567 void test_hello_world_handler(trapframe_t *tf, void* data)
568 {
569         int trapno;
570         #if defined(__i386__)
571         trapno = tf->tf_trapno;
572         #elif defined(__sparc_v8__)
573         trapno = (tf->tbr >> 4) & 0xFF;
574         #else
575         trapno = 0;
576         #endif
577
578         cprintf("Incoming IRQ, ISR: %d on core %d with tf at 0x%08x\n",
579                 trapno, core_id(), tf);
580 }
581
582 spinlock_t print_info_lock = SPINLOCK_INITIALIZER;
583
584 void test_print_info_handler(trapframe_t *tf, void* data)
585 {
586         uint64_t tsc = read_tsc();
587
588         spin_lock_irqsave(&print_info_lock);
589         cprintf("----------------------------\n");
590         cprintf("This is Core %d\n", core_id());
591         cprintf("Timestamp = %lld\n", tsc);
592 #ifdef __i386__
593         cprintf("Hardware core %d\n", hw_core_id());
594         cprintf("MTRR_DEF_TYPE = 0x%08x\n", read_msr(IA32_MTRR_DEF_TYPE));
595         cprintf("MTRR Phys0 Base = 0x%016llx, Mask = 0x%016llx\n",
596                 read_msr(0x200), read_msr(0x201));
597         cprintf("MTRR Phys1 Base = 0x%016llx, Mask = 0x%016llx\n",
598                 read_msr(0x202), read_msr(0x203));
599         cprintf("MTRR Phys2 Base = 0x%016llx, Mask = 0x%016llx\n",
600                 read_msr(0x204), read_msr(0x205));
601         cprintf("MTRR Phys3 Base = 0x%016llx, Mask = 0x%016llx\n",
602                 read_msr(0x206), read_msr(0x207));
603         cprintf("MTRR Phys4 Base = 0x%016llx, Mask = 0x%016llx\n",
604                 read_msr(0x208), read_msr(0x209));
605         cprintf("MTRR Phys5 Base = 0x%016llx, Mask = 0x%016llx\n",
606                 read_msr(0x20a), read_msr(0x20b));
607         cprintf("MTRR Phys6 Base = 0x%016llx, Mask = 0x%016llx\n",
608                 read_msr(0x20c), read_msr(0x20d));
609         cprintf("MTRR Phys7 Base = 0x%016llx, Mask = 0x%016llx\n",
610                 read_msr(0x20e), read_msr(0x20f));
611 #endif // __i386__
612         cprintf("----------------------------\n");
613         spin_unlock_irqsave(&print_info_lock);
614 }
615
616 void test_barrier_handler(trapframe_t *tf, void* data)
617 {
618         cprintf("Round 1: Core %d\n", core_id());
619         waiton_barrier(&test_cpu_array);
620         waiton_barrier(&test_cpu_array);
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         cprintf("Round 2: Core %d\n", core_id());
626         waiton_barrier(&test_cpu_array);
627         cprintf("Round 3: Core %d\n", core_id());
628         // uncomment to see it fucked up
629         //cprintf("Round 4: Core %d\n", core_id());
630 }
631
632 #ifdef __IVY__
633 static void test_waiting_handler(trapframe_t *tf, atomic_t *data)
634 #else
635 static void test_waiting_handler(trapframe_t *tf, void *data)
636 #endif
637 {
638         atomic_dec(data);
639 }
640
641 #ifdef __i386__
642 void test_pit(void)
643 {
644         cprintf("Starting test for PIT now (10s)\n");
645         udelay_pit(10000000);
646         cprintf("End now\n");
647         cprintf("Starting test for TSC (if stable) now (10s)\n");
648         udelay(10000000);
649         cprintf("End now\n");
650
651         cprintf("Starting test for LAPIC (if stable) now (10s)\n");
652         enable_irq();
653         lapic_set_timer(10000000, FALSE);
654
655         atomic_t waiting;
656         atomic_init(&waiting, 1);
657         register_interrupt_handler(interrupt_handlers, I_TESTING,
658                                    test_waiting_handler, &waiting);
659         while(atomic_read(&waiting))
660                 cpu_relax();
661         cprintf("End now\n");
662 }
663
664 void test_circ_buffer(void)
665 {
666         int arr[5] = {0, 1, 2, 3, 4};
667
668         for (int i = 0; i < 5; i++) {
669                 FOR_CIRC_BUFFER(i, 5, j)
670                         printk("Starting with current = %d, each value = %d\n", i, j);
671         }
672         return;
673 }
674
675 void test_km_handler(trapframe_t* tf, uint32_t srcid, void *a0, void *a1,
676                      void *a2)
677 {
678         printk("Received KM on core %d from core %d: arg0= 0x%08x, arg1 = "
679                "0x%08x, arg2 = 0x%08x\n", core_id(), srcid, a0, a1, a2);
680         return;
681 }
682
683 void test_kernel_messages(void)
684 {
685         printk("Testing Kernel Messages\n");
686         /* Testing sending multiples, sending different types, alternating, and
687          * precendence (the immediates should trump the others) */
688         printk("sending 5 IMMED to core 1, sending (#,deadbeef,0)\n");
689         for (int i = 0; i < 5; i++)
690                 send_kernel_message(1, test_km_handler, (void*)i, (void*)0xdeadbeef,
691                                     (void*)0, KMSG_IMMEDIATE);
692         udelay(5000000);
693         printk("sending 5 routine to core 1, sending (#,cafebabe,0)\n");
694         for (int i = 0; i < 5; i++)
695                 send_kernel_message(1, test_km_handler, (void*)i, (void*)0xcafebabe,
696                                     (void*)0, KMSG_ROUTINE);
697         udelay(5000000);
698         printk("sending 10 routine and 3 immediate to core 2\n");
699         for (int i = 0; i < 10; i++)
700                 send_kernel_message(2, test_km_handler, (void*)i, (void*)0xcafebabe,
701                                     (void*)0, KMSG_ROUTINE);
702         for (int i = 0; i < 3; i++)
703                 send_kernel_message(2, test_km_handler, (void*)i, (void*)0xdeadbeef,
704                                     (void*)0, KMSG_IMMEDIATE);
705         udelay(5000000);
706         printk("sending 5 ea alternating to core 2\n");
707         for (int i = 0; i < 5; i++) {
708                 send_kernel_message(2, test_km_handler, (void*)i, (void*)0xdeadbeef,
709                                     (void*)0, KMSG_IMMEDIATE);
710                 send_kernel_message(2, test_km_handler, (void*)i, (void*)0xcafebabe,
711                                     (void*)0, KMSG_ROUTINE);
712         }
713         udelay(5000000);
714         return;
715 }
716 #endif // __i386__
717
718 static void test_single_cache(int iters, size_t size, int align, int flags,
719                               void (*ctor)(void *, size_t),
720                               void (*dtor)(void *, size_t))
721 {
722         struct kmem_cache *test_cache;
723         void *objects[iters];
724         test_cache = kmem_cache_create("test_cache", size, align, flags, ctor, dtor);
725         printk("Testing Kmem Cache:\n");
726         print_kmem_cache(test_cache);
727         for (int i = 0; i < iters; i++) {
728                 objects[i] = kmem_cache_alloc(test_cache, 0);
729                 printk("Buffer %d addr = %p\n", i, objects[i]);
730         }
731         for (int i = 0; i < iters; i++) {
732                 kmem_cache_free(test_cache, objects[i]);
733         }
734         kmem_cache_destroy(test_cache);
735         printk("\n\n\n\n");
736 }
737
738 void a_ctor(void *buf, size_t size)
739 {
740         printk("constructin tests\n");
741 }
742 void a_dtor(void *buf, size_t size)
743 {
744         printk("destructin tests\n");
745 }
746
747 void test_slab(void)
748 {
749         test_single_cache(10, 128, 512, 0, 0, 0);
750         test_single_cache(10, 128, 4, 0, a_ctor, a_dtor);
751         test_single_cache(10, 1024, 16, 0, 0, 0);
752 }
753
754 void test_kmalloc(void)
755 {
756         printk("Testing Kmalloc\n");
757         void *bufs[NUM_KMALLOC_CACHES + 1];     
758         size_t size;
759         for (int i = 0; i < NUM_KMALLOC_CACHES + 1; i++){
760                 size = (KMALLOC_SMALLEST << i) - KMALLOC_OFFSET;
761                 bufs[i] = kmalloc(size, 0);
762                 printk("Size %d, Addr = %p\n", size, bufs[i]);
763         }
764         for (int i = 0; i < NUM_KMALLOC_CACHES; i++) {
765                 printk("Freeing buffer %d\n", i);
766                 kfree(bufs[i]);
767         }
768         printk("Testing a large kmalloc\n");
769         size = (KMALLOC_LARGEST << 2);
770         bufs[0] = kmalloc(size, 0);
771         printk("Size %d, Addr = %p\n", size, bufs[0]);
772         kfree(bufs[0]);
773 }
774
775 static size_t test_hash_fn_col(void *k)
776 {
777         return (size_t)k % 2; // collisions in slots 0 and 1
778 }
779
780 void test_hashtable(void)
781 {
782         struct test {int x; int y;};
783         struct test tstruct[10];
784
785         struct hashtable *h;
786         int k = 5;
787         struct test *v = &tstruct[0];
788
789         h = create_hashtable(32, __generic_hash, __generic_eq);
790         
791         // test inserting one item, then finding it again
792         printk("Tesing one item, insert, search, and removal\n");
793         if(!hashtable_insert(h, (void*)k, v))
794                 printk("Failed to insert to hashtable!\n");
795         v = NULL;
796         if (!(v = hashtable_search(h, (void*)k)))
797                 printk("Failed to find in hashtable!\n");
798         if (v != &tstruct[0])
799                 printk("Got the wrong item! (got %p, wanted %p)\n", v, &tstruct[0]);
800         v = NULL;
801         if (!(v = hashtable_remove(h, (void*)k)))
802                 printk("Failed to remove from hashtable!\n");
803         // shouldn't be able to find it again
804         if ((v = hashtable_search(h, (void*)k)))
805                 printk("Should not have been able to find in hashtable!\n");
806         
807         printk("Tesing a bunch of items, insert, search, and removal\n");
808         for (int i = 0; i < 10; i++) {
809                 k = i; // vary the key, we don't do KEY collisions
810                 if(!hashtable_insert(h, (void*)k, &tstruct[i]))
811                         printk("Failed to insert iter %d to hashtable!\n", i);
812         }
813         // read out the 10 items
814         for (int i = 0; i < 10; i++) {
815                 k = i;
816                 if (!(v = hashtable_search(h, (void*)k)))
817                         printk("Failed to find in hashtable!\n");
818                 if (v != &tstruct[i])
819                         printk("Got the wrong item! (got %p, wanted %p)\n", v, &tstruct[i]);
820         }
821         if (hashtable_count(h) != 10)
822                 printk("Wrong accounting of number of elements!\n");
823         // remove the 10 items
824         for (int i = 0; i < 10; i++) {
825                 k = i;
826                 if (!(v = hashtable_remove(h, (void*)k)))
827                         printk("Failed to remove from hashtable!\n");
828         }
829         // make sure they are all gone
830         for (int i = 0; i < 10; i++) {
831                 k = i;
832                 if ((v = hashtable_search(h, (void*)k)))
833                         printk("Should not have been able to find in hashtable!\n");
834         }
835         if (hashtable_count(h))
836                 printk("Wrong accounting of number of elements!\n");
837         hashtable_destroy(h);
838
839         // same test of a bunch of items, but with collisions.
840         printk("Tesing a bunch of items with collisions, etc.\n");
841         h = create_hashtable(32, test_hash_fn_col, __generic_eq);
842         // insert 10 items
843         for (int i = 0; i < 10; i++) {
844                 k = i; // vary the key, we don't do KEY collisions
845                 if(!hashtable_insert(h, (void*)k, &tstruct[i]))
846                         printk("Failed to insert iter %d to hashtable!\n", i);
847         }
848         // read out the 10 items
849         for (int i = 0; i < 10; i++) {
850                 k = i;
851                 if (!(v = hashtable_search(h, (void*)k)))
852                         printk("Failed to find in hashtable!\n");
853                 if (v != &tstruct[i])
854                         printk("Got the wrong item! (got %p, wanted %p)\n", v, &tstruct[i]);
855         }
856         if (hashtable_count(h) != 10)
857                 printk("Wrong accounting of number of elements!\n");
858         // remove the 10 items
859         for (int i = 0; i < 10; i++) {
860                 k = i;
861                 if (!(v = hashtable_remove(h, (void*)k)))
862                         printk("Failed to remove from hashtable!\n");
863         }
864         // make sure they are all gone
865         for (int i = 0; i < 10; i++) {
866                 k = i;
867                 if ((v = hashtable_search(h, (void*)k)))
868                         printk("Should not have been able to find in hashtable!\n");
869         }
870         if (hashtable_count(h))
871                 printk("Wrong accounting of number of elements!\n");
872         hashtable_destroy(h);
873 }
874
875 /* Ghetto test, only tests one prod or consumer at a time */
876 void test_bcq(void)
877 {
878         struct my_struct {
879                 int x;
880                 int y;
881         };
882         struct my_struct in_struct, out_struct;
883         
884         DEFINE_BCQ_TYPES(test, struct my_struct, 16);
885         struct test_bcq t_bcq;
886         bcq_init(&t_bcq, struct my_struct, 16);
887         
888         in_struct.x = 4;
889         in_struct.y = 5;
890         out_struct.x = 1;
891         out_struct.y = 2;
892         
893         bcq_enqueue(&t_bcq, &in_struct, 16, 5);
894         bcq_dequeue(&t_bcq, &out_struct, 16);
895         printk("out x %d. out y %d\n", out_struct.x, out_struct.y);
896         
897         DEFINE_BCQ_TYPES(my, int, 8);
898         struct my_bcq a_bcq;
899         bcq_init(&a_bcq, int, 8);
900         
901         int y = 2;
902         int output[100];
903         int retval[100];
904         
905         for (int i = 0; i < 15; i++) {
906                 y = i;
907                 retval[i] = bcq_enqueue(&a_bcq, &y, 8, 10);
908                 printk("enqueued: %d, had retval %d \n", y, retval[i]);
909         }
910         
911         for (int i = 0; i < 15; i++) {
912                 retval[i] = bcq_dequeue(&a_bcq, &output[i], 8);
913                 printk("dequeued: %d with retval %d\n", output[i], retval[i]);
914         }
915         
916         for (int i = 0; i < 3; i++) {
917                 y = i;
918                 retval[i] = bcq_enqueue(&a_bcq, &y, 8, 10);
919                 printk("enqueued: %d, had retval %d \n", y, retval[i]);
920         }
921         
922         for (int i = 0; i < 5; i++) {
923                 retval[i] = bcq_dequeue(&a_bcq, &output[i], 8);
924                 printk("dequeued: %d with retval %d\n", output[i], retval[i]);
925         }
926         
927         for (int i = 0; i < 5; i++) {
928                 y = i;
929                 retval[i] = bcq_enqueue(&a_bcq, &y, 8, 10);
930                 printk("enqueued: %d, had retval %d \n", y, retval[i]);
931                 retval[i] = bcq_dequeue(&a_bcq, &output[i], 8);
932                 printk("dequeued: %d with retval %d\n", output[i], retval[i]);
933         }
934         
935 }
936
937 /* rudimentary tests.  does the basics, create, merge, split, etc.  Feel free to
938  * add more, esp for the error conditions and finding free slots.  This is also
939  * a bit lazy with setting the caller's fields (perm, flags, etc). */
940 void test_vm_regions(void)
941 {
942         #define MAX_VMR_TESTS 10
943         struct proc pr, *p = &pr;       /* too lazy to even create one */
944         int n = 0;
945         TAILQ_INIT(&p->vm_regions);
946
947         struct vmr_summary {
948                 uintptr_t base; 
949                 uintptr_t end; 
950         };
951         int check_vmrs(struct proc *p, struct vmr_summary *results, int len, int n)
952         {
953                 int count = 0;
954                 struct vm_region *vmr;
955                 TAILQ_FOREACH(vmr, &p->vm_regions, vm_link) {
956                         if (count >= len) {
957                                 printk("More vm_regions than expected\n");
958                                 break;
959                         }
960                         if ((vmr->vm_base != results[count].base) ||
961                             (vmr->vm_end != results[count].end)) {
962                                 printk("VM test case %d failed!\n", n);
963                                 print_vmrs(p);
964                                 return -1;
965                         }
966                         count++;
967                 }
968                 return count;
969         }
970         struct vm_region *vmrs[MAX_VMR_TESTS];
971         struct vmr_summary results[MAX_VMR_TESTS];
972
973         memset(results, 0, sizeof(results));
974         /* Make one */
975         vmrs[0] = create_vmr(p, 0x2000, 0x1000);
976         results[0].base = 0x2000;
977         results[0].end = 0x3000;
978         check_vmrs(p, results, 1, n++);
979         /* Grow it */
980         grow_vmr(vmrs[0], 0x4000);
981         results[0].base = 0x2000;
982         results[0].end = 0x4000;
983         check_vmrs(p, results, 1, n++);
984         /* Grow it poorly */
985         if (-1 != grow_vmr(vmrs[0], 0x3000))
986                 printk("Bad grow test failed\n");
987         check_vmrs(p, results, 1, n++);
988         /* Make another right next to it */
989         vmrs[1] = create_vmr(p, 0x4000, 0x1000);
990         results[1].base = 0x4000;
991         results[1].end = 0x5000;
992         check_vmrs(p, results, 2, n++);
993         /* try to grow through it */
994         if (-1 != grow_vmr(vmrs[0], 0x5000))
995                 printk("Bad grow test failed\n");
996         check_vmrs(p, results, 2, n++);
997         /* Merge them */
998         merge_vmr(vmrs[0], vmrs[1]);
999         results[0].end = 0x5000;
1000         results[1].base = 0;
1001         results[1].end = 0;
1002         check_vmrs(p, results, 1, n++);
1003         vmrs[1]= create_vmr(p, 0x6000, 0x4000);
1004         results[1].base = 0x6000;
1005         results[1].end = 0xa000;
1006         check_vmrs(p, results, 2, n++);
1007         /* try to merge unmergables (just testing ranges) */
1008         if (-1 != merge_vmr(vmrs[0], vmrs[1]))
1009                 printk("Bad merge test failed\n");
1010         check_vmrs(p, results, 2, n++);
1011         vmrs[2] = split_vmr(vmrs[1], 0x8000);
1012         results[1].end = 0x8000;
1013         results[2].base = 0x8000;
1014         results[2].end = 0xa000;
1015         check_vmrs(p, results, 3, n++);
1016         /* destroy one */
1017         destroy_vmr(vmrs[1]);
1018         results[1].base = 0x8000;
1019         results[1].end = 0xa000;
1020         check_vmrs(p, results, 2, n++);
1021         /* shrink */
1022         shrink_vmr(vmrs[2], 0x9000);
1023         results[1].base = 0x8000;
1024         results[1].end = 0x9000;
1025         check_vmrs(p, results, 2, n++);
1026         if (vmrs[2] != find_vmr(p, 0x8500))
1027                 printk("Failed to find the right vmr!");
1028         if (vmrs[2] != find_first_vmr(p, 0x8500))
1029                 printk("Failed to find the right vmr!");
1030         if (vmrs[2] != find_first_vmr(p, 0x7500))
1031                 printk("Failed to find the right vmr!");
1032         if (find_first_vmr(p, 0x9500))
1033                 printk("Found a vmr when we shouldn't!\n");
1034         /* grow up to another */
1035         grow_vmr(vmrs[0], 0x8000);
1036         results[0].end = 0x8000;
1037         check_vmrs(p, results, 2, n++);
1038         vmrs[0]->vm_perm = 88;
1039         vmrs[2]->vm_perm = 77;
1040         /* should be unmergeable due to perms */
1041         if (-1 != merge_vmr(vmrs[0], vmrs[2]))
1042                 printk("Bad merge test failed\n");
1043         check_vmrs(p, results, 2, n++);
1044         /* should merge now */
1045         vmrs[2]->vm_perm = 88;
1046         merge_vmr(vmrs[0], vmrs[2]);
1047         results[0].end = 0x9000;
1048         check_vmrs(p, results, 1, n++);
1049
1050         printk("Finished vm_regions test!\n");
1051 }