root/arch/sparc/kernel/probe.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. probe_cpu
  2. probe_vac
  3. probe_mmu
  4. probe_clock
  5. probe_esp
  6. probe_sbus
  7. probe_devices

   1 /* probe.c: Preliminary device tree probing routines...
   2 
   3    Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
   4 */
   5 
   6 #include <linux/kernel.h>
   7 #include <asm/vac-ops.h>
   8 
   9 /* #define DEBUG_PROBING */
  10 
  11 char promstr_buf[64];         /* overkill */
  12 unsigned int promint_buf[1];
  13 
  14 extern int prom_node_root;
  15 extern int num_segmaps, num_contexts;
  16 
  17 extern int node_get_sibling(int node);
  18 extern int node_get_child(int node);
  19 extern char* get_str_from_prom(int node, char* name, char* value);
  20 extern unsigned int* get_int_from_prom(int node, char* name, unsigned int *value);
  21 
  22 /* Cpu-type information and manufacturer strings */
  23 
  24 
  25 struct cpu_iu_info {
  26   int psr_impl;
  27   int psr_vers;
  28   char* cpu_name;   /* should be enough I hope... */
  29 };
  30 
  31 struct cpu_fp_info {
  32   int psr_impl;
  33   int fp_vers;
  34   char* fp_name;
  35 };
  36 
  37 struct cpu_fp_info linux_sparc_fpu[] = {
  38   { 0, 0, "Fujitsu MB86910 or Weitek WTL1164/5"},
  39   { 0, 1, "Fujitsu MB86911 or Weitek WTL1164/5"},
  40   { 0, 2, "LSI Logic L64802 or Texas Instruments ACT8847"},
  41   { 0, 3, "Weitek WTL3170/2"},
  42   { 0, 4, "Lsi Logic/Meiko L64804"},
  43   { 0, 5, "reserved"},
  44   { 0, 6, "reserved"},
  45   { 0, 7, "No FPU"},
  46   { 1, 0, "Lsi Logic L64812 or Texas Instruments ACT8847"},
  47   { 1, 1, "Lsi Logic L64814"},
  48   { 1, 2, "Texas Instruments TMS390-C602A"},
  49   { 1, 3, "Weitek WTL3171"},
  50   { 1, 4, "reserved"},
  51   { 1, 5, "reserved"},
  52   { 1, 6, "reserved"},
  53   { 1, 7, "No FPU"},
  54   { 2, 0, "BIT B5010 or B5110/20 or B5210"},
  55   { 2, 1, "reserved"},
  56   { 2, 2, "reserved"},
  57   { 2, 3, "reserved"},
  58   { 2, 4,  "reserved"},
  59   { 2, 5, "reserved"},
  60   { 2, 6, "reserved"},
  61   { 2, 7, "No FPU"},
  62   { 5, 0, "Matsushita MN10501"},
  63   { 5, 1, "reserved"},
  64   { 5, 2, "reserved"},
  65   { 5, 3, "reserved"},
  66   { 5, 4, "reserved"},
  67   { 5, 5, "reserved"},
  68   { 5, 6, "reserved"},
  69   { 5, 7, "No FPU"},
  70 };
  71 
  72 struct cpu_iu_info linux_sparc_chips[] = {
  73   { 0, 0, "Fujitsu Microelectronics, Inc. - MB86900/1A"},
  74   { 1, 0, "Cypress CY7C601"},
  75   { 1, 1, "LSI Logic Corporation - L64811"},
  76   { 1, 3, "Cypress CY7C611"},
  77   { 2, 0, "Bipolar Integrated Technology - B5010"},
  78   { 3, 0, "LSI Logic Corporation - unknown-type"},
  79   { 4, 0, "Texas Instruments, Inc. - unknown"},
  80   { 4, 1, "Texas Instruments, Inc. - unknown"},
  81   { 4, 2, "Texas Instruments, Inc. - unknown"},
  82   { 4, 3, "Texas Instruments, Inc. - unknown"},
  83   { 4, 4, "Texas Instruments, Inc. - unknown"},
  84   { 4, 5, "Texas Instruments, Inc. - unknown"},
  85   { 5, 0, "Matsushita - MN10501"},
  86   { 6, 0, "Philips Corporation - unknown"},
  87   { 7, 0, "Harvest VLSI Design Center, Inc. - unknown"},
  88   { 8, 0, "Systems and Processes Engineering Corporation (SPEC)"},
  89   { 9, 0, "UNKNOWN CPU-VENDOR/TYPE"},
  90   { 0xa, 0, "UNKNOWN CPU-VENDOR/TYPE"},
  91   { 0xb, 0, "UNKNOWN CPU-VENDOR/TYPE"},
  92   { 0xc, 0, "UNKNOWN CPU-VENDOR/TYPE"},
  93   { 0xd, 0, "UNKNOWN CPU-VENDOR/TYPE"},
  94   { 0xe, 0, "UNKNOWN CPU-VENDOR/TYPE"},
  95   { 0xf, 0, "UNKNOWN CPU-VENDOR/TYPE"},
  96 };
  97 
  98 char *sparc_cpu_type = "cpu-oops";
  99 char *sparc_fpu_type = "fpu-oops";
 100 
 101 /* various Virtual Address Cache parameters we find at boot time... */
 102 
 103 extern int vac_size, vac_linesize, vac_do_hw_vac_flushes;
 104 extern int vac_entries_per_context, vac_entries_per_segment;
 105 extern int vac_entries_per_page;
 106 
 107 extern int find_vac_size(void);
 108 extern int find_vac_linesize(void);
 109 extern int find_vac_hwflushes(void);
 110 extern void find_mmu_num_segmaps(void);
 111 extern void find_mmu_num_contexts(void);
 112 
 113 void
 114 probe_cpu(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 115 {
 116   register int psr_impl, psr_vers, fpu_vers, i;
 117   unsigned int tmp_fsr;
 118 
 119   &tmp_fsr;   /* GCC grrr... */
 120 
 121   __asm__("rd %%psr, %0\n\t"
 122           "mov %0, %1\n\t"
 123           "srl %0, 28, %0\n\t"
 124           "srl %1, 24, %1\n\t"
 125           "and %0, 0xf, %0\n\t"
 126           "and %1, 0xf, %1\n\t" :
 127           "=r" (psr_impl),
 128           "=r" (psr_vers) :
 129           "0" (psr_impl),
 130           "1" (psr_vers));
 131 
 132 
 133   __asm__("st %%fsr, %1\n\t"
 134           "ld %1, %0\n\t"
 135           "srl %0, 17, %0\n\t"
 136           "and %0, 0x7, %0\n\t" :
 137           "=r" (fpu_vers),
 138           "=m" (tmp_fsr) :
 139           "0" (fpu_vers),
 140           "1" (tmp_fsr));
 141 
 142   printk("fpu_vers: %d ", fpu_vers);
 143   printk("psr_impl: %d ", psr_impl);
 144   printk("psr_vers: %d \n\n", psr_vers);
 145 
 146   for(i = 0; i<23; i++)
 147     {
 148       if(linux_sparc_chips[i].psr_impl == psr_impl)
 149         if(linux_sparc_chips[i].psr_vers == psr_vers)
 150           {
 151             sparc_cpu_type = linux_sparc_chips[i].cpu_name;
 152             break;
 153           }
 154     }
 155 
 156   if(i==23)
 157     {
 158       printk("No CPU type! You lose\n");
 159       printk("DEBUG: psr.impl = 0x%x   psr.vers = 0x%x\n", psr_impl, 
 160              psr_vers);
 161       return;
 162     }
 163 
 164   for(i = 0; i<32; i++)
 165     {
 166       if(linux_sparc_fpu[i].psr_impl == psr_impl)
 167         if(linux_sparc_fpu[i].fp_vers == fpu_vers)
 168           {
 169             sparc_fpu_type = linux_sparc_fpu[i].fp_name;
 170             break;
 171           }
 172     }
 173 
 174   if(i == 32)
 175     {
 176       printk("No FPU type! You don't completely lose though...\n");
 177       printk("DEBUG: psr.impl = 0x%x  fsr.vers = 0x%x\n", psr_impl, fpu_vers);
 178       sparc_fpu_type = linux_sparc_fpu[31].fp_name;
 179     }
 180 
 181   printk("CPU: %s \n", sparc_cpu_type);
 182   printk("FPU: %s \n", sparc_fpu_type);
 183 
 184   return;
 185 }
 186 
 187 void
 188 probe_vac(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 189 {
 190   register unsigned int x,y;
 191 
 192   vac_size = find_vac_size();
 193   vac_linesize = find_vac_linesize();
 194   vac_do_hw_vac_flushes = find_vac_hwflushes();
 195 
 196   /* Calculate various constants that make the cache-flushing code
 197    * mode speedy.
 198    */
 199 
 200   vac_entries_per_segment = vac_entries_per_context = vac_size >> 12;
 201 
 202   for(x=0,y=vac_linesize; ((1<<x)<y); x++);
 203   if((1<<x) != vac_linesize) printk("Warning BOGUS VAC linesize 0x%x",
 204                                     vac_size);
 205 
 206   vac_entries_per_page = x;
 207 
 208   printk("Sparc VAC cache: Size=%d bytes  Line-Size=%d bytes ... ", vac_size,
 209          vac_linesize);
 210 
 211   /* Here we want to 'invalidate' all the software VAC "tags"
 212    * just in case there is garbage in there. Then we enable it.
 213    */
 214 
 215   for(x=0x80000000, y=(x+vac_size); x<y; x+=vac_linesize)
 216     __asm__("sta %0, [%1] %2" : : "r" (0), "r" (x), "n" (0x2));
 217 
 218   x=enable_vac();
 219   printk("ENABLED\n");
 220 
 221   return;
 222 }
 223 
 224 void
 225 probe_mmu(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 226 {
 227   find_mmu_num_segmaps();
 228   find_mmu_num_contexts();
 229 
 230   printk("\nMMU segmaps: %d     MMU contexts: %d\n", num_segmaps, 
 231          num_contexts);
 232 
 233   return;
 234 }
 235 
 236 void
 237 probe_clock(int fchild)
     /* [previous][next][first][last][top][bottom][index][help] */
 238 {
 239   /* TODO :> I just can't stomache it right now... */
 240   return;
 241 }
 242 
 243 
 244 void
 245 probe_esp(register int esp_node)
     /* [previous][next][first][last][top][bottom][index][help] */
 246 {
 247   register int nd;
 248   register char* lbuf;
 249 
 250   nd = node_get_child(esp_node);
 251 
 252   printk("\nProbing ESP:\n");
 253   lbuf = get_str_from_prom(nd, "name", promstr_buf);
 254 
 255   printk("\nProperty length for %s: 0x%x\n", "name", 
 256          *get_int_from_prom(nd, "name", promint_buf));
 257 
 258   if(*get_int_from_prom(nd, "name", promint_buf) != 0)
 259   printk("Node: 0x%x Name: %s", nd, lbuf);
 260 
 261   lbuf = get_str_from_prom(nd, "device-type", promstr_buf);
 262 
 263   printk("\nProperty length for %s: 0x%x\n", "device_type", 
 264          *get_int_from_prom(nd, "device_type", promint_buf));
 265 
 266   if(*get_int_from_prom(nd, "device-type", promint_buf) != 0)
 267     printk("Device-Type: %s ", lbuf);
 268   
 269   lbuf = get_str_from_prom(nd, "model", promstr_buf);
 270 
 271   printk("\nProperty length for %s: 0x%x\n", "model", 
 272          *get_int_from_prom(nd, "model", promint_buf));
 273 
 274   if(*get_int_from_prom(nd, "model", promint_buf) != 0)
 275     printk("Model: %s", lbuf);
 276 
 277   printk("\n");
 278 
 279   while((nd = node_get_sibling(nd)) != 0)
 280     {
 281       lbuf = get_str_from_prom(nd, "name", promstr_buf);
 282 
 283       if(*get_int_from_prom(nd, "name", promint_buf) != 0)
 284       printk("Node: 0x%x Name: %s ", nd, lbuf);
 285 
 286       lbuf = get_str_from_prom(nd, "device-type", promstr_buf);
 287 
 288       if(*get_int_from_prom(nd, "device-type", promint_buf) != 0)
 289       printk("Device-Type: %s ", lbuf);
 290 
 291       lbuf = get_str_from_prom(nd, "model", promstr_buf);
 292 
 293       if(*get_int_from_prom(nd, "model", promint_buf) != 0)
 294       printk("Model: %s", lbuf);
 295 
 296       printk("\n");
 297     }
 298 
 299   printk("\n");
 300 
 301   return;
 302 }
 303 
 304 void
 305 probe_sbus(register int cpu_child_node)
     /* [previous][next][first][last][top][bottom][index][help] */
 306 {
 307   register int nd, savend;
 308   register char* lbuf;
 309 
 310   nd = cpu_child_node;
 311 
 312   lbuf = (char *) 0;
 313 
 314   while((nd = node_get_sibling(nd)) != 0)
 315     {
 316       lbuf = get_str_from_prom(nd, "name", promstr_buf);
 317       if(lbuf[0]=='s' && lbuf[1]=='b' && lbuf[2]=='u' && lbuf[3]=='s')
 318         break;
 319     }
 320   nd = node_get_child(nd);
 321 
 322   printk("Node: 0x%x Name: %s\n", nd,
 323          get_str_from_prom(nd, "name", promstr_buf));
 324 
 325   if(lbuf[0]=='e' && lbuf[1]=='s' && lbuf[2]=='p')
 326     probe_esp(nd);
 327 
 328   while((nd = node_get_sibling(nd)) != 0)
 329     {
 330       printk("Node: 0x%x Name: %s\n", nd,
 331              get_str_from_prom(nd, "name", promstr_buf));
 332 
 333           if(lbuf[0]=='e' && lbuf[1]=='s' && lbuf[2]=='p')
 334             {
 335               savend = nd;
 336               probe_esp(nd);
 337               nd = savend;
 338             }
 339     }
 340 
 341   return;
 342 }
 343 
 344 void
 345 probe_devices(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 346 {
 347   register int nd, first_descent;
 348   register char* str;
 349 
 350   nd = prom_node_root;
 351 
 352   printk("PROBING DEVICES:\n");
 353 
 354   str = get_str_from_prom(nd, "device_type", promstr_buf);
 355   printk("Root Node: 0x%x ", nd);
 356 
 357 #ifdef DEBUG_PROBING
 358   printk("String address for d_type: 0x%x\n", (unsigned int) str);
 359   printk("str[0] = %c  str[1] = %c  str[2] = %c \n", str[0], str[1], str[2]);
 360 #endif
 361 
 362   printk("Device Type: %s ", str);
 363 
 364   str = get_str_from_prom(nd, "name", promstr_buf);
 365 
 366 #ifdef DEBUG_PROBING
 367   printk("String address for name: 0x%x\n", (unsigned int) str);
 368   printk("str[0] = %c  str[1] = %c  str[2] = %c \n", str[0], str[1], str[2]);
 369 #endif
 370 
 371   printk("Name: %s \n", str);
 372 
 373   first_descent = nd = node_get_child(nd);
 374 
 375 
 376 /* Ok, here will go a call to each specific device probe. We can
 377    call these now that we have the 'root' node and the child of
 378    this node to send to the routines. ORDER IS IMPORTANT!
 379 */
 380 
 381   probe_cpu();
 382   probe_vac();
 383   probe_mmu();
 384   probe_clock(first_descent);
 385 
 386 /*
 387   printk("PROM Root Child Node: 0x%x Name: %s \n", nd,
 388          get_str_from_prom(nd, "name", promstr_buf));
 389 
 390   while((nd = node_get_sibling(nd)) != 0)
 391     {
 392 
 393       printk("Node: 0x%x Name: %s\n", nd,
 394              get_str_from_prom(nd, "name", promstr_buf));
 395 
 396     }
 397 
 398   printk("\nProbing SBUS:\n");
 399   probe_sbus(first_descent);
 400 */
 401 
 402   return;
 403 }

/* [previous][next][first][last][top][bottom][index][help] */