aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/cputable.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/cputable.c')
-rw-r--r--arch/powerpc/kernel/cputable.c119
1 files changed, 76 insertions, 43 deletions
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index b1f8000952f3..d3fb7d0c6c1c 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -31,6 +31,9 @@ EXPORT_SYMBOL(cur_cpu_spec);
31 * and ppc64 31 * and ppc64
32 */ 32 */
33#ifdef CONFIG_PPC32 33#ifdef CONFIG_PPC32
34extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec);
35extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec);
36extern void __setup_cpu_440grx(unsigned long offset, struct cpu_spec* spec);
34extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec); 37extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
35extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec); 38extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
36extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec); 39extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
@@ -68,16 +71,7 @@ extern void __restore_cpu_ppc970(void);
68#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \ 71#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
69 PPC_FEATURE_BOOKE) 72 PPC_FEATURE_BOOKE)
70 73
71/* We only set the spe features if the kernel was compiled with 74static struct cpu_spec __initdata cpu_specs[] = {
72 * spe support
73 */
74#ifdef CONFIG_SPE
75#define PPC_FEATURE_SPE_COMP PPC_FEATURE_HAS_SPE
76#else
77#define PPC_FEATURE_SPE_COMP 0
78#endif
79
80static struct cpu_spec cpu_specs[] = {
81#ifdef CONFIG_PPC64 75#ifdef CONFIG_PPC64
82 { /* Power3 */ 76 { /* Power3 */
83 .pvr_mask = 0xffff0000, 77 .pvr_mask = 0xffff0000,
@@ -333,14 +327,6 @@ static struct cpu_spec cpu_specs[] = {
333 .cpu_user_features = COMMON_USER_POWER5_PLUS, 327 .cpu_user_features = COMMON_USER_POWER5_PLUS,
334 .icache_bsize = 128, 328 .icache_bsize = 128,
335 .dcache_bsize = 128, 329 .dcache_bsize = 128,
336 .num_pmcs = 6,
337 .pmc_type = PPC_PMC_IBM,
338 .oprofile_cpu_type = "ppc64/power6",
339 .oprofile_type = PPC_OPROFILE_POWER4,
340 .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV,
341 .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR,
342 .oprofile_mmcra_clear = POWER6_MMCRA_THRM |
343 POWER6_MMCRA_OTHER,
344 .platform = "power5+", 330 .platform = "power5+",
345 }, 331 },
346 { /* Power6 */ 332 { /* Power6 */
@@ -370,14 +356,6 @@ static struct cpu_spec cpu_specs[] = {
370 .cpu_user_features = COMMON_USER_POWER6, 356 .cpu_user_features = COMMON_USER_POWER6,
371 .icache_bsize = 128, 357 .icache_bsize = 128,
372 .dcache_bsize = 128, 358 .dcache_bsize = 128,
373 .num_pmcs = 6,
374 .pmc_type = PPC_PMC_IBM,
375 .oprofile_cpu_type = "ppc64/power6",
376 .oprofile_type = PPC_OPROFILE_POWER4,
377 .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV,
378 .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR,
379 .oprofile_mmcra_clear = POWER6_MMCRA_THRM |
380 POWER6_MMCRA_OTHER,
381 .platform = "power6", 359 .platform = "power6",
382 }, 360 },
383 { /* Cell Broadband Engine */ 361 { /* Cell Broadband Engine */
@@ -1109,6 +1087,17 @@ static struct cpu_spec cpu_specs[] = {
1109 .dcache_bsize = 32, 1087 .dcache_bsize = 32,
1110 .platform = "ppc405", 1088 .platform = "ppc405",
1111 }, 1089 },
1090 { /* 405EX */
1091 .pvr_mask = 0xffff0000,
1092 .pvr_value = 0x12910000,
1093 .cpu_name = "405EX",
1094 .cpu_features = CPU_FTRS_40X,
1095 .cpu_user_features = PPC_FEATURE_32 |
1096 PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
1097 .icache_bsize = 32,
1098 .dcache_bsize = 32,
1099 .platform = "ppc405",
1100 },
1112 1101
1113#endif /* CONFIG_40x */ 1102#endif /* CONFIG_40x */
1114#ifdef CONFIG_44x 1103#ifdef CONFIG_44x
@@ -1120,6 +1109,7 @@ static struct cpu_spec cpu_specs[] = {
1120 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, 1109 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
1121 .icache_bsize = 32, 1110 .icache_bsize = 32,
1122 .dcache_bsize = 32, 1111 .dcache_bsize = 32,
1112 .cpu_setup = __setup_cpu_440ep,
1123 .platform = "ppc440", 1113 .platform = "ppc440",
1124 }, 1114 },
1125 { 1115 {
@@ -1130,6 +1120,29 @@ static struct cpu_spec cpu_specs[] = {
1130 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, 1120 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
1131 .icache_bsize = 32, 1121 .icache_bsize = 32,
1132 .dcache_bsize = 32, 1122 .dcache_bsize = 32,
1123 .cpu_setup = __setup_cpu_440ep,
1124 .platform = "ppc440",
1125 },
1126 { /* 440EPX */
1127 .pvr_mask = 0xf0000ffb,
1128 .pvr_value = 0x200008D0,
1129 .cpu_name = "440EPX",
1130 .cpu_features = CPU_FTRS_44X,
1131 .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
1132 .icache_bsize = 32,
1133 .dcache_bsize = 32,
1134 .cpu_setup = __setup_cpu_440epx,
1135 .platform = "ppc440",
1136 },
1137 { /* 440GRX */
1138 .pvr_mask = 0xf0000ffb,
1139 .pvr_value = 0x200008D8,
1140 .cpu_name = "440GRX",
1141 .cpu_features = CPU_FTRS_44X,
1142 .cpu_user_features = COMMON_USER_BOOKE,
1143 .icache_bsize = 32,
1144 .dcache_bsize = 32,
1145 .cpu_setup = __setup_cpu_440grx,
1133 .platform = "ppc440", 1146 .platform = "ppc440",
1134 }, 1147 },
1135 { /* 440GP Rev. B */ 1148 { /* 440GP Rev. B */
@@ -1243,8 +1256,8 @@ static struct cpu_spec cpu_specs[] = {
1243 /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ 1256 /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
1244 .cpu_features = CPU_FTRS_E200, 1257 .cpu_features = CPU_FTRS_E200,
1245 .cpu_user_features = COMMON_USER_BOOKE | 1258 .cpu_user_features = COMMON_USER_BOOKE |
1246 PPC_FEATURE_SPE_COMP | 1259 PPC_FEATURE_HAS_SPE_COMP |
1247 PPC_FEATURE_HAS_EFP_SINGLE | 1260 PPC_FEATURE_HAS_EFP_SINGLE_COMP |
1248 PPC_FEATURE_UNIFIED_CACHE, 1261 PPC_FEATURE_UNIFIED_CACHE,
1249 .dcache_bsize = 32, 1262 .dcache_bsize = 32,
1250 .platform = "ppc5554", 1263 .platform = "ppc5554",
@@ -1256,8 +1269,8 @@ static struct cpu_spec cpu_specs[] = {
1256 /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ 1269 /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
1257 .cpu_features = CPU_FTRS_E500, 1270 .cpu_features = CPU_FTRS_E500,
1258 .cpu_user_features = COMMON_USER_BOOKE | 1271 .cpu_user_features = COMMON_USER_BOOKE |
1259 PPC_FEATURE_SPE_COMP | 1272 PPC_FEATURE_HAS_SPE_COMP |
1260 PPC_FEATURE_HAS_EFP_SINGLE, 1273 PPC_FEATURE_HAS_EFP_SINGLE_COMP,
1261 .icache_bsize = 32, 1274 .icache_bsize = 32,
1262 .dcache_bsize = 32, 1275 .dcache_bsize = 32,
1263 .num_pmcs = 4, 1276 .num_pmcs = 4,
@@ -1272,9 +1285,9 @@ static struct cpu_spec cpu_specs[] = {
1272 /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */ 1285 /* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
1273 .cpu_features = CPU_FTRS_E500_2, 1286 .cpu_features = CPU_FTRS_E500_2,
1274 .cpu_user_features = COMMON_USER_BOOKE | 1287 .cpu_user_features = COMMON_USER_BOOKE |
1275 PPC_FEATURE_SPE_COMP | 1288 PPC_FEATURE_HAS_SPE_COMP |
1276 PPC_FEATURE_HAS_EFP_SINGLE | 1289 PPC_FEATURE_HAS_EFP_SINGLE_COMP |
1277 PPC_FEATURE_HAS_EFP_DOUBLE, 1290 PPC_FEATURE_HAS_EFP_DOUBLE_COMP,
1278 .icache_bsize = 32, 1291 .icache_bsize = 32,
1279 .dcache_bsize = 32, 1292 .dcache_bsize = 32,
1280 .num_pmcs = 4, 1293 .num_pmcs = 4,
@@ -1298,29 +1311,49 @@ static struct cpu_spec cpu_specs[] = {
1298#endif /* CONFIG_PPC32 */ 1311#endif /* CONFIG_PPC32 */
1299}; 1312};
1300 1313
1301struct cpu_spec *identify_cpu(unsigned long offset, unsigned int pvr) 1314static struct cpu_spec the_cpu_spec;
1315
1316struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr)
1302{ 1317{
1303 struct cpu_spec *s = cpu_specs; 1318 struct cpu_spec *s = cpu_specs;
1304 struct cpu_spec **cur = &cur_cpu_spec; 1319 struct cpu_spec *t = &the_cpu_spec;
1305 int i; 1320 int i;
1306 1321
1307 s = PTRRELOC(s); 1322 s = PTRRELOC(s);
1308 cur = PTRRELOC(cur); 1323 t = PTRRELOC(t);
1309 1324
1310 for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) 1325 for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++)
1311 if ((pvr & s->pvr_mask) == s->pvr_value) { 1326 if ((pvr & s->pvr_mask) == s->pvr_value) {
1312 *cur = cpu_specs + i; 1327 /*
1313#ifdef CONFIG_PPC64 1328 * If we are overriding a previous value derived
1314 /* ppc64 expects identify_cpu to also call setup_cpu 1329 * from the real PVR with a new value obtained
1315 * for that processor. I will consolidate that at a 1330 * using a logical PVR value, don't modify the
1316 * later time, for now, just use our friend #ifdef. 1331 * performance monitor fields.
1332 */
1333 if (t->num_pmcs && !s->num_pmcs) {
1334 t->cpu_name = s->cpu_name;
1335 t->cpu_features = s->cpu_features;
1336 t->cpu_user_features = s->cpu_user_features;
1337 t->icache_bsize = s->icache_bsize;
1338 t->dcache_bsize = s->dcache_bsize;
1339 t->cpu_setup = s->cpu_setup;
1340 t->cpu_restore = s->cpu_restore;
1341 t->platform = s->platform;
1342 } else
1343 *t = *s;
1344 *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
1345#if defined(CONFIG_PPC64) || defined(CONFIG_BOOKE)
1346 /* ppc64 and booke expect identify_cpu to also call
1347 * setup_cpu for that processor. I will consolidate
1348 * that at a later time, for now, just use #ifdef.
1317 * we also don't need to PTRRELOC the function pointer 1349 * we also don't need to PTRRELOC the function pointer
1318 * on ppc64 as we are running at 0 in real mode. 1350 * on ppc64 and booke as we are running at 0 in real
1351 * mode on ppc64 and reloc_offset is always 0 on booke.
1319 */ 1352 */
1320 if (s->cpu_setup) { 1353 if (s->cpu_setup) {
1321 s->cpu_setup(offset, s); 1354 s->cpu_setup(offset, s);
1322 } 1355 }
1323#endif /* CONFIG_PPC64 */ 1356#endif /* CONFIG_PPC64 || CONFIG_BOOKE */
1324 return s; 1357 return s;
1325 } 1358 }
1326 BUG(); 1359 BUG();