hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/arch/mips/kernel/cpu-probe.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Processor capabilities determination functions.
34 *
....@@ -5,11 +6,6 @@
56 * Copyright (C) 1994 - 2006 Ralf Baechle
67 * Copyright (C) 2003, 2004 Maciej W. Rozycki
78 * Copyright (C) 2001, 2004, 2011, 2012 MIPS Technologies, Inc.
8
- *
9
- * This program is free software; you can redistribute it and/or
10
- * modify it under the terms of the GNU General Public License
11
- * as published by the Free Software Foundation; either version
12
- * 2 of the License, or (at your option) any later version.
139 */
1410 #include <linux/init.h>
1511 #include <linux/kernel.h>
....@@ -32,31 +28,13 @@
3228 #include <asm/spram.h>
3329 #include <linux/uaccess.h>
3430
31
+#include "fpu-probe.h"
32
+
33
+#include <asm/mach-loongson64/cpucfg-emul.h>
34
+
3535 /* Hardware capabilities */
3636 unsigned int elf_hwcap __read_mostly;
3737 EXPORT_SYMBOL_GPL(elf_hwcap);
38
-
39
-/*
40
- * Get the FPU Implementation/Revision.
41
- */
42
-static inline unsigned long cpu_get_fpu_id(void)
43
-{
44
- unsigned long tmp, fpu_id;
45
-
46
- tmp = read_c0_status();
47
- __enable_fpu(FPU_AS_IS);
48
- fpu_id = read_32bit_cp1_register(CP1_REVISION);
49
- write_c0_status(tmp);
50
- return fpu_id;
51
-}
52
-
53
-/*
54
- * Check if the CPU has an external FPU.
55
- */
56
-static inline int __cpu_has_fpu(void)
57
-{
58
- return (cpu_get_fpu_id() & FPIR_IMP_MASK) != FPIR_IMP_NONE;
59
-}
6038
6139 static inline unsigned long cpu_get_msa_id(void)
6240 {
....@@ -70,261 +48,6 @@
7048 write_c0_status(status);
7149 return msa_id;
7250 }
73
-
74
-/*
75
- * Determine the FCSR mask for FPU hardware.
76
- */
77
-static inline void cpu_set_fpu_fcsr_mask(struct cpuinfo_mips *c)
78
-{
79
- unsigned long sr, mask, fcsr, fcsr0, fcsr1;
80
-
81
- fcsr = c->fpu_csr31;
82
- mask = FPU_CSR_ALL_X | FPU_CSR_ALL_E | FPU_CSR_ALL_S | FPU_CSR_RM;
83
-
84
- sr = read_c0_status();
85
- __enable_fpu(FPU_AS_IS);
86
-
87
- fcsr0 = fcsr & mask;
88
- write_32bit_cp1_register(CP1_STATUS, fcsr0);
89
- fcsr0 = read_32bit_cp1_register(CP1_STATUS);
90
-
91
- fcsr1 = fcsr | ~mask;
92
- write_32bit_cp1_register(CP1_STATUS, fcsr1);
93
- fcsr1 = read_32bit_cp1_register(CP1_STATUS);
94
-
95
- write_32bit_cp1_register(CP1_STATUS, fcsr);
96
-
97
- write_c0_status(sr);
98
-
99
- c->fpu_msk31 = ~(fcsr0 ^ fcsr1) & ~mask;
100
-}
101
-
102
-/*
103
- * Determine the IEEE 754 NaN encodings and ABS.fmt/NEG.fmt execution modes
104
- * supported by FPU hardware.
105
- */
106
-static void cpu_set_fpu_2008(struct cpuinfo_mips *c)
107
-{
108
- if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
109
- MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
110
- MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
111
- unsigned long sr, fir, fcsr, fcsr0, fcsr1;
112
-
113
- sr = read_c0_status();
114
- __enable_fpu(FPU_AS_IS);
115
-
116
- fir = read_32bit_cp1_register(CP1_REVISION);
117
- if (fir & MIPS_FPIR_HAS2008) {
118
- fcsr = read_32bit_cp1_register(CP1_STATUS);
119
-
120
- fcsr0 = fcsr & ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
121
- write_32bit_cp1_register(CP1_STATUS, fcsr0);
122
- fcsr0 = read_32bit_cp1_register(CP1_STATUS);
123
-
124
- fcsr1 = fcsr | FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
125
- write_32bit_cp1_register(CP1_STATUS, fcsr1);
126
- fcsr1 = read_32bit_cp1_register(CP1_STATUS);
127
-
128
- write_32bit_cp1_register(CP1_STATUS, fcsr);
129
-
130
- if (!(fcsr0 & FPU_CSR_NAN2008))
131
- c->options |= MIPS_CPU_NAN_LEGACY;
132
- if (fcsr1 & FPU_CSR_NAN2008)
133
- c->options |= MIPS_CPU_NAN_2008;
134
-
135
- if ((fcsr0 ^ fcsr1) & FPU_CSR_ABS2008)
136
- c->fpu_msk31 &= ~FPU_CSR_ABS2008;
137
- else
138
- c->fpu_csr31 |= fcsr & FPU_CSR_ABS2008;
139
-
140
- if ((fcsr0 ^ fcsr1) & FPU_CSR_NAN2008)
141
- c->fpu_msk31 &= ~FPU_CSR_NAN2008;
142
- else
143
- c->fpu_csr31 |= fcsr & FPU_CSR_NAN2008;
144
- } else {
145
- c->options |= MIPS_CPU_NAN_LEGACY;
146
- }
147
-
148
- write_c0_status(sr);
149
- } else {
150
- c->options |= MIPS_CPU_NAN_LEGACY;
151
- }
152
-}
153
-
154
-/*
155
- * IEEE 754 conformance mode to use. Affects the NaN encoding and the
156
- * ABS.fmt/NEG.fmt execution mode.
157
- */
158
-static enum { STRICT, LEGACY, STD2008, RELAXED } ieee754 = STRICT;
159
-
160
-/*
161
- * Set the IEEE 754 NaN encodings and the ABS.fmt/NEG.fmt execution modes
162
- * to support by the FPU emulator according to the IEEE 754 conformance
163
- * mode selected. Note that "relaxed" straps the emulator so that it
164
- * allows 2008-NaN binaries even for legacy processors.
165
- */
166
-static void cpu_set_nofpu_2008(struct cpuinfo_mips *c)
167
-{
168
- c->options &= ~(MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY);
169
- c->fpu_csr31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
170
- c->fpu_msk31 &= ~(FPU_CSR_ABS2008 | FPU_CSR_NAN2008);
171
-
172
- switch (ieee754) {
173
- case STRICT:
174
- if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
175
- MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
176
- MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
177
- c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY;
178
- } else {
179
- c->options |= MIPS_CPU_NAN_LEGACY;
180
- c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
181
- }
182
- break;
183
- case LEGACY:
184
- c->options |= MIPS_CPU_NAN_LEGACY;
185
- c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
186
- break;
187
- case STD2008:
188
- c->options |= MIPS_CPU_NAN_2008;
189
- c->fpu_csr31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
190
- c->fpu_msk31 |= FPU_CSR_ABS2008 | FPU_CSR_NAN2008;
191
- break;
192
- case RELAXED:
193
- c->options |= MIPS_CPU_NAN_2008 | MIPS_CPU_NAN_LEGACY;
194
- break;
195
- }
196
-}
197
-
198
-/*
199
- * Override the IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode
200
- * according to the "ieee754=" parameter.
201
- */
202
-static void cpu_set_nan_2008(struct cpuinfo_mips *c)
203
-{
204
- switch (ieee754) {
205
- case STRICT:
206
- mips_use_nan_legacy = !!cpu_has_nan_legacy;
207
- mips_use_nan_2008 = !!cpu_has_nan_2008;
208
- break;
209
- case LEGACY:
210
- mips_use_nan_legacy = !!cpu_has_nan_legacy;
211
- mips_use_nan_2008 = !cpu_has_nan_legacy;
212
- break;
213
- case STD2008:
214
- mips_use_nan_legacy = !cpu_has_nan_2008;
215
- mips_use_nan_2008 = !!cpu_has_nan_2008;
216
- break;
217
- case RELAXED:
218
- mips_use_nan_legacy = true;
219
- mips_use_nan_2008 = true;
220
- break;
221
- }
222
-}
223
-
224
-/*
225
- * IEEE 754 NaN encoding and ABS.fmt/NEG.fmt execution mode override
226
- * settings:
227
- *
228
- * strict: accept binaries that request a NaN encoding supported by the FPU
229
- * legacy: only accept legacy-NaN binaries
230
- * 2008: only accept 2008-NaN binaries
231
- * relaxed: accept any binaries regardless of whether supported by the FPU
232
- */
233
-static int __init ieee754_setup(char *s)
234
-{
235
- if (!s)
236
- return -1;
237
- else if (!strcmp(s, "strict"))
238
- ieee754 = STRICT;
239
- else if (!strcmp(s, "legacy"))
240
- ieee754 = LEGACY;
241
- else if (!strcmp(s, "2008"))
242
- ieee754 = STD2008;
243
- else if (!strcmp(s, "relaxed"))
244
- ieee754 = RELAXED;
245
- else
246
- return -1;
247
-
248
- if (!(boot_cpu_data.options & MIPS_CPU_FPU))
249
- cpu_set_nofpu_2008(&boot_cpu_data);
250
- cpu_set_nan_2008(&boot_cpu_data);
251
-
252
- return 0;
253
-}
254
-
255
-early_param("ieee754", ieee754_setup);
256
-
257
-/*
258
- * Set the FIR feature flags for the FPU emulator.
259
- */
260
-static void cpu_set_nofpu_id(struct cpuinfo_mips *c)
261
-{
262
- u32 value;
263
-
264
- value = 0;
265
- if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
266
- MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
267
- MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6))
268
- value |= MIPS_FPIR_D | MIPS_FPIR_S;
269
- if (c->isa_level & (MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
270
- MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6))
271
- value |= MIPS_FPIR_F64 | MIPS_FPIR_L | MIPS_FPIR_W;
272
- if (c->options & MIPS_CPU_NAN_2008)
273
- value |= MIPS_FPIR_HAS2008;
274
- c->fpu_id = value;
275
-}
276
-
277
-/* Determined FPU emulator mask to use for the boot CPU with "nofpu". */
278
-static unsigned int mips_nofpu_msk31;
279
-
280
-/*
281
- * Set options for FPU hardware.
282
- */
283
-static void cpu_set_fpu_opts(struct cpuinfo_mips *c)
284
-{
285
- c->fpu_id = cpu_get_fpu_id();
286
- mips_nofpu_msk31 = c->fpu_msk31;
287
-
288
- if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1 |
289
- MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2 |
290
- MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6)) {
291
- if (c->fpu_id & MIPS_FPIR_3D)
292
- c->ases |= MIPS_ASE_MIPS3D;
293
- if (c->fpu_id & MIPS_FPIR_UFRP)
294
- c->options |= MIPS_CPU_UFR;
295
- if (c->fpu_id & MIPS_FPIR_FREP)
296
- c->options |= MIPS_CPU_FRE;
297
- }
298
-
299
- cpu_set_fpu_fcsr_mask(c);
300
- cpu_set_fpu_2008(c);
301
- cpu_set_nan_2008(c);
302
-}
303
-
304
-/*
305
- * Set options for the FPU emulator.
306
- */
307
-static void cpu_set_nofpu_opts(struct cpuinfo_mips *c)
308
-{
309
- c->options &= ~MIPS_CPU_FPU;
310
- c->fpu_msk31 = mips_nofpu_msk31;
311
-
312
- cpu_set_nofpu_2008(c);
313
- cpu_set_nan_2008(c);
314
- cpu_set_nofpu_id(c);
315
-}
316
-
317
-static int mips_fpu_disabled;
318
-
319
-static int __init fpu_disable(char *s)
320
-{
321
- cpu_set_nofpu_opts(&boot_cpu_data);
322
- mips_fpu_disabled = 1;
323
-
324
- return 1;
325
-}
326
-
327
-__setup("nofpu", fpu_disable);
32851
32952 static int mips_dsp_disabled;
33053
....@@ -475,6 +198,13 @@
475198 __elf_platform = plat;
476199 }
477200
201
+static inline void set_elf_base_platform(const char *plat)
202
+{
203
+ if (__elf_base_platform == NULL) {
204
+ __elf_base_platform = plat;
205
+ }
206
+}
207
+
478208 static inline void cpu_probe_vmbits(struct cpuinfo_mips *c)
479209 {
480210 #ifdef __NEED_VMBITS_PROBE
....@@ -487,31 +217,56 @@
487217 static void set_isa(struct cpuinfo_mips *c, unsigned int isa)
488218 {
489219 switch (isa) {
220
+ case MIPS_CPU_ISA_M64R5:
221
+ c->isa_level |= MIPS_CPU_ISA_M32R5 | MIPS_CPU_ISA_M64R5;
222
+ set_elf_base_platform("mips64r5");
223
+ fallthrough;
490224 case MIPS_CPU_ISA_M64R2:
491225 c->isa_level |= MIPS_CPU_ISA_M32R2 | MIPS_CPU_ISA_M64R2;
226
+ set_elf_base_platform("mips64r2");
227
+ fallthrough;
492228 case MIPS_CPU_ISA_M64R1:
493229 c->isa_level |= MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M64R1;
230
+ set_elf_base_platform("mips64");
231
+ fallthrough;
494232 case MIPS_CPU_ISA_V:
495233 c->isa_level |= MIPS_CPU_ISA_V;
234
+ set_elf_base_platform("mips5");
235
+ fallthrough;
496236 case MIPS_CPU_ISA_IV:
497237 c->isa_level |= MIPS_CPU_ISA_IV;
238
+ set_elf_base_platform("mips4");
239
+ fallthrough;
498240 case MIPS_CPU_ISA_III:
499241 c->isa_level |= MIPS_CPU_ISA_II | MIPS_CPU_ISA_III;
242
+ set_elf_base_platform("mips3");
500243 break;
501244
502245 /* R6 incompatible with everything else */
503246 case MIPS_CPU_ISA_M64R6:
504247 c->isa_level |= MIPS_CPU_ISA_M32R6 | MIPS_CPU_ISA_M64R6;
248
+ set_elf_base_platform("mips64r6");
249
+ fallthrough;
505250 case MIPS_CPU_ISA_M32R6:
506251 c->isa_level |= MIPS_CPU_ISA_M32R6;
252
+ set_elf_base_platform("mips32r6");
507253 /* Break here so we don't add incompatible ISAs */
508254 break;
255
+ case MIPS_CPU_ISA_M32R5:
256
+ c->isa_level |= MIPS_CPU_ISA_M32R5;
257
+ set_elf_base_platform("mips32r5");
258
+ fallthrough;
509259 case MIPS_CPU_ISA_M32R2:
510260 c->isa_level |= MIPS_CPU_ISA_M32R2;
261
+ set_elf_base_platform("mips32r2");
262
+ fallthrough;
511263 case MIPS_CPU_ISA_M32R1:
512264 c->isa_level |= MIPS_CPU_ISA_M32R1;
265
+ set_elf_base_platform("mips32");
266
+ fallthrough;
513267 case MIPS_CPU_ISA_II:
514268 c->isa_level |= MIPS_CPU_ISA_II;
269
+ set_elf_base_platform("mips2");
515270 break;
516271 }
517272 }
....@@ -558,14 +313,14 @@
558313 config = read_c0_config6();
559314
560315 if (flags & FTLB_EN)
561
- config |= MIPS_CONF6_FTLBEN;
316
+ config |= MTI_CONF6_FTLBEN;
562317 else
563
- config &= ~MIPS_CONF6_FTLBEN;
318
+ config &= ~MTI_CONF6_FTLBEN;
564319
565320 if (flags & FTLB_SET_PROB) {
566
- config &= ~(3 << MIPS_CONF6_FTLBP_SHIFT);
321
+ config &= ~(3 << MTI_CONF6_FTLBP_SHIFT);
567322 config |= calculate_ftlb_probability(c)
568
- << MIPS_CONF6_FTLBP_SHIFT;
323
+ << MTI_CONF6_FTLBP_SHIFT;
569324 }
570325
571326 write_c0_config6(config);
....@@ -577,7 +332,7 @@
577332 if (!(flags & FTLB_EN))
578333 return 1;
579334 return 0;
580
- case CPU_LOONGSON3:
335
+ case CPU_LOONGSON64:
581336 /* Flush ITLB, DTLB, VTLB and FTLB */
582337 write_c0_diag(LOONGSON_DIAG_ITLB | LOONGSON_DIAG_DTLB |
583338 LOONGSON_DIAG_VTLB | LOONGSON_DIAG_FTLB);
....@@ -585,13 +340,59 @@
585340 config = read_c0_config6();
586341 if (flags & FTLB_EN)
587342 /* Enable FTLB */
588
- write_c0_config6(config & ~MIPS_CONF6_FTLBDIS);
343
+ write_c0_config6(config & ~LOONGSON_CONF6_FTLBDIS);
589344 else
590345 /* Disable FTLB */
591
- write_c0_config6(config | MIPS_CONF6_FTLBDIS);
346
+ write_c0_config6(config | LOONGSON_CONF6_FTLBDIS);
592347 break;
593348 default:
594349 return 1;
350
+ }
351
+
352
+ return 0;
353
+}
354
+
355
+static int mm_config(struct cpuinfo_mips *c)
356
+{
357
+ unsigned int config0, update, mm;
358
+
359
+ config0 = read_c0_config();
360
+ mm = config0 & MIPS_CONF_MM;
361
+
362
+ /*
363
+ * It's implementation dependent what type of write-merge is supported
364
+ * and whether it can be enabled/disabled. If it is settable lets make
365
+ * the merging allowed by default. Some platforms might have
366
+ * write-through caching unsupported. In this case just ignore the
367
+ * CP0.Config.MM bit field value.
368
+ */
369
+ switch (c->cputype) {
370
+ case CPU_24K:
371
+ case CPU_34K:
372
+ case CPU_74K:
373
+ case CPU_P5600:
374
+ case CPU_P6600:
375
+ c->options |= MIPS_CPU_MM_FULL;
376
+ update = MIPS_CONF_MM_FULL;
377
+ break;
378
+ case CPU_1004K:
379
+ case CPU_1074K:
380
+ case CPU_INTERAPTIV:
381
+ case CPU_PROAPTIV:
382
+ mm = 0;
383
+ fallthrough;
384
+ default:
385
+ update = 0;
386
+ break;
387
+ }
388
+
389
+ if (update) {
390
+ config0 = (config0 & ~MIPS_CONF_MM) | update;
391
+ write_c0_config(config0);
392
+ } else if (mm == MIPS_CONF_MM_SYSAD) {
393
+ c->options |= MIPS_CPU_MM_SYSAD;
394
+ } else if (mm == MIPS_CONF_MM_FULL) {
395
+ c->options |= MIPS_CPU_MM_FULL;
595396 }
596397
597398 return 0;
....@@ -788,7 +589,7 @@
788589 MIPS_CONF4_VTLBSIZEEXT_SHIFT) * 0x40;
789590 c->tlbsize = c->tlbsizevtlb;
790591 ftlb_page = MIPS_CONF4_VFTLBPAGESIZE;
791
- /* fall through */
592
+ fallthrough;
792593 case MIPS_CONF4_MMUEXTDEF_FTLBSIZEEXT:
793594 if (mips_ftlb_disabled)
794595 break;
....@@ -837,10 +638,19 @@
837638
838639 static inline unsigned int decode_config5(struct cpuinfo_mips *c)
839640 {
840
- unsigned int config5;
641
+ unsigned int config5, max_mmid_width;
642
+ unsigned long asid_mask;
841643
842644 config5 = read_c0_config5();
843645 config5 &= ~(MIPS_CONF5_UFR | MIPS_CONF5_UFE);
646
+
647
+ if (cpu_has_mips_r6) {
648
+ if (!__builtin_constant_p(cpu_has_mmid) || cpu_has_mmid)
649
+ config5 |= MIPS_CONF5_MI;
650
+ else
651
+ config5 &= ~MIPS_CONF5_MI;
652
+ }
653
+
844654 write_c0_config5(config5);
845655
846656 if (config5 & MIPS_CONF5_EVA)
....@@ -858,6 +668,50 @@
858668
859669 if (config5 & MIPS_CONF5_CRCP)
860670 elf_hwcap |= HWCAP_MIPS_CRC32;
671
+
672
+ if (cpu_has_mips_r6) {
673
+ /* Ensure the write to config5 above takes effect */
674
+ back_to_back_c0_hazard();
675
+
676
+ /* Check whether we successfully enabled MMID support */
677
+ config5 = read_c0_config5();
678
+ if (config5 & MIPS_CONF5_MI)
679
+ c->options |= MIPS_CPU_MMID;
680
+
681
+ /*
682
+ * Warn if we've hardcoded cpu_has_mmid to a value unsuitable
683
+ * for the CPU we're running on, or if CPUs in an SMP system
684
+ * have inconsistent MMID support.
685
+ */
686
+ WARN_ON(!!cpu_has_mmid != !!(config5 & MIPS_CONF5_MI));
687
+
688
+ if (cpu_has_mmid) {
689
+ write_c0_memorymapid(~0ul);
690
+ back_to_back_c0_hazard();
691
+ asid_mask = read_c0_memorymapid();
692
+
693
+ /*
694
+ * We maintain a bitmap to track MMID allocation, and
695
+ * need a sensible upper bound on the size of that
696
+ * bitmap. The initial CPU with MMID support (I6500)
697
+ * supports 16 bit MMIDs, which gives us an 8KiB
698
+ * bitmap. The architecture recommends that hardware
699
+ * support 32 bit MMIDs, which would give us a 512MiB
700
+ * bitmap - that's too big in most cases.
701
+ *
702
+ * Cap MMID width at 16 bits for now & we can revisit
703
+ * this if & when hardware supports anything wider.
704
+ */
705
+ max_mmid_width = 16;
706
+ if (asid_mask > GENMASK(max_mmid_width - 1, 0)) {
707
+ pr_info("Capping MMID width at %d bits",
708
+ max_mmid_width);
709
+ asid_mask = GENMASK(max_mmid_width - 1, 0);
710
+ }
711
+
712
+ set_cpu_asid_mask(c, asid_mask);
713
+ }
714
+ }
861715
862716 return config5 & MIPS_CONF_M;
863717 }
....@@ -1300,15 +1154,6 @@
13001154 break;
13011155 }
13021156 break;
1303
- case PRID_IMP_R4300:
1304
- c->cputype = CPU_R4300;
1305
- __cpu_name[cpu] = "R4300";
1306
- set_isa(c, MIPS_CPU_ISA_III);
1307
- c->fpu_msk31 |= FPU_CSR_CONDX;
1308
- c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
1309
- MIPS_CPU_LLSC;
1310
- c->tlbsize = 32;
1311
- break;
13121157 case PRID_IMP_R4600:
13131158 c->cputype = CPU_R4600;
13141159 __cpu_name[cpu] = "R4600";
....@@ -1384,14 +1229,6 @@
13841229 MIPS_CPU_LLSC;
13851230 c->tlbsize = 48;
13861231 break;
1387
- case PRID_IMP_R5432:
1388
- c->cputype = CPU_R5432;
1389
- __cpu_name[cpu] = "R5432";
1390
- set_isa(c, MIPS_CPU_ISA_IV);
1391
- c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR |
1392
- MIPS_CPU_WATCH | MIPS_CPU_LLSC;
1393
- c->tlbsize = 48;
1394
- break;
13951232 case PRID_IMP_R5500:
13961233 c->cputype = CPU_R5500;
13971234 __cpu_name[cpu] = "R5500";
....@@ -1424,15 +1261,6 @@
14241261 */
14251262 c->tlbsize = (read_c0_info() & (1 << 29)) ? 64 : 48;
14261263 break;
1427
- case PRID_IMP_R8000:
1428
- c->cputype = CPU_R8000;
1429
- __cpu_name[cpu] = "RM8000";
1430
- set_isa(c, MIPS_CPU_ISA_IV);
1431
- c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
1432
- MIPS_CPU_FPU | MIPS_CPU_32FPR |
1433
- MIPS_CPU_LLSC;
1434
- c->tlbsize = 384; /* has weird TLB: 3-way x 128 */
1435
- break;
14361264 case PRID_IMP_R10000:
14371265 c->cputype = CPU_R10000;
14381266 __cpu_name[cpu] = "R10000";
....@@ -1450,8 +1278,9 @@
14501278 c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
14511279 MIPS_CPU_FPU | MIPS_CPU_32FPR |
14521280 MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
1453
- MIPS_CPU_LLSC | MIPS_CPU_BP_GHIST;
1281
+ MIPS_CPU_LLSC;
14541282 c->tlbsize = 64;
1283
+ write_c0_r10k_diag(read_c0_r10k_diag() | R10K_DIAG_E_GHIST);
14551284 break;
14561285 case PRID_IMP_R14000:
14571286 if (((c->processor_id >> 4) & 0x0f) > 2) {
....@@ -1465,27 +1294,28 @@
14651294 c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX |
14661295 MIPS_CPU_FPU | MIPS_CPU_32FPR |
14671296 MIPS_CPU_COUNTER | MIPS_CPU_WATCH |
1468
- MIPS_CPU_LLSC | MIPS_CPU_BP_GHIST;
1297
+ MIPS_CPU_LLSC;
14691298 c->tlbsize = 64;
1299
+ write_c0_r10k_diag(read_c0_r10k_diag() | R10K_DIAG_E_GHIST);
14701300 break;
1471
- case PRID_IMP_LOONGSON_64: /* Loongson-2/3 */
1301
+ case PRID_IMP_LOONGSON_64C: /* Loongson-2/3 */
14721302 switch (c->processor_id & PRID_REV_MASK) {
14731303 case PRID_REV_LOONGSON2E:
1474
- c->cputype = CPU_LOONGSON2;
1304
+ c->cputype = CPU_LOONGSON2EF;
14751305 __cpu_name[cpu] = "ICT Loongson-2";
14761306 set_elf_platform(cpu, "loongson2e");
14771307 set_isa(c, MIPS_CPU_ISA_III);
14781308 c->fpu_msk31 |= FPU_CSR_CONDX;
14791309 break;
14801310 case PRID_REV_LOONGSON2F:
1481
- c->cputype = CPU_LOONGSON2;
1311
+ c->cputype = CPU_LOONGSON2EF;
14821312 __cpu_name[cpu] = "ICT Loongson-2";
14831313 set_elf_platform(cpu, "loongson2f");
14841314 set_isa(c, MIPS_CPU_ISA_III);
14851315 c->fpu_msk31 |= FPU_CSR_CONDX;
14861316 break;
14871317 case PRID_REV_LOONGSON3A_R1:
1488
- c->cputype = CPU_LOONGSON3;
1318
+ c->cputype = CPU_LOONGSON64;
14891319 __cpu_name[cpu] = "ICT Loongson-3";
14901320 set_elf_platform(cpu, "loongson3a");
14911321 set_isa(c, MIPS_CPU_ISA_M64R1);
....@@ -1494,7 +1324,7 @@
14941324 break;
14951325 case PRID_REV_LOONGSON3B_R1:
14961326 case PRID_REV_LOONGSON3B_R2:
1497
- c->cputype = CPU_LOONGSON3;
1327
+ c->cputype = CPU_LOONGSON64;
14981328 __cpu_name[cpu] = "ICT Loongson-3";
14991329 set_elf_platform(cpu, "loongson3b");
15001330 set_isa(c, MIPS_CPU_ISA_M64R1);
....@@ -1507,12 +1337,13 @@
15071337 MIPS_CPU_FPU | MIPS_CPU_LLSC |
15081338 MIPS_CPU_32FPR;
15091339 c->tlbsize = 64;
1340
+ set_cpu_asid_mask(c, MIPS_ENTRYHI_ASID);
15101341 c->writecombine = _CACHE_UNCACHED_ACCELERATED;
15111342 break;
15121343 case PRID_IMP_LOONGSON_32: /* Loongson-1 */
15131344 decode_configs(c);
15141345
1515
- c->cputype = CPU_LOONGSON1;
1346
+ c->cputype = CPU_LOONGSON32;
15161347
15171348 switch (c->processor_id & PRID_REV_MASK) {
15181349 case PRID_REV_LOONGSON1B:
....@@ -1660,14 +1491,33 @@
16601491
16611492 spram_config();
16621493
1494
+ mm_config(c);
1495
+
16631496 switch (__get_cpu_type(c->cputype)) {
1497
+ case CPU_M5150:
1498
+ case CPU_P5600:
1499
+ set_isa(c, MIPS_CPU_ISA_M32R5);
1500
+ break;
16641501 case CPU_I6500:
16651502 c->options |= MIPS_CPU_SHARED_FTLB_ENTRIES;
1666
- /* fall-through */
1503
+ fallthrough;
16671504 case CPU_I6400:
16681505 c->options |= MIPS_CPU_SHARED_FTLB_RAM;
1669
- /* fall-through */
1506
+ fallthrough;
16701507 default:
1508
+ break;
1509
+ }
1510
+
1511
+ /* Recent MIPS cores use the implementation-dependent ExcCode 16 for
1512
+ * cache/FTLB parity exceptions.
1513
+ */
1514
+ switch (__get_cpu_type(c->cputype)) {
1515
+ case CPU_PROAPTIV:
1516
+ case CPU_P5600:
1517
+ case CPU_P6600:
1518
+ case CPU_I6400:
1519
+ case CPU_I6500:
1520
+ c->options |= MIPS_CPU_FTLBPAREX;
16711521 break;
16721522 }
16731523 }
....@@ -1842,49 +1692,121 @@
18421692 }
18431693 }
18441694
1695
+#ifdef CONFIG_CPU_LOONGSON64
1696
+#include <loongson_regs.h>
1697
+
1698
+static inline void decode_cpucfg(struct cpuinfo_mips *c)
1699
+{
1700
+ u32 cfg1 = read_cpucfg(LOONGSON_CFG1);
1701
+ u32 cfg2 = read_cpucfg(LOONGSON_CFG2);
1702
+ u32 cfg3 = read_cpucfg(LOONGSON_CFG3);
1703
+
1704
+ if (cfg1 & LOONGSON_CFG1_MMI)
1705
+ c->ases |= MIPS_ASE_LOONGSON_MMI;
1706
+
1707
+ if (cfg2 & LOONGSON_CFG2_LEXT1)
1708
+ c->ases |= MIPS_ASE_LOONGSON_EXT;
1709
+
1710
+ if (cfg2 & LOONGSON_CFG2_LEXT2)
1711
+ c->ases |= MIPS_ASE_LOONGSON_EXT2;
1712
+
1713
+ if (cfg2 & LOONGSON_CFG2_LSPW) {
1714
+ c->options |= MIPS_CPU_LDPTE;
1715
+ c->guest.options |= MIPS_CPU_LDPTE;
1716
+ }
1717
+
1718
+ if (cfg3 & LOONGSON_CFG3_LCAMP)
1719
+ c->ases |= MIPS_ASE_LOONGSON_CAM;
1720
+}
1721
+
18451722 static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
18461723 {
1724
+ c->cputype = CPU_LOONGSON64;
1725
+
1726
+ /* All Loongson processors covered here define ExcCode 16 as GSExc. */
1727
+ decode_configs(c);
1728
+ c->options |= MIPS_CPU_GSEXCEX;
1729
+
18471730 switch (c->processor_id & PRID_IMP_MASK) {
1848
- case PRID_IMP_LOONGSON_64: /* Loongson-2/3 */
1731
+ case PRID_IMP_LOONGSON_64R: /* Loongson-64 Reduced */
18491732 switch (c->processor_id & PRID_REV_MASK) {
1850
- case PRID_REV_LOONGSON3A_R2:
1851
- c->cputype = CPU_LOONGSON3;
1733
+ case PRID_REV_LOONGSON2K_R1_0:
1734
+ case PRID_REV_LOONGSON2K_R1_1:
1735
+ case PRID_REV_LOONGSON2K_R1_2:
1736
+ case PRID_REV_LOONGSON2K_R1_3:
1737
+ __cpu_name[cpu] = "Loongson-2K";
1738
+ set_elf_platform(cpu, "gs264e");
1739
+ set_isa(c, MIPS_CPU_ISA_M64R2);
1740
+ break;
1741
+ }
1742
+ c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_EXT |
1743
+ MIPS_ASE_LOONGSON_EXT2);
1744
+ break;
1745
+ case PRID_IMP_LOONGSON_64C: /* Loongson-3 Classic */
1746
+ switch (c->processor_id & PRID_REV_MASK) {
1747
+ case PRID_REV_LOONGSON3A_R2_0:
1748
+ case PRID_REV_LOONGSON3A_R2_1:
18521749 __cpu_name[cpu] = "ICT Loongson-3";
18531750 set_elf_platform(cpu, "loongson3a");
18541751 set_isa(c, MIPS_CPU_ISA_M64R2);
18551752 break;
18561753 case PRID_REV_LOONGSON3A_R3_0:
18571754 case PRID_REV_LOONGSON3A_R3_1:
1858
- c->cputype = CPU_LOONGSON3;
18591755 __cpu_name[cpu] = "ICT Loongson-3";
18601756 set_elf_platform(cpu, "loongson3a");
18611757 set_isa(c, MIPS_CPU_ISA_M64R2);
18621758 break;
18631759 }
1864
-
1865
- decode_configs(c);
1760
+ /*
1761
+ * Loongson-3 Classic did not implement MIPS standard TLBINV
1762
+ * but implemented TLBINVF and EHINV. As currently we're only
1763
+ * using these two features, enable MIPS_CPU_TLBINV as well.
1764
+ *
1765
+ * Also some early Loongson-3A2000 had wrong TLB type in Config
1766
+ * register, we correct it here.
1767
+ */
18661768 c->options |= MIPS_CPU_FTLB | MIPS_CPU_TLBINV | MIPS_CPU_LDPTE;
1867
- c->writecombine = _CACHE_UNCACHED_ACCELERATED;
18681769 c->ases |= (MIPS_ASE_LOONGSON_MMI | MIPS_ASE_LOONGSON_CAM |
18691770 MIPS_ASE_LOONGSON_EXT | MIPS_ASE_LOONGSON_EXT2);
1771
+ c->ases &= ~MIPS_ASE_VZ; /* VZ of Loongson-3A2000/3000 is incomplete */
1772
+ break;
1773
+ case PRID_IMP_LOONGSON_64G:
1774
+ __cpu_name[cpu] = "ICT Loongson-3";
1775
+ set_elf_platform(cpu, "loongson3a");
1776
+ set_isa(c, MIPS_CPU_ISA_M64R2);
1777
+ decode_cpucfg(c);
18701778 break;
18711779 default:
18721780 panic("Unknown Loongson Processor ID!");
18731781 break;
18741782 }
18751783 }
1784
+#else
1785
+static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu) { }
1786
+#endif
18761787
18771788 static inline void cpu_probe_ingenic(struct cpuinfo_mips *c, unsigned int cpu)
18781789 {
18791790 decode_configs(c);
1880
- /* JZRISC does not implement the CP0 counter. */
1791
+
1792
+ /*
1793
+ * XBurst misses a config2 register, so config3 decode was skipped in
1794
+ * decode_configs().
1795
+ */
1796
+ decode_config3(c);
1797
+
1798
+ /* XBurst does not implement the CP0 counter. */
18811799 c->options &= ~MIPS_CPU_COUNTER;
1882
- BUG_ON(!__builtin_constant_p(cpu_has_counter) || cpu_has_counter);
1800
+ BUG_ON(__builtin_constant_p(cpu_has_counter) && cpu_has_counter);
1801
+
1802
+ /* XBurst has virtually tagged icache */
1803
+ c->icache.flags |= MIPS_CACHE_VTAG;
1804
+
18831805 switch (c->processor_id & PRID_IMP_MASK) {
1884
- case PRID_IMP_JZRISC:
1885
- c->cputype = CPU_JZRISC;
1886
- c->writecombine = _CACHE_UNCACHED_ACCELERATED;
1887
- __cpu_name[cpu] = "Ingenic JZRISC";
1806
+
1807
+ /* XBurst®1 with MXU1.0/MXU1.1 SIMD ISA */
1808
+ case PRID_IMP_XBURST_REV1:
1809
+
18881810 /*
18891811 * The XBurst core by default attempts to avoid branch target
18901812 * buffer lookups by detecting & special casing loops. This
....@@ -1892,7 +1814,56 @@
18921814 * Set cp0 config7 bit 4 to disable this feature.
18931815 */
18941816 set_c0_config7(MIPS_CONF7_BTB_LOOP_EN);
1817
+
1818
+ switch (c->processor_id & PRID_COMP_MASK) {
1819
+
1820
+ /*
1821
+ * The config0 register in the XBurst CPUs with a processor ID of
1822
+ * PRID_COMP_INGENIC_D0 report themselves as MIPS32r2 compatible,
1823
+ * but they don't actually support this ISA.
1824
+ */
1825
+ case PRID_COMP_INGENIC_D0:
1826
+ c->isa_level &= ~MIPS_CPU_ISA_M32R2;
1827
+
1828
+ /* FPU is not properly detected on JZ4760(B). */
1829
+ if (c->processor_id == 0x2ed0024f)
1830
+ c->options |= MIPS_CPU_FPU;
1831
+
1832
+ fallthrough;
1833
+
1834
+ /*
1835
+ * The config0 register in the XBurst CPUs with a processor ID of
1836
+ * PRID_COMP_INGENIC_D0 or PRID_COMP_INGENIC_D1 has an abandoned
1837
+ * huge page tlb mode, this mode is not compatible with the MIPS
1838
+ * standard, it will cause tlbmiss and into an infinite loop
1839
+ * (line 21 in the tlb-funcs.S) when starting the init process.
1840
+ * After chip reset, the default is HPTLB mode, Write 0xa9000000
1841
+ * to cp0 register 5 sel 4 to switch back to VTLB mode to prevent
1842
+ * getting stuck.
1843
+ */
1844
+ case PRID_COMP_INGENIC_D1:
1845
+ write_c0_page_ctrl(XBURST_PAGECTRL_HPTLB_DIS);
1846
+ break;
1847
+
1848
+ default:
1849
+ break;
1850
+ }
1851
+ fallthrough;
1852
+
1853
+ /* XBurst®1 with MXU2.0 SIMD ISA */
1854
+ case PRID_IMP_XBURST_REV2:
1855
+ /* Ingenic uses the WA bit to achieve write-combine memory writes */
1856
+ c->writecombine = _CACHE_CACHABLE_WA;
1857
+ c->cputype = CPU_XBURST;
1858
+ __cpu_name[cpu] = "Ingenic XBurst";
18951859 break;
1860
+
1861
+ /* XBurst®2 with MXU2.1 SIMD ISA */
1862
+ case PRID_IMP_XBURST2:
1863
+ c->cputype = CPU_XBURST;
1864
+ __cpu_name[cpu] = "Ingenic XBurst II";
1865
+ break;
1866
+
18961867 default:
18971868 panic("Unknown Ingenic Processor ID!");
18981869 break;
....@@ -1988,6 +1959,7 @@
19881959
19891960 const char *__cpu_name[NR_CPUS];
19901961 const char *__elf_platform;
1962
+const char *__elf_base_platform;
19911963
19921964 void cpu_probe(void)
19931965 {
....@@ -2037,6 +2009,7 @@
20372009 case PRID_COMP_LOONGSON:
20382010 cpu_probe_loongson(c, cpu);
20392011 break;
2012
+ case PRID_COMP_INGENIC_13:
20402013 case PRID_COMP_INGENIC_D0:
20412014 case PRID_COMP_INGENIC_D1:
20422015 case PRID_COMP_INGENIC_E1:
....@@ -2082,10 +2055,6 @@
20822055 cpu_set_fpu_opts(c);
20832056 else
20842057 cpu_set_nofpu_opts(c);
2085
-
2086
- if (cpu_has_bp_ghist)
2087
- write_c0_r10k_diag(read_c0_r10k_diag() |
2088
- R10K_DIAG_E_GHIST);
20892058
20902059 if (cpu_has_mips_r2_r6) {
20912060 c->srsets = ((read_c0_srsctl() >> 26) & 0x0f) + 1;
....@@ -2143,6 +2112,13 @@
21432112
21442113 cpu_probe_vmbits(c);
21452114
2115
+ /* Synthesize CPUCFG data if running on Loongson processors;
2116
+ * no-op otherwise.
2117
+ *
2118
+ * This looks at previously probed features, so keep this at bottom.
2119
+ */
2120
+ loongson3_cpucfg_synthesize_data(c);
2121
+
21462122 #ifdef CONFIG_64BIT
21472123 if (cpu == 0)
21482124 __ua_limit = ~((1ull << cpu_vmbits) - 1);