Beispiel #1
0
static void tbase_triggerSgiDump(void)
{
  uint64_t mpidr = read_mpidr();
  uint32_t linear_id = platform_get_core_pos(mpidr);

  uint32_t SGITargets;

  /* Configure SGI */
  gicd_clr_igroupr(get_plat_config()->gicd_base, FIQ_SMP_CALL_SGI);
  gicd_set_ipriorityr(get_plat_config()->gicd_base, FIQ_SMP_CALL_SGI, GIC_HIGHEST_SEC_PRIORITY);      

  /* Enable SGI */
  gicd_set_isenabler(get_plat_config()->gicd_base, FIQ_SMP_CALL_SGI);

  /* Send SGIs to all cores except the current one 
     (current will directly branch to the dump handler) */
  SGITargets = 0xFF;
  SGITargets &= ~(1 << linear_id);

  /* Trigger SGI */
  irq_raise_softirq(SGITargets, FIQ_SMP_CALL_SGI);

  /* Current core directly branches to dump handler */
  plat_tbase_dump();
}
Beispiel #2
0
int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
{
    unsigned long timeout;
    static int is_first_boot = 1;
    
    printk(KERN_CRIT "Boot slave CPU\n");
    
    /*
     * Set synchronisation state between this boot processor
     * and the secondary one
     */
    spin_lock(&boot_lock);
    
    HOTPLUG_INFO("boot_secondary, cpu: %d\n", cpu);
    /*
    * 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;
    __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
    outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
    
    if (is_first_boot)
    {
        mt65xx_reg_sync_writel(SLAVE_MAGIC_NUM, SLAVE_MAGIC_REG);
        is_first_boot = 0;
    }
    else
    {
        mt65xx_reg_sync_writel(virt_to_phys(mt_secondary_startup), BOOTROM_BOOT_ADDR);
    }
    power_on_cpu1();
    
    irq_raise_softirq(cpumask_of(cpu), IPI_CPU_START);
    
    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;
}