Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge
[linux-2.6] / arch / ppc / kernel / setup.c
1 /*
2  * Common prep/pmac/chrp boot and setup code.
3  */
4
5 #include <linux/config.h>
6 #include <linux/module.h>
7 #include <linux/string.h>
8 #include <linux/sched.h>
9 #include <linux/init.h>
10 #include <linux/kernel.h>
11 #include <linux/reboot.h>
12 #include <linux/delay.h>
13 #include <linux/initrd.h>
14 #include <linux/ide.h>
15 #include <linux/tty.h>
16 #include <linux/bootmem.h>
17 #include <linux/seq_file.h>
18 #include <linux/root_dev.h>
19 #include <linux/cpu.h>
20 #include <linux/console.h>
21
22 #include <asm/residual.h>
23 #include <asm/io.h>
24 #include <asm/prom.h>
25 #include <asm/processor.h>
26 #include <asm/pgtable.h>
27 #include <asm/bootinfo.h>
28 #include <asm/setup.h>
29 #include <asm/amigappc.h>
30 #include <asm/smp.h>
31 #include <asm/elf.h>
32 #include <asm/cputable.h>
33 #include <asm/bootx.h>
34 #include <asm/btext.h>
35 #include <asm/machdep.h>
36 #include <asm/uaccess.h>
37 #include <asm/system.h>
38 #include <asm/pmac_feature.h>
39 #include <asm/sections.h>
40 #include <asm/nvram.h>
41 #include <asm/xmon.h>
42 #include <asm/ocp.h>
43
44 #define USES_PPC_SYS (defined(CONFIG_85xx) || defined(CONFIG_83xx) || \
45                       defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \
46                       defined(CONFIG_PPC_MPC52xx))
47
48 #if USES_PPC_SYS
49 #include <asm/ppc_sys.h>
50 #endif
51
52 #if defined CONFIG_KGDB
53 #include <asm/kgdb.h>
54 #endif
55
56 extern void platform_init(unsigned long r3, unsigned long r4,
57                 unsigned long r5, unsigned long r6, unsigned long r7);
58 extern void bootx_init(unsigned long r4, unsigned long phys);
59 extern void identify_cpu(unsigned long offset, unsigned long cpu);
60 extern void do_cpu_ftr_fixups(unsigned long offset);
61 extern void reloc_got2(unsigned long offset);
62
63 extern void ppc6xx_idle(void);
64 extern void power4_idle(void);
65
66 extern boot_infos_t *boot_infos;
67 struct ide_machdep_calls ppc_ide_md;
68
69 /* Used with the BI_MEMSIZE bootinfo parameter to store the memory
70    size value reported by the boot loader. */
71 unsigned long boot_mem_size;
72
73 unsigned long ISA_DMA_THRESHOLD;
74 unsigned int DMA_MODE_READ;
75 unsigned int DMA_MODE_WRITE;
76
77 #ifdef CONFIG_PPC_MULTIPLATFORM
78 int _machine = 0;
79 EXPORT_SYMBOL(_machine);
80
81 extern void prep_init(unsigned long r3, unsigned long r4,
82                 unsigned long r5, unsigned long r6, unsigned long r7);
83 extern void pmac_init(unsigned long r3, unsigned long r4,
84                 unsigned long r5, unsigned long r6, unsigned long r7);
85 extern void chrp_init(unsigned long r3, unsigned long r4,
86                 unsigned long r5, unsigned long r6, unsigned long r7);
87
88 dev_t boot_dev;
89 #endif /* CONFIG_PPC_MULTIPLATFORM */
90
91 int have_of;
92 EXPORT_SYMBOL(have_of);
93
94 #ifdef __DO_IRQ_CANON
95 int ppc_do_canonicalize_irqs;
96 EXPORT_SYMBOL(ppc_do_canonicalize_irqs);
97 #endif
98
99 #ifdef CONFIG_MAGIC_SYSRQ
100 unsigned long SYSRQ_KEY = 0x54;
101 #endif /* CONFIG_MAGIC_SYSRQ */
102
103 #ifdef CONFIG_VGA_CONSOLE
104 unsigned long vgacon_remap_base;
105 #endif
106
107 struct machdep_calls ppc_md;
108
109 /*
110  * These are used in binfmt_elf.c to put aux entries on the stack
111  * for each elf executable being started.
112  */
113 int dcache_bsize;
114 int icache_bsize;
115 int ucache_bsize;
116
117 #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_FB_VGA16) || \
118     defined(CONFIG_FB_VGA16_MODULE) || defined(CONFIG_FB_VESA)
119 struct screen_info screen_info = {
120         0, 25,                  /* orig-x, orig-y */
121         0,                      /* unused */
122         0,                      /* orig-video-page */
123         0,                      /* orig-video-mode */
124         80,                     /* orig-video-cols */
125         0,0,0,                  /* ega_ax, ega_bx, ega_cx */
126         25,                     /* orig-video-lines */
127         1,                      /* orig-video-isVGA */
128         16                      /* orig-video-points */
129 };
130 #endif /* CONFIG_VGA_CONSOLE || CONFIG_FB_VGA16 || CONFIG_FB_VESA */
131
132 void machine_restart(char *cmd)
133 {
134 #ifdef CONFIG_NVRAM
135         nvram_sync();
136 #endif
137         ppc_md.restart(cmd);
138 }
139
140 void machine_power_off(void)
141 {
142 #ifdef CONFIG_NVRAM
143         nvram_sync();
144 #endif
145         ppc_md.power_off();
146 }
147
148 void machine_halt(void)
149 {
150 #ifdef CONFIG_NVRAM
151         nvram_sync();
152 #endif
153         ppc_md.halt();
154 }
155
156 void (*pm_power_off)(void) = machine_power_off;
157
158 #ifdef CONFIG_TAU
159 extern u32 cpu_temp(unsigned long cpu);
160 extern u32 cpu_temp_both(unsigned long cpu);
161 #endif /* CONFIG_TAU */
162
163 int show_cpuinfo(struct seq_file *m, void *v)
164 {
165         int i = (int) v - 1;
166         int err = 0;
167         unsigned int pvr;
168         unsigned short maj, min;
169         unsigned long lpj;
170
171         if (i >= NR_CPUS) {
172                 /* Show summary information */
173 #ifdef CONFIG_SMP
174                 unsigned long bogosum = 0;
175                 for (i = 0; i < NR_CPUS; ++i)
176                         if (cpu_online(i))
177                                 bogosum += cpu_data[i].loops_per_jiffy;
178                 seq_printf(m, "total bogomips\t: %lu.%02lu\n",
179                            bogosum/(500000/HZ), bogosum/(5000/HZ) % 100);
180 #endif /* CONFIG_SMP */
181
182                 if (ppc_md.show_cpuinfo != NULL)
183                         err = ppc_md.show_cpuinfo(m);
184                 return err;
185         }
186
187 #ifdef CONFIG_SMP
188         if (!cpu_online(i))
189                 return 0;
190         pvr = cpu_data[i].pvr;
191         lpj = cpu_data[i].loops_per_jiffy;
192 #else
193         pvr = mfspr(SPRN_PVR);
194         lpj = loops_per_jiffy;
195 #endif
196
197         seq_printf(m, "processor\t: %d\n", i);
198         seq_printf(m, "cpu\t\t: ");
199
200         if (cur_cpu_spec->pvr_mask)
201                 seq_printf(m, "%s", cur_cpu_spec->cpu_name);
202         else
203                 seq_printf(m, "unknown (%08x)", pvr);
204 #ifdef CONFIG_ALTIVEC
205         if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
206                 seq_printf(m, ", altivec supported");
207 #endif
208         seq_printf(m, "\n");
209
210 #ifdef CONFIG_TAU
211         if (cur_cpu_spec->cpu_features & CPU_FTR_TAU) {
212 #ifdef CONFIG_TAU_AVERAGE
213                 /* more straightforward, but potentially misleading */
214                 seq_printf(m,  "temperature \t: %u C (uncalibrated)\n",
215                            cpu_temp(i));
216 #else
217                 /* show the actual temp sensor range */
218                 u32 temp;
219                 temp = cpu_temp_both(i);
220                 seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n",
221                            temp & 0xff, temp >> 16);
222 #endif
223         }
224 #endif /* CONFIG_TAU */
225
226         if (ppc_md.show_percpuinfo != NULL) {
227                 err = ppc_md.show_percpuinfo(m, i);
228                 if (err)
229                         return err;
230         }
231
232         /* If we are a Freescale core do a simple check so
233          * we dont have to keep adding cases in the future */
234         if ((PVR_VER(pvr) & 0x8000) == 0x8000) {
235                 maj = PVR_MAJ(pvr);
236                 min = PVR_MIN(pvr);
237         } else {
238                 switch (PVR_VER(pvr)) {
239                         case 0x0020:    /* 403 family */
240                                 maj = PVR_MAJ(pvr) + 1;
241                                 min = PVR_MIN(pvr);
242                                 break;
243                         case 0x1008:    /* 740P/750P ?? */
244                                 maj = ((pvr >> 8) & 0xFF) - 1;
245                                 min = pvr & 0xFF;
246                                 break;
247                         default:
248                                 maj = (pvr >> 8) & 0xFF;
249                                 min = pvr & 0xFF;
250                                 break;
251                 }
252         }
253
254         seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n",
255                    maj, min, PVR_VER(pvr), PVR_REV(pvr));
256
257         seq_printf(m, "bogomips\t: %lu.%02lu\n",
258                    lpj / (500000/HZ), (lpj / (5000/HZ)) % 100);
259
260 #if USES_PPC_SYS
261         if (cur_ppc_sys_spec->ppc_sys_name)
262                 seq_printf(m, "chipset\t\t: %s\n",
263                         cur_ppc_sys_spec->ppc_sys_name);
264 #endif
265
266 #ifdef CONFIG_SMP
267         seq_printf(m, "\n");
268 #endif
269
270         return 0;
271 }
272
273 static void *c_start(struct seq_file *m, loff_t *pos)
274 {
275         int i = *pos;
276
277         return i <= NR_CPUS? (void *) (i + 1): NULL;
278 }
279
280 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
281 {
282         ++*pos;
283         return c_start(m, pos);
284 }
285
286 static void c_stop(struct seq_file *m, void *v)
287 {
288 }
289
290 struct seq_operations cpuinfo_op = {
291         .start =c_start,
292         .next = c_next,
293         .stop = c_stop,
294         .show = show_cpuinfo,
295 };
296
297 /*
298  * We're called here very early in the boot.  We determine the machine
299  * type and call the appropriate low-level setup functions.
300  *  -- Cort <cort@fsmlabs.com>
301  *
302  * Note that the kernel may be running at an address which is different
303  * from the address that it was linked at, so we must use RELOC/PTRRELOC
304  * to access static data (including strings).  -- paulus
305  */
306 __init
307 unsigned long
308 early_init(int r3, int r4, int r5)
309 {
310         unsigned long phys;
311         unsigned long offset = reloc_offset();
312
313         /* Default */
314         phys = offset + KERNELBASE;
315
316         /* First zero the BSS -- use memset, some arches don't have
317          * caches on yet */
318         memset_io(PTRRELOC(&__bss_start), 0, _end - __bss_start);
319
320         /*
321          * Identify the CPU type and fix up code sections
322          * that depend on which cpu we have.
323          */
324         identify_cpu(offset, 0);
325         do_cpu_ftr_fixups(offset);
326
327 #if defined(CONFIG_PPC_MULTIPLATFORM)
328         reloc_got2(offset);
329
330         /* If we came here from BootX, clear the screen,
331          * set up some pointers and return. */
332         if ((r3 == 0x426f6f58) && (r5 == 0))
333                 bootx_init(r4, phys);
334
335         /*
336          * don't do anything on prep
337          * for now, don't use bootinfo because it breaks yaboot 0.5
338          * and assume that if we didn't find a magic number, we have OF
339          */
340         else if (*(unsigned long *)(0) != 0xdeadc0de)
341                 phys = prom_init(r3, r4, (prom_entry)r5);
342
343         reloc_got2(-offset);
344 #endif
345
346         return phys;
347 }
348
349 #ifdef CONFIG_PPC_OF
350 /*
351  * Assume here that all clock rates are the same in a
352  * smp system.  -- Cort
353  */
354 int
355 of_show_percpuinfo(struct seq_file *m, int i)
356 {
357         struct device_node *cpu_node;
358         u32 *fp;
359         int s;
360         
361         cpu_node = find_type_devices("cpu");
362         if (!cpu_node)
363                 return 0;
364         for (s = 0; s < i && cpu_node->next; s++)
365                 cpu_node = cpu_node->next;
366         fp = (u32 *)get_property(cpu_node, "clock-frequency", NULL);
367         if (fp)
368                 seq_printf(m, "clock\t\t: %dMHz\n", *fp / 1000000);
369         return 0;
370 }
371
372 void __init
373 intuit_machine_type(void)
374 {
375         char *model;
376         struct device_node *root;
377         
378         /* ask the OF info if we're a chrp or pmac */
379         root = find_path_device("/");
380         if (root != 0) {
381                 /* assume pmac unless proven to be chrp -- Cort */
382                 _machine = _MACH_Pmac;
383                 model = get_property(root, "device_type", NULL);
384                 if (model && !strncmp("chrp", model, 4))
385                         _machine = _MACH_chrp;
386                 else {
387                         model = get_property(root, "model", NULL);
388                         if (model && !strncmp(model, "IBM", 3))
389                                 _machine = _MACH_chrp;
390                 }
391         }
392 }
393 #endif
394
395 #ifdef CONFIG_PPC_MULTIPLATFORM
396 /*
397  * The PPC_MULTIPLATFORM version of platform_init...
398  */
399 void __init
400 platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
401               unsigned long r6, unsigned long r7)
402 {
403 #ifdef CONFIG_BOOTX_TEXT
404         if (boot_text_mapped) {
405                 btext_clearscreen();
406                 btext_welcome();
407         }
408 #endif
409
410         parse_bootinfo(find_bootinfo());
411
412         /* if we didn't get any bootinfo telling us what we are... */
413         if (_machine == 0) {
414                 /* prep boot loader tells us if we're prep or not */
415                 if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
416                         _machine = _MACH_prep;
417         }
418
419 #ifdef CONFIG_PPC_PREP
420         /* not much more to do here, if prep */
421         if (_machine == _MACH_prep) {
422                 prep_init(r3, r4, r5, r6, r7);
423                 return;
424         }
425 #endif
426
427         have_of = 1;
428
429         /* prom_init has already been called from __start */
430         if (boot_infos)
431                 relocate_nodes();
432
433         /* If we aren't PReP, we can find out if we're Pmac
434          * or CHRP with this. */
435         if (_machine == 0)
436                 intuit_machine_type();
437
438         /* finish_device_tree may need _machine defined. */
439         finish_device_tree();
440
441         /*
442          * If we were booted via quik, r3 points to the physical
443          * address of the command-line parameters.
444          * If we were booted from an xcoff image (i.e. netbooted or
445          * booted from floppy), we get the command line from the
446          * bootargs property of the /chosen node.
447          * If an initial ramdisk is present, r3 and r4
448          * are used for initrd_start and initrd_size,
449          * otherwise they contain 0xdeadbeef.
450          */
451         if (r3 >= 0x4000 && r3 < 0x800000 && r4 == 0) {
452                 strlcpy(cmd_line, (char *)r3 + KERNELBASE,
453                         sizeof(cmd_line));
454         } else if (boot_infos != 0) {
455                 /* booted by BootX - check for ramdisk */
456                 if (boot_infos->kernelParamsOffset != 0)
457                         strlcpy(cmd_line, (char *) boot_infos
458                                 + boot_infos->kernelParamsOffset,
459                                 sizeof(cmd_line));
460 #ifdef CONFIG_BLK_DEV_INITRD
461                 if (boot_infos->ramDisk) {
462                         initrd_start = (unsigned long) boot_infos
463                                 + boot_infos->ramDisk;
464                         initrd_end = initrd_start + boot_infos->ramDiskSize;
465                         initrd_below_start_ok = 1;
466                 }
467 #endif
468         } else {
469                 struct device_node *chosen;
470                 char *p;
471         
472 #ifdef CONFIG_BLK_DEV_INITRD
473                 if (r3 && r4 && r4 != 0xdeadbeef) {
474                         if (r3 < KERNELBASE)
475                                 r3 += KERNELBASE;
476                         initrd_start = r3;
477                         initrd_end = r3 + r4;
478                         ROOT_DEV = Root_RAM0;
479                         initrd_below_start_ok = 1;
480                 }
481 #endif
482                 chosen = find_devices("chosen");
483                 if (chosen != NULL) {
484                         p = get_property(chosen, "bootargs", NULL);
485                         if (p && *p) {
486                                 strlcpy(cmd_line, p, sizeof(cmd_line));
487                         }
488                 }
489         }
490 #ifdef CONFIG_ADB
491         if (strstr(cmd_line, "adb_sync")) {
492                 extern int __adb_probe_sync;
493                 __adb_probe_sync = 1;
494         }
495 #endif /* CONFIG_ADB */
496
497         switch (_machine) {
498 #ifdef CONFIG_PPC_PMAC
499         case _MACH_Pmac:
500                 pmac_init(r3, r4, r5, r6, r7);
501                 break;
502 #endif
503 #ifdef CONFIG_PPC_CHRP
504         case _MACH_chrp:
505                 chrp_init(r3, r4, r5, r6, r7);
506                 break;
507 #endif
508         }
509 }
510
511 #ifdef CONFIG_SERIAL_CORE_CONSOLE
512 extern char *of_stdout_device;
513
514 static int __init set_preferred_console(void)
515 {
516         struct device_node *prom_stdout;
517         char *name;
518         int offset = 0;
519
520         if (of_stdout_device == NULL)
521                 return -ENODEV;
522
523         /* The user has requested a console so this is already set up. */
524         if (strstr(saved_command_line, "console="))
525                 return -EBUSY;
526
527         prom_stdout = find_path_device(of_stdout_device);
528         if (!prom_stdout)
529                 return -ENODEV;
530
531         name = (char *)get_property(prom_stdout, "name", NULL);
532         if (!name)
533                 return -ENODEV;
534
535         if (strcmp(name, "serial") == 0) {
536                 int i;
537                 u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i);
538                 if (i > 8) {
539                         switch (reg[1]) {
540                                 case 0x3f8:
541                                         offset = 0;
542                                         break;
543                                 case 0x2f8:
544                                         offset = 1;
545                                         break;
546                                 case 0x898:
547                                         offset = 2;
548                                         break;
549                                 case 0x890:
550                                         offset = 3;
551                                         break;
552                                 default:
553                                         /* We dont recognise the serial port */
554                                         return -ENODEV;
555                         }
556                 }
557         } else if (strcmp(name, "ch-a") == 0)
558                 offset = 0;
559         else if (strcmp(name, "ch-b") == 0)
560                 offset = 1;
561         else
562                 return -ENODEV;
563         return add_preferred_console("ttyS", offset, NULL);
564 }
565 console_initcall(set_preferred_console);
566 #endif /* CONFIG_SERIAL_CORE_CONSOLE */
567 #endif /* CONFIG_PPC_MULTIPLATFORM */
568
569 struct bi_record *find_bootinfo(void)
570 {
571         struct bi_record *rec;
572
573         rec = (struct bi_record *)_ALIGN((ulong)__bss_start+(1<<20)-1,(1<<20));
574         if ( rec->tag != BI_FIRST ) {
575                 /*
576                  * This 0x10000 offset is a terrible hack but it will go away when
577                  * we have the bootloader handle all the relocation and
578                  * prom calls -- Cort
579                  */
580                 rec = (struct bi_record *)_ALIGN((ulong)__bss_start+0x10000+(1<<20)-1,(1<<20));
581                 if ( rec->tag != BI_FIRST )
582                         return NULL;
583         }
584         return rec;
585 }
586
587 void parse_bootinfo(struct bi_record *rec)
588 {
589         if (rec == NULL || rec->tag != BI_FIRST)
590                 return;
591         while (rec->tag != BI_LAST) {
592                 ulong *data = rec->data;
593                 switch (rec->tag) {
594                 case BI_CMD_LINE:
595                         strlcpy(cmd_line, (void *)data, sizeof(cmd_line));
596                         break;
597 #ifdef CONFIG_BLK_DEV_INITRD
598                 case BI_INITRD:
599                         initrd_start = data[0] + KERNELBASE;
600                         initrd_end = data[0] + data[1] + KERNELBASE;
601                         break;
602 #endif /* CONFIG_BLK_DEV_INITRD */
603 #ifdef CONFIG_PPC_MULTIPLATFORM
604                 case BI_MACHTYPE:
605                         /* Machine types changed with the merge. Since the
606                          * bootinfo are now deprecated, we can just hard code
607                          * the appropriate conversion here for when we are
608                          * called with yaboot which passes us a machine type
609                          * this way.
610                          */
611                         switch(data[0]) {
612                         case 1: _machine = _MACH_prep; break;
613                         case 2: _machine = _MACH_Pmac; break;
614                         case 4: _machine = _MACH_chrp; break;
615                         default:
616                                 _machine = data[0];
617                         }
618                         break;
619 #endif
620                 case BI_MEMSIZE:
621                         boot_mem_size = data[0];
622                         break;
623                 }
624                 rec = (struct bi_record *)((ulong)rec + rec->size);
625         }
626 }
627
628 /*
629  * Find out what kind of machine we're on and save any data we need
630  * from the early boot process (devtree is copied on pmac by prom_init()).
631  * This is called very early on the boot process, after a minimal
632  * MMU environment has been set up but before MMU_init is called.
633  */
634 void __init
635 machine_init(unsigned long r3, unsigned long r4, unsigned long r5,
636              unsigned long r6, unsigned long r7)
637 {
638 #ifdef CONFIG_CMDLINE
639         strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
640 #endif /* CONFIG_CMDLINE */
641
642 #ifdef CONFIG_6xx
643         ppc_md.power_save = ppc6xx_idle;
644 #endif
645 #ifdef CONFIG_POWER4
646         ppc_md.power_save = power4_idle;
647 #endif
648
649         platform_init(r3, r4, r5, r6, r7);
650
651         if (ppc_md.progress)
652                 ppc_md.progress("id mach(): done", 0x200);
653 }
654 #ifdef CONFIG_BOOKE_WDT
655 /* Checks wdt=x and wdt_period=xx command-line option */
656 int __init early_parse_wdt(char *p)
657 {
658         if (p && strncmp(p, "0", 1) != 0)
659                booke_wdt_enabled = 1;
660
661         return 0;
662 }
663 early_param("wdt", early_parse_wdt);
664
665 int __init early_parse_wdt_period (char *p)
666 {
667         if (p)
668                 booke_wdt_period = simple_strtoul(p, NULL, 0);
669
670         return 0;
671 }
672 early_param("wdt_period", early_parse_wdt_period);
673 #endif  /* CONFIG_BOOKE_WDT */
674
675 /* Checks "l2cr=xxxx" command-line option */
676 int __init ppc_setup_l2cr(char *str)
677 {
678         if (cpu_has_feature(CPU_FTR_L2CR)) {
679                 unsigned long val = simple_strtoul(str, NULL, 0);
680                 printk(KERN_INFO "l2cr set to %lx\n", val);
681                 _set_L2CR(0);           /* force invalidate by disable cache */
682                 _set_L2CR(val);         /* and enable it */
683         }
684         return 1;
685 }
686 __setup("l2cr=", ppc_setup_l2cr);
687
688 #ifdef CONFIG_GENERIC_NVRAM
689
690 /* Generic nvram hooks used by drivers/char/gen_nvram.c */
691 unsigned char nvram_read_byte(int addr)
692 {
693         if (ppc_md.nvram_read_val)
694                 return ppc_md.nvram_read_val(addr);
695         return 0xff;
696 }
697 EXPORT_SYMBOL(nvram_read_byte);
698
699 void nvram_write_byte(unsigned char val, int addr)
700 {
701         if (ppc_md.nvram_write_val)
702                 ppc_md.nvram_write_val(addr, val);
703 }
704 EXPORT_SYMBOL(nvram_write_byte);
705
706 void nvram_sync(void)
707 {
708         if (ppc_md.nvram_sync)
709                 ppc_md.nvram_sync();
710 }
711 EXPORT_SYMBOL(nvram_sync);
712
713 #endif /* CONFIG_NVRAM */
714
715 static struct cpu cpu_devices[NR_CPUS];
716
717 int __init ppc_init(void)
718 {
719         int i;
720
721         /* clear the progress line */
722         if ( ppc_md.progress ) ppc_md.progress("             ", 0xffff);
723
724         /* register CPU devices */
725         for (i = 0; i < NR_CPUS; i++)
726                 if (cpu_possible(i))
727                         register_cpu(&cpu_devices[i], i, NULL);
728
729         /* call platform init */
730         if (ppc_md.init != NULL) {
731                 ppc_md.init();
732         }
733         return 0;
734 }
735
736 arch_initcall(ppc_init);
737
738 /* Warning, IO base is not yet inited */
739 void __init setup_arch(char **cmdline_p)
740 {
741         extern char *klimit;
742         extern void do_init_bootmem(void);
743
744         /* so udelay does something sensible, assume <= 1000 bogomips */
745         loops_per_jiffy = 500000000 / HZ;
746
747 #ifdef CONFIG_PPC_MULTIPLATFORM
748         /* This could be called "early setup arch", it must be done
749          * now because xmon need it
750          */
751         if (_machine == _MACH_Pmac)
752                 pmac_feature_init();    /* New cool way */
753 #endif
754
755 #ifdef CONFIG_XMON
756         xmon_init(1);
757         if (strstr(cmd_line, "xmon"))
758                 xmon(NULL);
759 #endif /* CONFIG_XMON */
760         if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab);
761
762 #if defined(CONFIG_KGDB)
763         if (ppc_md.kgdb_map_scc)
764                 ppc_md.kgdb_map_scc();
765         set_debug_traps();
766         if (strstr(cmd_line, "gdb")) {
767                 if (ppc_md.progress)
768                         ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000);
769                 printk("kgdb breakpoint activated\n");
770                 breakpoint();
771         }
772 #endif
773
774         /*
775          * Set cache line size based on type of cpu as a default.
776          * Systems with OF can look in the properties on the cpu node(s)
777          * for a possibly more accurate value.
778          */
779         if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) {
780                 dcache_bsize = cur_cpu_spec->dcache_bsize;
781                 icache_bsize = cur_cpu_spec->icache_bsize;
782                 ucache_bsize = 0;
783         } else
784                 ucache_bsize = dcache_bsize = icache_bsize
785                         = cur_cpu_spec->dcache_bsize;
786
787         /* reboot on panic */
788         panic_timeout = 180;
789
790         init_mm.start_code = PAGE_OFFSET;
791         init_mm.end_code = (unsigned long) _etext;
792         init_mm.end_data = (unsigned long) _edata;
793         init_mm.brk = (unsigned long) klimit;
794
795         /* Save unparsed command line copy for /proc/cmdline */
796         strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
797         *cmdline_p = cmd_line;
798
799         parse_early_param();
800
801         /* set up the bootmem stuff with available memory */
802         do_init_bootmem();
803         if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
804
805 #ifdef CONFIG_PPC_OCP
806         /* Initialize OCP device list */
807         ocp_early_init();
808         if ( ppc_md.progress ) ppc_md.progress("ocp: exit", 0x3eab);
809 #endif
810
811 #ifdef CONFIG_DUMMY_CONSOLE
812         conswitchp = &dummy_con;
813 #endif
814
815         ppc_md.setup_arch();
816         if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
817
818         paging_init();
819
820         /* this is for modules since _machine can be a define -- Cort */
821         ppc_md.ppc_machine = _machine;
822 }