smp_call wait / backend work
[akaros.git] / kern / smp.c
1 #ifdef __DEPUTY__
2 #pragma nodeputy
3 #endif
4
5 #include <inc/stdio.h>
6 #include <inc/string.h>
7 #include <inc/assert.h>
8 #include <inc/x86.h>
9
10 #include <kern/smp.h>
11 #include <kern/console.h>
12 #include <kern/pmap.h>
13 #include <kern/env.h>
14 #include <kern/apic.h>
15 #include <kern/atomic.h>
16
17 volatile uint8_t num_cpus = 0xee;
18 uintptr_t smp_stack_top;
19 barrier_t generic_barrier;
20
21 /*************************** IPI Wrapper Stuff ********************************/
22 // checklists to protect the global interrupt_handlers for 0xf0, f1, f2, f3, f4
23 // need to be global, since there is no function that will always exist for them
24 handler_wrapper_t             handler_wrappers[NUM_HANDLER_WRAPPERS];
25
26 #define DECLARE_HANDLER_CHECKLISTS(vector)                          \
27         INIT_CHECKLIST(f##vector##_front_cpu_list, MAX_NUM_CPUS);   \
28         INIT_CHECKLIST(f##vector##_back_cpu_list, MAX_NUM_CPUS);
29
30 #define INIT_HANDLER_WRAPPER(v)                                               \
31 {                                                                         \
32         handler_wrappers[(v)].vector = 0xf##v;                                    \
33         handler_wrappers[(v)].front_cpu_list = &f##v##_front_cpu_list;            \
34         handler_wrappers[(v)].front_cpu_list->mask.size = num_cpus;               \
35         handler_wrappers[(v)].back_cpu_list = &f##v##_back_cpu_list;              \
36         handler_wrappers[(v)].back_cpu_list->mask.size = num_cpus;                \
37 }
38
39 DECLARE_HANDLER_CHECKLISTS(0);
40 DECLARE_HANDLER_CHECKLISTS(1);
41 DECLARE_HANDLER_CHECKLISTS(2);
42 DECLARE_HANDLER_CHECKLISTS(3);
43 DECLARE_HANDLER_CHECKLISTS(4);
44
45 static void init_smp_call_function(void)
46 {
47         INIT_HANDLER_WRAPPER(0);
48         INIT_HANDLER_WRAPPER(1);
49         INIT_HANDLER_WRAPPER(2);
50         INIT_HANDLER_WRAPPER(3);
51         INIT_HANDLER_WRAPPER(4);
52 }
53
54 /******************************************************************************/
55
56 static void smp_mtrr_handler(trapframe_t *tf)
57 {
58         setup_default_mtrrs(&generic_barrier);
59 }
60
61 void smp_boot(void)
62 {
63         #define boot_vector 0xeb
64         // this needs to be set in smp_entry too...
65         #define trampoline_pg 0x00001000
66         page_t *smp_stack;
67         extern isr_t interrupt_handlers[];
68         // NEED TO GRAB A LOWMEM FREE PAGE FOR AP BOOTUP CODE
69         // page1 (2nd page) is reserved, hardcoded in pmap.c
70         extern smp_entry(), smp_entry_end(), smp_boot_lock(), smp_semaphore();
71         memset(KADDR(trampoline_pg), 0, PGSIZE);
72         memcpy(KADDR(trampoline_pg), &smp_entry, &smp_entry_end - &smp_entry);
73
74         // This mapping allows access to the trampoline with paging on and off
75         // via trampoline_pg
76         page_insert(boot_pgdir, pa2page(trampoline_pg), (void*)trampoline_pg, PTE_W);
77
78         // Allocate a stack for the cores starting up.  One for all, must share
79         if (page_alloc(&smp_stack))
80                 panic("No memory for SMP boot stack!");
81         smp_stack_top = (uintptr_t)(page2kva(smp_stack) + PGSIZE);
82
83         // Start the IPI process (INIT, wait, SIPI, wait, SIPI, wait)
84         send_init_ipi();
85         // SDM 3A is a little wonky wrt the proper delays.  These are my best guess.
86         udelay(10000);
87         // first SIPI
88         send_startup_ipi(0x01);
89         /* BOCHS does not like this second SIPI.
90         // second SIPI
91         udelay(200);
92         send_startup_ipi(0x01);
93         */
94         udelay(100000);
95
96         // Each core will also increment smp_semaphore, and decrement when it is done,
97         // all in smp_entry.  It's purpose is to keep Core0 from competing for the
98         // smp_boot_lock.  So long as one AP increments the sem before the final
99         // LAPIC timer goes off, all available cores will be initialized.
100         while(*(volatile uint32_t*)(&smp_semaphore - &smp_entry + trampoline_pg));
101
102         // From here on, no other cores are coming up.  Grab the lock to ensure it.
103         // Another core could be in it's prelock phase and be trying to grab the lock
104         // forever....
105         // The lock exists on the trampoline, so it can be grabbed right away in
106         // real mode.  If core0 wins the race and blocks other CPUs from coming up
107         // it can crash the machine if the other cores are allowed to proceed with
108         // booting.  Specifically, it's when they turn on paging and have that temp
109         // mapping pulled out from under them.  Now, if a core loses, it will spin
110         // on the trampoline (which we must be careful to not deallocate)
111         spin_lock((uint32_t*)(&smp_boot_lock - &smp_entry + trampoline_pg));
112         cprintf("Num_Cpus Detected: %d\n", num_cpus);
113
114         // Deregister smp_boot_handler
115         register_interrupt_handler(interrupt_handlers, boot_vector, 0);
116         // Remove the mapping of the page used by the trampoline
117         page_remove(boot_pgdir, (void*)trampoline_pg);
118         // It had a refcount of 2 earlier, so we need to dec once more to free it
119         // but only if all cores are in (or we reset / reinit those that failed)
120         // TODO after we parse ACPI tables
121         if (num_cpus == 8) // TODO - ghetto coded for our 8 way SMPs
122                 page_decref(pa2page(trampoline_pg));
123         // Dealloc the temp shared stack
124         page_decref(smp_stack);
125
126         // Set up the generic remote function call facility
127         init_smp_call_function();
128
129         // Set up all cores to use the proper MTRRs
130         init_barrier(&generic_barrier, num_cpus); // barrier used by smp_mtrr_handler
131         smp_call_function_all(smp_mtrr_handler, 0);
132
133         // Should probably flush everyone's TLB at this point, to get rid of
134         // temp mappings that were removed.  TODO
135 }
136
137 /*
138  * This is called from smp_entry by each core to finish the core bootstrapping.
139  * There is a spinlock around this entire function in smp_entry, for a few reasons,
140  * the most important being that all cores use the same stack when entering here.
141  */
142 uint32_t smp_main(void)
143 {
144         /*
145         // Print some diagnostics.  Uncomment if there're issues.
146         cprintf("Good morning Vietnam!\n");
147         cprintf("This core's Default APIC ID: 0x%08x\n", lapic_get_default_id());
148         cprintf("This core's Current APIC ID: 0x%08x\n", lapic_get_id());
149         if (read_msr(IA32_APIC_BASE) & 0x00000100)
150                 cprintf("I am the Boot Strap Processor\n");
151         else
152                 cprintf("I am an Application Processor\n");
153         cprintf("Num_Cpus: %d\n\n", num_cpus);
154         */
155
156         // Get a per-core kernel stack
157         page_t *my_stack;
158         if (page_alloc(&my_stack))
159                 panic("Unable to alloc a per-core stack!");
160         memset(page2kva(my_stack), 0, PGSIZE);
161
162         // Set up a gdt / gdt_pd for this core, stored at the top of the stack
163         // This is necessary, eagle-eyed readers know why
164         // GDT should be 4-byte aligned.  TS isn't aligned.  Not sure if it matters.
165         pseudodesc_t *my_gdt_pd = page2kva(my_stack) + PGSIZE -
166                 sizeof(pseudodesc_t) - sizeof(segdesc_t)*SEG_COUNT;
167         segdesc_t *my_gdt = page2kva(my_stack) + PGSIZE -
168                 sizeof(segdesc_t)*SEG_COUNT;
169         // TS also needs to be permanent
170         taskstate_t *my_ts = page2kva(my_stack) + PGSIZE -
171                 sizeof(pseudodesc_t) - sizeof(segdesc_t)*SEG_COUNT -
172                 sizeof(taskstate_t);
173         // Usable portion of the KSTACK grows down from here
174         // Won't actually start using this stack til our first interrupt
175         // (issues with changing the stack pointer and then trying to "return")
176         uintptr_t my_stack_top = (uintptr_t)my_ts;
177
178         // Build and load the gdt / gdt_pd
179         memcpy(my_gdt, gdt, sizeof(segdesc_t)*SEG_COUNT);
180         *my_gdt_pd = (pseudodesc_t) {
181                 sizeof(segdesc_t)*SEG_COUNT - 1, (uintptr_t) my_gdt };
182         asm volatile("lgdt %0" : : "m"(*my_gdt_pd));
183
184         // Need to set the TSS so we know where to trap on this core
185         my_ts->ts_esp0 = my_stack_top;
186         my_ts->ts_ss0 = GD_KD;
187         // Initialize the TSS field of my_gdt.
188         my_gdt[GD_TSS >> 3] = SEG16(STS_T32A, (uint32_t) (my_ts), sizeof(taskstate_t), 0);
189         my_gdt[GD_TSS >> 3].sd_s = 0;
190         // Load the TSS
191         ltr(GD_TSS);
192
193         // Loads the same IDT used by the other cores
194         asm volatile("lidt idt_pd");
195
196         // APIC setup
197         // set LINT0 to receive ExtINTs (KVM's default).  At reset they are 0x1000.
198         write_mmreg32(LAPIC_LVT_LINT0, 0x700);
199         // mask it to shut it up for now.  Doesn't seem to matter yet, since both
200         // KVM and Bochs seem to only route the PIC to core0.
201         mask_lapic_lvt(LAPIC_LVT_LINT0);
202         // and then turn it on
203         lapic_enable();
204
205         // set a default logical id for now
206         lapic_set_logid(lapic_get_id());
207
208         return my_stack_top; // will be loaded in smp_entry.S
209 }
210
211 // this idles a core, sometimes we need to call it directly.  never returns.
212 // the pause is somewhat of a hack, since kvm isn't halting.  not sure what the
213 // deal is wit that.
214 void smp_idle(void)
215 {
216         asm volatile("1: hlt; pause; jmp 1b;");
217 }
218
219 static int smp_call_function(uint8_t type, uint8_t dest, isr_t handler, 
220                               handler_wrapper_t** wait_wrapper)
221 {
222         extern isr_t interrupt_handlers[];
223         int8_t state = 0;
224         uint32_t vector;
225         handler_wrapper_t* wrapper;
226
227         // assumes our cores are numbered in order
228         if ((type == 4) && (dest >= num_cpus))
229                 panic("Destination CPU does not exist!");
230
231         // build the mask based on the type and destination
232         INIT_CHECKLIST_MASK(cpu_mask, MAX_NUM_CPUS);
233         // set checklist mask's size dynamically to the num cpus actually present
234         cpu_mask.size = num_cpus;
235         switch (type) {
236                 case 1: // self
237                         SET_BITMASK_BIT(cpu_mask.bits, lapic_get_id());
238                         break;
239                 case 2: // all
240                         FILL_BITMASK(cpu_mask.bits, num_cpus);
241                         break;
242                 case 3: // all but self
243                         FILL_BITMASK(cpu_mask.bits, num_cpus);
244                         CLR_BITMASK_BIT(cpu_mask.bits, lapic_get_id());
245                         break;
246                 case 4: // physical mode
247                         // note this only supports sending to one specific physical id
248                         // (only sets one bit, so if multiple cores have the same phys id
249                         // the first one through will set this).
250                         SET_BITMASK_BIT(cpu_mask.bits, dest);
251                         break;
252                 case 5: // logical mode
253                         // TODO
254                         warn("Logical mode bitmask handler protection not implemented!");
255                         break;
256                 default:
257                         panic("Invalid type for cross-core function call!");
258         }
259
260         // Find an available vector.  Starts with this core's vector (mod the
261         // number of wrappers).  Walk through on conflict
262         // Commit returns an error if it wanted to give up for some reason,
263         // like taking too long to acquire the lock or clear the mask, at which
264         // point, we try the next one.
265         // When we are done, wrapper points to the one we finally got.
266         // Note we need to make sure the backend is unused too, even if we don't
267         // want to wait.  Don't want our backend responses clobbering another
268         // waiters results.  Even if we don't plan on waiting, we need to make sure
269         // the list is done, so that old results don't trick future viewers into
270         // thinking the list is clear.  The main idea is that if a backend is
271         // unlocked, then no one is waiting on it.  If it is clear, then all
272         // previous callees have *finished* the entire handler function.  We don't
273         // want a weird sequence of events to be able to bypass that.
274         vector = lapic_get_id() % NUM_HANDLER_WRAPPERS;
275         while(1) {
276                 wrapper = &handler_wrappers[vector];
277                 if (!commit_checklist_nowait(wrapper->front_cpu_list, &cpu_mask)) {
278                         // if the backend is free (not locked and clear), then we can break.
279                         if ((!checklist_is_locked(wrapper->back_cpu_list)) && 
280                            (checklist_is_clear(wrapper->back_cpu_list)))
281                                 break;
282                         else
283                                 reset_checklist(wrapper->front_cpu_list);       
284                 }
285                 vector = (vector + 1) % NUM_HANDLER_WRAPPERS;
286         }
287
288         // Wanting to wait is expressed by having a non-NULL handler_wrapper_t**
289         // passed in.
290         // Should be no contention here, since this one is protected by the mask
291         // being present in the frontend.  the only way someone would try to commit
292         // on this would be if it holds the front.
293         // Set this mask regardless if we want to wait or not.  the recipients will
294         // all down it anyway, and it protects any future users of this handler from
295         // waiting on a backend that is actually in use.  Note that above we did not
296         // allow the use of a wrapper if the backend still isn't clear - even if we
297         // won the front end.
298         if (wait_wrapper) {
299                 commit_checklist_wait(wrapper->back_cpu_list, &cpu_mask);
300                 // pass out our reference to wrapper, so waiting can be done later.
301                 *wait_wrapper = wrapper;
302         } else
303                 commit_checklist_nowait(wrapper->back_cpu_list, &cpu_mask);
304
305         // now register our handler to run
306         register_interrupt_handler(interrupt_handlers, wrapper->vector, handler);
307         // WRITE MEMORY BARRIER HERE
308         enable_irqsave(&state);
309         // Send the proper type of IPI.  I made up these numbers.
310         switch (type) {
311                 case 1:
312                         send_self_ipi(wrapper->vector);
313                         break;
314                 case 2:
315                         send_broadcast_ipi(wrapper->vector);
316                         break;
317                 case 3:
318                         send_all_others_ipi(wrapper->vector);
319                         break;
320                 case 4: // physical mode
321                         send_ipi(dest, 0, wrapper->vector);
322                         break;
323                 case 5: // logical mode
324                         send_ipi(dest, 1, wrapper->vector);
325                         break;
326                 default:
327                         panic("Invalid type for cross-core function call!");
328         }
329         // wait long enough to receive our own broadcast (PROBABLY WORKS) TODO
330         lapic_wait_to_send();
331         disable_irqsave(&state);
332         return 0;
333 }
334
335 // I'd rather have these functions take an arbitrary function and arguments...
336 // Right now, I build a handler that just calls whatever I want, which is
337 // another layer of indirection.
338 int smp_call_function_self(isr_t handler, handler_wrapper_t** wait_wrapper)
339 {
340         return smp_call_function(1, 0, handler, wait_wrapper);
341 }
342
343 int smp_call_function_all(isr_t handler, handler_wrapper_t** wait_wrapper)
344 {
345         return smp_call_function(2, 0, handler, wait_wrapper);
346 }
347
348 int smp_call_function_single(uint8_t dest, isr_t handler,
349                              handler_wrapper_t** wait_wrapper)
350 {
351         return smp_call_function(4, dest, handler, wait_wrapper);
352 }
353
354 // If you want to wait, pass the address of a pointer up above, then call
355 // this to do the actual waiting
356 int smp_call_wait(handler_wrapper_t* wrapper)
357 {
358         waiton_checklist(wrapper->back_cpu_list);
359         return 0;
360 }
361