Blame view

arch/mips/kernel/setup.c 14.2 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
  /*
   * This file is subject to the terms and conditions of the GNU General Public
   * License.  See the file "COPYING" in the main directory of this archive
   * for more details.
   *
   * Copyright (C) 1995 Linus Torvalds
   * Copyright (C) 1995 Waldorf Electronics
   * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 01, 02, 03  Ralf Baechle
   * Copyright (C) 1996 Stoned Elipot
   * Copyright (C) 1999 Silicon Graphics, Inc.
20d60d997   Maciej W. Rozycki   [MIPS] R4000/R440...
11
   * Copyright (C) 2000, 2001, 2002, 2007  Maciej W. Rozycki
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
  #include <linux/init.h>
  #include <linux/ioport.h>
73bc256d4   Paul Gortmaker   mips: migrate cor...
15
  #include <linux/export.h>
894673ee6   Jon Smirl   [PATCH] tty: Remo...
16
  #include <linux/screen_info.h>
9d15ffc82   Tejun Heo   mips: Use HAVE_ME...
17
  #include <linux/memblock.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
  #include <linux/bootmem.h>
  #include <linux/initrd.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
21
22
  #include <linux/root_dev.h>
  #include <linux/highmem.h>
  #include <linux/console.h>
22a9835c3   Dave Hansen   [PATCH] unify PFN...
23
  #include <linux/pfn.h>
6312e0ee4   Atsushi Nemoto   [MIPS] Add some d...
24
  #include <linux/debugfs.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
25
26
27
  
  #include <asm/addrspace.h>
  #include <asm/bootinfo.h>
20d60d997   Maciej W. Rozycki   [MIPS] R4000/R440...
28
  #include <asm/bugs.h>
ec74e361f   Ralf Baechle   Mark a few variab...
29
  #include <asm/cache.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
31
32
  #include <asm/cpu.h>
  #include <asm/sections.h>
  #include <asm/setup.h>
87353d8ac   Ralf Baechle   [MIPS] SMP: Call ...
33
  #include <asm/smp-ops.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
  #include <asm/system.h>
f2ffa5ab7   Dezhong Diao   of/mips: Add devi...
35
  #include <asm/prom.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36

ec74e361f   Ralf Baechle   Mark a few variab...
37
  struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  
  EXPORT_SYMBOL(cpu_data);
  
  #ifdef CONFIG_VT
  struct screen_info screen_info;
  #endif
  
  /*
   * Despite it's name this variable is even if we don't have PCI
   */
  unsigned int PCI_DMA_BUS_IS_PHYS;
  
  EXPORT_SYMBOL(PCI_DMA_BUS_IS_PHYS);
  
  /*
   * Setup information
   *
   * These are initialized so they are in the .data section
   */
ec74e361f   Ralf Baechle   Mark a few variab...
57
  unsigned long mips_machtype __read_mostly = MACH_UNKNOWN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
59
  
  EXPORT_SYMBOL(mips_machtype);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60
61
  
  struct boot_mem_map boot_mem_map;
6acc7d485   Dmitri Vorobiev   MIPS: Fix and enh...
62
63
64
65
66
67
  static char __initdata command_line[COMMAND_LINE_SIZE];
  char __initdata arcs_cmdline[COMMAND_LINE_SIZE];
  
  #ifdef CONFIG_CMDLINE_BOOL
  static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
69
70
71
72
  
  /*
   * mips_io_port_base is the begin of the address space to which x86 style
   * I/O ports are mapped.
   */
