void __cpuinit platform_secondary_init(unsigned int cpu) { /* Enable the full line of zero */ if (soc_is_exynos4210() || soc_is_exynos4212() || soc_is_exynos4412() || soc_is_exynos4415()) enable_cache_foz(); /* * if any interrupts are already enabled for the primary * core (e.g. timer irq), then they will not have been enabled * for us: do so */ gic_secondary_init(0); /* * let the primary processor know we're out of the * pen, then head off into the C entry point */ write_pen_release(-1); #ifdef CONFIG_ARM_TRUSTZONE clear_boot_flag(cpu, HOTPLUG); #endif /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); spin_unlock(&boot_lock); }
void __cpuinit mt_smp_secondary_init(unsigned int cpu) { #if 0 struct wd_api *wd_api = NULL; //fix build error get_wd_api(&wd_api); if (wd_api) wd_api->wd_cpu_hot_plug_on_notify(cpu); #endif pr_debug("Slave cpu init\n"); HOTPLUG_INFO("platform_secondary_init, cpu: %d\n", cpu); mt_gic_secondary_init(); /* * let the primary processor know we're out of the * pen, then head off into the C entry point */ write_pen_release(-1); #if !defined (CONFIG_ARM_PSCI) //cannot enable in secure world fiq_glue_resume(); #endif //#if !defined (CONFIG_ARM_PSCI) /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); spin_unlock(&boot_lock); }
static int secondary_pen_release(unsigned int cpu) { unsigned long timeout; /* * Set synchronisation state between this boot processor * and the secondary one */ raw_spin_lock(&boot_lock); write_pen_release(cpu_logical_map(cpu)); /* * Wake-up cpu with am IPI */ arch_send_wakeup_ipi_mask(cpumask_of(cpu)); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { if (secondary_holding_pen_release == INVALID_HWID) break; udelay(10); } raw_spin_unlock(&boot_lock); return secondary_holding_pen_release != INVALID_HWID ? -ENOSYS : 0; }
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) { unsigned long timeout; /* * Set synchronisation state between this boot processor * and the secondary one */ spin_lock(&boot_lock); /* * Don't know why we need this when realview and omap2 appear not to, but * the secondary CPU doesn't start without it. */ write_pen_release(cpu); gic_raise_softirq(cpumask_of(cpu), 1); /* Wake the CPU from WFI */ /* Give the secondary CPU time to get going */ timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { smp_rmb(); if (pen_release == -1) break; } spin_unlock(&boot_lock); return pen_release != -1 ? -ENOSYS : 0; }
static int __cpuinit release_from_pen(unsigned int cpu) { unsigned long timeout; preset_lpj = loops_per_jiffy; spin_lock(&boot_lock); write_pen_release(cpu_logical_map(cpu)); arch_send_wakeup_ipi_mask(cpumask_of(cpu)); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { smp_rmb(); if (pen_release == -1) break; udelay(10); } spin_unlock(&boot_lock); return pen_release != -1 ? -ENOSYS : 0; }
void __cpuinit meson_secondary_init(unsigned int cpu) { /* * if any interrupts are already enabled for the primary * core (e.g. timer irq), then they will not have been enabled * for us: do so */ // gic_secondary_init(0); #ifdef CONFIG_MESON_ARM_GIC_FIQ extern void init_fiq(void); init_fiq(); #endif /* * let the primary processor know we're out of the * pen, then head off into the C entry point */ write_pen_release(-1); smp_wmb(); /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); spin_unlock(&boot_lock); }
/* * Boot a secondary CPU, and assign it the specified idle task. * This also gives us the initial stack to use for this CPU. */ static int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) { unsigned long timeout; /* * Set synchronisation state between this boot processor * and the secondary one */ raw_spin_lock(&boot_lock); /* * Update the pen release flag. */ write_pen_release(cpu_logical_map(cpu)); /* * Send an event, causing the secondaries to read pen_release. */ sev(); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { if (secondary_holding_pen_release == INVALID_HWID) break; udelay(10); } /* * Now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ raw_spin_unlock(&boot_lock); return secondary_holding_pen_release != INVALID_HWID ? -ENOSYS : 0; }
void platform_secondary_init(unsigned int cpu) { pr_debug("CPU%u: Booted secondary processor\n", cpu); WARN_ON(msm_platform_secondary_init(cpu)); /* * if any interrupts are already enabled for the primary * core (e.g. timer irq), then they will not have been enabled * for us: do so */ gic_secondary_init(0); /* * let the primary processor know we're out of the * pen, then head off into the C entry point */ write_pen_release(-1); /* clear the IPC1(SPI-8) pending SPI */ if (power_collapsed) { raise_clear_spi(1, false); clear_pending_spi(MSM8625_INT_ACSR_MP_CORE_IPC1); power_collapsed = 0; } /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); spin_unlock(&boot_lock); }
static int __cpuinit ux500_boot_secondary(unsigned int cpu, struct task_struct *idle) { unsigned long timeout; /* * set synchronisation state between this boot processor * and the secondary one */ spin_lock(&boot_lock); /* * The secondary processor is waiting to be released from * the holding pen - release it, then wait for it to flag * that it has been released by resetting pen_release. */ write_pen_release(cpu_logical_map(cpu)); smp_send_reschedule(cpu); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { if (pen_release == -1) break; } /* * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ spin_unlock(&boot_lock); return pen_release != -1 ? -ENOSYS : 0; }
/* * This is the secondary CPU boot entry. We're using this CPUs * idle thread stack, but a set of temporary page tables. */ asmlinkage void __cpuinit secondary_start_kernel(void) { struct mm_struct *mm = &init_mm; unsigned int cpu = smp_processor_id(); printk("CPU%u: Booted secondary processor\n", cpu); /* * All kernel threads share the same mm context; grab a * reference and switch to it. */ atomic_inc(&mm->mm_count); current->active_mm = mm; cpumask_set_cpu(cpu, mm_cpumask(mm)); /* * TTBR0 is only used for the identity mapping at this stage. Make it * point to zero page to avoid speculatively fetching new entries. */ cpu_set_reserved_ttbr0(); flush_tlb_all(); preempt_disable(); trace_hardirqs_off(); /* * Let the primary processor know we're out of the * pen, then head off into the C entry point */ write_pen_release(INVALID_HWID); /* * Synchronise with the boot thread. */ raw_spin_lock(&boot_lock); raw_spin_unlock(&boot_lock); /* * OK, now it's safe to let the boot CPU continue. Wait for * the CPU migration code to notice that the CPU is online * before we continue. */ set_cpu_online(cpu, true); complete(&cpu_running); /* * Enable GIC and timers. */ notify_cpu_starting(cpu); local_irq_enable(); local_fiq_enable(); /* * OK, it's off to the idle thread for us */ cpu_startup_entry(CPUHP_ONLINE); }
void __cpuinit msm_secondary_init(unsigned int cpu) { WARN_ON(msm_platform_secondary_init(cpu)); write_pen_release(-1); spin_lock(&boot_lock); spin_unlock(&boot_lock); }
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) { int ret; int flag = 0; unsigned long timeout; pr_debug("Starting secondary CPU %d\n", cpu); preset_lpj = loops_per_jiffy; if (cpu > 0 && cpu < ARRAY_SIZE(cold_boot_flags)) flag = cold_boot_flags[cpu]; else __WARN(); if (per_cpu(cold_boot_done, cpu) == false) { init_cpu_debug_counter_for_cold_boot(); ret = scm_set_boot_addr((void *) virt_to_phys(msm_secondary_startup), flag); if (ret == 0) release_secondary(cpu); else printk(KERN_DEBUG "Failed to set secondary core boot " "address\n"); per_cpu(cold_boot_done, cpu) = true; } spin_lock(&boot_lock); /* * The secondary processor is waiting to be released from * the holding pen - release it, then wait for it to flag * that it has been released by resetting pen_release. * * Note that "pen_release" is the hardware CPU ID, whereas * "cpu" is Linux's internal ID. */ write_pen_release(cpu_logical_map(cpu)); gic_raise_softirq(cpumask_of(cpu), 1); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { smp_rmb(); if (pen_release == -1) break; udelay(10); } spin_unlock(&boot_lock); return pen_release != -1 ? -ENOSYS : 0; }
static int __cpuinit brcm_boot_secondary(unsigned int cpu, struct task_struct *idle) { unsigned long timeout; /* * set synchronisation state between this boot processor * and the secondary one */ spin_lock(&boot_lock); /* * The secondary processor is waiting to be released from * the holding pen - release it, then wait for it to flag * that it has been released by resetting pen_release. * * Note that "pen_release" is the hardware CPU ID, whereas * "cpu" is Linux's internal ID. */ write_pen_release(cpu); dsb_sev(); /* * Timeout set on purpose in jiffies so that on slow processors * that must also have low HZ it will wait longer. */ timeout = jiffies + (HZ * 10); udelay(100); /* * If the secondary CPU was waiting on WFE, it should * be already watching <pen_release>, or it could be * waiting in WFI, send it an IPI to be sure it wakes. */ if (pen_release != -1) tick_broadcast(cpumask_of(cpu)); while (time_before(jiffies, timeout)) { smp_rmb(); if (pen_release == -1) break; udelay(10); } /* * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ spin_unlock(&boot_lock); return pen_release != -1 ? -ENOSYS : 0; }
void smp_spin_table_cpu_postboot(void) { /* * Let the primary processor know we're out of the pen. */ write_pen_release(INVALID_HWID); /* * Synchronise with the boot thread. */ raw_spin_lock(&boot_lock); raw_spin_unlock(&boot_lock); }
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) { unsigned long timeout; /* * set synchronisation state between this boot processor * and the secondary one */ spin_lock(&boot_lock); /* * The secondary processor is waiting to be released from * the holding pen - release it, then wait for it to flag * that it has been released by resetting pen_release. * * Note that "pen_release" is the hardware CPU ID, whereas * "cpu" is Linux's internal ID. */ write_pen_release(cpu); /* * Send the secondary CPU a soft interrupt, thereby causing * the boot monitor to read the system wide flags register, * and branch to the address found there. */ //l4/smp_cross_call(cpumask_of(cpu), 1); l4x_cpu_release(cpu); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { smp_rmb(); if (pen_release == -1) break; //udelay(10); { L4XV_V(f); L4XV_L(f); l4_sleep(10); L4XV_U(f); } } /* * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ spin_unlock(&boot_lock); return 0; //pen_release != -1 ? -ENOSYS : 0; }
static int smp_spin_table_cpu_boot(unsigned int cpu) { /* * Update the pen release flag. */ write_pen_release(cpu_logical_map(cpu)); /* * Send an event, causing the secondaries to read pen_release. */ sev(); return 0; }
int __cpuinit meson_boot_secondary(unsigned int cpu, struct task_struct *idle) { unsigned long timeout; /* * Set synchronisation state between this boot processor * and the secondary one */ spin_lock(&boot_lock); /* * The secondary processor is waiting to be released from * the holding pen - release it, then wait for it to flag * that it has been released by resetting pen_release. */ printk("write pen_release: %d\n",cpu_logical_map(cpu)); write_pen_release(cpu_logical_map(cpu)); #ifndef CONFIG_MESON_TRUSTZONE // check_and_rewrite_cpu_entry(); meson_set_cpu_ctrl_addr(cpu, (const uint32_t)virt_to_phys(meson_secondary_startup)); meson_set_cpu_power_ctrl(cpu, 1); timeout = jiffies + (10* HZ); while(meson_get_cpu_ctrl_addr(cpu)); { if(!time_before(jiffies, timeout)) return -EPERM; } #endif meson_secondary_set(cpu); dsb_sev(); // smp_send_reschedule(cpu); timeout = jiffies + (10* HZ); while (time_before(jiffies, timeout)) { smp_rmb(); if (pen_release == -1) break; udelay(10); } /* * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ spin_unlock(&boot_lock); return pen_release != -1 ? -ENOSYS : 0; }
static void exynos_secondary_init(unsigned int cpu) { /* * let the primary processor know we're out of the * pen, then head off into the C entry point */ write_pen_release(-1); /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); spin_unlock(&boot_lock); }
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) { unsigned long timeout; /* * Set synchronisation state between this boot processor * and the secondary one */ spin_lock(&boot_lock); /* * This is really belt and braces; we hold unintended secondary * CPUs in the holding pen until we're ready for them. However, * since we haven't sent them a soft interrupt, they shouldn't * be there. */ write_pen_release(cpu); #if 1 //debug { volatile int *ptr = &pen_release; printk("pen_release = 0x%08x, addr= 0x%08x, pen_release ptr = 0x%08x\n ",pen_release,(unsigned int)&pen_release,*ptr); } #endif /* * Send the secondary CPU a soft interrupt, thereby causing * the boot monitor to read the system wide flags register, * and branch to the address found there. */ gic_raise_softirq(cpumask_of(cpu), 1); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { smp_rmb(); if (pen_release == -1) break; udelay(10); } /* * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ spin_unlock(&boot_lock); return pen_release != -1 ? -ENOSYS : 0; }
void __cpuinit sti_secondary_init(unsigned int cpu) { trace_hardirqs_off(); /* * let the primary processor know we're out of the * pen, then head off into the C entry point */ write_pen_release(-1); /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); spin_unlock(&boot_lock); }
void __cpuinit msm_secondary_init(unsigned int cpu) { WARN_ON(msm_platform_secondary_init(cpu)); /* * let the primary processor know we're out of the * pen, then head off into the C entry point */ write_pen_release(-1); /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); spin_unlock(&boot_lock); }
void msm_cpu_postboot(void) { msm_jtag_restore_state(); /* * Let the primary processor know we're out of the pen. */ write_pen_release(INVALID_HWID); msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING, false); /* * Synchronise with the boot thread. */ raw_spin_lock(&boot_lock); raw_spin_unlock(&boot_lock); }
static int __cpuinit release_from_pen(unsigned int cpu) { unsigned long timeout; /* Set preset_lpj to avoid subsequent lpj recalculations */ preset_lpj = loops_per_jiffy; /* * set synchronisation state between this boot processor * and the secondary one */ spin_lock(&boot_lock); /* * The secondary processor is waiting to be released from * the holding pen - release it, then wait for it to flag * that it has been released by resetting pen_release. * * Note that "pen_release" is the hardware CPU ID, whereas * "cpu" is Linux's internal ID. */ write_pen_release(cpu_logical_map(cpu)); /* * Send the secondary CPU a soft interrupt, thereby causing * the boot monitor to read the system wide flags register, * and branch to the address found there. */ gic_raise_softirq(cpumask_of(cpu), 1); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { smp_rmb(); if (pen_release == -1) break; udelay(10); } /* * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ spin_unlock(&boot_lock); return pen_release != -1 ? -ENOSYS : 0; }
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) { unsigned long timeout; /* * Set synchronisation state between this boot processor * and the secondary one */ spin_lock(&boot_lock); /* * This is really belt and braces; we hold unintended secondary * CPUs in the holding pen until we're ready for them. However, * since we haven't sent them a soft interrupt, they shouldn't * be there. */ write_pen_release(cpu_logical_map(cpu)); /* * Send the secondary CPU a soft interrupt, thereby causing * the boot monitor to read the system wide flags register, * and branch to the address found there. */ timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { smp_rmb(); __raw_writel(virt_to_phys(wmt_secondary_startup), CPU1_BOOT_REG); gic_raise_softirq(cpumask_of(cpu), 1); if (pen_release == -1) break; udelay(10); } /* * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ spin_unlock(&boot_lock); return pen_release != -1 ? -ENOSYS : 0; }
void __cpuinit platform_secondary_init(unsigned int cpu) { /* * If any interrupts are already enabled for the primary * core (e.g. timer irq), then they will not have been enabled * for us: do so */ gic_secondary_init(0); write_pen_release(-1); /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); spin_unlock(&boot_lock); }
static int smp_spin_table_cpu_boot(unsigned int cpu) { #ifdef CONFIG_HOTPLUG_CPU if (soc_ops && soc_ops->cpu_on) soc_ops->cpu_on(cpu); #endif /* * Update the pen release flag. */ write_pen_release(cpu_logical_map(cpu)); /* * Send an event, causing the secondaries to read pen_release. */ sev(); return 0; }
int sti_boot_secondary(unsigned int cpu, struct task_struct *idle) { unsigned long timeout; /* * set synchronisation state between this boot processor * and the secondary one */ spin_lock(&boot_lock); /* * The secondary processor is waiting to be released from * the holding pen - release it, then wait for it to flag * that it has been released by resetting pen_release. * * Note that "pen_release" is the hardware CPU ID, whereas * "cpu" is Linux's internal ID. */ write_pen_release(cpu_logical_map(cpu)); /* * Send the secondary CPU a soft interrupt, thereby causing * it to jump to the secondary entrypoint. */ arch_send_wakeup_ipi_mask(cpumask_of(cpu)); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { smp_rmb(); if (pen_release == -1) break; udelay(10); } /* * now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ spin_unlock(&boot_lock); return pen_release != -1 ? -ENOSYS : 0; }
void __cpuinit platform_secondary_init(unsigned int cpu) { pr_debug("CPU%u: Booted secondary processor\n", cpu); WARN_ON(msm_platform_secondary_init(cpu)); gic_secondary_init(0); write_pen_release(-1); if (per_cpu(power_collapsed, cpu)) { raise_clear_spi(cpu, false); clear_pending_spi(cpu_data[cpu].ipc_irq); per_cpu(power_collapsed, cpu) = 0; } spin_lock(&boot_lock); spin_unlock(&boot_lock); }
void __cpuinit platform_secondary_init(unsigned int cpu) { /* */ gic_secondary_init(0); /* */ write_pen_release(-1); /* */ spin_lock(&boot_lock); spin_unlock(&boot_lock); }
static void __cpuinit ux500_secondary_init(unsigned int cpu) { /* * if any interrupts are already enabled for the primary * core (e.g. timer irq), then they will not have been enabled * for us: do so */ gic_secondary_init(0); /* * let the primary processor know we're out of the * pen, then head off into the C entry point */ write_pen_release(-1); /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); spin_unlock(&boot_lock); }