3 * Common boot and setup code.
5 * Copyright (C) 2001 PPC64 Team, IBM Corp
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
13 #include <linux/config.h>
14 #include <linux/module.h>
15 #include <linux/string.h>
16 #include <linux/sched.h>
17 #include <linux/init.h>
18 #include <linux/reboot.h>
19 #include <linux/delay.h>
20 #include <linux/blk.h>
21 #include <linux/ide.h>
22 #include <linux/seq_file.h>
23 #include <linux/ioport.h>
24 #include <linux/console.h>
25 #include <linux/version.h>
26 #include <linux/tty.h>
27 #include <linux/root_dev.h>
30 #include <asm/processor.h>
31 #include <asm/pgtable.h>
32 #include <asm/bootinfo.h>
35 #include <asm/machdep.h>
36 #include <asm/iSeries/LparData.h>
39 #include <asm/ppcdebug.h>
42 extern unsigned long klimit
;
43 /* extern void *stab; */
44 extern HTAB htab_data
;
45 extern unsigned long loops_per_jiffy
;
49 extern void chrp_init(unsigned long r3
,
55 extern void iSeries_init( void );
56 extern void iSeries_init_early( void );
57 extern void pSeries_init_early( void );
58 extern void pSeriesLP_init_early(void);
59 extern void mm_init_ppc64( void );
61 unsigned long decr_overclock
= 1;
62 unsigned long decr_overclock_proc0
= 1;
63 unsigned long decr_overclock_set
= 0;
64 unsigned long decr_overclock_proc0_set
= 0;
67 extern void xmon_map_scc(void);
70 char saved_command_line
[256];
71 unsigned char aux_device_present
;
73 void parse_cmd_line(unsigned long r3
, unsigned long r4
, unsigned long r5
,
74 unsigned long r6
, unsigned long r7
);
75 int parse_bootinfo(void);
77 #ifdef CONFIG_MAGIC_SYSRQ
78 unsigned long SYSRQ_KEY
;
79 #endif /* CONFIG_MAGIC_SYSRQ */
81 struct machdep_calls ppc_md
;
84 * Perhaps we can put the pmac screen_info[] here
85 * on pmac as well so we don't need the ifdef's.
86 * Until we get multiple-console support in here
88 * Maybe tie it to serial consoles, since this is really what
89 * these processors use on existing boards. -- Dan
91 struct screen_info screen_info
= {
92 0, 25, /* orig-x, orig-y */
94 0, /* orig-video-page */
95 0, /* orig-video-mode */
96 80, /* orig-video-cols */
97 0,0,0, /* ega_ax, ega_bx, ega_cx */
98 25, /* orig-video-lines */
99 1, /* orig-video-isVGA */
100 16 /* orig-video-points */
104 * These are used in binfmt_elf.c to put aux entries on the stack
105 * for each elf executable being started.
112 * Initialize the PPCDBG state. Called before relocation has been enabled.
114 void ppcdbg_initialize(void) {
115 unsigned long offset
= reloc_offset();
116 struct naca_struct
*_naca
= RELOC(naca
);
118 _naca
->debug_switch
= PPC_DEBUG_DEFAULT
; /* | PPCDBG_BUSWALK | PPCDBG_PHBINIT | PPCDBG_MM | PPCDBG_MMINIT | PPCDBG_TCEINIT | PPCDBG_TCE */;
121 static struct console udbg_console
= {
123 .write
= udbg_console_write
,
124 .flags
= CON_PRINTBUFFER
,
128 static int early_console_initialized
;
130 void __init
disable_early_printk(void)
132 if (!early_console_initialized
)
134 unregister_console(&udbg_console
);
135 early_console_initialized
= 0;
139 * Do some initial setup of the system. The paramters are those which
140 * were passed in from the bootloader.
142 void setup_system(unsigned long r3
, unsigned long r4
, unsigned long r5
,
143 unsigned long r6
, unsigned long r7
)
145 /* This should be fixed properly in kernel/resource.c */
146 iomem_resource
.end
= MEM_SPACE_LIMIT
;
148 #ifdef CONFIG_XMON_DEFAULT
150 debugger_bpt
= xmon_bpt
;
151 debugger_sstep
= xmon_sstep
;
152 debugger_iabr_match
= xmon_iabr_match
;
153 debugger_dabr_match
= xmon_dabr_match
;
156 /* pSeries systems are identified in prom.c via OF. */
157 if ( itLpNaca
.xLparInstalled
== 1 )
158 naca
->platform
= PLATFORM_ISERIES_LPAR
;
160 switch (naca
->platform
) {
161 case PLATFORM_ISERIES_LPAR
:
162 iSeries_init_early();
165 #ifdef CONFIG_PPC_PSERIES
166 case PLATFORM_PSERIES
:
167 pSeries_init_early();
168 #ifdef CONFIG_BLK_DEV_INITRD
169 initrd_start
= initrd_end
= 0;
174 case PLATFORM_PSERIES_LPAR
:
175 pSeriesLP_init_early();
176 #ifdef CONFIG_BLK_DEV_INITRD
177 initrd_start
= initrd_end
= 0;
184 if (naca
->platform
& PLATFORM_PSERIES
) {
185 early_console_initialized
= 1;
186 register_console(&udbg_console
);
189 printk("Starting Linux PPC64 %s\n", UTS_RELEASE
);
191 printk("-----------------------------------------------------\n");
192 printk("naca = 0x%p\n", naca
);
194 printk("naca->processorCount = 0x%x\n", naca
->processorCount
);
196 printk("naca->physicalMemorySize = 0x%lx\n", naca
->physicalMemorySize
);
197 printk("naca->dCacheL1LineSize = 0x%x\n", naca
->dCacheL1LineSize
);
198 printk("naca->dCacheL1LogLineSize = 0x%x\n", naca
->dCacheL1LogLineSize
);
199 printk("naca->dCacheL1LinesPerPage = 0x%x\n", naca
->dCacheL1LinesPerPage
);
200 printk("naca->iCacheL1LineSize = 0x%x\n", naca
->iCacheL1LineSize
);
201 printk("naca->iCacheL1LogLineSize = 0x%x\n", naca
->iCacheL1LogLineSize
);
202 printk("naca->iCacheL1LinesPerPage = 0x%x\n", naca
->iCacheL1LinesPerPage
);
203 printk("naca->pftSize = 0x%lx\n", naca
->pftSize
);
204 printk("naca->debug_switch = 0x%lx\n", naca
->debug_switch
);
205 printk("naca->interrupt_controller = 0x%d\n", naca
->interrupt_controller
);
206 printk("htab_data.htab = 0x%p\n", htab_data
.htab
);
207 printk("htab_data.num_ptegs = 0x%lx\n", htab_data
.htab_num_ptegs
);
208 printk("-----------------------------------------------------\n");
210 if (naca
->platform
& PLATFORM_PSERIES
) {
211 finish_device_tree();
212 chrp_init(r3
, r4
, r5
, r6
, r7
);
217 switch (naca
->platform
) {
218 case PLATFORM_ISERIES_LPAR
:
222 /* The following relies on the device tree being */
223 /* fully configured. */
224 parse_cmd_line(r3
, r4
, r5
, r6
, r7
);
228 void machine_restart(char *cmd
)
233 void machine_power_off(void)
238 void machine_halt(void)
243 unsigned long ppc_proc_freq
;
244 unsigned long ppc_tb_freq
;
246 static int show_cpuinfo(struct seq_file
*m
, void *v
)
248 unsigned long cpu_id
= (unsigned long)v
- 1;
253 if (cpu_id
== NR_CPUS
) {
255 if (ppc_md
.get_cpuinfo
!= NULL
)
256 ppc_md
.get_cpuinfo(m
);
261 if (!(cpu_online_map
& (1<<cpu_id
)))
265 pvr
= paca
[cpu_id
].pvr
;
269 maj
= (pvr
>> 8) & 0xFF;
272 seq_printf(m
, "processor\t: %lu\n", cpu_id
);
273 seq_printf(m
, "cpu\t\t: ");
275 switch (PVR_VER(pvr
)) {
277 seq_printf(m
, "RS64-II (northstar)\n");
280 seq_printf(m
, "RS64-III (pulsar)\n");
283 seq_printf(m
, "POWER4 (gp)\n");
286 seq_printf(m
, "RS64-III (icestar)\n");
289 seq_printf(m
, "RS64-IV (sstar)\n");
292 seq_printf(m
, "POWER4+ (gq)\n");
295 seq_printf(m
, "POWER3 (630)\n");
298 seq_printf(m
, "POWER3 (630+)\n");
301 seq_printf(m
, "Unknown (%08x)\n", pvr
);
306 * Assume here that all clock rates are the same in a
307 * smp system. -- Cort
309 if (naca
->platform
!= PLATFORM_ISERIES_LPAR
) {
310 struct device_node
*cpu_node
;
313 cpu_node
= find_type_devices("cpu");
315 fp
= (int *) get_property(cpu_node
, "clock-frequency",
318 seq_printf(m
, "clock\t\t: %dMHz\n",
323 if (ppc_md
.setup_residual
!= NULL
)
324 ppc_md
.setup_residual(m
, cpu_id
);
326 seq_printf(m
, "revision\t: %hd.%hd\n\n", maj
, min
);
331 static void *c_start(struct seq_file
*m
, loff_t
*pos
)
333 return *pos
<= NR_CPUS
? (void *)((*pos
)+1) : NULL
;
335 static void *c_next(struct seq_file
*m
, void *v
, loff_t
*pos
)
338 return c_start(m
, pos
);
340 static void c_stop(struct seq_file
*m
, void *v
)
343 struct seq_operations cpuinfo_op
= {
347 .show
= show_cpuinfo
,
351 * Fetch the cmd_line from open firmware. */
352 void parse_cmd_line(unsigned long r3
, unsigned long r4
, unsigned long r5
,
353 unsigned long r6
, unsigned long r7
)
355 struct device_node
*chosen
;
358 #ifdef CONFIG_BLK_DEV_INITRD
359 if ((initrd_start
== 0) && r3
&& r4
&& r4
!= 0xdeadbeef) {
360 initrd_start
= (r3
>= KERNELBASE
) ? r3
: (unsigned long)__va(r3
);
361 initrd_end
= initrd_start
+ r4
;
362 ROOT_DEV
= Root_RAM0
;
363 initrd_below_start_ok
= 1;
369 #ifdef CONFIG_CMDLINE
370 strcpy(cmd_line
, CONFIG_CMDLINE
);
371 #endif /* CONFIG_CMDLINE */
373 chosen
= find_devices("chosen");
374 if (chosen
!= NULL
) {
375 p
= get_property(chosen
, "bootargs", NULL
);
376 if (p
!= NULL
&& p
[0] != 0)
377 strncpy(cmd_line
, p
, sizeof(cmd_line
));
379 cmd_line
[sizeof(cmd_line
) - 1] = 0;
381 /* Look for mem= option on command line */
382 if (strstr(cmd_line
, "mem=")) {
384 unsigned long maxmem
= 0;
385 extern unsigned long __max_memory
;
387 for (q
= cmd_line
; (p
= strstr(q
, "mem=")) != 0; ) {
389 if (p
> cmd_line
&& p
[-1] != ' ')
391 maxmem
= simple_strtoul(q
, &q
, 0);
392 if (*q
== 'k' || *q
== 'K') {
395 } else if (*q
== 'm' || *q
== 'M') {
400 __max_memory
= maxmem
;
405 char *bi_tag2str(unsigned long tag
)
413 return "BI_CMD_LINE";
414 case BI_BOOTLOADER_ID
:
415 return "BI_BOOTLOADER_ID";
421 return "BI_MACHTYPE";
427 int parse_bootinfo(void)
429 struct bi_record
*rec
;
431 extern unsigned long sysmap_size
;
435 if ( rec
== NULL
|| rec
->tag
!= BI_FIRST
)
438 for ( ; rec
->tag
!= BI_LAST
; rec
= bi_rec_next(rec
) ) {
441 memcpy(cmd_line
, (void *)rec
->data
, rec
->size
);
444 sysmap
= (char *)((rec
->data
[0] >= (KERNELBASE
))
445 ? rec
->data
[0] : (unsigned long)__va(rec
->data
[0]));
446 sysmap_size
= rec
->data
[1];
448 #ifdef CONFIG_BLK_DEV_INITRD
450 initrd_start
= (unsigned long)__va(rec
->data
[0]);
451 initrd_end
= initrd_start
+ rec
->data
[1];
452 ROOT_DEV
= Root_RAM0
;
453 initrd_below_start_ok
= 1;
455 #endif /* CONFIG_BLK_DEV_INITRD */
462 int __init
ppc_init(void)
464 /* clear the progress line */
465 ppc_md
.progress(" ", 0xffff);
467 if (ppc_md
.init
!= NULL
) {
473 arch_initcall(ppc_init
);
475 void __init
ppc64_calibrate_delay(void)
477 loops_per_jiffy
= tb_ticks_per_jiffy
;
479 printk("Calibrating delay loop... %lu.%02lu BogoMips\n",
480 loops_per_jiffy
/(500000/HZ
),
481 loops_per_jiffy
/(5000/HZ
) % 100);
484 extern void (*calibrate_delay
)(void);
485 extern void sort_exception_table(void);
488 * Called into from start_kernel, after lock_kernel has been called.
489 * Initializes bootmem, which is unsed to manage page allocation until
490 * mem_init is called.
492 void __init
setup_arch(char **cmdline_p
)
494 extern int panic_timeout
;
495 extern char _etext
[], _edata
[];
496 extern void do_init_bootmem(void);
498 calibrate_delay
= ppc64_calibrate_delay
;
500 ppc64_boot_msg(0x12, "Setup Arch");
503 if (strstr(cmd_line
, "xmon"))
505 #endif /* CONFIG_XMON */
509 * Set cache line size based on type of cpu as a default.
510 * Systems with OF can look in the properties on the cpu node(s)
511 * for a possibly more accurate value.
513 dcache_bsize
= naca
->dCacheL1LineSize
;
514 icache_bsize
= naca
->iCacheL1LineSize
;
516 /* reboot on panic */
519 init_mm
.start_code
= PAGE_OFFSET
;
520 init_mm
.end_code
= (unsigned long) _etext
;
521 init_mm
.end_data
= (unsigned long) _edata
;
522 init_mm
.brk
= (unsigned long) klimit
;
524 /* Save unparsed command line copy for /proc/cmdline */
525 strcpy(saved_command_line
, cmd_line
);
526 *cmdline_p
= cmd_line
;
528 /* set up the bootmem stuff with available memory */
534 sort_exception_table();
535 ppc64_boot_msg(0x15, "Setup Done");
538 /* ToDo: do something useful if ppc_md is not yet setup. */
539 #define PPC64_LINUX_FUNCTION 0x0f000000
540 #define PPC64_IPL_MESSAGE 0xc0000000
541 #define PPC64_TERM_MESSAGE 0xb0000000
542 #define PPC64_ATTN_MESSAGE 0xa0000000
543 #define PPC64_DUMP_MESSAGE 0xd0000000
545 static void ppc64_do_msg(unsigned int src
, const char *msg
)
547 if (ppc_md
.progress
) {
550 sprintf(buf
, "%08x \n", src
);
551 ppc_md
.progress(buf
, 0);
552 sprintf(buf
, "%-16s", msg
);
553 ppc_md
.progress(buf
, 0);
557 /* Print a boot progress message. */
558 void ppc64_boot_msg(unsigned int src
, const char *msg
)
560 ppc64_do_msg(PPC64_LINUX_FUNCTION
|PPC64_IPL_MESSAGE
|src
, msg
);
561 printk("[boot]%04x %s\n", src
, msg
);
564 /* Print a termination message (print only -- does not stop the kernel) */
565 void ppc64_terminate_msg(unsigned int src
, const char *msg
)
567 ppc64_do_msg(PPC64_LINUX_FUNCTION
|PPC64_TERM_MESSAGE
|src
, msg
);
568 printk("[terminate]%04x %s\n", src
, msg
);
571 /* Print something that needs attention (device error, etc) */
572 void ppc64_attention_msg(unsigned int src
, const char *msg
)
574 ppc64_do_msg(PPC64_LINUX_FUNCTION
|PPC64_ATTN_MESSAGE
|src
, msg
);
575 printk("[attention]%04x %s\n", src
, msg
);
578 /* Print a dump progress message. */
579 void ppc64_dump_msg(unsigned int src
, const char *msg
)
581 ppc64_do_msg(PPC64_LINUX_FUNCTION
|PPC64_DUMP_MESSAGE
|src
, msg
);
582 printk("[dump]%04x %s\n", src
, msg
);
585 int set_spread_lpevents( char * str
)
587 /* The parameter is the number of processors to share in processing lp events */
589 unsigned long val
= simple_strtoul( str
, NULL
, 0 );
590 if ( ( val
> 0 ) && ( val
<= MAX_PACAS
) ) {
591 for ( i
=1; i
<val
; ++i
)
592 paca
[i
].lpQueuePtr
= paca
[0].lpQueuePtr
;
593 printk("lpevent processing spread over %ld processors\n", val
);
596 printk("invalid spreaqd_lpevents %ld\n", val
);
600 /* This should only be called on processor 0 during calibrate decr */
601 void setup_default_decr(void)
603 struct paca_struct
*lpaca
= get_paca();
605 if ( decr_overclock_set
&& !decr_overclock_proc0_set
)
606 decr_overclock_proc0
= decr_overclock
;
608 lpaca
->default_decr
= tb_ticks_per_jiffy
/ decr_overclock_proc0
;
609 lpaca
->next_jiffy_update_tb
= get_tb() + tb_ticks_per_jiffy
;
612 int set_decr_overclock_proc0( char * str
)
614 unsigned long val
= simple_strtoul( str
, NULL
, 0 );
615 if ( ( val
>= 1 ) && ( val
<= 48 ) ) {
616 decr_overclock_proc0_set
= 1;
617 decr_overclock_proc0
= val
;
618 printk("proc 0 decrementer overclock factor of %ld\n", val
);
621 printk("invalid proc 0 decrementer overclock factor of %ld\n", val
);
625 int set_decr_overclock( char * str
)
627 unsigned long val
= simple_strtoul( str
, NULL
, 0 );
628 if ( ( val
>= 1 ) && ( val
<= 48 ) ) {
629 decr_overclock_set
= 1;
630 decr_overclock
= val
;
631 printk("decrementer overclock factor of %ld\n", val
);
634 printk("invalid decrementer overclock factor of %ld\n", val
);
639 __setup("spread_lpevents=", set_spread_lpevents
);
640 __setup("decr_overclock_proc0=", set_decr_overclock_proc0
);
641 __setup("decr_overclock=", set_decr_overclock
);