Blame view

arch/powerpc/kernel/setup_32.c 8.18 KB
9b6b563c0   Paul Mackerras   powerpc: Merge in...
1
2
3
  /*
   * Common prep/pmac/chrp boot and setup code.
   */
9b6b563c0   Paul Mackerras   powerpc: Merge in...
4
5
6
7
8
9
10
11
  #include <linux/module.h>
  #include <linux/string.h>
  #include <linux/sched.h>
  #include <linux/init.h>
  #include <linux/kernel.h>
  #include <linux/reboot.h>
  #include <linux/delay.h>
  #include <linux/initrd.h>
9b6b563c0   Paul Mackerras   powerpc: Merge in...
12
13
14
15
16
17
  #include <linux/tty.h>
  #include <linux/bootmem.h>
  #include <linux/seq_file.h>
  #include <linux/root_dev.h>
  #include <linux/cpu.h>
  #include <linux/console.h>
95f72d1ed   Yinghai Lu   lmb: rename to me...
18
  #include <linux/memblock.h>
9b6b563c0   Paul Mackerras   powerpc: Merge in...
19

9b6b563c0   Paul Mackerras   powerpc: Merge in...
20
21
22
23
  #include <asm/io.h>
  #include <asm/prom.h>
  #include <asm/processor.h>
  #include <asm/pgtable.h>
9b6b563c0   Paul Mackerras   powerpc: Merge in...
24
  #include <asm/setup.h>
9b6b563c0   Paul Mackerras   powerpc: Merge in...
25
26
27
28
29
30
31
32
33
34
35
36
  #include <asm/smp.h>
  #include <asm/elf.h>
  #include <asm/cputable.h>
  #include <asm/bootx.h>
  #include <asm/btext.h>
  #include <asm/machdep.h>
  #include <asm/uaccess.h>
  #include <asm/system.h>
  #include <asm/pmac_feature.h>
  #include <asm/sections.h>
  #include <asm/nvram.h>
  #include <asm/xmon.h>
6d7f58b04   Kumar Gala   [PATCH] powerpc: ...
37
  #include <asm/time.h>
463ce0e10   Benjamin Herrenschmidt   [PATCH] powerpc: ...
38
  #include <asm/serial.h>
51d3082fe   Benjamin Herrenschmidt   [PATCH] powerpc: ...
39
  #include <asm/udbg.h>
775203518   Benjamin Herrenschmidt   powerpc/mm: Runti...
40
  #include <asm/mmu_context.h>
9b6b563c0   Paul Mackerras   powerpc: Merge in...
41

66ba135c5   Stephen Rothwell   powerpc: create k...
42
  #include "setup.h"
03501dab0   Paul Mackerras   powerpc: Pull com...
43
  #define DBG(fmt...)
9b6b563c0   Paul Mackerras   powerpc: Merge in...
44
  extern void bootx_init(unsigned long r4, unsigned long phys);
2ed38b235   Matthew McClintock   powerpc/fsl_booke...
45
  int boot_cpuid = -1;
80579e1f4   Paul Mackerras   powerpc: 32-bit C...
46
47
  EXPORT_SYMBOL_GPL(boot_cpuid);
  int boot_cpuid_phys;
9974eec2b   Andrew Gabbasov   powerpc: Exportin...
48
  EXPORT_SYMBOL_GPL(boot_cpuid_phys);
80579e1f4   Paul Mackerras   powerpc: 32-bit C...
49

13a9801eb   Nathan Lynch   powerpc: Move smp...
50
  int smp_hw_index[NR_CPUS];
9b6b563c0   Paul Mackerras   powerpc: Merge in...
51
52
53
  unsigned long ISA_DMA_THRESHOLD;
  unsigned int DMA_MODE_READ;
  unsigned int DMA_MODE_WRITE;
9b6b563c0   Paul Mackerras   powerpc: Merge in...
54
55
  #ifdef CONFIG_VGA_CONSOLE
  unsigned long vgacon_remap_base;
d003e7a1a   Mathieu Desnoyers   [POWERPC] Add exp...
56
  EXPORT_SYMBOL(vgacon_remap_base);
9b6b563c0   Paul Mackerras   powerpc: Merge in...
57
  #endif
