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