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

malta-init.c (7805B)


      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 * PROM library initialisation code.
      7 *
      8 * Copyright (C) 1999,2000,2004,2005,2012  MIPS Technologies, Inc.
      9 * All rights reserved.
     10 * Authors: Carsten Langgaard <carstenl@mips.com>
     11 *         Maciej W. Rozycki <macro@mips.com>
     12 *          Steven J. Hill <sjhill@mips.com>
     13 */
     14#include <linux/init.h>
     15#include <linux/string.h>
     16#include <linux/kernel.h>
     17#include <linux/pci_regs.h>
     18#include <linux/serial_core.h>
     19
     20#include <asm/cacheflush.h>
     21#include <asm/smp-ops.h>
     22#include <asm/traps.h>
     23#include <asm/fw/fw.h>
     24#include <asm/mips-cps.h>
     25#include <asm/mips-boards/generic.h>
     26#include <asm/mips-boards/malta.h>
     27
     28static int mips_revision_corid;
     29int mips_revision_sconid;
     30
     31/* Bonito64 system controller register base. */
     32unsigned long _pcictrl_bonito;
     33unsigned long _pcictrl_bonito_pcicfg;
     34
     35/* GT64120 system controller register base */
     36unsigned long _pcictrl_gt64120;
     37
     38/* MIPS System controller register base */
     39unsigned long _pcictrl_msc;
     40
     41#ifdef CONFIG_SERIAL_8250_CONSOLE
     42static void __init console_config(void)
     43{
     44	char console_string[40];
     45	int baud = 0;
     46	char parity = '\0', bits = '\0', flow = '\0';
     47	char *s;
     48
     49	s = fw_getenv("modetty0");
     50	if (s) {
     51		while (*s >= '0' && *s <= '9')
     52			baud = baud*10 + *s++ - '0';
     53		if (*s == ',')
     54			s++;
     55		if (*s)
     56			parity = *s++;
     57		if (*s == ',')
     58			s++;
     59		if (*s)
     60			bits = *s++;
     61		if (*s == ',')
     62			s++;
     63		if (*s == 'h')
     64			flow = 'r';
     65	}
     66	if (baud == 0)
     67		baud = 38400;
     68	if (parity != 'n' && parity != 'o' && parity != 'e')
     69		parity = 'n';
     70	if (bits != '7' && bits != '8')
     71		bits = '8';
     72	if (flow == '\0')
     73		flow = 'r';
     74
     75	if ((strstr(fw_getcmdline(), "earlycon=")) == NULL) {
     76		sprintf(console_string, "uart8250,io,0x3f8,%d%c%c", baud,
     77			parity, bits);
     78		setup_earlycon(console_string);
     79	}
     80
     81	if ((strstr(fw_getcmdline(), "console=")) == NULL) {
     82		sprintf(console_string, " console=ttyS0,%d%c%c%c", baud,
     83			parity, bits, flow);
     84		strcat(fw_getcmdline(), console_string);
     85		pr_info("Config serial console:%s\n", console_string);
     86	}
     87}
     88#endif
     89
     90static void __init mips_nmi_setup(void)
     91{
     92	void *base;
     93
     94	base = cpu_has_veic ?
     95		(void *)(CAC_BASE + 0xa80) :
     96		(void *)(CAC_BASE + 0x380);
     97	memcpy(base, except_vec_nmi, 0x80);
     98	flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
     99}
    100
    101static void __init mips_ejtag_setup(void)
    102{
    103	void *base;
    104	extern char except_vec_ejtag_debug[];
    105
    106	base = cpu_has_veic ?
    107		(void *)(CAC_BASE + 0xa00) :
    108		(void *)(CAC_BASE + 0x300);
    109	memcpy(base, except_vec_ejtag_debug, 0x80);
    110	flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
    111}
    112
    113phys_addr_t mips_cpc_default_phys_base(void)
    114{
    115	return CPC_BASE_ADDR;
    116}
    117
    118void __init prom_init(void)
    119{
    120	/*
    121	 * early setup of _pcictrl_bonito so that we can determine
    122	 * the system controller on a CORE_EMUL board
    123	 */
    124	_pcictrl_bonito = (unsigned long)ioremap(BONITO_REG_BASE, BONITO_REG_SIZE);
    125
    126	mips_revision_corid = MIPS_REVISION_CORID;
    127
    128	if (mips_revision_corid == MIPS_REVISION_CORID_CORE_EMUL) {
    129		if (BONITO_PCIDID == 0x0001df53 ||
    130		    BONITO_PCIDID == 0x0003df53)
    131			mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_BON;
    132		else
    133			mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_MSC;
    134	}
    135
    136	mips_revision_sconid = MIPS_REVISION_SCONID;
    137	if (mips_revision_sconid == MIPS_REVISION_SCON_OTHER) {
    138		switch (mips_revision_corid) {
    139		case MIPS_REVISION_CORID_QED_RM5261:
    140		case MIPS_REVISION_CORID_CORE_LV:
    141		case MIPS_REVISION_CORID_CORE_FPGA:
    142		case MIPS_REVISION_CORID_CORE_FPGAR2:
    143			mips_revision_sconid = MIPS_REVISION_SCON_GT64120;
    144			break;
    145		case MIPS_REVISION_CORID_CORE_EMUL_BON:
    146		case MIPS_REVISION_CORID_BONITO64:
    147		case MIPS_REVISION_CORID_CORE_20K:
    148			mips_revision_sconid = MIPS_REVISION_SCON_BONITO;
    149			break;
    150		case MIPS_REVISION_CORID_CORE_MSC:
    151		case MIPS_REVISION_CORID_CORE_FPGA2:
    152		case MIPS_REVISION_CORID_CORE_24K:
    153			/*
    154			 * SOCit/ROCit support is essentially identical
    155			 * but make an attempt to distinguish them
    156			 */
    157			mips_revision_sconid = MIPS_REVISION_SCON_SOCIT;
    158			break;
    159		case MIPS_REVISION_CORID_CORE_FPGA3:
    160		case MIPS_REVISION_CORID_CORE_FPGA4:
    161		case MIPS_REVISION_CORID_CORE_FPGA5:
    162		case MIPS_REVISION_CORID_CORE_EMUL_MSC:
    163		default:
    164			/* See above */
    165			mips_revision_sconid = MIPS_REVISION_SCON_ROCIT;
    166			break;
    167		}
    168	}
    169
    170	switch (mips_revision_sconid) {
    171		u32 start, map, mask, data;
    172
    173	case MIPS_REVISION_SCON_GT64120:
    174		/*
    175		 * Setup the North bridge to do Master byte-lane swapping
    176		 * when running in bigendian.
    177		 */
    178		_pcictrl_gt64120 = (unsigned long)ioremap(MIPS_GT_BASE, 0x2000);
    179
    180#ifdef CONFIG_CPU_LITTLE_ENDIAN
    181		GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT |
    182			 GT_PCI0_CMD_SBYTESWAP_BIT);
    183#else
    184		GT_WRITE(GT_PCI0_CMD_OFS, 0);
    185#endif
    186		/* Fix up PCI I/O mapping if necessary (for Atlas).  */
    187		start = GT_READ(GT_PCI0IOLD_OFS);
    188		map = GT_READ(GT_PCI0IOREMAP_OFS);
    189		if ((start & map) != 0) {
    190			map &= ~start;
    191			GT_WRITE(GT_PCI0IOREMAP_OFS, map);
    192		}
    193
    194		set_io_port_base(MALTA_GT_PORT_BASE);
    195		break;
    196
    197	case MIPS_REVISION_SCON_BONITO:
    198		_pcictrl_bonito_pcicfg = (unsigned long)ioremap(BONITO_PCICFG_BASE, BONITO_PCICFG_SIZE);
    199
    200		/*
    201		 * Disable Bonito IOBC.
    202		 */
    203		BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG &
    204			~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
    205			  BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
    206
    207		/*
    208		 * Setup the North bridge to do Master byte-lane swapping
    209		 * when running in bigendian.
    210		 */
    211#ifdef CONFIG_CPU_LITTLE_ENDIAN
    212		BONITO_BONGENCFG = BONITO_BONGENCFG &
    213			~(BONITO_BONGENCFG_MSTRBYTESWAP |
    214			  BONITO_BONGENCFG_BYTESWAP);
    215#else
    216		BONITO_BONGENCFG = BONITO_BONGENCFG |
    217			BONITO_BONGENCFG_MSTRBYTESWAP |
    218			BONITO_BONGENCFG_BYTESWAP;
    219#endif
    220
    221		set_io_port_base(MALTA_BONITO_PORT_BASE);
    222		break;
    223
    224	case MIPS_REVISION_SCON_SOCIT:
    225	case MIPS_REVISION_SCON_ROCIT:
    226		_pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000);
    227mips_pci_controller:
    228		mb();
    229		MSC_READ(MSC01_PCI_CFG, data);
    230		MSC_WRITE(MSC01_PCI_CFG, data & ~MSC01_PCI_CFG_EN_BIT);
    231		wmb();
    232
    233		/* Fix up lane swapping.  */
    234#ifdef CONFIG_CPU_LITTLE_ENDIAN
    235		MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP);
    236#else
    237		MSC_WRITE(MSC01_PCI_SWAP,
    238			  MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_IO_SHF |
    239			  MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF |
    240			  MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF);
    241#endif
    242
    243		/*
    244		 * Setup the Malta max (2GB) memory for PCI DMA in host bridge
    245		 * in transparent addressing mode.
    246		 */
    247		mask = PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_PREFETCH;
    248		MSC_WRITE(MSC01_PCI_BAR0, mask);
    249		MSC_WRITE(MSC01_PCI_HEAD4, mask);
    250
    251		mask &= MSC01_PCI_BAR0_SIZE_MSK;
    252		MSC_WRITE(MSC01_PCI_P2SCMSKL, mask);
    253		MSC_WRITE(MSC01_PCI_P2SCMAPL, mask);
    254
    255		/* Don't handle target retries indefinitely.  */
    256		if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) ==
    257		    MSC01_PCI_CFG_MAXRTRY_MSK)
    258			data = (data & ~(MSC01_PCI_CFG_MAXRTRY_MSK <<
    259					 MSC01_PCI_CFG_MAXRTRY_SHF)) |
    260			       ((MSC01_PCI_CFG_MAXRTRY_MSK - 1) <<
    261				MSC01_PCI_CFG_MAXRTRY_SHF);
    262
    263		wmb();
    264		MSC_WRITE(MSC01_PCI_CFG, data);
    265		mb();
    266
    267		set_io_port_base(MALTA_MSC_PORT_BASE);
    268		break;
    269
    270	case MIPS_REVISION_SCON_SOCITSC:
    271	case MIPS_REVISION_SCON_SOCITSCP:
    272		_pcictrl_msc = (unsigned long)ioremap(MIPS_SOCITSC_PCI_REG_BASE, 0x2000);
    273		goto mips_pci_controller;
    274
    275	default:
    276		/* Unknown system controller */
    277		while (1);	/* We die here... */
    278	}
    279	board_nmi_handler_setup = mips_nmi_setup;
    280	board_ejtag_handler_setup = mips_ejtag_setup;
    281
    282	fw_init_cmdline();
    283	fw_meminit();
    284#ifdef CONFIG_SERIAL_8250_CONSOLE
    285	console_config();
    286#endif
    287	/* Early detection of CMP support */
    288	mips_cpc_probe();
    289
    290	if (!register_cps_smp_ops())
    291		return;
    292	if (!register_cmp_smp_ops())
    293		return;
    294	if (!register_vsmp_smp_ops())
    295		return;
    296	register_up_smp_ops();
    297}