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