usr/src/uts/i86pc/os/cpuid.c
author stevel@tonic-gate
Tue, 14 Jun 2005 00:00:00 -0700
changeset 0 68f95e015346
child 359 a88cb999e7ec
permissions -rw-r--r--
OpenSolaris Launch
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     5
 * Common Development and Distribution License, Version 1.0 only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     6
 * (the "License").  You may not use this file except in compliance
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 * with the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    21
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
#pragma ident	"%Z%%M%	%I%	%E% SMI"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
 * Various routines to handle identification
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
 * and classification of x86 processors.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
#include <sys/archsystm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
#include <sys/x86_archext.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
#include <sys/kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#include <sys/sunddi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
#include <sys/sunndi.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#include <sys/cpuvar.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#include <sys/processor.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
#include <sys/chip.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
#include <sys/fp.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
#include <sys/controlregs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
#include <sys/auxv_386.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#include <sys/bitmap.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
#include <sys/controlregs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
#include <sys/memnode.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
 * Pass 0 of cpuid feature analysis happens in locore. It contains special code
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
 * to recognize Cyrix processors that are not cpuid-compliant, and to deal with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
 * them accordingly. For most modern processors, feature detection occurs here
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
 * in pass 1.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
 * Pass 1 of cpuid feature analysis happens just at the beginning of mlsetup()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
 * for the boot CPU and does the basic analysis that the early kernel needs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
 * x86_feature is set based on the return value of cpuid_pass1() of the boot
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
 * CPU.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
 * Pass 1 includes:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
 *	o Determining vendor/model/family/stepping and setting x86_type and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
 *	  x86_vendor accordingly.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
 *	o Processing the feature flags returned by the cpuid instruction while
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
 *	  applying any workarounds or tricks for the specific processor.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
 *	o Mapping the feature flags into Solaris feature bits (X86_*).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
 *	o Processing extended feature flags if supported by the processor,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
 *	  again while applying specific processor knowledge.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
 *	o Determining the CMT characteristics of the system.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
 * Pass 1 is done on non-boot CPUs during their initialization and the results
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
 * are used only as a meager attempt at ensuring that all processors within the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
 * system support the same features.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
 * Pass 2 of cpuid feature analysis happens just at the beginning
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
 * of startup().  It just copies in and corrects the remainder
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
 * of the cpuid data we depend on: standard cpuid functions that we didn't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
 * need for pass1 feature analysis, and extended cpuid functions beyond the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
 * simple feature processing done in pass1.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
 * Pass 3 of cpuid analysis is invoked after basic kernel services; in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
 * particular kernel memory allocation has been made available. It creates a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
 * readable brand string based on the data collected in the first two passes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
 * Pass 4 of cpuid analysis is invoked after post_startup() when all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
 * the support infrastructure for various hardware features has been
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
 * initialized. It determines which processor features will be reported
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
 * to userland via the aux vector.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
 * All passes are executed on all CPUs, but only the boot CPU determines what
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
 * features the kernel will use.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
 * Much of the worst junk in this file is for the support of processors
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
 * that didn't really implement the cpuid instruction properly.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
 * NOTE: The accessor functions (cpuid_get*) are aware of, and ASSERT upon,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
 * the pass numbers.  Accordingly, changes to the pass code may require changes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
 * to the accessor code.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
