/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Copyright 2012 Nexenta Systems, Inc. All rights reserved. */ /* * Portions Copyright 2009 Advanced Micro Devices, Inc. */ /* * Copyright 2012 Jens Elkner * Copyright 2012 Hans Rosenfeld * Copyright 2019 Joyent, Inc. * Copyright 2021 Oxide Computer Company */ /* * Support functions that interpret CPUID and similar information. * These should not be used from anywhere other than cpuid.c and * cmi_hw.c - as such we will not list them in any header file * such as x86_archext.h. * * In cpuid.c we process CPUID information for each cpu_t instance * we're presented with, and stash this raw information and material * derived from it in per-cpu_t structures. * * If we are virtualized then the CPUID information derived from CPUID * instructions executed in the guest is based on whatever the hypervisor * wanted to make things look like, and the cpu_t are not necessarily in 1:1 * or fixed correspondence with real processor execution resources. In cmi_hw.c * we are interested in the native properties of a processor - for fault * management (and potentially other, such as power management) purposes; * it will tunnel through to real hardware information, and use the * functionality provided in this file to process it. */ #include #include #include #include #include #include #ifdef __xpv #include #endif /* * AMD socket types. * First index defines a processor family; see notes inline. The second index * selects the socket type by either (model & 0x3) for family 0fh or the CPUID * pkg bits (Fn8000_0001_EBX[31:28]) for later families. */ static uint32_t amd_skts[][8] = { /* * Family 0xf revisions B through E */ #define A_SKTS_0 0 { X86_SOCKET_754, /* 0b000 */ X86_SOCKET_940, /* 0b001 */ X86_SOCKET_754, /* 0b010 */ X86_SOCKET_939, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0xf revisions F and G */ #define A_SKTS_1 1 { X86_SOCKET_S1g1, /* 0b000 */ X86_SOCKET_F1207, /* 0b001 */ X86_SOCKET_UNKNOWN, /* 0b010 */ X86_SOCKET_AM2, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x10 */ #define A_SKTS_2 2 { X86_SOCKET_F1207, /* 0b000 */ X86_SOCKET_AM2R2, /* 0b001 */ X86_SOCKET_S1g3, /* 0b010 */ X86_SOCKET_G34, /* 0b011 */ X86_SOCKET_ASB2, /* 0b100 */ X86_SOCKET_C32, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x11 */ #define A_SKTS_3 3 { X86_SOCKET_UNKNOWN, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_S1g2, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x12 */ #define A_SKTS_4 4 { X86_SOCKET_UNKNOWN, /* 0b000 */ X86_SOCKET_FS1, /* 0b001 */ X86_SOCKET_FM1, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x14 */ #define A_SKTS_5 5 { X86_SOCKET_FT1, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_UNKNOWN, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x15 models 00 - 0f */ #define A_SKTS_6 6 { X86_SOCKET_UNKNOWN, /* 0b000 */ X86_SOCKET_AM3R2, /* 0b001 */ X86_SOCKET_UNKNOWN, /* 0b010 */ X86_SOCKET_G34, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_C32, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x15 models 10 - 1f */ #define A_SKTS_7 7 { X86_SOCKET_FP2, /* 0b000 */ X86_SOCKET_FS1R2, /* 0b001 */ X86_SOCKET_FM2, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x15 models 30-3f */ #define A_SKTS_8 8 { X86_SOCKET_FP3, /* 0b000 */ X86_SOCKET_FM2R2, /* 0b001 */ X86_SOCKET_UNKNOWN, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x15 models 60-6f */ #define A_SKTS_9 9 { X86_SOCKET_FP4, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_AM4, /* 0b010 */ X86_SOCKET_FM2R2, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x15 models 70-7f */ #define A_SKTS_10 10 { X86_SOCKET_FP4, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_AM4, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_FT4, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x16 models 00-0f */ #define A_SKTS_11 11 { X86_SOCKET_FT3, /* 0b000 */ X86_SOCKET_FS1B, /* 0b001 */ X86_SOCKET_UNKNOWN, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x16 models 30-3f */ #define A_SKTS_12 12 { X86_SOCKET_FT3B, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_UNKNOWN, /* 0b010 */ X86_SOCKET_FP4, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x17 models 00-0f (Zen 1 - Naples, Ryzen) */ #define A_SKTS_13 13 { X86_SOCKET_UNKNOWN, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_AM4, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_SP3, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_SP3R2 /* 0b111 */ }, /* * Family 0x17 models 10-2f (Zen 1 - APU: Raven Ridge) * (Zen 1 - APU: Banded Kestrel) * (Zen 1 - APU: Dali) */ #define A_SKTS_14 14 { X86_SOCKET_FP5, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_AM4, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x17 models 30-3f (Zen 2 - Rome) */ #define A_SKTS_15 15 { X86_SOCKET_UNKNOWN, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_UNKNOWN, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_SP3, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_SP3R2 /* 0b111 */ }, /* * Family 0x17 models 60-6f (Zen 2 - Renoir) */ #define A_SKTS_16 16 { X86_SOCKET_FP6, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_AM4, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x17 models 70-7f (Zen 2 - Matisse) */ #define A_SKTS_17 17 { X86_SOCKET_UNKNOWN, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_AM4, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x18 models 00-0f (Dhyana) */ #define A_SKTS_18 18 { X86_SOCKET_UNKNOWN, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_UNKNOWN, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_SL1, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_DM1, /* 0b110 */ X86_SOCKET_SL1R2 /* 0b111 */ }, /* * Family 0x19 models 00-0f (Zen 3 - Milan) */ #define A_SKTS_19 19 { X86_SOCKET_UNKNOWN, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_UNKNOWN, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_SP3, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_STRX4 /* 0b111 */ }, /* * Family 0x19 models 20-2f (Zen 3 - Vermeer) */ #define A_SKTS_20 20 { X86_SOCKET_UNKNOWN, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_AM4, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x19 models 50-5f (Zen 3 - Cezanne) */ #define A_SKTS_21 21 { X86_SOCKET_FP6, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_AM4, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x19 models 10-1f (Zen 4 - Genoa) */ #define A_SKTS_22 22 { X86_SOCKET_UNKNOWN, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_UNKNOWN, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_SP5, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x19 models 40-4f (Zen 3 - Rembrandt) */ #define A_SKTS_23 23 { X86_SOCKET_AM5, /* 0b000 */ X86_SOCKET_FP7, /* 0b001 */ X86_SOCKET_FP7R2, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x19 models 60-6f (Zen 4 - Raphael) * Family 0x17 models a0-af (Zen 2 - Mendocino) */ #define A_SKTS_24 24 { X86_SOCKET_AM5, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_UNKNOWN, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * The always-unknown socket group, used for undocumented parts. It * need not be last; the position is arbitrary. */ #define A_SKTS_UNKNOWN 25 { X86_SOCKET_UNKNOWN, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_UNKNOWN, /* 0b010 */ X86_SOCKET_UNKNOWN, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ }, /* * Family 0x17 models 90-97 (Zen 2 - Van Gogh) */ #define A_SKTS_26 26 { X86_SOCKET_UNKNOWN, /* 0b000 */ X86_SOCKET_UNKNOWN, /* 0b001 */ X86_SOCKET_UNKNOWN, /* 0b010 */ X86_SOCKET_FF3, /* 0b011 */ X86_SOCKET_UNKNOWN, /* 0b100 */ X86_SOCKET_UNKNOWN, /* 0b101 */ X86_SOCKET_UNKNOWN, /* 0b110 */ X86_SOCKET_UNKNOWN /* 0b111 */ } }; struct amd_sktmap_s { uint32_t skt_code; char sktstr[16]; }; static struct amd_sktmap_s amd_sktmap_strs[] = { { X86_SOCKET_754, "754" }, { X86_SOCKET_939, "939" }, { X86_SOCKET_940, "940" }, { X86_SOCKET_S1g1, "S1g1" }, { X86_SOCKET_AM2, "AM2" }, { X86_SOCKET_F1207, "F(1207)" }, { X86_SOCKET_S1g2, "S1g2" }, { X86_SOCKET_S1g3, "S1g3" }, { X86_SOCKET_AM, "AM" }, { X86_SOCKET_AM2R2, "AM2r2" }, { X86_SOCKET_AM3, "AM3" }, { X86_SOCKET_G34, "G34" }, { X86_SOCKET_ASB2, "ASB2" }, { X86_SOCKET_C32, "C32" }, { X86_SOCKET_S1g4, "S1g4" }, { X86_SOCKET_FT1, "FT1" }, { X86_SOCKET_FM1, "FM1" }, { X86_SOCKET_FS1, "FS1" }, { X86_SOCKET_AM3R2, "AM3r2" }, { X86_SOCKET_FP2, "FP2" }, { X86_SOCKET_FS1R2, "FS1r2" }, { X86_SOCKET_FM2, "FM2" }, { X86_SOCKET_FP3, "FP3" }, { X86_SOCKET_FM2R2, "FM2r2" }, { X86_SOCKET_FP4, "FP4" }, { X86_SOCKET_AM4, "AM4" }, { X86_SOCKET_FT3, "FT3" }, { X86_SOCKET_FT4, "FT4" }, { X86_SOCKET_FS1B, "FS1b" }, { X86_SOCKET_FT3B, "FT3b" }, { X86_SOCKET_SP3, "SP3" }, { X86_SOCKET_SP3R2, "SP3r2" }, { X86_SOCKET_FP5, "FP5" }, { X86_SOCKET_FP6, "FP6" }, { X86_SOCKET_STRX4, "sTRX4" }, { X86_SOCKET_SL1, "SL1" }, { X86_SOCKET_SL1R2, "SL1R2" }, { X86_SOCKET_DM1, "DM1" }, { X86_SOCKET_SP5, "SP5" }, { X86_SOCKET_AM5, "AM5" }, { X86_SOCKET_FP7, "FP7" }, { X86_SOCKET_FP7R2, "FP7r2" }, { X86_SOCKET_FF3, "FF3" }, { X86_SOCKET_UNKNOWN, "Unknown" } /* Must be last! */ }; /* Keep the array above in sync with the definitions in x86_archext.h. */ CTASSERT(ARRAY_SIZE(amd_sktmap_strs) == X86_NUM_SOCKETS + 1); /* * Table for mapping AMD family/model/stepping ranges onto three derived items: * * * The "chiprev" and associated string, which is generally the AMD silicon * revision along with a symbolic representation of the marketing (not cpuid) * family. In line with the overall cpuid usage, we refer to this as a * processor family. * * The uarch, which is analogous to the chiprev and provides the * microarchitecture/core generation and silicon revision. Note that this is * distinct from the package-level silicon/product revision and is often common * to multiple product lines offered at a given time. * * The socket map selector, used to translate this collection of products' * last 4 model bits (for family 0xf only) or Fn8000_0001_EBX[30:28] into a * socket ID. * * The first member of this array that matches a given family, extended model * plus model range, and stepping range will be considered a match. This allows * us to end each cpuid family and/or processor family with a catchall that * while less specific than we might like still allows us to provide a fair * amount of detail to both other kernel consumers and userland. */ static const struct amd_rev_mapent { uint_t rm_family; uint_t rm_modello; uint_t rm_modelhi; uint_t rm_steplo; uint_t rm_stephi; x86_chiprev_t rm_chiprev; const char *rm_chiprevstr; x86_uarchrev_t rm_uarchrev; uint_t rm_sktidx; } amd_revmap[] = { /* * =============== AuthenticAMD Family 0xf =============== */ /* * Rev B includes model 0x4 stepping 0 and model 0x5 stepping 0 and 1. */ { 0xf, 0x04, 0x04, 0x0, 0x0, X86_CHIPREV_AMD_LEGACY_F_REV_B, "B", X86_UARCHREV_AMD_LEGACY, A_SKTS_0 }, { 0xf, 0x05, 0x05, 0x0, 0x1, X86_CHIPREV_AMD_LEGACY_F_REV_B, "B", X86_UARCHREV_AMD_LEGACY, A_SKTS_0 }, /* * Rev C0 includes model 0x4 stepping 8 and model 0x5 stepping 8 */ { 0xf, 0x04, 0x05, 0x8, 0x8, X86_CHIPREV_AMD_LEGACY_F_REV_C0, "C0", X86_UARCHREV_AMD_LEGACY, A_SKTS_0 }, /* * Rev CG is the rest of extended model 0x0 - i.e., everything * but the rev B and C0 combinations covered above. */ { 0xf, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_F_REV_CG, "CG", X86_UARCHREV_AMD_LEGACY, A_SKTS_0 }, /* * Rev D has extended model 0x1. */ { 0xf, 0x10, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_F_REV_D, "D", X86_UARCHREV_AMD_LEGACY, A_SKTS_0 }, /* * Rev E has extended model 0x2. * Extended model 0x3 is unused but available to grow into. */ { 0xf, 0x20, 0x3f, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_F_REV_E, "E", X86_UARCHREV_AMD_LEGACY, A_SKTS_0 }, /* * Rev F has extended models 0x4 and 0x5. */ { 0xf, 0x40, 0x5f, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_F_REV_F, "F", X86_UARCHREV_AMD_LEGACY, A_SKTS_1 }, /* * Rev G has extended model 0x6. */ { 0xf, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_F_REV_G, "G", X86_UARCHREV_AMD_LEGACY, A_SKTS_1 }, /* * =============== AuthenticAMD Family 0x10 =============== */ /* * Rev A has model 0 and stepping 0/1/2 for DR-{A0,A1,A2}. * Give all of model 0 stepping range to rev A. */ { 0x10, 0x00, 0x00, 0x0, 0x2, X86_CHIPREV_AMD_LEGACY_10_REV_A, "A", X86_UARCHREV_AMD_LEGACY, A_SKTS_2 }, /* * Rev B has model 2 and steppings 0/1/0xa/2 for DR-{B0,B1,BA,B2}. * Give all of model 2 stepping range to rev B. */ { 0x10, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_10_REV_B, "B", X86_UARCHREV_AMD_LEGACY, A_SKTS_2 }, /* * Rev C has models 4-6 (depending on L3 cache configuration) * Give all of models 4-6 stepping range 0-2 to rev C2. */ { 0x10, 0x4, 0x6, 0x0, 0x2, X86_CHIPREV_AMD_LEGACY_10_REV_C2, "C2", X86_UARCHREV_AMD_LEGACY, A_SKTS_2 }, /* * Rev C has models 4-6 (depending on L3 cache configuration) * Give all of models 4-6 stepping range >= 3 to rev C3. */ { 0x10, 0x4, 0x6, 0x3, 0xf, X86_CHIPREV_AMD_LEGACY_10_REV_C3, "C3", X86_UARCHREV_AMD_LEGACY, A_SKTS_2 }, /* * Rev D has models 8 and 9 * Give all of model 8 and 9 stepping 0 to rev D0. */ { 0x10, 0x8, 0x9, 0x0, 0x0, X86_CHIPREV_AMD_LEGACY_10_REV_D0, "D0", X86_UARCHREV_AMD_LEGACY, A_SKTS_2 }, /* * Rev D has models 8 and 9 * Give all of model 8 and 9 stepping range >= 1 to rev D1. */ { 0x10, 0x8, 0x9, 0x1, 0xf, X86_CHIPREV_AMD_LEGACY_10_REV_D1, "D1", X86_UARCHREV_AMD_LEGACY, A_SKTS_2 }, /* * Rev E has models A and stepping 0 * Give all of model A stepping range to rev E. */ { 0x10, 0xA, 0xA, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_10_REV_E, "E", X86_UARCHREV_AMD_LEGACY, A_SKTS_2 }, { 0x10, 0x0, 0xff, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_10_UNKNOWN, "??", X86_UARCHREV_AMD_LEGACY, A_SKTS_2 }, /* * =============== AuthenticAMD Family 0x11 =============== */ { 0x11, 0x03, 0x03, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_11_REV_B, "B", X86_UARCHREV_AMD_LEGACY, A_SKTS_3 }, { 0x11, 0x00, 0xff, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_11_UNKNOWN, "??", X86_UARCHREV_AMD_LEGACY, A_SKTS_3 }, /* * =============== AuthenticAMD Family 0x12 =============== */ { 0x12, 0x01, 0x01, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_12_REV_B, "B", X86_UARCHREV_AMD_LEGACY, A_SKTS_4 }, { 0x12, 0x00, 0x00, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_12_UNKNOWN, "??", X86_UARCHREV_AMD_LEGACY, A_SKTS_4 }, /* * =============== AuthenticAMD Family 0x14 =============== */ { 0x14, 0x01, 0x01, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_14_REV_B, "B", X86_UARCHREV_AMD_LEGACY, A_SKTS_5 }, { 0x14, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_14_REV_C, "C", X86_UARCHREV_AMD_LEGACY, A_SKTS_5 }, { 0x14, 0x00, 0xff, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_14_UNKNOWN, "??", X86_UARCHREV_AMD_LEGACY, A_SKTS_5 }, /* * =============== AuthenticAMD Family 0x15 =============== */ { 0x15, 0x01, 0x01, 0x2, 0x2, X86_CHIPREV_AMD_OROCHI_REV_B2, "OR-B2", X86_UARCHREV_AMD_LEGACY, A_SKTS_6 }, { 0x15, 0x02, 0x02, 0x0, 0x0, X86_CHIPREV_AMD_OROCHI_REV_C0, "OR-C0", X86_UARCHREV_AMD_LEGACY, A_SKTS_6 }, { 0x15, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_OROCHI_UNKNOWN, "OR-??", X86_UARCHREV_AMD_LEGACY, A_SKTS_6 }, { 0x15, 0x10, 0x10, 0x1, 0x1, X86_CHIPREV_AMD_TRINITY_REV_A1, "TN-A1", X86_UARCHREV_AMD_LEGACY, A_SKTS_7 }, { 0x15, 0x10, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_TRINITY_UNKNOWN, "TN-??", X86_UARCHREV_AMD_LEGACY, A_SKTS_7 }, { 0x15, 0x30, 0x30, 0x1, 0x1, X86_CHIPREV_AMD_KAVERI_REV_A1, "KV-A1", X86_UARCHREV_AMD_LEGACY, A_SKTS_8 }, { 0x15, 0x30, 0x3f, 0x0, 0xf, X86_CHIPREV_AMD_KAVERI_UNKNOWN, "KV-??", X86_UARCHREV_AMD_LEGACY, A_SKTS_8 }, /* * The Carrizo rev guide mentions A0 as having an ID of "00600F00h" but * this appears to be a typo as elsewhere it's given as "00660F00h". We * assume the latter is correct. */ { 0x15, 0x60, 0x60, 0x0, 0x0, X86_CHIPREV_AMD_CARRIZO_REV_A0, "CZ-A0", X86_UARCHREV_AMD_LEGACY, A_SKTS_9 }, { 0x15, 0x60, 0x60, 0x1, 0x1, X86_CHIPREV_AMD_CARRIZO_REV_A1, "CZ-A1", X86_UARCHREV_AMD_LEGACY, A_SKTS_9 }, /* * CZ-DDR4 and BR-A1 are indistinguishable via cpuid; the rev guide * indicates that they should be distinguished by the contents of the * OSVW MSR, but this register is just a software scratch space which * means the actual method of distinguishing the two is not documented * and on PCs will be done by a BIOS. In the extremely unlikely event * it becomes necessary to distinguish these, an OSVW-driven fixup can * be added. */ { 0x15, 0x65, 0x65, 0x1, 0x1, X86_CHIPREV_AMD_CARRIZO_REV_DDR4, "CZ-DDR4", X86_UARCHREV_AMD_LEGACY, A_SKTS_9 }, { 0x15, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_CARRIZO_UNKNOWN, "CZ-??", X86_UARCHREV_AMD_LEGACY, A_SKTS_9 }, { 0x15, 0x70, 0x70, 0x0, 0x0, X86_CHIPREV_AMD_STONEY_RIDGE_REV_A0, "ST-A0", X86_UARCHREV_AMD_LEGACY, A_SKTS_10 }, { 0x15, 0x70, 0x7f, 0x0, 0xf, X86_CHIPREV_AMD_STONEY_RIDGE_UNKNOWN, "ST-??", X86_UARCHREV_AMD_LEGACY, A_SKTS_10 }, /* * =============== AuthenticAMD Family 0x16 =============== */ { 0x16, 0x00, 0x00, 0x1, 0x1, X86_CHIPREV_AMD_KABINI_A1, "KB-A1", X86_UARCHREV_AMD_LEGACY, A_SKTS_11 }, { 0x16, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_KABINI_UNKNOWN, "KB-??", X86_UARCHREV_AMD_LEGACY, A_SKTS_11 }, { 0x16, 0x30, 0x30, 0x1, 0x1, X86_CHIPREV_AMD_MULLINS_A1, "ML-A1", X86_UARCHREV_AMD_LEGACY, A_SKTS_12 }, { 0x16, 0x30, 0x3f, 0x0, 0xf, X86_CHIPREV_AMD_MULLINS_UNKNOWN, "ML-??", X86_UARCHREV_AMD_LEGACY, A_SKTS_12 }, /* * =============== AuthenticAMD Family 0x17 =============== */ /* Naples == Zeppelin == ZP */ { 0x17, 0x00, 0x00, 0x0, 0x0, X86_CHIPREV_AMD_NAPLES_A0, "ZP-A0", X86_UARCHREV_AMD_ZEN1, A_SKTS_13 }, { 0x17, 0x01, 0x01, 0x1, 0x1, X86_CHIPREV_AMD_NAPLES_B1, "ZP-B1", X86_UARCHREV_AMD_ZEN1, A_SKTS_13 }, { 0x17, 0x01, 0x01, 0x2, 0x2, X86_CHIPREV_AMD_NAPLES_B2, "ZP-B2", X86_UARCHREV_AMD_ZEN1, A_SKTS_13 }, { 0x17, 0x00, 0x07, 0x0, 0xf, X86_CHIPREV_AMD_NAPLES_UNKNOWN, "ZP-??", X86_UARCHREV_AMD_ZEN1, A_SKTS_13 }, { 0x17, 0x08, 0x08, 0x2, 0x2, X86_CHIPREV_AMD_PINNACLE_RIDGE_B2, "PiR-B2", X86_UARCHREV_AMD_ZENPLUS, A_SKTS_13 }, { 0x17, 0x08, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_PINNACLE_RIDGE_UNKNOWN, "PiR-??", X86_UARCHREV_AMD_ZENPLUS, A_SKTS_13 }, { 0x17, 0x11, 0x11, 0x0, 0x0, X86_CHIPREV_AMD_RAVEN_RIDGE_B0, "RV-B0", X86_UARCHREV_AMD_ZEN1, A_SKTS_14 }, { 0x17, 0x11, 0x11, 0x1, 0x1, X86_CHIPREV_AMD_RAVEN_RIDGE_B1, "RV-B1", X86_UARCHREV_AMD_ZEN1, A_SKTS_14 }, { 0x17, 0x10, 0x17, 0x0, 0xf, X86_CHIPREV_AMD_RAVEN_RIDGE_UNKNOWN, "RV-??", X86_UARCHREV_AMD_ZEN1, A_SKTS_14 }, { 0x17, 0x18, 0x18, 0x1, 0x1, X86_CHIPREV_AMD_PICASSO_B1, "PCO-B1", X86_UARCHREV_AMD_ZENPLUS, A_SKTS_14 }, { 0x17, 0x18, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_PICASSO_UNKNOWN, "PCO-??", X86_UARCHREV_AMD_ZENPLUS, A_SKTS_14 }, { 0x17, 0x20, 0x20, 0x1, 0x1, X86_CHIPREV_AMD_DALI_A1, "RV2X-A1", X86_UARCHREV_AMD_ZEN1, A_SKTS_14 }, { 0x17, 0x20, 0x2f, 0x0, 0xf, X86_CHIPREV_AMD_DALI_UNKNOWN, "RV2X-??", X86_UARCHREV_AMD_ZEN1, A_SKTS_14 }, /* Rome == Starship == SSP */ { 0x17, 0x30, 0x30, 0x0, 0x0, X86_CHIPREV_AMD_ROME_A0, "SSP-A0", X86_UARCHREV_AMD_ZEN2_A0, A_SKTS_15 }, { 0x17, 0x31, 0x31, 0x0, 0x0, X86_CHIPREV_AMD_ROME_B0, "SSP-B0", X86_UARCHREV_AMD_ZEN2_B0, A_SKTS_15 }, { 0x17, 0x30, 0x3f, 0x0, 0xf, X86_CHIPREV_AMD_ROME_UNKNOWN, "SSP-??", X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_15 }, { 0x17, 0x60, 0x60, 0x1, 0x1, X86_CHIPREV_AMD_RENOIR_A1, "RN-A1", X86_UARCHREV_AMD_ZEN2_B0, A_SKTS_16 }, { 0x17, 0x60, 0x67, 0x0, 0xf, X86_CHIPREV_AMD_RENOIR_UNKNOWN, "RN-??", X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_16 }, { 0x17, 0x68, 0x68, 0x1, 0x1, X86_CHIPREV_AMD_RENOIR_LCN_A1, "LCN-A1", X86_UARCHREV_AMD_ZEN2_B0, A_SKTS_16 }, { 0x17, 0x68, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_RENOIR_UNKNOWN, "LCN-??", X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_16 }, { 0x17, 0x71, 0x71, 0x0, 0x0, X86_CHIPREV_AMD_MATISSE_B0, "MTS-B0", X86_UARCHREV_AMD_ZEN2_B0, A_SKTS_17 }, { 0x17, 0x70, 0x7f, 0x0, 0xf, X86_CHIPREV_AMD_MATISSE_UNKNOWN, "MTS-??", X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_17 }, { 0x17, 0x90, 0x97, 0x0, 0xf, X86_CHIPREV_AMD_VAN_GOGH_UNKNOWN, "??", X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_26 }, { 0x17, 0x98, 0x9f, 0x0, 0xf, X86_CHIPREV_AMD_VAN_GOGH_UNKNOWN, "??", X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_UNKNOWN }, { 0x17, 0xa0, 0xaf, 0x0, 0xf, X86_CHIPREV_AMD_MENDOCINO_UNKNOWN, "??", X86_UARCHREV_AMD_ZEN2_UNKNOWN, A_SKTS_24 }, /* * =============== HygonGenuine Family 0x18 =============== */ { 0x18, 0x00, 0x00, 0x1, 0x1, X86_CHIPREV_HYGON_DHYANA_A1, "DN_A1", X86_UARCHREV_AMD_ZEN1, A_SKTS_18 }, { 0x18, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_HYGON_DHYANA_UNKNOWN, "DN_??", X86_UARCHREV_AMD_ZEN1, A_SKTS_18 }, /* * =============== AuthenticAMD Family 0x19 =============== */ /* Milan == Genesis == GN */ { 0x19, 0x00, 0x00, 0x0, 0x0, X86_CHIPREV_AMD_MILAN_A0, "GN-A0", X86_UARCHREV_AMD_ZEN3_A0, A_SKTS_19 }, { 0x19, 0x01, 0x01, 0x0, 0x0, X86_CHIPREV_AMD_MILAN_B0, "GN-B0", X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_19 }, { 0x19, 0x01, 0x01, 0x1, 0x1, X86_CHIPREV_AMD_MILAN_B1, "GN-B1", X86_UARCHREV_AMD_ZEN3_B1, A_SKTS_19 }, /* Marketed as Milan-X but still GN */ { 0x19, 0x01, 0x01, 0x2, 0x2, X86_CHIPREV_AMD_MILAN_B2, "GN-B2", X86_UARCHREV_AMD_ZEN3_B2, A_SKTS_19 }, { 0x19, 0x00, 0x0f, 0x0, 0xf, X86_CHIPREV_AMD_MILAN_UNKNOWN, "GN-??", X86_UARCHREV_AMD_ZEN3_UNKNOWN, A_SKTS_19 }, /* Genoa == Stones == RS */ { 0x19, 0x10, 0x10, 0x0, 0x0, X86_CHIPREV_AMD_GENOA_A0, "RS-A0", X86_UARCHREV_AMD_ZEN4, A_SKTS_22 }, { 0x19, 0x10, 0x1f, 0x0, 0xf, X86_CHIPREV_AMD_GENOA_UNKNOWN, "RS-??", X86_UARCHREV_AMD_ZEN4, A_SKTS_22 }, { 0x19, 0x20, 0x20, 0x0, 0x0, X86_CHIPREV_AMD_VERMEER_A0, "VMR-A0", X86_UARCHREV_AMD_ZEN3_A0, A_SKTS_20 }, { 0x19, 0x21, 0x21, 0x0, 0x0, X86_CHIPREV_AMD_VERMEER_B0, "VMR-B0", X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_20 }, { 0x19, 0x21, 0x21, 0x2, 0x2, X86_CHIPREV_AMD_VERMEER_B2, "VMR-B2", X86_UARCHREV_AMD_ZEN3_B2, A_SKTS_20 }, { 0x19, 0x20, 0x2f, 0x0, 0xf, X86_CHIPREV_AMD_VERMEER_UNKNOWN, "VMR-??", X86_UARCHREV_AMD_ZEN3_UNKNOWN, A_SKTS_20 }, /* Rev guide is missing AM5 information, including A0 and B0 */ { 0x19, 0x40, 0x40, 0x0, 0x0, X86_CHIPREV_AMD_REMBRANDT_A0, "RMB-A0", X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_23 }, { 0x19, 0x44, 0x44, 0x0, 0x0, X86_CHIPREV_AMD_REMBRANDT_B0, "RMB-B0", X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_23 }, { 0x19, 0x44, 0x44, 0x1, 0x1, X86_CHIPREV_AMD_REMBRANDT_B1, "RMB-B1", X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_23 }, { 0x19, 0x40, 0x4f, 0x0, 0xf, X86_CHIPREV_AMD_REMBRANDT_UNKNOWN, "RMB-??", X86_UARCHREV_AMD_ZEN3_UNKNOWN, A_SKTS_23 }, { 0x19, 0x50, 0x50, 0x0, 0x0, X86_CHIPREV_AMD_CEZANNE_A0, "CZN-A0", X86_UARCHREV_AMD_ZEN3_B0, A_SKTS_21 }, { 0x19, 0x50, 0x5f, 0x0, 0xf, X86_CHIPREV_AMD_CEZANNE_UNKNOWN, "CZN-??", X86_UARCHREV_AMD_ZEN3_UNKNOWN, A_SKTS_21 }, { 0x19, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_RAPHAEL_UNKNOWN, "??", X86_UARCHREV_AMD_ZEN4, A_SKTS_24 } }; /* * AMD keeps the socket type in CPUID Fn8000_0001_EBX, bits 31:28. */ static uint32_t synth_amd_skt_cpuid(uint_t family, uint_t sktid) { struct cpuid_regs cp; uint_t idx; cp.cp_eax = 0x80000001; (void) __cpuid_insn(&cp); /* PkgType bits */ idx = BITX(cp.cp_ebx, 31, 28); if (idx > 7) { return (X86_SOCKET_UNKNOWN); } if (family == 0x10) { uint32_t val; val = pci_getl_func(0, 24, 2, 0x94); if (BITX(val, 8, 8)) { if (amd_skts[sktid][idx] == X86_SOCKET_AM2R2) { return (X86_SOCKET_AM3); } else if (amd_skts[sktid][idx] == X86_SOCKET_S1g3) { return (X86_SOCKET_S1g4); } } } return (amd_skts[sktid][idx]); } static void synth_amd_info(uint_t family, uint_t model, uint_t step, uint32_t *skt_p, x86_chiprev_t *chiprev_p, const char **chiprevstr_p, x86_uarchrev_t *uarchrev_p) { const struct amd_rev_mapent *rmp; int found = 0; int i; if (family < 0xf) return; for (i = 0, rmp = amd_revmap; i < ARRAY_SIZE(amd_revmap); i++, rmp++) { if (family == rmp->rm_family && model >= rmp->rm_modello && model <= rmp->rm_modelhi && step >= rmp->rm_steplo && step <= rmp->rm_stephi) { found = 1; break; } } if (found) { if (chiprev_p != NULL) *chiprev_p = rmp->rm_chiprev; if (chiprevstr_p != NULL) *chiprevstr_p = rmp->rm_chiprevstr; if (uarchrev_p != NULL) *uarchrev_p = rmp->rm_uarchrev; } if (skt_p != NULL) { int platform; #ifdef __xpv /* PV guest */ if (!is_controldom()) { *skt_p = X86_SOCKET_UNKNOWN; return; } #endif platform = get_hwenv(); if ((platform & HW_VIRTUAL) != 0) { *skt_p = X86_SOCKET_UNKNOWN; return; } if (!found) return; if (family == 0xf) { *skt_p = amd_skts[rmp->rm_sktidx][model & 0x3]; } else { *skt_p = synth_amd_skt_cpuid(family, rmp->rm_sktidx); } } } uint32_t _cpuid_skt(uint_t vendor, uint_t family, uint_t model, uint_t step) { uint32_t skt = X86_SOCKET_UNKNOWN; switch (vendor) { case X86_VENDOR_AMD: case X86_VENDOR_HYGON: synth_amd_info(family, model, step, &skt, NULL, NULL, NULL); break; default: break; } return (skt); } const char * _cpuid_sktstr(uint_t vendor, uint_t family, uint_t model, uint_t step) { const char *sktstr = "Unknown"; struct amd_sktmap_s *sktmapp; uint32_t skt = X86_SOCKET_UNKNOWN; switch (vendor) { case X86_VENDOR_AMD: case X86_VENDOR_HYGON: synth_amd_info(family, model, step, &skt, NULL, NULL, NULL); sktmapp = amd_sktmap_strs; while (sktmapp->skt_code != X86_SOCKET_UNKNOWN) { if (sktmapp->skt_code == skt) break; sktmapp++; } sktstr = sktmapp->sktstr; break; default: break; } return (sktstr); } x86_chiprev_t _cpuid_chiprev(uint_t vendor, uint_t family, uint_t model, uint_t step) { x86_chiprev_t chiprev = X86_CHIPREV_UNKNOWN; switch (vendor) { case X86_VENDOR_AMD: case X86_VENDOR_HYGON: synth_amd_info(family, model, step, NULL, &chiprev, NULL, NULL); break; default: break; } return (chiprev); } x86_uarchrev_t _cpuid_uarchrev(uint_t vendor, uint_t family, uint_t model, uint_t step) { x86_uarchrev_t uarchrev = X86_UARCHREV_UNKNOWN; switch (vendor) { case X86_VENDOR_AMD: case X86_VENDOR_HYGON: synth_amd_info(family, model, step, NULL, NULL, NULL, &uarchrev); break; default: break; } return (uarchrev); } const char * _cpuid_chiprevstr(uint_t vendor, uint_t family, uint_t model, uint_t step) { const char *revstr = "Unknown"; switch (vendor) { case X86_VENDOR_AMD: case X86_VENDOR_HYGON: synth_amd_info(family, model, step, NULL, NULL, &revstr, NULL); break; default: break; } return (revstr); } /* * Map the vendor string to a type code */ uint_t _cpuid_vendorstr_to_vendorcode(char *vendorstr) { if (strcmp(vendorstr, X86_VENDORSTR_Intel) == 0) return (X86_VENDOR_Intel); else if (strcmp(vendorstr, X86_VENDORSTR_AMD) == 0) return (X86_VENDOR_AMD); else if (strcmp(vendorstr, X86_VENDORSTR_HYGON) == 0) return (X86_VENDOR_HYGON); else if (strcmp(vendorstr, X86_VENDORSTR_TM) == 0) return (X86_VENDOR_TM); else if (strcmp(vendorstr, X86_VENDORSTR_CYRIX) == 0) return (X86_VENDOR_Cyrix); else if (strcmp(vendorstr, X86_VENDORSTR_UMC) == 0) return (X86_VENDOR_UMC); else if (strcmp(vendorstr, X86_VENDORSTR_NexGen) == 0) return (X86_VENDOR_NexGen); else if (strcmp(vendorstr, X86_VENDORSTR_Centaur) == 0) return (X86_VENDOR_Centaur); else if (strcmp(vendorstr, X86_VENDORSTR_Rise) == 0) return (X86_VENDOR_Rise); else if (strcmp(vendorstr, X86_VENDORSTR_SiS) == 0) return (X86_VENDOR_SiS); else if (strcmp(vendorstr, X86_VENDORSTR_NSC) == 0) return (X86_VENDOR_NSC); else return (X86_VENDOR_IntelClone); }