1 /* 2 * Secondary cpu support 3 * 4 * Copyright (C) 2015, Red Hat Inc, Andrew Jones <drjones@redhat.com> 5 * 6 * This work is licensed under the terms of the GNU LGPL, version 2. 7 */ 8 #include <libcflat.h> 9 #include <asm/thread_info.h> 10 #include <asm/cpumask.h> 11 #include <asm/barrier.h> 12 #include <asm/mmu.h> 13 #include <asm/psci.h> 14 #include <asm/smp.h> 15 16 cpumask_t cpu_present_mask; 17 cpumask_t cpu_online_mask; 18 struct secondary_data secondary_data; 19 20 secondary_entry_fn secondary_cinit(void) 21 { 22 struct thread_info *ti = current_thread_info(); 23 secondary_entry_fn entry; 24 25 thread_info_init(ti, 0); 26 mmu_mark_enabled(ti->cpu); 27 28 /* 29 * Save secondary_data.entry locally to avoid opening a race 30 * window between marking ourselves online and calling it. 31 */ 32 entry = secondary_data.entry; 33 set_cpu_online(ti->cpu, true); 34 sev(); 35 36 /* 37 * Return to the assembly stub, allowing entry to be called 38 * from there with an empty stack. 39 */ 40 return entry; 41 } 42 43 void smp_boot_secondary(int cpu, secondary_entry_fn entry) 44 { 45 int ret; 46 47 secondary_data.stack = thread_stack_alloc(); 48 secondary_data.entry = entry; 49 mmu_mark_disabled(cpu); 50 ret = cpu_psci_cpu_boot(cpu); 51 assert(ret == 0); 52 53 while (!cpu_online(cpu)) 54 wfe(); 55 } 56