1befdd553   David Daney   MIPS: Implement _...
73
  const unsigned long mips_io_port_base = -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
  EXPORT_SYMBOL(mips_io_port_base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
76
77
78
79
80
81
  static struct resource code_resource = { .name = "Kernel code", };
  static struct resource data_resource = { .name = "Kernel data", };
  
  void __init add_memory_region(phys_t start, phys_t size, long type)
  {
  	int x = boot_mem_map.nr_map;
  	struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1;
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
82
83
  	/* Sanity check */
  	if (start + size < start) {
a64ae7a22   Mike Crowe   [MIPS] Convert pr...
84
85
  		pr_warning("Trying to add an invalid memory region, skipped
  ");
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
86
87
  		return;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
89
90
91
92
93
94
95
96
97
  	/*
  	 * Try to merge with previous entry if any.  This is far less than
  	 * perfect but is sufficient for most real world cases.
  	 */
  	if (x && prev->addr + prev->size == start && prev->type == type) {
  		prev->size += size;
  		return;
  	}
  
  	if (x == BOOT_MEM_MAP_MAX) {
a64ae7a22   Mike Crowe   [MIPS] Convert pr...
98
99
  		pr_err("Ooops! Too many entries in the memory map!
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
  		return;
  	}
  
  	boot_mem_map.map[x].addr = start;
  	boot_mem_map.map[x].size = size;
  	boot_mem_map.map[x].type = type;
  	boot_mem_map.nr_map++;
  }
  
  static void __init print_memory_map(void)
  {
  	int i;
  	const int field = 2 * sizeof(unsigned long);
  
  	for (i = 0; i < boot_mem_map.nr_map; i++) {
a64ae7a22   Mike Crowe   [MIPS] Convert pr...
115
  		printk(KERN_INFO " memory: %0*Lx @ %0*Lx ",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
117
118
119
120
  		       field, (unsigned long long) boot_mem_map.map[i].size,
  		       field, (unsigned long long) boot_mem_map.map[i].addr);
  
  		switch (boot_mem_map.map[i].type) {
  		case BOOT_MEM_RAM:
a64ae7a22   Mike Crowe   [MIPS] Convert pr...
121
122
  			printk(KERN_CONT "(usable)
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
123
  			break;
43064c0c8   David Daney   MIPS: Handle init...
124
125
126
127
  		case BOOT_MEM_INIT_RAM:
  			printk(KERN_CONT "(usable after init)
  ");
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
  		case BOOT_MEM_ROM_DATA:
a64ae7a22   Mike Crowe   [MIPS] Convert pr...
129
130
  			printk(KERN_CONT "(ROM data)
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
132
  			break;
  		case BOOT_MEM_RESERVED:
a64ae7a22   Mike Crowe   [MIPS] Convert pr...
133
134
  			printk(KERN_CONT "(reserved)
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
135
136
  			break;
  		default:
a64ae7a22   Mike Crowe   [MIPS] Convert pr...
137
138
  			printk(KERN_CONT "type %lu
  ", boot_mem_map.map[i].type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
140
141
142
  			break;
  		}
  	}
  }
d2043ca84   Franck Bui-Huu   [MIPS] setup.c: m...
143
144
145
146
  /*
   * Manage initrd
   */
  #ifdef CONFIG_BLK_DEV_INITRD
a09fc446f   Franck Bui-Huu   [MIPS] setup.c: u...
147
  static int __init rd_start_early(char *p)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
  {
a09fc446f   Franck Bui-Huu   [MIPS] setup.c: u...
149
  	unsigned long start = memparse(p, &p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
150

875d43e72   Ralf Baechle   [PATCH] mips: cle...
151
  #ifdef CONFIG_64BIT
a7837b76b   Franck Bui-Huu   [MIPS] setup.c: c...
152
153
154
  	/* Guess if the sign extension was forgotten by bootloader */
  	if (start < XKPHYS)
  		start = (int)start;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
155
  #endif
a09fc446f   Franck Bui-Huu   [MIPS] setup.c: u...
156
157
  	initrd_start = start;
  	initrd_end += start;
a09fc446f   Franck Bui-Huu   [MIPS] setup.c: u...
158
159
160
161
162
163
164
  	return 0;
  }
  early_param("rd_start", rd_start_early);
  
  static int __init rd_size_early(char *p)
  {
  	initrd_end += memparse(p, &p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165
166
  	return 0;
  }
a09fc446f   Franck Bui-Huu   [MIPS] setup.c: u...
167
  early_param("rd_size", rd_size_early);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168

a7837b76b   Franck Bui-Huu   [MIPS] setup.c: c...
169
  /* it returns the next free pfn after initrd */
d2043ca84   Franck Bui-Huu   [MIPS] setup.c: m...
170
171
  static unsigned long __init init_initrd(void)
  {
a7837b76b   Franck Bui-Huu   [MIPS] setup.c: c...
172
  	unsigned long end;
d2043ca84   Franck Bui-Huu   [MIPS] setup.c: m...
173

d2043ca84   Franck Bui-Huu   [MIPS] setup.c: m...
174
  	/*
a09fc446f   Franck Bui-Huu   [MIPS] setup.c: u...
175
176
177
  	 * Board specific code or command line parser should have
  	 * already set up initrd_start and initrd_end. In these cases
  	 * perfom sanity checks and use them if all looks good.
d2043ca84   Franck Bui-Huu   [MIPS] setup.c: m...
178
  	 */
32028f1f7   Ralf Baechle   MIPS: Remove addi...
179
  	if (!initrd_start || initrd_end <= initrd_start)
a7837b76b   Franck Bui-Huu   [MIPS] setup.c: c...
180
  		goto disable;
a7837b76b   Franck Bui-Huu   [MIPS] setup.c: c...
181

a7837b76b   Franck Bui-Huu   [MIPS] setup.c: c...
182
  	if (initrd_start & ~PAGE_MASK) {
a64ae7a22   Mike Crowe   [MIPS] Convert pr...
183
184
  		pr_err("initrd start must be page aligned
  ");
a7837b76b   Franck Bui-Huu   [MIPS] setup.c: c...
185
  		goto disable;
d2043ca84   Franck Bui-Huu   [MIPS] setup.c: m...
186
  	}
a7837b76b   Franck Bui-Huu   [MIPS] setup.c: c...
187
  	if (initrd_start < PAGE_OFFSET) {
a64ae7a22   Mike Crowe   [MIPS] Convert pr...
188
189
  		pr_err("initrd start < PAGE_OFFSET
  ");
a7837b76b   Franck Bui-Huu   [MIPS] setup.c: c...
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
  		goto disable;
  	}
  
  	/*
  	 * Sanitize initrd addresses. For example firmware
  	 * can't guess if they need to pass them through
  	 * 64-bits values if the kernel has been built in pure
  	 * 32-bit. We need also to switch from KSEG0 to XKPHYS
  	 * addresses now, so the code can now safely use __pa().
  	 */
  	end = __pa(initrd_end);
  	initrd_end = (unsigned long)__va(end);
  	initrd_start = (unsigned long)__va(__pa(initrd_start));
  
  	ROOT_DEV = Root_RAM0;
  	return PFN_UP(end);
  disable:
  	initrd_start = 0;
  	initrd_end = 0;
  	return 0;
d2043ca84   Franck Bui-Huu   [MIPS] setup.c: m...
210
211
212
213
214
215
216
217
218
219
  }
  
  static void __init finalize_initrd(void)
  {
  	unsigned long size = initrd_end - initrd_start;
  
  	if (size == 0) {
  		printk(KERN_INFO "Initrd not found or empty");
  		goto disable;
  	}
d4df6d4e7   Franck Bui-Huu   [MIPS] setup.c: g...
220
  	if (__pa(initrd_end) > PFN_PHYS(max_low_pfn)) {
a64ae7a22   Mike Crowe   [MIPS] Convert pr...
221
  		printk(KERN_ERR "Initrd extends beyond end of memory");
d2043ca84   Franck Bui-Huu   [MIPS] setup.c: m...
222
223
  		goto disable;
  	}
72a7fe396   Bernhard Walle   Introduce flags f...
224
  	reserve_bootmem(__pa(initrd_start), size, BOOTMEM_DEFAULT);
d2043ca84   Franck Bui-Huu   [MIPS] setup.c: m...
225
  	initrd_below_start_ok = 1;
a64ae7a22   Mike Crowe   [MIPS] Convert pr...
226
227
228
  	pr_info("Initial ramdisk at: 0x%lx (%lu bytes)
  ",
  		initrd_start, size);
d2043ca84   Franck Bui-Huu   [MIPS] setup.c: m...
229
230
  	return;
  disable:
a64ae7a22   Mike Crowe   [MIPS] Convert pr...
231
232
  	printk(KERN_CONT " - disabling initrd
  ");
d2043ca84   Franck Bui-Huu   [MIPS] setup.c: m...
233
234
235
236
237
  	initrd_start = 0;
  	initrd_end = 0;
  }
  
  #else  /* !CONFIG_BLK_DEV_INITRD */
9ba126cfb   Ralf Baechle   [MIPS] Fix warnin...
238
239
240
241
  static unsigned long __init init_initrd(void)
  {
  	return 0;
  }
d2043ca84   Franck Bui-Huu   [MIPS] setup.c: m...
242
243
244
  #define finalize_initrd()	do {} while (0)
  
  #endif
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
245
246
247
248
  /*
   * Initialize the bootmem allocator. It also setup initrd related data
   * if needed.
   */
d2043ca84   Franck Bui-Huu   [MIPS] setup.c: m...
249
  #ifdef CONFIG_SGI_IP27
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
250
  static void __init bootmem_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
251
  {
d2043ca84   Franck Bui-Huu   [MIPS] setup.c: m...
252
253
254
255
256
257
258
259
  	init_initrd();
  	finalize_initrd();
  }
  
  #else  /* !CONFIG_SGI_IP27 */
  
  static void __init bootmem_init(void)
  {
e452e94e2   Atsushi Nemoto   [MIPS] Replace 40...
260
  	unsigned long reserved_end;
db84dc615   Franck Bui-Huu   [MIPS] Setup min_...
261
  	unsigned long mapstart = ~0UL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
263
  	unsigned long bootmap_size;
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
264
265
  
  	/*
d2043ca84   Franck Bui-Huu   [MIPS] setup.c: m...
266
267
268
  	 * Init any data related to initrd. It's a nop if INITRD is
  	 * not selected. Once that done we can determine the low bound
  	 * of usable memory.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269
  	 */
12e22e8e6   Ralf Baechle   MIPS: Stop using ...
270
271
  	reserved_end = max(init_initrd(),
  			   (unsigned long) PFN_UP(__pa_symbol(&_end)));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272

b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
273
  	/*
db84dc615   Franck Bui-Huu   [MIPS] Setup min_...
274
275
276
277
278
279
280
  	 * max_low_pfn is not a number of pages. The number of pages
  	 * of the system is given by 'max_low_pfn - min_low_pfn'.
  	 */
  	min_low_pfn = ~0UL;
  	max_low_pfn = 0;
  
  	/*
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
281
282
  	 * Find the highest page frame number we have available.
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
283
284
285
286
287
288
289
290
  	for (i = 0; i < boot_mem_map.nr_map; i++) {
  		unsigned long start, end;
  
  		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
  			continue;
  
  		start = PFN_UP(boot_mem_map.map[i].addr);
  		end = PFN_DOWN(boot_mem_map.map[i].addr
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
291
  				+ boot_mem_map.map[i].size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292

db84dc615   Franck Bui-Huu   [MIPS] Setup min_...
293
294
295
296
  		if (end > max_low_pfn)
  			max_low_pfn = end;
  		if (start < min_low_pfn)
  			min_low_pfn = start;
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
297
  		if (end <= reserved_end)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298
  			continue;
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
299
300
301
  		if (start >= mapstart)
  			continue;
  		mapstart = max(reserved_end, start);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
  	}
db84dc615   Franck Bui-Huu   [MIPS] Setup min_...
303
304
  	if (min_low_pfn >= max_low_pfn)
  		panic("Incorrect memory mapping !!!");
6f284a2ce   Franck Bui-Huu   [MIPS] FLATMEM: i...
305
  	if (min_low_pfn > ARCH_PFN_OFFSET) {
a64ae7a22   Mike Crowe   [MIPS] Convert pr...
306
307
308
309
  		pr_info("Wasting %lu bytes for tracking %lu unused pages
  ",
  			(min_low_pfn - ARCH_PFN_OFFSET) * sizeof(struct page),
  			min_low_pfn - ARCH_PFN_OFFSET);
6f284a2ce   Franck Bui-Huu   [MIPS] FLATMEM: i...
310
  	} else if (min_low_pfn < ARCH_PFN_OFFSET) {
a64ae7a22   Mike Crowe   [MIPS] Convert pr...
311
312
313
  		pr_info("%lu free pages won't be used
  ",
  			ARCH_PFN_OFFSET - min_low_pfn);
db84dc615   Franck Bui-Huu   [MIPS] Setup min_...
314
  	}
6f284a2ce   Franck Bui-Huu   [MIPS] FLATMEM: i...
315
  	min_low_pfn = ARCH_PFN_OFFSET;
db84dc615   Franck Bui-Huu   [MIPS] Setup min_...
316

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317
318
319
  	/*
  	 * Determine low and high memory ranges
  	 */
dc3bf3532   Ralf Baechle   [MIPS] Initialize...
320
  	max_pfn = max_low_pfn;
db84dc615   Franck Bui-Huu   [MIPS] Setup min_...
321
  	if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) {
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
322
323
  #ifdef CONFIG_HIGHMEM
  		highstart_pfn = PFN_DOWN(HIGHMEM_START);
db84dc615   Franck Bui-Huu   [MIPS] Setup min_...
324
  		highend_pfn = max_low_pfn;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
325
  #endif
db84dc615   Franck Bui-Huu   [MIPS] Setup min_...
326
  		max_low_pfn = PFN_DOWN(HIGHMEM_START);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
327
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328
  	/*
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
329
  	 * Initialize the boot-time allocator with low memory only.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
330
  	 */
db84dc615   Franck Bui-Huu   [MIPS] Setup min_...
331
332
  	bootmap_size = init_bootmem_node(NODE_DATA(0), mapstart,
  					 min_low_pfn, max_low_pfn);
cce335ae4   Ralf Baechle   [MIPS] 64-bit Sib...
333

cce335ae4   Ralf Baechle   [MIPS] 64-bit Sib...
334
335
336
337
338
339
  	for (i = 0; i < boot_mem_map.nr_map; i++) {
  		unsigned long start, end;
  
  		start = PFN_UP(boot_mem_map.map[i].addr);
  		end = PFN_DOWN(boot_mem_map.map[i].addr
  				+ boot_mem_map.map[i].size);
e452e94e2   Atsushi Nemoto   [MIPS] Replace 40...
340
341
  		if (start <= min_low_pfn)
  			start = min_low_pfn;
cce335ae4   Ralf Baechle   [MIPS] 64-bit Sib...
342
343
344
345
346
347
348
349
350
351
352
353
354
  		if (start >= end)
  			continue;
  
  #ifndef CONFIG_HIGHMEM
  		if (end > max_low_pfn)
  			end = max_low_pfn;
  
  		/*
  		 * ... finally, is the area going away?
  		 */
  		if (end <= start)
  			continue;
  #endif
9d15ffc82   Tejun Heo   mips: Use HAVE_ME...
355
  		memblock_add_node(PFN_PHYS(start), PFN_PHYS(end - start), 0);
cce335ae4   Ralf Baechle   [MIPS] 64-bit Sib...
356
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
357
358
359
360
  	/*
  	 * Register fully available low RAM pages with the bootmem allocator.
  	 */
  	for (i = 0; i < boot_mem_map.nr_map; i++) {
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
361
  		unsigned long start, end, size;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362

43064c0c8   David Daney   MIPS: Handle init...
363
364
365
  		start = PFN_UP(boot_mem_map.map[i].addr);
  		end   = PFN_DOWN(boot_mem_map.map[i].addr
  				    + boot_mem_map.map[i].size);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
366
367
368
  		/*
  		 * Reserve usable memory.
  		 */
43064c0c8   David Daney   MIPS: Handle init...
369
370
371
372
373
  		switch (boot_mem_map.map[i].type) {
  		case BOOT_MEM_RAM:
  			break;
  		case BOOT_MEM_INIT_RAM:
  			memory_present(0, start, end);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
374
  			continue;
43064c0c8   David Daney   MIPS: Handle init...
375
376
377
378
  		default:
  			/* Not usable memory */
  			continue;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
379

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
380
  		/*
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
381
382
  		 * We are rounding up the start address of usable memory
  		 * and at the end of the usable range downwards.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
  		 */
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
384
  		if (start >= max_low_pfn)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
385
  			continue;
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
386
387
388
389
  		if (start < reserved_end)
  			start = reserved_end;
  		if (end > max_low_pfn)
  			end = max_low_pfn;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
391
  
  		/*
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
392
  		 * ... finally, is the area going away?
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393
  		 */
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
394
  		if (end <= start)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
  			continue;
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
396
  		size = end - start;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
398
  
  		/* Register lowmem ranges */
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
399
400
  		free_bootmem(PFN_PHYS(start), size << PAGE_SHIFT);
  		memory_present(0, start, end);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
  	}
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
402
403
404
  	/*
  	 * Reserve the bootmap memory.
  	 */
72a7fe396   Bernhard Walle   Introduce flags f...
405
  	reserve_bootmem(PFN_PHYS(mapstart), bootmap_size, BOOTMEM_DEFAULT);
b6f1f0dea   Franck Bui-Huu   [MIPS] setup.c: c...
406

d2043ca84   Franck Bui-Huu   [MIPS] setup.c: m...
407
408
409
410
  	/*
  	 * Reserve initrd memory if needed.
  	 */
  	finalize_initrd();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
411
  }
d2043ca84   Franck Bui-Huu   [MIPS] setup.c: m...
412
  #endif	/* CONFIG_SGI_IP27 */
2925aba42   Ralf Baechle   [MIPS] Cleanup me...
413
  /*
603e82edf   Joe Perches   arch/mips/: Spell...
414
   * arch_mem_init - initialize memory management subsystem
2925aba42   Ralf Baechle   [MIPS] Cleanup me...
415
416
417
   *
   *  o plat_mem_setup() detects the memory configuration and will record detected
   *    memory areas using add_memory_region.
2925aba42   Ralf Baechle   [MIPS] Cleanup me...
418
419
   *
   * At this stage the memory configuration of the system is known to the
603e82edf   Joe Perches   arch/mips/: Spell...
420
   * kernel but generic memory management system is still entirely uninitialized.
2925aba42   Ralf Baechle   [MIPS] Cleanup me...
421
422
423
424
425
426
427
428
429
430
431
432
433
   *
   *  o bootmem_init()
   *  o sparse_init()
   *  o paging_init()
   *
   * At this stage the bootmem allocator is ready to use.
   *
   * NOTE: historically plat_mem_setup did the entire platform initialization.
   *       This was rather impractical because it meant plat_mem_setup had to
   * get away without any kind of memory allocator.  To keep old code from
   * breaking plat_setup was just renamed to plat_setup and a second platform
   * initialization hook for anything else was introduced.
   */
982f6ffee   Ralf Baechle   MIPS: Remove usel...
434
  static int usermem __initdata;
a09fc446f   Franck Bui-Huu   [MIPS] setup.c: u...
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
  
  static int __init early_parse_mem(char *p)
  {
  	unsigned long start, size;
  
  	/*
  	 * If a user specifies memory size, we
  	 * blow away any automatically generated
  	 * size.
  	 */
  	if (usermem == 0) {
  		boot_mem_map.nr_map = 0;
  		usermem = 1;
   	}
  	start = 0;
  	size = memparse(p, &p);
  	if (*p == '@')
  		start = memparse(p + 1, &p);
  
  	add_memory_region(start, size, BOOT_MEM_RAM);
  	return 0;
  }
  early_param("mem", early_parse_mem);
2925aba42   Ralf Baechle   [MIPS] Cleanup me...
458
459
460
  
  static void __init arch_mem_init(char **cmdline_p)
  {
43064c0c8   David Daney   MIPS: Handle init...
461
  	phys_t init_mem, init_end, init_size;
a09fc446f   Franck Bui-Huu   [MIPS] setup.c: u...
462
  	extern void plat_mem_setup(void);
2925aba42   Ralf Baechle   [MIPS] Cleanup me...
463
464
  	/* call board setup routine */
  	plat_mem_setup();
43064c0c8   David Daney   MIPS: Handle init...
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
  	init_mem = PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT;
  	init_end = PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT;
  	init_size = init_end - init_mem;
  	if (init_size) {
  		/* Make sure it is in the boot_mem_map */
  		int i, found;
  		found = 0;
  		for (i = 0; i < boot_mem_map.nr_map; i++) {
  			if (init_mem >= boot_mem_map.map[i].addr &&
  			    init_mem < (boot_mem_map.map[i].addr +
  					boot_mem_map.map[i].size)) {
  				found = 1;
  				break;
  			}
  		}
  		if (!found)
  			add_memory_region(init_mem, init_size,
  					  BOOT_MEM_INIT_RAM);
  	}
a64ae7a22   Mike Crowe   [MIPS] Convert pr...
484
485
  	pr_info("Determined physical RAM map:
  ");
a09fc446f   Franck Bui-Huu   [MIPS] setup.c: u...
486
  	print_memory_map();
6acc7d485   Dmitri Vorobiev   MIPS: Fix and enh...
487
488
489
490
491
492
493
494
495
496
497
498
499
500
  #ifdef CONFIG_CMDLINE_BOOL
  #ifdef CONFIG_CMDLINE_OVERRIDE
  	strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
  #else
  	if (builtin_cmdline[0]) {
  		strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
  		strlcat(arcs_cmdline, builtin_cmdline, COMMAND_LINE_SIZE);
  	}
  	strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
  #endif
  #else
  	strlcpy(boot_command_line, arcs_cmdline, COMMAND_LINE_SIZE);
  #endif
  	strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
2925aba42   Ralf Baechle   [MIPS] Cleanup me...
501
502
  
  	*cmdline_p = command_line;
a09fc446f   Franck Bui-Huu   [MIPS] setup.c: u...
503
504
505
  	parse_early_param();
  
  	if (usermem) {
a64ae7a22   Mike Crowe   [MIPS] Convert pr...
506
507
  		pr_info("User-defined physical RAM map:
  ");
a09fc446f   Franck Bui-Huu   [MIPS] setup.c: u...
508
509
  		print_memory_map();
  	}
2925aba42   Ralf Baechle   [MIPS] Cleanup me...
510
  	bootmem_init();
f2ffa5ab7   Dezhong Diao   of/mips: Add devi...
511
  	device_tree_init();
2925aba42   Ralf Baechle   [MIPS] Cleanup me...
512
  	sparse_init();
ee71b7d2f   David Daney   MIPS: Add a platf...
513
  	plat_swiotlb_setup();
2925aba42   Ralf Baechle   [MIPS] Cleanup me...
514
515
  	paging_init();
  }
8df32c636   Franck Bui-Huu   [MIPS] setup.c: d...
516
  static void __init resource_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
517
518
  {
  	int i;
6adb5fe70   Ralf Baechle   [MIPS] Only regis...
519
520
  	if (UNCAC_BASE != IO_BASE)
  		return;
f5bffe3a9   Franck Bui-Huu   [MIPS] setup.c: u...
521
522
523
524
  	code_resource.start = __pa_symbol(&_text);
  	code_resource.end = __pa_symbol(&_etext) - 1;
  	data_resource.start = __pa_symbol(&_etext);
  	data_resource.end = __pa_symbol(&_edata) - 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
525
526
527
528
529
530
531
532
533
534
  
  	/*
  	 * Request address space for all standard RAM.
  	 */
  	for (i = 0; i < boot_mem_map.nr_map; i++) {
  		struct resource *res;
  		unsigned long start, end;
  
  		start = boot_mem_map.map[i].addr;
  		end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1;
1c6fd44d7   Franck Bui-Huu   [MIPS] setup.c: r...
535
  		if (start >= HIGHMEM_START)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
536
  			continue;
1c6fd44d7   Franck Bui-Huu   [MIPS] setup.c: r...
537
538
  		if (end >= HIGHMEM_START)
  			end = HIGHMEM_START - 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
539
540
541
542
  
  		res = alloc_bootmem(sizeof(struct resource));
  		switch (boot_mem_map.map[i].type) {
  		case BOOT_MEM_RAM:
43064c0c8   David Daney   MIPS: Handle init...
543
  		case BOOT_MEM_INIT_RAM:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
  		case BOOT_MEM_ROM_DATA:
  			res->name = "System RAM";
  			break;
  		case BOOT_MEM_RESERVED:
  		default:
  			res->name = "reserved";
  		}
  
  		res->start = start;
  		res->end = end;
  
  		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
  		request_resource(&iomem_resource, res);
  
  		/*
  		 *  We don't know which RAM region contains kernel data,
  		 *  so we try it repeatedly and let the resource manager
  		 *  test it.
  		 */
  		request_resource(res, &code_resource);
  		request_resource(res, &data_resource);
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
567
568
569
570
  void __init setup_arch(char **cmdline_p)
  {
  	cpu_probe();
  	prom_init();
36a885306   Ralf Baechle   [MIPS] Fix and cl...
571
572
  
  #ifdef CONFIG_EARLY_PRINTK
07cdb7843   Dmitri Vorobiev   [MIPS] fix sparse...
573
  	setup_early_printk();
36a885306   Ralf Baechle   [MIPS] Fix and cl...
574
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
575
  	cpu_report();
20d60d997   Maciej W. Rozycki   [MIPS] R4000/R440...
576
  	check_bugs_early();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
577
578
579
  
  #if defined(CONFIG_VT)
  #if defined(CONFIG_VGA_CONSOLE)
e0daad449   Ralf Baechle   [MIPS] Whitespace...
580
  	conswitchp = &vga_con;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
581
  #elif defined(CONFIG_DUMMY_CONSOLE)
e0daad449   Ralf Baechle   [MIPS] Whitespace...
582
  	conswitchp = &dummy_con;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
583
584
  #endif
  #endif
2925aba42   Ralf Baechle   [MIPS] Cleanup me...
585
  	arch_mem_init(cmdline_p);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
586

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
587
  	resource_init();
9b6695a8a   Ralf Baechle   [MIPS] SMP: Fix i...
588
  	plat_smp_setup();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
589
  }
69a6c312e   Atsushi Nemoto   [MIPS] Move some ...
590
591
  unsigned long kernelsp[NR_CPUS];
  unsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3;
6312e0ee4   Atsushi Nemoto   [MIPS] Add some d...
592
593
594
595
596
597
598
599
  
  #ifdef CONFIG_DEBUG_FS
  struct dentry *mips_debugfs_dir;
  static int __init debugfs_mips(void)
  {
  	struct dentry *d;
  
  	d = debugfs_create_dir("mips", NULL);
b517531ce   Zhaolei   MIPS: Fix debugfs...
600
601
  	if (!d)
  		return -ENOMEM;
6312e0ee4   Atsushi Nemoto   [MIPS] Add some d...
602
603
604
605
606
  	mips_debugfs_dir = d;
  	return 0;
  }
  arch_initcall(debugfs_mips);
  #endif