1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 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 * Copyright 2012 Nexenta Systems, Inc. All rights reserved. 27 */ 28 29 /* 30 * Portions Copyright 2009 Advanced Micro Devices, Inc. 31 */ 32 33 /* 34 * Copyright 2012 Jens Elkner <jel+illumos@cs.uni-magdeburg.de> 35 * Copyright 2012 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> 36 * Copyright 2019 Joyent, Inc. 37 * Copyright 2021 Oxide Computer Company 38 */ 39 40 /* 41 * Support functions that interpret CPUID and similar information. 42 * These should not be used from anywhere other than cpuid.c and 43 * cmi_hw.c - as such we will not list them in any header file 44 * such as x86_archext.h. 45 * 46 * In cpuid.c we process CPUID information for each cpu_t instance 47 * we're presented with, and stash this raw information and material 48 * derived from it in per-cpu_t structures. 49 * 50 * If we are virtualized then the CPUID information derived from CPUID 51 * instructions executed in the guest is based on whatever the hypervisor 52 * wanted to make things look like, and the cpu_t are not necessarily in 1:1 53 * or fixed correspondence with real processor execution resources. In cmi_hw.c 54 * we are interested in the native properties of a processor - for fault 55 * management (and potentially other, such as power management) purposes; 56 * it will tunnel through to real hardware information, and use the 57 * functionality provided in this file to process it. 58 */ 59 60 #include <sys/types.h> 61 #include <sys/systm.h> 62 #include <sys/bitmap.h> 63 #include <sys/x86_archext.h> 64 #include <sys/pci_cfgspace.h> 65 #include <sys/sysmacros.h> 66 #ifdef __xpv 67 #include <sys/hypervisor.h> 68 #endif 69 70 /* 71 * AMD socket types. 72 * First index : 73 * 0 for family 0xf, revs B thru E 74 * 1 for family 0xf, revs F and G 75 * 2 for family 0x10 76 * 3 for family 0x11 77 * 4 for family 0x12 78 * 5 for family 0x14 79 * 6 for family 0x15, models 00 - 0f 80 * 7 for family 0x15, models 10 - 1f 81 * 8 for family 0x15, models 30 - 3f 82 * 9 for family 0x15, models 60 - 6f 83 * 10 for family 0x15, models 70 - 7f 84 * 11 for family 0x16, models 00 - 0f 85 * 12 for family 0x16, models 30 - 3f 86 * 13 for family 0x17, models 00 - 0f 87 * 14 for family 0x17, models 10 - 2f 88 * 15 for family 0x17, models 30 - 3f 89 * 16 for family 0x17, models 60 - 6f 90 * 17 for family 0x17, models 70 - 7f 91 * 18 for family 0x18, models 00 - 0f 92 * 19 for family 0x19, models 00 - 0f 93 * 20 for family 0x19, models 20 - 2f 94 * 21 for family 0x19, models 50 - 5f 95 * Second index by (model & 0x3) for family 0fh, 96 * CPUID pkg bits (Fn8000_0001_EBX[31:28]) for later families. 97 */ 98 static uint32_t amd_skts[22][8] = { 99 /* 100 * Family 0xf revisions B through E 101 */ 102 #define A_SKTS_0 0 103 { 104 X86_SOCKET_754, /* 0b000 */ 105 X86_SOCKET_940, /* 0b001 */ 106 X86_SOCKET_754, /* 0b010 */ 107 X86_SOCKET_939, /* 0b011 */ 108 X86_SOCKET_UNKNOWN, /* 0b100 */ 109 X86_SOCKET_UNKNOWN, /* 0b101 */ 110 X86_SOCKET_UNKNOWN, /* 0b110 */ 111 X86_SOCKET_UNKNOWN /* 0b111 */ 112 }, 113 /* 114 * Family 0xf revisions F and G 115 */ 116 #define A_SKTS_1 1 117 { 118 X86_SOCKET_S1g1, /* 0b000 */ 119 X86_SOCKET_F1207, /* 0b001 */ 120 X86_SOCKET_UNKNOWN, /* 0b010 */ 121 X86_SOCKET_AM2, /* 0b011 */ 122 X86_SOCKET_UNKNOWN, /* 0b100 */ 123 X86_SOCKET_UNKNOWN, /* 0b101 */ 124 X86_SOCKET_UNKNOWN, /* 0b110 */ 125 X86_SOCKET_UNKNOWN /* 0b111 */ 126 }, 127 /* 128 * Family 0x10 129 */ 130 #define A_SKTS_2 2 131 { 132 X86_SOCKET_F1207, /* 0b000 */ 133 X86_SOCKET_AM2R2, /* 0b001 */ 134 X86_SOCKET_S1g3, /* 0b010 */ 135 X86_SOCKET_G34, /* 0b011 */ 136 X86_SOCKET_ASB2, /* 0b100 */ 137 X86_SOCKET_C32, /* 0b101 */ 138 X86_SOCKET_UNKNOWN, /* 0b110 */ 139 X86_SOCKET_UNKNOWN /* 0b111 */ 140 }, 141 142 /* 143 * Family 0x11 144 */ 145 #define A_SKTS_3 3 146 { 147 X86_SOCKET_UNKNOWN, /* 0b000 */ 148 X86_SOCKET_UNKNOWN, /* 0b001 */ 149 X86_SOCKET_S1g2, /* 0b010 */ 150 X86_SOCKET_UNKNOWN, /* 0b011 */ 151 X86_SOCKET_UNKNOWN, /* 0b100 */ 152 X86_SOCKET_UNKNOWN, /* 0b101 */ 153 X86_SOCKET_UNKNOWN, /* 0b110 */ 154 X86_SOCKET_UNKNOWN /* 0b111 */ 155 }, 156 157 /* 158 * Family 0x12 159 */ 160 #define A_SKTS_4 4 161 { 162 X86_SOCKET_UNKNOWN, /* 0b000 */ 163 X86_SOCKET_FS1, /* 0b001 */ 164 X86_SOCKET_FM1, /* 0b010 */ 165 X86_SOCKET_UNKNOWN, /* 0b011 */ 166 X86_SOCKET_UNKNOWN, /* 0b100 */ 167 X86_SOCKET_UNKNOWN, /* 0b101 */ 168 X86_SOCKET_UNKNOWN, /* 0b110 */ 169 X86_SOCKET_UNKNOWN /* 0b111 */ 170 }, 171 172 /* 173 * Family 0x14 174 */ 175 #define A_SKTS_5 5 176 { 177 X86_SOCKET_FT1, /* 0b000 */ 178 X86_SOCKET_UNKNOWN, /* 0b001 */ 179 X86_SOCKET_UNKNOWN, /* 0b010 */ 180 X86_SOCKET_UNKNOWN, /* 0b011 */ 181 X86_SOCKET_UNKNOWN, /* 0b100 */ 182 X86_SOCKET_UNKNOWN, /* 0b101 */ 183 X86_SOCKET_UNKNOWN, /* 0b110 */ 184 X86_SOCKET_UNKNOWN /* 0b111 */ 185 }, 186 187 /* 188 * Family 0x15 models 00 - 0f 189 */ 190 #define A_SKTS_6 6 191 { 192 X86_SOCKET_UNKNOWN, /* 0b000 */ 193 X86_SOCKET_AM3R2, /* 0b001 */ 194 X86_SOCKET_UNKNOWN, /* 0b010 */ 195 X86_SOCKET_G34, /* 0b011 */ 196 X86_SOCKET_UNKNOWN, /* 0b100 */ 197 X86_SOCKET_C32, /* 0b101 */ 198 X86_SOCKET_UNKNOWN, /* 0b110 */ 199 X86_SOCKET_UNKNOWN /* 0b111 */ 200 }, 201 202 /* 203 * Family 0x15 models 10 - 1f 204 */ 205 #define A_SKTS_7 7 206 { 207 X86_SOCKET_FP2, /* 0b000 */ 208 X86_SOCKET_FS1R2, /* 0b001 */ 209 X86_SOCKET_FM2, /* 0b010 */ 210 X86_SOCKET_UNKNOWN, /* 0b011 */ 211 X86_SOCKET_UNKNOWN, /* 0b100 */ 212 X86_SOCKET_UNKNOWN, /* 0b101 */ 213 X86_SOCKET_UNKNOWN, /* 0b110 */ 214 X86_SOCKET_UNKNOWN /* 0b111 */ 215 }, 216 217 /* 218 * Family 0x15 models 30-3f 219 */ 220 #define A_SKTS_8 8 221 { 222 X86_SOCKET_FP3, /* 0b000 */ 223 X86_SOCKET_FM2R2, /* 0b001 */ 224 X86_SOCKET_UNKNOWN, /* 0b010 */ 225 X86_SOCKET_UNKNOWN, /* 0b011 */ 226 X86_SOCKET_UNKNOWN, /* 0b100 */ 227 X86_SOCKET_UNKNOWN, /* 0b101 */ 228 X86_SOCKET_UNKNOWN, /* 0b110 */ 229 X86_SOCKET_UNKNOWN /* 0b111 */ 230 }, 231 232 /* 233 * Family 0x15 models 60-6f 234 */ 235 #define A_SKTS_9 9 236 { 237 X86_SOCKET_FP4, /* 0b000 */ 238 X86_SOCKET_UNKNOWN, /* 0b001 */ 239 X86_SOCKET_AM4, /* 0b010 */ 240 X86_SOCKET_FM2R2, /* 0b011 */ 241 X86_SOCKET_UNKNOWN, /* 0b100 */ 242 X86_SOCKET_UNKNOWN, /* 0b101 */ 243 X86_SOCKET_UNKNOWN, /* 0b110 */ 244 X86_SOCKET_UNKNOWN /* 0b111 */ 245 }, 246 247 /* 248 * Family 0x15 models 70-7f 249 */ 250 #define A_SKTS_10 10 251 { 252 X86_SOCKET_FP4, /* 0b000 */ 253 X86_SOCKET_UNKNOWN, /* 0b001 */ 254 X86_SOCKET_AM4, /* 0b010 */ 255 X86_SOCKET_UNKNOWN, /* 0b011 */ 256 X86_SOCKET_FT4, /* 0b100 */ 257 X86_SOCKET_UNKNOWN, /* 0b101 */ 258 X86_SOCKET_UNKNOWN, /* 0b110 */ 259 X86_SOCKET_UNKNOWN /* 0b111 */ 260 }, 261 262 /* 263 * Family 0x16 models 00-0f 264 */ 265 #define A_SKTS_11 11 266 { 267 X86_SOCKET_FT3, /* 0b000 */ 268 X86_SOCKET_FS1B, /* 0b001 */ 269 X86_SOCKET_UNKNOWN, /* 0b010 */ 270 X86_SOCKET_UNKNOWN, /* 0b011 */ 271 X86_SOCKET_UNKNOWN, /* 0b100 */ 272 X86_SOCKET_UNKNOWN, /* 0b101 */ 273 X86_SOCKET_UNKNOWN, /* 0b110 */ 274 X86_SOCKET_UNKNOWN /* 0b111 */ 275 }, 276 277 /* 278 * Family 0x16 models 30-3f 279 */ 280 #define A_SKTS_12 12 281 { 282 X86_SOCKET_FT3B, /* 0b000 */ 283 X86_SOCKET_UNKNOWN, /* 0b001 */ 284 X86_SOCKET_UNKNOWN, /* 0b010 */ 285 X86_SOCKET_FP4, /* 0b011 */ 286 X86_SOCKET_UNKNOWN, /* 0b100 */ 287 X86_SOCKET_UNKNOWN, /* 0b101 */ 288 X86_SOCKET_UNKNOWN, /* 0b110 */ 289 X86_SOCKET_UNKNOWN /* 0b111 */ 290 }, 291 292 /* 293 * Family 0x17 models 00-0f (Zen 1 - Naples, Ryzen) 294 */ 295 #define A_SKTS_13 13 296 { 297 X86_SOCKET_UNKNOWN, /* 0b000 */ 298 X86_SOCKET_UNKNOWN, /* 0b001 */ 299 X86_SOCKET_AM4, /* 0b010 */ 300 X86_SOCKET_UNKNOWN, /* 0b011 */ 301 X86_SOCKET_SP3, /* 0b100 */ 302 X86_SOCKET_UNKNOWN, /* 0b101 */ 303 X86_SOCKET_UNKNOWN, /* 0b110 */ 304 X86_SOCKET_SP3R2 /* 0b111 */ 305 }, 306 307 /* 308 * Family 0x17 models 10-2f (Zen 1 - APU: Raven Ridge) 309 * (Zen 1 - APU: Banded Kestrel) 310 * (Zen 1 - APU: Dali) 311 */ 312 #define A_SKTS_14 14 313 { 314 X86_SOCKET_FP5, /* 0b000 */ 315 X86_SOCKET_UNKNOWN, /* 0b001 */ 316 X86_SOCKET_AM4, /* 0b010 */ 317 X86_SOCKET_UNKNOWN, /* 0b011 */ 318 X86_SOCKET_UNKNOWN, /* 0b100 */ 319 X86_SOCKET_UNKNOWN, /* 0b101 */ 320 X86_SOCKET_UNKNOWN, /* 0b110 */ 321 X86_SOCKET_UNKNOWN /* 0b111 */ 322 }, 323 324 /* 325 * Family 0x17 models 30-3f (Zen 2 - Rome) 326 */ 327 #define A_SKTS_15 15 328 { 329 X86_SOCKET_UNKNOWN, /* 0b000 */ 330 X86_SOCKET_UNKNOWN, /* 0b001 */ 331 X86_SOCKET_UNKNOWN, /* 0b010 */ 332 X86_SOCKET_UNKNOWN, /* 0b011 */ 333 X86_SOCKET_SP3, /* 0b100 */ 334 X86_SOCKET_UNKNOWN, /* 0b101 */ 335 X86_SOCKET_UNKNOWN, /* 0b110 */ 336 X86_SOCKET_SP3R2 /* 0b111 */ 337 }, 338 339 /* 340 * Family 0x17 models 60-6f (Zen 2 - Renoir) 341 */ 342 #define A_SKTS_16 16 343 { 344 X86_SOCKET_FP6, /* 0b000 */ 345 X86_SOCKET_UNKNOWN, /* 0b001 */ 346 X86_SOCKET_AM4, /* 0b010 */ 347 X86_SOCKET_UNKNOWN, /* 0b011 */ 348 X86_SOCKET_UNKNOWN, /* 0b100 */ 349 X86_SOCKET_UNKNOWN, /* 0b101 */ 350 X86_SOCKET_UNKNOWN, /* 0b110 */ 351 X86_SOCKET_UNKNOWN /* 0b111 */ 352 }, 353 354 /* 355 * Family 0x17 models 70-7f (Zen 2 - Matisse) 356 */ 357 #define A_SKTS_17 17 358 { 359 X86_SOCKET_UNKNOWN, /* 0b000 */ 360 X86_SOCKET_UNKNOWN, /* 0b001 */ 361 X86_SOCKET_AM4, /* 0b010 */ 362 X86_SOCKET_UNKNOWN, /* 0b011 */ 363 X86_SOCKET_UNKNOWN, /* 0b100 */ 364 X86_SOCKET_UNKNOWN, /* 0b101 */ 365 X86_SOCKET_UNKNOWN, /* 0b110 */ 366 X86_SOCKET_UNKNOWN /* 0b111 */ 367 }, 368 369 /* 370 * Family 0x18 models 00-0f (Dhyana) 371 */ 372 #define A_SKTS_18 18 373 { 374 X86_SOCKET_UNKNOWN, /* 0b000 */ 375 X86_SOCKET_UNKNOWN, /* 0b001 */ 376 X86_SOCKET_UNKNOWN, /* 0b010 */ 377 X86_SOCKET_UNKNOWN, /* 0b011 */ 378 X86_SOCKET_SL1, /* 0b100 */ 379 X86_SOCKET_UNKNOWN, /* 0b101 */ 380 X86_SOCKET_DM1, /* 0b110 */ 381 X86_SOCKET_SL1R2 /* 0b111 */ 382 }, 383 384 /* 385 * Family 0x19 models 00-0f (Zen 3 - Milan) 386 */ 387 #define A_SKTS_19 19 388 { 389 X86_SOCKET_UNKNOWN, /* 0b000 */ 390 X86_SOCKET_UNKNOWN, /* 0b001 */ 391 X86_SOCKET_UNKNOWN, /* 0b010 */ 392 X86_SOCKET_UNKNOWN, /* 0b011 */ 393 X86_SOCKET_SP3, /* 0b100 */ 394 X86_SOCKET_UNKNOWN, /* 0b101 */ 395 X86_SOCKET_UNKNOWN, /* 0b110 */ 396 X86_SOCKET_STRX4 /* 0b111 */ 397 }, 398 399 /* 400 * Family 0x19 models 20-2f (Zen 3 - Vermeer) 401 */ 402 #define A_SKTS_20 20 403 { 404 X86_SOCKET_UNKNOWN, /* 0b000 */ 405 X86_SOCKET_UNKNOWN, /* 0b001 */ 406 X86_SOCKET_AM4, /* 0b010 */ 407 X86_SOCKET_UNKNOWN, /* 0b011 */ 408 X86_SOCKET_UNKNOWN, /* 0b100 */ 409 X86_SOCKET_UNKNOWN, /* 0b101 */ 410 X86_SOCKET_UNKNOWN, /* 0b110 */ 411 X86_SOCKET_UNKNOWN /* 0b111 */ 412 }, 413 414 /* 415 * Family 0x19 models 50-5f (Zen 3 - Cezanne) 416 */ 417 #define A_SKTS_21 21 418 { 419 X86_SOCKET_FP6, /* 0b000 */ 420 X86_SOCKET_UNKNOWN, /* 0b001 */ 421 X86_SOCKET_AM4, /* 0b010 */ 422 X86_SOCKET_UNKNOWN, /* 0b011 */ 423 X86_SOCKET_UNKNOWN, /* 0b100 */ 424 X86_SOCKET_UNKNOWN, /* 0b101 */ 425 X86_SOCKET_UNKNOWN, /* 0b110 */ 426 X86_SOCKET_UNKNOWN /* 0b111 */ 427 }, 428 }; 429 430 struct amd_sktmap_s { 431 uint32_t skt_code; 432 char sktstr[16]; 433 }; 434 static struct amd_sktmap_s amd_sktmap_strs[X86_NUM_SOCKETS + 1] = { 435 { X86_SOCKET_754, "754" }, 436 { X86_SOCKET_939, "939" }, 437 { X86_SOCKET_940, "940" }, 438 { X86_SOCKET_S1g1, "S1g1" }, 439 { X86_SOCKET_AM2, "AM2" }, 440 { X86_SOCKET_F1207, "F(1207)" }, 441 { X86_SOCKET_S1g2, "S1g2" }, 442 { X86_SOCKET_S1g3, "S1g3" }, 443 { X86_SOCKET_AM, "AM" }, 444 { X86_SOCKET_AM2R2, "AM2r2" }, 445 { X86_SOCKET_AM3, "AM3" }, 446 { X86_SOCKET_G34, "G34" }, 447 { X86_SOCKET_ASB2, "ASB2" }, 448 { X86_SOCKET_C32, "C32" }, 449 { X86_SOCKET_FT1, "FT1" }, 450 { X86_SOCKET_FM1, "FM1" }, 451 { X86_SOCKET_FS1, "FS1" }, 452 { X86_SOCKET_AM3R2, "AM3r2" }, 453 { X86_SOCKET_FP2, "FP2" }, 454 { X86_SOCKET_FS1R2, "FS1r2" }, 455 { X86_SOCKET_FM2, "FM2" }, 456 { X86_SOCKET_FP3, "FP3" }, 457 { X86_SOCKET_FM2R2, "FM2r2" }, 458 { X86_SOCKET_FP4, "FP4" }, 459 { X86_SOCKET_AM4, "AM4" }, 460 { X86_SOCKET_FT3, "FT3" }, 461 { X86_SOCKET_FT4, "FT4" }, 462 { X86_SOCKET_FS1B, "FS1b" }, 463 { X86_SOCKET_FT3B, "FT3b" }, 464 { X86_SOCKET_SP3, "SP3" }, 465 { X86_SOCKET_SP3R2, "SP3r2" }, 466 { X86_SOCKET_FP5, "FP5" }, 467 { X86_SOCKET_FP6, "FP6" }, 468 { X86_SOCKET_STRX4, "sTRX4" }, 469 { X86_SOCKET_SL1, "SL1" }, 470 { X86_SOCKET_SL1R2, "SL1R2" }, 471 { X86_SOCKET_DM1, "DM1" }, 472 { X86_SOCKET_UNKNOWN, "Unknown" } 473 }; 474 475 static const struct amd_skt_mapent { 476 uint_t sm_family; 477 uint_t sm_modello; 478 uint_t sm_modelhi; 479 uint_t sm_sktidx; 480 } amd_sktmap[] = { 481 { 0x10, 0x00, 0xff, A_SKTS_2 }, 482 { 0x11, 0x00, 0xff, A_SKTS_3 }, 483 { 0x12, 0x00, 0xff, A_SKTS_4 }, 484 { 0x14, 0x00, 0x0f, A_SKTS_5 }, 485 { 0x15, 0x00, 0x0f, A_SKTS_6 }, 486 { 0x15, 0x10, 0x1f, A_SKTS_7 }, 487 { 0x15, 0x30, 0x3f, A_SKTS_8 }, 488 { 0x15, 0x60, 0x6f, A_SKTS_9 }, 489 { 0x15, 0x70, 0x7f, A_SKTS_10 }, 490 { 0x16, 0x00, 0x0f, A_SKTS_11 }, 491 { 0x16, 0x30, 0x3f, A_SKTS_12 }, 492 { 0x17, 0x00, 0x0f, A_SKTS_13 }, 493 { 0x17, 0x10, 0x2f, A_SKTS_14 }, 494 { 0x17, 0x30, 0x3f, A_SKTS_15 }, 495 { 0x17, 0x60, 0x6f, A_SKTS_16 }, 496 { 0x17, 0x70, 0x7f, A_SKTS_17 }, 497 { 0x18, 0x00, 0x0f, A_SKTS_18 }, 498 { 0x19, 0x00, 0x0f, A_SKTS_19 }, 499 { 0x19, 0x20, 0x2f, A_SKTS_20 }, 500 { 0x19, 0x50, 0x5f, A_SKTS_21 } 501 }; 502 503 /* 504 * Table for mapping AMD Family 0xf and AMD Family 0x10 model/stepping 505 * combination to chip "revision" and socket type. 506 * 507 * The first member of this array that matches a given family, extended model 508 * plus model range, and stepping range will be considered a match. 509 */ 510 static const struct amd_rev_mapent { 511 uint_t rm_family; 512 uint_t rm_modello; 513 uint_t rm_modelhi; 514 uint_t rm_steplo; 515 uint_t rm_stephi; 516 uint32_t rm_chiprev; 517 const char *rm_chiprevstr; 518 uint_t rm_sktidx; 519 } amd_revmap[] = { 520 /* 521 * =============== AuthenticAMD Family 0xf =============== 522 */ 523 524 /* 525 * Rev B includes model 0x4 stepping 0 and model 0x5 stepping 0 and 1. 526 */ 527 { 0xf, 0x04, 0x04, 0x0, 0x0, X86_CHIPREV_AMD_F_REV_B, "B", A_SKTS_0 }, 528 { 0xf, 0x05, 0x05, 0x0, 0x1, X86_CHIPREV_AMD_F_REV_B, "B", A_SKTS_0 }, 529 /* 530 * Rev C0 includes model 0x4 stepping 8 and model 0x5 stepping 8 531 */ 532 { 0xf, 0x04, 0x05, 0x8, 0x8, X86_CHIPREV_AMD_F_REV_C0, "C0", A_SKTS_0 }, 533 /* 534 * Rev CG is the rest of extended model 0x0 - i.e., everything 535 * but the rev B and C0 combinations covered above. 536 */ 537 { 0xf, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_CG, "CG", A_SKTS_0 }, 538 /* 539 * Rev D has extended model 0x1. 540 */ 541 { 0xf, 0x10, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_D, "D", A_SKTS_0 }, 542 /* 543 * Rev E has extended model 0x2. 544 * Extended model 0x3 is unused but available to grow into. 545 */ 546 { 0xf, 0x20, 0x3f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_E, "E", A_SKTS_0 }, 547 /* 548 * Rev F has extended models 0x4 and 0x5. 549 */ 550 { 0xf, 0x40, 0x5f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_F, "F", A_SKTS_1 }, 551 /* 552 * Rev G has extended model 0x6. 553 */ 554 { 0xf, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_F_REV_G, "G", A_SKTS_1 }, 555 556 /* 557 * =============== AuthenticAMD Family 0x10 =============== 558 */ 559 560 /* 561 * Rev A has model 0 and stepping 0/1/2 for DR-{A0,A1,A2}. 562 * Give all of model 0 stepping range to rev A. 563 */ 564 { 0x10, 0x00, 0x00, 0x0, 0x2, X86_CHIPREV_AMD_10_REV_A, "A", A_SKTS_2 }, 565 566 /* 567 * Rev B has model 2 and steppings 0/1/0xa/2 for DR-{B0,B1,BA,B2}. 568 * Give all of model 2 stepping range to rev B. 569 */ 570 { 0x10, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_B, "B", A_SKTS_2 }, 571 572 /* 573 * Rev C has models 4-6 (depending on L3 cache configuration) 574 * Give all of models 4-6 stepping range 0-2 to rev C2. 575 */ 576 { 0x10, 0x4, 0x6, 0x0, 0x2, X86_CHIPREV_AMD_10_REV_C2, "C2", A_SKTS_2 }, 577 578 /* 579 * Rev C has models 4-6 (depending on L3 cache configuration) 580 * Give all of models 4-6 stepping range >= 3 to rev C3. 581 */ 582 { 0x10, 0x4, 0x6, 0x3, 0xf, X86_CHIPREV_AMD_10_REV_C3, "C3", A_SKTS_2 }, 583 584 /* 585 * Rev D has models 8 and 9 586 * Give all of model 8 and 9 stepping 0 to rev D0. 587 */ 588 { 0x10, 0x8, 0x9, 0x0, 0x0, X86_CHIPREV_AMD_10_REV_D0, "D0", A_SKTS_2 }, 589 590 /* 591 * Rev D has models 8 and 9 592 * Give all of model 8 and 9 stepping range >= 1 to rev D1. 593 */ 594 { 0x10, 0x8, 0x9, 0x1, 0xf, X86_CHIPREV_AMD_10_REV_D1, "D1", A_SKTS_2 }, 595 596 /* 597 * Rev E has models A and stepping 0 598 * Give all of model A stepping range to rev E. 599 */ 600 { 0x10, 0xA, 0xA, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_E, "E", A_SKTS_2 }, 601 602 /* 603 * =============== AuthenticAMD Family 0x11 =============== 604 */ 605 { 0x11, 0x03, 0x03, 0x0, 0xf, X86_CHIPREV_AMD_11_REV_B, "B", A_SKTS_3 }, 606 607 /* 608 * =============== AuthenticAMD Family 0x12 =============== 609 */ 610 { 0x12, 0x01, 0x01, 0x0, 0xf, X86_CHIPREV_AMD_12_REV_B, "B", A_SKTS_4 }, 611 612 /* 613 * =============== AuthenticAMD Family 0x14 =============== 614 */ 615 { 0x14, 0x01, 0x01, 0x0, 0xf, X86_CHIPREV_AMD_14_REV_B, "B", A_SKTS_5 }, 616 { 0x14, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_14_REV_C, "C", A_SKTS_5 }, 617 618 /* 619 * =============== AuthenticAMD Family 0x15 =============== 620 */ 621 { 0x15, 0x01, 0x01, 0x2, 0x2, X86_CHIPREV_AMD_15OR_REV_B2, "OR-B2", 622 A_SKTS_6 }, 623 { 0x15, 0x02, 0x02, 0x0, 0x0, X86_CHIPREV_AMD_150R_REV_C0, "OR-C0", 624 A_SKTS_6 }, 625 { 0x15, 0x10, 0x10, 0x1, 0x1, X86_CHIPREV_AMD_15TN_REV_A1, "TN-A1", 626 A_SKTS_7 }, 627 { 0x15, 0x30, 0x30, 0x1, 0x1, X86_CHIPREV_AMD_15KV_REV_A1, "KV-A1", 628 A_SKTS_8 }, 629 /* 630 * There is no Family 15 Models 60-6f revision guide available, so at 631 * least get the socket information. 632 */ 633 { 0x15, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_15F60, "??", 634 A_SKTS_9 }, 635 { 0x15, 0x70, 0x70, 0x0, 0x0, X86_CHIPREV_AMD_15ST_REV_A0, "ST-A0", 636 A_SKTS_10 }, 637 638 /* 639 * =============== AuthenticAMD Family 0x16 =============== 640 */ 641 { 0x16, 0x00, 0x00, 0x1, 0x1, X86_CHIPREV_AMD_16_KB_A1, "KB-A1", 642 A_SKTS_11 }, 643 { 0x16, 0x30, 0x30, 0x1, 0x1, X86_CHIPREV_AMD_16_ML_A1, "ML-A1", 644 A_SKTS_12 }, 645 646 /* 647 * =============== AuthenticAMD Family 0x17 =============== 648 */ 649 { 0x17, 0x01, 0x01, 0x1, 0x1, X86_CHIPREV_AMD_17_ZP_B1, "ZP-B1", 650 A_SKTS_13 }, 651 { 0x17, 0x01, 0x01, 0x2, 0x2, X86_CHIPREV_AMD_17_ZP_B2, "ZP-B2", 652 A_SKTS_13 }, 653 { 0x17, 0x01, 0x01, 0x1, 0x1, X86_CHIPREV_AMD_17_PiR_B2, "PiR-B2", 654 A_SKTS_13 }, 655 656 { 0x17, 0x11, 0x11, 0x0, 0x0, X86_CHIPREV_AMD_17_RV_B0, "RV-B0", 657 A_SKTS_14 }, 658 { 0x17, 0x11, 0x11, 0x1, 0x1, X86_CHIPREV_AMD_17_RV_B1, "RV-B1", 659 A_SKTS_14 }, 660 { 0x17, 0x18, 0x18, 0x1, 0x1, X86_CHIPREV_AMD_17_PCO_B1, "PCO-B1", 661 A_SKTS_14 }, 662 663 { 0x17, 0x30, 0x30, 0x0, 0x0, X86_CHIPREV_AMD_17_SSP_A0, "SSP-A0", 664 A_SKTS_15 }, 665 { 0x17, 0x31, 0x31, 0x0, 0x0, X86_CHIPREV_AMD_17_SSP_B0, "SSP-B0", 666 A_SKTS_15 }, 667 668 { 0x17, 0x71, 0x71, 0x0, 0x0, X86_CHIPREV_AMD_17_MTS_B0, "MTS-B0", 669 A_SKTS_17 }, 670 671 /* 672 * =============== HygonGenuine Family 0x18 =============== 673 */ 674 { 0x18, 0x00, 0x00, 0x1, 0x1, X86_CHIPREV_HYGON_18_DN_A1, "DN_A1", 675 A_SKTS_18 }, 676 677 /* 678 * =============== AuthenticAMD Family 0x19 =============== 679 */ 680 { 0x19, 0x00, 0x00, 0x0, 0x0, X86_CHIPREV_AMD_19_GN_A0, "GN-A0", 681 A_SKTS_19 }, 682 { 0x19, 0x01, 0x01, 0x0, 0x0, X86_CHIPREV_AMD_19_GN_B0, "GN-B0", 683 A_SKTS_19 }, 684 { 0x19, 0x01, 0x01, 0x1, 0x1, X86_CHIPREV_AMD_19_GN_B1, "GN-B1", 685 A_SKTS_19 }, 686 687 { 0x19, 0x21, 0x21, 0x0, 0x0, X86_CHIPREV_AMD_19_VMR_B0, "VMR-B0", 688 A_SKTS_20 }, 689 { 0x19, 0x21, 0x21, 0x2, 0x2, X86_CHIPREV_AMD_19_VMR_B1, "VMR-B1", 690 A_SKTS_20 }, 691 }; 692 693 /* 694 * AMD keeps the socket type in CPUID Fn8000_0001_EBX, bits 31:28. 695 */ 696 static uint32_t 697 synth_amd_skt_cpuid(uint_t family, uint_t sktid) 698 { 699 struct cpuid_regs cp; 700 uint_t idx; 701 702 cp.cp_eax = 0x80000001; 703 (void) __cpuid_insn(&cp); 704 705 /* PkgType bits */ 706 idx = BITX(cp.cp_ebx, 31, 28); 707 708 if (idx > 7) { 709 return (X86_SOCKET_UNKNOWN); 710 } 711 712 if (family == 0x10) { 713 uint32_t val; 714 715 val = pci_getl_func(0, 24, 2, 0x94); 716 if (BITX(val, 8, 8)) { 717 if (amd_skts[sktid][idx] == X86_SOCKET_AM2R2) { 718 return (X86_SOCKET_AM3); 719 } else if (amd_skts[sktid][idx] == X86_SOCKET_S1g3) { 720 return (X86_SOCKET_S1g4); 721 } 722 } 723 } 724 725 return (amd_skts[sktid][idx]); 726 } 727 728 static void 729 synth_amd_skt(uint_t family, uint_t model, uint32_t *skt_p) 730 { 731 int platform; 732 const struct amd_skt_mapent *skt; 733 uint_t i; 734 735 if (skt_p == NULL || family < 0xf) 736 return; 737 738 #ifdef __xpv 739 /* PV guest */ 740 if (!is_controldom()) { 741 *skt_p = X86_SOCKET_UNKNOWN; 742 return; 743 } 744 #endif 745 platform = get_hwenv(); 746 747 if ((platform & HW_VIRTUAL) != 0) { 748 *skt_p = X86_SOCKET_UNKNOWN; 749 return; 750 } 751 752 for (i = 0, skt = amd_sktmap; i < ARRAY_SIZE(amd_sktmap); 753 i++, skt++) { 754 if (family == skt->sm_family && 755 model >= skt->sm_modello && model <= skt->sm_modelhi) { 756 *skt_p = synth_amd_skt_cpuid(family, skt->sm_sktidx); 757 } 758 } 759 } 760 761 static void 762 synth_amd_info(uint_t family, uint_t model, uint_t step, 763 uint32_t *skt_p, uint32_t *chiprev_p, const char **chiprevstr_p) 764 { 765 const struct amd_rev_mapent *rmp; 766 int found = 0; 767 int i; 768 769 if (family < 0xf) 770 return; 771 772 for (i = 0, rmp = amd_revmap; i < ARRAY_SIZE(amd_revmap); i++, rmp++) { 773 if (family == rmp->rm_family && 774 model >= rmp->rm_modello && model <= rmp->rm_modelhi && 775 step >= rmp->rm_steplo && step <= rmp->rm_stephi) { 776 found = 1; 777 break; 778 } 779 } 780 781 if (!found) { 782 synth_amd_skt(family, model, skt_p); 783 return; 784 } 785 786 if (chiprev_p != NULL) 787 *chiprev_p = rmp->rm_chiprev; 788 if (chiprevstr_p != NULL) 789 *chiprevstr_p = rmp->rm_chiprevstr; 790 791 if (skt_p != NULL) { 792 int platform; 793 794 #ifdef __xpv 795 /* PV guest */ 796 if (!is_controldom()) { 797 *skt_p = X86_SOCKET_UNKNOWN; 798 return; 799 } 800 #endif 801 platform = get_hwenv(); 802 803 if ((platform & HW_VIRTUAL) != 0) { 804 *skt_p = X86_SOCKET_UNKNOWN; 805 } else if (family == 0xf) { 806 *skt_p = amd_skts[rmp->rm_sktidx][model & 0x3]; 807 } else { 808 *skt_p = synth_amd_skt_cpuid(family, rmp->rm_sktidx); 809 } 810 } 811 } 812 813 uint32_t 814 _cpuid_skt(uint_t vendor, uint_t family, uint_t model, uint_t step) 815 { 816 uint32_t skt = X86_SOCKET_UNKNOWN; 817 818 switch (vendor) { 819 case X86_VENDOR_AMD: 820 case X86_VENDOR_HYGON: 821 synth_amd_info(family, model, step, &skt, NULL, NULL); 822 break; 823 824 default: 825 break; 826 827 } 828 829 return (skt); 830 } 831 832 const char * 833 _cpuid_sktstr(uint_t vendor, uint_t family, uint_t model, uint_t step) 834 { 835 const char *sktstr = "Unknown"; 836 struct amd_sktmap_s *sktmapp; 837 uint32_t skt = X86_SOCKET_UNKNOWN; 838 839 switch (vendor) { 840 case X86_VENDOR_AMD: 841 case X86_VENDOR_HYGON: 842 synth_amd_info(family, model, step, &skt, NULL, NULL); 843 844 sktmapp = amd_sktmap_strs; 845 while (sktmapp->skt_code != X86_SOCKET_UNKNOWN) { 846 if (sktmapp->skt_code == skt) 847 break; 848 sktmapp++; 849 } 850 sktstr = sktmapp->sktstr; 851 break; 852 853 default: 854 break; 855 856 } 857 858 return (sktstr); 859 } 860 861 uint32_t 862 _cpuid_chiprev(uint_t vendor, uint_t family, uint_t model, uint_t step) 863 { 864 uint32_t chiprev = X86_CHIPREV_UNKNOWN; 865 866 switch (vendor) { 867 case X86_VENDOR_AMD: 868 case X86_VENDOR_HYGON: 869 synth_amd_info(family, model, step, NULL, &chiprev, NULL); 870 break; 871 872 default: 873 break; 874 875 } 876 877 return (chiprev); 878 } 879 880 const char * 881 _cpuid_chiprevstr(uint_t vendor, uint_t family, uint_t model, uint_t step) 882 { 883 const char *revstr = "Unknown"; 884 885 switch (vendor) { 886 case X86_VENDOR_AMD: 887 case X86_VENDOR_HYGON: 888 synth_amd_info(family, model, step, NULL, NULL, &revstr); 889 break; 890 891 default: 892 break; 893 894 } 895 896 return (revstr); 897 898 } 899 900 /* 901 * Map the vendor string to a type code 902 */ 903 uint_t 904 _cpuid_vendorstr_to_vendorcode(char *vendorstr) 905 { 906 if (strcmp(vendorstr, X86_VENDORSTR_Intel) == 0) 907 return (X86_VENDOR_Intel); 908 else if (strcmp(vendorstr, X86_VENDORSTR_AMD) == 0) 909 return (X86_VENDOR_AMD); 910 else if (strcmp(vendorstr, X86_VENDORSTR_HYGON) == 0) 911 return (X86_VENDOR_HYGON); 912 else if (strcmp(vendorstr, X86_VENDORSTR_TM) == 0) 913 return (X86_VENDOR_TM); 914 else if (strcmp(vendorstr, X86_VENDORSTR_CYRIX) == 0) 915 return (X86_VENDOR_Cyrix); 916 else if (strcmp(vendorstr, X86_VENDORSTR_UMC) == 0) 917 return (X86_VENDOR_UMC); 918 else if (strcmp(vendorstr, X86_VENDORSTR_NexGen) == 0) 919 return (X86_VENDOR_NexGen); 920 else if (strcmp(vendorstr, X86_VENDORSTR_Centaur) == 0) 921 return (X86_VENDOR_Centaur); 922 else if (strcmp(vendorstr, X86_VENDORSTR_Rise) == 0) 923 return (X86_VENDOR_Rise); 924 else if (strcmp(vendorstr, X86_VENDORSTR_SiS) == 0) 925 return (X86_VENDOR_SiS); 926 else if (strcmp(vendorstr, X86_VENDORSTR_NSC) == 0) 927 return (X86_VENDOR_NSC); 928 else 929 return (X86_VENDOR_IntelClone); 930 } 931