aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/prom_init.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2005-10-26 07:45:56 -0400
committerPaul Mackerras <paulus@samba.org>2005-10-26 07:45:56 -0400
commitbbd0abda9cc689a54df509aae00000bbb2a1a7d1 (patch)
treed04e8f196f65f5598300485e654e5e90a6160aa6 /arch/powerpc/kernel/prom_init.c
parent303d72a0006c65bb8d16199c75a26338ce723811 (diff)
powerpc: Merge 32-bit CHRP support.
SMP still needs more work but UP gets as far as starting userspace at least. This uses the 64-bit-style code for spinning up the cpus. Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/prom_init.c')
-rw-r--r--arch/powerpc/kernel/prom_init.c54
1 files changed, 23 insertions, 31 deletions
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 18d266d8935d..debe9734636e 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -1155,9 +1155,18 @@ static void __init prom_initialize_tce_table(void)
1155 * 1155 *
1156 * -- Cort 1156 * -- Cort
1157 */ 1157 */
1158extern void __secondary_hold(void);
1159extern unsigned long __secondary_hold_spinloop;
1160extern unsigned long __secondary_hold_acknowledge;
1161
1162/*
1163 * We want to reference the copy of __secondary_hold_* in the
1164 * 0 - 0x100 address range
1165 */
1166#define LOW_ADDR(x) (((unsigned long) &(x)) & 0xff)
1167
1158static void __init prom_hold_cpus(void) 1168static void __init prom_hold_cpus(void)
1159{ 1169{
1160#ifdef CONFIG_PPC64
1161 unsigned long i; 1170 unsigned long i;
1162 unsigned int reg; 1171 unsigned int reg;
1163 phandle node; 1172 phandle node;
@@ -1166,20 +1175,18 @@ static void __init prom_hold_cpus(void)
1166 unsigned int interrupt_server[MAX_CPU_THREADS]; 1175 unsigned int interrupt_server[MAX_CPU_THREADS];
1167 unsigned int cpu_threads, hw_cpu_num; 1176 unsigned int cpu_threads, hw_cpu_num;
1168 int propsize; 1177 int propsize;
1169 extern void __secondary_hold(void); 1178 struct prom_t *_prom = &RELOC(prom);
1170 extern unsigned long __secondary_hold_spinloop;
1171 extern unsigned long __secondary_hold_acknowledge;
1172 unsigned long *spinloop 1179 unsigned long *spinloop
1173 = (void *) __pa(&__secondary_hold_spinloop); 1180 = (void *) LOW_ADDR(__secondary_hold_spinloop);
1174 unsigned long *acknowledge 1181 unsigned long *acknowledge
1175 = (void *) __pa(&__secondary_hold_acknowledge); 1182 = (void *) LOW_ADDR(__secondary_hold_acknowledge);
1176#ifdef CONFIG_PPC64 1183#ifdef CONFIG_PPC64
1184 /* __secondary_hold is actually a descriptor, not the text address */
1177 unsigned long secondary_hold 1185 unsigned long secondary_hold
1178 = __pa(*PTRRELOC((unsigned long *)__secondary_hold)); 1186 = __pa(*PTRRELOC((unsigned long *)__secondary_hold));
1179#else 1187#else
1180 unsigned long secondary_hold = __pa(&__secondary_hold); 1188 unsigned long secondary_hold = LOW_ADDR(__secondary_hold);
1181#endif 1189#endif
1182 struct prom_t *_prom = &RELOC(prom);
1183 1190
1184 prom_debug("prom_hold_cpus: start...\n"); 1191 prom_debug("prom_hold_cpus: start...\n");
1185 prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop); 1192 prom_debug(" 1) spinloop = 0x%x\n", (unsigned long)spinloop);
@@ -1197,9 +1204,8 @@ static void __init prom_hold_cpus(void)
1197 *spinloop = 0; 1204 *spinloop = 0;
1198 1205
1199#ifdef CONFIG_HMT 1206#ifdef CONFIG_HMT
1200 for (i = 0; i < NR_CPUS; i++) { 1207 for (i = 0; i < NR_CPUS; i++)
1201 RELOC(hmt_thread_data)[i].pir = 0xdeadbeef; 1208 RELOC(hmt_thread_data)[i].pir = 0xdeadbeef;
1202 }
1203#endif 1209#endif
1204 /* look for cpus */ 1210 /* look for cpus */
1205 for (node = 0; prom_next_node(&node); ) { 1211 for (node = 0; prom_next_node(&node); ) {
@@ -1250,34 +1256,22 @@ static void __init prom_hold_cpus(void)
1250 call_prom("start-cpu", 3, 0, node, 1256 call_prom("start-cpu", 3, 0, node,
1251 secondary_hold, reg); 1257 secondary_hold, reg);
1252 1258
1253 for ( i = 0 ; (i < 100000000) && 1259 for (i = 0; (i < 100000000) &&
1254 (*acknowledge == ((unsigned long)-1)); i++ ) 1260 (*acknowledge == ((unsigned long)-1)); i++ )
1255 mb(); 1261 mb();
1256 1262
1257 if (*acknowledge == reg) { 1263 if (*acknowledge == reg)
1258 prom_printf("done\n"); 1264 prom_printf("done\n");
1259 /* We have to get every CPU out of OF, 1265 else
1260 * even if we never start it. */
1261 if (cpuid >= NR_CPUS)
1262 goto next;
1263 } else {
1264 prom_printf("failed: %x\n", *acknowledge); 1266 prom_printf("failed: %x\n", *acknowledge);
1265 }
1266 } 1267 }
1267#ifdef CONFIG_SMP 1268#ifdef CONFIG_SMP
1268 else 1269 else
1269 prom_printf("%x : boot cpu %x\n", cpuid, reg); 1270 prom_printf("%x : boot cpu %x\n", cpuid, reg);
1270#endif
1271next:
1272#ifdef CONFIG_SMP
1273 /* Init paca for secondary threads. They start later. */
1274 for (i=1; i < cpu_threads; i++) {
1275 cpuid++;
1276 if (cpuid >= NR_CPUS)
1277 continue;
1278 }
1279#endif /* CONFIG_SMP */ 1271#endif /* CONFIG_SMP */
1280 cpuid++; 1272
1273 /* Reserve cpu #s for secondary threads. They start later. */
1274 cpuid += cpu_threads;
1281 } 1275 }
1282#ifdef CONFIG_HMT 1276#ifdef CONFIG_HMT
1283 /* Only enable HMT on processors that provide support. */ 1277 /* Only enable HMT on processors that provide support. */
@@ -1311,7 +1305,6 @@ next:
1311 ") exceeded: ignoring extras\n"); 1305 ") exceeded: ignoring extras\n");
1312 1306
1313 prom_debug("prom_hold_cpus: end...\n"); 1307 prom_debug("prom_hold_cpus: end...\n");
1314#endif
1315} 1308}
1316 1309
1317 1310
@@ -1940,7 +1933,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
1940 unsigned long r6, unsigned long r7) 1933 unsigned long r6, unsigned long r7)
1941{ 1934{
1942 struct prom_t *_prom; 1935 struct prom_t *_prom;
1943 extern char _stext[];
1944 unsigned long hdr; 1936 unsigned long hdr;
1945 u32 getprop_rval; 1937 u32 getprop_rval;
1946 unsigned long offset = reloc_offset(); 1938 unsigned long offset = reloc_offset();