Added bitmask macros
[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 = 0x7ffffff0; // 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 barrier_t test_cpu_array;
97
98 void test_barrier(void)
99 {
100         cprintf("Core 0 initializing barrier\n");
101         init_barrier_all(&test_cpu_array);
102         cprintf("Core 0 asking all cores to print ids, barrier, rinse, repeat\n");
103         smp_call_function_all(test_barrier_handler, 0);
104 }
105
106 void test_interrupts_irqsave(void)
107 {
108         int8_t state = 0;
109         printd("Testing Nesting Enabling first, turning ints off:\n");
110         disable_irq();
111         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
112         assert((read_eflags() & FL_IF) == 0);
113         printd("Enabling IRQSave\n");
114         enable_irqsave(&state);
115         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
116         assert((read_eflags() & FL_IF) == 0x200);
117         printd("Enabling IRQSave Again\n");
118         enable_irqsave(&state);
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) == 0x200);
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("Done.  Should have been 0, 200, 200, 200, 0\n");        
130
131         printd("Testing Nesting Disabling first, turning ints on:\n");
132         state = 0;
133         enable_irq();
134         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
135         assert((read_eflags() & FL_IF) == 0x200);
136         printd("Disabling IRQSave Once\n");
137         disable_irqsave(&state);
138         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
139         assert((read_eflags() & FL_IF) == 0);
140         printd("Disabling IRQSave Again\n");
141         disable_irqsave(&state);
142         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
143         assert((read_eflags() & FL_IF) == 0);
144         printd("Enabling IRQSave Once\n");
145         enable_irqsave(&state);
146         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
147         assert((read_eflags() & FL_IF) == 0);
148         printd("Enabling IRQSave Again\n");
149         enable_irqsave(&state);
150         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
151         assert((read_eflags() & FL_IF) == 0x200);
152         printd("Done.  Should have been 200, 0, 0, 0, 200 \n"); 
153
154         state = 0;
155         disable_irq();
156         printd("Ints are off, enabling then disabling.\n");
157         enable_irqsave(&state);
158         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
159         assert((read_eflags() & FL_IF) == 0x200);
160         disable_irqsave(&state);
161         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
162         assert((read_eflags() & FL_IF) == 0);
163         printd("Done.  Should have been 200, 0\n");     
164
165         state = 0;
166         enable_irq();
167         printd("Ints are on, enabling then disabling.\n");
168         enable_irqsave(&state);
169         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
170         assert((read_eflags() & FL_IF) == 0x200);
171         disable_irqsave(&state);
172         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
173         assert((read_eflags() & FL_IF) == 0x200);
174         printd("Done.  Should have been 200, 200\n");   
175
176         state = 0;
177         disable_irq();
178         printd("Ints are off, disabling then enabling.\n");
179         disable_irqsave(&state);
180         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
181         assert((read_eflags() & FL_IF) == 0);
182         enable_irqsave(&state);
183         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
184         assert((read_eflags() & FL_IF) == 0);
185         printd("Done.  Should have been 0, 0\n");       
186
187         state = 0;
188         enable_irq();
189         printd("Ints are on, disabling then enabling.\n");
190         disable_irqsave(&state);
191         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
192         assert((read_eflags() & FL_IF) == 0);
193         enable_irqsave(&state);
194         printd("Interrupts are: %x\n", read_eflags() & FL_IF);
195         assert((read_eflags() & FL_IF) == 0x200);
196         printd("Done.  Should have been 0, 200\n");     
197
198         disable_irq();
199         cprintf("Passed enable_irqsave tests\n");
200 }
201
202 void test_bitmasks(void)
203 {
204 #define print_mask() { \
205         for (int i = 0; i < BYTES_FOR_BITMASK(258); i++) \
206                 for (int j = 0; j < 8; j++) \
207                         printk("%x", (mask[i] >> j) & 1); \
208         printk("\n"); \
209
210
211         DECL_BITMASK(mask, 258);
212         printk("size of mask %d\n", sizeof(mask));
213         CLR_BITMASK(mask, 258);
214         print_mask();
215         printk("cleared\n");
216         SET_BITMASK_BIT(mask, 0);
217         SET_BITMASK_BIT(mask, 11);
218         SET_BITMASK_BIT(mask, 17);
219         SET_BITMASK_BIT(mask, 257);
220         printk("bits set\n");
221         print_mask();
222         CLR_BITMASK_BIT(mask, 11);
223         printk("11 cleared\n");
224         print_mask();
225         printk("bit 17 is %d (should be 1)\n", GET_BITMASK_BIT(mask, 17));
226         printk("bit 11 is %d (should be 0)\n", GET_BITMASK_BIT(mask, 11));
227         CLR_BITMASK(mask, 258);
228         print_mask();
229         printk("should be cleared\n");
230 }
231
232 /* Helper Functions */
233
234 void test_hello_world_handler(struct Trapframe *tf)
235 {
236         cprintf("Incoming IRQ, ISR: %d on core %d with tf at 0x%08x\n", 
237                 tf->tf_trapno, lapic_get_id(), tf);
238 }
239
240 uint32_t print_info_lock = 0;
241
242 void test_print_info_handler(struct Trapframe *tf)
243 {
244         spin_lock_irqsave(&print_info_lock);
245         cprintf("----------------------------\n");
246         cprintf("This is Core %d\n", lapic_get_id());
247         cprintf("MTRR_DEF_TYPE = 0x%08x\n", read_msr(IA32_MTRR_DEF_TYPE));
248         cprintf("MTRR Phys0 Base = 0x%016llx, Mask = 0x%016llx\n",
249                 read_msr(0x200), read_msr(0x201));
250         cprintf("MTRR Phys1 Base = 0x%016llx, Mask = 0x%016llx\n",
251                 read_msr(0x202), read_msr(0x203));
252         cprintf("MTRR Phys2 Base = 0x%016llx, Mask = 0x%016llx\n",
253                 read_msr(0x204), read_msr(0x205));
254         cprintf("MTRR Phys3 Base = 0x%016llx, Mask = 0x%016llx\n",
255                 read_msr(0x206), read_msr(0x207));
256         cprintf("MTRR Phys4 Base = 0x%016llx, Mask = 0x%016llx\n",
257                 read_msr(0x208), read_msr(0x209));
258         cprintf("MTRR Phys5 Base = 0x%016llx, Mask = 0x%016llx\n",
259                 read_msr(0x20a), read_msr(0x20b));
260         cprintf("MTRR Phys6 Base = 0x%016llx, Mask = 0x%016llx\n",
261                 read_msr(0x20c), read_msr(0x20d));
262         cprintf("MTRR Phys7 Base = 0x%016llx, Mask = 0x%016llx\n",
263                 read_msr(0x20e), read_msr(0x20f));
264         cprintf("----------------------------\n");
265         spin_unlock_irqsave(&print_info_lock);
266 }
267
268 void test_barrier_handler(struct Trapframe *tf)
269 {
270         cprintf("Round 1: Core %d\n", lapic_get_id());
271         barrier_all(&test_cpu_array);
272         barrier_all(&test_cpu_array);
273         barrier_all(&test_cpu_array);
274         barrier_all(&test_cpu_array);
275         barrier_all(&test_cpu_array);
276         barrier_all(&test_cpu_array);
277         cprintf("Round 2: Core %d\n", lapic_get_id());
278         barrier_all(&test_cpu_array);
279         cprintf("Round 3: Core %d\n", lapic_get_id());
280         // uncomment to see it fucked up
281         //cprintf("Round 4: Core %d\n", lapic_get_id());
282 }