source: trunk/athena/bin/machtype/machtype_sun4.c @ 11418

Revision 11418, 10.0 KB checked in by danw, 26 years ago (diff)
add -C option to print ATHENA_SYS_COMPAT value
Line 
1/*
2 *  Machtype: determine machine type & display type
3 *
4 * RCS Info
5 *    $Id: machtype_sun4.c,v 1.22 1998-04-18 16:58:45 danw Exp $
6 *    $Locker:  $
7 */
8
9#define volatile
10#include <stdio.h>
11#include <string.h>
12#include <kvm.h>
13#include <nlist.h>
14#include <fcntl.h>
15#include <unistd.h>
16#include <sys/types.h>
17#include <sys/file.h>
18#include <sys/cpu.h>
19#include <ctype.h>
20#include <dirent.h>
21#include <sys/vtoc.h>
22/* OpenPROM stuff */
23#include <sys/promif.h>
24#include <sys/ddi.h>
25#include <sys/sunddi.h>
26#include <sys/ddi_impldefs.h>
27/* Frame buffer stuff */
28#include <sys/fbio.h>
29#include <errno.h>
30
31int verbose =0;
32
33struct nlist nl[] = {
34#define X_cpu 0
35      { "cputype" },
36#define X_maxmem 1
37      { "maxmem" },
38#define X_physmem 2
39      { "physmem" },
40#define X_topnode 3
41      { "top_devinfo" },
42      { "" }
43};
44
45main(argc, argv)
46int   argc;
47char  **argv;
48{
49kvm_t *kv;
50    int i;
51    int cpuflg = 0, dpyflg = 0, raflg = 0, memflg = 0;
52    int doathenaV = 0;
53    int dosyspV = 0;
54    int dolocalV = 0;
55    int dobosN = 0;
56    int dobosV = 0;
57    int dosysnam = 0;
58    int dosyscompatnam = 0;
59    char *kernel = "/dev/ksyms",  *memory = "/dev/mem";
60    FILE *f;
61
62    for (i = 1; i < argc; i++) {
63      if (argv[i][0] != '-')
64        usage(argv[0]);
65
66      switch (argv[i][1]) {
67      case 'c':
68          cpuflg++;
69          break;
70      case 'd':
71          dpyflg++;
72          break;
73      case 'r':
74          raflg++;
75          break;
76      case 'M':
77          memflg++;
78        break;
79      case 'k':
80          kernel = argv[i+1];
81          i++;
82          break;
83      case 'm':
84          memory = argv[i+1];
85          i++;
86          break;
87        case 'A':
88          doathenaV = 1;
89          break;
90        case 'L':
91          dolocalV = 1;
92          break;
93        case 'P':
94          dosyspV = 1;
95          break;
96      case 'N':
97          dobosN = 1;
98          break;
99      case 'E':
100          dobosV = 1;
101          break;
102      case 'S':
103          dosysnam = 1;
104          break;
105      case 'C':
106          dosyscompatnam = 1;
107          break;
108      case 'v':
109          verbose++;
110          break;
111      default:
112          usage(argv[0]);
113      }
114    }
115
116    if ((argc == 1) || ((argc == 2) && verbose)) {
117      puts("sun4");
118      exit(0);
119    }
120
121     /* Print out version of Athena machtype compiled against */
122    if (doathenaV) {
123      if (verbose)
124      printf("Machtype version: %s.%s\n",ATHMAJV,ATHMINV);
125      else
126      printf("%s.%s\n",ATHMAJV,ATHMINV);
127    }
128
129   /* Print out version of attached packs */
130    if (dosyspV) {
131      char buf[256],rvd_version[256], *p;
132      if ((f = fopen("/srvd/.rvdinfo","r")) == NULL) {
133      printf("Syspack information unavailable\n");
134      } else {
135      fgets(buf,256,f);
136      fclose(f);
137     /* If it is verbose, give the whole line, else just the vers # */
138      if (verbose) {
139        printf(buf);
140      } else {
141        p = strchr(buf,' '); /* skip "Athena" */
142        p = strchr(p+1,' '); /* skip "RVD" */
143        p = strchr(p+1,' '); /* Skip "RSAIX" */
144        p = strchr(p+1,' '); /* skip "version" */
145        strncpy(rvd_version,p+1,256);
146        p = strchr(rvd_version,' ');
147        *p = '\0';
148        printf("%s\n",rvd_version);
149      }
150      }
151    }
152
153    /* Print out local version from /etc/athena/version */
154    if (dolocalV) {
155      char buf[256],loc_version[256], *p;
156      if ((f = fopen("/etc/athena/version","r")) == NULL) {
157      printf("Local version information unavailable\n");
158      } else {
159      fseek(f,-100,2);
160      while (fgets(buf,256,f) != NULL)
161        ;
162      fclose(f);
163
164      if (verbose) {
165        printf(buf);
166      } else {
167        p = strchr(buf,' '); /* skip "Athena" */
168        p = strchr(p+1,' '); /* skip "Workstation/Server" */
169        p = strchr(p+1,' '); /* Skip "RSAIX" */
170        p = strchr(p+1,' '); /* skip "version" */
171        strncpy(loc_version,p+1,256);
172        p = strchr(loc_version,' ');
173        *p = '\0';
174        printf("%s\n",loc_version);
175      }
176      }
177    }
178
179    /* Print out vendor OS name */
180    if (dobosN) {
181      if (verbose) {
182     printf(OSNAME " " OSVERS "\n");
183      } else {
184        printf(OSNAME "\n");
185      }
186    }
187
188    /* Print out vendor OS version */
189    if (dobosV) {
190        printf(OSVERS "\n");
191    }
192
193    /* Print out Athena System name */
194    if (dosysnam) {
195      printf("%s\n", ATHSYS);
196    }
197
198    /* Print out compatible Athena System names */
199    if (dosyscompatnam) {
200      printf("%s\n", ATHSYSCOMPAT);
201    }
202
203    if (cpuflg || dpyflg || raflg || memflg)
204      {
205        int memfd;
206      kv = kvm_open(NULL,NULL,NULL,O_RDONLY,NULL);
207      if (!kv) {
208        fprintf(stderr,"%s: unable to examine the kernel\n", argv[0]);
209        exit(2);
210      }
211      if (kvm_nlist(kv, &nl) < 0) {
212        fprintf(stderr,"%s: can't get namelist\n", argv[0]);
213        exit(2);
214      }
215     if (cpuflg)
216        do_cpu(kv, memfd);
217      if (dpyflg)
218        do_dpy(kernel, memfd);
219      if (raflg)
220        do_disk(kernel, memfd);
221      if (memflg)
222        do_memory(kv, memfd);
223      }
224      if (cpuflg || dpyflg || raflg || memflg)
225        kvm_close(kv);
226    exit(0);
227}
228
229usage(name)
230char *name;
231{
232    fprintf(stderr, "usage: %s [-v] [-c] [-d] [-r] [-E] [-N] [-M]\n",name);
233    fprintf(stderr, "             [-k kernel] [-m memory] [-A] [-L] [-P] [-S]\n");
234    exit(1);
235}
236
237void do_cpu_prom(kvm_t *kernel)
238{
239  unsigned long   ptop;
240  struct dev_info top;
241  char            buf[BUFSIZ];
242
243  char*           cpustr;
244
245  /* read device name of the top node of the OpenPROM */
246
247  if (   (! nl[X_topnode].n_value)
248      || (kvm_read(kernel, (unsigned long) nl[X_topnode].n_value,
249                            (char*) &ptop, sizeof(ptop)) != sizeof(ptop))
250      || (! ptop)
251      || (kvm_read(kernel, (unsigned long) ptop,
252                            (char*) &top, sizeof(top)) != sizeof(top))
253      || (! top.devi_name)
254      || (kvm_read(kernel, (unsigned long) top.devi_name,
255                            (char*) &buf, sizeof(buf)) != sizeof(buf))
256      || (! buf[0]) ) {
257    fprintf(stderr, "Can't get CPU information from the kernel\n");
258    exit(2);
259  }
260  buf[BUFSIZ-1] = '\0';
261
262  /* now, return a string identifying the CPU */
263
264  if (verbose) {
265    /* "verbose" returns the kernel information directly */
266    puts(buf);
267
268  } else {
269
270    /* skip the initial "SUNW," */
271    if (cpustr = strchr(buf, ','))
272      cpustr++;
273    else
274      cpustr = buf;
275
276    /* reformat the result to look like "SPARC/Classic" or "SPARC/5" */
277    if (! strncmp(cpustr, "SPARC", sizeof("SPARC")-1)) {
278      cpustr += sizeof("SPARC")-1;
279
280      if (! strncmp(cpustr, "station-", sizeof("station-")-1))
281        cpustr += sizeof("station-")-1;
282      else
283        if (! strcmp(cpustr, "classic")) /* backwards compat - cap classic */
284          (*cpustr) = toupper(*cpustr);
285
286      printf("SPARC/%s\n", cpustr);
287
288    } else {
289      /* if it didn't start with "SPARC", just leave it be... */
290      puts(cpustr);
291    }
292  }
293
294  return;
295}
296
297do_cpu(kernel, mf)
298kvm_t *kernel;
299int mf;
300{
301     short cpu;
302short cpu_type;
303
304    cpu_type = kvm_read(kernel,nl[X_cpu].n_value,&cpu, sizeof(cpu));
305{
306        switch(cpu) {
307          case CPU_SUN4C_60:
308            puts(verbose ? "SPARCstation 1": "SPARC/1");
309            break;
310          case CPU_SUN4C_40:
311            puts(verbose ? "SPARCstation IPC" : "SPARC/IPC");
312            break;
313          case CPU_SUN4C_65:
314            puts(verbose ? "SPARCstation 1+" : "SPARC/1+");
315            break;
316          case CPU_SUN4C_20:
317            puts(verbose ? "SPARCstation SLC" : "SPARC/SLC");
318            break;
319          case CPU_SUN4C_75:
320            puts(verbose ? "SPARCstation 2" : "SPARC/2");
321            break;
322          case CPU_SUN4C_25:
323            puts(verbose ? "SPARCstation ELC" : "SPARC/ELC");
324            break;
325          case CPU_SUN4C_50:
326            puts(verbose ? "SPARCstation IPX" : "SPARC/IPX");
327            break;
328          case CPU_SUN4M_50:    /* 114... Sparc20 */
329          case OBP_ARCH:        /* 128 */
330            do_cpu_prom(kernel);
331                break;
332
333         default:
334           if(verbose)
335                printf("Unknown SUN type %d\n", cpu);
336           else
337              puts("SUN???");
338         }
339       }
340    return;
341}
342
343do_dpy(kernel, mf)
344char *kernel;
345int mf;
346{
347  int count;
348  char buf[1024], *p;
349
350  count = readlink("/dev/fb", buf, sizeof(buf) - 1);
351  if (count == -1) {
352    puts(verbose ? "unknown frame buffer" : "unknown");
353    return;
354  }
355  buf[count] = 0;
356  p = buf + count;
357  while (p > buf && isdigit(*(p - 1)))
358    *--p = 0;
359  p = strrchr(buf, ':');
360  if (!p) {
361    puts(verbose ? "unknown frame buffer" : "unknown");
362    return;
363  }
364  printf("%s%s\n", p + 1, verbose ? " frame buffer" : "");
365}
366
367do_disk(kernel, mf)
368char *kernel;
369int mf;
370{
371  DIR *dp;
372  struct dirent *de;
373  char path[MAXPATHLEN];
374  const char *devdir = "/dev/rdsk";
375  char *cp;
376  int fd;
377  int devlen;                   /* Length of device name, w/o partition */
378  struct vtoc vtoc;
379 
380  dp = opendir(devdir);
381  if (dp == NULL)
382    {
383      fprintf(stderr, "Cannot open %s: %s\n", devdir, strerror(errno));
384      exit(1);
385    }
386
387  while ((de = readdir(dp)) != NULL)
388    {
389      if ((!strcmp(de->d_name, ".")) || (!strcmp(de->d_name, "..")))
390        continue;
391
392      /* By convention partition (slice) 2 is the whole disk. */
393      cp = strrchr(de->d_name, 's');
394      if ((cp == NULL) || (strcmp(cp, "s2") != 0))
395        continue;
396      devlen = cp - de->d_name;         /* Get name length w/o partition */
397      sprintf(path, "%s/%s", devdir, de->d_name);
398      fd = open(path, O_RDONLY);
399      if (fd == -1)
400        continue;
401
402      if ((read_vtoc(fd, &vtoc) < 0) || (vtoc.v_sanity != VTOC_SANE))
403        {
404          close(fd);
405          continue;
406        }
407      close(fd);
408
409      if (!verbose)
410        {
411          /* Strip geometry info from the label text. */
412          cp = strchr(vtoc.v_asciilabel, ' ');
413          if (cp)
414            *cp = '\0';
415        }
416
417      printf("%.*s: %.*s\n",
418             devlen, de->d_name,
419             LEN_DKL_ASCII, vtoc.v_asciilabel);
420    }
421
422  closedir(dp);
423  return;
424}
425
426#define MEG (1024*1024)
427
428do_memory (kernel, mf)
429kvm_t *kernel;
430int mf;
431{
432   int pos, mem, nbpp;
433
434   nbpp = getpagesize() / 1024;
435   kvm_read(kernel, nl[X_maxmem].n_value, &mem, sizeof(mem));
436   if(verbose)
437      printf("%d user, ", mem * nbpp);
438   kvm_read(kernel, nl[X_physmem].n_value, &mem, sizeof(mem));
439   if(verbose)
440      printf("%d (%d M) total\n", mem * nbpp, (mem * nbpp + 916) / 1024);
441   else
442      printf("%d\n", mem * nbpp + 916);
443   return;
444}
445
Note: See TracBrowser for help on using the repository browser.