2 * $Id: setup.c,v 1.138 1999/07/11 16:32:21 cort Exp $
3 * Common prep/pmac/chrp boot and setup code.
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>
18 #include <asm/residual.h>
20 #include <linux/ide.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>
31 #include <asm/8xx_immap.h>
33 #include <asm/bootx.h>
34 #include <asm/machdep.h>
36 extern void pmac_init(unsigned long r3
,
42 extern void chrp_init(unsigned long r3
,
48 extern void prep_init(unsigned long r3
,
54 extern void mbx_init(unsigned long r3
,
60 extern void apus_init(unsigned long r3
,
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. */
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 */
90 struct machdep_calls ppc_md
;
93 /* copy of the residual data */
95 unsigned char __res
[sizeof(RESIDUAL
)] __prepdata
= {0,};
97 unsigned char __res
[sizeof(bd_t
)] = {0,};
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
109 struct screen_info screen_info
= {
110 0, 25, /* orig-x, orig-y */
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
))
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 */
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
)
155 void machine_power_off(void)
160 void machine_halt(void)
165 unsigned long cpu_temp(void)
167 unsigned char thres
= 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 */
177 _set_THRM3(THRM3_E
| (300*30)<<18 );
180 /* wait for the compare to complete */
181 /*while ( !(_get_THRM1() & THRM1_TIV) ) ;*/
182 if ( !(_get_THRM1() & THRM1_TIV
) )
184 if ( _get_THRM1() & THRM1_TIN
)
186 /* turn everything off */
194 int get_cpuinfo(char *buffer
)
196 unsigned long len
= 0;
197 unsigned long bogosum
= 0;
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)
205 #define CPU_PRESENT(x) ((x)==0)
206 #define smp_num_cpus 1
207 #define GET_PVR ((long int)_get_PVR())
211 for ( i
= 0; i
< smp_num_cpus
; i
++ )
213 if ( !CPU_PRESENT(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)
223 len
+= sprintf(len
+buffer
, "601\n");
226 len
+= sprintf(len
+buffer
, "603\n");
229 len
+= sprintf(len
+buffer
, "604\n");
232 len
+= sprintf(len
+buffer
, "603e\n");
235 len
+= sprintf(len
+buffer
, "603ev\n");
238 len
+= sprintf(len
+buffer
, "750\n");
239 len
+= sprintf(len
+buffer
, "temperature \t: %lu C\n",
243 len
+= sprintf(len
+buffer
, "604e\n");
246 len
+= sprintf(len
+buffer
, "604ev5 (MachV)\n");
249 len
+= sprintf(len
+buffer
, "821\n");
251 len
+= sprintf(len
+buffer
, "860\n");
254 len
+= sprintf(len
+buffer
, "unknown (%lu)\n",
260 * Assume here that all clock rates are the same in a
261 * smp system. -- Cort
265 struct device_node
*cpu_node
;
268 cpu_node
= find_type_devices("cpu");
269 if ( !cpu_node
) break;
270 fp
= (int *) get_property(cpu_node
, "clock-frequency", NULL
);
272 len
+= sprintf(len
+buffer
, "clock\t\t: %dMHz\n",
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
);
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);
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",
305 (zero_cache_total
*PAGE_SIZE
)>>10,
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
);
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() )
327 identify_machine(unsigned long r3
, unsigned long r4
, unsigned long r5
,
328 unsigned long r6
, unsigned long r7
)
332 if ( first_cpu_booted
) return 0;
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
;
343 /* prep boot loader tells us if we're prep or not */
344 else if ( *(unsigned long *)(KERNELBASE
) == (0xdeadc0de) ) {
345 _machine
= _MACH_prep
;
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
;
363 model
= get_property(find_path_device("/"),
365 if ( model
&& !strncmp(model
, "IBM", 3))
367 _machine
= _MACH_chrp
;
372 _machine
= _MACH_Pmac
;
377 #else /* CONFIG_MACH_SPECIFIC */
380 _machine
= _MACH_prep
;
382 #elif defined(CONFIG_CHRP)
383 _machine
= _MACH_chrp
;
386 #elif defined(CONFIG_PMAC)
387 _machine
= _MACH_Pmac
;
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
;
396 #error "Machine not defined correctly"
397 #endif /* CONFIG_APUS */
398 #endif /* CONFIG_MACH_SPECIFIC */
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.
417 if (r3
>= 0x4000 && r3
< 0x800000 && r4
== 0) {
418 strncpy(cmd_line
, (char *)r3
+ KERNELBASE
,
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
,
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;
435 struct device_node
*chosen
;
438 #ifdef CONFIG_BLK_DEV_INITRD
439 if (r3
- KERNELBASE
< 0x800000
440 && r4
!= 0 && r4
!= 0xdeadbeef) {
442 initrd_end
= r3
+ r4
;
443 ROOT_DEV
= MKDEV(RAMDISK_MAJOR
, 0);
447 chosen
= find_devices("chosen");
448 if (chosen
!= NULL
) {
449 p
= get_property(chosen
, "bootargs", NULL
);
451 strncpy(cmd_line
, p
, sizeof(cmd_line
));
454 cmd_line
[sizeof(cmd_line
) - 1] = 0;
460 pmac_init(r3
, r4
, r5
, r6
, r7
);
463 prep_init(r3
, r4
, r5
, r6
, r7
);
466 chrp_init(r3
, r4
, r5
, r6
, r7
);
470 apus_init(r3
, r4
, r5
, r6
, r7
);
475 mbx_init(r3
, r4
, r5
, r6
, r7
);
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);
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
);
506 if (ppc_md
.init
!= NULL
) {
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
[];
517 extern unsigned long find_available_memory(void);
518 extern unsigned long *end_of_DRAM
;
521 extern void xmon_map_scc(void);
523 if (strstr(cmd_line
, "xmon"))
525 #endif /* CONFIG_XMON */
527 /* reboot on panic */
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
)
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
]);