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

cmu.c (5010B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  cmu.c, Clock Mask Unit routines for the NEC VR4100 series.
      4 *
      5 *  Copyright (C) 2001-2002  MontaVista Software Inc.
      6 *    Author: Yoichi Yuasa <source@mvista.com>
      7 *  Copyright (C) 2003-2005  Yoichi Yuasa <yuasa@linux-mips.org>
      8 */
      9/*
     10 * Changes:
     11 *  MontaVista Software Inc. <source@mvista.com>
     12 *  - New creation, NEC VR4122 and VR4131 are supported.
     13 *  - Added support for NEC VR4111 and VR4121.
     14 *
     15 *  Yoichi Yuasa <yuasa@linux-mips.org>
     16 *  - Added support for NEC VR4133.
     17 */
     18#include <linux/export.h>
     19#include <linux/init.h>
     20#include <linux/ioport.h>
     21#include <linux/smp.h>
     22#include <linux/spinlock.h>
     23#include <linux/types.h>
     24
     25#include <asm/cpu.h>
     26#include <asm/io.h>
     27#include <asm/vr41xx/vr41xx.h>
     28
     29#define CMU_TYPE1_BASE	0x0b000060UL
     30#define CMU_TYPE1_SIZE	0x4
     31
     32#define CMU_TYPE2_BASE	0x0f000060UL
     33#define CMU_TYPE2_SIZE	0x4
     34
     35#define CMU_TYPE3_BASE	0x0f000060UL
     36#define CMU_TYPE3_SIZE	0x8
     37
     38#define CMUCLKMSK	0x0
     39 #define MSKPIU		0x0001
     40 #define MSKSIU		0x0002
     41 #define MSKAIU		0x0004
     42 #define MSKKIU		0x0008
     43 #define MSKFIR		0x0010
     44 #define MSKDSIU	0x0820
     45 #define MSKCSI		0x0040
     46 #define MSKPCIU	0x0080
     47 #define MSKSSIU	0x0100
     48 #define MSKSHSP	0x0200
     49 #define MSKFFIR	0x0400
     50 #define MSKSCSI	0x1000
     51 #define MSKPPCIU	0x2000
     52#define CMUCLKMSK2	0x4
     53 #define MSKCEU		0x0001
     54 #define MSKMAC0	0x0002
     55 #define MSKMAC1	0x0004
     56
     57static void __iomem *cmu_base;
     58static uint16_t cmuclkmsk, cmuclkmsk2;
     59static DEFINE_SPINLOCK(cmu_lock);
     60
     61#define cmu_read(offset)		readw(cmu_base + (offset))
     62#define cmu_write(offset, value)	writew((value), cmu_base + (offset))
     63
     64void vr41xx_supply_clock(vr41xx_clock_t clock)
     65{
     66	spin_lock_irq(&cmu_lock);
     67
     68	switch (clock) {
     69	case PIU_CLOCK:
     70		cmuclkmsk |= MSKPIU;
     71		break;
     72	case SIU_CLOCK:
     73		cmuclkmsk |= MSKSIU | MSKSSIU;
     74		break;
     75	case AIU_CLOCK:
     76		cmuclkmsk |= MSKAIU;
     77		break;
     78	case KIU_CLOCK:
     79		cmuclkmsk |= MSKKIU;
     80		break;
     81	case FIR_CLOCK:
     82		cmuclkmsk |= MSKFIR | MSKFFIR;
     83		break;
     84	case DSIU_CLOCK:
     85		if (current_cpu_type() == CPU_VR4111 ||
     86		    current_cpu_type() == CPU_VR4121)
     87			cmuclkmsk |= MSKDSIU;
     88		else
     89			cmuclkmsk |= MSKSIU | MSKDSIU;
     90		break;
     91	case CSI_CLOCK:
     92		cmuclkmsk |= MSKCSI | MSKSCSI;
     93		break;
     94	case PCIU_CLOCK:
     95		cmuclkmsk |= MSKPCIU;
     96		break;
     97	case HSP_CLOCK:
     98		cmuclkmsk |= MSKSHSP;
     99		break;
    100	case PCI_CLOCK:
    101		cmuclkmsk |= MSKPPCIU;
    102		break;
    103	case CEU_CLOCK:
    104		cmuclkmsk2 |= MSKCEU;
    105		break;
    106	case ETHER0_CLOCK:
    107		cmuclkmsk2 |= MSKMAC0;
    108		break;
    109	case ETHER1_CLOCK:
    110		cmuclkmsk2 |= MSKMAC1;
    111		break;
    112	default:
    113		break;
    114	}
    115
    116	if (clock == CEU_CLOCK || clock == ETHER0_CLOCK ||
    117	    clock == ETHER1_CLOCK)
    118		cmu_write(CMUCLKMSK2, cmuclkmsk2);
    119	else
    120		cmu_write(CMUCLKMSK, cmuclkmsk);
    121
    122	spin_unlock_irq(&cmu_lock);
    123}
    124
    125EXPORT_SYMBOL_GPL(vr41xx_supply_clock);
    126
    127void vr41xx_mask_clock(vr41xx_clock_t clock)
    128{
    129	spin_lock_irq(&cmu_lock);
    130
    131	switch (clock) {
    132	case PIU_CLOCK:
    133		cmuclkmsk &= ~MSKPIU;
    134		break;
    135	case SIU_CLOCK:
    136		if (current_cpu_type() == CPU_VR4111 ||
    137		    current_cpu_type() == CPU_VR4121) {
    138			cmuclkmsk &= ~(MSKSIU | MSKSSIU);
    139		} else {
    140			if (cmuclkmsk & MSKDSIU)
    141				cmuclkmsk &= ~MSKSSIU;
    142			else
    143				cmuclkmsk &= ~(MSKSIU | MSKSSIU);
    144		}
    145		break;
    146	case AIU_CLOCK:
    147		cmuclkmsk &= ~MSKAIU;
    148		break;
    149	case KIU_CLOCK:
    150		cmuclkmsk &= ~MSKKIU;
    151		break;
    152	case FIR_CLOCK:
    153		cmuclkmsk &= ~(MSKFIR | MSKFFIR);
    154		break;
    155	case DSIU_CLOCK:
    156		if (current_cpu_type() == CPU_VR4111 ||
    157		    current_cpu_type() == CPU_VR4121) {
    158			cmuclkmsk &= ~MSKDSIU;
    159		} else {
    160			if (cmuclkmsk & MSKSSIU)
    161				cmuclkmsk &= ~MSKDSIU;
    162			else
    163				cmuclkmsk &= ~(MSKSIU | MSKDSIU);
    164		}
    165		break;
    166	case CSI_CLOCK:
    167		cmuclkmsk &= ~(MSKCSI | MSKSCSI);
    168		break;
    169	case PCIU_CLOCK:
    170		cmuclkmsk &= ~MSKPCIU;
    171		break;
    172	case HSP_CLOCK:
    173		cmuclkmsk &= ~MSKSHSP;
    174		break;
    175	case PCI_CLOCK:
    176		cmuclkmsk &= ~MSKPPCIU;
    177		break;
    178	case CEU_CLOCK:
    179		cmuclkmsk2 &= ~MSKCEU;
    180		break;
    181	case ETHER0_CLOCK:
    182		cmuclkmsk2 &= ~MSKMAC0;
    183		break;
    184	case ETHER1_CLOCK:
    185		cmuclkmsk2 &= ~MSKMAC1;
    186		break;
    187	default:
    188		break;
    189	}
    190
    191	if (clock == CEU_CLOCK || clock == ETHER0_CLOCK ||
    192	    clock == ETHER1_CLOCK)
    193		cmu_write(CMUCLKMSK2, cmuclkmsk2);
    194	else
    195		cmu_write(CMUCLKMSK, cmuclkmsk);
    196
    197	spin_unlock_irq(&cmu_lock);
    198}
    199
    200EXPORT_SYMBOL_GPL(vr41xx_mask_clock);
    201
    202static int __init vr41xx_cmu_init(void)
    203{
    204	unsigned long start, size;
    205
    206	switch (current_cpu_type()) {
    207	case CPU_VR4111:
    208	case CPU_VR4121:
    209		start = CMU_TYPE1_BASE;
    210		size = CMU_TYPE1_SIZE;
    211		break;
    212	case CPU_VR4122:
    213	case CPU_VR4131:
    214		start = CMU_TYPE2_BASE;
    215		size = CMU_TYPE2_SIZE;
    216		break;
    217	case CPU_VR4133:
    218		start = CMU_TYPE3_BASE;
    219		size = CMU_TYPE3_SIZE;
    220		break;
    221	default:
    222		panic("Unexpected CPU of NEC VR4100 series");
    223		break;
    224	}
    225
    226	if (request_mem_region(start, size, "CMU") == NULL)
    227		return -EBUSY;
    228
    229	cmu_base = ioremap(start, size);
    230	if (cmu_base == NULL) {
    231		release_mem_region(start, size);
    232		return -EBUSY;
    233	}
    234
    235	cmuclkmsk = cmu_read(CMUCLKMSK);
    236	if (current_cpu_type() == CPU_VR4133)
    237		cmuclkmsk2 = cmu_read(CMUCLKMSK2);
    238
    239	return 0;
    240}
    241
    242core_initcall(vr41xx_cmu_init);