4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * Copyright (c) 2012, Joyent, Inc. All rights reserved.
30 #include <sys/types.h>
31 #include <sys/systeminfo.h>
32 #include <sys/utsname.h>
36 #include <sys/cpuid_drv.h>
50 static const char dev_cpu_self_cpuid
[] = "/dev/" CPUID_SELF_NAME
;
55 #define NATIVE_MODE 0x2
57 #define VERBOSE_MODE 0x8
58 #define EXTN_MODE 0x10
64 size_t bufsize
= 20; /* wild guess */
67 if ((buf
= malloc(bufsize
)) == NULL
)
70 ret
= sysinfo(cmd
, buf
, bufsize
);
75 buf
= realloc(buf
, bufsize
);
78 } while (buf
!= NULL
);
84 * Classify isa's as to bitness of the corresponding ABIs.
85 * isa's which have no "official" Solaris ABI are returned
86 * unrecognised i.e. "zero bit".
89 bitness(const char *isaname
)
91 if (strcmp(isaname
, "sparc") == 0 ||
92 strcmp(isaname
, "i386") == 0)
95 if (strcmp(isaname
, "sparcv9") == 0 ||
96 strcmp(isaname
, "amd64") == 0)
103 report_abi(int cmd
, const char *vfmt
)
108 if ((isa
= getsysinfo(cmd
)) == NULL
)
110 if ((bits
= bitness(isa
)) == 0) {
111 (void) fprintf(stderr
,
112 gettext("%s: unable to identify isa '%s'!\n"),
117 if (mode
& VERBOSE_MODE
)
118 (void) printf(vfmt
, bits
, isa
);
119 else if (mode
& BITS_MODE
)
120 (void) printf("%d\n", bits
);
121 else if (mode
& (NATIVE_MODE
|KERN_MODE
))
122 (void) printf("%s\n", isa
);
124 (void) printf("%s", isa
);
129 * Classify isas as their machine type.
132 machtype(const char *isaname
)
134 if (strcmp(isaname
, "sparc") == 0)
136 if (strcmp(isaname
, "sparcv9") == 0)
138 if (strcmp(isaname
, "i386") == 0)
140 if (strcmp(isaname
, "amd64") == 0)
147 report_hwcap(int d
, const char *isa
)
149 struct cpuid_get_hwcap __cgh
, *cgh
= &__cgh
;
150 char buffer
[1024], cap2
[1024];
152 cgh
->cgh_archname
= (char *)isa
;
153 if (ioctl(d
, CPUID_GET_HWCAP
, cgh
) != 0)
156 (void) elfcap_hw1_to_str(ELFCAP_STYLE_LC
, cgh
->cgh_hwcap
[0],
157 buffer
, sizeof (buffer
), ELFCAP_FMT_SNGSPACE
, machtype(isa
));
159 if (cgh
->cgh_hwcap
[1] != 0)
160 (void) elfcap_hw2_to_str(ELFCAP_STYLE_LC
, cgh
->cgh_hwcap
[1],
161 cap2
, sizeof (cap2
), ELFCAP_FMT_SNGSPACE
, machtype(isa
));
165 if (mode
& EXTN_MODE
) {
167 if (cgh
->cgh_hwcap
[1] != NULL
)
168 (void) printf(" %s", cap2
);
169 (void) printf(" %s", buffer
);
175 for (p
= strtok(cap2
, " "); p
; p
= strtok(NULL
, " ")) {
176 if (linecnt
+ strlen(p
) > 68) {
181 linecnt
= printf("\t");
182 linecnt
+= printf("%s ", p
);
185 for (p
= strtok(buffer
, " "); p
; p
= strtok(NULL
, " ")) {
186 if (linecnt
+ strlen(p
) > 68) {
191 linecnt
= printf("\t");
192 linecnt
+= printf("%s ", p
);
200 #if !defined(TEXT_DOMAIN)
201 #define TEXT_DOMAIN "SYS_TEST"
205 main(int argc
, char *argv
[])
212 const int excl_modes
= /* exclusive mode settings */
213 NATIVE_MODE
| BITS_MODE
| KERN_MODE
| EXTN_MODE
;
215 (void) setlocale(LC_ALL
, "");
216 (void) textdomain(TEXT_DOMAIN
);
218 if ((pgmname
= strrchr(*argv
, '/')) == 0)
223 while ((c
= getopt(argc
, argv
, "nbkvx")) != EOF
)
226 if (mode
& excl_modes
)
231 if (mode
& excl_modes
)
236 if (mode
& excl_modes
)
241 if (mode
& excl_modes
|| mode
& VERBOSE_MODE
)
246 if (mode
& EXTN_MODE
)
248 mode
|= VERBOSE_MODE
;
256 if (errflg
|| optind
!= argc
) {
257 (void) fprintf(stderr
,
258 gettext("usage: %s [ [-v] [-b | -n | -k] | [-x] ]\n"),
264 * We use dev_cpu_self_cpuid for discovering hardware capabilities;
265 * but we only complain if we can't open it if we've been
266 * asked to report on those capabilities.
268 if ((mode
& (VERBOSE_MODE
|EXTN_MODE
)) != 0 &&
269 (d
= open(dev_cpu_self_cpuid
, O_RDONLY
)) == -1)
270 perror(dev_cpu_self_cpuid
), exit(1);
272 if (mode
& KERN_MODE
) {
273 vfmt
= gettext("%d-bit %s kernel modules\n");
274 (void) report_abi(SI_ARCHITECTURE_K
, vfmt
);
278 vfmt
= gettext("%d-bit %s applications\n");
280 if (mode
& (BITS_MODE
| NATIVE_MODE
)) {
281 if ((isa
= report_abi(SI_ARCHITECTURE_64
, vfmt
)) == NULL
)
282 isa
= report_abi(SI_ARCHITECTURE_32
, vfmt
);
283 if (isa
!= NULL
&& (mode
& VERBOSE_MODE
) != 0)
284 report_hwcap(d
, isa
);
286 if ((isa
= report_abi(SI_ARCHITECTURE_64
, vfmt
)) != NULL
) {
287 if (mode
& (EXTN_MODE
|VERBOSE_MODE
))
288 report_hwcap(d
, isa
);
293 if ((isa32
= report_abi(SI_ARCHITECTURE_32
, vfmt
)) != NULL
) {
294 if (mode
& (EXTN_MODE
|VERBOSE_MODE
))
295 report_hwcap(d
, isa32
);
298 if ((isa32
!= NULL
|| isa
!= NULL
) &&
299 (mode
& (EXTN_MODE
|VERBOSE_MODE
)) == 0)
300 (void) putchar('\n');