1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Processor capabilities determination functions.
5 * Copyright (C) xxxx the Anonymous
6 * Copyright (C) 1994 - 2006 Ralf Baechle
7 * Copyright (C) 2003, 2004 Maciej W. Rozycki
8 * Copyright (C) 2001, 2004, 2011, 2012 MIPS Technologies, Inc.
10 #include <linux/init.h>
11 #include <linux/kernel.h>
12 #include <linux/ptrace.h>
13 #include <linux/smp.h>
14 #include <linux/stddef.h>
15 #include <linux/export.h>
19 #include <asm/cpu-features.h>
20 #include <asm/cpu-type.h>
22 #include <asm/mipsregs.h>
25 #include "fpu-probe.h"
27 /* Hardware capabilities */
28 unsigned int elf_hwcap __read_mostly
;
29 EXPORT_SYMBOL_GPL(elf_hwcap
);
31 void __init
check_bugs32(void)
37 * Probe whether cpu has config register by trying to play with
38 * alternate cache bit and see whether it matters.
39 * It's used by cpu_probe to distinguish between R3000A and R3081.
41 static inline int cpu_has_confreg(void)
43 #ifdef CONFIG_CPU_R3000
44 extern unsigned long r3k_cache_size(unsigned long);
45 unsigned long size1
, size2
;
46 unsigned long cfg
= read_c0_conf();
48 size1
= r3k_cache_size(ST0_ISC
);
49 write_c0_conf(cfg
^ R30XX_CONF_AC
);
50 size2
= r3k_cache_size(ST0_ISC
);
52 return size1
!= size2
;
58 static inline void set_elf_platform(int cpu
, const char *plat
)
61 __elf_platform
= plat
;
64 const char *__cpu_name
[NR_CPUS
];
65 const char *__elf_platform
;
66 const char *__elf_base_platform
;
70 struct cpuinfo_mips
*c
= ¤t_cpu_data
;
71 unsigned int cpu
= smp_processor_id();
74 * Set a default elf platform, cpu probe may later
75 * overwrite it with a more precise value
77 set_elf_platform(cpu
, "mips");
79 c
->processor_id
= PRID_IMP_UNKNOWN
;
80 c
->fpu_id
= FPIR_IMP_NONE
;
81 c
->cputype
= CPU_UNKNOWN
;
82 c
->writecombine
= _CACHE_UNCACHED
;
84 c
->fpu_csr31
= FPU_CSR_RN
;
85 c
->fpu_msk31
= FPU_CSR_RSVD
| FPU_CSR_ABS2008
| FPU_CSR_NAN2008
|
86 FPU_CSR_CONDX
| FPU_CSR_FS
;
90 c
->processor_id
= read_c0_prid();
91 switch (c
->processor_id
& (PRID_COMP_MASK
| PRID_IMP_MASK
)) {
92 case PRID_COMP_LEGACY
| PRID_IMP_R2000
:
93 c
->cputype
= CPU_R2000
;
94 __cpu_name
[cpu
] = "R2000";
95 c
->options
= MIPS_CPU_TLB
| MIPS_CPU_3K_CACHE
|
98 c
->options
|= MIPS_CPU_FPU
;
101 case PRID_COMP_LEGACY
| PRID_IMP_R3000
:
102 if ((c
->processor_id
& PRID_REV_MASK
) == PRID_REV_R3000A
) {
103 if (cpu_has_confreg()) {
104 c
->cputype
= CPU_R3081E
;
105 __cpu_name
[cpu
] = "R3081";
107 c
->cputype
= CPU_R3000A
;
108 __cpu_name
[cpu
] = "R3000A";
111 c
->cputype
= CPU_R3000
;
112 __cpu_name
[cpu
] = "R3000";
114 c
->options
= MIPS_CPU_TLB
| MIPS_CPU_3K_CACHE
|
117 c
->options
|= MIPS_CPU_FPU
;
120 case PRID_COMP_LEGACY
| PRID_IMP_TX39
:
121 c
->options
= MIPS_CPU_TLB
| MIPS_CPU_TX39_CACHE
;
123 if ((c
->processor_id
& 0xf0) == (PRID_REV_TX3927
& 0xf0)) {
124 c
->cputype
= CPU_TX3927
;
125 __cpu_name
[cpu
] = "TX3927";
128 switch (c
->processor_id
& PRID_REV_MASK
) {
129 case PRID_REV_TX3912
:
130 c
->cputype
= CPU_TX3912
;
131 __cpu_name
[cpu
] = "TX3912";
134 case PRID_REV_TX3922
:
135 c
->cputype
= CPU_TX3922
;
136 __cpu_name
[cpu
] = "TX3922";
144 BUG_ON(!__cpu_name
[cpu
]);
145 BUG_ON(c
->cputype
== CPU_UNKNOWN
);
148 * Platform code can force the cpu type to optimize code
149 * generation. In that case be sure the cpu type is correctly
150 * manually setup otherwise it could trigger some nasty bugs.
152 BUG_ON(current_cpu_type() != c
->cputype
);
154 if (mips_fpu_disabled
)
155 c
->options
&= ~MIPS_CPU_FPU
;
157 if (c
->options
& MIPS_CPU_FPU
)
160 cpu_set_nofpu_opts(c
);
163 void cpu_report(void)
165 struct cpuinfo_mips
*c
= ¤t_cpu_data
;
167 pr_info("CPU%d revision is: %08x (%s)\n",
168 smp_processor_id(), c
->processor_id
, cpu_name_string());
169 if (c
->options
& MIPS_CPU_FPU
)
170 pr_info("FPU revision is: %08x\n", c
->fpu_id
);