cpu.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /* cpu.c: Dinky routines to look for the kind of Sparc cpu
  2. * we are on.
  3. *
  4. * Copyright (C) 1996, 2007 David S. Miller (davem@davemloft.net)
  5. */
  6. #include <linux/kernel.h>
  7. #include <linux/init.h>
  8. #include <linux/sched.h>
  9. #include <linux/smp.h>
  10. #include <asm/asi.h>
  11. #include <asm/system.h>
  12. #include <asm/fpumacro.h>
  13. #include <asm/cpudata.h>
  14. #include <asm/spitfire.h>
  15. #include <asm/oplib.h>
  16. #include "entry.h"
  17. DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 };
  18. struct cpu_iu_info {
  19. short manuf;
  20. short impl;
  21. char* cpu_name; /* should be enough I hope... */
  22. };
  23. struct cpu_fp_info {
  24. short manuf;
  25. short impl;
  26. char fpu_vers;
  27. char* fp_name;
  28. };
  29. static struct cpu_fp_info linux_sparc_fpu[] = {
  30. { 0x17, 0x10, 0, "UltraSparc I integrated FPU"},
  31. { 0x22, 0x10, 0, "UltraSparc I integrated FPU"},
  32. { 0x17, 0x11, 0, "UltraSparc II integrated FPU"},
  33. { 0x17, 0x12, 0, "UltraSparc IIi integrated FPU"},
  34. { 0x17, 0x13, 0, "UltraSparc IIe integrated FPU"},
  35. { 0x3e, 0x14, 0, "UltraSparc III integrated FPU"},
  36. { 0x3e, 0x15, 0, "UltraSparc III+ integrated FPU"},
  37. { 0x3e, 0x16, 0, "UltraSparc IIIi integrated FPU"},
  38. { 0x3e, 0x18, 0, "UltraSparc IV integrated FPU"},
  39. { 0x3e, 0x19, 0, "UltraSparc IV+ integrated FPU"},
  40. { 0x3e, 0x22, 0, "UltraSparc IIIi+ integrated FPU"},
  41. };
  42. #define NSPARCFPU ARRAY_SIZE(linux_sparc_fpu)
  43. static struct cpu_iu_info linux_sparc_chips[] = {
  44. { 0x17, 0x10, "TI UltraSparc I (SpitFire)"},
  45. { 0x22, 0x10, "TI UltraSparc I (SpitFire)"},
  46. { 0x17, 0x11, "TI UltraSparc II (BlackBird)"},
  47. { 0x17, 0x12, "TI UltraSparc IIi (Sabre)"},
  48. { 0x17, 0x13, "TI UltraSparc IIe (Hummingbird)"},
  49. { 0x3e, 0x14, "TI UltraSparc III (Cheetah)"},
  50. { 0x3e, 0x15, "TI UltraSparc III+ (Cheetah+)"},
  51. { 0x3e, 0x16, "TI UltraSparc IIIi (Jalapeno)"},
  52. { 0x3e, 0x18, "TI UltraSparc IV (Jaguar)"},
  53. { 0x3e, 0x19, "TI UltraSparc IV+ (Panther)"},
  54. { 0x3e, 0x22, "TI UltraSparc IIIi+ (Serrano)"},
  55. };
  56. #define NSPARCCHIPS ARRAY_SIZE(linux_sparc_chips)
  57. char *sparc_cpu_type;
  58. char *sparc_fpu_type;
  59. static void __init sun4v_cpu_probe(void)
  60. {
  61. switch (sun4v_chip_type) {
  62. case SUN4V_CHIP_NIAGARA1:
  63. sparc_cpu_type = "UltraSparc T1 (Niagara)";
  64. sparc_fpu_type = "UltraSparc T1 integrated FPU";
  65. break;
  66. case SUN4V_CHIP_NIAGARA2:
  67. sparc_cpu_type = "UltraSparc T2 (Niagara2)";
  68. sparc_fpu_type = "UltraSparc T2 integrated FPU";
  69. break;
  70. default:
  71. printk(KERN_WARNING "CPU: Unknown sun4v cpu type [%s]\n",
  72. prom_cpu_compatible);
  73. sparc_cpu_type = "Unknown SUN4V CPU";
  74. sparc_fpu_type = "Unknown SUN4V FPU";
  75. break;
  76. }
  77. }
  78. void __init cpu_probe(void)
  79. {
  80. unsigned long ver, fpu_vers, manuf, impl, fprs;
  81. int i;
  82. if (tlb_type == hypervisor) {
  83. sun4v_cpu_probe();
  84. return;
  85. }
  86. fprs = fprs_read();
  87. fprs_write(FPRS_FEF);
  88. __asm__ __volatile__ ("rdpr %%ver, %0; stx %%fsr, [%1]"
  89. : "=&r" (ver)
  90. : "r" (&fpu_vers));
  91. fprs_write(fprs);
  92. manuf = ((ver >> 48) & 0xffff);
  93. impl = ((ver >> 32) & 0xffff);
  94. fpu_vers = ((fpu_vers >> 17) & 0x7);
  95. retry:
  96. for (i = 0; i < NSPARCCHIPS; i++) {
  97. if (linux_sparc_chips[i].manuf == manuf) {
  98. if (linux_sparc_chips[i].impl == impl) {
  99. sparc_cpu_type =
  100. linux_sparc_chips[i].cpu_name;
  101. break;
  102. }
  103. }
  104. }
  105. if (i == NSPARCCHIPS) {
  106. /* Maybe it is a cheetah+ derivative, report it as cheetah+
  107. * in that case until we learn the real names.
  108. */
  109. if (manuf == 0x3e &&
  110. impl > 0x15) {
  111. impl = 0x15;
  112. goto retry;
  113. } else {
  114. printk("DEBUG: manuf[%lx] impl[%lx]\n",
  115. manuf, impl);
  116. }
  117. sparc_cpu_type = "Unknown CPU";
  118. }
  119. for (i = 0; i < NSPARCFPU; i++) {
  120. if (linux_sparc_fpu[i].manuf == manuf &&
  121. linux_sparc_fpu[i].impl == impl) {
  122. if (linux_sparc_fpu[i].fpu_vers == fpu_vers) {
  123. sparc_fpu_type =
  124. linux_sparc_fpu[i].fp_name;
  125. break;
  126. }
  127. }
  128. }
  129. if (i == NSPARCFPU) {
  130. printk("DEBUG: manuf[%lx] impl[%lx] fsr.vers[%lx]\n",
  131. manuf, impl, fpu_vers);
  132. sparc_fpu_type = "Unknown FPU";
  133. }
  134. }