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

smp-bmips.c (16873B)


      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) 2011 by Kevin Cernekee (cernekee@gmail.com)
      7 *
      8 * SMP support for BMIPS
      9 */
     10
     11#include <linux/init.h>
     12#include <linux/sched.h>
     13#include <linux/sched/hotplug.h>
     14#include <linux/sched/task_stack.h>
     15#include <linux/mm.h>
     16#include <linux/delay.h>
     17#include <linux/smp.h>
     18#include <linux/interrupt.h>
     19#include <linux/spinlock.h>
     20#include <linux/cpu.h>
     21#include <linux/cpumask.h>
     22#include <linux/reboot.h>
     23#include <linux/io.h>
     24#include <linux/compiler.h>
     25#include <linux/linkage.h>
     26#include <linux/bug.h>
     27#include <linux/kernel.h>
     28#include <linux/kexec.h>
     29#include <linux/irq.h>
     30
     31#include <asm/time.h>
     32#include <asm/processor.h>
     33#include <asm/bootinfo.h>
     34#include <asm/cacheflush.h>
     35#include <asm/tlbflush.h>
     36#include <asm/mipsregs.h>
     37#include <asm/bmips.h>
     38#include <asm/traps.h>
     39#include <asm/barrier.h>
     40#include <asm/cpu-features.h>
     41
     42static int __maybe_unused max_cpus = 1;
     43
     44/* these may be configured by the platform code */
     45int bmips_smp_enabled = 1;
     46int bmips_cpu_offset;
     47cpumask_t bmips_booted_mask;
     48unsigned long bmips_tp1_irqs = IE_IRQ1;
     49
     50#define RESET_FROM_KSEG0		0x80080800
     51#define RESET_FROM_KSEG1		0xa0080800
     52
     53static void bmips_set_reset_vec(int cpu, u32 val);
     54
     55#ifdef CONFIG_SMP
     56
     57/* initial $sp, $gp - used by arch/mips/kernel/bmips_vec.S */
     58unsigned long bmips_smp_boot_sp;
     59unsigned long bmips_smp_boot_gp;
     60
     61static void bmips43xx_send_ipi_single(int cpu, unsigned int action);
     62static void bmips5000_send_ipi_single(int cpu, unsigned int action);
     63static irqreturn_t bmips43xx_ipi_interrupt(int irq, void *dev_id);
     64static irqreturn_t bmips5000_ipi_interrupt(int irq, void *dev_id);
     65
     66/* SW interrupts 0,1 are used for interprocessor signaling */
     67#define IPI0_IRQ			(MIPS_CPU_IRQ_BASE + 0)
     68#define IPI1_IRQ			(MIPS_CPU_IRQ_BASE + 1)
     69
     70#define CPUNUM(cpu, shift)		(((cpu) + bmips_cpu_offset) << (shift))
     71#define ACTION_CLR_IPI(cpu, ipi)	(0x2000 | CPUNUM(cpu, 9) | ((ipi) << 8))
     72#define ACTION_SET_IPI(cpu, ipi)	(0x3000 | CPUNUM(cpu, 9) | ((ipi) << 8))
     73#define ACTION_BOOT_THREAD(cpu)		(0x08 | CPUNUM(cpu, 0))
     74
     75static void __init bmips_smp_setup(void)
     76{
     77	int i, cpu = 1, boot_cpu = 0;
     78	int cpu_hw_intr;
     79
     80	switch (current_cpu_type()) {
     81	case CPU_BMIPS4350:
     82	case CPU_BMIPS4380:
     83		/* arbitration priority */
     84		clear_c0_brcm_cmt_ctrl(0x30);
     85
     86		/* NBK and weak order flags */
     87		set_c0_brcm_config_0(0x30000);
     88
     89		/* Find out if we are running on TP0 or TP1 */
     90		boot_cpu = !!(read_c0_brcm_cmt_local() & (1 << 31));
     91
     92		/*
     93		 * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other
     94		 * thread
     95		 * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
     96		 * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
     97		 */
     98		if (boot_cpu == 0)
     99			cpu_hw_intr = 0x02;
    100		else
    101			cpu_hw_intr = 0x1d;
    102
    103		change_c0_brcm_cmt_intr(0xf8018000,
    104					(cpu_hw_intr << 27) | (0x03 << 15));
    105
    106		/* single core, 2 threads (2 pipelines) */
    107		max_cpus = 2;
    108
    109		break;
    110	case CPU_BMIPS5000:
    111		/* enable raceless SW interrupts */
    112		set_c0_brcm_config(0x03 << 22);
    113
    114		/* route HW interrupt 0 to CPU0, HW interrupt 1 to CPU1 */
    115		change_c0_brcm_mode(0x1f << 27, 0x02 << 27);
    116
    117		/* N cores, 2 threads per core */
    118		max_cpus = (((read_c0_brcm_config() >> 6) & 0x03) + 1) << 1;
    119
    120		/* clear any pending SW interrupts */
    121		for (i = 0; i < max_cpus; i++) {
    122			write_c0_brcm_action(ACTION_CLR_IPI(i, 0));
    123			write_c0_brcm_action(ACTION_CLR_IPI(i, 1));
    124		}
    125
    126		break;
    127	default:
    128		max_cpus = 1;
    129	}
    130
    131	if (!bmips_smp_enabled)
    132		max_cpus = 1;
    133
    134	/* this can be overridden by the BSP */
    135	if (!board_ebase_setup)
    136		board_ebase_setup = &bmips_ebase_setup;
    137
    138	if (max_cpus > 1) {
    139		__cpu_number_map[boot_cpu] = 0;
    140		__cpu_logical_map[0] = boot_cpu;
    141
    142		for (i = 0; i < max_cpus; i++) {
    143			if (i != boot_cpu) {
    144				__cpu_number_map[i] = cpu;
    145				__cpu_logical_map[cpu] = i;
    146				cpu++;
    147			}
    148			set_cpu_possible(i, 1);
    149			set_cpu_present(i, 1);
    150		}
    151	} else {
    152		__cpu_number_map[0] = boot_cpu;
    153		__cpu_logical_map[0] = 0;
    154		set_cpu_possible(0, 1);
    155		set_cpu_present(0, 1);
    156	}
    157}
    158
    159/*
    160 * IPI IRQ setup - runs on CPU0
    161 */
    162static void bmips_prepare_cpus(unsigned int max_cpus)
    163{
    164	irqreturn_t (*bmips_ipi_interrupt)(int irq, void *dev_id);
    165
    166	switch (current_cpu_type()) {
    167	case CPU_BMIPS4350:
    168	case CPU_BMIPS4380:
    169		bmips_ipi_interrupt = bmips43xx_ipi_interrupt;
    170		break;
    171	case CPU_BMIPS5000:
    172		bmips_ipi_interrupt = bmips5000_ipi_interrupt;
    173		break;
    174	default:
    175		return;
    176	}
    177
    178	if (request_irq(IPI0_IRQ, bmips_ipi_interrupt,
    179			IRQF_PERCPU | IRQF_NO_SUSPEND, "smp_ipi0", NULL))
    180		panic("Can't request IPI0 interrupt");
    181	if (request_irq(IPI1_IRQ, bmips_ipi_interrupt,
    182			IRQF_PERCPU | IRQF_NO_SUSPEND, "smp_ipi1", NULL))
    183		panic("Can't request IPI1 interrupt");
    184}
    185
    186/*
    187 * Tell the hardware to boot CPUx - runs on CPU0
    188 */
    189static int bmips_boot_secondary(int cpu, struct task_struct *idle)
    190{
    191	bmips_smp_boot_sp = __KSTK_TOS(idle);
    192	bmips_smp_boot_gp = (unsigned long)task_thread_info(idle);
    193	mb();
    194
    195	/*
    196	 * Initial boot sequence for secondary CPU:
    197	 *   bmips_reset_nmi_vec @ a000_0000 ->
    198	 *   bmips_smp_entry ->
    199	 *   plat_wired_tlb_setup (cached function call; optional) ->
    200	 *   start_secondary (cached jump)
    201	 *
    202	 * Warm restart sequence:
    203	 *   play_dead WAIT loop ->
    204	 *   bmips_smp_int_vec @ BMIPS_WARM_RESTART_VEC ->
    205	 *   eret to play_dead ->
    206	 *   bmips_secondary_reentry ->
    207	 *   start_secondary
    208	 */
    209
    210	pr_info("SMP: Booting CPU%d...\n", cpu);
    211
    212	if (cpumask_test_cpu(cpu, &bmips_booted_mask)) {
    213		/* kseg1 might not exist if this CPU enabled XKS01 */
    214		bmips_set_reset_vec(cpu, RESET_FROM_KSEG0);
    215
    216		switch (current_cpu_type()) {
    217		case CPU_BMIPS4350:
    218		case CPU_BMIPS4380:
    219			bmips43xx_send_ipi_single(cpu, 0);
    220			break;
    221		case CPU_BMIPS5000:
    222			bmips5000_send_ipi_single(cpu, 0);
    223			break;
    224		}
    225	} else {
    226		bmips_set_reset_vec(cpu, RESET_FROM_KSEG1);
    227
    228		switch (current_cpu_type()) {
    229		case CPU_BMIPS4350:
    230		case CPU_BMIPS4380:
    231			/* Reset slave TP1 if booting from TP0 */
    232			if (cpu_logical_map(cpu) == 1)
    233				set_c0_brcm_cmt_ctrl(0x01);
    234			break;
    235		case CPU_BMIPS5000:
    236			write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
    237			break;
    238		}
    239		cpumask_set_cpu(cpu, &bmips_booted_mask);
    240	}
    241
    242	return 0;
    243}
    244
    245/*
    246 * Early setup - runs on secondary CPU after cache probe
    247 */
    248static void bmips_init_secondary(void)
    249{
    250	bmips_cpu_setup();
    251
    252	switch (current_cpu_type()) {
    253	case CPU_BMIPS4350:
    254	case CPU_BMIPS4380:
    255		clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
    256		break;
    257	case CPU_BMIPS5000:
    258		write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
    259		cpu_set_core(&current_cpu_data, (read_c0_brcm_config() >> 25) & 3);
    260		break;
    261	}
    262}
    263
    264/*
    265 * Late setup - runs on secondary CPU before entering the idle loop
    266 */
    267static void bmips_smp_finish(void)
    268{
    269	pr_info("SMP: CPU%d is running\n", smp_processor_id());
    270
    271	/* make sure there won't be a timer interrupt for a little while */
    272	write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ);
    273
    274	irq_enable_hazard();
    275	set_c0_status(IE_SW0 | IE_SW1 | bmips_tp1_irqs | IE_IRQ5 | ST0_IE);
    276	irq_enable_hazard();
    277}
    278
    279/*
    280 * BMIPS5000 raceless IPIs
    281 *
    282 * Each CPU has two inbound SW IRQs which are independent of all other CPUs.
    283 * IPI0 is used for SMP_RESCHEDULE_YOURSELF
    284 * IPI1 is used for SMP_CALL_FUNCTION
    285 */
    286
    287static void bmips5000_send_ipi_single(int cpu, unsigned int action)
    288{
    289	write_c0_brcm_action(ACTION_SET_IPI(cpu, action == SMP_CALL_FUNCTION));
    290}
    291
    292static irqreturn_t bmips5000_ipi_interrupt(int irq, void *dev_id)
    293{
    294	int action = irq - IPI0_IRQ;
    295
    296	write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), action));
    297
    298	if (action == 0)
    299		scheduler_ipi();
    300	else
    301		generic_smp_call_function_interrupt();
    302
    303	return IRQ_HANDLED;
    304}
    305
    306static void bmips5000_send_ipi_mask(const struct cpumask *mask,
    307	unsigned int action)
    308{
    309	unsigned int i;
    310
    311	for_each_cpu(i, mask)
    312		bmips5000_send_ipi_single(i, action);
    313}
    314
    315/*
    316 * BMIPS43xx racey IPIs
    317 *
    318 * We use one inbound SW IRQ for each CPU.
    319 *
    320 * A spinlock must be held in order to keep CPUx from accidentally clearing
    321 * an incoming IPI when it writes CP0 CAUSE to raise an IPI on CPUy.  The
    322 * same spinlock is used to protect the action masks.
    323 */
    324
    325static DEFINE_SPINLOCK(ipi_lock);
    326static DEFINE_PER_CPU(int, ipi_action_mask);
    327
    328static void bmips43xx_send_ipi_single(int cpu, unsigned int action)
    329{
    330	unsigned long flags;
    331
    332	spin_lock_irqsave(&ipi_lock, flags);
    333	set_c0_cause(cpu ? C_SW1 : C_SW0);
    334	per_cpu(ipi_action_mask, cpu) |= action;
    335	irq_enable_hazard();
    336	spin_unlock_irqrestore(&ipi_lock, flags);
    337}
    338
    339static irqreturn_t bmips43xx_ipi_interrupt(int irq, void *dev_id)
    340{
    341	unsigned long flags;
    342	int action, cpu = irq - IPI0_IRQ;
    343
    344	spin_lock_irqsave(&ipi_lock, flags);
    345	action = __this_cpu_read(ipi_action_mask);
    346	per_cpu(ipi_action_mask, cpu) = 0;
    347	clear_c0_cause(cpu ? C_SW1 : C_SW0);
    348	spin_unlock_irqrestore(&ipi_lock, flags);
    349
    350	if (action & SMP_RESCHEDULE_YOURSELF)
    351		scheduler_ipi();
    352	if (action & SMP_CALL_FUNCTION)
    353		generic_smp_call_function_interrupt();
    354
    355	return IRQ_HANDLED;
    356}
    357
    358static void bmips43xx_send_ipi_mask(const struct cpumask *mask,
    359	unsigned int action)
    360{
    361	unsigned int i;
    362
    363	for_each_cpu(i, mask)
    364		bmips43xx_send_ipi_single(i, action);
    365}
    366
    367#ifdef CONFIG_HOTPLUG_CPU
    368
    369static int bmips_cpu_disable(void)
    370{
    371	unsigned int cpu = smp_processor_id();
    372
    373	pr_info("SMP: CPU%d is offline\n", cpu);
    374
    375	set_cpu_online(cpu, false);
    376	calculate_cpu_foreign_map();
    377	irq_migrate_all_off_this_cpu();
    378	clear_c0_status(IE_IRQ5);
    379
    380	local_flush_tlb_all();
    381	local_flush_icache_range(0, ~0);
    382
    383	return 0;
    384}
    385
    386static void bmips_cpu_die(unsigned int cpu)
    387{
    388}
    389
    390void __ref play_dead(void)
    391{
    392	idle_task_exit();
    393
    394	/* flush data cache */
    395	_dma_cache_wback_inv(0, ~0);
    396
    397	/*
    398	 * Wakeup is on SW0 or SW1; disable everything else
    399	 * Use BEV !IV (BMIPS_WARM_RESTART_VEC) to avoid the regular Linux
    400	 * IRQ handlers; this clears ST0_IE and returns immediately.
    401	 */
    402	clear_c0_cause(CAUSEF_IV | C_SW0 | C_SW1);
    403	change_c0_status(
    404		IE_IRQ5 | bmips_tp1_irqs | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV,
    405		IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV);
    406	irq_disable_hazard();
    407
    408	/*
    409	 * wait for SW interrupt from bmips_boot_secondary(), then jump
    410	 * back to start_secondary()
    411	 */
    412	__asm__ __volatile__(
    413	"	wait\n"
    414	"	j	bmips_secondary_reentry\n"
    415	: : : "memory");
    416}
    417
    418#endif /* CONFIG_HOTPLUG_CPU */
    419
    420const struct plat_smp_ops bmips43xx_smp_ops = {
    421	.smp_setup		= bmips_smp_setup,
    422	.prepare_cpus		= bmips_prepare_cpus,
    423	.boot_secondary		= bmips_boot_secondary,
    424	.smp_finish		= bmips_smp_finish,
    425	.init_secondary		= bmips_init_secondary,
    426	.send_ipi_single	= bmips43xx_send_ipi_single,
    427	.send_ipi_mask		= bmips43xx_send_ipi_mask,
    428#ifdef CONFIG_HOTPLUG_CPU
    429	.cpu_disable		= bmips_cpu_disable,
    430	.cpu_die		= bmips_cpu_die,
    431#endif
    432#ifdef CONFIG_KEXEC
    433	.kexec_nonboot_cpu	= kexec_nonboot_cpu_jump,
    434#endif
    435};
    436
    437const struct plat_smp_ops bmips5000_smp_ops = {
    438	.smp_setup		= bmips_smp_setup,
    439	.prepare_cpus		= bmips_prepare_cpus,
    440	.boot_secondary		= bmips_boot_secondary,
    441	.smp_finish		= bmips_smp_finish,
    442	.init_secondary		= bmips_init_secondary,
    443	.send_ipi_single	= bmips5000_send_ipi_single,
    444	.send_ipi_mask		= bmips5000_send_ipi_mask,
    445#ifdef CONFIG_HOTPLUG_CPU
    446	.cpu_disable		= bmips_cpu_disable,
    447	.cpu_die		= bmips_cpu_die,
    448#endif
    449#ifdef CONFIG_KEXEC
    450	.kexec_nonboot_cpu	= kexec_nonboot_cpu_jump,
    451#endif
    452};
    453
    454#endif /* CONFIG_SMP */
    455
    456/***********************************************************************
    457 * BMIPS vector relocation
    458 * This is primarily used for SMP boot, but it is applicable to some
    459 * UP BMIPS systems as well.
    460 ***********************************************************************/
    461
    462static void bmips_wr_vec(unsigned long dst, char *start, char *end)
    463{
    464	memcpy((void *)dst, start, end - start);
    465	dma_cache_wback(dst, end - start);
    466	local_flush_icache_range(dst, dst + (end - start));
    467	instruction_hazard();
    468}
    469
    470static inline void bmips_nmi_handler_setup(void)
    471{
    472	bmips_wr_vec(BMIPS_NMI_RESET_VEC, bmips_reset_nmi_vec,
    473		bmips_reset_nmi_vec_end);
    474	bmips_wr_vec(BMIPS_WARM_RESTART_VEC, bmips_smp_int_vec,
    475		bmips_smp_int_vec_end);
    476}
    477
    478struct reset_vec_info {
    479	int cpu;
    480	u32 val;
    481};
    482
    483static void bmips_set_reset_vec_remote(void *vinfo)
    484{
    485	struct reset_vec_info *info = vinfo;
    486	int shift = info->cpu & 0x01 ? 16 : 0;
    487	u32 mask = ~(0xffff << shift), val = info->val >> 16;
    488
    489	preempt_disable();
    490	if (smp_processor_id() > 0) {
    491		smp_call_function_single(0, &bmips_set_reset_vec_remote,
    492					 info, 1);
    493	} else {
    494		if (info->cpu & 0x02) {
    495			/* BMIPS5200 "should" use mask/shift, but it's buggy */
    496			bmips_write_zscm_reg(0xa0, (val << 16) | val);
    497			bmips_read_zscm_reg(0xa0);
    498		} else {
    499			write_c0_brcm_bootvec((read_c0_brcm_bootvec() & mask) |
    500					      (val << shift));
    501		}
    502	}
    503	preempt_enable();
    504}
    505
    506static void bmips_set_reset_vec(int cpu, u32 val)
    507{
    508	struct reset_vec_info info;
    509
    510	if (current_cpu_type() == CPU_BMIPS5000) {
    511		/* this needs to run from CPU0 (which is always online) */
    512		info.cpu = cpu;
    513		info.val = val;
    514		bmips_set_reset_vec_remote(&info);
    515	} else {
    516		void __iomem *cbr = BMIPS_GET_CBR();
    517
    518		if (cpu == 0)
    519			__raw_writel(val, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
    520		else {
    521			if (current_cpu_type() != CPU_BMIPS4380)
    522				return;
    523			__raw_writel(val, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
    524		}
    525	}
    526	__sync();
    527	back_to_back_c0_hazard();
    528}
    529
    530void bmips_ebase_setup(void)
    531{
    532	unsigned long new_ebase = ebase;
    533
    534	BUG_ON(ebase != CKSEG0);
    535
    536	switch (current_cpu_type()) {
    537	case CPU_BMIPS4350:
    538		/*
    539		 * BMIPS4350 cannot relocate the normal vectors, but it
    540		 * can relocate the BEV=1 vectors.  So CPU1 starts up at
    541		 * the relocated BEV=1, IV=0 general exception vector @
    542		 * 0xa000_0380.
    543		 *
    544		 * set_uncached_handler() is used here because:
    545		 *  - CPU1 will run this from uncached space
    546		 *  - None of the cacheflush functions are set up yet
    547		 */
    548		set_uncached_handler(BMIPS_WARM_RESTART_VEC - CKSEG0,
    549			&bmips_smp_int_vec, 0x80);
    550		__sync();
    551		return;
    552	case CPU_BMIPS3300:
    553	case CPU_BMIPS4380:
    554		/*
    555		 * 0x8000_0000: reset/NMI (initially in kseg1)
    556		 * 0x8000_0400: normal vectors
    557		 */
    558		new_ebase = 0x80000400;
    559		bmips_set_reset_vec(0, RESET_FROM_KSEG0);
    560		break;
    561	case CPU_BMIPS5000:
    562		/*
    563		 * 0x8000_0000: reset/NMI (initially in kseg1)
    564		 * 0x8000_1000: normal vectors
    565		 */
    566		new_ebase = 0x80001000;
    567		bmips_set_reset_vec(0, RESET_FROM_KSEG0);
    568		write_c0_ebase(new_ebase);
    569		break;
    570	default:
    571		return;
    572	}
    573
    574	board_nmi_handler_setup = &bmips_nmi_handler_setup;
    575	ebase = new_ebase;
    576}
    577
    578asmlinkage void __weak plat_wired_tlb_setup(void)
    579{
    580	/*
    581	 * Called when starting/restarting a secondary CPU.
    582	 * Kernel stacks and other important data might only be accessible
    583	 * once the wired entries are present.
    584	 */
    585}
    586
    587void bmips_cpu_setup(void)
    588{
    589	void __iomem __maybe_unused *cbr = BMIPS_GET_CBR();
    590	u32 __maybe_unused cfg;
    591
    592	switch (current_cpu_type()) {
    593	case CPU_BMIPS3300:
    594		/* Set BIU to async mode */
    595		set_c0_brcm_bus_pll(BIT(22));
    596		__sync();
    597
    598		/* put the BIU back in sync mode */
    599		clear_c0_brcm_bus_pll(BIT(22));
    600
    601		/* clear BHTD to enable branch history table */
    602		clear_c0_brcm_reset(BIT(16));
    603
    604		/* Flush and enable RAC */
    605		cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG);
    606		__raw_writel(cfg | 0x100, cbr + BMIPS_RAC_CONFIG);
    607		__raw_readl(cbr + BMIPS_RAC_CONFIG);
    608
    609		cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG);
    610		__raw_writel(cfg | 0xf, cbr + BMIPS_RAC_CONFIG);
    611		__raw_readl(cbr + BMIPS_RAC_CONFIG);
    612
    613		cfg = __raw_readl(cbr + BMIPS_RAC_ADDRESS_RANGE);
    614		__raw_writel(cfg | 0x0fff0000, cbr + BMIPS_RAC_ADDRESS_RANGE);
    615		__raw_readl(cbr + BMIPS_RAC_ADDRESS_RANGE);
    616		break;
    617
    618	case CPU_BMIPS4380:
    619		/* CBG workaround for early BMIPS4380 CPUs */
    620		switch (read_c0_prid()) {
    621		case 0x2a040:
    622		case 0x2a042:
    623		case 0x2a044:
    624		case 0x2a060:
    625			cfg = __raw_readl(cbr + BMIPS_L2_CONFIG);
    626			__raw_writel(cfg & ~0x07000000, cbr + BMIPS_L2_CONFIG);
    627			__raw_readl(cbr + BMIPS_L2_CONFIG);
    628		}
    629
    630		/* clear BHTD to enable branch history table */
    631		clear_c0_brcm_config_0(BIT(21));
    632
    633		/* XI/ROTR enable */
    634		set_c0_brcm_config_0(BIT(23));
    635		set_c0_brcm_cmt_ctrl(BIT(15));
    636		break;
    637
    638	case CPU_BMIPS5000:
    639		/* enable RDHWR, BRDHWR */
    640		set_c0_brcm_config(BIT(17) | BIT(21));
    641
    642		/* Disable JTB */
    643		__asm__ __volatile__(
    644		"	.set	noreorder\n"
    645		"	li	$8, 0x5a455048\n"
    646		"	.word	0x4088b00f\n"	/* mtc0	t0, $22, 15 */
    647		"	.word	0x4008b008\n"	/* mfc0	t0, $22, 8 */
    648		"	li	$9, 0x00008000\n"
    649		"	or	$8, $8, $9\n"
    650		"	.word	0x4088b008\n"	/* mtc0	t0, $22, 8 */
    651		"	sync\n"
    652		"	li	$8, 0x0\n"
    653		"	.word	0x4088b00f\n"	/* mtc0	t0, $22, 15 */
    654		"	.set	reorder\n"
    655		: : : "$8", "$9");
    656
    657		/* XI enable */
    658		set_c0_brcm_config(BIT(27));
    659
    660		/* enable MIPS32R2 ROR instruction for XI TLB handlers */
    661		__asm__ __volatile__(
    662		"	li	$8, 0x5a455048\n"
    663		"	.word	0x4088b00f\n"	/* mtc0 $8, $22, 15 */
    664		"	nop; nop; nop\n"
    665		"	.word	0x4008b008\n"	/* mfc0 $8, $22, 8 */
    666		"	lui	$9, 0x0100\n"
    667		"	or	$8, $9\n"
    668		"	.word	0x4088b008\n"	/* mtc0 $8, $22, 8 */
    669		: : : "$8", "$9");
    670		break;
    671	}
    672}