diff options
Diffstat (limited to 'arch/powerpc/kernel/cputable.c')
-rw-r--r-- | arch/powerpc/kernel/cputable.c | 119 |
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 |
34 | extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec); | ||
35 | extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec); | ||
36 | extern void __setup_cpu_440grx(unsigned long offset, struct cpu_spec* spec); | ||
34 | extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec); | 37 | extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec); |
35 | extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec); | 38 | extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec); |
36 | extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec); | 39 | extern 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 | 74 | static 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 | |||
80 | static 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 | ||
1301 | struct cpu_spec *identify_cpu(unsigned long offset, unsigned int pvr) | 1314 | static struct cpu_spec the_cpu_spec; |
1315 | |||
1316 | struct 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(); |