2 * $Id: setup.c,v 1.148 1999/09/05 11:56:34 paulus 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>
19 #include <asm/residual.h>
21 #include <linux/ide.h>
24 #include <asm/processor.h>
25 #include <asm/pgtable.h>
26 #include <asm/bootinfo.h>
27 #include <asm/setup.h>
28 #include <asm/amigappc.h>
32 #include <asm/8xx_immap.h>
34 #include <asm/bootx.h>
35 #include <asm/machdep.h>
37 extern void pmac_init(unsigned long r3
,
43 extern void chrp_init(unsigned long r3
,
49 extern void prep_init(unsigned long r3
,
55 extern void mbx_init(unsigned long r3
,
61 extern void apus_init(unsigned long r3
,
67 extern void gemini_init(unsigned long r3
,
73 extern boot_infos_t
*boot_infos
;
74 extern char cmd_line
[512];
75 char saved_command_line
[256];
76 unsigned char aux_device_present
;
78 struct ide_machdep_calls ppc_ide_md
;
80 unsigned long ISA_DMA_THRESHOLD
;
81 unsigned long DMA_MODE_READ
, DMA_MODE_WRITE
;
83 /* Temporary hacks until machdep.h is fully done. */
89 #ifdef CONFIG_MAGIC_SYSRQ
90 unsigned long SYSRQ_KEY
;
91 #endif /* CONFIG_MAGIC_SYSRQ */
92 /* For MTX/MVME boards.. with Raven/Falcon Chipset
93 Real close to CHRP, but boot like PReP (via PPCbug)
94 There's probably a nicer way to do this.. --Troy */
97 struct machdep_calls ppc_md
;
100 /* copy of the residual data */
102 unsigned char __res
[sizeof(RESIDUAL
)] __prepdata
= {0,};
104 unsigned char __res
[sizeof(bd_t
)] = {0,};
107 RESIDUAL
*res
= (RESIDUAL
*)&__res
;
110 * Perhaps we can put the pmac screen_info[] here
111 * on pmac as well so we don't need the ifdef's.
112 * Until we get multiple-console support in here
116 struct screen_info screen_info
= {
117 0, 25, /* orig-x, orig-y */
119 0, /* orig-video-page */
120 0, /* orig-video-mode */
121 80, /* orig-video-cols */
122 0,0,0, /* ega_ax, ega_bx, ega_cx */
123 25, /* orig-video-lines */
124 1, /* orig-video-isVGA */
125 16 /* orig-video-points */
129 * I really need to add multiple-console support... -- Cort
131 int __init
pmac_display_supported(char *name
)
135 void __init
pmac_find_display(void)
139 #else /* CONFIG_MBX */
141 /* We need this to satisfy some external references until we can
142 * strip the kernel down.
144 struct screen_info screen_info
= {
145 0, 25, /* orig-x, orig-y */
147 0, /* orig-video-page */
148 0, /* orig-video-mode */
149 80, /* orig-video-cols */
150 0,0,0, /* ega_ax, ega_bx, ega_cx */
151 25, /* orig-video-lines */
152 0, /* orig-video-isVGA */
153 16 /* orig-video-points */
155 #endif /* CONFIG_MBX */
157 void machine_restart(char *cmd
)
162 void machine_power_off(void)
167 void machine_halt(void)
172 unsigned long cpu_temp(void)
174 unsigned char thres
= 0;
179 /* threshold 0 C, tid: exceeding threshold, tie: don't generate interrupt */
180 _set_THRM1( THRM1_V
);
182 /* we need 20us to do the compare - assume 300MHz processor clock */
184 _set_THRM3(THRM3_E
| (300*30)<<18 );
187 /* wait for the compare to complete */
188 /*while ( !(_get_THRM1() & THRM1_TIV) ) ;*/
189 if ( !(_get_THRM1() & THRM1_TIV
) )
191 if ( _get_THRM1() & THRM1_TIN
)
193 /* turn everything off */
201 int get_cpuinfo(char *buffer
)
203 unsigned long len
= 0;
204 unsigned long bogosum
= 0;
208 #define CPU_PRESENT(x) (cpu_callin_map[(x)])
209 #define GET_PVR ((long int)(cpu_data[i].pvr))
210 #define CD(x) (cpu_data[i].x)
212 #define CPU_PRESENT(x) ((x)==0)
213 #define smp_num_cpus 1
214 #define GET_PVR ((long int)_get_PVR())
218 for ( i
= 0; i
< smp_num_cpus
; i
++ )
220 if ( !CPU_PRESENT(i
) )
223 len
+= sprintf(len
+buffer
,"\n");
224 len
+= sprintf(len
+buffer
,"processor\t: %lu\n",i
);
225 len
+= sprintf(len
+buffer
,"cpu\t\t: ");
227 switch (GET_PVR
>> 16)
230 len
+= sprintf(len
+buffer
, "601\n");
233 len
+= sprintf(len
+buffer
, "603\n");
236 len
+= sprintf(len
+buffer
, "604\n");
239 len
+= sprintf(len
+buffer
, "603e\n");
242 len
+= sprintf(len
+buffer
, "603ev\n");
245 len
+= sprintf(len
+buffer
, "750\n");
246 len
+= sprintf(len
+buffer
, "temperature \t: %lu C\n",
250 len
+= sprintf(len
+buffer
, "604e\n");
253 len
+= sprintf(len
+buffer
, "604ev5 (MachV)\n");
256 len
+= sprintf(len
+buffer
, "821\n");
258 len
+= sprintf(len
+buffer
, "860\n");
261 len
+= sprintf(len
+buffer
, "unknown (%lu)\n",
267 * Assume here that all clock rates are the same in a
268 * smp system. -- Cort
272 struct device_node
*cpu_node
;
275 cpu_node
= find_type_devices("cpu");
276 if ( !cpu_node
) break;
279 for ( s
= 0; (s
< i
) && cpu_node
->next
;
280 s
++, cpu_node
= cpu_node
->next
)
282 #if 0 /* SMP Pmacs don't have all cpu nodes -- Cort */
284 printk("get_cpuinfo(): ran out of "
288 fp
= (int *) get_property(cpu_node
, "clock-frequency", NULL
);
290 len
+= sprintf(len
+buffer
, "clock\t\t: %dMHz\n",
294 if (ppc_md
.setup_residual
!= NULL
)
296 len
+= ppc_md
.setup_residual(buffer
+ len
);
299 len
+= sprintf(len
+buffer
, "revision\t: %ld.%ld\n",
300 (GET_PVR
& 0xff00) >> 8, GET_PVR
& 0xff);
302 len
+= sprintf(buffer
+len
, "bogomips\t: %lu.%02lu\n",
303 (CD(loops_per_sec
)+2500)/500000,
304 (CD(loops_per_sec
)+2500)/5000 % 100);
305 bogosum
+= CD(loops_per_sec
);
310 len
+= sprintf(buffer
+len
, "\n");
311 len
+= sprintf(buffer
+len
,"total bogomips\t: %lu.%02lu\n",
312 (bogosum
+2500)/500000,
313 (bogosum
+2500)/5000 % 100);
317 * Ooh's and aah's info about zero'd pages in idle task
320 len
+= sprintf(buffer
+len
,"zero pages\t: total %lu (%luKb) "
321 "current: %lu (%luKb) hits: %lu/%lu (%lu%%)\n",
323 (zero_cache_total
*PAGE_SIZE
)>>10,
325 (zero_cache_sz
*PAGE_SIZE
)>>10,
326 zero_cache_hits
,zero_cache_calls
,
327 /* : 1 below is so we don't div by zero */
328 (zero_cache_hits
*100) /
329 ((zero_cache_calls
)?zero_cache_calls
:1));
332 if (ppc_md
.get_cpuinfo
!= NULL
)
334 len
+= ppc_md
.get_cpuinfo(buffer
+len
);
341 * Find out what kind of machine we're on and save any data we need
342 * from the early boot process (devtree is copied on pmac by prom_init() )
345 identify_machine(unsigned long r3
, unsigned long r4
, unsigned long r5
,
346 unsigned long r6
, unsigned long r7
)
349 if ( first_cpu_booted
) return 0;
351 if ( ppc_md
.progress
) ppc_md
.progress("id mach(): start", 0x100);
353 #ifndef CONFIG_MACH_SPECIFIC
354 /* boot loader will tell us if we're APUS */
355 if ( r3
== 0x61707573 )
357 _machine
= _MACH_apus
;
360 /* prep boot loader tells us if we're prep or not */
361 else if ( *(unsigned long *)(KERNELBASE
) == (0xdeadc0de) ) {
362 _machine
= _MACH_prep
;
369 /* prom_init has already been called from __start */
370 finish_device_tree();
371 /* ask the OF info if we're a chrp or pmac */
372 model
= get_property(find_path_device("/"), "device_type", NULL
);
373 if ( model
&& !strncmp("chrp",model
,4) )
375 _machine
= _MACH_chrp
;
380 model
= get_property(find_path_device("/"),
382 if ( model
&& !strncmp(model
, "IBM", 3))
384 _machine
= _MACH_chrp
;
389 _machine
= _MACH_Pmac
;
394 #else /* CONFIG_MACH_SPECIFIC */
397 _machine
= _MACH_prep
;
399 #elif defined(CONFIG_CHRP)
400 _machine
= _MACH_chrp
;
403 #elif defined(CONFIG_PMAC)
404 _machine
= _MACH_Pmac
;
406 #elif defined(CONFIG_MBX)
407 _machine
= _MACH_mbx
;
408 #elif defined(CONFIG_FADS)
409 _machine
= _MACH_fads
;
410 #elif defined(CONFIG_APUS)
411 _machine
= _MACH_apus
;
412 #elif defined(CONFIG_GEMINI)
413 _machine
= _MACH_gemini
;
415 #error "Machine not defined correctly"
416 #endif /* CONFIG_APUS */
417 #endif /* CONFIG_MACH_SPECIFIC */
421 #ifdef CONFIG_MACH_SPECIFIC
422 /* prom_init has already been called from __start */
423 finish_device_tree();
424 #endif /* CONFIG_MACH_SPECIFIC */
426 * If we were booted via quik, r3 points to the physical
427 * address of the command-line parameters.
428 * If we were booted from an xcoff image (i.e. netbooted or
429 * booted from floppy), we get the command line from the
430 * bootargs property of the /chosen node.
431 * If an initial ramdisk is present, r3 and r4
432 * are used for initrd_start and initrd_size,
433 * otherwise they contain 0xdeadbeef.
436 if (r3
>= 0x4000 && r3
< 0x800000 && r4
== 0) {
437 strncpy(cmd_line
, (char *)r3
+ KERNELBASE
,
439 } else if (boot_infos
!= 0) {
440 /* booted by BootX - check for ramdisk */
441 if (boot_infos
->kernelParamsOffset
!= 0)
442 strncpy(cmd_line
, (char *) boot_infos
443 + boot_infos
->kernelParamsOffset
,
445 #ifdef CONFIG_BLK_DEV_INITRD
446 if (boot_infos
->ramDisk
) {
447 initrd_start
= (unsigned long) boot_infos
448 + boot_infos
->ramDisk
;
449 initrd_end
= initrd_start
+ boot_infos
->ramDiskSize
;
450 initrd_below_start_ok
= 1;
454 struct device_node
*chosen
;
457 #ifdef CONFIG_BLK_DEV_INITRD
458 if (r3
- KERNELBASE
< 0x800000
459 && r4
!= 0 && r4
!= 0xdeadbeef) {
461 initrd_end
= r3
+ r4
;
462 ROOT_DEV
= MKDEV(RAMDISK_MAJOR
, 0);
466 chosen
= find_devices("chosen");
467 if (chosen
!= NULL
) {
468 p
= get_property(chosen
, "bootargs", NULL
);
470 strncpy(cmd_line
, p
, sizeof(cmd_line
));
473 cmd_line
[sizeof(cmd_line
) - 1] = 0;
479 pmac_init(r3
, r4
, r5
, r6
, r7
);
482 prep_init(r3
, r4
, r5
, r6
, r7
);
485 chrp_init(r3
, r4
, r5
, r6
, r7
);
489 apus_init(r3
, r4
, r5
, r6
, r7
);
494 mbx_init(r3
, r4
, r5
, r6
, r7
);
498 gemini_init(r3
, r4
, r5
, r6
, r7
);
501 printk("Unknown machine type in identify_machine!\n");
503 /* Check for nobats option (used in mapin_ram). */
504 if (strstr(cmd_line
, "nobats")) {
505 extern int __map_without_bats
;
506 __map_without_bats
= 1;
509 if ( ppc_md
.progress
) ppc_md
.progress("id mach(): done", 0x200);
513 /* Checks "l2cr=xxxx" command-line option */
514 void ppc_setup_l2cr(char *str
, int *ints
)
516 if ( (_get_PVR() >> 16) == 8)
518 unsigned long val
= simple_strtoul(str
, NULL
, 0);
519 printk(KERN_INFO
"l2cr set to %lx\n", val
);
525 void __init
ppc_init(void)
527 /* clear the progress line */
528 if ( ppc_md
.progress
) ppc_md
.progress(" ", 0xffff);
530 if (ppc_md
.init
!= NULL
) {
535 void __init
setup_arch(char **cmdline_p
,
536 unsigned long * memory_start_p
, unsigned long * memory_end_p
)
538 extern int panic_timeout
;
539 extern char _etext
[], _edata
[];
541 extern unsigned long find_available_memory(void);
542 extern unsigned long *end_of_DRAM
;
545 extern void xmon_map_scc(void);
547 if (strstr(cmd_line
, "xmon"))
549 #endif /* CONFIG_XMON */
551 /* reboot on panic */
554 init_mm
.start_code
= PAGE_OFFSET
;
555 init_mm
.end_code
= (unsigned long) _etext
;
556 init_mm
.end_data
= (unsigned long) _edata
;
557 init_mm
.brk
= (unsigned long) klimit
;
559 /* Save unparsed command line copy for /proc/cmdline */
560 strcpy(saved_command_line
, cmd_line
);
561 *cmdline_p
= cmd_line
;
563 *memory_start_p
= find_available_memory();
564 *memory_end_p
= (unsigned long) end_of_DRAM
;
566 ppc_md
.setup_arch(memory_start_p
, memory_end_p
);
567 /* clear the progress line */
568 if ( ppc_md
.progress
) ppc_md
.progress("arch: exit", 0x3eab);
571 void ppc_generic_ide_fix_driveid(struct hd_driveid
*id
)
574 unsigned short *stringcast
;
577 id
->config
= __le16_to_cpu(id
->config
);
578 id
->cyls
= __le16_to_cpu(id
->cyls
);
579 id
->reserved2
= __le16_to_cpu(id
->reserved2
);
580 id
->heads
= __le16_to_cpu(id
->heads
);
581 id
->track_bytes
= __le16_to_cpu(id
->track_bytes
);
582 id
->sector_bytes
= __le16_to_cpu(id
->sector_bytes
);
583 id
->sectors
= __le16_to_cpu(id
->sectors
);
584 id
->vendor0
= __le16_to_cpu(id
->vendor0
);
585 id
->vendor1
= __le16_to_cpu(id
->vendor1
);
586 id
->vendor2
= __le16_to_cpu(id
->vendor2
);
587 stringcast
= (unsigned short *)&id
->serial_no
[0];
588 for (i
=0; i
<(20/2); i
++)
589 stringcast
[i
] = __le16_to_cpu(stringcast
[i
]);
590 id
->buf_type
= __le16_to_cpu(id
->buf_type
);
591 id
->buf_size
= __le16_to_cpu(id
->buf_size
);
592 id
->ecc_bytes
= __le16_to_cpu(id
->ecc_bytes
);
593 stringcast
= (unsigned short *)&id
->fw_rev
[0];
594 for (i
=0; i
<(8/2); i
++)
595 stringcast
[i
] = __le16_to_cpu(stringcast
[i
]);
596 stringcast
= (unsigned short *)&id
->model
[0];
597 for (i
=0; i
<(40/2); i
++)
598 stringcast
[i
] = __le16_to_cpu(stringcast
[i
]);
599 id
->dword_io
= __le16_to_cpu(id
->dword_io
);
600 id
->reserved50
= __le16_to_cpu(id
->reserved50
);
601 id
->field_valid
= __le16_to_cpu(id
->field_valid
);
602 id
->cur_cyls
= __le16_to_cpu(id
->cur_cyls
);
603 id
->cur_heads
= __le16_to_cpu(id
->cur_heads
);
604 id
->cur_sectors
= __le16_to_cpu(id
->cur_sectors
);
605 id
->cur_capacity0
= __le16_to_cpu(id
->cur_capacity0
);
606 id
->cur_capacity1
= __le16_to_cpu(id
->cur_capacity1
);
607 id
->lba_capacity
= __le32_to_cpu(id
->lba_capacity
);
608 id
->dma_1word
= __le16_to_cpu(id
->dma_1word
);
609 id
->dma_mword
= __le16_to_cpu(id
->dma_mword
);
610 id
->eide_pio_modes
= __le16_to_cpu(id
->eide_pio_modes
);
611 id
->eide_dma_min
= __le16_to_cpu(id
->eide_dma_min
);
612 id
->eide_dma_time
= __le16_to_cpu(id
->eide_dma_time
);
613 id
->eide_pio
= __le16_to_cpu(id
->eide_pio
);
614 id
->eide_pio_iordy
= __le16_to_cpu(id
->eide_pio_iordy
);
615 id
->word69
= __le16_to_cpu(id
->word69
);
616 id
->word70
= __le16_to_cpu(id
->word70
);
617 id
->word71
= __le16_to_cpu(id
->word71
);
618 id
->word72
= __le16_to_cpu(id
->word72
);
619 id
->word73
= __le16_to_cpu(id
->word73
);
620 id
->word74
= __le16_to_cpu(id
->word74
);
621 id
->word75
= __le16_to_cpu(id
->word75
);
622 id
->word76
= __le16_to_cpu(id
->word76
);
623 id
->word77
= __le16_to_cpu(id
->word77
);
624 id
->word78
= __le16_to_cpu(id
->word78
);
625 id
->word79
= __le16_to_cpu(id
->word79
);
626 id
->word80
= __le16_to_cpu(id
->word80
);
627 id
->word81
= __le16_to_cpu(id
->word81
);
628 id
->command_sets
= __le16_to_cpu(id
->command_sets
);
629 id
->word83
= __le16_to_cpu(id
->word83
);
630 id
->word84
= __le16_to_cpu(id
->word84
);
631 id
->word85
= __le16_to_cpu(id
->word85
);
632 id
->word86
= __le16_to_cpu(id
->word86
);
633 id
->word87
= __le16_to_cpu(id
->word87
);
634 id
->dma_ultra
= __le16_to_cpu(id
->dma_ultra
);
635 id
->word89
= __le16_to_cpu(id
->word89
);
636 id
->word90
= __le16_to_cpu(id
->word90
);
637 id
->word91
= __le16_to_cpu(id
->word91
);
638 id
->word92
= __le16_to_cpu(id
->word92
);
639 id
->word93
= __le16_to_cpu(id
->word93
);
640 id
->word94
= __le16_to_cpu(id
->word94
);
641 id
->word95
= __le16_to_cpu(id
->word95
);
642 id
->word96
= __le16_to_cpu(id
->word96
);
643 id
->word97
= __le16_to_cpu(id
->word97
);
644 id
->word98
= __le16_to_cpu(id
->word98
);
645 id
->word99
= __le16_to_cpu(id
->word99
);
646 id
->word100
= __le16_to_cpu(id
->word100
);
647 id
->word101
= __le16_to_cpu(id
->word101
);
648 id
->word102
= __le16_to_cpu(id
->word102
);
649 id
->word103
= __le16_to_cpu(id
->word103
);
650 id
->word104
= __le16_to_cpu(id
->word104
);
651 id
->word105
= __le16_to_cpu(id
->word105
);
652 id
->word106
= __le16_to_cpu(id
->word106
);
653 id
->word107
= __le16_to_cpu(id
->word107
);
654 id
->word108
= __le16_to_cpu(id
->word108
);
655 id
->word109
= __le16_to_cpu(id
->word109
);
656 id
->word110
= __le16_to_cpu(id
->word110
);
657 id
->word111
= __le16_to_cpu(id
->word111
);
658 id
->word112
= __le16_to_cpu(id
->word112
);
659 id
->word113
= __le16_to_cpu(id
->word113
);
660 id
->word114
= __le16_to_cpu(id
->word114
);
661 id
->word115
= __le16_to_cpu(id
->word115
);
662 id
->word116
= __le16_to_cpu(id
->word116
);
663 id
->word117
= __le16_to_cpu(id
->word117
);
664 id
->word118
= __le16_to_cpu(id
->word118
);
665 id
->word119
= __le16_to_cpu(id
->word119
);
666 id
->word120
= __le16_to_cpu(id
->word120
);
667 id
->word121
= __le16_to_cpu(id
->word121
);
668 id
->word122
= __le16_to_cpu(id
->word122
);
669 id
->word123
= __le16_to_cpu(id
->word123
);
670 id
->word124
= __le16_to_cpu(id
->word124
);
671 id
->word125
= __le16_to_cpu(id
->word125
);
672 id
->word126
= __le16_to_cpu(id
->word126
);
673 id
->word127
= __le16_to_cpu(id
->word127
);
674 id
->security
= __le16_to_cpu(id
->security
);
675 for (i
=0; i
<127; i
++)
676 id
->reserved
[i
] = __le16_to_cpu(id
->reserved
[i
]);