diff options
Diffstat (limited to 'arch/sparc/kernel/cpu_64.c')
-rw-r--r-- | arch/sparc/kernel/cpu_64.c | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/arch/sparc/kernel/cpu_64.c b/arch/sparc/kernel/cpu_64.c new file mode 100644 index 000000000000..0c9ac83ed0a8 --- /dev/null +++ b/arch/sparc/kernel/cpu_64.c @@ -0,0 +1,166 @@ +/* cpu.c: Dinky routines to look for the kind of Sparc cpu + * we are on. + * + * Copyright (C) 1996, 2007, 2008 David S. Miller (davem@davemloft.net) + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/sched.h> +#include <linux/smp.h> +#include <asm/asi.h> +#include <asm/system.h> +#include <asm/fpumacro.h> +#include <asm/cpudata.h> +#include <asm/spitfire.h> +#include <asm/oplib.h> + +#include "entry.h" + +DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 }; + +struct cpu_chip_info { + unsigned short manuf; + unsigned short impl; + const char *cpu_name; + const char *fp_name; +}; + +static const struct cpu_chip_info cpu_chips[] = { + { + .manuf = 0x17, + .impl = 0x10, + .cpu_name = "TI UltraSparc I (SpitFire)", + .fp_name = "UltraSparc I integrated FPU", + }, + { + .manuf = 0x22, + .impl = 0x10, + .cpu_name = "TI UltraSparc I (SpitFire)", + .fp_name = "UltraSparc I integrated FPU", + }, + { + .manuf = 0x17, + .impl = 0x11, + .cpu_name = "TI UltraSparc II (BlackBird)", + .fp_name = "UltraSparc II integrated FPU", + }, + { + .manuf = 0x17, + .impl = 0x12, + .cpu_name = "TI UltraSparc IIi (Sabre)", + .fp_name = "UltraSparc IIi integrated FPU", + }, + { + .manuf = 0x17, + .impl = 0x13, + .cpu_name = "TI UltraSparc IIe (Hummingbird)", + .fp_name = "UltraSparc IIe integrated FPU", + }, + { + .manuf = 0x3e, + .impl = 0x14, + .cpu_name = "TI UltraSparc III (Cheetah)", + .fp_name = "UltraSparc III integrated FPU", + }, + { + .manuf = 0x3e, + .impl = 0x15, + .cpu_name = "TI UltraSparc III+ (Cheetah+)", + .fp_name = "UltraSparc III+ integrated FPU", + }, + { + .manuf = 0x3e, + .impl = 0x16, + .cpu_name = "TI UltraSparc IIIi (Jalapeno)", + .fp_name = "UltraSparc IIIi integrated FPU", + }, + { + .manuf = 0x3e, + .impl = 0x18, + .cpu_name = "TI UltraSparc IV (Jaguar)", + .fp_name = "UltraSparc IV integrated FPU", + }, + { + .manuf = 0x3e, + .impl = 0x19, + .cpu_name = "TI UltraSparc IV+ (Panther)", + .fp_name = "UltraSparc IV+ integrated FPU", + }, + { + .manuf = 0x3e, + .impl = 0x22, + .cpu_name = "TI UltraSparc IIIi+ (Serrano)", + .fp_name = "UltraSparc IIIi+ integrated FPU", + }, +}; + +#define NSPARCCHIPS ARRAY_SIZE(linux_sparc_chips) + +const char *sparc_cpu_type; +const char *sparc_fpu_type; + +static void __init sun4v_cpu_probe(void) +{ + switch (sun4v_chip_type) { + case SUN4V_CHIP_NIAGARA1: + sparc_cpu_type = "UltraSparc T1 (Niagara)"; + sparc_fpu_type = "UltraSparc T1 integrated FPU"; + break; + + case SUN4V_CHIP_NIAGARA2: + sparc_cpu_type = "UltraSparc T2 (Niagara2)"; + sparc_fpu_type = "UltraSparc T2 integrated FPU"; + break; + + default: + printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n", + prom_cpu_compatible); + sparc_cpu_type = "Unknown SUN4V CPU"; + sparc_fpu_type = "Unknown SUN4V FPU"; + break; + } +} + +static const struct cpu_chip_info * __init find_cpu_chip(unsigned short manuf, + unsigned short impl) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cpu_chips); i++) { + const struct cpu_chip_info *p = &cpu_chips[i]; + + if (p->manuf == manuf && p->impl == impl) + return p; + } + return NULL; +} + +static int __init cpu_type_probe(void) +{ + if (tlb_type == hypervisor) { + sun4v_cpu_probe(); + } else { + unsigned long ver, manuf, impl; + const struct cpu_chip_info *p; + + __asm__ __volatile__("rdpr %%ver, %0" : "=r" (ver)); + + manuf = ((ver >> 48) & 0xffff); + impl = ((ver >> 32) & 0xffff); + + p = find_cpu_chip(manuf, impl); + if (p) { + sparc_cpu_type = p->cpu_name; + sparc_fpu_type = p->fp_name; + } else { + printk(KERN_ERR "CPU: Unknown chip, manuf[%lx] impl[%lx]\n", + manuf, impl); + sparc_cpu_type = "Unknown CPU"; + sparc_fpu_type = "Unknown FPU"; + } + } + return 0; +} + +arch_initcall(cpu_type_probe); |