static int __cpuinit psci_boot_secondary(unsigned int cpu, struct task_struct *idle) { if (psci_ops.cpu_on) return psci_ops.cpu_on(cpu_logical_map(cpu), __pa(secondary_startup)); return -ENODEV; }
static int octeon_coreid_for_cpu(int cpu) { #ifdef CONFIG_SMP return cpu_logical_map(cpu); #else return cvmx_get_core_num(); #endif }
int hs_get_cpu_jump(int cpu) { int offset = hs_smp_reg; cpu = cpu_logical_map(cpu); if (cpu > 0) offset += 0x04 * (cpu - 1); return readl_relaxed(hs_sctrl_base + offset); }
void hs_set_cpu_jump(int cpu, void *jump_addr) { int offset = hs_smp_reg; cpu = cpu_logical_map(cpu); if (cpu > 0) offset += 0x04 * (cpu - 1); writel_relaxed(virt_to_phys(jump_addr), hs_sctrl_base + offset); }
/* * Duplicate MPIDRs are a recipe for disaster. Scan all initialized * entries and check for duplicates. If any is found just ignore the * cpu. cpu_logical_map was initialized to INVALID_HWID to avoid * matching valid MPIDR values. */ static bool __init is_mpidr_duplicate(unsigned int cpu, u64 hwid) { unsigned int i; for (i = 1; (i < cpu) && (i < NR_CPUS); i++) if (cpu_logical_map(i) == hwid) return true; return false; }
/** * Cause the function described by call_data to be executed on the passed * cpu. When the function has finished, increment the finished field of * call_data. */ void octeon_send_ipi_single(int cpu, unsigned int action) { int coreid = cpu_logical_map(cpu); /* pr_info("SMP: Mailbox send cpu=%d, coreid=%d, action=%u\n", cpu, coreid, action); */ cvmx_write_csr(CVMX_CIU_MBOX_SETX(coreid), action); }
void __init smp_clear_cpu_maps (void) { cpumask_clear(&cpu_possible_map); cpumask_clear(&cpu_online_map); cpumask_set_cpu(0, &cpu_online_map); cpumask_set_cpu(0, &cpu_possible_map); cpu_logical_map(0) = READ_SYSREG(MPIDR_EL1) & MPIDR_HWID_MASK; }
void nlm_send_ipi_single(int logical_cpu, unsigned int action) { int cpu = cpu_logical_map(logical_cpu); if (action & SMP_CALL_FUNCTION) nlm_pic_send_ipi(nlm_pic_base, cpu, IRQ_IPI_SMP_FUNCTION, 0); if (action & SMP_RESCHEDULE_YOURSELF) nlm_pic_send_ipi(nlm_pic_base, cpu, IRQ_IPI_SMP_RESCHEDULE, 0); }
static void cpu_to_pcpu(unsigned int cpu, unsigned int *pcpu, unsigned int *pcluster) { unsigned int mpidr; mpidr = cpu_logical_map(cpu); *pcpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); *pcluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); }
static void __init emev2_smp_prepare_cpus(unsigned int max_cpus) { int cpu = cpu_logical_map(0); scu_enable(scu_base); /* enable cache coherency on CPU0 */ modify_scu_cpu_psr(0, 3 << (cpu * 8)); }
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; }
void imx_enable_cpu(int cpu, bool enable) { u32 mask, val; cpu = cpu_logical_map(cpu); mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1); val = readl_relaxed(src_base + SRC_SCR); val = enable ? val | mask : val & ~mask; writel_relaxed(val, src_base + SRC_SCR); }
int tegra_cpu_kill(unsigned int cpu) { cpu = cpu_logical_map(cpu); tegra_wait_cpu_in_reset(cpu); tegra_disable_cpu_clock(cpu); return 1; }
int tegra_cpu_kill(unsigned cpu) { cpu = cpu_logical_map(cpu); /* Clock gate the CPU */ tegra_wait_cpu_in_reset(cpu); tegra_disable_cpu_clock(cpu); return 1; }
static inline void unmask_loongson_irq(struct irq_data *d) { /* Workaround: UART IRQ may deliver to any core */ if (d->irq == LOONGSON_UART_IRQ) { int cpu = smp_processor_id(); int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node; int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node; u64 intenset_addr = smp_group[node_id] | (u64)(&LOONGSON_INT_ROUTER_INTENSET); u64 introuter_lpc_addr = smp_group[node_id] | (u64)(&LOONGSON_INT_ROUTER_LPC); *(volatile u32 *)intenset_addr = 1 << 10; *(volatile u8 *)introuter_lpc_addr = 0x10 + (1<<core_id); } set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); irq_enable_hazard(); }
static int fold_prot_inuse(struct proto *proto) { int res = 0; int cpu; for (cpu=0; cpu<smp_num_cpus; cpu++) res += proto->stats[cpu_logical_map(cpu)].inuse; return res; }
/* * Setup the PC, SP, and GP of a secondary processor and start it * running! */ void prom_boot_secondary(int cpu, struct task_struct *idle) { int retval; retval = cfe_cpu_start(cpu_logical_map(cpu), &smp_bootstrap, __KSTK_TOS(idle), (unsigned long)task_thread_info(idle), 0); if (retval != 0) printk("cfe_start_cpu(%i) returned %i\n" , cpu, retval); }
void shmobile_smp_hook(unsigned int cpu, unsigned long fn, unsigned long arg) { shmobile_smp_fn[cpu] = 0; flush_cache_all(); shmobile_smp_mpidr[cpu] = cpu_logical_map(cpu); shmobile_smp_fn[cpu] = fn; shmobile_smp_arg[cpu] = arg; flush_cache_all(); }
static int tegra_boot_secondary(unsigned int cpu, struct task_struct *idle) { BUG_ON(cpu == raw_smp_processor_id()); if (tegra_boot_secondary_cpu) { cpu = cpu_logical_map(cpu); tegra_boot_secondary_cpu(cpu); } 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_power_ctrl(cpu, 1); #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; }
void tegra_clear_cpu_in_lp2(void) { int phy_cpu_id = cpu_logical_map(smp_processor_id()); u32 *cpu_in_lp2 = tegra_cpu_lp2_mask; spin_lock(&tegra_lp2_lock); BUG_ON(!(*cpu_in_lp2 & BIT(phy_cpu_id))); *cpu_in_lp2 &= ~BIT(phy_cpu_id); spin_unlock(&tegra_lp2_lock); }
/** * Firmware CPU startup hook * */ static void octeon_boot_secondary(int cpu, struct task_struct *idle) { int count; pr_info("SMP: Booting CPU%02d (CoreId %2d)...\n", cpu, cpu_logical_map(cpu)); octeon_processor_sp = __KSTK_TOS(idle); octeon_processor_gp = (unsigned long)(task_thread_info(idle)); octeon_processor_boot = cpu_logical_map(cpu); mb(); count = 10000; while (octeon_processor_sp && count) { /* Waiting for processor to get the SP and GP */ udelay(1); count--; } if (count == 0) pr_err("Secondary boot timeout\n"); }
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) { unsigned long timeout; static int cold_boot_done; /* Only need to bring cpu out of reset this way once */ if (cold_boot_done == false) { prepare_cold_cpu(cpu); cold_boot_done = true; } /* * 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. */ pen_release = cpu_logical_map(cpu); __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); /* * 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), 0); 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 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) { 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; init_cpu_debug_counter_for_cold_boot(); } spin_lock(&boot_lock); pen_release = cpu_logical_map(cpu); __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); gic_raise_softirq(cpumask_of(cpu), 1); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { smp_rmb(); if (pen_release == -1) break; dmac_inv_range((void *)&pen_release, (void *)(&pen_release+sizeof(pen_release))); udelay(10); } spin_unlock(&boot_lock); return pen_release != -1 ? -ENOSYS : 0; }
static void acpi_power_off (void) { if (unlikely(in_interrupt())) BUG(); /* Some SMP machines only can poweroff in boot CPU */ set_cpus_allowed(current, 1UL << cpu_logical_map(0)); acpi_enter_sleep_state_prep(ACPI_STATE_S5); ACPI_DISABLE_IRQS(); acpi_enter_sleep_state(ACPI_STATE_S5); printk(KERN_EMERG "ACPI: can not power off machine\n"); }
static int alpine_boot_secondary(unsigned int cpu, struct task_struct *idle) { phys_addr_t addr; addr = __pa_symbol(secondary_startup); if (addr > (phys_addr_t)(uint32_t)(-1)) { pr_err("FAIL: resume address over 32bit (%pa)", &addr); return -EINVAL; } return alpine_cpu_wakeup(cpu_logical_map(cpu), (uint32_t)addr); }
void __init smp_setup_processor_id(void) { u64 mpidr = read_cpuid_mpidr() & MPIDR_HWID_BITMASK; cpu_logical_map(0) = mpidr; /* * clear __my_cpu_offset on boot CPU to avoid hang caused by * using percpu variable early, for example, lockdep will * access percpu variable inside lock_release */ set_my_cpu_offset(0); pr_info("Booting Linux on physical CPU 0x%lx\n", (unsigned long)mpidr); }
static int exynos_cpu_state(unsigned int cpu_id) { unsigned int phys_cpu = cpu_logical_map(cpu_id); unsigned int core, cluster, val; core = MPIDR_AFFINITY_LEVEL(phys_cpu, 0); cluster = MPIDR_AFFINITY_LEVEL(phys_cpu, 1); val = __raw_readl(EXYNOS_PMU_CPU_STATUS(core + (4 * cluster))) & LOCAL_PWR_CFG; return val == LOCAL_PWR_CFG; }
unsigned int exynos7420_cpu_state(unsigned int cpu_id) { unsigned int phys_cpu = cpu_logical_map(cpu_id); unsigned int core, cluster, val; core = MPIDR_AFFINITY_LEVEL(phys_cpu, 0); cluster = MPIDR_AFFINITY_LEVEL(phys_cpu, 1); val = __raw_readl(EXYNOS_ARM_CORE_STATUS(core + (4 * cluster))) & EXYNOS_CORE_PWR_EN; return val == 0xf; }
static inline void platform_do_lowpower(unsigned int cpu, int *spurious) { for (;;) { msm_pm_cpu_enter_lowpower(cpu); if (pen_release == cpu_logical_map(cpu)) { break; } (*spurious)++; } }