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

cpu.c (8554B)


      1/*
      2 * This file is subject to the terms and conditions of the GNU General Public
      3 * License.  See the file "COPYING" in the main directory of this archive
      4 * for more details.
      5 *
      6 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
      7 * Copyright (C) 2009 Florian Fainelli <florian@openwrt.org>
      8 */
      9
     10#include <linux/kernel.h>
     11#include <linux/export.h>
     12#include <linux/cpu.h>
     13#include <asm/cpu.h>
     14#include <asm/cpu-info.h>
     15#include <asm/mipsregs.h>
     16#include <bcm63xx_cpu.h>
     17#include <bcm63xx_regs.h>
     18#include <bcm63xx_io.h>
     19#include <bcm63xx_irq.h>
     20
     21const unsigned long *bcm63xx_regs_base;
     22EXPORT_SYMBOL(bcm63xx_regs_base);
     23
     24const int *bcm63xx_irqs;
     25EXPORT_SYMBOL(bcm63xx_irqs);
     26
     27u16 bcm63xx_cpu_id __read_mostly;
     28EXPORT_SYMBOL(bcm63xx_cpu_id);
     29
     30static u8 bcm63xx_cpu_rev;
     31static unsigned int bcm63xx_cpu_freq;
     32static unsigned int bcm63xx_memory_size;
     33
     34static const unsigned long bcm3368_regs_base[] = {
     35	__GEN_CPU_REGS_TABLE(3368)
     36};
     37
     38static const int bcm3368_irqs[] = {
     39	__GEN_CPU_IRQ_TABLE(3368)
     40};
     41
     42static const unsigned long bcm6328_regs_base[] = {
     43	__GEN_CPU_REGS_TABLE(6328)
     44};
     45
     46static const int bcm6328_irqs[] = {
     47	__GEN_CPU_IRQ_TABLE(6328)
     48};
     49
     50static const unsigned long bcm6338_regs_base[] = {
     51	__GEN_CPU_REGS_TABLE(6338)
     52};
     53
     54static const int bcm6338_irqs[] = {
     55	__GEN_CPU_IRQ_TABLE(6338)
     56};
     57
     58static const unsigned long bcm6345_regs_base[] = {
     59	__GEN_CPU_REGS_TABLE(6345)
     60};
     61
     62static const int bcm6345_irqs[] = {
     63	__GEN_CPU_IRQ_TABLE(6345)
     64};
     65
     66static const unsigned long bcm6348_regs_base[] = {
     67	__GEN_CPU_REGS_TABLE(6348)
     68};
     69
     70static const int bcm6348_irqs[] = {
     71	__GEN_CPU_IRQ_TABLE(6348)
     72
     73};
     74
     75static const unsigned long bcm6358_regs_base[] = {
     76	__GEN_CPU_REGS_TABLE(6358)
     77};
     78
     79static const int bcm6358_irqs[] = {
     80	__GEN_CPU_IRQ_TABLE(6358)
     81
     82};
     83
     84static const unsigned long bcm6362_regs_base[] = {
     85	__GEN_CPU_REGS_TABLE(6362)
     86};
     87
     88static const int bcm6362_irqs[] = {
     89	__GEN_CPU_IRQ_TABLE(6362)
     90
     91};
     92
     93static const unsigned long bcm6368_regs_base[] = {
     94	__GEN_CPU_REGS_TABLE(6368)
     95};
     96
     97static const int bcm6368_irqs[] = {
     98	__GEN_CPU_IRQ_TABLE(6368)
     99
    100};
    101
    102u8 bcm63xx_get_cpu_rev(void)
    103{
    104	return bcm63xx_cpu_rev;
    105}
    106
    107EXPORT_SYMBOL(bcm63xx_get_cpu_rev);
    108
    109unsigned int bcm63xx_get_cpu_freq(void)
    110{
    111	return bcm63xx_cpu_freq;
    112}
    113
    114unsigned int bcm63xx_get_memory_size(void)
    115{
    116	return bcm63xx_memory_size;
    117}
    118
    119static unsigned int detect_cpu_clock(void)
    120{
    121	u16 cpu_id = bcm63xx_get_cpu_id();
    122
    123	switch (cpu_id) {
    124	case BCM3368_CPU_ID:
    125		return 300000000;
    126
    127	case BCM6328_CPU_ID:
    128	{
    129		unsigned int tmp, mips_pll_fcvo;
    130
    131		tmp = bcm_misc_readl(MISC_STRAPBUS_6328_REG);
    132		mips_pll_fcvo = (tmp & STRAPBUS_6328_FCVO_MASK)
    133				>> STRAPBUS_6328_FCVO_SHIFT;
    134
    135		switch (mips_pll_fcvo) {
    136		case 0x12:
    137		case 0x14:
    138		case 0x19:
    139			return 160000000;
    140		case 0x1c:
    141			return 192000000;
    142		case 0x13:
    143		case 0x15:
    144			return 200000000;
    145		case 0x1a:
    146			return 384000000;
    147		case 0x16:
    148			return 400000000;
    149		default:
    150			return 320000000;
    151		}
    152
    153	}
    154	case BCM6338_CPU_ID:
    155		/* BCM6338 has a fixed 240 Mhz frequency */
    156		return 240000000;
    157
    158	case BCM6345_CPU_ID:
    159		/* BCM6345 has a fixed 140Mhz frequency */
    160		return 140000000;
    161
    162	case BCM6348_CPU_ID:
    163	{
    164		unsigned int tmp, n1, n2, m1;
    165
    166		/* 16MHz * (N1 + 1) * (N2 + 2) / (M1_CPU + 1) */
    167		tmp = bcm_perf_readl(PERF_MIPSPLLCTL_REG);
    168		n1 = (tmp & MIPSPLLCTL_N1_MASK) >> MIPSPLLCTL_N1_SHIFT;
    169		n2 = (tmp & MIPSPLLCTL_N2_MASK) >> MIPSPLLCTL_N2_SHIFT;
    170		m1 = (tmp & MIPSPLLCTL_M1CPU_MASK) >> MIPSPLLCTL_M1CPU_SHIFT;
    171		n1 += 1;
    172		n2 += 2;
    173		m1 += 1;
    174		return (16 * 1000000 * n1 * n2) / m1;
    175	}
    176
    177	case BCM6358_CPU_ID:
    178	{
    179		unsigned int tmp, n1, n2, m1;
    180
    181		/* 16MHz * N1 * N2 / M1_CPU */
    182		tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_REG);
    183		n1 = (tmp & DMIPSPLLCFG_N1_MASK) >> DMIPSPLLCFG_N1_SHIFT;
    184		n2 = (tmp & DMIPSPLLCFG_N2_MASK) >> DMIPSPLLCFG_N2_SHIFT;
    185		m1 = (tmp & DMIPSPLLCFG_M1_MASK) >> DMIPSPLLCFG_M1_SHIFT;
    186		return (16 * 1000000 * n1 * n2) / m1;
    187	}
    188
    189	case BCM6362_CPU_ID:
    190	{
    191		unsigned int tmp, mips_pll_fcvo;
    192
    193		tmp = bcm_misc_readl(MISC_STRAPBUS_6362_REG);
    194		mips_pll_fcvo = (tmp & STRAPBUS_6362_FCVO_MASK)
    195				>> STRAPBUS_6362_FCVO_SHIFT;
    196		switch (mips_pll_fcvo) {
    197		case 0x03:
    198		case 0x0b:
    199		case 0x13:
    200		case 0x1b:
    201			return 240000000;
    202		case 0x04:
    203		case 0x0c:
    204		case 0x14:
    205		case 0x1c:
    206			return 160000000;
    207		case 0x05:
    208		case 0x0e:
    209		case 0x16:
    210		case 0x1e:
    211		case 0x1f:
    212			return 400000000;
    213		case 0x06:
    214			return 440000000;
    215		case 0x07:
    216		case 0x17:
    217			return 384000000;
    218		case 0x15:
    219		case 0x1d:
    220			return 200000000;
    221		default:
    222			return 320000000;
    223		}
    224	}
    225	case BCM6368_CPU_ID:
    226	{
    227		unsigned int tmp, p1, p2, ndiv, m1;
    228
    229		/* (64MHz / P1) * P2 * NDIV / M1_CPU */
    230		tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_6368_REG);
    231
    232		p1 = (tmp & DMIPSPLLCFG_6368_P1_MASK) >>
    233			DMIPSPLLCFG_6368_P1_SHIFT;
    234
    235		p2 = (tmp & DMIPSPLLCFG_6368_P2_MASK) >>
    236			DMIPSPLLCFG_6368_P2_SHIFT;
    237
    238		ndiv = (tmp & DMIPSPLLCFG_6368_NDIV_MASK) >>
    239			DMIPSPLLCFG_6368_NDIV_SHIFT;
    240
    241		tmp = bcm_ddr_readl(DDR_DMIPSPLLDIV_6368_REG);
    242		m1 = (tmp & DMIPSPLLDIV_6368_MDIV_MASK) >>
    243			DMIPSPLLDIV_6368_MDIV_SHIFT;
    244
    245		return (((64 * 1000000) / p1) * p2 * ndiv) / m1;
    246	}
    247
    248	default:
    249		panic("Failed to detect clock for CPU with id=%04X\n", cpu_id);
    250	}
    251}
    252
    253/*
    254 * attempt to detect the amount of memory installed
    255 */
    256static unsigned int detect_memory_size(void)
    257{
    258	unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0;
    259	u32 val;
    260
    261	if (BCMCPU_IS_6328() || BCMCPU_IS_6362())
    262		return bcm_ddr_readl(DDR_CSEND_REG) << 24;
    263
    264	if (BCMCPU_IS_6345()) {
    265		val = bcm_sdram_readl(SDRAM_MBASE_REG);
    266		return val * 8 * 1024 * 1024;
    267	}
    268
    269	if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
    270		val = bcm_sdram_readl(SDRAM_CFG_REG);
    271		rows = (val & SDRAM_CFG_ROW_MASK) >> SDRAM_CFG_ROW_SHIFT;
    272		cols = (val & SDRAM_CFG_COL_MASK) >> SDRAM_CFG_COL_SHIFT;
    273		is_32bits = (val & SDRAM_CFG_32B_MASK) ? 1 : 0;
    274		banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1;
    275	}
    276
    277	if (BCMCPU_IS_3368() || BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
    278		val = bcm_memc_readl(MEMC_CFG_REG);
    279		rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT;
    280		cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT;
    281		is_32bits = (val & MEMC_CFG_32B_MASK) ? 0 : 1;
    282		banks = 2;
    283	}
    284
    285	/* 0 => 11 address bits ... 2 => 13 address bits */
    286	rows += 11;
    287
    288	/* 0 => 8 address bits ... 2 => 10 address bits */
    289	cols += 8;
    290
    291	return 1 << (cols + rows + (is_32bits + 1) + banks);
    292}
    293
    294void __init bcm63xx_cpu_init(void)
    295{
    296	unsigned int tmp;
    297	unsigned int cpu = smp_processor_id();
    298	u32 chipid_reg;
    299
    300	/* soc registers location depends on cpu type */
    301	chipid_reg = 0;
    302
    303	switch (current_cpu_type()) {
    304	case CPU_BMIPS3300:
    305		if ((read_c0_prid() & PRID_IMP_MASK) != PRID_IMP_BMIPS3300_ALT)
    306			__cpu_name[cpu] = "Broadcom BCM6338";
    307		fallthrough;
    308	case CPU_BMIPS32:
    309		chipid_reg = BCM_6345_PERF_BASE;
    310		break;
    311	case CPU_BMIPS4350:
    312		switch ((read_c0_prid() & PRID_REV_MASK)) {
    313		case 0x04:
    314			chipid_reg = BCM_3368_PERF_BASE;
    315			break;
    316		case 0x10:
    317			chipid_reg = BCM_6345_PERF_BASE;
    318			break;
    319		default:
    320			chipid_reg = BCM_6368_PERF_BASE;
    321			break;
    322		}
    323		break;
    324	}
    325
    326	/*
    327	 * really early to panic, but delaying panic would not help since we
    328	 * will never get any working console
    329	 */
    330	if (!chipid_reg)
    331		panic("unsupported Broadcom CPU");
    332
    333	/* read out CPU type */
    334	tmp = bcm_readl(chipid_reg);
    335	bcm63xx_cpu_id = (tmp & REV_CHIPID_MASK) >> REV_CHIPID_SHIFT;
    336	bcm63xx_cpu_rev = (tmp & REV_REVID_MASK) >> REV_REVID_SHIFT;
    337
    338	switch (bcm63xx_cpu_id) {
    339	case BCM3368_CPU_ID:
    340		bcm63xx_regs_base = bcm3368_regs_base;
    341		bcm63xx_irqs = bcm3368_irqs;
    342		break;
    343	case BCM6328_CPU_ID:
    344		bcm63xx_regs_base = bcm6328_regs_base;
    345		bcm63xx_irqs = bcm6328_irqs;
    346		break;
    347	case BCM6338_CPU_ID:
    348		bcm63xx_regs_base = bcm6338_regs_base;
    349		bcm63xx_irqs = bcm6338_irqs;
    350		break;
    351	case BCM6345_CPU_ID:
    352		bcm63xx_regs_base = bcm6345_regs_base;
    353		bcm63xx_irqs = bcm6345_irqs;
    354		break;
    355	case BCM6348_CPU_ID:
    356		bcm63xx_regs_base = bcm6348_regs_base;
    357		bcm63xx_irqs = bcm6348_irqs;
    358		break;
    359	case BCM6358_CPU_ID:
    360		bcm63xx_regs_base = bcm6358_regs_base;
    361		bcm63xx_irqs = bcm6358_irqs;
    362		break;
    363	case BCM6362_CPU_ID:
    364		bcm63xx_regs_base = bcm6362_regs_base;
    365		bcm63xx_irqs = bcm6362_irqs;
    366		break;
    367	case BCM6368_CPU_ID:
    368		bcm63xx_regs_base = bcm6368_regs_base;
    369		bcm63xx_irqs = bcm6368_irqs;
    370		break;
    371	default:
    372		panic("unsupported broadcom CPU %x", bcm63xx_cpu_id);
    373		break;
    374	}
    375
    376	bcm63xx_cpu_freq = detect_cpu_clock();
    377	bcm63xx_memory_size = detect_memory_size();
    378
    379	pr_info("Detected Broadcom 0x%04x CPU revision %02x\n",
    380		bcm63xx_cpu_id, bcm63xx_cpu_rev);
    381	pr_info("CPU frequency is %u MHz\n",
    382		bcm63xx_cpu_freq / 1000000);
    383	pr_info("%uMB of RAM installed\n",
    384		bcm63xx_memory_size >> 20);
    385}