Import 2.3.12pre2
[davej-history.git] / arch / ppc / kernel / setup.c
blobee3ace0a2088d8a44432f2178cbde5704779588c
1 /*
2 * $Id: setup.c,v 1.138 1999/07/11 16:32:21 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>
36 extern void pmac_init(unsigned long r3,
37 unsigned long r4,
38 unsigned long r5,
39 unsigned long r6,
40 unsigned long r7);
42 extern void chrp_init(unsigned long r3,
43 unsigned long r4,
44 unsigned long r5,
45 unsigned long r6,
46 unsigned long r7);
48 extern void prep_init(unsigned long r3,
49 unsigned long r4,
50 unsigned long r5,
51 unsigned long r6,
52 unsigned long r7);
54 extern void mbx_init(unsigned long r3,
55 unsigned long r4,
56 unsigned long r5,
57 unsigned long r6,
58 unsigned long r7);
60 extern void apus_init(unsigned long r3,
61 unsigned long r4,
62 unsigned long r5,
63 unsigned long r6,
64 unsigned long r7);
66 extern boot_infos_t *boot_infos;
67 extern char cmd_line[512];
68 char saved_command_line[256];
69 unsigned char aux_device_present;
71 struct ide_machdep_calls ppc_ide_md;
73 unsigned long ISA_DMA_THRESHOLD;
74 unsigned long DMA_MODE_READ, DMA_MODE_WRITE;
76 /* Temporary hacks until machdep.h is fully done. */
77 int _machine = 0;
78 /* do we have OF? */
79 int have_of = 0;
80 int is_prep = 0;
81 int is_chrp = 0;
82 #ifdef CONFIG_MAGIC_SYSRQ
83 unsigned long SYSRQ_KEY;
84 #endif /* CONFIG_MAGIC_SYSRQ */
85 /* For MTX/MVME boards.. with Raven/Falcon Chipset
86 Real close to CHRP, but boot like PReP (via PPCbug)
87 There's probably a nicer way to do this.. --Troy */
88 int is_powerplus = 0;
90 struct machdep_calls ppc_md;
93 /* copy of the residual data */
94 #ifndef CONFIG_MBX
95 unsigned char __res[sizeof(RESIDUAL)] __prepdata = {0,};
96 #else
97 unsigned char __res[sizeof(bd_t)] = {0,};
98 #endif
100 RESIDUAL *res = (RESIDUAL *)&__res;
103 * Perhaps we can put the pmac screen_info[] here
104 * on pmac as well so we don't need the ifdef's.
105 * Until we get multiple-console support in here
106 * that is. -- Cort
108 #ifndef CONFIG_MBX
109 struct screen_info screen_info = {
110 0, 25, /* orig-x, orig-y */
111 0, /* unused */
112 0, /* orig-video-page */
113 0, /* orig-video-mode */
114 80, /* orig-video-cols */
115 0,0,0, /* ega_ax, ega_bx, ega_cx */
116 25, /* orig-video-lines */
117 1, /* orig-video-isVGA */
118 16 /* orig-video-points */
122 * I really need to add multiple-console support... -- Cort
124 __initfunc(int pmac_display_supported(char *name))
126 return 0;
128 __initfunc(void pmac_find_display(void))
132 #else /* CONFIG_MBX */
134 /* We need this to satisfy some external references until we can
135 * strip the kernel down.
137 struct screen_info screen_info = {
138 0, 25, /* orig-x, orig-y */
139 0, /* unused */
140 0, /* orig-video-page */
141 0, /* orig-video-mode */
142 80, /* orig-video-cols */
143 0,0,0, /* ega_ax, ega_bx, ega_cx */
144 25, /* orig-video-lines */
145 0, /* orig-video-isVGA */
146 16 /* orig-video-points */
148 #endif /* CONFIG_MBX */
150 void machine_restart(char *cmd)
152 ppc_md.restart(cmd);
155 void machine_power_off(void)
157 ppc_md.power_off();
160 void machine_halt(void)
162 ppc_md.halt();
165 unsigned long cpu_temp(void)
167 unsigned char thres = 0;
169 #if 0
170 /* disable thrm2 */
171 _set_THRM2( 0 );
172 /* threshold 0 C, tid: exceeding threshold, tie: don't generate interrupt */
173 _set_THRM1( THRM1_V );
175 /* we need 20us to do the compare - assume 300MHz processor clock */
176 _set_THRM3(0);
177 _set_THRM3(THRM3_E | (300*30)<<18 );
179 udelay(100);
180 /* wait for the compare to complete */
181 /*while ( !(_get_THRM1() & THRM1_TIV) ) ;*/
182 if ( !(_get_THRM1() & THRM1_TIV) )
183 printk("no tiv\n");
184 if ( _get_THRM1() & THRM1_TIN )
185 printk("crossed\n");
186 /* turn everything off */
187 _set_THRM3(0);
188 _set_THRM1(0);
189 #endif
191 return thres;
194 int get_cpuinfo(char *buffer)
196 unsigned long len = 0;
197 unsigned long bogosum = 0;
198 unsigned long i;
200 #ifdef __SMP__
201 #define CPU_PRESENT(x) (cpu_callin_map[(x)])
202 #define GET_PVR ((long int)(cpu_data[i].pvr))
203 #define CD(x) (cpu_data[i].x)
204 #else
205 #define CPU_PRESENT(x) ((x)==0)
206 #define smp_num_cpus 1
207 #define GET_PVR ((long int)_get_PVR())
208 #define CD(x) (x)
209 #endif
211 for ( i = 0; i < smp_num_cpus ; i++ )
213 if ( !CPU_PRESENT(i) )
214 continue;
215 if ( i )
216 len += sprintf(len+buffer,"\n");
217 len += sprintf(len+buffer,"processor\t: %lu\n",i);
218 len += sprintf(len+buffer,"cpu\t\t: ");
220 switch (GET_PVR >> 16)
222 case 1:
223 len += sprintf(len+buffer, "601\n");
224 break;
225 case 3:
226 len += sprintf(len+buffer, "603\n");
227 break;
228 case 4:
229 len += sprintf(len+buffer, "604\n");
230 break;
231 case 6:
232 len += sprintf(len+buffer, "603e\n");
233 break;
234 case 7:
235 len += sprintf(len+buffer, "603ev\n");
236 break;
237 case 8:
238 len += sprintf(len+buffer, "750\n");
239 len += sprintf(len+buffer, "temperature \t: %lu C\n",
240 cpu_temp());
241 break;
242 case 9:
243 len += sprintf(len+buffer, "604e\n");
244 break;
245 case 10:
246 len += sprintf(len+buffer, "604ev5 (MachV)\n");
247 break;
248 case 50:
249 len += sprintf(len+buffer, "821\n");
250 case 80:
251 len += sprintf(len+buffer, "860\n");
252 break;
253 default:
254 len += sprintf(len+buffer, "unknown (%lu)\n",
255 GET_PVR>>16);
256 break;
260 * Assume here that all clock rates are the same in a
261 * smp system. -- Cort
263 if ( have_of )
265 struct device_node *cpu_node;
266 int *fp;
268 cpu_node = find_type_devices("cpu");
269 if ( !cpu_node ) break;
270 fp = (int *) get_property(cpu_node, "clock-frequency", NULL);
271 if ( !fp ) break;
272 len += sprintf(len+buffer, "clock\t\t: %dMHz\n",
273 *fp / 1000000);
276 if (ppc_md.setup_residual != NULL)
278 len += ppc_md.setup_residual(buffer + len);
281 len += sprintf(len+buffer, "revision\t: %ld.%ld\n",
282 (GET_PVR & 0xff00) >> 8, GET_PVR & 0xff);
284 len += sprintf(buffer+len, "bogomips\t: %lu.%02lu\n",
285 (CD(loops_per_sec)+2500)/500000,
286 (CD(loops_per_sec)+2500)/5000 % 100);
287 bogosum += CD(loops_per_sec);
290 #ifdef __SMP__
291 if ( i )
292 len += sprintf(buffer+len, "\n");
293 len += sprintf(buffer+len,"total bogomips\t: %lu.%02lu\n",
294 (bogosum+2500)/500000,
295 (bogosum+2500)/5000 % 100);
296 #endif /* __SMP__ */
299 * Ooh's and aah's info about zero'd pages in idle task
302 len += sprintf(buffer+len,"zero pages\t: total %lu (%luKb) "
303 "current: %lu (%luKb) hits: %lu/%lu (%lu%%)\n",
304 zero_cache_total,
305 (zero_cache_total*PAGE_SIZE)>>10,
306 zero_cache_sz,
307 (zero_cache_sz*PAGE_SIZE)>>10,
308 zero_cache_hits,zero_cache_calls,
309 /* : 1 below is so we don't div by zero */
310 (zero_cache_hits*100) /
311 ((zero_cache_calls)?zero_cache_calls:1));
314 if (ppc_md.get_cpuinfo != NULL)
316 len += ppc_md.get_cpuinfo(buffer+len);
319 return len;
323 * Find out what kind of machine we're on and save any data we need
324 * from the early boot process (devtree is copied on pmac by prom_init() )
326 unsigned long __init
327 identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
328 unsigned long r6, unsigned long r7)
331 #ifdef __SMP__
332 if ( first_cpu_booted ) return 0;
333 #endif /* __SMP__ */
334 if ( ppc_md.progress ) ppc_md.progress("id mach(): start", 0x100);
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");
481 /* Check for nobats option (used in mapin_ram). */
482 if (strstr(cmd_line, "nobats")) {
483 extern int __map_without_bats;
484 __map_without_bats = 1;
487 if ( ppc_md.progress ) ppc_md.progress("id mach(): done", 0x200);
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_mm.start_code = PAGE_OFFSET;
531 init_mm.end_code = (unsigned long) _etext;
532 init_mm.end_data = (unsigned long) _edata;
533 init_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);
543 /* clear the progress line */
544 if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff);
547 void ppc_generic_ide_fix_driveid(struct hd_driveid *id)
549 int i;
550 unsigned short *stringcast;
553 id->config = __le16_to_cpu(id->config);
554 id->cyls = __le16_to_cpu(id->cyls);
555 id->reserved2 = __le16_to_cpu(id->reserved2);
556 id->heads = __le16_to_cpu(id->heads);
557 id->track_bytes = __le16_to_cpu(id->track_bytes);
558 id->sector_bytes = __le16_to_cpu(id->sector_bytes);
559 id->sectors = __le16_to_cpu(id->sectors);
560 id->vendor0 = __le16_to_cpu(id->vendor0);
561 id->vendor1 = __le16_to_cpu(id->vendor1);
562 id->vendor2 = __le16_to_cpu(id->vendor2);
563 stringcast = (unsigned short *)&id->serial_no[0];
564 for (i=0; i<(20/2); i++)
565 stringcast[i] = __le16_to_cpu(stringcast[i]);
566 id->buf_type = __le16_to_cpu(id->buf_type);
567 id->buf_size = __le16_to_cpu(id->buf_size);
568 id->ecc_bytes = __le16_to_cpu(id->ecc_bytes);
569 stringcast = (unsigned short *)&id->fw_rev[0];
570 for (i=0; i<(8/2); i++)
571 stringcast[i] = __le16_to_cpu(stringcast[i]);
572 stringcast = (unsigned short *)&id->model[0];
573 for (i=0; i<(40/2); i++)
574 stringcast[i] = __le16_to_cpu(stringcast[i]);
575 id->dword_io = __le16_to_cpu(id->dword_io);
576 id->reserved50 = __le16_to_cpu(id->reserved50);
577 id->field_valid = __le16_to_cpu(id->field_valid);
578 id->cur_cyls = __le16_to_cpu(id->cur_cyls);
579 id->cur_heads = __le16_to_cpu(id->cur_heads);
580 id->cur_sectors = __le16_to_cpu(id->cur_sectors);
581 id->cur_capacity0 = __le16_to_cpu(id->cur_capacity0);
582 id->cur_capacity1 = __le16_to_cpu(id->cur_capacity1);
583 id->lba_capacity = __le32_to_cpu(id->lba_capacity);
584 id->dma_1word = __le16_to_cpu(id->dma_1word);
585 id->dma_mword = __le16_to_cpu(id->dma_mword);
586 id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);
587 id->eide_dma_min = __le16_to_cpu(id->eide_dma_min);
588 id->eide_dma_time = __le16_to_cpu(id->eide_dma_time);
589 id->eide_pio = __le16_to_cpu(id->eide_pio);
590 id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
591 id->word69 = __le16_to_cpu(id->word69);
592 id->word70 = __le16_to_cpu(id->word70);
593 id->word71 = __le16_to_cpu(id->word71);
594 id->word72 = __le16_to_cpu(id->word72);
595 id->word73 = __le16_to_cpu(id->word73);
596 id->word74 = __le16_to_cpu(id->word74);
597 id->word75 = __le16_to_cpu(id->word75);
598 id->word76 = __le16_to_cpu(id->word76);
599 id->word77 = __le16_to_cpu(id->word77);
600 id->word78 = __le16_to_cpu(id->word78);
601 id->word79 = __le16_to_cpu(id->word79);
602 id->word80 = __le16_to_cpu(id->word80);
603 id->word81 = __le16_to_cpu(id->word81);
604 id->command_sets = __le16_to_cpu(id->command_sets);
605 id->word83 = __le16_to_cpu(id->word83);
606 id->word84 = __le16_to_cpu(id->word84);
607 id->word85 = __le16_to_cpu(id->word85);
608 id->word86 = __le16_to_cpu(id->word86);
609 id->word87 = __le16_to_cpu(id->word87);
610 id->dma_ultra = __le16_to_cpu(id->dma_ultra);
611 id->word89 = __le16_to_cpu(id->word89);
612 id->word90 = __le16_to_cpu(id->word90);
613 id->word91 = __le16_to_cpu(id->word91);
614 id->word92 = __le16_to_cpu(id->word92);
615 id->word93 = __le16_to_cpu(id->word93);
616 id->word94 = __le16_to_cpu(id->word94);
617 id->word95 = __le16_to_cpu(id->word95);
618 id->word96 = __le16_to_cpu(id->word96);
619 id->word97 = __le16_to_cpu(id->word97);
620 id->word98 = __le16_to_cpu(id->word98);
621 id->word99 = __le16_to_cpu(id->word99);
622 id->word100 = __le16_to_cpu(id->word100);
623 id->word101 = __le16_to_cpu(id->word101);
624 id->word102 = __le16_to_cpu(id->word102);
625 id->word103 = __le16_to_cpu(id->word103);
626 id->word104 = __le16_to_cpu(id->word104);
627 id->word105 = __le16_to_cpu(id->word105);
628 id->word106 = __le16_to_cpu(id->word106);
629 id->word107 = __le16_to_cpu(id->word107);
630 id->word108 = __le16_to_cpu(id->word108);
631 id->word109 = __le16_to_cpu(id->word109);
632 id->word110 = __le16_to_cpu(id->word110);
633 id->word111 = __le16_to_cpu(id->word111);
634 id->word112 = __le16_to_cpu(id->word112);
635 id->word113 = __le16_to_cpu(id->word113);
636 id->word114 = __le16_to_cpu(id->word114);
637 id->word115 = __le16_to_cpu(id->word115);
638 id->word116 = __le16_to_cpu(id->word116);
639 id->word117 = __le16_to_cpu(id->word117);
640 id->word118 = __le16_to_cpu(id->word118);
641 id->word119 = __le16_to_cpu(id->word119);
642 id->word120 = __le16_to_cpu(id->word120);
643 id->word121 = __le16_to_cpu(id->word121);
644 id->word122 = __le16_to_cpu(id->word122);
645 id->word123 = __le16_to_cpu(id->word123);
646 id->word124 = __le16_to_cpu(id->word124);
647 id->word125 = __le16_to_cpu(id->word125);
648 id->word126 = __le16_to_cpu(id->word126);
649 id->word127 = __le16_to_cpu(id->word127);
650 id->security = __le16_to_cpu(id->security);
651 for (i=0; i<127; i++)
652 id->reserved[i] = __le16_to_cpu(id->reserved[i]);