uint_t x86_feature = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
uint_t x86_vendor = X86_VENDOR_IntelClone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
uint_t x86_type = X86_TYPE_OTHER;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
ulong_t cr4_value;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
uint_t pentiumpro_bug4046376;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
uint_t pentiumpro_bug4064495;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
uint_t enable486;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
 * This set of strings are for processors rumored to support the cpuid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
 * instruction, and is used by locore.s to figure out how to set x86_vendor
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
const char CyrixInstead[] = "CyrixInstead";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
struct cpuidr {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
	uint32_t	cp_eax;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
	uint32_t	cp_ebx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
	uint32_t	cp_ecx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
	uint32_t	cp_edx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
 * These constants determine how many of the elements of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
 * cpuid we cache in the cpuid_info data structure; the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
 * remaining elements are accessible via the cpuid instruction.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
#define	NMAX_CPI_STD	6		/* eax = 0 .. 5 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
#define	NMAX_CPI_EXTD	9		/* eax = 0x80000000 .. 0x80000008 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
struct cpuid_info {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
	uint_t cpi_pass;		/* last pass completed */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
	 * standard function information
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
	uint_t cpi_maxeax;		/* fn 0: %eax */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
	char cpi_vendorstr[13];		/* fn 0: %ebx:%ecx:%edx */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
	uint_t cpi_vendor;		/* enum of cpi_vendorstr */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
	uint_t cpi_family;		/* fn 1: extended family */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
	uint_t cpi_model;		/* fn 1: extended model */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
	uint_t cpi_step;		/* fn 1: stepping */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
	chipid_t cpi_chipid;		/* fn 1: %ebx: chip # on ht cpus */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
	uint_t cpi_brandid;		/* fn 1: %ebx: brand ID */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
	int cpi_clogid;			/* fn 1: %ebx: thread # */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
	uint_t cpi_ncpu_per_chip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
	uint8_t cpi_cacheinfo[16];	/* fn 2: intel-style cache desc */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
	uint_t cpi_ncache;		/* fn 2: number of elements */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
	struct cpuidr cpi_std[NMAX_CPI_STD];	/* 0 .. 5 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
	 * extended function information
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
	uint_t cpi_xmaxeax;		/* fn 0x80000000: %eax */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
	char cpi_brandstr[49];		/* fn 0x8000000[234] */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
	uint8_t cpi_pabits;		/* fn 0x80000006: %eax */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
	uint8_t cpi_vabits;		/* fn 0x80000006: %eax */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
	struct cpuidr cpi_extd[NMAX_CPI_EXTD];	/* 0x80000000 .. 0x80000008 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
	 * supported feature information
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
	uint32_t cpi_support[4];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
#define	STD_EDX_FEATURES	0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
#define	AMD_EDX_FEATURES	1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
#define	TM_EDX_FEATURES		2
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
#define	STD_ECX_FEATURES	3
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
static struct cpuid_info cpuid_info0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
 * These bit fields are defined by the Intel Application Note AP-485
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
 * "Intel Processor Identification and the CPUID Instruction"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
#define	CPI_FAMILY_XTD(cpi)	BITX((cpi)->cpi_std[1].cp_eax, 27, 20)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
#define	CPI_MODEL_XTD(cpi)	BITX((cpi)->cpi_std[1].cp_eax, 19, 16)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
#define	CPI_TYPE(cpi)		BITX((cpi)->cpi_std[1].cp_eax, 13, 12)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
#define	CPI_FAMILY(cpi)		BITX((cpi)->cpi_std[1].cp_eax, 11, 8)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
#define	CPI_STEP(cpi)		BITX((cpi)->cpi_std[1].cp_eax, 3, 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
#define	CPI_MODEL(cpi)		BITX((cpi)->cpi_std[1].cp_eax, 7, 4)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
#define	CPI_FEATURES_EDX(cpi)		((cpi)->cpi_std[1].cp_edx)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
#define	CPI_FEATURES_ECX(cpi)		((cpi)->cpi_std[1].cp_ecx)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
#define	CPI_FEATURES_XTD_EDX(cpi)	((cpi)->cpi_extd[1].cp_edx)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
#define	CPI_FEATURES_XTD_ECX(cpi)	((cpi)->cpi_extd[1].cp_ecx)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
#define	CPI_BRANDID(cpi)	BITX((cpi)->cpi_std[1].cp_ebx, 7, 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
#define	CPI_CHUNKS(cpi)		BITX((cpi)->cpi_std[1].cp_ebx, 15, 7)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
#define	CPI_CPU_COUNT(cpi)	BITX((cpi)->cpi_std[1].cp_ebx, 23, 16)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
#define	CPI_APIC_ID(cpi)	BITX((cpi)->cpi_std[1].cp_ebx, 31, 24)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
#define	CPI_MAXEAX_MAX		0x100		/* sanity control */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
#define	CPI_XMAXEAX_MAX		0x80000100
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
 *  Some undocumented ways of patching the results of the cpuid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
 *  instruction to permit running Solaris 10 on future cpus that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
 *  we don't currently support.  Could be set to non-zero values
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
 *  via settings in eeprom.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
uint32_t cpuid_feature_ecx_include;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
uint32_t cpuid_feature_ecx_exclude;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
uint32_t cpuid_feature_edx_include;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
uint32_t cpuid_feature_edx_exclude;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
uint_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
cpuid_pass1(cpu_t *cpu)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
	uint32_t mask_ecx, mask_edx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
	uint_t feature = X86_CPUID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
	struct cpuid_info *cpi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
	struct cpuidr *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
	int xcpuid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
	 * By convention, cpu0 is the boot cpu, which is called
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
	 * before memory allocation is available.  Other cpus are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
	 * initialized when memory becomes available.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
	if (cpu->cpu_id == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
		cpu->cpu_m.mcpu_cpi = cpi = &cpuid_info0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
		cpu->cpu_m.mcpu_cpi = cpi =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
		    kmem_zalloc(sizeof (*cpi), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
	cp = &cpi->cpi_std[0];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
	cp->cp_eax = __cpuid_insn(0, &cp->cp_ebx, &cp->cp_ecx, &cp->cp_edx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
	cpi->cpi_maxeax = cp->cp_eax;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
	{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
		uint32_t *iptr = (uint32_t *)cpi->cpi_vendorstr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
		*iptr++ = cp->cp_ebx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
		*iptr++ = cp->cp_edx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
		*iptr++ = cp->cp_ecx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
		*(char *)&cpi->cpi_vendorstr[12] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
	 * Map the vendor string to a type code
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
	if (strcmp(cpi->cpi_vendorstr, "GenuineIntel") == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
		cpi->cpi_vendor = X86_VENDOR_Intel;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
	else if (strcmp(cpi->cpi_vendorstr, "AuthenticAMD") == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
		cpi->cpi_vendor = X86_VENDOR_AMD;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
	else if (strcmp(cpi->cpi_vendorstr, "GenuineTMx86") == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
		cpi->cpi_vendor = X86_VENDOR_TM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
	else if (strcmp(cpi->cpi_vendorstr, CyrixInstead) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
		 * CyrixInstead is a variable used by the Cyrix detection code
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
		 * in locore.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
		cpi->cpi_vendor = X86_VENDOR_Cyrix;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
	else if (strcmp(cpi->cpi_vendorstr, "UMC UMC UMC ") == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
		cpi->cpi_vendor = X86_VENDOR_UMC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
	else if (strcmp(cpi->cpi_vendorstr, "NexGenDriven") == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
		cpi->cpi_vendor = X86_VENDOR_NexGen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
	else if (strcmp(cpi->cpi_vendorstr, "CentaurHauls") == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
		cpi->cpi_vendor = X86_VENDOR_Centaur;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
	else if (strcmp(cpi->cpi_vendorstr, "RiseRiseRise") == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
		cpi->cpi_vendor = X86_VENDOR_Rise;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
	else if (strcmp(cpi->cpi_vendorstr, "SiS SiS SiS ") == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
		cpi->cpi_vendor = X86_VENDOR_SiS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
	else if (strcmp(cpi->cpi_vendorstr, "Geode by NSC") == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
		cpi->cpi_vendor = X86_VENDOR_NSC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
		cpi->cpi_vendor = X86_VENDOR_IntelClone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
	x86_vendor = cpi->cpi_vendor; /* for compatibility */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
	 * Limit the range in case of weird hardware
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
	if (cpi->cpi_maxeax > CPI_MAXEAX_MAX)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
		cpi->cpi_maxeax = CPI_MAXEAX_MAX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
	if (cpi->cpi_maxeax < 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
		goto pass1_done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
	cp = &cpi->cpi_std[1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
	cp->cp_eax = __cpuid_insn(1, &cp->cp_ebx, &cp->cp_ecx, &cp->cp_edx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
	 * Extract identifying constants for easy access.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
	cpi->cpi_model = CPI_MODEL(cpi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
	cpi->cpi_family = CPI_FAMILY(cpi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
	if (cpi->cpi_family == 0xf) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
		cpi->cpi_family += CPI_FAMILY_XTD(cpi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
		cpi->cpi_model += CPI_MODEL_XTD(cpi) << 4;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
	cpi->cpi_step = CPI_STEP(cpi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
	cpi->cpi_brandid = CPI_BRANDID(cpi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
	 * *default* assumptions:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
	 * - believe %edx feature word
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
	 * - ignore %ecx feature word
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
	 * - 32-bit virtual and physical addressing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
	mask_edx = 0xffffffff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
	mask_ecx = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
	cpi->cpi_pabits = cpi->cpi_vabits = 32;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
	switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
	case X86_VENDOR_Intel:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
		if (cpi->cpi_family == 5)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
			x86_type = X86_TYPE_P5;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
		else if (cpi->cpi_family == 6) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
			x86_type = X86_TYPE_P6;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
			pentiumpro_bug4046376 = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
			pentiumpro_bug4064495 = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
			 * Clear the SEP bit when it was set erroneously
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
			if (cpi->cpi_model < 3 && cpi->cpi_step < 3)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
				cp->cp_edx &= ~CPUID_INTC_EDX_SEP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
		} else if (cpi->cpi_family == 0xf) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
			x86_type = X86_TYPE_P4;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
			 * We don't currently depend on any of the %ecx
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
			 * features until Prescott, so we'll only check
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
			 * this from P4 onwards.  We might want to revisit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
			 * that idea later.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
			mask_ecx = 0xffffffff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
		} else if (cpi->cpi_family > 0xf)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
			mask_ecx = 0xffffffff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
	case X86_VENDOR_IntelClone:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
	case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
#if defined(OPTERON_ERRATUM_108)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
		if (cpi->cpi_family == 0xf && cpi->cpi_model == 0xe) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
			cp->cp_eax = (0xf0f & cp->cp_eax) | 0xc0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
			cpi->cpi_model = 0xc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
		} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
		if (cpi->cpi_family == 5) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
			 * AMD K5 and K6
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
			 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
			 * These CPUs have an incomplete implementation
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
			 * of MCA/MCE which we mask away.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
			mask_edx =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
			    CPUID_INTC_EDX_DE |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
			    CPUID_INTC_EDX_PSE |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
			    CPUID_INTC_EDX_TSC |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
			    CPUID_INTC_EDX_MSR |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
			    CPUID_INTC_EDX_CX8 |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
			    CPUID_INTC_EDX_PGE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
			if (cpi->cpi_model == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
				 * Model 0 uses the wrong (APIC) bit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
				 * to indicate PGE.  Fix it here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
				if (cp->cp_edx & 0x200) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
					cp->cp_edx &= ~0x200;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
					cp->cp_edx |= CPUID_INTC_EDX_PGE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
			} else if (cpi->cpi_model >= 6)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
				mask_edx |= CPUID_INTC_EDX_MMX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
	case X86_VENDOR_TM:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
		 * workaround the NT workaround in CMS 4.1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
		if (cpi->cpi_family == 5 && cpi->cpi_model == 4 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
		    (cpi->cpi_step == 2 || cpi->cpi_step == 3))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
			cp->cp_edx |= CPUID_INTC_EDX_CX8;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
	case X86_VENDOR_Centaur:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
		 * workaround the NT workarounds again
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
		if (cpi->cpi_family == 6)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
			cp->cp_edx |= CPUID_INTC_EDX_CX8;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
	case X86_VENDOR_Cyrix:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
		 * We rely heavily on the probing in locore
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
		 * to actually figure out what parts, if any,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
		 * of the Cyrix cpuid instruction to believe.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
		switch (x86_type) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
		case X86_TYPE_CYRIX_486:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
			mask_edx = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
		case X86_TYPE_CYRIX_6x86:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
			mask_edx = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
		case X86_TYPE_CYRIX_6x86L:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
			mask_edx =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
			    CPUID_INTC_EDX_DE |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
			    CPUID_INTC_EDX_CX8;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
		case X86_TYPE_CYRIX_6x86MX:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
			mask_edx =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
			    CPUID_INTC_EDX_DE |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
			    CPUID_INTC_EDX_MSR |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
			    CPUID_INTC_EDX_CX8 |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
			    CPUID_INTC_EDX_PGE |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
			    CPUID_INTC_EDX_CMOV |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
			    CPUID_INTC_EDX_MMX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
		case X86_TYPE_CYRIX_GXm:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
			mask_edx =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
			    CPUID_INTC_EDX_MSR |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
			    CPUID_INTC_EDX_CX8 |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
			    CPUID_INTC_EDX_CMOV |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
			    CPUID_INTC_EDX_MMX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
		case X86_TYPE_CYRIX_MediaGX:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
		case X86_TYPE_CYRIX_MII:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
		case X86_TYPE_VIA_CYRIX_III:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
			mask_edx =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
			    CPUID_INTC_EDX_DE |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
			    CPUID_INTC_EDX_TSC |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
			    CPUID_INTC_EDX_MSR |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
			    CPUID_INTC_EDX_CX8 |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
			    CPUID_INTC_EDX_PGE |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
			    CPUID_INTC_EDX_CMOV |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
			    CPUID_INTC_EDX_MMX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
	 * Now we've figured out the masks that determine
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
	 * which bits we choose to believe, apply the masks
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
	 * to the feature words, then map the kernel's view
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
	 * of these feature words into its feature word.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
	cp->cp_edx &= mask_edx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
	cp->cp_ecx &= mask_ecx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
	 * fold in fix ups
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
	cp->cp_edx |= cpuid_feature_edx_include;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
	cp->cp_edx &= ~cpuid_feature_edx_exclude;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
	cp->cp_ecx |= cpuid_feature_ecx_include;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
	cp->cp_ecx &= ~cpuid_feature_ecx_exclude;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
	if (cp->cp_edx & CPUID_INTC_EDX_PSE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
		feature |= X86_LARGEPAGE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
	if (cp->cp_edx & CPUID_INTC_EDX_TSC)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
		feature |= X86_TSC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
	if (cp->cp_edx & CPUID_INTC_EDX_MSR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
		feature |= X86_MSR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
	if (cp->cp_edx & CPUID_INTC_EDX_MTRR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
		feature |= X86_MTRR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
	if (cp->cp_edx & CPUID_INTC_EDX_PGE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
		feature |= X86_PGE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
	if (cp->cp_edx & CPUID_INTC_EDX_CMOV)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
		feature |= X86_CMOV;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
	if (cp->cp_edx & CPUID_INTC_EDX_MMX)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
		feature |= X86_MMX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
	if ((cp->cp_edx & CPUID_INTC_EDX_MCE) != 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
	    (cp->cp_edx & CPUID_INTC_EDX_MCA) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
		feature |= X86_MCA;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
	if (cp->cp_edx & CPUID_INTC_EDX_PAE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
		feature |= X86_PAE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
	if (cp->cp_edx & CPUID_INTC_EDX_CX8)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
		feature |= X86_CX8;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
#if defined(CPUID_INTC_ECX_CX16)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
	 * In the July 16 2004 edition of AN 485, Intel rescinded
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
	 * the definition of this bit -- it's now in the "Do not count on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
	 * their value" category.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
	if (cp->cp_ecx & CPUID_INTC_ECX_CX16)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
		feature |= X86_CX16;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
	if (cp->cp_edx & CPUID_INTC_EDX_PAT)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
		feature |= X86_PAT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
	if (cp->cp_edx & CPUID_INTC_EDX_SEP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
		feature |= X86_SEP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
	if (cp->cp_edx & CPUID_INTC_EDX_FXSR) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
		 * In our implementation, fxsave/fxrstor
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
		 * are prerequisites before we'll even
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
		 * try and do SSE things.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
		if (cp->cp_edx & CPUID_INTC_EDX_SSE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
			feature |= X86_SSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
		if (cp->cp_edx & CPUID_INTC_EDX_SSE2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
			feature |= X86_SSE2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
		if (cp->cp_ecx & CPUID_INTC_ECX_SSE3)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
			feature |= X86_SSE3;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
	if (cp->cp_edx & CPUID_INTC_EDX_DE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
		cr4_value |= CR4_DE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
	if (feature & X86_PAE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
		cpi->cpi_pabits = 36;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
	 * Hyperthreading configuration is slightly tricky on Intel
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
	 * and pure clones, and even trickier on AMD.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
	 * (AMD chose to set the HTT bit on their CMP processors,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
	 * even though they're not actually hyperthreaded.  Thus it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
	 * takes a bit more work to figure out what's really going
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
	 * on ... see the handling of the HTvalid bit below)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
	if (cp->cp_edx & CPUID_INTC_EDX_HTT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
		cpi->cpi_ncpu_per_chip = CPI_CPU_COUNT(cpi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
		if (cpi->cpi_ncpu_per_chip > 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
			feature |= X86_HTT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
	 * Work on the "extended" feature information, doing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
	 * some basic initialization for cpuid_pass2()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
	xcpuid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
	switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
	case X86_VENDOR_Intel:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
		if (cpi->cpi_family >= 0xf)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
			xcpuid++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
	case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
		if (cpi->cpi_family > 5 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
		    (cpi->cpi_family == 5 && cpi->cpi_model >= 1))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
			xcpuid++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
	case X86_VENDOR_Cyrix:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
		 * Only these Cyrix CPUs are -known- to support
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
		 * extended cpuid operations.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
		if (x86_type == X86_TYPE_VIA_CYRIX_III ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
		    x86_type == X86_TYPE_CYRIX_GXm)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
			xcpuid++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
	case X86_VENDOR_Centaur:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
	case X86_VENDOR_TM:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
		xcpuid++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
	if (xcpuid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
		cp = &cpi->cpi_extd[0];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
		cpi->cpi_xmaxeax = cp->cp_eax = __cpuid_insn(0x80000000,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
		    &cp->cp_ebx, &cp->cp_ecx, &cp->cp_edx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
	if (cpi->cpi_xmaxeax & 0x80000000) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
		if (cpi->cpi_xmaxeax > CPI_XMAXEAX_MAX)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
			cpi->cpi_xmaxeax = CPI_XMAXEAX_MAX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
		switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
		case X86_VENDOR_Intel:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
		case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
			if (cpi->cpi_xmaxeax < 0x80000001)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
			cp = &cpi->cpi_extd[1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
			cp->cp_eax = __cpuid_insn(0x80000001,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
			    &cp->cp_ebx, &cp->cp_ecx, &cp->cp_edx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
			if (cpi->cpi_vendor == X86_VENDOR_AMD &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
			    cpi->cpi_family == 5 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
			    cpi->cpi_model == 6 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
			    cpi->cpi_step == 6) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
				 * K6 model 6 uses bit 10 to indicate SYSC
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
				 * Later models use bit 11. Fix it here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
				if (cp->cp_edx & 0x400) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
					cp->cp_edx &= ~0x400;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
					cp->cp_edx |= CPUID_AMD_EDX_SYSC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
			 * Compute the additions to the kernel's feature word.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
			if (cp->cp_edx & CPUID_AMD_EDX_NX)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
				feature |= X86_NX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
			 * Unless both the HTT bit is set, and the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
			 * HTvalid bit is set, then we're not actually
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
			 * HyperThreaded at all..
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
			if (cpi->cpi_vendor == X86_VENDOR_AMD &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
			    (feature & X86_HTT) == X86_HTT &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
			    (cp->cp_ecx & CPUID_AMD_ECX_HTvalid) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
				feature &= ~X86_HTT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
#if defined(_LP64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
			 * It's really tricky to support syscall/sysret in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
			 * the i386 kernel; we rely on sysenter/sysexit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
			 * instead.  In the amd64 kernel, things are -way-
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
			 * better.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
			if (cp->cp_edx & CPUID_AMD_EDX_SYSC)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
				feature |= X86_ASYSC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
			 * While we're thinking about system calls, note
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
			 * that AMD processors don't support sysenter
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
			 * in long mode at all, so don't try to program them.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
			if (x86_vendor == X86_VENDOR_AMD)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
				feature &= ~X86_SEP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
		switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
		case X86_VENDOR_Intel:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
		case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
			if (cpi->cpi_xmaxeax < 0x80000008)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
			cp = &cpi->cpi_extd[8];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
			cp->cp_eax = __cpuid_insn(0x80000008,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
			    &cp->cp_ebx, &cp->cp_ecx, &cp->cp_edx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
			 * Virtual and physical address limits from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
			 * cpuid override previously guessed values.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
			cpi->cpi_pabits = BITX(cp->cp_eax, 7, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
			cpi->cpi_vabits = BITX(cp->cp_eax, 15, 8);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
			 * This -might- be a CMP processor?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
			if (cpi->cpi_vendor == X86_VENDOR_AMD) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
				cpi->cpi_ncpu_per_chip =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
				    1 + BITX(cp->cp_ecx, 7, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
				if (cpi->cpi_ncpu_per_chip > 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
					feature |= X86_CMP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
	if ((feature & (X86_HTT | X86_CMP)) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
		cpi->cpi_chipid = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
		cpi->cpi_clogid = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
	} else if (cpi->cpi_ncpu_per_chip > 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
		uint_t i, cid_shift, apic_id;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
		for (i = 1, cid_shift = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
		    i < cpi->cpi_ncpu_per_chip; i <<= 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
			cid_shift++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
		apic_id = CPI_APIC_ID(cpi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
		cpi->cpi_chipid = apic_id >> cid_shift;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
		cpi->cpi_clogid = apic_id & ((1 << cid_shift) - 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
pass1_done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
	cpi->cpi_pass = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
	return (feature);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
 * Make copies of the cpuid table entries we depend on, in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
 * part for ease of parsing now, in part so that we have only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
 * one place to correct any of it, in part for ease of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
 * later export to userland, and in part so we can look at
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
 * this stuff in a crash dump.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
cpuid_pass2(cpu_t *cpu)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
	uint_t n, nmax;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
	struct cpuidr *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
	uint8_t *dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
	uint32_t *iptr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
	struct cpuid_info *cpi = cpu->cpu_m.mcpu_cpi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
	ASSERT(cpi->cpi_pass == 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
	if (cpi->cpi_maxeax < 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
		goto pass2_done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
	if ((nmax = cpi->cpi_maxeax + 1) > NMAX_CPI_STD)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
		nmax = NMAX_CPI_STD;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
	 * (We already handled n == 0 and n == 1 in pass 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
	for (n = 2, cp = &cpi->cpi_std[2]; n < nmax; n++, cp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
		cp->cp_eax = __cpuid_insn(n,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
		    &cp->cp_ebx, &cp->cp_ecx, &cp->cp_edx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
		switch (n) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
		case 2:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
			 * "the lower 8 bits of the %eax register
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
			 * contain a value that identifies the number
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
			 * of times the cpuid [instruction] has to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
			 * executed to obtain a complete image of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
			 * processor's caching systems."
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
			 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
			 * How *do* they make this stuff up?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
			cpi->cpi_ncache = sizeof (*cp) *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
			    BITX(cp->cp_eax, 7, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
			if (cpi->cpi_ncache == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
			cpi->cpi_ncache--;	/* skip count byte */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
			 * Well, for now, rather than attempt to implement
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
			 * this slightly dubious algorithm, we just look
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
			 * at the first 15 ..
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
			if (cpi->cpi_ncache > (sizeof (*cp) - 1))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   737
				cpi->cpi_ncache = sizeof (*cp) - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   738
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
			dp = cpi->cpi_cacheinfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
			if (BITX(cp->cp_eax, 31, 31) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
				uint8_t *p = (void *)&cp->cp_eax;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
				for (i = 1; i < 3; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
					if (p[i] != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
						*dp++ = p[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
			if (BITX(cp->cp_ebx, 31, 31) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
				uint8_t *p = (void *)&cp->cp_ebx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
				for (i = 0; i < 4; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
					if (p[i] != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
						*dp++ = p[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
			if (BITX(cp->cp_ecx, 31, 31) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
				uint8_t *p = (void *)&cp->cp_ecx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
				for (i = 0; i < 4; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
					if (p[i] != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
						*dp++ = p[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
			if (BITX(cp->cp_edx, 31, 31) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
				uint8_t *p = (void *)&cp->cp_edx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
				for (i = 0; i < 4; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
					if (p[i] != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
						*dp++ = p[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
		case 3:	/* Processor serial number, if PSN supported */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
		case 4:	/* Deterministic cache parameters */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
		case 5:	/* Monitor/Mwait parameters */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
	if ((cpi->cpi_xmaxeax & 0x80000000) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
		goto pass2_done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
	if ((nmax = cpi->cpi_xmaxeax - 0x80000000 + 1) > NMAX_CPI_EXTD)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
		nmax = NMAX_CPI_EXTD;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
	 * Copy the extended properties, fixing them as we go.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
	 * (We already handled n == 0 and n == 1 in pass 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
	iptr = (void *)cpi->cpi_brandstr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
	for (n = 2, cp = &cpi->cpi_extd[2]; n < nmax; cp++, n++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
		cp->cp_eax = __cpuid_insn(n + 0x80000000,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
		    &cp->cp_ebx, &cp->cp_ecx, &cp->cp_edx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
		switch (n) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
		case 2:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
		case 3:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
		case 4:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
			 * Extract the brand string
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
			*iptr++ = cp->cp_eax;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
			*iptr++ = cp->cp_ebx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
			*iptr++ = cp->cp_ecx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
			*iptr++ = cp->cp_edx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
		case 5:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
			switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
			case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
				 * The Athlon and Duron were the first
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
				 * parts to report the sizes of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
				 * TLB for large pages. Before then,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
				 * we don't trust the data.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
				if (cpi->cpi_family < 6 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
				    (cpi->cpi_family == 6 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
				    cpi->cpi_model < 1))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
					cp->cp_eax = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
			default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
		case 6:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
			switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
			case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
				 * The Athlon and Duron were the first
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
				 * AMD parts with L2 TLB's.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
				 * Before then, don't trust the data.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
				if (cpi->cpi_family < 6 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
				    cpi->cpi_family == 6 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
				    cpi->cpi_model < 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
					cp->cp_eax = cp->cp_ebx = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
				 * AMD Duron rev A0 reports L2
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
				 * cache size incorrectly as 1K
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
				 * when it is really 64K
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
				if (cpi->cpi_family == 6 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
				    cpi->cpi_model == 3 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
				    cpi->cpi_step == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
					cp->cp_ecx &= 0xffff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
					cp->cp_ecx |= 0x400000;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   838
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   839
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   840
			case X86_VENDOR_Cyrix:	/* VIA C3 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   841
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   842
				 * VIA C3 processors are a bit messed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   843
				 * up w.r.t. encoding cache sizes in %ecx
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   845
				if (cpi->cpi_family != 6)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
				 * model 7 and 8 were incorrectly encoded
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
				 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
				 * xxx is model 8 really broken?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   852
				if (cpi->cpi_model == 7 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
				    cpi->cpi_model == 8)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
					cp->cp_ecx =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
					    BITX(cp->cp_ecx, 31, 24) << 16 |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
					    BITX(cp->cp_ecx, 23, 16) << 12 |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
					    BITX(cp->cp_ecx, 15, 8) << 8 |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
					    BITX(cp->cp_ecx, 7, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
				 * model 9 stepping 1 has wrong associativity
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
				if (cpi->cpi_model == 9 && cpi->cpi_step == 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
					cp->cp_ecx |= 8 << 12;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
			case X86_VENDOR_Intel:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   866
				/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   867
				 * Extended L2 Cache features function.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   868
				 * First appeared on Prescott.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   869
				 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   870
			default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   871
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   872
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
pass2_done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
	cpi->cpi_pass = 2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
static const char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
intel_cpubrand(const struct cpuid_info *cpi)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
	if ((x86_feature & X86_CPUID) == 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
	    cpi->cpi_maxeax < 1 || cpi->cpi_family < 5)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
		return ("i486");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
	switch (cpi->cpi_family) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
	case 5:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
		return ("Intel Pentium(r)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
	case 6:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
		switch (cpi->cpi_model) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
			uint_t celeron, xeon;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
			const struct cpuidr *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
		case 0:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   900
		case 1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   901
		case 2:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   902
			return ("Intel Pentium(r) Pro");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   903
		case 3:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   904
		case 4:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   905
			return ("Intel Pentium(r) II");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   906
		case 6:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   907
			return ("Intel Celeron(r)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   908
		case 5:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   909
		case 7:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   910
			celeron = xeon = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   911
			cp = &cpi->cpi_std[2];	/* cache info */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   912
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   913
			for (i = 1; i < 3; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   914
				uint_t tmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   915
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   916
				tmp = (cp->cp_eax >> (8 * i)) & 0xff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   917
				if (tmp == 0x40)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   918
					celeron++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   919
				if (tmp >= 0x44 && tmp <= 0x45)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   920
					xeon++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   921
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   922
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   923
			for (i = 0; i < 2; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   924
				uint_t tmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   925
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   926
				tmp = (cp->cp_ebx >> (8 * i)) & 0xff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   927
				if (tmp == 0x40)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   928
					celeron++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   929
				else if (tmp >= 0x44 && tmp <= 0x45)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   930
					xeon++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   931
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   932
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   933
			for (i = 0; i < 4; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   934
				uint_t tmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   935
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   936
				tmp = (cp->cp_ecx >> (8 * i)) & 0xff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   937
				if (tmp == 0x40)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   938
					celeron++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   939
				else if (tmp >= 0x44 && tmp <= 0x45)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   940
					xeon++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   941
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   942
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   943
			for (i = 0; i < 4; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   944
				uint_t tmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   945
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   946
				tmp = (cp->cp_edx >> (8 * i)) & 0xff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   947
				if (tmp == 0x40)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   948
					celeron++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   949
				else if (tmp >= 0x44 && tmp <= 0x45)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   950
					xeon++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   951
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   952
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   953
			if (celeron)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   954
				return ("Intel Celeron(r)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   955
			if (xeon)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   956
				return (cpi->cpi_model == 5 ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   957
				    "Intel Pentium(r) II Xeon(tm)" :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   958
				    "Intel Pentium(r) III Xeon(tm)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   959
			return (cpi->cpi_model == 5 ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   960
			    "Intel Pentium(r) II or Pentium(r) II Xeon(tm)" :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   961
			    "Intel Pentium(r) III or Pentium(r) III Xeon(tm)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   962
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   963
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   964
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   965
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   966
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   967
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   968
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   969
	if (cpi->cpi_family <= 0xf && cpi->cpi_model <= 0xf &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   970
	    cpi->cpi_brandid != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   971
		static const struct {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   972
			uint_t bt_bid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   973
			const char *bt_str;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   974
		} brand_tbl[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   975
			{ 0x1,	"Intel(r) Celeron(r)" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   976
			{ 0x2,	"Intel(r) Pentium(r) III" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   977
			{ 0x3,	"Intel(r) Pentium(r) III Xeon(tm)" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   978
			{ 0x4,	"Intel(r) Pentium(r) III" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   979
			{ 0x6,	"Mobile Intel(r) Pentium(r) III" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   980
			{ 0x7,	"Mobile Intel(r) Celeron(r)" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   981
			{ 0x8,	"Intel(r) Pentium(r) 4" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   982
			{ 0x9,	"Intel(r) Pentium(r) 4" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   983
			{ 0xa,	"Intel(r) Celeron(r)" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   984
			{ 0xb,	"Intel(r) Xeon(tm)" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   985
			{ 0xc,	"Intel(r) Xeon(tm) MP" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   986
			{ 0xe,	"Mobile Intel(r) Pentium(r) 4" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   987
			{ 0xf,	"Mobile Intel(r) Celeron(r)" }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   988
		};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   989
		uint_t btblmax = sizeof (brand_tbl) / sizeof (brand_tbl[0]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   990
		uint_t sgn;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   991
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   992
		sgn = (cpi->cpi_family << 8) |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   993
		    (cpi->cpi_model << 4) | cpi->cpi_step;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   994
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   995
		for (i = 0; i < btblmax; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   996
			if (brand_tbl[i].bt_bid == cpi->cpi_brandid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   997
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   998
		if (i < btblmax) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   999
			if (sgn == 0x6b1 && cpi->cpi_brandid == 3)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1000
				return ("Intel(r) Celeron(r)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1001
			if (sgn < 0xf13 && cpi->cpi_brandid == 0xb)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1002
				return ("Intel(r) Xeon(tm) MP");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1003
			if (sgn < 0xf13 && cpi->cpi_brandid == 0xe)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1004
				return ("Intel(r) Xeon(tm)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1005
			return (brand_tbl[i].bt_str);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1006
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1007
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1008
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1009
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1010
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1011
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1012
static const char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1013
amd_cpubrand(const struct cpuid_info *cpi)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1014
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1015
	if ((x86_feature & X86_CPUID) == 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1016
	    cpi->cpi_maxeax < 1 || cpi->cpi_family < 5)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1017
		return ("i486 compatible");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1018
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1019
	switch (cpi->cpi_family) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1020
	case 5:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1021
		switch (cpi->cpi_model) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1022
		case 0:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1023
		case 1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1024
		case 2:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1025
		case 3:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1026
		case 4:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1027
		case 5:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1028
			return ("AMD-K5(r)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1029
		case 6:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1030
		case 7:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1031
			return ("AMD-K6(r)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1032
		case 8:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1033
			return ("AMD-K6(r)-2");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1034
		case 9:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1035
			return ("AMD-K6(r)-III");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1036
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1037
			return ("AMD (family 5)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1038
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1039
	case 6:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1040
		switch (cpi->cpi_model) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1041
		case 1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1042
			return ("AMD-K7(tm)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1043
		case 0:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1044
		case 2:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1045
		case 4:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1046
			return ("AMD Athlon(tm)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1047
		case 3:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1048
		case 7:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1049
			return ("AMD Duron(tm)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1050
		case 6:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1051
		case 8:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1052
		case 10:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1053
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1054
			 * Use the L2 cache size to distinguish
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1055
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1056
			return ((cpi->cpi_extd[6].cp_ecx >> 16) >= 256 ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1057
			    "AMD Athlon(tm)" : "AMD Duron(tm)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1058
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1059
			return ("AMD (family 6)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1060
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1061
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1062
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1063
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1064
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1065
	if (cpi->cpi_family == 0xf && cpi->cpi_model == 5 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1066
	    cpi->cpi_brandid != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1067
		switch (BITX(cpi->cpi_brandid, 7, 5)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1068
		case 3:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1069
			return ("AMD Opteron(tm) UP 1xx");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1070
		case 4:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1071
			return ("AMD Opteron(tm) DP 2xx");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1072
		case 5:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1073
			return ("AMD Opteron(tm) MP 8xx");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1074
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1075
			return ("AMD Opteron(tm)");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1076
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1077
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1078
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1079
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1080
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1081
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1082
static const char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1083
cyrix_cpubrand(struct cpuid_info *cpi, uint_t type)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1084
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1085
	if ((x86_feature & X86_CPUID) == 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1086
	    cpi->cpi_maxeax < 1 || cpi->cpi_family < 5 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1087
	    type == X86_TYPE_CYRIX_486)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1088
		return ("i486 compatible");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1089
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1090
	switch (type) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1091
	case X86_TYPE_CYRIX_6x86:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1092
		return ("Cyrix 6x86");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1093
	case X86_TYPE_CYRIX_6x86L:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1094
		return ("Cyrix 6x86L");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1095
	case X86_TYPE_CYRIX_6x86MX:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1096
		return ("Cyrix 6x86MX");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1097
	case X86_TYPE_CYRIX_GXm:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1098
		return ("Cyrix GXm");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1099
	case X86_TYPE_CYRIX_MediaGX:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1100
		return ("Cyrix MediaGX");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1101
	case X86_TYPE_CYRIX_MII:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1102
		return ("Cyrix M2");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1103
	case X86_TYPE_VIA_CYRIX_III:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1104
		return ("VIA Cyrix M3");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1105
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1106
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1107
		 * Have another wild guess ..
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1108
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1109
		if (cpi->cpi_family == 4 && cpi->cpi_model == 9)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1110
			return ("Cyrix 5x86");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1111
		else if (cpi->cpi_family == 5) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1112
			switch (cpi->cpi_model) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1113
			case 2:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1114
				return ("Cyrix 6x86");	/* Cyrix M1 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1115
			case 4:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1116
				return ("Cyrix MediaGX");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1117
			default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1118
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1119
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1120
		} else if (cpi->cpi_family == 6) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1121
			switch (cpi->cpi_model) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1122
			case 0:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1123
				return ("Cyrix 6x86MX"); /* Cyrix M2? */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1124
			case 5:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1125
			case 6:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1126
			case 7:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1127
			case 8:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1128
			case 9:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1129
				return ("VIA C3");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1130
			default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1131
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1132
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1133
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1134
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1135
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1136
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1137
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1138
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1139
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1140
 * This only gets called in the case that the CPU extended
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1141
 * feature brand string (0x80000002, 0x80000003, 0x80000004)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1142
 * aren't available, or contain null bytes for some reason.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1143
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1144
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1145
fabricate_brandstr(struct cpuid_info *cpi)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1146
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1147
	const char *brand = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1148
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1149
	switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1150
	case X86_VENDOR_Intel:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1151
		brand = intel_cpubrand(cpi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1152
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1153
	case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1154
		brand = amd_cpubrand(cpi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1155
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1156
	case X86_VENDOR_Cyrix:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1157
		brand = cyrix_cpubrand(cpi, x86_type);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1158
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1159
	case X86_VENDOR_NexGen:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1160
		if (cpi->cpi_family == 5 && cpi->cpi_model == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1161
			brand = "NexGen Nx586";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1162
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1163
	case X86_VENDOR_Centaur:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1164
		if (cpi->cpi_family == 5)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1165
			switch (cpi->cpi_model) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1166
			case 4:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1167
				brand = "Centaur C6";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1168
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1169
			case 8:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1170
				brand = "Centaur C2";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1171
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1172
			case 9:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1173
				brand = "Centaur C3";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1174
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1175
			default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1176
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1177
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1178
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1179
	case X86_VENDOR_Rise:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1180
		if (cpi->cpi_family == 5 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1181
		    (cpi->cpi_model == 0 || cpi->cpi_model == 2))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1182
			brand = "Rise mP6";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1183
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1184
	case X86_VENDOR_SiS:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1185
		if (cpi->cpi_family == 5 && cpi->cpi_model == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1186
			brand = "SiS 55x";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1187
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1188
	case X86_VENDOR_TM:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1189
		if (cpi->cpi_family == 5 && cpi->cpi_model == 4)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1190
			brand = "Transmeta Crusoe TM3x00 or TM5x00";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1191
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1192
	case X86_VENDOR_NSC:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1193
	case X86_VENDOR_UMC:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1194
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1195
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1196
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1197
	if (brand) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1198
		(void) strcpy((char *)cpi->cpi_brandstr, brand);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1199
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1200
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1201
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1202
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1203
	 * If all else fails ...
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1204
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1205
	(void) snprintf(cpi->cpi_brandstr, sizeof (cpi->cpi_brandstr),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1206
	    "%s %d.%d.%d", cpi->cpi_vendorstr, cpi->cpi_family,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1207
	    cpi->cpi_model, cpi->cpi_step);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1208
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1209
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1210
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1211
 * This routine is called just after kernel memory allocation
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1212
 * becomes available on cpu0, and as part of mp_startup() on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1213
 * the other cpus.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1214
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1215
 * Fixup the brand string.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1216
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1217
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1218
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1219
cpuid_pass3(cpu_t *cpu)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1220
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1221
	struct cpuid_info *cpi = cpu->cpu_m.mcpu_cpi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1222
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1223
	ASSERT(cpi->cpi_pass == 2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1224
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1225
	if ((cpi->cpi_xmaxeax & 0x80000000) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1226
		fabricate_brandstr(cpi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1227
		goto pass3_done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1228
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1229
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1230
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1231
	 * If we successfully extracted a brand string from the cpuid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1232
	 * instruction, clean it up by removing leading spaces and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1233
	 * similar junk.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1234
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1235
	if (cpi->cpi_brandstr[0]) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1236
		size_t maxlen = sizeof (cpi->cpi_brandstr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1237
		char *src, *dst;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1238
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1239
		dst = src = (char *)cpi->cpi_brandstr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1240
		src[maxlen - 1] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1241
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1242
		 * strip leading spaces
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1243
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1244
		while (*src == ' ')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1245
			src++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1246
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1247
		 * Remove any 'Genuine' or "Authentic" prefixes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1248
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1249
		if (strncmp(src, "Genuine ", 8) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1250
			src += 8;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1251
		if (strncmp(src, "Authentic ", 10) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1252
			src += 10;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1253
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1254
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1255
		 * Now do an in-place copy.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1256
		 * Map (R) to (r) and (TM) to (tm).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1257
		 * The era of teletypes is long gone, and there's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1258
		 * -really- no need to shout.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1259
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1260
		while (*src != '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1261
			if (src[0] == '(') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1262
				if (strncmp(src + 1, "R)", 2) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1263
					(void) strncpy(dst, "(r)", 3);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1264
					src += 3;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1265
					dst += 3;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1266
					continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1267
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1268
				if (strncmp(src + 1, "TM)", 3) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1269
					(void) strncpy(dst, "(tm)", 4);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1270
					src += 4;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1271
					dst += 4;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1272
					continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1273
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1274
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1275
			*dst++ = *src++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1276
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1277
		*dst = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1278
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1279
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1280
		 * Finally, remove any trailing spaces
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1281
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1282
		while (--dst > cpi->cpi_brandstr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1283
			if (*dst == ' ')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1284
				*dst = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1285
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1286
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1287
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1288
		fabricate_brandstr(cpi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1289
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1290
pass3_done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1291
	cpi->cpi_pass = 3;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1292
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1293
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1294
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1295
 * This routine is called out of bind_hwcap() much later in the life
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1296
 * of the kernel (post_startup()).  The job of this routine is to resolve
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1297
 * the hardware feature support and kernel support for those features into
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1298
 * what we're actually going to tell applications via the aux vector.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1299
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1300
uint_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1301
cpuid_pass4(cpu_t *cpu)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1302
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1303
	struct cpuid_info *cpi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1304
	uint_t hwcap_flags = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1305
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1306
	if (cpu == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1307
		cpu = CPU;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1308
	cpi = cpu->cpu_m.mcpu_cpi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1309
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1310
	ASSERT(cpi->cpi_pass == 3);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1311
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1312
	if (cpi->cpi_maxeax >= 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1313
		uint32_t *edx = &cpi->cpi_support[STD_EDX_FEATURES];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1314
		uint32_t *ecx = &cpi->cpi_support[STD_ECX_FEATURES];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1315
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1316
		*edx = CPI_FEATURES_EDX(cpi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1317
		*ecx = CPI_FEATURES_ECX(cpi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1318
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1319
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1320
		 * [these require explicit kernel support]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1321
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1322
		if ((x86_feature & X86_SEP) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1323
			*edx &= ~CPUID_INTC_EDX_SEP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1324
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1325
		if ((x86_feature & X86_SSE) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1326
			*edx &= ~(CPUID_INTC_EDX_FXSR|CPUID_INTC_EDX_SSE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1327
		if ((x86_feature & X86_SSE2) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1328
			*edx &= ~CPUID_INTC_EDX_SSE2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1329
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1330
		if ((x86_feature & X86_HTT) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1331
			*edx &= ~CPUID_INTC_EDX_HTT;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1332
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1333
		if ((x86_feature & X86_SSE3) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1334
			*ecx &= ~CPUID_INTC_ECX_SSE3;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1335
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1336
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1337
		 * [no explicit support required beyond x87 fp context]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1338
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1339
		if (!fpu_exists)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1340
			*edx &= ~(CPUID_INTC_EDX_FPU | CPUID_INTC_EDX_MMX);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1341
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1342
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1343
		 * Now map the supported feature vector to things that we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1344
		 * think userland will care about.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1345
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1346
		if (*edx & CPUID_INTC_EDX_SEP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1347
			hwcap_flags |= AV_386_SEP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1348
		if (*edx & CPUID_INTC_EDX_SSE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1349
			hwcap_flags |= AV_386_FXSR | AV_386_SSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1350
		if (*edx & CPUID_INTC_EDX_SSE2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1351
			hwcap_flags |= AV_386_SSE2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1352
		if (*ecx & CPUID_INTC_ECX_SSE3)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1353
			hwcap_flags |= AV_386_SSE3;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1354
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1355
		if (*edx & CPUID_INTC_EDX_FPU)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1356
			hwcap_flags |= AV_386_FPU;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1357
		if (*edx & CPUID_INTC_EDX_MMX)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1358
			hwcap_flags |= AV_386_MMX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1359
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1360
		if (*edx & CPUID_INTC_EDX_TSC)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1361
			hwcap_flags |= AV_386_TSC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1362
		if (*edx & CPUID_INTC_EDX_CX8)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1363
			hwcap_flags |= AV_386_CX8;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1364
		if (*edx & CPUID_INTC_EDX_CMOV)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1365
			hwcap_flags |= AV_386_CMOV;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1366
		if (*ecx & CPUID_INTC_ECX_MON)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1367
			hwcap_flags |= AV_386_MON;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1368
#if defined(CPUID_INTC_ECX_CX16)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1369
		if (*ecx & CPUID_INTC_ECX_CX16)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1370
			hwcap_flags |= AV_386_CX16;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1371
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1372
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1373
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1374
	if (cpuid_is_ht(cpu))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1375
		hwcap_flags |= AV_386_PAUSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1376
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1377
	if (cpi->cpi_xmaxeax < 0x80000001)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1378
		goto pass4_done;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1379
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1380
	switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1381
		uint32_t junk, *edx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1382
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1383
	case X86_VENDOR_Intel:	/* sigh */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1384
	case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1385
		edx = &cpi->cpi_support[AMD_EDX_FEATURES];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1386
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1387
		*edx = CPI_FEATURES_XTD_EDX(cpi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1388
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1389
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1390
		 * [no explicit support required beyond
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1391
		 * x87 fp context and exception handlers]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1392
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1393
		if (!fpu_exists)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1394
			*edx &= ~(CPUID_AMD_EDX_MMXamd |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1395
			    CPUID_AMD_EDX_3DNow | CPUID_AMD_EDX_3DNowx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1396
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1397
		if ((x86_feature & X86_ASYSC) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1398
			*edx &= ~CPUID_AMD_EDX_SYSC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1399
		if ((x86_feature & X86_NX) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1400
			*edx &= ~CPUID_AMD_EDX_NX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1401
#if !defined(_LP64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1402
		*edx &= ~CPUID_AMD_EDX_LM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1403
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1404
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1405
		 * Now map the supported feature vector to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1406
		 * things that we think userland will care about.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1407
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1408
		if (*edx & CPUID_AMD_EDX_SYSC)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1409
			hwcap_flags |= AV_386_AMD_SYSC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1410
		if (*edx & CPUID_AMD_EDX_MMXamd)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1411
			hwcap_flags |= AV_386_AMD_MMX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1412
		if (*edx & CPUID_AMD_EDX_3DNow)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1413
			hwcap_flags |= AV_386_AMD_3DNow;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1414
		if (*edx & CPUID_AMD_EDX_3DNowx)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1415
			hwcap_flags |= AV_386_AMD_3DNowx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1416
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1417
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1418
	case X86_VENDOR_TM:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1419
		edx = &cpi->cpi_support[TM_EDX_FEATURES];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1420
		(void) __cpuid_insn(0x80860001, &junk, &junk, edx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1421
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1422
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1423
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1424
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1425
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1426
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1427
pass4_done:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1428
	cpi->cpi_pass = 4;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1429
	return (hwcap_flags);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1430
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1431
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1432
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1433
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1434
 * Simulate the cpuid instruction using the data we previously
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1435
 * captured about this CPU.  We try our best to return the truth
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1436
 * about the hardware, independently of kernel support.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1437
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1438
uint32_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1439
cpuid_insn(cpu_t *cpu,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1440
    uint32_t eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1441
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1442
	struct cpuid_info *cpi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1443
	struct cpuidr *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1444
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1445
	if (cpu == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1446
		cpu = CPU;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1447
	cpi = cpu->cpu_m.mcpu_cpi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1448
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1449
	ASSERT(cpuid_checkpass(cpu, 3));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1450
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1451
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1452
	 * CPUID data is cached in two separate places: cpi_std for standard
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1453
	 * CPUID functions, and cpi_extd for extended CPUID functions.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1454
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1455
	if (eax <= cpi->cpi_maxeax && eax < NMAX_CPI_STD)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1456
		cp = &cpi->cpi_std[eax];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1457
	else if (eax >= 0x80000000 && eax <= cpi->cpi_xmaxeax &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1458
	    eax < 0x80000000 + NMAX_CPI_EXTD)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1459
		cp = &cpi->cpi_extd[eax - 0x80000000];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1460
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1461
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1462
		 * The caller is asking for data from an input parameter which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1463
		 * the kernel has not cached.  In this case we go fetch from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1464
		 * the hardware and return the data directly to the user.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1465
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1466
		return (__cpuid_insn(eax, ebx, ecx, edx));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1467
	*ebx = cp->cp_ebx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1468
	*ecx = cp->cp_ecx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1469
	*edx = cp->cp_edx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1470
	return (cp->cp_eax);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1471
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1472
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1473
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1474
cpuid_checkpass(cpu_t *cpu, int pass)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1475
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1476
	return (cpu != NULL && cpu->cpu_m.mcpu_cpi != NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1477
	    cpu->cpu_m.mcpu_cpi->cpi_pass >= pass);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1478
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1479
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1480
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1481
cpuid_getbrandstr(cpu_t *cpu, char *s, size_t n)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1482
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1483
	ASSERT(cpuid_checkpass(cpu, 3));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1484
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1485
	return (snprintf(s, n, "%s", cpu->cpu_m.mcpu_cpi->cpi_brandstr));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1486
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1487
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1488
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1489
cpuid_is_ht(cpu_t *cpu)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1490
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1491
	if (cpu == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1492
		cpu = CPU;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1493
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1494
	ASSERT(cpuid_checkpass(cpu, 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1495
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1496
	return (cpu->cpu_m.mcpu_cpi->cpi_chipid >= 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1497
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1498
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1499
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1500
 * AMD and Intel both implement the 64-bit variant of the syscall
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1501
 * instruction (syscallq), so if there's -any- support for syscall,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1502
 * cpuid currently says "yes, we support this".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1503
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1504
 * However, Intel decided to -not- implement the 32-bit variant of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1505
 * syscall instruction, so we provide a predicate to allow our caller
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1506
 * to test that subtlety here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1507
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1508
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1509
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1510
cpuid_syscall32_insn(cpu_t *cpu)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1511
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1512
	ASSERT(cpuid_checkpass((cpu == NULL ? CPU : cpu), 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1513
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1514
	if (x86_feature & X86_ASYSC)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1515
		return (x86_vendor != X86_VENDOR_Intel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1516
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1517
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1518
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1519
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1520
cpuid_getidstr(cpu_t *cpu, char *s, size_t n)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1521
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1522
	struct cpuid_info *cpi = cpu->cpu_m.mcpu_cpi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1523
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1524
	static const char fmt[] =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1525
	    "x86 (%s family %d model %d step %d clock %d MHz)";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1526
	static const char fmt_ht[] =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1527
	    "x86 (chipid 0x%x %s family %d model %d step %d clock %d MHz)";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1528
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1529
	ASSERT(cpuid_checkpass(cpu, 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1530
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1531
	if (cpuid_is_ht(cpu))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1532
		return (snprintf(s, n, fmt_ht, cpi->cpi_chipid,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1533
		    cpi->cpi_vendorstr, cpi->cpi_family, cpi->cpi_model,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1534
		    cpi->cpi_step, cpu->cpu_type_info.pi_clock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1535
	return (snprintf(s, n, fmt,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1536
	    cpi->cpi_vendorstr, cpi->cpi_family, cpi->cpi_model,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1537
	    cpi->cpi_step, cpu->cpu_type_info.pi_clock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1538
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1539
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1540
const char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1541
cpuid_getvendorstr(cpu_t *cpu)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1542
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1543
	ASSERT(cpuid_checkpass(cpu, 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1544
	return ((const char *)cpu->cpu_m.mcpu_cpi->cpi_vendorstr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1545
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1546
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1547
uint_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1548
cpuid_getvendor(cpu_t *cpu)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1549
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1550
	ASSERT(cpuid_checkpass(cpu, 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1551
	return (cpu->cpu_m.mcpu_cpi->cpi_vendor);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1552
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1553
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1554
uint_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1555
cpuid_getfamily(cpu_t *cpu)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1556
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1557
	ASSERT(cpuid_checkpass(cpu, 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1558
	return (cpu->cpu_m.mcpu_cpi->cpi_family);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1559
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1560
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1561
uint_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1562
cpuid_getmodel(cpu_t *cpu)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1563
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1564
	ASSERT(cpuid_checkpass(cpu, 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1565
	return (cpu->cpu_m.mcpu_cpi->cpi_model);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1566
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1567
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1568
uint_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1569
cpuid_get_ncpu_per_chip(cpu_t *cpu)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1570
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1571
	ASSERT(cpuid_checkpass(cpu, 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1572
	return (cpu->cpu_m.mcpu_cpi->cpi_ncpu_per_chip);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1573
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1574
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1575
uint_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1576
cpuid_getstep(cpu_t *cpu)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1577
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1578
	ASSERT(cpuid_checkpass(cpu, 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1579
	return (cpu->cpu_m.mcpu_cpi->cpi_step);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1580
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1581
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1582
chipid_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1583
chip_plat_get_chipid(cpu_t *cpu)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1584
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1585
	ASSERT(cpuid_checkpass(cpu, 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1586
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1587
	if (cpuid_is_ht(cpu))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1588
		return (cpu->cpu_m.mcpu_cpi->cpi_chipid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1589
	return (cpu->cpu_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1590
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1591
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1592
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1593
chip_plat_get_clogid(cpu_t *cpu)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1594
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1595
	ASSERT(cpuid_checkpass(cpu, 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1596
	return (cpu->cpu_m.mcpu_cpi->cpi_clogid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1597
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1598
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1599
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1600
cpuid_get_addrsize(cpu_t *cpu, uint_t *pabits, uint_t *vabits)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1601
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1602
	struct cpuid_info *cpi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1603
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1604
	if (cpu == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1605
		cpu = CPU;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1606
	cpi = cpu->cpu_m.mcpu_cpi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1607
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1608
	ASSERT(cpuid_checkpass(cpu, 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1609
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1610
	if (pabits)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1611
		*pabits = cpi->cpi_pabits;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1612
	if (vabits)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1613
		*vabits = cpi->cpi_vabits;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1614
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1615
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1616
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1617
 * Returns the number of data TLB entries for a corresponding
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1618
 * pagesize.  If it can't be computed, or isn't known, the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1619
 * routine returns zero.  If you ask about an architecturally
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1620
 * impossible pagesize, the routine will panic (so that the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1621
 * hat implementor knows that things are inconsistent.)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1622
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1623
uint_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1624
cpuid_get_dtlb_nent(cpu_t *cpu, size_t pagesize)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1625
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1626
	struct cpuid_info *cpi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1627
	uint_t dtlb_nent = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1628
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1629
	if (cpu == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1630
		cpu = CPU;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1631
	cpi = cpu->cpu_m.mcpu_cpi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1632
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1633
	ASSERT(cpuid_checkpass(cpu, 1));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1634
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1635
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1636
	 * Check the L2 TLB info
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1637
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1638
	if (cpi->cpi_xmaxeax >= 0x80000006) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1639
		struct cpuidr *cp = &cpi->cpi_extd[6];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1640
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1641
		switch (pagesize) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1642
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1643
		case 4 * 1024:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1644
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1645
			 * All zero in the top 16 bits of the register
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1646
			 * indicates a unified TLB. Size is in low 16 bits.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1647
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1648
			if ((cp->cp_ebx & 0xffff0000) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1649
				dtlb_nent = cp->cp_ebx & 0x0000ffff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1650
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1651
				dtlb_nent = BITX(cp->cp_ebx, 27, 16);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1652
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1653
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1654
		case 2 * 1024 * 1024:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1655
			if ((cp->cp_eax & 0xffff0000) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1656
				dtlb_nent = cp->cp_eax & 0x0000ffff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1657
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1658
				dtlb_nent = BITX(cp->cp_eax, 27, 16);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1659
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1660
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1661
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1662
			panic("unknown L2 pagesize");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1663
			/*NOTREACHED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1664
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1665
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1666
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1667
	if (dtlb_nent != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1668
		return (dtlb_nent);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1669
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1670
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1671
	 * No L2 TLB support for this size, try L1.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1672
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1673
	if (cpi->cpi_xmaxeax >= 0x80000005) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1674
		struct cpuidr *cp = &cpi->cpi_extd[5];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1675
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1676
		switch (pagesize) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1677
		case 4 * 1024:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1678
			dtlb_nent = BITX(cp->cp_ebx, 23, 16);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1679
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1680
		case 2 * 1024 * 1024:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1681
			dtlb_nent = BITX(cp->cp_eax, 23, 16);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1682
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1683
		default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1684
			panic("unknown L1 d-TLB pagesize");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1685
			/*NOTREACHED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1686
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1687
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1688
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1689
	return (dtlb_nent);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1690
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1691
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1692
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1693
 * Return 0 if the erratum is not present or not applicable, positive
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1694
 * if it is, and negative if the status of the erratum is unknown.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1695
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1696
 * See "Revision Guide for AMD Athlon(tm) 64 and AMD Opteron(tm)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1697
 * Processors" #25759, Rev 3.50, May 2005
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1698
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1699
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1700
cpuid_opteron_erratum(cpu_t *cpu, uint_t erratum)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1701
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1702
	struct cpuid_info *cpi = cpu->cpu_m.mcpu_cpi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1703
	uint_t eax;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1704
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1705
	if (cpi->cpi_vendor != X86_VENDOR_AMD)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1706
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1707
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1708
	eax = cpi->cpi_std[1].cp_eax;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1709
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1710
#define	SH_B0(eax)	(eax == 0xf40 || eax == 0xf50)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1711
#define	SH_B3(eax) 	(eax == 0xf51)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1712
#define	B(eax)		(SH_B0(eax) | SH_B3(eax))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1713
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1714
#define	SH_C0(eax)	(eax == 0xf48 || eax == 0xf58)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1715
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1716
#define	SH_CG(eax)	(eax == 0xf4a || eax == 0xf5a || eax == 0xf7a)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1717
#define	DH_CG(eax)	(eax == 0xfc0 || eax == 0xfe0 || eax == 0xff0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1718
#define	CH_CG(eax)	(eax == 0xf82 || eax == 0xfb2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1719
#define	CG(eax)		(SH_CG(eax) | DH_CG(eax) | CH_CG(eax))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1720
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1721
#define	SH_D0(eax)	(eax == 0x10f40 || eax == 0x10f50 || eax == 0x10f70)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1722
#define	DH_D0(eax)	(eax == 0x10fc0 || eax == 0x10ff0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1723
#define	CH_D0(eax)	(eax == 0x10f80 || eax == 0x10fb0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1724
#define	D0(eax)		(SH_D0(eax) | DH_D0(eax) | CH_D0(eax))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1725
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1726
#define	SH_E0(eax)	(eax == 0x20f50 || eax == 0x20f40 || eax == 0x20f70)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1727
#define	JH_E1(eax)	(eax == 0x20f10)	/* JH8_E0 had 0x20f30 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1728
#define	DH_E3(eax)	(eax == 0x20fc0 || eax == 0x20ff0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1729
#define	SH_E4(eax)	(eax == 0x20f51 || eax == 0x20f71)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1730
#define	BH_E4(eax)	(eax == 0x20fb1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1731
#define	SH_E5(eax)	(eax == 0x20f42)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1732
#define	DH_E6(eax)	(eax == 0x20ff2 || eax == 0x20fc2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1733
#define	JH_E6(eax)	(eax == 0x20f12 || eax == 0x20f32)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1734
#define	EX(eax)		(SH_E0(eax) | JH_E1(eax) | DH_E3(eax) | SH_E4(eax) | \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1735
			    BH_E4(eax) | SH_E5(eax) | DH_E6(eax) | JH_E6(eax))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1736
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1737
	switch (erratum) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1738
	case 1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1739
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1740
	case 51:	/* what does the asterisk mean? */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1741
		return (B(eax) || SH_C0(eax) || CG(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1742
	case 52:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1743
		return (B(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1744
	case 57:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1745
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1746
	case 58:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1747
		return (B(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1748
	case 60:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1749
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1750
	case 61:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1751
	case 62:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1752
	case 63:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1753
	case 64:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1754
	case 65:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1755
	case 66:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1756
	case 68:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1757
	case 69:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1758
	case 70:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1759
	case 71:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1760
		return (B(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1761
	case 72:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1762
		return (SH_B0(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1763
	case 74:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1764
		return (B(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1765
	case 75:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1766
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1767
	case 76:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1768
		return (B(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1769
	case 77:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1770
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1771
	case 78:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1772
		return (B(eax) || SH_C0(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1773
	case 79:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1774
		return (B(eax) || SH_C0(eax) || CG(eax) || D0(eax) || EX(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1775
	case 80:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1776
	case 81:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1777
	case 82:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1778
		return (B(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1779
	case 83:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1780
		return (B(eax) || SH_C0(eax) || CG(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1781
	case 85:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1782
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1783
	case 86:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1784
		return (SH_C0(eax) || CG(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1785
	case 88:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1786
#if !defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1787
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1788
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1789
		return (B(eax) || SH_C0(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1790
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1791
	case 89:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1792
		return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1793
	case 90:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1794
		return (B(eax) || SH_C0(eax) || CG(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1795
	case 91:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1796
	case 92:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1797
		return (B(eax) || SH_C0(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1798
	case 93:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1799
		return (SH_C0(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1800
	case 94:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1801
		return (B(eax) || SH_C0(eax) || CG(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1802
	case 95:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1803
#if !defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1804
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1805
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1806
		return (B(eax) || SH_C0(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1807
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1808
	case 96:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1809
		return (B(eax) || SH_C0(eax) || CG(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1810
	case 97:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1811
	case 98:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1812
		return (SH_C0(eax) || CG(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1813
	case 99:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1814
		return (B(eax) || SH_C0(eax) || CG(eax) || D0(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1815
	case 100:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1816
		return (B(eax) || SH_C0(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1817
	case 101:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1818
	case 103:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1819
		return (B(eax) || SH_C0(eax) || CG(eax) || D0(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1820
	case 104:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1821
		return (SH_C0(eax) || CG(eax) || D0(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1822
	case 105:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1823
	case 106:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1824
	case 107:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1825
		return (B(eax) || SH_C0(eax) || CG(eax) || D0(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1826
	case 108:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1827
		return (DH_CG(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1828
	case 109:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1829
		return (SH_C0(eax) || CG(eax) || D0(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1830
	case 110:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1831
		return (D0(eax) || EX(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1832
	case 111:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1833
		return (CG(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1834
	case 112:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1835
		return (B(eax) || SH_C0(eax) || CG(eax) || D0(eax) || EX(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1836
	case 113:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1837
		return (eax == 0x20fc0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1838
	case 114:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1839
		return (SH_E0(eax) || JH_E1(eax) || DH_E3(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1840
	case 115:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1841
		return (SH_E0(eax) || JH_E1(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1842
	case 116:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1843
		return (SH_E0(eax) || JH_E1(eax) || DH_E3(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1844
	case 117:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1845
		return (B(eax) || SH_C0(eax) || CG(eax) || D0(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1846
	case 118:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1847
		return (SH_E0(eax) || JH_E1(eax) || SH_E4(eax) || BH_E4(eax) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1848
		    JH_E6(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1849
	case 121:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1850
		return (B(eax) || SH_C0(eax) || CG(eax) || D0(eax) || EX(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1851
	case 122:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1852
		return (SH_C0(eax) || CG(eax) || D0(eax) || EX(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1853
	case 123:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1854
		return (JH_E1(eax) || BH_E4(eax) || JH_E6(eax));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1855
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1856
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1857
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1858
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1859
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1860
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1861
static const char assoc_str[] = "associativity";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1862
static const char line_str[] = "line-size";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1863
static const char size_str[] = "size";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1864
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1865
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1866
add_cache_prop(dev_info_t *devi, const char *label, const char *type,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1867
    uint32_t val)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1868
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1869
	char buf[128];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1870
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1871
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1872
	 * ndi_prop_update_int() is used because it is desirable for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1873
	 * DDI_PROP_HW_DEF and DDI_PROP_DONTSLEEP to be set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1874
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1875
	if (snprintf(buf, sizeof (buf), "%s-%s", label, type) < sizeof (buf))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1876
		(void) ndi_prop_update_int(DDI_DEV_T_NONE, devi, buf, val);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1877
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1878
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1879
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1880
 * Intel-style cache/tlb description
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1881
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1882
 * Standard cpuid level 2 gives a randomly ordered
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1883
 * selection of tags that index into a table that describes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1884
 * cache and tlb properties.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1885
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1886
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1887
static const char l1_icache_str[] = "l1-icache";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1888
static const char l1_dcache_str[] = "l1-dcache";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1889
static const char l2_cache_str[] = "l2-cache";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1890
static const char itlb4k_str[] = "itlb-4K";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1891
static const char dtlb4k_str[] = "dtlb-4K";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1892
static const char itlb4M_str[] = "itlb-4M";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1893
static const char dtlb4M_str[] = "dtlb-4M";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1894
static const char itlb424_str[] = "itlb-4K-2M-4M";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1895
static const char dtlb44_str[] = "dtlb-4K-4M";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1896
static const char sl1_dcache_str[] = "sectored-l1-dcache";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1897
static const char sl2_cache_str[] = "sectored-l2-cache";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1898
static const char itrace_str[] = "itrace-cache";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1899
static const char sl3_cache_str[] = "sectored-l3-cache";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1900
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1901
static const struct cachetab {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1902
	uint8_t 	ct_code;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1903
	uint8_t		ct_assoc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1904
	uint16_t 	ct_line_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1905
	size_t		ct_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1906
	const char	*ct_label;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1907
} intel_ctab[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1908
	/* maintain descending order! */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1909
	{ 0xb3, 4, 0, 128, dtlb4k_str },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1910
	{ 0xb0, 4, 0, 128, itlb4k_str },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1911
	{ 0x87, 8, 64, 1024*1024, l2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1912
	{ 0x86, 4, 64, 512*1024, l2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1913
	{ 0x85, 8, 32, 2*1024*1024, l2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1914
	{ 0x84, 8, 32, 1024*1024, l2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1915
	{ 0x83, 8, 32, 512*1024, l2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1916
	{ 0x82, 8, 32, 256*1024, l2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1917
	{ 0x81, 8, 32, 128*1024, l2_cache_str},		/* suspect! */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1918
	{ 0x7f, 2, 64, 512*1024, l2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1919
	{ 0x7d, 8, 64, 2*1024*1024, sl2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1920
	{ 0x7c, 8, 64, 1024*1024, sl2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1921
	{ 0x7b, 8, 64, 512*1024, sl2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1922
	{ 0x7a, 8, 64, 256*1024, sl2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1923
	{ 0x79, 8, 64, 128*1024, sl2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1924
	{ 0x78, 8, 64, 1024*1024, l2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1925
	{ 0x72, 8, 0, 32*1024, itrace_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1926
	{ 0x71, 8, 0, 16*1024, itrace_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1927
	{ 0x70, 8, 0, 12*1024, itrace_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1928
	{ 0x68, 4, 64, 32*1024, sl1_dcache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1929
	{ 0x67, 4, 64, 16*1024, sl1_dcache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1930
	{ 0x66, 4, 64, 8*1024, sl1_dcache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1931
	{ 0x60, 8, 64, 16*1024, sl1_dcache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1932
	{ 0x5d, 0, 0, 256, dtlb44_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1933
	{ 0x5c, 0, 0, 128, dtlb44_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1934
	{ 0x5b, 0, 0, 64, dtlb44_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1935
	{ 0x52, 0, 0, 256, itlb424_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1936
	{ 0x51, 0, 0, 128, itlb424_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1937
	{ 0x50, 0, 0, 64, itlb424_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1938
	{ 0x45, 4, 32, 2*1024*1024, l2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1939
	{ 0x44, 4, 32, 1024*1024, l2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1940
	{ 0x43, 4, 32, 512*1024, l2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1941
	{ 0x42, 4, 32, 256*1024, l2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1942
	{ 0x41, 4, 32, 128*1024, l2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1943
	{ 0x3c, 4, 64, 256*1024, sl2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1944
	{ 0x3b, 2, 64, 128*1024, sl2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1945
	{ 0x39, 4, 64, 128*1024, sl2_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1946
	{ 0x30, 8, 64, 32*1024, l1_icache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1947
	{ 0x2c, 8, 64, 32*1024, l1_dcache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1948
	{ 0x29, 8, 64, 4096*1024, sl3_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1949
	{ 0x25, 8, 64, 2048*1024, sl3_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1950
	{ 0x23, 8, 64, 1024*1024, sl3_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1951
	{ 0x22, 4, 64, 512*1024, sl3_cache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1952
	{ 0x0c, 4, 32, 16*1024, l1_dcache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1953
	{ 0x0a, 2, 32, 8*1024, l1_dcache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1954
	{ 0x08, 4, 32, 16*1024, l1_icache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1955
	{ 0x06, 4, 32, 8*1024, l1_icache_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1956
	{ 0x04, 4, 0, 8, dtlb4M_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1957
	{ 0x03, 4, 0, 64, dtlb4k_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1958
	{ 0x02, 4, 0, 2, itlb4M_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1959
	{ 0x01, 4, 0, 32, itlb4k_str},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1960
	{ 0 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1961
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1962
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1963
static const struct cachetab cyrix_ctab[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1964
	{ 0x70, 4, 0, 32, "tlb-4K" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1965
	{ 0x80, 4, 16, 16*1024, "l1-cache" },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1966
	{ 0 }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1967
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1968
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1969
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1970
 * Search a cache table for a matching entry
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1971
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1972
static const struct cachetab *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1973
find_cacheent(const struct cachetab *ct, uint_t code)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1974
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1975
	if (code != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1976
		for (; ct->ct_code != 0; ct++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1977
			if (ct->ct_code <= code)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1978
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1979
		if (ct->ct_code == code)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1980
			return (ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1981
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1982
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1983
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1984
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1985
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1986
 * Walk the cacheinfo descriptor, applying 'func' to every valid element
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1987
 * The walk is terminated if the walker returns non-zero.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1988
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1989
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1990
intel_walk_cacheinfo(struct cpuid_info *cpi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1991
    void *arg, int (*func)(void *, const struct cachetab *))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1992
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1993
	const struct cachetab *ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1994
	uint8_t *dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1995
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1996
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1997
	if ((dp = cpi->cpi_cacheinfo) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1998
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1999
	for (i = 0; i < cpi->cpi_ncache; i++, dp++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2000
		if ((ct = find_cacheent(intel_ctab, *dp)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2001
			if (func(arg, ct) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2002
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2003
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2004
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2005
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2006
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2007
 * (Like the Intel one, except for Cyrix CPUs)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2008
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2009
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2010
cyrix_walk_cacheinfo(struct cpuid_info *cpi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2011
    void *arg, int (*func)(void *, const struct cachetab *))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2012
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2013
	const struct cachetab *ct;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2014
	uint8_t *dp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2015
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2016
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2017
	if ((dp = cpi->cpi_cacheinfo) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2018
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2019
	for (i = 0; i < cpi->cpi_ncache; i++, dp++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2020
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2021
		 * Search Cyrix-specific descriptor table first ..
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2022
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2023
		if ((ct = find_cacheent(cyrix_ctab, *dp)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2024
			if (func(arg, ct) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2025
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2026
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2027
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2028
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2029
		 * .. else fall back to the Intel one
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2030
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2031
		if ((ct = find_cacheent(intel_ctab, *dp)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2032
			if (func(arg, ct) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2033
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2034
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2035
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2036
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2037
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2038
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2039
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2040
 * A cacheinfo walker that adds associativity, line-size, and size properties
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2041
 * to the devinfo node it is passed as an argument.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2042
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2043
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2044
add_cacheent_props(void *arg, const struct cachetab *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2045
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2046
	dev_info_t *devi = arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2047
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2048
	add_cache_prop(devi, ct->ct_label, assoc_str, ct->ct_assoc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2049
	if (ct->ct_line_size != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2050
		add_cache_prop(devi, ct->ct_label, line_str,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2051
		    ct->ct_line_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2052
	add_cache_prop(devi, ct->ct_label, size_str, ct->ct_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2053
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2054
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2055
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2056
static const char fully_assoc[] = "fully-associative?";
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2057
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2058
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2059
 * AMD style cache/tlb description
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2060
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2061
 * Extended functions 5 and 6 directly describe properties of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2062
 * tlbs and various cache levels.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2063
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2064
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2065
add_amd_assoc(dev_info_t *devi, const char *label, uint_t assoc)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2066
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2067
	switch (assoc) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2068
	case 0:	/* reserved; ignore */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2069
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2070
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2071
		add_cache_prop(devi, label, assoc_str, assoc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2072
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2073
	case 0xff:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2074
		add_cache_prop(devi, label, fully_assoc, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2075
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2076
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2077
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2078
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2079
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2080
add_amd_tlb(dev_info_t *devi, const char *label, uint_t assoc, uint_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2081
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2082
	if (size == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2083
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2084
	add_cache_prop(devi, label, size_str, size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2085
	add_amd_assoc(devi, label, assoc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2086
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2087
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2088
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2089
add_amd_cache(dev_info_t *devi, const char *label,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2090
    uint_t size, uint_t assoc, uint_t lines_per_tag, uint_t line_size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2091
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2092
	if (size == 0 || line_size == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2093
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2094
	add_amd_assoc(devi, label, assoc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2095
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2096
	 * Most AMD parts have a sectored cache. Multiple cache lines are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2097
	 * associated with each tag. A sector consists of all cache lines
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2098
	 * associated with a tag. For example, the AMD K6-III has a sector
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2099
	 * size of 2 cache lines per tag.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2100
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2101
	if (lines_per_tag != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2102
		add_cache_prop(devi, label, "lines-per-tag", lines_per_tag);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2103
	add_cache_prop(devi, label, line_str, line_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2104
	add_cache_prop(devi, label, size_str, size * 1024);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2105
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2106
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2107
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2108
add_amd_l2_assoc(dev_info_t *devi, const char *label, uint_t assoc)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2109
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2110
	switch (assoc) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2111
	case 0:	/* off */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2112
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2113
	case 1:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2114
	case 2:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2115
	case 4:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2116
		add_cache_prop(devi, label, assoc_str, assoc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2117
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2118
	case 6:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2119
		add_cache_prop(devi, label, assoc_str, 8);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2120
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2121
	case 8:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2122
		add_cache_prop(devi, label, assoc_str, 16);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2123
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2124
	case 0xf:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2125
		add_cache_prop(devi, label, fully_assoc, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2126
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2127
	default: /* reserved; ignore */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2128
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2129
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2130
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2131
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2132
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2133
add_amd_l2_tlb(dev_info_t *devi, const char *label, uint_t assoc, uint_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2134
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2135
	if (size == 0 || assoc == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2136
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2137
	add_amd_l2_assoc(devi, label, assoc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2138
	add_cache_prop(devi, label, size_str, size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2139
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2140
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2141
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2142
add_amd_l2_cache(dev_info_t *devi, const char *label,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2143
    uint_t size, uint_t assoc, uint_t lines_per_tag, uint_t line_size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2144
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2145
	if (size == 0 || assoc == 0 || line_size == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2146
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2147
	add_amd_l2_assoc(devi, label, assoc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2148
	if (lines_per_tag != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2149
		add_cache_prop(devi, label, "lines-per-tag", lines_per_tag);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2150
	add_cache_prop(devi, label, line_str, line_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2151
	add_cache_prop(devi, label, size_str, size * 1024);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2152
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2153
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2154
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2155
amd_cache_info(struct cpuid_info *cpi, dev_info_t *devi)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2156
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2157
	struct cpuidr *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2158
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2159
	if (cpi->cpi_xmaxeax < 0x80000005)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2160
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2161
	cp = &cpi->cpi_extd[5];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2162
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2163
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2164
	 * 4M/2M L1 TLB configuration
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2165
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2166
	 * We report the size for 2M pages because AMD uses two
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2167
	 * TLB entries for one 4M page.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2168
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2169
	add_amd_tlb(devi, "dtlb-2M",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2170
	    BITX(cp->cp_eax, 31, 24), BITX(cp->cp_eax, 23, 16));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2171
	add_amd_tlb(devi, "itlb-2M",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2172
	    BITX(cp->cp_eax, 15, 8), BITX(cp->cp_eax, 7, 0));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2173
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2174
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2175
	 * 4K L1 TLB configuration
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2176
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2177
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2178
	switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2179
		uint_t nentries;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2180
	case X86_VENDOR_TM:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2181
		if (cpi->cpi_family >= 5) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2182
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2183
			 * Crusoe processors have 256 TLB entries, but
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2184
			 * cpuid data format constrains them to only
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2185
			 * reporting 255 of them.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2186
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2187
			if ((nentries = BITX(cp->cp_ebx, 23, 16)) == 255)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2188
				nentries = 256;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2189
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2190
			 * Crusoe processors also have a unified TLB
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2191
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2192
			add_amd_tlb(devi, "tlb-4K", BITX(cp->cp_ebx, 31, 24),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2193
			    nentries);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2194
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2195
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2196
		/*FALLTHROUGH*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2197
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2198
		add_amd_tlb(devi, itlb4k_str,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2199
		    BITX(cp->cp_ebx, 31, 24), BITX(cp->cp_ebx, 23, 16));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2200
		add_amd_tlb(devi, dtlb4k_str,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2201
		    BITX(cp->cp_ebx, 15, 8), BITX(cp->cp_ebx, 7, 0));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2202
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2203
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2204
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2205
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2206
	 * data L1 cache configuration
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2207
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2208
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2209
	add_amd_cache(devi, l1_dcache_str,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2210
	    BITX(cp->cp_ecx, 31, 24), BITX(cp->cp_ecx, 23, 16),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2211
	    BITX(cp->cp_ecx, 15, 8), BITX(cp->cp_ecx, 7, 0));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2212
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2213
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2214
	 * code L1 cache configuration
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2215
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2216
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2217
	add_amd_cache(devi, l1_icache_str,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2218
	    BITX(cp->cp_edx, 31, 24), BITX(cp->cp_edx, 23, 16),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2219
	    BITX(cp->cp_edx, 15, 8), BITX(cp->cp_edx, 7, 0));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2220
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2221
	if (cpi->cpi_xmaxeax < 0x80000006)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2222
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2223
	cp = &cpi->cpi_extd[6];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2224
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2225
	/* Check for a unified L2 TLB for large pages */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2226
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2227
	if (BITX(cp->cp_eax, 31, 16) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2228
		add_amd_l2_tlb(devi, "l2-tlb-2M",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2229
		    BITX(cp->cp_eax, 15, 12), BITX(cp->cp_eax, 11, 0));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2230
	else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2231
		add_amd_l2_tlb(devi, "l2-dtlb-2M",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2232
		    BITX(cp->cp_eax, 31, 28), BITX(cp->cp_eax, 27, 16));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2233
		add_amd_l2_tlb(devi, "l2-itlb-2M",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2234
		    BITX(cp->cp_eax, 15, 12), BITX(cp->cp_eax, 11, 0));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2235
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2236
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2237
	/* Check for a unified L2 TLB for 4K pages */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2238
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2239
	if (BITX(cp->cp_ebx, 31, 16) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2240
		add_amd_l2_tlb(devi, "l2-tlb-4K",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2241
		    BITX(cp->cp_eax, 15, 12), BITX(cp->cp_eax, 11, 0));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2242
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2243
		add_amd_l2_tlb(devi, "l2-dtlb-4K",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2244
		    BITX(cp->cp_eax, 31, 28), BITX(cp->cp_eax, 27, 16));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2245
		add_amd_l2_tlb(devi, "l2-itlb-4K",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2246
		    BITX(cp->cp_eax, 15, 12), BITX(cp->cp_eax, 11, 0));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2247
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2248
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2249
	add_amd_l2_cache(devi, l2_cache_str,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2250
	    BITX(cp->cp_ecx, 31, 16), BITX(cp->cp_ecx, 15, 12),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2251
	    BITX(cp->cp_ecx, 11, 8), BITX(cp->cp_ecx, 7, 0));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2252
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2253
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2254
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2255
 * There are two basic ways that the x86 world describes it cache
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2256
 * and tlb architecture - Intel's way and AMD's way.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2257
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2258
 * Return which flavor of cache architecture we should use
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2259
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2260
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2261
x86_which_cacheinfo(struct cpuid_info *cpi)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2262
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2263
	switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2264
	case X86_VENDOR_Intel:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2265
		if (cpi->cpi_maxeax >= 2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2266
			return (X86_VENDOR_Intel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2267
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2268
	case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2269
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2270
		 * The K5 model 1 was the first part from AMD that reported
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2271
		 * cache sizes via extended cpuid functions.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2272
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2273
		if (cpi->cpi_family > 5 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2274
		    (cpi->cpi_family == 5 && cpi->cpi_model >= 1))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2275
			return (X86_VENDOR_AMD);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2276
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2277
	case X86_VENDOR_TM:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2278
		if (cpi->cpi_family >= 5)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2279
			return (X86_VENDOR_AMD);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2280
		/*FALLTHROUGH*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2281
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2282
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2283
		 * If they have extended CPU data for 0x80000005
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2284
		 * then we assume they have AMD-format cache
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2285
		 * information.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2286
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2287
		 * If not, and the vendor happens to be Cyrix,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2288
		 * then try our-Cyrix specific handler.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2289
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2290
		 * If we're not Cyrix, then assume we're using Intel's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2291
		 * table-driven format instead.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2292
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2293
		if (cpi->cpi_xmaxeax >= 0x80000005)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2294
			return (X86_VENDOR_AMD);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2295
		else if (cpi->cpi_vendor == X86_VENDOR_Cyrix)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2296
			return (X86_VENDOR_Cyrix);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2297
		else if (cpi->cpi_maxeax >= 2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2298
			return (X86_VENDOR_Intel);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2299
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2300
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2301
	return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2302
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2303
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2304
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2305
 * create a node for the given cpu under the prom root node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2306
 * Also, create a cpu node in the device tree.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2307
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2308
static dev_info_t *cpu_nex_devi = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2309
static kmutex_t cpu_node_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2310
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2311
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2312
 * Called from post_startup() and mp_startup()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2313
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2314
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2315
add_cpunode2devtree(processorid_t cpu_id, struct cpuid_info *cpi)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2316
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2317
	dev_info_t *cpu_devi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2318
	int create;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2319
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2320
	mutex_enter(&cpu_node_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2321
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2322
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2323
	 * create a nexus node for all cpus identified as 'cpu_id' under
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2324
	 * the root node.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2325
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2326
	if (cpu_nex_devi == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2327
		if (ndi_devi_alloc(ddi_root_node(), "cpus",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2328
		    (dnode_t)DEVI_SID_NODEID, &cpu_nex_devi) != NDI_SUCCESS) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2329
			mutex_exit(&cpu_node_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2330
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2331
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2332
		(void) ndi_devi_online(cpu_nex_devi, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2333
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2334
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2335
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2336
	 * create a child node for cpu identified as 'cpu_id'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2337
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2338
	cpu_devi = ddi_add_child(cpu_nex_devi, "cpu", DEVI_SID_NODEID,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2339
		cpu_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2340
	if (cpu_devi == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2341
		mutex_exit(&cpu_node_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2342
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2343
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2344
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2345
	/* device_type */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2346
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2347
	(void) ndi_prop_update_string(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2348
	    "device_type", "cpu");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2349
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2350
	/* reg */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2351
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2352
	(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2353
	    "reg", cpu_id);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2354
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2355
	/* cpu-mhz, and clock-frequency */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2356
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2357
	if (cpu_freq > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2358
		long long mul;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2359
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2360
		(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2361
		    "cpu-mhz", cpu_freq);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2362
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2363
		if ((mul = cpu_freq * 1000000LL) <= INT_MAX)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2364
			(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2365
			    "clock-frequency", (int)mul);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2366
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2367
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2368
	(void) ndi_devi_online(cpu_devi, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2369
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2370
	if ((x86_feature & X86_CPUID) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2371
		mutex_exit(&cpu_node_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2372
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2373
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2374
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2375
	/* vendor-id */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2376
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2377
	(void) ndi_prop_update_string(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2378
		"vendor-id", cpi->cpi_vendorstr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2379
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2380
	if (cpi->cpi_maxeax == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2381
		mutex_exit(&cpu_node_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2382
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2383
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2384
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2385
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2386
	 * family, model, and step
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2387
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2388
	(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2389
		"family", CPI_FAMILY(cpi));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2390
	(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2391
		"cpu-model", CPI_MODEL(cpi));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2392
	(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2393
		"stepping-id", CPI_STEP(cpi));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2394
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2395
	/* type */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2396
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2397
	switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2398
	case X86_VENDOR_Intel:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2399
		create = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2400
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2401
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2402
		create = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2403
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2404
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2405
	if (create)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2406
		(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2407
			"type", CPI_TYPE(cpi));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2408
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2409
	/* ext-family */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2410
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2411
	switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2412
	case X86_VENDOR_Intel:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2413
	case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2414
		create = cpi->cpi_family >= 0xf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2415
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2416
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2417
		create = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2418
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2419
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2420
	if (create)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2421
		(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2422
		    "ext-family", CPI_FAMILY_XTD(cpi));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2423
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2424
	/* ext-model */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2425
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2426
	switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2427
	case X86_VENDOR_Intel:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2428
	case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2429
		create = CPI_MODEL(cpi) == 0xf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2430
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2431
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2432
		create = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2433
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2434
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2435
	if (create)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2436
		(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2437
			"ext-model", CPI_MODEL_XTD(cpi));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2438
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2439
	/* generation */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2440
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2441
	switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2442
	case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2443
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2444
		 * AMD K5 model 1 was the first part to support this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2445
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2446
		create = cpi->cpi_xmaxeax >= 0x80000001;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2447
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2448
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2449
		create = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2450
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2451
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2452
	if (create)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2453
		(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2454
		    "generation", BITX((cpi)->cpi_extd[1].cp_eax, 11, 8));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2455
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2456
	/* brand-id */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2457
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2458
	switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2459
	case X86_VENDOR_Intel:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2460
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2461
		 * brand id first appeared on Pentium III Xeon model 8,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2462
		 * and Celeron model 8 processors and Opteron
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2463
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2464
		create = cpi->cpi_family > 6 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2465
		    (cpi->cpi_family == 6 && cpi->cpi_model >= 8);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2466
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2467
	case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2468
		create = cpi->cpi_family >= 0xf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2469
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2470
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2471
		create = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2472
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2473
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2474
	if (create && cpi->cpi_brandid != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2475
		(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2476
		    "brand-id", cpi->cpi_brandid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2477
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2478
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2479
	/* chunks, and apic-id */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2480
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2481
	switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2482
	case X86_VENDOR_Intel:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2483
	case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2484
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2485
		 * first available on Pentium IV and Opteron (K8)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2486
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2487
		create = cpi->cpi_family >= 0xf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2488
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2489
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2490
		create = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2491
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2492
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2493
	if (create) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2494
		(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2495
			"chunks", CPI_CHUNKS(cpi));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2496
		(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2497
			"apic-id", CPI_APIC_ID(cpi));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2498
		if (cpi->cpi_chipid >= 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2499
			(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2500
			    "chip#", cpi->cpi_chipid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2501
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2502
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2503
	/* cpuid-features */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2504
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2505
	(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2506
	    "cpuid-features", CPI_FEATURES_EDX(cpi));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2507
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2508
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2509
	/* cpuid-features-ecx */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2510
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2511
	switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2512
	case X86_VENDOR_Intel:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2513
		create = cpi->cpi_family >= 0xf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2514
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2515
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2516
		create = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2517
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2518
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2519
	if (create)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2520
		(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2521
		    "cpuid-features-ecx", CPI_FEATURES_ECX(cpi));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2522
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2523
	/* ext-cpuid-features */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2524
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2525
	switch (cpi->cpi_vendor) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2526
	case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2527
	case X86_VENDOR_Cyrix:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2528
	case X86_VENDOR_TM:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2529
	case X86_VENDOR_Centaur:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2530
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2531
		 * The extended cpuid features are not relevant on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2532
		 * Intel but are available from the AMD K5 model 1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2533
		 * and most Cyrix GXm and later.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2534
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2535
		create = cpi->cpi_xmaxeax >= 0x80000001;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2536
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2537
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2538
		create = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2539
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2540
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2541
	if (create)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2542
		(void) ndi_prop_update_int(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2543
			"ext-cpuid-features", CPI_FEATURES_XTD_EDX(cpi));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2544
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2545
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2546
	 * Brand String first appeared in Intel Pentium IV, AMD K5
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2547
	 * model 1, and Cyrix GXm.  On earlier models we try and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2548
	 * simulate something similar .. so this string should always
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2549
	 * same -something- about the processor, however lame.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2550
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2551
	(void) ndi_prop_update_string(DDI_DEV_T_NONE, cpu_devi,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2552
	    "brand-string", cpi->cpi_brandstr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2553
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2554
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2555
	 * Finally, cache and tlb information
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2556
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2557
	switch (x86_which_cacheinfo(cpi)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2558
	case X86_VENDOR_Intel:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2559
		intel_walk_cacheinfo(cpi, cpu_devi, add_cacheent_props);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2560
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2561
	case X86_VENDOR_Cyrix:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2562
		cyrix_walk_cacheinfo(cpi, cpu_devi, add_cacheent_props);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2563
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2564
	case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2565
		amd_cache_info(cpi, cpu_devi);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2566
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2567
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2568
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2569
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2570
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2571
	mutex_exit(&cpu_node_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2572
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2573
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2574
struct l2info {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2575
	int *l2i_csz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2576
	int *l2i_lsz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2577
	int *l2i_assoc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2578
	int l2i_ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2579
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2580
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2581
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2582
 * A cacheinfo walker that fetches the size, line-size and associativity
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2583
 * of the L2 cache
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2584
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2585
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2586
intel_l2cinfo(void *arg, const struct cachetab *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2587
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2588
	struct l2info *l2i = arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2589
	int *ip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2590
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2591
	if (ct->ct_label != l2_cache_str &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2592
	    ct->ct_label != sl2_cache_str)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2593
		return (0);	/* not an L2 -- keep walking */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2594
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2595
	if ((ip = l2i->l2i_csz) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2596
		*ip = ct->ct_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2597
	if ((ip = l2i->l2i_lsz) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2598
		*ip = ct->ct_line_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2599
	if ((ip = l2i->l2i_assoc) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2600
		*ip = ct->ct_assoc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2601
	l2i->l2i_ret = ct->ct_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2602
	return (1);		/* was an L2 -- terminate walk */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2603
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2604
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2605
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2606
amd_l2cacheinfo(struct cpuid_info *cpi, struct l2info *l2i)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2607
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2608
	struct cpuidr *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2609
	uint_t size, assoc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2610
	int *ip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2611
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2612
	if (cpi->cpi_xmaxeax < 0x80000006)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2613
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2614
	cp = &cpi->cpi_extd[6];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2615
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2616
	if ((assoc = BITX(cp->cp_ecx, 15, 12)) != 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2617
	    (size = BITX(cp->cp_ecx, 31, 16)) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2618
		uint_t cachesz = size * 1024;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2619
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2620
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2621
		if ((ip = l2i->l2i_csz) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2622
			*ip = cachesz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2623
		if ((ip = l2i->l2i_lsz) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2624
			*ip = BITX(cp->cp_ecx, 7, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2625
		if ((ip = l2i->l2i_assoc) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2626
			*ip = assoc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2627
		l2i->l2i_ret = cachesz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2628
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2629
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2630
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2631
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2632
getl2cacheinfo(cpu_t *cpu, int *csz, int *lsz, int *assoc)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2633
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2634
	struct cpuid_info *cpi = cpu->cpu_m.mcpu_cpi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2635
	struct l2info __l2info, *l2i = &__l2info;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2636
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2637
	l2i->l2i_csz = csz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2638
	l2i->l2i_lsz = lsz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2639
	l2i->l2i_assoc = assoc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2640
	l2i->l2i_ret = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2641
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2642
	switch (x86_which_cacheinfo(cpi)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2643
	case X86_VENDOR_Intel:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2644
		intel_walk_cacheinfo(cpi, l2i, intel_l2cinfo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2645
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2646
	case X86_VENDOR_Cyrix:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2647
		cyrix_walk_cacheinfo(cpi, l2i, intel_l2cinfo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2648
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2649
	case X86_VENDOR_AMD:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2650
		amd_l2cacheinfo(cpi, l2i);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2651
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2652
	default:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2653
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2654
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2655
	return (l2i->l2i_ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2656
}