diff options
| author | Dan McDonald <danmcd@mnx.io> | 2022-08-24 13:28:00 -0400 |
|---|---|---|
| committer | Dan McDonald <danmcd@mnx.io> | 2022-08-24 13:28:00 -0400 |
| commit | 90af780510dfbe56b250e428abeaa2b5bc489bce (patch) | |
| tree | b60c81c6fb2be6a519f5a7be07e939abbc5f0c21 /usr | |
| parent | 03b1b834d019d8a5b0af2b5dc462ba12b31b7ec1 (diff) | |
| parent | 22e4c3ac083467e1e6241dedfea03e25c101eedf (diff) | |
| download | illumos-joyent-90af780510dfbe56b250e428abeaa2b5bc489bce.tar.gz | |
[illumos-gate merge]
commit 22e4c3ac083467e1e6241dedfea03e25c101eedf
14836 extend AMD chiprev mechanism to identify core revs
commit b8f43eb65c2ac2ff69cf1a69aabc90c27cdb859e
14686 nvme should use namespace GUID for devid if available
Diffstat (limited to 'usr')
22 files changed, 957 insertions, 524 deletions
diff --git a/usr/src/uts/common/io/nvme/nvme.c b/usr/src/uts/common/io/nvme/nvme.c index 6ce0b3dcf9..9710dd5728 100644 --- a/usr/src/uts/common/io/nvme/nvme.c +++ b/usr/src/uts/common/io/nvme/nvme.c @@ -93,9 +93,10 @@ * namespaces that have these attributes. * * As of NVMe 1.1 namespaces can have an 64bit Extended Unique Identifier - * (EUI64). This driver uses the EUI64 if present to generate the devid and - * passes it to blkdev to use it in the device node names. As this is currently - * untested namespaces with EUI64 are ignored by default. + * (EUI64), and NVMe 1.2 introduced an additional 128bit Namespace Globally + * Unique Identifier (NGUID). This driver uses either the NGUID or the EUI64 + * if present to generate the devid, and passes the EUI64 to blkdev to use it + * in the device node names. * * We currently support only (2 << NVME_MINOR_INST_SHIFT) - 2 namespaces in a * single controller. This is an artificial limit imposed by the driver to be @@ -136,9 +137,9 @@ * Blkdev also supports querying device/media information and generating a * devid. The driver reports the best block size as determined by the namespace * format back to blkdev as physical block size to support partition and block - * alignment. The devid is either based on the namespace EUI64, if present, or - * composed using the device vendor ID, model number, serial number, and the - * namespace ID. + * alignment. The devid is either based on the namespace GUID or EUI64, if + * present, or composed using the device vendor ID, model number, serial number, + * and the namespace ID. * * * Error Handling: @@ -2996,11 +2997,17 @@ nvme_init_ns(nvme_t *nvme, int nsid) ns->ns_best_block_size = ns->ns_block_size; /* - * Get the EUI64 if present. Use it for devid and device node names. + * Get the EUI64 if present. */ if (NVME_VERSION_ATLEAST(&nvme->n_version, 1, 1)) bcopy(idns->id_eui64, ns->ns_eui64, sizeof (ns->ns_eui64)); + /* + * Get the NGUID if present. + */ + if (NVME_VERSION_ATLEAST(&nvme->n_version, 1, 2)) + bcopy(idns->id_nguid, ns->ns_nguid, sizeof (ns->ns_nguid)); + /*LINTED: E_BAD_PTR_CAST_ALIGN*/ if (*(uint64_t *)ns->ns_eui64 != 0) { uint8_t *eui64 = ns->ns_eui64; @@ -4647,12 +4654,15 @@ nvme_bd_devid(void *arg, dev_info_t *devinfo, ddi_devid_t *devid) return (EIO); } - /*LINTED: E_BAD_PTR_CAST_ALIGN*/ - if (*(uint64_t *)ns->ns_eui64 != 0) { - return (ddi_devid_init(devinfo, DEVID_SCSI3_WWN, + if (*(uint64_t *)ns->ns_nguid != 0 || + *(uint64_t *)(ns->ns_nguid + 8) != 0) { + return (ddi_devid_init(devinfo, DEVID_NVME_NGUID, + sizeof (ns->ns_nguid), ns->ns_nguid, devid)); + } else if (*(uint64_t *)ns->ns_eui64 != 0) { + return (ddi_devid_init(devinfo, DEVID_NVME_EUI64, sizeof (ns->ns_eui64), ns->ns_eui64, devid)); } else { - return (ddi_devid_init(devinfo, DEVID_ENCAP, + return (ddi_devid_init(devinfo, DEVID_NVME_NSID, strlen(ns->ns_devid), ns->ns_devid, devid)); } } diff --git a/usr/src/uts/common/io/nvme/nvme_var.h b/usr/src/uts/common/io/nvme/nvme_var.h index 10cc529fd9..dde0af58fb 100644 --- a/usr/src/uts/common/io/nvme/nvme_var.h +++ b/usr/src/uts/common/io/nvme/nvme_var.h @@ -278,6 +278,7 @@ struct nvme { struct nvme_namespace { nvme_t *ns_nvme; uint8_t ns_eui64[8]; + uint8_t ns_nguid[16]; char ns_name[17]; bd_handle_t ns_bd_hdl; @@ -298,7 +299,7 @@ struct nvme_namespace { nvme_minor_state_t ns_minor; /* - * If a namespace has no EUI64, we create a devid in + * If a namespace has neither NGUID nor EUI64, we create a devid in * nvme_prepare_devid(). */ char *ns_devid; diff --git a/usr/src/uts/common/os/sunddi.c b/usr/src/uts/common/os/sunddi.c index 1874a2ef00..7c094a0f20 100644 --- a/usr/src/uts/common/os/sunddi.c +++ b/usr/src/uts/common/os/sunddi.c @@ -22,6 +22,7 @@ /* * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2022 Garrett D'Amore + * Copyright 2022 Tintri by DDN, Inc. All rights reserved. */ #include <sys/note.h> @@ -7805,6 +7806,12 @@ ddi_devid_init( /*FALLTHRU*/ case DEVID_ATA_SERIAL: /*FALLTHRU*/ + case DEVID_NVME_NSID: + /*FALLTHRU*/ + case DEVID_NVME_EUI64: + /*FALLTHRU*/ + case DEVID_NVME_NGUID: + /*FALLTHRU*/ case DEVID_ENCAP: if (nbytes == 0) return (DDI_FAILURE); diff --git a/usr/src/uts/common/sys/ddi_impldefs.h b/usr/src/uts/common/sys/ddi_impldefs.h index bf3e29397f..2570fe8772 100644 --- a/usr/src/uts/common/sys/ddi_impldefs.h +++ b/usr/src/uts/common/sys/ddi_impldefs.h @@ -23,6 +23,7 @@ * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved. * Copyright 2016 Joyent, Inc. * Copyright (c) 2016 by Delphix. All rights reserved. + * Copyright 2022 Tintri by DDN, Inc. All rights reserved. */ #ifndef _SYS_DDI_IMPLDEFS_H @@ -1119,6 +1120,12 @@ typedef struct impl_devid { * 'E' | // DEVID_ENCAP <ascii_id> * 'a' | // DEVID_ATA_SERIAL <hex_id> * 'A' | // DEVID_ATA_SERIAL <ascii_id> + * 'd' | // DEVID_NVME_NSID <hex_id> + * 'D' | // DEVID_NVME_NSID <ascii_id> + * 'i' | // DEVID_NVME_EUI64 <hex_id> + * 'I' | // DEVID_NVME_EUI64 <ascii_id> + * 'g' | // DEVID_NVME_NGUID <hex_id> + * 'G' | // DEVID_NVME_NGUID <ascii_id> * 'u' | // unknown <hex_id> * 'U' // unknown <ascii_id> * // NOTE:lower case -> <hex_id> @@ -1179,6 +1186,9 @@ typedef struct impl_devid { ((b) == DEVID_FAB) ? 'f' : \ ((b) == DEVID_ENCAP) ? 'e' : \ ((b) == DEVID_ATA_SERIAL) ? 'a' : \ + ((b) == DEVID_NVME_NSID) ? 'd' : \ + ((b) == DEVID_NVME_EUI64) ? 'i' : \ + ((b) == DEVID_NVME_NGUID) ? 'g' : \ 'u') /* unknown */ /* convert type field from ascii to binary */ @@ -1191,6 +1201,9 @@ typedef struct impl_devid { (((c) == 'f') || ((c) == 'F')) ? DEVID_FAB : \ (((c) == 'e') || ((c) == 'E')) ? DEVID_ENCAP : \ (((c) == 'a') || ((c) == 'A')) ? DEVID_ATA_SERIAL : \ + (((c) == 'd') || ((c) == 'D')) ? DEVID_NVME_NSID : \ + (((c) == 'i') || ((c) == 'I')) ? DEVID_NVME_EUI64 : \ + (((c) == 'g') || ((c) == 'G')) ? DEVID_NVME_NGUID : \ DEVID_MAXTYPE +1) /* unknown */ /* determine if the type should be forced to hex encoding (non-ascii) */ @@ -1198,6 +1211,8 @@ typedef struct impl_devid { ((b) == DEVID_SCSI3_WWN) || \ ((b) == DEVID_SCSI3_VPD_EUI) || \ ((b) == DEVID_SCSI3_VPD_NAA) || \ + ((b) == DEVID_NVME_EUI64) || \ + ((b) == DEVID_NVME_NGUID) || \ ((b) == DEVID_FAB)) /* determine if the type is from a scsi3 vpd */ diff --git a/usr/src/uts/common/sys/dditypes.h b/usr/src/uts/common/sys/dditypes.h index 733b35772e..b11052e39b 100644 --- a/usr/src/uts/common/sys/dditypes.h +++ b/usr/src/uts/common/sys/dditypes.h @@ -22,6 +22,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2022 Tintri by DDN, Inc. All rights reserved. */ #ifndef _SYS_DDITYPES_H @@ -83,7 +84,7 @@ typedef struct __ddi_dma_seg *ddi_dma_seg_t; typedef struct { union { uint64_t _dmac_ll; /* 64 bit DMA address */ - uint32_t _dmac_la[2]; /* 2 x 32 bit address */ + uint32_t _dmac_la[2]; /* 2 x 32 bit address */ } _dmu; size_t dmac_size; /* DMA cookie size */ uint_t dmac_type; /* bus specific type bits */ @@ -163,7 +164,10 @@ typedef struct __ddi_devid *ddi_devid_t; #define DEVID_SCSI3_VPD_T10 6 #define DEVID_SCSI3_VPD_EUI 7 #define DEVID_SCSI3_VPD_NAA 8 -#define DEVID_MAXTYPE 8 +#define DEVID_NVME_NSID 9 +#define DEVID_NVME_EUI64 10 +#define DEVID_NVME_NGUID 11 +#define DEVID_MAXTYPE 11 /* * Device id scsi encode versions (version of encode interface, not devid) @@ -232,8 +236,8 @@ typedef struct ddi_device_acc_attr { uchar_t devacc_attr_access; /* access error protection */ } ddi_device_acc_attr_t; -#define DDI_DEVICE_ATTR_V0 0x0001 -#define DDI_DEVICE_ATTR_V1 0x0002 +#define DDI_DEVICE_ATTR_V0 0x0001 +#define DDI_DEVICE_ATTR_V1 0x0002 /* * endian-ness flags @@ -262,14 +266,14 @@ typedef struct ddi_device_acc_attr { /* * Data Access Handle */ -#define VERS_ACCHDL 0x0001 +#define VERS_ACCHDL 0x0001 typedef struct __ddi_acc_handle *ddi_acc_handle_t; typedef struct ddi_acc_hdl { int ah_vers; /* version number */ void *ah_bus_private; /* bus private pointer */ - void *ah_platform_private; /* platform private pointer */ + void *ah_platform_private; /* platform private pointer */ dev_info_t *ah_dip; /* requesting device */ uint_t ah_rnumber; /* register number */ diff --git a/usr/src/uts/i86pc/cpu/amd_opteron/ao.h b/usr/src/uts/i86pc/cpu/amd_opteron/ao.h index 621c18ec4c..d3f01d62fd 100644 --- a/usr/src/uts/i86pc/cpu/amd_opteron/ao.h +++ b/usr/src/uts/i86pc/cpu/amd_opteron/ao.h @@ -126,7 +126,7 @@ typedef struct ao_ms_mca { * Per-chip shared state */ struct ao_chipshared { - uint32_t aos_chiprev; + x86_chiprev_t aos_chiprev; volatile ulong_t aos_cfgonce; /* Config performed once per chip */ hrtime_t aos_nb_poll_timestamp; cmi_hdl_t aos_nb_poll_owner; diff --git a/usr/src/uts/i86pc/cpu/amd_opteron/ao_mca.c b/usr/src/uts/i86pc/cpu/amd_opteron/ao_mca.c index fc8fa29887..27fd89b0fb 100644 --- a/usr/src/uts/i86pc/cpu/amd_opteron/ao_mca.c +++ b/usr/src/uts/i86pc/cpu/amd_opteron/ao_mca.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Oxide Computer Co. */ #include <sys/types.h> @@ -56,7 +57,8 @@ #include "ao.h" #include "ao_mca_disp.h" -#define AO_F_REVS_FG (X86_CHIPREV_AMD_F_REV_F | X86_CHIPREV_AMD_F_REV_G) +#define AO_F_REVS_FG (X86_CHIPREV_AMD_LEGACY_F_REV_F | \ + X86_CHIPREV_AMD_LEGACY_F_REV_G) int ao_mca_smi_disable = 1; /* attempt to disable SMI polling */ @@ -202,7 +204,7 @@ ao_disp_match_one(const ao_error_disp_t *aed, uint64_t status, uint32_t rev, * This behaviour is fixed in revision F. */ if (bankno == AMD_MCA_BANK_NB && - !X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_F) && + !chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_F_REV_F) && status & MSR_MC_STATUS_OVER) { stat_mask &= ~AMD_BANK_STAT_CECC; stat_mask_res &= ~AMD_BANK_STAT_CECC; @@ -243,7 +245,7 @@ ao_ms_disp_match(cmi_hdl_t hdl, int ismc, int banknum, uint64_t status, uint64_t addr, uint64_t misc, void *mslogout) { ao_ms_data_t *ao = cms_hdl_getcmsdata(hdl); - uint32_t rev = ao->ao_ms_shared->aos_chiprev; + x86_chiprev_t rev = ao->ao_ms_shared->aos_chiprev; const ao_error_disp_t *aed; for (aed = ao_error_disp[banknum]; aed->aed_stat_mask != 0; aed++) { @@ -295,7 +297,7 @@ nb_mcamisc_init(cmi_hdl_t hdl, ao_ms_data_t *ao, uint32_t rev) { uint64_t val, nval; - if (!X86_CHIPREV_MATCH(rev, AO_F_REVS_FG)) + if (!chiprev_matches(rev, AO_F_REVS_FG)) return; if (cmi_hdl_rdmsr(hdl, AMD_MSR_NB_MISC, &val) != CMI_SUCCESS) @@ -453,7 +455,7 @@ ao_nb_cfg(ao_ms_data_t *ao, uint32_t rev) val |= ao_nb_cfg_add_cmn; while (nbcp->cfg_revmask != X86_CHIPREV_UNKNOWN) { - if (X86_CHIPREV_MATCH(rev, nbcp->cfg_revmask)) { + if (chiprev_matches(rev, nbcp->cfg_revmask)) { val &= ~(*nbcp->cfg_remove_p); val |= *nbcp->cfg_add_p; } @@ -474,7 +476,7 @@ ao_dram_cfg(ao_ms_data_t *ao, uint32_t rev) ao->ao_ms_shared->aos_bcfg_dcfg_hi = ao_pcicfg_read(procnodeid, MC_FUNC_DRAMCTL, MC_DC_REG_DRAMCFGHI); #ifdef OPTERON_ERRATUM_172 - if (X86_CHIPREV_MATCH(rev, AO_F_REVS_FG) && + if (chiprev_matches(rev, AO_F_REVS_FG) && MCREG_FIELD_F_revFG(&dcfglo, ParEn)) { MCREG_FIELD_F_revFG(&dcfglo, ParEn) = 0; ao_pcicfg_write(procnodeid, MC_FUNC_DRAMCTL, @@ -796,7 +798,7 @@ ao_ms_bankctl_val(cmi_hdl_t hdl, int banknum, uint64_t def) const struct ao_ctl_init *extrap; const ao_bank_cfg_t *bankcfg; uint64_t mcictl; - uint32_t rev = ao->ao_ms_shared->aos_chiprev; + x86_chiprev_t rev = ao->ao_ms_shared->aos_chiprev; if (banknum >= sizeof (ao_bank_cfgs) / sizeof (ao_bank_cfgs[0])) return (def); @@ -807,7 +809,7 @@ ao_ms_bankctl_val(cmi_hdl_t hdl, int banknum, uint64_t def) mcictl = bankcfg->bank_ctl_init_cmn; while (extrap != NULL && extrap->ctl_revmask != X86_CHIPREV_UNKNOWN) { - if (X86_CHIPREV_MATCH(rev, extrap->ctl_revmask)) + if (chiprev_matches(rev, extrap->ctl_revmask)) mcictl |= extrap->ctl_bits; extrap++; } @@ -852,7 +854,7 @@ void ao_ms_mca_init(cmi_hdl_t hdl, int nbanks) { ao_ms_data_t *ao = cms_hdl_getcmsdata(hdl); - uint32_t rev = ao->ao_ms_shared->aos_chiprev; + x86_chiprev_t rev = ao->ao_ms_shared->aos_chiprev; ao_ms_mca_t *mca = &ao->ao_ms_mca; uint64_t *maskp; int i; @@ -876,7 +878,7 @@ ao_ms_mca_init(cmi_hdl_t hdl, int nbanks) if (ao_chip_once(ao, AO_CFGONCE_NBCFG) == B_TRUE) { ao_nb_cfg(ao, rev); - if (X86_CHIPREV_MATCH(rev, AO_F_REVS_FG)) + if (chiprev_matches(rev, AO_F_REVS_FG)) ao_sparectl_cfg(ao); } diff --git a/usr/src/uts/i86pc/cpu/authenticamd/authamd.h b/usr/src/uts/i86pc/cpu/authenticamd/authamd.h index a77cd79f33..791e057221 100644 --- a/usr/src/uts/i86pc/cpu/authenticamd/authamd.h +++ b/usr/src/uts/i86pc/cpu/authenticamd/authamd.h @@ -69,7 +69,7 @@ struct authamd_nodeshared { uint_t ans_chipid; uint_t ans_procnodeid; uint_t ans_family; /* family number */ - uint32_t ans_rev; /* revision per cpuid_getchiprev */ + x86_chiprev_t ans_rev; /* revision per cpuid_getchiprev */ volatile ulong_t ans_cfgonce; /* Config performed once per chip */ hrtime_t ans_poll_timestamp; /* Checks poll owner is alive */ cmi_hdl_t ans_pollowner; /* poller of shared resources */ diff --git a/usr/src/uts/i86pc/cpu/authenticamd/authamd_main.c b/usr/src/uts/i86pc/cpu/authenticamd/authamd_main.c index b073734aaa..88b46e7b57 100644 --- a/usr/src/uts/i86pc/cpu/authenticamd/authamd_main.c +++ b/usr/src/uts/i86pc/cpu/authenticamd/authamd_main.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Oxide Computer Co. */ /* @@ -59,15 +60,15 @@ extern int x86gentopo_legacy; /* x86 generic topo support */ int authamd_ms_support_disable = 0; #define AUTHAMD_F_REVS_BCDE \ - (X86_CHIPREV_AMD_F_REV_B | X86_CHIPREV_AMD_F_REV_C0 | \ - X86_CHIPREV_AMD_F_REV_CG | X86_CHIPREV_AMD_F_REV_D | \ - X86_CHIPREV_AMD_F_REV_E) + (X86_CHIPREV_AMD_LEGACY_F_REV_B | X86_CHIPREV_AMD_LEGACY_F_REV_C0 | \ + X86_CHIPREV_AMD_LEGACY_F_REV_CG | X86_CHIPREV_AMD_LEGACY_F_REV_D | \ + X86_CHIPREV_AMD_LEGACY_F_REV_E) #define AUTHAMD_F_REVS_FG \ - (X86_CHIPREV_AMD_F_REV_F | X86_CHIPREV_AMD_F_REV_G) + (X86_CHIPREV_AMD_LEGACY_F_REV_F | X86_CHIPREV_AMD_LEGACY_F_REV_G) #define AUTHAMD_10_REVS_AB \ - (X86_CHIPREV_AMD_10_REV_A | X86_CHIPREV_AMD_10_REV_B) + (X86_CHIPREV_AMD_LEGACY_10_REV_A | X86_CHIPREV_AMD_LEGACY_10_REV_B) /* * Bitmasks of support for various features. Try to enable features @@ -80,64 +81,64 @@ int authamd_ms_support_disable = 0; * Models that include an on-chip NorthBridge. */ #define AUTHAMD_NBONCHIP(rev) \ - (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_B) || \ - X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A)) + (chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_F_REV_B) || \ + chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_10_REV_A)) /* * Families/revisions for which we can recognise main memory ECC errors. */ #define AUTHAMD_MEMECC_RECOGNISED(rev) \ - (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_B) || \ - X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A)) + (chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_F_REV_B) || \ + chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_10_REV_A)) /* * Families/revisions that have an Online Spare Control Register */ #define AUTHAMD_HAS_ONLINESPARECTL(rev) \ - (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_F) || \ - X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A)) + (chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_F_REV_F) || \ + chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_10_REV_A)) /* * Families/revisions for which we will perform NB MCA Config changes */ #define AUTHAMD_DO_NBMCACFG(rev) \ - (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_B) || \ - X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A)) + (chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_F_REV_B) || \ + chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_10_REV_A)) /* * Families/revisions that have chip cache scrubbers. */ #define AUTHAMD_HAS_CHIPSCRUB(rev) \ - (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_B) || \ - X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A)) + (chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_F_REV_B) || \ + chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_10_REV_A)) /* * Families/revisions that have a NB misc register or registers - * evaluates to 0 if no support, otherwise the number of MC4_MISCj. */ #define AUTHAMD_NBMISC_NUM(rev) \ - (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_F)? 1 : \ - (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A) ? 3 : 0)) + (chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_F_REV_F)? 1 : \ + (chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_10_REV_A) ? 3 : 0)) /* * Families/revision for which we wish not to machine check for GART * table walk errors - bit 10 of NB CTL. */ #define AUTHAMD_NOGARTTBLWLK_MC(rev) \ - (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_B) || \ - X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A)) + (chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_F_REV_B) || \ + chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_10_REV_A)) /* * Families/revisions that are potentially L3 capable */ #define AUTHAMD_L3CAPABLE(rev) \ - (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A)) + (chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_10_REV_A)) /* * Families/revisions that support x8 ChipKill ECC */ #define AUTHAMD_SUPPORTS_X8ECC(rev) \ - (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_D0)) + (chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_10_REV_D0)) /* * We recognise main memory ECC errors for AUTHAMD_MEMECC_RECOGNISED @@ -290,7 +291,7 @@ authamd_read_ecccnt(authamd_data_t *authamd, struct authamd_logout *msl) union mcreg_sparectl sparectl; uint_t procnodeid = authamd->amd_shared->ans_procnodeid; uint_t family = authamd->amd_shared->ans_family; - uint32_t rev = authamd->amd_shared->ans_rev; + x86_chiprev_t rev = authamd->amd_shared->ans_rev; int chan, cs; /* @@ -382,7 +383,7 @@ authamd_clear_ecccnt(authamd_data_t *authamd, boolean_t clrint) union mcreg_sparectl sparectl; uint_t procnodeid = authamd->amd_shared->ans_procnodeid; uint_t family = authamd->amd_shared->ans_family; - uint32_t rev = authamd->amd_shared->ans_rev; + x86_chiprev_t rev = authamd->amd_shared->ans_rev; int chan, cs; if (!AUTHAMD_HAS_ONLINESPARECTL(rev)) @@ -452,7 +453,7 @@ authamd_clear_ecccnt(authamd_data_t *authamd, boolean_t clrint) /* * Return - * 1: supported + * 1: supported * 0: unsupported */ static int @@ -484,7 +485,7 @@ authamd_init(cmi_hdl_t hdl, void **datap) uint_t procnodeid = cmi_hdl_procnodeid(hdl); struct authamd_nodeshared *sp, *osp; uint_t family = cmi_hdl_family(hdl); - uint32_t rev = cmi_hdl_chiprev(hdl); + x86_chiprev_t rev = cmi_hdl_chiprev(hdl); authamd_data_t *authamd; uint64_t cap; @@ -560,7 +561,7 @@ boolean_t authamd_bankctl_skipinit(cmi_hdl_t hdl, int bank) { authamd_data_t *authamd = cms_hdl_getcmsdata(hdl); - uint32_t rev = authamd->amd_shared->ans_rev; + x86_chiprev_t rev = authamd->amd_shared->ans_rev; if (authamd->amd_shared->ans_family == AUTHAMD_FAMILY_6) return (bank == 0 ? B_TRUE : B_FALSE); @@ -580,7 +581,7 @@ uint64_t authamd_bankctl_val(cmi_hdl_t hdl, int bank, uint64_t proposed) { authamd_data_t *authamd = cms_hdl_getcmsdata(hdl); - uint32_t rev = authamd->amd_shared->ans_rev; + x86_chiprev_t rev = authamd->amd_shared->ans_rev; uint64_t val = proposed; /* @@ -677,7 +678,7 @@ void authamd_mca_init(cmi_hdl_t hdl, int nbanks) { authamd_data_t *authamd = cms_hdl_getcmsdata(hdl); - uint32_t rev = authamd->amd_shared->ans_rev; + x86_chiprev_t rev = authamd->amd_shared->ans_rev; uint_t procnodeid = authamd->amd_shared->ans_procnodeid; /* @@ -705,12 +706,13 @@ authamd_mca_init(cmi_hdl_t hdl, int nbanks) (uint64_t *)&nbm) != CMI_SUCCESS) continue; - if (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_F) && + if (chiprev_at_least(rev, + X86_CHIPREV_AMD_LEGACY_F_REV_F) && MCMSR_FIELD_F_revFG(&nbm, mcmisc_Valid) && MCMSR_FIELD_F_revFG(&nbm, mcmisc_CntP)) { MCMSR_FIELD_F_revFG(&nbm, mcmisc_IntType) = 0; - } else if (X86_CHIPREV_ATLEAST(rev, - X86_CHIPREV_AMD_10_REV_A) && + } else if (chiprev_at_least(rev, + X86_CHIPREV_AMD_LEGACY_10_REV_A) && MCMSR_FIELD_10_revAB(&nbm, mcmisc_Valid) && MCMSR_FIELD_10_revAB(&nbm, mcmisc_CntP)) { MCMSR_FIELD_10_revAB(&nbm, mcmisc_IntType) = 0; @@ -764,7 +766,7 @@ authamd_mca_init(cmi_hdl_t hdl, int nbanks) * Bit 0 of the NB MCA Config register is reserved on family * 0x10. */ - if (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_10_REV_A)) + if (chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_10_REV_A)) authamd_nb_mcacfg_add &= ~AMD_NB_CFG_CPUECCERREN; val &= ~authamd_nb_mcacfg_remove; @@ -863,7 +865,7 @@ authamd_bank_logout(cmi_hdl_t hdl, int bank, uint64_t status, { authamd_data_t *authamd = cms_hdl_getcmsdata(hdl); struct authamd_logout *msl = mslogout; - uint32_t rev = authamd->amd_shared->ans_rev; + x86_chiprev_t rev = authamd->amd_shared->ans_rev; if (msl == NULL) return; @@ -940,7 +942,7 @@ authamd_disp_match(cmi_hdl_t hdl, int ismc, int bank, uint64_t status, authamd_data_t *authamd = cms_hdl_getcmsdata(hdl); /* uint16_t errcode = MCAX86_ERRCODE(status); */ uint16_t exterrcode = AMD_EXT_ERRCODE(status); - uint32_t rev = authamd->amd_shared->ans_rev; + x86_chiprev_t rev = authamd->amd_shared->ans_rev; /* * Recognise main memory ECC errors diff --git a/usr/src/uts/i86pc/cpu/generic_cpu/gcpu_mca.c b/usr/src/uts/i86pc/cpu/generic_cpu/gcpu_mca.c index 2f71105178..f2ba4cf5b6 100644 --- a/usr/src/uts/i86pc/cpu/generic_cpu/gcpu_mca.c +++ b/usr/src/uts/i86pc/cpu/generic_cpu/gcpu_mca.c @@ -22,6 +22,7 @@ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, Joyent, Inc. + * Copyright 2022 Oxide Computer Co. */ /* * Copyright (c) 2010, Intel Corporation. @@ -1125,7 +1126,6 @@ gcpu_mca_init(cmi_hdl_t hdl) uint64_t cap; uint_t vendor = cmi_hdl_vendor(hdl); uint_t family = cmi_hdl_family(hdl); - uint_t rev = cmi_hdl_chiprev(hdl); gcpu_mca_t *mca = &gcpu->gcpu_mca; int mcg_ctl_present; uint_t nbanks; @@ -1141,7 +1141,7 @@ gcpu_mca_init(cmi_hdl_t hdl) return; /* We add MCi_ADDR always for AMD Family 0xf and above */ - if (X86_CHIPFAM_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_B)) + if (family >= 0xf) gcpu_force_addr_in_payload = 1; /* diff --git a/usr/src/uts/i86pc/os/cmi_hw.c b/usr/src/uts/i86pc/os/cmi_hw.c index 094f5d2bff..dca6543b88 100644 --- a/usr/src/uts/i86pc/os/cmi_hw.c +++ b/usr/src/uts/i86pc/os/cmi_hw.c @@ -118,7 +118,7 @@ struct cmi_hdl_ops { uint_t (*cmio_strandid)(cmi_hdl_impl_t *); uint_t (*cmio_procnodes_per_pkg)(cmi_hdl_impl_t *); uint_t (*cmio_strand_apicid)(cmi_hdl_impl_t *); - uint32_t (*cmio_chiprev)(cmi_hdl_impl_t *); + x86_chiprev_t (*cmio_chiprev)(cmi_hdl_impl_t *); const char *(*cmio_chiprevstr)(cmi_hdl_impl_t *); uint32_t (*cmio_getsockettype)(cmi_hdl_impl_t *); const char *(*cmio_getsocketstr)(cmi_hdl_impl_t *); @@ -662,7 +662,7 @@ ntv_smb_bboard(cmi_hdl_impl_t *hdl) return (hdl->cmih_smb_bboard); } -static uint32_t +static x86_chiprev_t ntv_chiprev(cmi_hdl_impl_t *hdl) { return (cpuid_getchiprev(HDLPRIV(hdl))); @@ -969,9 +969,9 @@ xpv_smb_bboard(cmi_hdl_impl_t *hdl) return (hdl->cmih_smb_bboard); } -extern uint32_t _cpuid_chiprev(uint_t, uint_t, uint_t, uint_t); +extern x86_chiprev_t _cpuid_chiprev(uint_t, uint_t, uint_t, uint_t); -static uint32_t +static x86_chiprev_t xpv_chiprev(cmi_hdl_impl_t *hdl) { return (_cpuid_chiprev(xpv_vendor(hdl), xpv_family(hdl), @@ -1631,7 +1631,7 @@ CMI_HDL_OPFUNC(coreid, uint_t) CMI_HDL_OPFUNC(strandid, uint_t) CMI_HDL_OPFUNC(procnodes_per_pkg, uint_t) CMI_HDL_OPFUNC(strand_apicid, uint_t) -CMI_HDL_OPFUNC(chiprev, uint32_t) +CMI_HDL_OPFUNC(chiprev, x86_chiprev_t) CMI_HDL_OPFUNC(chiprevstr, const char *) CMI_HDL_OPFUNC(getsockettype, uint32_t) CMI_HDL_OPFUNC(getsocketstr, const char *) diff --git a/usr/src/uts/intel/io/amdzen/amdzen.c b/usr/src/uts/intel/io/amdzen/amdzen.c index f8ec834e66..c3617c9742 100644 --- a/usr/src/uts/intel/io/amdzen/amdzen.c +++ b/usr/src/uts/intel/io/amdzen/amdzen.c @@ -187,71 +187,6 @@ static const amdzen_child_data_t amdzen_children[] = { { "zen_umc", AMDZEN_C_ZEN_UMC } }; -/* - * Provide a caller with the notion of what CPU family their device falls into. - * This is useful for client drivers that want to make decisions based on model - * ranges. - */ -zen_family_t -amdzen_c_family(void) -{ - uint_t vendor, family, model; - zen_family_t ret = ZEN_FAMILY_UNKNOWN; - - vendor = cpuid_getvendor(CPU); - family = cpuid_getfamily(CPU); - model = cpuid_getmodel(CPU); - - switch (family) { - case 0x17: - if (vendor != X86_VENDOR_AMD) - break; - if (model < 0x10) { - ret = ZEN_FAMILY_NAPLES; - } else if (model >= 0x10 && model < 0x30) { - ret = ZEN_FAMILY_DALI; - } else if (model >= 0x30 && model < 0x40) { - ret = ZEN_FAMILY_ROME; - } else if (model >= 0x60 && model < 0x70) { - ret = ZEN_FAMILY_RENOIR; - } else if (model >= 0x70 && model < 0x80) { - ret = ZEN_FAMILY_MATISSE; - } else if (model >= 0x90 && model < 0xa0) { - ret = ZEN_FAMILY_VAN_GOGH; - } else if (model >= 0xa0 && model < 0xb0) { - ret = ZEN_FAMILY_MENDOCINO; - } - break; - case 0x18: - if (vendor != X86_VENDOR_HYGON) - break; - if (model < 0x10) - ret = ZEN_FAMILY_DHYANA; - break; - case 0x19: - if (vendor != X86_VENDOR_AMD) - break; - if (model < 0x10) { - ret = ZEN_FAMILY_MILAN; - } else if (model >= 0x10 && model < 0x20) { - ret = ZEN_FAMILY_GENOA; - } else if (model >= 0x20 && model < 0x30) { - ret = ZEN_FAMILY_VERMEER; - } else if (model >= 0x40 && model < 0x50) { - ret = ZEN_FAMILY_REMBRANDT; - } else if (model >= 0x50 && model < 0x60) { - ret = ZEN_FAMILY_CEZANNE; - } else if (model >= 0x60 && model < 0x70) { - ret = ZEN_FAMILY_RAPHAEL; - } - break; - default: - break; - } - - return (ret); -} - static uint32_t amdzen_stub_get32(amdzen_stub_t *stub, off_t reg) { diff --git a/usr/src/uts/intel/io/amdzen/amdzen_client.h b/usr/src/uts/intel/io/amdzen/amdzen_client.h index fe8cd87751..4d937a1321 100644 --- a/usr/src/uts/intel/io/amdzen/amdzen_client.h +++ b/usr/src/uts/intel/io/amdzen/amdzen_client.h @@ -28,30 +28,6 @@ extern "C" { #endif /* - * This enumeration is used to identify a given family of Zen era processors. - * This is derived from a family/model/stepping range. In some cases such as - * Dali, several different chips are covered that appear to be mostly the same - * as far as we can tell for our purposes (e.g. Raven Ridge, Picasso, etc.). - */ -typedef enum { - ZEN_FAMILY_UNKNOWN, - ZEN_FAMILY_NAPLES, - ZEN_FAMILY_DHYANA, - ZEN_FAMILY_DALI, - ZEN_FAMILY_ROME, - ZEN_FAMILY_RENOIR, - ZEN_FAMILY_MATISSE, - ZEN_FAMILY_VAN_GOGH, - ZEN_FAMILY_MENDOCINO, - ZEN_FAMILY_MILAN, - ZEN_FAMILY_GENOA, - ZEN_FAMILY_VERMEER, - ZEN_FAMILY_REMBRANDT, - ZEN_FAMILY_CEZANNE, - ZEN_FAMILY_RAPHAEL -} zen_family_t; - -/* * This struct encodes enough information to later be used to compose and * decompose a fabric ID and component ID. A fabric ID is broken into its node * and component IDs and then a node ID is further decomposed into a socket and @@ -68,7 +44,6 @@ typedef struct { uint8_t dfd_comp_shift; } df_fabric_decomp_t; -extern zen_family_t amdzen_c_family(void); extern uint_t amdzen_c_df_count(void); extern df_rev_t amdzen_c_df_rev(void); extern int amdzen_c_df_fabric_decomp(df_fabric_decomp_t *); diff --git a/usr/src/uts/intel/io/amdzen/zen_umc.c b/usr/src/uts/intel/io/amdzen/zen_umc.c index 485b645299..bf5914fae6 100644 --- a/usr/src/uts/intel/io/amdzen/zen_umc.c +++ b/usr/src/uts/intel/io/amdzen/zen_umc.c @@ -1178,25 +1178,25 @@ static zen_umc_t *zen_umc; */ static const zen_umc_fam_data_t zen_umc_fam_data[] = { { - .zufd_family = ZEN_FAMILY_NAPLES, + .zufd_family = X86_PF_AMD_NAPLES, .zufd_dram_nrules = 16, .zufd_cs_nrules = 2, .zufd_umc_style = ZEN_UMC_UMC_S_DDR4, .zufd_chan_hash = UMC_CHAN_HASH_F_BANK | UMC_CHAN_HASH_F_CS }, { - .zufd_family = ZEN_FAMILY_DHYANA, + .zufd_family = X86_PF_HYGON_DHYANA, .zufd_dram_nrules = 16, .zufd_cs_nrules = 2, .zufd_umc_style = ZEN_UMC_UMC_S_DDR4, .zufd_chan_hash = UMC_CHAN_HASH_F_BANK | UMC_CHAN_HASH_F_CS }, { - .zufd_family = ZEN_FAMILY_DALI, + .zufd_family = X86_PF_AMD_DALI, .zufd_dram_nrules = 2, .zufd_cs_nrules = 2, .zufd_umc_style = ZEN_UMC_UMC_S_DDR4_APU, .zufd_chan_hash = UMC_CHAN_HASH_F_BANK | UMC_CHAN_HASH_F_CS }, { - .zufd_family = ZEN_FAMILY_ROME, + .zufd_family = X86_PF_AMD_ROME, .zufd_flags = ZEN_UMC_FAM_F_NP2 | ZEN_UMC_FAM_F_NORM_HASH | ZEN_UMC_FAM_F_UMC_HASH, .zufd_dram_nrules = 16, @@ -1205,7 +1205,7 @@ static const zen_umc_fam_data_t zen_umc_fam_data[] = { .zufd_chan_hash = UMC_CHAN_HASH_F_BANK | UMC_CHAN_HASH_F_RM | UMC_CHAN_HASH_F_CS }, { - .zufd_family = ZEN_FAMILY_RENOIR, + .zufd_family = X86_PF_AMD_RENOIR, .zufd_flags = ZEN_UMC_FAM_F_NORM_HASH, .zufd_dram_nrules = 2, .zufd_cs_nrules = 2, @@ -1213,7 +1213,7 @@ static const zen_umc_fam_data_t zen_umc_fam_data[] = { .zufd_chan_hash = UMC_CHAN_HASH_F_BANK | UMC_CHAN_HASH_F_PC | UMC_CHAN_HASH_F_CS }, { - .zufd_family = ZEN_FAMILY_MATISSE, + .zufd_family = X86_PF_AMD_MATISSE, .zufd_flags = ZEN_UMC_FAM_F_NORM_HASH | ZEN_UMC_FAM_F_UMC_HASH, .zufd_dram_nrules = 16, .zufd_cs_nrules = 2, @@ -1221,21 +1221,21 @@ static const zen_umc_fam_data_t zen_umc_fam_data[] = { .zufd_chan_hash = UMC_CHAN_HASH_F_BANK | UMC_CHAN_HASH_F_RM | UMC_CHAN_HASH_F_CS }, { - .zufd_family = ZEN_FAMILY_VAN_GOGH, + .zufd_family = X86_PF_AMD_VAN_GOGH, .zufd_flags = ZEN_UMC_FAM_F_NORM_HASH, .zufd_dram_nrules = 2, .zufd_cs_nrules = 2, .zufd_umc_style = ZEN_UMC_UMC_S_DDR5_APU, .zufd_chan_hash = UMC_CHAN_HASH_F_BANK | UMC_CHAN_HASH_F_CS }, { - .zufd_family = ZEN_FAMILY_MENDOCINO, + .zufd_family = X86_PF_AMD_MENDOCINO, .zufd_flags = ZEN_UMC_FAM_F_NORM_HASH, .zufd_dram_nrules = 2, .zufd_cs_nrules = 2, .zufd_umc_style = ZEN_UMC_UMC_S_DDR5_APU, .zufd_chan_hash = UMC_CHAN_HASH_F_BANK | UMC_CHAN_HASH_F_CS }, { - .zufd_family = ZEN_FAMILY_MILAN, + .zufd_family = X86_PF_AMD_MILAN, .zufd_flags = ZEN_UMC_FAM_F_TARG_REMAP | ZEN_UMC_FAM_F_NP2 | ZEN_UMC_FAM_F_NORM_HASH | ZEN_UMC_FAM_F_UMC_HASH, .zufd_dram_nrules = 16, @@ -1244,7 +1244,7 @@ static const zen_umc_fam_data_t zen_umc_fam_data[] = { .zufd_chan_hash = UMC_CHAN_HASH_F_BANK | UMC_CHAN_HASH_F_RM | UMC_CHAN_HASH_F_CS }, { - .zufd_family = ZEN_FAMILY_GENOA, + .zufd_family = X86_PF_AMD_GENOA, .zufd_flags = ZEN_UMC_FAM_F_TARG_REMAP | ZEN_UMC_FAM_F_UMC_HASH | ZEN_UMC_FAM_F_UMC_EADDR | ZEN_UMC_FAM_F_CS_XOR, @@ -1254,7 +1254,7 @@ static const zen_umc_fam_data_t zen_umc_fam_data[] = { .zufd_chan_hash = UMC_CHAN_HASH_F_BANK | UMC_CHAN_HASH_F_RM | UMC_CHAN_HASH_F_PC | UMC_CHAN_HASH_F_CS }, { - .zufd_family = ZEN_FAMILY_VERMEER, + .zufd_family = X86_PF_AMD_VERMEER, .zufd_flags = ZEN_UMC_FAM_F_NORM_HASH | ZEN_UMC_FAM_F_UMC_HASH, .zufd_dram_nrules = 16, .zufd_cs_nrules = 2, @@ -1262,14 +1262,14 @@ static const zen_umc_fam_data_t zen_umc_fam_data[] = { .zufd_chan_hash = UMC_CHAN_HASH_F_BANK | UMC_CHAN_HASH_F_RM | UMC_CHAN_HASH_F_CS, }, { - .zufd_family = ZEN_FAMILY_REMBRANDT, + .zufd_family = X86_PF_AMD_REMBRANDT, .zufd_flags = ZEN_UMC_FAM_F_NORM_HASH, .zufd_dram_nrules = 2, .zufd_cs_nrules = 2, .zufd_umc_style = ZEN_UMC_UMC_S_DDR5_APU, .zufd_chan_hash = UMC_CHAN_HASH_F_BANK | UMC_CHAN_HASH_F_CS }, { - .zufd_family = ZEN_FAMILY_CEZANNE, + .zufd_family = X86_PF_AMD_CEZANNE, .zufd_flags = ZEN_UMC_FAM_F_NORM_HASH, .zufd_dram_nrules = 2, .zufd_cs_nrules = 2, @@ -1277,7 +1277,7 @@ static const zen_umc_fam_data_t zen_umc_fam_data[] = { .zufd_chan_hash = UMC_CHAN_HASH_F_BANK | UMC_CHAN_HASH_F_PC | UMC_CHAN_HASH_F_CS }, { - .zufd_family = ZEN_FAMILY_RAPHAEL, + .zufd_family = X86_PF_AMD_RAPHAEL, .zufd_flags = ZEN_UMC_FAM_F_TARG_REMAP | ZEN_UMC_FAM_F_CS_XOR, .zufd_dram_nrules = 2, .zufd_cs_nrules = 2, @@ -2998,7 +2998,7 @@ zen_umc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) */ umc = kmem_zalloc(sizeof (zen_umc_t), KM_SLEEP); mutex_init(&umc->umc_nvl_lock, NULL, MUTEX_DRIVER, NULL); - umc->umc_family = amdzen_c_family(); + umc->umc_family = chiprev_family(cpuid_getchiprev(CPU)); umc->umc_ndfs = amdzen_c_df_count(); umc->umc_dip = dip; diff --git a/usr/src/uts/intel/io/amdzen/zen_umc.h b/usr/src/uts/intel/io/amdzen/zen_umc.h index d4f2127d74..7c3cfc5fe8 100644 --- a/usr/src/uts/intel/io/amdzen/zen_umc.h +++ b/usr/src/uts/intel/io/amdzen/zen_umc.h @@ -28,6 +28,7 @@ extern "C" { #include <sys/stdint.h> #include <sys/sunddi.h> #include <sys/nvpair.h> +#include <sys/x86_archext.h> #include <amdzen_client.h> /* @@ -458,7 +459,7 @@ typedef enum zen_umc_fam_flags { * way it works, etc. */ typedef struct zen_umc_fam_data { - zen_family_t zufd_family; + x86_processor_family_t zufd_family; zen_umc_fam_flags_t zufd_flags; uint8_t zufd_dram_nrules; uint8_t zufd_cs_nrules; @@ -475,7 +476,7 @@ typedef struct zen_umc { uint64_t umc_tom; uint64_t umc_tom2; dev_info_t *umc_dip; - zen_family_t umc_family; + x86_processor_family_t umc_family; df_rev_t umc_df_rev; const zen_umc_fam_data_t *umc_fdata; df_fabric_decomp_t umc_decomp; diff --git a/usr/src/uts/intel/io/mc-amd/mcamd_drv.c b/usr/src/uts/intel/io/mc-amd/mcamd_drv.c index 627888e5ab..e30a6f07eb 100644 --- a/usr/src/uts/intel/io/mc-amd/mcamd_drv.c +++ b/usr/src/uts/intel/io/mc-amd/mcamd_drv.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2022 Oxide Computer Co. */ #include <sys/conf.h> @@ -207,7 +208,7 @@ mc_nvl_add_socket(nvlist_t *nvl, mc_t *mc) static uint32_t mc_ecc_enabled(mc_t *mc) { - uint32_t rev = mc->mc_props.mcp_rev; + x86_chiprev_t rev = mc->mc_props.mcp_rev; union mcreg_nbcfg nbcfg; MCREG_VAL32(&nbcfg) = mc->mc_cfgregs.mcr_nbcfg; @@ -220,7 +221,7 @@ mc_ecc_enabled(mc_t *mc) static uint32_t mc_ck_enabled(mc_t *mc) { - uint32_t rev = mc->mc_props.mcp_rev; + x86_chiprev_t rev = mc->mc_props.mcp_rev; union mcreg_nbcfg nbcfg; MCREG_VAL32(&nbcfg) = mc->mc_cfgregs.mcr_nbcfg; @@ -533,7 +534,7 @@ mc_dimmlist_create(mc_t *mc) union mcreg_dramcfg_hi *drcfghip = (union mcreg_dramcfg_hi *)(&mc->mc_cfgregs.mcr_dramcfghi); mc_props_t *mcp = &mc->mc_props; - uint32_t rev = mcp->mcp_rev; + x86_chiprev_t rev = mcp->mcp_rev; mc_cs_t *mccs; int r4 = 0, s4 = 0; @@ -726,7 +727,7 @@ mc_mkprops_addrmap(mc_pcicfg_hdl_t cfghdl, mc_t *mc) static void mc_getmiscctl(mc_t *mc) { - uint32_t rev = mc->mc_props.mcp_rev; + x86_chiprev_t rev = mc->mc_props.mcp_rev; union mcreg_nbcfg nbcfg; union mcreg_sparectl sparectl; @@ -786,7 +787,7 @@ mc_mkprops_dramctl(mc_pcicfg_hdl_t cfghdl, mc_t *mc) mc_cfgregs_t *mcr = &mc->mc_cfgregs; int maskdivisor; int wide = 0; - uint32_t rev = mc->mc_props.mcp_rev; + x86_chiprev_t rev = mc->mc_props.mcp_rev; int i; mcamd_hdl_t hdl; @@ -1401,7 +1402,7 @@ mc_scrubber_enable(mc_t *mc) { mc_props_t *mcp = &mc->mc_props; chipid_t chipid = (chipid_t)mcp->mcp_num; - uint32_t rev = (uint32_t)mcp->mcp_rev; + x86_chiprev_t rev = (x86_chiprev_t)mcp->mcp_rev; mc_cfgregs_t *mcr = &mc->mc_cfgregs; union mcreg_scrubctl scrubctl; union mcreg_dramscrublo dalo; @@ -1495,7 +1496,7 @@ mc_scrubber_enable(mc_t *mc) */ if (mc_scrub_rate_dram != AMD_NB_SCRUBCTL_RATE_NONE && mcp->mcp_ilen != 0 && - !X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_E)) { + !chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_F_REV_E)) { cmn_err(CE_CONT, "?Opteron DRAM scrubber disabled on revision " "%s chip %d because DRAM memory is node-interleaved", mc->mc_revname, chipid); diff --git a/usr/src/uts/intel/os/cpuid.c b/usr/src/uts/intel/os/cpuid.c index ad54edc4b5..a723ae904e 100644 --- a/usr/src/uts/intel/os/cpuid.c +++ b/usr/src/uts/intel/os/cpuid.c @@ -158,7 +158,16 @@ * * On the other hand, each major AMD architecture generally has its own family. * For example, the K8 is family 0x10, Bulldozer 0x15, and Zen 0x17. Within it - * the model number is used to help identify specific processors. + * the model number is used to help identify specific processors. As AMD's + * product lines have expanded, they have started putting a mixed bag of + * processors into the same family, with each processor under a single + * identifying banner (e.g., Milan, Cezanne) using a range of model numbers. We + * refer to each such collection as a processor family, distinct from cpuid + * family. Importantly, each processor family has a BIOS and Kernel Developer's + * Guide (BKDG, older parts) or Processor Programming Reference (PPR) that + * defines the processor family's non-architectural features. In general, we'll + * use "family" here to mean the family number reported by the cpuid instruction + * and distinguish the processor family from it where appropriate. * * The stepping is used to refer to a revision of a specific microprocessor. The * term comes from equipment used to produce masks that are used to create @@ -195,6 +204,30 @@ * programmatic consumption. That is what the family, model, and stepping are * for. * + * We use the x86_chiprev_t to encode a combination of vendor, processor family, + * and stepping(s) that refer to a single or very closely related set of silicon + * implementations; while there are sometimes more specific ways to learn of the + * presence or absence of a particular erratum or workaround, one may generally + * assume that all processors of the same chiprev have the same errata and we + * have chosen to represent them this way precisely because that is how AMD + * groups them in their revision guides (errata documentation). The processor + * family (x86_processor_family_t) may be extracted from the chiprev if that + * level of detail is not needed. Processor families are considered unordered + * but revisions within a family may be compared for either an exact match or at + * least as recent as a reference revision. See the chiprev_xxx() functions + * below. + * + * Similarly, each processor family implements a particular microarchitecture, + * which itself may have multiple revisions. In general, non-architectural + * features are specific to a processor family, but some may exist across + * families containing cores that implement the same microarchitectural revision + * (and, such cores share common bugs, too). We provide utility routines + * analogous to those for extracting and comparing chiprevs for + * microarchitectures as well; see the uarch_xxx() functions. + * + * Both chiprevs and uarchrevs are defined in x86_archext.h and both are at + * present used and available only for AMD and AMD-like processors. + * * ------------ * CPUID Passes * ------------ @@ -227,7 +260,13 @@ * the cpuid instruction will report during subsequent * passes if needed, and so that any intervening * machine-dependent code that needs basic identity will - * have it available. + * have it available. This includes synthesised + * identifiers such as chiprev and uarchrev as well as the + * values obtained directly from cpuid. Prior to executing + * this pass, machine-depedent boot code is responsible for + * ensuring that the PCI configuration space access + * functions have been set up and, if necessary, that + * determine_platform() has been called. * * BASIC This is the primary pass and is responsible for doing a * large number of different things: @@ -1781,9 +1820,10 @@ struct cpuid_info { /* * Synthesized information, where known. */ - uint32_t cpi_chiprev; /* See X86_CHIPREV_* in x86_archext.h */ + x86_chiprev_t cpi_chiprev; /* See X86_CHIPREV_* in x86_archext.h */ const char *cpi_chiprevstr; /* May be NULL if chiprev unknown */ uint32_t cpi_socket; /* Chip package/socket type */ + x86_uarchrev_t cpi_uarchrev; /* Microarchitecture and revision */ struct mwait_info cpi_mwait; /* fn 5: monitor/mwait info */ uint32_t cpi_apicid; @@ -1917,8 +1957,9 @@ static struct cpuid_info cpuid_info0; */ extern uint32_t _cpuid_skt(uint_t, uint_t, uint_t, uint_t); extern const char *_cpuid_sktstr(uint_t, uint_t, uint_t, uint_t); -extern uint32_t _cpuid_chiprev(uint_t, uint_t, uint_t, uint_t); +extern x86_chiprev_t _cpuid_chiprev(uint_t, uint_t, uint_t, uint_t); extern const char *_cpuid_chiprevstr(uint_t, uint_t, uint_t, uint_t); +extern x86_uarchrev_t _cpuid_uarchrev(uint_t, uint_t, uint_t, uint_t); extern uint_t _cpuid_vendorstr_to_vendorcode(char *); /* @@ -3422,7 +3463,9 @@ cpuid_pass_ident(cpu_t *cpu, void *arg __unused) * config space access has been set up; at present there is no reliable * way to determine the latter. */ +#if !defined(__xpv) ASSERT3S(platform_type, !=, -1); +#endif /* !__xpv */ cpi = cpu->cpu_m.mcpu_cpi; ASSERT(cpi != NULL); @@ -3498,6 +3541,8 @@ cpuid_pass_ident(cpu_t *cpu, void *arg __unused) cpi->cpi_family, cpi->cpi_model, cpi->cpi_step); cpi->cpi_socket = _cpuid_skt(cpi->cpi_vendor, cpi->cpi_family, cpi->cpi_model, cpi->cpi_step); + cpi->cpi_uarchrev = _cpuid_uarchrev(cpi->cpi_vendor, cpi->cpi_family, + cpi->cpi_model, cpi->cpi_step); } static void @@ -5936,6 +5981,12 @@ cpuid_getsocketstr(cpu_t *cpu) return (socketstr); } +x86_uarchrev_t +cpuid_getuarchrev(cpu_t *cpu) +{ + return (cpu->cpu_m.mcpu_cpi->cpi_uarchrev); +} + int cpuid_get_chipid(cpu_t *cpu) { @@ -7864,3 +7915,77 @@ cpuid_execpass(cpu_t *cp, cpuid_pass_t pass, void *arg) panic("unable to execute invalid cpuid pass %d on cpu%d\n", pass, cp->cpu_id); } + +/* + * Extract the processor family from a chiprev. Processor families are not the + * same as cpuid families; see comments above and in x86_archext.h. + */ +x86_processor_family_t +chiprev_family(const x86_chiprev_t cr) +{ + return ((x86_processor_family_t)_X86_CHIPREV_FAMILY(cr)); +} + +/* + * A chiprev matches its template if the vendor and family are identical and the + * revision of the chiprev matches one of the bits set in the template. Callers + * may bitwise-OR together chiprevs of the same vendor and family to form the + * template, or use the _ANY variant. It is not possible to match chiprevs of + * multiple vendors or processor families with a single call. Note that this + * function operates on processor families, not cpuid families. + */ +boolean_t +chiprev_matches(const x86_chiprev_t cr, const x86_chiprev_t template) +{ + return (_X86_CHIPREV_VENDOR(cr) == _X86_CHIPREV_VENDOR(template) && + _X86_CHIPREV_FAMILY(cr) == _X86_CHIPREV_FAMILY(template) && + (_X86_CHIPREV_REV(cr) & _X86_CHIPREV_REV(template)) != 0); +} + +/* + * A chiprev is at least min if the vendor and family are identical and the + * revision of the chiprev is at least as recent as that of min. Processor + * families are considered unordered and cannot be compared using this function. + * Note that this function operates on processor families, not cpuid families. + * Use of the _ANY chiprev variant with this function is not useful; it will + * always return B_FALSE if the _ANY variant is supplied as the minimum + * revision. To determine only whether a chiprev is of a given processor + * family, test the return value of chiprev_family() instead. + */ +boolean_t +chiprev_at_least(const x86_chiprev_t cr, const x86_chiprev_t min) +{ + return (_X86_CHIPREV_VENDOR(cr) == _X86_CHIPREV_VENDOR(min) && + _X86_CHIPREV_FAMILY(cr) == _X86_CHIPREV_FAMILY(min) && + _X86_CHIPREV_REV(cr) >= _X86_CHIPREV_REV(min)); +} + +/* + * The uarch functions operate in a manner similar to the chiprev functions + * above. While it is tempting to allow these to operate on microarchitectures + * produced by a specific vendor in an ordered fashion (e.g., ZEN3 is "newer" + * than ZEN2), we elect not to do so because a manufacturer may supply + * processors of multiple different microarchitecture families each of which may + * be internally ordered but unordered with respect to those of other families. + */ +x86_uarch_t +uarchrev_uarch(const x86_uarchrev_t ur) +{ + return ((x86_uarch_t)_X86_UARCHREV_UARCH(ur)); +} + +boolean_t +uarchrev_matches(const x86_uarchrev_t ur, const x86_uarchrev_t template) +{ + return (_X86_UARCHREV_VENDOR(ur) == _X86_UARCHREV_VENDOR(template) && + _X86_UARCHREV_UARCH(ur) == _X86_UARCHREV_UARCH(template) && + (_X86_UARCHREV_REV(ur) & _X86_UARCHREV_REV(template)) != 0); +} + +boolean_t +uarchrev_at_least(const x86_uarchrev_t ur, const x86_uarchrev_t min) +{ + return (_X86_UARCHREV_VENDOR(ur) == _X86_UARCHREV_VENDOR(min) && + _X86_UARCHREV_UARCH(ur) == _X86_UARCHREV_UARCH(min) && + _X86_UARCHREV_REV(ur) >= _X86_UARCHREV_REV(min)); +} diff --git a/usr/src/uts/intel/os/cpuid_subr.c b/usr/src/uts/intel/os/cpuid_subr.c index 8f8aa89062..325ec7e56b 100644 --- a/usr/src/uts/intel/os/cpuid_subr.c +++ b/usr/src/uts/intel/os/cpuid_subr.c @@ -69,33 +69,11 @@ /* * AMD socket types. - * First index : - * 0 for family 0xf, revs B thru E - * 1 for family 0xf, revs F and G - * 2 for family 0x10 - * 3 for family 0x11 - * 4 for family 0x12 - * 5 for family 0x14 - * 6 for family 0x15, models 00 - 0f - * 7 for family 0x15, models 10 - 1f - * 8 for family 0x15, models 30 - 3f - * 9 for family 0x15, models 60 - 6f - * 10 for family 0x15, models 70 - 7f - * 11 for family 0x16, models 00 - 0f - * 12 for family 0x16, models 30 - 3f - * 13 for family 0x17, models 00 - 0f - * 14 for family 0x17, models 10 - 2f - * 15 for family 0x17, models 30 - 3f - * 16 for family 0x17, models 60 - 6f - * 17 for family 0x17, models 70 - 7f - * 18 for family 0x18, models 00 - 0f - * 19 for family 0x19, models 00 - 0f - * 20 for family 0x19, models 20 - 2f - * 21 for family 0x19, models 50 - 5f - * Second index by (model & 0x3) for family 0fh, - * CPUID pkg bits (Fn8000_0001_EBX[31:28]) for later families. + * 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[22][8] = { +static uint32_t amd_skts[][8] = { /* * Family 0xf revisions B through E */ @@ -425,13 +403,89 @@ static uint32_t amd_skts[22][8] = { 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_NUM_SOCKETS + 1] = { +static struct amd_sktmap_s amd_sktmap_strs[] = { { X86_SOCKET_754, "754" }, { X86_SOCKET_939, "939" }, { X86_SOCKET_940, "940" }, @@ -446,6 +500,7 @@ static struct amd_sktmap_s amd_sktmap_strs[X86_NUM_SOCKETS + 1] = { { 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" }, @@ -469,43 +524,37 @@ static struct amd_sktmap_s amd_sktmap_strs[X86_NUM_SOCKETS + 1] = { { X86_SOCKET_SL1, "SL1" }, { X86_SOCKET_SL1R2, "SL1R2" }, { X86_SOCKET_DM1, "DM1" }, - { X86_SOCKET_UNKNOWN, "Unknown" } + { 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! */ }; -static const struct amd_skt_mapent { - uint_t sm_family; - uint_t sm_modello; - uint_t sm_modelhi; - uint_t sm_sktidx; -} amd_sktmap[] = { - { 0x10, 0x00, 0xff, A_SKTS_2 }, - { 0x11, 0x00, 0xff, A_SKTS_3 }, - { 0x12, 0x00, 0xff, A_SKTS_4 }, - { 0x14, 0x00, 0x0f, A_SKTS_5 }, - { 0x15, 0x00, 0x0f, A_SKTS_6 }, - { 0x15, 0x10, 0x1f, A_SKTS_7 }, - { 0x15, 0x30, 0x3f, A_SKTS_8 }, - { 0x15, 0x60, 0x6f, A_SKTS_9 }, - { 0x15, 0x70, 0x7f, A_SKTS_10 }, - { 0x16, 0x00, 0x0f, A_SKTS_11 }, - { 0x16, 0x30, 0x3f, A_SKTS_12 }, - { 0x17, 0x00, 0x0f, A_SKTS_13 }, - { 0x17, 0x10, 0x2f, A_SKTS_14 }, - { 0x17, 0x30, 0x3f, A_SKTS_15 }, - { 0x17, 0x60, 0x6f, A_SKTS_16 }, - { 0x17, 0x70, 0x7f, A_SKTS_17 }, - { 0x18, 0x00, 0x0f, A_SKTS_18 }, - { 0x19, 0x00, 0x0f, A_SKTS_19 }, - { 0x19, 0x20, 0x2f, A_SKTS_20 }, - { 0x19, 0x50, 0x5f, A_SKTS_21 } -}; +/* 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 0xf and AMD Family 0x10 model/stepping - * combination to chip "revision" and socket type. + * 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. + * 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; @@ -513,8 +562,9 @@ static const struct amd_rev_mapent { uint_t rm_modelhi; uint_t rm_steplo; uint_t rm_stephi; - uint32_t rm_chiprev; + x86_chiprev_t rm_chiprev; const char *rm_chiprevstr; + x86_uarchrev_t rm_uarchrev; uint_t rm_sktidx; } amd_revmap[] = { /* @@ -524,34 +574,42 @@ static const struct amd_rev_mapent { /* * Rev B includes model 0x4 stepping 0 and model 0x5 stepping 0 and 1. */ - { 0xf, 0x04, 0x04, 0x0, 0x0, X86_CHIPREV_AMD_F_REV_B, "B", A_SKTS_0 }, - { 0xf, 0x05, 0x05, 0x0, 0x1, X86_CHIPREV_AMD_F_REV_B, "B", A_SKTS_0 }, + { 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_F_REV_C0, "C0", A_SKTS_0 }, + { 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_F_REV_CG, "CG", A_SKTS_0 }, + { 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_F_REV_D, "D", A_SKTS_0 }, + { 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_F_REV_E, "E", A_SKTS_0 }, + { 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_F_REV_F, "F", A_SKTS_1 }, + { 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_F_REV_G, "G", A_SKTS_1 }, + { 0xf, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_LEGACY_F_REV_G, "G", + X86_UARCHREV_AMD_LEGACY, A_SKTS_1 }, /* * =============== AuthenticAMD Family 0x10 =============== @@ -561,133 +619,260 @@ static const struct amd_rev_mapent { * 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_10_REV_A, "A", A_SKTS_2 }, + { 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_10_REV_B, "B", A_SKTS_2 }, + { 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_10_REV_C2, "C2", A_SKTS_2 }, + { 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_10_REV_C3, "C3", A_SKTS_2 }, + { 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_10_REV_D0, "D0", A_SKTS_2 }, + { 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_10_REV_D1, "D1", A_SKTS_2 }, + { 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_10_REV_E, "E", A_SKTS_2 }, + { 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_11_REV_B, "B", A_SKTS_3 }, + { 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_12_REV_B, "B", A_SKTS_4 }, + { 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_14_REV_B, "B", A_SKTS_5 }, - { 0x14, 0x02, 0x02, 0x0, 0xf, X86_CHIPREV_AMD_14_REV_C, "C", A_SKTS_5 }, + { 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_15OR_REV_B2, "OR-B2", - A_SKTS_6 }, - { 0x15, 0x02, 0x02, 0x0, 0x0, X86_CHIPREV_AMD_150R_REV_C0, "OR-C0", - A_SKTS_6 }, - { 0x15, 0x10, 0x10, 0x1, 0x1, X86_CHIPREV_AMD_15TN_REV_A1, "TN-A1", - A_SKTS_7 }, - { 0x15, 0x30, 0x30, 0x1, 0x1, X86_CHIPREV_AMD_15KV_REV_A1, "KV-A1", - A_SKTS_8 }, + { 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 }, /* - * There is no Family 15 Models 60-6f revision guide available, so at - * least get the socket information. + * 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, 0x60, 0x6f, 0x0, 0xf, X86_CHIPREV_AMD_15F60, "??", - A_SKTS_9 }, - { 0x15, 0x70, 0x70, 0x0, 0x0, X86_CHIPREV_AMD_15ST_REV_A0, "ST-A0", - A_SKTS_10 }, + { 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_16_KB_A1, "KB-A1", - A_SKTS_11 }, - { 0x16, 0x30, 0x30, 0x1, 0x1, X86_CHIPREV_AMD_16_ML_A1, "ML-A1", - A_SKTS_12 }, + { 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 =============== */ - { 0x17, 0x01, 0x01, 0x1, 0x1, X86_CHIPREV_AMD_17_ZP_B1, "ZP-B1", - A_SKTS_13 }, - { 0x17, 0x01, 0x01, 0x2, 0x2, X86_CHIPREV_AMD_17_ZP_B2, "ZP-B2", - A_SKTS_13 }, - { 0x17, 0x01, 0x01, 0x1, 0x1, X86_CHIPREV_AMD_17_PiR_B2, "PiR-B2", - A_SKTS_13 }, - - { 0x17, 0x11, 0x11, 0x0, 0x0, X86_CHIPREV_AMD_17_RV_B0, "RV-B0", - A_SKTS_14 }, - { 0x17, 0x11, 0x11, 0x1, 0x1, X86_CHIPREV_AMD_17_RV_B1, "RV-B1", - A_SKTS_14 }, - { 0x17, 0x18, 0x18, 0x1, 0x1, X86_CHIPREV_AMD_17_PCO_B1, "PCO-B1", - A_SKTS_14 }, - - { 0x17, 0x30, 0x30, 0x0, 0x0, X86_CHIPREV_AMD_17_SSP_A0, "SSP-A0", - A_SKTS_15 }, - { 0x17, 0x31, 0x31, 0x0, 0x0, X86_CHIPREV_AMD_17_SSP_B0, "SSP-B0", - A_SKTS_15 }, - - { 0x17, 0x71, 0x71, 0x0, 0x0, X86_CHIPREV_AMD_17_MTS_B0, "MTS-B0", - A_SKTS_17 }, + /* 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_18_DN_A1, "DN_A1", - A_SKTS_18 }, + { 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 =============== */ - { 0x19, 0x00, 0x00, 0x0, 0x0, X86_CHIPREV_AMD_19_GN_A0, "GN-A0", - A_SKTS_19 }, - { 0x19, 0x01, 0x01, 0x0, 0x0, X86_CHIPREV_AMD_19_GN_B0, "GN-B0", - A_SKTS_19 }, - { 0x19, 0x01, 0x01, 0x1, 0x1, X86_CHIPREV_AMD_19_GN_B1, "GN-B1", - A_SKTS_19 }, - - { 0x19, 0x21, 0x21, 0x0, 0x0, X86_CHIPREV_AMD_19_VMR_B0, "VMR-B0", - A_SKTS_20 }, - { 0x19, 0x21, 0x21, 0x2, 0x2, X86_CHIPREV_AMD_19_VMR_B1, "VMR-B1", - A_SKTS_20 }, + /* 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 } }; /* @@ -726,41 +911,9 @@ synth_amd_skt_cpuid(uint_t family, uint_t sktid) } static void -synth_amd_skt(uint_t family, uint_t model, uint32_t *skt_p) -{ - int platform; - const struct amd_skt_mapent *skt; - uint_t i; - - if (skt_p == NULL || family < 0xf) - return; - -#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; - } - - for (i = 0, skt = amd_sktmap; i < ARRAY_SIZE(amd_sktmap); - i++, skt++) { - if (family == skt->sm_family && - model >= skt->sm_modello && model <= skt->sm_modelhi) { - *skt_p = synth_amd_skt_cpuid(family, skt->sm_sktidx); - } - } -} - -static void synth_amd_info(uint_t family, uint_t model, uint_t step, - uint32_t *skt_p, uint32_t *chiprev_p, const char **chiprevstr_p) + 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; @@ -778,16 +931,15 @@ synth_amd_info(uint_t family, uint_t model, uint_t step, } } - if (!found) { - synth_amd_skt(family, model, skt_p); - return; + 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 (chiprev_p != NULL) - *chiprev_p = rmp->rm_chiprev; - if (chiprevstr_p != NULL) - *chiprevstr_p = rmp->rm_chiprevstr; - if (skt_p != NULL) { int platform; @@ -802,7 +954,13 @@ synth_amd_info(uint_t family, uint_t model, uint_t step, if ((platform & HW_VIRTUAL) != 0) { *skt_p = X86_SOCKET_UNKNOWN; - } else if (family == 0xf) { + 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); @@ -818,7 +976,7 @@ _cpuid_skt(uint_t vendor, uint_t family, uint_t model, uint_t step) switch (vendor) { case X86_VENDOR_AMD: case X86_VENDOR_HYGON: - synth_amd_info(family, model, step, &skt, NULL, NULL); + synth_amd_info(family, model, step, &skt, NULL, NULL, NULL); break; default: @@ -839,7 +997,7 @@ _cpuid_sktstr(uint_t vendor, uint_t family, uint_t model, uint_t step) switch (vendor) { case X86_VENDOR_AMD: case X86_VENDOR_HYGON: - synth_amd_info(family, model, step, &skt, NULL, NULL); + synth_amd_info(family, model, step, &skt, NULL, NULL, NULL); sktmapp = amd_sktmap_strs; while (sktmapp->skt_code != X86_SOCKET_UNKNOWN) { @@ -858,15 +1016,15 @@ _cpuid_sktstr(uint_t vendor, uint_t family, uint_t model, uint_t step) return (sktstr); } -uint32_t +x86_chiprev_t _cpuid_chiprev(uint_t vendor, uint_t family, uint_t model, uint_t step) { - uint32_t chiprev = X86_CHIPREV_UNKNOWN; + 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); + synth_amd_info(family, model, step, NULL, &chiprev, NULL, NULL); break; default: @@ -877,6 +1035,26 @@ _cpuid_chiprev(uint_t vendor, uint_t family, uint_t model, uint_t step) 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) { @@ -885,7 +1063,7 @@ _cpuid_chiprevstr(uint_t vendor, uint_t family, uint_t model, uint_t step) switch (vendor) { case X86_VENDOR_AMD: case X86_VENDOR_HYGON: - synth_amd_info(family, model, step, NULL, NULL, &revstr); + synth_amd_info(family, model, step, NULL, NULL, &revstr, NULL); break; default: diff --git a/usr/src/uts/intel/pcbe/opteron_pcbe.c b/usr/src/uts/intel/pcbe/opteron_pcbe.c index 2cae323ee5..ac70402460 100644 --- a/usr/src/uts/intel/pcbe/opteron_pcbe.c +++ b/usr/src/uts/intel/pcbe/opteron_pcbe.c @@ -66,7 +66,7 @@ /* * Portions Copyright 2009 Advanced Micro Devices, Inc. * Copyright 2019 Joyent, Inc. - * Copyright 2021 Oxide Computer Company + * Copyright 2022 Oxide Computer Company */ /* @@ -602,11 +602,11 @@ opt_pcbe_init(void) */ if (amd_family == 0xf) { - uint32_t rev; + x86_chiprev_t rev; rev = cpuid_getchiprev(CPU); - if (X86_CHIPREV_ATLEAST(rev, X86_CHIPREV_AMD_F_REV_F)) + if (chiprev_at_least(rev, X86_CHIPREV_AMD_LEGACY_F_REV_F)) amd_pcbe_cpuref = amd_fam_f_NPT_bkdg; else amd_pcbe_cpuref = amd_fam_f_rev_ae_bkdg; diff --git a/usr/src/uts/intel/sys/cpu_module.h b/usr/src/uts/intel/sys/cpu_module.h index ad5308d28a..d10606d96e 100644 --- a/usr/src/uts/intel/sys/cpu_module.h +++ b/usr/src/uts/intel/sys/cpu_module.h @@ -23,6 +23,7 @@ * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * Copyright 2019 Joyent, Inc. + * Copyright 2022 Oxide Computer Co. */ #ifndef _SYS_CPU_MODULE_H @@ -33,6 +34,7 @@ #include <sys/nvpair.h> #include <sys/mc.h> #include <sys/sunddi.h> +#include <sys/x86_archext.h> #ifdef __cplusplus extern "C" { @@ -157,7 +159,7 @@ extern uint_t cmi_hdl_strandid(cmi_hdl_t); extern uint_t cmi_hdl_strand_apicid(cmi_hdl_t); extern uint_t cmi_hdl_procnodes_per_pkg(cmi_hdl_t); extern boolean_t cmi_hdl_is_cmt(cmi_hdl_t); -extern uint32_t cmi_hdl_chiprev(cmi_hdl_t); +extern x86_chiprev_t cmi_hdl_chiprev(cmi_hdl_t); extern const char *cmi_hdl_chiprevstr(cmi_hdl_t); extern uint32_t cmi_hdl_getsockettype(cmi_hdl_t); extern const char *cmi_hdl_getsocketstr(cmi_hdl_t); diff --git a/usr/src/uts/intel/sys/mc_amd.h b/usr/src/uts/intel/sys/mc_amd.h index 91b4f9c4cb..e95d06a169 100644 --- a/usr/src/uts/intel/sys/mc_amd.h +++ b/usr/src/uts/intel/sys/mc_amd.h @@ -21,6 +21,9 @@ * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright 2022 Oxide Computer Co. + */ #ifndef _MC_AMD_H #define _MC_AMD_H @@ -242,15 +245,16 @@ enum mc_funcnum { #define MC_REV_UNKNOWN X86_CHIPREV_UNKNOWN -#define MC_F_REV_B X86_CHIPREV_AMD_F_REV_B -#define MC_F_REV_C (X86_CHIPREV_AMD_F_REV_C0 | X86_CHIPREV_AMD_F_REV_CG) -#define MC_F_REV_D X86_CHIPREV_AMD_F_REV_D -#define MC_F_REV_E X86_CHIPREV_AMD_F_REV_E -#define MC_F_REV_F X86_CHIPREV_AMD_F_REV_F -#define MC_F_REV_G X86_CHIPREV_AMD_F_REV_G +#define MC_F_REV_B X86_CHIPREV_AMD_LEGACY_F_REV_B +#define MC_F_REV_C (X86_CHIPREV_AMD_LEGACY_F_REV_C0 | \ + X86_CHIPREV_AMD_LEGACY_F_REV_CG) +#define MC_F_REV_D X86_CHIPREV_AMD_LEGACY_F_REV_D +#define MC_F_REV_E X86_CHIPREV_AMD_LEGACY_F_REV_E +#define MC_F_REV_F X86_CHIPREV_AMD_LEGACY_F_REV_F +#define MC_F_REV_G X86_CHIPREV_AMD_LEGACY_F_REV_G -#define MC_10_REV_A X86_CHIPREV_AMD_10_REV_A -#define MC_10_REV_B X86_CHIPREV_AMD_10_REV_B +#define MC_10_REV_A X86_CHIPREV_AMD_LEGACY_10_REV_A +#define MC_10_REV_B X86_CHIPREV_AMD_LEGACY_10_REV_B /* * The most common groupings for memory controller features. @@ -265,12 +269,12 @@ enum mc_funcnum { /* * Is 'rev' included in the 'revmask' bitmask? */ -#define MC_REV_MATCH(rev, revmask) X86_CHIPREV_MATCH(rev, revmask) +#define MC_REV_MATCH(rev, revmask) chiprev_matches(rev, revmask) /* * Is 'rev' at least revision 'revmin' or greater */ -#define MC_REV_ATLEAST(rev, minrev) X86_CHIPREV_ATLEAST(rev, minrev) +#define MC_REV_ATLEAST(rev, minrev) chiprev_at_least(rev, minrev) #define _MCREG_FIELD(up, revsuffix, field) ((up)->_fmt_##revsuffix.field) diff --git a/usr/src/uts/intel/sys/x86_archext.h b/usr/src/uts/intel/sys/x86_archext.h index b936012dac..8202ab3fd0 100644 --- a/usr/src/uts/intel/sys/x86_archext.h +++ b/usr/src/uts/intel/sys/x86_archext.h @@ -39,6 +39,7 @@ #define _SYS_X86_ARCHEXT_H #if !defined(_ASM) +#include <sys/bitext.h> #include <sys/regset.h> #include <sys/processor.h> #include <vm/seg_enum.h> @@ -837,179 +838,335 @@ extern "C" { #define X86_VENDOR_STRLEN 13 /* - * Some vendor/family/model/stepping ranges are commonly grouped under - * a single identifying banner by the vendor. The following encode - * that "revision" in a uint32_t with the 8 most significant bits - * identifying the vendor with X86_VENDOR_*, the next 8 identifying the - * family, and the remaining 16 typically forming a bitmask of revisions - * within that family with more significant bits indicating "later" revisions. + * For lookups and matching functions only; not an actual vendor. + */ +#define _X86_VENDOR_MATCH_ALL 0xff + +/* + * See the big theory statement at the top of cpuid.c for information about how + * processor families and microarchitecture families relate to cpuid families, + * models, and steppings. */ -#define _X86_CHIPREV_VENDOR_MASK 0xff000000u #define _X86_CHIPREV_VENDOR_SHIFT 24 -#define _X86_CHIPREV_FAMILY_MASK 0x00ff0000u #define _X86_CHIPREV_FAMILY_SHIFT 16 -#define _X86_CHIPREV_REV_MASK 0x0000ffffu -#define _X86_CHIPREV_VENDOR(x) \ - (((x) & _X86_CHIPREV_VENDOR_MASK) >> _X86_CHIPREV_VENDOR_SHIFT) -#define _X86_CHIPREV_FAMILY(x) \ - (((x) & _X86_CHIPREV_FAMILY_MASK) >> _X86_CHIPREV_FAMILY_SHIFT) -#define _X86_CHIPREV_REV(x) \ - ((x) & _X86_CHIPREV_REV_MASK) +#define _X86_CHIPREV_VENDOR(x) \ + bitx32((uint32_t)(x), 31, _X86_CHIPREV_VENDOR_SHIFT) -/* True if x matches in vendor and family and if x matches the given rev mask */ -#define X86_CHIPREV_MATCH(x, mask) \ - (_X86_CHIPREV_VENDOR(x) == _X86_CHIPREV_VENDOR(mask) && \ - _X86_CHIPREV_FAMILY(x) == _X86_CHIPREV_FAMILY(mask) && \ - ((_X86_CHIPREV_REV(x) & _X86_CHIPREV_REV(mask)) != 0)) +#define _X86_CHIPREV_FAMILY(x) \ + bitx32((uint32_t)(x), 23, _X86_CHIPREV_FAMILY_SHIFT) -/* True if x matches in vendor and family, and rev is at least minx */ -#define X86_CHIPREV_ATLEAST(x, minx) \ - (_X86_CHIPREV_VENDOR(x) == _X86_CHIPREV_VENDOR(minx) && \ - _X86_CHIPREV_FAMILY(x) == _X86_CHIPREV_FAMILY(minx) && \ - _X86_CHIPREV_REV(x) >= _X86_CHIPREV_REV(minx)) +#define _X86_CHIPREV_REV(x) \ + bitx32((uint32_t)(x), 15, 0) #define _X86_CHIPREV_MKREV(vendor, family, rev) \ ((uint32_t)(vendor) << _X86_CHIPREV_VENDOR_SHIFT | \ - (family) << _X86_CHIPREV_FAMILY_SHIFT | (rev)) - -/* True if x matches in vendor, and family is at least minx */ -#define X86_CHIPFAM_ATLEAST(x, minx) \ - (_X86_CHIPREV_VENDOR(x) == _X86_CHIPREV_VENDOR(minx) && \ - _X86_CHIPREV_FAMILY(x) >= _X86_CHIPREV_FAMILY(minx)) - -/* Revision default */ -#define X86_CHIPREV_UNKNOWN 0x0 - -/* - * Definitions for AMD Family 0xf. Minor revisions C0 and CG are - * sufficiently different that we will distinguish them; in all other - * case we will identify the major revision. - */ -#define X86_CHIPREV_AMD_F_REV_B _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0001) -#define X86_CHIPREV_AMD_F_REV_C0 _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0002) -#define X86_CHIPREV_AMD_F_REV_CG _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0004) -#define X86_CHIPREV_AMD_F_REV_D _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0008) -#define X86_CHIPREV_AMD_F_REV_E _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0010) -#define X86_CHIPREV_AMD_F_REV_F _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0020) -#define X86_CHIPREV_AMD_F_REV_G _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0xf, 0x0040) - -/* - * Definitions for AMD Family 0x10. Rev A was Engineering Samples only. - */ -#define X86_CHIPREV_AMD_10_REV_A \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x10, 0x0001) -#define X86_CHIPREV_AMD_10_REV_B \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x10, 0x0002) -#define X86_CHIPREV_AMD_10_REV_C2 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x10, 0x0004) -#define X86_CHIPREV_AMD_10_REV_C3 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x10, 0x0008) -#define X86_CHIPREV_AMD_10_REV_D0 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x10, 0x0010) -#define X86_CHIPREV_AMD_10_REV_D1 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x10, 0x0020) -#define X86_CHIPREV_AMD_10_REV_E \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x10, 0x0040) - -/* - * Definitions for AMD Family 0x11. - */ -#define X86_CHIPREV_AMD_11_REV_B \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x11, 0x0002) + (uint32_t)(family) << _X86_CHIPREV_FAMILY_SHIFT | (uint32_t)(rev)) /* - * Definitions for AMD Family 0x12. + * The legacy families here are a little bit unfortunate. Part of this is that + * the way AMD used the cpuid family/model/stepping changed somewhat over time, + * but the more immediate reason it's this way is more that the way we use + * chiprev/processor family changed with it. The ancient amd_opteron and mc-amd + * drivers used the chiprevs that were based on cpuid family, mainly 0xf and + * 0x10. amdzen_umc wants the processor family, in part because AMD's + * overloading of the cpuid family has made it effectively useless for + * discerning anything about the processor. That also tied into the way + * amd_revmap was previously organised in cpuid_subr.c: up to family 0x14 + * everything was just "rev A", "rev B", etc.; afterward we started using the + * new shorthand, again tied to how AMD was presenting this information. + * Because there are other consumers of the processor family, it no longer made + * sense for amdzen to derive the processor family from the cpuid family/model + * given that we have this collection of definitions already and code in + * cpuid_subr.c to make use of them. The result is this unified approach that + * tries to keep old consumers happy while allowing new ones to get the degree + * of detail they need and expect. That required bending things a bit to make + * them fit, though critically as long as AMD keep on their current path and all + * new consumers look like the ones we are adding these days, we will be able to + * continue making new additions that will match all the recent ones and the way + * AMD are currently using families and models. There is absolutely no reason + * we couldn't go back and dig through all the legacy parts and break them down + * the same way, then change the old MC and CPU drivers to match, but I didn't + * feel like doing a lot of work for processors that it's unlikely anyone is + * still using and even more unlikely anyone will introduce new code to support. + * My compromise was to flesh things out starting where we already had more + * detail even if nothing was consuming it programmatically: at 0x15. Before + * that, processor family and cpuid family were effectively the same, because + * that's what those old consumers expect. */ -#define X86_CHIPREV_AMD_12_REV_B \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x12, 0x0002) -/* - * Definitions for AMD Family 0x14. - */ -#define X86_CHIPREV_AMD_14_REV_B \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x14, 0x0002) -#define X86_CHIPREV_AMD_14_REV_C \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x14, 0x0004) +#ifndef _ASM +typedef enum x86_processor_family { + X86_PF_UNKNOWN, + X86_PF_AMD_LEGACY_F = 0xf, + X86_PF_AMD_LEGACY_10 = 0x10, + X86_PF_AMD_LEGACY_11 = 0x11, + X86_PF_AMD_LEGACY_12 = 0x12, + X86_PF_AMD_LEGACY_14 = 0x14, + X86_PF_AMD_OROCHI, + X86_PF_AMD_TRINITY, + X86_PF_AMD_KAVERI, + X86_PF_AMD_CARRIZO, + X86_PF_AMD_STONEY_RIDGE, + X86_PF_AMD_KABINI, + X86_PF_AMD_MULLINS, + X86_PF_AMD_NAPLES, + X86_PF_AMD_PINNACLE_RIDGE, + X86_PF_AMD_RAVEN_RIDGE, + X86_PF_AMD_PICASSO, + X86_PF_AMD_DALI, + X86_PF_AMD_ROME, + X86_PF_AMD_RENOIR, + X86_PF_AMD_MATISSE, + X86_PF_AMD_VAN_GOGH, + X86_PF_AMD_MENDOCINO, + X86_PF_HYGON_DHYANA, + X86_PF_AMD_MILAN, + X86_PF_AMD_GENOA, + X86_PF_AMD_VERMEER, + X86_PF_AMD_REMBRANDT, + X86_PF_AMD_CEZANNE, + X86_PF_AMD_RAPHAEL, + + X86_PF_ANY = 0xff +} x86_processor_family_t; + +#define _DECL_CHIPREV(_v, _f, _revn, _revb) \ + X86_CHIPREV_ ## _v ## _ ## _f ## _ ## _revn = \ + _X86_CHIPREV_MKREV(X86_VENDOR_ ## _v, X86_PF_ ## _v ## _ ## _f, _revb) + +#define _X86_CHIPREV_REV_MATCH_ALL 0xffff + +typedef enum x86_chiprev { + X86_CHIPREV_UNKNOWN, + _DECL_CHIPREV(AMD, LEGACY_F, REV_B, 0x0001), + /* + * Definitions for AMD Family 0xf. Minor revisions C0 and CG are + * sufficiently different that we will distinguish them; in all other + * case we will identify the major revision. + */ + _DECL_CHIPREV(AMD, LEGACY_F, REV_C0, 0x0002), + _DECL_CHIPREV(AMD, LEGACY_F, REV_CG, 0x0004), + _DECL_CHIPREV(AMD, LEGACY_F, REV_D, 0x0008), + _DECL_CHIPREV(AMD, LEGACY_F, REV_E, 0x0010), + _DECL_CHIPREV(AMD, LEGACY_F, REV_F, 0x0020), + _DECL_CHIPREV(AMD, LEGACY_F, REV_G, 0x0040), + _DECL_CHIPREV(AMD, LEGACY_F, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, LEGACY_10, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, LEGACY_10, REV_A, 0x0002), + _DECL_CHIPREV(AMD, LEGACY_10, REV_B, 0x0004), + _DECL_CHIPREV(AMD, LEGACY_10, REV_C2, 0x0008), + _DECL_CHIPREV(AMD, LEGACY_10, REV_C3, 0x0010), + _DECL_CHIPREV(AMD, LEGACY_10, REV_D0, 0x0020), + _DECL_CHIPREV(AMD, LEGACY_10, REV_D1, 0x0040), + _DECL_CHIPREV(AMD, LEGACY_10, REV_E, 0x0080), + _DECL_CHIPREV(AMD, LEGACY_10, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, LEGACY_11, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, LEGACY_11, REV_B, 0x0002), + _DECL_CHIPREV(AMD, LEGACY_11, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, LEGACY_12, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, LEGACY_12, REV_B, 0x0002), + _DECL_CHIPREV(AMD, LEGACY_12, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, LEGACY_14, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, LEGACY_14, REV_B, 0x0002), + _DECL_CHIPREV(AMD, LEGACY_14, REV_C, 0x0004), + _DECL_CHIPREV(AMD, LEGACY_14, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, OROCHI, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, OROCHI, REV_B2, 0x0002), + _DECL_CHIPREV(AMD, OROCHI, REV_C0, 0x0004), + _DECL_CHIPREV(AMD, OROCHI, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, TRINITY, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, TRINITY, REV_A1, 0x0002), + _DECL_CHIPREV(AMD, TRINITY, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, KAVERI, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, KAVERI, REV_A1, 0x0002), + _DECL_CHIPREV(AMD, KAVERI, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, CARRIZO, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, CARRIZO, REV_A0, 0x0002), + _DECL_CHIPREV(AMD, CARRIZO, REV_A1, 0x0004), + _DECL_CHIPREV(AMD, CARRIZO, REV_DDR4, 0x0008), + _DECL_CHIPREV(AMD, CARRIZO, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, STONEY_RIDGE, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, STONEY_RIDGE, REV_A0, 0x0002), + _DECL_CHIPREV(AMD, STONEY_RIDGE, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, KABINI, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, KABINI, A1, 0x0002), + _DECL_CHIPREV(AMD, KABINI, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, MULLINS, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, MULLINS, A1, 0x0002), + _DECL_CHIPREV(AMD, MULLINS, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, NAPLES, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, NAPLES, A0, 0x0002), + _DECL_CHIPREV(AMD, NAPLES, B1, 0x0004), + _DECL_CHIPREV(AMD, NAPLES, B2, 0x0008), + _DECL_CHIPREV(AMD, NAPLES, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, PINNACLE_RIDGE, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, PINNACLE_RIDGE, B2, 0x0002), + _DECL_CHIPREV(AMD, PINNACLE_RIDGE, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, RAVEN_RIDGE, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, RAVEN_RIDGE, B0, 0x0002), + _DECL_CHIPREV(AMD, RAVEN_RIDGE, B1, 0x0004), + _DECL_CHIPREV(AMD, RAVEN_RIDGE, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, PICASSO, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, PICASSO, B1, 0x0002), + _DECL_CHIPREV(AMD, PICASSO, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, DALI, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, DALI, A1, 0x0002), + _DECL_CHIPREV(AMD, DALI, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, ROME, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, ROME, A0, 0x0002), + _DECL_CHIPREV(AMD, ROME, B0, 0x0004), + _DECL_CHIPREV(AMD, ROME, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, RENOIR, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, RENOIR, A1, 0x0002), + _DECL_CHIPREV(AMD, RENOIR, LCN_A1, 0x0004), + _DECL_CHIPREV(AMD, RENOIR, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, MATISSE, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, MATISSE, B0, 0x0002), + _DECL_CHIPREV(AMD, MATISSE, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, VAN_GOGH, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, VAN_GOGH, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, MENDOCINO, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, MENDOCINO, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(HYGON, DHYANA, UNKNOWN, 0x0001), + _DECL_CHIPREV(HYGON, DHYANA, A1, 0x0002), + _DECL_CHIPREV(HYGON, DHYANA, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, MILAN, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, MILAN, A0, 0x0002), + _DECL_CHIPREV(AMD, MILAN, B0, 0x0004), + _DECL_CHIPREV(AMD, MILAN, B1, 0x0008), + _DECL_CHIPREV(AMD, MILAN, B2, 0x0010), + _DECL_CHIPREV(AMD, MILAN, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, GENOA, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, GENOA, A0, 0x0002), + _DECL_CHIPREV(AMD, GENOA, A1, 0x0004), + _DECL_CHIPREV(AMD, GENOA, B0, 0x0008), + _DECL_CHIPREV(AMD, GENOA, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, VERMEER, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, VERMEER, A0, 0x0002), + _DECL_CHIPREV(AMD, VERMEER, B0, 0x0004), + _DECL_CHIPREV(AMD, VERMEER, B2, 0x0008), /* No B1 */ + _DECL_CHIPREV(AMD, VERMEER, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, REMBRANDT, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, REMBRANDT, A0, 0x0002), + _DECL_CHIPREV(AMD, REMBRANDT, B0, 0x0004), + _DECL_CHIPREV(AMD, REMBRANDT, B1, 0x0008), + _DECL_CHIPREV(AMD, REMBRANDT, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, CEZANNE, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, CEZANNE, A0, 0x0002), + _DECL_CHIPREV(AMD, CEZANNE, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + _DECL_CHIPREV(AMD, RAPHAEL, UNKNOWN, 0x0001), + _DECL_CHIPREV(AMD, RAPHAEL, ANY, _X86_CHIPREV_REV_MATCH_ALL), + + /* Keep at the end */ + X86_CHIPREV_ANY = _X86_CHIPREV_MKREV(_X86_VENDOR_MATCH_ALL, X86_PF_ANY, + _X86_CHIPREV_REV_MATCH_ALL) +} x86_chiprev_t; + +#undef _DECL_CHIPREV /* - * Definitions for AMD Family 0x15 + * Same thing, but for microarchitecture (core implementations). We are not + * attempting to capture every possible fine-grained detail here; to the extent + * that it matters, we do so in cpuid.c via ISA/feature bits. We use the same + * number of bits for each field as in chiprev. */ -#define X86_CHIPREV_AMD_15OR_REV_B2 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x15, 0x0001) -#define X86_CHIPREV_AMD_15TN_REV_A1 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x15, 0x0002) +#define _X86_UARCHREV_VENDOR(x) _X86_CHIPREV_VENDOR(x) +#define _X86_UARCHREV_UARCH(x) _X86_CHIPREV_FAMILY(x) +#define _X86_UARCHREV_REV(x) _X86_CHIPREV_REV(x) -#define X86_CHIPREV_AMD_150R_REV_C0 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x15, 0x0003) +#define _X86_UARCHREV_MKREV(vendor, family, rev) \ + _X86_CHIPREV_MKREV(vendor, family, rev) -#define X86_CHIPREV_AMD_15KV_REV_A1 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x15, 0x0004) +typedef enum x86_uarch { + X86_UARCH_UNKNOWN, -#define X86_CHIPREV_AMD_15F60 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x15, 0x0005) + X86_UARCH_AMD_LEGACY, + X86_UARCH_AMD_ZEN1, + X86_UARCH_AMD_ZENPLUS, + X86_UARCH_AMD_ZEN2, + X86_UARCH_AMD_ZEN3, + X86_UARCH_AMD_ZEN4, -#define X86_CHIPREV_AMD_15ST_REV_A0 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x15, 0x0006) + X86_UARCH_ANY = 0xff +} x86_uarch_t; -/* - * Definitions for AMD Family 0x16 - */ -#define X86_CHIPREV_AMD_16_KB_A1 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x16, 0x0001) +#define _DECL_UARCHREV(_v, _f, _revn, _revb) \ + X86_UARCHREV_ ## _v ## _ ## _f ## _ ## _revn = \ + _X86_UARCHREV_MKREV(X86_VENDOR_ ## _v, X86_UARCH_ ## _v ## _ ## _f, \ + _revb) -#define X86_CHIPREV_AMD_16_ML_A1 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x16, 0x0002) +#define _DECL_UARCHREV_NOREV(_v, _f, _revb) \ + X86_UARCHREV_ ## _v ## _ ## _f = \ + _X86_UARCHREV_MKREV(X86_VENDOR_ ## _v, X86_UARCH_ ## _v ## _ ## _f, \ + _revb) -/* - * Definitions for AMD Family 0x17 - */ - -#define X86_CHIPREV_AMD_17_ZP_B1 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x17, 0x0001) +#define _X86_UARCHREV_REV_MATCH_ALL 0xffff -#define X86_CHIPREV_AMD_17_ZP_B2 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x17, 0x0002) +typedef enum x86_uarchrev { + X86_UARCHREV_UNKNOWN, + _DECL_UARCHREV_NOREV(AMD, LEGACY, 0x0001), + _DECL_UARCHREV(AMD, LEGACY, ANY, _X86_UARCHREV_REV_MATCH_ALL), -#define X86_CHIPREV_AMD_17_PiR_B2 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x17, 0x0003) + _DECL_UARCHREV_NOREV(AMD, ZEN1, 0x0001), + _DECL_UARCHREV(AMD, ZEN1, ANY, _X86_UARCHREV_REV_MATCH_ALL), -#define X86_CHIPREV_AMD_17_RV_B0 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x17, 0x0004) + _DECL_UARCHREV_NOREV(AMD, ZENPLUS, 0x0001), + _DECL_UARCHREV(AMD, ZENPLUS, ANY, _X86_UARCHREV_REV_MATCH_ALL), -#define X86_CHIPREV_AMD_17_RV_B1 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x17, 0x0005) + _DECL_UARCHREV(AMD, ZEN2, UNKNOWN, 0x0001), + _DECL_UARCHREV(AMD, ZEN2, A0, 0x0002), + _DECL_UARCHREV(AMD, ZEN2, B0, 0x0004), + _DECL_UARCHREV(AMD, ZEN2, ANY, _X86_UARCHREV_REV_MATCH_ALL), -#define X86_CHIPREV_AMD_17_PCO_B1 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x17, 0x0006) + _DECL_UARCHREV(AMD, ZEN3, UNKNOWN, 0x0001), + _DECL_UARCHREV(AMD, ZEN3, A0, 0x0002), + _DECL_UARCHREV(AMD, ZEN3, B0, 0x0004), + _DECL_UARCHREV(AMD, ZEN3, B1, 0x0008), + _DECL_UARCHREV(AMD, ZEN3, B2, 0x0010), + _DECL_UARCHREV(AMD, ZEN3, ANY, _X86_UARCHREV_REV_MATCH_ALL), -#define X86_CHIPREV_AMD_17_SSP_A0 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x17, 0x0007) + _DECL_UARCHREV_NOREV(AMD, ZEN4, 0x0001), + _DECL_UARCHREV(AMD, ZEN4, ANY, _X86_UARCHREV_REV_MATCH_ALL), -#define X86_CHIPREV_AMD_17_SSP_B0 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x17, 0x0008) + /* Keep at the end */ + _X86_UARCHREV_ANY = _X86_UARCHREV_MKREV(_X86_VENDOR_MATCH_ALL, + X86_UARCH_ANY, _X86_UARCHREV_REV_MATCH_ALL) +} x86_uarchrev_t; -#define X86_CHIPREV_AMD_17_MTS_B0 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x17, 0x0009) +#undef _DECL_UARCHREV -/* - * Definitions for Hygon Family 0x18 - */ -#define X86_CHIPREV_HYGON_18_DN_A1 \ - _X86_CHIPREV_MKREV(X86_VENDOR_HYGON, 0x18, 0x0001) - -#define X86_CHIPREV_AMD_19_GN_A0 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x19, 0x0000) -#define X86_CHIPREV_AMD_19_GN_B0 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x19, 0x0001) -#define X86_CHIPREV_AMD_19_GN_B1 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x19, 0x0002) -#define X86_CHIPREV_AMD_19_VMR_B0 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x19, 0x0003) -#define X86_CHIPREV_AMD_19_VMR_B1 \ - _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x19, 0x0004) +#endif /* !_ASM */ /* * Various socket/package types, extended as the need to distinguish @@ -1068,7 +1225,12 @@ extern "C" { #define X86_SOCKET_FP5 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x21) #define X86_SOCKET_FP6 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x22) #define X86_SOCKET_STRX4 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x23) -#define X86_NUM_SOCKETS_AMD 0x24 +#define X86_SOCKET_SP5 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x24) +#define X86_SOCKET_AM5 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x25) +#define X86_SOCKET_FP7 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x26) +#define X86_SOCKET_FP7R2 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x27) +#define X86_SOCKET_FF3 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x28) +#define X86_NUM_SOCKETS_AMD 0x28 /* * Hygon socket types @@ -1076,7 +1238,7 @@ extern "C" { #define X86_SOCKET_SL1 _X86_SOCKET_MKVAL(X86_VENDOR_HYGON, 0x01) #define X86_SOCKET_SL1R2 _X86_SOCKET_MKVAL(X86_VENDOR_HYGON, 0x02) #define X86_SOCKET_DM1 _X86_SOCKET_MKVAL(X86_VENDOR_HYGON, 0x03) -#define X86_NUM_SOCKETS_HYGON 0x04 +#define X86_NUM_SOCKETS_HYGON 0x03 #define X86_NUM_SOCKETS (X86_NUM_SOCKETS_AMD + X86_NUM_SOCKETS_HYGON) @@ -1298,10 +1460,11 @@ extern int cpuid_is_cmt(struct cpu *); extern int cpuid_syscall32_insn(struct cpu *); extern int getl2cacheinfo(struct cpu *, int *, int *, int *); -extern uint32_t cpuid_getchiprev(struct cpu *); +extern x86_chiprev_t cpuid_getchiprev(struct cpu *); extern const char *cpuid_getchiprevstr(struct cpu *); extern uint32_t cpuid_getsockettype(struct cpu *); extern const char *cpuid_getsocketstr(struct cpu *); +extern x86_uarchrev_t cpuid_getuarchrev(struct cpu *); extern int cpuid_opteron_erratum(struct cpu *, uint_t); @@ -1327,6 +1490,14 @@ extern int cpuid_deadline_tsc_supported(void); extern void vmware_port(int, uint32_t *); #endif +extern x86_processor_family_t chiprev_family(const x86_chiprev_t); +extern boolean_t chiprev_matches(const x86_chiprev_t, const x86_chiprev_t); +extern boolean_t chiprev_at_least(const x86_chiprev_t, const x86_chiprev_t); + +extern x86_uarch_t uarchrev_uarch(const x86_uarchrev_t); +extern boolean_t uarchrev_matches(const x86_uarchrev_t, const x86_uarchrev_t); +extern boolean_t uarchrev_at_least(const x86_uarchrev_t, const x86_uarchrev_t); + struct cpu_ucode_info; extern void ucode_alloc_space(struct cpu *); |
