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 defines a processor family; see notes inline. The second index 73 * selects the socket type by either (model & 0x3) for family 0fh or the CPUID 74 * pkg bits (Fn8000_0001_EBX[31:28]) for later families. 75 */ 76 static uint32_t amd_skts[][8] = { 77 /* 78 * Family 0xf revisions B through E 79 */ 80 #define A_SKTS_0 0 81 { 82 X86_SOCKET_754, /* 0b000 */ 83 X86_SOCKET_940, /* 0b001 */ 84 X86_SOCKET_754, /* 0b010 */ 85 X86_SOCKET_939, /* 0b011 */ 86 X86_SOCKET_UNKNOWN, /* 0b100 */ 87 X86_SOCKET_UNKNOWN, /* 0b101 */ 88 X86_SOCKET_UNKNOWN, /* 0b110 */ 89 X86_SOCKET_UNKNOWN /* 0b111 */ 90 }, 91 /* 92 * Family 0xf revisions F and G 93 */ 94 #define A_SKTS_1 1 95 { 96 X86_SOCKET_S1g1, /* 0b000 */ 97 X86_SOCKET_F1207, /* 0b001 */ 98 X86_SOCKET_UNKNOWN, /* 0b010 */ 99 X86_SOCKET_AM2, /* 0b011 */ 100 X86_SOCKET_UNKNOWN, /* 0b100 */ 101 X86_SOCKET_UNKNOWN, /* 0b101 */ 102 X86_SOCKET_UNKNOWN, /* 0b110 */ 103 X86_SOCKET_UNKNOWN /* 0b111 */ 104 }, 105 /* 106 * Family 0x10 107 */ 108 #define A_SKTS_2 2 109 { 110 X86_SOCKET_F1207, /* 0b000 */ 111 X86_SOCKET_AM2R2, /* 0b001 */ 112 X86_SOCKET_S1g3, /* 0b010 */ 113 X86_SOCKET_G34, /* 0b011 */ 114 X86_SOCKET_ASB2, /* 0b100 */ 115 X86_SOCKET_C32, /* 0b101 */ 116 X86_SOCKET_UNKNOWN, /* 0b110 */ 117 X86_SOCKET_UNKNOWN /* 0b111 */ 118 }, 119 120 /* 121 * Family 0x11 122 */ 123 #define A_SKTS_3 3 124 { 125 X86_SOCKET_UNKNOWN, /* 0b000 */ 126 X86_SOCKET_UNKNOWN, /* 0b001 */ 127 X86_SOCKET_S1g2, /* 0b010 */ 128 X86_SOCKET_UNKNOWN, /* 0b011 */ 129 X86_SOCKET_UNKNOWN, /* 0b100 */ 130 X86_SOCKET_UNKNOWN, /* 0b101 */ 131 X86_SOCKET_UNKNOWN, /* 0b110 */ 132 X86_SOCKET_UNKNOWN /* 0b111 */ 133 }, 134 135 /* 136 * Family 0x12 137 */ 138 #define A_SKTS_4 4 139 { 140 X86_SOCKET_UNKNOWN, /* 0b000 */ 141 X86_SOCKET_FS1, /* 0b001 */ 142 X86_SOCKET_FM1, /* 0b010 */ 143 X86_SOCKET_UNKNOWN, /* 0b011 */ 144 X86_SOCKET_UNKNOWN, /* 0b100 */ 145 X86_SOCKET_UNKNOWN, /* 0b101 */ 146 X86_SOCKET_UNKNOWN, /* 0b110 */ 147 X86_SOCKET_UNKNOWN /* 0b111 */ 148 }, 149 150 /* 151 * Family 0x14 152 */ 153 #define A_SKTS_5 5 154 { 155 X86_SOCKET_FT1, /* 0b000 */ 156 X86_SOCKET_UNKNOWN, /* 0b001 */ 157 X86_SOCKET_UNKNOWN, /* 0b010 */ 158 X86_SOCKET_UNKNOWN, /* 0b011 */ 159 X86_SOCKET_UNKNOWN, /* 0b100 */ 160 X86_SOCKET_UNKNOWN, /* 0b101 */ 161 X86_SOCKET_UNKNOWN, /* 0b110 */ 162 X86_SOCKET_UNKNOWN /* 0b111 */ 163 }, 164 165 /* 166 * Family 0x15 models 00 - 0f 167 */ 168 #define A_SKTS_6 6 169 { 170 X86_SOCKET_UNKNOWN, /* 0b000 */ 171 X86_SOCKET_AM3R2, /* 0b001 */ 172 X86_SOCKET_UNKNOWN, /* 0b010 */ 173 X86_SOCKET_G34, /* 0b011 */ 174 X86_SOCKET_UNKNOWN, /* 0b100 */ 175 X86_SOCKET_C32, /* 0b101 */ 176 X86_SOCKET_UNKNOWN, /* 0b110 */ 177 X86_SOCKET_UNKNOWN /* 0b111 */ 178 }, 179 180 /* 181 * Family 0x15 models 10 - 1f 182 */ 183 #define A_SKTS_7 7 184 { 185 X86_SOCKET_FP2, /* 0b000 */ 186 X86_SOCKET_FS1R2, /* 0b001 */ 187 X86_SOCKET_FM2, /* 0b010 */ 188 X86_SOCKET_UNKNOWN, /* 0b011 */ 189 X86_SOCKET_UNKNOWN, /* 0b100 */ 190 X86_SOCKET_UNKNOWN, /* 0b101 */ 191 X86_SOCKET_UNKNOWN, /* 0b110 */ 192 X86_SOCKET_UNKNOWN /* 0b111 */ 193 }, 194 195 /* 196 * Family 0x15 models 30-3f 197 */ 198 #define A_SKTS_8 8 199 { 200 X86_SOCKET_FP3, /* 0b000 */ 201 X86_SOCKET_FM2R2, /* 0b001 */ 202 X86_SOCKET_UNKNOWN, /* 0b010 */ 203 X86_SOCKET_UNKNOWN, /* 0b011 */ 204 X86_SOCKET_UNKNOWN, /* 0b100 */ 205 X86_SOCKET_UNKNOWN, /* 0b101 */ 206 X86_SOCKET_UNKNOWN, /* 0b110 */ 207 X86_SOCKET_UNKNOWN /* 0b111 */ 208 }, 209 210 /* 211 * Family 0x15 models 60-6f 212 */ 213 #define A_SKTS_9 9 214 { 215 X86_SOCKET_FP4, /* 0b000 */ 216 X86_SOCKET_UNKNOWN, /* 0b001 */ 217 X86_SOCKET_AM4, /* 0b010 */ 218 X86_SOCKET_FM2R2, /* 0b011 */ 219 X86_SOCKET_UNKNOWN, /* 0b100 */ 220 X86_SOCKET_UNKNOWN, /* 0b101 */ 221 X86_SOCKET_UNKNOWN, /* 0b110 */ 222 X86_SOCKET_UNKNOWN /* 0b111 */ 223 }, 224 225 /* 226 * Family 0x15 models 70-7f 227 */ 228 #define A_SKTS_10 10 229 { 230 X86_SOCKET_FP4, /* 0b000 */ 231 X86_SOCKET_UNKNOWN, /* 0b001 */ 232 X86_SOCKET_AM4, /* 0b010 */ 233 X86_SOCKET_UNKNOWN, /* 0b011 */ 234 X86_SOCKET_FT4, /* 0b100 */ 235 X86_SOCKET_UNKNOWN, /* 0b101 */ 236 X86_SOCKET_UNKNOWN, /* 0b110 */ 237 X86_SOCKET_UNKNOWN /* 0b111 */ 238 }, 239 240 /* 241 * Family 0x16 models 00-0f 242 */ 243 #define A_SKTS_11 11 244 { 245 X86_SOCKET_FT3, /* 0b000 */ 246 X86_SOCKET_FS1B, /* 0b001 */ 247 X86_SOCKET_UNKNOWN, /* 0b010 */ 248 X86_SOCKET_UNKNOWN, /* 0b011 */ 249 X86_SOCKET_UNKNOWN, /* 0b100 */ 250 X86_SOCKET_UNKNOWN, /* 0b101 */ 251 X86_SOCKET_UNKNOWN, /* 0b110 */ 252 X86_SOCKET_UNKNOWN /* 0b111 */ 253 }, 254 255 /* 256 * Family 0x16 models 30-3f 257 */ 258 #define A_SKTS_12 12 259 { 260 X86_SOCKET_FT3B, /* 0b000 */ 261 X86_SOCKET_UNKNOWN, /* 0b001 */ 262 X86_SOCKET_UNKNOWN, /* 0b010 */ 263 X86_SOCKET_FP4, /* 0b011 */ 264 X86_SOCKET_UNKNOWN, /* 0b100 */ 265 X86_SOCKET_UNKNOWN, /* 0b101 */ 266 X86_SOCKET_UNKNOWN, /* 0b110 */ 267 X86_SOCKET_UNKNOWN /* 0b111 */ 268 }, 269 270 /* 271 * Family 0x17 models 00-0f (Zen 1 - Naples, Ryzen) 272 */ 273 #define A_SKTS_13 13 274 { 275 X86_SOCKET_UNKNOWN, /* 0b000 */ 276 X86_SOCKET_UNKNOWN, /* 0b001 */ 277 X86_SOCKET_AM4, /* 0b010 */ 278 X86_SOCKET_UNKNOWN, /* 0b011 */ 279 X86_SOCKET_SP3, /* 0b100 */ 280 X86_SOCKET_UNKNOWN, /* 0b101 */ 281 X86_SOCKET_UNKNOWN, /* 0b110 */ 282 X86_SOCKET_SP3R2 /* 0b111 */ 283 }, 284 285 /* 286 * Family 0x17 models 10-2f (Zen 1 - APU: Raven Ridge) 287 * (Zen 1 - APU: Banded Kestrel) 288 * (Zen 1 - APU: Dali) 289 */ 290 #define A_SKTS_14 14 291 { 292 X86_SOCKET_FP5, /* 0b000 */ 293 X86_SOCKET_UNKNOWN, /* 0b001 */ 294 X86_SOCKET_AM4, /* 0b010 */ 295 X86_SOCKET_UNKNOWN, /* 0b011 */ 296 X86_SOCKET_UNKNOWN, /* 0b100 */ 297 X86_SOCKET_UNKNOWN, /* 0b101 */ 298 X86_SOCKET_UNKNOWN, /* 0b110 */ 299 X86_SOCKET_UNKNOWN /* 0b111 */ 300 }, 301 302 /* 303 * Family 0x17 models 30-3f (Zen 2 - Rome) 304 */ 305 #define A_SKTS_15 15 306 { 307 X86_SOCKET_UNKNOWN, /* 0b000 */ 308 X86_SOCKET_UNKNOWN, /* 0b001 */ 309 X86_SOCKET_UNKNOWN, /* 0b010 */ 310 X86_SOCKET_UNKNOWN, /* 0b011 */ 311 X86_SOCKET_SP3, /* 0b100 */ 312 X86_SOCKET_UNKNOWN, /* 0b101 */ 313 X86_SOCKET_UNKNOWN, /* 0b110 */ 314 X86_SOCKET_SP3R2 /* 0b111 */ 315 }, 316 317 /* 318 * Family 0x17 models 60-6f (Zen 2 - Renoir) 319 */ 320 #define A_SKTS_16 16 321 { 322 X86_SOCKET_FP6, /* 0b000 */ 323 X86_SOCKET_UNKNOWN, /* 0b001 */ 324 X86_SOCKET_AM4, /* 0b010 */ 325 X86_SOCKET_UNKNOWN, /* 0b011 */ 326 X86_SOCKET_UNKNOWN, /* 0b100 */ 327 X86_SOCKET_UNKNOWN, /* 0b101 */ 328 X86_SOCKET_UNKNOWN, /* 0b110 */ 329 X86_SOCKET_UNKNOWN /* 0b111 */ 330 }, 331 332 /* 333 * Family 0x17 models 70-7f (Zen 2 - Matisse) 334 */ 335 #define A_SKTS_17 17 336 { 337 X86_SOCKET_UNKNOWN, /* 0b000 */ 338 X86_SOCKET_UNKNOWN, /* 0b001 */ 339 X86_SOCKET_AM4, /* 0b010 */ 340 X86_SOCKET_UNKNOWN, /* 0b011 */ 341 X86_SOCKET_UNKNOWN, /* 0b100 */ 342 X86_SOCKET_UNKNOWN, /* 0b101 */ 343 X86_SOCKET_UNKNOWN, /* 0b110 */ 344 X86_SOCKET_UNKNOWN /* 0b111 */ 345 }, 346 347 /* 348 * Family 0x18 models 00-0f (Dhyana) 349 */ 350 #define A_SKTS_18 18 351 { 352 X86_SOCKET_UNKNOWN, /* 0b000 */ 353 X86_SOCKET_UNKNOWN, /* 0b001 */ 354 X86_SOCKET_UNKNOWN, /* 0b010 */ 355 X86_SOCKET_UNKNOWN, /* 0b011 */ 356 X86_SOCKET_SL1, /* 0b100 */ 357 X86_SOCKET_UNKNOWN, /* 0b101 */ 358 X86_SOCKET_DM1, /* 0b110 */ 359 X86_SOCKET_SL1R2 /* 0b111 */ 360 }, 361 362 /* 363 * Family 0x19 models 00-0f (Zen 3 - Milan) 364 */ 365 #define A_SKTS_19 19 366 { 367 X86_SOCKET_UNKNOWN, /* 0b000 */ 368 X86_SOCKET_UNKNOWN, /* 0b001 */ 369 X86_SOCKET_UNKNOWN, /* 0b010 */ 370 X86_SOCKET_UNKNOWN, /* 0b011 */ 371 X86_SOCKET_SP3, /* 0b100 */ 372 X86_SOCKET_UNKNOWN, /* 0b101 */ 373 X86_SOCKET_UNKNOWN, /* 0b110 */ 374 X86_SOCKET_STRX4 /* 0b111 */ 375 }, 376 377 /* 378 * Family 0x19 models 20-2f (Zen 3 - Vermeer) 379 */ 380 #define A_SKTS_20 20 381 { 382 X86_SOCKET_UNKNOWN, /* 0b000 */ 383 X86_SOCKET_UNKNOWN, /* 0b001 */ 384 X86_SOCKET_AM4, /* 0b010 */ 385 X86_SOCKET_UNKNOWN, /* 0b011 */ 386 X86_SOCKET_UNKNOWN, /* 0b100 */ 387 X86_SOCKET_UNKNOWN, /* 0b101 */ 388 X86_SOCKET_UNKNOWN, /* 0b110 */ 389 X86_SOCKET_UNKNOWN /* 0b111 */ 390 }, 391 392 /* 393 * Family 0x19 models 50-5f (Zen 3 - Cezanne) 394 */ 395 #define A_SKTS_21 21 396 { 397 X86_SOCKET_FP6, /* 0b000 */ 398 X86_SOCKET_UNKNOWN, /* 0b001 */ 399 X86_SOCKET_AM4, /* 0b010 */ 400 X86_SOCKET_UNKNOWN, /* 0b011 */ 401 X86_SOCKET_UNKNOWN, /* 0b100 */ 402 X86_SOCKET_UNKNOWN, /* 0b101 */ 403 X86_SOCKET_UNKNOWN, /* 0b110 */ 404 X86_SOCKET_UNKNOWN /* 0b111 */ 405 }, 406 407 /* 408 * Family 0x19 models 10-1f (Zen 4 - Genoa) 409 */ 410 #define A_SKTS_22 22 411 { 412 X86_SOCKET_UNKNOWN, /* 0b000 */ 413 X86_SOCKET_UNKNOWN, /* 0b001 */ 414 X86_SOCKET_UNKNOWN, /* 0b010 */ 415 X86_SOCKET_UNKNOWN, /* 0b011 */ 416 X86_SOCKET_SP5, /* 0b100 */ 417 X86_SOCKET_UNKNOWN, /* 0b101 */ 418 X86_SOCKET_UNKNOWN, /* 0b110 */ 419 X86_SOCKET_UNKNOWN /* 0b111 */ 420 }, 421 422 /* 423 * Family 0x19 models 40-4f (Zen 3 - Rembrandt) 424 */ 425 #define A_SKTS_23 23 426 { 427 X86_SOCKET_AM5, /* 0b000 */ 428 X86_SOCKET_FP7, /* 0b001 */ 429 X86_SOCKET_FP7R2, /* 0b010 */ 430 X86_SOCKET_UNKNOWN, /* 0b011 */ 431 X86_SOCKET_UNKNOWN, /* 0b100 */ 432 X86_SOCKET_UNKNOWN, /* 0b101 */ 433 X86_SOCKET_UNKNOWN, /* 0b110 */ 434 X86_SOCKET_UNKNOWN /* 0b111 */ 435 }, 436 437 /* 438 * Family 0x19 models 60-6f (Zen 4 - Raphael) 439 * Family 0x17 models a0-af (Zen 2 - Mendocino) 440 */ 441 #define A_SKTS_24 24 442 { 443 X86_SOCKET_AM5, /* 0b000 */ 444 X86_SOCKET_UNKNOWN, /* 0b001 */ 445 X86_SOCKET_UNKNOWN, /* 0b010 */ 446 X86_SOCKET_UNKNOWN, /* 0b011 */ 447 X86_SOCKET_UNKNOWN, /* 0b100 */ 448 X86_SOCKET_UNKNOWN, /* 0b101 */ 449 X86_SOCKET_UNKNOWN, /* 0b110 */ 450 X86_SOCKET_UNKNOWN /* 0b111 */ 451 }, 452 453 /* 454 * The always-unknown socket group, used for undocumented parts. It 455 * need not be last; the position is arbitrary. 456 */ 457 #define A_SKTS_UNKNOWN 25 458 { 459 X86_SOCKET_UNKNOWN, /* 0b000 */ 460 X86_SOCKET_UNKNOWN, /* 0b001 */ 461 X86_SOCKET_UNKNOWN, /* 0b010 */ 462 X86_SOCKET_UNKNOWN, /* 0b011 */ 463 X86_SOCKET_UNKNOWN, /* 0b100 */ 464 X86_SOCKET_UNKNOWN, /* 0b101 */ 465 X86_SOCKET_UNKNOWN, /* 0b110 */ 466 X86_SOCKET_UNKNOWN /* 0b111 */ 467 }, 468 /* 469 * Family 0x17 models 90-97 (Zen 2 - Van Gogh) 470 */ 471 #define A_SKTS_26 26 472 { 473 X86_SOCKET_UNKNOWN, /* 0b000 */ 474 X86_SOCKET_UNKNOWN, /* 0b001 */ 475 X86_SOCKET_UNKNOWN, /* 0b010 */ 476 X86_SOCKET_FF3, /* 0b011 */ 477 X86_SOCKET_UNKNOWN, /* 0b100 */ 478 X86_SOCKET_UNKNOWN, /* 0b101 */ 479 X86_SOCKET_UNKNOWN, /* 0b110 */ 480 X86_SOCKET_UNKNOWN /* 0b111 */ 481 } 482 }; 483 484 struct amd_sktmap_s { 485 uint32_t skt_code; 486 char sktstr[16]; 487 }; 488 static struct amd_sktmap_s amd_sktmap_strs[] = { 489 { X86_SOCKET_754, "754" }, 490 { X86_SOCKET_939, "939" }, 491 { X86_SOCKET_940, "940" }, 492 { X86_SOCKET_S1g1, "S1g1" }, 493 { X86_SOCKET_AM2, "AM2" }, 494 { X86_SOCKET_F1207, "F(1207)" }, 495 { X86_SOCKET_S1g2, "S1g2" }, 496 { X86_SOCKET_S1g3, "S1g3" }, 497 { X86_SOCKET_AM, "AM" }, 498 { X86_SOCKET_AM2R2, "AM2r2" }, 499 { X86_SOCKET_AM3, "AM3" }, 500 { X86_SOCKET_G34, "G34" }, 501 { X86_SOCKET_ASB2, "ASB2" }, 502 { X86_SOCKET_C32, "C32" }, 503 { X86_SOCKET_S1g4, "S1g4" }, 504 { X86_SOCKET_FT1, "FT1" }, 505 { X86_SOCKET_FM1, "FM1" }, 506 { X86_SOCKET_FS1, "FS1" }, 507 { X86_SOCKET_AM3R2, "AM3r2" }, 508 { X86_SOCKET_FP2, "FP2" }, 509 { X86_SOCKET_FS1R2, "FS1r2" }, 510 { X86_SOCKET_FM2, "FM2" }, 511 { X86_SOCKET_FP3, "FP3" }, 512 { X86_SOCKET_FM2R2, "FM2r2" }, 513 { X86_SOCKET_FP4, "FP4" }, 514 { X86_SOCKET_AM4, "AM4" }, 515 { X86_SOCKET_FT3, "FT3" }, 516 { X86_SOCKET_FT4, "FT4" }, 517 { X86_SOCKET_FS1B, "FS1b" }, 518 { X86_SOCKET_FT3B, "FT3b" }, 519 { X86_SOCKET_SP3, "SP3" }, 520 { X86_SOCKET_SP3R2, "SP3r2" }, 521 { X86_SOCKET_FP5, "FP5" }, 522 { X86_SOCKET_FP6, "FP6" }, 523 { X86_SOCKET_STRX4, "sTRX4" }, 524 { X86_SOCKET_SL1, "SL1" }, 525 { X86_SOCKET_SL1R2, "SL1R2" }, 526 { X86_SOCKET_DM1, "DM1" }, 527 { X86_SOCKET_SP5, "SP5" }, 528 { X86_SOCKET_AM5, "AM5" }, 529 { X86_SOCKET_FP7, "FP7" }, 530 { X86_SOCKET_FP7R2, "FP7r2" }, 531 { X86_SOCKET_FF3, "FF3" }, 532 { X86_SOCKET_UNKNOWN, "Unknown" } /* Must be last! */ 533 }; 534 535 /* Keep the array above in sync with the definitions in x86_archext.h. */ 536 CTASSERT(ARRAY_SIZE(amd_sktmap_strs) == X86_NUM_SOCKETS + 1); 537 538 /* 539 * Table for mapping AMD family/model/stepping ranges onto three derived items: 540 * 541 * * The "chiprev" and associated string, which is generally the AMD silicon 542 * revision along with a symbolic representation of the marketing (not cpuid) 543 * family. In line with the overall cpuid usage, we refer to this as a 544 * processor family. 545 * * The uarch, which is analogous to the chiprev and provides the 546 * microarchitecture/core generation and silicon revision. Note that this is 547 * distinct from the package-level silicon/product revision and is often common 548 * to multiple product lines offered at a given time. 549 * * The socket map selector, used to translate this collection of products' 550 * last 4 model bits (for family 0xf only) or Fn8000_0001_EBX[30:28] into a 551 * socket ID. 552 * 553 * The first member of this array that matches a given family, extended model 554 * plus model range, and stepping range will be considered a match. This allows 555 * us to end each cpuid family and/or processor family with a catchall that 556 * while less specific than we might like still allows us to provide a fair 557 * amount of detail to both other kernel consumers and userland. 558 */ 559 static const struct amd_rev_mapent { 560 uint_t rm_family; 561 uint_t rm_modello; 562 uint_t rm_modelhi; 563 uint_t rm_steplo; 564 uint_t rm_stephi; 565 x86_chiprev_t rm_chiprev; 566 const char *rm_chiprevstr; 567 x86_uarchrev_t rm_uarchrev; 568 uint_t rm_sktidx; 569 } amd_revmap[] = { 570 /* 571 * =============== AuthenticAMD Family 0xf =============== 572 */ 573 574 /* 575 * Rev B includes model 0x4 stepping 0 and model 0x5 stepping 0 and 1. 576 */ 577 { 0xf, 0x04, 0x04, 0x0, 0x0, X86_CHIPREV_AMD_LEGACY_F_REV_B, "B", 578 X86_UARCHREV_AMD_LEGACY, A_SKTS_0 }, 579 { 0xf, 0x05, 0x05, 0x0, 0x1, X86_CHIPREV_AMD_LEGACY_F_REV_B, "B", 580 X86_UARCHREV_AMD_LEGACY, A_SKTS_0 }, 581 /* 582 * Rev C0 includes model 0x4 stepping 8 and model 0x5 stepping 8 583 */ 584 { 0xf, 0x04, 0x05, 0x8, 0x8, X86_CHIPREV_AMD_LEGACY_F_REV_C0, "C0", 585 X86_UARCHREV_AMD_LEGACY, A_SKTS_0 }, 586 /* 587 * Rev CG is the rest of extended model 0x0 - i.e., everything 588 * but the rev B and C0 combinations covered above. 589 */ 590 { 0xf, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_F_REV_CG, "CG", 591 X86_UARCHREV_AMD_LEGACY, A_SKTS_0 }, 592 /* 593 * Rev D has extended model 0x1. 594 */ 595 { 0xf, 0x10, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_F_REV_D, "D", 596 X86_UARCHREV_AMD_LEGACY, A_SKTS_0 }, 597 /* 598 * Rev E has extended model 0x2. 599 * Extended model 0x3 is unused but available to grow into. 600 */ 601 { 0xf, 0x20, 0x3f, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_F_REV_E, "E", 602 X86_UARCHREV_AMD_LEGACY, A_SKTS_0 }, 603 /* 604 * Rev F has extended models 0x4 and 0x5. 605 */ 606 { 0xf, 0x40, 0x5f, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_F_REV_F, "F", 607 X86_UARCHREV_AMD_LEGACY, A_SKTS_1 }, 608 /* 609 * Rev G has extended model 0x6. 610 */ 611 { 0xf, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_F_REV_G, "G", 612 X86_UARCHREV_AMD_LEGACY, A_SKTS_1 }, 613 614 /* 615 * =============== AuthenticAMD Family 0x10 =============== 616 */ 617 618 /* 619 * Rev A has model 0 and stepping 0/1/2 for DR-{A0,A1,A2}. 620 * Give all of model 0 stepping range to rev A. 621 */ 622 { 0x10, 0x00, 0x00, 0x0, 0x2, X86_CHIPREV_AMD_LEGACY_10_REV_A, "A", 623 X86_UARCHREV_AMD_LEGACY, A_SKTS_2 }, 624 625 /* 626 * Rev B has model 2 and steppings 0/1/0xa/2 for DR-{B0,B1,BA,B2}. 627 * Give all of model 2 stepping range to rev B. 628 */ 629 { 0x10, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_10_REV_B, "B", 630 X86_UARCHREV_AMD_LEGACY, A_SKTS_2 }, 631 632 /* 633 * Rev C has models 4-6 (depending on L3 cache configuration) 634 * Give all of models 4-6 stepping range 0-2 to rev C2. 635 */ 636 { 0x10, 0x4, 0x6, 0x0, 0x2, X86_CHIPREV_AMD_LEGACY_10_REV_C2, "C2", 637 X86_UARCHREV_AMD_LEGACY, A_SKTS_2 }, 638 639 /* 640 * Rev C has models 4-6 (depending on L3 cache configuration) 641 * Give all of models 4-6 stepping range >= 3 to rev C3. 642 */ 643 { 0x10, 0x4, 0x6, 0x3, 0xf, X86_CHIPREV_AMD_LEGACY_10_REV_C3, "C3", 644 X86_UARCHREV_AMD_LEGACY, A_SKTS_2 }, 645 646 /* 647 * Rev D has models 8 and 9 648 * Give all of model 8 and 9 stepping 0 to rev D0. 649 */ 650 { 0x10, 0x8, 0x9, 0x0, 0x0, X86_CHIPREV_AMD_LEGACY_10_REV_D0, "D0", 651 X86_UARCHREV_AMD_LEGACY, A_SKTS_2 }, 652 653 /* 654 * Rev D has models 8 and 9 655 * Give all of model 8 and 9 stepping range >= 1 to rev D1. 656 */ 657 { 0x10, 0x8, 0x9, 0x1, 0xf, X86_CHIPREV_AMD_LEGACY_10_REV_D1, "D1", 658 X86_UARCHREV_AMD_LEGACY, A_SKTS_2 }, 659 660 /* 661 * Rev E has models A and stepping 0 662 * Give all of model A stepping range to rev E. 663 */ 664 { 0x10, 0xA, 0xA, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_10_REV_E, "E", 665 X86_UARCHREV_AMD_LEGACY, A_SKTS_2 }, 666 667 { 0x10, 0x0, 0xff, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_10_UNKNOWN, "??", 668 X86_UARCHREV_AMD_LEGACY, A_SKTS_2 }, 669 670 /* 671 * =============== AuthenticAMD Family 0x11 =============== 672 */ 673 { 0x11, 0x03, 0x03, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_11_REV_B, "B", 674 X86_UARCHREV_AMD_LEGACY, A_SKTS_3 }, 675 { 0x11, 0x00, 0xff, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_11_UNKNOWN, "??", 676 X86_UARCHREV_AMD_LEGACY, A_SKTS_3 }, 677 678 /* 679 * =============== AuthenticAMD Family 0x12 =============== 680 */ 681 { 0x12, 0x01, 0x01, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_12_REV_B, "B", 682 X86_UARCHREV_AMD_LEGACY, A_SKTS_4 }, 683 { 0x12, 0x00, 0x00, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_12_UNKNOWN, "??", 684 X86_UARCHREV_AMD_LEGACY, A_SKTS_4 }, 685 686 /* 687 * =============== AuthenticAMD Family 0x14 =============== 688 */ 689 { 0x14, 0x01, 0x01, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_14_REV_B, "B", 690 X86_UARCHREV_AMD_LEGACY, A_SKTS_5 }, 691 { 0x14, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_14_REV_C, "C", 692 X86_UARCHREV_AMD_LEGACY, A_SKTS_5 }, 693 { 0x14, 0x00, 0xff, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_14_UNKNOWN, "??", 694 X86_UARCHREV_AMD_LEGACY, A_SKTS_5 }, 695 696 /* 697 * =============== AuthenticAMD Family 0x15 =============== 698 */ 699 { 0x15, 0x01, 0x01, 0x2, 0x2, X86_CHIPREV_AMD_OROCHI_REV_B2, "OR-B2", 700 X86_UARCHREV_AMD_LEGACY, A_SKTS_6 }, 701 { 0x15, 0x02, 0x02, 0x0, 0x0, X86_CHIPREV_AMD_OROCHI_REV_C0, "OR-C0", 702 X86_UARCHREV_AMD_LEGACY, A_SKTS_6 }, 703 { 0x15, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_OROCHI_UNKNOWN, "OR-??", 704 X86_UARCHREV_AMD_LEGACY, A_SKTS_6 }, 705 706 { 0x15, 0x10, 0x10, 0x1, 0x1, X86_CHIPREV_AMD_TRINITY_REV_A1, "TN-A1", 707 X86_UARCHREV_AMD_LEGACY, A_SKTS_7 }, 708 { 0x15, 0x10, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_TRINITY_UNKNOWN, "TN-??", 709 X86_UARCHREV_AMD_LEGACY, A_SKTS_7 }, 710 711 { 0x15, 0x30, 0x30, 0x1, 0x1, X86_CHIPREV_AMD_KAVERI_REV_A1, "KV-A1", 712 X86_UARCHREV_AMD_LEGACY, A_SKTS_8 }, 713 { 0x15, 0x30, 0x3f, 0x0, 0xf, X86_CHIPREV_AMD_KAVERI_UNKNOWN, "KV-??", 714 X86_UARCHREV_AMD_LEGACY, A_SKTS_8 }, 715 716 /* 717 * The Carrizo rev guide mentions A0 as having an ID of "00600F00h" but 718 * this appears to be a typo as elsewhere it's given as "00660F00h". We 719 * assume the latter is correct. 720 */ 721 { 0x15, 0x60, 0x60, 0x0, 0x0, X86_CHIPREV_AMD_CARRIZO_REV_A0, "CZ-A0", 722 X86_UARCHREV_AMD_LEGACY, A_SKTS_9 }, 723 { 0x15, 0x60, 0x60, 0x1, 0x1, X86_CHIPREV_AMD_CARRIZO_REV_A1, "CZ-A1", 724 X86_UARCHREV_AMD_LEGACY, A_SKTS_9 }, 725 /* 726 * CZ-DDR4 and BR-A1 are indistinguishable via cpuid; the rev guide 727 * indicates that they should be distinguished by the contents of the 728 * OSVW MSR, but this register is just a software scratch space which 729 * means the actual method of distinguishing the two is not documented 730 * and on PCs will be done by a BIOS. In the extremely unlikely event 731 * it becomes necessary to distinguish these, an OSVW-driven fixup can 732 * be added. 733 */ 734 { 0x15, 0x65, 0x65, 0x1, 0x1, X86_CHIPREV_AMD_CARRIZO_REV_DDR4, 735 "CZ-DDR4", X86_UARCHREV_AMD_LEGACY, A_SKTS_9 }, 736 { 0x15, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_CARRIZO_UNKNOWN, "CZ-??", 737 X86_UARCHREV_AMD_LEGACY, A_SKTS_9 }, 738 739 { 0x15, 0x70, 0x70, 0x0, 0x0, X86_CHIPREV_AMD_STONEY_RIDGE_REV_A0, 740 "ST-A0", X86_UARCHREV_AMD_LEGACY, A_SKTS_10 }, 741 { 0x15, 0x70, 0x7f, 0x0, 0xf, X86_CHIPREV_AMD_STONEY_RIDGE_UNKNOWN, 742 "ST-??", X86_UARCHREV_AMD_LEGACY, A_SKTS_10 }, 743 744 /* 745 * =============== AuthenticAMD Family 0x16 =============== 746 */ 747 { 0x16, 0x00, 0x00, 0x1, 0x1, X86_CHIPREV_AMD_KABINI_A1, "KB-A1", 748 X86_UARCHREV_AMD_LEGACY, A_SKTS_11 }, 749 { 0x16, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_KABINI_UNKNOWN, "KB-??", 750 X86_UARCHREV_AMD_LEGACY, A_SKTS_11 }, 751 752 { 0x16, 0x30, 0x30, 0x1, 0x1, X86_CHIPREV_AMD_MULLINS_A1, "ML-A1", 753 X86_UARCHREV_AMD_LEGACY, A_SKTS_12 }, 754 { 0x16, 0x30, 0x3f, 0x0, 0xf, X86_CHIPREV_AMD_MULLINS_UNKNOWN, "ML-??", 755 X86_UARCHREV_AMD_LEGACY, A_SKTS_12 }, 756 757 /* 758 * =============== AuthenticAMD Family 0x17 =============== 759 */ 760 /* Naples == Zeppelin == ZP */ 761 { 0x17, 0x00, 0x00, 0x0, 0x0, X86_CHIPREV_AMD_NAPLES_A0, "ZP-A0", 762 X86_UARCHREV_AMD_ZEN1, A_SKTS_13 }, 763 { 0x17, 0x01, 0x01, 0x1, 0x1, X86_CHIPREV_AMD_NAPLES_B1, "ZP-B1", 764 X86_UARCHREV_AMD_ZEN1, A_SKTS_13 }, 765 { 0x17, 0x01, 0x01, 0x2, 0x2, X86_CHIPREV_AMD_NAPLES_B2, "ZP-B2", 766 X86_UARCHREV_AMD_ZEN1, A_SKTS_13 }, 767 { 0x17, 0x00, 0x07, 0x0, 0xf, X86_CHIPREV_AMD_NAPLES_UNKNOWN, "ZP-??", 768 X86_UARCHREV_AMD_ZEN1, A_SKTS_13 }, 769 { 0x17, 0x08, 0x08, 0x2, 0x2, X86_CHIPREV_AMD_PINNACLE_RIDGE_B2, 770 "PiR-B2", X86_UARCHREV_AMD_ZENPLUS, A_SKTS_13 }, 771 { 0x17, 0x08, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_PINNACLE_RIDGE_UNKNOWN, 772 "PiR-??", X86_UARCHREV_AMD_ZENPLUS, A_SKTS_13 }, 773 774 { 0x17, 0x11, 0x11, 0x0, 0x0, X86_CHIPREV_AMD_RAVEN_RIDGE_B0, 775 "RV-B0", X86_UARCHREV_AMD_ZEN1, A_SKTS_14 }, 776 { 0x17, 0x11, 0x11, 0x1, 0x1, X86_CHIPREV_AMD_RAVEN_RIDGE_B1, 777 "RV-B1", X86_UARCHREV_AMD_ZEN1, A_SKTS_14 }, 778 { 0x17, 0x10, 0x17, 0x0, 0xf, X86_CHIPREV_AMD_RAVEN_RIDGE_UNKNOWN, 779 "RV-??", X86_UARCHREV_AMD_ZEN1, A_SKTS_14 }, 780 { 0x17, 0x18, 0x18, 0x1, 0x1, X86_CHIPREV_AMD_PICASSO_B1, "PCO-B1", 781 X86_UARCHREV_AMD_ZENPLUS, A_SKTS_14 }, 782 { 0x17, 0x18, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_PICASSO_UNKNOWN, "PCO-??", 783 X86_UARCHREV_AMD_ZENPLUS, A_SKTS_14 }, 784 785 { 0x17, 0x20, 0x20, 0x1, 0x1, X86_CHIPREV_AMD_DALI_A1, "RV2X-A1", 786 X86_UARCHREV_AMD_ZEN1, A_SKTS_14 }, 787 { 0x17, 0x20, 0x2f, 0x0, 0xf, X86_CHIPREV_AMD_DALI_UNKNOWN, "RV2X-??", 788 X86_UARCHREV_AMD_ZEN1, A_SKTS_14 }, 789 790 /* Rome == Starship == SSP */ 791 { 0x17, 0x30, 0x30, 0x0, 0x0, X86_CHIPREV_AMD_ROME_A0, "SSP-A0", 792 X86_UARCHREV_AMD_ZEN2_A0, A_SKTS_15 }, 793 { 0x17, 0x31, 0x31, 0x0, 0x0, X86_CHIPREV_AMD_ROME_B0, "SSP-B0", 794 X86_UARCHREV_AMD_ZEN2_B0, A_SKTS_15 }, 795 { 0x17, 0x30, 0x3f, 0x0, 0xf, X86_CHIPREV_AMD_ROME_UNKNOWN, "SSP-??", 796 X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_15 }, 797 798 { 0x17, 0x60, 0x60, 0x1, 0x1, X86_CHIPREV_AMD_RENOIR_A1, "RN-A1", 799 X86_UARCHREV_AMD_ZEN2_B0, A_SKTS_16 }, 800 { 0x17, 0x60, 0x67, 0x0, 0xf, X86_CHIPREV_AMD_RENOIR_UNKNOWN, "RN-??", 801 X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_16 }, 802 { 0x17, 0x68, 0x68, 0x1, 0x1, X86_CHIPREV_AMD_RENOIR_LCN_A1, "LCN-A1", 803 X86_UARCHREV_AMD_ZEN2_B0, A_SKTS_16 }, 804 { 0x17, 0x68, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_RENOIR_UNKNOWN, "LCN-??", 805 X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_16 }, 806 807 { 0x17, 0x71, 0x71, 0x0, 0x0, X86_CHIPREV_AMD_MATISSE_B0, "MTS-B0", 808 X86_UARCHREV_AMD_ZEN2_B0, A_SKTS_17 }, 809 { 0x17, 0x70, 0x7f, 0x0, 0xf, X86_CHIPREV_AMD_MATISSE_UNKNOWN, "MTS-??", 810 X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_17 }, 811 812 { 0x17, 0x90, 0x97, 0x0, 0xf, X86_CHIPREV_AMD_VAN_GOGH_UNKNOWN, "??", 813 X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_26 }, 814 { 0x17, 0x98, 0x9f, 0x0, 0xf, X86_CHIPREV_AMD_VAN_GOGH_UNKNOWN, "??", 815 X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_UNKNOWN }, 816 817 { 0x17, 0xa0, 0xaf, 0x0, 0xf, X86_CHIPREV_AMD_MENDOCINO_UNKNOWN, "??", 818 X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_24 }, 819 820 /* 821 * =============== HygonGenuine Family 0x18 =============== 822 */ 823 { 0x18, 0x00, 0x00, 0x1, 0x1, X86_CHIPREV_HYGON_DHYANA_A1, "DN_A1", 824 X86_UARCHREV_AMD_ZEN1, A_SKTS_18 }, 825 { 0x18, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_HYGON_DHYANA_UNKNOWN, "DN_??", 826 X86_UARCHREV_AMD_ZEN1, A_SKTS_18 }, 827 828 /* 829 * =============== AuthenticAMD Family 0x19 =============== 830 */ 831 /* Milan == Genesis == GN */ 832 { 0x19, 0x00, 0x00, 0x0, 0x0, X86_CHIPREV_AMD_MILAN_A0, "GN-A0", 833 X86_UARCHREV_AMD_ZEN3_A0, A_SKTS_19 }, 834 { 0x19, 0x01, 0x01, 0x0, 0x0, X86_CHIPREV_AMD_MILAN_B0, "GN-B0", 835 X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_19 }, 836 { 0x19, 0x01, 0x01, 0x1, 0x1, X86_CHIPREV_AMD_MILAN_B1, "GN-B1", 837 X86_UARCHREV_AMD_ZEN3_B1, A_SKTS_19 }, 838 /* Marketed as Milan-X but still GN */ 839 { 0x19, 0x01, 0x01, 0x2, 0x2, X86_CHIPREV_AMD_MILAN_B2, "GN-B2", 840 X86_UARCHREV_AMD_ZEN3_B2, A_SKTS_19 }, 841 { 0x19, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_MILAN_UNKNOWN, "GN-??", 842 X86_UARCHREV_AMD_ZEN3_UNKNOWN, A_SKTS_19 }, 843 844 /* Genoa == Stones == RS */ 845 { 0x19, 0x10, 0x10, 0x0, 0x0, X86_CHIPREV_AMD_GENOA_A0, "RS-A0", 846 X86_UARCHREV_AMD_ZEN4, A_SKTS_22 }, 847 { 0x19, 0x10, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_GENOA_UNKNOWN, "RS-??", 848 X86_UARCHREV_AMD_ZEN4, A_SKTS_22 }, 849 850 { 0x19, 0x20, 0x20, 0x0, 0x0, X86_CHIPREV_AMD_VERMEER_A0, "VMR-A0", 851 X86_UARCHREV_AMD_ZEN3_A0, A_SKTS_20 }, 852 { 0x19, 0x21, 0x21, 0x0, 0x0, X86_CHIPREV_AMD_VERMEER_B0, "VMR-B0", 853 X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_20 }, 854 { 0x19, 0x21, 0x21, 0x2, 0x2, X86_CHIPREV_AMD_VERMEER_B2, "VMR-B2", 855 X86_UARCHREV_AMD_ZEN3_B2, A_SKTS_20 }, 856 { 0x19, 0x20, 0x2f, 0x0, 0xf, X86_CHIPREV_AMD_VERMEER_UNKNOWN, "VMR-??", 857 X86_UARCHREV_AMD_ZEN3_UNKNOWN, A_SKTS_20 }, 858 859 /* Rev guide is missing AM5 information, including A0 and B0 */ 860 { 0x19, 0x40, 0x40, 0x0, 0x0, X86_CHIPREV_AMD_REMBRANDT_A0, "RMB-A0", 861 X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_23 }, 862 { 0x19, 0x44, 0x44, 0x0, 0x0, X86_CHIPREV_AMD_REMBRANDT_B0, "RMB-B0", 863 X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_23 }, 864 { 0x19, 0x44, 0x44, 0x1, 0x1, X86_CHIPREV_AMD_REMBRANDT_B1, "RMB-B1", 865 X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_23 }, 866 { 0x19, 0x40, 0x4f, 0x0, 0xf, X86_CHIPREV_AMD_REMBRANDT_UNKNOWN, 867 "RMB-??", X86_UARCHREV_AMD_ZEN3_UNKNOWN, A_SKTS_23 }, 868 869 { 0x19, 0x50, 0x50, 0x0, 0x0, X86_CHIPREV_AMD_CEZANNE_A0, "CZN-A0", 870 X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_21 }, 871 { 0x19, 0x50, 0x5f, 0x0, 0xf, X86_CHIPREV_AMD_CEZANNE_UNKNOWN, "CZN-??", 872 X86_UARCHREV_AMD_ZEN3_UNKNOWN, A_SKTS_21 }, 873 874 { 0x19, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_RAPHAEL_UNKNOWN, "??", 875 X86_UARCHREV_AMD_ZEN4, A_SKTS_24 } 876 }; 877 878 /* 879 * AMD keeps the socket type in CPUID Fn8000_0001_EBX, bits 31:28. 880 */ 881 static uint32_t 882 synth_amd_skt_cpuid(uint_t family, uint_t sktid) 883 { 884 struct cpuid_regs cp; 885 uint_t idx; 886 887 cp.cp_eax = 0x80000001; 888 (void) __cpuid_insn(&cp); 889 890 /* PkgType bits */ 891 idx = BITX(cp.cp_ebx, 31, 28); 892 893 if (idx > 7) { 894 return (X86_SOCKET_UNKNOWN); 895 } 896 897 if (family == 0x10) { 898 uint32_t val; 899 900 val = pci_getl_func(0, 24, 2, 0x94); 901 if (BITX(val, 8, 8)) { 902 if (amd_skts[sktid][idx] == X86_SOCKET_AM2R2) { 903 return (X86_SOCKET_AM3); 904 } else if (amd_skts[sktid][idx] == X86_SOCKET_S1g3) { 905 return (X86_SOCKET_S1g4); 906 } 907 } 908 } 909 910 return (amd_skts[sktid][idx]); 911 } 912 913 static void 914 synth_amd_info(uint_t family, uint_t model, uint_t step, 915 uint32_t *skt_p, x86_chiprev_t *chiprev_p, const char **chiprevstr_p, 916 x86_uarchrev_t *uarchrev_p) 917 { 918 const struct amd_rev_mapent *rmp; 919 int found = 0; 920 int i; 921 922 if (family < 0xf) 923 return; 924 925 for (i = 0, rmp = amd_revmap; i < ARRAY_SIZE(amd_revmap); i++, rmp++) { 926 if (family == rmp->rm_family && 927 model >= rmp->rm_modello && model <= rmp->rm_modelhi && 928 step >= rmp->rm_steplo && step <= rmp->rm_stephi) { 929 found = 1; 930 break; 931 } 932 } 933 934 if (found) { 935 if (chiprev_p != NULL) 936 *chiprev_p = rmp->rm_chiprev; 937 if (chiprevstr_p != NULL) 938 *chiprevstr_p = rmp->rm_chiprevstr; 939 if (uarchrev_p != NULL) 940 *uarchrev_p = rmp->rm_uarchrev; 941 } 942 943 if (skt_p != NULL) { 944 int platform; 945 946 #ifdef __xpv 947 /* PV guest */ 948 if (!is_controldom()) { 949 *skt_p = X86_SOCKET_UNKNOWN; 950 return; 951 } 952 #endif 953 platform = get_hwenv(); 954 955 if ((platform & HW_VIRTUAL) != 0) { 956 *skt_p = X86_SOCKET_UNKNOWN; 957 return; 958 } 959 960 if (!found) 961 return; 962 963 if (family == 0xf) { 964 *skt_p = amd_skts[rmp->rm_sktidx][model & 0x3]; 965 } else { 966 *skt_p = synth_amd_skt_cpuid(family, rmp->rm_sktidx); 967 } 968 } 969 } 970 971 uint32_t 972 _cpuid_skt(uint_t vendor, uint_t family, uint_t model, uint_t step) 973 { 974 uint32_t skt = X86_SOCKET_UNKNOWN; 975 976 switch (vendor) { 977 case X86_VENDOR_AMD: 978 case X86_VENDOR_HYGON: 979 synth_amd_info(family, model, step, &skt, NULL, NULL, NULL); 980 break; 981 982 default: 983 break; 984 985 } 986 987 return (skt); 988 } 989 990 const char * 991 _cpuid_sktstr(uint_t vendor, uint_t family, uint_t model, uint_t step) 992 { 993 const char *sktstr = "Unknown"; 994 struct amd_sktmap_s *sktmapp; 995 uint32_t skt = X86_SOCKET_UNKNOWN; 996 997 switch (vendor) { 998 case X86_VENDOR_AMD: 999 case X86_VENDOR_HYGON: 1000 synth_amd_info(family, model, step, &skt, NULL, NULL, NULL); 1001 1002 sktmapp = amd_sktmap_strs; 1003 while (sktmapp->skt_code != X86_SOCKET_UNKNOWN) { 1004 if (sktmapp->skt_code == skt) 1005 break; 1006 sktmapp++; 1007 } 1008 sktstr = sktmapp->sktstr; 1009 break; 1010 1011 default: 1012 break; 1013 1014 } 1015 1016 return (sktstr); 1017 } 1018 1019 x86_chiprev_t 1020 _cpuid_chiprev(uint_t vendor, uint_t family, uint_t model, uint_t step) 1021 { 1022 x86_chiprev_t chiprev = X86_CHIPREV_UNKNOWN; 1023 1024 switch (vendor) { 1025 case X86_VENDOR_AMD: 1026 case X86_VENDOR_HYGON: 1027 synth_amd_info(family, model, step, NULL, &chiprev, NULL, NULL); 1028 break; 1029 1030 default: 1031 break; 1032 1033 } 1034 1035 return (chiprev); 1036 } 1037 1038 x86_uarchrev_t 1039 _cpuid_uarchrev(uint_t vendor, uint_t family, uint_t model, uint_t step) 1040 { 1041 x86_uarchrev_t uarchrev = X86_UARCHREV_UNKNOWN; 1042 1043 switch (vendor) { 1044 case X86_VENDOR_AMD: 1045 case X86_VENDOR_HYGON: 1046 synth_amd_info(family, model, step, NULL, NULL, NULL, 1047 &uarchrev); 1048 break; 1049 1050 default: 1051 break; 1052 1053 } 1054 1055 return (uarchrev); 1056 } 1057 1058 const char * 1059 _cpuid_chiprevstr(uint_t vendor, uint_t family, uint_t model, uint_t step) 1060 { 1061 const char *revstr = "Unknown"; 1062 1063 switch (vendor) { 1064 case X86_VENDOR_AMD: 1065 case X86_VENDOR_HYGON: 1066 synth_amd_info(family, model, step, NULL, NULL, &revstr, NULL); 1067 break; 1068 1069 default: 1070 break; 1071 1072 } 1073 1074 return (revstr); 1075 1076 } 1077 1078 /* 1079 * Map the vendor string to a type code 1080 */ 1081 uint_t 1082 _cpuid_vendorstr_to_vendorcode(char *vendorstr) 1083 { 1084 if (strcmp(vendorstr, X86_VENDORSTR_Intel) == 0) 1085 return (X86_VENDOR_Intel); 1086 else if (strcmp(vendorstr, X86_VENDORSTR_AMD) == 0) 1087 return (X86_VENDOR_AMD); 1088 else if (strcmp(vendorstr, X86_VENDORSTR_HYGON) == 0) 1089 return (X86_VENDOR_HYGON); 1090 else if (strcmp(vendorstr, X86_VENDORSTR_TM) == 0) 1091 return (X86_VENDOR_TM); 1092 else if (strcmp(vendorstr, X86_VENDORSTR_CYRIX) == 0) 1093 return (X86_VENDOR_Cyrix); 1094 else if (strcmp(vendorstr, X86_VENDORSTR_UMC) == 0) 1095 return (X86_VENDOR_UMC); 1096 else if (strcmp(vendorstr, X86_VENDORSTR_NexGen) == 0) 1097 return (X86_VENDOR_NexGen); 1098 else if (strcmp(vendorstr, X86_VENDORSTR_Centaur) == 0) 1099 return (X86_VENDOR_Centaur); 1100 else if (strcmp(vendorstr, X86_VENDORSTR_Rise) == 0) 1101 return (X86_VENDOR_Rise); 1102 else if (strcmp(vendorstr, X86_VENDORSTR_SiS) == 0) 1103 return (X86_VENDOR_SiS); 1104 else if (strcmp(vendorstr, X86_VENDORSTR_NSC) == 0) 1105 return (X86_VENDOR_NSC); 1106 else 1107 return (X86_VENDOR_IntelClone); 1108 } 1109