0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/init.h>
0011 #include <linux/kernel.h>
0012 #include <linux/ptrace.h>
0013 #include <linux/smp.h>
0014 #include <linux/stddef.h>
0015 #include <linux/export.h>
0016
0017 #include <asm/bugs.h>
0018 #include <asm/cpu.h>
0019 #include <asm/cpu-features.h>
0020 #include <asm/cpu-type.h>
0021 #include <asm/fpu.h>
0022 #include <asm/mipsregs.h>
0023 #include <asm/elf.h>
0024 #include <asm/traps.h>
0025
0026 #include "fpu-probe.h"
0027
0028
0029 unsigned int elf_hwcap __read_mostly;
0030 EXPORT_SYMBOL_GPL(elf_hwcap);
0031
0032 void __init check_bugs32(void)
0033 {
0034
0035 }
0036
0037
0038
0039
0040
0041
0042 static inline int cpu_has_confreg(void)
0043 {
0044 #ifdef CONFIG_CPU_R3000
0045 extern unsigned long r3k_cache_size(unsigned long);
0046 unsigned long size1, size2;
0047 unsigned long cfg = read_c0_conf();
0048
0049 size1 = r3k_cache_size(ST0_ISC);
0050 write_c0_conf(cfg ^ R30XX_CONF_AC);
0051 size2 = r3k_cache_size(ST0_ISC);
0052 write_c0_conf(cfg);
0053 return size1 != size2;
0054 #else
0055 return 0;
0056 #endif
0057 }
0058
0059 static inline void set_elf_platform(int cpu, const char *plat)
0060 {
0061 if (cpu == 0)
0062 __elf_platform = plat;
0063 }
0064
0065 const char *__cpu_name[NR_CPUS];
0066 const char *__elf_platform;
0067 const char *__elf_base_platform;
0068
0069 void cpu_probe(void)
0070 {
0071 struct cpuinfo_mips *c = ¤t_cpu_data;
0072 unsigned int cpu = smp_processor_id();
0073
0074
0075
0076
0077
0078 set_elf_platform(cpu, "mips");
0079
0080 c->processor_id = PRID_IMP_UNKNOWN;
0081 c->fpu_id = FPIR_IMP_NONE;
0082 c->cputype = CPU_UNKNOWN;
0083 c->writecombine = _CACHE_UNCACHED;
0084
0085 c->fpu_csr31 = FPU_CSR_RN;
0086 c->fpu_msk31 = FPU_CSR_RSVD | FPU_CSR_ABS2008 | FPU_CSR_NAN2008 |
0087 FPU_CSR_CONDX | FPU_CSR_FS;
0088
0089 c->srsets = 1;
0090
0091 c->processor_id = read_c0_prid();
0092 switch (c->processor_id & (PRID_COMP_MASK | PRID_IMP_MASK)) {
0093 case PRID_COMP_LEGACY | PRID_IMP_R2000:
0094 c->cputype = CPU_R2000;
0095 __cpu_name[cpu] = "R2000";
0096 c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
0097 MIPS_CPU_NOFPUEX;
0098 if (__cpu_has_fpu())
0099 c->options |= MIPS_CPU_FPU;
0100 c->tlbsize = 64;
0101 break;
0102 case PRID_COMP_LEGACY | PRID_IMP_R3000:
0103 if ((c->processor_id & PRID_REV_MASK) == PRID_REV_R3000A) {
0104 if (cpu_has_confreg()) {
0105 c->cputype = CPU_R3081E;
0106 __cpu_name[cpu] = "R3081";
0107 } else {
0108 c->cputype = CPU_R3000A;
0109 __cpu_name[cpu] = "R3000A";
0110 }
0111 } else {
0112 c->cputype = CPU_R3000;
0113 __cpu_name[cpu] = "R3000";
0114 }
0115 c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
0116 MIPS_CPU_NOFPUEX;
0117 if (__cpu_has_fpu())
0118 c->options |= MIPS_CPU_FPU;
0119 c->tlbsize = 64;
0120 break;
0121 }
0122
0123 BUG_ON(!__cpu_name[cpu]);
0124 BUG_ON(c->cputype == CPU_UNKNOWN);
0125
0126
0127
0128
0129
0130
0131 BUG_ON(current_cpu_type() != c->cputype);
0132
0133 if (mips_fpu_disabled)
0134 c->options &= ~MIPS_CPU_FPU;
0135
0136 if (c->options & MIPS_CPU_FPU)
0137 cpu_set_fpu_opts(c);
0138 else
0139 cpu_set_nofpu_opts(c);
0140
0141 reserve_exception_space(0, 0x400);
0142 }
0143
0144 void cpu_report(void)
0145 {
0146 struct cpuinfo_mips *c = ¤t_cpu_data;
0147
0148 pr_info("CPU%d revision is: %08x (%s)\n",
0149 smp_processor_id(), c->processor_id, cpu_name_string());
0150 if (c->options & MIPS_CPU_FPU)
0151 pr_info("FPU revision is: %08x\n", c->fpu_id);
0152 }