Print this page
2650 AMD family 0x15 PG support
*** 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 I$ 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: ComputeUnit ID, Intel: coreid */
+ uint_t cpi_cores_per_compunit; /* AMD: # of cores in the ComputeUnit */
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 I$ and L2 caches and the FPU. Enumeration of this feature 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,795 ****
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.
* All processors in the system have the same number of nodes
*/
--- 795,819 ----
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)
! + (cpi->cpi_ncore_per_chip / cpi->cpi_cores_per_compunit)
! * (cpi->cpi_procnodeid / cpi->cpi_procnodes_per_pkg);
! } else if (cpi->cpi_family == 0xf || cpi->cpi_family >= 0x11) {
cpi->cpi_procnodeid = (cpi->cpi_apicid >> coreidsz) & 7;
} else if (cpi->cpi_family == 0x10) {
/*
* See if we are a multi-node processor.
* All processors in the system have the same number of nodes
*/
*** 796,806 ****
nb_caps_reg = pci_getl_func(0, 24, 3, 0xe8);
if ((cpi->cpi_model < 8) || BITX(nb_caps_reg, 29, 29) == 0) {
/* Single-node */
cpi->cpi_procnodeid = BITX(cpi->cpi_apicid, 5,
coreidsz);
- cpi->cpi_chipid = cpi->cpi_procnodeid;
} else {
/*
* Multi-node revision D (2 nodes per package
* are supported)
--- 820,829 ----
*** 811,821 ****
(cpi->cpi_ncore_per_chip/2 - 1));
if (cpi->cpi_apicid == cpi->cpi_pkgcoreid) {
/* We are BSP */
cpi->cpi_procnodeid = (first_half ? 0 : 1);
- cpi->cpi_chipid = cpi->cpi_procnodeid >> 1;
} else {
/* We are AP */
/* NodeId[2:1] bits to use for reading F3xe8 */
node2_1 = BITX(cpi->cpi_apicid, 5, 4) << 1;
--- 834,843 ----
*** 831,851 ****
cpi->cpi_procnodeid = node2_1 +
!first_half;
else
cpi->cpi_procnodeid = node2_1 +
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;
}
}
/*
* Setup XFeature_Enabled_Mask register. Required by xsave feature.
*/
--- 853,870 ----
cpi->cpi_procnodeid = node2_1 +
!first_half;
else
cpi->cpi_procnodeid = node2_1 +
first_half;
}
}
} else {
cpi->cpi_procnodeid = 0;
}
+
+ cpi->cpi_chipid =
+ cpi->cpi_procnodeid / cpi->cpi_procnodes_per_pkg;
}
/*
* Setup XFeature_Enabled_Mask register. Required by xsave feature.
*/
*** 1435,1444 ****
--- 1454,1467 ----
}
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 ****
--- 1566,1576 ----
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 ****
--- 1593,1603 ----
* 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
*** 3002,3011 ****
--- 3027,3050 ----
{
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)