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

setup.c (5394B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
      4 */
      5#include <linux/export.h>
      6#include <linux/init.h>
      7#include <linux/kernel.h>
      8#include <linux/reboot.h>
      9#include <linux/string.h>
     10
     11#include <asm/bootinfo.h>
     12#include <asm/cpu.h>
     13#include <asm/mipsregs.h>
     14#include <asm/io.h>
     15#include <asm/sibyte/sb1250.h>
     16#include <asm/sibyte/sb1250_regs.h>
     17#include <asm/sibyte/sb1250_scd.h>
     18
     19unsigned int sb1_pass;
     20unsigned int soc_pass;
     21unsigned int soc_type;
     22EXPORT_SYMBOL(soc_type);
     23unsigned int periph_rev;
     24EXPORT_SYMBOL_GPL(periph_rev);
     25unsigned int zbbus_mhz;
     26EXPORT_SYMBOL(zbbus_mhz);
     27
     28static char *soc_str;
     29static char *pass_str;
     30static unsigned int war_pass;	/* XXXKW don't overload PASS defines? */
     31
     32static int __init setup_bcm1250(void)
     33{
     34	int ret = 0;
     35
     36	switch (soc_pass) {
     37	case K_SYS_REVISION_BCM1250_PASS1:
     38		periph_rev = 1;
     39		pass_str = "Pass 1";
     40		break;
     41	case K_SYS_REVISION_BCM1250_A10:
     42		periph_rev = 2;
     43		pass_str = "A8/A10";
     44		/* XXXKW different war_pass? */
     45		war_pass = K_SYS_REVISION_BCM1250_PASS2;
     46		break;
     47	case K_SYS_REVISION_BCM1250_PASS2_2:
     48		periph_rev = 2;
     49		pass_str = "B1";
     50		break;
     51	case K_SYS_REVISION_BCM1250_B2:
     52		periph_rev = 2;
     53		pass_str = "B2";
     54		war_pass = K_SYS_REVISION_BCM1250_PASS2_2;
     55		break;
     56	case K_SYS_REVISION_BCM1250_PASS3:
     57		periph_rev = 3;
     58		pass_str = "C0";
     59		break;
     60	case K_SYS_REVISION_BCM1250_C1:
     61		periph_rev = 3;
     62		pass_str = "C1";
     63		break;
     64	default:
     65		if (soc_pass < K_SYS_REVISION_BCM1250_PASS2_2) {
     66			periph_rev = 2;
     67			pass_str = "A0-A6";
     68			war_pass = K_SYS_REVISION_BCM1250_PASS2;
     69		} else {
     70			printk("Unknown BCM1250 rev %x\n", soc_pass);
     71			ret = 1;
     72		}
     73		break;
     74	}
     75
     76	return ret;
     77}
     78
     79int sb1250_m3_workaround_needed(void)
     80{
     81	switch (soc_type) {
     82	case K_SYS_SOC_TYPE_BCM1250:
     83	case K_SYS_SOC_TYPE_BCM1250_ALT:
     84	case K_SYS_SOC_TYPE_BCM1250_ALT2:
     85	case K_SYS_SOC_TYPE_BCM1125:
     86	case K_SYS_SOC_TYPE_BCM1125H:
     87		return soc_pass < K_SYS_REVISION_BCM1250_C0;
     88
     89	default:
     90		return 0;
     91	}
     92}
     93
     94static int __init setup_bcm112x(void)
     95{
     96	int ret = 0;
     97
     98	switch (soc_pass) {
     99	case 0:
    100		/* Early build didn't have revid set */
    101		periph_rev = 3;
    102		pass_str = "A1";
    103		war_pass = K_SYS_REVISION_BCM112x_A1;
    104		break;
    105	case K_SYS_REVISION_BCM112x_A1:
    106		periph_rev = 3;
    107		pass_str = "A1";
    108		break;
    109	case K_SYS_REVISION_BCM112x_A2:
    110		periph_rev = 3;
    111		pass_str = "A2";
    112		break;
    113	case K_SYS_REVISION_BCM112x_A3:
    114		periph_rev = 3;
    115		pass_str = "A3";
    116		break;
    117	case K_SYS_REVISION_BCM112x_A4:
    118		periph_rev = 3;
    119		pass_str = "A4";
    120		break;
    121	case K_SYS_REVISION_BCM112x_B0:
    122		periph_rev = 3;
    123		pass_str = "B0";
    124		break;
    125	default:
    126		printk("Unknown %s rev %x\n", soc_str, soc_pass);
    127		ret = 1;
    128	}
    129
    130	return ret;
    131}
    132
    133/* Setup code likely to be common to all SiByte platforms */
    134
    135static int __init sys_rev_decode(void)
    136{
    137	int ret = 0;
    138
    139	war_pass = soc_pass;
    140	switch (soc_type) {
    141	case K_SYS_SOC_TYPE_BCM1250:
    142	case K_SYS_SOC_TYPE_BCM1250_ALT:
    143	case K_SYS_SOC_TYPE_BCM1250_ALT2:
    144		soc_str = "BCM1250";
    145		ret = setup_bcm1250();
    146		break;
    147	case K_SYS_SOC_TYPE_BCM1120:
    148		soc_str = "BCM1120";
    149		ret = setup_bcm112x();
    150		break;
    151	case K_SYS_SOC_TYPE_BCM1125:
    152		soc_str = "BCM1125";
    153		ret = setup_bcm112x();
    154		break;
    155	case K_SYS_SOC_TYPE_BCM1125H:
    156		soc_str = "BCM1125H";
    157		ret = setup_bcm112x();
    158		break;
    159	default:
    160		printk("Unknown SOC type %x\n", soc_type);
    161		ret = 1;
    162		break;
    163	}
    164
    165	return ret;
    166}
    167
    168void __init sb1250_setup(void)
    169{
    170	uint64_t sys_rev;
    171	int plldiv;
    172	int bad_config = 0;
    173
    174	sb1_pass = read_c0_prid() & PRID_REV_MASK;
    175	sys_rev = __raw_readq(IOADDR(A_SCD_SYSTEM_REVISION));
    176	soc_type = SYS_SOC_TYPE(sys_rev);
    177	soc_pass = G_SYS_REVISION(sys_rev);
    178
    179	if (sys_rev_decode()) {
    180		printk("Restart after failure to identify SiByte chip\n");
    181		machine_restart(NULL);
    182	}
    183
    184	plldiv = G_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
    185	zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25);
    186
    187	printk("Broadcom SiByte %s %s @ %d MHz (SB1 rev %d)\n",
    188		    soc_str, pass_str, zbbus_mhz * 2, sb1_pass);
    189	printk("Board type: %s\n", get_system_type());
    190
    191	switch (war_pass) {
    192	case K_SYS_REVISION_BCM1250_PASS1:
    193		printk("@@@@ This is a BCM1250 A0-A2 (Pass 1) board, "
    194			    "and the kernel doesn't have the proper "
    195			    "workarounds compiled in. @@@@\n");
    196		bad_config = 1;
    197		break;
    198	case K_SYS_REVISION_BCM1250_PASS2:
    199		/* Pass 2 - easiest as default for now - so many numbers */
    200#if !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) || \
    201    !defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS)
    202		printk("@@@@ This is a BCM1250 A3-A10 board, and the "
    203			    "kernel doesn't have the proper workarounds "
    204			    "compiled in. @@@@\n");
    205		bad_config = 1;
    206#endif
    207#ifdef CONFIG_CPU_HAS_PREFETCH
    208		printk("@@@@ Prefetches may be enabled in this kernel, "
    209			    "but are buggy on this board.  @@@@\n");
    210		bad_config = 1;
    211#endif
    212		break;
    213	case K_SYS_REVISION_BCM1250_PASS2_2:
    214#ifndef CONFIG_SB1_PASS_2_WORKAROUNDS
    215		printk("@@@@ This is a BCM1250 B1/B2. board, and the "
    216			    "kernel doesn't have the proper workarounds "
    217			    "compiled in. @@@@\n");
    218		bad_config = 1;
    219#endif
    220#if defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) || \
    221    !defined(CONFIG_CPU_HAS_PREFETCH)
    222		printk("@@@@ This is a BCM1250 B1/B2, but the kernel is "
    223			    "conservatively configured for an 'A' stepping. "
    224			    "@@@@\n");
    225#endif
    226		break;
    227	default:
    228		break;
    229	}
    230	if (bad_config) {
    231		printk("Invalid configuration for this chip.\n");
    232		machine_restart(NULL);
    233	}
    234}