aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/cpu-r3k-probe.c
diff options
context:
space:
mode:
authorWe-unite <3205135446@qq.com>2025-03-08 22:04:20 +0800
committerWe-unite <3205135446@qq.com>2025-03-08 22:04:20 +0800
commita07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch)
tree84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /arch/mips/kernel/cpu-r3k-probe.c
downloadohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.tar.gz
ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.zip
Initial commit: OpenHarmony-v4.0-ReleaseOpenHarmony-v4.0-Release
Diffstat (limited to 'arch/mips/kernel/cpu-r3k-probe.c')
-rw-r--r--arch/mips/kernel/cpu-r3k-probe.c171
1 files changed, 171 insertions, 0 deletions
diff --git a/arch/mips/kernel/cpu-r3k-probe.c b/arch/mips/kernel/cpu-r3k-probe.c
new file mode 100644
index 000000000..abdbbe8c5
--- /dev/null
+++ b/arch/mips/kernel/cpu-r3k-probe.c
@@ -0,0 +1,171 @@
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Processor capabilities determination functions.
4 *
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.
9 */
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>
16
17#include <asm/bugs.h>
18#include <asm/cpu.h>
19#include <asm/cpu-features.h>
20#include <asm/cpu-type.h>
21#include <asm/fpu.h>
22#include <asm/mipsregs.h>
23#include <asm/elf.h>
24
25#include "fpu-probe.h"
26
27/* Hardware capabilities */
28unsigned int elf_hwcap __read_mostly;
29EXPORT_SYMBOL_GPL(elf_hwcap);
30
31void __init check_bugs32(void)
32{
33
34}
35
36/*
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.
40 */
41static inline int cpu_has_confreg(void)
42{
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();
47
48 size1 = r3k_cache_size(ST0_ISC);
49 write_c0_conf(cfg ^ R30XX_CONF_AC);
50 size2 = r3k_cache_size(ST0_ISC);
51 write_c0_conf(cfg);
52 return size1 != size2;
53#else
54 return 0;
55#endif
56}
57
58static inline void set_elf_platform(int cpu, const char *plat)
59{
60 if (cpu == 0)
61 __elf_platform = plat;
62}
63
64const char *__cpu_name[NR_CPUS];
65const char *__elf_platform;
66const char *__elf_base_platform;
67
68void cpu_probe(void)
69{
70 struct cpuinfo_mips *c = &current_cpu_data;
71 unsigned int cpu = smp_processor_id();
72
73 /*
74 * Set a default elf platform, cpu probe may later
75 * overwrite it with a more precise value
76 */
77 set_elf_platform(cpu, "mips");
78
79 c->processor_id = PRID_IMP_UNKNOWN;
80 c->fpu_id = FPIR_IMP_NONE;
81 c->cputype = CPU_UNKNOWN;
82 c->writecombine = _CACHE_UNCACHED;
83
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;
87
88 c->srsets = 1;
89
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 |
96 MIPS_CPU_NOFPUEX;
97 if (__cpu_has_fpu())
98 c->options |= MIPS_CPU_FPU;
99 c->tlbsize = 64;
100 break;
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";
106 } else {
107 c->cputype = CPU_R3000A;
108 __cpu_name[cpu] = "R3000A";
109 }
110 } else {
111 c->cputype = CPU_R3000;
112 __cpu_name[cpu] = "R3000";
113 }
114 c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
115 MIPS_CPU_NOFPUEX;
116 if (__cpu_has_fpu())
117 c->options |= MIPS_CPU_FPU;
118 c->tlbsize = 64;
119 break;
120 case PRID_COMP_LEGACY | PRID_IMP_TX39:
121 c->options = MIPS_CPU_TLB | MIPS_CPU_TX39_CACHE;
122
123 if ((c->processor_id & 0xf0) == (PRID_REV_TX3927 & 0xf0)) {
124 c->cputype = CPU_TX3927;
125 __cpu_name[cpu] = "TX3927";
126 c->tlbsize = 64;
127 } else {
128 switch (c->processor_id & PRID_REV_MASK) {
129 case PRID_REV_TX3912:
130 c->cputype = CPU_TX3912;
131 __cpu_name[cpu] = "TX3912";
132 c->tlbsize = 32;
133 break;
134 case PRID_REV_TX3922:
135 c->cputype = CPU_TX3922;
136 __cpu_name[cpu] = "TX3922";
137 c->tlbsize = 64;
138 break;
139 }
140 }
141 break;
142 }
143
144 BUG_ON(!__cpu_name[cpu]);
145 BUG_ON(c->cputype == CPU_UNKNOWN);
146
147 /*
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.
151 */
152 BUG_ON(current_cpu_type() != c->cputype);
153
154 if (mips_fpu_disabled)
155 c->options &= ~MIPS_CPU_FPU;
156
157 if (c->options & MIPS_CPU_FPU)
158 cpu_set_fpu_opts(c);
159 else
160 cpu_set_nofpu_opts(c);
161}
162
163void cpu_report(void)
164{
165 struct cpuinfo_mips *c = &current_cpu_data;
166
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);
171}