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