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


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * linux/arch/arm/mach-axxia/platsmp.c
      4 *
      5 * Copyright (C) 2012 LSI Corporation
      6 */
      7
      8#include <linux/init.h>
      9#include <linux/io.h>
     10#include <linux/smp.h>
     11#include <linux/of.h>
     12#include <linux/of_address.h>
     13#include <asm/cacheflush.h>
     14
     15/* Syscon register offsets for releasing cores from reset */
     16#define SC_CRIT_WRITE_KEY	0x1000
     17#define SC_RST_CPU_HOLD		0x1010
     18
     19/*
     20 * Write the kernel entry point for secondary CPUs to the specified address
     21 */
     22static void write_release_addr(u32 release_phys)
     23{
     24	u32 *virt = (u32 *) phys_to_virt(release_phys);
     25	writel_relaxed(__pa_symbol(secondary_startup), virt);
     26	/* Make sure this store is visible to other CPUs */
     27	smp_wmb();
     28	__cpuc_flush_dcache_area(virt, sizeof(u32));
     29}
     30
     31static int axxia_boot_secondary(unsigned int cpu, struct task_struct *idle)
     32{
     33	struct device_node *syscon_np;
     34	void __iomem *syscon;
     35	u32 tmp;
     36
     37	syscon_np = of_find_compatible_node(NULL, NULL, "lsi,axxia-syscon");
     38	if (!syscon_np)
     39		return -ENOENT;
     40
     41	syscon = of_iomap(syscon_np, 0);
     42	of_node_put(syscon_np);
     43	if (!syscon)
     44		return -ENOMEM;
     45
     46	tmp = readl(syscon + SC_RST_CPU_HOLD);
     47	writel(0xab, syscon + SC_CRIT_WRITE_KEY);
     48	tmp &= ~(1 << cpu);
     49	writel(tmp, syscon + SC_RST_CPU_HOLD);
     50
     51	return 0;
     52}
     53
     54static void __init axxia_smp_prepare_cpus(unsigned int max_cpus)
     55{
     56	int cpu_count = 0;
     57	int cpu;
     58
     59	/*
     60	 * Initialise the present map, which describes the set of CPUs actually
     61	 * populated at the present time.
     62	 */
     63	for_each_possible_cpu(cpu) {
     64		struct device_node *np;
     65		u32 release_phys;
     66
     67		np = of_get_cpu_node(cpu, NULL);
     68		if (!np)
     69			continue;
     70		if (of_property_read_u32(np, "cpu-release-addr", &release_phys))
     71			continue;
     72
     73		if (cpu_count < max_cpus) {
     74			set_cpu_present(cpu, true);
     75			cpu_count++;
     76		}
     77
     78		if (release_phys != 0)
     79			write_release_addr(release_phys);
     80	}
     81}
     82
     83static const struct smp_operations axxia_smp_ops __initconst = {
     84	.smp_prepare_cpus	= axxia_smp_prepare_cpus,
     85	.smp_boot_secondary	= axxia_boot_secondary,
     86};
     87CPU_METHOD_OF_DECLARE(axxia_smp, "lsi,syscon-release", &axxia_smp_ops);