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