Mercurial > illumos > illumos-gate
changeset 9482:42f3d60af7ca onnv_114
6770233 New model ID for Istanbul processor
6672305 Need to support Griffin processors
6824550 AMD G34 processors need cpuid support
Contributed by Boris Ostrovsky <boris.ostrovsky@amd.com>
author | Kuriakose Kuruvilla <Kuriakose.Kuruvilla@Sun.COM> |
---|---|
date | Mon, 27 Apr 2009 23:10:26 -0700 |
parents | b25f8de94abf |
children | 74ff44a6bba1 |
files | usr/src/cmd/psrinfo/psrinfo.pl usr/src/uts/common/os/cpu.c usr/src/uts/i86pc/os/cmi_hw.c usr/src/uts/i86pc/os/cpuid.c usr/src/uts/i86pc/os/cpuid_subr.c usr/src/uts/intel/io/mc-amd/mcamd_drv.c usr/src/uts/intel/sys/cpu_module.h usr/src/uts/intel/sys/x86_archext.h |
diffstat | 8 files changed, 250 insertions(+), 53 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/psrinfo/psrinfo.pl Tue Apr 28 12:24:30 2009 +0800 +++ b/usr/src/cmd/psrinfo/psrinfo.pl Mon Apr 27 23:10:26 2009 -0700 @@ -20,11 +20,9 @@ # # CDDL HEADER END # -# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#ident "%Z%%M% %I% %E% SMI" -# # psrinfo: displays information about processors # # See detailed comment in the end of this file. @@ -686,6 +684,7 @@ my $brand = $cpu->{brand} || gettext("(unknown)"); my $impl = $cpu->{implementation} || gettext("(unknown)"); + my $socket = $cpu->{socket_type}; # # Remove cpuid and chipid information from # implementation string and print it. @@ -702,7 +701,10 @@ $cname, $ncpus, $cpu_name; print "($cl)\n"; print " $impl\n" if $impl; - print "\t$brand\n" if $brand; + print "\t$brand" if $brand; + print "\t[ Socket: $socket ]" if $socket && + $socket ne "Unknown"; + print "\n"; } else { # Get child count my $nchildren =
--- a/usr/src/uts/common/os/cpu.c Tue Apr 28 12:24:30 2009 +0800 +++ b/usr/src/uts/common/os/cpu.c Mon Apr 27 23:10:26 2009 -0700 @@ -2166,6 +2166,7 @@ kstat_named_t ci_ncoreperchip; kstat_named_t ci_max_cstates; kstat_named_t ci_curr_cstate; + kstat_named_t ci_sktstr; #endif } cpu_info_template = { { "state", KSTAT_DATA_CHAR }, @@ -2194,6 +2195,7 @@ { "ncore_per_chip", KSTAT_DATA_INT32 }, { "supported_max_cstates", KSTAT_DATA_INT32 }, { "current_cstate", KSTAT_DATA_INT32 }, + { "socket_type", KSTAT_DATA_STRING }, #endif }; @@ -2265,6 +2267,8 @@ cpu_info_template.ci_pkg_core_id.value.l = cpuid_get_pkgcoreid(cp); cpu_info_template.ci_max_cstates.value.l = cp->cpu_m.max_cstates; cpu_info_template.ci_curr_cstate.value.l = cp->cpu_m.curr_cstate; + kstat_named_setstr(&cpu_info_template.ci_sktstr, + cpuid_getsocketstr(cp)); #endif return (0);
--- a/usr/src/uts/i86pc/os/cmi_hw.c Tue Apr 28 12:24:30 2009 +0800 +++ b/usr/src/uts/i86pc/os/cmi_hw.c Mon Apr 27 23:10:26 2009 -0700 @@ -95,6 +95,8 @@ uint32_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 *); + id_t (*cmio_logical_id)(cmi_hdl_impl_t *); /* * These ops are optional in an implementation. @@ -617,6 +619,12 @@ return (cpuid_getsockettype(HDLPRIV(hdl))); } +static const char * +ntv_getsocketstr(cmi_hdl_impl_t *hdl) +{ + return (cpuid_getsocketstr(HDLPRIV(hdl))); +} + static id_t ntv_logical_id(cmi_hdl_impl_t *hdl) { @@ -876,6 +884,15 @@ xpv_model(hdl), xpv_stepping(hdl))); } +extern const char *_cpuid_sktstr(uint_t, uint_t, uint_t, uint_t); + +static const char * +xpv_getsocketstr(cmi_hdl_impl_t *hdl) +{ + return (_cpuid_sktstr(xpv_vendor(hdl), xpv_family(hdl), + xpv_model(hdl), xpv_stepping(hdl))); +} + static id_t xpv_logical_id(cmi_hdl_impl_t *hdl) { @@ -1391,6 +1408,7 @@ CMI_HDL_OPFUNC(chiprev, uint32_t) CMI_HDL_OPFUNC(chiprevstr, const char *) CMI_HDL_OPFUNC(getsockettype, uint32_t) +CMI_HDL_OPFUNC(getsocketstr, const char *) CMI_HDL_OPFUNC(logical_id, id_t) boolean_t @@ -1722,6 +1740,7 @@ xpv_chiprev, /* cmio_chiprev */ xpv_chiprevstr, /* cmio_chiprevstr */ xpv_getsockettype, /* cmio_getsockettype */ + xpv_getsocketstr, /* cmio_getsocketstr */ xpv_logical_id, /* cmio_logical_id */ NULL, /* cmio_getcr4 */ NULL, /* cmio_setcr4 */ @@ -1747,6 +1766,7 @@ ntv_chiprev, /* cmio_chiprev */ ntv_chiprevstr, /* cmio_chiprevstr */ ntv_getsockettype, /* cmio_getsockettype */ + ntv_getsocketstr, /* cmio_getsocketstr */ ntv_logical_id, /* cmio_logical_id */ ntv_getcr4, /* cmio_getcr4 */ ntv_setcr4, /* cmio_setcr4 */
--- a/usr/src/uts/i86pc/os/cpuid.c Tue Apr 28 12:24:30 2009 +0800 +++ b/usr/src/uts/i86pc/os/cpuid.c Mon Apr 27 23:10:26 2009 -0700 @@ -306,6 +306,7 @@ * file to try and keep people using the expected cpuid_* interfaces. */ 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 const char *_cpuid_chiprevstr(uint_t, uint_t, uint_t, uint_t); extern uint_t _cpuid_vendorstr_to_vendorcode(char *); @@ -495,6 +496,10 @@ extern int idle_cpu_prefer_mwait; #endif + +#if !defined(__xpv) + determine_platform(); +#endif /* * Space statically allocated for cpu0, ensure pointer is set */ @@ -1226,9 +1231,6 @@ cpi->cpi_model, cpi->cpi_step); pass1_done: -#if !defined(__xpv) - determine_platform(); -#endif cpi->cpi_pass = 1; return (feature); } @@ -2484,6 +2486,24 @@ return (cpu->cpu_m.mcpu_cpi->cpi_socket); } +const char * +cpuid_getsocketstr(cpu_t *cpu) +{ + static const char *socketstr = NULL; + struct cpuid_info *cpi; + + ASSERT(cpuid_checkpass(cpu, 1)); + cpi = cpu->cpu_m.mcpu_cpi; + + /* Assume that socket types are the same across the system */ + if (socketstr == NULL) + socketstr = _cpuid_sktstr(cpi->cpi_vendor, cpi->cpi_family, + cpi->cpi_model, cpi->cpi_step); + + + return (socketstr); +} + int cpuid_get_chipid(cpu_t *cpu) {
--- a/usr/src/uts/i86pc/os/cpuid_subr.c Tue Apr 28 12:24:30 2009 +0800 +++ b/usr/src/uts/i86pc/os/cpuid_subr.c Mon Apr 27 23:10:26 2009 -0700 @@ -20,11 +20,15 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* + * Portions Copyright 2009 Advanced Micro Devices, Inc. + */ + +/* * Support functions that interpret CPUID and similar information. * These should not be used from anywhere other than cpuid.c and * cmi_hw.c - as such we will not list them in any header file @@ -46,17 +50,24 @@ #include <sys/types.h> #include <sys/systm.h> +#include <sys/bitmap.h> #include <sys/x86_archext.h> +#include <sys/pci_cfgspace.h> +#ifdef __xpv +#include <sys/hypervisor.h> +#endif /* - * AMD family 0xf and family 0x10 socket types. + * 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, rev B - * Second index by (model & 0x3) + * 2 for family 0x10 + * 3 for family 0x11 + * Second index by (model & 0x3) for family 0fh + * or CPUID bits for later families */ -static uint32_t amd_skts[3][4] = { +static uint32_t amd_skts[4][4] = { /* * Family 0xf revisions B through E */ @@ -78,19 +89,48 @@ X86_SOCKET_AM2 /* 0b11 */ }, /* - * Family 0x10 revisions A and B - * It is not clear whether, as new sockets release, that - * model & 0x3 will id socket for this family + * Family 0x10 */ #define A_SKTS_2 2 { X86_SOCKET_F1207, /* 0b00 */ - X86_SOCKET_F1207, /* 0b01 */ - X86_SOCKET_F1207, /* 0b10 */ - X86_SOCKET_F1207, /* 0b11 */ + X86_SOCKET_AM, /* 0b01 */ + X86_SOCKET_S1g3, /* 0b10 */ + X86_SOCKET_G34, /* 0b11 */ + }, + + /* + * Family 0x11 + */ +#define A_SKTS_3 3 + { + X86_SOCKET_UNKNOWN, /* 0b00 */ + X86_SOCKET_UNKNOWN, /* 0b01 */ + X86_SOCKET_S1g2, /* 0b10 */ + X86_SOCKET_UNKNOWN, /* 0b11 */ } }; +struct amd_sktmap_s { + uint32_t skt_code; + char sktstr[16]; +}; +static struct amd_sktmap_s amd_sktmap[13] = { + { X86_SOCKET_754, "754" }, + { X86_SOCKET_939, "939" }, + { X86_SOCKET_940, "940" }, + { X86_SOCKET_S1g1, "S1g1" }, + { X86_SOCKET_AM2, "AM2" }, + { X86_SOCKET_F1207, "F(1207)" }, + { X86_SOCKET_S1g2, "S1g2" }, + { X86_SOCKET_S1g3, "S1g3" }, + { X86_SOCKET_AM, "AM" }, + { X86_SOCKET_AM2R2, "AM2r2" }, + { X86_SOCKET_AM3, "AM3" }, + { X86_SOCKET_G34, "G34" }, + { X86_SOCKET_UNKNOWN, "Unknown" } +}; + /* * Table for mapping AMD Family 0xf and AMD Family 0x10 model/stepping * combination to chip "revision" and socket type. @@ -162,9 +202,20 @@ /* * Rev C has models 4-6 (depending on L3 cache configuration) - * Give all of model 2 stepping range to rev c. + * Give all of models 4-6 stepping range to rev C. */ { 0x10, 0x04, 0x06, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_C, "C", A_SKTS_2 }, + + /* + * Rev D has models 8 and 9 + * Give all of model 8 and 9 stepping range to rev D. + */ + { 0x10, 0x08, 0x09, 0x0, 0xf, X86_CHIPREV_AMD_10_REV_D, "D", A_SKTS_2 }, + + /* + * =============== AuthenticAMD Family 0x11 =============== + */ + { 0x11, 0x03, 0x3, 0x0, 0xf, X86_CHIPREV_AMD_11, "B", A_SKTS_3 }, }; static void @@ -175,10 +226,7 @@ int found = 0; int i; - /* - * Currently only AMD family 0xf and family 0x10 use these fields. - */ - if (family != 0xf && family != 0x10) + if (family < 0xf) return; for (i = 0, rmp = amd_revmap; i < sizeof (amd_revmap) / sizeof (*rmp); @@ -191,13 +239,66 @@ } } - if (found) { - if (skt_p != NULL) + if (!found) + return; + + if (chiprev_p != NULL) + *chiprev_p = rmp->rm_chiprev; + if (chiprevstr_p != NULL) + *chiprevstr_p = rmp->rm_chiprevstr; + + if (skt_p != NULL) { + int platform; + +#ifdef __xpv + /* PV guest */ + if (!is_controldom()) { + *skt_p = X86_SOCKET_UNKNOWN; + return; + } +#endif + platform = get_hwenv(); + + if ((platform == HW_XEN_HVM) || (platform == HW_VMWARE)) { + *skt_p = X86_SOCKET_UNKNOWN; + } else if (family == 0xf) { *skt_p = amd_skts[rmp->rm_sktidx][model & 0x3]; - if (chiprev_p != NULL) - *chiprev_p = rmp->rm_chiprev; - if (chiprevstr_p != NULL) - *chiprevstr_p = rmp->rm_chiprevstr; + } else { + /* + * Starting with family 10h, socket type is stored in + * CPUID Fn8000_0001_EBX + */ + struct cpuid_regs cp; + int idx; + + cp.cp_eax = 0x80000001; + (void) __cpuid_insn(&cp); + + /* PkgType bits */ + idx = BITX(cp.cp_ebx, 31, 28); + + if (idx > 3) { + /* Reserved bits */ + *skt_p = X86_SOCKET_UNKNOWN; + } else if (family == 0x10 && + amd_skts[rmp->rm_sktidx][idx] == + X86_SOCKET_AM) { + /* + * Look at Ddr3Mode bit of DRAM Configuration + * High Register to decide whether this is + * AM2r2 (aka AM2+) or AM3. + */ + uint32_t val; + + val = pci_getl_func(0, 24, 2, 0x94); + if (BITX(val, 8, 8)) + *skt_p = X86_SOCKET_AM3; + else + *skt_p = X86_SOCKET_AM2R2; + } else { + *skt_p = amd_skts[rmp->rm_sktidx][idx]; + } + } } } @@ -219,6 +320,34 @@ return (skt); } +const char * +_cpuid_sktstr(uint_t vendor, uint_t family, uint_t model, uint_t step) +{ + const char *sktstr = "Unknown"; + struct amd_sktmap_s *sktmapp; + uint32_t skt = X86_SOCKET_UNKNOWN; + + switch (vendor) { + case X86_VENDOR_AMD: + synth_amd_info(family, model, step, &skt, NULL, NULL); + + sktmapp = amd_sktmap; + while (sktmapp->skt_code != X86_SOCKET_UNKNOWN) { + if (sktmapp->skt_code == skt) + break; + sktmapp++; + } + sktstr = sktmapp->sktstr; + break; + + default: + break; + + } + + return (sktstr); +} + uint32_t _cpuid_chiprev(uint_t vendor, uint_t family, uint_t model, uint_t step) {
--- a/usr/src/uts/intel/io/mc-amd/mcamd_drv.c Tue Apr 28 12:24:30 2009 +0800 +++ b/usr/src/uts/intel/io/mc-amd/mcamd_drv.c Mon Apr 27 23:10:26 2009 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -165,34 +165,39 @@ } } -#define NSKT 6 +/*ARGSUSED*/ +static int +mc_nvl_add_socket_cb(cmi_hdl_t whdl, void *arg1, void *arg2, void *arg3) +{ + uint32_t skt = *((uint32_t *)arg1); + cmi_hdl_t *hdlp = (cmi_hdl_t *)arg2; + + if (cmi_hdl_getsockettype(whdl) == skt) { + cmi_hdl_hold(whdl); /* short-term hold */ + *hdlp = whdl; + return (CMI_HDL_WALK_DONE); + } else { + return (CMI_HDL_WALK_NEXT); + } +} static void mc_nvl_add_socket(nvlist_t *nvl, mc_t *mc) { - const char *s = "Unknown"; - int i; + cmi_hdl_t hdl = NULL; + const char *s; - static const struct { - uint32_t type; - const char *name; - } sktnames[NSKT] = { - { X86_SOCKET_754, "Socket 754" }, - { X86_SOCKET_939, "Socket 939" }, - { X86_SOCKET_940, "Socket 940" }, - { X86_SOCKET_AM2, "Socket AM2" }, - { X86_SOCKET_F1207, "Socket F(1207)" }, - { X86_SOCKET_S1g1, "Socket S1g1" }, - }; - - for (i = 0; i < NSKT; i++) { - if (mc->mc_socket == sktnames[i].type) { - s = sktnames[i].name; - break; - } - } + cmi_hdl_walk(mc_nvl_add_socket_cb, (void *)&mc->mc_socket, + (void *)&hdl, NULL); + if (hdl == NULL) + s = "Unknown"; /* no cpu for this chipid found */ + else + s = cmi_hdl_getsocketstr(hdl); (void) nvlist_add_string(nvl, "socket", s); + + if (hdl != NULL) + cmi_hdl_rele(hdl); } static uint32_t
--- a/usr/src/uts/intel/sys/cpu_module.h Tue Apr 28 12:24:30 2009 +0800 +++ b/usr/src/uts/intel/sys/cpu_module.h Mon Apr 27 23:10:26 2009 -0700 @@ -20,7 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -157,6 +157,7 @@ extern uint32_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); extern id_t cmi_hdl_logical_id(cmi_hdl_t); extern int cmi_hdl_online(cmi_hdl_t, int, int *);
--- a/usr/src/uts/intel/sys/x86_archext.h Tue Apr 28 12:24:30 2009 +0800 +++ b/usr/src/uts/intel/sys/x86_archext.h Mon Apr 27 23:10:26 2009 -0700 @@ -506,6 +506,15 @@ _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x10, 0x0002) #define X86_CHIPREV_AMD_10_REV_C \ _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x10, 0x0004) +#define X86_CHIPREV_AMD_10_REV_D \ + _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x10, 0x0008) + +/* + * Definitions for AMD Family 0x11. + */ +#define X86_CHIPREV_AMD_11 \ + _X86_CHIPREV_MKREV(X86_VENDOR_AMD, 0x11, 0x0003) + /* * Various socket/package types, extended as the need to distinguish @@ -523,7 +532,7 @@ #define X86_SOCKET_MATCH(s, mask) \ (_X86_SOCKET_VENDOR(s) == _X86_SOCKET_VENDOR(mask) && \ - (_X86_SOCKET_TYPE(s) & _X86_SOCKET_TYPE(mask)) != 0) + (_X86_SOCKET_TYPE(s) == _X86_SOCKET_TYPE(mask))) #define X86_SOCKET_UNKNOWN 0x0 /* @@ -535,6 +544,12 @@ #define X86_SOCKET_S1g1 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x000008) #define X86_SOCKET_AM2 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x000010) #define X86_SOCKET_F1207 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x000020) +#define X86_SOCKET_S1g2 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x000030) +#define X86_SOCKET_S1g3 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x000040) +#define X86_SOCKET_AM _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x000050) +#define X86_SOCKET_AM2R2 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x000060) +#define X86_SOCKET_AM3 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x000070) +#define X86_SOCKET_G34 _X86_SOCKET_MKVAL(X86_VENDOR_AMD, 0x000080) #if !defined(_ASM) @@ -611,6 +626,7 @@ extern uint32_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 int cpuid_opteron_erratum(struct cpu *, uint_t);