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-vexpress.c (2239B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  Copyright (C) 2002 ARM Ltd.
      4 *  All Rights Reserved
      5 */
      6#include <linux/init.h>
      7#include <linux/errno.h>
      8#include <linux/smp.h>
      9#include <linux/io.h>
     10#include <linux/of_address.h>
     11#include <linux/vexpress.h>
     12
     13#include <asm/mcpm.h>
     14#include <asm/smp_scu.h>
     15#include <asm/mach/map.h>
     16
     17#include "platsmp.h"
     18#include "vexpress.h"
     19
     20bool __init vexpress_smp_init_ops(void)
     21{
     22#ifdef CONFIG_MCPM
     23	int cpu;
     24	struct device_node *cpu_node, *cci_node;
     25
     26	/*
     27	 * The best way to detect a multi-cluster configuration
     28	 * is to detect if the kernel can take over CCI ports
     29	 * control. Loop over possible CPUs and check if CCI
     30	 * port control is available.
     31	 * Override the default vexpress_smp_ops if so.
     32	 */
     33	for_each_possible_cpu(cpu) {
     34		bool available;
     35
     36		cpu_node = of_get_cpu_node(cpu, NULL);
     37		if (WARN(!cpu_node, "Missing cpu device node!"))
     38			return false;
     39
     40		cci_node = of_parse_phandle(cpu_node, "cci-control-port", 0);
     41		available = cci_node && of_device_is_available(cci_node);
     42		of_node_put(cci_node);
     43		of_node_put(cpu_node);
     44
     45		if (!available)
     46			return false;
     47	}
     48
     49	mcpm_smp_set_ops();
     50	return true;
     51#else
     52	return false;
     53#endif
     54}
     55
     56static const struct of_device_id vexpress_smp_dt_scu_match[] __initconst = {
     57	{ .compatible = "arm,cortex-a5-scu", },
     58	{ .compatible = "arm,cortex-a9-scu", },
     59	{}
     60};
     61
     62static void __init vexpress_smp_dt_prepare_cpus(unsigned int max_cpus)
     63{
     64	struct device_node *scu = of_find_matching_node(NULL,
     65			vexpress_smp_dt_scu_match);
     66
     67	if (scu)
     68		scu_enable(of_iomap(scu, 0));
     69
     70	/*
     71	 * Write the address of secondary startup into the
     72	 * system-wide flags register. The boot monitor waits
     73	 * until it receives a soft interrupt, and then the
     74	 * secondary CPU branches to this address.
     75	 */
     76	vexpress_flags_set(__pa_symbol(versatile_secondary_startup));
     77}
     78
     79#ifdef CONFIG_HOTPLUG_CPU
     80static void vexpress_cpu_die(unsigned int cpu)
     81{
     82	versatile_immitation_cpu_die(cpu, 0x40);
     83}
     84#endif
     85
     86const struct smp_operations vexpress_smp_dt_ops __initconst = {
     87	.smp_prepare_cpus	= vexpress_smp_dt_prepare_cpus,
     88	.smp_secondary_init	= versatile_secondary_init,
     89	.smp_boot_secondary	= versatile_boot_secondary,
     90#ifdef CONFIG_HOTPLUG_CPU
     91	.cpu_die		= vexpress_cpu_die,
     92#endif
     93};