aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/cputable.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-11-10 04:38:53 -0500
committerPaul Mackerras <paulus@samba.org>2006-12-04 04:40:16 -0500
commit974a76f51355d22f4f63d83d6bb1ccecd019ec58 (patch)
tree9a6c5745d8e1f592427d96fbf64d8546af4feb39 /arch/powerpc/kernel/cputable.c
parent18f2190d796198fbb5d4bc4c87511acf3ced7d47 (diff)
[POWERPC] Distinguish POWER6 partition modes and tell userspace
This adds code to look at the properties firmware puts in the device tree to determine what compatibility mode the partition is in on POWER6 machines, and set the ELF aux vector AT_HWCAP and AT_PLATFORM entries appropriately. Specifically, we look at the cpu-version property in the cpu node(s). If that contains a "logical" PVR value (of the form 0x0f00000x), we call identify_cpu again with this PVR value. A value of 0x0f000001 indicates the partition is in POWER5+ compatibility mode, and a value of 0x0f000002 indicates "POWER6 architected" mode, with various extensions disabled. We also look for various other properties: ibm,dfp, ibm,purr and ibm,spurr. Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/cputable.c')
-rw-r--r--arch/powerpc/kernel/cputable.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 992121b2d261..911ac442f44a 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -277,10 +277,45 @@ static struct cpu_spec cpu_specs[] = {
277 .oprofile_mmcra_sipr = MMCRA_SIPR, 277 .oprofile_mmcra_sipr = MMCRA_SIPR,
278 .platform = "power5+", 278 .platform = "power5+",
279 }, 279 },
280 { /* POWER6 in P5+ mode; 2.04-compliant processor */
281 .pvr_mask = 0xffffffff,
282 .pvr_value = 0x0f000001,
283 .cpu_name = "POWER5+",
284 .cpu_features = CPU_FTRS_POWER5,
285 .cpu_user_features = COMMON_USER_POWER5_PLUS,
286 .icache_bsize = 128,
287 .dcache_bsize = 128,
288 .num_pmcs = 6,
289 .oprofile_cpu_type = "ppc64/power6",
290 .oprofile_type = PPC_OPROFILE_POWER4,
291 .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV,
292 .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR,
293 .oprofile_mmcra_clear = POWER6_MMCRA_THRM |
294 POWER6_MMCRA_OTHER,
295 .platform = "power5+",
296 },
280 { /* Power6 */ 297 { /* Power6 */
281 .pvr_mask = 0xffff0000, 298 .pvr_mask = 0xffff0000,
282 .pvr_value = 0x003e0000, 299 .pvr_value = 0x003e0000,
283 .cpu_name = "POWER6", 300 .cpu_name = "POWER6 (raw)",
301 .cpu_features = CPU_FTRS_POWER6,
302 .cpu_user_features = COMMON_USER_POWER6 |
303 PPC_FEATURE_POWER6_EXT,
304 .icache_bsize = 128,
305 .dcache_bsize = 128,
306 .num_pmcs = 6,
307 .oprofile_cpu_type = "ppc64/power6",
308 .oprofile_type = PPC_OPROFILE_POWER4,
309 .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV,
310 .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR,
311 .oprofile_mmcra_clear = POWER6_MMCRA_THRM |
312 POWER6_MMCRA_OTHER,
313 .platform = "power6x",
314 },
315 { /* 2.05-compliant processor, i.e. Power6 "architected" mode */
316 .pvr_mask = 0xffffffff,
317 .pvr_value = 0x0f000002,
318 .cpu_name = "POWER6 (architected)",
284 .cpu_features = CPU_FTRS_POWER6, 319 .cpu_features = CPU_FTRS_POWER6,
285 .cpu_user_features = COMMON_USER_POWER6, 320 .cpu_user_features = COMMON_USER_POWER6,
286 .icache_bsize = 128, 321 .icache_bsize = 128,
@@ -1173,19 +1208,15 @@ static struct cpu_spec cpu_specs[] = {
1173#endif /* CONFIG_PPC32 */ 1208#endif /* CONFIG_PPC32 */
1174}; 1209};
1175 1210
1176struct cpu_spec *identify_cpu(unsigned long offset) 1211struct cpu_spec *identify_cpu(unsigned long offset, unsigned int pvr)
1177{ 1212{
1178 struct cpu_spec *s = cpu_specs; 1213 struct cpu_spec *s = cpu_specs;
1179 struct cpu_spec **cur = &cur_cpu_spec; 1214 struct cpu_spec **cur = &cur_cpu_spec;
1180 unsigned int pvr = mfspr(SPRN_PVR);
1181 int i; 1215 int i;
1182 1216
1183 s = PTRRELOC(s); 1217 s = PTRRELOC(s);
1184 cur = PTRRELOC(cur); 1218 cur = PTRRELOC(cur);
1185 1219
1186 if (*cur != NULL)
1187 return PTRRELOC(*cur);
1188
1189 for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) 1220 for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++)
1190 if ((pvr & s->pvr_mask) == s->pvr_value) { 1221 if ((pvr & s->pvr_mask) == s->pvr_value) {
1191 *cur = cpu_specs + i; 1222 *cur = cpu_specs + i;