diff options
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 *); |