FILE
cpu-r3k-probe.c
File preview with syntax highlighting.
linux-6.19.14/arch/mips/kernel/cpu-r3k-probe.c
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#include <asm/traps.h> 25 26#include "fpu-probe.h" 27 28/* Hardware capabilities */ 29unsigned int elf_hwcap __read_mostly; 30EXPORT_SYMBOL_GPL(elf_hwcap); 31 32void __init check_bugs32(void) 33{ 34 35} 36 37/* 38 * Probe whether cpu has config register by trying to play with 39 * alternate cache bit and see whether it matters. 40 * It's used by cpu_probe to distinguish between R3000A and R3081. 41 */ 42static inline int cpu_has_confreg(void) 43{ 44#ifdef CONFIG_CPU_R3000 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 = ¤t_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 } 121 122 BUG_ON(!__cpu_name[cpu]); 123 BUG_ON(c->cputype == CPU_UNKNOWN); 124 125 /* 126 * Platform code can force the cpu type to optimize code 127 * generation. In that case be sure the cpu type is correctly 128 * manually setup otherwise it could trigger some nasty bugs. 129 */ 130 BUG_ON(current_cpu_type() != c->cputype); 131 132 if (mips_fpu_disabled) 133 c->options &= ~MIPS_CPU_FPU; 134 135 if (c->options & MIPS_CPU_FPU) 136 cpu_set_fpu_opts(c); 137 else 138 cpu_set_nofpu_opts(c); 139 140 c->vmbits = 31; 141 142 reserve_exception_space(0, 0x400); 143} 144 145void cpu_report(void) 146{ 147 struct cpuinfo_mips *c = ¤t_cpu_data; 148 149 pr_info("CPU%d revision is: %08x (%s)\n", 150 smp_processor_id(), c->processor_id, cpu_name_string()); 151 if (c->options & MIPS_CPU_FPU) 152 pr_info("FPU revision is: %08x\n", c->fpu_id); 153}
~/
Read-only file preview.