aboutsummaryrefslogtreecommitdiff
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 b1f8000952f..d3fb7d0c6c1 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -31,6 +31,9 @@ EXPORT_SYMBOL(cur_cpu_spec);
* and ppc64
*/
#ifdef CONFIG_PPC32
+extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_440grx(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec);
extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec);
@@ -68,16 +71,7 @@ extern void __restore_cpu_ppc970(void);
#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
PPC_FEATURE_BOOKE)
-/* We only set the spe features if the kernel was compiled with
- * spe support
- */
-#ifdef CONFIG_SPE
-#define PPC_FEATURE_SPE_COMP PPC_FEATURE_HAS_SPE
-#else
-#define PPC_FEATURE_SPE_COMP 0
-#endif
-
-static struct cpu_spec cpu_specs[] = {
+static struct cpu_spec __initdata cpu_specs[] = {
#ifdef CONFIG_PPC64
{ /* Power3 */
.pvr_mask = 0xffff0000,
@@ -333,14 +327,6 @@ static struct cpu_spec cpu_specs[] = {
.cpu_user_features = COMMON_USER_POWER5_PLUS,
.icache_bsize = 128,
.dcache_bsize = 128,
- .num_pmcs = 6,
- .pmc_type = PPC_PMC_IBM,
- .oprofile_cpu_type = "ppc64/power6",
- .oprofile_type = PPC_OPROFILE_POWER4,
- .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV,
- .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR,
- .oprofile_mmcra_clear = POWER6_MMCRA_THRM |
- POWER6_MMCRA_OTHER,
.platform = "power5+",
},
{ /* Power6 */
@@ -370,14 +356,6 @@ static struct cpu_spec cpu_specs[] = {
.cpu_user_features = COMMON_USER_POWER6,
.icache_bsize = 128,
.dcache_bsize = 128,
- .num_pmcs = 6,
- .pmc_type = PPC_PMC_IBM,
- .oprofile_cpu_type = "ppc64/power6",
- .oprofile_type = PPC_OPROFILE_POWER4,
- .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV,
- .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR,
- .oprofile_mmcra_clear = POWER6_MMCRA_THRM |
- POWER6_MMCRA_OTHER,
.platform = "power6",
},
{ /* Cell Broadband Engine */
@@ -1109,6 +1087,17 @@ static struct cpu_spec cpu_specs[] = {
.dcache_bsize = 32,
.platform = "ppc405",
},
+ { /* 405EX */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x12910000,
+ .cpu_name = "405EX",
+ .cpu_features = CPU_FTRS_40X,
+ .cpu_user_features = PPC_FEATURE_32 |
+ PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ .icache_bsize = 32,
+ .dcache_bsize = 32,
+ .platform = "ppc405",
+ },
#endif /* CONFIG_40x */
#ifdef CONFIG_44x
@@ -1120,6 +1109,7 @@ static struct cpu_spec cpu_specs[] = {
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
.icache_bsize = 32,
.dcache_bsize = 32,
+ .cpu_setup = __setup_cpu_440ep,
.platform = "ppc440",
},
{
@@ -1130,6 +1120,29 @@ static struct cpu_spec cpu_specs[] = {
.cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
.icache_bsize = 32,
.dcache_bsize = 32,
+ .cpu_setup = __setup_cpu_440ep,
+ .platform = "ppc440",
+ },
+ { /* 440EPX */
+ .pvr_mask = 0xf0000ffb,
+ .pvr_value = 0x200008D0,
+ .cpu_name = "440EPX",
+ .cpu_features = CPU_FTRS_44X,
+ .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
+ .icache_bsize = 32,
+ .dcache_bsize = 32,
+ .cpu_setup = __setup_cpu_440epx,
+ .platform = "ppc440",
+ },
+ { /* 440GRX */
+ .pvr_mask = 0xf0000ffb,
+ .pvr_value = 0x200008D8,
+ .cpu_name = "440GRX",
+ .cpu_features = CPU_FTRS_44X,
+ .cpu_user_features = COMMON_USER_BOOKE,
+ .icache_bsize = 32,
+ .dcache_bsize = 32,
+ .cpu_setup = __setup_cpu_440grx,
.platform = "ppc440",
},
{ /* 440GP Rev. B */
@@ -1243,8 +1256,8 @@ static struct cpu_spec cpu_specs[] = {
/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
.cpu_features = CPU_FTRS_E200,
.cpu_user_features = COMMON_USER_BOOKE |
- PPC_FEATURE_SPE_COMP |
- PPC_FEATURE_HAS_EFP_SINGLE |
+ PPC_FEATURE_HAS_SPE_COMP |
+ PPC_FEATURE_HAS_EFP_SINGLE_COMP |
PPC_FEATURE_UNIFIED_CACHE,
.dcache_bsize = 32,
.platform = "ppc5554",
@@ -1256,8 +1269,8 @@ static struct cpu_spec cpu_specs[] = {
/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
.cpu_features = CPU_FTRS_E500,
.cpu_user_features = COMMON_USER_BOOKE |
- PPC_FEATURE_SPE_COMP |
- PPC_FEATURE_HAS_EFP_SINGLE,
+ PPC_FEATURE_HAS_SPE_COMP |
+ PPC_FEATURE_HAS_EFP_SINGLE_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -1272,9 +1285,9 @@ static struct cpu_spec cpu_specs[] = {
/* xxx - galak: add CPU_FTR_MAYBE_CAN_DOZE */
.cpu_features = CPU_FTRS_E500_2,
.cpu_user_features = COMMON_USER_BOOKE |
- PPC_FEATURE_SPE_COMP |
- PPC_FEATURE_HAS_EFP_SINGLE |
- PPC_FEATURE_HAS_EFP_DOUBLE,
+ PPC_FEATURE_HAS_SPE_COMP |
+ PPC_FEATURE_HAS_EFP_SINGLE_COMP |
+ PPC_FEATURE_HAS_EFP_DOUBLE_COMP,
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
@@ -1298,29 +1311,49 @@ static struct cpu_spec cpu_specs[] = {
#endif /* CONFIG_PPC32 */
};
-struct cpu_spec *identify_cpu(unsigned long offset, unsigned int pvr)
+static struct cpu_spec the_cpu_spec;
+
+struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr)
{
struct cpu_spec *s = cpu_specs;
- struct cpu_spec **cur = &cur_cpu_spec;
+ struct cpu_spec *t = &the_cpu_spec;
int i;
s = PTRRELOC(s);
- cur = PTRRELOC(cur);
+ t = PTRRELOC(t);
for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++)
if ((pvr & s->pvr_mask) == s->pvr_value) {
- *cur = cpu_specs + i;
-#ifdef CONFIG_PPC64
- /* ppc64 expects identify_cpu to also call setup_cpu
- * for that processor. I will consolidate that at a
- * later time, for now, just use our friend #ifdef.
+ /*
+ * If we are overriding a previous value derived
+ * from the real PVR with a new value obtained
+ * using a logical PVR value, don't modify the
+ * performance monitor fields.
+ */
+ if (t->num_pmcs && !s->num_pmcs) {
+ t->cpu_name = s->cpu_name;
+ t->cpu_features = s->cpu_features;
+ t->cpu_user_features = s->cpu_user_features;
+ t->icache_bsize = s->icache_bsize;
+ t->dcache_bsize = s->dcache_bsize;
+ t->cpu_setup = s->cpu_setup;
+ t->cpu_restore = s->cpu_restore;
+ t->platform = s->platform;
+ } else
+ *t = *s;
+ *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
+#if defined(CONFIG_PPC64) || defined(CONFIG_BOOKE)
+ /* ppc64 and booke expect identify_cpu to also call
+ * setup_cpu for that processor. I will consolidate
+ * that at a later time, for now, just use #ifdef.
* we also don't need to PTRRELOC the function pointer
- * on ppc64 as we are running at 0 in real mode.
+ * on ppc64 and booke as we are running at 0 in real
+ * mode on ppc64 and reloc_offset is always 0 on booke.
*/
if (s->cpu_setup) {
s->cpu_setup(offset, s);
}
-#endif /* CONFIG_PPC64 */
+#endif /* CONFIG_PPC64 || CONFIG_BOOKE */
return s;
}
BUG();