aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/cputable.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-12-03 23:59:07 -0500
committerPaul Mackerras <paulus@samba.org>2006-12-03 23:59:07 -0500
commit79acbb3ff2d8095b692e1502b9eb2ccec348de26 (patch)
tree6ab773e5a8f9de2cd6443362b21d0d6fffe3b35e /arch/powerpc/kernel/cputable.c
parent19a79859e168640f8e16d7b216d211c1c52b687a (diff)
parent2b5f6dcce5bf94b9b119e9ed8d537098ec61c3d2 (diff)
Merge branch 'linux-2.6' into for-linus
Diffstat (limited to 'arch/powerpc/kernel/cputable.c')
-rw-r--r--arch/powerpc/kernel/cputable.c86
1 files changed, 85 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index f02b402c66d9..1e4ed0731d15 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -18,6 +18,7 @@
18 18
19#include <asm/oprofile_impl.h> 19#include <asm/oprofile_impl.h>
20#include <asm/cputable.h> 20#include <asm/cputable.h>
21#include <asm/prom.h> /* for PTRRELOC on ARCH=ppc */
21 22
22struct cpu_spec* cur_cpu_spec = NULL; 23struct cpu_spec* cur_cpu_spec = NULL;
23EXPORT_SYMBOL(cur_cpu_spec); 24EXPORT_SYMBOL(cur_cpu_spec);
@@ -74,7 +75,7 @@ extern void __restore_cpu_ppc970(void);
74#define PPC_FEATURE_SPE_COMP 0 75#define PPC_FEATURE_SPE_COMP 0
75#endif 76#endif
76 77
77struct cpu_spec cpu_specs[] = { 78static struct cpu_spec cpu_specs[] = {
78#ifdef CONFIG_PPC64 79#ifdef CONFIG_PPC64
79 { /* Power3 */ 80 { /* Power3 */
80 .pvr_mask = 0xffff0000, 81 .pvr_mask = 0xffff0000,
@@ -228,6 +229,21 @@ struct cpu_spec cpu_specs[] = {
228 .oprofile_type = PPC_OPROFILE_POWER4, 229 .oprofile_type = PPC_OPROFILE_POWER4,
229 .platform = "ppc970", 230 .platform = "ppc970",
230 }, 231 },
232 { /* PPC970GX */
233 .pvr_mask = 0xffff0000,
234 .pvr_value = 0x00450000,
235 .cpu_name = "PPC970GX",
236 .cpu_features = CPU_FTRS_PPC970,
237 .cpu_user_features = COMMON_USER_POWER4 |
238 PPC_FEATURE_HAS_ALTIVEC_COMP,
239 .icache_bsize = 128,
240 .dcache_bsize = 128,
241 .num_pmcs = 8,
242 .cpu_setup = __setup_cpu_ppc970,
243 .oprofile_cpu_type = "ppc64/970",
244 .oprofile_type = PPC_OPROFILE_POWER4,
245 .platform = "ppc970",
246 },
231 { /* Power5 GR */ 247 { /* Power5 GR */
232 .pvr_mask = 0xffff0000, 248 .pvr_mask = 0xffff0000,
233 .pvr_value = 0x003a0000, 249 .pvr_value = 0x003a0000,
@@ -1153,3 +1169,71 @@ struct cpu_spec cpu_specs[] = {
1153#endif /* !CLASSIC_PPC */ 1169#endif /* !CLASSIC_PPC */
1154#endif /* CONFIG_PPC32 */ 1170#endif /* CONFIG_PPC32 */
1155}; 1171};
1172
1173struct cpu_spec *identify_cpu(unsigned long offset)
1174{
1175 struct cpu_spec *s = cpu_specs;
1176 struct cpu_spec **cur = &cur_cpu_spec;
1177 unsigned int pvr = mfspr(SPRN_PVR);
1178 int i;
1179
1180 s = PTRRELOC(s);
1181 cur = PTRRELOC(cur);
1182
1183 if (*cur != NULL)
1184 return PTRRELOC(*cur);
1185
1186 for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++)
1187 if ((pvr & s->pvr_mask) == s->pvr_value) {
1188 *cur = cpu_specs + i;
1189#ifdef CONFIG_PPC64
1190 /* ppc64 expects identify_cpu to also call setup_cpu
1191 * for that processor. I will consolidate that at a
1192 * later time, for now, just use our friend #ifdef.
1193 * we also don't need to PTRRELOC the function pointer
1194 * on ppc64 as we are running at 0 in real mode.
1195 */
1196 if (s->cpu_setup) {
1197 s->cpu_setup(offset, s);
1198 }
1199#endif /* CONFIG_PPC64 */
1200 return s;
1201 }
1202 BUG();
1203 return NULL;
1204}
1205
1206void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end)
1207{
1208 struct fixup_entry {
1209 unsigned long mask;
1210 unsigned long value;
1211 long start_off;
1212 long end_off;
1213 } *fcur, *fend;
1214
1215 fcur = fixup_start;
1216 fend = fixup_end;
1217
1218 for (; fcur < fend; fcur++) {
1219 unsigned int *pstart, *pend, *p;
1220
1221 if ((value & fcur->mask) == fcur->value)
1222 continue;
1223
1224 /* These PTRRELOCs will disappear once the new scheme for
1225 * modules and vdso is implemented
1226 */
1227 pstart = ((unsigned int *)fcur) + (fcur->start_off / 4);
1228 pend = ((unsigned int *)fcur) + (fcur->end_off / 4);
1229
1230 for (p = pstart; p < pend; p++) {
1231 *p = 0x60000000u;
1232 asm volatile ("dcbst 0, %0" : : "r" (p));
1233 }
1234 asm volatile ("sync" : : : "memory");
1235 for (p = pstart; p < pend; p++)
1236 asm volatile ("icbi 0,%0" : : "r" (p));
1237 asm volatile ("sync; isync" : : : "memory");
1238 }
1239}