2f7f440ed3af3e6ba560f138167ba02c193a7c78
[akaros.git] / kern / 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 void test_ipi_sending(void)
18 {
19         extern isr_t interrupt_handlers[];
20         uint32_t i, amount = SMP_CALL_FUNCTION_TIMEOUT; // should calibrate this
21         int8_t state = 0;
22         register_interrupt_handler(interrupt_handlers, 0xf1, test_hello_world_handler);
23         enable_irqsave(&state);
24         
25         cprintf("\nCORE 0 sending broadcast\n");
26         send_broadcast_ipi(0xf1);
27         for (i = 0; i < amount; i++)
28                 asm volatile("nop;");
29         
30         cprintf("\nCORE 0 sending all others\n");
31         send_all_others_ipi(0xf1);
32         for (i = 0; i < amount; i++)
33                 asm volatile("nop;");
34         
35         cprintf("\nCORE 0 sending self\n");
36         send_self_ipi(0xf1);
37         for (i = 0; i < amount; i++)
38                 asm volatile("nop;");
39         
40         cprintf("\nCORE 0 sending ipi to physical 1\n");
41         send_ipi(0x01, 0, 0xf1);
42         for (i = 0; i < amount; i++)
43                 asm volatile("nop;");
44         
45         cprintf("\nCORE 0 sending ipi to physical 2\n");
46         send_ipi(0x02, 0, 0xf1);
47         for (i = 0; i < amount; i++)
48                 asm volatile("nop;");
49         
50         cprintf("\nCORE 0 sending ipi to physical 3\n");
51         send_ipi(0x03, 0, 0xf1);
52         for (i = 0; i < amount; i++)
53                 asm volatile("nop;");
54         
55         cprintf("\nCORE 0 sending ipi to physical 15\n");
56         send_ipi(0x0f, 0, 0xf1);
57         for (i = 0; i < amount; i++)
58                 asm volatile("nop;");
59         
60         cprintf("\nCORE 0 sending ipi to logical 2\n");
61         send_ipi(0x02, 1, 0xf1);
62         for (i = 0; i < amount; i++)
63                 asm volatile("nop;");
64         
65         cprintf("\nCORE 0 sending ipi to logical 1\n");
66         send_ipi(0x01, 1, 0xf1);
67         for (i = 0; i < amount; i++)
68                 asm volatile("nop;");
69
70         cprintf("\nDone!\n");
71         disable_irqsave(&state);
72 }
73
74 // Note this never returns and will muck with any other timer work
75 void test_pic_reception(void)
76 {
77         register_interrupt_handler(interrupt_handlers, 0x20, test_hello_world_handler);
78         pit_set_timer(1000, 1); // totally arbitrary time
79         pic_unmask_irq(0);
80         cprintf("PIC1 Mask = 0x%04x\n", inb(PIC1_DATA));
81         cprintf("PIC2 Mask = 0x%04x\n", inb(PIC2_DATA));
82         unmask_lapic_lvt(LAPIC_LVT_LINT0);
83         cprintf("Core %d's LINT0: 0x%08x\n", lapic_get_id(), read_mmreg32(LAPIC_LVT_LINT0));
84         enable_irq();
85         while(1);
86 }
87
88 void test_print_info(void)
89 {
90         cprintf("\nCORE 0 asking all cores to print info:\n");
91         smp_call_function_all(test_print_info_handler, 0);
92         cprintf("\nDone!\n");
93 }
94         
95
96 extern uint8_t num_cpus;
97 barrier_t test_cpu_array;
98
99 void test_barrier(void)
100 {
101         cprintf("Core 0 initializing barrier\n");
102         init_barrier(&test_cpu_array, num_cpus);
103         cprintf("Core 0 asking all cores to print ids, barrier, rinse, repeat\n");
104         smp_call_function_all(test_barrier_handler, 0);
105 }
106
107 void test_interrupts_irqsave(void)
108 {
109         int8_t state = 0;
110         printd("Testing Nesting Enabling first, turning ints off:\n");
111         disable_irq();
112         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
113         assert((read_eflags() & FL_IF) == 0);
114         printd("Enabling IRQSave\n");
115         enable_irqsave(&state);
116         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
117         assert((read_eflags() & FL_IF) == 0x200);
118         printd("Enabling IRQSave Again\n");
119         enable_irqsave(&state);
120         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
121         assert((read_eflags() & FL_IF) == 0x200);
122         printd("Disabling IRQSave Once\n");
123         disable_irqsave(&state);
124         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
125         assert((read_eflags() & FL_IF) == 0x200);
126         printd("Disabling IRQSave Again\n");
127         disable_irqsave(&state);
128         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
129         assert((read_eflags() & FL_IF) == 0);
130         printd("Done.  Should have been 0, 200, 200, 200, 0\n");        
131
132         printd("Testing Nesting Disabling first, turning ints on:\n");
133         state = 0;
134         enable_irq();
135         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
136         assert((read_eflags() & FL_IF) == 0x200);
137         printd("Disabling IRQSave Once\n");
138         disable_irqsave(&state);
139         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
140         assert((read_eflags() & FL_IF) == 0);
141         printd("Disabling IRQSave Again\n");
142         disable_irqsave(&state);
143         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
144         assert((read_eflags() & FL_IF) == 0);
145         printd("Enabling IRQSave Once\n");
146         enable_irqsave(&state);
147         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
148         assert((read_eflags() & FL_IF) == 0);
149         printd("Enabling IRQSave Again\n");
150         enable_irqsave(&state);
151         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
152         assert((read_eflags() & FL_IF) == 0x200);
153         printd("Done.  Should have been 200, 0, 0, 0, 200 \n"); 
154
155         state = 0;
156         disable_irq();
157         printd("Ints are off, enabling then disabling.\n");
158         enable_irqsave(&state);
159         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
160         assert((read_eflags() & FL_IF) == 0x200);
161         disable_irqsave(&state);
162         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
163         assert((read_eflags() & FL_IF) == 0);
164         printd("Done.  Should have been 200, 0\n");     
165
166         state = 0;
167         enable_irq();
168         printd("Ints are on, enabling then disabling.\n");
169         enable_irqsave(&state);
170         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
171         assert((read_eflags() & FL_IF) == 0x200);
172         disable_irqsave(&state);
173         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
174         assert((read_eflags() & FL_IF) == 0x200);
175         printd("Done.  Should have been 200, 200\n");   
176
177         state = 0;
178         disable_irq();
179         printd("Ints are off, disabling then enabling.\n");
180         disable_irqsave(&state);
181         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
182         assert((read_eflags() & FL_IF) == 0);
183         enable_irqsave(&state);
184         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
185         assert((read_eflags() & FL_IF) == 0);
186         printd("Done.  Should have been 0, 0\n");       
187
188         state = 0;
189         enable_irq();
190         printd("Ints are on, disabling then enabling.\n");
191         disable_irqsave(&state);
192         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
193         assert((read_eflags() & FL_IF) == 0);
194         enable_irqsave(&state);
195         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
196         assert((read_eflags() & FL_IF) == 0x200);
197         printd("Done.  Should have been 0, 200\n");     
198
199         disable_irq();
200         cprintf("Passed enable_irqsave tests\n");
201 }
202
203 void test_bitmasks(void)
204 {
205 #define masksize 67
206         DECL_BITMASK(mask, masksize);
207         printk("size of mask %d\n", sizeof(mask));
208         CLR_BITMASK(mask, masksize);
209         PRINT_MASK(mask, masksize);
210         printk("cleared\n");
211         SET_BITMASK_BIT(mask, 0);
212         SET_BITMASK_BIT(mask, 11);
213         SET_BITMASK_BIT(mask, 17);
214         SET_BITMASK_BIT(mask, masksize-1);
215         printk("bits set\n");
216         PRINT_MASK(mask, masksize);
217         DECL_BITMASK(mask2, masksize);
218         COPY_BITMASK(mask2, mask, masksize);
219         printk("copy of original mask, should be the same as the prev\n");
220         PRINT_MASK(mask2, masksize);
221         CLR_BITMASK_BIT(mask, 11);
222         printk("11 cleared\n");
223         PRINT_MASK(mask, masksize);
224         printk("bit 17 is %d (should be 1)\n", GET_BITMASK_BIT(mask, 17));
225         printk("bit 11 is %d (should be 0)\n", GET_BITMASK_BIT(mask, 11));
226         FILL_BITMASK(mask, masksize);
227         PRINT_MASK(mask, masksize);
228         printk("should be all 1's, except for a few at the end\n");
229         printk("Is Clear?: %d (should be 0)\n", BITMASK_IS_CLEAR(mask,masksize));
230         CLR_BITMASK(mask, masksize);
231         PRINT_MASK(mask, masksize);
232         printk("Is Clear?: %d (should be 1)\n", BITMASK_IS_CLEAR(mask,masksize));
233         printk("should be cleared\n");
234 }
235
236 checklist_t* the_global_list;
237
238 void test_checklist_handler(trapframe_t *tf)
239 {
240         for (int i = 0; i < SMP_BOOT_TIMEOUT; i++);
241         for (int i = 0; i < SMP_BOOT_TIMEOUT; i++);
242         down_checklist(the_global_list);
243 }
244
245 extern uint8_t num_cpus;
246
247 void test_checklists(void)
248 {
249         INIT_CHECKLIST(a_list, MAX_NUM_CPUS);
250         the_global_list = &a_list;
251         printk("Checklist built, mask\n");
252         PRINT_MASK(a_list.mask.bits, a_list.mask.size);
253         SET_BITMASK_BIT(a_list.mask.bits, 11);
254         printk("Set bit 11\n");
255         PRINT_MASK(a_list.mask.bits, a_list.mask.size);
256
257         CLR_BITMASK(a_list.mask.bits, a_list.mask.size);
258         INIT_CHECKLIST_MASK(a_mask, MAX_NUM_CPUS);
259         FILL_BITMASK(a_mask.bits, num_cpus);
260         //CLR_BITMASK_BIT(a_mask.bits, lapic_get_id());
261         //SET_BITMASK_BIT(a_mask.bits, 1);
262         //printk("New mask (1, 17, 25):\n");
263         PRINT_MASK(a_mask.bits, a_mask.size);
264         printk("committing new mask\n");
265         commit_checklist_wait(&a_list, &a_mask);
266         printk("Old mask (copied onto) (1, 17, 25):\n");
267         PRINT_MASK(a_list.mask.bits, a_list.mask.size);
268         //smp_call_function_single(1, test_checklist_handler, 0);       
269         smp_call_function_all(test_checklist_handler, 0);       
270
271         printk("Waiting on checklist\n");
272         waiton_checklist(&a_list);      
273         printk("Done Waiting!\n");
274
275 }
276
277 /* Helper Functions */
278
279 void test_hello_world_handler(trapframe_t *tf)
280 {
281         cprintf("Incoming IRQ, ISR: %d on core %d with tf at 0x%08x\n", 
282                 tf->tf_trapno, lapic_get_id(), tf);
283 }
284
285 uint32_t print_info_lock = 0;
286
287 void test_print_info_handler(trapframe_t *tf)
288 {
289         spin_lock_irqsave(&print_info_lock);
290         cprintf("----------------------------\n");
291         cprintf("This is Core %d\n", lapic_get_id());
292         cprintf("MTRR_DEF_TYPE = 0x%08x\n", read_msr(IA32_MTRR_DEF_TYPE));
293         cprintf("MTRR Phys0 Base = 0x%016llx, Mask = 0x%016llx\n",
294                 read_msr(0x200), read_msr(0x201));
295         cprintf("MTRR Phys1 Base = 0x%016llx, Mask = 0x%016llx\n",
296                 read_msr(0x202), read_msr(0x203));
297         cprintf("MTRR Phys2 Base = 0x%016llx, Mask = 0x%016llx\n",
298                 read_msr(0x204), read_msr(0x205));
299         cprintf("MTRR Phys3 Base = 0x%016llx, Mask = 0x%016llx\n",
300                 read_msr(0x206), read_msr(0x207));
301         cprintf("MTRR Phys4 Base = 0x%016llx, Mask = 0x%016llx\n",
302                 read_msr(0x208), read_msr(0x209));
303         cprintf("MTRR Phys5 Base = 0x%016llx, Mask = 0x%016llx\n",
304                 read_msr(0x20a), read_msr(0x20b));
305         cprintf("MTRR Phys6 Base = 0x%016llx, Mask = 0x%016llx\n",
306                 read_msr(0x20c), read_msr(0x20d));
307         cprintf("MTRR Phys7 Base = 0x%016llx, Mask = 0x%016llx\n",
308                 read_msr(0x20e), read_msr(0x20f));
309         cprintf("----------------------------\n");
310         spin_unlock_irqsave(&print_info_lock);
311 }
312
313 void test_barrier_handler(trapframe_t *tf)
314 {
315         cprintf("Round 1: Core %d\n", lapic_get_id());
316         waiton_barrier(&test_cpu_array);
317         waiton_barrier(&test_cpu_array);
318         waiton_barrier(&test_cpu_array);
319         waiton_barrier(&test_cpu_array);
320         waiton_barrier(&test_cpu_array);
321         waiton_barrier(&test_cpu_array);
322         cprintf("Round 2: Core %d\n", lapic_get_id());
323         waiton_barrier(&test_cpu_array);
324         cprintf("Round 3: Core %d\n", lapic_get_id());
325         // uncomment to see it fucked up
326         //cprintf("Round 4: Core %d\n", lapic_get_id());
327 }