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

hotplug.c (2548B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  Copyright (C) 2002 ARM Ltd.
      4 *  All Rights Reserved
      5 *
      6 * This hotplug implementation is _specific_ to the situation found on
      7 * ARM development platforms where there is _no_ possibility of actually
      8 * taking a CPU offline, resetting it, or otherwise.  Real platforms must
      9 * NOT copy this code.
     10 */
     11#include <linux/kernel.h>
     12#include <linux/errno.h>
     13#include <linux/smp.h>
     14
     15#include <asm/smp_plat.h>
     16#include <asm/cp15.h>
     17
     18#include "platsmp.h"
     19
     20static inline void versatile_immitation_enter_lowpower(unsigned int actrl_mask)
     21{
     22	unsigned int v;
     23
     24	asm volatile(
     25		"mcr	p15, 0, %1, c7, c5, 0\n"
     26	"	mcr	p15, 0, %1, c7, c10, 4\n"
     27	/*
     28	 * Turn off coherency
     29	 */
     30	"	mrc	p15, 0, %0, c1, c0, 1\n"
     31	"	bic	%0, %0, %3\n"
     32	"	mcr	p15, 0, %0, c1, c0, 1\n"
     33	"	mrc	p15, 0, %0, c1, c0, 0\n"
     34	"	bic	%0, %0, %2\n"
     35	"	mcr	p15, 0, %0, c1, c0, 0\n"
     36	  : "=&r" (v)
     37	  : "r" (0), "Ir" (CR_C), "Ir" (actrl_mask)
     38	  : "cc");
     39}
     40
     41static inline void versatile_immitation_leave_lowpower(unsigned int actrl_mask)
     42{
     43	unsigned int v;
     44
     45	asm volatile(
     46		"mrc	p15, 0, %0, c1, c0, 0\n"
     47	"	orr	%0, %0, %1\n"
     48	"	mcr	p15, 0, %0, c1, c0, 0\n"
     49	"	mrc	p15, 0, %0, c1, c0, 1\n"
     50	"	orr	%0, %0, %2\n"
     51	"	mcr	p15, 0, %0, c1, c0, 1\n"
     52	  : "=&r" (v)
     53	  : "Ir" (CR_C), "Ir" (actrl_mask)
     54	  : "cc");
     55}
     56
     57static inline void versatile_immitation_do_lowpower(unsigned int cpu, int *spurious)
     58{
     59	/*
     60	 * there is no power-control hardware on this platform, so all
     61	 * we can do is put the core into WFI; this is safe as the calling
     62	 * code will have already disabled interrupts.
     63	 *
     64	 * This code should not be used outside Versatile platforms.
     65	 */
     66	for (;;) {
     67		wfi();
     68
     69		if (versatile_cpu_release == cpu_logical_map(cpu)) {
     70			/*
     71			 * OK, proper wakeup, we're done
     72			 */
     73			break;
     74		}
     75
     76		/*
     77		 * Getting here, means that we have come out of WFI without
     78		 * having been woken up - this shouldn't happen
     79		 *
     80		 * Just note it happening - when we're woken, we can report
     81		 * its occurrence.
     82		 */
     83		(*spurious)++;
     84	}
     85}
     86
     87/*
     88 * platform-specific code to shutdown a CPU.
     89 * This code supports immitation-style CPU hotplug for Versatile/Realview/
     90 * Versatile Express platforms that are unable to do real CPU hotplug.
     91 */
     92void versatile_immitation_cpu_die(unsigned int cpu, unsigned int actrl_mask)
     93{
     94	int spurious = 0;
     95
     96	versatile_immitation_enter_lowpower(actrl_mask);
     97	versatile_immitation_do_lowpower(cpu, &spurious);
     98	versatile_immitation_leave_lowpower(actrl_mask);
     99
    100	if (spurious)
    101		pr_warn("CPU%u: %u spurious wakeup calls\n", cpu, spurious);
    102}