cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cpu-r3k-probe.c (3667B)


      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	extern unsigned long r3k_cache_size(unsigned long);
     46	unsigned long size1, size2;
     47	unsigned long cfg = read_c0_conf();
     48
     49	size1 = r3k_cache_size(ST0_ISC);
     50	write_c0_conf(cfg ^ R30XX_CONF_AC);
     51	size2 = r3k_cache_size(ST0_ISC);
     52	write_c0_conf(cfg);
     53	return size1 != size2;
     54#else
     55	return 0;
     56#endif
     57}
     58
     59static inline void set_elf_platform(int cpu, const char *plat)
     60{
     61	if (cpu == 0)
     62		__elf_platform = plat;
     63}
     64
     65const char *__cpu_name[NR_CPUS];
     66const char *__elf_platform;
     67const char *__elf_base_platform;
     68
     69void cpu_probe(void)
     70{
     71	struct cpuinfo_mips *c = &current_cpu_data;
     72	unsigned int cpu = smp_processor_id();
     73
     74	/*
     75	 * Set a default elf platform, cpu probe may later
     76	 * overwrite it with a more precise value
     77	 */
     78	set_elf_platform(cpu, "mips");
     79
     80	c->processor_id = PRID_IMP_UNKNOWN;
     81	c->fpu_id	= FPIR_IMP_NONE;
     82	c->cputype	= CPU_UNKNOWN;
     83	c->writecombine = _CACHE_UNCACHED;
     84
     85	c->fpu_csr31	= FPU_CSR_RN;
     86	c->fpu_msk31	= FPU_CSR_RSVD | FPU_CSR_ABS2008 | FPU_CSR_NAN2008 |
     87			  FPU_CSR_CONDX | FPU_CSR_FS;
     88
     89	c->srsets = 1;
     90
     91	c->processor_id = read_c0_prid();
     92	switch (c->processor_id & (PRID_COMP_MASK | PRID_IMP_MASK)) {
     93	case PRID_COMP_LEGACY | PRID_IMP_R2000:
     94		c->cputype = CPU_R2000;
     95		__cpu_name[cpu] = "R2000";
     96		c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
     97			     MIPS_CPU_NOFPUEX;
     98		if (__cpu_has_fpu())
     99			c->options |= MIPS_CPU_FPU;
    100		c->tlbsize = 64;
    101		break;
    102	case PRID_COMP_LEGACY | PRID_IMP_R3000:
    103		if ((c->processor_id & PRID_REV_MASK) == PRID_REV_R3000A) {
    104			if (cpu_has_confreg()) {
    105				c->cputype = CPU_R3081E;
    106				__cpu_name[cpu] = "R3081";
    107			} else {
    108				c->cputype = CPU_R3000A;
    109				__cpu_name[cpu] = "R3000A";
    110			}
    111		} else {
    112			c->cputype = CPU_R3000;
    113			__cpu_name[cpu] = "R3000";
    114		}
    115		c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE |
    116			     MIPS_CPU_NOFPUEX;
    117		if (__cpu_has_fpu())
    118			c->options |= MIPS_CPU_FPU;
    119		c->tlbsize = 64;
    120		break;
    121	}
    122
    123	BUG_ON(!__cpu_name[cpu]);
    124	BUG_ON(c->cputype == CPU_UNKNOWN);
    125
    126	/*
    127	 * Platform code can force the cpu type to optimize code
    128	 * generation. In that case be sure the cpu type is correctly
    129	 * manually setup otherwise it could trigger some nasty bugs.
    130	 */
    131	BUG_ON(current_cpu_type() != c->cputype);
    132
    133	if (mips_fpu_disabled)
    134		c->options &= ~MIPS_CPU_FPU;
    135
    136	if (c->options & MIPS_CPU_FPU)
    137		cpu_set_fpu_opts(c);
    138	else
    139		cpu_set_nofpu_opts(c);
    140
    141	reserve_exception_space(0, 0x400);
    142}
    143
    144void cpu_report(void)
    145{
    146	struct cpuinfo_mips *c = &current_cpu_data;
    147
    148	pr_info("CPU%d revision is: %08x (%s)\n",
    149		smp_processor_id(), c->processor_id, cpu_name_string());
    150	if (c->options & MIPS_CPU_FPU)
    151		pr_info("FPU revision is: %08x\n", c->fpu_id);
    152}