diff options
Diffstat (limited to 'arch/ppc/kernel/setup.c')
-rw-r--r-- | arch/ppc/kernel/setup.c | 264 |
1 files changed, 11 insertions, 253 deletions
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index c08ab432e958..1f79e84ab464 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Common prep/chrp boot and setup code. | 2 | * Common prep boot and setup code. |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/config.h> | 5 | #include <linux/config.h> |
@@ -72,17 +72,12 @@ unsigned long ISA_DMA_THRESHOLD; | |||
72 | unsigned int DMA_MODE_READ; | 72 | unsigned int DMA_MODE_READ; |
73 | unsigned int DMA_MODE_WRITE; | 73 | unsigned int DMA_MODE_WRITE; |
74 | 74 | ||
75 | #ifdef CONFIG_PPC_MULTIPLATFORM | 75 | #ifdef CONFIG_PPC_PREP |
76 | int _machine = 0; | ||
77 | EXPORT_SYMBOL(_machine); | ||
78 | |||
79 | extern void prep_init(unsigned long r3, unsigned long r4, | 76 | extern void prep_init(unsigned long r3, unsigned long r4, |
80 | unsigned long r5, unsigned long r6, unsigned long r7); | 77 | unsigned long r5, unsigned long r6, unsigned long r7); |
81 | extern void chrp_init(unsigned long r3, unsigned long r4, | ||
82 | unsigned long r5, unsigned long r6, unsigned long r7); | ||
83 | 78 | ||
84 | dev_t boot_dev; | 79 | dev_t boot_dev; |
85 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | 80 | #endif /* CONFIG_PPC_PREP */ |
86 | 81 | ||
87 | int have_of; | 82 | int have_of; |
88 | EXPORT_SYMBOL(have_of); | 83 | EXPORT_SYMBOL(have_of); |
@@ -168,9 +163,8 @@ int show_cpuinfo(struct seq_file *m, void *v) | |||
168 | /* Show summary information */ | 163 | /* Show summary information */ |
169 | #ifdef CONFIG_SMP | 164 | #ifdef CONFIG_SMP |
170 | unsigned long bogosum = 0; | 165 | unsigned long bogosum = 0; |
171 | for (i = 0; i < NR_CPUS; ++i) | 166 | for_each_online_cpu(i) |
172 | if (cpu_online(i)) | 167 | bogosum += cpu_data[i].loops_per_jiffy; |
173 | bogosum += cpu_data[i].loops_per_jiffy; | ||
174 | seq_printf(m, "total bogomips\t: %lu.%02lu\n", | 168 | seq_printf(m, "total bogomips\t: %lu.%02lu\n", |
175 | bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); | 169 | bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); |
176 | #endif /* CONFIG_SMP */ | 170 | #endif /* CONFIG_SMP */ |
@@ -320,72 +314,12 @@ early_init(int r3, int r4, int r5) | |||
320 | identify_cpu(offset, 0); | 314 | identify_cpu(offset, 0); |
321 | do_cpu_ftr_fixups(offset); | 315 | do_cpu_ftr_fixups(offset); |
322 | 316 | ||
323 | #if defined(CONFIG_PPC_OF) | ||
324 | reloc_got2(offset); | ||
325 | |||
326 | /* | ||
327 | * don't do anything on prep | ||
328 | * for now, don't use bootinfo because it breaks yaboot 0.5 | ||
329 | * and assume that if we didn't find a magic number, we have OF | ||
330 | */ | ||
331 | if (*(unsigned long *)(0) != 0xdeadc0de) | ||
332 | phys = prom_init(r3, r4, (prom_entry)r5); | ||
333 | |||
334 | reloc_got2(-offset); | ||
335 | #endif | ||
336 | |||
337 | return phys; | 317 | return phys; |
338 | } | 318 | } |
339 | 319 | ||
340 | #ifdef CONFIG_PPC_OF | 320 | #ifdef CONFIG_PPC_PREP |
341 | /* | ||
342 | * Assume here that all clock rates are the same in a | ||
343 | * smp system. -- Cort | ||
344 | */ | ||
345 | int | ||
346 | of_show_percpuinfo(struct seq_file *m, int i) | ||
347 | { | ||
348 | struct device_node *cpu_node; | ||
349 | u32 *fp; | ||
350 | int s; | ||
351 | |||
352 | cpu_node = find_type_devices("cpu"); | ||
353 | if (!cpu_node) | ||
354 | return 0; | ||
355 | for (s = 0; s < i && cpu_node->next; s++) | ||
356 | cpu_node = cpu_node->next; | ||
357 | fp = (u32 *)get_property(cpu_node, "clock-frequency", NULL); | ||
358 | if (fp) | ||
359 | seq_printf(m, "clock\t\t: %dMHz\n", *fp / 1000000); | ||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | void __init | ||
364 | intuit_machine_type(void) | ||
365 | { | ||
366 | char *model; | ||
367 | struct device_node *root; | ||
368 | |||
369 | /* ask the OF info if we're a chrp or pmac */ | ||
370 | root = find_path_device("/"); | ||
371 | if (root != 0) { | ||
372 | /* assume pmac unless proven to be chrp -- Cort */ | ||
373 | _machine = _MACH_Pmac; | ||
374 | model = get_property(root, "device_type", NULL); | ||
375 | if (model && !strncmp("chrp", model, 4)) | ||
376 | _machine = _MACH_chrp; | ||
377 | else { | ||
378 | model = get_property(root, "model", NULL); | ||
379 | if (model && !strncmp(model, "IBM", 3)) | ||
380 | _machine = _MACH_chrp; | ||
381 | } | ||
382 | } | ||
383 | } | ||
384 | #endif | ||
385 | |||
386 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
387 | /* | 321 | /* |
388 | * The PPC_MULTIPLATFORM version of platform_init... | 322 | * The PPC_PREP version of platform_init... |
389 | */ | 323 | */ |
390 | void __init | 324 | void __init |
391 | platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | 325 | platform_init(unsigned long r3, unsigned long r4, unsigned long r5, |
@@ -400,161 +334,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
400 | 334 | ||
401 | parse_bootinfo(find_bootinfo()); | 335 | parse_bootinfo(find_bootinfo()); |
402 | 336 | ||
403 | /* if we didn't get any bootinfo telling us what we are... */ | 337 | prep_init(r3, r4, r5, r6, r7); |
404 | if (_machine == 0) { | ||
405 | /* prep boot loader tells us if we're prep or not */ | ||
406 | if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) | ||
407 | _machine = _MACH_prep; | ||
408 | } | ||
409 | |||
410 | #ifdef CONFIG_PPC_PREP | ||
411 | /* not much more to do here, if prep */ | ||
412 | if (_machine == _MACH_prep) { | ||
413 | prep_init(r3, r4, r5, r6, r7); | ||
414 | return; | ||
415 | } | ||
416 | #endif | ||
417 | |||
418 | #ifdef CONFIG_PPC_OF | ||
419 | have_of = 1; | ||
420 | |||
421 | /* prom_init has already been called from __start */ | ||
422 | if (boot_infos) | ||
423 | relocate_nodes(); | ||
424 | |||
425 | /* If we aren't PReP, we can find out if we're Pmac | ||
426 | * or CHRP with this. */ | ||
427 | if (_machine == 0) | ||
428 | intuit_machine_type(); | ||
429 | |||
430 | /* finish_device_tree may need _machine defined. */ | ||
431 | finish_device_tree(); | ||
432 | |||
433 | /* | ||
434 | * If we were booted via quik, r3 points to the physical | ||
435 | * address of the command-line parameters. | ||
436 | * If we were booted from an xcoff image (i.e. netbooted or | ||
437 | * booted from floppy), we get the command line from the | ||
438 | * bootargs property of the /chosen node. | ||
439 | * If an initial ramdisk is present, r3 and r4 | ||
440 | * are used for initrd_start and initrd_size, | ||
441 | * otherwise they contain 0xdeadbeef. | ||
442 | */ | ||
443 | if (r3 >= 0x4000 && r3 < 0x800000 && r4 == 0) { | ||
444 | strlcpy(cmd_line, (char *)r3 + KERNELBASE, | ||
445 | sizeof(cmd_line)); | ||
446 | } else if (boot_infos != 0) { | ||
447 | /* booted by BootX - check for ramdisk */ | ||
448 | if (boot_infos->kernelParamsOffset != 0) | ||
449 | strlcpy(cmd_line, (char *) boot_infos | ||
450 | + boot_infos->kernelParamsOffset, | ||
451 | sizeof(cmd_line)); | ||
452 | #ifdef CONFIG_BLK_DEV_INITRD | ||
453 | if (boot_infos->ramDisk) { | ||
454 | initrd_start = (unsigned long) boot_infos | ||
455 | + boot_infos->ramDisk; | ||
456 | initrd_end = initrd_start + boot_infos->ramDiskSize; | ||
457 | initrd_below_start_ok = 1; | ||
458 | } | ||
459 | #endif | ||
460 | } else { | ||
461 | struct device_node *chosen; | ||
462 | char *p; | ||
463 | |||
464 | #ifdef CONFIG_BLK_DEV_INITRD | ||
465 | if (r3 && r4 && r4 != 0xdeadbeef) { | ||
466 | if (r3 < KERNELBASE) | ||
467 | r3 += KERNELBASE; | ||
468 | initrd_start = r3; | ||
469 | initrd_end = r3 + r4; | ||
470 | ROOT_DEV = Root_RAM0; | ||
471 | initrd_below_start_ok = 1; | ||
472 | } | ||
473 | #endif | ||
474 | chosen = find_devices("chosen"); | ||
475 | if (chosen != NULL) { | ||
476 | p = get_property(chosen, "bootargs", NULL); | ||
477 | if (p && *p) { | ||
478 | strlcpy(cmd_line, p, sizeof(cmd_line)); | ||
479 | } | ||
480 | } | ||
481 | } | ||
482 | #ifdef CONFIG_ADB | ||
483 | if (strstr(cmd_line, "adb_sync")) { | ||
484 | extern int __adb_probe_sync; | ||
485 | __adb_probe_sync = 1; | ||
486 | } | ||
487 | #endif /* CONFIG_ADB */ | ||
488 | |||
489 | switch (_machine) { | ||
490 | #ifdef CONFIG_PPC_CHRP | ||
491 | case _MACH_chrp: | ||
492 | chrp_init(r3, r4, r5, r6, r7); | ||
493 | break; | ||
494 | #endif | ||
495 | } | ||
496 | #endif /* CONFIG_PPC_OF */ | ||
497 | } | 338 | } |
498 | #endif /* CONFIG_PPC_MULTIPLATFORM */ | 339 | #endif /* CONFIG_PPC_PREP */ |
499 | |||
500 | #ifdef CONFIG_PPC_OF | ||
501 | #ifdef CONFIG_SERIAL_CORE_CONSOLE | ||
502 | extern char *of_stdout_device; | ||
503 | |||
504 | static int __init set_preferred_console(void) | ||
505 | { | ||
506 | struct device_node *prom_stdout; | ||
507 | char *name; | ||
508 | int offset = 0; | ||
509 | |||
510 | if (of_stdout_device == NULL) | ||
511 | return -ENODEV; | ||
512 | |||
513 | /* The user has requested a console so this is already set up. */ | ||
514 | if (strstr(saved_command_line, "console=")) | ||
515 | return -EBUSY; | ||
516 | |||
517 | prom_stdout = find_path_device(of_stdout_device); | ||
518 | if (!prom_stdout) | ||
519 | return -ENODEV; | ||
520 | |||
521 | name = (char *)get_property(prom_stdout, "name", NULL); | ||
522 | if (!name) | ||
523 | return -ENODEV; | ||
524 | |||
525 | if (strcmp(name, "serial") == 0) { | ||
526 | int i; | ||
527 | u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i); | ||
528 | if (i > 8) { | ||
529 | switch (reg[1]) { | ||
530 | case 0x3f8: | ||
531 | offset = 0; | ||
532 | break; | ||
533 | case 0x2f8: | ||
534 | offset = 1; | ||
535 | break; | ||
536 | case 0x898: | ||
537 | offset = 2; | ||
538 | break; | ||
539 | case 0x890: | ||
540 | offset = 3; | ||
541 | break; | ||
542 | default: | ||
543 | /* We dont recognise the serial port */ | ||
544 | return -ENODEV; | ||
545 | } | ||
546 | } | ||
547 | } else if (strcmp(name, "ch-a") == 0) | ||
548 | offset = 0; | ||
549 | else if (strcmp(name, "ch-b") == 0) | ||
550 | offset = 1; | ||
551 | else | ||
552 | return -ENODEV; | ||
553 | return add_preferred_console("ttyS", offset, NULL); | ||
554 | } | ||
555 | console_initcall(set_preferred_console); | ||
556 | #endif /* CONFIG_SERIAL_CORE_CONSOLE */ | ||
557 | #endif /* CONFIG_PPC_OF */ | ||
558 | 340 | ||
559 | struct bi_record *find_bootinfo(void) | 341 | struct bi_record *find_bootinfo(void) |
560 | { | 342 | { |
@@ -590,23 +372,6 @@ void parse_bootinfo(struct bi_record *rec) | |||
590 | initrd_end = data[0] + data[1] + KERNELBASE; | 372 | initrd_end = data[0] + data[1] + KERNELBASE; |
591 | break; | 373 | break; |
592 | #endif /* CONFIG_BLK_DEV_INITRD */ | 374 | #endif /* CONFIG_BLK_DEV_INITRD */ |
593 | #ifdef CONFIG_PPC_MULTIPLATFORM | ||
594 | case BI_MACHTYPE: | ||
595 | /* Machine types changed with the merge. Since the | ||
596 | * bootinfo are now deprecated, we can just hard code | ||
597 | * the appropriate conversion here for when we are | ||
598 | * called with yaboot which passes us a machine type | ||
599 | * this way. | ||
600 | */ | ||
601 | switch(data[0]) { | ||
602 | case 1: _machine = _MACH_prep; break; | ||
603 | case 2: _machine = _MACH_Pmac; break; | ||
604 | case 4: _machine = _MACH_chrp; break; | ||
605 | default: | ||
606 | _machine = data[0]; | ||
607 | } | ||
608 | break; | ||
609 | #endif | ||
610 | case BI_MEMSIZE: | 375 | case BI_MEMSIZE: |
611 | boot_mem_size = data[0]; | 376 | boot_mem_size = data[0]; |
612 | break; | 377 | break; |
@@ -632,9 +397,6 @@ machine_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
632 | #ifdef CONFIG_6xx | 397 | #ifdef CONFIG_6xx |
633 | ppc_md.power_save = ppc6xx_idle; | 398 | ppc_md.power_save = ppc6xx_idle; |
634 | #endif | 399 | #endif |
635 | #ifdef CONFIG_POWER4 | ||
636 | ppc_md.power_save = power4_idle; | ||
637 | #endif | ||
638 | 400 | ||
639 | platform_init(r3, r4, r5, r6, r7); | 401 | platform_init(r3, r4, r5, r6, r7); |
640 | 402 | ||
@@ -712,9 +474,8 @@ int __init ppc_init(void) | |||
712 | if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); | 474 | if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); |
713 | 475 | ||
714 | /* register CPU devices */ | 476 | /* register CPU devices */ |
715 | for (i = 0; i < NR_CPUS; i++) | 477 | for_each_possible_cpu(i) |
716 | if (cpu_possible(i)) | 478 | register_cpu(&cpu_devices[i], i, NULL); |
717 | register_cpu(&cpu_devices[i], i, NULL); | ||
718 | 479 | ||
719 | /* call platform init */ | 480 | /* call platform init */ |
720 | if (ppc_md.init != NULL) { | 481 | if (ppc_md.init != NULL) { |
@@ -801,7 +562,4 @@ void __init setup_arch(char **cmdline_p) | |||
801 | if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); | 562 | if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); |
802 | 563 | ||
803 | paging_init(); | 564 | paging_init(); |
804 | |||
805 | /* this is for modules since _machine can be a define -- Cort */ | ||
806 | ppc_md.ppc_machine = _machine; | ||
807 | } | 565 | } |