1e4b86885SCheng Sean Ye /* 2e4b86885SCheng Sean Ye * CDDL HEADER START 3e4b86885SCheng Sean Ye * 4e4b86885SCheng Sean Ye * The contents of this file are subject to the terms of the 5e4b86885SCheng Sean Ye * Common Development and Distribution License (the "License"). 6e4b86885SCheng Sean Ye * You may not use this file except in compliance with the License. 7e4b86885SCheng Sean Ye * 8e4b86885SCheng Sean Ye * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9e4b86885SCheng Sean Ye * or http://www.opensolaris.org/os/licensing. 10e4b86885SCheng Sean Ye * See the License for the specific language governing permissions 11e4b86885SCheng Sean Ye * and limitations under the License. 12e4b86885SCheng Sean Ye * 13e4b86885SCheng Sean Ye * When distributing Covered Code, include this CDDL HEADER in each 14e4b86885SCheng Sean Ye * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15e4b86885SCheng Sean Ye * If applicable, add the following below this CDDL HEADER, with the 16e4b86885SCheng Sean Ye * fields enclosed by brackets "[]" replaced with your own identifying 17e4b86885SCheng Sean Ye * information: Portions Copyright [yyyy] [name of copyright owner] 18e4b86885SCheng Sean Ye * 19e4b86885SCheng Sean Ye * CDDL HEADER END 20e4b86885SCheng Sean Ye */ 21e4b86885SCheng Sean Ye 22e4b86885SCheng Sean Ye /* 2389e921d5SKuriakose Kuruvilla * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24e4b86885SCheng Sean Ye * Use is subject to license terms. 25*79ec9da8SYuri Pankov * 26*79ec9da8SYuri Pankov * Copyright 2012 Nexenta Systems, Inc. All rights reserved. 27e4b86885SCheng Sean Ye */ 28e4b86885SCheng Sean Ye 29e4b86885SCheng Sean Ye /* 3089e921d5SKuriakose Kuruvilla * Portions Copyright 2009 Advanced Micro Devices, Inc. 3189e921d5SKuriakose Kuruvilla */ 3289e921d5SKuriakose Kuruvilla 3389e921d5SKuriakose Kuruvilla /* 3479321794SJens Elkner * Copyright 2012 Jens Elkner <jel+illumos@cs.uni-magdeburg.de> 3579321794SJens Elkner * Copyright 2012 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> 3679321794SJens Elkner */ 3779321794SJens Elkner 3879321794SJens Elkner /* 39e4b86885SCheng Sean Ye * Support functions that interpret CPUID and similar information. 40e4b86885SCheng Sean Ye * These should not be used from anywhere other than cpuid.c and 41e4b86885SCheng Sean Ye * cmi_hw.c - as such we will not list them in any header file 42e4b86885SCheng Sean Ye * such as x86_archext.h. 43e4b86885SCheng Sean Ye * 44e4b86885SCheng Sean Ye * In cpuid.c we process CPUID information for each cpu_t instance 45e4b86885SCheng Sean Ye * we're presented with, and stash this raw information and material 46e4b86885SCheng Sean Ye * derived from it in per-cpu_t structures. 47e4b86885SCheng Sean Ye * 48e4b86885SCheng Sean Ye * If we are virtualized then the CPUID information derived from CPUID 49e4b86885SCheng Sean Ye * instructions executed in the guest is based on whatever the hypervisor 50e4b86885SCheng Sean Ye * wanted to make things look like, and the cpu_t are not necessarily in 1:1 51e4b86885SCheng Sean Ye * or fixed correspondence with real processor execution resources. In cmi_hw.c 52e4b86885SCheng Sean Ye * we are interested in the native properties of a processor - for fault 53e4b86885SCheng Sean Ye * management (and potentially other, such as power management) purposes; 54e4b86885SCheng Sean Ye * it will tunnel through to real hardware information, and use the 55e4b86885SCheng Sean Ye * functionality provided in this file to process it. 56e4b86885SCheng Sean Ye */ 57e4b86885SCheng Sean Ye 58e4b86885SCheng Sean Ye #include <sys/types.h> 59e4b86885SCheng Sean Ye #include <sys/systm.h> 6089e921d5SKuriakose Kuruvilla #include <sys/bitmap.h> 61e4b86885SCheng Sean Ye #include <sys/x86_archext.h> 6289e921d5SKuriakose Kuruvilla #include <sys/pci_cfgspace.h> 6389e921d5SKuriakose Kuruvilla #ifdef __xpv 6489e921d5SKuriakose Kuruvilla #include <sys/hypervisor.h> 6589e921d5SKuriakose Kuruvilla #endif 66e4b86885SCheng Sean Ye 67e4b86885SCheng Sean Ye /* 6889e921d5SKuriakose Kuruvilla * AMD socket types. 69e4b86885SCheng Sean Ye * First index : 70e4b86885SCheng Sean Ye * 0 for family 0xf, revs B thru E 71e4b86885SCheng Sean Ye * 1 for family 0xf, revs F and G 7289e921d5SKuriakose Kuruvilla * 2 for family 0x10 7389e921d5SKuriakose Kuruvilla * 3 for family 0x11 7479321794SJens Elkner * 4 for family 0x12 7579321794SJens Elkner * 5 for family 0x14 7679321794SJens Elkner * 6 for family 0x15, models 00 - 0f 7779321794SJens Elkner * 7 for family 0x15, models 10 - 1f 7879321794SJens Elkner * Second index by (model & 0x3) for family 0fh, 7979321794SJens Elkner * CPUID pkg bits (Fn8000_0001_EBX[31:28]) for later families. 80e4b86885SCheng Sean Ye */ 8179321794SJens Elkner static uint32_t amd_skts[8][8] = { 82e4b86885SCheng Sean Ye /* 83e4b86885SCheng Sean Ye * Family 0xf revisions B through E 84e4b86885SCheng Sean Ye */ 85e4b86885SCheng Sean Ye #define A_SKTS_0 0 86e4b86885SCheng Sean Ye { 87bd15239eSSrihari Venkatesan X86_SOCKET_754, /* 0b000 */ 88bd15239eSSrihari Venkatesan X86_SOCKET_940, /* 0b001 */ 89bd15239eSSrihari Venkatesan X86_SOCKET_754, /* 0b010 */ 90bd15239eSSrihari Venkatesan X86_SOCKET_939, /* 0b011 */ 91bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN, /* 0b100 */ 92bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN, /* 0b101 */ 93bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN, /* 0b110 */ 94bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN /* 0b111 */ 95e4b86885SCheng Sean Ye }, 96e4b86885SCheng Sean Ye /* 97e4b86885SCheng Sean Ye * Family 0xf revisions F and G 98e4b86885SCheng Sean Ye */ 99e4b86885SCheng Sean Ye #define A_SKTS_1 1 100e4b86885SCheng Sean Ye { 101bd15239eSSrihari Venkatesan X86_SOCKET_S1g1, /* 0b000 */ 102bd15239eSSrihari Venkatesan X86_SOCKET_F1207, /* 0b001 */ 103bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN, /* 0b010 */ 104bd15239eSSrihari Venkatesan X86_SOCKET_AM2, /* 0b011 */ 105bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN, /* 0b100 */ 106bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN, /* 0b101 */ 107bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN, /* 0b110 */ 108bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN /* 0b111 */ 109e4b86885SCheng Sean Ye }, 110e4b86885SCheng Sean Ye /* 11189e921d5SKuriakose Kuruvilla * Family 0x10 112e4b86885SCheng Sean Ye */ 113e4b86885SCheng Sean Ye #define A_SKTS_2 2 114e4b86885SCheng Sean Ye { 115bd15239eSSrihari Venkatesan X86_SOCKET_F1207, /* 0b000 */ 11679321794SJens Elkner X86_SOCKET_AM2R2, /* 0b001 */ 117bd15239eSSrihari Venkatesan X86_SOCKET_S1g3, /* 0b010 */ 118bd15239eSSrihari Venkatesan X86_SOCKET_G34, /* 0b011 */ 119bd15239eSSrihari Venkatesan X86_SOCKET_ASB2, /* 0b100 */ 120bd15239eSSrihari Venkatesan X86_SOCKET_C32, /* 0b101 */ 121bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN, /* 0b110 */ 122bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN /* 0b111 */ 12389e921d5SKuriakose Kuruvilla }, 12489e921d5SKuriakose Kuruvilla 12589e921d5SKuriakose Kuruvilla /* 12689e921d5SKuriakose Kuruvilla * Family 0x11 12789e921d5SKuriakose Kuruvilla */ 12889e921d5SKuriakose Kuruvilla #define A_SKTS_3 3 12989e921d5SKuriakose Kuruvilla { 130bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN, /* 0b000 */ 131bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN, /* 0b001 */ 132bd15239eSSrihari Venkatesan X86_SOCKET_S1g2, /* 0b010 */ 133bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN, /* 0b011 */ 134bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN, /* 0b100 */ 135bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN, /* 0b101 */ 136bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN, /* 0b110 */ 137bd15239eSSrihari Venkatesan X86_SOCKET_UNKNOWN /* 0b111 */ 13879321794SJens Elkner }, 13979321794SJens Elkner 14079321794SJens Elkner /* 14179321794SJens Elkner * Family 0x12 14279321794SJens Elkner */ 14379321794SJens Elkner #define A_SKTS_4 4 14479321794SJens Elkner { 14579321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b000 */ 14679321794SJens Elkner X86_SOCKET_FS1, /* 0b001 */ 14779321794SJens Elkner X86_SOCKET_FM1, /* 0b010 */ 14879321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b011 */ 14979321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b100 */ 15079321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b101 */ 15179321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b110 */ 15279321794SJens Elkner X86_SOCKET_UNKNOWN /* 0b111 */ 15379321794SJens Elkner }, 15479321794SJens Elkner 15579321794SJens Elkner /* 15679321794SJens Elkner * Family 0x14 15779321794SJens Elkner */ 15879321794SJens Elkner #define A_SKTS_5 5 15979321794SJens Elkner { 16079321794SJens Elkner X86_SOCKET_FT1, /* 0b000 */ 16179321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b001 */ 16279321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b010 */ 16379321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b011 */ 16479321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b100 */ 16579321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b101 */ 16679321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b110 */ 16779321794SJens Elkner X86_SOCKET_UNKNOWN /* 0b111 */ 16879321794SJens Elkner }, 16979321794SJens Elkner 17079321794SJens Elkner /* 17179321794SJens Elkner * Family 0x15 models 00 - 0f 17279321794SJens Elkner */ 17379321794SJens Elkner #define A_SKTS_6 6 17479321794SJens Elkner { 17579321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b000 */ 17679321794SJens Elkner X86_SOCKET_AM3R2, /* 0b001 */ 17779321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b010 */ 17879321794SJens Elkner X86_SOCKET_G34, /* 0b011 */ 17979321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b100 */ 18079321794SJens Elkner X86_SOCKET_C32, /* 0b101 */ 18179321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b110 */ 18279321794SJens Elkner X86_SOCKET_UNKNOWN /* 0b111 */ 18379321794SJens Elkner }, 18479321794SJens Elkner 18579321794SJens Elkner /* 18679321794SJens Elkner * Family 0x15 models 10 - 1f 18779321794SJens Elkner */ 18879321794SJens Elkner #define A_SKTS_7 7 18979321794SJens Elkner { 19079321794SJens Elkner X86_SOCKET_FP2, /* 0b000 */ 19179321794SJens Elkner X86_SOCKET_FS1R2, /* 0b001 */ 19279321794SJens Elkner X86_SOCKET_FM2, /* 0b010 */ 19379321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b011 */ 19479321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b100 */ 19579321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b101 */ 19679321794SJens Elkner X86_SOCKET_UNKNOWN, /* 0b110 */ 19779321794SJens Elkner X86_SOCKET_UNKNOWN /* 0b111 */ 19879321794SJens Elkner }, 19979321794SJens Elkner 200e4b86885SCheng Sean Ye }; 201e4b86885SCheng Sean Ye 20289e921d5SKuriakose Kuruvilla struct amd_sktmap_s { 20389e921d5SKuriakose Kuruvilla uint32_t skt_code; 20489e921d5SKuriakose Kuruvilla char sktstr[16]; 20589e921d5SKuriakose Kuruvilla }; 20679321794SJens Elkner static struct amd_sktmap_s amd_sktmap[23] = { 20789e921d5SKuriakose Kuruvilla { X86_SOCKET_754, "754" }, 20889e921d5SKuriakose Kuruvilla { X86_SOCKET_939, "939" }, 20989e921d5SKuriakose Kuruvilla { X86_SOCKET_940, "940" }, 21089e921d5SKuriakose Kuruvilla { X86_SOCKET_S1g1, "S1g1" }, 21189e921d5SKuriakose Kuruvilla { X86_SOCKET_AM2, "AM2" }, 21289e921d5SKuriakose Kuruvilla { X86_SOCKET_F1207, "F(1207)" }, 21389e921d5SKuriakose Kuruvilla { X86_SOCKET_S1g2, "S1g2" }, 21489e921d5SKuriakose Kuruvilla { X86_SOCKET_S1g3, "S1g3" }, 21589e921d5SKuriakose Kuruvilla { X86_SOCKET_AM, "AM" }, 21689e921d5SKuriakose Kuruvilla { X86_SOCKET_AM2R2, "AM2r2" }, 21789e921d5SKuriakose Kuruvilla { X86_SOCKET_AM3, "AM3" }, 21889e921d5SKuriakose Kuruvilla { X86_SOCKET_G34, "G34" }, 219bd15239eSSrihari Venkatesan { X86_SOCKET_ASB2, "ASB2" }, 220bd15239eSSrihari Venkatesan { X86_SOCKET_C32, "C32" }, 22179321794SJens Elkner { X86_SOCKET_FT1, "FT1" }, 22279321794SJens Elkner { X86_SOCKET_FM1, "FM1" }, 22379321794SJens Elkner { X86_SOCKET_FS1, "FS1" }, 22479321794SJens Elkner { X86_SOCKET_AM3R2, "AM3r2" }, 22579321794SJens Elkner { X86_SOCKET_FP2, "FP2" }, 22679321794SJens Elkner { X86_SOCKET_FS1R2, "FS1r2" }, 22779321794SJens Elkner { X86_SOCKET_FM2, "FM2" }, 22889e921d5SKuriakose Kuruvilla { X86_SOCKET_UNKNOWN, "Unknown" } 22989e921d5SKuriakose Kuruvilla }; 23089e921d5SKuriakose Kuruvilla 231e4b86885SCheng Sean Ye /* 232e4b86885SCheng Sean Ye * Table for mapping AMD Family 0xf and AMD Family 0x10 model/stepping 233e4b86885SCheng Sean Ye * combination to chip "revision" and socket type. 234e4b86885SCheng Sean Ye * 235e4b86885SCheng Sean Ye * The first member of this array that matches a given family, extended model 236e4b86885SCheng Sean Ye * plus model range, and stepping range will be considered a match. 237e4b86885SCheng Sean Ye */ 238e4b86885SCheng Sean Ye static const struct amd_rev_mapent { 239e4b86885SCheng Sean Ye uint_t rm_family; 240e4b86885SCheng Sean Ye uint_t rm_modello; 241e4b86885SCheng Sean Ye uint_t rm_modelhi; 242e4b86885SCheng Sean Ye uint_t rm_steplo; 243e4b86885SCheng Sean Ye uint_t rm_stephi; 244e4b86885SCheng Sean Ye uint32_t rm_chiprev; 245e4b86885SCheng Sean Ye const char *rm_chiprevstr; 246e4b86885SCheng Sean Ye int rm_sktidx; 247e4b86885SCheng Sean Ye } amd_revmap[] = { 248e4b86885SCheng Sean Ye /* 249e4b86885SCheng Sean Ye * =============== AuthenticAMD Family 0xf =============== 250e4b86885SCheng Sean Ye */ 251e4b86885SCheng Sean Ye 252e4b86885SCheng Sean Ye /* 253e4b86885SCheng Sean Ye * Rev B includes model 0x4 stepping 0 and model 0x5 stepping 0 and 1. 254e4b86885SCheng Sean Ye */ 255e4b86885SCheng Sean Ye { 0xf, 0x04, 0x04, 0x0, 0x0, X86_CHIPREV_AMD_F_REV_B, "B", A_SKTS_0 }, 256e4b86885SCheng Sean Ye { 0xf, 0x05, 0x05, 0x0, 0x1, X86_CHIPREV_AMD_F_REV_B, "B", A_SKTS_0 }, 257e4b86885SCheng Sean Ye /* 258e4b86885SCheng Sean Ye * Rev C0 includes model 0x4 stepping 8 and model 0x5 stepping 8 259e4b86885SCheng Sean Ye */ 260e4b86885SCheng Sean Ye { 0xf, 0x04, 0x05, 0x8, 0x8, X86_CHIPREV_AMD_F_REV_C0, "C0", A_SKTS_0 }, 261e4b86885SCheng Sean Ye /* 262e4b86885SCheng Sean Ye * Rev CG is the rest of extended model 0x0 - i.e., everything 263e4b86885SCheng Sean Ye * but the rev B and C0 combinations covered above. 264e4b86885SCheng Sean Ye */ 265e4b86885SCheng Sean Ye { 0xf, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_CG, "CG", A_SKTS_0 }, 266e4b86885SCheng Sean Ye /* 267e4b86885SCheng Sean Ye * Rev D has extended model 0x1. 268e4b86885SCheng Sean Ye */ 269e4b86885SCheng Sean Ye { 0xf, 0x10, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_D, "D", A_SKTS_0 }, 270e4b86885SCheng Sean Ye /* 271e4b86885SCheng Sean Ye * Rev E has extended model 0x2. 272e4b86885SCheng Sean Ye * Extended model 0x3 is unused but available to grow into. 273e4b86885SCheng Sean Ye */ 274e4b86885SCheng Sean Ye { 0xf, 0x20, 0x3f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_E, "E", A_SKTS_0 }, 275e4b86885SCheng Sean Ye /* 276e4b86885SCheng Sean Ye * Rev F has extended models 0x4 and 0x5. 277e4b86885SCheng Sean Ye */ 278e4b86885SCheng Sean Ye { 0xf, 0x40, 0x5f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_F, "F", A_SKTS_1 }, 279e4b86885SCheng Sean Ye /* 280e4b86885SCheng Sean Ye * Rev G has extended model 0x6. 281e4b86885SCheng Sean Ye */ 282e4b86885SCheng Sean Ye { 0xf, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_G, "G", A_SKTS_1 }, 283e4b86885SCheng Sean Ye 284e4b86885SCheng Sean Ye /* 285e4b86885SCheng Sean Ye * =============== AuthenticAMD Family 0x10 =============== 286e4b86885SCheng Sean Ye */ 287e4b86885SCheng Sean Ye 288e4b86885SCheng Sean Ye /* 289e4b86885SCheng Sean Ye * Rev A has model 0 and stepping 0/1/2 for DR-{A0,A1,A2}. 290e4b86885SCheng Sean Ye * Give all of model 0 stepping range to rev A. 291e4b86885SCheng Sean Ye */ 292e4b86885SCheng Sean Ye { 0x10, 0x00, 0x00, 0x0, 0x2, X86_CHIPREV_AMD_10_REV_A, "A", A_SKTS_2 }, 293e4b86885SCheng Sean Ye 294e4b86885SCheng Sean Ye /* 295e4b86885SCheng Sean Ye * Rev B has model 2 and steppings 0/1/0xa/2 for DR-{B0,B1,BA,B2}. 296e4b86885SCheng Sean Ye * Give all of model 2 stepping range to rev B. 297e4b86885SCheng Sean Ye */ 298e4b86885SCheng Sean Ye { 0x10, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_B, "B", A_SKTS_2 }, 29964452efdSKit Chow 30064452efdSKit Chow /* 30164452efdSKit Chow * Rev C has models 4-6 (depending on L3 cache configuration) 30279321794SJens Elkner * Give all of models 4-6 stepping range 0-2 to rev C2. 30364452efdSKit Chow */ 30479321794SJens Elkner { 0x10, 0x4, 0x6, 0x0, 0x2, X86_CHIPREV_AMD_10_REV_C2, "C2", A_SKTS_2 }, 30579321794SJens Elkner 30679321794SJens Elkner /* 30779321794SJens Elkner * Rev C has models 4-6 (depending on L3 cache configuration) 30879321794SJens Elkner * Give all of models 4-6 stepping range >= 3 to rev C3. 30979321794SJens Elkner */ 31079321794SJens Elkner { 0x10, 0x4, 0x6, 0x3, 0xf, X86_CHIPREV_AMD_10_REV_C3, "C3", A_SKTS_2 }, 31189e921d5SKuriakose Kuruvilla 31289e921d5SKuriakose Kuruvilla /* 31389e921d5SKuriakose Kuruvilla * Rev D has models 8 and 9 31479321794SJens Elkner * Give all of model 8 and 9 stepping 0 to rev D0. 31589e921d5SKuriakose Kuruvilla */ 31679321794SJens Elkner { 0x10, 0x8, 0x9, 0x0, 0x0, X86_CHIPREV_AMD_10_REV_D0, "D0", A_SKTS_2 }, 31779321794SJens Elkner 31879321794SJens Elkner /* 31979321794SJens Elkner * Rev D has models 8 and 9 32079321794SJens Elkner * Give all of model 8 and 9 stepping range >= 1 to rev D1. 32179321794SJens Elkner */ 32279321794SJens Elkner { 0x10, 0x8, 0x9, 0x1, 0xf, X86_CHIPREV_AMD_10_REV_D1, "D1", A_SKTS_2 }, 32379321794SJens Elkner 32479321794SJens Elkner /* 32579321794SJens Elkner * Rev E has models A and stepping 0 32679321794SJens Elkner * Give all of model A stepping range to rev E. 32779321794SJens Elkner */ 32879321794SJens Elkner { 0x10, 0xA, 0xA, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_E, "E", A_SKTS_2 }, 32989e921d5SKuriakose Kuruvilla 33089e921d5SKuriakose Kuruvilla /* 33189e921d5SKuriakose Kuruvilla * =============== AuthenticAMD Family 0x11 =============== 33289e921d5SKuriakose Kuruvilla */ 33379321794SJens Elkner { 0x11, 0x03, 0x03, 0x0, 0xf, X86_CHIPREV_AMD_11_REV_B, "B", A_SKTS_3 }, 33479321794SJens Elkner 33579321794SJens Elkner /* 33679321794SJens Elkner * =============== AuthenticAMD Family 0x12 =============== 33779321794SJens Elkner */ 33879321794SJens Elkner { 0x12, 0x01, 0x01, 0x0, 0xf, X86_CHIPREV_AMD_12_REV_B, "B", A_SKTS_4 }, 33979321794SJens Elkner 34079321794SJens Elkner /* 34179321794SJens Elkner * =============== AuthenticAMD Family 0x14 =============== 34279321794SJens Elkner */ 34379321794SJens Elkner { 0x14, 0x01, 0x01, 0x0, 0xf, X86_CHIPREV_AMD_14_REV_B, "B", A_SKTS_5 }, 34479321794SJens Elkner { 0x14, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_14_REV_C, "C", A_SKTS_5 }, 34579321794SJens Elkner 34679321794SJens Elkner /* 34779321794SJens Elkner * =============== AuthenticAMD Family 0x15 =============== 34879321794SJens Elkner */ 34979321794SJens Elkner { 0x15, 0x01, 0x01, 0x2, 0x2, X86_CHIPREV_AMD_15OR_REV_B2, "B2", 35079321794SJens Elkner A_SKTS_6 }, 35179321794SJens Elkner { 0x15, 0x10, 0x10, 0x1, 0x1, X86_CHIPREV_AMD_15TN_REV_A1, "A1", 35279321794SJens Elkner A_SKTS_7 }, 353e4b86885SCheng Sean Ye }; 354e4b86885SCheng Sean Ye 355e4b86885SCheng Sean Ye static void 356e4b86885SCheng Sean Ye synth_amd_info(uint_t family, uint_t model, uint_t step, 357e4b86885SCheng Sean Ye uint32_t *skt_p, uint32_t *chiprev_p, const char **chiprevstr_p) 358e4b86885SCheng Sean Ye { 359e4b86885SCheng Sean Ye const struct amd_rev_mapent *rmp; 360e4b86885SCheng Sean Ye int found = 0; 361e4b86885SCheng Sean Ye int i; 362e4b86885SCheng Sean Ye 36389e921d5SKuriakose Kuruvilla if (family < 0xf) 364e4b86885SCheng Sean Ye return; 365e4b86885SCheng Sean Ye 366e4b86885SCheng Sean Ye for (i = 0, rmp = amd_revmap; i < sizeof (amd_revmap) / sizeof (*rmp); 367e4b86885SCheng Sean Ye i++, rmp++) { 368e4b86885SCheng Sean Ye if (family == rmp->rm_family && 369e4b86885SCheng Sean Ye model >= rmp->rm_modello && model <= rmp->rm_modelhi && 370e4b86885SCheng Sean Ye step >= rmp->rm_steplo && step <= rmp->rm_stephi) { 371e4b86885SCheng Sean Ye found = 1; 372e4b86885SCheng Sean Ye break; 373e4b86885SCheng Sean Ye } 374e4b86885SCheng Sean Ye } 375e4b86885SCheng Sean Ye 37689e921d5SKuriakose Kuruvilla if (!found) 37789e921d5SKuriakose Kuruvilla return; 37889e921d5SKuriakose Kuruvilla 379e4b86885SCheng Sean Ye if (chiprev_p != NULL) 380e4b86885SCheng Sean Ye *chiprev_p = rmp->rm_chiprev; 381e4b86885SCheng Sean Ye if (chiprevstr_p != NULL) 382e4b86885SCheng Sean Ye *chiprevstr_p = rmp->rm_chiprevstr; 38389e921d5SKuriakose Kuruvilla 38489e921d5SKuriakose Kuruvilla if (skt_p != NULL) { 38589e921d5SKuriakose Kuruvilla int platform; 38689e921d5SKuriakose Kuruvilla 38789e921d5SKuriakose Kuruvilla #ifdef __xpv 38889e921d5SKuriakose Kuruvilla /* PV guest */ 38989e921d5SKuriakose Kuruvilla if (!is_controldom()) { 39089e921d5SKuriakose Kuruvilla *skt_p = X86_SOCKET_UNKNOWN; 39189e921d5SKuriakose Kuruvilla return; 39289e921d5SKuriakose Kuruvilla } 39389e921d5SKuriakose Kuruvilla #endif 39489e921d5SKuriakose Kuruvilla platform = get_hwenv(); 39589e921d5SKuriakose Kuruvilla 396*79ec9da8SYuri Pankov if ((platform & HW_VIRTUAL) != 0) { 39789e921d5SKuriakose Kuruvilla *skt_p = X86_SOCKET_UNKNOWN; 39889e921d5SKuriakose Kuruvilla } else if (family == 0xf) { 39989e921d5SKuriakose Kuruvilla *skt_p = amd_skts[rmp->rm_sktidx][model & 0x3]; 40089e921d5SKuriakose Kuruvilla } else { 40189e921d5SKuriakose Kuruvilla /* 40289e921d5SKuriakose Kuruvilla * Starting with family 10h, socket type is stored in 40389e921d5SKuriakose Kuruvilla * CPUID Fn8000_0001_EBX 40489e921d5SKuriakose Kuruvilla */ 40589e921d5SKuriakose Kuruvilla struct cpuid_regs cp; 40689e921d5SKuriakose Kuruvilla int idx; 40789e921d5SKuriakose Kuruvilla 40889e921d5SKuriakose Kuruvilla cp.cp_eax = 0x80000001; 40989e921d5SKuriakose Kuruvilla (void) __cpuid_insn(&cp); 41089e921d5SKuriakose Kuruvilla 41189e921d5SKuriakose Kuruvilla /* PkgType bits */ 41289e921d5SKuriakose Kuruvilla idx = BITX(cp.cp_ebx, 31, 28); 41389e921d5SKuriakose Kuruvilla 414bd15239eSSrihari Venkatesan if (idx > 7) { 41589e921d5SKuriakose Kuruvilla /* Reserved bits */ 41689e921d5SKuriakose Kuruvilla *skt_p = X86_SOCKET_UNKNOWN; 41779321794SJens Elkner } else { 41879321794SJens Elkner *skt_p = amd_skts[rmp->rm_sktidx][idx]; 41979321794SJens Elkner } 42079321794SJens Elkner if (family == 0x10) { 42189e921d5SKuriakose Kuruvilla /* 42289e921d5SKuriakose Kuruvilla * Look at Ddr3Mode bit of DRAM Configuration 42389e921d5SKuriakose Kuruvilla * High Register to decide whether this is 42479321794SJens Elkner * actually AM3 or S1g4. 42589e921d5SKuriakose Kuruvilla */ 42689e921d5SKuriakose Kuruvilla uint32_t val; 42789e921d5SKuriakose Kuruvilla 42889e921d5SKuriakose Kuruvilla val = pci_getl_func(0, 24, 2, 0x94); 42979321794SJens Elkner if (BITX(val, 8, 8)) { 43079321794SJens Elkner if (*skt_p == X86_SOCKET_AM2R2) 43189e921d5SKuriakose Kuruvilla *skt_p = X86_SOCKET_AM3; 43279321794SJens Elkner else if (*skt_p == X86_SOCKET_S1g3) 43379321794SJens Elkner *skt_p = X86_SOCKET_S1g4; 43479321794SJens Elkner } 43589e921d5SKuriakose Kuruvilla } 43689e921d5SKuriakose Kuruvilla } 437e4b86885SCheng Sean Ye } 438e4b86885SCheng Sean Ye } 439e4b86885SCheng Sean Ye 440e4b86885SCheng Sean Ye uint32_t 441e4b86885SCheng Sean Ye _cpuid_skt(uint_t vendor, uint_t family, uint_t model, uint_t step) 442e4b86885SCheng Sean Ye { 443e4b86885SCheng Sean Ye uint32_t skt = X86_SOCKET_UNKNOWN; 444e4b86885SCheng Sean Ye 445e4b86885SCheng Sean Ye switch (vendor) { 446e4b86885SCheng Sean Ye case X86_VENDOR_AMD: 447e4b86885SCheng Sean Ye synth_amd_info(family, model, step, &skt, NULL, NULL); 448e4b86885SCheng Sean Ye break; 449e4b86885SCheng Sean Ye 450e4b86885SCheng Sean Ye default: 451e4b86885SCheng Sean Ye break; 452e4b86885SCheng Sean Ye 453e4b86885SCheng Sean Ye } 454e4b86885SCheng Sean Ye 455e4b86885SCheng Sean Ye return (skt); 456e4b86885SCheng Sean Ye } 457e4b86885SCheng Sean Ye 45889e921d5SKuriakose Kuruvilla const char * 45989e921d5SKuriakose Kuruvilla _cpuid_sktstr(uint_t vendor, uint_t family, uint_t model, uint_t step) 46089e921d5SKuriakose Kuruvilla { 46189e921d5SKuriakose Kuruvilla const char *sktstr = "Unknown"; 46289e921d5SKuriakose Kuruvilla struct amd_sktmap_s *sktmapp; 46389e921d5SKuriakose Kuruvilla uint32_t skt = X86_SOCKET_UNKNOWN; 46489e921d5SKuriakose Kuruvilla 46589e921d5SKuriakose Kuruvilla switch (vendor) { 46689e921d5SKuriakose Kuruvilla case X86_VENDOR_AMD: 46789e921d5SKuriakose Kuruvilla synth_amd_info(family, model, step, &skt, NULL, NULL); 46889e921d5SKuriakose Kuruvilla 46989e921d5SKuriakose Kuruvilla sktmapp = amd_sktmap; 47089e921d5SKuriakose Kuruvilla while (sktmapp->skt_code != X86_SOCKET_UNKNOWN) { 47189e921d5SKuriakose Kuruvilla if (sktmapp->skt_code == skt) 47289e921d5SKuriakose Kuruvilla break; 47389e921d5SKuriakose Kuruvilla sktmapp++; 47489e921d5SKuriakose Kuruvilla } 47589e921d5SKuriakose Kuruvilla sktstr = sktmapp->sktstr; 47689e921d5SKuriakose Kuruvilla break; 47789e921d5SKuriakose Kuruvilla 47889e921d5SKuriakose Kuruvilla default: 47989e921d5SKuriakose Kuruvilla break; 48089e921d5SKuriakose Kuruvilla 48189e921d5SKuriakose Kuruvilla } 48289e921d5SKuriakose Kuruvilla 48389e921d5SKuriakose Kuruvilla return (sktstr); 48489e921d5SKuriakose Kuruvilla } 48589e921d5SKuriakose Kuruvilla 486e4b86885SCheng Sean Ye uint32_t 487e4b86885SCheng Sean Ye _cpuid_chiprev(uint_t vendor, uint_t family, uint_t model, uint_t step) 488e4b86885SCheng Sean Ye { 489e4b86885SCheng Sean Ye uint32_t chiprev = X86_CHIPREV_UNKNOWN; 490e4b86885SCheng Sean Ye 491e4b86885SCheng Sean Ye switch (vendor) { 492e4b86885SCheng Sean Ye case X86_VENDOR_AMD: 493e4b86885SCheng Sean Ye synth_amd_info(family, model, step, NULL, &chiprev, NULL); 494e4b86885SCheng Sean Ye break; 495e4b86885SCheng Sean Ye 496e4b86885SCheng Sean Ye default: 497e4b86885SCheng Sean Ye break; 498e4b86885SCheng Sean Ye 499e4b86885SCheng Sean Ye } 500e4b86885SCheng Sean Ye 501e4b86885SCheng Sean Ye return (chiprev); 502e4b86885SCheng Sean Ye } 503e4b86885SCheng Sean Ye 504e4b86885SCheng Sean Ye const char * 505e4b86885SCheng Sean Ye _cpuid_chiprevstr(uint_t vendor, uint_t family, uint_t model, uint_t step) 506e4b86885SCheng Sean Ye { 507e4b86885SCheng Sean Ye const char *revstr = "Unknown"; 508e4b86885SCheng Sean Ye 509e4b86885SCheng Sean Ye switch (vendor) { 510e4b86885SCheng Sean Ye case X86_VENDOR_AMD: 511e4b86885SCheng Sean Ye synth_amd_info(family, model, step, NULL, NULL, &revstr); 512e4b86885SCheng Sean Ye break; 513e4b86885SCheng Sean Ye 514e4b86885SCheng Sean Ye default: 515e4b86885SCheng Sean Ye break; 516e4b86885SCheng Sean Ye 517e4b86885SCheng Sean Ye } 518e4b86885SCheng Sean Ye 519e4b86885SCheng Sean Ye return (revstr); 520e4b86885SCheng Sean Ye 521e4b86885SCheng Sean Ye } 522e4b86885SCheng Sean Ye 523e4b86885SCheng Sean Ye /* 524e4b86885SCheng Sean Ye * CyrixInstead is a variable used by the Cyrix detection code 525e4b86885SCheng Sean Ye * in locore. 526e4b86885SCheng Sean Ye */ 527e4b86885SCheng Sean Ye const char CyrixInstead[] = X86_VENDORSTR_CYRIX; 528e4b86885SCheng Sean Ye 529e4b86885SCheng Sean Ye /* 530e4b86885SCheng Sean Ye * Map the vendor string to a type code 531e4b86885SCheng Sean Ye */ 532e4b86885SCheng Sean Ye uint_t 533e4b86885SCheng Sean Ye _cpuid_vendorstr_to_vendorcode(char *vendorstr) 534e4b86885SCheng Sean Ye { 535e4b86885SCheng Sean Ye if (strcmp(vendorstr, X86_VENDORSTR_Intel) == 0) 536e4b86885SCheng Sean Ye return (X86_VENDOR_Intel); 537e4b86885SCheng Sean Ye else if (strcmp(vendorstr, X86_VENDORSTR_AMD) == 0) 538e4b86885SCheng Sean Ye return (X86_VENDOR_AMD); 539e4b86885SCheng Sean Ye else if (strcmp(vendorstr, X86_VENDORSTR_TM) == 0) 540e4b86885SCheng Sean Ye return (X86_VENDOR_TM); 541e4b86885SCheng Sean Ye else if (strcmp(vendorstr, CyrixInstead) == 0) 542e4b86885SCheng Sean Ye return (X86_VENDOR_Cyrix); 543e4b86885SCheng Sean Ye else if (strcmp(vendorstr, X86_VENDORSTR_UMC) == 0) 544e4b86885SCheng Sean Ye return (X86_VENDOR_UMC); 545e4b86885SCheng Sean Ye else if (strcmp(vendorstr, X86_VENDORSTR_NexGen) == 0) 546e4b86885SCheng Sean Ye return (X86_VENDOR_NexGen); 547e4b86885SCheng Sean Ye else if (strcmp(vendorstr, X86_VENDORSTR_Centaur) == 0) 548e4b86885SCheng Sean Ye return (X86_VENDOR_Centaur); 549e4b86885SCheng Sean Ye else if (strcmp(vendorstr, X86_VENDORSTR_Rise) == 0) 550e4b86885SCheng Sean Ye return (X86_VENDOR_Rise); 551e4b86885SCheng Sean Ye else if (strcmp(vendorstr, X86_VENDORSTR_SiS) == 0) 552e4b86885SCheng Sean Ye return (X86_VENDOR_SiS); 553e4b86885SCheng Sean Ye else if (strcmp(vendorstr, X86_VENDORSTR_NSC) == 0) 554e4b86885SCheng Sean Ye return (X86_VENDOR_NSC); 555e4b86885SCheng Sean Ye else 556e4b86885SCheng Sean Ye return (X86_VENDOR_IntelClone); 557e4b86885SCheng Sean Ye } 558