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