diff options
author | Andreas Herrmann <andreas.herrmann3@amd.com> | 2010-09-30 08:36:28 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2010-10-01 19:18:32 -0400 |
commit | 23588c38a84c9175c6668789b64ffba4651e5c6a (patch) | |
tree | ec6076af69e7b4131c9ade3f00e3a60f073ab42b | |
parent | 420b13b60a3e5c5dcc6ec290e131cf5fbc603d94 (diff) |
x86, amd: Add support for CPUID topology extension of AMD CPUs
Node information (ID, number of internal nodes) is provided via
CPUID Fn8000_001e_ECX.
See AMD CPUID Specification (Publication # 25481, Revision 2.34,
September 2010).
Signed-off-by: Andreas Herrmann <andreas.herrmann3@amd.com>
LKML-Reference: <20100930123628.GD20545@loge.amd.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r-- | arch/x86/kernel/cpu/amd.c | 50 |
1 files changed, 26 insertions, 24 deletions
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 0f0ace5d7db5..7e6a37d24253 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -253,37 +253,41 @@ static int __cpuinit nearby_node(int apicid) | |||
253 | #endif | 253 | #endif |
254 | 254 | ||
255 | /* | 255 | /* |
256 | * Fixup core topology information for AMD multi-node processors. | 256 | * Fixup core topology information for |
257 | * Assumption: Number of cores in each internal node is the same. | 257 | * (1) AMD multi-node processors |
258 | * Assumption: Number of cores in each internal node is the same. | ||
258 | */ | 259 | */ |
259 | #ifdef CONFIG_X86_HT | 260 | #ifdef CONFIG_X86_HT |
260 | static void __cpuinit amd_fixup_dcm(struct cpuinfo_x86 *c) | 261 | static void __cpuinit amd_get_topology(struct cpuinfo_x86 *c) |
261 | { | 262 | { |
262 | unsigned long long value; | ||
263 | u32 nodes, cores_per_node; | 263 | u32 nodes, cores_per_node; |
264 | u8 node_id; | ||
265 | unsigned long long value; | ||
264 | int cpu = smp_processor_id(); | 266 | int cpu = smp_processor_id(); |
265 | 267 | ||
266 | if (!cpu_has(c, X86_FEATURE_NODEID_MSR)) | 268 | /* get information required for multi-node processors */ |
267 | return; | 269 | if (cpu_has(c, X86_FEATURE_TOPOEXT)) { |
268 | 270 | value = cpuid_ecx(0x8000001e); | |
269 | /* fixup topology information only once for a core */ | 271 | nodes = ((value >> 8) & 7) + 1; |
270 | if (cpu_has(c, X86_FEATURE_AMD_DCM)) | 272 | node_id = value & 7; |
273 | } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) { | ||
274 | rdmsrl(MSR_FAM10H_NODE_ID, value); | ||
275 | nodes = ((value >> 3) & 7) + 1; | ||
276 | node_id = value & 7; | ||
277 | } else | ||
271 | return; | 278 | return; |
272 | 279 | ||
273 | rdmsrl(MSR_FAM10H_NODE_ID, value); | 280 | /* fixup multi-node processor information */ |
281 | if (nodes > 1) { | ||
282 | set_cpu_cap(c, X86_FEATURE_AMD_DCM); | ||
283 | cores_per_node = c->x86_max_cores / nodes; | ||
274 | 284 | ||
275 | nodes = ((value >> 3) & 7) + 1; | 285 | /* store NodeID, use llc_shared_map to store sibling info */ |
276 | if (nodes == 1) | 286 | per_cpu(cpu_llc_id, cpu) = node_id; |
277 | return; | ||
278 | |||
279 | set_cpu_cap(c, X86_FEATURE_AMD_DCM); | ||
280 | cores_per_node = c->x86_max_cores / nodes; | ||
281 | 287 | ||
282 | /* store NodeID, use llc_shared_map to store sibling info */ | 288 | /* core id to be in range from 0 to (cores_per_node - 1) */ |
283 | per_cpu(cpu_llc_id, cpu) = value & 7; | 289 | c->cpu_core_id = c->cpu_core_id % cores_per_node; |
284 | 290 | } | |
285 | /* fixup core id to be in range from 0 to (cores_per_node - 1) */ | ||
286 | c->cpu_core_id = c->cpu_core_id % cores_per_node; | ||
287 | } | 291 | } |
288 | #endif | 292 | #endif |
289 | 293 | ||
@@ -304,9 +308,7 @@ static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c) | |||
304 | c->phys_proc_id = c->initial_apicid >> bits; | 308 | c->phys_proc_id = c->initial_apicid >> bits; |
305 | /* use socket ID also for last level cache */ | 309 | /* use socket ID also for last level cache */ |
306 | per_cpu(cpu_llc_id, cpu) = c->phys_proc_id; | 310 | per_cpu(cpu_llc_id, cpu) = c->phys_proc_id; |
307 | /* fixup topology information on multi-node processors */ | 311 | amd_get_topology(c); |
308 | if ((c->x86 == 0x10) && (c->x86_model == 9)) | ||
309 | amd_fixup_dcm(c); | ||
310 | #endif | 312 | #endif |
311 | } | 313 | } |
312 | 314 | ||