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