Module Name: src Committed By: pgoyette Date: Wed May 13 22:25:51 UTC 2009
Modified Files: src/sys/arch/x86/include: cacheinfo.h specialreg.h src/usr.sbin/cpuctl/arch: i386.c Log Message: 1. Extend CPU probe of Intel processors to handle extended-models. This allows us to properly identify new Intel 45nm processors, Core i7, Atom, and the 45nm Xeon MP. 2. Properly decode several new Intel cache descriptors, as listed in the most recent (March 2009) edition of Intel's Application Note 485. 3. Convert decode of the various features masks to use the newly added snprintb_m(3) routine. Addresses my PR bin/41289 Addresses my PR bin/41290 To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/sys/arch/x86/include/cacheinfo.h cvs rdiff -u -r1.33 -r1.34 src/sys/arch/x86/include/specialreg.h cvs rdiff -u -r1.17 -r1.18 src/usr.sbin/cpuctl/arch/i386.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x86/include/cacheinfo.h diff -u src/sys/arch/x86/include/cacheinfo.h:1.10 src/sys/arch/x86/include/cacheinfo.h:1.11 --- src/sys/arch/x86/include/cacheinfo.h:1.10 Wed Apr 15 05:56:36 2009 +++ src/sys/arch/x86/include/cacheinfo.h Wed May 13 22:25:51 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: cacheinfo.h,v 1.10 2009/04/15 05:56:36 lukem Exp $ */ +/* $NetBSD: cacheinfo.h,v 1.11 2009/05/13 22:25:51 pgoyette Exp $ */ #ifndef _X86_CACHEINFO_H_ #define _X86_CACHEINFO_H_ @@ -199,6 +199,10 @@ #define __CI_TBL(a,b,c,d,e,f) { a, b, c, d, e, f } #endif +/* + * XXX Currently organized mostly by cache type, but would be + * XXX easier to maintain if it were in descriptor type order. + */ #define INTEL_CACHE_INFO { \ __CI_TBL(CAI_ITLB, 0x01, 4, 32, 4 * 1024, NULL), \ __CI_TBL(CAI_ITLB, 0xb0, 4,128, 4 * 1024, NULL), \ @@ -211,14 +215,23 @@ __CI_TBL(CAI_ITLB, 0x50, 0xff, 64, 4 * 1024, "4K/4M: 64 entries"), \ __CI_TBL(CAI_ITLB, 0x51, 0xff, 64, 4 * 1024, "4K/4M: 128 entries"),\ __CI_TBL(CAI_ITLB, 0x52, 0xff, 64, 4 * 1024, "4K/4M: 256 entries"),\ +__CI_TBL(CAI_ITLB, 0x55, 0xff, 64, 4 * 1024, "2M/4M: 7 entries"), \ +__CI_TBL(CAI_DTLB2, 0x56, 4, 16, 4 * 1024 * 1024, NULL), \ +__CI_TBL(CAI_DTLB2, 0x57, 4, 16, 4 * 1024, NULL), \ +__CI_TBL(CAI_DTLB, 0x5a, 0xff, 64, 4 * 1024, "2M/4M: 32 entries (L0)"), \ __CI_TBL(CAI_DTLB, 0x5b, 0xff, 64, 4 * 1024, "4K/4M: 64 entries"), \ __CI_TBL(CAI_DTLB, 0x5c, 0xff, 64, 4 * 1024, "4K/4M: 128 entries"),\ __CI_TBL(CAI_DTLB, 0x5d, 0xff, 64, 4 * 1024, "4K/4M: 256 entries"),\ +__CI_TBL(CAI_ITLB, 0xb1, 4, 64, 0, "8 2M/4 4M entries"), \ +__CI_TBL(CAI_ITLB, 0xb2, 4, 64, 4 * 1024, NULL), \ __CI_TBL(CAI_ICACHE, 0x06, 4, 8 * 1024, 32, NULL), \ __CI_TBL(CAI_ICACHE, 0x08, 4, 16 * 1024, 32, NULL), \ +__CI_TBL(CAI_ICACHE, 0x09, 4, 32 * 1024, 64, NULL), \ __CI_TBL(CAI_ICACHE, 0x30, 8, 32 * 1024, 64, NULL), \ __CI_TBL(CAI_DCACHE, 0x0a, 2, 8 * 1024, 32, NULL), \ __CI_TBL(CAI_DCACHE, 0x0c, 4, 16 * 1024, 32, NULL), \ +__CI_TBL(CAI_DCACHE, 0x0d, 4, 16 * 1024, 32, NULL), \ +__CI_TBL(CAI_L2CACHE, 0x21, 8, 256 * 1024, 64, NULL), /* L2 (MLC) */ \ __CI_TBL(CAI_L2CACHE, 0x39, 4, 128 * 1024, 64, NULL), \ __CI_TBL(CAI_L2CACHE, 0x3a, 6, 192 * 1024, 64, NULL), \ __CI_TBL(CAI_L2CACHE, 0x3b, 2, 128 * 1024, 64, NULL), \ @@ -231,6 +244,9 @@ __CI_TBL(CAI_L2CACHE, 0x43, 4, 512 * 1024, 32, NULL), \ __CI_TBL(CAI_L2CACHE, 0x44, 4, 1 * 1024 * 1024, 32, NULL), \ __CI_TBL(CAI_L2CACHE, 0x45, 4, 2 * 1024 * 1024, 32, NULL), \ +__CI_TBL(CAI_L2CACHE, 0x48, 12, 3 * 1024 * 1024, 64, NULL), \ + \ +/* 0x49 Is L2 on Xeon MP (Failym 0f, Model 06), L3 otherwise */ \ __CI_TBL(CAI_L2CACHE, 0x49, 16, 4 * 1024 * 1024, 64, NULL), \ __CI_TBL(CAI_L2CACHE, 0x4e, 24, 6 * 1024 * 1024, 64, NULL), \ __CI_TBL(CAI_DCACHE, 0x60, 8, 16 * 1024, 64, NULL), \ @@ -255,6 +271,32 @@ __CI_TBL(CAI_L2CACHE, 0x85, 8, 2 * 1024 * 1024, 32, NULL), \ __CI_TBL(CAI_L2CACHE, 0x86, 4, 512 * 1024, 64, NULL), \ __CI_TBL(CAI_L2CACHE, 0x87, 8, 1 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0x22, 0xff, 512 * 1024, 64, "sectored, 4-way "), \ +__CI_TBL(CAI_L3CACHE, 0x23, 0xff, 1 * 1024 * 1024, 64, "sectored, 8-way "), \ +__CI_TBL(CAI_L3CACHE, 0x25, 0xff, 2 * 1024 * 1024, 64, "sectored, 8-way "), \ +__CI_TBL(CAI_L3CACHE, 0x29, 0xff, 4 * 1024 * 1024, 64, "sectored, 8-way "), \ +__CI_TBL(CAI_L3CACHE, 0x46, 4, 4 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0x47, 8, 8 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0x49, 16, 4 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0x4a, 12, 6 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0x4b, 16, 8 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0x4c, 12,12 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0x4d, 16,16 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0xd0, 4, 512 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0xd1, 4, 1 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0xd2, 4, 2 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0xd6, 8, 1 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0xd7, 8, 2 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0xd8, 8, 4 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0xdc, 12, 3 * 512 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0xdd, 12, 3 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0xde, 12, 6 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0xe2, 16, 2 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0xe3, 16, 4 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0xe4, 16, 8 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0xea, 24,12 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0xeb, 24,24 * 1024 * 1024, 64, NULL), \ +__CI_TBL(CAI_L3CACHE, 0xec, 24,24 * 1024 * 1024, 64, NULL), \ __CI_TBL(0, 0, 0, 0, 0, NULL) \ } Index: src/sys/arch/x86/include/specialreg.h diff -u src/sys/arch/x86/include/specialreg.h:1.33 src/sys/arch/x86/include/specialreg.h:1.34 --- src/sys/arch/x86/include/specialreg.h:1.33 Thu Mar 12 09:08:40 2009 +++ src/sys/arch/x86/include/specialreg.h Wed May 13 22:25:51 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: specialreg.h,v 1.33 2009/03/12 09:08:40 yamt Exp $ */ +/* $NetBSD: specialreg.h,v 1.34 2009/05/13 22:25:51 pgoyette Exp $ */ /*- * Copyright (c) 1991 The Regents of the University of California. @@ -121,24 +121,27 @@ #define CPUID_IA64 0x40000000 /* IA-64 architecture */ #define CPUID_SBF 0x80000000 /* signal break on FERR */ -#define CPUID_FLAGS1 "\20\1FPU\2VME\3DE\4PSE\5TSC\6MSR\7PAE" \ - "\10MCE\11CX8\12APIC\13B10\14SEP\15MTRR" -#define CPUID_MASK1 0x00001fff -#define CPUID_FLAGS2 "\20\16PGE\17MCA\20CMOV\21PAT\22PSE36\23PN\24CFLUSH" \ - "\25B20\26DS\27ACPI\30MMX" -#define CPUID_MASK2 0x00ffe000 -#define CPUID_FLAGS3 "\20\31FXSR\32SSE\33SSE2\34SS\35HTT\36TM\37IA64\40SBF" -#define CPUID_MASK3 0xff000000 +#define CPUID_FLAGS1 "\20\1FPU\2VME\3DE\4PSE\5TSC\6MSR\7PAE\10MCE\11CX8" \ + "\12APIC\13B10\14SEP\15MTRR\16PGE\17MCA\20CMOV" \ + "\21PAT\22PSE36\23PN\24CFLUSH\25B20\26DS\27ACPI" \ + "\30MMX\31FXSR\32SSE\33SSE2\34SS\35HTT\36TM" \ + "\37IA64\40SBF" /* - * CPUID Intel extended features + * CPUID Intel extended features - %EDX */ #define CPUID_SYSCALL 0x00000800 /* SYSCALL/SYSRET */ #define CPUID_XD 0x00100000 /* Execute Disable */ #define CPUID_EM64T 0x20000000 /* Intel EM64T */ -#define CPUID_INTEL_MASK4 0x20100800 -#define CPUID_INTEL_FLAGS4 "\20\14SYSCALL/SYSRET\25XD\36EM64T" +#define CPUID_INTEL_EXT_FLAGS "\20\14SYSCALL/SYSRET\25XD\36EM64T" + +/* + * CPUID Intel extended features - %ECX + */ +#define CPUID_LAHF 0x00000001 /* LAHF/SAHF in IA-32e mode, 64bit sub*/ + +#define CPUID_INTEL_FLAGS4 "\20\1LAHF" /* * AMD/VIA processor specific flags. @@ -175,7 +178,6 @@ #define CPUID_SKINIT 0x00001000 /* SKINIT */ #define CPUID_WDT 0x00002000 /* watchdog timer support */ -#define CPUID_AMD_MASK4 0x00003fff #define CPUID_AMD_FLAGS4 "\20\1LAHF\2CMPLEGACY\3SVM\4EAPIC\5ALTMOVCR0" \ "\6LZCNT\7SSE4A\10MISALIGNSSE" \ "\0113DNOWPREFETCH\12OSVW\13IBS" \ @@ -204,8 +206,8 @@ #define CPUID_APM_HWP 0x00000080 /* HW P-State control */ #define CPUID_APM_TSC 0x00000100 /* TSC invariant */ -#define CPUID_APM_FLAGS "\20\1TS\2FID\3VID\4TTP\5HTC\6STC\007100\10HWP\11TSC" - +#define CPUID_APM_FLAGS "\20\1TS\2FID\3VID\4TTP\5HTC\6STC\007100" \ + "\10HWP\11TSC" /* * Centaur Extended Feature flags @@ -246,9 +248,11 @@ #define CPUID2_X2APIC 0x00200000 /* xAPIC Extensions */ #define CPUID2_POPCNT 0x00800000 -#define CPUID2_FLAGS "\20\1SSE3\3DTES64\4MONITOR\5DS-CPL\6VMX\7SMX\10EST" \ - "\11TM2\12SSSE3\13CID\16CX16\17xTPR\20PDCM\23DCA" \ - "\24SSE41\25SSE42\26X2APIC\30POPCNT" +#define CPUID2_FLAGS1 "\20\1SSE3\2B01\3DTES64\4MONITOR\5DS-CPL\6VMX\7SMX" \ + "\10EST\11TM2\12SSE3\13CID\14B11\15B12\16CX16" \ + "\17xTPR\20PDCM\21B16\22B17\23DCA\24SSE41\25SSE42" \ + "\26X2APIC\27MOVBE\30POPCNT\31B24\32B25\33XSAVE" \ + "\34OSXSAVE\35B28\36B29\37B30\40B31" #define CPUID2FAMILY(cpuid) (((cpuid) >> 8) & 0xf) #define CPUID2MODEL(cpuid) (((cpuid) >> 4) & 0xf) Index: src/usr.sbin/cpuctl/arch/i386.c diff -u src/usr.sbin/cpuctl/arch/i386.c:1.17 src/usr.sbin/cpuctl/arch/i386.c:1.18 --- src/usr.sbin/cpuctl/arch/i386.c:1.17 Wed Apr 22 18:10:38 2009 +++ src/usr.sbin/cpuctl/arch/i386.c Wed May 13 22:25:51 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: i386.c,v 1.17 2009/04/22 18:10:38 christos Exp $ */ +/* $NetBSD: i386.c,v 1.18 2009/05/13 22:25:51 pgoyette Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -57,7 +57,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: i386.c,v 1.17 2009/04/22 18:10:38 christos Exp $"); +__RCSID("$NetBSD: i386.c,v 1.18 2009/05/13 22:25:51 pgoyette Exp $"); #endif /* not lint */ #include <sys/types.h> @@ -94,11 +94,13 @@ const char *ci_dev; int32_t ci_cpuid_level; uint32_t ci_signature; /* X86 cpuid type */ - uint32_t ci_feature_flags;/* X86 %edx CPUID feature bits */ - uint32_t ci_feature2_flags;/* X86 %ecx CPUID feature bits */ - uint32_t ci_feature3_flags;/* X86 extended %edx feature bits */ - uint32_t ci_feature4_flags;/* X86 extended %ecx feature bits */ - uint32_t ci_padlock_flags;/* VIA PadLock feature bits */ + uint32_t ci_feat_val[5]; /* X86 CPUID feature bits + * [0] basic features %edx + * [1] basic features %ecx + * [2] extended features %edx + * [3] extended features %ecx + * [4] VIA padlock features + */ uint32_t ci_cpu_class; /* CPU class */ uint32_t ci_brand_id; /* Intel brand id */ uint32_t ci_vendor[4]; /* vendor string */ @@ -122,6 +124,10 @@ void (*cpu_info)(struct cpu_info *); }; +struct cpu_extend_nameclass { + int ext_model; + const char *cpu_models[CPU_MAXMODEL+1]; +}; struct cpu_cpuid_nameclass { const char *cpu_id; @@ -133,6 +139,7 @@ void (*cpu_setup)(struct cpu_info *); void (*cpu_probe)(struct cpu_info *); void (*cpu_info)(struct cpu_info *); + struct cpu_extend_nameclass *cpu_extended_names; } cpu_family[CPU_MAXFAMILY - CPU_MINFAMILY + 1]; }; @@ -237,6 +244,21 @@ "" }; +struct cpu_extend_nameclass intel_family6_ext_models[] = { + { /* Extended models 1x */ + 0x01, { NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + "Core i7 (Nehalem)", NULL, + "Atom", "XeonMP (Nehalem)", + NULL, NULL} }, + { /* End of list */ + 0x00, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL} } +}; + const struct cpu_cpuid_nameclass i386_cpuid_cpus[] = { { "GenuineIntel", @@ -254,6 +276,7 @@ NULL, NULL, NULL, + NULL, }, /* Family 5 */ { @@ -269,6 +292,7 @@ NULL, NULL, NULL, + NULL, }, /* Family 6 */ { @@ -291,6 +315,7 @@ NULL, intel_family_new_probe, NULL, + &intel_family6_ext_models[0], }, /* Family > 6 */ { @@ -303,6 +328,7 @@ NULL, intel_family_new_probe, NULL, + NULL, } } }, { @@ -324,6 +350,7 @@ NULL, NULL, NULL, + NULL, }, /* Family 5 */ { @@ -337,6 +364,7 @@ amd_family5_setup, NULL, amd_cpu_cacheinfo, + NULL, }, /* Family 6 */ { @@ -351,6 +379,7 @@ NULL, amd_family6_probe, amd_cpu_cacheinfo, + NULL, }, /* Family > 6 */ { @@ -363,6 +392,7 @@ NULL, amd_family6_probe, amd_cpu_cacheinfo, + NULL, } } }, { @@ -381,6 +411,7 @@ cyrix6x86_cpu_setup, /* XXX ?? */ NULL, NULL, + NULL, }, /* Family 5 */ { @@ -394,6 +425,7 @@ cyrix6x86_cpu_setup, NULL, NULL, + NULL, }, /* Family 6 */ { @@ -406,6 +438,7 @@ cyrix6x86_cpu_setup, NULL, NULL, + NULL, }, /* Family > 6 */ { @@ -418,6 +451,7 @@ NULL, NULL, NULL, + NULL, } } }, { /* MediaGX is now owned by National Semiconductor */ @@ -435,6 +469,7 @@ NULL, NULL, NULL, + NULL, }, /* Family 5: Geode family, formerly MediaGX */ { @@ -448,6 +483,7 @@ cyrix6x86_cpu_setup, NULL, amd_cpu_cacheinfo, + NULL, }, /* Family 6, not yet available from NSC */ { @@ -460,6 +496,7 @@ NULL, NULL, NULL, + NULL, }, /* Family > 6, not yet available from NSC */ { @@ -472,6 +509,7 @@ NULL, NULL, NULL, + NULL, } } }, { @@ -489,6 +527,7 @@ NULL, NULL, NULL, + NULL, }, /* Family 5 */ { @@ -501,6 +540,7 @@ winchip_cpu_setup, NULL, NULL, + NULL, }, /* Family 6, VIA acquired IDT Centaur design subsidiary */ { @@ -514,6 +554,7 @@ NULL, via_cpu_probe, via_cpu_cacheinfo, + NULL, }, /* Family > 6, not yet available from VIA */ { @@ -526,6 +567,7 @@ NULL, NULL, NULL, + NULL, } } }, { @@ -543,6 +585,7 @@ NULL, NULL, NULL, + NULL, }, /* Family 5 */ { @@ -555,6 +598,7 @@ NULL, NULL, transmeta_cpu_info, + NULL, }, /* Family 6, not yet available from Transmeta */ { @@ -567,6 +611,7 @@ NULL, NULL, NULL, + NULL, }, /* Family > 6, not yet available from Transmeta */ { @@ -579,6 +624,7 @@ NULL, NULL, NULL, + NULL, } } } }; @@ -590,8 +636,8 @@ static void disable_tsc(struct cpu_info *ci) { - if (ci->ci_feature_flags & CPUID_TSC) { - ci->ci_feature_flags &= ~CPUID_TSC; + if (ci->ci_feat_val[0] & CPUID_TSC) { + ci->ci_feat_val[0] &= ~CPUID_TSC; aprint_error("WARNING: broken TSC disabled\n"); } } @@ -640,7 +686,7 @@ * 253668.pdf 7.10.2 */ - if ((ci->ci_feature_flags & CPUID_HTT) != 0) { + if ((ci->ci_feat_val[0] & CPUID_HTT) != 0) { x86_cpuid(1, descs); lp_max = (descs[1] >> 16) & 0xff; } @@ -692,7 +738,7 @@ */ if (lfunc >= 0x80000001) { x86_cpuid(0x80000001, descs); - ci->ci_feature3_flags |= descs[3]; + ci->ci_feat_val[2] |= descs[3]; } if (model < 0x9) @@ -708,7 +754,7 @@ lfunc = descs[3]; if (model > 0x9 || stepping >= 8) { /* ACE */ if (lfunc & CPUID_VIA_HAS_ACE) { - ci->ci_padlock_flags = lfunc; + ci->ci_feat_val[4] = lfunc; } } } @@ -966,8 +1012,8 @@ x86_cpuid(1, descs); ci->ci_signature = descs[0]; miscbytes = descs[1]; - ci->ci_feature2_flags = descs[2]; - ci->ci_feature_flags = descs[3]; + ci->ci_feat_val[1] = descs[2]; + ci->ci_feat_val[0] = descs[3]; /* Brand is low order 8 bits of ebx */ ci->ci_brand_id = miscbytes & 0xff; @@ -1009,7 +1055,7 @@ * If the processor serial number misfeature is present and supported, * extract it here. */ - if ((ci->ci_feature_flags & CPUID_PN) != 0) { + if ((ci->ci_feat_val[0] & CPUID_PN) != 0) { ci->ci_cpu_serial[0] = ci->ci_signature; x86_cpuid(3, descs); ci->ci_cpu_serial[2] = descs[2]; @@ -1065,7 +1111,8 @@ */ if (descs[0] >= 0x80000001) { x86_cpuid(0x80000001, descs); - ci->ci_feature3_flags |= descs[3]; + ci->ci_feat_val[2] |= descs[3]; + ci->ci_feat_val[3] |= descs[2]; } } @@ -1083,8 +1130,8 @@ */ if (descs[0] >= 0x80000001) { x86_cpuid(0x80000001, descs); - ci->ci_feature3_flags |= descs[3]; /* %edx */ - ci->ci_feature4_flags = descs[2]; /* %ecx */ + ci->ci_feat_val[2] |= descs[3]; /* %edx */ + ci->ci_feat_val[3] = descs[2]; /* %ecx */ } if (*cpu_brand_string == '\0') @@ -1110,8 +1157,9 @@ * support for global PTEs, instead using bit 9 (APIC) * rather than bit 13 (i.e. "0x200" vs. 0x2000". Oops!). */ - if (ci->ci_feature_flags & CPUID_APIC) - ci->ci_feature_flags = (ci->ci_feature_flags & ~CPUID_APIC) | CPUID_PGE; + if (ci->ci_feat_val[0] & CPUID_APIC) + ci->ci_feat_val[0] = + (ci->ci_feat_val[0] & ~CPUID_APIC) | CPUID_PGE; /* * XXX But pmap_pg_g is already initialized -- need to kick * XXX the pmap somehow. How does the MP branch do this? @@ -1181,9 +1229,10 @@ void identifycpu(const char *cpuname) { - const char *name, *modifier, *vendorname, *brand = ""; + const char *name = "", *modifier, *vendorname, *brand = ""; int class = CPUCLASS_386, i, xmax; - int modif, family, model; + int modif, family, model, ext_model; + const struct cpu_extend_nameclass *modlist; const struct cpu_cpuid_nameclass *cpup = NULL; const struct cpu_cpuid_family *cpufam; const char *feature_str[5]; @@ -1191,7 +1240,8 @@ extern int cpu; extern int cpu_info_level; size_t sz; - char buf[256]; + char buf[512]; + char *bp; ci = &cistore; memset(ci, 0, sizeof(*ci)); @@ -1217,6 +1267,7 @@ if (family < CPU_MINFAMILY) errx(1, "identifycpu: strange family value"); model = CPUID2MODEL(ci->ci_signature); + ext_model = CPUID2EXTMODEL(ci->ci_signature); for (i = 0; i < xmax; i++) { if (!strncmp((char *)ci->ci_vendor, @@ -1245,11 +1296,29 @@ if (family > CPU_MAXFAMILY) { family = CPU_MAXFAMILY; model = CPU_DEFMODEL; - } else if (model > CPU_MAXMODEL) + } else if (model > CPU_MAXMODEL) { model = CPU_DEFMODEL; + ext_model = 0; + } cpufam = &cpup->cpu_family[family - CPU_MINFAMILY]; - name = cpufam->cpu_models[model]; - if (name == NULL) + if (cpufam->cpu_extended_names == NULL || + ext_model == 0) + name = cpufam->cpu_models[model]; + else { + /* + * Scan list(s) of extended model names + */ + modlist = cpufam->cpu_extended_names; + while (modlist->ext_model != 0) { + if (modlist->ext_model == ext_model) { + name = + modlist->cpu_models[model]; + break; + } + modlist++; + } + } + if (name == NULL || *name == '\0') name = cpufam->cpu_models[CPU_DEFMODEL]; class = cpufam->cpu_class; ci->ci_info = cpufam->cpu_info; @@ -1324,70 +1393,53 @@ if (ci->ci_info) (*ci->ci_info)(ci); + /* + * display CPU feature flags + */ + +#define MAX_FEATURE_LEN 60 /* XXX Need to find a better way to set this */ + feature_str[0] = CPUID_FLAGS1; - feature_str[1] = CPUID_FLAGS2; - feature_str[2] = CPUID_FLAGS3; + feature_str[1] = CPUID2_FLAGS1; + feature_str[2] = CPUID_EXT_FLAGS; + feature_str[3] = NULL; + feature_str[4] = NULL; switch (cpu_vendor) { case CPUVENDOR_AMD: - feature_str[3] = CPUID_EXT_FLAGS; - feature_str[4] = CPUID_AMD_FLAGS4; + feature_str[3] = CPUID_AMD_FLAGS4; break; case CPUVENDOR_INTEL: + feature_str[2] = CPUID_INTEL_EXT_FLAGS; feature_str[3] = CPUID_INTEL_FLAGS4; break; + case CPUVENDOR_CYRIX: + feature_str[4] = CPUID_FLAGS_PADLOCK; + /* FALLTHRU */ default: - feature_str[3] = CPUID_EXT_FLAGS; break; } - if (ci->ci_feature_flags) { - if ((ci->ci_feature_flags & CPUID_MASK1) != 0) { - snprintb(buf, sizeof(buf), feature_str[0], - ci->ci_feature_flags); - aprint_verbose("%s: features %s\n", cpuname, buf); - } - if ((ci->ci_feature_flags & CPUID_MASK2) != 0) { - snprintb(buf, sizeof(buf), feature_str[1], - ci->ci_feature_flags); - aprint_verbose("%s: features %s\n", cpuname, buf); - } - if ((ci->ci_feature_flags & CPUID_MASK3) != 0) { - snprintb(buf, sizeof(buf), feature_str[2], - ci->ci_feature_flags); - aprint_verbose("%s: features %s\n", cpuname, buf); + for (i = 0; i <= 4; i++) { + if (ci->ci_feat_val[i] && feature_str[i] != NULL) { + snprintb_m(buf, sizeof(buf), feature_str[i], + ci->ci_feat_val[i], MAX_FEATURE_LEN); + bp = buf; + while (*bp != '\0') { + aprint_verbose("%s: %sfeatures%c %s\n", + cpuname, (i == 4)?"padlock ":"", + (i == 4 || i == 0)?' ':'1' + i, bp); + bp += strlen(bp) + 1; + } } } - if (ci->ci_feature2_flags) { - snprintb(buf, sizeof(buf), CPUID2_FLAGS, ci->ci_feature2_flags); - aprint_verbose("%s: features2 %s\n", cpuname, buf); - } - - if (ci->ci_feature3_flags) { - snprintb(buf, sizeof(buf), feature_str[3], - ci->ci_feature3_flags); - aprint_verbose("%s: features3 %s\n", cpuname, buf); - } - - if (ci->ci_feature4_flags) { - snprintb(buf, sizeof(buf), feature_str[4], - ci->ci_feature4_flags); - aprint_verbose("%s: features4 %s\n", cpuname, buf); - } - - if (ci->ci_padlock_flags) { - snprintb(buf, sizeof(buf), CPUID_FLAGS_PADLOCK, - ci->ci_padlock_flags); - aprint_verbose("%s: padlock features %s\n", cpuname, buf); - } - if (*cpu_brand_string != '\0') aprint_normal("%s: \"%s\"\n", cpuname, cpu_brand_string); x86_print_cacheinfo(ci); - if (ci->ci_cpuid_level >= 3 && (ci->ci_feature_flags & CPUID_PN)) { + if (ci->ci_cpuid_level >= 3 && (ci->ci_feat_val[0] & CPUID_PN)) { aprint_verbose("%s: serial number %04X-%04X-%04X-%04X-%04X-%04X\n", cpuname, ci->ci_cpu_serial[0] / 65536, ci->ci_cpu_serial[0] % 65536, @@ -1427,7 +1479,7 @@ if (cpu_vendor == CPUVENDOR_AMD) { powernow_probe(ci); - if ((ci->ci_feature3_flags & CPUID_SVM) != 0) { + if ((ci->ci_feat_val[3] & CPUID_SVM) != 0) { uint32_t data[4]; x86_cpuid(0x8000000a, data);