cpu.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. /* cpu.c: Dinky routines to look for the kind of Sparc cpu
  2. * we are on.
  3. *
  4. * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
  5. */
  6. #include <linux/kernel.h>
  7. #include <linux/init.h>
  8. #include <linux/smp.h>
  9. #include <linux/threads.h>
  10. #include <asm/spitfire.h>
  11. #include <asm/oplib.h>
  12. #include <asm/page.h>
  13. #include <asm/head.h>
  14. #include <asm/psr.h>
  15. #include <asm/mbus.h>
  16. #include <asm/cpudata.h>
  17. #include "kernel.h"
  18. DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 };
  19. struct cpu_info {
  20. int psr_vers;
  21. const char *name;
  22. };
  23. struct fpu_info {
  24. int fp_vers;
  25. const char *name;
  26. };
  27. #define NOCPU 8
  28. #define NOFPU 8
  29. struct manufacturer_info {
  30. int psr_impl;
  31. struct cpu_info cpu_info[NOCPU];
  32. struct fpu_info fpu_info[NOFPU];
  33. };
  34. #define CPU(ver, _name) \
  35. { .psr_vers = ver, .name = _name }
  36. #define FPU(ver, _name) \
  37. { .fp_vers = ver, .name = _name }
  38. static const struct manufacturer_info __initconst manufacturer_info[] = {
  39. {
  40. 0,
  41. /* Sun4/100, 4/200, SLC */
  42. .cpu_info = {
  43. CPU(0, "Fujitsu MB86900/1A or LSI L64831 SparcKIT-40"),
  44. /* borned STP1012PGA */
  45. CPU(4, "Fujitsu MB86904"),
  46. CPU(5, "Fujitsu TurboSparc MB86907"),
  47. CPU(-1, NULL)
  48. },
  49. .fpu_info = {
  50. FPU(0, "Fujitsu MB86910 or Weitek WTL1164/5"),
  51. FPU(1, "Fujitsu MB86911 or Weitek WTL1164/5 or LSI L64831"),
  52. FPU(2, "LSI Logic L64802 or Texas Instruments ACT8847"),
  53. /* SparcStation SLC, SparcStation1 */
  54. FPU(3, "Weitek WTL3170/2"),
  55. /* SPARCstation-5 */
  56. FPU(4, "Lsi Logic/Meiko L64804 or compatible"),
  57. FPU(-1, NULL)
  58. }
  59. },{
  60. 1,
  61. .cpu_info = {
  62. /* SparcStation2, SparcServer 490 & 690 */
  63. CPU(0, "LSI Logic Corporation - L64811"),
  64. /* SparcStation2 */
  65. CPU(1, "Cypress/ROSS CY7C601"),
  66. /* Embedded controller */
  67. CPU(3, "Cypress/ROSS CY7C611"),
  68. /* Ross Technologies HyperSparc */
  69. CPU(0xf, "ROSS HyperSparc RT620"),
  70. CPU(0xe, "ROSS HyperSparc RT625 or RT626"),
  71. CPU(-1, NULL)
  72. },
  73. .fpu_info = {
  74. FPU(0, "ROSS HyperSparc combined IU/FPU"),
  75. FPU(1, "Lsi Logic L64814"),
  76. FPU(2, "Texas Instruments TMS390-C602A"),
  77. FPU(3, "Cypress CY7C602 FPU"),
  78. FPU(-1, NULL)
  79. }
  80. },{
  81. 2,
  82. .cpu_info = {
  83. /* ECL Implementation, CRAY S-MP Supercomputer... AIEEE! */
  84. /* Someone please write the code to support this beast! ;) */
  85. CPU(0, "Bipolar Integrated Technology - B5010"),
  86. CPU(-1, NULL)
  87. },
  88. .fpu_info = {
  89. FPU(-1, NULL)
  90. }
  91. },{
  92. 3,
  93. .cpu_info = {
  94. CPU(0, "LSI Logic Corporation - unknown-type"),
  95. CPU(-1, NULL)
  96. },
  97. .fpu_info = {
  98. FPU(-1, NULL)
  99. }
  100. },{
  101. 4,
  102. .cpu_info = {
  103. CPU(0, "Texas Instruments, Inc. - SuperSparc-(II)"),
  104. /* SparcClassic -- borned STP1010TAB-50*/
  105. CPU(1, "Texas Instruments, Inc. - MicroSparc"),
  106. CPU(2, "Texas Instruments, Inc. - MicroSparc II"),
  107. CPU(3, "Texas Instruments, Inc. - SuperSparc 51"),
  108. CPU(4, "Texas Instruments, Inc. - SuperSparc 61"),
  109. CPU(5, "Texas Instruments, Inc. - unknown"),
  110. CPU(-1, NULL)
  111. },
  112. .fpu_info = {
  113. /* SuperSparc 50 module */
  114. FPU(0, "SuperSparc on-chip FPU"),
  115. /* SparcClassic */
  116. FPU(4, "TI MicroSparc on chip FPU"),
  117. FPU(-1, NULL)
  118. }
  119. },{
  120. 5,
  121. .cpu_info = {
  122. CPU(0, "Matsushita - MN10501"),
  123. CPU(-1, NULL)
  124. },
  125. .fpu_info = {
  126. FPU(0, "Matsushita MN10501"),
  127. FPU(-1, NULL)
  128. }
  129. },{
  130. 6,
  131. .cpu_info = {
  132. CPU(0, "Philips Corporation - unknown"),
  133. CPU(-1, NULL)
  134. },
  135. .fpu_info = {
  136. FPU(-1, NULL)
  137. }
  138. },{
  139. 7,
  140. .cpu_info = {
  141. CPU(0, "Harvest VLSI Design Center, Inc. - unknown"),
  142. CPU(-1, NULL)
  143. },
  144. .fpu_info = {
  145. FPU(-1, NULL)
  146. }
  147. },{
  148. 8,
  149. .cpu_info = {
  150. CPU(0, "Systems and Processes Engineering Corporation (SPEC)"),
  151. CPU(-1, NULL)
  152. },
  153. .fpu_info = {
  154. FPU(-1, NULL)
  155. }
  156. },{
  157. 9,
  158. .cpu_info = {
  159. /* Gallium arsenide 200MHz, BOOOOGOOOOMIPS!!! */
  160. CPU(0, "Fujitsu or Weitek Power-UP"),
  161. CPU(1, "Fujitsu or Weitek Power-UP"),
  162. CPU(2, "Fujitsu or Weitek Power-UP"),
  163. CPU(3, "Fujitsu or Weitek Power-UP"),
  164. CPU(-1, NULL)
  165. },
  166. .fpu_info = {
  167. FPU(3, "Fujitsu or Weitek on-chip FPU"),
  168. FPU(-1, NULL)
  169. }
  170. },{
  171. 0x17,
  172. .cpu_info = {
  173. CPU(0x10, "TI UltraSparc I (SpitFire)"),
  174. CPU(0x11, "TI UltraSparc II (BlackBird)"),
  175. CPU(0x12, "TI UltraSparc IIi (Sabre)"),
  176. CPU(0x13, "TI UltraSparc IIe (Hummingbird)"),
  177. CPU(-1, NULL)
  178. },
  179. .fpu_info = {
  180. FPU(0x10, "UltraSparc I integrated FPU"),
  181. FPU(0x11, "UltraSparc II integrated FPU"),
  182. FPU(0x12, "UltraSparc IIi integrated FPU"),
  183. FPU(0x13, "UltraSparc IIe integrated FPU"),
  184. FPU(-1, NULL)
  185. }
  186. },{
  187. 0x22,
  188. .cpu_info = {
  189. CPU(0x10, "TI UltraSparc I (SpitFire)"),
  190. CPU(-1, NULL)
  191. },
  192. .fpu_info = {
  193. FPU(0x10, "UltraSparc I integrated FPU"),
  194. FPU(-1, NULL)
  195. }
  196. },{
  197. 0x3e,
  198. .cpu_info = {
  199. CPU(0x14, "TI UltraSparc III (Cheetah)"),
  200. CPU(0x15, "TI UltraSparc III+ (Cheetah+)"),
  201. CPU(0x16, "TI UltraSparc IIIi (Jalapeno)"),
  202. CPU(0x18, "TI UltraSparc IV (Jaguar)"),
  203. CPU(0x19, "TI UltraSparc IV+ (Panther)"),
  204. CPU(0x22, "TI UltraSparc IIIi+ (Serrano)"),
  205. CPU(-1, NULL)
  206. },
  207. .fpu_info = {
  208. FPU(0x14, "UltraSparc III integrated FPU"),
  209. FPU(0x15, "UltraSparc III+ integrated FPU"),
  210. FPU(0x16, "UltraSparc IIIi integrated FPU"),
  211. FPU(0x18, "UltraSparc IV integrated FPU"),
  212. FPU(0x19, "UltraSparc IV+ integrated FPU"),
  213. FPU(0x22, "UltraSparc IIIi+ integrated FPU"),
  214. FPU(-1, NULL)
  215. }
  216. }};
  217. /* In order to get the fpu type correct, you need to take the IDPROM's
  218. * machine type value into consideration too. I will fix this.
  219. */
  220. const char *sparc_cpu_type;
  221. const char *sparc_fpu_type;
  222. unsigned int fsr_storage;
  223. static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers)
  224. {
  225. sparc_cpu_type = NULL;
  226. sparc_fpu_type = NULL;
  227. if (psr_impl < ARRAY_SIZE(manufacturer_info))
  228. {
  229. const struct cpu_info *cpu;
  230. const struct fpu_info *fpu;
  231. cpu = &manufacturer_info[psr_impl].cpu_info[0];
  232. while (cpu->psr_vers != -1)
  233. {
  234. if (cpu->psr_vers == psr_vers) {
  235. sparc_cpu_type = cpu->name;
  236. sparc_fpu_type = "No FPU";
  237. break;
  238. }
  239. cpu++;
  240. }
  241. fpu = &manufacturer_info[psr_impl].fpu_info[0];
  242. while (fpu->fp_vers != -1)
  243. {
  244. if (fpu->fp_vers == fpu_vers) {
  245. sparc_fpu_type = fpu->name;
  246. break;
  247. }
  248. fpu++;
  249. }
  250. }
  251. if (sparc_cpu_type == NULL)
  252. {
  253. printk(KERN_ERR "CPU: Unknown chip, impl[0x%x] vers[0x%x]\n",
  254. psr_impl, psr_vers);
  255. sparc_cpu_type = "Unknown CPU";
  256. }
  257. if (sparc_fpu_type == NULL)
  258. {
  259. printk(KERN_ERR "FPU: Unknown chip, impl[0x%x] vers[0x%x]\n",
  260. psr_impl, fpu_vers);
  261. sparc_fpu_type = "Unknown FPU";
  262. }
  263. }
  264. #ifdef CONFIG_SPARC32
  265. void __cpuinit cpu_probe(void)
  266. {
  267. int psr_impl, psr_vers, fpu_vers;
  268. int psr;
  269. psr_impl = ((get_psr() >> 28) & 0xf);
  270. psr_vers = ((get_psr() >> 24) & 0xf);
  271. psr = get_psr();
  272. put_psr(psr | PSR_EF);
  273. fpu_vers = ((get_fsr() >> 17) & 0x7);
  274. put_psr(psr);
  275. set_cpu_and_fpu(psr_impl, psr_vers, fpu_vers);
  276. }
  277. #else
  278. static void __init sun4v_cpu_probe(void)
  279. {
  280. switch (sun4v_chip_type) {
  281. case SUN4V_CHIP_NIAGARA1:
  282. sparc_cpu_type = "UltraSparc T1 (Niagara)";
  283. sparc_fpu_type = "UltraSparc T1 integrated FPU";
  284. break;
  285. case SUN4V_CHIP_NIAGARA2:
  286. sparc_cpu_type = "UltraSparc T2 (Niagara2)";
  287. sparc_fpu_type = "UltraSparc T2 integrated FPU";
  288. break;
  289. default:
  290. printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n",
  291. prom_cpu_compatible);
  292. sparc_cpu_type = "Unknown SUN4V CPU";
  293. sparc_fpu_type = "Unknown SUN4V FPU";
  294. break;
  295. }
  296. }
  297. static int __init cpu_type_probe(void)
  298. {
  299. if (tlb_type == hypervisor) {
  300. sun4v_cpu_probe();
  301. } else {
  302. unsigned long ver;
  303. int manuf, impl;
  304. __asm__ __volatile__("rdpr %%ver, %0" : "=r" (ver));
  305. manuf = ((ver >> 48) & 0xffff);
  306. impl = ((ver >> 32) & 0xffff);
  307. set_cpu_and_fpu(manuf, impl, impl);
  308. }
  309. return 0;
  310. }
  311. arch_initcall(cpu_type_probe);
  312. #endif