9b6b563c0   Paul Mackerras   powerpc: Merge in...
58
59
60
61
62
63
64
  /*
   * These are used in binfmt_elf.c to put aux entries on the stack
   * for each elf executable being started.
   */
  int dcache_bsize;
  int icache_bsize;
  int ucache_bsize;
9b6b563c0   Paul Mackerras   powerpc: Merge in...
65
66
67
68
69
70
71
72
73
  /*
   * We're called here very early in the boot.  We determine the machine
   * type and call the appropriate low-level setup functions.
   *  -- Cort <cort@fsmlabs.com>
   *
   * Note that the kernel may be running at an address which is different
   * from the address that it was linked at, so we must use RELOC/PTRRELOC
   * to access static data (including strings).  -- paulus
   */
4e491d14f   Steven Rostedt   ftrace: support f...
74
  notrace unsigned long __init early_init(unsigned long dt_ptr)
9b6b563c0   Paul Mackerras   powerpc: Merge in...
75
76
  {
  	unsigned long offset = reloc_offset();
42c4aaadb   Benjamin Herrenschmidt   [POWERPC] Consoli...
77
  	struct cpu_spec *spec;
9b6b563c0   Paul Mackerras   powerpc: Merge in...
78

dd184343b   Paul Mackerras   powerpc: Clear th...
79
80
  	/* First zero the BSS -- use memset_io, some platforms don't have
  	 * caches on yet */
556b09c81   Mark A. Greer   [POWERPC] 32-bit ...
81
82
  	memset_io((void __iomem *)PTRRELOC(&__bss_start), 0,
  			__bss_stop - __bss_start);
dd184343b   Paul Mackerras   powerpc: Clear th...
83

9b6b563c0   Paul Mackerras   powerpc: Merge in...
84
85
86
87
  	/*
  	 * Identify the CPU type and fix up code sections
  	 * that depend on which cpu we have.
  	 */
974a76f51   Paul Mackerras   [POWERPC] Disting...
88
  	spec = identify_cpu(offset, mfspr(SPRN_PVR));
42c4aaadb   Benjamin Herrenschmidt   [POWERPC] Consoli...
89

0909c8c2d   Benjamin Herrenschmidt   [POWERPC] Support...
90
  	do_feature_fixups(spec->cpu_features,
42c4aaadb   Benjamin Herrenschmidt   [POWERPC] Consoli...
91
92
  			  PTRRELOC(&__start___ftr_fixup),
  			  PTRRELOC(&__stop___ftr_fixup));
9b6b563c0   Paul Mackerras   powerpc: Merge in...
93

7c03d653c   Benjamin Herrenschmidt   powerpc/mm: Intro...
94
95
96
  	do_feature_fixups(spec->mmu_features,
  			  PTRRELOC(&__start___mmu_ftr_fixup),
  			  PTRRELOC(&__stop___mmu_ftr_fixup));
2d1b20276   Kumar Gala   powerpc: Fixup lw...
97
98
99
  	do_lwsync_fixups(spec->cpu_features,
  			 PTRRELOC(&__start___lwsync_fixup),
  			 PTRRELOC(&__stop___lwsync_fixup));
d715e433b   Anton Blanchard   powerpc: Copy dow...
100
  	do_final_fixups();
9b6b563c0   Paul Mackerras   powerpc: Merge in...
101
102
  	return KERNELBASE + offset;
  }
9b6b563c0   Paul Mackerras   powerpc: Merge in...
103

9b6b563c0   Paul Mackerras   powerpc: Merge in...
104
105
106
107
108
109
  /*
   * Find out what kind of machine we're on and save any data we need
   * from the early boot process (devtree is copied on pmac by prom_init()).
   * This is called very early on the boot process, after a minimal
   * MMU environment has been set up but before MMU_init is called.
   */
6dece0eb6   Scott Wood   powerpc/32: Pass ...
110
  notrace void __init machine_init(u64 dt_ptr)
9b6b563c0   Paul Mackerras   powerpc: Merge in...
111
  {
5d38902c4   Benjamin Herrenschmidt   powerpc: Add irqt...
112
  	lockdep_init();
719c91cca   David Gibson   [POWERPC] Use udb...
113
114
  	/* Enable early debugging if any specified (see udbg.h) */
  	udbg_early_init();
51d3082fe   Benjamin Herrenschmidt   [PATCH] powerpc: ...
115
116
  
  	/* Do some early initialization based on the flat device tree */
9b6b563c0   Paul Mackerras   powerpc: Merge in...
117
  	early_init_devtree(__va(dt_ptr));
91b191c71   Dave Kleikamp   powerpc/44x: don'...
118
  	early_init_mmu();
e8222502e   Benjamin Herrenschmidt   [PATCH] powerpc: ...
119
  	probe_machine();
35499c019   Paul Mackerras   powerpc: Merge in...
120

f8f50b1bd   Dale Farnsworth   powerpc/32: Wire ...
121
  	setup_kdump_trampoline();
9b6b563c0   Paul Mackerras   powerpc: Merge in...
122
  #ifdef CONFIG_6xx
a0652fc9a   Paul Mackerras   powerpc: Unify th...
123
124
125
  	if (cpu_has_feature(CPU_FTR_CAN_DOZE) ||
  	    cpu_has_feature(CPU_FTR_CAN_NAP))
  		ppc_md.power_save = ppc6xx_idle;
9b6b563c0   Paul Mackerras   powerpc: Merge in...
126
  #endif
9b6b563c0   Paul Mackerras   powerpc: Merge in...
127

fc4033b2f   Kumar Gala   powerpc/85xx: add...
128
129
130
131
132
  #ifdef CONFIG_E500
  	if (cpu_has_feature(CPU_FTR_CAN_DOZE) ||
  	    cpu_has_feature(CPU_FTR_CAN_NAP))
  		ppc_md.power_save = e500_idle;
  #endif
9b6b563c0   Paul Mackerras   powerpc: Merge in...
133
134
135
136
137
138
  	if (ppc_md.progress)
  		ppc_md.progress("id mach(): done", 0x200);
  }
  
  #ifdef CONFIG_BOOKE_WDT
  /* Checks wdt=x and wdt_period=xx command-line option */
4e491d14f   Steven Rostedt   ftrace: support f...
139
  notrace int __init early_parse_wdt(char *p)
