cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

platsmp-a9.c (3395B)


      1/*
      2 * Symmetric Multi Processing (SMP) support for Marvell EBU Cortex-A9
      3 * based SOCs (Armada 375/38x).
      4 *
      5 * Copyright (C) 2014 Marvell
      6 *
      7 * Gregory CLEMENT <gregory.clement@free-electrons.com>
      8 * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
      9 *
     10 * This file is licensed under the terms of the GNU General Public
     11 * License version 2.  This program is licensed "as is" without any
     12 * warranty of any kind, whether express or implied.
     13 */
     14
     15#include <linux/init.h>
     16#include <linux/io.h>
     17#include <linux/of.h>
     18#include <linux/smp.h>
     19#include <linux/mbus.h>
     20#include <asm/smp_scu.h>
     21#include <asm/smp_plat.h>
     22#include "common.h"
     23#include "pmsu.h"
     24
     25extern void mvebu_cortex_a9_secondary_startup(void);
     26
     27static int mvebu_cortex_a9_boot_secondary(unsigned int cpu,
     28						    struct task_struct *idle)
     29{
     30	int ret, hw_cpu;
     31
     32	pr_info("Booting CPU %d\n", cpu);
     33
     34	/*
     35	 * Write the address of secondary startup into the system-wide
     36	 * flags register. The boot monitor waits until it receives a
     37	 * soft interrupt, and then the secondary CPU branches to this
     38	 * address.
     39	 */
     40	hw_cpu = cpu_logical_map(cpu);
     41	if (of_machine_is_compatible("marvell,armada375"))
     42		mvebu_system_controller_set_cpu_boot_addr(mvebu_cortex_a9_secondary_startup);
     43	else
     44		mvebu_pmsu_set_cpu_boot_addr(hw_cpu, mvebu_cortex_a9_secondary_startup);
     45	smp_wmb();
     46
     47	/*
     48	 * Doing this before deasserting the CPUs is needed to wake up CPUs
     49	 * in the offline state after using CPU hotplug.
     50	 */
     51	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
     52
     53	ret = mvebu_cpu_reset_deassert(hw_cpu);
     54	if (ret) {
     55		pr_err("Could not start the secondary CPU: %d\n", ret);
     56		return ret;
     57	}
     58
     59	return 0;
     60}
     61/*
     62 * When a CPU is brought back online, either through CPU hotplug, or
     63 * because of the boot of a kexec'ed kernel, the PMSU configuration
     64 * for this CPU might be in the deep idle state, preventing this CPU
     65 * from receiving interrupts. Here, we therefore take out the current
     66 * CPU from this state, which was entered by armada_38x_cpu_die()
     67 * below.
     68 */
     69static void armada_38x_secondary_init(unsigned int cpu)
     70{
     71	mvebu_v7_pmsu_idle_exit();
     72}
     73
     74#ifdef CONFIG_HOTPLUG_CPU
     75static void armada_38x_cpu_die(unsigned int cpu)
     76{
     77	/*
     78	 * CPU hotplug is implemented by putting offline CPUs into the
     79	 * deep idle sleep state.
     80	 */
     81	armada_38x_do_cpu_suspend(true);
     82}
     83
     84/*
     85 * We need a dummy function, so that platform_can_cpu_hotplug() knows
     86 * we support CPU hotplug. However, the function does not need to do
     87 * anything, because CPUs going offline can enter the deep idle state
     88 * by themselves, without any help from a still alive CPU.
     89 */
     90static int armada_38x_cpu_kill(unsigned int cpu)
     91{
     92	return 1;
     93}
     94#endif
     95
     96static const struct smp_operations mvebu_cortex_a9_smp_ops __initconst = {
     97	.smp_boot_secondary	= mvebu_cortex_a9_boot_secondary,
     98};
     99
    100static const struct smp_operations armada_38x_smp_ops __initconst = {
    101	.smp_boot_secondary	= mvebu_cortex_a9_boot_secondary,
    102	.smp_secondary_init     = armada_38x_secondary_init,
    103#ifdef CONFIG_HOTPLUG_CPU
    104	.cpu_die		= armada_38x_cpu_die,
    105	.cpu_kill               = armada_38x_cpu_kill,
    106#endif
    107};
    108
    109CPU_METHOD_OF_DECLARE(mvebu_armada_375_smp, "marvell,armada-375-smp",
    110		      &mvebu_cortex_a9_smp_ops);
    111CPU_METHOD_OF_DECLARE(mvebu_armada_380_smp, "marvell,armada-380-smp",
    112		      &armada_38x_smp_ops);
    113CPU_METHOD_OF_DECLARE(mvebu_armada_390_smp, "marvell,armada-390-smp",
    114		      &armada_38x_smp_ops);