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

ppc_cbe_cpufreq_pervasive.c (2288B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * pervasive backend for the cbe_cpufreq driver
      4 *
      5 * This driver makes use of the pervasive unit to
      6 * engage the desired frequency.
      7 *
      8 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007
      9 *
     10 * Author: Christian Krafft <krafft@de.ibm.com>
     11 */
     12
     13#include <linux/io.h>
     14#include <linux/kernel.h>
     15#include <linux/time.h>
     16#include <asm/machdep.h>
     17#include <asm/hw_irq.h>
     18#include <asm/cell-regs.h>
     19
     20#include "ppc_cbe_cpufreq.h"
     21
     22/* to write to MIC register */
     23static u64 MIC_Slow_Fast_Timer_table[] = {
     24	[0 ... 7] = 0x007fc00000000000ull,
     25};
     26
     27/* more values for the MIC */
     28static u64 MIC_Slow_Next_Timer_table[] = {
     29	0x0000240000000000ull,
     30	0x0000268000000000ull,
     31	0x000029C000000000ull,
     32	0x00002D0000000000ull,
     33	0x0000300000000000ull,
     34	0x0000334000000000ull,
     35	0x000039C000000000ull,
     36	0x00003FC000000000ull,
     37};
     38
     39
     40int cbe_cpufreq_set_pmode(int cpu, unsigned int pmode)
     41{
     42	struct cbe_pmd_regs __iomem *pmd_regs;
     43	struct cbe_mic_tm_regs __iomem *mic_tm_regs;
     44	unsigned long flags;
     45	u64 value;
     46#ifdef DEBUG
     47	long time;
     48#endif
     49
     50	local_irq_save(flags);
     51
     52	mic_tm_regs = cbe_get_cpu_mic_tm_regs(cpu);
     53	pmd_regs = cbe_get_cpu_pmd_regs(cpu);
     54
     55#ifdef DEBUG
     56	time = jiffies;
     57#endif
     58
     59	out_be64(&mic_tm_regs->slow_fast_timer_0, MIC_Slow_Fast_Timer_table[pmode]);
     60	out_be64(&mic_tm_regs->slow_fast_timer_1, MIC_Slow_Fast_Timer_table[pmode]);
     61
     62	out_be64(&mic_tm_regs->slow_next_timer_0, MIC_Slow_Next_Timer_table[pmode]);
     63	out_be64(&mic_tm_regs->slow_next_timer_1, MIC_Slow_Next_Timer_table[pmode]);
     64
     65	value = in_be64(&pmd_regs->pmcr);
     66	/* set bits to zero */
     67	value &= 0xFFFFFFFFFFFFFFF8ull;
     68	/* set bits to next pmode */
     69	value |= pmode;
     70
     71	out_be64(&pmd_regs->pmcr, value);
     72
     73#ifdef DEBUG
     74	/* wait until new pmode appears in status register */
     75	value = in_be64(&pmd_regs->pmsr) & 0x07;
     76	while (value != pmode) {
     77		cpu_relax();
     78		value = in_be64(&pmd_regs->pmsr) & 0x07;
     79	}
     80
     81	time = jiffies  - time;
     82	time = jiffies_to_msecs(time);
     83	pr_debug("had to wait %lu ms for a transition using " \
     84		 "pervasive unit\n", time);
     85#endif
     86	local_irq_restore(flags);
     87
     88	return 0;
     89}
     90
     91
     92int cbe_cpufreq_get_pmode(int cpu)
     93{
     94	int ret;
     95	struct cbe_pmd_regs __iomem *pmd_regs;
     96
     97	pmd_regs = cbe_get_cpu_pmd_regs(cpu);
     98	ret = in_be64(&pmd_regs->pmsr) & 0x07;
     99
    100	return ret;
    101}
    102