xref: /openbmc/linux/arch/arm/kernel/setup.c (revision a09d2831)
1 /*
2  *  linux/arch/arm/kernel/setup.c
3  *
4  *  Copyright (C) 1995-2001 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/module.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/initrd.h>
17 #include <linux/console.h>
18 #include <linux/bootmem.h>
19 #include <linux/seq_file.h>
20 #include <linux/screen_info.h>
21 #include <linux/init.h>
22 #include <linux/root_dev.h>
23 #include <linux/cpu.h>
24 #include <linux/interrupt.h>
25 #include <linux/smp.h>
26 #include <linux/fs.h>
27 
28 #include <asm/unified.h>
29 #include <asm/cpu.h>
30 #include <asm/cputype.h>
31 #include <asm/elf.h>
32 #include <asm/procinfo.h>
33 #include <asm/sections.h>
34 #include <asm/setup.h>
35 #include <asm/mach-types.h>
36 #include <asm/cacheflush.h>
37 #include <asm/cachetype.h>
38 #include <asm/tlbflush.h>
39 
40 #include <asm/mach/arch.h>
41 #include <asm/mach/irq.h>
42 #include <asm/mach/time.h>
43 #include <asm/traps.h>
44 #include <asm/unwind.h>
45 
46 #include "compat.h"
47 #include "atags.h"
48 #include "tcm.h"
49 
50 #ifndef MEM_SIZE
51 #define MEM_SIZE	(16*1024*1024)
52 #endif
53 
54 #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
55 char fpe_type[8];
56 
57 static int __init fpe_setup(char *line)
58 {
59 	memcpy(fpe_type, line, 8);
60 	return 1;
61 }
62 
63 __setup("fpe=", fpe_setup);
64 #endif
65 
66 extern void paging_init(struct machine_desc *desc);
67 extern void reboot_setup(char *str);
68 
69 unsigned int processor_id;
70 EXPORT_SYMBOL(processor_id);
71 unsigned int __machine_arch_type;
72 EXPORT_SYMBOL(__machine_arch_type);
73 unsigned int cacheid;
74 EXPORT_SYMBOL(cacheid);
75 
76 unsigned int __atags_pointer __initdata;
77 
78 unsigned int system_rev;
79 EXPORT_SYMBOL(system_rev);
80 
81 unsigned int system_serial_low;
82 EXPORT_SYMBOL(system_serial_low);
83 
84 unsigned int system_serial_high;
85 EXPORT_SYMBOL(system_serial_high);
86 
87 unsigned int elf_hwcap;
88 EXPORT_SYMBOL(elf_hwcap);
89 
90 
91 #ifdef MULTI_CPU
92 struct processor processor;
93 #endif
94 #ifdef MULTI_TLB
95 struct cpu_tlb_fns cpu_tlb;
96 #endif
97 #ifdef MULTI_USER
98 struct cpu_user_fns cpu_user;
99 #endif
100 #ifdef MULTI_CACHE
101 struct cpu_cache_fns cpu_cache;
102 #endif
103 #ifdef CONFIG_OUTER_CACHE
104 struct outer_cache_fns outer_cache;
105 #endif
106 
107 struct stack {
108 	u32 irq[3];
109 	u32 abt[3];
110 	u32 und[3];
111 } ____cacheline_aligned;
112 
113 static struct stack stacks[NR_CPUS];
114 
115 char elf_platform[ELF_PLATFORM_SIZE];
116 EXPORT_SYMBOL(elf_platform);
117 
118 static const char *cpu_name;
119 static const char *machine_name;
120 static char __initdata command_line[COMMAND_LINE_SIZE];
121 
122 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
123 static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
124 #define ENDIANNESS ((char)endian_test.l)
125 
126 DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data);
127 
128 /*
129  * Standard memory resources
130  */
131 static struct resource mem_res[] = {
132 	{
133 		.name = "Video RAM",
134 		.start = 0,
135 		.end = 0,
136 		.flags = IORESOURCE_MEM
137 	},
138 	{
139 		.name = "Kernel text",
140 		.start = 0,
141 		.end = 0,
142 		.flags = IORESOURCE_MEM
143 	},
144 	{
145 		.name = "Kernel data",
146 		.start = 0,
147 		.end = 0,
148 		.flags = IORESOURCE_MEM
149 	}
150 };
151 
152 #define video_ram   mem_res[0]
153 #define kernel_code mem_res[1]
154 #define kernel_data mem_res[2]
155 
156 static struct resource io_res[] = {
157 	{
158 		.name = "reserved",
159 		.start = 0x3bc,
160 		.end = 0x3be,
161 		.flags = IORESOURCE_IO | IORESOURCE_BUSY
162 	},
163 	{
164 		.name = "reserved",
165 		.start = 0x378,
166 		.end = 0x37f,
167 		.flags = IORESOURCE_IO | IORESOURCE_BUSY
168 	},
169 	{
170 		.name = "reserved",
171 		.start = 0x278,
172 		.end = 0x27f,
173 		.flags = IORESOURCE_IO | IORESOURCE_BUSY
174 	}
175 };
176 
177 #define lp0 io_res[0]
178 #define lp1 io_res[1]
179 #define lp2 io_res[2]
180 
181 static const char *proc_arch[] = {
182 	"undefined/unknown",
183 	"3",
184 	"4",
185 	"4T",
186 	"5",
187 	"5T",
188 	"5TE",
189 	"5TEJ",
190 	"6TEJ",
191 	"7",
192 	"?(11)",
193 	"?(12)",
194 	"?(13)",
195 	"?(14)",
196 	"?(15)",
197 	"?(16)",
198 	"?(17)",
199 };
200 
201 int cpu_architecture(void)
202 {
203 	int cpu_arch;
204 
205 	if ((read_cpuid_id() & 0x0008f000) == 0) {
206 		cpu_arch = CPU_ARCH_UNKNOWN;
207 	} else if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
208 		cpu_arch = (read_cpuid_id() & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
209 	} else if ((read_cpuid_id() & 0x00080000) == 0x00000000) {
210 		cpu_arch = (read_cpuid_id() >> 16) & 7;
211 		if (cpu_arch)
212 			cpu_arch += CPU_ARCH_ARMv3;
213 	} else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
214 		unsigned int mmfr0;
215 
216 		/* Revised CPUID format. Read the Memory Model Feature
217 		 * Register 0 and check for VMSAv7 or PMSAv7 */
218 		asm("mrc	p15, 0, %0, c0, c1, 4"
219 		    : "=r" (mmfr0));
220 		if ((mmfr0 & 0x0000000f) == 0x00000003 ||
221 		    (mmfr0 & 0x000000f0) == 0x00000030)
222 			cpu_arch = CPU_ARCH_ARMv7;
223 		else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
224 			 (mmfr0 & 0x000000f0) == 0x00000020)
225 			cpu_arch = CPU_ARCH_ARMv6;
226 		else
227 			cpu_arch = CPU_ARCH_UNKNOWN;
228 	} else
229 		cpu_arch = CPU_ARCH_UNKNOWN;
230 
231 	return cpu_arch;
232 }
233 
234 static void __init cacheid_init(void)
235 {
236 	unsigned int cachetype = read_cpuid_cachetype();
237 	unsigned int arch = cpu_architecture();
238 
239 	if (arch >= CPU_ARCH_ARMv6) {
240 		if ((cachetype & (7 << 29)) == 4 << 29) {
241 			/* ARMv7 register format */
242 			cacheid = CACHEID_VIPT_NONALIASING;
243 			if ((cachetype & (3 << 14)) == 1 << 14)
244 				cacheid |= CACHEID_ASID_TAGGED;
245 		} else if (cachetype & (1 << 23))
246 			cacheid = CACHEID_VIPT_ALIASING;
247 		else
248 			cacheid = CACHEID_VIPT_NONALIASING;
249 	} else {
250 		cacheid = CACHEID_VIVT;
251 	}
252 
253 	printk("CPU: %s data cache, %s instruction cache\n",
254 		cache_is_vivt() ? "VIVT" :
255 		cache_is_vipt_aliasing() ? "VIPT aliasing" :
256 		cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown",
257 		cache_is_vivt() ? "VIVT" :
258 		icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
259 		cache_is_vipt_aliasing() ? "VIPT aliasing" :
260 		cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
261 }
262 
263 /*
264  * These functions re-use the assembly code in head.S, which
265  * already provide the required functionality.
266  */
267 extern struct proc_info_list *lookup_processor_type(unsigned int);
268 extern struct machine_desc *lookup_machine_type(unsigned int);
269 
270 static void __init setup_processor(void)
271 {
272 	struct proc_info_list *list;
273 
274 	/*
275 	 * locate processor in the list of supported processor
276 	 * types.  The linker builds this table for us from the
277 	 * entries in arch/arm/mm/proc-*.S
278 	 */
279 	list = lookup_processor_type(read_cpuid_id());
280 	if (!list) {
281 		printk("CPU configuration botched (ID %08x), unable "
282 		       "to continue.\n", read_cpuid_id());
283 		while (1);
284 	}
285 
286 	cpu_name = list->cpu_name;
287 
288 #ifdef MULTI_CPU
289 	processor = *list->proc;
290 #endif
291 #ifdef MULTI_TLB
292 	cpu_tlb = *list->tlb;
293 #endif
294 #ifdef MULTI_USER
295 	cpu_user = *list->user;
296 #endif
297 #ifdef MULTI_CACHE
298 	cpu_cache = *list->cache;
299 #endif
300 
301 	printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n",
302 	       cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
303 	       proc_arch[cpu_architecture()], cr_alignment);
304 
305 	sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS);
306 	sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
307 	elf_hwcap = list->elf_hwcap;
308 #ifndef CONFIG_ARM_THUMB
309 	elf_hwcap &= ~HWCAP_THUMB;
310 #endif
311 
312 	cacheid_init();
313 	cpu_proc_init();
314 }
315 
316 /*
317  * cpu_init - initialise one CPU.
318  *
319  * cpu_init sets up the per-CPU stacks.
320  */
321 void cpu_init(void)
322 {
323 	unsigned int cpu = smp_processor_id();
324 	struct stack *stk = &stacks[cpu];
325 
326 	if (cpu >= NR_CPUS) {
327 		printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu);
328 		BUG();
329 	}
330 
331 	/*
332 	 * Define the placement constraint for the inline asm directive below.
333 	 * In Thumb-2, msr with an immediate value is not allowed.
334 	 */
335 #ifdef CONFIG_THUMB2_KERNEL
336 #define PLC	"r"
337 #else
338 #define PLC	"I"
339 #endif
340 
341 	/*
342 	 * setup stacks for re-entrant exception handlers
343 	 */
344 	__asm__ (
345 	"msr	cpsr_c, %1\n\t"
346 	"add	r14, %0, %2\n\t"
347 	"mov	sp, r14\n\t"
348 	"msr	cpsr_c, %3\n\t"
349 	"add	r14, %0, %4\n\t"
350 	"mov	sp, r14\n\t"
351 	"msr	cpsr_c, %5\n\t"
352 	"add	r14, %0, %6\n\t"
353 	"mov	sp, r14\n\t"
354 	"msr	cpsr_c, %7"
355 	    :
356 	    : "r" (stk),
357 	      PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
358 	      "I" (offsetof(struct stack, irq[0])),
359 	      PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
360 	      "I" (offsetof(struct stack, abt[0])),
361 	      PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE),
362 	      "I" (offsetof(struct stack, und[0])),
363 	      PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
364 	    : "r14");
365 }
366 
367 static struct machine_desc * __init setup_machine(unsigned int nr)
368 {
369 	struct machine_desc *list;
370 
371 	/*
372 	 * locate machine in the list of supported machines.
373 	 */
374 	list = lookup_machine_type(nr);
375 	if (!list) {
376 		printk("Machine configuration botched (nr %d), unable "
377 		       "to continue.\n", nr);
378 		while (1);
379 	}
380 
381 	printk("Machine: %s\n", list->name);
382 
383 	return list;
384 }
385 
386 static int __init arm_add_memory(unsigned long start, unsigned long size)
387 {
388 	struct membank *bank = &meminfo.bank[meminfo.nr_banks];
389 
390 	if (meminfo.nr_banks >= NR_BANKS) {
391 		printk(KERN_CRIT "NR_BANKS too low, "
392 			"ignoring memory at %#lx\n", start);
393 		return -EINVAL;
394 	}
395 
396 	/*
397 	 * Ensure that start/size are aligned to a page boundary.
398 	 * Size is appropriately rounded down, start is rounded up.
399 	 */
400 	size -= start & ~PAGE_MASK;
401 	bank->start = PAGE_ALIGN(start);
402 	bank->size  = size & PAGE_MASK;
403 	bank->node  = PHYS_TO_NID(start);
404 
405 	/*
406 	 * Check whether this memory region has non-zero size or
407 	 * invalid node number.
408 	 */
409 	if (bank->size == 0 || bank->node >= MAX_NUMNODES)
410 		return -EINVAL;
411 
412 	meminfo.nr_banks++;
413 	return 0;
414 }
415 
416 /*
417  * Pick out the memory size.  We look for mem=size@start,
418  * where start and size are "size[KkMm]"
419  */
420 static void __init early_mem(char **p)
421 {
422 	static int usermem __initdata = 0;
423 	unsigned long size, start;
424 
425 	/*
426 	 * If the user specifies memory size, we
427 	 * blow away any automatically generated
428 	 * size.
429 	 */
430 	if (usermem == 0) {
431 		usermem = 1;
432 		meminfo.nr_banks = 0;
433 	}
434 
435 	start = PHYS_OFFSET;
436 	size  = memparse(*p, p);
437 	if (**p == '@')
438 		start = memparse(*p + 1, p);
439 
440 	arm_add_memory(start, size);
441 }
442 __early_param("mem=", early_mem);
443 
444 /*
445  * Initial parsing of the command line.
446  */
447 static void __init parse_cmdline(char **cmdline_p, char *from)
448 {
449 	char c = ' ', *to = command_line;
450 	int len = 0;
451 
452 	for (;;) {
453 		if (c == ' ') {
454 			extern struct early_params __early_begin, __early_end;
455 			struct early_params *p;
456 
457 			for (p = &__early_begin; p < &__early_end; p++) {
458 				int arglen = strlen(p->arg);
459 
460 				if (memcmp(from, p->arg, arglen) == 0) {
461 					if (to != command_line)
462 						to -= 1;
463 					from += arglen;
464 					p->fn(&from);
465 
466 					while (*from != ' ' && *from != '\0')
467 						from++;
468 					break;
469 				}
470 			}
471 		}
472 		c = *from++;
473 		if (!c)
474 			break;
475 		if (COMMAND_LINE_SIZE <= ++len)
476 			break;
477 		*to++ = c;
478 	}
479 	*to = '\0';
480 	*cmdline_p = command_line;
481 }
482 
483 static void __init
484 setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
485 {
486 #ifdef CONFIG_BLK_DEV_RAM
487 	extern int rd_size, rd_image_start, rd_prompt, rd_doload;
488 
489 	rd_image_start = image_start;
490 	rd_prompt = prompt;
491 	rd_doload = doload;
492 
493 	if (rd_sz)
494 		rd_size = rd_sz;
495 #endif
496 }
497 
498 static void __init
499 request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
500 {
501 	struct resource *res;
502 	int i;
503 
504 	kernel_code.start   = virt_to_phys(_text);
505 	kernel_code.end     = virt_to_phys(_etext - 1);
506 	kernel_data.start   = virt_to_phys(_data);
507 	kernel_data.end     = virt_to_phys(_end - 1);
508 
509 	for (i = 0; i < mi->nr_banks; i++) {
510 		if (mi->bank[i].size == 0)
511 			continue;
512 
513 		res = alloc_bootmem_low(sizeof(*res));
514 		res->name  = "System RAM";
515 		res->start = mi->bank[i].start;
516 		res->end   = mi->bank[i].start + mi->bank[i].size - 1;
517 		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
518 
519 		request_resource(&iomem_resource, res);
520 
521 		if (kernel_code.start >= res->start &&
522 		    kernel_code.end <= res->end)
523 			request_resource(res, &kernel_code);
524 		if (kernel_data.start >= res->start &&
525 		    kernel_data.end <= res->end)
526 			request_resource(res, &kernel_data);
527 	}
528 
529 	if (mdesc->video_start) {
530 		video_ram.start = mdesc->video_start;
531 		video_ram.end   = mdesc->video_end;
532 		request_resource(&iomem_resource, &video_ram);
533 	}
534 
535 	/*
536 	 * Some machines don't have the possibility of ever
537 	 * possessing lp0, lp1 or lp2
538 	 */
539 	if (mdesc->reserve_lp0)
540 		request_resource(&ioport_resource, &lp0);
541 	if (mdesc->reserve_lp1)
542 		request_resource(&ioport_resource, &lp1);
543 	if (mdesc->reserve_lp2)
544 		request_resource(&ioport_resource, &lp2);
545 }
546 
547 /*
548  *  Tag parsing.
549  *
550  * This is the new way of passing data to the kernel at boot time.  Rather
551  * than passing a fixed inflexible structure to the kernel, we pass a list
552  * of variable-sized tags to the kernel.  The first tag must be a ATAG_CORE
553  * tag for the list to be recognised (to distinguish the tagged list from
554  * a param_struct).  The list is terminated with a zero-length tag (this tag
555  * is not parsed in any way).
556  */
557 static int __init parse_tag_core(const struct tag *tag)
558 {
559 	if (tag->hdr.size > 2) {
560 		if ((tag->u.core.flags & 1) == 0)
561 			root_mountflags &= ~MS_RDONLY;
562 		ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
563 	}
564 	return 0;
565 }
566 
567 __tagtable(ATAG_CORE, parse_tag_core);
568 
569 static int __init parse_tag_mem32(const struct tag *tag)
570 {
571 	return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
572 }
573 
574 __tagtable(ATAG_MEM, parse_tag_mem32);
575 
576 #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
577 struct screen_info screen_info = {
578  .orig_video_lines	= 30,
579  .orig_video_cols	= 80,
580  .orig_video_mode	= 0,
581  .orig_video_ega_bx	= 0,
582  .orig_video_isVGA	= 1,
583  .orig_video_points	= 8
584 };
585 
586 static int __init parse_tag_videotext(const struct tag *tag)
587 {
588 	screen_info.orig_x            = tag->u.videotext.x;
589 	screen_info.orig_y            = tag->u.videotext.y;
590 	screen_info.orig_video_page   = tag->u.videotext.video_page;
591 	screen_info.orig_video_mode   = tag->u.videotext.video_mode;
592 	screen_info.orig_video_cols   = tag->u.videotext.video_cols;
593 	screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
594 	screen_info.orig_video_lines  = tag->u.videotext.video_lines;
595 	screen_info.orig_video_isVGA  = tag->u.videotext.video_isvga;
596 	screen_info.orig_video_points = tag->u.videotext.video_points;
597 	return 0;
598 }
599 
600 __tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
601 #endif
602 
603 static int __init parse_tag_ramdisk(const struct tag *tag)
604 {
605 	setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
606 		      (tag->u.ramdisk.flags & 2) == 0,
607 		      tag->u.ramdisk.start, tag->u.ramdisk.size);
608 	return 0;
609 }
610 
611 __tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
612 
613 static int __init parse_tag_serialnr(const struct tag *tag)
614 {
615 	system_serial_low = tag->u.serialnr.low;
616 	system_serial_high = tag->u.serialnr.high;
617 	return 0;
618 }
619 
620 __tagtable(ATAG_SERIAL, parse_tag_serialnr);
621 
622 static int __init parse_tag_revision(const struct tag *tag)
623 {
624 	system_rev = tag->u.revision.rev;
625 	return 0;
626 }
627 
628 __tagtable(ATAG_REVISION, parse_tag_revision);
629 
630 static int __init parse_tag_cmdline(const struct tag *tag)
631 {
632 	strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
633 	return 0;
634 }
635 
636 __tagtable(ATAG_CMDLINE, parse_tag_cmdline);
637 
638 /*
639  * Scan the tag table for this tag, and call its parse function.
640  * The tag table is built by the linker from all the __tagtable
641  * declarations.
642  */
643 static int __init parse_tag(const struct tag *tag)
644 {
645 	extern struct tagtable __tagtable_begin, __tagtable_end;
646 	struct tagtable *t;
647 
648 	for (t = &__tagtable_begin; t < &__tagtable_end; t++)
649 		if (tag->hdr.tag == t->tag) {
650 			t->parse(tag);
651 			break;
652 		}
653 
654 	return t < &__tagtable_end;
655 }
656 
657 /*
658  * Parse all tags in the list, checking both the global and architecture
659  * specific tag tables.
660  */
661 static void __init parse_tags(const struct tag *t)
662 {
663 	for (; t->hdr.size; t = tag_next(t))
664 		if (!parse_tag(t))
665 			printk(KERN_WARNING
666 				"Ignoring unrecognised tag 0x%08x\n",
667 				t->hdr.tag);
668 }
669 
670 /*
671  * This holds our defaults.
672  */
673 static struct init_tags {
674 	struct tag_header hdr1;
675 	struct tag_core   core;
676 	struct tag_header hdr2;
677 	struct tag_mem32  mem;
678 	struct tag_header hdr3;
679 } init_tags __initdata = {
680 	{ tag_size(tag_core), ATAG_CORE },
681 	{ 1, PAGE_SIZE, 0xff },
682 	{ tag_size(tag_mem32), ATAG_MEM },
683 	{ MEM_SIZE, PHYS_OFFSET },
684 	{ 0, ATAG_NONE }
685 };
686 
687 static void (*init_machine)(void) __initdata;
688 
689 static int __init customize_machine(void)
690 {
691 	/* customizes platform devices, or adds new ones */
692 	if (init_machine)
693 		init_machine();
694 	return 0;
695 }
696 arch_initcall(customize_machine);
697 
698 void __init setup_arch(char **cmdline_p)
699 {
700 	struct tag *tags = (struct tag *)&init_tags;
701 	struct machine_desc *mdesc;
702 	char *from = default_command_line;
703 
704 	unwind_init();
705 
706 	setup_processor();
707 	mdesc = setup_machine(machine_arch_type);
708 	machine_name = mdesc->name;
709 
710 	if (mdesc->soft_reboot)
711 		reboot_setup("s");
712 
713 	if (__atags_pointer)
714 		tags = phys_to_virt(__atags_pointer);
715 	else if (mdesc->boot_params)
716 		tags = phys_to_virt(mdesc->boot_params);
717 
718 	/*
719 	 * If we have the old style parameters, convert them to
720 	 * a tag list.
721 	 */
722 	if (tags->hdr.tag != ATAG_CORE)
723 		convert_to_tag_list(tags);
724 	if (tags->hdr.tag != ATAG_CORE)
725 		tags = (struct tag *)&init_tags;
726 
727 	if (mdesc->fixup)
728 		mdesc->fixup(mdesc, tags, &from, &meminfo);
729 
730 	if (tags->hdr.tag == ATAG_CORE) {
731 		if (meminfo.nr_banks != 0)
732 			squash_mem_tags(tags);
733 		save_atags(tags);
734 		parse_tags(tags);
735 	}
736 
737 	init_mm.start_code = (unsigned long) _text;
738 	init_mm.end_code   = (unsigned long) _etext;
739 	init_mm.end_data   = (unsigned long) _edata;
740 	init_mm.brk	   = (unsigned long) _end;
741 
742 	memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
743 	boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
744 	parse_cmdline(cmdline_p, from);
745 	paging_init(mdesc);
746 	request_standard_resources(&meminfo, mdesc);
747 
748 #ifdef CONFIG_SMP
749 	smp_init_cpus();
750 #endif
751 
752 	cpu_init();
753 	tcm_init();
754 
755 	/*
756 	 * Set up various architecture-specific pointers
757 	 */
758 	init_arch_irq = mdesc->init_irq;
759 	system_timer = mdesc->timer;
760 	init_machine = mdesc->init_machine;
761 
762 #ifdef CONFIG_VT
763 #if defined(CONFIG_VGA_CONSOLE)
764 	conswitchp = &vga_con;
765 #elif defined(CONFIG_DUMMY_CONSOLE)
766 	conswitchp = &dummy_con;
767 #endif
768 #endif
769 	early_trap_init();
770 }
771 
772 
773 static int __init topology_init(void)
774 {
775 	int cpu;
776 
777 	for_each_possible_cpu(cpu) {
778 		struct cpuinfo_arm *cpuinfo = &per_cpu(cpu_data, cpu);
779 		cpuinfo->cpu.hotpluggable = 1;
780 		register_cpu(&cpuinfo->cpu, cpu);
781 	}
782 
783 	return 0;
784 }
785 
786 subsys_initcall(topology_init);
787 
788 static const char *hwcap_str[] = {
789 	"swp",
790 	"half",
791 	"thumb",
792 	"26bit",
793 	"fastmult",
794 	"fpa",
795 	"vfp",
796 	"edsp",
797 	"java",
798 	"iwmmxt",
799 	"crunch",
800 	"thumbee",
801 	"neon",
802 	"vfpv3",
803 	"vfpv3d16",
804 	NULL
805 };
806 
807 static int c_show(struct seq_file *m, void *v)
808 {
809 	int i;
810 
811 	seq_printf(m, "Processor\t: %s rev %d (%s)\n",
812 		   cpu_name, read_cpuid_id() & 15, elf_platform);
813 
814 #if defined(CONFIG_SMP)
815 	for_each_online_cpu(i) {
816 		/*
817 		 * glibc reads /proc/cpuinfo to determine the number of
818 		 * online processors, looking for lines beginning with
819 		 * "processor".  Give glibc what it expects.
820 		 */
821 		seq_printf(m, "processor\t: %d\n", i);
822 		seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
823 			   per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
824 			   (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);
825 	}
826 #else /* CONFIG_SMP */
827 	seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
828 		   loops_per_jiffy / (500000/HZ),
829 		   (loops_per_jiffy / (5000/HZ)) % 100);
830 #endif
831 
832 	/* dump out the processor features */
833 	seq_puts(m, "Features\t: ");
834 
835 	for (i = 0; hwcap_str[i]; i++)
836 		if (elf_hwcap & (1 << i))
837 			seq_printf(m, "%s ", hwcap_str[i]);
838 
839 	seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
840 	seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]);
841 
842 	if ((read_cpuid_id() & 0x0008f000) == 0x00000000) {
843 		/* pre-ARM7 */
844 		seq_printf(m, "CPU part\t: %07x\n", read_cpuid_id() >> 4);
845 	} else {
846 		if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
847 			/* ARM7 */
848 			seq_printf(m, "CPU variant\t: 0x%02x\n",
849 				   (read_cpuid_id() >> 16) & 127);
850 		} else {
851 			/* post-ARM7 */
852 			seq_printf(m, "CPU variant\t: 0x%x\n",
853 				   (read_cpuid_id() >> 20) & 15);
854 		}
855 		seq_printf(m, "CPU part\t: 0x%03x\n",
856 			   (read_cpuid_id() >> 4) & 0xfff);
857 	}
858 	seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);
859 
860 	seq_puts(m, "\n");
861 
862 	seq_printf(m, "Hardware\t: %s\n", machine_name);
863 	seq_printf(m, "Revision\t: %04x\n", system_rev);
864 	seq_printf(m, "Serial\t\t: %08x%08x\n",
865 		   system_serial_high, system_serial_low);
866 
867 	return 0;
868 }
869 
870 static void *c_start(struct seq_file *m, loff_t *pos)
871 {
872 	return *pos < 1 ? (void *)1 : NULL;
873 }
874 
875 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
876 {
877 	++*pos;
878 	return NULL;
879 }
880 
881 static void c_stop(struct seq_file *m, void *v)
882 {
883 }
884 
885 const struct seq_operations cpuinfo_op = {
886 	.start	= c_start,
887 	.next	= c_next,
888 	.stop	= c_stop,
889 	.show	= c_show
890 };
891