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

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