Massive reorganizing and making all the makefiles consistent.
[akaros.git] / kern / src / testing.c
1 #ifdef __DEPUTY__
2 #pragma nodeputy
3 #endif
4
5 #include <inc/mmu.h>
6 #include <inc/x86.h>
7 #include <inc/stdio.h>
8 #include <inc/assert.h>
9 #include <inc/string.h>
10
11 #include <kern/testing.h>
12 #include <kern/trap.h>
13 #include <kern/apic.h>
14 #include <kern/atomic.h>
15 #include <kern/smp.h>
16
17 #define test_vector 0xeb
18
19 void test_ipi_sending(void)
20 {
21         extern handler_t interrupt_handlers[];
22         int8_t state = 0;
23         
24         register_interrupt_handler(interrupt_handlers, test_vector,
25                                    test_hello_world_handler, 0);
26         enable_irqsave(&state);
27         cprintf("\nCORE 0 sending broadcast\n");
28         send_broadcast_ipi(test_vector);
29         udelay(3000000);
30         cprintf("\nCORE 0 sending all others\n");
31         send_all_others_ipi(test_vector);
32         udelay(3000000);
33         cprintf("\nCORE 0 sending self\n");
34         send_self_ipi(test_vector);
35         udelay(3000000);
36         cprintf("\nCORE 0 sending ipi to physical 1\n");
37         send_ipi(0x01, 0, test_vector);
38         udelay(3000000);
39         cprintf("\nCORE 0 sending ipi to physical 2\n");
40         send_ipi(0x02, 0, test_vector);
41         udelay(3000000);
42         cprintf("\nCORE 0 sending ipi to physical 3\n");
43         send_ipi(0x03, 0, test_vector);
44         udelay(3000000);
45         cprintf("\nCORE 0 sending ipi to physical 15\n");
46         send_ipi(0x0f, 0, test_vector);
47         udelay(3000000);
48         cprintf("\nCORE 0 sending ipi to logical 2\n");
49         send_ipi(0x02, 1, test_vector);
50         udelay(3000000);
51         cprintf("\nCORE 0 sending ipi to logical 1\n");
52         send_ipi(0x01, 1, test_vector);
53         udelay(3000000);
54         cprintf("\nDone!\n");
55         disable_irqsave(&state);
56 }
57
58 // Note this never returns and will muck with any other timer work
59 void test_pic_reception(void)
60 {
61         register_interrupt_handler(interrupt_handlers, 0x20, test_hello_world_handler, 0);
62         pit_set_timer(100,TIMER_RATEGEN); // totally arbitrary time
63         pic_unmask_irq(0);
64         cprintf("PIC1 Mask = 0x%04x\n", inb(PIC1_DATA));
65         cprintf("PIC2 Mask = 0x%04x\n", inb(PIC2_DATA));
66         unmask_lapic_lvt(LAPIC_LVT_LINT0);
67         cprintf("Core %d's LINT0: 0x%08x\n", lapic_get_id(), read_mmreg32(LAPIC_LVT_LINT0));
68         enable_irq();
69         while(1);
70 }
71
72 void test_print_info(void)
73 {
74         cprintf("\nCORE 0 asking all cores to print info:\n");
75         smp_call_function_all(test_print_info_handler, 0, 0);
76         cprintf("\nDone!\n");
77 }
78         
79
80 extern uint8_t num_cpus;
81 barrier_t test_cpu_array;
82
83 void test_barrier(void)
84 {
85         cprintf("Core 0 initializing barrier\n");
86         init_barrier(&test_cpu_array, num_cpus);
87         cprintf("Core 0 asking all cores to print ids, barrier, rinse, repeat\n");
88         smp_call_function_all(test_barrier_handler, 0, 0);
89 }
90
91 void test_interrupts_irqsave(void)
92 {
93         int8_t state = 0;
94         printd("Testing Nesting Enabling first, turning ints off:\n");
95         disable_irq();
96         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
97         assert((read_eflags() & FL_IF) == 0);
98         printd("Enabling IRQSave\n");
99         enable_irqsave(&state);
100         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
101         assert((read_eflags() & FL_IF) == 0x200);
102         printd("Enabling IRQSave Again\n");
103         enable_irqsave(&state);
104         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
105         assert((read_eflags() & FL_IF) == 0x200);
106         printd("Disabling IRQSave Once\n");
107         disable_irqsave(&state);
108         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
109         assert((read_eflags() & FL_IF) == 0x200);
110         printd("Disabling IRQSave Again\n");
111         disable_irqsave(&state);
112         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
113         assert((read_eflags() & FL_IF) == 0);
114         printd("Done.  Should have been 0, 200, 200, 200, 0\n");        
115
116         printd("Testing Nesting Disabling first, turning ints on:\n");
117         state = 0;
118         enable_irq();
119         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
120         assert((read_eflags() & FL_IF) == 0x200);
121         printd("Disabling IRQSave Once\n");
122         disable_irqsave(&state);
123         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
124         assert((read_eflags() & FL_IF) == 0);
125         printd("Disabling IRQSave Again\n");
126         disable_irqsave(&state);
127         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
128         assert((read_eflags() & FL_IF) == 0);
129         printd("Enabling IRQSave Once\n");
130         enable_irqsave(&state);
131         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
132         assert((read_eflags() & FL_IF) == 0);
133         printd("Enabling IRQSave Again\n");
134         enable_irqsave(&state);
135         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
136         assert((read_eflags() & FL_IF) == 0x200);
137         printd("Done.  Should have been 200, 0, 0, 0, 200 \n"); 
138
139         state = 0;
140         disable_irq();
141         printd("Ints are off, enabling then disabling.\n");
142         enable_irqsave(&state);
143         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
144         assert((read_eflags() & FL_IF) == 0x200);
145         disable_irqsave(&state);
146         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
147         assert((read_eflags() & FL_IF) == 0);
148         printd("Done.  Should have been 200, 0\n");     
149
150         state = 0;
151         enable_irq();
152         printd("Ints are on, enabling then disabling.\n");
153         enable_irqsave(&state);
154         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
155         assert((read_eflags() & FL_IF) == 0x200);
156         disable_irqsave(&state);
157         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
158         assert((read_eflags() & FL_IF) == 0x200);
159         printd("Done.  Should have been 200, 200\n");   
160
161         state = 0;
162         disable_irq();
163         printd("Ints are off, disabling then enabling.\n");
164         disable_irqsave(&state);
165         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
166         assert((read_eflags() & FL_IF) == 0);
167         enable_irqsave(&state);
168         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
169         assert((read_eflags() & FL_IF) == 0);
170         printd("Done.  Should have been 0, 0\n");       
171
172         state = 0;
173         enable_irq();
174         printd("Ints are on, disabling then enabling.\n");
175         disable_irqsave(&state);
176         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
177         assert((read_eflags() & FL_IF) == 0);
178         enable_irqsave(&state);
179         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
180         assert((read_eflags() & FL_IF) == 0x200);
181         printd("Done.  Should have been 0, 200\n");     
182
183         disable_irq();
184         cprintf("Passed enable_irqsave tests\n");
185 }
186
187 void test_bitmasks(void)
188 {
189 #define masksize 67
190         DECL_BITMASK(mask, masksize);
191         printk("size of mask %d\n", sizeof(mask));
192         CLR_BITMASK(mask, masksize);
193         PRINT_BITMASK(mask, masksize);
194         printk("cleared\n");
195         SET_BITMASK_BIT(mask, 0);
196         SET_BITMASK_BIT(mask, 11);
197         SET_BITMASK_BIT(mask, 17);
198         SET_BITMASK_BIT(mask, masksize-1);
199         printk("bits set\n");
200         PRINT_BITMASK(mask, masksize);
201         DECL_BITMASK(mask2, masksize);
202         COPY_BITMASK(mask2, mask, masksize);
203         printk("copy of original mask, should be the same as the prev\n");
204         PRINT_BITMASK(mask2, masksize);
205         CLR_BITMASK_BIT(mask, 11);
206         printk("11 cleared\n");
207         PRINT_BITMASK(mask, masksize);
208         printk("bit 17 is %d (should be 1)\n", GET_BITMASK_BIT(mask, 17));
209         printk("bit 11 is %d (should be 0)\n", GET_BITMASK_BIT(mask, 11));
210         FILL_BITMASK(mask, masksize);
211         PRINT_BITMASK(mask, masksize);
212         printk("should be all 1's, except for a few at the end\n");
213         printk("Is Clear?: %d (should be 0)\n", BITMASK_IS_CLEAR(mask,masksize));
214         CLR_BITMASK(mask, masksize);
215         PRINT_BITMASK(mask, masksize);
216         printk("Is Clear?: %d (should be 1)\n", BITMASK_IS_CLEAR(mask,masksize));
217         printk("should be cleared\n");
218 }
219
220 checklist_t* the_global_list;
221
222 void test_checklist_handler(trapframe_t *tf, void* data)
223 {
224         for (int i = 0; i < SMP_BOOT_TIMEOUT; i++);
225         for (int i = 0; i < SMP_BOOT_TIMEOUT; i++);
226         down_checklist(the_global_list);
227 }
228
229 extern uint8_t num_cpus;
230
231 void test_checklists(void)
232 {
233         INIT_CHECKLIST(a_list, MAX_NUM_CPUS);
234         the_global_list = &a_list;
235         printk("Checklist Build, mask size: %d\n", sizeof(a_list.mask.bits));
236         printk("mask\n");
237         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
238         SET_BITMASK_BIT(a_list.mask.bits, 11);
239         printk("Set bit 11\n");
240         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
241
242         CLR_BITMASK(a_list.mask.bits, a_list.mask.size);
243         INIT_CHECKLIST_MASK(a_mask, MAX_NUM_CPUS);
244         FILL_BITMASK(a_mask.bits, num_cpus);
245         //CLR_BITMASK_BIT(a_mask.bits, lapic_get_id());
246         //SET_BITMASK_BIT(a_mask.bits, 1);
247         //printk("New mask (1, 17, 25):\n");
248         printk("Created new mask, filled up to num_cpus\n");
249         PRINT_BITMASK(a_mask.bits, a_mask.size);
250         printk("committing new mask\n");
251         commit_checklist_wait(&a_list, &a_mask);
252         printk("Old mask (copied onto):\n");
253         PRINT_BITMASK(a_list.mask.bits, a_list.mask.size);
254         //smp_call_function_single(1, test_checklist_handler, 0, 0);    
255         smp_call_function_all(test_checklist_handler, 0, 0);    
256
257         printk("Waiting on checklist\n");
258         waiton_checklist(&a_list);      
259         printk("Done Waiting!\n");
260
261 }
262
263 uint32_t a = 0, b = 0, c = 0;
264
265 void test_incrementer_handler(struct Trapframe *tf, void* data)
266 {
267         assert(data);
268         atomic_inc((uint32_t*)data);
269 }
270
271 void test_null_handler(struct Trapframe *tf, void* data)
272 {
273         asm volatile("nop");
274 }
275
276 void test_smp_call_functions(void)
277 {
278         handler_wrapper_t *waiter0 = 0, *waiter1 = 0, *waiter2 = 0, *waiter3 = 0,
279                           *waiter4 = 0, *waiter5 = 0;
280         uint8_t me = lapic_get_id();
281         printk("\nCore %d: SMP Call Self (nowait):\n", me);
282         printk("---------------------\n");
283         smp_call_function_self(test_hello_world_handler, 0, 0);
284         printk("\nCore %d: SMP Call Self (wait):\n", me);
285         printk("---------------------\n");
286         smp_call_function_self(test_hello_world_handler, 0, &waiter0);
287         smp_call_wait(waiter0);
288         printk("\nCore %d: SMP Call All (nowait):\n", me);
289         printk("---------------------\n");
290         smp_call_function_all(test_hello_world_handler, 0, 0);
291         printk("\nCore %d: SMP Call All (wait):\n", me);
292         printk("---------------------\n");
293         smp_call_function_all(test_hello_world_handler, 0, &waiter0);
294         smp_call_wait(waiter0);
295         printk("\nCore %d: SMP Call All-Else Individually, in order (nowait):\n", me);
296         printk("---------------------\n");
297         smp_call_function_single(1, test_hello_world_handler, 0, 0);
298         smp_call_function_single(2, test_hello_world_handler, 0, 0);
299         smp_call_function_single(3, test_hello_world_handler, 0, 0);
300         smp_call_function_single(4, test_hello_world_handler, 0, 0);
301         smp_call_function_single(5, test_hello_world_handler, 0, 0);
302         smp_call_function_single(6, test_hello_world_handler, 0, 0);
303         smp_call_function_single(7, test_hello_world_handler, 0, 0);
304         printk("\nCore %d: SMP Call Self (wait):\n", me);
305         printk("---------------------\n");
306         smp_call_function_self(test_hello_world_handler, 0, &waiter0);
307         smp_call_wait(waiter0);
308         printk("\nCore %d: SMP Call All-Else Individually, in order (wait):\n", me);
309         printk("---------------------\n");
310         smp_call_function_single(1, test_hello_world_handler, 0, &waiter0);
311         smp_call_wait(waiter0);
312         smp_call_function_single(2, test_hello_world_handler, 0, &waiter0);
313         smp_call_wait(waiter0);
314         smp_call_function_single(3, test_hello_world_handler, 0, &waiter0);
315         smp_call_wait(waiter0);
316         smp_call_function_single(4, test_hello_world_handler, 0, &waiter0);
317         smp_call_wait(waiter0);
318         smp_call_function_single(5, test_hello_world_handler, 0, &waiter0);
319         smp_call_wait(waiter0);
320         smp_call_function_single(6, test_hello_world_handler, 0, &waiter0);
321         smp_call_wait(waiter0);
322         smp_call_function_single(7, test_hello_world_handler, 0, &waiter0);
323         smp_call_wait(waiter0);
324         printk("\nTesting to see if any IPI-functions are dropped when not waiting:\n");
325         printk("A: %d, B: %d, C: %d (should be 0,0,0)\n", a, b, c);
326         smp_call_function_all(test_incrementer_handler, &a, 0);
327         smp_call_function_all(test_incrementer_handler, &b, 0);
328         smp_call_function_all(test_incrementer_handler, &c, 0);
329         // if i can clobber a previous IPI, the interleaving might do it
330         smp_call_function_single(1, test_incrementer_handler, &a, 0);
331         smp_call_function_single(2, test_incrementer_handler, &b, 0);
332         smp_call_function_single(3, test_incrementer_handler, &c, 0);
333         smp_call_function_single(4, test_incrementer_handler, &a, 0);
334         smp_call_function_single(5, test_incrementer_handler, &b, 0);
335         smp_call_function_single(6, test_incrementer_handler, &c, 0);
336         smp_call_function_all(test_incrementer_handler, &a, 0);
337         smp_call_function_single(3, test_incrementer_handler, &c, 0);
338         smp_call_function_all(test_incrementer_handler, &b, 0);
339         smp_call_function_single(1, test_incrementer_handler, &a, 0);
340         smp_call_function_all(test_incrementer_handler, &c, 0);
341         smp_call_function_single(2, test_incrementer_handler, &b, 0);
342         // wait, so we're sure the others finish before printing.
343         // without this, we could (and did) get 19,18,19, since the B_inc
344         // handler didn't finish yet
345         smp_call_function_self(test_null_handler, 0, &waiter0);
346         // need to grab all 5 handlers (max), since the code moves to the next free.
347         smp_call_function_self(test_null_handler, 0, &waiter1);
348         smp_call_function_self(test_null_handler, 0, &waiter2);
349         smp_call_function_self(test_null_handler, 0, &waiter3);
350         smp_call_function_self(test_null_handler, 0, &waiter4);
351         smp_call_wait(waiter0);
352         smp_call_wait(waiter1);
353         smp_call_wait(waiter2);
354         smp_call_wait(waiter3);
355         smp_call_wait(waiter4);
356         printk("A: %d, B: %d, C: %d (should be 19,19,19)\n", a, b, c);
357         printk("Attempting to deadlock by smp_calling with an outstanding wait:\n");
358         smp_call_function_self(test_null_handler, 0, &waiter0);
359         smp_call_function_self(test_null_handler, 0, &waiter1);
360         smp_call_wait(waiter0);
361         smp_call_wait(waiter1);
362         printk("\tMade it through!\n");
363         printk("Attempting to deadlock by smp_calling more than are available:\n");
364         printk("\tShould see an Insufficient message and a kernel warning.\n");
365         if (smp_call_function_self(test_null_handler, 0, &waiter0))
366                 printk("\tInsufficient handlers to call function (0)\n");
367         if (smp_call_function_self(test_null_handler, 0, &waiter1))
368                 printk("\tInsufficient handlers to call function (1)\n");
369         if (smp_call_function_self(test_null_handler, 0, &waiter2))
370                 printk("\tInsufficient handlers to call function (2)\n");
371         if (smp_call_function_self(test_null_handler, 0, &waiter3))
372                 printk("\tInsufficient handlers to call function (3)\n");
373         if (smp_call_function_self(test_null_handler, 0, &waiter4))
374                 printk("\tInsufficient handlers to call function (4)\n");
375         if (smp_call_function_self(test_null_handler, 0, &waiter5))
376                 printk("\tInsufficient handlers to call function (5)\n");
377         smp_call_wait(waiter0);
378         smp_call_wait(waiter1);
379         smp_call_wait(waiter2);
380         smp_call_wait(waiter3);
381         smp_call_wait(waiter4);
382         smp_call_wait(waiter5);
383         printk("\tMade it through!\n");
384
385         printk("Done\n");
386 }
387
388 void test_lapic_status_bit(void)
389 {
390         register_interrupt_handler(interrupt_handlers, test_vector,
391                                    test_incrementer_handler, &a);
392         #define NUM_IPI 100000
393         a = 0;
394         printk("IPIs received (should be 0): %d\n", a);
395         for(int i = 0; i < NUM_IPI; i++) {
396                 send_ipi(7, 0, test_vector);
397                 lapic_wait_to_send();
398         }
399         // need to wait a bit to let those IPIs get there
400         udelay(5000000);
401         printk("IPIs received (should be %d): %d\n", a, NUM_IPI);
402         // hopefully that handler never fires again.  leaving it registered for now.
403 }
404
405 /* Helper Functions */
406
407 void test_hello_world_handler(trapframe_t *tf, void* data)
408 {
409         cprintf("Incoming IRQ, ISR: %d on core %d with tf at 0x%08x\n", 
410                 tf->tf_trapno, lapic_get_id(), tf);
411 }
412
413 uint32_t print_info_lock = 0;
414
415 void test_print_info_handler(trapframe_t *tf, void* data)
416 {
417         spin_lock_irqsave(&print_info_lock);
418         cprintf("----------------------------\n");
419         cprintf("This is Core %d\n", lapic_get_id());
420         cprintf("MTRR_DEF_TYPE = 0x%08x\n", read_msr(IA32_MTRR_DEF_TYPE));
421         cprintf("MTRR Phys0 Base = 0x%016llx, Mask = 0x%016llx\n",
422                 read_msr(0x200), read_msr(0x201));
423         cprintf("MTRR Phys1 Base = 0x%016llx, Mask = 0x%016llx\n",
424                 read_msr(0x202), read_msr(0x203));
425         cprintf("MTRR Phys2 Base = 0x%016llx, Mask = 0x%016llx\n",
426                 read_msr(0x204), read_msr(0x205));
427         cprintf("MTRR Phys3 Base = 0x%016llx, Mask = 0x%016llx\n",
428                 read_msr(0x206), read_msr(0x207));
429         cprintf("MTRR Phys4 Base = 0x%016llx, Mask = 0x%016llx\n",
430                 read_msr(0x208), read_msr(0x209));
431         cprintf("MTRR Phys5 Base = 0x%016llx, Mask = 0x%016llx\n",
432                 read_msr(0x20a), read_msr(0x20b));
433         cprintf("MTRR Phys6 Base = 0x%016llx, Mask = 0x%016llx\n",
434                 read_msr(0x20c), read_msr(0x20d));
435         cprintf("MTRR Phys7 Base = 0x%016llx, Mask = 0x%016llx\n",
436                 read_msr(0x20e), read_msr(0x20f));
437         cprintf("----------------------------\n");
438         spin_unlock_irqsave(&print_info_lock);
439 }
440
441 void test_barrier_handler(trapframe_t *tf, void* data)
442 {
443         cprintf("Round 1: Core %d\n", lapic_get_id());
444         waiton_barrier(&test_cpu_array);
445         waiton_barrier(&test_cpu_array);
446         waiton_barrier(&test_cpu_array);
447         waiton_barrier(&test_cpu_array);
448         waiton_barrier(&test_cpu_array);
449         waiton_barrier(&test_cpu_array);
450         cprintf("Round 2: Core %d\n", lapic_get_id());
451         waiton_barrier(&test_cpu_array);
452         cprintf("Round 3: Core %d\n", lapic_get_id());
453         // uncomment to see it fucked up
454         //cprintf("Round 4: Core %d\n", lapic_get_id());
455 }
456
457 static void test_waiting_handler(trapframe_t *tf, void* data)
458 {
459         {HANDLER_ATOMIC atomic_dec((uint32_t*)data);}
460 }
461
462 void test_pit(void)
463 {
464         cprintf("Starting test for PIT now (10s)\n");
465         udelay_pit(10000000);
466         cprintf("End now\n");
467         cprintf("Starting test for TSC (if stable) now (10s)\n");
468         udelay(10000000);
469         cprintf("End now\n");
470         
471         cprintf("Starting test for LAPIC (if stable) now (10s)\n");
472         enable_irq();
473         lapic_set_timer(10000000, FALSE);
474         
475         uint32_t waiting = 1;
476         register_interrupt_handler(interrupt_handlers, test_vector,
477                                    test_waiting_handler, &waiting);
478         while(waiting)
479                 cpu_relax();
480         cprintf("End now\n");
481 }