Home | History | Annotate | Line # | Download | only in arch
i386.c revision 1.18
      1  1.18  pgoyette /*	$NetBSD: i386.c,v 1.18 2009/05/13 22:25:51 pgoyette Exp $	*/
      2   1.1        ad 
      3   1.1        ad /*-
      4   1.1        ad  * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
      5   1.1        ad  * All rights reserved.
      6   1.1        ad  *
      7   1.1        ad  * This code is derived from software contributed to The NetBSD Foundation
      8   1.1        ad  * by Frank van der Linden,  and by Jason R. Thorpe.
      9   1.1        ad  *
     10   1.1        ad  * Redistribution and use in source and binary forms, with or without
     11   1.1        ad  * modification, are permitted provided that the following conditions
     12   1.1        ad  * are met:
     13   1.1        ad  * 1. Redistributions of source code must retain the above copyright
     14   1.1        ad  *    notice, this list of conditions and the following disclaimer.
     15   1.1        ad  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1        ad  *    notice, this list of conditions and the following disclaimer in the
     17   1.1        ad  *    documentation and/or other materials provided with the distribution.
     18   1.1        ad  *
     19   1.1        ad  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20   1.1        ad  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21   1.1        ad  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22   1.1        ad  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23   1.1        ad  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24   1.1        ad  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25   1.1        ad  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26   1.1        ad  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27   1.1        ad  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28   1.1        ad  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29   1.1        ad  * POSSIBILITY OF SUCH DAMAGE.
     30   1.1        ad  */
     31   1.1        ad 
     32   1.1        ad /*-
     33   1.1        ad  * Copyright (c)2008 YAMAMOTO Takashi,
     34   1.1        ad  * All rights reserved.
     35   1.1        ad  *
     36   1.1        ad  * Redistribution and use in source and binary forms, with or without
     37   1.1        ad  * modification, are permitted provided that the following conditions
     38   1.1        ad  * are met:
     39   1.1        ad  * 1. Redistributions of source code must retain the above copyright
     40   1.1        ad  *    notice, this list of conditions and the following disclaimer.
     41   1.1        ad  * 2. Redistributions in binary form must reproduce the above copyright
     42   1.1        ad  *    notice, this list of conditions and the following disclaimer in the
     43   1.1        ad  *    documentation and/or other materials provided with the distribution.
     44   1.1        ad  *
     45   1.1        ad  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     46   1.1        ad  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     47   1.1        ad  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     48   1.1        ad  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     49   1.1        ad  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     50   1.1        ad  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     51   1.1        ad  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     52   1.1        ad  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     53   1.1        ad  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     54   1.1        ad  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     55   1.1        ad  * SUCH DAMAGE.
     56   1.1        ad  */
     57   1.1        ad 
     58   1.1        ad #include <sys/cdefs.h>
     59   1.1        ad #ifndef lint
     60  1.18  pgoyette __RCSID("$NetBSD: i386.c,v 1.18 2009/05/13 22:25:51 pgoyette Exp $");
     61   1.1        ad #endif /* not lint */
     62   1.1        ad 
     63   1.1        ad #include <sys/types.h>
     64   1.1        ad #include <sys/param.h>
     65   1.1        ad #include <sys/bitops.h>
     66   1.1        ad #include <sys/sysctl.h>
     67   1.1        ad 
     68   1.1        ad #include <string.h>
     69   1.1        ad #include <stdio.h>
     70   1.1        ad #include <stdlib.h>
     71   1.1        ad #include <err.h>
     72   1.1        ad #include <assert.h>
     73   1.1        ad #include <math.h>
     74  1.14  christos #include <util.h>
     75   1.1        ad 
     76   1.1        ad #include <machine/specialreg.h>
     77   1.1        ad #include <machine/cpu.h>
     78   1.1        ad 
     79   1.1        ad #include <x86/cpuvar.h>
     80   1.1        ad #include <x86/cputypes.h>
     81   1.6  christos #include <x86/cacheinfo.h>
     82   1.1        ad 
     83   1.1        ad #include "../cpuctl.h"
     84   1.1        ad 
     85   1.7  christos /* Size of buffer for printing humanized numbers */
     86  1.16   tsutsui #define HUMAN_BUFSIZE sizeof("999KB")
     87   1.7  christos 
     88   1.1        ad #define       x86_cpuid(a,b)  x86_cpuid2((a),0,(b))
     89   1.1        ad 
     90   1.1        ad void	x86_cpuid2(uint32_t, uint32_t, uint32_t *);
     91   1.1        ad void	x86_identify(void);
     92   1.1        ad 
     93   1.1        ad struct cpu_info {
     94   1.1        ad 	const char	*ci_dev;
     95   1.1        ad 	int32_t		ci_cpuid_level;
     96   1.1        ad 	uint32_t	ci_signature;	 /* X86 cpuid type */
     97  1.18  pgoyette 	uint32_t	ci_feat_val[5];	 /* X86 CPUID feature bits
     98  1.18  pgoyette 					  *	[0] basic features %edx
     99  1.18  pgoyette 					  *	[1] basic features %ecx
    100  1.18  pgoyette 					  *	[2] extended features %edx
    101  1.18  pgoyette 					  *	[3] extended features %ecx
    102  1.18  pgoyette 					  *	[4] VIA padlock features
    103  1.18  pgoyette 					  */
    104   1.1        ad 	uint32_t	ci_cpu_class;	 /* CPU class */
    105   1.1        ad 	uint32_t	ci_brand_id;	 /* Intel brand id */
    106   1.1        ad 	uint32_t	ci_vendor[4];	 /* vendor string */
    107   1.1        ad 	uint32_t	ci_cpu_serial[3]; /* PIII serial number */
    108   1.1        ad 	uint64_t	ci_tsc_freq;	 /* cpu cycles/second */
    109   1.1        ad 	uint8_t		ci_packageid;
    110   1.1        ad 	uint8_t		ci_coreid;
    111   1.1        ad 	uint8_t		ci_smtid;
    112   1.1        ad 	uint32_t	ci_initapicid;
    113   1.1        ad 	struct x86_cache_info ci_cinfo[CAI_COUNT];
    114   1.1        ad 	void		(*ci_info)(struct cpu_info *);
    115   1.1        ad };
    116   1.1        ad 
    117   1.1        ad struct cpu_nocpuid_nameclass {
    118   1.1        ad 	int cpu_vendor;
    119   1.1        ad 	const char *cpu_vendorname;
    120   1.1        ad 	const char *cpu_name;
    121   1.1        ad 	int cpu_class;
    122   1.1        ad 	void (*cpu_setup)(struct cpu_info *);
    123   1.1        ad 	void (*cpu_cacheinfo)(struct cpu_info *);
    124   1.1        ad 	void (*cpu_info)(struct cpu_info *);
    125   1.1        ad };
    126   1.1        ad 
    127  1.18  pgoyette struct cpu_extend_nameclass {
    128  1.18  pgoyette 	int ext_model;
    129  1.18  pgoyette 	const char *cpu_models[CPU_MAXMODEL+1];
    130  1.18  pgoyette };
    131   1.1        ad 
    132   1.1        ad struct cpu_cpuid_nameclass {
    133   1.1        ad 	const char *cpu_id;
    134   1.1        ad 	int cpu_vendor;
    135   1.1        ad 	const char *cpu_vendorname;
    136   1.1        ad 	struct cpu_cpuid_family {
    137   1.1        ad 		int cpu_class;
    138   1.1        ad 		const char *cpu_models[CPU_MAXMODEL+2];
    139   1.1        ad 		void (*cpu_setup)(struct cpu_info *);
    140   1.1        ad 		void (*cpu_probe)(struct cpu_info *);
    141   1.1        ad 		void (*cpu_info)(struct cpu_info *);
    142  1.18  pgoyette 		struct cpu_extend_nameclass *cpu_extended_names;
    143   1.1        ad 	} cpu_family[CPU_MAXFAMILY - CPU_MINFAMILY + 1];
    144   1.1        ad };
    145   1.1        ad 
    146   1.7  christos static const struct x86_cache_info intel_cpuid_cache_info[] = INTEL_CACHE_INFO;
    147   1.1        ad 
    148   1.1        ad /*
    149   1.1        ad  * Map Brand ID from cpuid instruction to brand name.
    150   1.1        ad  * Source: Intel Processor Identification and the CPUID Instruction, AP-485
    151   1.1        ad  */
    152   1.1        ad static const char * const i386_intel_brand[] = {
    153   1.1        ad 	"",		    /* Unsupported */
    154   1.1        ad 	"Celeron",	    /* Intel (R) Celeron (TM) processor */
    155   1.1        ad 	"Pentium III",      /* Intel (R) Pentium (R) III processor */
    156   1.1        ad 	"Pentium III Xeon", /* Intel (R) Pentium (R) III Xeon (TM) processor */
    157   1.1        ad 	"Pentium III",      /* Intel (R) Pentium (R) III processor */
    158   1.1        ad 	"",		    /* Reserved */
    159   1.1        ad 	"Mobile Pentium III", /* Mobile Intel (R) Pentium (R) III processor-M */
    160   1.1        ad 	"Mobile Celeron",   /* Mobile Intel (R) Celeron (R) processor */
    161   1.1        ad 	"Pentium 4",	    /* Intel (R) Pentium (R) 4 processor */
    162   1.1        ad 	"Pentium 4",	    /* Intel (R) Pentium (R) 4 processor */
    163   1.1        ad 	"Celeron",	    /* Intel (R) Celeron (TM) processor */
    164   1.1        ad 	"Xeon",		    /* Intel (R) Xeon (TM) processor */
    165   1.1        ad 	"Xeon MP",	    /* Intel (R) Xeon (TM) processor MP */
    166   1.1        ad 	"",		    /* Reserved */
    167   1.1        ad 	"Mobile Pentium 4", /* Mobile Intel (R) Pentium (R) 4 processor-M */
    168   1.1        ad 	"Mobile Celeron",   /* Mobile Intel (R) Celeron (R) processor */
    169   1.1        ad };
    170   1.1        ad 
    171   1.1        ad /*
    172   1.1        ad  * AMD processors don't have Brand IDs, so we need these names for probe.
    173   1.1        ad  */
    174   1.1        ad static const char * const amd_brand[] = {
    175   1.1        ad 	"",
    176   1.1        ad 	"Duron",	/* AMD Duron(tm) */
    177   1.1        ad 	"MP",		/* AMD Athlon(tm) MP */
    178   1.1        ad 	"XP",		/* AMD Athlon(tm) XP */
    179   1.1        ad 	"4"		/* AMD Athlon(tm) 4 */
    180   1.1        ad };
    181   1.1        ad 
    182   1.1        ad static int cpu_vendor;
    183   1.1        ad static char cpu_brand_string[49];
    184   1.1        ad static char amd_brand_name[48];
    185   1.1        ad 
    186   1.1        ad static void via_cpu_probe(struct cpu_info *);
    187   1.1        ad static void amd_family6_probe(struct cpu_info *);
    188   1.1        ad static void intel_family_new_probe(struct cpu_info *);
    189   1.1        ad static const char *intel_family6_name(struct cpu_info *);
    190   1.1        ad static const char *amd_amd64_name(struct cpu_info *);
    191   1.1        ad static void amd_family5_setup(struct cpu_info *);
    192   1.1        ad static void transmeta_cpu_info(struct cpu_info *);
    193   1.1        ad static const char *print_cache_config(struct cpu_info *, int, const char *,
    194   1.1        ad     const char *);
    195   1.1        ad static const char *print_tlb_config(struct cpu_info *, int, const char *,
    196   1.1        ad     const char *);
    197   1.1        ad static void 	amd_cpu_cacheinfo(struct cpu_info *);
    198   1.1        ad static void	via_cpu_cacheinfo(struct cpu_info *);
    199   1.1        ad static void	x86_print_cacheinfo(struct cpu_info *);
    200   1.1        ad static const struct x86_cache_info *cache_info_lookup(
    201   1.1        ad     const struct x86_cache_info *, uint8_t);
    202   1.1        ad static void cyrix6x86_cpu_setup(struct cpu_info *);
    203   1.1        ad static void winchip_cpu_setup(struct cpu_info *);
    204   1.1        ad static void amd_family5_setup(struct cpu_info *);
    205   1.5        ad static void powernow_probe(struct cpu_info *);
    206   1.1        ad 
    207   1.1        ad /*
    208   1.1        ad  * Info for CTL_HW
    209   1.1        ad  */
    210   1.1        ad static char	cpu_model[120];
    211   1.1        ad 
    212   1.1        ad /*
    213   1.1        ad  * Note: these are just the ones that may not have a cpuid instruction.
    214   1.1        ad  * We deal with the rest in a different way.
    215   1.1        ad  */
    216   1.1        ad const struct cpu_nocpuid_nameclass i386_nocpuid_cpus[] = {
    217   1.1        ad 	{ CPUVENDOR_INTEL, "Intel", "386SX",	CPUCLASS_386,
    218   1.1        ad 	  NULL, NULL, NULL },			/* CPU_386SX */
    219   1.1        ad 	{ CPUVENDOR_INTEL, "Intel", "386DX",	CPUCLASS_386,
    220   1.1        ad 	  NULL, NULL, NULL },			/* CPU_386   */
    221   1.1        ad 	{ CPUVENDOR_INTEL, "Intel", "486SX",	CPUCLASS_486,
    222   1.1        ad 	  NULL, NULL, NULL },			/* CPU_486SX */
    223   1.1        ad 	{ CPUVENDOR_INTEL, "Intel", "486DX",	CPUCLASS_486,
    224   1.1        ad 	  NULL, NULL, NULL },			/* CPU_486   */
    225   1.1        ad 	{ CPUVENDOR_CYRIX, "Cyrix", "486DLC",	CPUCLASS_486,
    226   1.1        ad 	  NULL, NULL, NULL },			/* CPU_486DLC */
    227   1.1        ad 	{ CPUVENDOR_CYRIX, "Cyrix", "6x86",	CPUCLASS_486,
    228   1.1        ad 	  NULL, NULL, NULL },		/* CPU_6x86 */
    229   1.1        ad 	{ CPUVENDOR_NEXGEN,"NexGen","586",      CPUCLASS_386,
    230   1.1        ad 	  NULL, NULL, NULL },			/* CPU_NX586 */
    231   1.1        ad };
    232   1.1        ad 
    233   1.1        ad const char *classnames[] = {
    234   1.1        ad 	"386",
    235   1.1        ad 	"486",
    236   1.1        ad 	"586",
    237   1.1        ad 	"686"
    238   1.1        ad };
    239   1.1        ad 
    240   1.1        ad const char *modifiers[] = {
    241   1.1        ad 	"",
    242   1.1        ad 	"OverDrive",
    243   1.1        ad 	"Dual",
    244   1.1        ad 	""
    245   1.1        ad };
    246   1.1        ad 
    247  1.18  pgoyette struct cpu_extend_nameclass intel_family6_ext_models[] = {
    248  1.18  pgoyette 	{ /* Extended models 1x */
    249  1.18  pgoyette 	  0x01, { NULL,			NULL,
    250  1.18  pgoyette 		  NULL,			NULL,
    251  1.18  pgoyette 		  NULL,			NULL,
    252  1.18  pgoyette 		  NULL,			NULL,
    253  1.18  pgoyette 		  NULL,			NULL,
    254  1.18  pgoyette 		  "Core i7 (Nehalem)",	NULL,
    255  1.18  pgoyette 		  "Atom",		"XeonMP (Nehalem)",
    256  1.18  pgoyette 		   NULL,		NULL} },
    257  1.18  pgoyette 	{ /* End of list */
    258  1.18  pgoyette 	  0x00, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
    259  1.18  pgoyette 		  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL} }
    260  1.18  pgoyette };
    261  1.18  pgoyette 
    262   1.1        ad const struct cpu_cpuid_nameclass i386_cpuid_cpus[] = {
    263   1.1        ad 	{
    264   1.1        ad 		"GenuineIntel",
    265   1.1        ad 		CPUVENDOR_INTEL,
    266   1.1        ad 		"Intel",
    267   1.1        ad 		/* Family 4 */
    268   1.1        ad 		{ {
    269   1.1        ad 			CPUCLASS_486,
    270   1.1        ad 			{
    271   1.1        ad 				"486DX", "486DX", "486SX", "486DX2", "486SL",
    272   1.1        ad 				"486SX2", 0, "486DX2 W/B Enhanced",
    273   1.1        ad 				"486DX4", 0, 0, 0, 0, 0, 0, 0,
    274   1.1        ad 				"486"		/* Default */
    275   1.1        ad 			},
    276   1.1        ad 			NULL,
    277   1.1        ad 			NULL,
    278   1.1        ad 			NULL,
    279  1.18  pgoyette 			NULL,
    280   1.1        ad 		},
    281   1.1        ad 		/* Family 5 */
    282   1.1        ad 		{
    283   1.1        ad 			CPUCLASS_586,
    284   1.1        ad 			{
    285   1.1        ad 				"Pentium (P5 A-step)", "Pentium (P5)",
    286   1.1        ad 				"Pentium (P54C)", "Pentium (P24T)",
    287   1.1        ad 				"Pentium/MMX", "Pentium", 0,
    288   1.1        ad 				"Pentium (P54C)", "Pentium/MMX (Tillamook)",
    289   1.1        ad 				0, 0, 0, 0, 0, 0, 0,
    290   1.1        ad 				"Pentium"	/* Default */
    291   1.1        ad 			},
    292   1.1        ad 			NULL,
    293   1.1        ad 			NULL,
    294   1.1        ad 			NULL,
    295  1.18  pgoyette 			NULL,
    296   1.1        ad 		},
    297   1.1        ad 		/* Family 6 */
    298   1.1        ad 		{
    299   1.1        ad 			CPUCLASS_686,
    300   1.1        ad 			{
    301   1.1        ad 				"Pentium Pro (A-step)", "Pentium Pro", 0,
    302   1.1        ad 				"Pentium II (Klamath)", "Pentium Pro",
    303   1.1        ad 				"Pentium II/Celeron (Deschutes)",
    304   1.1        ad 				"Celeron (Mendocino)",
    305   1.1        ad 				"Pentium III (Katmai)",
    306   1.1        ad 				"Pentium III (Coppermine)",
    307   1.1        ad 				"Pentium M (Banias)",
    308   1.1        ad 				"Pentium III Xeon (Cascades)",
    309   1.1        ad 				"Pentium III (Tualatin)", 0,
    310   1.1        ad 				"Pentium M (Dothan)",
    311   1.1        ad 				"Pentium M (Yonah)",
    312   1.1        ad 				"Core 2 (Merom)",
    313   1.1        ad 				"Pentium Pro, II or III"	/* Default */
    314   1.1        ad 			},
    315   1.1        ad 			NULL,
    316   1.1        ad 			intel_family_new_probe,
    317   1.1        ad 			NULL,
    318  1.18  pgoyette 			&intel_family6_ext_models[0],
    319   1.1        ad 		},
    320   1.1        ad 		/* Family > 6 */
    321   1.1        ad 		{
    322   1.1        ad 			CPUCLASS_686,
    323   1.1        ad 			{
    324   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    325   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    326   1.1        ad 				"Pentium 4"	/* Default */
    327   1.1        ad 			},
    328   1.1        ad 			NULL,
    329   1.1        ad 			intel_family_new_probe,
    330   1.1        ad 			NULL,
    331  1.18  pgoyette 			NULL,
    332   1.1        ad 		} }
    333   1.1        ad 	},
    334   1.1        ad 	{
    335   1.1        ad 		"AuthenticAMD",
    336   1.1        ad 		CPUVENDOR_AMD,
    337   1.1        ad 		"AMD",
    338   1.1        ad 		/* Family 4 */
    339   1.1        ad 		{ {
    340   1.1        ad 			CPUCLASS_486,
    341   1.1        ad 			{
    342   1.1        ad 				0, 0, 0, "Am486DX2 W/T",
    343   1.1        ad 				0, 0, 0, "Am486DX2 W/B",
    344   1.1        ad 				"Am486DX4 W/T or Am5x86 W/T 150",
    345   1.1        ad 				"Am486DX4 W/B or Am5x86 W/B 150", 0, 0,
    346   1.1        ad 				0, 0, "Am5x86 W/T 133/160",
    347   1.1        ad 				"Am5x86 W/B 133/160",
    348   1.1        ad 				"Am486 or Am5x86"	/* Default */
    349   1.1        ad 			},
    350   1.1        ad 			NULL,
    351   1.1        ad 			NULL,
    352   1.1        ad 			NULL,
    353  1.18  pgoyette 			NULL,
    354   1.1        ad 		},
    355   1.1        ad 		/* Family 5 */
    356   1.1        ad 		{
    357   1.1        ad 			CPUCLASS_586,
    358   1.1        ad 			{
    359   1.1        ad 				"K5", "K5", "K5", "K5", 0, 0, "K6",
    360   1.1        ad 				"K6", "K6-2", "K6-III", "Geode LX", 0, 0,
    361   1.1        ad 				"K6-2+/III+", 0, 0,
    362   1.1        ad 				"K5 or K6"		/* Default */
    363   1.1        ad 			},
    364   1.1        ad 			amd_family5_setup,
    365   1.1        ad 			NULL,
    366   1.1        ad 			amd_cpu_cacheinfo,
    367  1.18  pgoyette 			NULL,
    368   1.1        ad 		},
    369   1.1        ad 		/* Family 6 */
    370   1.1        ad 		{
    371   1.1        ad 			CPUCLASS_686,
    372   1.1        ad 			{
    373   1.1        ad 				0, "Athlon Model 1", "Athlon Model 2",
    374   1.1        ad 				"Duron", "Athlon Model 4 (Thunderbird)",
    375   1.1        ad 				0, "Athlon", "Duron", "Athlon", 0,
    376   1.1        ad 				"Athlon", 0, 0, 0, 0, 0,
    377   1.1        ad 				"K7 (Athlon)"	/* Default */
    378   1.1        ad 			},
    379   1.1        ad 			NULL,
    380   1.1        ad 			amd_family6_probe,
    381   1.1        ad 			amd_cpu_cacheinfo,
    382  1.18  pgoyette 			NULL,
    383   1.1        ad 		},
    384   1.1        ad 		/* Family > 6 */
    385   1.1        ad 		{
    386   1.1        ad 			CPUCLASS_686,
    387   1.1        ad 			{
    388   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    389   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    390   1.1        ad 				"Unknown K8 (Athlon)"	/* Default */
    391   1.1        ad 			},
    392   1.1        ad 			NULL,
    393   1.1        ad 			amd_family6_probe,
    394   1.1        ad 			amd_cpu_cacheinfo,
    395  1.18  pgoyette 			NULL,
    396   1.1        ad 		} }
    397   1.1        ad 	},
    398   1.1        ad 	{
    399   1.1        ad 		"CyrixInstead",
    400   1.1        ad 		CPUVENDOR_CYRIX,
    401   1.1        ad 		"Cyrix",
    402   1.1        ad 		/* Family 4 */
    403   1.1        ad 		{ {
    404   1.1        ad 			CPUCLASS_486,
    405   1.1        ad 			{
    406   1.1        ad 				0, 0, 0,
    407   1.1        ad 				"MediaGX",
    408   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    409   1.1        ad 				"486"		/* Default */
    410   1.1        ad 			},
    411   1.1        ad 			cyrix6x86_cpu_setup, /* XXX ?? */
    412   1.1        ad 			NULL,
    413   1.1        ad 			NULL,
    414  1.18  pgoyette 			NULL,
    415   1.1        ad 		},
    416   1.1        ad 		/* Family 5 */
    417   1.1        ad 		{
    418   1.1        ad 			CPUCLASS_586,
    419   1.1        ad 			{
    420   1.1        ad 				0, 0, "6x86", 0,
    421   1.1        ad 				"MMX-enhanced MediaGX (GXm)", /* or Geode? */
    422   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    423   1.1        ad 				"6x86"		/* Default */
    424   1.1        ad 			},
    425   1.1        ad 			cyrix6x86_cpu_setup,
    426   1.1        ad 			NULL,
    427   1.1        ad 			NULL,
    428  1.18  pgoyette 			NULL,
    429   1.1        ad 		},
    430   1.1        ad 		/* Family 6 */
    431   1.1        ad 		{
    432   1.1        ad 			CPUCLASS_686,
    433   1.1        ad 			{
    434   1.1        ad 				"6x86MX", 0, 0, 0, 0, 0, 0, 0,
    435   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    436   1.1        ad 				"6x86MX"		/* Default */
    437   1.1        ad 			},
    438   1.1        ad 			cyrix6x86_cpu_setup,
    439   1.1        ad 			NULL,
    440   1.1        ad 			NULL,
    441  1.18  pgoyette 			NULL,
    442   1.1        ad 		},
    443   1.1        ad 		/* Family > 6 */
    444   1.1        ad 		{
    445   1.1        ad 			CPUCLASS_686,
    446   1.1        ad 			{
    447   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    448   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    449   1.1        ad 				"Unknown 6x86MX"		/* Default */
    450   1.1        ad 			},
    451   1.1        ad 			NULL,
    452   1.1        ad 			NULL,
    453   1.1        ad 			NULL,
    454  1.18  pgoyette 			NULL,
    455   1.1        ad 		} }
    456   1.1        ad 	},
    457   1.1        ad 	{	/* MediaGX is now owned by National Semiconductor */
    458   1.1        ad 		"Geode by NSC",
    459   1.1        ad 		CPUVENDOR_CYRIX, /* XXX */
    460   1.1        ad 		"National Semiconductor",
    461   1.1        ad 		/* Family 4, NSC never had any of these */
    462   1.1        ad 		{ {
    463   1.1        ad 			CPUCLASS_486,
    464   1.1        ad 			{
    465   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    466   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    467   1.1        ad 				"486 compatible"	/* Default */
    468   1.1        ad 			},
    469   1.1        ad 			NULL,
    470   1.1        ad 			NULL,
    471   1.1        ad 			NULL,
    472  1.18  pgoyette 			NULL,
    473   1.1        ad 		},
    474   1.1        ad 		/* Family 5: Geode family, formerly MediaGX */
    475   1.1        ad 		{
    476   1.1        ad 			CPUCLASS_586,
    477   1.1        ad 			{
    478   1.1        ad 				0, 0, 0, 0,
    479   1.1        ad 				"Geode GX1",
    480   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    481   1.1        ad 				"Geode"		/* Default */
    482   1.1        ad 			},
    483   1.1        ad 			cyrix6x86_cpu_setup,
    484   1.1        ad 			NULL,
    485   1.1        ad 			amd_cpu_cacheinfo,
    486  1.18  pgoyette 			NULL,
    487   1.1        ad 		},
    488   1.1        ad 		/* Family 6, not yet available from NSC */
    489   1.1        ad 		{
    490   1.1        ad 			CPUCLASS_686,
    491   1.1        ad 			{
    492   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    493   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    494   1.1        ad 				"Pentium Pro compatible" /* Default */
    495   1.1        ad 			},
    496   1.1        ad 			NULL,
    497   1.1        ad 			NULL,
    498   1.1        ad 			NULL,
    499  1.18  pgoyette 			NULL,
    500   1.1        ad 		},
    501   1.1        ad 		/* Family > 6, not yet available from NSC */
    502   1.1        ad 		{
    503   1.1        ad 			CPUCLASS_686,
    504   1.1        ad 			{
    505   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    506   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    507   1.1        ad 				"Pentium Pro compatible"	/* Default */
    508   1.1        ad 			},
    509   1.1        ad 			NULL,
    510   1.1        ad 			NULL,
    511   1.1        ad 			NULL,
    512  1.18  pgoyette 			NULL,
    513   1.1        ad 		} }
    514   1.1        ad 	},
    515   1.1        ad 	{
    516   1.1        ad 		"CentaurHauls",
    517   1.1        ad 		CPUVENDOR_IDT,
    518   1.1        ad 		"IDT",
    519   1.1        ad 		/* Family 4, IDT never had any of these */
    520   1.1        ad 		{ {
    521   1.1        ad 			CPUCLASS_486,
    522   1.1        ad 			{
    523   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    524   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    525   1.1        ad 				"486 compatible"	/* Default */
    526   1.1        ad 			},
    527   1.1        ad 			NULL,
    528   1.1        ad 			NULL,
    529   1.1        ad 			NULL,
    530  1.18  pgoyette 			NULL,
    531   1.1        ad 		},
    532   1.1        ad 		/* Family 5 */
    533   1.1        ad 		{
    534   1.1        ad 			CPUCLASS_586,
    535   1.1        ad 			{
    536   1.1        ad 				0, 0, 0, 0, "WinChip C6", 0, 0, 0,
    537   1.1        ad 				"WinChip 2", "WinChip 3", 0, 0, 0, 0, 0, 0,
    538   1.1        ad 				"WinChip"		/* Default */
    539   1.1        ad 			},
    540   1.1        ad 			winchip_cpu_setup,
    541   1.1        ad 			NULL,
    542   1.1        ad 			NULL,
    543  1.18  pgoyette 			NULL,
    544   1.1        ad 		},
    545   1.1        ad 		/* Family 6, VIA acquired IDT Centaur design subsidiary */
    546   1.1        ad 		{
    547   1.1        ad 			CPUCLASS_686,
    548   1.1        ad 			{
    549   1.1        ad 				0, 0, 0, 0, 0, 0, "C3 Samuel",
    550   1.1        ad 				"C3 Samuel 2/Ezra", "C3 Ezra-T",
    551   1.1        ad 				"C3 Nehemiah", "C7 Esther", 0, 0, 0, 0, 0,
    552   1.1        ad 				"C3"	/* Default */
    553   1.1        ad 			},
    554   1.1        ad 			NULL,
    555   1.1        ad 			via_cpu_probe,
    556   1.1        ad 			via_cpu_cacheinfo,
    557  1.18  pgoyette 			NULL,
    558   1.1        ad 		},
    559   1.1        ad 		/* Family > 6, not yet available from VIA */
    560   1.1        ad 		{
    561   1.1        ad 			CPUCLASS_686,
    562   1.1        ad 			{
    563   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    564   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    565   1.1        ad 				"Pentium Pro compatible"	/* Default */
    566   1.1        ad 			},
    567   1.1        ad 			NULL,
    568   1.1        ad 			NULL,
    569   1.1        ad 			NULL,
    570  1.18  pgoyette 			NULL,
    571   1.1        ad 		} }
    572   1.1        ad 	},
    573   1.1        ad 	{
    574   1.1        ad 		"GenuineTMx86",
    575   1.1        ad 		CPUVENDOR_TRANSMETA,
    576   1.1        ad 		"Transmeta",
    577   1.1        ad 		/* Family 4, Transmeta never had any of these */
    578   1.1        ad 		{ {
    579   1.1        ad 			CPUCLASS_486,
    580   1.1        ad 			{
    581   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    582   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    583   1.1        ad 				"486 compatible"	/* Default */
    584   1.1        ad 			},
    585   1.1        ad 			NULL,
    586   1.1        ad 			NULL,
    587   1.1        ad 			NULL,
    588  1.18  pgoyette 			NULL,
    589   1.1        ad 		},
    590   1.1        ad 		/* Family 5 */
    591   1.1        ad 		{
    592   1.1        ad 			CPUCLASS_586,
    593   1.1        ad 			{
    594   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    595   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    596   1.1        ad 				"Crusoe"		/* Default */
    597   1.1        ad 			},
    598   1.1        ad 			NULL,
    599   1.1        ad 			NULL,
    600   1.1        ad 			transmeta_cpu_info,
    601  1.18  pgoyette 			NULL,
    602   1.1        ad 		},
    603   1.1        ad 		/* Family 6, not yet available from Transmeta */
    604   1.1        ad 		{
    605   1.1        ad 			CPUCLASS_686,
    606   1.1        ad 			{
    607   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    608   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    609   1.1        ad 				"Pentium Pro compatible"	/* Default */
    610   1.1        ad 			},
    611   1.1        ad 			NULL,
    612   1.1        ad 			NULL,
    613   1.1        ad 			NULL,
    614  1.18  pgoyette 			NULL,
    615   1.1        ad 		},
    616   1.1        ad 		/* Family > 6, not yet available from Transmeta */
    617   1.1        ad 		{
    618   1.1        ad 			CPUCLASS_686,
    619   1.1        ad 			{
    620   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    621   1.1        ad 				0, 0, 0, 0, 0, 0, 0, 0,
    622   1.1        ad 				"Pentium Pro compatible"	/* Default */
    623   1.1        ad 			},
    624   1.1        ad 			NULL,
    625   1.1        ad 			NULL,
    626   1.1        ad 			NULL,
    627  1.18  pgoyette 			NULL,
    628   1.1        ad 		} }
    629   1.1        ad 	}
    630   1.1        ad };
    631   1.1        ad 
    632   1.1        ad /*
    633   1.1        ad  * disable the TSC such that we don't use the TSC in microtime(9)
    634   1.1        ad  * because some CPUs got the implementation wrong.
    635   1.1        ad  */
    636   1.1        ad static void
    637   1.1        ad disable_tsc(struct cpu_info *ci)
    638   1.1        ad {
    639  1.18  pgoyette 	if (ci->ci_feat_val[0] & CPUID_TSC) {
    640  1.18  pgoyette 		ci->ci_feat_val[0] &= ~CPUID_TSC;
    641   1.1        ad 		aprint_error("WARNING: broken TSC disabled\n");
    642   1.1        ad 	}
    643   1.1        ad }
    644   1.1        ad 
    645   1.1        ad static void
    646   1.1        ad cyrix6x86_cpu_setup(struct cpu_info *ci)
    647   1.1        ad {
    648   1.1        ad 
    649   1.1        ad 	/*
    650   1.1        ad 	 * Do not disable the TSC on the Geode GX, it's reported to
    651   1.1        ad 	 * work fine.
    652   1.1        ad 	 */
    653   1.1        ad 	if (ci->ci_signature != 0x552)
    654   1.1        ad 		disable_tsc(ci);
    655   1.1        ad }
    656   1.1        ad 
    657   1.1        ad void
    658   1.1        ad winchip_cpu_setup(struct cpu_info *ci)
    659   1.1        ad {
    660   1.1        ad 	switch (CPUID2MODEL(ci->ci_signature)) { /* model */
    661   1.1        ad 	case 4:	/* WinChip C6 */
    662   1.1        ad 		disable_tsc(ci);
    663   1.1        ad 	}
    664   1.1        ad }
    665   1.1        ad 
    666   1.1        ad 
    667   1.1        ad static void
    668   1.1        ad identifycpu_cpuids(struct cpu_info *ci)
    669   1.1        ad {
    670   1.1        ad 	const char *cpuname = ci->ci_dev;
    671   1.1        ad 	u_int lp_max = 1;	/* logical processors per package */
    672   1.1        ad 	u_int smt_max;		/* smt per core */
    673   1.1        ad 	u_int core_max = 1;	/* core per package */
    674  1.17  christos 	u_int smt_bits, core_bits;
    675   1.1        ad 	uint32_t descs[4];
    676   1.1        ad 
    677   1.1        ad 	aprint_verbose("%s: Initial APIC ID %u\n", cpuname, ci->ci_initapicid);
    678   1.1        ad 	ci->ci_packageid = ci->ci_initapicid;
    679   1.1        ad 	ci->ci_coreid = 0;
    680   1.1        ad 	ci->ci_smtid = 0;
    681   1.1        ad 	if (cpu_vendor != CPUVENDOR_INTEL) {
    682   1.1        ad 		return;
    683   1.1        ad 	}
    684   1.1        ad 
    685   1.1        ad 	/*
    686   1.1        ad 	 * 253668.pdf 7.10.2
    687   1.1        ad 	 */
    688   1.1        ad 
    689  1.18  pgoyette 	if ((ci->ci_feat_val[0] & CPUID_HTT) != 0) {
    690   1.1        ad 		x86_cpuid(1, descs);
    691   1.1        ad 		lp_max = (descs[1] >> 16) & 0xff;
    692   1.1        ad 	}
    693   1.1        ad 	x86_cpuid(0, descs);
    694   1.1        ad 	if (descs[0] >= 4) {
    695   1.1        ad 		x86_cpuid2(4, 0, descs);
    696   1.1        ad 		core_max = (descs[0] >> 26) + 1;
    697   1.1        ad 	}
    698   1.1        ad 	assert(lp_max >= core_max);
    699   1.1        ad 	smt_max = lp_max / core_max;
    700   1.1        ad 	smt_bits = ilog2(smt_max - 1) + 1;
    701   1.1        ad 	core_bits = ilog2(core_max - 1) + 1;
    702   1.1        ad 	if (smt_bits + core_bits) {
    703   1.1        ad 		ci->ci_packageid = ci->ci_initapicid >> (smt_bits + core_bits);
    704   1.1        ad 	}
    705   1.1        ad 	aprint_verbose("%s: Cluster/Package ID %u\n", cpuname,
    706   1.1        ad 	    ci->ci_packageid);
    707   1.1        ad 	if (core_bits) {
    708   1.1        ad 		u_int core_mask = __BITS(smt_bits, smt_bits + core_bits - 1);
    709   1.1        ad 
    710   1.1        ad 		ci->ci_coreid =
    711   1.1        ad 		    __SHIFTOUT(ci->ci_initapicid, core_mask);
    712   1.1        ad 		aprint_verbose("%s: Core ID %u\n", cpuname, ci->ci_coreid);
    713   1.1        ad 	}
    714   1.1        ad 	if (smt_bits) {
    715  1.17  christos 		u_int smt_mask = __BITS((int)0, (int)(smt_bits - 1));
    716   1.1        ad 
    717   1.1        ad 		ci->ci_smtid = __SHIFTOUT(ci->ci_initapicid, smt_mask);
    718   1.1        ad 		aprint_verbose("%s: SMT ID %u\n", cpuname, ci->ci_smtid);
    719   1.1        ad 	}
    720   1.1        ad }
    721   1.1        ad 
    722   1.1        ad static void
    723   1.1        ad via_cpu_probe(struct cpu_info *ci)
    724   1.1        ad {
    725   1.1        ad 	u_int model = CPUID2MODEL(ci->ci_signature);
    726   1.1        ad 	u_int stepping = CPUID2STEPPING(ci->ci_signature);
    727   1.1        ad 	u_int descs[4];
    728   1.1        ad 	u_int lfunc;
    729   1.1        ad 
    730   1.1        ad 	/*
    731   1.1        ad 	 * Determine the largest extended function value.
    732   1.1        ad 	 */
    733   1.1        ad 	x86_cpuid(0x80000000, descs);
    734   1.1        ad 	lfunc = descs[0];
    735   1.1        ad 
    736   1.1        ad 	/*
    737   1.1        ad 	 * Determine the extended feature flags.
    738   1.1        ad 	 */
    739   1.1        ad 	if (lfunc >= 0x80000001) {
    740   1.1        ad 		x86_cpuid(0x80000001, descs);
    741  1.18  pgoyette 		ci->ci_feat_val[2] |= descs[3];
    742   1.1        ad 	}
    743   1.1        ad 
    744   1.1        ad 	if (model < 0x9)
    745   1.1        ad 		return;
    746   1.1        ad 
    747   1.1        ad 	/* Nehemiah or Esther */
    748   1.1        ad 	x86_cpuid(0xc0000000, descs);
    749   1.1        ad 	lfunc = descs[0];
    750   1.1        ad 	if (lfunc < 0xc0000001)	/* no ACE, no RNG */
    751   1.1        ad 		return;
    752   1.1        ad 
    753   1.1        ad 	x86_cpuid(0xc0000001, descs);
    754   1.1        ad 	lfunc = descs[3];
    755   1.1        ad 	if (model > 0x9 || stepping >= 8) {	/* ACE */
    756   1.1        ad 		if (lfunc & CPUID_VIA_HAS_ACE) {
    757  1.18  pgoyette 			ci->ci_feat_val[4] = lfunc;
    758   1.1        ad 		}
    759   1.1        ad 	}
    760   1.1        ad }
    761   1.1        ad 
    762   1.1        ad static const char *
    763   1.1        ad intel_family6_name(struct cpu_info *ci)
    764   1.1        ad {
    765   1.1        ad 	int model = CPUID2MODEL(ci->ci_signature);
    766   1.1        ad 	const char *ret = NULL;
    767   1.1        ad 	u_int l2cache = ci->ci_cinfo[CAI_L2CACHE].cai_totalsize;
    768   1.1        ad 
    769   1.1        ad 	if (model == 5) {
    770   1.1        ad 		switch (l2cache) {
    771   1.1        ad 		case 0:
    772   1.1        ad 		case 128 * 1024:
    773   1.1        ad 			ret = "Celeron (Covington)";
    774   1.1        ad 			break;
    775   1.1        ad 		case 256 * 1024:
    776   1.1        ad 			ret = "Mobile Pentium II (Dixon)";
    777   1.1        ad 			break;
    778   1.1        ad 		case 512 * 1024:
    779   1.1        ad 			ret = "Pentium II";
    780   1.1        ad 			break;
    781   1.1        ad 		case 1 * 1024 * 1024:
    782   1.1        ad 		case 2 * 1024 * 1024:
    783   1.1        ad 			ret = "Pentium II Xeon";
    784   1.1        ad 			break;
    785   1.1        ad 		}
    786   1.1        ad 	} else if (model == 6) {
    787   1.1        ad 		switch (l2cache) {
    788   1.1        ad 		case 256 * 1024:
    789   1.1        ad 		case 512 * 1024:
    790   1.1        ad 			ret = "Mobile Pentium II";
    791   1.1        ad 			break;
    792   1.1        ad 		}
    793   1.1        ad 	} else if (model == 7) {
    794   1.1        ad 		switch (l2cache) {
    795   1.1        ad 		case 512 * 1024:
    796   1.1        ad 			ret = "Pentium III";
    797   1.1        ad 			break;
    798   1.1        ad 		case 1 * 1024 * 1024:
    799   1.1        ad 		case 2 * 1024 * 1024:
    800   1.1        ad 			ret = "Pentium III Xeon";
    801   1.1        ad 			break;
    802   1.1        ad 		}
    803   1.1        ad 	} else if (model >= 8) {
    804   1.1        ad 		if (ci->ci_brand_id && ci->ci_brand_id < 0x10) {
    805   1.1        ad 			switch (ci->ci_brand_id) {
    806   1.1        ad 			case 0x3:
    807   1.1        ad 				if (ci->ci_signature == 0x6B1)
    808   1.1        ad 					ret = "Celeron";
    809   1.1        ad 				break;
    810   1.1        ad 			case 0x8:
    811   1.1        ad 				if (ci->ci_signature >= 0xF13)
    812   1.1        ad 					ret = "genuine processor";
    813   1.1        ad 				break;
    814   1.1        ad 			case 0xB:
    815   1.1        ad 				if (ci->ci_signature >= 0xF13)
    816   1.1        ad 					ret = "Xeon MP";
    817   1.1        ad 				break;
    818   1.1        ad 			case 0xE:
    819   1.1        ad 				if (ci->ci_signature < 0xF13)
    820   1.1        ad 					ret = "Xeon";
    821   1.1        ad 				break;
    822   1.1        ad 			}
    823   1.1        ad 			if (ret == NULL)
    824   1.1        ad 				ret = i386_intel_brand[ci->ci_brand_id];
    825   1.1        ad 		}
    826   1.1        ad 	}
    827   1.1        ad 
    828   1.1        ad 	return ret;
    829   1.1        ad }
    830   1.1        ad 
    831   1.1        ad /*
    832   1.1        ad  * Identify AMD64 CPU names from cpuid.
    833   1.1        ad  *
    834   1.1        ad  * Based on:
    835   1.1        ad  * "Revision Guide for AMD Athlon 64 and AMD Opteron Processors"
    836   1.1        ad  * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25759.pdf
    837   1.1        ad  * "Revision Guide for AMD NPT Family 0Fh Processors"
    838   1.1        ad  * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/33610.pdf
    839   1.1        ad  * and other miscellaneous reports.
    840   1.1        ad  */
    841   1.1        ad static const char *
    842   1.1        ad amd_amd64_name(struct cpu_info *ci)
    843   1.1        ad {
    844   1.1        ad 	int extfamily, extmodel, model;
    845   1.1        ad 	const char *ret = NULL;
    846   1.1        ad 
    847   1.1        ad 	model = CPUID2MODEL(ci->ci_signature);
    848   1.1        ad 	extfamily = CPUID2EXTFAMILY(ci->ci_signature);
    849   1.1        ad 	extmodel  = CPUID2EXTMODEL(ci->ci_signature);
    850   1.1        ad 
    851   1.7  christos 	switch (extfamily) {
    852   1.7  christos 	case 0x00:
    853   1.1        ad 		switch (model) {
    854   1.1        ad 		case 0x1:
    855   1.1        ad 			switch (extmodel) {
    856   1.1        ad 			case 0x2:	/* rev JH-E1/E6 */
    857   1.1        ad 			case 0x4:	/* rev JH-F2 */
    858   1.1        ad 				ret = "Dual-Core Opteron";
    859   1.1        ad 				break;
    860   1.1        ad 			}
    861   1.1        ad 			break;
    862   1.1        ad 		case 0x3:
    863   1.1        ad 			switch (extmodel) {
    864   1.1        ad 			case 0x2:	/* rev JH-E6 (Toledo) */
    865   1.1        ad 				ret = "Dual-Core Opteron or Athlon 64 X2";
    866   1.1        ad 				break;
    867   1.1        ad 			case 0x4:	/* rev JH-F2 (Windsor) */
    868   1.1        ad 				ret = "Athlon 64 FX or Athlon 64 X2";
    869   1.1        ad 				break;
    870   1.1        ad 			}
    871   1.1        ad 			break;
    872   1.1        ad 		case 0x4:
    873   1.1        ad 			switch (extmodel) {
    874   1.1        ad 			case 0x0:	/* rev SH-B0/C0/CG (ClawHammer) */
    875   1.1        ad 			case 0x1:	/* rev SH-D0 */
    876   1.1        ad 				ret = "Athlon 64";
    877   1.1        ad 				break;
    878   1.1        ad 			case 0x2:	/* rev SH-E5 (Lancaster?) */
    879   1.1        ad 				ret = "Mobile Athlon 64 or Turion 64";
    880   1.1        ad 				break;
    881   1.1        ad 			}
    882   1.1        ad 			break;
    883   1.1        ad 		case 0x5:
    884   1.1        ad 			switch (extmodel) {
    885   1.1        ad 			case 0x0:	/* rev SH-B0/B3/C0/CG (SledgeHammer?) */
    886   1.1        ad 				ret = "Opteron or Athlon 64 FX";
    887   1.1        ad 				break;
    888   1.1        ad 			case 0x1:	/* rev SH-D0 */
    889   1.1        ad 			case 0x2:	/* rev SH-E4 */
    890   1.1        ad 				ret = "Opteron";
    891   1.1        ad 				break;
    892   1.1        ad 			}
    893   1.1        ad 			break;
    894   1.1        ad 		case 0x7:
    895   1.1        ad 			switch (extmodel) {
    896   1.1        ad 			case 0x0:	/* rev SH-CG (ClawHammer) */
    897   1.1        ad 			case 0x1:	/* rev SH-D0 */
    898   1.1        ad 				ret = "Athlon 64";
    899   1.1        ad 				break;
    900   1.1        ad 			case 0x2:	/* rev DH-E4, SH-E4 */
    901   1.1        ad 				ret = "Athlon 64 or Athlon 64 FX or Opteron";
    902   1.1        ad 				break;
    903   1.1        ad 			}
    904   1.1        ad 			break;
    905   1.1        ad 		case 0x8:
    906   1.1        ad 			switch (extmodel) {
    907   1.1        ad 			case 0x0:	/* rev CH-CG */
    908   1.1        ad 			case 0x1:	/* rev CH-D0 */
    909   1.1        ad 				ret = "Athlon 64 or Sempron";
    910   1.1        ad 				break;
    911   1.1        ad 			case 0x4:	/* rev BH-F2 */
    912   1.1        ad 				ret = "Turion 64 X2";
    913   1.1        ad 				break;
    914   1.1        ad 			}
    915   1.1        ad 			break;
    916   1.1        ad 		case 0xb:
    917   1.1        ad 			switch (extmodel) {
    918   1.1        ad 			case 0x0:	/* rev CH-CG */
    919   1.1        ad 			case 0x1:	/* rev CH-D0 */
    920   1.1        ad 				ret = "Athlon 64";
    921   1.1        ad 				break;
    922   1.1        ad 			case 0x2:	/* rev BH-E4 (Manchester) */
    923   1.1        ad 			case 0x4:	/* rev BH-F2 (Windsor) */
    924   1.1        ad 				ret = "Athlon 64 X2";
    925   1.1        ad 				break;
    926   1.1        ad 			case 0x6:	/* rev BH-G1 (Brisbane) */
    927   1.1        ad 				ret = "Athlon X2 or Athlon 64 X2";
    928   1.1        ad 				break;
    929   1.1        ad 			}
    930   1.1        ad 			break;
    931   1.1        ad 		case 0xc:
    932   1.1        ad 			switch (extmodel) {
    933   1.1        ad 			case 0x0:	/* rev DH-CG (Newcastle) */
    934   1.1        ad 			case 0x1:	/* rev DH-D0 (Winchester) */
    935   1.1        ad 			case 0x2:	/* rev DH-E3/E6 */
    936   1.1        ad 				ret = "Athlon 64 or Sempron";
    937   1.1        ad 				break;
    938   1.1        ad 			}
    939   1.1        ad 			break;
    940   1.1        ad 		case 0xe:
    941   1.1        ad 			switch (extmodel) {
    942   1.1        ad 			case 0x0:	/* rev DH-CG (Newcastle?) */
    943   1.1        ad 				ret = "Athlon 64 or Sempron";
    944   1.1        ad 				break;
    945   1.1        ad 			}
    946   1.1        ad 			break;
    947   1.1        ad 		case 0xf:
    948   1.1        ad 			switch (extmodel) {
    949   1.1        ad 			case 0x0:	/* rev DH-CG (Newcastle/Paris) */
    950   1.1        ad 			case 0x1:	/* rev DH-D0 (Winchester/Victoria) */
    951   1.1        ad 			case 0x2:	/* rev DH-E3/E6 (Venice/Palermo) */
    952   1.1        ad 			case 0x4:	/* rev DH-F2 (Orleans/Manila) */
    953   1.1        ad 			case 0x5:	/* rev DH-F2 (Orleans/Manila) */
    954   1.1        ad 			case 0x6:	/* rev DH-G1 */
    955   1.1        ad 				ret = "Athlon 64 or Sempron";
    956   1.1        ad 				break;
    957   1.1        ad 			}
    958   1.1        ad 			break;
    959   1.1        ad 		default:
    960   1.1        ad 			ret = "Unknown AMD64 CPU";
    961   1.1        ad 		}
    962   1.7  christos 		break;
    963   1.7  christos 	case 0x01:
    964   1.7  christos 		switch (model) {
    965   1.7  christos 			case 0x02:
    966   1.7  christos 				ret = "Family 10h";
    967   1.7  christos 				break;
    968   1.7  christos 			default:
    969   1.7  christos 				ret = "Unknown AMD64 CPU";
    970   1.7  christos 				break;
    971   1.7  christos 		}
    972   1.7  christos 		break;
    973   1.1        ad 	}
    974   1.1        ad 
    975   1.1        ad 	return ret;
    976   1.1        ad }
    977   1.1        ad 
    978   1.1        ad static void
    979   1.1        ad cpu_probe_base_features(struct cpu_info *ci)
    980   1.1        ad {
    981   1.1        ad 	const struct x86_cache_info *cai;
    982   1.1        ad 	u_int descs[4];
    983   1.1        ad 	int iterations, i, j;
    984   1.1        ad 	uint8_t desc;
    985   1.1        ad 	uint32_t miscbytes;
    986   1.1        ad 	uint32_t brand[12];
    987   1.1        ad 
    988   1.1        ad 	if (ci->ci_cpuid_level < 0)
    989   1.1        ad 		return;
    990   1.1        ad 
    991   1.1        ad 	x86_cpuid(0, descs);
    992   1.1        ad 	ci->ci_cpuid_level = descs[0];
    993   1.1        ad 	ci->ci_vendor[0] = descs[1];
    994   1.1        ad 	ci->ci_vendor[2] = descs[2];
    995   1.1        ad 	ci->ci_vendor[1] = descs[3];
    996   1.1        ad 	ci->ci_vendor[3] = 0;
    997   1.1        ad 
    998   1.1        ad 	x86_cpuid(0x80000000, brand);
    999   1.1        ad 	if (brand[0] >= 0x80000004) {
   1000   1.1        ad 		x86_cpuid(0x80000002, brand);
   1001   1.1        ad 		x86_cpuid(0x80000003, brand + 4);
   1002   1.1        ad 		x86_cpuid(0x80000004, brand + 8);
   1003   1.1        ad 		for (i = 0; i < 48; i++)
   1004   1.1        ad 			if (((char *) brand)[i] != ' ')
   1005   1.1        ad 				break;
   1006   1.1        ad 		memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i);
   1007   1.1        ad 	}
   1008   1.1        ad 
   1009   1.1        ad 	if (ci->ci_cpuid_level < 1)
   1010   1.1        ad 		return;
   1011   1.1        ad 
   1012   1.1        ad 	x86_cpuid(1, descs);
   1013   1.1        ad 	ci->ci_signature = descs[0];
   1014   1.1        ad 	miscbytes = descs[1];
   1015  1.18  pgoyette 	ci->ci_feat_val[1] = descs[2];
   1016  1.18  pgoyette 	ci->ci_feat_val[0] = descs[3];
   1017   1.1        ad 
   1018   1.1        ad 	/* Brand is low order 8 bits of ebx */
   1019   1.1        ad 	ci->ci_brand_id = miscbytes & 0xff;
   1020   1.1        ad 	ci->ci_initapicid = (miscbytes >> 24) & 0xff;
   1021   1.1        ad 	if (ci->ci_cpuid_level < 2)
   1022   1.1        ad 		return;
   1023   1.1        ad 
   1024   1.1        ad 	/*
   1025   1.1        ad 	 * Parse the cache info from `cpuid', if we have it.
   1026   1.1        ad 	 * XXX This is kinda ugly, but hey, so is the architecture...
   1027   1.1        ad 	 */
   1028   1.1        ad 
   1029   1.1        ad 	x86_cpuid(2, descs);
   1030   1.1        ad 
   1031   1.1        ad 	iterations = descs[0] & 0xff;
   1032   1.1        ad 	while (iterations-- > 0) {
   1033   1.1        ad 		for (i = 0; i < 4; i++) {
   1034   1.1        ad 			if (descs[i] & 0x80000000)
   1035   1.1        ad 				continue;
   1036   1.1        ad 			for (j = 0; j < 4; j++) {
   1037   1.1        ad 				if (i == 0 && j == 0)
   1038   1.1        ad 					continue;
   1039   1.1        ad 				desc = (descs[i] >> (j * 8)) & 0xff;
   1040   1.1        ad 				if (desc == 0)
   1041   1.1        ad 					continue;
   1042   1.1        ad 				cai = cache_info_lookup(intel_cpuid_cache_info,
   1043   1.1        ad 				    desc);
   1044   1.1        ad 				if (cai != NULL)
   1045   1.1        ad 					ci->ci_cinfo[cai->cai_index] = *cai;
   1046   1.1        ad 			}
   1047   1.1        ad 		}
   1048   1.1        ad 		x86_cpuid(2, descs);
   1049   1.1        ad 	}
   1050   1.1        ad 
   1051   1.1        ad 	if (ci->ci_cpuid_level < 3)
   1052   1.1        ad 		return;
   1053   1.1        ad 
   1054   1.1        ad 	/*
   1055   1.1        ad 	 * If the processor serial number misfeature is present and supported,
   1056   1.1        ad 	 * extract it here.
   1057   1.1        ad 	 */
   1058  1.18  pgoyette 	if ((ci->ci_feat_val[0] & CPUID_PN) != 0) {
   1059   1.1        ad 		ci->ci_cpu_serial[0] = ci->ci_signature;
   1060   1.1        ad 		x86_cpuid(3, descs);
   1061   1.1        ad 		ci->ci_cpu_serial[2] = descs[2];
   1062   1.1        ad 		ci->ci_cpu_serial[1] = descs[3];
   1063   1.1        ad 	}
   1064   1.1        ad }
   1065   1.1        ad 
   1066   1.1        ad static void
   1067   1.1        ad cpu_probe_features(struct cpu_info *ci)
   1068   1.1        ad {
   1069   1.1        ad 	const struct cpu_cpuid_nameclass *cpup = NULL;
   1070   1.1        ad 	int i, xmax, family;
   1071   1.1        ad 
   1072   1.1        ad 	cpu_probe_base_features(ci);
   1073   1.1        ad 
   1074   1.1        ad 	if (ci->ci_cpuid_level < 1)
   1075   1.1        ad 		return;
   1076   1.1        ad 
   1077   1.3     chris 	xmax = __arraycount(i386_cpuid_cpus);
   1078   1.1        ad 	for (i = 0; i < xmax; i++) {
   1079   1.1        ad 		if (!strncmp((char *)ci->ci_vendor,
   1080   1.1        ad 		    i386_cpuid_cpus[i].cpu_id, 12)) {
   1081   1.1        ad 			cpup = &i386_cpuid_cpus[i];
   1082   1.1        ad 			break;
   1083   1.1        ad 		}
   1084   1.1        ad 	}
   1085   1.1        ad 
   1086   1.1        ad 	if (cpup == NULL)
   1087   1.1        ad 		return;
   1088   1.1        ad 
   1089   1.1        ad 	family = (ci->ci_signature >> 8) & 0xf;
   1090   1.1        ad 
   1091   1.1        ad 	if (family > CPU_MAXFAMILY) {
   1092   1.1        ad 		family = CPU_MAXFAMILY;
   1093   1.1        ad 	}
   1094   1.1        ad 	i = family - CPU_MINFAMILY;
   1095   1.1        ad 
   1096   1.1        ad 	if (cpup->cpu_family[i].cpu_probe == NULL)
   1097   1.1        ad 		return;
   1098   1.1        ad 
   1099   1.1        ad 	(*cpup->cpu_family[i].cpu_probe)(ci);
   1100   1.1        ad }
   1101   1.1        ad 
   1102   1.1        ad static void
   1103   1.1        ad intel_family_new_probe(struct cpu_info *ci)
   1104   1.1        ad {
   1105   1.1        ad 	uint32_t descs[4];
   1106   1.1        ad 
   1107   1.1        ad 	x86_cpuid(0x80000000, descs);
   1108   1.1        ad 
   1109   1.1        ad 	/*
   1110   1.1        ad 	 * Determine extended feature flags.
   1111   1.1        ad 	 */
   1112   1.1        ad 	if (descs[0] >= 0x80000001) {
   1113   1.1        ad 		x86_cpuid(0x80000001, descs);
   1114  1.18  pgoyette 		ci->ci_feat_val[2] |= descs[3];
   1115  1.18  pgoyette 		ci->ci_feat_val[3] |= descs[2];
   1116   1.1        ad 	}
   1117   1.1        ad }
   1118   1.1        ad 
   1119   1.1        ad static void
   1120   1.1        ad amd_family6_probe(struct cpu_info *ci)
   1121   1.1        ad {
   1122   1.1        ad 	uint32_t descs[4];
   1123   1.1        ad 	char *p;
   1124  1.17  christos 	size_t i;
   1125   1.1        ad 
   1126   1.1        ad 	x86_cpuid(0x80000000, descs);
   1127   1.1        ad 
   1128   1.1        ad 	/*
   1129   1.1        ad 	 * Determine the extended feature flags.
   1130   1.1        ad 	 */
   1131   1.1        ad 	if (descs[0] >= 0x80000001) {
   1132   1.1        ad 		x86_cpuid(0x80000001, descs);
   1133  1.18  pgoyette 		ci->ci_feat_val[2] |= descs[3]; /* %edx */
   1134  1.18  pgoyette 		ci->ci_feat_val[3] = descs[2]; /* %ecx */
   1135   1.1        ad 	}
   1136   1.1        ad 
   1137   1.1        ad 	if (*cpu_brand_string == '\0')
   1138   1.1        ad 		return;
   1139   1.1        ad 
   1140   1.3     chris 	for (i = 1; i < __arraycount(amd_brand); i++)
   1141   1.1        ad 		if ((p = strstr(cpu_brand_string, amd_brand[i])) != NULL) {
   1142   1.1        ad 			ci->ci_brand_id = i;
   1143   1.1        ad 			strlcpy(amd_brand_name, p, sizeof(amd_brand_name));
   1144   1.1        ad 			break;
   1145   1.1        ad 		}
   1146   1.1        ad }
   1147   1.1        ad 
   1148   1.1        ad static void
   1149   1.1        ad amd_family5_setup(struct cpu_info *ci)
   1150   1.1        ad {
   1151   1.1        ad 
   1152   1.1        ad 	switch (CPUID2MODEL(ci->ci_signature)) {
   1153   1.1        ad 	case 0:		/* AMD-K5 Model 0 */
   1154   1.1        ad 		/*
   1155   1.1        ad 		 * According to the AMD Processor Recognition App Note,
   1156   1.1        ad 		 * the AMD-K5 Model 0 uses the wrong bit to indicate
   1157   1.1        ad 		 * support for global PTEs, instead using bit 9 (APIC)
   1158   1.1        ad 		 * rather than bit 13 (i.e. "0x200" vs. 0x2000".  Oops!).
   1159   1.1        ad 		 */
   1160  1.18  pgoyette 		if (ci->ci_feat_val[0] & CPUID_APIC)
   1161  1.18  pgoyette 			ci->ci_feat_val[0] =
   1162  1.18  pgoyette 			    (ci->ci_feat_val[0] & ~CPUID_APIC) | CPUID_PGE;
   1163   1.1        ad 		/*
   1164   1.1        ad 		 * XXX But pmap_pg_g is already initialized -- need to kick
   1165   1.1        ad 		 * XXX the pmap somehow.  How does the MP branch do this?
   1166   1.1        ad 		 */
   1167   1.1        ad 		break;
   1168   1.1        ad 	}
   1169   1.1        ad }
   1170   1.1        ad 
   1171   1.1        ad static void
   1172   1.1        ad tmx86_get_longrun_status(u_int *frequency, u_int *voltage, u_int *percentage)
   1173   1.1        ad {
   1174   1.1        ad 	u_int descs[4];
   1175   1.1        ad 
   1176   1.1        ad 	x86_cpuid(0x80860007, descs);
   1177   1.1        ad 	*frequency = descs[0];
   1178   1.1        ad 	*voltage = descs[1];
   1179   1.1        ad 	*percentage = descs[2];
   1180   1.1        ad }
   1181   1.1        ad 
   1182   1.1        ad static void
   1183   1.1        ad transmeta_cpu_info(struct cpu_info *ci)
   1184   1.1        ad {
   1185   1.1        ad 	u_int descs[4], nreg;
   1186   1.1        ad 	u_int frequency, voltage, percentage;
   1187   1.1        ad 
   1188   1.1        ad 	x86_cpuid(0x80860000, descs);
   1189   1.1        ad 	nreg = descs[0];
   1190   1.1        ad 	if (nreg >= 0x80860001) {
   1191   1.1        ad 		x86_cpuid(0x80860001, descs);
   1192   1.1        ad 		aprint_verbose_dev(ci->ci_dev, "Processor revision %u.%u.%u.%u\n",
   1193   1.1        ad 		    (descs[1] >> 24) & 0xff,
   1194   1.1        ad 		    (descs[1] >> 16) & 0xff,
   1195   1.1        ad 		    (descs[1] >> 8) & 0xff,
   1196   1.1        ad 		    descs[1] & 0xff);
   1197   1.1        ad 	}
   1198   1.1        ad 	if (nreg >= 0x80860002) {
   1199   1.1        ad 		x86_cpuid(0x80860002, descs);
   1200   1.1        ad 		aprint_verbose_dev(ci->ci_dev, "Code Morphing Software Rev: %u.%u.%u-%u-%u\n",
   1201   1.1        ad 		    (descs[1] >> 24) & 0xff,
   1202   1.1        ad 		    (descs[1] >> 16) & 0xff,
   1203   1.1        ad 		    (descs[1] >> 8) & 0xff,
   1204   1.1        ad 		    descs[1] & 0xff,
   1205   1.1        ad 		    descs[2]);
   1206   1.1        ad 	}
   1207   1.1        ad 	if (nreg >= 0x80860006) {
   1208   1.1        ad 		union {
   1209   1.1        ad 			char text[65];
   1210   1.1        ad 			u_int descs[4][4];
   1211   1.1        ad 		} info;
   1212   1.1        ad 		int i;
   1213   1.1        ad 
   1214   1.1        ad 		for (i=0; i<4; i++) {
   1215   1.1        ad 			x86_cpuid(0x80860003 + i, info.descs[i]);
   1216   1.1        ad 		}
   1217   1.1        ad 		info.text[64] = '\0';
   1218   1.1        ad 		aprint_verbose_dev(ci->ci_dev, "%s\n", info.text);
   1219   1.1        ad 	}
   1220   1.1        ad 
   1221   1.1        ad 	if (nreg >= 0x80860007) {
   1222   1.1        ad 		tmx86_get_longrun_status(&frequency,
   1223   1.1        ad 		    &voltage, &percentage);
   1224   1.1        ad 		aprint_verbose_dev(ci->ci_dev, "LongRun <%dMHz %dmV %d%%>\n",
   1225   1.1        ad 		    frequency, voltage, percentage);
   1226   1.1        ad 	}
   1227   1.1        ad }
   1228   1.1        ad 
   1229   1.1        ad void
   1230   1.1        ad identifycpu(const char *cpuname)
   1231   1.1        ad {
   1232  1.18  pgoyette 	const char *name = "", *modifier, *vendorname, *brand = "";
   1233   1.1        ad 	int class = CPUCLASS_386, i, xmax;
   1234  1.18  pgoyette 	int modif, family, model, ext_model;
   1235  1.18  pgoyette 	const struct cpu_extend_nameclass *modlist;
   1236   1.1        ad 	const struct cpu_cpuid_nameclass *cpup = NULL;
   1237   1.1        ad 	const struct cpu_cpuid_family *cpufam;
   1238  1.12    cegger 	const char *feature_str[5];
   1239   1.1        ad 	struct cpu_info *ci, cistore;
   1240   1.1        ad 	extern int cpu;
   1241   1.1        ad 	extern int cpu_info_level;
   1242   1.1        ad 	size_t sz;
   1243  1.18  pgoyette 	char buf[512];
   1244  1.18  pgoyette 	char *bp;
   1245   1.1        ad 
   1246   1.1        ad 	ci = &cistore;
   1247   1.1        ad 	memset(ci, 0, sizeof(*ci));
   1248   1.1        ad 	ci->ci_dev = cpuname;
   1249   1.1        ad 
   1250   1.1        ad 	x86_identify();
   1251   1.1        ad 	ci->ci_cpuid_level = cpu_info_level;
   1252   1.1        ad 	cpu_probe_features(ci);
   1253   1.1        ad 
   1254   1.1        ad 	if (ci->ci_cpuid_level == -1) {
   1255  1.17  christos 		if ((size_t)cpu >= __arraycount(i386_nocpuid_cpus))
   1256   1.1        ad 			errx(1, "unknown cpu type %d", cpu);
   1257   1.1        ad 		name = i386_nocpuid_cpus[cpu].cpu_name;
   1258   1.1        ad 		cpu_vendor = i386_nocpuid_cpus[cpu].cpu_vendor;
   1259   1.1        ad 		vendorname = i386_nocpuid_cpus[cpu].cpu_vendorname;
   1260   1.1        ad 		class = i386_nocpuid_cpus[cpu].cpu_class;
   1261   1.1        ad 		ci->ci_info = i386_nocpuid_cpus[cpu].cpu_info;
   1262   1.1        ad 		modifier = "";
   1263   1.1        ad 	} else {
   1264   1.1        ad 		xmax = __arraycount(i386_cpuid_cpus);
   1265   1.1        ad 		modif = (ci->ci_signature >> 12) & 0x3;
   1266   1.1        ad 		family = CPUID2FAMILY(ci->ci_signature);
   1267   1.1        ad 		if (family < CPU_MINFAMILY)
   1268   1.1        ad 			errx(1, "identifycpu: strange family value");
   1269   1.1        ad 		model = CPUID2MODEL(ci->ci_signature);
   1270  1.18  pgoyette 		ext_model = CPUID2EXTMODEL(ci->ci_signature);
   1271   1.1        ad 
   1272   1.1        ad 		for (i = 0; i < xmax; i++) {
   1273   1.1        ad 			if (!strncmp((char *)ci->ci_vendor,
   1274   1.1        ad 			    i386_cpuid_cpus[i].cpu_id, 12)) {
   1275   1.1        ad 				cpup = &i386_cpuid_cpus[i];
   1276   1.1        ad 				break;
   1277   1.1        ad 			}
   1278   1.1        ad 		}
   1279   1.1        ad 
   1280   1.1        ad 		if (cpup == NULL) {
   1281   1.1        ad 			cpu_vendor = CPUVENDOR_UNKNOWN;
   1282   1.1        ad 			if (ci->ci_vendor[0] != '\0')
   1283   1.1        ad 				vendorname = (char *)&ci->ci_vendor[0];
   1284   1.1        ad 			else
   1285   1.1        ad 				vendorname = "Unknown";
   1286   1.1        ad 			if (family >= CPU_MAXFAMILY)
   1287   1.1        ad 				family = CPU_MINFAMILY;
   1288   1.1        ad 			class = family - 3;
   1289   1.1        ad 			modifier = "";
   1290   1.1        ad 			name = "";
   1291   1.1        ad 			ci->ci_info = NULL;
   1292   1.1        ad 		} else {
   1293   1.1        ad 			cpu_vendor = cpup->cpu_vendor;
   1294   1.1        ad 			vendorname = cpup->cpu_vendorname;
   1295   1.1        ad 			modifier = modifiers[modif];
   1296   1.1        ad 			if (family > CPU_MAXFAMILY) {
   1297   1.1        ad 				family = CPU_MAXFAMILY;
   1298   1.1        ad 				model = CPU_DEFMODEL;
   1299  1.18  pgoyette 			} else if (model > CPU_MAXMODEL) {
   1300   1.1        ad 				model = CPU_DEFMODEL;
   1301  1.18  pgoyette 				ext_model = 0;
   1302  1.18  pgoyette 			}
   1303   1.1        ad 			cpufam = &cpup->cpu_family[family - CPU_MINFAMILY];
   1304  1.18  pgoyette 			if (cpufam->cpu_extended_names == NULL ||
   1305  1.18  pgoyette 			    ext_model == 0)
   1306  1.18  pgoyette 				name = cpufam->cpu_models[model];
   1307  1.18  pgoyette 			else {
   1308  1.18  pgoyette 				/*
   1309  1.18  pgoyette 				 * Scan list(s) of extended model names
   1310  1.18  pgoyette 				 */
   1311  1.18  pgoyette 				modlist = cpufam->cpu_extended_names;
   1312  1.18  pgoyette 				while (modlist->ext_model != 0) {
   1313  1.18  pgoyette 					if (modlist->ext_model == ext_model) {
   1314  1.18  pgoyette 						name =
   1315  1.18  pgoyette 						     modlist->cpu_models[model];
   1316  1.18  pgoyette 						break;
   1317  1.18  pgoyette 					}
   1318  1.18  pgoyette 					modlist++;
   1319  1.18  pgoyette 				}
   1320  1.18  pgoyette 			}
   1321  1.18  pgoyette 			if (name == NULL || *name == '\0')
   1322   1.1        ad 			    name = cpufam->cpu_models[CPU_DEFMODEL];
   1323   1.1        ad 			class = cpufam->cpu_class;
   1324   1.1        ad 			ci->ci_info = cpufam->cpu_info;
   1325   1.1        ad 
   1326   1.1        ad 			if (cpu_vendor == CPUVENDOR_INTEL) {
   1327   1.1        ad 				if (family == 6 && model >= 5) {
   1328   1.1        ad 					const char *tmp;
   1329   1.1        ad 					tmp = intel_family6_name(ci);
   1330   1.1        ad 					if (tmp != NULL)
   1331   1.1        ad 						name = tmp;
   1332   1.1        ad 				}
   1333   1.1        ad 				if (family == CPU_MAXFAMILY &&
   1334   1.1        ad 				    ci->ci_brand_id <
   1335   1.1        ad 				    __arraycount(i386_intel_brand) &&
   1336   1.1        ad 				    i386_intel_brand[ci->ci_brand_id])
   1337   1.1        ad 					name =
   1338   1.1        ad 					     i386_intel_brand[ci->ci_brand_id];
   1339   1.1        ad 			}
   1340   1.1        ad 
   1341   1.1        ad 			if (cpu_vendor == CPUVENDOR_AMD) {
   1342   1.1        ad 				if (family == 6 && model >= 6) {
   1343   1.1        ad 					if (ci->ci_brand_id == 1)
   1344   1.1        ad 						/*
   1345   1.1        ad 						 * It's Duron. We override the
   1346   1.1        ad 						 * name, since it might have
   1347   1.1        ad 						 * been misidentified as Athlon.
   1348   1.1        ad 						 */
   1349   1.1        ad 						name =
   1350   1.1        ad 						    amd_brand[ci->ci_brand_id];
   1351   1.1        ad 					else
   1352   1.1        ad 						brand = amd_brand_name;
   1353   1.1        ad 				}
   1354   1.1        ad 				if (CPUID2FAMILY(ci->ci_signature) == 0xf) {
   1355   1.1        ad 					/*
   1356   1.1        ad 					 * Identify AMD64 CPU names.
   1357   1.1        ad 					 * Note family value is clipped by
   1358   1.1        ad 					 * CPU_MAXFAMILY.
   1359   1.1        ad 					 */
   1360   1.1        ad 					const char *tmp;
   1361   1.1        ad 					tmp = amd_amd64_name(ci);
   1362   1.1        ad 					if (tmp != NULL)
   1363   1.1        ad 						name = tmp;
   1364   1.1        ad 				}
   1365   1.1        ad 			}
   1366   1.1        ad 
   1367   1.1        ad 			if (cpu_vendor == CPUVENDOR_IDT && family >= 6)
   1368   1.1        ad 				vendorname = "VIA";
   1369   1.1        ad 		}
   1370   1.1        ad 	}
   1371   1.1        ad 
   1372   1.1        ad 	ci->ci_cpu_class = class;
   1373   1.1        ad 
   1374   1.1        ad 	sz = sizeof(ci->ci_tsc_freq);
   1375   1.1        ad 	(void)sysctlbyname("machdep.tsc_freq", &ci->ci_tsc_freq, &sz, NULL, 0);
   1376   1.1        ad 
   1377   1.1        ad 	snprintf(cpu_model, sizeof(cpu_model), "%s%s%s%s%s%s%s (%s-class)",
   1378   1.1        ad 	    vendorname,
   1379   1.1        ad 	    *modifier ? " " : "", modifier,
   1380   1.1        ad 	    *name ? " " : "", name,
   1381   1.1        ad 	    *brand ? " " : "", brand,
   1382   1.1        ad 	    classnames[class]);
   1383   1.1        ad 	aprint_normal("%s: %s", cpuname, cpu_model);
   1384   1.1        ad 
   1385   1.1        ad 	if (ci->ci_tsc_freq != 0)
   1386   1.1        ad 		aprint_normal(", %qd.%02qd MHz",
   1387   1.1        ad 		    (ci->ci_tsc_freq + 4999) / 1000000,
   1388   1.1        ad 		    ((ci->ci_tsc_freq + 4999) / 10000) % 100);
   1389   1.1        ad 	if (ci->ci_signature != 0)
   1390   1.1        ad 		aprint_normal(", id 0x%x", ci->ci_signature);
   1391   1.1        ad 	aprint_normal("\n");
   1392   1.1        ad 
   1393   1.1        ad 	if (ci->ci_info)
   1394   1.1        ad 		(*ci->ci_info)(ci);
   1395   1.1        ad 
   1396  1.18  pgoyette 	/*
   1397  1.18  pgoyette 	 * display CPU feature flags
   1398  1.18  pgoyette 	 */
   1399  1.18  pgoyette 
   1400  1.18  pgoyette #define	MAX_FEATURE_LEN	60	/* XXX Need to find a better way to set this */
   1401  1.18  pgoyette 
   1402  1.10  pgoyette 	feature_str[0] = CPUID_FLAGS1;
   1403  1.18  pgoyette 	feature_str[1] = CPUID2_FLAGS1;
   1404  1.18  pgoyette 	feature_str[2] = CPUID_EXT_FLAGS;
   1405  1.18  pgoyette 	feature_str[3] = NULL;
   1406  1.18  pgoyette 	feature_str[4] = NULL;
   1407  1.12    cegger 
   1408  1.12    cegger 	switch (cpu_vendor) {
   1409  1.12    cegger 	case CPUVENDOR_AMD:
   1410  1.18  pgoyette 		feature_str[3] = CPUID_AMD_FLAGS4;
   1411  1.12    cegger 		break;
   1412  1.12    cegger 	case CPUVENDOR_INTEL:
   1413  1.18  pgoyette 		feature_str[2] = CPUID_INTEL_EXT_FLAGS;
   1414  1.11    cegger 		feature_str[3] = CPUID_INTEL_FLAGS4;
   1415  1.12    cegger 		break;
   1416  1.18  pgoyette 	case CPUVENDOR_CYRIX:
   1417  1.18  pgoyette 		feature_str[4] = CPUID_FLAGS_PADLOCK;
   1418  1.18  pgoyette 		/* FALLTHRU */
   1419  1.12    cegger 	default:
   1420  1.12    cegger 		break;
   1421  1.12    cegger 	}
   1422   1.1        ad 
   1423  1.18  pgoyette 	for (i = 0; i <= 4; i++) {
   1424  1.18  pgoyette 		if (ci->ci_feat_val[i] && feature_str[i] != NULL) {
   1425  1.18  pgoyette 			snprintb_m(buf, sizeof(buf), feature_str[i],
   1426  1.18  pgoyette 				   ci->ci_feat_val[i], MAX_FEATURE_LEN);
   1427  1.18  pgoyette 			bp = buf;
   1428  1.18  pgoyette 			while (*bp != '\0') {
   1429  1.18  pgoyette 				aprint_verbose("%s: %sfeatures%c %s\n",
   1430  1.18  pgoyette 				    cpuname, (i == 4)?"padlock ":"",
   1431  1.18  pgoyette 				    (i == 4 || i == 0)?' ':'1' + i, bp);
   1432  1.18  pgoyette 				bp += strlen(bp) + 1;
   1433  1.18  pgoyette 			}
   1434   1.1        ad 		}
   1435   1.1        ad 	}
   1436   1.1        ad 
   1437   1.1        ad 	if (*cpu_brand_string != '\0')
   1438   1.1        ad 		aprint_normal("%s: \"%s\"\n", cpuname, cpu_brand_string);
   1439   1.1        ad 
   1440   1.1        ad 	x86_print_cacheinfo(ci);
   1441   1.1        ad 
   1442  1.18  pgoyette 	if (ci->ci_cpuid_level >= 3 && (ci->ci_feat_val[0] & CPUID_PN)) {
   1443   1.1        ad 		aprint_verbose("%s: serial number %04X-%04X-%04X-%04X-%04X-%04X\n",
   1444   1.1        ad 		    cpuname,
   1445   1.1        ad 		    ci->ci_cpu_serial[0] / 65536, ci->ci_cpu_serial[0] % 65536,
   1446   1.1        ad 		    ci->ci_cpu_serial[1] / 65536, ci->ci_cpu_serial[1] % 65536,
   1447   1.1        ad 		    ci->ci_cpu_serial[2] / 65536, ci->ci_cpu_serial[2] % 65536);
   1448   1.1        ad 	}
   1449   1.1        ad 
   1450   1.1        ad 	if (ci->ci_cpu_class == CPUCLASS_386) {
   1451   1.1        ad 		errx(1, "NetBSD requires an 80486 or later processor");
   1452   1.1        ad 	}
   1453   1.1        ad 
   1454   1.1        ad 	if (cpu == CPU_486DLC) {
   1455   1.1        ad #ifndef CYRIX_CACHE_WORKS
   1456   1.1        ad 		aprint_error("WARNING: CYRIX 486DLC CACHE UNCHANGED.\n");
   1457   1.1        ad #else
   1458   1.1        ad #ifndef CYRIX_CACHE_REALLY_WORKS
   1459   1.1        ad 		aprint_error("WARNING: CYRIX 486DLC CACHE ENABLED IN HOLD-FLUSH MODE.\n");
   1460   1.1        ad #else
   1461   1.1        ad 		aprint_error("WARNING: CYRIX 486DLC CACHE ENABLED.\n");
   1462   1.1        ad #endif
   1463   1.1        ad #endif
   1464   1.1        ad 	}
   1465   1.1        ad 
   1466   1.1        ad 	/*
   1467   1.1        ad 	 * Everything past this point requires a Pentium or later.
   1468   1.1        ad 	 */
   1469   1.1        ad 	if (ci->ci_cpuid_level < 0)
   1470   1.1        ad 		return;
   1471   1.1        ad 
   1472   1.1        ad 	identifycpu_cpuids(ci);
   1473   1.1        ad 
   1474   1.1        ad #ifdef INTEL_CORETEMP
   1475   1.1        ad 	if (cpu_vendor == CPUVENDOR_INTEL && ci->ci_cpuid_level >= 0x06)
   1476   1.1        ad 		coretemp_register(ci);
   1477   1.1        ad #endif
   1478   1.1        ad 
   1479   1.5        ad 	if (cpu_vendor == CPUVENDOR_AMD) {
   1480   1.5        ad 		powernow_probe(ci);
   1481  1.15      yamt 
   1482  1.18  pgoyette 		if ((ci->ci_feat_val[3] & CPUID_SVM) != 0) {
   1483  1.15      yamt 			uint32_t data[4];
   1484  1.15      yamt 
   1485  1.15      yamt 			x86_cpuid(0x8000000a, data);
   1486  1.15      yamt 			aprint_verbose("%s: SVM Rev. %d\n", cpuname,
   1487  1.15      yamt 			    data[0] & 0xf);
   1488  1.15      yamt 			aprint_verbose("%s: SVM NASID %d\n", cpuname, data[1]);
   1489  1.15      yamt 			snprintb(buf, sizeof(buf), CPUID_AMD_SVM_FLAGS,
   1490  1.15      yamt 			    data[3]);
   1491  1.15      yamt 			aprint_verbose("%s: SVM features %s\n", cpuname, buf);
   1492  1.15      yamt 		}
   1493   1.1        ad 	}
   1494   1.1        ad 
   1495   1.1        ad #ifdef INTEL_ONDEMAND_CLOCKMOD
   1496   1.1        ad 	clockmod_init();
   1497   1.1        ad #endif
   1498   1.2        ad 
   1499   1.2        ad 	aprint_normal_dev(ci->ci_dev, "family %02x model %02x "
   1500   1.2        ad 	    "extfamily %02x extmodel %02x\n", CPUID2FAMILY(ci->ci_signature),
   1501   1.2        ad 	    CPUID2MODEL(ci->ci_signature), CPUID2EXTFAMILY(ci->ci_signature),
   1502   1.2        ad 	    CPUID2EXTMODEL(ci->ci_signature));
   1503   1.1        ad }
   1504   1.1        ad 
   1505   1.1        ad static const char *
   1506   1.1        ad print_cache_config(struct cpu_info *ci, int cache_tag, const char *name,
   1507   1.1        ad     const char *sep)
   1508   1.1        ad {
   1509   1.1        ad 	struct x86_cache_info *cai = &ci->ci_cinfo[cache_tag];
   1510   1.7  christos 	char human_num[HUMAN_BUFSIZE];
   1511   1.1        ad 
   1512   1.1        ad 	if (cai->cai_totalsize == 0)
   1513   1.1        ad 		return sep;
   1514   1.1        ad 
   1515   1.1        ad 	if (sep == NULL)
   1516   1.1        ad 		aprint_verbose_dev(ci->ci_dev, "");
   1517   1.1        ad 	else
   1518   1.1        ad 		aprint_verbose("%s", sep);
   1519   1.1        ad 	if (name != NULL)
   1520   1.1        ad 		aprint_verbose("%s ", name);
   1521   1.1        ad 
   1522   1.1        ad 	if (cai->cai_string != NULL) {
   1523   1.1        ad 		aprint_verbose("%s ", cai->cai_string);
   1524   1.1        ad 	} else {
   1525   1.8  christos 		(void)humanize_number(human_num, sizeof(human_num),
   1526   1.7  christos 			cai->cai_totalsize, "B", HN_AUTOSCALE, HN_NOSPACE);
   1527   1.7  christos 		aprint_verbose("%s %dB/line ", human_num, cai->cai_linesize);
   1528   1.1        ad 	}
   1529   1.1        ad 	switch (cai->cai_associativity) {
   1530   1.1        ad 	case    0:
   1531   1.1        ad 		aprint_verbose("disabled");
   1532   1.1        ad 		break;
   1533   1.1        ad 	case    1:
   1534   1.1        ad 		aprint_verbose("direct-mapped");
   1535   1.1        ad 		break;
   1536   1.1        ad 	case 0xff:
   1537   1.1        ad 		aprint_verbose("fully associative");
   1538   1.1        ad 		break;
   1539   1.1        ad 	default:
   1540   1.1        ad 		aprint_verbose("%d-way", cai->cai_associativity);
   1541   1.1        ad 		break;
   1542   1.1        ad 	}
   1543   1.1        ad 	return ", ";
   1544   1.1        ad }
   1545   1.1        ad 
   1546   1.1        ad static const char *
   1547   1.1        ad print_tlb_config(struct cpu_info *ci, int cache_tag, const char *name,
   1548   1.1        ad     const char *sep)
   1549   1.1        ad {
   1550   1.1        ad 	struct x86_cache_info *cai = &ci->ci_cinfo[cache_tag];
   1551   1.7  christos 	char human_num[HUMAN_BUFSIZE];
   1552   1.1        ad 
   1553   1.1        ad 	if (cai->cai_totalsize == 0)
   1554   1.1        ad 		return sep;
   1555   1.1        ad 
   1556   1.1        ad 	if (sep == NULL)
   1557   1.1        ad 		aprint_verbose_dev(ci->ci_dev, "");
   1558   1.1        ad 	else
   1559   1.1        ad 		aprint_verbose("%s", sep);
   1560   1.1        ad 	if (name != NULL)
   1561   1.1        ad 		aprint_verbose("%s ", name);
   1562   1.1        ad 
   1563   1.1        ad 	if (cai->cai_string != NULL) {
   1564   1.1        ad 		aprint_verbose("%s", cai->cai_string);
   1565   1.1        ad 	} else {
   1566   1.7  christos 		(void)humanize_number(human_num, sizeof(human_num),
   1567   1.7  christos 			cai->cai_linesize, "B", HN_AUTOSCALE, HN_NOSPACE);
   1568   1.7  christos 		aprint_verbose("%d %s entries ", cai->cai_totalsize,
   1569   1.7  christos 		    human_num);
   1570   1.1        ad 		switch (cai->cai_associativity) {
   1571   1.1        ad 		case 0:
   1572   1.1        ad 			aprint_verbose("disabled");
   1573   1.1        ad 			break;
   1574   1.1        ad 		case 1:
   1575   1.1        ad 			aprint_verbose("direct-mapped");
   1576   1.1        ad 			break;
   1577   1.1        ad 		case 0xff:
   1578   1.1        ad 			aprint_verbose("fully associative");
   1579   1.1        ad 			break;
   1580   1.1        ad 		default:
   1581   1.1        ad 			aprint_verbose("%d-way", cai->cai_associativity);
   1582   1.1        ad 			break;
   1583   1.1        ad 		}
   1584   1.1        ad 	}
   1585   1.1        ad 	return ", ";
   1586   1.1        ad }
   1587   1.1        ad 
   1588   1.1        ad static const struct x86_cache_info *
   1589   1.1        ad cache_info_lookup(const struct x86_cache_info *cai, uint8_t desc)
   1590   1.1        ad {
   1591   1.1        ad 	int i;
   1592   1.1        ad 
   1593   1.1        ad 	for (i = 0; cai[i].cai_desc != 0; i++) {
   1594   1.1        ad 		if (cai[i].cai_desc == desc)
   1595   1.1        ad 			return (&cai[i]);
   1596   1.1        ad 	}
   1597   1.1        ad 
   1598   1.1        ad 	return (NULL);
   1599   1.1        ad }
   1600   1.1        ad 
   1601   1.7  christos static const struct x86_cache_info amd_cpuid_l2cache_assoc_info[] =
   1602   1.7  christos     AMD_L2CACHE_INFO;
   1603   1.1        ad 
   1604   1.7  christos static const struct x86_cache_info amd_cpuid_l3cache_assoc_info[] =
   1605   1.7  christos     AMD_L3CACHE_INFO;
   1606   1.1        ad 
   1607   1.1        ad static void
   1608   1.1        ad amd_cpu_cacheinfo(struct cpu_info *ci)
   1609   1.1        ad {
   1610   1.1        ad 	const struct x86_cache_info *cp;
   1611   1.1        ad 	struct x86_cache_info *cai;
   1612   1.1        ad 	int family, model;
   1613   1.1        ad 	u_int descs[4];
   1614   1.1        ad 	u_int lfunc;
   1615   1.1        ad 
   1616   1.1        ad 	family = (ci->ci_signature >> 8) & 15;
   1617   1.1        ad 	model = CPUID2MODEL(ci->ci_signature);
   1618   1.1        ad 
   1619   1.1        ad 	/*
   1620   1.1        ad 	 * K5 model 0 has none of this info.
   1621   1.1        ad 	 */
   1622   1.1        ad 	if (family == 5 && model == 0)
   1623   1.1        ad 		return;
   1624   1.1        ad 
   1625   1.1        ad 	/*
   1626   1.1        ad 	 * Get extended values for K8 and up.
   1627   1.1        ad 	 */
   1628   1.1        ad 	if (family == 0xf) {
   1629   1.1        ad 		family += CPUID2EXTFAMILY(ci->ci_signature);
   1630   1.1        ad 		model += CPUID2EXTMODEL(ci->ci_signature);
   1631   1.1        ad 	}
   1632   1.1        ad 
   1633   1.1        ad 	/*
   1634   1.1        ad 	 * Determine the largest extended function value.
   1635   1.1        ad 	 */
   1636   1.1        ad 	x86_cpuid(0x80000000, descs);
   1637   1.1        ad 	lfunc = descs[0];
   1638   1.1        ad 
   1639   1.1        ad 	/*
   1640   1.1        ad 	 * Determine L1 cache/TLB info.
   1641   1.1        ad 	 */
   1642   1.1        ad 	if (lfunc < 0x80000005) {
   1643   1.1        ad 		/* No L1 cache info available. */
   1644   1.1        ad 		return;
   1645   1.1        ad 	}
   1646   1.1        ad 
   1647   1.1        ad 	x86_cpuid(0x80000005, descs);
   1648   1.1        ad 
   1649   1.1        ad 	/*
   1650   1.1        ad 	 * K6-III and higher have large page TLBs.
   1651   1.1        ad 	 */
   1652   1.1        ad 	if ((family == 5 && model >= 9) || family >= 6) {
   1653   1.1        ad 		cai = &ci->ci_cinfo[CAI_ITLB2];
   1654   1.1        ad 		cai->cai_totalsize = AMD_L1_EAX_ITLB_ENTRIES(descs[0]);
   1655   1.1        ad 		cai->cai_associativity = AMD_L1_EAX_ITLB_ASSOC(descs[0]);
   1656   1.1        ad 		cai->cai_linesize = (4 * 1024 * 1024);
   1657   1.1        ad 
   1658   1.1        ad 		cai = &ci->ci_cinfo[CAI_DTLB2];
   1659   1.1        ad 		cai->cai_totalsize = AMD_L1_EAX_DTLB_ENTRIES(descs[0]);
   1660   1.1        ad 		cai->cai_associativity = AMD_L1_EAX_DTLB_ASSOC(descs[0]);
   1661   1.1        ad 		cai->cai_linesize = (4 * 1024 * 1024);
   1662   1.1        ad 	}
   1663   1.1        ad 
   1664   1.1        ad 	cai = &ci->ci_cinfo[CAI_ITLB];
   1665   1.1        ad 	cai->cai_totalsize = AMD_L1_EBX_ITLB_ENTRIES(descs[1]);
   1666   1.1        ad 	cai->cai_associativity = AMD_L1_EBX_ITLB_ASSOC(descs[1]);
   1667   1.1        ad 	cai->cai_linesize = (4 * 1024);
   1668   1.1        ad 
   1669   1.1        ad 	cai = &ci->ci_cinfo[CAI_DTLB];
   1670   1.1        ad 	cai->cai_totalsize = AMD_L1_EBX_DTLB_ENTRIES(descs[1]);
   1671   1.1        ad 	cai->cai_associativity = AMD_L1_EBX_DTLB_ASSOC(descs[1]);
   1672   1.1        ad 	cai->cai_linesize = (4 * 1024);
   1673   1.1        ad 
   1674   1.1        ad 	cai = &ci->ci_cinfo[CAI_DCACHE];
   1675   1.1        ad 	cai->cai_totalsize = AMD_L1_ECX_DC_SIZE(descs[2]);
   1676   1.1        ad 	cai->cai_associativity = AMD_L1_ECX_DC_ASSOC(descs[2]);
   1677   1.1        ad 	cai->cai_linesize = AMD_L1_EDX_IC_LS(descs[2]);
   1678   1.1        ad 
   1679   1.1        ad 	cai = &ci->ci_cinfo[CAI_ICACHE];
   1680   1.1        ad 	cai->cai_totalsize = AMD_L1_EDX_IC_SIZE(descs[3]);
   1681   1.1        ad 	cai->cai_associativity = AMD_L1_EDX_IC_ASSOC(descs[3]);
   1682   1.1        ad 	cai->cai_linesize = AMD_L1_EDX_IC_LS(descs[3]);
   1683   1.1        ad 
   1684   1.1        ad 	/*
   1685   1.1        ad 	 * Determine L2 cache/TLB info.
   1686   1.1        ad 	 */
   1687   1.1        ad 	if (lfunc < 0x80000006) {
   1688   1.1        ad 		/* No L2 cache info available. */
   1689   1.1        ad 		return;
   1690   1.1        ad 	}
   1691   1.1        ad 
   1692   1.1        ad 	x86_cpuid(0x80000006, descs);
   1693   1.1        ad 
   1694   1.1        ad 	cai = &ci->ci_cinfo[CAI_L2CACHE];
   1695   1.1        ad 	cai->cai_totalsize = AMD_L2_ECX_C_SIZE(descs[2]);
   1696   1.1        ad 	cai->cai_associativity = AMD_L2_ECX_C_ASSOC(descs[2]);
   1697   1.1        ad 	cai->cai_linesize = AMD_L2_ECX_C_LS(descs[2]);
   1698   1.1        ad 
   1699   1.1        ad 	cp = cache_info_lookup(amd_cpuid_l2cache_assoc_info,
   1700   1.1        ad 	    cai->cai_associativity);
   1701   1.1        ad 	if (cp != NULL)
   1702   1.1        ad 		cai->cai_associativity = cp->cai_associativity;
   1703   1.1        ad 	else
   1704   1.1        ad 		cai->cai_associativity = 0;	/* XXX Unknown/reserved */
   1705   1.7  christos 
   1706   1.7  christos 	/*
   1707   1.7  christos 	 * Determine L3 cache info on AMD Family 10h processors
   1708   1.7  christos 	 */
   1709   1.7  christos 	if (family == 0x10) {
   1710   1.7  christos 		cai = &ci->ci_cinfo[CAI_L3CACHE];
   1711   1.7  christos 		cai->cai_totalsize = AMD_L3_EDX_C_SIZE(descs[3]);
   1712   1.7  christos 		cai->cai_associativity = AMD_L3_EDX_C_ASSOC(descs[3]);
   1713   1.7  christos 		cai->cai_linesize = AMD_L3_EDX_C_LS(descs[3]);
   1714   1.7  christos 
   1715   1.7  christos 		cp = cache_info_lookup(amd_cpuid_l3cache_assoc_info,
   1716   1.7  christos 		    cai->cai_associativity);
   1717   1.7  christos 		if (cp != NULL)
   1718   1.7  christos 			cai->cai_associativity = cp->cai_associativity;
   1719   1.7  christos 		else
   1720   1.7  christos 			cai->cai_associativity = 0;	/* XXX Unkn/Rsvd */
   1721   1.7  christos 	}
   1722   1.1        ad }
   1723   1.1        ad 
   1724   1.1        ad static void
   1725   1.1        ad via_cpu_cacheinfo(struct cpu_info *ci)
   1726   1.1        ad {
   1727   1.1        ad 	struct x86_cache_info *cai;
   1728   1.1        ad 	int family, model, stepping;
   1729   1.1        ad 	u_int descs[4];
   1730   1.1        ad 	u_int lfunc;
   1731   1.1        ad 
   1732   1.1        ad 	family = (ci->ci_signature >> 8) & 15;
   1733   1.1        ad 	model = CPUID2MODEL(ci->ci_signature);
   1734   1.1        ad 	stepping = CPUID2STEPPING(ci->ci_signature);
   1735   1.1        ad 
   1736   1.1        ad 	/*
   1737   1.1        ad 	 * Determine the largest extended function value.
   1738   1.1        ad 	 */
   1739   1.1        ad 	x86_cpuid(0x80000000, descs);
   1740   1.1        ad 	lfunc = descs[0];
   1741   1.1        ad 
   1742   1.1        ad 	/*
   1743   1.1        ad 	 * Determine L1 cache/TLB info.
   1744   1.1        ad 	 */
   1745   1.1        ad 	if (lfunc < 0x80000005) {
   1746   1.1        ad 		/* No L1 cache info available. */
   1747   1.1        ad 		return;
   1748   1.1        ad 	}
   1749   1.1        ad 
   1750   1.1        ad 	x86_cpuid(0x80000005, descs);
   1751   1.1        ad 
   1752   1.1        ad 	cai = &ci->ci_cinfo[CAI_ITLB];
   1753   1.1        ad 	cai->cai_totalsize = VIA_L1_EBX_ITLB_ENTRIES(descs[1]);
   1754   1.1        ad 	cai->cai_associativity = VIA_L1_EBX_ITLB_ASSOC(descs[1]);
   1755   1.1        ad 	cai->cai_linesize = (4 * 1024);
   1756   1.1        ad 
   1757   1.1        ad 	cai = &ci->ci_cinfo[CAI_DTLB];
   1758   1.1        ad 	cai->cai_totalsize = VIA_L1_EBX_DTLB_ENTRIES(descs[1]);
   1759   1.1        ad 	cai->cai_associativity = VIA_L1_EBX_DTLB_ASSOC(descs[1]);
   1760   1.1        ad 	cai->cai_linesize = (4 * 1024);
   1761   1.1        ad 
   1762   1.1        ad 	cai = &ci->ci_cinfo[CAI_DCACHE];
   1763   1.1        ad 	cai->cai_totalsize = VIA_L1_ECX_DC_SIZE(descs[2]);
   1764   1.1        ad 	cai->cai_associativity = VIA_L1_ECX_DC_ASSOC(descs[2]);
   1765   1.1        ad 	cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[2]);
   1766   1.1        ad 	if (model == 9 && stepping == 8) {
   1767   1.1        ad 		/* Erratum: stepping 8 reports 4 when it should be 2 */
   1768   1.1        ad 		cai->cai_associativity = 2;
   1769   1.1        ad 	}
   1770   1.1        ad 
   1771   1.1        ad 	cai = &ci->ci_cinfo[CAI_ICACHE];
   1772   1.1        ad 	cai->cai_totalsize = VIA_L1_EDX_IC_SIZE(descs[3]);
   1773   1.1        ad 	cai->cai_associativity = VIA_L1_EDX_IC_ASSOC(descs[3]);
   1774   1.1        ad 	cai->cai_linesize = VIA_L1_EDX_IC_LS(descs[3]);
   1775   1.1        ad 	if (model == 9 && stepping == 8) {
   1776   1.1        ad 		/* Erratum: stepping 8 reports 4 when it should be 2 */
   1777   1.1        ad 		cai->cai_associativity = 2;
   1778   1.1        ad 	}
   1779   1.1        ad 
   1780   1.1        ad 	/*
   1781   1.1        ad 	 * Determine L2 cache/TLB info.
   1782   1.1        ad 	 */
   1783   1.1        ad 	if (lfunc < 0x80000006) {
   1784   1.1        ad 		/* No L2 cache info available. */
   1785   1.1        ad 		return;
   1786   1.1        ad 	}
   1787   1.1        ad 
   1788   1.1        ad 	x86_cpuid(0x80000006, descs);
   1789   1.1        ad 
   1790   1.1        ad 	cai = &ci->ci_cinfo[CAI_L2CACHE];
   1791   1.1        ad 	if (model >= 9) {
   1792   1.1        ad 		cai->cai_totalsize = VIA_L2N_ECX_C_SIZE(descs[2]);
   1793   1.1        ad 		cai->cai_associativity = VIA_L2N_ECX_C_ASSOC(descs[2]);
   1794   1.1        ad 		cai->cai_linesize = VIA_L2N_ECX_C_LS(descs[2]);
   1795   1.1        ad 	} else {
   1796   1.1        ad 		cai->cai_totalsize = VIA_L2_ECX_C_SIZE(descs[2]);
   1797   1.1        ad 		cai->cai_associativity = VIA_L2_ECX_C_ASSOC(descs[2]);
   1798   1.1        ad 		cai->cai_linesize = VIA_L2_ECX_C_LS(descs[2]);
   1799   1.1        ad 	}
   1800   1.1        ad }
   1801   1.1        ad 
   1802   1.1        ad static void
   1803   1.1        ad x86_print_cacheinfo(struct cpu_info *ci)
   1804   1.1        ad {
   1805   1.1        ad 	const char *sep;
   1806   1.1        ad 
   1807   1.1        ad 	if (ci->ci_cinfo[CAI_ICACHE].cai_totalsize != 0 ||
   1808   1.1        ad 	    ci->ci_cinfo[CAI_DCACHE].cai_totalsize != 0) {
   1809   1.1        ad 		sep = print_cache_config(ci, CAI_ICACHE, "I-cache", NULL);
   1810   1.1        ad 		sep = print_cache_config(ci, CAI_DCACHE, "D-cache", sep);
   1811   1.1        ad 		if (sep != NULL)
   1812   1.1        ad 			aprint_verbose("\n");
   1813   1.1        ad 	}
   1814   1.1        ad 	if (ci->ci_cinfo[CAI_L2CACHE].cai_totalsize != 0) {
   1815   1.1        ad 		sep = print_cache_config(ci, CAI_L2CACHE, "L2 cache", NULL);
   1816   1.1        ad 		if (sep != NULL)
   1817   1.1        ad 			aprint_verbose("\n");
   1818   1.1        ad 	}
   1819   1.1        ad 	if (ci->ci_cinfo[CAI_ITLB].cai_totalsize != 0) {
   1820   1.1        ad 		sep = print_tlb_config(ci, CAI_ITLB, "ITLB", NULL);
   1821   1.1        ad 		sep = print_tlb_config(ci, CAI_ITLB2, NULL, sep);
   1822   1.1        ad 		if (sep != NULL)
   1823   1.1        ad 			aprint_verbose("\n");
   1824   1.1        ad 	}
   1825   1.1        ad 	if (ci->ci_cinfo[CAI_DTLB].cai_totalsize != 0) {
   1826   1.1        ad 		sep = print_tlb_config(ci, CAI_DTLB, "DTLB", NULL);
   1827   1.1        ad 		sep = print_tlb_config(ci, CAI_DTLB2, NULL, sep);
   1828   1.1        ad 		if (sep != NULL)
   1829   1.1        ad 			aprint_verbose("\n");
   1830   1.1        ad 	}
   1831   1.7  christos 	if (ci->ci_cinfo[CAI_L3CACHE].cai_totalsize != 0) {
   1832   1.7  christos 		sep = print_cache_config(ci, CAI_L3CACHE, "L3 cache", NULL);
   1833   1.7  christos 		if (sep != NULL)
   1834   1.7  christos 			aprint_verbose("\n");
   1835   1.7  christos 	}
   1836   1.1        ad }
   1837   1.5        ad 
   1838   1.5        ad static void
   1839   1.5        ad powernow_probe(struct cpu_info *ci)
   1840   1.5        ad {
   1841   1.5        ad 	uint32_t regs[4];
   1842  1.14  christos 	char buf[256];
   1843   1.5        ad 
   1844   1.5        ad 	x86_cpuid(0x80000000, regs);
   1845   1.5        ad 
   1846   1.5        ad 	/* We need CPUID(0x80000007) */
   1847   1.5        ad 	if (regs[0] < 0x80000007)
   1848   1.5        ad 		return;
   1849   1.5        ad 	x86_cpuid(0x80000007, regs);
   1850   1.5        ad 
   1851  1.14  christos 	snprintb(buf, sizeof(buf), CPUID_APM_FLAGS, regs[3]);
   1852   1.5        ad 	aprint_normal_dev(ci->ci_dev, "AMD Power Management features: %s\n",
   1853  1.14  christos 	    buf);
   1854   1.5        ad }
   1855