diff options
author | Kuriakose Kuruvilla <Kuriakose.Kuruvilla@Sun.COM> | 2009-04-27 23:10:26 -0700 |
---|---|---|
committer | Kuriakose Kuruvilla <Kuriakose.Kuruvilla@Sun.COM> | 2009-04-27 23:10:26 -0700 |
commit | 89e921d5e5050628462effb26c9db2cf1a87fdf4 (patch) | |
tree | 233a8acf7da1b63b1ca05ec11b2c7edce098a577 | |
parent | 2273e7c709f1df61ff7132f9095307e2cedd865b (diff) | |
download | illumos-gate-89e921d5e5050628462effb26c9db2cf1a87fdf4.tar.gz |
6770233 New model ID for Istanbul processoronnv_114
6672305 Need to support Griffin processors
6824550 AMD G34 processors need cpuid support
Contributed by Boris Ostrovsky <boris.ostrovsky@amd.com>
-rw-r--r-- | usr/src/cmd/psrinfo/psrinfo.pl | 10 | ||||
-rw-r--r-- | usr/src/uts/common/os/cpu.c | 4 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/cmi_hw.c | 20 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/cpuid.c | 26 | ||||
-rw-r--r-- | usr/src/uts/i86pc/os/cpuid_subr.c | 173 | ||||
-rw-r--r-- | usr/src/uts/intel/io/mc-amd/mcamd_drv.c | 49 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/cpu_module.h | 3 | ||||
-rw-r--r-- | usr/src/uts/intel/sys/x86_archext.h | 18 |
8 files changed, 250 insertions, 53 deletions
diff --git a/usr/src/cmd/psrinfo/psrinfo.pl b/usr/src/cmd/psrinfo/psrinfo.pl index c9901aa91c..237e4d00f5 100644 --- a/usr/src/cmd/psrinfo/psrinfo.pl +++ b/usr/src/cmd/psrinfo/psrinfo.pl @@ -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 @@ if ($phys_view) { 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 @@ if ($phys_view) { $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 = diff --git a/usr/src/uts/common/os/cpu.c b/usr/src/uts/common/os/cpu.c index 8b8d0d08b5..6ee6c941f7 100644 --- a/usr/src/uts/common/os/cpu.c +++ b/usr/src/uts/common/os/cpu.c @@ -2166,6 +2166,7 @@ static struct { 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 @@ static struct { { "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_kstat_update(kstat_t *ksp, int rw) 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); diff --git a/usr/src/uts/i86pc/os/cmi_hw.c b/usr/src/uts/i86pc/os/cmi_hw.c index cabe81d8f1..d788fe560d 100644 --- a/usr/src/uts/i86pc/os/cmi_hw.c +++ b/usr/src/uts/i86pc/os/cmi_hw.c @@ -95,6 +95,8 @@ struct cmi_hdl_ops { 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 @@ ntv_getsockettype(cmi_hdl_impl_t *hdl) 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_getsockettype(cmi_hdl_impl_t *hdl) 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(strandid, uint_t) 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 @@ static const struct cmi_hdl_ops cmi_hdl_ops = { 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 @@ static const struct cmi_hdl_ops cmi_hdl_ops = { 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 */ diff --git a/usr/src/uts/i86pc/os/cpuid.c b/usr/src/uts/i86pc/os/cpuid.c index 182c4aa7a6..b87c5f9887 100644 --- a/usr/src/uts/i86pc/os/cpuid.c +++ b/usr/src/uts/i86pc/os/cpuid.c @@ -306,6 +306,7 @@ static struct cpuid_info cpuid_info0; * 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 @@ cpuid_pass1(cpu_t *cpu) 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 @@ cpuid_pass1(cpu_t *cpu) cpi->cpi_model, cpi->cpi_step); pass1_done: -#if !defined(__xpv) - determine_platform(); -#endif cpi->cpi_pass = 1; return (feature); } @@ -2484,6 +2486,24 @@ cpuid_getsockettype(struct cpu *cpu) 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) { diff --git a/usr/src/uts/i86pc/os/cpuid_subr.c b/usr/src/uts/i86pc/os/cpuid_subr.c index 411d833bef..a5f813115c 100644 --- a/usr/src/uts/i86pc/os/cpuid_subr.c +++ b/usr/src/uts/i86pc/os/cpuid_subr.c @@ -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 @@ static uint32_t amd_skts[3][4] = { 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 @@ static const struct amd_rev_mapent { /* * 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 @@ synth_amd_info(uint_t family, uint_t model, uint_t step, 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 @@ synth_amd_info(uint_t family, uint_t model, uint_t step, } } - 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 @@ _cpuid_skt(uint_t vendor, uint_t family, uint_t model, uint_t step) 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) { 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 fee2fa17b5..4f2db363e7 100644 --- a/usr/src/uts/intel/io/mc-amd/mcamd_drv.c +++ b/usr/src/uts/intel/io/mc-amd/mcamd_drv.c @@ -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 @@ mc_prop_read_pair(mc_pcicfg_hdl_t cfghdl, uint32_t *r1, off_t r1addr, } } -#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 diff --git a/usr/src/uts/intel/sys/cpu_module.h b/usr/src/uts/intel/sys/cpu_module.h index 2479a011fb..4f7d3fc605 100644 --- a/usr/src/uts/intel/sys/cpu_module.h +++ b/usr/src/uts/intel/sys/cpu_module.h @@ -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 boolean_t cmi_hdl_is_cmt(cmi_hdl_t); 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 *); diff --git a/usr/src/uts/intel/sys/x86_archext.h b/usr/src/uts/intel/sys/x86_archext.h index eebfe5e69c..667b4cc3e2 100644 --- a/usr/src/uts/intel/sys/x86_archext.h +++ b/usr/src/uts/intel/sys/x86_archext.h @@ -506,6 +506,15 @@ extern "C" { _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 @@ extern "C" { #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 @@ extern "C" { #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 int getl2cacheinfo(struct cpu *, int *, int *, int *); 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); |