Import 2.3.9pre7
[davej-history.git] / arch / ppc / kernel / setup.c
blob48c06d6e8255a7cea25ef63436fbc54ba4e722cc
1 /*
2 * $Id: setup.c,v 1.136 1999/06/18 07:11:35 cort Exp $
3 * Common prep/pmac/chrp boot and setup code.
4 */
6 #include <linux/config.h>
7 #include <linux/module.h>
8 #include <linux/string.h>
9 #include <linux/sched.h>
10 #include <linux/init.h>
11 #include <linux/reboot.h>
12 #include <linux/delay.h>
13 #include <linux/blk.h>
15 #include <asm/adb.h>
16 #include <asm/cuda.h>
17 #include <asm/pmu.h>
18 #include <asm/residual.h>
19 #include <asm/io.h>
20 #include <linux/ide.h>
21 #include <asm/ide.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 #ifdef CONFIG_MBX
30 #include <asm/mbx.h>
31 #include <asm/8xx_immap.h>
32 #endif
33 #include <asm/bootx.h>
34 #include <asm/machdep.h>
35 #include <asm/ide.h>
37 extern void pmac_init(unsigned long r3,
38 unsigned long r4,
39 unsigned long r5,
40 unsigned long r6,
41 unsigned long r7);
43 extern void chrp_init(unsigned long r3,
44 unsigned long r4,
45 unsigned long r5,
46 unsigned long r6,
47 unsigned long r7);
49 extern void prep_init(unsigned long r3,
50 unsigned long r4,
51 unsigned long r5,
52 unsigned long r6,
53 unsigned long r7);
55 extern void mbx_init(unsigned long r3,
56 unsigned long r4,
57 unsigned long r5,
58 unsigned long r6,
59 unsigned long r7);
61 extern void apus_init(unsigned long r3,
62 unsigned long r4,
63 unsigned long r5,
64 unsigned long r6,
65 unsigned long r7);
67 extern boot_infos_t *boot_infos;
68 extern char cmd_line[512];
69 char saved_command_line[256];
70 unsigned char aux_device_present;
72 struct ide_machdep_calls ppc_ide_md;
74 unsigned long ISA_DMA_THRESHOLD;
75 unsigned long DMA_MODE_READ, DMA_MODE_WRITE;
77 /* Temporary hacks until machdep.h is fully done. */
78 int _machine = 0;
79 /* do we have OF? */
80 int have_of = 0;
81 int is_prep = 0;
82 int is_chrp = 0;
83 #ifdef CONFIG_MAGIC_SYSRQ
84 unsigned long SYSRQ_KEY;
85 #endif /* CONFIG_MAGIC_SYSRQ */
86 /* For MTX/MVME boards.. with Raven/Falcon Chipset
87 Real close to CHRP, but boot like PReP (via PPCbug)
88 There's probably a nicer way to do this.. --Troy */
89 int is_powerplus = 0;
91 struct machdep_calls ppc_md;
94 /* copy of the residual data */
95 #ifndef CONFIG_MBX
96 unsigned char __res[sizeof(RESIDUAL)] __prepdata = {0,};
97 #else
98 unsigned char __res[sizeof(bd_t)] = {0,};
99 #endif
101 RESIDUAL *res = (RESIDUAL *)&__res;
104 * Perhaps we can put the pmac screen_info[] here
105 * on pmac as well so we don't need the ifdef's.
106 * Until we get multiple-console support in here
107 * that is. -- Cort
109 #ifndef CONFIG_MBX
110 struct screen_info screen_info = {
111 0, 25, /* orig-x, orig-y */
112 0, /* unused */
113 0, /* orig-video-page */
114 0, /* orig-video-mode */
115 80, /* orig-video-cols */
116 0,0,0, /* ega_ax, ega_bx, ega_cx */
117 25, /* orig-video-lines */
118 1, /* orig-video-isVGA */
119 16 /* orig-video-points */
123 * I really need to add multiple-console support... -- Cort
125 __initfunc(int pmac_display_supported(char *name))
127 return 0;
129 __initfunc(void pmac_find_display(void))
133 #else /* CONFIG_MBX */
135 /* We need this to satisfy some external references until we can
136 * strip the kernel down.
138 struct screen_info screen_info = {
139 0, 25, /* orig-x, orig-y */
140 0, /* unused */
141 0, /* orig-video-page */
142 0, /* orig-video-mode */
143 80, /* orig-video-cols */
144 0,0,0, /* ega_ax, ega_bx, ega_cx */
145 25, /* orig-video-lines */
146 0, /* orig-video-isVGA */
147 16 /* orig-video-points */
149 #endif /* CONFIG_MBX */
151 void machine_restart(char *cmd)
153 ppc_md.restart(cmd);
156 void machine_power_off(void)
158 ppc_md.power_off();
161 void machine_halt(void)
163 ppc_md.halt();
166 unsigned long cpu_temp(void)
168 unsigned char thres = 0;
170 #if 0
171 /* disable thrm2 */
172 _set_THRM2( 0 );
173 /* threshold 0 C, tid: exceeding threshold, tie: don't generate interrupt */
174 _set_THRM1( THRM1_V );
176 /* we need 20us to do the compare - assume 300MHz processor clock */
177 _set_THRM3(0);
178 _set_THRM3(THRM3_E | (300*30)<<18 );
180 udelay(100);
181 /* wait for the compare to complete */
182 /*while ( !(_get_THRM1() & THRM1_TIV) ) ;*/
183 if ( !(_get_THRM1() & THRM1_TIV) )
184 printk("no tiv\n");
185 if ( _get_THRM1() & THRM1_TIN )
186 printk("crossed\n");
187 /* turn everything off */
188 _set_THRM3(0);
189 _set_THRM1(0);
190 #endif
192 return thres;
195 int get_cpuinfo(char *buffer)
197 unsigned long len = 0;
198 unsigned long bogosum = 0;
199 unsigned long i;
201 #ifdef __SMP__
202 #define CPU_PRESENT(x) (cpu_callin_map[(x)])
203 #define GET_PVR ((long int)(cpu_data[i].pvr))
204 #define CD(x) (cpu_data[i].x)
205 #else
206 #define CPU_PRESENT(x) ((x)==0)
207 #define smp_num_cpus 1
208 #define GET_PVR ((long int)_get_PVR())
209 #define CD(x) (x)
210 #endif
212 for ( i = 0; i < smp_num_cpus ; i++ )
214 if ( !CPU_PRESENT(i) )
215 continue;
216 if ( i )
217 len += sprintf(len+buffer,"\n");
218 len += sprintf(len+buffer,"processor\t: %lu\n",i);
219 len += sprintf(len+buffer,"cpu\t\t: ");
221 switch (GET_PVR >> 16)
223 case 1:
224 len += sprintf(len+buffer, "601\n");
225 break;
226 case 3:
227 len += sprintf(len+buffer, "603\n");
228 break;
229 case 4:
230 len += sprintf(len+buffer, "604\n");
231 break;
232 case 6:
233 len += sprintf(len+buffer, "603e\n");
234 break;
235 case 7:
236 len += sprintf(len+buffer, "603ev\n");
237 break;
238 case 8:
239 len += sprintf(len+buffer, "750\n");
240 len += sprintf(len+buffer, "temperature \t: %lu C\n",
241 cpu_temp());
242 break;
243 case 9:
244 len += sprintf(len+buffer, "604e\n");
245 break;
246 case 10:
247 len += sprintf(len+buffer, "604ev5 (MachV)\n");
248 break;
249 case 50:
250 len += sprintf(len+buffer, "821\n");
251 case 80:
252 len += sprintf(len+buffer, "860\n");
253 break;
254 default:
255 len += sprintf(len+buffer, "unknown (%lu)\n",
256 GET_PVR>>16);
257 break;
261 * Assume here that all clock rates are the same in a
262 * smp system. -- Cort
264 if ( have_of )
266 struct device_node *cpu_node;
267 int *fp;
269 cpu_node = find_type_devices("cpu");
270 if ( !cpu_node ) break;
271 fp = (int *) get_property(cpu_node, "clock-frequency", NULL);
272 if ( !fp ) break;
273 len += sprintf(len+buffer, "clock\t\t: %dMHz\n",
274 *fp / 1000000);
277 if (ppc_md.setup_residual != NULL)
279 len += ppc_md.setup_residual(buffer + len);
282 len += sprintf(len+buffer, "revision\t: %ld.%ld\n",
283 (GET_PVR & 0xff00) >> 8, GET_PVR & 0xff);
285 len += sprintf(buffer+len, "bogomips\t: %lu.%02lu\n",
286 (CD(loops_per_sec)+2500)/500000,
287 (CD(loops_per_sec)+2500)/5000 % 100);
288 bogosum += CD(loops_per_sec);
291 #ifdef __SMP__
292 if ( i )
293 len += sprintf(buffer+len, "\n");
294 len += sprintf(buffer+len,"total bogomips\t: %lu.%02lu\n",
295 (bogosum+2500)/500000,
296 (bogosum+2500)/5000 % 100);
297 #endif /* __SMP__ */
300 * Ooh's and aah's info about zero'd pages in idle task
303 len += sprintf(buffer+len,"zero pages\t: total %lu (%luKb) "
304 "current: %lu (%luKb) hits: %lu/%lu (%lu%%)\n",
305 zero_cache_total,
306 (zero_cache_total*PAGE_SIZE)>>10,
307 zero_cache_sz,
308 (zero_cache_sz*PAGE_SIZE)>>10,
309 zero_cache_hits,zero_cache_calls,
310 /* : 1 below is so we don't div by zero */
311 (zero_cache_hits*100) /
312 ((zero_cache_calls)?zero_cache_calls:1));
315 if (ppc_md.get_cpuinfo != NULL)
317 len += ppc_md.get_cpuinfo(buffer+len);
320 return len;
324 * Find out what kind of machine we're on and save any data we need
325 * from the early boot process (devtree is copied on pmac by prom_init() )
327 unsigned long __init
328 identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
329 unsigned long r6, unsigned long r7)
332 #ifdef __SMP__
333 if ( first_cpu_booted ) return 0;
334 #endif /* __SMP__ */
336 #ifndef CONFIG_MACH_SPECIFIC
337 /* boot loader will tell us if we're APUS */
338 if ( r3 == 0x61707573 )
340 _machine = _MACH_apus;
341 r3 = 0;
343 /* prep boot loader tells us if we're prep or not */
344 else if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) {
345 _machine = _MACH_prep;
346 is_prep = 1;
347 } else {
348 char *model;
350 have_of = 1;
352 /* prom_init has already been called from __start */
353 finish_device_tree();
354 /* ask the OF info if we're a chrp or pmac */
355 model = get_property(find_path_device("/"), "device_type", NULL);
356 if ( model && !strncmp("chrp",model,4) )
358 _machine = _MACH_chrp;
359 is_chrp = 1;
361 else
363 model = get_property(find_path_device("/"),
364 "model", NULL);
365 if ( model && !strncmp(model, "IBM", 3))
367 _machine = _MACH_chrp;
368 is_chrp = 1;
370 else
372 _machine = _MACH_Pmac;
377 #else /* CONFIG_MACH_SPECIFIC */
379 #ifdef CONFIG_PREP
380 _machine = _MACH_prep;
381 is_prep = 1;
382 #elif defined(CONFIG_CHRP)
383 _machine = _MACH_chrp;
384 is_chrp = 1;
385 have_of = 1;
386 #elif defined(CONFIG_PMAC)
387 _machine = _MACH_Pmac;
388 have_of = 1;
389 #elif defined(CONFIG_MBX)
390 _machine = _MACH_mbx;
391 #elif defined(CONFIG_FADS)
392 _machine = _MACH_fads;
393 #elif defined(CONFIG_APUS)
394 _machine = _MACH_apus;
395 #else
396 #error "Machine not defined correctly"
397 #endif /* CONFIG_APUS */
398 #endif /* CONFIG_MACH_SPECIFIC */
400 if ( have_of )
402 #ifdef CONFIG_MACH_SPECIFIC
403 /* prom_init has already been called from __start */
404 finish_device_tree();
405 #endif /* CONFIG_MACH_SPECIFIC */
407 * If we were booted via quik, r3 points to the physical
408 * address of the command-line parameters.
409 * If we were booted from an xcoff image (i.e. netbooted or
410 * booted from floppy), we get the command line from the
411 * bootargs property of the /chosen node.
412 * If an initial ramdisk is present, r3 and r4
413 * are used for initrd_start and initrd_size,
414 * otherwise they contain 0xdeadbeef.
416 cmd_line[0] = 0;
417 if (r3 >= 0x4000 && r3 < 0x800000 && r4 == 0) {
418 strncpy(cmd_line, (char *)r3 + KERNELBASE,
419 sizeof(cmd_line));
420 } else if (boot_infos != 0) {
421 /* booted by BootX - check for ramdisk */
422 if (boot_infos->kernelParamsOffset != 0)
423 strncpy(cmd_line, (char *) boot_infos
424 + boot_infos->kernelParamsOffset,
425 sizeof(cmd_line));
426 #ifdef CONFIG_BLK_DEV_INITRD
427 if (boot_infos->ramDisk) {
428 initrd_start = (unsigned long) boot_infos
429 + boot_infos->ramDisk;
430 initrd_end = initrd_start + boot_infos->ramDiskSize;
431 initrd_below_start_ok = 1;
433 #endif
434 } else {
435 struct device_node *chosen;
436 char *p;
438 #ifdef CONFIG_BLK_DEV_INITRD
439 if (r3 - KERNELBASE < 0x800000
440 && r4 != 0 && r4 != 0xdeadbeef) {
441 initrd_start = r3;
442 initrd_end = r3 + r4;
443 ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
445 #endif
446 cmd_line[0] = 0;
447 chosen = find_devices("chosen");
448 if (chosen != NULL) {
449 p = get_property(chosen, "bootargs", NULL);
450 if (p != NULL)
451 strncpy(cmd_line, p, sizeof(cmd_line));
454 cmd_line[sizeof(cmd_line) - 1] = 0;
457 switch (_machine)
459 case _MACH_Pmac:
460 pmac_init(r3, r4, r5, r6, r7);
461 break;
462 case _MACH_prep:
463 prep_init(r3, r4, r5, r6, r7);
464 break;
465 case _MACH_chrp:
466 chrp_init(r3, r4, r5, r6, r7);
467 break;
468 #ifdef CONFIG_APUS
469 case _MACH_apus:
470 apus_init(r3, r4, r5, r6, r7);
471 break;
472 #endif
473 #ifdef CONFIG_MBX
474 case _MACH_mbx:
475 mbx_init(r3, r4, r5, r6, r7);
476 break;
477 #endif
478 default:
479 printk("Unknown machine type in identify_machine!\n");
482 /* Check for nobats option (used in mapin_ram). */
483 if (strstr(cmd_line, "nobats")) {
484 extern int __map_without_bats;
485 __map_without_bats = 1;
488 return 0;
491 /* Checks "l2cr=xxxx" command-line option */
492 void ppc_setup_l2cr(char *str, int *ints)
494 if ( (_get_PVR() >> 16) == 8)
496 unsigned long val = simple_strtoul(str, NULL, 0);
497 printk(KERN_INFO "l2cr set to %lx\n", val);
498 _set_L2CR(0);
499 _set_L2CR(val);
503 __initfunc(void
504 ppc_init(void))
506 if (ppc_md.init != NULL) {
507 ppc_md.init();
511 __initfunc(void setup_arch(char **cmdline_p,
512 unsigned long * memory_start_p, unsigned long * memory_end_p))
514 extern int panic_timeout;
515 extern char _etext[], _edata[];
516 extern char *klimit;
517 extern unsigned long find_available_memory(void);
518 extern unsigned long *end_of_DRAM;
520 #ifdef CONFIG_XMON
521 extern void xmon_map_scc(void);
522 xmon_map_scc();
523 if (strstr(cmd_line, "xmon"))
524 xmon(0);
525 #endif /* CONFIG_XMON */
527 /* reboot on panic */
528 panic_timeout = 180;
530 init_task.mm->start_code = PAGE_OFFSET;
531 init_task.mm->end_code = (unsigned long) _etext;
532 init_task.mm->end_data = (unsigned long) _edata;
533 init_task.mm->brk = (unsigned long) klimit;
535 /* Save unparsed command line copy for /proc/cmdline */
536 strcpy(saved_command_line, cmd_line);
537 *cmdline_p = cmd_line;
539 *memory_start_p = find_available_memory();
540 *memory_end_p = (unsigned long) end_of_DRAM;
542 ppc_md.setup_arch(memory_start_p, memory_end_p);
545 void ppc_generic_ide_fix_driveid(struct hd_driveid *id)
547 int i;
548 unsigned short *stringcast;
551 id->config = __le16_to_cpu(id->config);
552 id->cyls = __le16_to_cpu(id->cyls);
553 id->reserved2 = __le16_to_cpu(id->reserved2);
554 id->heads = __le16_to_cpu(id->heads);
555 id->track_bytes = __le16_to_cpu(id->track_bytes);
556 id->sector_bytes = __le16_to_cpu(id->sector_bytes);
557 id->sectors = __le16_to_cpu(id->sectors);
558 id->vendor0 = __le16_to_cpu(id->vendor0);
559 id->vendor1 = __le16_to_cpu(id->vendor1);
560 id->vendor2 = __le16_to_cpu(id->vendor2);
561 stringcast = (unsigned short *)&id->serial_no[0];
562 for (i=0; i<(20/2); i++)
563 stringcast[i] = __le16_to_cpu(stringcast[i]);
564 id->buf_type = __le16_to_cpu(id->buf_type);
565 id->buf_size = __le16_to_cpu(id->buf_size);
566 id->ecc_bytes = __le16_to_cpu(id->ecc_bytes);
567 stringcast = (unsigned short *)&id->fw_rev[0];
568 for (i=0; i<(8/2); i++)
569 stringcast[i] = __le16_to_cpu(stringcast[i]);
570 stringcast = (unsigned short *)&id->model[0];
571 for (i=0; i<(40/2); i++)
572 stringcast[i] = __le16_to_cpu(stringcast[i]);
573 id->dword_io = __le16_to_cpu(id->dword_io);
574 id->reserved50 = __le16_to_cpu(id->reserved50);
575 id->field_valid = __le16_to_cpu(id->field_valid);
576 id->cur_cyls = __le16_to_cpu(id->cur_cyls);
577 id->cur_heads = __le16_to_cpu(id->cur_heads);
578 id->cur_sectors = __le16_to_cpu(id->cur_sectors);
579 id->cur_capacity0 = __le16_to_cpu(id->cur_capacity0);
580 id->cur_capacity1 = __le16_to_cpu(id->cur_capacity1);
581 id->lba_capacity = __le32_to_cpu(id->lba_capacity);
582 id->dma_1word = __le16_to_cpu(id->dma_1word);
583 id->dma_mword = __le16_to_cpu(id->dma_mword);
584 id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);
585 id->eide_dma_min = __le16_to_cpu(id->eide_dma_min);
586 id->eide_dma_time = __le16_to_cpu(id->eide_dma_time);
587 id->eide_pio = __le16_to_cpu(id->eide_pio);
588 id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
589 id->word69 = __le16_to_cpu(id->word69);
590 id->word70 = __le16_to_cpu(id->word70);
591 id->word71 = __le16_to_cpu(id->word71);
592 id->word72 = __le16_to_cpu(id->word72);
593 id->word73 = __le16_to_cpu(id->word73);
594 id->word74 = __le16_to_cpu(id->word74);
595 id->word75 = __le16_to_cpu(id->word75);
596 id->word76 = __le16_to_cpu(id->word76);
597 id->word77 = __le16_to_cpu(id->word77);
598 id->word78 = __le16_to_cpu(id->word78);
599 id->word79 = __le16_to_cpu(id->word79);
600 id->word80 = __le16_to_cpu(id->word80);
601 id->word81 = __le16_to_cpu(id->word81);
602 id->command_sets = __le16_to_cpu(id->command_sets);
603 id->word83 = __le16_to_cpu(id->word83);
604 id->word84 = __le16_to_cpu(id->word84);
605 id->word85 = __le16_to_cpu(id->word85);
606 id->word86 = __le16_to_cpu(id->word86);
607 id->word87 = __le16_to_cpu(id->word87);
608 id->dma_ultra = __le16_to_cpu(id->dma_ultra);
609 id->word89 = __le16_to_cpu(id->word89);
610 id->word90 = __le16_to_cpu(id->word90);
611 id->word91 = __le16_to_cpu(id->word91);
612 id->word92 = __le16_to_cpu(id->word92);
613 id->word93 = __le16_to_cpu(id->word93);
614 id->word94 = __le16_to_cpu(id->word94);
615 id->word95 = __le16_to_cpu(id->word95);
616 id->word96 = __le16_to_cpu(id->word96);
617 id->word97 = __le16_to_cpu(id->word97);
618 id->word98 = __le16_to_cpu(id->word98);
619 id->word99 = __le16_to_cpu(id->word99);
620 id->word100 = __le16_to_cpu(id->word100);
621 id->word101 = __le16_to_cpu(id->word101);
622 id->word102 = __le16_to_cpu(id->word102);
623 id->word103 = __le16_to_cpu(id->word103);
624 id->word104 = __le16_to_cpu(id->word104);
625 id->word105 = __le16_to_cpu(id->word105);
626 id->word106 = __le16_to_cpu(id->word106);
627 id->word107 = __le16_to_cpu(id->word107);
628 id->word108 = __le16_to_cpu(id->word108);
629 id->word109 = __le16_to_cpu(id->word109);
630 id->word110 = __le16_to_cpu(id->word110);
631 id->word111 = __le16_to_cpu(id->word111);
632 id->word112 = __le16_to_cpu(id->word112);
633 id->word113 = __le16_to_cpu(id->word113);
634 id->word114 = __le16_to_cpu(id->word114);
635 id->word115 = __le16_to_cpu(id->word115);
636 id->word116 = __le16_to_cpu(id->word116);
637 id->word117 = __le16_to_cpu(id->word117);
638 id->word118 = __le16_to_cpu(id->word118);
639 id->word119 = __le16_to_cpu(id->word119);
640 id->word120 = __le16_to_cpu(id->word120);
641 id->word121 = __le16_to_cpu(id->word121);
642 id->word122 = __le16_to_cpu(id->word122);
643 id->word123 = __le16_to_cpu(id->word123);
644 id->word124 = __le16_to_cpu(id->word124);
645 id->word125 = __le16_to_cpu(id->word125);
646 id->word126 = __le16_to_cpu(id->word126);
647 id->word127 = __le16_to_cpu(id->word127);
648 id->security = __le16_to_cpu(id->security);
649 for (i=0; i<127; i++)
650 id->reserved[i] = __le16_to_cpu(id->reserved[i]);