// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Processor capabilities determination functions .
*
* Copyright ( C ) xxxx the Anonymous
* Copyright ( C ) 1994 - 2006 Ralf Baechle
* Copyright ( C ) 2003 , 2004 Maciej W . Rozycki
* Copyright ( C ) 2001 , 2004 , 2011 , 2012 MIPS Technologies , Inc .
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ptrace.h>
#include <linux/smp.h>
#include <linux/stddef.h>
#include <linux/export.h>
#include <asm /bugs.h>
#include <asm /cpu.h>
#include <asm /cpu-features.h>
#include <asm /cpu-type.h>
#include <asm /fpu.h>
#include <asm /mipsregs.h>
#include <asm /elf.h>
#include <asm /traps.h>
#include "fpu-probe.h"
/* Hardware capabilities */
unsigned int elf_hwcap __read_mostly;
EXPORT_SYMBOL_GPL(elf_hwcap);
void __init check_bugs32(void )
{
}
/*
* Probe whether cpu has config register by trying to play with
* alternate cache bit and see whether it matters .
* It ' s used by cpu_probe to distinguish between R3000A and R3081 .
*/
static inline int cpu_has_confreg(void )
{
#ifdef CONFIG_CPU_R3000
unsigned long size1, size2;
unsigned long cfg = read_c0_conf();
size1 = r3k_cache_size(ST0_ISC);
write_c0_conf(cfg ^ R30XX_CONF_AC);
size2 = r3k_cache_size(ST0_ISC);
write_c0_conf(cfg);
return size1 != size2;
#else
return 0 ;
#endif
}
static inline void set_elf_platform(int cpu, const char *plat)
{
if (cpu == 0 )
__elf_platform = plat;
}
const char *__cpu_name[NR_CPUS];
const char *__elf_platform;
const char *__elf_base_platform;
void cpu_probe(void )
{
struct cpuinfo_mips *c = ¤t_cpu_data;
unsigned int cpu = smp_processor_id();
/*
* Set a default elf platform , cpu probe may later
* overwrite it with a more precise value
*/
set_elf_platform(cpu, "mips" );
c->processor_id = PRID_IMP_UNKNOWN;
c->fpu_id = FPIR_IMP_NONE;
c->cputype = CPU_UNKNOWN;
c->writecombine = _CACHE_UNCACHED;
c->fpu_csr31 = FPU_CSR_RN;
c->fpu_msk31 = FPU_CSR_RSVD | FPU_CSR_ABS2008 | FPU_CSR_NAN2008 |
FPU_CSR_CONDX | FPU_CSR_FS;
c->srsets = 1 ;
c->processor_id = read_c0_prid();
switch (c->processor_id & (PRID_COMP_MASK | PRID_IMP_MASK)) {
case PRID_COMP_LEGACY | PRID_IMP_R2000:
c->cputype = CPU_R2000;
__cpu_name[cpu] = "R2000" ;
c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
MIPS_CPU_NOFPUEX;
if (__cpu_has_fpu())
c->options |= MIPS_CPU_FPU;
c->tlbsize = 64 ;
break ;
case PRID_COMP_LEGACY | PRID_IMP_R3000:
if ((c->processor_id & PRID_REV_MASK) == PRID_REV_R3000A) {
if (cpu_has_confreg()) {
c->cputype = CPU_R3081E;
__cpu_name[cpu] = "R3081" ;
} else {
c->cputype = CPU_R3000A;
__cpu_name[cpu] = "R3000A" ;
}
} else {
c->cputype = CPU_R3000;
__cpu_name[cpu] = "R3000" ;
}
c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
MIPS_CPU_NOFPUEX;
if (__cpu_has_fpu())
c->options |= MIPS_CPU_FPU;
c->tlbsize = 64 ;
break ;
}
BUG_ON(!__cpu_name[cpu]);
BUG_ON(c->cputype == CPU_UNKNOWN);
/*
* Platform code can force the cpu type to optimize code
* generation . In that case be sure the cpu type is correctly
* manually setup otherwise it could trigger some nasty bugs .
*/
BUG_ON(current_cpu_type() != c->cputype);
if (mips_fpu_disabled)
c->options &= ~MIPS_CPU_FPU;
if (c->options & MIPS_CPU_FPU)
cpu_set_fpu_opts(c);
else
cpu_set_nofpu_opts(c);
reserve_exception_space(0 , 0 x400);
}
void cpu_report(void )
{
struct cpuinfo_mips *c = ¤t_cpu_data;
pr_info("CPU%d revision is: %08x (%s)\n" ,
smp_processor_id(), c->processor_id, cpu_name_string());
if (c->options & MIPS_CPU_FPU)
pr_info("FPU revision is: %08x\n" , c->fpu_id);
}
Messung V0.5 in Prozent C=95 H=74 G=84
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland