xref: /openbmc/linux/arch/powerpc/kernel/setup_32.c (revision 6d7f58b04d824843f7539a132e1ad8220bbe589a)
170d64ceaSPaul Mackerras /*
270d64ceaSPaul Mackerras  * Common prep/pmac/chrp boot and setup code.
370d64ceaSPaul Mackerras  */
470d64ceaSPaul Mackerras 
570d64ceaSPaul Mackerras #include <linux/config.h>
670d64ceaSPaul Mackerras #include <linux/module.h>
770d64ceaSPaul Mackerras #include <linux/string.h>
870d64ceaSPaul Mackerras #include <linux/sched.h>
970d64ceaSPaul Mackerras #include <linux/init.h>
1070d64ceaSPaul Mackerras #include <linux/kernel.h>
1170d64ceaSPaul Mackerras #include <linux/reboot.h>
1270d64ceaSPaul Mackerras #include <linux/delay.h>
1370d64ceaSPaul Mackerras #include <linux/initrd.h>
1470d64ceaSPaul Mackerras #include <linux/ide.h>
1570d64ceaSPaul Mackerras #include <linux/tty.h>
1670d64ceaSPaul Mackerras #include <linux/bootmem.h>
1770d64ceaSPaul Mackerras #include <linux/seq_file.h>
1870d64ceaSPaul Mackerras #include <linux/root_dev.h>
1970d64ceaSPaul Mackerras #include <linux/cpu.h>
2070d64ceaSPaul Mackerras #include <linux/console.h>
2170d64ceaSPaul Mackerras 
2270d64ceaSPaul Mackerras #include <asm/residual.h>
2370d64ceaSPaul Mackerras #include <asm/io.h>
2470d64ceaSPaul Mackerras #include <asm/prom.h>
2570d64ceaSPaul Mackerras #include <asm/processor.h>
2670d64ceaSPaul Mackerras #include <asm/pgtable.h>
2770d64ceaSPaul Mackerras #include <asm/bootinfo.h>
2870d64ceaSPaul Mackerras #include <asm/setup.h>
2970d64ceaSPaul Mackerras #include <asm/amigappc.h>
3070d64ceaSPaul Mackerras #include <asm/smp.h>
3170d64ceaSPaul Mackerras #include <asm/elf.h>
3270d64ceaSPaul Mackerras #include <asm/cputable.h>
3370d64ceaSPaul Mackerras #include <asm/bootx.h>
3470d64ceaSPaul Mackerras #include <asm/btext.h>
3570d64ceaSPaul Mackerras #include <asm/machdep.h>
3670d64ceaSPaul Mackerras #include <asm/uaccess.h>
3770d64ceaSPaul Mackerras #include <asm/system.h>
3870d64ceaSPaul Mackerras #include <asm/pmac_feature.h>
3970d64ceaSPaul Mackerras #include <asm/sections.h>
4070d64ceaSPaul Mackerras #include <asm/nvram.h>
4170d64ceaSPaul Mackerras #include <asm/xmon.h>
42*6d7f58b0SKumar Gala #include <asm/time.h>
4370d64ceaSPaul Mackerras 
4470d64ceaSPaul Mackerras #if defined CONFIG_KGDB
4570d64ceaSPaul Mackerras #include <asm/kgdb.h>
4670d64ceaSPaul Mackerras #endif
4770d64ceaSPaul Mackerras 
4870d64ceaSPaul Mackerras extern void platform_init(void);
4970d64ceaSPaul Mackerras extern void bootx_init(unsigned long r4, unsigned long phys);
5070d64ceaSPaul Mackerras 
5170d64ceaSPaul Mackerras extern void ppc6xx_idle(void);
5270d64ceaSPaul Mackerras extern void power4_idle(void);
5370d64ceaSPaul Mackerras 
5470d64ceaSPaul Mackerras boot_infos_t *boot_infos;
5570d64ceaSPaul Mackerras struct ide_machdep_calls ppc_ide_md;
5670d64ceaSPaul Mackerras 
5770d64ceaSPaul Mackerras /* Used with the BI_MEMSIZE bootinfo parameter to store the memory
5870d64ceaSPaul Mackerras    size value reported by the boot loader. */
5970d64ceaSPaul Mackerras unsigned long boot_mem_size;
6070d64ceaSPaul Mackerras 
6170d64ceaSPaul Mackerras unsigned long ISA_DMA_THRESHOLD;
6270d64ceaSPaul Mackerras unsigned int DMA_MODE_READ;
6370d64ceaSPaul Mackerras unsigned int DMA_MODE_WRITE;
6470d64ceaSPaul Mackerras 
65e574d238SPaul Mackerras int have_of = 1;
66e574d238SPaul Mackerras 
6770d64ceaSPaul Mackerras #ifdef CONFIG_PPC_MULTIPLATFORM
6870d64ceaSPaul Mackerras int _machine = 0;
6970d64ceaSPaul Mackerras 
7070d64ceaSPaul Mackerras extern void prep_init(void);
7170d64ceaSPaul Mackerras extern void pmac_init(void);
7270d64ceaSPaul Mackerras extern void chrp_init(void);
7370d64ceaSPaul Mackerras 
7470d64ceaSPaul Mackerras dev_t boot_dev;
7570d64ceaSPaul Mackerras #endif /* CONFIG_PPC_MULTIPLATFORM */
7670d64ceaSPaul Mackerras 
7770d64ceaSPaul Mackerras #ifdef CONFIG_MAGIC_SYSRQ
7870d64ceaSPaul Mackerras unsigned long SYSRQ_KEY = 0x54;
7970d64ceaSPaul Mackerras #endif /* CONFIG_MAGIC_SYSRQ */
8070d64ceaSPaul Mackerras 
8170d64ceaSPaul Mackerras #ifdef CONFIG_VGA_CONSOLE
8270d64ceaSPaul Mackerras unsigned long vgacon_remap_base;
8370d64ceaSPaul Mackerras #endif
8470d64ceaSPaul Mackerras 
8570d64ceaSPaul Mackerras struct machdep_calls ppc_md;
86e574d238SPaul Mackerras EXPORT_SYMBOL(ppc_md);
8770d64ceaSPaul Mackerras 
8870d64ceaSPaul Mackerras /*
8970d64ceaSPaul Mackerras  * These are used in binfmt_elf.c to put aux entries on the stack
9070d64ceaSPaul Mackerras  * for each elf executable being started.
9170d64ceaSPaul Mackerras  */
9270d64ceaSPaul Mackerras int dcache_bsize;
9370d64ceaSPaul Mackerras int icache_bsize;
9470d64ceaSPaul Mackerras int ucache_bsize;
9570d64ceaSPaul Mackerras 
9670d64ceaSPaul Mackerras #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_FB_VGA16) || \
9770d64ceaSPaul Mackerras     defined(CONFIG_FB_VGA16_MODULE) || defined(CONFIG_FB_VESA)
9870d64ceaSPaul Mackerras struct screen_info screen_info = {
9970d64ceaSPaul Mackerras 	0, 25,			/* orig-x, orig-y */
10070d64ceaSPaul Mackerras 	0,			/* unused */
10170d64ceaSPaul Mackerras 	0,			/* orig-video-page */
10270d64ceaSPaul Mackerras 	0,			/* orig-video-mode */
10370d64ceaSPaul Mackerras 	80,			/* orig-video-cols */
10470d64ceaSPaul Mackerras 	0,0,0,			/* ega_ax, ega_bx, ega_cx */
10570d64ceaSPaul Mackerras 	25,			/* orig-video-lines */
10670d64ceaSPaul Mackerras 	1,			/* orig-video-isVGA */
10770d64ceaSPaul Mackerras 	16			/* orig-video-points */
10870d64ceaSPaul Mackerras };
10970d64ceaSPaul Mackerras #endif /* CONFIG_VGA_CONSOLE || CONFIG_FB_VGA16 || CONFIG_FB_VESA */
11070d64ceaSPaul Mackerras 
11170d64ceaSPaul Mackerras void machine_restart(char *cmd)
11270d64ceaSPaul Mackerras {
11370d64ceaSPaul Mackerras #ifdef CONFIG_NVRAM
11470d64ceaSPaul Mackerras 	nvram_sync();
11570d64ceaSPaul Mackerras #endif
11670d64ceaSPaul Mackerras 	ppc_md.restart(cmd);
11770d64ceaSPaul Mackerras }
11870d64ceaSPaul Mackerras 
11970d64ceaSPaul Mackerras void machine_power_off(void)
12070d64ceaSPaul Mackerras {
12170d64ceaSPaul Mackerras #ifdef CONFIG_NVRAM
12270d64ceaSPaul Mackerras 	nvram_sync();
12370d64ceaSPaul Mackerras #endif
12470d64ceaSPaul Mackerras 	ppc_md.power_off();
12570d64ceaSPaul Mackerras }
12670d64ceaSPaul Mackerras 
12770d64ceaSPaul Mackerras void machine_halt(void)
12870d64ceaSPaul Mackerras {
12970d64ceaSPaul Mackerras #ifdef CONFIG_NVRAM
13070d64ceaSPaul Mackerras 	nvram_sync();
13170d64ceaSPaul Mackerras #endif
13270d64ceaSPaul Mackerras 	ppc_md.halt();
13370d64ceaSPaul Mackerras }
13470d64ceaSPaul Mackerras 
13570d64ceaSPaul Mackerras void (*pm_power_off)(void) = machine_power_off;
13670d64ceaSPaul Mackerras 
13770d64ceaSPaul Mackerras #ifdef CONFIG_TAU
13870d64ceaSPaul Mackerras extern u32 cpu_temp(unsigned long cpu);
13970d64ceaSPaul Mackerras extern u32 cpu_temp_both(unsigned long cpu);
14070d64ceaSPaul Mackerras #endif /* CONFIG_TAU */
14170d64ceaSPaul Mackerras 
14270d64ceaSPaul Mackerras int show_cpuinfo(struct seq_file *m, void *v)
14370d64ceaSPaul Mackerras {
14470d64ceaSPaul Mackerras 	int i = (int) v - 1;
14570d64ceaSPaul Mackerras 	unsigned int pvr;
14670d64ceaSPaul Mackerras 	unsigned short maj, min;
14770d64ceaSPaul Mackerras 	unsigned long lpj;
14870d64ceaSPaul Mackerras 
14970d64ceaSPaul Mackerras 	if (i >= NR_CPUS) {
15070d64ceaSPaul Mackerras 		/* Show summary information */
15170d64ceaSPaul Mackerras #ifdef CONFIG_SMP
15270d64ceaSPaul Mackerras 		unsigned long bogosum = 0;
15370d64ceaSPaul Mackerras 		for (i = 0; i < NR_CPUS; ++i)
15470d64ceaSPaul Mackerras 			if (cpu_online(i))
15570d64ceaSPaul Mackerras 				bogosum += cpu_data[i].loops_per_jiffy;
15670d64ceaSPaul Mackerras 		seq_printf(m, "total bogomips\t: %lu.%02lu\n",
15770d64ceaSPaul Mackerras 			   bogosum/(500000/HZ), bogosum/(5000/HZ) % 100);
15870d64ceaSPaul Mackerras #endif /* CONFIG_SMP */
15970d64ceaSPaul Mackerras 
16070d64ceaSPaul Mackerras 		if (ppc_md.show_cpuinfo != NULL)
1610dd194d0SPaul Mackerras 			ppc_md.show_cpuinfo(m);
1620dd194d0SPaul Mackerras 		return 0;
16370d64ceaSPaul Mackerras 	}
16470d64ceaSPaul Mackerras 
16570d64ceaSPaul Mackerras #ifdef CONFIG_SMP
16670d64ceaSPaul Mackerras 	if (!cpu_online(i))
16770d64ceaSPaul Mackerras 		return 0;
16870d64ceaSPaul Mackerras 	pvr = cpu_data[i].pvr;
16970d64ceaSPaul Mackerras 	lpj = cpu_data[i].loops_per_jiffy;
17070d64ceaSPaul Mackerras #else
17170d64ceaSPaul Mackerras 	pvr = mfspr(SPRN_PVR);
17270d64ceaSPaul Mackerras 	lpj = loops_per_jiffy;
17370d64ceaSPaul Mackerras #endif
17470d64ceaSPaul Mackerras 
17570d64ceaSPaul Mackerras 	seq_printf(m, "processor\t: %d\n", i);
17670d64ceaSPaul Mackerras 	seq_printf(m, "cpu\t\t: ");
17770d64ceaSPaul Mackerras 
17870d64ceaSPaul Mackerras 	if (cur_cpu_spec->pvr_mask)
17970d64ceaSPaul Mackerras 		seq_printf(m, "%s", cur_cpu_spec->cpu_name);
18070d64ceaSPaul Mackerras 	else
18170d64ceaSPaul Mackerras 		seq_printf(m, "unknown (%08x)", pvr);
18270d64ceaSPaul Mackerras #ifdef CONFIG_ALTIVEC
18370d64ceaSPaul Mackerras 	if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
18470d64ceaSPaul Mackerras 		seq_printf(m, ", altivec supported");
18570d64ceaSPaul Mackerras #endif
18670d64ceaSPaul Mackerras 	seq_printf(m, "\n");
18770d64ceaSPaul Mackerras 
18870d64ceaSPaul Mackerras #ifdef CONFIG_TAU
18970d64ceaSPaul Mackerras 	if (cur_cpu_spec->cpu_features & CPU_FTR_TAU) {
19070d64ceaSPaul Mackerras #ifdef CONFIG_TAU_AVERAGE
19170d64ceaSPaul Mackerras 		/* more straightforward, but potentially misleading */
19270d64ceaSPaul Mackerras 		seq_printf(m,  "temperature \t: %u C (uncalibrated)\n",
19370d64ceaSPaul Mackerras 			   cpu_temp(i));
19470d64ceaSPaul Mackerras #else
19570d64ceaSPaul Mackerras 		/* show the actual temp sensor range */
19670d64ceaSPaul Mackerras 		u32 temp;
19770d64ceaSPaul Mackerras 		temp = cpu_temp_both(i);
19870d64ceaSPaul Mackerras 		seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n",
19970d64ceaSPaul Mackerras 			   temp & 0xff, temp >> 16);
20070d64ceaSPaul Mackerras #endif
20170d64ceaSPaul Mackerras 	}
20270d64ceaSPaul Mackerras #endif /* CONFIG_TAU */
20370d64ceaSPaul Mackerras 
2040dd194d0SPaul Mackerras 	if (ppc_md.show_percpuinfo != NULL)
2050dd194d0SPaul Mackerras 		ppc_md.show_percpuinfo(m, i);
20670d64ceaSPaul Mackerras 
20770d64ceaSPaul Mackerras 	/* If we are a Freescale core do a simple check so
20870d64ceaSPaul Mackerras 	 * we dont have to keep adding cases in the future */
2090dd194d0SPaul Mackerras 	if (PVR_VER(pvr) & 0x8000) {
21070d64ceaSPaul Mackerras 		maj = PVR_MAJ(pvr);
21170d64ceaSPaul Mackerras 		min = PVR_MIN(pvr);
21270d64ceaSPaul Mackerras 	} else {
21370d64ceaSPaul Mackerras 		switch (PVR_VER(pvr)) {
21470d64ceaSPaul Mackerras 			case 0x0020:	/* 403 family */
21570d64ceaSPaul Mackerras 				maj = PVR_MAJ(pvr) + 1;
21670d64ceaSPaul Mackerras 				min = PVR_MIN(pvr);
21770d64ceaSPaul Mackerras 				break;
21870d64ceaSPaul Mackerras 			case 0x1008:	/* 740P/750P ?? */
21970d64ceaSPaul Mackerras 				maj = ((pvr >> 8) & 0xFF) - 1;
22070d64ceaSPaul Mackerras 				min = pvr & 0xFF;
22170d64ceaSPaul Mackerras 				break;
22270d64ceaSPaul Mackerras 			default:
22370d64ceaSPaul Mackerras 				maj = (pvr >> 8) & 0xFF;
22470d64ceaSPaul Mackerras 				min = pvr & 0xFF;
22570d64ceaSPaul Mackerras 				break;
22670d64ceaSPaul Mackerras 		}
22770d64ceaSPaul Mackerras 	}
22870d64ceaSPaul Mackerras 
229*6d7f58b0SKumar Gala 	/*
230*6d7f58b0SKumar Gala 	 * Assume here that all clock rates are the same in a
231*6d7f58b0SKumar Gala 	 * smp system.  -- Cort
232*6d7f58b0SKumar Gala 	 */
233*6d7f58b0SKumar Gala 	seq_printf(m, "clock\t\t: %lu.%06luMHz\n", ppc_proc_freq / 1000000,
234*6d7f58b0SKumar Gala 		   ppc_proc_freq % 1000000);
235*6d7f58b0SKumar Gala 
23670d64ceaSPaul Mackerras 	seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n",
23770d64ceaSPaul Mackerras 		   maj, min, PVR_VER(pvr), PVR_REV(pvr));
23870d64ceaSPaul Mackerras 
23970d64ceaSPaul Mackerras 	seq_printf(m, "bogomips\t: %lu.%02lu\n",
24070d64ceaSPaul Mackerras 		   lpj / (500000/HZ), (lpj / (5000/HZ)) % 100);
24170d64ceaSPaul Mackerras 
24270d64ceaSPaul Mackerras #ifdef CONFIG_SMP
24370d64ceaSPaul Mackerras 	seq_printf(m, "\n");
24470d64ceaSPaul Mackerras #endif
24570d64ceaSPaul Mackerras 
24670d64ceaSPaul Mackerras 	return 0;
24770d64ceaSPaul Mackerras }
24870d64ceaSPaul Mackerras 
24970d64ceaSPaul Mackerras static void *c_start(struct seq_file *m, loff_t *pos)
25070d64ceaSPaul Mackerras {
25170d64ceaSPaul Mackerras 	int i = *pos;
25270d64ceaSPaul Mackerras 
25370d64ceaSPaul Mackerras 	return i <= NR_CPUS? (void *) (i + 1): NULL;
25470d64ceaSPaul Mackerras }
25570d64ceaSPaul Mackerras 
25670d64ceaSPaul Mackerras static void *c_next(struct seq_file *m, void *v, loff_t *pos)
25770d64ceaSPaul Mackerras {
25870d64ceaSPaul Mackerras 	++*pos;
25970d64ceaSPaul Mackerras 	return c_start(m, pos);
26070d64ceaSPaul Mackerras }
26170d64ceaSPaul Mackerras 
26270d64ceaSPaul Mackerras static void c_stop(struct seq_file *m, void *v)
26370d64ceaSPaul Mackerras {
26470d64ceaSPaul Mackerras }
26570d64ceaSPaul Mackerras 
26670d64ceaSPaul Mackerras struct seq_operations cpuinfo_op = {
26770d64ceaSPaul Mackerras 	.start =c_start,
26870d64ceaSPaul Mackerras 	.next =	c_next,
26970d64ceaSPaul Mackerras 	.stop =	c_stop,
27070d64ceaSPaul Mackerras 	.show =	show_cpuinfo,
27170d64ceaSPaul Mackerras };
27270d64ceaSPaul Mackerras 
27370d64ceaSPaul Mackerras /*
27470d64ceaSPaul Mackerras  * We're called here very early in the boot.  We determine the machine
27570d64ceaSPaul Mackerras  * type and call the appropriate low-level setup functions.
27670d64ceaSPaul Mackerras  *  -- Cort <cort@fsmlabs.com>
27770d64ceaSPaul Mackerras  *
27870d64ceaSPaul Mackerras  * Note that the kernel may be running at an address which is different
27970d64ceaSPaul Mackerras  * from the address that it was linked at, so we must use RELOC/PTRRELOC
28070d64ceaSPaul Mackerras  * to access static data (including strings).  -- paulus
28170d64ceaSPaul Mackerras  */
28270d64ceaSPaul Mackerras unsigned long __init early_init(unsigned long dt_ptr)
28370d64ceaSPaul Mackerras {
28470d64ceaSPaul Mackerras 	unsigned long offset = reloc_offset();
28570d64ceaSPaul Mackerras 
286dd184343SPaul Mackerras 	/* First zero the BSS -- use memset_io, some platforms don't have
287dd184343SPaul Mackerras 	 * caches on yet */
288dd184343SPaul Mackerras 	memset_io(PTRRELOC(&__bss_start), 0, _end - __bss_start);
289dd184343SPaul Mackerras 
29070d64ceaSPaul Mackerras 	/*
29170d64ceaSPaul Mackerras 	 * Identify the CPU type and fix up code sections
29270d64ceaSPaul Mackerras 	 * that depend on which cpu we have.
29370d64ceaSPaul Mackerras 	 */
29470d64ceaSPaul Mackerras 	identify_cpu(offset, 0);
29570d64ceaSPaul Mackerras 	do_cpu_ftr_fixups(offset);
29670d64ceaSPaul Mackerras 
29770d64ceaSPaul Mackerras 	return KERNELBASE + offset;
29870d64ceaSPaul Mackerras }
29970d64ceaSPaul Mackerras 
30070d64ceaSPaul Mackerras #ifdef CONFIG_PPC_OF
30170d64ceaSPaul Mackerras void __init
30270d64ceaSPaul Mackerras intuit_machine_type(void)
30370d64ceaSPaul Mackerras {
30470d64ceaSPaul Mackerras 	char *model;
30570d64ceaSPaul Mackerras 	struct device_node *root;
30670d64ceaSPaul Mackerras 
30770d64ceaSPaul Mackerras 	/* ask the OF info if we're a chrp or pmac */
30870d64ceaSPaul Mackerras 	root = find_path_device("/");
30970d64ceaSPaul Mackerras 	if (root != 0) {
31070d64ceaSPaul Mackerras 		/* assume pmac unless proven to be chrp -- Cort */
31170d64ceaSPaul Mackerras 		_machine = _MACH_Pmac;
31270d64ceaSPaul Mackerras 		model = get_property(root, "device_type", NULL);
31370d64ceaSPaul Mackerras 		if (model && !strncmp("chrp", model, 4))
31470d64ceaSPaul Mackerras 			_machine = _MACH_chrp;
31570d64ceaSPaul Mackerras 		else {
31670d64ceaSPaul Mackerras 			model = get_property(root, "model", NULL);
31770d64ceaSPaul Mackerras 			if (model && !strncmp(model, "IBM", 3))
31870d64ceaSPaul Mackerras 				_machine = _MACH_chrp;
31970d64ceaSPaul Mackerras 		}
32070d64ceaSPaul Mackerras 	}
32170d64ceaSPaul Mackerras }
32270d64ceaSPaul Mackerras #endif
32370d64ceaSPaul Mackerras 
32470d64ceaSPaul Mackerras #ifdef CONFIG_PPC_MULTIPLATFORM
32570d64ceaSPaul Mackerras /*
32670d64ceaSPaul Mackerras  * The PPC_MULTIPLATFORM version of platform_init...
32770d64ceaSPaul Mackerras  */
32870d64ceaSPaul Mackerras void __init platform_init(void)
32970d64ceaSPaul Mackerras {
33070d64ceaSPaul Mackerras 	/* if we didn't get any bootinfo telling us what we are... */
33170d64ceaSPaul Mackerras 	if (_machine == 0) {
33270d64ceaSPaul Mackerras 		/* prep boot loader tells us if we're prep or not */
33370d64ceaSPaul Mackerras 		if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
33470d64ceaSPaul Mackerras 			_machine = _MACH_prep;
33570d64ceaSPaul Mackerras 	}
33670d64ceaSPaul Mackerras 
33770d64ceaSPaul Mackerras #ifdef CONFIG_PPC_PREP
33870d64ceaSPaul Mackerras 	/* not much more to do here, if prep */
33970d64ceaSPaul Mackerras 	if (_machine == _MACH_prep) {
34070d64ceaSPaul Mackerras 		prep_init();
34170d64ceaSPaul Mackerras 		return;
34270d64ceaSPaul Mackerras 	}
34370d64ceaSPaul Mackerras #endif
34470d64ceaSPaul Mackerras 
34570d64ceaSPaul Mackerras #ifdef CONFIG_ADB
34670d64ceaSPaul Mackerras 	if (strstr(cmd_line, "adb_sync")) {
34770d64ceaSPaul Mackerras 		extern int __adb_probe_sync;
34870d64ceaSPaul Mackerras 		__adb_probe_sync = 1;
34970d64ceaSPaul Mackerras 	}
35070d64ceaSPaul Mackerras #endif /* CONFIG_ADB */
35170d64ceaSPaul Mackerras 
35270d64ceaSPaul Mackerras 	switch (_machine) {
35370d64ceaSPaul Mackerras #ifdef CONFIG_PPC_PMAC
35470d64ceaSPaul Mackerras 	case _MACH_Pmac:
35570d64ceaSPaul Mackerras 		pmac_init();
35670d64ceaSPaul Mackerras 		break;
35770d64ceaSPaul Mackerras #endif
35870d64ceaSPaul Mackerras #ifdef CONFIG_PPC_CHRP
35970d64ceaSPaul Mackerras 	case _MACH_chrp:
36070d64ceaSPaul Mackerras 		chrp_init();
36170d64ceaSPaul Mackerras 		break;
36270d64ceaSPaul Mackerras #endif
36370d64ceaSPaul Mackerras 	}
36470d64ceaSPaul Mackerras }
36570d64ceaSPaul Mackerras 
36670d64ceaSPaul Mackerras #ifdef CONFIG_SERIAL_CORE_CONSOLE
36770d64ceaSPaul Mackerras extern char *of_stdout_device;
36870d64ceaSPaul Mackerras 
36970d64ceaSPaul Mackerras static int __init set_preferred_console(void)
37070d64ceaSPaul Mackerras {
37170d64ceaSPaul Mackerras 	struct device_node *prom_stdout;
37270d64ceaSPaul Mackerras 	char *name;
37370d64ceaSPaul Mackerras 	int offset = 0;
37470d64ceaSPaul Mackerras 
37570d64ceaSPaul Mackerras 	if (of_stdout_device == NULL)
37670d64ceaSPaul Mackerras 		return -ENODEV;
37770d64ceaSPaul Mackerras 
37870d64ceaSPaul Mackerras 	/* The user has requested a console so this is already set up. */
37970d64ceaSPaul Mackerras 	if (strstr(saved_command_line, "console="))
38070d64ceaSPaul Mackerras 		return -EBUSY;
38170d64ceaSPaul Mackerras 
38270d64ceaSPaul Mackerras 	prom_stdout = find_path_device(of_stdout_device);
38370d64ceaSPaul Mackerras 	if (!prom_stdout)
38470d64ceaSPaul Mackerras 		return -ENODEV;
38570d64ceaSPaul Mackerras 
38670d64ceaSPaul Mackerras 	name = (char *)get_property(prom_stdout, "name", NULL);
38770d64ceaSPaul Mackerras 	if (!name)
38870d64ceaSPaul Mackerras 		return -ENODEV;
38970d64ceaSPaul Mackerras 
39070d64ceaSPaul Mackerras 	if (strcmp(name, "serial") == 0) {
39170d64ceaSPaul Mackerras 		int i;
39270d64ceaSPaul Mackerras 		u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i);
39370d64ceaSPaul Mackerras 		if (i > 8) {
39470d64ceaSPaul Mackerras 			switch (reg[1]) {
39570d64ceaSPaul Mackerras 				case 0x3f8:
39670d64ceaSPaul Mackerras 					offset = 0;
39770d64ceaSPaul Mackerras 					break;
39870d64ceaSPaul Mackerras 				case 0x2f8:
39970d64ceaSPaul Mackerras 					offset = 1;
40070d64ceaSPaul Mackerras 					break;
40170d64ceaSPaul Mackerras 				case 0x898:
40270d64ceaSPaul Mackerras 					offset = 2;
40370d64ceaSPaul Mackerras 					break;
40470d64ceaSPaul Mackerras 				case 0x890:
40570d64ceaSPaul Mackerras 					offset = 3;
40670d64ceaSPaul Mackerras 					break;
40770d64ceaSPaul Mackerras 				default:
40870d64ceaSPaul Mackerras 					/* We dont recognise the serial port */
40970d64ceaSPaul Mackerras 					return -ENODEV;
41070d64ceaSPaul Mackerras 			}
41170d64ceaSPaul Mackerras 		}
41270d64ceaSPaul Mackerras 	} else if (strcmp(name, "ch-a") == 0)
41370d64ceaSPaul Mackerras 		offset = 0;
41470d64ceaSPaul Mackerras 	else if (strcmp(name, "ch-b") == 0)
41570d64ceaSPaul Mackerras 		offset = 1;
41670d64ceaSPaul Mackerras 	else
41770d64ceaSPaul Mackerras 		return -ENODEV;
41870d64ceaSPaul Mackerras 	return add_preferred_console("ttyS", offset, NULL);
41970d64ceaSPaul Mackerras }
42070d64ceaSPaul Mackerras console_initcall(set_preferred_console);
42170d64ceaSPaul Mackerras #endif /* CONFIG_SERIAL_CORE_CONSOLE */
42270d64ceaSPaul Mackerras #endif /* CONFIG_PPC_MULTIPLATFORM */
42370d64ceaSPaul Mackerras 
42470d64ceaSPaul Mackerras /*
42570d64ceaSPaul Mackerras  * Find out what kind of machine we're on and save any data we need
42670d64ceaSPaul Mackerras  * from the early boot process (devtree is copied on pmac by prom_init()).
42770d64ceaSPaul Mackerras  * This is called very early on the boot process, after a minimal
42870d64ceaSPaul Mackerras  * MMU environment has been set up but before MMU_init is called.
42970d64ceaSPaul Mackerras  */
43070d64ceaSPaul Mackerras void __init machine_init(unsigned long dt_ptr, unsigned long phys)
43170d64ceaSPaul Mackerras {
43270d64ceaSPaul Mackerras 	early_init_devtree(__va(dt_ptr));
43370d64ceaSPaul Mackerras 
43470d64ceaSPaul Mackerras #ifdef CONFIG_CMDLINE
43570d64ceaSPaul Mackerras 	strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
43670d64ceaSPaul Mackerras #endif /* CONFIG_CMDLINE */
43770d64ceaSPaul Mackerras 
43835499c01SPaul Mackerras 	platform_init();
43935499c01SPaul Mackerras 
44070d64ceaSPaul Mackerras #ifdef CONFIG_6xx
44170d64ceaSPaul Mackerras 	ppc_md.power_save = ppc6xx_idle;
44270d64ceaSPaul Mackerras #endif
44370d64ceaSPaul Mackerras 
44470d64ceaSPaul Mackerras 	if (ppc_md.progress)
44570d64ceaSPaul Mackerras 		ppc_md.progress("id mach(): done", 0x200);
44670d64ceaSPaul Mackerras }
44770d64ceaSPaul Mackerras 
44870d64ceaSPaul Mackerras #ifdef CONFIG_BOOKE_WDT
44970d64ceaSPaul Mackerras /* Checks wdt=x and wdt_period=xx command-line option */
45070d64ceaSPaul Mackerras int __init early_parse_wdt(char *p)
45170d64ceaSPaul Mackerras {
45270d64ceaSPaul Mackerras 	if (p && strncmp(p, "0", 1) != 0)
45370d64ceaSPaul Mackerras 	       booke_wdt_enabled = 1;
45470d64ceaSPaul Mackerras 
45570d64ceaSPaul Mackerras 	return 0;
45670d64ceaSPaul Mackerras }
45770d64ceaSPaul Mackerras early_param("wdt", early_parse_wdt);
45870d64ceaSPaul Mackerras 
45970d64ceaSPaul Mackerras int __init early_parse_wdt_period (char *p)
46070d64ceaSPaul Mackerras {
46170d64ceaSPaul Mackerras 	if (p)
46270d64ceaSPaul Mackerras 		booke_wdt_period = simple_strtoul(p, NULL, 0);
46370d64ceaSPaul Mackerras 
46470d64ceaSPaul Mackerras 	return 0;
46570d64ceaSPaul Mackerras }
46670d64ceaSPaul Mackerras early_param("wdt_period", early_parse_wdt_period);
46770d64ceaSPaul Mackerras #endif	/* CONFIG_BOOKE_WDT */
46870d64ceaSPaul Mackerras 
46970d64ceaSPaul Mackerras /* Checks "l2cr=xxxx" command-line option */
47070d64ceaSPaul Mackerras int __init ppc_setup_l2cr(char *str)
47170d64ceaSPaul Mackerras {
47270d64ceaSPaul Mackerras 	if (cpu_has_feature(CPU_FTR_L2CR)) {
47370d64ceaSPaul Mackerras 		unsigned long val = simple_strtoul(str, NULL, 0);
47470d64ceaSPaul Mackerras 		printk(KERN_INFO "l2cr set to %lx\n", val);
47570d64ceaSPaul Mackerras 		_set_L2CR(0);		/* force invalidate by disable cache */
47670d64ceaSPaul Mackerras 		_set_L2CR(val);		/* and enable it */
47770d64ceaSPaul Mackerras 	}
47870d64ceaSPaul Mackerras 	return 1;
47970d64ceaSPaul Mackerras }
48070d64ceaSPaul Mackerras __setup("l2cr=", ppc_setup_l2cr);
48170d64ceaSPaul Mackerras 
48270d64ceaSPaul Mackerras #ifdef CONFIG_GENERIC_NVRAM
48370d64ceaSPaul Mackerras 
48470d64ceaSPaul Mackerras /* Generic nvram hooks used by drivers/char/gen_nvram.c */
48570d64ceaSPaul Mackerras unsigned char nvram_read_byte(int addr)
48670d64ceaSPaul Mackerras {
48770d64ceaSPaul Mackerras 	if (ppc_md.nvram_read_val)
48870d64ceaSPaul Mackerras 		return ppc_md.nvram_read_val(addr);
48970d64ceaSPaul Mackerras 	return 0xff;
49070d64ceaSPaul Mackerras }
49170d64ceaSPaul Mackerras EXPORT_SYMBOL(nvram_read_byte);
49270d64ceaSPaul Mackerras 
49370d64ceaSPaul Mackerras void nvram_write_byte(unsigned char val, int addr)
49470d64ceaSPaul Mackerras {
49570d64ceaSPaul Mackerras 	if (ppc_md.nvram_write_val)
49670d64ceaSPaul Mackerras 		ppc_md.nvram_write_val(addr, val);
49770d64ceaSPaul Mackerras }
49870d64ceaSPaul Mackerras EXPORT_SYMBOL(nvram_write_byte);
49970d64ceaSPaul Mackerras 
50070d64ceaSPaul Mackerras void nvram_sync(void)
50170d64ceaSPaul Mackerras {
50270d64ceaSPaul Mackerras 	if (ppc_md.nvram_sync)
50370d64ceaSPaul Mackerras 		ppc_md.nvram_sync();
50470d64ceaSPaul Mackerras }
50570d64ceaSPaul Mackerras EXPORT_SYMBOL(nvram_sync);
50670d64ceaSPaul Mackerras 
50770d64ceaSPaul Mackerras #endif /* CONFIG_NVRAM */
50870d64ceaSPaul Mackerras 
50970d64ceaSPaul Mackerras static struct cpu cpu_devices[NR_CPUS];
51070d64ceaSPaul Mackerras 
51170d64ceaSPaul Mackerras int __init ppc_init(void)
51270d64ceaSPaul Mackerras {
51370d64ceaSPaul Mackerras 	int i;
51470d64ceaSPaul Mackerras 
51570d64ceaSPaul Mackerras 	/* clear the progress line */
51670d64ceaSPaul Mackerras 	if ( ppc_md.progress ) ppc_md.progress("             ", 0xffff);
51770d64ceaSPaul Mackerras 
51870d64ceaSPaul Mackerras 	/* register CPU devices */
51970d64ceaSPaul Mackerras 	for (i = 0; i < NR_CPUS; i++)
52070d64ceaSPaul Mackerras 		if (cpu_possible(i))
52170d64ceaSPaul Mackerras 			register_cpu(&cpu_devices[i], i, NULL);
52270d64ceaSPaul Mackerras 
52370d64ceaSPaul Mackerras 	/* call platform init */
52470d64ceaSPaul Mackerras 	if (ppc_md.init != NULL) {
52570d64ceaSPaul Mackerras 		ppc_md.init();
52670d64ceaSPaul Mackerras 	}
52770d64ceaSPaul Mackerras 	return 0;
52870d64ceaSPaul Mackerras }
52970d64ceaSPaul Mackerras 
53070d64ceaSPaul Mackerras arch_initcall(ppc_init);
53170d64ceaSPaul Mackerras 
53270d64ceaSPaul Mackerras /* Warning, IO base is not yet inited */
53370d64ceaSPaul Mackerras void __init setup_arch(char **cmdline_p)
53470d64ceaSPaul Mackerras {
53570d64ceaSPaul Mackerras 	extern char *klimit;
53670d64ceaSPaul Mackerras 	extern void do_init_bootmem(void);
53770d64ceaSPaul Mackerras 
53870d64ceaSPaul Mackerras 	/* so udelay does something sensible, assume <= 1000 bogomips */
53970d64ceaSPaul Mackerras 	loops_per_jiffy = 500000000 / HZ;
54070d64ceaSPaul Mackerras 
54170d64ceaSPaul Mackerras 	unflatten_device_tree();
54270d64ceaSPaul Mackerras 	finish_device_tree();
54370d64ceaSPaul Mackerras 
54430cd4a4eSPaul Mackerras #ifdef CONFIG_BOOTX_TEXT
54530cd4a4eSPaul Mackerras 	init_boot_display();
54630cd4a4eSPaul Mackerras #endif
54730cd4a4eSPaul Mackerras 
54870d64ceaSPaul Mackerras #ifdef CONFIG_PPC_MULTIPLATFORM
54970d64ceaSPaul Mackerras 	/* This could be called "early setup arch", it must be done
55070d64ceaSPaul Mackerras 	 * now because xmon need it
55170d64ceaSPaul Mackerras 	 */
55270d64ceaSPaul Mackerras 	if (_machine == _MACH_Pmac)
55370d64ceaSPaul Mackerras 		pmac_feature_init();	/* New cool way */
55470d64ceaSPaul Mackerras #endif
55570d64ceaSPaul Mackerras 
55670d64ceaSPaul Mackerras #ifdef CONFIG_XMON
55770d64ceaSPaul Mackerras 	xmon_map_scc();
55870d64ceaSPaul Mackerras 	if (strstr(cmd_line, "xmon"))
55970d64ceaSPaul Mackerras 		xmon(NULL);
56070d64ceaSPaul Mackerras #endif /* CONFIG_XMON */
56170d64ceaSPaul Mackerras 	if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab);
56270d64ceaSPaul Mackerras 
56370d64ceaSPaul Mackerras #if defined(CONFIG_KGDB)
56470d64ceaSPaul Mackerras 	if (ppc_md.kgdb_map_scc)
56570d64ceaSPaul Mackerras 		ppc_md.kgdb_map_scc();
56670d64ceaSPaul Mackerras 	set_debug_traps();
56770d64ceaSPaul Mackerras 	if (strstr(cmd_line, "gdb")) {
56870d64ceaSPaul Mackerras 		if (ppc_md.progress)
56970d64ceaSPaul Mackerras 			ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000);
57070d64ceaSPaul Mackerras 		printk("kgdb breakpoint activated\n");
57170d64ceaSPaul Mackerras 		breakpoint();
57270d64ceaSPaul Mackerras 	}
57370d64ceaSPaul Mackerras #endif
57470d64ceaSPaul Mackerras 
57570d64ceaSPaul Mackerras 	/*
57670d64ceaSPaul Mackerras 	 * Set cache line size based on type of cpu as a default.
57770d64ceaSPaul Mackerras 	 * Systems with OF can look in the properties on the cpu node(s)
57870d64ceaSPaul Mackerras 	 * for a possibly more accurate value.
57970d64ceaSPaul Mackerras 	 */
58070d64ceaSPaul Mackerras 	if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) {
58170d64ceaSPaul Mackerras 		dcache_bsize = cur_cpu_spec->dcache_bsize;
58270d64ceaSPaul Mackerras 		icache_bsize = cur_cpu_spec->icache_bsize;
58370d64ceaSPaul Mackerras 		ucache_bsize = 0;
58470d64ceaSPaul Mackerras 	} else
58570d64ceaSPaul Mackerras 		ucache_bsize = dcache_bsize = icache_bsize
58670d64ceaSPaul Mackerras 			= cur_cpu_spec->dcache_bsize;
58770d64ceaSPaul Mackerras 
58870d64ceaSPaul Mackerras 	/* reboot on panic */
58970d64ceaSPaul Mackerras 	panic_timeout = 180;
59070d64ceaSPaul Mackerras 
59170d64ceaSPaul Mackerras 	init_mm.start_code = PAGE_OFFSET;
59270d64ceaSPaul Mackerras 	init_mm.end_code = (unsigned long) _etext;
59370d64ceaSPaul Mackerras 	init_mm.end_data = (unsigned long) _edata;
59470d64ceaSPaul Mackerras 	init_mm.brk = (unsigned long) klimit;
59570d64ceaSPaul Mackerras 
59670d64ceaSPaul Mackerras 	/* Save unparsed command line copy for /proc/cmdline */
59770d64ceaSPaul Mackerras 	strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
59870d64ceaSPaul Mackerras 	*cmdline_p = cmd_line;
59970d64ceaSPaul Mackerras 
60070d64ceaSPaul Mackerras 	parse_early_param();
60170d64ceaSPaul Mackerras 
60270d64ceaSPaul Mackerras 	/* set up the bootmem stuff with available memory */
60370d64ceaSPaul Mackerras 	do_init_bootmem();
60470d64ceaSPaul Mackerras 	if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
60570d64ceaSPaul Mackerras 
60670d64ceaSPaul Mackerras #ifdef CONFIG_PPC_OCP
60770d64ceaSPaul Mackerras 	/* Initialize OCP device list */
60870d64ceaSPaul Mackerras 	ocp_early_init();
60970d64ceaSPaul Mackerras 	if ( ppc_md.progress ) ppc_md.progress("ocp: exit", 0x3eab);
61070d64ceaSPaul Mackerras #endif
61170d64ceaSPaul Mackerras 
61270d64ceaSPaul Mackerras #ifdef CONFIG_DUMMY_CONSOLE
61370d64ceaSPaul Mackerras 	conswitchp = &dummy_con;
61470d64ceaSPaul Mackerras #endif
61570d64ceaSPaul Mackerras 
61670d64ceaSPaul Mackerras 	ppc_md.setup_arch();
61770d64ceaSPaul Mackerras 	if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
61870d64ceaSPaul Mackerras 
61970d64ceaSPaul Mackerras 	paging_init();
62070d64ceaSPaul Mackerras 
62170d64ceaSPaul Mackerras 	/* this is for modules since _machine can be a define -- Cort */
62270d64ceaSPaul Mackerras 	ppc_md.ppc_machine = _machine;
62370d64ceaSPaul Mackerras }
624