[6676] | 1 | /* |
---|
| 2 | * Machtype: determine machine type & display type |
---|
| 3 | * |
---|
| 4 | * RCS Info |
---|
[12350] | 5 | * $Id: machtype_sun4.c,v 1.25 1999-01-22 23:11:36 ghudson Exp $ |
---|
[6676] | 6 | */ |
---|
| 7 | |
---|
[8154] | 8 | #define volatile |
---|
[6676] | 9 | #include <stdio.h> |
---|
| 10 | #include <string.h> |
---|
| 11 | #include <kvm.h> |
---|
[6677] | 12 | #include <nlist.h> |
---|
[6676] | 13 | #include <fcntl.h> |
---|
[11216] | 14 | #include <unistd.h> |
---|
[6676] | 15 | #include <sys/types.h> |
---|
| 16 | #include <sys/file.h> |
---|
| 17 | #include <sys/cpu.h> |
---|
[7974] | 18 | #include <ctype.h> |
---|
[11306] | 19 | #include <dirent.h> |
---|
| 20 | #include <sys/vtoc.h> |
---|
[7974] | 21 | /* OpenPROM stuff */ |
---|
| 22 | #include <sys/promif.h> |
---|
[9428] | 23 | #include <sys/ddi.h> |
---|
| 24 | #include <sys/sunddi.h> |
---|
| 25 | #include <sys/ddi_impldefs.h> |
---|
[11232] | 26 | /* Frame buffer stuff */ |
---|
| 27 | #include <sys/fbio.h> |
---|
| 28 | #include <errno.h> |
---|
[12029] | 29 | #include "machtype.h" |
---|
[6676] | 30 | |
---|
| 31 | struct nlist nl[] = { |
---|
| 32 | #define X_cpu 0 |
---|
| 33 | { "cputype" }, |
---|
| 34 | #define X_maxmem 1 |
---|
| 35 | { "maxmem" }, |
---|
| 36 | #define X_physmem 2 |
---|
| 37 | { "physmem" }, |
---|
[7974] | 38 | #define X_topnode 3 |
---|
| 39 | { "top_devinfo" }, |
---|
[6677] | 40 | { "" } |
---|
[6676] | 41 | }; |
---|
| 42 | |
---|
[12029] | 43 | kvm_t *do_init(void) |
---|
[6676] | 44 | { |
---|
[12029] | 45 | kvm_t *kernel; |
---|
[6676] | 46 | |
---|
[12029] | 47 | kernel = kvm_open(NULL,NULL,NULL,O_RDONLY,NULL); |
---|
| 48 | if (!kernel) { |
---|
| 49 | fprintf(stderr,"unable to examine the kernel\n"); |
---|
| 50 | exit(2); |
---|
[6676] | 51 | } |
---|
[12029] | 52 | if (kvm_nlist(kernel, &nl) < 0) { |
---|
| 53 | fprintf(stderr,"can't get namelist\n"); |
---|
| 54 | exit(2); |
---|
[6676] | 55 | } |
---|
[12029] | 56 | return kernel; |
---|
| 57 | } |
---|
[6676] | 58 | |
---|
[12029] | 59 | void do_cleanup(kvm_t *kernel) |
---|
| 60 | { |
---|
| 61 | kvm_close(kernel); |
---|
[6676] | 62 | } |
---|
| 63 | |
---|
[12029] | 64 | void do_machtype(void) |
---|
[6676] | 65 | { |
---|
[12029] | 66 | puts("sun4"); |
---|
[6676] | 67 | } |
---|
| 68 | |
---|
[12029] | 69 | void do_cpu_prom(kvm_t *kernel, int verbose) |
---|
[7974] | 70 | { |
---|
| 71 | unsigned long ptop; |
---|
| 72 | struct dev_info top; |
---|
| 73 | char buf[BUFSIZ]; |
---|
| 74 | |
---|
| 75 | char* cpustr; |
---|
| 76 | |
---|
| 77 | /* read device name of the top node of the OpenPROM */ |
---|
| 78 | |
---|
| 79 | if ( (! nl[X_topnode].n_value) |
---|
| 80 | || (kvm_read(kernel, (unsigned long) nl[X_topnode].n_value, |
---|
| 81 | (char*) &ptop, sizeof(ptop)) != sizeof(ptop)) |
---|
| 82 | || (! ptop) |
---|
| 83 | || (kvm_read(kernel, (unsigned long) ptop, |
---|
| 84 | (char*) &top, sizeof(top)) != sizeof(top)) |
---|
| 85 | || (! top.devi_name) |
---|
| 86 | || (kvm_read(kernel, (unsigned long) top.devi_name, |
---|
| 87 | (char*) &buf, sizeof(buf)) != sizeof(buf)) |
---|
| 88 | || (! buf[0]) ) { |
---|
| 89 | fprintf(stderr, "Can't get CPU information from the kernel\n"); |
---|
| 90 | exit(2); |
---|
| 91 | } |
---|
| 92 | buf[BUFSIZ-1] = '\0'; |
---|
| 93 | |
---|
| 94 | /* now, return a string identifying the CPU */ |
---|
| 95 | |
---|
| 96 | if (verbose) { |
---|
| 97 | /* "verbose" returns the kernel information directly */ |
---|
| 98 | puts(buf); |
---|
| 99 | |
---|
| 100 | } else { |
---|
| 101 | |
---|
| 102 | /* skip the initial "SUNW," */ |
---|
| 103 | if (cpustr = strchr(buf, ',')) |
---|
| 104 | cpustr++; |
---|
| 105 | else |
---|
| 106 | cpustr = buf; |
---|
| 107 | |
---|
| 108 | /* reformat the result to look like "SPARC/Classic" or "SPARC/5" */ |
---|
| 109 | if (! strncmp(cpustr, "SPARC", sizeof("SPARC")-1)) { |
---|
| 110 | cpustr += sizeof("SPARC")-1; |
---|
| 111 | |
---|
| 112 | if (! strncmp(cpustr, "station-", sizeof("station-")-1)) |
---|
| 113 | cpustr += sizeof("station-")-1; |
---|
| 114 | else |
---|
| 115 | if (! strcmp(cpustr, "classic")) /* backwards compat - cap classic */ |
---|
| 116 | (*cpustr) = toupper(*cpustr); |
---|
| 117 | |
---|
| 118 | printf("SPARC/%s\n", cpustr); |
---|
| 119 | |
---|
| 120 | } else { |
---|
| 121 | /* if it didn't start with "SPARC", just leave it be... */ |
---|
| 122 | puts(cpustr); |
---|
| 123 | } |
---|
| 124 | } |
---|
| 125 | |
---|
| 126 | return; |
---|
| 127 | } |
---|
| 128 | |
---|
[12029] | 129 | void do_cpu(int verbose) |
---|
[6676] | 130 | { |
---|
[12029] | 131 | kvm_t *kernel; |
---|
| 132 | short cpu, cpu_type; |
---|
[6676] | 133 | |
---|
[12029] | 134 | kernel = do_init(); |
---|
[6676] | 135 | cpu_type = kvm_read(kernel,nl[X_cpu].n_value,&cpu, sizeof(cpu)); |
---|
[12029] | 136 | |
---|
[6676] | 137 | switch(cpu) { |
---|
| 138 | case CPU_SUN4C_60: |
---|
| 139 | puts(verbose ? "SPARCstation 1": "SPARC/1"); |
---|
| 140 | break; |
---|
| 141 | case CPU_SUN4C_40: |
---|
| 142 | puts(verbose ? "SPARCstation IPC" : "SPARC/IPC"); |
---|
| 143 | break; |
---|
| 144 | case CPU_SUN4C_65: |
---|
| 145 | puts(verbose ? "SPARCstation 1+" : "SPARC/1+"); |
---|
| 146 | break; |
---|
| 147 | case CPU_SUN4C_20: |
---|
| 148 | puts(verbose ? "SPARCstation SLC" : "SPARC/SLC"); |
---|
| 149 | break; |
---|
| 150 | case CPU_SUN4C_75: |
---|
| 151 | puts(verbose ? "SPARCstation 2" : "SPARC/2"); |
---|
| 152 | break; |
---|
| 153 | case CPU_SUN4C_25: |
---|
| 154 | puts(verbose ? "SPARCstation ELC" : "SPARC/ELC"); |
---|
| 155 | break; |
---|
| 156 | case CPU_SUN4C_50: |
---|
| 157 | puts(verbose ? "SPARCstation IPX" : "SPARC/IPX"); |
---|
| 158 | break; |
---|
[8021] | 159 | case CPU_SUN4M_50: /* 114... Sparc20 */ |
---|
| 160 | case OBP_ARCH: /* 128 */ |
---|
[12029] | 161 | do_cpu_prom(kernel, verbose); |
---|
[6676] | 162 | break; |
---|
| 163 | |
---|
| 164 | default: |
---|
| 165 | if(verbose) |
---|
| 166 | printf("Unknown SUN type %d\n", cpu); |
---|
| 167 | else |
---|
| 168 | puts("SUN???"); |
---|
| 169 | } |
---|
[12029] | 170 | |
---|
| 171 | do_cleanup(kernel); |
---|
[6676] | 172 | return; |
---|
| 173 | } |
---|
| 174 | |
---|
[12029] | 175 | void do_dpy(int verbose) |
---|
[6676] | 176 | { |
---|
[11234] | 177 | int count; |
---|
| 178 | char buf[1024], *p; |
---|
[11232] | 179 | |
---|
[11234] | 180 | count = readlink("/dev/fb", buf, sizeof(buf) - 1); |
---|
| 181 | if (count == -1) { |
---|
| 182 | puts(verbose ? "unknown frame buffer" : "unknown"); |
---|
| 183 | return; |
---|
| 184 | } |
---|
| 185 | buf[count] = 0; |
---|
| 186 | p = buf + count; |
---|
| 187 | while (p > buf && isdigit(*(p - 1))) |
---|
| 188 | *--p = 0; |
---|
| 189 | p = strrchr(buf, ':'); |
---|
| 190 | if (!p) { |
---|
| 191 | puts(verbose ? "unknown frame buffer" : "unknown"); |
---|
| 192 | return; |
---|
| 193 | } |
---|
| 194 | printf("%s%s\n", p + 1, verbose ? " frame buffer" : ""); |
---|
[6676] | 195 | } |
---|
| 196 | |
---|
[12029] | 197 | void do_disk(int verbose) |
---|
[6676] | 198 | { |
---|
[11306] | 199 | DIR *dp; |
---|
| 200 | struct dirent *de; |
---|
| 201 | char path[MAXPATHLEN]; |
---|
| 202 | const char *devdir = "/dev/rdsk"; |
---|
| 203 | char *cp; |
---|
| 204 | int fd; |
---|
| 205 | int devlen; /* Length of device name, w/o partition */ |
---|
| 206 | struct vtoc vtoc; |
---|
| 207 | |
---|
| 208 | dp = opendir(devdir); |
---|
| 209 | if (dp == NULL) |
---|
| 210 | { |
---|
| 211 | fprintf(stderr, "Cannot open %s: %s\n", devdir, strerror(errno)); |
---|
| 212 | exit(1); |
---|
| 213 | } |
---|
[7095] | 214 | |
---|
[11306] | 215 | while ((de = readdir(dp)) != NULL) |
---|
| 216 | { |
---|
| 217 | if ((!strcmp(de->d_name, ".")) || (!strcmp(de->d_name, ".."))) |
---|
| 218 | continue; |
---|
[7095] | 219 | |
---|
[11306] | 220 | /* By convention partition (slice) 2 is the whole disk. */ |
---|
| 221 | cp = strrchr(de->d_name, 's'); |
---|
| 222 | if ((cp == NULL) || (strcmp(cp, "s2") != 0)) |
---|
| 223 | continue; |
---|
| 224 | devlen = cp - de->d_name; /* Get name length w/o partition */ |
---|
| 225 | sprintf(path, "%s/%s", devdir, de->d_name); |
---|
| 226 | fd = open(path, O_RDONLY); |
---|
| 227 | if (fd == -1) |
---|
| 228 | continue; |
---|
[7894] | 229 | |
---|
[11306] | 230 | if ((read_vtoc(fd, &vtoc) < 0) || (vtoc.v_sanity != VTOC_SANE)) |
---|
| 231 | { |
---|
| 232 | close(fd); |
---|
| 233 | continue; |
---|
| 234 | } |
---|
| 235 | close(fd); |
---|
| 236 | |
---|
| 237 | if (!verbose) |
---|
| 238 | { |
---|
| 239 | /* Strip geometry info from the label text. */ |
---|
| 240 | cp = strchr(vtoc.v_asciilabel, ' '); |
---|
| 241 | if (cp) |
---|
| 242 | *cp = '\0'; |
---|
| 243 | } |
---|
| 244 | |
---|
| 245 | printf("%.*s: %.*s\n", |
---|
| 246 | devlen, de->d_name, |
---|
| 247 | LEN_DKL_ASCII, vtoc.v_asciilabel); |
---|
| 248 | } |
---|
| 249 | |
---|
| 250 | closedir(dp); |
---|
| 251 | return; |
---|
[6676] | 252 | } |
---|
| 253 | |
---|
| 254 | #define MEG (1024*1024) |
---|
| 255 | |
---|
[12029] | 256 | void do_memory(int verbose) |
---|
[6676] | 257 | { |
---|
[12029] | 258 | kvm_t *kernel; |
---|
[11216] | 259 | int pos, mem, nbpp; |
---|
[6676] | 260 | |
---|
[12029] | 261 | kernel = do_init(); |
---|
[11216] | 262 | nbpp = getpagesize() / 1024; |
---|
| 263 | kvm_read(kernel, nl[X_maxmem].n_value, &mem, sizeof(mem)); |
---|
[6676] | 264 | if(verbose) |
---|
[11216] | 265 | printf("%d user, ", mem * nbpp); |
---|
| 266 | kvm_read(kernel, nl[X_physmem].n_value, &mem, sizeof(mem)); |
---|
[6676] | 267 | if(verbose) |
---|
[11216] | 268 | printf("%d (%d M) total\n", mem * nbpp, (mem * nbpp + 916) / 1024); |
---|
| 269 | else |
---|
| 270 | printf("%d\n", mem * nbpp + 916); |
---|
[12029] | 271 | do_cleanup(kernel); |
---|
[6676] | 272 | return; |
---|
| 273 | } |
---|
| 274 | |
---|