aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/cputable.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2006-10-24 02:42:40 -0400
committerPaul Mackerras <paulus@samba.org>2006-10-24 21:42:10 -0400
commit42c4aaadb737e0e672b3fb86b2c41ff59f0fb8bc (patch)
tree368a26a61085e567357b3974e7799e56069032eb /arch/powerpc/kernel/cputable.c
parentfb20f65a01a97bdf4bb746eecfc24a08561e2648 (diff)
[POWERPC] Consolidate feature fixup code
There are currently two versions of the functions for applying the feature fixups, one for CPU features and one for firmware features. In addition, they are both in assembly and with separate implementations for 32 and 64 bits. identify_cpu() is also implemented in assembly and separately for 32 and 64 bits. This patch replaces them with a pair of C functions. The call sites are slightly moved on ppc64 as well to be called from C instead of from assembly, though it's a very small change, and thus shouldn't cause any problem. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Acked-by: Olof Johansson <olof@lixom.net> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/cputable.c')
-rw-r--r--arch/powerpc/kernel/cputable.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index f23aad66a79e..6fdfaa4a82b8 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);
@@ -73,7 +74,7 @@ extern void __restore_cpu_ppc970(void);
73#define PPC_FEATURE_SPE_COMP 0 74#define PPC_FEATURE_SPE_COMP 0
74#endif 75#endif
75 76
76struct cpu_spec cpu_specs[] = { 77static struct cpu_spec cpu_specs[] = {
77#ifdef CONFIG_PPC64 78#ifdef CONFIG_PPC64
78 { /* Power3 */ 79 { /* Power3 */
79 .pvr_mask = 0xffff0000, 80 .pvr_mask = 0xffff0000,
@@ -1167,3 +1168,72 @@ struct cpu_spec cpu_specs[] = {
1167#endif /* !CLASSIC_PPC */ 1168#endif /* !CLASSIC_PPC */
1168#endif /* CONFIG_PPC32 */ 1169#endif /* CONFIG_PPC32 */
1169}; 1170};
1171
1172struct cpu_spec *identify_cpu(unsigned long offset)
1173{
1174 struct cpu_spec *s = cpu_specs;
1175 struct cpu_spec **cur = &cur_cpu_spec;
1176 unsigned int pvr = mfspr(SPRN_PVR);
1177 int i;
1178
1179 s = PTRRELOC(s);
1180 cur = PTRRELOC(cur);
1181
1182 if (*cur != NULL)
1183 return PTRRELOC(*cur);
1184
1185 for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++)
1186 if ((pvr & s->pvr_mask) == s->pvr_value) {
1187 *cur = cpu_specs + i;
1188#ifdef CONFIG_PPC64
1189 /* ppc64 expects identify_cpu to also call setup_cpu
1190 * for that processor. I will consolidate that at a
1191 * later time, for now, just use our friend #ifdef.
1192 * we also don't need to PTRRELOC the function pointer
1193 * on ppc64 as we are running at 0 in real mode.
1194 */
1195 if (s->cpu_setup) {
1196 s->cpu_setup(offset, s);
1197 }
1198#endif /* CONFIG_PPC64 */
1199 return s;
1200 }
1201 BUG();
1202 return NULL;
1203}
1204
1205void do_feature_fixups(unsigned long offset, unsigned long value,
1206 void *fixup_start, void *fixup_end)
1207{
1208 struct fixup_entry {
1209 unsigned long mask;
1210 unsigned long value;
1211 unsigned int *start;
1212 unsigned int *end;
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 = PTRRELOC(fcur->start);
1228 pend = PTRRELOC(fcur->end);
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}