setup.c revision 98d877c487a75af78f74780703aa6b174780788d
1711fa8096863e4b50bb97f9ebc44606dc2182ac3Paul Mundt/*
211c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt * arch/sh/kernel/setup.c
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file handles the architecture-dependent parts of initialization
511c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt *
611c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt *  Copyright (C) 1999  Niibe Yutaka
701066625e9ae39742c92e21163f7f2a818e02762Paul Mundt *  Copyright (C) 2002 - 2007 Paul Mundt
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
9894673ee6122a3ce1958e1fe096901ba5356a96bJon Smirl#include <linux/screen_info.h>
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ioport.h>
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/initrd.h>
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/bootmem.h>
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/console.h>
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/seq_file.h>
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/root_dev.h>
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/utsname.h>
1801066625e9ae39742c92e21163f7f2a818e02762Paul Mundt#include <linux/nodemask.h>
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/cpu.h>
2022a9835c350782a5c3257343713932af3ac92ee0Dave Hansen#include <linux/pfn.h>
21711fa8096863e4b50bb97f9ebc44606dc2182ac3Paul Mundt#include <linux/fs.h>
2201066625e9ae39742c92e21163f7f2a818e02762Paul Mundt#include <linux/mm.h>
234d5ade5b29c618e97a8988efb6967cb4dd0e2183Paul Mundt#include <linux/kexec.h>
2498d877c487a75af78f74780703aa6b174780788dPaul Mundt#include <linux/module.h>
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h>
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h>
277a302a9674593259866de4a9d5ae8edc03dc1934Paul Mundt#include <asm/page.h>
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/sections.h>
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/irq.h>
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/setup.h>
31de02797aa744c96a90f47be7bc081ce2f74b17fdPaul Mundt#include <asm/clock.h>
3201066625e9ae39742c92e21163f7f2a818e02762Paul Mundt#include <asm/mmu_context.h>
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern void * __rd_start, * __rd_end;
35fa5da2f7bdcf885efe65a37df13907c7d72296f6Paul Mundt
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Machine setup..
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Initialize loops_per_jiffy as 10000000 (1000MIPS).
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This value will be used at the very early stage of serial setup.
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The bigger value means no problem.
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
45de02797aa744c96a90f47be7bc081ce2f74b17fdPaul Mundtstruct sh_cpuinfo boot_cpu_data = { CPU_SH_NONE, 10000000, };
4682f81f4784479df17a80caff4a7156da0a2f7deaPaul Mundt
4782f81f4784479df17a80caff4a7156da0a2f7deaPaul Mundt/*
4882f81f4784479df17a80caff4a7156da0a2f7deaPaul Mundt * The machine vector. First entry in .machvec.init, or clobbered by
4982f81f4784479df17a80caff4a7156da0a2f7deaPaul Mundt * sh_mv= on the command line, prior to .machvec.init teardown.
5082f81f4784479df17a80caff4a7156da0a2f7deaPaul Mundt */
51fd8f20e8e2f8f1d9201086bff444c8d35f0a6a45Paul Mundtstruct sh_machine_vector sh_mv = { .mv_name = "generic", };
5282f81f4784479df17a80caff4a7156da0a2f7deaPaul Mundt
532c7834a6f15fe6c50ed4766f1bb6f9183b9e2740Paul Mundt#ifdef CONFIG_VT
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct screen_info screen_info;
552c7834a6f15fe6c50ed4766f1bb6f9183b9e2740Paul Mundt#endif
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsextern int root_mountflags;
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This is set up by the setup-routine at boot-time
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PARAM	((unsigned char *)empty_zero_page)
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MOUNT_ROOT_RDONLY (*(unsigned long *) (PARAM+0x000))
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RAMDISK_FLAGS (*(unsigned long *) (PARAM+0x004))
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ORIG_ROOT_DEV (*(unsigned long *) (PARAM+0x008))
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LOADER_TYPE (*(unsigned long *) (PARAM+0x00c))
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define INITRD_START (*(unsigned long *) (PARAM+0x010))
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define INITRD_SIZE (*(unsigned long *) (PARAM+0x014))
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ... */
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define COMMAND_LINE ((char *) (PARAM+0x100))
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7365463b73b14ed43368dc5961a6c3dcb0d98cfe1fPaul Mundt#define RAMDISK_IMAGE_START_MASK	0x07FF
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RAMDISK_PROMPT_FLAG		0x8000
7565463b73b14ed43368dc5961a6c3dcb0d98cfe1fPaul Mundt#define RAMDISK_LOAD_FLAG		0x4000
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7753c82622c2db808c015953336faecefc0ebf29bcAlon Bar-Levstatic char __initdata command_line[COMMAND_LINE_SIZE] = { 0, };
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
792c7834a6f15fe6c50ed4766f1bb6f9183b9e2740Paul Mundtstatic struct resource code_resource = { .name = "Kernel code", };
802c7834a6f15fe6c50ed4766f1bb6f9183b9e2740Paul Mundtstatic struct resource data_resource = { .name = "Kernel data", };
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8298d877c487a75af78f74780703aa6b174780788dPaul Mundtunsigned long memory_start;
8398d877c487a75af78f74780703aa6b174780788dPaul MundtEXPORT_SYMBOL(memory_start);
8498d877c487a75af78f74780703aa6b174780788dPaul Mundt
8598d877c487a75af78f74780703aa6b174780788dPaul Mundtunsigned long memory_end;
8698d877c487a75af78f74780703aa6b174780788dPaul MundtEXPORT_SYMBOL(memory_end);
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
889655ad03af2d232c3b26e7562ab4f8c29b107e49Paul Mundtstatic int __init early_parse_mem(char *p)
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
909655ad03af2d232c3b26e7562ab4f8c29b107e49Paul Mundt	unsigned long size;
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START;
939655ad03af2d232c3b26e7562ab4f8c29b107e49Paul Mundt	size = memparse(p, &p);
949655ad03af2d232c3b26e7562ab4f8c29b107e49Paul Mundt	memory_end = memory_start + size;
952c7834a6f15fe6c50ed4766f1bb6f9183b9e2740Paul Mundt
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
989655ad03af2d232c3b26e7562ab4f8c29b107e49Paul Mundtearly_param("mem", early_parse_mem);
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10001066625e9ae39742c92e21163f7f2a818e02762Paul Mundt/*
10101066625e9ae39742c92e21163f7f2a818e02762Paul Mundt * Register fully available low RAM pages with the bootmem allocator.
10201066625e9ae39742c92e21163f7f2a818e02762Paul Mundt */
10301066625e9ae39742c92e21163f7f2a818e02762Paul Mundtstatic void __init register_bootmem_low_pages(void)
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
10501066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	unsigned long curr_pfn, last_pfn, pages;
106b641fe016a29fe2c0c7b0d717a5918e3f067a44fPaul Mundt
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
10801066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	 * We are rounding up the start address of usable memory:
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
11001066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	curr_pfn = PFN_UP(__MEMORY_START);
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
11301066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	 * ... and at the end of the usable range downwards:
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
11501066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	last_pfn = PFN_DOWN(__pa(memory_end));
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
11701066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	if (last_pfn > max_low_pfn)
11801066625e9ae39742c92e21163f7f2a818e02762Paul Mundt		last_pfn = max_low_pfn;
11901066625e9ae39742c92e21163f7f2a818e02762Paul Mundt
12001066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	pages = last_pfn - curr_pfn;
12101066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages));
12201066625e9ae39742c92e21163f7f2a818e02762Paul Mundt}
12301066625e9ae39742c92e21163f7f2a818e02762Paul Mundt
1242826fa61c13716816c7ae658b8f1c5a4a505d8acPaul Mundtvoid __init setup_bootmem_allocator(unsigned long free_pfn)
12501066625e9ae39742c92e21163f7f2a818e02762Paul Mundt{
12601066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	unsigned long bootmap_size;
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Find a proper area for the bootmem bitmap. After this
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * bootstrap step all allocations (until the page allocator
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * is intact) must be done via bootmem_alloc().
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1332826fa61c13716816c7ae658b8f1c5a4a505d8acPaul Mundt	bootmap_size = init_bootmem_node(NODE_DATA(0), free_pfn,
13401066625e9ae39742c92e21163f7f2a818e02762Paul Mundt					 min_low_pfn, max_low_pfn);
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
136dfbb9042801eaeb4df9015bb86224291a39a0f52Paul Mundt	add_active_range(0, min_low_pfn, max_low_pfn);
13701066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	register_bootmem_low_pages();
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13901066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	node_set_online(0);
140b641fe016a29fe2c0c7b0d717a5918e3f067a44fPaul Mundt
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Reserve the kernel text and
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Reserve the bootmem bitmap. We do this in two steps (first step
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * was init_bootmem()), because this catches the (definitely buggy)
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * case of us accidentally initializing the bootmem allocator with
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * an invalid RAM area.
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
14801066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	reserve_bootmem(__MEMORY_START+PAGE_SIZE,
1492826fa61c13716816c7ae658b8f1c5a4a505d8acPaul Mundt		(PFN_PHYS(free_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START);
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * reserve physical page 0 - it's a special BIOS page on many boxes,
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * enabling clean reboots, SMP operation, laptop functions.
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
15501066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	reserve_bootmem(__MEMORY_START, PAGE_SIZE);
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1572826fa61c13716816c7ae658b8f1c5a4a505d8acPaul Mundt	sparse_memory_present_with_active_regions(0);
1582826fa61c13716816c7ae658b8f1c5a4a505d8acPaul Mundt
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_BLK_DEV_INITRD
16065463b73b14ed43368dc5961a6c3dcb0d98cfe1fPaul Mundt	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
16165463b73b14ed43368dc5961a6c3dcb0d98cfe1fPaul Mundt	if (&__rd_start != &__rd_end) {
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		LOADER_TYPE = 1;
16341504c39726a7099e5a42508dd57fe561c8b4129Paul Mundt		INITRD_START = PHYSADDR((unsigned long)&__rd_start) -
16441504c39726a7099e5a42508dd57fe561c8b4129Paul Mundt					__MEMORY_START;
16541504c39726a7099e5a42508dd57fe561c8b4129Paul Mundt		INITRD_SIZE = (unsigned long)&__rd_end -
16641504c39726a7099e5a42508dd57fe561c8b4129Paul Mundt			      (unsigned long)&__rd_start;
16765463b73b14ed43368dc5961a6c3dcb0d98cfe1fPaul Mundt	}
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (LOADER_TYPE && INITRD_START) {
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
17101066625e9ae39742c92e21163f7f2a818e02762Paul Mundt			reserve_bootmem(INITRD_START + __MEMORY_START,
17201066625e9ae39742c92e21163f7f2a818e02762Paul Mundt					INITRD_SIZE);
17341504c39726a7099e5a42508dd57fe561c8b4129Paul Mundt			initrd_start = INITRD_START + PAGE_OFFSET +
17441504c39726a7099e5a42508dd57fe561c8b4129Paul Mundt					__MEMORY_START;
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			initrd_end = initrd_start + INITRD_SIZE;
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printk("initrd extends beyond end of memory "
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				    INITRD_START + INITRD_SIZE,
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				    max_low_pfn << PAGE_SHIFT);
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			initrd_start = 0;
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
1854d5ade5b29c618e97a8988efb6967cb4dd0e2183Paul Mundt#ifdef CONFIG_KEXEC
1864d5ade5b29c618e97a8988efb6967cb4dd0e2183Paul Mundt	if (crashk_res.start != crashk_res.end)
1874d5ade5b29c618e97a8988efb6967cb4dd0e2183Paul Mundt		reserve_bootmem(crashk_res.start,
1884d5ade5b29c618e97a8988efb6967cb4dd0e2183Paul Mundt			crashk_res.end - crashk_res.start + 1);
1894d5ade5b29c618e97a8988efb6967cb4dd0e2183Paul Mundt#endif
19001066625e9ae39742c92e21163f7f2a818e02762Paul Mundt}
19101066625e9ae39742c92e21163f7f2a818e02762Paul Mundt
19201066625e9ae39742c92e21163f7f2a818e02762Paul Mundt#ifndef CONFIG_NEED_MULTIPLE_NODES
19301066625e9ae39742c92e21163f7f2a818e02762Paul Mundtstatic void __init setup_memory(void)
19401066625e9ae39742c92e21163f7f2a818e02762Paul Mundt{
19501066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	unsigned long start_pfn;
19601066625e9ae39742c92e21163f7f2a818e02762Paul Mundt
19701066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	/*
19801066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	 * Partially used pages are not usable - thus
19901066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	 * we are rounding upwards:
20001066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	 */
20101066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	start_pfn = PFN_UP(__pa(_end));
20201066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	setup_bootmem_allocator(start_pfn);
20301066625e9ae39742c92e21163f7f2a818e02762Paul Mundt}
20401066625e9ae39742c92e21163f7f2a818e02762Paul Mundt#else
20501066625e9ae39742c92e21163f7f2a818e02762Paul Mundtextern void __init setup_memory(void);
20601066625e9ae39742c92e21163f7f2a818e02762Paul Mundt#endif
20701066625e9ae39742c92e21163f7f2a818e02762Paul Mundt
20801066625e9ae39742c92e21163f7f2a818e02762Paul Mundtvoid __init setup_arch(char **cmdline_p)
20901066625e9ae39742c92e21163f7f2a818e02762Paul Mundt{
21001066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	enable_mmu();
21101066625e9ae39742c92e21163f7f2a818e02762Paul Mundt
21201066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
21301066625e9ae39742c92e21163f7f2a818e02762Paul Mundt
21401066625e9ae39742c92e21163f7f2a818e02762Paul Mundt#ifdef CONFIG_BLK_DEV_RAM
21501066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
21601066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
21701066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
21801066625e9ae39742c92e21163f7f2a818e02762Paul Mundt#endif
21901066625e9ae39742c92e21163f7f2a818e02762Paul Mundt
22001066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	if (!MOUNT_ROOT_RDONLY)
22101066625e9ae39742c92e21163f7f2a818e02762Paul Mundt		root_mountflags &= ~MS_RDONLY;
22201066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	init_mm.start_code = (unsigned long) _text;
22301066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	init_mm.end_code = (unsigned long) _etext;
22401066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	init_mm.end_data = (unsigned long) _edata;
22501066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	init_mm.brk = (unsigned long) _end;
22601066625e9ae39742c92e21163f7f2a818e02762Paul Mundt
22701066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	code_resource.start = virt_to_phys(_text);
22801066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	code_resource.end = virt_to_phys(_etext)-1;
22901066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	data_resource.start = virt_to_phys(_etext);
23001066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	data_resource.end = virt_to_phys(_edata)-1;
23101066625e9ae39742c92e21163f7f2a818e02762Paul Mundt
2329655ad03af2d232c3b26e7562ab4f8c29b107e49Paul Mundt	memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START;
2339655ad03af2d232c3b26e7562ab4f8c29b107e49Paul Mundt	memory_end = memory_start + __MEMORY_SIZE;
2349655ad03af2d232c3b26e7562ab4f8c29b107e49Paul Mundt
235ba36197cf4ff68f631bb1b3d4cc442d567279fe3Paul Mundt#ifdef CONFIG_CMDLINE_BOOL
236ba36197cf4ff68f631bb1b3d4cc442d567279fe3Paul Mundt	strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line));
237ba36197cf4ff68f631bb1b3d4cc442d567279fe3Paul Mundt#else
238ba36197cf4ff68f631bb1b3d4cc442d567279fe3Paul Mundt	strlcpy(command_line, COMMAND_LINE, sizeof(command_line));
239ba36197cf4ff68f631bb1b3d4cc442d567279fe3Paul Mundt#endif
2409655ad03af2d232c3b26e7562ab4f8c29b107e49Paul Mundt
241ba36197cf4ff68f631bb1b3d4cc442d567279fe3Paul Mundt	/* Save unparsed command line copy for /proc/cmdline */
242ba36197cf4ff68f631bb1b3d4cc442d567279fe3Paul Mundt	memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
2439655ad03af2d232c3b26e7562ab4f8c29b107e49Paul Mundt	*cmdline_p = command_line;
2449655ad03af2d232c3b26e7562ab4f8c29b107e49Paul Mundt
24501066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	parse_early_param();
24601066625e9ae39742c92e21163f7f2a818e02762Paul Mundt
2479655ad03af2d232c3b26e7562ab4f8c29b107e49Paul Mundt	sh_mv_setup();
24801066625e9ae39742c92e21163f7f2a818e02762Paul Mundt
24901066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	/*
25001066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	 * Find the highest page frame number we have available
25101066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	 */
25201066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	max_pfn = PFN_DOWN(__pa(memory_end));
25301066625e9ae39742c92e21163f7f2a818e02762Paul Mundt
25401066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	/*
25501066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	 * Determine low and high memory ranges:
25601066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	 */
25701066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	max_low_pfn = max_pfn;
25801066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	min_low_pfn = __MEMORY_START >> PAGE_SHIFT;
25901066625e9ae39742c92e21163f7f2a818e02762Paul Mundt
26001066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	nodes_clear(node_online_map);
261dfbb9042801eaeb4df9015bb86224291a39a0f52Paul Mundt
262dfbb9042801eaeb4df9015bb86224291a39a0f52Paul Mundt	/* Setup bootmem with available RAM */
26301066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	setup_memory();
26401066625e9ae39742c92e21163f7f2a818e02762Paul Mundt	sparse_init();
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_DUMMY_CONSOLE
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	conswitchp = &dummy_con;
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Perform the machine specific initialisation */
2712c7834a6f15fe6c50ed4766f1bb6f9183b9e2740Paul Mundt	if (likely(sh_mv.mv_setup))
2722c7834a6f15fe6c50ed4766f1bb6f9183b9e2740Paul Mundt		sh_mv.mv_setup(cmdline_p);
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
274dfbb9042801eaeb4df9015bb86224291a39a0f52Paul Mundt	paging_init();
275dfbb9042801eaeb4df9015bb86224291a39a0f52Paul Mundt}
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const char *cpu_name[] = {
278b552c7e8bceae8a04ae79ecee6fa369c1ba4f8e4Paul Mundt	[CPU_SH7206]	= "SH7206",	[CPU_SH7619]	= "SH7619",
279b9601c5e59dd25693345558a301e833741bf5874Paul Mundt	[CPU_SH7300]	= "SH7300",
280e5723e0eeb2dc16629e86d66785024ead9169000Paul Mundt	[CPU_SH7705]	= "SH7705",	[CPU_SH7706]	= "SH7706",
281e5723e0eeb2dc16629e86d66785024ead9169000Paul Mundt	[CPU_SH7707]	= "SH7707",	[CPU_SH7708]	= "SH7708",
282e5723e0eeb2dc16629e86d66785024ead9169000Paul Mundt	[CPU_SH7709]	= "SH7709",	[CPU_SH7710]	= "SH7710",
2839465a54fa4a9da628091c372baa84120f8304587Nobuhiro Iwamatsu	[CPU_SH7712]	= "SH7712",
284e5723e0eeb2dc16629e86d66785024ead9169000Paul Mundt	[CPU_SH7729]	= "SH7729",	[CPU_SH7750]	= "SH7750",
285e5723e0eeb2dc16629e86d66785024ead9169000Paul Mundt	[CPU_SH7750S]	= "SH7750S",	[CPU_SH7750R]	= "SH7750R",
286e5723e0eeb2dc16629e86d66785024ead9169000Paul Mundt	[CPU_SH7751]	= "SH7751",	[CPU_SH7751R]	= "SH7751R",
287e5723e0eeb2dc16629e86d66785024ead9169000Paul Mundt	[CPU_SH7760]	= "SH7760",	[CPU_SH73180]	= "SH73180",
288e5723e0eeb2dc16629e86d66785024ead9169000Paul Mundt	[CPU_ST40RA]	= "ST40RA",	[CPU_ST40GX1]	= "ST40GX1",
289e5723e0eeb2dc16629e86d66785024ead9169000Paul Mundt	[CPU_SH4_202]	= "SH4-202",	[CPU_SH4_501]	= "SH4-501",
290e5723e0eeb2dc16629e86d66785024ead9169000Paul Mundt	[CPU_SH7770]	= "SH7770",	[CPU_SH7780]	= "SH7780",
291e5723e0eeb2dc16629e86d66785024ead9169000Paul Mundt	[CPU_SH7781]	= "SH7781",	[CPU_SH7343]	= "SH7343",
29241504c39726a7099e5a42508dd57fe561c8b4129Paul Mundt	[CPU_SH7785]	= "SH7785",	[CPU_SH7722]	= "SH7722",
2932b1bd1ac5d4bffe3fd542bfe1784a583bd7df4faPaul Mundt	[CPU_SHX3]	= "SH-X3",	[CPU_SH_NONE]	= "Unknown"
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
29611c1965687b0a472add948d4240dfe65a2fcb298Paul Mundtconst char *get_cpu_subtype(struct sh_cpuinfo *c)
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
29811c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt	return cpu_name[c->type];
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_PROC_FS
3022220d164933a8776d1336c814e3c2e5573256d34Paul Mundt/* Symbolic CPU flags, keep in sync with asm/cpu-features.h */
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic const char *cpu_flags[] = {
3042220d164933a8776d1336c814e3c2e5573256d34Paul Mundt	"none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr",
305074f98df0547b7d15f78db9a17e985da0c22af28Paul Mundt	"ptea", "llsc", "l2", "op32", NULL
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
30811c1965687b0a472add948d4240dfe65a2fcb298Paul Mundtstatic void show_cpuflags(struct seq_file *m, struct sh_cpuinfo *c)
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long i;
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	seq_printf(m, "cpu flags\t:");
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
31411c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt	if (!c->flags) {
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		seq_printf(m, " %s\n", cpu_flags[0]);
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return;
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
319de02797aa744c96a90f47be7bc081ce2f74b17fdPaul Mundt	for (i = 0; cpu_flags[i]; i++)
32011c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt		if ((c->flags & (1 << i)))
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			seq_printf(m, " %s", cpu_flags[i+1]);
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	seq_printf(m, "\n");
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3262c7834a6f15fe6c50ed4766f1bb6f9183b9e2740Paul Mundtstatic void show_cacheinfo(struct seq_file *m, const char *type,
3272c7834a6f15fe6c50ed4766f1bb6f9183b9e2740Paul Mundt			   struct cache_info info)
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int cache_size;
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cache_size = info.ways * info.sets * info.linesz;
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
333de02797aa744c96a90f47be7bc081ce2f74b17fdPaul Mundt	seq_printf(m, "%s size\t: %2dKiB (%d-way)\n",
334de02797aa744c96a90f47be7bc081ce2f74b17fdPaul Mundt		   type, cache_size >> 10, info.ways);
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *	Get CPU information for use by the procfs.
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int show_cpuinfo(struct seq_file *m, void *v)
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
34211c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt	struct sh_cpuinfo *c = v;
34311c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt	unsigned int cpu = c - cpu_data;
34411c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt
34511c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt	if (!cpu_online(cpu))
34611c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt		return 0;
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
34811c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt	if (cpu == 0)
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		seq_printf(m, "machine\t\t: %s\n", get_system_type());
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	seq_printf(m, "processor\t: %d\n", cpu);
35296b644bdec977b97a45133e5b4466ba47a7a5e65Serge E. Hallyn	seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine);
35311c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt	seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype(c));
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
35511c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt	show_cpuflags(m, c);
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	seq_printf(m, "cache type\t: ");
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/*
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * Check for what type of cache we have, we support both the
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * unified cache on the SH-2 and SH-3, as well as the harvard
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * style cache on the SH-4.
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
36411c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt	if (c->icache.flags & SH_CACHE_COMBINED) {
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		seq_printf(m, "unified\n");
36611c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt		show_cacheinfo(m, "cache", c->icache);
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		seq_printf(m, "split (harvard)\n");
36911c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt		show_cacheinfo(m, "icache", c->icache);
37011c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt		show_cacheinfo(m, "dcache", c->dcache);
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
37372c35543f8cf1316773ffbd9619575bb84ac44fbPaul Mundt	/* Optional secondary cache */
37411c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt	if (c->flags & CPU_HAS_L2_CACHE)
37511c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt		show_cacheinfo(m, "scache", c->scache);
37672c35543f8cf1316773ffbd9619575bb84ac44fbPaul Mundt
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	seq_printf(m, "bogomips\t: %lu.%02lu\n",
37811c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt		     c->loops_per_jiffy/(500000/HZ),
37911c1965687b0a472add948d4240dfe65a2fcb298Paul Mundt		     (c->loops_per_jiffy/(5000/HZ)) % 100);
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
381db62e5bd297d1f325811c5495ad23de36db0fdd4Paul Mundt	return 0;
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void *c_start(struct seq_file *m, loff_t *pos)
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return *pos < NR_CPUS ? cpu_data + *pos : NULL;
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void *c_next(struct seq_file *m, void *v, loff_t *pos)
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	++*pos;
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return c_start(m, pos);
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void c_stop(struct seq_file *m, void *v)
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct seq_operations cpuinfo_op = {
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.start	= c_start,
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.next	= c_next,
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.stop	= c_stop,
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.show	= show_cpuinfo,
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* CONFIG_PROC_FS */
403