aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/prom_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/prom_init.c')
-rw-r--r--arch/powerpc/kernel/prom_init.c211
1 files changed, 0 insertions, 211 deletions
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 078145acf7fb..1a85d8f96739 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -1268,201 +1268,6 @@ static u64 __initdata prom_opal_base;
1268static u64 __initdata prom_opal_entry; 1268static u64 __initdata prom_opal_entry;
1269#endif 1269#endif
1270 1270
1271#ifdef __BIG_ENDIAN__
1272/* XXX Don't change this structure without updating opal-takeover.S */
1273static struct opal_secondary_data {
1274 s64 ack; /* 0 */
1275 u64 go; /* 8 */
1276 struct opal_takeover_args args; /* 16 */
1277} opal_secondary_data;
1278
1279static u64 __initdata prom_opal_align;
1280static u64 __initdata prom_opal_size;
1281static int __initdata prom_rtas_start_cpu;
1282static u64 __initdata prom_rtas_data;
1283static u64 __initdata prom_rtas_entry;
1284
1285extern char opal_secondary_entry;
1286
1287static void __init prom_query_opal(void)
1288{
1289 long rc;
1290
1291 /* We must not query for OPAL presence on a machine that
1292 * supports TNK takeover (970 blades), as this uses the same
1293 * h-call with different arguments and will crash
1294 */
1295 if (PHANDLE_VALID(call_prom("finddevice", 1, 1,
1296 ADDR("/tnk-memory-map")))) {
1297 prom_printf("TNK takeover detected, skipping OPAL check\n");
1298 return;
1299 }
1300
1301 prom_printf("Querying for OPAL presence... ");
1302
1303 rc = opal_query_takeover(&prom_opal_size,
1304 &prom_opal_align);
1305 prom_debug("(rc = %ld) ", rc);
1306 if (rc != 0) {
1307 prom_printf("not there.\n");
1308 return;
1309 }
1310 of_platform = PLATFORM_OPAL;
1311 prom_printf(" there !\n");
1312 prom_debug(" opal_size = 0x%lx\n", prom_opal_size);
1313 prom_debug(" opal_align = 0x%lx\n", prom_opal_align);
1314 if (prom_opal_align < 0x10000)
1315 prom_opal_align = 0x10000;
1316}
1317
1318static int __init prom_rtas_call(int token, int nargs, int nret,
1319 int *outputs, ...)
1320{
1321 struct rtas_args rtas_args;
1322 va_list list;
1323 int i;
1324
1325 rtas_args.token = token;
1326 rtas_args.nargs = nargs;
1327 rtas_args.nret = nret;
1328 rtas_args.rets = (rtas_arg_t *)&(rtas_args.args[nargs]);
1329 va_start(list, outputs);
1330 for (i = 0; i < nargs; ++i)
1331 rtas_args.args[i] = va_arg(list, rtas_arg_t);
1332 va_end(list);
1333
1334 for (i = 0; i < nret; ++i)
1335 rtas_args.rets[i] = 0;
1336
1337 opal_enter_rtas(&rtas_args, prom_rtas_data,
1338 prom_rtas_entry);
1339
1340 if (nret > 1 && outputs != NULL)
1341 for (i = 0; i < nret-1; ++i)
1342 outputs[i] = rtas_args.rets[i+1];
1343 return (nret > 0)? rtas_args.rets[0]: 0;
1344}
1345
1346static void __init prom_opal_hold_cpus(void)
1347{
1348 int i, cnt, cpu, rc;
1349 long j;
1350 phandle node;
1351 char type[64];
1352 u32 servers[8];
1353 void *entry = (unsigned long *)&opal_secondary_entry;
1354 struct opal_secondary_data *data = &opal_secondary_data;
1355
1356 prom_debug("prom_opal_hold_cpus: start...\n");
1357 prom_debug(" - entry = 0x%x\n", entry);
1358 prom_debug(" - data = 0x%x\n", data);
1359
1360 data->ack = -1;
1361 data->go = 0;
1362
1363 /* look for cpus */
1364 for (node = 0; prom_next_node(&node); ) {
1365 type[0] = 0;
1366 prom_getprop(node, "device_type", type, sizeof(type));
1367 if (strcmp(type, "cpu") != 0)
1368 continue;
1369
1370 /* Skip non-configured cpus. */
1371 if (prom_getprop(node, "status", type, sizeof(type)) > 0)
1372 if (strcmp(type, "okay") != 0)
1373 continue;
1374
1375 cnt = prom_getprop(node, "ibm,ppc-interrupt-server#s", servers,
1376 sizeof(servers));
1377 if (cnt == PROM_ERROR)
1378 break;
1379 cnt >>= 2;
1380 for (i = 0; i < cnt; i++) {
1381 cpu = servers[i];
1382 prom_debug("CPU %d ... ", cpu);
1383 if (cpu == prom.cpu) {
1384 prom_debug("booted !\n");
1385 continue;
1386 }
1387 prom_debug("starting ... ");
1388
1389 /* Init the acknowledge var which will be reset by
1390 * the secondary cpu when it awakens from its OF
1391 * spinloop.
1392 */
1393 data->ack = -1;
1394 rc = prom_rtas_call(prom_rtas_start_cpu, 3, 1,
1395 NULL, cpu, entry, data);
1396 prom_debug("rtas rc=%d ...", rc);
1397
1398 for (j = 0; j < 100000000 && data->ack == -1; j++) {
1399 HMT_low();
1400 mb();
1401 }
1402 HMT_medium();
1403 if (data->ack != -1)
1404 prom_debug("done, PIR=0x%x\n", data->ack);
1405 else
1406 prom_debug("timeout !\n");
1407 }
1408 }
1409 prom_debug("prom_opal_hold_cpus: end...\n");
1410}
1411
1412static void __init prom_opal_takeover(void)
1413{
1414 struct opal_secondary_data *data = &opal_secondary_data;
1415 struct opal_takeover_args *args = &data->args;
1416 u64 align = prom_opal_align;
1417 u64 top_addr, opal_addr;
1418
1419 args->k_image = (u64)_stext;
1420 args->k_size = _end - _stext;
1421 args->k_entry = 0;
1422 args->k_entry2 = 0x60;
1423
1424 top_addr = _ALIGN_UP(args->k_size, align);
1425
1426 if (prom_initrd_start != 0) {
1427 args->rd_image = prom_initrd_start;
1428 args->rd_size = prom_initrd_end - args->rd_image;
1429 args->rd_loc = top_addr;
1430 top_addr = _ALIGN_UP(args->rd_loc + args->rd_size, align);
1431 }
1432
1433 /* Pickup an address for the HAL. We want to go really high
1434 * up to avoid problem with future kexecs. On the other hand
1435 * we don't want to be all over the TCEs on P5IOC2 machines
1436 * which are going to be up there too. We assume the machine
1437 * has plenty of memory, and we ask for the HAL for now to
1438 * be just below the 1G point, or above the initrd
1439 */
1440 opal_addr = _ALIGN_DOWN(0x40000000 - prom_opal_size, align);
1441 if (opal_addr < top_addr)
1442 opal_addr = top_addr;
1443 args->hal_addr = opal_addr;
1444
1445 /* Copy the command line to the kernel image */
1446 strlcpy(boot_command_line, prom_cmd_line,
1447 COMMAND_LINE_SIZE);
1448
1449 prom_debug(" k_image = 0x%lx\n", args->k_image);
1450 prom_debug(" k_size = 0x%lx\n", args->k_size);
1451 prom_debug(" k_entry = 0x%lx\n", args->k_entry);
1452 prom_debug(" k_entry2 = 0x%lx\n", args->k_entry2);
1453 prom_debug(" hal_addr = 0x%lx\n", args->hal_addr);
1454 prom_debug(" rd_image = 0x%lx\n", args->rd_image);
1455 prom_debug(" rd_size = 0x%lx\n", args->rd_size);
1456 prom_debug(" rd_loc = 0x%lx\n", args->rd_loc);
1457 prom_printf("Performing OPAL takeover,this can take a few minutes..\n");
1458 prom_close_stdin();
1459 mb();
1460 data->go = 1;
1461 for (;;)
1462 opal_do_takeover(args);
1463}
1464#endif /* __BIG_ENDIAN__ */
1465
1466/* 1271/*
1467 * Allocate room for and instantiate OPAL 1272 * Allocate room for and instantiate OPAL
1468 */ 1273 */
@@ -1597,12 +1402,6 @@ static void __init prom_instantiate_rtas(void)
1597 &val, sizeof(val)) != PROM_ERROR) 1402 &val, sizeof(val)) != PROM_ERROR)
1598 rtas_has_query_cpu_stopped = true; 1403 rtas_has_query_cpu_stopped = true;
1599 1404
1600#if defined(CONFIG_PPC_POWERNV) && defined(__BIG_ENDIAN__)
1601 /* PowerVN takeover hack */
1602 prom_rtas_data = base;
1603 prom_rtas_entry = entry;
1604 prom_getprop(rtas_node, "start-cpu", &prom_rtas_start_cpu, 4);
1605#endif
1606 prom_debug("rtas base = 0x%x\n", base); 1405 prom_debug("rtas base = 0x%x\n", base);
1607 prom_debug("rtas entry = 0x%x\n", entry); 1406 prom_debug("rtas entry = 0x%x\n", entry);
1608 prom_debug("rtas size = 0x%x\n", (long)size); 1407 prom_debug("rtas size = 0x%x\n", (long)size);
@@ -3027,16 +2826,6 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
3027 prom_instantiate_rtas(); 2826 prom_instantiate_rtas();
3028 2827
3029#ifdef CONFIG_PPC_POWERNV 2828#ifdef CONFIG_PPC_POWERNV
3030#ifdef __BIG_ENDIAN__
3031 /* Detect HAL and try instanciating it & doing takeover */
3032 if (of_platform == PLATFORM_PSERIES_LPAR) {
3033 prom_query_opal();
3034 if (of_platform == PLATFORM_OPAL) {
3035 prom_opal_hold_cpus();
3036 prom_opal_takeover();
3037 }
3038 } else
3039#endif /* __BIG_ENDIAN__ */
3040 if (of_platform == PLATFORM_OPAL) 2829 if (of_platform == PLATFORM_OPAL)
3041 prom_instantiate_opal(); 2830 prom_instantiate_opal();
3042#endif /* CONFIG_PPC_POWERNV */ 2831#endif /* CONFIG_PPC_POWERNV */