/*
* Processor capabilities determination functions.
*
* Copyright (C) xxxx the Anonymous
* Copyright (C) 1994 - 2006 Ralf Baechle
* Copyright (C) 2003, 2004 Maciej W. Rozycki
* Copyright (C) 2001, 2004, 2011, 2012 MIPS Technologies, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ptrace.h>
#include <linux/smp.h>
#include <linux/stddef.h>
#include <linux/export.h>
#include <asm/bugs.h>
#include <asm/cpu.h>
#include <asm/cpu-type.h>
#include <asm/fpu.h>
#include <asm/mipsregs.h>
#include <asm/mipsmtregs.h>
#include <asm/msa.h>
#include <asm/watch.h>
#include <asm/elf.h>
#include <asm/pgtable-bits.h>
#include <asm/spram.h>
#include <asm/uaccess.h>
static int mips_fpu_disabled;
static int __init fpu_disable(char *s)
{
cpu_data[0].options &= ~MIPS_CPU_FPU;
mips_fpu_disabled = 1;
return 1;
}
__setup("nofpu", fpu_disable);
int mips_dsp_disabled;
static int __init dsp_disable(char *s)
{
cpu_data[0].ases &= ~(MIPS_ASE_DSP | MIPS_ASE_DSP2P);
mips_dsp_disabled = 1;
return 1;
}
__setup("nodsp", dsp_disable);
static int mips_htw_disabled;
static int __init htw_disable(char *s)
{
mips_htw_disabled = 1;
cpu_data[0].options &= ~MIPS_CPU_HTW;
write_c0_pwctl(read_c0_pwctl() &
~(1 << MIPS_PWCTL_PWEN_SHIFT));
return 1;
}
__setup("nohtw", htw_disable);
static inline void check_errata(void)
{
struct cpuinfo_mips *c = ¤t_cpu_data;
switch (current_cpu_type()) {
case CPU_34K:
/*
* Erratum "RPS May Cause Incorrect Instruction Execution"
* This code only handles VPE0, any SMP/RTOS code
* making use of VPE1 will be responsable for that VPE.
*/
if ((c->processor_id & PRID_REV_MASK) <= PRID_REV_34K_V1_0_2)
write_c0_config7(read_c0_config7() | MIPS_CONF7_RPS);
break;
default:
break;
}
}
void __init check_bugs32(void)
{
check_errata();
}
/*
* Probe whether cpu has config register by trying to play with
* alternate cache bit and see whether it matters.
* It's used by cpu_probe to distinguish between R3000A and R3081.
*/
static inline int cpu_has_confreg(void)
{
#ifdef CONFIG_CPU_R3000
extern unsigned long r3k_cache_size(unsigned long);
unsigned long size1, size2;
unsigned long cfg = read_c0_conf();
size1 = r3k_cache_size(ST0_ISC);
write_c0_conf(cfg ^ R30XX_CONF_AC);
size2 = r3k_cache_size(ST0_ISC);
write_c0_conf(cfg);
return size1 != size2;
#else
return 0;
#endif
}
static inline void set_elf_platform(int cpu, const char *plat)
{
if (cpu == 0)
__elf_platform = plat;
}
/*
|