9b6b563c0   Paul Mackerras   powerpc: Merge in...
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
  {
  	if (p && strncmp(p, "0", 1) != 0)
  	       booke_wdt_enabled = 1;
  
  	return 0;
  }
  early_param("wdt", early_parse_wdt);
  
  int __init early_parse_wdt_period (char *p)
  {
  	if (p)
  		booke_wdt_period = simple_strtoul(p, NULL, 0);
  
  	return 0;
  }
  early_param("wdt_period", early_parse_wdt_period);
  #endif	/* CONFIG_BOOKE_WDT */
  
  /* Checks "l2cr=xxxx" command-line option */
  int __init ppc_setup_l2cr(char *str)
  {
  	if (cpu_has_feature(CPU_FTR_L2CR)) {
  		unsigned long val = simple_strtoul(str, NULL, 0);
  		printk(KERN_INFO "l2cr set to %lx
  ", val);
  		_set_L2CR(0);		/* force invalidate by disable cache */
  		_set_L2CR(val);		/* and enable it */
  	}
  	return 1;
  }
  __setup("l2cr=", ppc_setup_l2cr);
a78bfbfcf   Robert Brose   [POWERPC] Add ker...
171
172
173
174
175
176
177
178
179
180
181
182
  /* Checks "l3cr=xxxx" command-line option */
  int __init ppc_setup_l3cr(char *str)
  {
  	if (cpu_has_feature(CPU_FTR_L3CR)) {
  		unsigned long val = simple_strtoul(str, NULL, 0);
  		printk(KERN_INFO "l3cr set to %lx
  ", val);
  		_set_L3CR(val);		/* and enable it */
  	}
  	return 1;
  }
  __setup("l3cr=", ppc_setup_l3cr);
9b6b563c0   Paul Mackerras   powerpc: Merge in...
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
  #ifdef CONFIG_GENERIC_NVRAM
  
  /* Generic nvram hooks used by drivers/char/gen_nvram.c */
  unsigned char nvram_read_byte(int addr)
  {
  	if (ppc_md.nvram_read_val)
  		return ppc_md.nvram_read_val(addr);
  	return 0xff;
  }
  EXPORT_SYMBOL(nvram_read_byte);
  
  void nvram_write_byte(unsigned char val, int addr)
  {
  	if (ppc_md.nvram_write_val)
  		ppc_md.nvram_write_val(addr, val);
  }
  EXPORT_SYMBOL(nvram_write_byte);
d331d8305   Martyn Welch   powerpc/nvram: En...
200
201
202
203
204
205
206
  ssize_t nvram_get_size(void)
  {
  	if (ppc_md.nvram_size)
  		return ppc_md.nvram_size();
  	return -1;
  }
  EXPORT_SYMBOL(nvram_get_size);
9b6b563c0   Paul Mackerras   powerpc: Merge in...
207
208
209
210
211
212
213
214
  void nvram_sync(void)
  {
  	if (ppc_md.nvram_sync)
  		ppc_md.nvram_sync();
  }
  EXPORT_SYMBOL(nvram_sync);
  
  #endif /* CONFIG_NVRAM */
9b6b563c0   Paul Mackerras   powerpc: Merge in...
215
216
  int __init ppc_init(void)
  {
9b6b563c0   Paul Mackerras   powerpc: Merge in...
217
  	/* clear the progress line */
5e41763ae   Giuliano Pochini   [POWERPC] Fix bre...
218
219
  	if (ppc_md.progress)
  		ppc_md.progress("             ", 0xffff);
9b6b563c0   Paul Mackerras   powerpc: Merge in...
220

9b6b563c0   Paul Mackerras   powerpc: Merge in...
221
222
223
224
225
226
227
228
  	/* call platform init */
  	if (ppc_md.init != NULL) {
  		ppc_md.init();
  	}
  	return 0;
  }
  
  arch_initcall(ppc_init);
85218827c   Kumar Gala   [POWERPC] Add IRQ...
229
230
231
232
233
  static void __init irqstack_early_init(void)
  {
  	unsigned int i;
  
  	/* interrupt stacks must be in lowmem, we get that for free on ppc32
e63075a3c   Benjamin Herrenschmidt   memblock: Introdu...
234
  	 * as the memblock is limited to lowmem by default */
85218827c   Kumar Gala   [POWERPC] Add IRQ...
235
236
  	for_each_possible_cpu(i) {
  		softirq_ctx[i] = (struct thread_info *)
95f72d1ed   Yinghai Lu   lmb: rename to me...
237
  			__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
85218827c   Kumar Gala   [POWERPC] Add IRQ...
238
  		hardirq_ctx[i] = (struct thread_info *)
95f72d1ed   Yinghai Lu   lmb: rename to me...
239
  			__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
85218827c   Kumar Gala   [POWERPC] Add IRQ...
240
241
  	}
  }
85218827c   Kumar Gala   [POWERPC] Add IRQ...
242

bcf0b0880   Kumar Gala   [POWERPC] Move to...
243
244
245
  #if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
  static void __init exc_lvl_early_init(void)
  {
3e7f45ad5   Dave Kleikamp   powerpc/4xx: Inde...
246
  	unsigned int i, hw_cpu;
bcf0b0880   Kumar Gala   [POWERPC] Move to...
247
248
  
  	/* interrupt stacks must be in lowmem, we get that for free on ppc32
95f72d1ed   Yinghai Lu   lmb: rename to me...
249
  	 * as the memblock is limited to lowmem by MEMBLOCK_REAL_LIMIT */
bcf0b0880   Kumar Gala   [POWERPC] Move to...
250
  	for_each_possible_cpu(i) {
3e7f45ad5   Dave Kleikamp   powerpc/4xx: Inde...
251
252
  		hw_cpu = get_hard_smp_processor_id(i);
  		critirq_ctx[hw_cpu] = (struct thread_info *)
95f72d1ed   Yinghai Lu   lmb: rename to me...
253
  			__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
bcf0b0880   Kumar Gala   [POWERPC] Move to...
254
  #ifdef CONFIG_BOOKE
3e7f45ad5   Dave Kleikamp   powerpc/4xx: Inde...
255
  		dbgirq_ctx[hw_cpu] = (struct thread_info *)
95f72d1ed   Yinghai Lu   lmb: rename to me...
256
  			__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
3e7f45ad5   Dave Kleikamp   powerpc/4xx: Inde...
257
  		mcheckirq_ctx[hw_cpu] = (struct thread_info *)
95f72d1ed   Yinghai Lu   lmb: rename to me...
258
  			__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
bcf0b0880   Kumar Gala   [POWERPC] Move to...
259
260
261
262
263
264
  #endif
  	}
  }
  #else
  #define exc_lvl_early_init()
  #endif
9b6b563c0   Paul Mackerras   powerpc: Merge in...
265
266
267
  /* Warning, IO base is not yet inited */
  void __init setup_arch(char **cmdline_p)
  {
846f77b08   Michael Ellerman   [PATCH] powerpc: ...
268
  	*cmdline_p = cmd_line;
9b6b563c0   Paul Mackerras   powerpc: Merge in...
269
270
  	/* so udelay does something sensible, assume <= 1000 bogomips */
  	loops_per_jiffy = 500000000 / HZ;
9b6b563c0   Paul Mackerras   powerpc: Merge in...
271
  	unflatten_device_tree();
a82765b6e   David Woodhouse   [PATCH] powerpc: ...
272
  	check_for_initrd();
463ce0e10   Benjamin Herrenschmidt   [PATCH] powerpc: ...
273
274
275
  
  	if (ppc_md.init_early)
  		ppc_md.init_early();
463ce0e10   Benjamin Herrenschmidt   [PATCH] powerpc: ...
276
  	find_legacy_serial_ports();
9b6b563c0   Paul Mackerras   powerpc: Merge in...
277

5ad570786   Paul Mackerras   powerpc: Merge sm...
278
  	smp_setup_cpu_maps();
51d3082fe   Benjamin Herrenschmidt   [PATCH] powerpc: ...
279
280
  	/* Register early console */
  	register_early_udbg_console();
9b6b563c0   Paul Mackerras   powerpc: Merge in...
281

476792839   Michael Ellerman   [POWERPC] Fix xmo...
282
  	xmon_setup();
9b6b563c0   Paul Mackerras   powerpc: Merge in...
283
284
285
286
287
  	/*
  	 * Set cache line size based on type of cpu as a default.
  	 * Systems with OF can look in the properties on the cpu node(s)
  	 * for a possibly more accurate value.
  	 */
4508dc21f   David Gibson   [POWERPC] Merge C...
288
289
290
291
292
  	dcache_bsize = cur_cpu_spec->dcache_bsize;
  	icache_bsize = cur_cpu_spec->icache_bsize;
  	ucache_bsize = 0;
  	if (cpu_has_feature(CPU_FTR_UNIFIED_ID_CACHE))
  		ucache_bsize = icache_bsize = dcache_bsize;
9b6b563c0   Paul Mackerras   powerpc: Merge in...
293
294
295
  
  	/* reboot on panic */
  	panic_timeout = 180;
7e990266c   Kumar Gala   powerpc: provide ...
296
297
  	if (ppc_md.panic)
  		setup_panic();
4846c5deb   Kumar Gala   [POWERPC] Clean u...
298
  	init_mm.start_code = (unsigned long)_stext;
9b6b563c0   Paul Mackerras   powerpc: Merge in...
299
300
  	init_mm.end_code = (unsigned long) _etext;
  	init_mm.end_data = (unsigned long) _edata;
49b09853d   Paul Mackerras   powerpc: Move som...
301
  	init_mm.brk = klimit;
9b6b563c0   Paul Mackerras   powerpc: Merge in...
302

bcf0b0880   Kumar Gala   [POWERPC] Move to...
303
  	exc_lvl_early_init();
85218827c   Kumar Gala   [POWERPC] Add IRQ...
304
  	irqstack_early_init();
9b6b563c0   Paul Mackerras   powerpc: Merge in...
305
306
307
  	/* set up the bootmem stuff with available memory */
  	do_init_bootmem();
  	if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
9b6b563c0   Paul Mackerras   powerpc: Merge in...
308
309
310
  #ifdef CONFIG_DUMMY_CONSOLE
  	conswitchp = &dummy_con;
  #endif
38db7e740   Grant Likely   [POWERPC] Only ca...
311
312
  	if (ppc_md.setup_arch)
  		ppc_md.setup_arch();
9b6b563c0   Paul Mackerras   powerpc: Merge in...
313
314
315
  	if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
  
  	paging_init();
775203518   Benjamin Herrenschmidt   powerpc/mm: Runti...
316
317
318
  
  	/* Initialize the MMU context management stuff */
  	mmu_context_init();
9b6b563c0   Paul Mackerras   powerpc: Merge in...
319
  }