Print this page
*** NO COMMENTS ***

*** 158,168 **** "aes", "pclmulqdq", "xsave", "avx", "vmx", ! "svm" }; boolean_t is_x86_feature(void *featureset, uint_t feature) { --- 158,169 ---- "aes", "pclmulqdq", "xsave", "avx", "vmx", ! "svm", ! "topoext" }; boolean_t is_x86_feature(void *featureset, uint_t feature) {
*** 267,277 **** * cpuid we cache in the cpuid_info data structure; the * remaining elements are accessible via the cpuid instruction. */ #define NMAX_CPI_STD 6 /* eax = 0 .. 5 */ ! #define NMAX_CPI_EXTD 0x1c /* eax = 0x80000000 .. 0x8000001b */ /* * Some terminology needs to be explained: * - Socket: Something that can be plugged into a motherboard. * - Package: Same as socket --- 268,278 ---- * cpuid we cache in the cpuid_info data structure; the * remaining elements are accessible via the cpuid instruction. */ #define NMAX_CPI_STD 6 /* eax = 0 .. 5 */ ! #define NMAX_CPI_EXTD 0x1f /* eax = 0x80000000 .. 0x8000001e */ /* * Some terminology needs to be explained: * - Socket: Something that can be plugged into a motherboard. * - Package: Same as socket
*** 281,290 **** --- 282,293 ---- * "subprocessor" embedded in a package. These subprocessors (nodes) * are fully-functional processors themselves with cores, caches, * memory controllers, PCI configuration spaces. They are connected * inside the package with Hypertransport links. On single-node * processors, processor node is equivalent to chip/socket/package. + * - Compute Unit: Some AMD processors pair cores in "compute units" that + * share the FPU and the L1I and L2 caches. */ struct cpuid_info { uint_t cpi_pass; /* last pass completed */ /*
*** 341,350 **** --- 344,355 ---- struct mwait_info cpi_mwait; /* fn 5: monitor/mwait info */ uint32_t cpi_apicid; uint_t cpi_procnodeid; /* AMD: nodeID on HT, Intel: chipid */ uint_t cpi_procnodes_per_pkg; /* AMD: # of nodes in the package */ /* Intel: 1 */ + uint_t cpi_compunitid; /* AMD: compute unit ID, Intel: coreid */ + uint_t cpi_cores_per_compunit; /* AMD: # of cores in the compute unit */ struct xsave_info cpi_xsave; /* fn D: xsave/xrestor info */ };
*** 725,743 **** --- 730,750 ---- */ cpi->cpi_coreid = cpi->cpi_chipid; cpi->cpi_pkgcoreid = 0; } cpi->cpi_procnodeid = cpi->cpi_chipid; + cpi->cpi_compunitid = cpi->cpi_coreid; } static void cpuid_amd_getids(cpu_t *cpu) { int i, first_half, coreidsz; uint32_t nb_caps_reg; uint_t node2_1; struct cpuid_info *cpi = cpu->cpu_m.mcpu_cpi; + struct cpuid_regs *cp; /* * AMD CMP chips currently have a single thread per core. * * Since no two cpus share a core we must assign a distinct coreid
*** 751,763 **** --- 758,776 ---- * All processors in the system have the same number of enabled * cores. Cores within a processor are always numbered sequentially * from 0 regardless of how many or which are disabled, and there * is no way for operating system to discover the real core id when some * are disabled. + * + * In family 0x15, the cores come in pairs called compute units. They + * share L1I and L2 caches and the FPU. Enumeration of this features is + * simplified by the new topology extensions CPUID leaf, indicated by the + * X86 feature X86FSET_TOPOEXT. */ cpi->cpi_coreid = cpu->cpu_id; + cpi->cpi_compunitid = cpu->cpu_id; if (cpi->cpi_xmaxeax >= 0x80000008) { coreidsz = BITX((cpi)->cpi_extd[8].cp_ecx, 15, 12);
*** 782,793 **** cpi->cpi_clogid = cpi->cpi_pkgcoreid = cpi->cpi_apicid & ((1<<coreidsz) - 1); cpi->cpi_ncpu_per_chip = cpi->cpi_ncore_per_chip; ! /* Get nodeID */ ! if (cpi->cpi_family == 0xf) { cpi->cpi_procnodeid = (cpi->cpi_apicid >> coreidsz) & 7; cpi->cpi_chipid = cpi->cpi_procnodeid; } else if (cpi->cpi_family == 0x10) { /* * See if we are a multi-node processor. --- 795,816 ---- cpi->cpi_clogid = cpi->cpi_pkgcoreid = cpi->cpi_apicid & ((1<<coreidsz) - 1); cpi->cpi_ncpu_per_chip = cpi->cpi_ncore_per_chip; ! /* Get node ID, compute unit ID */ ! if (is_x86_feature(x86_featureset, X86FSET_TOPOEXT) && ! cpi->cpi_xmaxeax >= 0x8000001e) { ! cp = &cpi->cpi_extd[0x1e]; ! cp->cp_eax = 0x8000001e; ! (void) __cpuid_insn(cp); ! ! cpi->cpi_procnodes_per_pkg = BITX(cp->cp_ecx, 10, 8) + 1; ! cpi->cpi_procnodeid = BITX(cp->cp_ecx, 7, 0); ! cpi->cpi_cores_per_compunit = BITX(cp->cp_ebx, 15, 8) + 1; ! cpi->cpi_compunitid = BITX(cp->cp_ebx, 7, 0); ! } else if (cpi->cpi_family == 0xf || cpi->cpi_family >= 0x11) { cpi->cpi_procnodeid = (cpi->cpi_apicid >> coreidsz) & 7; cpi->cpi_chipid = cpi->cpi_procnodeid; } else if (cpi->cpi_family == 0x10) { /* * See if we are a multi-node processor.
*** 835,847 **** first_half; cpi->cpi_chipid = cpi->cpi_procnodeid >> 1; } } - } else if (cpi->cpi_family >= 0x11) { - cpi->cpi_procnodeid = (cpi->cpi_apicid >> coreidsz) & 7; - cpi->cpi_chipid = cpi->cpi_procnodeid; } else { cpi->cpi_procnodeid = 0; cpi->cpi_chipid = cpi->cpi_procnodeid; } } --- 858,867 ----
*** 1435,1444 **** --- 1455,1468 ---- } if (cp->cp_ecx & CPUID_AMD_ECX_SVM) { add_x86_feature(featureset, X86FSET_SVM); } + + if (cp->cp_ecx & CPUID_AMD_ECX_TOPOEXT) { + add_x86_feature(featureset, X86FSET_TOPOEXT); + } break; default: break; }
*** 1543,1552 **** --- 1567,1577 ---- remove_x86_feature(featureset, X86FSET_HTT); } cpi->cpi_apicid = CPI_APIC_ID(cpi); cpi->cpi_procnodes_per_pkg = 1; + cpi->cpi_cores_per_compunit = 1; if (is_x86_feature(featureset, X86FSET_HTT) == B_FALSE && is_x86_feature(featureset, X86FSET_CMP) == B_FALSE) { /* * Single-core single-threaded processors. */
*** 1569,1578 **** --- 1594,1604 ---- * assumed to have single cores. */ cpi->cpi_coreid = cpi->cpi_chipid; cpi->cpi_pkgcoreid = 0; cpi->cpi_procnodeid = cpi->cpi_chipid; + cpi->cpi_compunitid = cpi->cpi_chipid; } } /* * Synthesize chip "revision" and socket type
*** 2998,3007 **** --- 3024,3047 ---- { ASSERT(cpuid_checkpass(cpu, 1)); return (cpu->cpu_m.mcpu_cpi->cpi_procnodes_per_pkg); } + uint_t + cpuid_get_compunitid(cpu_t *cpu) + { + ASSERT(cpuid_checkpass(cpu, 1)); + return (cpu->cpu_m.mcpu_cpi->cpi_compunitid); + } + + uint_t + cpuid_get_cores_per_compunit(cpu_t *cpu) + { + ASSERT(cpuid_checkpass(cpu, 1)); + return (cpu->cpu_m.mcpu_cpi->cpi_cores_per_compunit); + } + /*ARGSUSED*/ int cpuid_have_cr8access(cpu_t *cpu) { #if defined(__amd64)