Skip to content

Commit

Permalink
2650 AMD family 0x15 PG support
Browse files Browse the repository at this point in the history
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Approved by: Albert Lee <trisk@nexenta.com>
  • Loading branch information
hrosenfeld committed May 3, 2012
1 parent 2384d9f commit 7660e73
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 14 deletions.
65 changes: 52 additions & 13 deletions usr/src/uts/i86pc/os/cpuid.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ static char *x86_feature_names[NUM_X86_FEATURES] = {
"xsave",
"avx",
"vmx",
"svm"
"svm",
"topoext"
};

boolean_t
Expand Down Expand Up @@ -269,7 +270,7 @@ struct xsave_info {
*/

#define NMAX_CPI_STD 6 /* eax = 0 .. 5 */
#define NMAX_CPI_EXTD 0x1c /* eax = 0x80000000 .. 0x8000001b */
#define NMAX_CPI_EXTD 0x1f /* eax = 0x80000000 .. 0x8000001e */

/*
* Some terminology needs to be explained:
Expand All @@ -283,6 +284,8 @@ struct xsave_info {
* 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 {
Expand Down Expand Up @@ -343,6 +346,8 @@ struct cpuid_info {
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 */
};
Expand Down Expand Up @@ -727,6 +732,7 @@ cpuid_intel_getids(cpu_t *cpu, void *feature)
cpi->cpi_pkgcoreid = 0;
}
cpi->cpi_procnodeid = cpi->cpi_chipid;
cpi->cpi_compunitid = cpi->cpi_coreid;
}

static void
Expand All @@ -736,6 +742,7 @@ cpuid_amd_getids(cpu_t *cpu)
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.
Expand All @@ -753,9 +760,15 @@ cpuid_amd_getids(cpu_t *cpu)
* 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) {

Expand Down Expand Up @@ -784,10 +797,21 @@ cpuid_amd_getids(cpu_t *cpu)
cpi->cpi_apicid & ((1<<coreidsz) - 1);
cpi->cpi_ncpu_per_chip = cpi->cpi_ncore_per_chip;

/* Get nodeID */
if (cpi->cpi_family == 0xf) {
/* 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;
cpi->cpi_chipid = cpi->cpi_procnodeid;
} else if (cpi->cpi_family == 0x10) {
/*
* See if we are a multi-node processor.
Expand All @@ -798,7 +822,6 @@ cpuid_amd_getids(cpu_t *cpu)
/* Single-node */
cpi->cpi_procnodeid = BITX(cpi->cpi_apicid, 5,
coreidsz);
cpi->cpi_chipid = cpi->cpi_procnodeid;
} else {

/*
Expand All @@ -813,7 +836,6 @@ cpuid_amd_getids(cpu_t *cpu)
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 */
Expand All @@ -833,17 +855,14 @@ cpuid_amd_getids(cpu_t *cpu)
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;
}

cpi->cpi_chipid =
cpi->cpi_procnodeid / cpi->cpi_procnodes_per_pkg;
}

