blob: 0c9ac83ed0a89949c562d962f30c3837c04958b6 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* cpu.c: Dinky routines to look for the kind of Sparc cpu
2 * we are on.
3 *
David S. Millerba4962d2008-08-31 21:48:12 -07004 * Copyright (C) 1996, 2007, 2008 David S. Miller (davem@davemloft.net)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 */
6
Linus Torvalds1da177e2005-04-16 15:20:36 -07007#include <linux/kernel.h>
8#include <linux/init.h>
9#include <linux/sched.h>
10#include <linux/smp.h>
11#include <asm/asi.h>
12#include <asm/system.h>
13#include <asm/fpumacro.h>
14#include <asm/cpudata.h>
David S. Miller12816ab2006-02-09 03:00:00 -080015#include <asm/spitfire.h>
David S. Miller6c70b6f2007-08-08 17:11:39 -070016#include <asm/oplib.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070017
David S. Miller3d5ae6b2008-03-25 21:51:40 -070018#include "entry.h"
19
Linus Torvalds1da177e2005-04-16 15:20:36 -070020DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 };
21
David S. Millerba4962d2008-08-31 21:48:12 -070022struct cpu_chip_info {
23 unsigned short manuf;
24 unsigned short impl;
25 const char *cpu_name;
26 const char *fp_name;
Linus Torvalds1da177e2005-04-16 15:20:36 -070027};
28
David S. Millerba4962d2008-08-31 21:48:12 -070029static const struct cpu_chip_info cpu_chips[] = {
30 {
31 .manuf = 0x17,
32 .impl = 0x10,
33 .cpu_name = "TI UltraSparc I (SpitFire)",
34 .fp_name = "UltraSparc I integrated FPU",
35 },
36 {
37 .manuf = 0x22,
38 .impl = 0x10,
39 .cpu_name = "TI UltraSparc I (SpitFire)",
40 .fp_name = "UltraSparc I integrated FPU",
41 },
42 {
43 .manuf = 0x17,
44 .impl = 0x11,
45 .cpu_name = "TI UltraSparc II (BlackBird)",
46 .fp_name = "UltraSparc II integrated FPU",
47 },
48 {
49 .manuf = 0x17,
50 .impl = 0x12,
51 .cpu_name = "TI UltraSparc IIi (Sabre)",
52 .fp_name = "UltraSparc IIi integrated FPU",
53 },
54 {
55 .manuf = 0x17,
56 .impl = 0x13,
57 .cpu_name = "TI UltraSparc IIe (Hummingbird)",
58 .fp_name = "UltraSparc IIe integrated FPU",
59 },
60 {
61 .manuf = 0x3e,
62 .impl = 0x14,
63 .cpu_name = "TI UltraSparc III (Cheetah)",
64 .fp_name = "UltraSparc III integrated FPU",
65 },
66 {
67 .manuf = 0x3e,
68 .impl = 0x15,
69 .cpu_name = "TI UltraSparc III+ (Cheetah+)",
70 .fp_name = "UltraSparc III+ integrated FPU",
71 },
72 {
73 .manuf = 0x3e,
74 .impl = 0x16,
75 .cpu_name = "TI UltraSparc IIIi (Jalapeno)",
76 .fp_name = "UltraSparc IIIi integrated FPU",
77 },
78 {
79 .manuf = 0x3e,
80 .impl = 0x18,
81 .cpu_name = "TI UltraSparc IV (Jaguar)",
82 .fp_name = "UltraSparc IV integrated FPU",
83 },
84 {
85 .manuf = 0x3e,
86 .impl = 0x19,
87 .cpu_name = "TI UltraSparc IV+ (Panther)",
88 .fp_name = "UltraSparc IV+ integrated FPU",
89 },
90 {
91 .manuf = 0x3e,
92 .impl = 0x22,
93 .cpu_name = "TI UltraSparc IIIi+ (Serrano)",
94 .fp_name = "UltraSparc IIIi+ integrated FPU",
95 },
Linus Torvalds1da177e2005-04-16 15:20:36 -070096};
97
David S. Millerba4962d2008-08-31 21:48:12 -070098#define NSPARCCHIPS ARRAY_SIZE(linux_sparc_chips)
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
David S. Millerba4962d2008-08-31 21:48:12 -0700100const char *sparc_cpu_type;
101const char *sparc_fpu_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
David S. Miller68c9f9f2007-08-07 19:09:29 -0700103static void __init sun4v_cpu_probe(void)
104{
David S. Miller6c70b6f2007-08-08 17:11:39 -0700105 switch (sun4v_chip_type) {
106 case SUN4V_CHIP_NIAGARA1:
David S. Miller68c9f9f2007-08-07 19:09:29 -0700107 sparc_cpu_type = "UltraSparc T1 (Niagara)";
108 sparc_fpu_type = "UltraSparc T1 integrated FPU";
David S. Miller6c70b6f2007-08-08 17:11:39 -0700109 break;
110
111 case SUN4V_CHIP_NIAGARA2:
David S. Miller68c9f9f2007-08-07 19:09:29 -0700112 sparc_cpu_type = "UltraSparc T2 (Niagara2)";
113 sparc_fpu_type = "UltraSparc T2 integrated FPU";
David S. Miller6c70b6f2007-08-08 17:11:39 -0700114 break;
David S. Miller68c9f9f2007-08-07 19:09:29 -0700115
David S. Miller6c70b6f2007-08-08 17:11:39 -0700116 default:
117 printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n",
118 prom_cpu_compatible);
119 sparc_cpu_type = "Unknown SUN4V CPU";
120 sparc_fpu_type = "Unknown SUN4V FPU";
121 break;
122 }
David S. Miller68c9f9f2007-08-07 19:09:29 -0700123}
124
David S. Millerba4962d2008-08-31 21:48:12 -0700125static const struct cpu_chip_info * __init find_cpu_chip(unsigned short manuf,
126 unsigned short impl)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128 int i;
David S. Millerba4962d2008-08-31 21:48:12 -0700129
130 for (i = 0; i < ARRAY_SIZE(cpu_chips); i++) {
131 const struct cpu_chip_info *p = &cpu_chips[i];
132
133 if (p->manuf == manuf && p->impl == impl)
134 return p;
135 }
136 return NULL;
137}
138
139static int __init cpu_type_probe(void)
140{
David S. Miller3d5ae6b2008-03-25 21:51:40 -0700141 if (tlb_type == hypervisor) {
142 sun4v_cpu_probe();
David S. Millerba4962d2008-08-31 21:48:12 -0700143 } else {
144 unsigned long ver, manuf, impl;
145 const struct cpu_chip_info *p;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146
David S. Millerba4962d2008-08-31 21:48:12 -0700147 __asm__ __volatile__("rdpr %%ver, %0" : "=r" (ver));
148
149 manuf = ((ver >> 48) & 0xffff);
150 impl = ((ver >> 32) & 0xffff);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151
David S. Millerba4962d2008-08-31 21:48:12 -0700152 p = find_cpu_chip(manuf, impl);
153 if (p) {
154 sparc_cpu_type = p->cpu_name;
155 sparc_fpu_type = p->fp_name;
156 } else {
157 printk(KERN_ERR "CPU: Unknown chip, manuf[%lx] impl[%lx]\n",
158 manuf, impl);
159 sparc_cpu_type = "Unknown CPU";
160 sparc_fpu_type = "Unknown FPU";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161 }
162 }
David S. Millerba4962d2008-08-31 21:48:12 -0700163 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700164}
David S. Millerba4962d2008-08-31 21:48:12 -0700165
166arch_initcall(cpu_type_probe);