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 <alloc.h> 10 #include <asm/thread_info.h> 11 #include <asm/cpumask.h> 12 #include <asm/barrier.h> 13 #include <asm/mmu.h> 14 #include <asm/psci.h> 15 #include <asm/smp.h> 16 17 cpumask_t cpu_present_mask; 18 cpumask_t cpu_online_mask; 19 struct secondary_data secondary_data; 20 21 secondary_entry_fn secondary_cinit(void) 22 { 23 struct thread_info *ti = current_thread_info(); 24 secondary_entry_fn entry; 25 26 thread_info_init(ti, 0); 27 mmu_mark_enabled(ti->cpu); 28 29 /* 30 * Save secondary_data.entry locally to avoid opening a race 31 * window between marking ourselves online and calling it. 32 */ 33 entry = secondary_data.entry; 34 set_cpu_online(ti->cpu, true); 35 sev(); 36 37 /* 38 * Return to the assembly stub, allowing entry to be called 39 * from there with an empty stack. 40 */ 41 return entry; 42 } 43 44 void smp_boot_secondary(int cpu, secondary_entry_fn entry) 45 { 46 void *stack_base = memalign(THREAD_SIZE, THREAD_SIZE); 47 int ret; 48 49 secondary_data.stack = stack_base + THREAD_START_SP; 50 secondary_data.entry = entry; 51 mmu_mark_disabled(cpu); 52 ret = cpu_psci_cpu_boot(cpu); 53 assert(ret == 0); 54 55 while (!cpu_online(cpu)) 56 wfe(); 57 } 58