Print this page
3408 detect socket type of newer AMD CPUs
Reviewed by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>


  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Portions Copyright 2009 Advanced Micro Devices, Inc.
  29  */
  30 
  31 /*





  32  * Support functions that interpret CPUID and similar information.
  33  * These should not be used from anywhere other than cpuid.c and
  34  * cmi_hw.c - as such we will not list them in any header file
  35  * such as x86_archext.h.
  36  *
  37  * In cpuid.c we process CPUID information for each cpu_t instance
  38  * we're presented with, and stash this raw information and material
  39  * derived from it in per-cpu_t structures.
  40  *
  41  * If we are virtualized then the CPUID information derived from CPUID
  42  * instructions executed in the guest is based on whatever the hypervisor
  43  * wanted to make things look like, and the cpu_t are not necessarily in 1:1
  44  * or fixed correspondence with real processor execution resources.  In cmi_hw.c
  45  * we are interested in the native properties of a processor - for fault
  46  * management (and potentially other, such as power management) purposes;
  47  * it will tunnel through to real hardware information, and use the
  48  * functionality provided in this file to process it.
  49  */
  50 
  51 #include <sys/types.h>
  52 #include <sys/systm.h>
  53 #include <sys/bitmap.h>
  54 #include <sys/x86_archext.h>
  55 #include <sys/pci_cfgspace.h>
  56 #ifdef __xpv
  57 #include <sys/hypervisor.h>
  58 #endif
  59 
  60 /*
  61  * AMD socket types.
  62  * First index :
  63  *              0 for family 0xf, revs B thru E
  64  *              1 for family 0xf, revs F and G
  65  *              2 for family 0x10
  66  *              3 for family 0x11
  67  * Second index by (model & 0x3) for family 0fh
  68  * or CPUID bits for later families




  69  */
  70 static uint32_t amd_skts[4][8] = {
  71         /*
  72          * Family 0xf revisions B through E
  73          */
  74 #define A_SKTS_0                        0
  75         {
  76                 X86_SOCKET_754,         /* 0b000 */
  77                 X86_SOCKET_940,         /* 0b001 */
  78                 X86_SOCKET_754,         /* 0b010 */
  79                 X86_SOCKET_939,         /* 0b011 */
  80                 X86_SOCKET_UNKNOWN,     /* 0b100 */
  81                 X86_SOCKET_UNKNOWN,     /* 0b101 */
  82                 X86_SOCKET_UNKNOWN,     /* 0b110 */
  83                 X86_SOCKET_UNKNOWN      /* 0b111 */
  84         },
  85         /*
  86          * Family 0xf revisions F and G
  87          */
  88 #define A_SKTS_1                        1
  89         {
  90                 X86_SOCKET_S1g1,        /* 0b000 */
  91                 X86_SOCKET_F1207,       /* 0b001 */
  92                 X86_SOCKET_UNKNOWN,     /* 0b010 */
  93                 X86_SOCKET_AM2,         /* 0b011 */
  94                 X86_SOCKET_UNKNOWN,     /* 0b100 */
  95                 X86_SOCKET_UNKNOWN,     /* 0b101 */
  96                 X86_SOCKET_UNKNOWN,     /* 0b110 */
  97                 X86_SOCKET_UNKNOWN      /* 0b111 */
  98         },
  99         /*
 100          * Family 0x10
 101          */
 102 #define A_SKTS_2                        2
 103         {
 104                 X86_SOCKET_F1207,       /* 0b000 */
 105                 X86_SOCKET_AM,          /* 0b001 */
 106                 X86_SOCKET_S1g3,        /* 0b010 */
 107                 X86_SOCKET_G34,         /* 0b011 */
 108                 X86_SOCKET_ASB2,        /* 0b100 */
 109                 X86_SOCKET_C32,         /* 0b101 */
 110                 X86_SOCKET_UNKNOWN,     /* 0b110 */
 111                 X86_SOCKET_UNKNOWN      /* 0b111 */
 112         },
 113 
 114         /*
 115          * Family 0x11
 116          */
 117 #define A_SKTS_3                        3
 118         {
 119                 X86_SOCKET_UNKNOWN,     /* 0b000 */
 120                 X86_SOCKET_UNKNOWN,     /* 0b001 */
 121                 X86_SOCKET_S1g2,        /* 0b010 */
 122                 X86_SOCKET_UNKNOWN,     /* 0b011 */
 123                 X86_SOCKET_UNKNOWN,     /* 0b100 */
 124                 X86_SOCKET_UNKNOWN,     /* 0b101 */
 125                 X86_SOCKET_UNKNOWN,     /* 0b110 */
 126                 X86_SOCKET_UNKNOWN      /* 0b111 */
 127         }





























































 128 };
 129 
 130 struct amd_sktmap_s {
 131         uint32_t        skt_code;
 132         char            sktstr[16];
 133 };
 134 static struct amd_sktmap_s amd_sktmap[15] = {
 135         { X86_SOCKET_754,       "754" },
 136         { X86_SOCKET_939,       "939" },
 137         { X86_SOCKET_940,       "940" },
 138         { X86_SOCKET_S1g1,      "S1g1" },
 139         { X86_SOCKET_AM2,       "AM2" },
 140         { X86_SOCKET_F1207,     "F(1207)" },
 141         { X86_SOCKET_S1g2,      "S1g2" },
 142         { X86_SOCKET_S1g3,      "S1g3" },
 143         { X86_SOCKET_AM,        "AM" },
 144         { X86_SOCKET_AM2R2,     "AM2r2" },
 145         { X86_SOCKET_AM3,       "AM3" },
 146         { X86_SOCKET_G34,       "G34" },
 147         { X86_SOCKET_ASB2,      "ASB2" },
 148         { X86_SOCKET_C32,       "C32" },







 149         { X86_SOCKET_UNKNOWN,   "Unknown" }
 150 };
 151 
 152 /*
 153  * Table for mapping AMD Family 0xf and AMD Family 0x10 model/stepping
 154  * combination to chip "revision" and socket type.
 155  *
 156  * The first member of this array that matches a given family, extended model
 157  * plus model range, and stepping range will be considered a match.
 158  */
 159 static const struct amd_rev_mapent {
 160         uint_t rm_family;
 161         uint_t rm_modello;
 162         uint_t rm_modelhi;
 163         uint_t rm_steplo;
 164         uint_t rm_stephi;
 165         uint32_t rm_chiprev;
 166         const char *rm_chiprevstr;
 167         int rm_sktidx;
 168 } amd_revmap[] = {


 203         { 0xf, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_G, "G", A_SKTS_1 },
 204 
 205         /*
 206          * =============== AuthenticAMD Family 0x10 ===============
 207          */
 208 
 209         /*
 210          * Rev A has model 0 and stepping 0/1/2 for DR-{A0,A1,A2}.
 211          * Give all of model 0 stepping range to rev A.
 212          */
 213         { 0x10, 0x00, 0x00, 0x0, 0x2, X86_CHIPREV_AMD_10_REV_A, "A", A_SKTS_2 },
 214 
 215         /*
 216          * Rev B has model 2 and steppings 0/1/0xa/2 for DR-{B0,B1,BA,B2}.
 217          * Give all of model 2 stepping range to rev B.
 218          */
 219         { 0x10, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_B, "B", A_SKTS_2 },
 220 
 221         /*
 222          * Rev C has models 4-6 (depending on L3 cache configuration)
 223          * Give all of models 4-6 stepping range to rev C.
 224          */
 225         { 0x10, 0x04, 0x06, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_C, "C", A_SKTS_2 },
 226 
 227         /*






 228          * Rev D has models 8 and 9
 229          * Give all of model 8 and 9 stepping range to rev D.
 230          */
 231         { 0x10, 0x08, 0x09, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_D, "D", A_SKTS_2 },
 232 
 233         /*












 234          * =============== AuthenticAMD Family 0x11 ===============
 235          */
 236         { 0x11, 0x03, 0x3, 0x0, 0xf, X86_CHIPREV_AMD_11, "B", A_SKTS_3 },



















 237 };
 238 
 239 static void
 240 synth_amd_info(uint_t family, uint_t model, uint_t step,
 241     uint32_t *skt_p, uint32_t *chiprev_p, const char **chiprevstr_p)
 242 {
 243         const struct amd_rev_mapent *rmp;
 244         int found = 0;
 245         int i;
 246 
 247         if (family < 0xf)
 248                 return;
 249 
 250         for (i = 0, rmp = amd_revmap; i < sizeof (amd_revmap) / sizeof (*rmp);
 251             i++, rmp++) {
 252                 if (family == rmp->rm_family &&
 253                     model >= rmp->rm_modello && model <= rmp->rm_modelhi &&
 254                     step >= rmp->rm_steplo && step <= rmp->rm_stephi) {
 255                         found = 1;
 256                         break;


 281                         *skt_p = X86_SOCKET_UNKNOWN;
 282                 } else if (family == 0xf) {
 283                         *skt_p = amd_skts[rmp->rm_sktidx][model & 0x3];
 284                 } else {
 285                         /*
 286                          * Starting with family 10h, socket type is stored in
 287                          * CPUID Fn8000_0001_EBX
 288                          */
 289                         struct cpuid_regs cp;
 290                         int idx;
 291 
 292                         cp.cp_eax = 0x80000001;
 293                         (void) __cpuid_insn(&cp);
 294 
 295                         /* PkgType bits */
 296                         idx = BITX(cp.cp_ebx, 31, 28);
 297 
 298                         if (idx > 7) {
 299                                 /* Reserved bits */
 300                                 *skt_p = X86_SOCKET_UNKNOWN;
 301                         } else if (family == 0x10 &&
 302                             amd_skts[rmp->rm_sktidx][idx] ==
 303                             X86_SOCKET_AM) {

 304                                 /*
 305                                  * Look at Ddr3Mode bit of DRAM Configuration
 306                                  * High Register to decide whether this is
 307                                  * AM2r2 (aka AM2+) or AM3.
 308                                  */
 309                                 uint32_t val;
 310 
 311                                 val = pci_getl_func(0, 24, 2, 0x94);
 312                                 if (BITX(val, 8, 8))

 313                                         *skt_p = X86_SOCKET_AM3;
 314                                 else
 315                                         *skt_p = X86_SOCKET_AM2R2;
 316                         } else {
 317                                 *skt_p = amd_skts[rmp->rm_sktidx][idx];
 318                         }
 319                 }

 320         }
 321 }
 322 
 323 uint32_t
 324 _cpuid_skt(uint_t vendor, uint_t family, uint_t model, uint_t step)
 325 {
 326         uint32_t skt = X86_SOCKET_UNKNOWN;
 327 
 328         switch (vendor) {
 329         case X86_VENDOR_AMD:
 330                 synth_amd_info(family, model, step, &skt, NULL, NULL);
 331                 break;
 332 
 333         default:
 334                 break;
 335 
 336         }
 337 
 338         return (skt);
 339 }




  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Portions Copyright 2009 Advanced Micro Devices, Inc.
  29  */
  30 
  31 /*
  32  * Copyright 2012 Jens Elkner <jel+illumos@cs.uni-magdeburg.de>
  33  * Copyright 2012 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
  34  */
  35 
  36 /*
  37  * Support functions that interpret CPUID and similar information.
  38  * These should not be used from anywhere other than cpuid.c and
  39  * cmi_hw.c - as such we will not list them in any header file
  40  * such as x86_archext.h.
  41  *
  42  * In cpuid.c we process CPUID information for each cpu_t instance
  43  * we're presented with, and stash this raw information and material
  44  * derived from it in per-cpu_t structures.
  45  *
  46  * If we are virtualized then the CPUID information derived from CPUID
  47  * instructions executed in the guest is based on whatever the hypervisor
  48  * wanted to make things look like, and the cpu_t are not necessarily in 1:1
  49  * or fixed correspondence with real processor execution resources.  In cmi_hw.c
  50  * we are interested in the native properties of a processor - for fault
  51  * management (and potentially other, such as power management) purposes;
  52  * it will tunnel through to real hardware information, and use the
  53  * functionality provided in this file to process it.
  54  */
  55 
  56 #include <sys/types.h>
  57 #include <sys/systm.h>
  58 #include <sys/bitmap.h>
  59 #include <sys/x86_archext.h>
  60 #include <sys/pci_cfgspace.h>
  61 #ifdef __xpv
  62 #include <sys/hypervisor.h>
  63 #endif
  64 
  65 /*
  66  * AMD socket types.
  67  * First index :
  68  *              0 for family 0xf, revs B thru E
  69  *              1 for family 0xf, revs F and G
  70  *              2 for family 0x10
  71  *              3 for family 0x11
  72  *              4 for family 0x12
  73  *              5 for family 0x14
  74  *              6 for family 0x15, models 00 - 0f
  75  *              7 for family 0x15, models 10 - 1f
  76  * Second index by (model & 0x3) for family 0fh,
  77  * CPUID pkg bits (Fn8000_0001_EBX[31:28]) for later families.
  78  */
  79 static uint32_t amd_skts[8][8] = {
  80         /*
  81          * Family 0xf revisions B through E
  82          */
  83 #define A_SKTS_0                        0
  84         {
  85                 X86_SOCKET_754,         /* 0b000 */
  86                 X86_SOCKET_940,         /* 0b001 */
  87                 X86_SOCKET_754,         /* 0b010 */
  88                 X86_SOCKET_939,         /* 0b011 */
  89                 X86_SOCKET_UNKNOWN,     /* 0b100 */
  90                 X86_SOCKET_UNKNOWN,     /* 0b101 */
  91                 X86_SOCKET_UNKNOWN,     /* 0b110 */
  92                 X86_SOCKET_UNKNOWN      /* 0b111 */
  93         },
  94         /*
  95          * Family 0xf revisions F and G
  96          */
  97 #define A_SKTS_1                        1
  98         {
  99                 X86_SOCKET_S1g1,        /* 0b000 */
 100                 X86_SOCKET_F1207,       /* 0b001 */
 101                 X86_SOCKET_UNKNOWN,     /* 0b010 */
 102                 X86_SOCKET_AM2,         /* 0b011 */
 103                 X86_SOCKET_UNKNOWN,     /* 0b100 */
 104                 X86_SOCKET_UNKNOWN,     /* 0b101 */
 105                 X86_SOCKET_UNKNOWN,     /* 0b110 */
 106                 X86_SOCKET_UNKNOWN      /* 0b111 */
 107         },
 108         /*
 109          * Family 0x10
 110          */
 111 #define A_SKTS_2                        2
 112         {
 113                 X86_SOCKET_F1207,       /* 0b000 */
 114                 X86_SOCKET_AM2R2,       /* 0b001 */
 115                 X86_SOCKET_S1g3,        /* 0b010 */
 116                 X86_SOCKET_G34,         /* 0b011 */
 117                 X86_SOCKET_ASB2,        /* 0b100 */
 118                 X86_SOCKET_C32,         /* 0b101 */
 119                 X86_SOCKET_UNKNOWN,     /* 0b110 */
 120                 X86_SOCKET_UNKNOWN      /* 0b111 */
 121         },
 122 
 123         /*
 124          * Family 0x11
 125          */
 126 #define A_SKTS_3                        3
 127         {
 128                 X86_SOCKET_UNKNOWN,     /* 0b000 */
 129                 X86_SOCKET_UNKNOWN,     /* 0b001 */
 130                 X86_SOCKET_S1g2,        /* 0b010 */
 131                 X86_SOCKET_UNKNOWN,     /* 0b011 */
 132                 X86_SOCKET_UNKNOWN,     /* 0b100 */
 133                 X86_SOCKET_UNKNOWN,     /* 0b101 */
 134                 X86_SOCKET_UNKNOWN,     /* 0b110 */
 135                 X86_SOCKET_UNKNOWN      /* 0b111 */
 136         },
 137 
 138         /*
 139          * Family 0x12
 140          */
 141 #define A_SKTS_4                        4
 142         {
 143                 X86_SOCKET_UNKNOWN,     /* 0b000 */
 144                 X86_SOCKET_FS1,         /* 0b001 */
 145                 X86_SOCKET_FM1,         /* 0b010 */
 146                 X86_SOCKET_UNKNOWN,     /* 0b011 */
 147                 X86_SOCKET_UNKNOWN,     /* 0b100 */
 148                 X86_SOCKET_UNKNOWN,     /* 0b101 */
 149                 X86_SOCKET_UNKNOWN,     /* 0b110 */
 150                 X86_SOCKET_UNKNOWN      /* 0b111 */
 151         },
 152 
 153         /*
 154          * Family 0x14
 155          */
 156 #define A_SKTS_5                        5
 157         {
 158                 X86_SOCKET_FT1,         /* 0b000 */
 159                 X86_SOCKET_UNKNOWN,     /* 0b001 */
 160                 X86_SOCKET_UNKNOWN,     /* 0b010 */
 161                 X86_SOCKET_UNKNOWN,     /* 0b011 */
 162                 X86_SOCKET_UNKNOWN,     /* 0b100 */
 163                 X86_SOCKET_UNKNOWN,     /* 0b101 */
 164                 X86_SOCKET_UNKNOWN,     /* 0b110 */
 165                 X86_SOCKET_UNKNOWN      /* 0b111 */
 166         },
 167 
 168         /*
 169          * Family 0x15 models 00 - 0f
 170          */
 171 #define A_SKTS_6                        6
 172         {
 173                 X86_SOCKET_UNKNOWN,     /* 0b000 */
 174                 X86_SOCKET_AM3R2,       /* 0b001 */
 175                 X86_SOCKET_UNKNOWN,     /* 0b010 */
 176                 X86_SOCKET_G34,         /* 0b011 */
 177                 X86_SOCKET_UNKNOWN,     /* 0b100 */
 178                 X86_SOCKET_C32,         /* 0b101 */
 179                 X86_SOCKET_UNKNOWN,     /* 0b110 */
 180                 X86_SOCKET_UNKNOWN      /* 0b111 */
 181         },
 182 
 183         /*
 184          * Family 0x15 models 10 - 1f
 185          */
 186 #define A_SKTS_7                        7
 187         {
 188                 X86_SOCKET_FP2,         /* 0b000 */
 189                 X86_SOCKET_FS1R2,       /* 0b001 */
 190                 X86_SOCKET_FM2,         /* 0b010 */
 191                 X86_SOCKET_UNKNOWN,     /* 0b011 */
 192                 X86_SOCKET_UNKNOWN,     /* 0b100 */
 193                 X86_SOCKET_UNKNOWN,     /* 0b101 */
 194                 X86_SOCKET_UNKNOWN,     /* 0b110 */
 195                 X86_SOCKET_UNKNOWN      /* 0b111 */
 196         },
 197 
 198 };
 199 
 200 struct amd_sktmap_s {
 201         uint32_t        skt_code;
 202         char            sktstr[16];
 203 };
 204 static struct amd_sktmap_s amd_sktmap[23] = {
 205         { X86_SOCKET_754,       "754" },
 206         { X86_SOCKET_939,       "939" },
 207         { X86_SOCKET_940,       "940" },
 208         { X86_SOCKET_S1g1,      "S1g1" },
 209         { X86_SOCKET_AM2,       "AM2" },
 210         { X86_SOCKET_F1207,     "F(1207)" },
 211         { X86_SOCKET_S1g2,      "S1g2" },
 212         { X86_SOCKET_S1g3,      "S1g3" },
 213         { X86_SOCKET_AM,        "AM" },
 214         { X86_SOCKET_AM2R2,     "AM2r2" },
 215         { X86_SOCKET_AM3,       "AM3" },
 216         { X86_SOCKET_G34,       "G34" },
 217         { X86_SOCKET_ASB2,      "ASB2" },
 218         { X86_SOCKET_C32,       "C32" },
 219         { X86_SOCKET_FT1,       "FT1" },
 220         { X86_SOCKET_FM1,       "FM1" },
 221         { X86_SOCKET_FS1,       "FS1" },
 222         { X86_SOCKET_AM3R2,     "AM3r2" },
 223         { X86_SOCKET_FP2,       "FP2" },
 224         { X86_SOCKET_FS1R2,     "FS1r2" },
 225         { X86_SOCKET_FM2,       "FM2" },
 226         { X86_SOCKET_UNKNOWN,   "Unknown" }
 227 };
 228 
 229 /*
 230  * Table for mapping AMD Family 0xf and AMD Family 0x10 model/stepping
 231  * combination to chip "revision" and socket type.
 232  *
 233  * The first member of this array that matches a given family, extended model
 234  * plus model range, and stepping range will be considered a match.
 235  */
 236 static const struct amd_rev_mapent {
 237         uint_t rm_family;
 238         uint_t rm_modello;
 239         uint_t rm_modelhi;
 240         uint_t rm_steplo;
 241         uint_t rm_stephi;
 242         uint32_t rm_chiprev;
 243         const char *rm_chiprevstr;
 244         int rm_sktidx;
 245 } amd_revmap[] = {


 280         { 0xf, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_G, "G", A_SKTS_1 },
 281 
 282         /*
 283          * =============== AuthenticAMD Family 0x10 ===============
 284          */
 285 
 286         /*
 287          * Rev A has model 0 and stepping 0/1/2 for DR-{A0,A1,A2}.
 288          * Give all of model 0 stepping range to rev A.
 289          */
 290         { 0x10, 0x00, 0x00, 0x0, 0x2, X86_CHIPREV_AMD_10_REV_A, "A", A_SKTS_2 },
 291 
 292         /*
 293          * Rev B has model 2 and steppings 0/1/0xa/2 for DR-{B0,B1,BA,B2}.
 294          * Give all of model 2 stepping range to rev B.
 295          */
 296         { 0x10, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_B, "B", A_SKTS_2 },
 297 
 298         /*
 299          * Rev C has models 4-6 (depending on L3 cache configuration)
 300          * Give all of models 4-6 stepping range 0-2 to rev C2.
 301          */
 302         { 0x10, 0x4, 0x6, 0x0, 0x2, X86_CHIPREV_AMD_10_REV_C2, "C2", A_SKTS_2 },
 303 
 304         /*
 305          * Rev C has models 4-6 (depending on L3 cache configuration)
 306          * Give all of models 4-6 stepping range >= 3 to rev C3.
 307          */
 308         { 0x10, 0x4, 0x6, 0x3, 0xf, X86_CHIPREV_AMD_10_REV_C3, "C3", A_SKTS_2 },
 309 
 310         /*
 311          * Rev D has models 8 and 9
 312          * Give all of model 8 and 9 stepping 0 to rev D0.
 313          */
 314         { 0x10, 0x8, 0x9, 0x0, 0x0, X86_CHIPREV_AMD_10_REV_D0, "D0", A_SKTS_2 },
 315 
 316         /*
 317          * Rev D has models 8 and 9
 318          * Give all of model 8 and 9 stepping range >= 1 to rev D1.
 319          */
 320         { 0x10, 0x8, 0x9, 0x1, 0xf, X86_CHIPREV_AMD_10_REV_D1, "D1", A_SKTS_2 },
 321 
 322         /*
 323          * Rev E has models A and stepping 0
 324          * Give all of model A stepping range to rev E.
 325          */
 326         { 0x10, 0xA, 0xA, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_E, "E", A_SKTS_2 },
 327 
 328         /*
 329          * =============== AuthenticAMD Family 0x11 ===============
 330          */
 331         { 0x11, 0x03, 0x03, 0x0, 0xf, X86_CHIPREV_AMD_11_REV_B, "B", A_SKTS_3 },
 332 
 333         /*
 334          * =============== AuthenticAMD Family 0x12 ===============
 335          */
 336         { 0x12, 0x01, 0x01, 0x0, 0xf, X86_CHIPREV_AMD_12_REV_B, "B", A_SKTS_4 },
 337 
 338         /*
 339          * =============== AuthenticAMD Family 0x14 ===============
 340          */
 341         { 0x14, 0x01, 0x01, 0x0, 0xf, X86_CHIPREV_AMD_14_REV_B, "B", A_SKTS_5 },
 342         { 0x14, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_14_REV_C, "C", A_SKTS_5 },
 343 
 344         /*
 345          * =============== AuthenticAMD Family 0x15 ===============
 346          */
 347         { 0x15, 0x01, 0x01, 0x2, 0x2, X86_CHIPREV_AMD_15OR_REV_B2, "B2",
 348             A_SKTS_6 },
 349         { 0x15, 0x10, 0x10, 0x1, 0x1, X86_CHIPREV_AMD_15TN_REV_A1, "A1",
 350             A_SKTS_7 },
 351 };
 352 
 353 static void
 354 synth_amd_info(uint_t family, uint_t model, uint_t step,
 355     uint32_t *skt_p, uint32_t *chiprev_p, const char **chiprevstr_p)
 356 {
 357         const struct amd_rev_mapent *rmp;
 358         int found = 0;
 359         int i;
 360 
 361         if (family < 0xf)
 362                 return;
 363 
 364         for (i = 0, rmp = amd_revmap; i < sizeof (amd_revmap) / sizeof (*rmp);
 365             i++, rmp++) {
 366                 if (family == rmp->rm_family &&
 367                     model >= rmp->rm_modello && model <= rmp->rm_modelhi &&
 368                     step >= rmp->rm_steplo && step <= rmp->rm_stephi) {
 369                         found = 1;
 370                         break;


 395                         *skt_p = X86_SOCKET_UNKNOWN;
 396                 } else if (family == 0xf) {
 397                         *skt_p = amd_skts[rmp->rm_sktidx][model & 0x3];
 398                 } else {
 399                         /*
 400                          * Starting with family 10h, socket type is stored in
 401                          * CPUID Fn8000_0001_EBX
 402                          */
 403                         struct cpuid_regs cp;
 404                         int idx;
 405 
 406                         cp.cp_eax = 0x80000001;
 407                         (void) __cpuid_insn(&cp);
 408 
 409                         /* PkgType bits */
 410                         idx = BITX(cp.cp_ebx, 31, 28);
 411 
 412                         if (idx > 7) {
 413                                 /* Reserved bits */
 414                                 *skt_p = X86_SOCKET_UNKNOWN;
 415                         } else {
 416                                 *skt_p = amd_skts[rmp->rm_sktidx][idx];
 417                         }
 418                         if (family == 0x10) {
 419                                 /*
 420                                  * Look at Ddr3Mode bit of DRAM Configuration
 421                                  * High Register to decide whether this is
 422                                  * actually AM3 or S1g4.
 423                                  */
 424                                 uint32_t val;
 425 
 426                                 val = pci_getl_func(0, 24, 2, 0x94);
 427                                 if (BITX(val, 8, 8)) {
 428                                         if (*skt_p == X86_SOCKET_AM2R2)
 429                                                 *skt_p = X86_SOCKET_AM3;
 430                                         else if (*skt_p == X86_SOCKET_S1g3)
 431                                                 *skt_p = X86_SOCKET_S1g4;


 432                                 }
 433                         }
 434                 }
 435         }
 436 }
 437 
 438 uint32_t
 439 _cpuid_skt(uint_t vendor, uint_t family, uint_t model, uint_t step)
 440 {
 441         uint32_t skt = X86_SOCKET_UNKNOWN;
 442 
 443         switch (vendor) {
 444         case X86_VENDOR_AMD:
 445                 synth_amd_info(family, model, step, &skt, NULL, NULL);
 446                 break;
 447 
 448         default:
 449                 break;
 450 
 451         }
 452 
 453         return (skt);
 454 }