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

prom.c (2466B)


      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 */
      8
      9#include <linux/init.h>
     10#include <linux/memblock.h>
     11#include <linux/smp.h>
     12#include <asm/bootinfo.h>
     13#include <asm/bmips.h>
     14#include <asm/smp-ops.h>
     15#include <asm/mipsregs.h>
     16#include <bcm63xx_board.h>
     17#include <bcm63xx_cpu.h>
     18#include <bcm63xx_io.h>
     19#include <bcm63xx_regs.h>
     20
     21void __init prom_init(void)
     22{
     23	u32 reg, mask;
     24
     25	bcm63xx_cpu_init();
     26
     27	/* stop any running watchdog */
     28	bcm_wdt_writel(WDT_STOP_1, WDT_CTL_REG);
     29	bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG);
     30
     31	/* disable all hardware blocks clock for now */
     32	if (BCMCPU_IS_3368())
     33		mask = CKCTL_3368_ALL_SAFE_EN;
     34	else if (BCMCPU_IS_6328())
     35		mask = CKCTL_6328_ALL_SAFE_EN;
     36	else if (BCMCPU_IS_6338())
     37		mask = CKCTL_6338_ALL_SAFE_EN;
     38	else if (BCMCPU_IS_6345())
     39		mask = CKCTL_6345_ALL_SAFE_EN;
     40	else if (BCMCPU_IS_6348())
     41		mask = CKCTL_6348_ALL_SAFE_EN;
     42	else if (BCMCPU_IS_6358())
     43		mask = CKCTL_6358_ALL_SAFE_EN;
     44	else if (BCMCPU_IS_6362())
     45		mask = CKCTL_6362_ALL_SAFE_EN;
     46	else if (BCMCPU_IS_6368())
     47		mask = CKCTL_6368_ALL_SAFE_EN;
     48	else
     49		mask = 0;
     50
     51	reg = bcm_perf_readl(PERF_CKCTL_REG);
     52	reg &= ~mask;
     53	bcm_perf_writel(reg, PERF_CKCTL_REG);
     54
     55	/* do low level board init */
     56	board_prom_init();
     57
     58	/* set up SMP */
     59	if (!register_bmips_smp_ops()) {
     60		/*
     61		 * BCM6328 might not have its second CPU enabled, while BCM3368
     62		 * and BCM6358 need special handling for their shared TLB, so
     63		 * disable SMP for now.
     64		 */
     65		if (BCMCPU_IS_6328()) {
     66			reg = bcm_readl(BCM_6328_OTP_BASE +
     67					OTP_USER_BITS_6328_REG(3));
     68
     69			if (reg & OTP_6328_REG3_TP1_DISABLED)
     70				bmips_smp_enabled = 0;
     71		} else if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) {
     72			bmips_smp_enabled = 0;
     73		}
     74
     75		if (!bmips_smp_enabled)
     76			return;
     77
     78		/*
     79		 * The bootloader has set up the CPU1 reset vector at
     80		 * 0xa000_0200.
     81		 * This conflicts with the special interrupt vector (IV).
     82		 * The bootloader has also set up CPU1 to respond to the wrong
     83		 * IPI interrupt.
     84		 * Here we will start up CPU1 in the background and ask it to
     85		 * reconfigure itself then go back to sleep.
     86		 */
     87		memcpy((void *)0xa0000200, bmips_smp_movevec, 0x20);
     88		__sync();
     89		set_c0_cause(C_SW0);
     90		cpumask_set_cpu(1, &bmips_booted_mask);
     91
     92		/*
     93		 * FIXME: we really should have some sort of hazard barrier here
     94		 */
     95	}
     96}