aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/setup.c')
-rw-r--r--arch/sh/kernel/setup.c267
1 files changed, 104 insertions, 163 deletions
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 98802ab28211..477d2a854fc4 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -4,7 +4,7 @@
4 * This file handles the architecture-dependent parts of initialization 4 * This file handles the architecture-dependent parts of initialization
5 * 5 *
6 * Copyright (C) 1999 Niibe Yutaka 6 * Copyright (C) 1999 Niibe Yutaka
7 * Copyright (C) 2002 - 2006 Paul Mundt 7 * Copyright (C) 2002 - 2007 Paul Mundt
8 */ 8 */
9#include <linux/screen_info.h> 9#include <linux/screen_info.h>
10#include <linux/ioport.h> 10#include <linux/ioport.h>
@@ -15,21 +15,22 @@
15#include <linux/seq_file.h> 15#include <linux/seq_file.h>
16#include <linux/root_dev.h> 16#include <linux/root_dev.h>
17#include <linux/utsname.h> 17#include <linux/utsname.h>
18#include <linux/nodemask.h>
18#include <linux/cpu.h> 19#include <linux/cpu.h>
19#include <linux/pfn.h> 20#include <linux/pfn.h>
20#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/mm.h>
23#include <linux/kexec.h>
21#include <asm/uaccess.h> 24#include <asm/uaccess.h>
22#include <asm/io.h> 25#include <asm/io.h>
23#include <asm/sections.h> 26#include <asm/sections.h>
24#include <asm/irq.h> 27#include <asm/irq.h>
25#include <asm/setup.h> 28#include <asm/setup.h>
26#include <asm/clock.h> 29#include <asm/clock.h>
30#include <asm/mmu_context.h>
27 31
28#ifdef CONFIG_SH_KGDB
29#include <asm/kgdb.h>
30static int kgdb_parse_options(char *options);
31#endif
32extern void * __rd_start, * __rd_end; 32extern void * __rd_start, * __rd_end;
33
33/* 34/*
34 * Machine setup.. 35 * Machine setup..
35 */ 36 */
@@ -205,53 +206,33 @@ static int __init sh_mv_setup(char **cmdline_p)
205 return 0; 206 return 0;
206} 207}
207 208
208void __init setup_arch(char **cmdline_p) 209/*
210 * Register fully available low RAM pages with the bootmem allocator.
211 */
212static void __init register_bootmem_low_pages(void)
209{ 213{
210 unsigned long bootmap_size; 214 unsigned long curr_pfn, last_pfn, pages;
211 unsigned long start_pfn, max_pfn, max_low_pfn;
212
213#ifdef CONFIG_CMDLINE_BOOL
214 strcpy(COMMAND_LINE, CONFIG_CMDLINE);
215#endif
216
217 ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
218
219#ifdef CONFIG_BLK_DEV_RAM
220 rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
221 rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
222 rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
223#endif
224
225 if (!MOUNT_ROOT_RDONLY)
226 root_mountflags &= ~MS_RDONLY;
227 init_mm.start_code = (unsigned long) _text;
228 init_mm.end_code = (unsigned long) _etext;
229 init_mm.end_data = (unsigned long) _edata;
230 init_mm.brk = (unsigned long) _end;
231
232 code_resource.start = (unsigned long)virt_to_phys(_text);
233 code_resource.end = (unsigned long)virt_to_phys(_etext)-1;
234 data_resource.start = (unsigned long)virt_to_phys(_etext);
235 data_resource.end = (unsigned long)virt_to_phys(_edata)-1;
236
237 sh_mv_setup(cmdline_p);
238
239 215
240 /* 216 /*
241 * Find the highest page frame number we have available 217 * We are rounding up the start address of usable memory:
242 */ 218 */
243 max_pfn = PFN_DOWN(__pa(memory_end)); 219 curr_pfn = PFN_UP(__MEMORY_START);
244 220
245 /* 221 /*
246 * Determine low and high memory ranges: 222 * ... and at the end of the usable range downwards:
247 */ 223 */
248 max_low_pfn = max_pfn; 224 last_pfn = PFN_DOWN(__pa(memory_end));
249 225
250 /* 226 if (last_pfn > max_low_pfn)
251 * Partially used pages are not usable - thus 227 last_pfn = max_low_pfn;
252 * we are rounding upwards: 228
253 */ 229 pages = last_pfn - curr_pfn;
254 start_pfn = PFN_UP(__pa(_end)); 230 free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages));
231}
232
233void __init setup_bootmem_allocator(unsigned long start_pfn)
234{
235 unsigned long bootmap_size;
255 236
256 /* 237 /*
257 * Find a proper area for the bootmem bitmap. After this 238 * Find a proper area for the bootmem bitmap. After this
@@ -259,31 +240,11 @@ void __init setup_arch(char **cmdline_p)
259 * is intact) must be done via bootmem_alloc(). 240 * is intact) must be done via bootmem_alloc().
260 */ 241 */
261 bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn, 242 bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
262 __MEMORY_START>>PAGE_SHIFT, 243 min_low_pfn, max_low_pfn);
263 max_low_pfn);
264 /*
265 * Register fully available low RAM pages with the bootmem allocator.
266 */
267 {
268 unsigned long curr_pfn, last_pfn, pages;
269
270 /*
271 * We are rounding up the start address of usable memory:
272 */
273 curr_pfn = PFN_UP(__MEMORY_START);
274 /*
275 * ... and at the end of the usable range downwards:
276 */
277 last_pfn = PFN_DOWN(__pa(memory_end));
278 244
279 if (last_pfn > max_low_pfn) 245 register_bootmem_low_pages();
280 last_pfn = max_low_pfn;
281
282 pages = last_pfn - curr_pfn;
283 free_bootmem_node(NODE_DATA(0), PFN_PHYS(curr_pfn),
284 PFN_PHYS(pages));
285 }
286 246
247 node_set_online(0);
287 248
288 /* 249 /*
289 * Reserve the kernel text and 250 * Reserve the kernel text and
@@ -292,14 +253,14 @@ void __init setup_arch(char **cmdline_p)
292 * case of us accidentally initializing the bootmem allocator with 253 * case of us accidentally initializing the bootmem allocator with
293 * an invalid RAM area. 254 * an invalid RAM area.
294 */ 255 */
295 reserve_bootmem_node(NODE_DATA(0), __MEMORY_START+PAGE_SIZE, 256 reserve_bootmem(__MEMORY_START+PAGE_SIZE,
296 (PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START); 257 (PFN_PHYS(start_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START);
297 258
298 /* 259 /*
299 * reserve physical page 0 - it's a special BIOS page on many boxes, 260 * reserve physical page 0 - it's a special BIOS page on many boxes,
300 * enabling clean reboots, SMP operation, laptop functions. 261 * enabling clean reboots, SMP operation, laptop functions.
301 */ 262 */
302 reserve_bootmem_node(NODE_DATA(0), __MEMORY_START, PAGE_SIZE); 263 reserve_bootmem(__MEMORY_START, PAGE_SIZE);
303 264
304#ifdef CONFIG_BLK_DEV_INITRD 265#ifdef CONFIG_BLK_DEV_INITRD
305 ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); 266 ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
@@ -313,8 +274,8 @@ void __init setup_arch(char **cmdline_p)
313 274
314 if (LOADER_TYPE && INITRD_START) { 275 if (LOADER_TYPE && INITRD_START) {
315 if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { 276 if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
316 reserve_bootmem_node(NODE_DATA(0), INITRD_START + 277 reserve_bootmem(INITRD_START + __MEMORY_START,
317 __MEMORY_START, INITRD_SIZE); 278 INITRD_SIZE);
318 initrd_start = INITRD_START + PAGE_OFFSET + 279 initrd_start = INITRD_START + PAGE_OFFSET +
319 __MEMORY_START; 280 __MEMORY_START;
320 initrd_end = initrd_start + INITRD_SIZE; 281 initrd_end = initrd_start + INITRD_SIZE;
@@ -327,6 +288,76 @@ void __init setup_arch(char **cmdline_p)
327 } 288 }
328 } 289 }
329#endif 290#endif
291#ifdef CONFIG_KEXEC
292 if (crashk_res.start != crashk_res.end)
293 reserve_bootmem(crashk_res.start,
294 crashk_res.end - crashk_res.start + 1);
295#endif
296}
297
298#ifndef CONFIG_NEED_MULTIPLE_NODES
299static void __init setup_memory(void)
300{
301 unsigned long start_pfn;
302
303 /*
304 * Partially used pages are not usable - thus
305 * we are rounding upwards:
306 */
307 start_pfn = PFN_UP(__pa(_end));
308 setup_bootmem_allocator(start_pfn);
309}
310#else
311extern void __init setup_memory(void);
312#endif
313
314void __init setup_arch(char **cmdline_p)
315{
316 enable_mmu();
317
318#ifdef CONFIG_CMDLINE_BOOL
319 strcpy(COMMAND_LINE, CONFIG_CMDLINE);
320#endif
321
322 ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
323
324#ifdef CONFIG_BLK_DEV_RAM
325 rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
326 rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
327 rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
328#endif
329
330 if (!MOUNT_ROOT_RDONLY)
331 root_mountflags &= ~MS_RDONLY;
332 init_mm.start_code = (unsigned long) _text;
333 init_mm.end_code = (unsigned long) _etext;
334 init_mm.end_data = (unsigned long) _edata;
335 init_mm.brk = (unsigned long) _end;
336
337 code_resource.start = virt_to_phys(_text);
338 code_resource.end = virt_to_phys(_etext)-1;
339 data_resource.start = virt_to_phys(_etext);
340 data_resource.end = virt_to_phys(_edata)-1;
341
342 parse_early_param();
343
344 sh_mv_setup(cmdline_p);
345
346 /*
347 * Find the highest page frame number we have available
348 */
349 max_pfn = PFN_DOWN(__pa(memory_end));
350
351 /*
352 * Determine low and high memory ranges:
353 */
354 max_low_pfn = max_pfn;
355 min_low_pfn = __MEMORY_START >> PAGE_SHIFT;
356
357 nodes_clear(node_online_map);
358 setup_memory();
359 paging_init();
360 sparse_init();
330 361
331#ifdef CONFIG_DUMMY_CONSOLE 362#ifdef CONFIG_DUMMY_CONSOLE
332 conswitchp = &dummy_con; 363 conswitchp = &dummy_con;
@@ -335,8 +366,6 @@ void __init setup_arch(char **cmdline_p)
335 /* Perform the machine specific initialisation */ 366 /* Perform the machine specific initialisation */
336 if (likely(sh_mv.mv_setup)) 367 if (likely(sh_mv.mv_setup))
337 sh_mv.mv_setup(cmdline_p); 368 sh_mv.mv_setup(cmdline_p);
338
339 paging_init();
340} 369}
341 370
342struct sh_machine_vector* __init get_mv_byname(const char* name) 371struct sh_machine_vector* __init get_mv_byname(const char* name)
@@ -380,6 +409,7 @@ static const char *cpu_name[] = {
380 [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706", 409 [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706",
381 [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708", 410 [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708",
382 [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710", 411 [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710",
412 [CPU_SH7712] = "SH7712",
383 [CPU_SH7729] = "SH7729", [CPU_SH7750] = "SH7750", 413 [CPU_SH7729] = "SH7729", [CPU_SH7750] = "SH7750",
384 [CPU_SH7750S] = "SH7750S", [CPU_SH7750R] = "SH7750R", 414 [CPU_SH7750S] = "SH7750S", [CPU_SH7750R] = "SH7750R",
385 [CPU_SH7751] = "SH7751", [CPU_SH7751R] = "SH7751R", 415 [CPU_SH7751] = "SH7751", [CPU_SH7751R] = "SH7751R",
@@ -477,7 +507,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
477 c->loops_per_jiffy/(500000/HZ), 507 c->loops_per_jiffy/(500000/HZ),
478 (c->loops_per_jiffy/(5000/HZ)) % 100); 508 (c->loops_per_jiffy/(5000/HZ)) % 100);
479 509
480 return show_clocks(m); 510 return 0;
481} 511}
482 512
483static void *c_start(struct seq_file *m, loff_t *pos) 513static void *c_start(struct seq_file *m, loff_t *pos)
@@ -499,92 +529,3 @@ struct seq_operations cpuinfo_op = {
499 .show = show_cpuinfo, 529 .show = show_cpuinfo,
500}; 530};
501#endif /* CONFIG_PROC_FS */ 531#endif /* CONFIG_PROC_FS */
502
503#ifdef CONFIG_SH_KGDB
504/*
505 * Parse command-line kgdb options. By default KGDB is enabled,
506 * entered on error (or other action) using default serial info.
507 * The command-line option can include a serial port specification
508 * and an action to override default or configured behavior.
509 */
510struct kgdb_sermap kgdb_sci_sermap =
511{ "ttySC", 5, kgdb_sci_setup, NULL };
512
513struct kgdb_sermap *kgdb_serlist = &kgdb_sci_sermap;
514struct kgdb_sermap *kgdb_porttype = &kgdb_sci_sermap;
515
516void kgdb_register_sermap(struct kgdb_sermap *map)
517{
518 struct kgdb_sermap *last;
519
520 for (last = kgdb_serlist; last->next; last = last->next)
521 ;
522 last->next = map;
523 if (!map->namelen) {
524 map->namelen = strlen(map->name);
525 }
526}
527
528static int __init kgdb_parse_options(char *options)
529{
530 char c;
531 int baud;
532
533 /* Check for port spec (or use default) */
534
535 /* Determine port type and instance */
536 if (!memcmp(options, "tty", 3)) {
537 struct kgdb_sermap *map = kgdb_serlist;
538
539 while (map && memcmp(options, map->name, map->namelen))
540 map = map->next;
541
542 if (!map) {
543 KGDB_PRINTK("unknown port spec in %s\n", options);
544 return -1;
545 }
546
547 kgdb_porttype = map;
548 kgdb_serial_setup = map->setup_fn;
549 kgdb_portnum = options[map->namelen] - '0';
550 options += map->namelen + 1;
551
552 options = (*options == ',') ? options+1 : options;
553
554 /* Read optional parameters (baud/parity/bits) */
555 baud = simple_strtoul(options, &options, 10);
556 if (baud != 0) {
557 kgdb_baud = baud;
558
559 c = toupper(*options);
560 if (c == 'E' || c == 'O' || c == 'N') {
561 kgdb_parity = c;
562 options++;
563 }
564
565 c = *options;
566 if (c == '7' || c == '8') {
567 kgdb_bits = c;
568 options++;
569 }
570 options = (*options == ',') ? options+1 : options;
571 }
572 }
573
574 /* Check for action specification */
575 if (!memcmp(options, "halt", 4)) {
576 kgdb_halt = 1;
577 options += 4;
578 } else if (!memcmp(options, "disabled", 8)) {
579 kgdb_enabled = 0;
580 options += 8;
581 }
582
583 if (*options) {
584 KGDB_PRINTK("ignored unknown options: %s\n", options);
585 return 0;
586 }
587 return 1;
588}
589__setup("kgdb=", kgdb_parse_options);
590#endif /* CONFIG_SH_KGDB */