|
@@ -72,35 +72,29 @@ void __init smp_cpus_done(unsigned int max_cpus)
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * After power-up, a non Master CPU needs to wait for Master to kick start it
|
|
|
- *
|
|
|
- * The default implementation halts
|
|
|
- *
|
|
|
- * This relies on platform specific support allowing Master to directly set
|
|
|
- * this CPU's PC (to be @first_lines_of_secondary() and kick start it.
|
|
|
- *
|
|
|
- * In lack of such h/w assist, platforms can override this function
|
|
|
- * - make this function busy-spin on a token, eventually set by Master
|
|
|
- * (from arc_platform_smp_wakeup_cpu())
|
|
|
- * - Once token is available, jump to @first_lines_of_secondary
|
|
|
- * (using inline asm).
|
|
|
- *
|
|
|
- * Alert: can NOT use stack here as it has not been determined/setup for CPU.
|
|
|
- * If it turns out to be elaborate, it's better to code it in assembly
|
|
|
- *
|
|
|
+ * Default smp boot helper for Run-on-reset case where all cores start off
|
|
|
+ * together. Non-masters need to wait for Master to start running.
|
|
|
+ * This is implemented using a flag in memory, which Non-masters spin-wait on.
|
|
|
+ * Master sets it to cpu-id of core to "ungate" it.
|
|
|
*/
|
|
|
-void __weak arc_platform_smp_wait_to_boot(int cpu)
|
|
|
+static volatile int wake_flag;
|
|
|
+
|
|
|
+static void arc_default_smp_cpu_kick(int cpu, unsigned long pc)
|
|
|
{
|
|
|
- /*
|
|
|
- * As a hack for debugging - since debugger will single-step over the
|
|
|
- * FLAG insn - wrap the halt itself it in a self loop
|
|
|
- */
|
|
|
- __asm__ __volatile__(
|
|
|
- "1: \n"
|
|
|
- " flag 1 \n"
|
|
|
- " b 1b \n");
|
|
|
+ BUG_ON(cpu == 0);
|
|
|
+ wake_flag = cpu;
|
|
|
+}
|
|
|
+
|
|
|
+void arc_platform_smp_wait_to_boot(int cpu)
|
|
|
+{
|
|
|
+ while (wake_flag != cpu)
|
|
|
+ ;
|
|
|
+
|
|
|
+ wake_flag = 0;
|
|
|
+ __asm__ __volatile__("j @first_lines_of_secondary \n");
|
|
|
}
|
|
|
|
|
|
+
|
|
|
const char *arc_platform_smp_cpuinfo(void)
|
|
|
{
|
|
|
return plat_smp_ops.info ? : "";
|
|
@@ -161,6 +155,8 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
|
|
|
if (plat_smp_ops.cpu_kick)
|
|
|
plat_smp_ops.cpu_kick(cpu,
|
|
|
(unsigned long)first_lines_of_secondary);
|
|
|
+ else
|
|
|
+ arc_default_smp_cpu_kick(cpu, (unsigned long)NULL);
|
|
|
|
|
|
/* wait for 1 sec after kicking the secondary */
|
|
|
wait_till = jiffies + HZ;
|