File: /usr/src/linux/arch/arm/kernel/setup.c

1     /*
2      *  linux/arch/arm/kernel/setup.c
3      *
4      *  Copyright (C) 1995-2000 Russell King
5      *
6      * This program is free software; you can redistribute it and/or modify
7      * it under the terms of the GNU General Public License version 2 as
8      * published by the Free Software Foundation.
9      */
10     #include <linux/config.h>
11     #include <linux/kernel.h>
12     #include <linux/stddef.h>
13     #include <linux/ioport.h>
14     #include <linux/delay.h>
15     #include <linux/utsname.h>
16     #include <linux/blk.h>
17     #include <linux/console.h>
18     #include <linux/bootmem.h>
19     #include <linux/init.h>
20     
21     #include <asm/elf.h>
22     #include <asm/hardware.h>
23     #include <asm/io.h>
24     #include <asm/procinfo.h>
25     #include <asm/setup.h>
26     #include <asm/mach-types.h>
27     
28     #include <asm/mach/arch.h>
29     #include <asm/mach/irq.h>
30     
31     #ifndef MEM_SIZE
32     #define MEM_SIZE	(16*1024*1024)
33     #endif
34     
35     #ifndef CONFIG_CMDLINE
36     #define CONFIG_CMDLINE ""
37     #endif
38     
39     #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
40     char fpe_type[8];
41     
42     static int __init fpe_setup(char *line)
43     {
44     	memcpy(fpe_type, line, 8);
45     	return 1;
46     }
47     
48     __setup("fpe=", fpe_setup);
49     #endif
50     
51     extern unsigned int mem_fclk_21285;
52     extern void paging_init(struct meminfo *, struct machine_desc *desc);
53     extern void convert_to_tag_list(struct param_struct *params, int mem_init);
54     extern void bootmem_init(struct meminfo *);
55     extern void reboot_setup(char *str);
56     extern int root_mountflags;
57     extern int _stext, _text, _etext, _edata, _end;
58     
59     unsigned int processor_id;
60     unsigned int compat;
61     unsigned int __machine_arch_type;
62     unsigned int system_rev;
63     unsigned int system_serial_low;
64     unsigned int system_serial_high;
65     unsigned int elf_hwcap;
66     
67     #ifdef MULTI_CPU
68     struct processor processor;
69     #endif
70     
71     unsigned char aux_device_present;
72     char elf_platform[ELF_PLATFORM_SIZE];
73     char saved_command_line[COMMAND_LINE_SIZE];
74     
75     static struct meminfo meminfo __initdata = { 0, };
76     static struct proc_info_item proc_info;
77     static const char *machine_name;
78     static char command_line[COMMAND_LINE_SIZE];
79     
80     static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
81     static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
82     #define ENDIANNESS ((char)endian_test.l)
83     
84     /*
85      * Standard memory resources
86      */
87     static struct resource mem_res[] = {
88     	{ "Video RAM",   0,     0,     IORESOURCE_MEM			},
89     	{ "Kernel code", 0,     0,     IORESOURCE_MEM			},
90     	{ "Kernel data", 0,     0,     IORESOURCE_MEM			}
91     };
92     
93     #define video_ram   mem_res[0]
94     #define kernel_code mem_res[1]
95     #define kernel_data mem_res[2]
96     
97     static struct resource io_res[] = {
98     	{ "reserved",    0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY },
99     	{ "reserved",    0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY },
100     	{ "reserved",    0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY }
101     };
102     
103     #define lp0 io_res[0]
104     #define lp1 io_res[1]
105     #define lp2 io_res[2]
106     
107     static void __init setup_processor(void)
108     {
109     	extern struct proc_info_list __proc_info_begin, __proc_info_end;
110     	struct proc_info_list *list;
111     
112     	/*
113     	 * locate processor in the list of supported processor
114     	 * types.  The linker builds this table for us from the
115     	 * entries in arch/arm/mm/proc-*.S
116     	 */
117     	for (list = &__proc_info_begin; list < &__proc_info_end ; list++)
118     		if ((processor_id & list->cpu_mask) == list->cpu_val)
119     			break;
120     
121     	/*
122     	 * If processor type is unrecognised, then we
123     	 * can do nothing...
124     	 */
125     	if (list >= &__proc_info_end) {
126     		printk("CPU configuration botched (ID %08x), unable "
127     		       "to continue.\n", processor_id);
128     		while (1);
129     	}
130     
131     	proc_info = *list->info;
132     
133     #ifdef MULTI_CPU
134     	processor = *list->proc;
135     #endif
136     
137     	printk("Processor: %s %s revision %d\n",
138     	       proc_info.manufacturer, proc_info.cpu_name,
139     	       (int)processor_id & 15);
140     
141     	sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
142     	sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
143     	elf_hwcap = list->elf_hwcap;
144     
145     	cpu_proc_init();
146     }
147     
148     static struct machine_desc * __init setup_architecture(unsigned int nr)
149     {
150     	extern struct machine_desc __arch_info_begin, __arch_info_end;
151     	struct machine_desc *list;
152     
153     	/*
154     	 * locate architecture in the list of supported architectures.
155     	 */
156     	for (list = &__arch_info_begin; list < &__arch_info_end; list++)
157     		if (list->nr == nr)
158     			break;
159     
160     	/*
161     	 * If the architecture type is not recognised, then we
162     	 * can co nothing...
163     	 */
164     	if (list >= &__arch_info_end) {
165     		printk("Architecture configuration botched (nr %d), unable "
166     		       "to continue.\n", nr);
167     		while (1);
168     	}
169     
170     	printk("Architecture: %s\n", list->name);
171     	if (compat)
172     		printk(KERN_WARNING "Using compatibility code "
173     			"scheduled for removal in v%d.%d.%d\n",
174     			compat >> 24, (compat >> 12) & 0x3ff,
175     			compat & 0x3ff);
176     
177     	return list;
178     }
179     
180     /*
181      * Initial parsing of the command line.  We need to pick out the
182      * memory size.  We look for mem=size@start, where start and size
183      * are "size[KkMm]"
184      */
185     static void __init
186     parse_cmdline(struct meminfo *mi, char **cmdline_p, char *from)
187     {
188     	char c = ' ', *to = command_line;
189     	int usermem = 0, len = 0;
190     
191     	for (;;) {
192     		if (c == ' ' && !memcmp(from, "mem=", 4)) {
193     			unsigned long size, start;
194     
195     			if (to != command_line)
196     				to -= 1;
197     
198     			/*
199     			 * If the user specifies memory size, we
200     			 * blow away any automatically generated
201     			 * size.
202     			 */
203     			if (usermem == 0) {
204     				usermem = 1;
205     				mi->nr_banks = 0;
206     			}
207     
208     			start = PHYS_OFFSET;
209     			size  = memparse(from + 4, &from);
210     			if (*from == '@')
211     				start = memparse(from + 1, &from);
212     
213     			mi->bank[mi->nr_banks].start = start;
214     			mi->bank[mi->nr_banks].size  = size;
215     			mi->bank[mi->nr_banks].node  = PHYS_TO_NID(start);
216     			mi->nr_banks += 1;
217     		}
218     		c = *from++;
219     		if (!c)
220     			break;
221     		if (COMMAND_LINE_SIZE <= ++len)
222     			break;
223     		*to++ = c;
224     	}
225     	*to = '\0';
226     	*cmdline_p = command_line;
227     }
228     
229     void __init
230     setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
231     {
232     #ifdef CONFIG_BLK_DEV_RAM
233     	extern int rd_size;
234     
235     	rd_image_start = image_start;
236     	rd_prompt = prompt;
237     	rd_doload = doload;
238     
239     	if (rd_sz)
240     		rd_size = rd_sz;
241     #endif
242     }
243     
244     /*
245      * initial ram disk
246      */
247     void __init setup_initrd(unsigned int start, unsigned int size)
248     {
249     #ifdef CONFIG_BLK_DEV_INITRD
250     	if (start == 0)
251     		size = 0;
252     	initrd_start = start;
253     	initrd_end   = start + size;
254     #endif
255     }
256     
257     static void __init
258     request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
259     {
260     	struct resource *res;
261     	int i;
262     
263     	kernel_code.start  = __virt_to_bus(init_mm.start_code);
264     	kernel_code.end    = __virt_to_bus(init_mm.end_code - 1);
265     	kernel_data.start  = __virt_to_bus(init_mm.end_code);
266     	kernel_data.end    = __virt_to_bus(init_mm.brk - 1);
267     
268     	for (i = 0; i < mi->nr_banks; i++) {
269     		unsigned long virt_start, virt_end;
270     
271     		if (mi->bank[i].size == 0)
272     			continue;
273     
274     		virt_start = __phys_to_virt(mi->bank[i].start);
275     		virt_end   = virt_start + mi->bank[i].size - 1;
276     
277     		res = alloc_bootmem_low(sizeof(*res));
278     		res->name  = "System RAM";
279     		res->start = __virt_to_phys(virt_start);
280     		res->end   = __virt_to_phys(virt_end);
281     		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
282     
283     		request_resource(&iomem_resource, res);
284     
285     		if (kernel_code.start >= res->start &&
286     		    kernel_code.end <= res->end)
287     			request_resource(res, &kernel_code);
288     		if (kernel_data.start >= res->start &&
289     		    kernel_data.end <= res->end)
290     			request_resource(res, &kernel_data);
291     	}
292     
293     	if (mdesc->video_start) {
294     		video_ram.start = mdesc->video_start;
295     		video_ram.end   = mdesc->video_end;
296     		request_resource(&iomem_resource, &video_ram);
297     	}
298     
299     	/*
300     	 * Some machines don't have the possibility of ever
301     	 * possessing lp0, lp1 or lp2
302     	 */
303     	if (mdesc->reserve_lp0)
304     		request_resource(&ioport_resource, &lp0);
305     	if (mdesc->reserve_lp1)
306     		request_resource(&ioport_resource, &lp1);
307     	if (mdesc->reserve_lp2)
308     		request_resource(&ioport_resource, &lp2);
309     }
310     
311     /*
312      *  Tag parsing.
313      *
314      * This is the new way of passing data to the kernel at boot time.  Rather
315      * than passing a fixed inflexible structure to the kernel, we pass a list
316      * of variable-sized tags to the kernel.  The first tag must be a ATAG_CORE
317      * tag for the list to be recognised (to distinguish the tagged list from
318      * a param_struct).  The list is terminated with a zero-length tag (this tag
319      * is not parsed in any way).
320      */
321     static int __init parse_tag_core(const struct tag *tag)
322     {
323     	if (tag->hdr.size > 2) {
324     		if ((tag->u.core.flags & 1) == 0)
325     			root_mountflags &= ~MS_RDONLY;
326     		ROOT_DEV = to_kdev_t(tag->u.core.rootdev);
327     	}
328     	return 0;
329     }
330     
331     __tagtable(ATAG_CORE, parse_tag_core);
332     
333     static int __init parse_tag_mem32(const struct tag *tag)
334     {
335     	if (meminfo.nr_banks >= NR_BANKS) {
336     		printk(KERN_WARNING
337     		       "Ignoring memory bank 0x%08x size %dKB\n",
338     			tag->u.mem.start, tag->u.mem.size / 1024);
339     		return -EINVAL;
340     	}
341     	meminfo.bank[meminfo.nr_banks].start = tag->u.mem.start;
342     	meminfo.bank[meminfo.nr_banks].size  = tag->u.mem.size;
343     	meminfo.bank[meminfo.nr_banks].node  = PHYS_TO_NID(tag->u.mem.start);
344     	meminfo.nr_banks += 1;
345     
346     	return 0;
347     }
348     
349     __tagtable(ATAG_MEM, parse_tag_mem32);
350     
351     #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
352     struct screen_info screen_info = {
353      orig_video_lines:	30,
354      orig_video_cols:	80,
355      orig_video_mode:	0,
356      orig_video_ega_bx:	0,
357      orig_video_isVGA:	1,
358      orig_video_points:	8
359     };
360     
361     static int __init parse_tag_videotext(const struct tag *tag)
362     {
363     	screen_info.orig_x            = tag->u.videotext.x;
364     	screen_info.orig_y            = tag->u.videotext.y;
365     	screen_info.orig_video_page   = tag->u.videotext.video_page;
366     	screen_info.orig_video_mode   = tag->u.videotext.video_mode;
367     	screen_info.orig_video_cols   = tag->u.videotext.video_cols;
368     	screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
369     	screen_info.orig_video_lines  = tag->u.videotext.video_lines;
370     	screen_info.orig_video_isVGA  = tag->u.videotext.video_isvga;
371     	screen_info.orig_video_points = tag->u.videotext.video_points;
372     	return 0;
373     }
374     
375     __tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
376     #endif
377     
378     static int __init parse_tag_ramdisk(const struct tag *tag)
379     {
380     	setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
381     		      (tag->u.ramdisk.flags & 2) == 0,
382     		      tag->u.ramdisk.start, tag->u.ramdisk.size);
383     	return 0;
384     }
385     
386     __tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
387     
388     static int __init parse_tag_initrd(const struct tag *tag)
389     {
390     	setup_initrd(tag->u.initrd.start, tag->u.initrd.size);
391     	return 0;
392     }
393     
394     __tagtable(ATAG_INITRD, parse_tag_initrd);
395     
396     static int __init parse_tag_serialnr(const struct tag *tag)
397     {
398     	system_serial_low = tag->u.serialnr.low;
399     	system_serial_high = tag->u.serialnr.high;
400     	return 0;
401     }
402     
403     __tagtable(ATAG_SERIAL, parse_tag_serialnr);
404     
405     static int __init parse_tag_revision(const struct tag *tag)
406     {
407     	system_rev = tag->u.revision.rev;
408     	return 0;
409     }
410     
411     __tagtable(ATAG_REVISION, parse_tag_revision);
412     
413     static int __init parse_tag_cmdline(const struct tag *tag)
414     {
415     	strncpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
416     	default_command_line[COMMAND_LINE_SIZE - 1] = '\0';
417     	return 0;
418     }
419     
420     __tagtable(ATAG_CMDLINE, parse_tag_cmdline);
421     
422     /*
423      * Scan the tag table for this tag, and call its parse function.
424      * The tag table is built by the linker from all the __tagtable
425      * declarations.
426      */
427     static int __init parse_tag(const struct tag *tag)
428     {
429     	extern struct tagtable __tagtable_begin, __tagtable_end;
430     	struct tagtable *t;
431     
432     	for (t = &__tagtable_begin; t < &__tagtable_end; t++)
433     		if (tag->hdr.tag == t->tag) {
434     			t->parse(tag);
435     			break;
436     		}
437     
438     	return t < &__tagtable_end;
439     }
440     
441     /*
442      * Parse all tags in the list, checking both the global and architecture
443      * specific tag tables.
444      */
445     static void __init parse_tags(const struct tag *t)
446     {
447     	for (; t->hdr.size; t = tag_next(t))
448     		if (!parse_tag(t))
449     			printk(KERN_WARNING
450     				"Ignoring unrecognised tag 0x%08x\n",
451     				t->hdr.tag);
452     }
453     
454     void __init setup_arch(char **cmdline_p)
455     {
456     	struct tag *tags = NULL;
457     	struct machine_desc *mdesc;
458     	char *from = default_command_line;
459     
460     	ROOT_DEV = MKDEV(0, 255);
461     
462     	setup_processor();
463     	mdesc = setup_architecture(machine_arch_type);
464     	machine_name = mdesc->name;
465     
466     	if (mdesc->soft_reboot)
467     		reboot_setup("s");
468     
469     	if (mdesc->param_offset)
470     		tags = phys_to_virt(mdesc->param_offset);
471     
472     	/*
473     	 * Do the machine-specific fixups before we parse the
474     	 * parameters or tags.
475     	 */
476     	if (mdesc->fixup)
477     		mdesc->fixup(mdesc, (struct param_struct *)tags,
478     			     &from, &meminfo);
479     
480     	/*
481     	 * If we have the old style parameters, convert them to
482     	 * a tag list before.
483     	 */
484     	if (tags && tags->hdr.tag != ATAG_CORE)
485     		convert_to_tag_list((struct param_struct *)tags,
486     				    meminfo.nr_banks == 0);
487     
488     	if (tags && tags->hdr.tag == ATAG_CORE)
489     		parse_tags(tags);
490     
491     	if (meminfo.nr_banks == 0) {
492     		meminfo.nr_banks      = 1;
493     		meminfo.bank[0].start = PHYS_OFFSET;
494     		meminfo.bank[0].size  = MEM_SIZE;
495     	}
496     
497     	init_mm.start_code = (unsigned long) &_text;
498     	init_mm.end_code   = (unsigned long) &_etext;
499     	init_mm.end_data   = (unsigned long) &_edata;
500     	init_mm.brk	   = (unsigned long) &_end;
501     
502     	memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
503     	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
504     	parse_cmdline(&meminfo, cmdline_p, from);
505     	bootmem_init(&meminfo);
506     	paging_init(&meminfo, mdesc);
507     	request_standard_resources(&meminfo, mdesc);
508     
509     	/*
510     	 * Set up various architecture-specific pointers
511     	 */
512     	init_arch_irq = mdesc->init_irq;
513     
514     #ifdef CONFIG_VT
515     #if defined(CONFIG_VGA_CONSOLE)
516     	conswitchp = &vga_con;
517     #elif defined(CONFIG_DUMMY_CONSOLE)
518     	conswitchp = &dummy_con;
519     #endif
520     #endif
521     }
522     
523     int get_cpuinfo(char * buffer)
524     {
525     	char *p = buffer;
526     
527     	p += sprintf(p, "Processor\t: %s %s rev %d (%s)\n",
528     		     proc_info.manufacturer, proc_info.cpu_name,
529     		     (int)processor_id & 15, elf_platform);
530     
531     	p += sprintf(p, "BogoMIPS\t: %lu.%02lu\n",
532     		     loops_per_jiffy / (500000/HZ),
533     		     (loops_per_jiffy / (5000/HZ)) % 100);
534     
535     	p += sprintf(p, "Hardware\t: %s\n", machine_name);
536     
537     	p += sprintf(p, "Revision\t: %04x\n",
538     		     system_rev);
539     
540     	p += sprintf(p, "Serial\t\t: %08x%08x\n",
541     		     system_serial_high,
542     		     system_serial_low);
543     
544     	return p - buffer;
545     }
546