/*
Expand Down Expand Up @@ -1437,6 +1456,10 @@ cpuid_pass1(cpu_t *cpu, uchar_t *featureset)
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;
Expand Down Expand Up @@ -1545,6 +1568,7 @@ cpuid_pass1(cpu_t *cpu, uchar_t *featureset)

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) {
/*
Expand All @@ -1571,6 +1595,7 @@ cpuid_pass1(cpu_t *cpu, uchar_t *featureset)
cpi->cpi_coreid = cpi->cpi_chipid;
cpi->cpi_pkgcoreid = 0;
cpi->cpi_procnodeid = cpi->cpi_chipid;
cpi->cpi_compunitid = cpi->cpi_chipid;
}
}

Expand Down Expand Up @@ -3004,6 +3029,20 @@ cpuid_get_procnodes_per_pkg(cpu_t *cpu)
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)
Expand Down
13 changes: 13 additions & 0 deletions usr/src/uts/i86pc/os/mp_machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,11 @@ pg_plat_hw_shared(cpu_t *cp, pghw_type_t hw)
} else {
return (0);
}
case PGHW_FPU:
if (cpuid_get_cores_per_compunit(cp) > 1)
return (1);
else
return (0);
case PGHW_PROCNODE:
if (cpuid_get_procnodes_per_pkg(cp) > 1)
return (1);
Expand Down Expand Up @@ -306,6 +311,8 @@ pg_plat_hw_instance_id(cpu_t *cpu, pghw_type_t hw)
return (cpuid_get_coreid(cpu));
case PGHW_CACHE:
return (cpuid_get_last_lvl_cacheid(cpu));
case PGHW_FPU:
return (cpuid_get_compunitid(cpu));
case PGHW_PROCNODE:
return (cpuid_get_procnodeid(cpu));
case PGHW_CHIP:
Expand All @@ -331,6 +338,7 @@ pg_plat_hw_rank(pghw_type_t hw1, pghw_type_t hw2)
static pghw_type_t hw_hier[] = {
PGHW_IPIPE,
PGHW_CACHE,
PGHW_FPU,
PGHW_PROCNODE,
PGHW_CHIP,
PGHW_POW_IDLE,
Expand Down Expand Up @@ -361,8 +369,13 @@ pg_plat_cmt_policy(pghw_type_t hw)
/*
* For shared caches, also load balance across them to
* maximize aggregate cache capacity
*
* On AMD family 0x15 CPUs, cores come in pairs called
* compute units, sharing the FPU and the I$ and L2
* caches. Use balancing and cache affinity.
*/
switch (hw) {
case PGHW_FPU:
case PGHW_CACHE:
return (CMT_BALANCE|CMT_AFFINITY);
default:
Expand Down
7 changes: 6 additions & 1 deletion usr/src/uts/intel/sys/x86_archext.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,11 @@ extern "C" {
#define CPUID_AMD_ECX_SSE5 0x00000800 /* AMD: SSE5 */
#define CPUID_AMD_ECX_SKINIT 0x00001000 /* AMD: SKINIT */
#define CPUID_AMD_ECX_WDT 0x00002000 /* AMD: WDT */
#define CPUID_AMD_ECX_TOPOEXT 0x00400000 /* AMD: Topology Extensions */

#define FMT_CPUID_AMD_ECX \
"\20" \
"\22topoext" \
"\14wdt\13skinit\12sse5\11ibs\10osvw\93dnp\8mas" \
"\7sse4a\6lzcnt\5cr8d\3svm\2lcmplgcy\1ahf64"

Expand Down Expand Up @@ -368,6 +370,7 @@ extern "C" {
#define X86FSET_AVX 34
#define X86FSET_VMX 35
#define X86FSET_SVM 36
#define X86FSET_TOPOEXT 37

/*
* flags to patch tsc_read routine.
Expand Down Expand Up @@ -591,7 +594,7 @@ extern "C" {

#if defined(_KERNEL) || defined(_KMEMUSER)

#define NUM_X86_FEATURES 37
#define NUM_X86_FEATURES 38
extern uchar_t x86_featureset[];

extern void free_x86_featureset(void *featureset);
Expand Down Expand Up @@ -676,6 +679,8 @@ extern int cpuid_get_cacheid(struct cpu *);
extern uint32_t cpuid_get_apicid(struct cpu *);
extern uint_t cpuid_get_procnodeid(struct cpu *cpu);
extern uint_t cpuid_get_procnodes_per_pkg(struct cpu *cpu);
extern uint_t cpuid_get_compunitid(struct cpu *cpu);
extern uint_t cpuid_get_cores_per_compunit(struct cpu *cpu);
extern int cpuid_is_cmt(struct cpu *);
extern int cpuid_syscall32_insn(struct cpu *);
extern int getl2cacheinfo(struct cpu *, int *, int *, int *);
Expand Down

0 comments on commit 7660e73

Please sign in to comment.