| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: i386.c,v 1.13 2008/10/14 15:49:04 cegger Exp $ */ | | 1 | /* $NetBSD: i386.c,v 1.13.2.1 2008/12/23 03:36:43 snj Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Frank van der Linden, and by Jason R. Thorpe. | | 8 | * by Frank van der Linden, and by Jason R. Thorpe. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -47,40 +47,41 @@ | | | @@ -47,40 +47,41 @@ |
47 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 47 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
48 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | | 48 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
49 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 49 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
50 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 50 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
51 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 51 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
54 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 54 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
55 | * SUCH DAMAGE. | | 55 | * SUCH DAMAGE. |
56 | */ | | 56 | */ |
57 | | | 57 | |
58 | #include <sys/cdefs.h> | | 58 | #include <sys/cdefs.h> |
59 | #ifndef lint | | 59 | #ifndef lint |
60 | __RCSID("$NetBSD: i386.c,v 1.13 2008/10/14 15:49:04 cegger Exp $"); | | 60 | __RCSID("$NetBSD: i386.c,v 1.13.2.1 2008/12/23 03:36:43 snj Exp $"); |
61 | #endif /* not lint */ | | 61 | #endif /* not lint */ |
62 | | | 62 | |
63 | #include <sys/types.h> | | 63 | #include <sys/types.h> |
64 | #include <sys/param.h> | | 64 | #include <sys/param.h> |
65 | #include <sys/bitops.h> | | 65 | #include <sys/bitops.h> |
66 | #include <sys/sysctl.h> | | 66 | #include <sys/sysctl.h> |
67 | | | 67 | |
68 | #include <string.h> | | 68 | #include <string.h> |
69 | #include <stdio.h> | | 69 | #include <stdio.h> |
70 | #include <stdlib.h> | | 70 | #include <stdlib.h> |
71 | #include <err.h> | | 71 | #include <err.h> |
72 | #include <assert.h> | | 72 | #include <assert.h> |
73 | #include <math.h> | | 73 | #include <math.h> |
| | | 74 | #include <util.h> |
74 | | | 75 | |
75 | #include <machine/specialreg.h> | | 76 | #include <machine/specialreg.h> |
76 | #include <machine/cpu.h> | | 77 | #include <machine/cpu.h> |
77 | | | 78 | |
78 | #include <x86/cpuvar.h> | | 79 | #include <x86/cpuvar.h> |
79 | #include <x86/cputypes.h> | | 80 | #include <x86/cputypes.h> |
80 | #include <x86/cacheinfo.h> | | 81 | #include <x86/cacheinfo.h> |
81 | | | 82 | |
82 | #include "../cpuctl.h" | | 83 | #include "../cpuctl.h" |
83 | | | 84 | |
84 | /* Size of buffer for printing humanized numbers */ | | 85 | /* Size of buffer for printing humanized numbers */ |
85 | #define HUMAN_BUFSIZE 5 | | 86 | #define HUMAN_BUFSIZE 5 |
86 | | | 87 | |
| @@ -1175,42 +1176,41 @@ transmeta_cpu_info(struct cpu_info *ci) | | | @@ -1175,42 +1176,41 @@ transmeta_cpu_info(struct cpu_info *ci) |
1175 | aprint_verbose_dev(ci->ci_dev, "LongRun <%dMHz %dmV %d%%>\n", | | 1176 | aprint_verbose_dev(ci->ci_dev, "LongRun <%dMHz %dmV %d%%>\n", |
1176 | frequency, voltage, percentage); | | 1177 | frequency, voltage, percentage); |
1177 | } | | 1178 | } |
1178 | } | | 1179 | } |
1179 | | | 1180 | |
1180 | void | | 1181 | void |
1181 | identifycpu(const char *cpuname) | | 1182 | identifycpu(const char *cpuname) |
1182 | { | | 1183 | { |
1183 | const char *name, *modifier, *vendorname, *brand = ""; | | 1184 | const char *name, *modifier, *vendorname, *brand = ""; |
1184 | int class = CPUCLASS_386, i, xmax; | | 1185 | int class = CPUCLASS_386, i, xmax; |
1185 | int modif, family, model; | | 1186 | int modif, family, model; |
1186 | const struct cpu_cpuid_nameclass *cpup = NULL; | | 1187 | const struct cpu_cpuid_nameclass *cpup = NULL; |
1187 | const struct cpu_cpuid_family *cpufam; | | 1188 | const struct cpu_cpuid_family *cpufam; |
1188 | char *buf; | | | |
1189 | const char *feature_str[5]; | | 1189 | const char *feature_str[5]; |
1190 | struct cpu_info *ci, cistore; | | 1190 | struct cpu_info *ci, cistore; |
1191 | extern int cpu; | | 1191 | extern int cpu; |
1192 | extern int cpu_info_level; | | 1192 | extern int cpu_info_level; |
1193 | size_t sz; | | 1193 | size_t sz; |
| | | 1194 | char buf[256]; |
1194 | | | 1195 | |
1195 | ci = &cistore; | | 1196 | ci = &cistore; |
1196 | memset(ci, 0, sizeof(*ci)); | | 1197 | memset(ci, 0, sizeof(*ci)); |
1197 | ci->ci_dev = cpuname; | | 1198 | ci->ci_dev = cpuname; |
1198 | | | 1199 | |
1199 | x86_identify(); | | 1200 | x86_identify(); |
1200 | ci->ci_cpuid_level = cpu_info_level; | | 1201 | ci->ci_cpuid_level = cpu_info_level; |
1201 | cpu_probe_features(ci); | | 1202 | cpu_probe_features(ci); |
1202 | | | 1203 | |
1203 | buf = malloc(MAXPATHLEN); | | | |
1204 | if (ci->ci_cpuid_level == -1) { | | 1204 | if (ci->ci_cpuid_level == -1) { |
1205 | if (cpu < 0 || cpu >= __arraycount(i386_nocpuid_cpus)) | | 1205 | if (cpu < 0 || cpu >= __arraycount(i386_nocpuid_cpus)) |
1206 | errx(1, "unknown cpu type %d", cpu); | | 1206 | errx(1, "unknown cpu type %d", cpu); |
1207 | name = i386_nocpuid_cpus[cpu].cpu_name; | | 1207 | name = i386_nocpuid_cpus[cpu].cpu_name; |
1208 | cpu_vendor = i386_nocpuid_cpus[cpu].cpu_vendor; | | 1208 | cpu_vendor = i386_nocpuid_cpus[cpu].cpu_vendor; |
1209 | vendorname = i386_nocpuid_cpus[cpu].cpu_vendorname; | | 1209 | vendorname = i386_nocpuid_cpus[cpu].cpu_vendorname; |
1210 | class = i386_nocpuid_cpus[cpu].cpu_class; | | 1210 | class = i386_nocpuid_cpus[cpu].cpu_class; |
1211 | ci->ci_info = i386_nocpuid_cpus[cpu].cpu_info; | | 1211 | ci->ci_info = i386_nocpuid_cpus[cpu].cpu_info; |
1212 | modifier = ""; | | 1212 | modifier = ""; |
1213 | } else { | | 1213 | } else { |
1214 | xmax = __arraycount(i386_cpuid_cpus); | | 1214 | xmax = __arraycount(i386_cpuid_cpus); |
1215 | modif = (ci->ci_signature >> 12) & 0x3; | | 1215 | modif = (ci->ci_signature >> 12) & 0x3; |
1216 | family = CPUID2FAMILY(ci->ci_signature); | | 1216 | family = CPUID2FAMILY(ci->ci_signature); |
| @@ -1333,68 +1333,65 @@ identifycpu(const char *cpuname) | | | @@ -1333,68 +1333,65 @@ identifycpu(const char *cpuname) |
1333 | feature_str[3] = CPUID_EXT_FLAGS; | | 1333 | feature_str[3] = CPUID_EXT_FLAGS; |
1334 | feature_str[4] = CPUID_AMD_FLAGS4; | | 1334 | feature_str[4] = CPUID_AMD_FLAGS4; |
1335 | break; | | 1335 | break; |
1336 | case CPUVENDOR_INTEL: | | 1336 | case CPUVENDOR_INTEL: |
1337 | feature_str[3] = CPUID_INTEL_FLAGS4; | | 1337 | feature_str[3] = CPUID_INTEL_FLAGS4; |
1338 | break; | | 1338 | break; |
1339 | default: | | 1339 | default: |
1340 | feature_str[3] = CPUID_EXT_FLAGS; | | 1340 | feature_str[3] = CPUID_EXT_FLAGS; |
1341 | break; | | 1341 | break; |
1342 | } | | 1342 | } |
1343 | | | 1343 | |
1344 | if (ci->ci_feature_flags) { | | 1344 | if (ci->ci_feature_flags) { |
1345 | if ((ci->ci_feature_flags & CPUID_MASK1) != 0) { | | 1345 | if ((ci->ci_feature_flags & CPUID_MASK1) != 0) { |
1346 | bitmask_snprintf(ci->ci_feature_flags, | | 1346 | snprintb(buf, sizeof(buf), feature_str[0], |
1347 | feature_str[0], buf, MAXPATHLEN); | | 1347 | ci->ci_feature_flags); |
1348 | aprint_verbose("%s: features %s\n", cpuname, buf); | | 1348 | aprint_verbose("%s: features %s\n", cpuname, buf); |
1349 | } | | 1349 | } |
1350 | if ((ci->ci_feature_flags & CPUID_MASK2) != 0) { | | 1350 | if ((ci->ci_feature_flags & CPUID_MASK2) != 0) { |
1351 | bitmask_snprintf(ci->ci_feature_flags, | | 1351 | snprintb(buf, sizeof(buf), feature_str[1], |
1352 | feature_str[1], buf, MAXPATHLEN); | | 1352 | ci->ci_feature_flags); |
1353 | aprint_verbose("%s: features %s\n", cpuname, buf); | | 1353 | aprint_verbose("%s: features %s\n", cpuname, buf); |
1354 | } | | 1354 | } |
1355 | if ((ci->ci_feature_flags & CPUID_MASK3) != 0) { | | 1355 | if ((ci->ci_feature_flags & CPUID_MASK3) != 0) { |
1356 | bitmask_snprintf(ci->ci_feature_flags, | | 1356 | snprintb(buf, sizeof(buf), feature_str[2], |
1357 | feature_str[2], buf, MAXPATHLEN); | | 1357 | ci->ci_feature_flags); |
1358 | aprint_verbose("%s: features %s\n", cpuname, buf); | | 1358 | aprint_verbose("%s: features %s\n", cpuname, buf); |
1359 | } | | 1359 | } |
1360 | } | | 1360 | } |
1361 | | | 1361 | |
1362 | if (ci->ci_feature2_flags) { | | 1362 | if (ci->ci_feature2_flags) { |
1363 | bitmask_snprintf(ci->ci_feature2_flags, | | 1363 | snprintb(buf, sizeof(buf), CPUID2_FLAGS, ci->ci_feature2_flags); |
1364 | CPUID2_FLAGS, buf, MAXPATHLEN); | | | |
1365 | aprint_verbose("%s: features2 %s\n", cpuname, buf); | | 1364 | aprint_verbose("%s: features2 %s\n", cpuname, buf); |
1366 | } | | 1365 | } |
1367 | | | 1366 | |
1368 | if (ci->ci_feature3_flags) { | | 1367 | if (ci->ci_feature3_flags) { |
1369 | bitmask_snprintf(ci->ci_feature3_flags, | | 1368 | snprintb(buf, sizeof(buf), feature_str[3], |
1370 | feature_str[3], buf, MAXPATHLEN); | | 1369 | ci->ci_feature3_flags); |
1371 | aprint_verbose("%s: features3 %s\n", cpuname, buf); | | 1370 | aprint_verbose("%s: features3 %s\n", cpuname, buf); |
1372 | } | | 1371 | } |
1373 | | | 1372 | |
1374 | if (ci->ci_feature4_flags) { | | 1373 | if (ci->ci_feature4_flags) { |
1375 | bitmask_snprintf(ci->ci_feature4_flags, | | 1374 | snprintb(buf, sizeof(buf), feature_str[4], |
1376 | feature_str[4], buf, MAXPATHLEN); | | 1375 | ci->ci_feature4_flags); |
1377 | aprint_verbose("%s: features4 %s\n", cpuname, buf); | | 1376 | aprint_verbose("%s: features4 %s\n", cpuname, buf); |
1378 | } | | 1377 | } |
1379 | | | 1378 | |
1380 | if (ci->ci_padlock_flags) { | | 1379 | if (ci->ci_padlock_flags) { |
1381 | bitmask_snprintf(ci->ci_padlock_flags, | | 1380 | snprintb(buf, sizeof(buf), CPUID_FLAGS_PADLOCK, |
1382 | CPUID_FLAGS_PADLOCK, buf, MAXPATHLEN); | | 1381 | ci->ci_padlock_flags); |
1383 | aprint_verbose("%s: padlock features %s\n", cpuname, buf); | | 1382 | aprint_verbose("%s: padlock features %s\n", cpuname, buf); |
1384 | } | | 1383 | } |
1385 | | | 1384 | |
1386 | free(buf); | | | |
1387 | | | | |
1388 | if (*cpu_brand_string != '\0') | | 1385 | if (*cpu_brand_string != '\0') |
1389 | aprint_normal("%s: \"%s\"\n", cpuname, cpu_brand_string); | | 1386 | aprint_normal("%s: \"%s\"\n", cpuname, cpu_brand_string); |
1390 | | | 1387 | |
1391 | x86_print_cacheinfo(ci); | | 1388 | x86_print_cacheinfo(ci); |
1392 | | | 1389 | |
1393 | if (ci->ci_cpuid_level >= 3 && (ci->ci_feature_flags & CPUID_PN)) { | | 1390 | if (ci->ci_cpuid_level >= 3 && (ci->ci_feature_flags & CPUID_PN)) { |
1394 | aprint_verbose("%s: serial number %04X-%04X-%04X-%04X-%04X-%04X\n", | | 1391 | aprint_verbose("%s: serial number %04X-%04X-%04X-%04X-%04X-%04X\n", |
1395 | cpuname, | | 1392 | cpuname, |
1396 | ci->ci_cpu_serial[0] / 65536, ci->ci_cpu_serial[0] % 65536, | | 1393 | ci->ci_cpu_serial[0] / 65536, ci->ci_cpu_serial[0] % 65536, |
1397 | ci->ci_cpu_serial[1] / 65536, ci->ci_cpu_serial[1] % 65536, | | 1394 | ci->ci_cpu_serial[1] / 65536, ci->ci_cpu_serial[1] % 65536, |
1398 | ci->ci_cpu_serial[2] / 65536, ci->ci_cpu_serial[2] % 65536); | | 1395 | ci->ci_cpu_serial[2] / 65536, ci->ci_cpu_serial[2] % 65536); |
1399 | } | | 1396 | } |
1400 | | | 1397 | |
| @@ -1768,26 +1765,26 @@ x86_print_cacheinfo(struct cpu_info *ci) | | | @@ -1768,26 +1765,26 @@ x86_print_cacheinfo(struct cpu_info *ci) |
1768 | aprint_verbose("\n"); | | 1765 | aprint_verbose("\n"); |
1769 | } | | 1766 | } |
1770 | if (ci->ci_cinfo[CAI_L3CACHE].cai_totalsize != 0) { | | 1767 | if (ci->ci_cinfo[CAI_L3CACHE].cai_totalsize != 0) { |
1771 | sep = print_cache_config(ci, CAI_L3CACHE, "L3 cache", NULL); | | 1768 | sep = print_cache_config(ci, CAI_L3CACHE, "L3 cache", NULL); |
1772 | if (sep != NULL) | | 1769 | if (sep != NULL) |
1773 | aprint_verbose("\n"); | | 1770 | aprint_verbose("\n"); |
1774 | } | | 1771 | } |
1775 | } | | 1772 | } |
1776 | | | 1773 | |
1777 | static void | | 1774 | static void |
1778 | powernow_probe(struct cpu_info *ci) | | 1775 | powernow_probe(struct cpu_info *ci) |
1779 | { | | 1776 | { |
1780 | uint32_t regs[4]; | | 1777 | uint32_t regs[4]; |
1781 | char line[256]; | | 1778 | char buf[256]; |
1782 | | | 1779 | |
1783 | x86_cpuid(0x80000000, regs); | | 1780 | x86_cpuid(0x80000000, regs); |
1784 | | | 1781 | |
1785 | /* We need CPUID(0x80000007) */ | | 1782 | /* We need CPUID(0x80000007) */ |
1786 | if (regs[0] < 0x80000007) | | 1783 | if (regs[0] < 0x80000007) |
1787 | return; | | 1784 | return; |
1788 | x86_cpuid(0x80000007, regs); | | 1785 | x86_cpuid(0x80000007, regs); |
1789 | | | 1786 | |
1790 | bitmask_snprintf(regs[3], CPUID_APM_FLAGS, line, sizeof(line)); | | 1787 | snprintb(buf, sizeof(buf), CPUID_APM_FLAGS, regs[3]); |
1791 | aprint_normal_dev(ci->ci_dev, "AMD Power Management features: %s\n", | | 1788 | aprint_normal_dev(ci->ci_dev, "AMD Power Management features: %s\n", |
1792 | line); | | 1789 | buf); |
1793 | } | | 1790 | } |