/*
- * Common prep boot and setup code.
+ * Common prep/chrp boot and setup code.
*/
#include <linux/config.h>
unsigned int DMA_MODE_READ;
unsigned int DMA_MODE_WRITE;
-#ifdef CONFIG_PPC_PREP
+#ifdef CONFIG_PPC_MULTIPLATFORM
+int _machine = 0;
+EXPORT_SYMBOL(_machine);
+
extern void prep_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7);
+extern void chrp_init(unsigned long r3, unsigned long r4,
+ unsigned long r5, unsigned long r6, unsigned long r7);
dev_t boot_dev;
-#endif /* CONFIG_PPC_PREP */
+#endif /* CONFIG_PPC_MULTIPLATFORM */
int have_of;
EXPORT_SYMBOL(have_of);
/* Show summary information */
#ifdef CONFIG_SMP
unsigned long bogosum = 0;
- for_each_online_cpu(i)
- bogosum += cpu_data[i].loops_per_jiffy;
+ for (i = 0; i < NR_CPUS; ++i)
+ if (cpu_online(i))
+ bogosum += cpu_data[i].loops_per_jiffy;
seq_printf(m, "total bogomips\t: %lu.%02lu\n",
bogosum/(500000/HZ), bogosum/(5000/HZ) % 100);
#endif /* CONFIG_SMP */
identify_cpu(offset, 0);
do_cpu_ftr_fixups(offset);
+#if defined(CONFIG_PPC_OF)
+ reloc_got2(offset);
+
+ /*
+ * don't do anything on prep
+ * for now, don't use bootinfo because it breaks yaboot 0.5
+ * and assume that if we didn't find a magic number, we have OF
+ */
+ if (*(unsigned long *)(0) != 0xdeadc0de)
+ phys = prom_init(r3, r4, (prom_entry)r5);
+
+ reloc_got2(-offset);
+#endif
+
return phys;
}
-#ifdef CONFIG_PPC_PREP
+#ifdef CONFIG_PPC_OF
/*
- * The PPC_PREP version of platform_init...
+ * Assume here that all clock rates are the same in a
+ * smp system. -- Cort
+ */
+int
+of_show_percpuinfo(struct seq_file *m, int i)
+{
+ struct device_node *cpu_node;
+ u32 *fp;
+ int s;
+
+ cpu_node = find_type_devices("cpu");
+ if (!cpu_node)
+ return 0;
+ for (s = 0; s < i && cpu_node->next; s++)
+ cpu_node = cpu_node->next;
+ fp = (u32 *)get_property(cpu_node, "clock-frequency", NULL);
+ if (fp)
+ seq_printf(m, "clock\t\t: %dMHz\n", *fp / 1000000);
+ return 0;
+}
+
+void __init
+intuit_machine_type(void)
+{
+ char *model;
+ struct device_node *root;
+
+ /* ask the OF info if we're a chrp or pmac */
+ root = find_path_device("/");
+ if (root != 0) {
+ /* assume pmac unless proven to be chrp -- Cort */
+ _machine = _MACH_Pmac;
+ model = get_property(root, "device_type", NULL);
+ if (model && !strncmp("chrp", model, 4))
+ _machine = _MACH_chrp;
+ else {
+ model = get_property(root, "model", NULL);
+ if (model && !strncmp(model, "IBM", 3))
+ _machine = _MACH_chrp;
+ }
+ }
+}
+#endif
+
+#ifdef CONFIG_PPC_MULTIPLATFORM
+/*
+ * The PPC_MULTIPLATFORM version of platform_init...
*/
void __init
platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
parse_bootinfo(find_bootinfo());
- prep_init(r3, r4, r5, r6, r7);
+ /* if we didn't get any bootinfo telling us what we are... */
+ if (_machine == 0) {
+ /* prep boot loader tells us if we're prep or not */
+ if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
+ _machine = _MACH_prep;
+ }
+
+#ifdef CONFIG_PPC_PREP
+ /* not much more to do here, if prep */
+ if (_machine == _MACH_prep) {
+ prep_init(r3, r4, r5, r6, r7);
+ return;
+ }
+#endif
+
+#ifdef CONFIG_PPC_OF
+ have_of = 1;
+
+ /* prom_init has already been called from __start */
+ if (boot_infos)
+ relocate_nodes();
+
+ /* If we aren't PReP, we can find out if we're Pmac
+ * or CHRP with this. */
+ if (_machine == 0)
+ intuit_machine_type();
+
+ /* finish_device_tree may need _machine defined. */
+ finish_device_tree();
+
+ /*
+ * If we were booted via quik, r3 points to the physical
+ * address of the command-line parameters.
+ * If we were booted from an xcoff image (i.e. netbooted or
+ * booted from floppy), we get the command line from the
+ * bootargs property of the /chosen node.
+ * If an initial ramdisk is present, r3 and r4
+ * are used for initrd_start and initrd_size,
+ * otherwise they contain 0xdeadbeef.
+ */
+ if (r3 >= 0x4000 && r3 < 0x800000 && r4 == 0) {
+ strlcpy(cmd_line, (char *)r3 + KERNELBASE,
+ sizeof(cmd_line));
+ } else if (boot_infos != 0) {
+ /* booted by BootX - check for ramdisk */
+ if (boot_infos->kernelParamsOffset != 0)
+ strlcpy(cmd_line, (char *) boot_infos
+ + boot_infos->kernelParamsOffset,
+ sizeof(cmd_line));
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (boot_infos->ramDisk) {
+ initrd_start = (unsigned long) boot_infos
+ + boot_infos->ramDisk;
+ initrd_end = initrd_start + boot_infos->ramDiskSize;
+ initrd_below_start_ok = 1;
+ }
+#endif
+ } else {
+ struct device_node *chosen;
+ char *p;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (r3 && r4 && r4 != 0xdeadbeef) {
+ if (r3 < KERNELBASE)
+ r3 += KERNELBASE;
+ initrd_start = r3;
+ initrd_end = r3 + r4;
+ ROOT_DEV = Root_RAM0;
+ initrd_below_start_ok = 1;
+ }
+#endif
+ chosen = find_devices("chosen");
+ if (chosen != NULL) {
+ p = get_property(chosen, "bootargs", NULL);
+ if (p && *p) {
+ strlcpy(cmd_line, p, sizeof(cmd_line));
+ }
+ }
+ }
+#ifdef CONFIG_ADB
+ if (strstr(cmd_line, "adb_sync")) {
+ extern int __adb_probe_sync;
+ __adb_probe_sync = 1;
+ }
+#endif /* CONFIG_ADB */
+
+ switch (_machine) {
+#ifdef CONFIG_PPC_CHRP
+ case _MACH_chrp:
+ chrp_init(r3, r4, r5, r6, r7);
+ break;
+#endif
+ }
+#endif /* CONFIG_PPC_OF */
}
-#endif /* CONFIG_PPC_PREP */
+#endif /* CONFIG_PPC_MULTIPLATFORM */
+
+#ifdef CONFIG_PPC_OF
+#ifdef CONFIG_SERIAL_CORE_CONSOLE
+extern char *of_stdout_device;
+
+static int __init set_preferred_console(void)
+{
+ struct device_node *prom_stdout;
+ char *name;
+ int offset = 0;
+
+ if (of_stdout_device == NULL)
+ return -ENODEV;
+
+ /* The user has requested a console so this is already set up. */
+ if (strstr(saved_command_line, "console="))
+ return -EBUSY;
+
+ prom_stdout = find_path_device(of_stdout_device);
+ if (!prom_stdout)
+ return -ENODEV;
+
+ name = (char *)get_property(prom_stdout, "name", NULL);
+ if (!name)
+ return -ENODEV;
+
+ if (strcmp(name, "serial") == 0) {
+ int i;
+ u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i);
+ if (i > 8) {
+ switch (reg[1]) {
+ case 0x3f8:
+ offset = 0;
+ break;
+ case 0x2f8:
+ offset = 1;
+ break;
+ case 0x898:
+ offset = 2;
+ break;
+ case 0x890:
+ offset = 3;
+ break;
+ default:
+ /* We dont recognise the serial port */
+ return -ENODEV;
+ }
+ }
+ } else if (strcmp(name, "ch-a") == 0)
+ offset = 0;
+ else if (strcmp(name, "ch-b") == 0)
+ offset = 1;
+ else
+ return -ENODEV;
+ return add_preferred_console("ttyS", offset, NULL);
+}
+console_initcall(set_preferred_console);
+#endif /* CONFIG_SERIAL_CORE_CONSOLE */
+#endif /* CONFIG_PPC_OF */
struct bi_record *find_bootinfo(void)
{
initrd_end = data[0] + data[1] + KERNELBASE;
break;
#endif /* CONFIG_BLK_DEV_INITRD */
+#ifdef CONFIG_PPC_MULTIPLATFORM
+ case BI_MACHTYPE:
+ /* Machine types changed with the merge. Since the
+ * bootinfo are now deprecated, we can just hard code
+ * the appropriate conversion here for when we are
+ * called with yaboot which passes us a machine type
+ * this way.
+ */
+ switch(data[0]) {
+ case 1: _machine = _MACH_prep; break;
+ case 2: _machine = _MACH_Pmac; break;
+ case 4: _machine = _MACH_chrp; break;
+ default:
+ _machine = data[0];
+ }
+ break;
+#endif
case BI_MEMSIZE:
boot_mem_size = data[0];
break;
#ifdef CONFIG_6xx
ppc_md.power_save = ppc6xx_idle;
#endif
+#ifdef CONFIG_POWER4
+ ppc_md.power_save = power4_idle;
+#endif
platform_init(r3, r4, r5, r6, r7);
if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff);
/* register CPU devices */
- for_each_possible_cpu(i)
- register_cpu(&cpu_devices[i], i, NULL);
+ for (i = 0; i < NR_CPUS; i++)
+ if (cpu_possible(i))
+ register_cpu(&cpu_devices[i], i, NULL);
/* call platform init */
if (ppc_md.init != NULL) {
if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
paging_init();
+
+ /* this is for modules since _machine can be a define -- Cort */
+ ppc_md.ppc_machine = _machine;
}