]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - arch/arm/kernel/setup.c
ARM: sort the meminfo array earlier
[mirror_ubuntu-artful-kernel.git] / arch / arm / kernel / setup.c
CommitLineData
1da177e4
LT
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 */
ecea4ab6 10#include <linux/export.h>
1da177e4
LT
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>
894673ee 20#include <linux/screen_info.h>
1da177e4 21#include <linux/init.h>
3c57fb43 22#include <linux/kexec.h>
93c02ab4 23#include <linux/of_fdt.h>
cea0bb1b 24#include <linux/crash_dump.h>
1da177e4
LT
25#include <linux/root_dev.h>
26#include <linux/cpu.h>
27#include <linux/interrupt.h>
7bbb7940 28#include <linux/smp.h>
4e950f6f 29#include <linux/fs.h>
e119bfff 30#include <linux/proc_fs.h>
2778f620 31#include <linux/memblock.h>
2ecccf90
DM
32#include <linux/bug.h>
33#include <linux/compiler.h>
27a3f0e9 34#include <linux/sort.h>
1da177e4 35
b86040a5 36#include <asm/unified.h>
1da177e4 37#include <asm/cpu.h>
0ba8b9b2 38#include <asm/cputype.h>
1da177e4 39#include <asm/elf.h>
1da177e4 40#include <asm/procinfo.h>
37efe642 41#include <asm/sections.h>
1da177e4 42#include <asm/setup.h>
f00ec48f 43#include <asm/smp_plat.h>
1da177e4
LT
44#include <asm/mach-types.h>
45#include <asm/cacheflush.h>
46097c7d 46#include <asm/cachetype.h>
1da177e4 47#include <asm/tlbflush.h>
2ecccf90 48#include <asm/system.h>
1da177e4 49
93c02ab4 50#include <asm/prom.h>
1da177e4
LT
51#include <asm/mach/arch.h>
52#include <asm/mach/irq.h>
53#include <asm/mach/time.h>
5cbad0eb 54#include <asm/traps.h>
bff595c1 55#include <asm/unwind.h>
1da177e4 56
73a65b3f 57#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
0fc1c832 58#include "compat.h"
73a65b3f 59#endif
4cd9d6f7 60#include "atags.h"
bc581770 61#include "tcm.h"
0fc1c832 62
1da177e4
LT
63#ifndef MEM_SIZE
64#define MEM_SIZE (16*1024*1024)
65#endif
66
67#if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
68char fpe_type[8];
69
70static int __init fpe_setup(char *line)
71{
72 memcpy(fpe_type, line, 8);
73 return 1;
74}
75
76__setup("fpe=", fpe_setup);
77#endif
78
4b5f32ce 79extern void paging_init(struct machine_desc *desc);
0371d3f7 80extern void sanity_check_meminfo(void);
1da177e4 81extern void reboot_setup(char *str);
1da177e4
LT
82
83unsigned int processor_id;
c18f6581 84EXPORT_SYMBOL(processor_id);
0385ebc0 85unsigned int __machine_arch_type __read_mostly;
1da177e4 86EXPORT_SYMBOL(__machine_arch_type);
0385ebc0 87unsigned int cacheid __read_mostly;
c0e95878 88EXPORT_SYMBOL(cacheid);
1da177e4 89
9d20fdd5
BG
90unsigned int __atags_pointer __initdata;
91
1da177e4
LT
92unsigned int system_rev;
93EXPORT_SYMBOL(system_rev);
94
95unsigned int system_serial_low;
96EXPORT_SYMBOL(system_serial_low);
97
98unsigned int system_serial_high;
99EXPORT_SYMBOL(system_serial_high);
100
0385ebc0 101unsigned int elf_hwcap __read_mostly;
1da177e4
LT
102EXPORT_SYMBOL(elf_hwcap);
103
104
105#ifdef MULTI_CPU
0385ebc0 106struct processor processor __read_mostly;
1da177e4
LT
107#endif
108#ifdef MULTI_TLB
0385ebc0 109struct cpu_tlb_fns cpu_tlb __read_mostly;
1da177e4
LT
110#endif
111#ifdef MULTI_USER
0385ebc0 112struct cpu_user_fns cpu_user __read_mostly;
1da177e4
LT
113#endif
114#ifdef MULTI_CACHE
0385ebc0 115struct cpu_cache_fns cpu_cache __read_mostly;
1da177e4 116#endif
953233dc 117#ifdef CONFIG_OUTER_CACHE
0385ebc0 118struct outer_cache_fns outer_cache __read_mostly;
6c09f09d 119EXPORT_SYMBOL(outer_cache);
953233dc 120#endif
1da177e4 121
2ecccf90
DM
122/*
123 * Cached cpu_architecture() result for use by assembler code.
124 * C code should use the cpu_architecture() function instead of accessing this
125 * variable directly.
126 */
127int __cpu_architecture __read_mostly = CPU_ARCH_UNKNOWN;
128
ccea7a19
RK
129struct stack {
130 u32 irq[3];
131 u32 abt[3];
132 u32 und[3];
133} ____cacheline_aligned;
134
135static struct stack stacks[NR_CPUS];
136
1da177e4
LT
137char elf_platform[ELF_PLATFORM_SIZE];
138EXPORT_SYMBOL(elf_platform);
139
1da177e4
LT
140static const char *cpu_name;
141static const char *machine_name;
48ab7e09 142static char __initdata cmd_line[COMMAND_LINE_SIZE];
8ff1443c 143struct machine_desc *machine_desc __initdata;
1da177e4
LT
144
145static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
146static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
147#define ENDIANNESS ((char)endian_test.l)
148
149DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data);
150
151/*
152 * Standard memory resources
153 */
154static struct resource mem_res[] = {
740e518e
GKH
155 {
156 .name = "Video RAM",
157 .start = 0,
158 .end = 0,
159 .flags = IORESOURCE_MEM
160 },
161 {
162 .name = "Kernel text",
163 .start = 0,
164 .end = 0,
165 .flags = IORESOURCE_MEM
166 },
167 {
168 .name = "Kernel data",
169 .start = 0,
170 .end = 0,
171 .flags = IORESOURCE_MEM
172 }
1da177e4
LT
173};
174
175#define video_ram mem_res[0]
176#define kernel_code mem_res[1]
177#define kernel_data mem_res[2]
178
179static struct resource io_res[] = {
740e518e
GKH
180 {
181 .name = "reserved",
182 .start = 0x3bc,
183 .end = 0x3be,
184 .flags = IORESOURCE_IO | IORESOURCE_BUSY
185 },
186 {
187 .name = "reserved",
188 .start = 0x378,
189 .end = 0x37f,
190 .flags = IORESOURCE_IO | IORESOURCE_BUSY
191 },
192 {
193 .name = "reserved",
194 .start = 0x278,
195 .end = 0x27f,
196 .flags = IORESOURCE_IO | IORESOURCE_BUSY
197 }
1da177e4
LT
198};
199
200#define lp0 io_res[0]
201#define lp1 io_res[1]
202#define lp2 io_res[2]
203
1da177e4
LT
204static const char *proc_arch[] = {
205 "undefined/unknown",
206 "3",
207 "4",
208 "4T",
209 "5",
210 "5T",
211 "5TE",
212 "5TEJ",
213 "6TEJ",
6b090a25 214 "7",
1da177e4
LT
215 "?(11)",
216 "?(12)",
217 "?(13)",
218 "?(14)",
219 "?(15)",
220 "?(16)",
221 "?(17)",
222};
223
2ecccf90 224static int __get_cpu_architecture(void)
1da177e4
LT
225{
226 int cpu_arch;
227
0ba8b9b2 228 if ((read_cpuid_id() & 0x0008f000) == 0) {
1da177e4 229 cpu_arch = CPU_ARCH_UNKNOWN;
0ba8b9b2
RK
230 } else if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
231 cpu_arch = (read_cpuid_id() & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
232 } else if ((read_cpuid_id() & 0x00080000) == 0x00000000) {
233 cpu_arch = (read_cpuid_id() >> 16) & 7;
1da177e4
LT
234 if (cpu_arch)
235 cpu_arch += CPU_ARCH_ARMv3;
0ba8b9b2 236 } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
180005c4
CM
237 unsigned int mmfr0;
238
239 /* Revised CPUID format. Read the Memory Model Feature
240 * Register 0 and check for VMSAv7 or PMSAv7 */
241 asm("mrc p15, 0, %0, c0, c1, 4"
242 : "=r" (mmfr0));
315cfe78
CM
243 if ((mmfr0 & 0x0000000f) >= 0x00000003 ||
244 (mmfr0 & 0x000000f0) >= 0x00000030)
180005c4
CM
245 cpu_arch = CPU_ARCH_ARMv7;
246 else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
247 (mmfr0 & 0x000000f0) == 0x00000020)
248 cpu_arch = CPU_ARCH_ARMv6;
249 else
250 cpu_arch = CPU_ARCH_UNKNOWN;
251 } else
252 cpu_arch = CPU_ARCH_UNKNOWN;
1da177e4
LT
253
254 return cpu_arch;
255}
256
2ecccf90
DM
257int __pure cpu_architecture(void)
258{
259 BUG_ON(__cpu_architecture == CPU_ARCH_UNKNOWN);
260
261 return __cpu_architecture;
262}
263
8925ec4c
WD
264static int cpu_has_aliasing_icache(unsigned int arch)
265{
266 int aliasing_icache;
267 unsigned int id_reg, num_sets, line_size;
268
7f94e9cc
WD
269 /* PIPT caches never alias. */
270 if (icache_is_pipt())
271 return 0;
272
8925ec4c
WD
273 /* arch specifies the register format */
274 switch (arch) {
275 case CPU_ARCH_ARMv7:
5fb31a96
LW
276 asm("mcr p15, 2, %0, c0, c0, 0 @ set CSSELR"
277 : /* No output operands */
8925ec4c 278 : "r" (1));
5fb31a96
LW
279 isb();
280 asm("mrc p15, 1, %0, c0, c0, 0 @ read CCSIDR"
281 : "=r" (id_reg));
8925ec4c
WD
282 line_size = 4 << ((id_reg & 0x7) + 2);
283 num_sets = ((id_reg >> 13) & 0x7fff) + 1;
284 aliasing_icache = (line_size * num_sets) > PAGE_SIZE;
285 break;
286 case CPU_ARCH_ARMv6:
287 aliasing_icache = read_cpuid_cachetype() & (1 << 11);
288 break;
289 default:
290 /* I-cache aliases will be handled by D-cache aliasing code */
291 aliasing_icache = 0;
292 }
293
294 return aliasing_icache;
295}
296
c0e95878
RK
297static void __init cacheid_init(void)
298{
299 unsigned int cachetype = read_cpuid_cachetype();
300 unsigned int arch = cpu_architecture();
301
b57ee99f
CM
302 if (arch >= CPU_ARCH_ARMv6) {
303 if ((cachetype & (7 << 29)) == 4 << 29) {
304 /* ARMv7 register format */
72dc53ac 305 arch = CPU_ARCH_ARMv7;
b57ee99f 306 cacheid = CACHEID_VIPT_NONALIASING;
7f94e9cc
WD
307 switch (cachetype & (3 << 14)) {
308 case (1 << 14):
b57ee99f 309 cacheid |= CACHEID_ASID_TAGGED;
7f94e9cc
WD
310 break;
311 case (3 << 14):
312 cacheid |= CACHEID_PIPT;
313 break;
314 }
8925ec4c 315 } else {
72dc53ac
WD
316 arch = CPU_ARCH_ARMv6;
317 if (cachetype & (1 << 23))
318 cacheid = CACHEID_VIPT_ALIASING;
319 else
320 cacheid = CACHEID_VIPT_NONALIASING;
8925ec4c 321 }
72dc53ac
WD
322 if (cpu_has_aliasing_icache(arch))
323 cacheid |= CACHEID_VIPT_I_ALIASING;
c0e95878
RK
324 } else {
325 cacheid = CACHEID_VIVT;
326 }
2b4ae1f1
RK
327
328 printk("CPU: %s data cache, %s instruction cache\n",
329 cache_is_vivt() ? "VIVT" :
330 cache_is_vipt_aliasing() ? "VIPT aliasing" :
7f94e9cc 331 cache_is_vipt_nonaliasing() ? "PIPT / VIPT nonaliasing" : "unknown",
2b4ae1f1
RK
332 cache_is_vivt() ? "VIVT" :
333 icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
8925ec4c 334 icache_is_vipt_aliasing() ? "VIPT aliasing" :
7f94e9cc 335 icache_is_pipt() ? "PIPT" :
2b4ae1f1 336 cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
c0e95878
RK
337}
338
1da177e4
LT
339/*
340 * These functions re-use the assembly code in head.S, which
341 * already provide the required functionality.
342 */
0f44ba1d 343extern struct proc_info_list *lookup_processor_type(unsigned int);
6fc31d54 344
93c02ab4 345void __init early_print(const char *str, ...)
6fc31d54
RK
346{
347 extern void printascii(const char *);
348 char buf[256];
349 va_list ap;
350
351 va_start(ap, str);
352 vsnprintf(buf, sizeof(buf), str, ap);
353 va_end(ap);
354
355#ifdef CONFIG_DEBUG_LL
356 printascii(buf);
357#endif
358 printk("%s", buf);
359}
360
f159f4ed
TL
361static void __init feat_v6_fixup(void)
362{
363 int id = read_cpuid_id();
364
365 if ((id & 0xff0f0000) != 0x41070000)
366 return;
367
368 /*
369 * HWCAP_TLS is available only on 1136 r1p0 and later,
370 * see also kuser_get_tls_init.
371 */
372 if ((((id >> 4) & 0xfff) == 0xb36) && (((id >> 20) & 3) == 0))
373 elf_hwcap &= ~HWCAP_TLS;
374}
375
ccea7a19
RK
376/*
377 * cpu_init - initialise one CPU.
378 *
90f1e084 379 * cpu_init sets up the per-CPU stacks.
ccea7a19 380 */
36c5ed23 381void cpu_init(void)
ccea7a19
RK
382{
383 unsigned int cpu = smp_processor_id();
384 struct stack *stk = &stacks[cpu];
385
386 if (cpu >= NR_CPUS) {
387 printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu);
388 BUG();
389 }
390
b69874e4
RK
391 cpu_proc_init();
392
b86040a5
CM
393 /*
394 * Define the placement constraint for the inline asm directive below.
395 * In Thumb-2, msr with an immediate value is not allowed.
396 */
397#ifdef CONFIG_THUMB2_KERNEL
398#define PLC "r"
399#else
400#define PLC "I"
401#endif
402
ccea7a19
RK
403 /*
404 * setup stacks for re-entrant exception handlers
405 */
406 __asm__ (
407 "msr cpsr_c, %1\n\t"
b86040a5
CM
408 "add r14, %0, %2\n\t"
409 "mov sp, r14\n\t"
ccea7a19 410 "msr cpsr_c, %3\n\t"
b86040a5
CM
411 "add r14, %0, %4\n\t"
412 "mov sp, r14\n\t"
ccea7a19 413 "msr cpsr_c, %5\n\t"
b86040a5
CM
414 "add r14, %0, %6\n\t"
415 "mov sp, r14\n\t"
ccea7a19
RK
416 "msr cpsr_c, %7"
417 :
418 : "r" (stk),
b86040a5 419 PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
ccea7a19 420 "I" (offsetof(struct stack, irq[0])),
b86040a5 421 PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
ccea7a19 422 "I" (offsetof(struct stack, abt[0])),
b86040a5 423 PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE),
ccea7a19 424 "I" (offsetof(struct stack, und[0])),
b86040a5 425 PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
aaaa3f9e 426 : "r14");
ccea7a19
RK
427}
428
b69874e4
RK
429static void __init setup_processor(void)
430{
431 struct proc_info_list *list;
432
433 /*
434 * locate processor in the list of supported processor
435 * types. The linker builds this table for us from the
436 * entries in arch/arm/mm/proc-*.S
437 */
438 list = lookup_processor_type(read_cpuid_id());
439 if (!list) {
440 printk("CPU configuration botched (ID %08x), unable "
441 "to continue.\n", read_cpuid_id());
442 while (1);
443 }
444
445 cpu_name = list->cpu_name;
2ecccf90 446 __cpu_architecture = __get_cpu_architecture();
b69874e4
RK
447
448#ifdef MULTI_CPU
449 processor = *list->proc;
450#endif
451#ifdef MULTI_TLB
452 cpu_tlb = *list->tlb;
453#endif
454#ifdef MULTI_USER
455 cpu_user = *list->user;
456#endif
457#ifdef MULTI_CACHE
458 cpu_cache = *list->cache;
459#endif
460
461 printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n",
462 cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
463 proc_arch[cpu_architecture()], cr_alignment);
464
465 sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS);
466 sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
467 elf_hwcap = list->elf_hwcap;
468#ifndef CONFIG_ARM_THUMB
469 elf_hwcap &= ~HWCAP_THUMB;
470#endif
471
472 feat_v6_fixup();
473
474 cacheid_init();
475 cpu_init();
476}
477
93c02ab4 478void __init dump_machine_table(void)
1da177e4 479{
dce72dd0 480 struct machine_desc *p;
1da177e4 481
6291319d
GL
482 early_print("Available machine support:\n\nID (hex)\tNAME\n");
483 for_each_machine_desc(p)
dce72dd0 484 early_print("%08x\t%s\n", p->nr, p->name);
1da177e4 485
dce72dd0 486 early_print("\nPlease check your kernel config and/or bootloader.\n");
1da177e4 487
dce72dd0
NP
488 while (true)
489 /* can't use cpu_relax() here as it may require MMU setup */;
1da177e4
LT
490}
491
9eb8f674 492int __init arm_add_memory(phys_addr_t start, unsigned long size)
3a669411 493{
4b5f32ce
NP
494 struct membank *bank = &meminfo.bank[meminfo.nr_banks];
495
496 if (meminfo.nr_banks >= NR_BANKS) {
497 printk(KERN_CRIT "NR_BANKS too low, "
29a38193 498 "ignoring memory at 0x%08llx\n", (long long)start);
4b5f32ce
NP
499 return -EINVAL;
500 }
05f96ef1 501
3a669411
RK
502 /*
503 * Ensure that start/size are aligned to a page boundary.
504 * Size is appropriately rounded down, start is rounded up.
505 */
506 size -= start & ~PAGE_MASK;
05f96ef1
RK
507 bank->start = PAGE_ALIGN(start);
508 bank->size = size & PAGE_MASK;
4b5f32ce
NP
509
510 /*
511 * Check whether this memory region has non-zero size or
512 * invalid node number.
513 */
be370302 514 if (bank->size == 0)
4b5f32ce
NP
515 return -EINVAL;
516
517 meminfo.nr_banks++;
518 return 0;
3a669411
RK
519}
520
1da177e4
LT
521/*
522 * Pick out the memory size. We look for mem=size@start,
523 * where start and size are "size[KkMm]"
524 */
2b0d8c25 525static int __init early_mem(char *p)
1da177e4
LT
526{
527 static int usermem __initdata = 0;
f60892d3
WD
528 unsigned long size;
529 phys_addr_t start;
2b0d8c25 530 char *endp;
1da177e4
LT
531
532 /*
533 * If the user specifies memory size, we
534 * blow away any automatically generated
535 * size.
536 */
537 if (usermem == 0) {
538 usermem = 1;
539 meminfo.nr_banks = 0;
540 }
541
542 start = PHYS_OFFSET;
2b0d8c25
JK
543 size = memparse(p, &endp);
544 if (*endp == '@')
545 start = memparse(endp + 1, NULL);
1da177e4 546
1c97b73e 547 arm_add_memory(start, size);
1da177e4 548
2b0d8c25 549 return 0;
1da177e4 550}
2b0d8c25 551early_param("mem", early_mem);
1da177e4
LT
552
553static void __init
554setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
555{
556#ifdef CONFIG_BLK_DEV_RAM
557 extern int rd_size, rd_image_start, rd_prompt, rd_doload;
558
559 rd_image_start = image_start;
560 rd_prompt = prompt;
561 rd_doload = doload;
562
563 if (rd_sz)
564 rd_size = rd_sz;
565#endif
566}
567
11b9369c 568static void __init request_standard_resources(struct machine_desc *mdesc)
1da177e4 569{
11b9369c 570 struct memblock_region *region;
1da177e4 571 struct resource *res;
1da177e4 572
37efe642
RK
573 kernel_code.start = virt_to_phys(_text);
574 kernel_code.end = virt_to_phys(_etext - 1);
842eab40 575 kernel_data.start = virt_to_phys(_sdata);
37efe642 576 kernel_data.end = virt_to_phys(_end - 1);
1da177e4 577
11b9369c 578 for_each_memblock(memory, region) {
1da177e4
LT
579 res = alloc_bootmem_low(sizeof(*res));
580 res->name = "System RAM";
11b9369c
DZ
581 res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
582 res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
1da177e4
LT
583 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
584
585 request_resource(&iomem_resource, res);
586
587 if (kernel_code.start >= res->start &&
588 kernel_code.end <= res->end)
589 request_resource(res, &kernel_code);
590 if (kernel_data.start >= res->start &&
591 kernel_data.end <= res->end)
592 request_resource(res, &kernel_data);
593 }
594
595 if (mdesc->video_start) {
596 video_ram.start = mdesc->video_start;
597 video_ram.end = mdesc->video_end;
598 request_resource(&iomem_resource, &video_ram);
599 }
600
601 /*
602 * Some machines don't have the possibility of ever
603 * possessing lp0, lp1 or lp2
604 */
605 if (mdesc->reserve_lp0)
606 request_resource(&ioport_resource, &lp0);
607 if (mdesc->reserve_lp1)
608 request_resource(&ioport_resource, &lp1);
609 if (mdesc->reserve_lp2)
610 request_resource(&ioport_resource, &lp2);
611}
612
613/*
614 * Tag parsing.
615 *
616 * This is the new way of passing data to the kernel at boot time. Rather
617 * than passing a fixed inflexible structure to the kernel, we pass a list
618 * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE
619 * tag for the list to be recognised (to distinguish the tagged list from
620 * a param_struct). The list is terminated with a zero-length tag (this tag
621 * is not parsed in any way).
622 */
623static int __init parse_tag_core(const struct tag *tag)
624{
625 if (tag->hdr.size > 2) {
626 if ((tag->u.core.flags & 1) == 0)
627 root_mountflags &= ~MS_RDONLY;
628 ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
629 }
630 return 0;
631}
632
633__tagtable(ATAG_CORE, parse_tag_core);
634
635static int __init parse_tag_mem32(const struct tag *tag)
636{
4b5f32ce 637 return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
1da177e4
LT
638}
639
640__tagtable(ATAG_MEM, parse_tag_mem32);
641
642#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
643struct screen_info screen_info = {
644 .orig_video_lines = 30,
645 .orig_video_cols = 80,
646 .orig_video_mode = 0,
647 .orig_video_ega_bx = 0,
648 .orig_video_isVGA = 1,
649 .orig_video_points = 8
650};
651
652static int __init parse_tag_videotext(const struct tag *tag)
653{
654 screen_info.orig_x = tag->u.videotext.x;
655 screen_info.orig_y = tag->u.videotext.y;
656 screen_info.orig_video_page = tag->u.videotext.video_page;
657 screen_info.orig_video_mode = tag->u.videotext.video_mode;
658 screen_info.orig_video_cols = tag->u.videotext.video_cols;
659 screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
660 screen_info.orig_video_lines = tag->u.videotext.video_lines;
661 screen_info.orig_video_isVGA = tag->u.videotext.video_isvga;
662 screen_info.orig_video_points = tag->u.videotext.video_points;
663 return 0;
664}
665
666__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
667#endif
668
669static int __init parse_tag_ramdisk(const struct tag *tag)
670{
671 setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
672 (tag->u.ramdisk.flags & 2) == 0,
673 tag->u.ramdisk.start, tag->u.ramdisk.size);
674 return 0;
675}
676
677__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
678
1da177e4
LT
679static int __init parse_tag_serialnr(const struct tag *tag)
680{
681 system_serial_low = tag->u.serialnr.low;
682 system_serial_high = tag->u.serialnr.high;
683 return 0;
684}
685
686__tagtable(ATAG_SERIAL, parse_tag_serialnr);
687
688static int __init parse_tag_revision(const struct tag *tag)
689{
690 system_rev = tag->u.revision.rev;
691 return 0;
692}
693
694__tagtable(ATAG_REVISION, parse_tag_revision);
695
696static int __init parse_tag_cmdline(const struct tag *tag)
697{
4394c124
VB
698#if defined(CONFIG_CMDLINE_EXTEND)
699 strlcat(default_command_line, " ", COMMAND_LINE_SIZE);
700 strlcat(default_command_line, tag->u.cmdline.cmdline,
701 COMMAND_LINE_SIZE);
702#elif defined(CONFIG_CMDLINE_FORCE)
22eeb8f6 703 pr_warning("Ignoring tag cmdline (using the default kernel command line)\n");
4394c124
VB
704#else
705 strlcpy(default_command_line, tag->u.cmdline.cmdline,
706 COMMAND_LINE_SIZE);
707#endif
1da177e4
LT
708 return 0;
709}
710
711__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
712
713/*
714 * Scan the tag table for this tag, and call its parse function.
715 * The tag table is built by the linker from all the __tagtable
716 * declarations.
717 */
718static int __init parse_tag(const struct tag *tag)
719{
720 extern struct tagtable __tagtable_begin, __tagtable_end;
721 struct tagtable *t;
722
723 for (t = &__tagtable_begin; t < &__tagtable_end; t++)
724 if (tag->hdr.tag == t->tag) {
725 t->parse(tag);
726 break;
727 }
728
729 return t < &__tagtable_end;
730}
731
732/*
733 * Parse all tags in the list, checking both the global and architecture
734 * specific tag tables.
735 */
736static void __init parse_tags(const struct tag *t)
737{
738 for (; t->hdr.size; t = tag_next(t))
739 if (!parse_tag(t))
740 printk(KERN_WARNING
741 "Ignoring unrecognised tag 0x%08x\n",
742 t->hdr.tag);
743}
744
745/*
746 * This holds our defaults.
747 */
748static struct init_tags {
749 struct tag_header hdr1;
750 struct tag_core core;
751 struct tag_header hdr2;
752 struct tag_mem32 mem;
753 struct tag_header hdr3;
754} init_tags __initdata = {
755 { tag_size(tag_core), ATAG_CORE },
756 { 1, PAGE_SIZE, 0xff },
757 { tag_size(tag_mem32), ATAG_MEM },
b75c178a 758 { MEM_SIZE },
1da177e4
LT
759 { 0, ATAG_NONE }
760};
761
1da177e4
LT
762static int __init customize_machine(void)
763{
764 /* customizes platform devices, or adds new ones */
8ff1443c
RK
765 if (machine_desc->init_machine)
766 machine_desc->init_machine();
1da177e4
LT
767 return 0;
768}
769arch_initcall(customize_machine);
770
3c57fb43
MW
771#ifdef CONFIG_KEXEC
772static inline unsigned long long get_total_mem(void)
773{
774 unsigned long total;
775
776 total = max_low_pfn - min_low_pfn;
777 return total << PAGE_SHIFT;
778}
779
780/**
781 * reserve_crashkernel() - reserves memory are for crash kernel
782 *
783 * This function reserves memory area given in "crashkernel=" kernel command
784 * line parameter. The memory reserved is used by a dump capture kernel when
785 * primary kernel is crashing.
786 */
787static void __init reserve_crashkernel(void)
788{
789 unsigned long long crash_size, crash_base;
790 unsigned long long total_mem;
791 int ret;
792
793 total_mem = get_total_mem();
794 ret = parse_crashkernel(boot_command_line, total_mem,
795 &crash_size, &crash_base);
796 if (ret)
797 return;
798
799 ret = reserve_bootmem(crash_base, crash_size, BOOTMEM_EXCLUSIVE);
800 if (ret < 0) {
801 printk(KERN_WARNING "crashkernel reservation failed - "
802 "memory is in use (0x%lx)\n", (unsigned long)crash_base);
803 return;
804 }
805
806 printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
807 "for crashkernel (System RAM: %ldMB)\n",
808 (unsigned long)(crash_size >> 20),
809 (unsigned long)(crash_base >> 20),
810 (unsigned long)(total_mem >> 20));
811
812 crashk_res.start = crash_base;
813 crashk_res.end = crash_base + crash_size - 1;
814 insert_resource(&iomem_resource, &crashk_res);
815}
816#else
817static inline void reserve_crashkernel(void) {}
818#endif /* CONFIG_KEXEC */
819
73a65b3f
UKK
820static void __init squash_mem_tags(struct tag *tag)
821{
822 for (; tag->hdr.size; tag = tag_next(tag))
823 if (tag->hdr.tag == ATAG_MEM)
824 tag->hdr.tag = ATAG_NONE;
825}
826
6291319d 827static struct machine_desc * __init setup_machine_tags(unsigned int nr)
1da177e4
LT
828{
829 struct tag *tags = (struct tag *)&init_tags;
6291319d 830 struct machine_desc *mdesc = NULL, *p;
1da177e4
LT
831 char *from = default_command_line;
832
b75c178a
RK
833 init_tags.mem.start = PHYS_OFFSET;
834
6291319d
GL
835 /*
836 * locate machine in the list of supported machines.
837 */
838 for_each_machine_desc(p)
839 if (nr == p->nr) {
840 printk("Machine: %s\n", p->name);
841 mdesc = p;
842 break;
843 }
1da177e4 844
6291319d
GL
845 if (!mdesc) {
846 early_print("\nError: unrecognized/unsupported machine ID"
847 " (r1 = 0x%08x).\n\n", nr);
848 dump_machine_table(); /* does not return */
849 }
1da177e4 850
9d20fdd5
BG
851 if (__atags_pointer)
852 tags = phys_to_virt(__atags_pointer);
2bb9839e
NP
853 else if (mdesc->atag_offset)
854 tags = (void *)(PAGE_OFFSET + mdesc->atag_offset);
1da177e4 855
73a65b3f 856#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
1da177e4
LT
857 /*
858 * If we have the old style parameters, convert them to
859 * a tag list.
860 */
861 if (tags->hdr.tag != ATAG_CORE)
862 convert_to_tag_list(tags);
73a65b3f 863#endif
93c02ab4
GL
864
865 if (tags->hdr.tag != ATAG_CORE) {
866#if defined(CONFIG_OF)
867 /*
868 * If CONFIG_OF is set, then assume this is a reasonably
869 * modern system that should pass boot parameters
870 */
871 early_print("Warning: Neither atags nor dtb found\n");
872#endif
1da177e4 873 tags = (struct tag *)&init_tags;
93c02ab4 874 }
1da177e4
LT
875
876 if (mdesc->fixup)
0744a3ee 877 mdesc->fixup(tags, &from, &meminfo);
1da177e4
LT
878
879 if (tags->hdr.tag == ATAG_CORE) {
880 if (meminfo.nr_banks != 0)
881 squash_mem_tags(tags);
4cd9d6f7 882 save_atags(tags);
1da177e4
LT
883 parse_tags(tags);
884 }
885
6291319d
GL
886 /* parse_early_param needs a boot_command_line */
887 strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
888
889 return mdesc;
890}
891
27a3f0e9
NP
892static int __init meminfo_cmp(const void *_a, const void *_b)
893{
894 const struct membank *a = _a, *b = _b;
895 long cmp = bank_pfn_start(a) - bank_pfn_start(b);
896 return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
897}
6291319d
GL
898
899void __init setup_arch(char **cmdline_p)
900{
901 struct machine_desc *mdesc;
902
903 unwind_init();
904
905 setup_processor();
93c02ab4
GL
906 mdesc = setup_machine_fdt(__atags_pointer);
907 if (!mdesc)
908 mdesc = setup_machine_tags(machine_arch_type);
6291319d
GL
909 machine_desc = mdesc;
910 machine_name = mdesc->name;
911
912 if (mdesc->soft_reboot)
913 reboot_setup("s");
914
37efe642
RK
915 init_mm.start_code = (unsigned long) _text;
916 init_mm.end_code = (unsigned long) _etext;
917 init_mm.end_data = (unsigned long) _edata;
918 init_mm.brk = (unsigned long) _end;
1da177e4 919
48ab7e09
JK
920 /* populate cmd_line too for later use, preserving boot_command_line */
921 strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
922 *cmdline_p = cmd_line;
2b0d8c25
JK
923
924 parse_early_param();
925
27a3f0e9 926 sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
0371d3f7 927 sanity_check_meminfo();
8d717a52 928 arm_memblock_init(&meminfo, mdesc);
2778f620 929
4b5f32ce 930 paging_init(mdesc);
11b9369c 931 request_standard_resources(mdesc);
1da177e4 932
93c02ab4
GL
933 unflatten_device_tree();
934
7bbb7940 935#ifdef CONFIG_SMP
f00ec48f
RK
936 if (is_smp())
937 smp_init_cpus();
7bbb7940 938#endif
3c57fb43 939 reserve_crashkernel();
7bbb7940 940
bc581770 941 tcm_init();
ccea7a19 942
4fddcaeb
NP
943#ifdef CONFIG_ZONE_DMA
944 if (mdesc->dma_zone_size) {
945 extern unsigned long arm_dma_zone_size;
946 arm_dma_zone_size = mdesc->dma_zone_size;
947 }
948#endif
52108641 949#ifdef CONFIG_MULTI_IRQ_HANDLER
950 handle_arch_irq = mdesc->handle_irq;
951#endif
1da177e4
LT
952
953#ifdef CONFIG_VT
954#if defined(CONFIG_VGA_CONSOLE)
955 conswitchp = &vga_con;
956#elif defined(CONFIG_DUMMY_CONSOLE)
957 conswitchp = &dummy_con;
958#endif
959#endif
5cbad0eb 960 early_trap_init();
dec12e62
RK
961
962 if (mdesc->init_early)
963 mdesc->init_early();
1da177e4
LT
964}
965
966
967static int __init topology_init(void)
968{
969 int cpu;
970
66fb8bd2
RK
971 for_each_possible_cpu(cpu) {
972 struct cpuinfo_arm *cpuinfo = &per_cpu(cpu_data, cpu);
973 cpuinfo->cpu.hotpluggable = 1;
974 register_cpu(&cpuinfo->cpu, cpu);
975 }
1da177e4
LT
976
977 return 0;
978}
1da177e4
LT
979subsys_initcall(topology_init);
980
e119bfff
RK
981#ifdef CONFIG_HAVE_PROC_CPU
982static int __init proc_cpu_init(void)
983{
984 struct proc_dir_entry *res;
985
986 res = proc_mkdir("cpu", NULL);
987 if (!res)
988 return -ENOMEM;
989 return 0;
990}
991fs_initcall(proc_cpu_init);
992#endif
993
1da177e4
LT
994static const char *hwcap_str[] = {
995 "swp",
996 "half",
997 "thumb",
998 "26bit",
999 "fastmult",
1000 "fpa",
1001 "vfp",
1002 "edsp",
1003 "java",
8f7f9435 1004 "iwmmxt",
99e4a6dd 1005 "crunch",
4369ae16 1006 "thumbee",
2bedbdf4 1007 "neon",
7279dc3e
CM
1008 "vfpv3",
1009 "vfpv3d16",
254cdf8e
WD
1010 "tls",
1011 "vfpv4",
1012 "idiva",
1013 "idivt",
1da177e4
LT
1014 NULL
1015};
1016
1da177e4
LT
1017static int c_show(struct seq_file *m, void *v)
1018{
1019 int i;
1020
1021 seq_printf(m, "Processor\t: %s rev %d (%s)\n",
0ba8b9b2 1022 cpu_name, read_cpuid_id() & 15, elf_platform);
1da177e4
LT
1023
1024#if defined(CONFIG_SMP)
1025 for_each_online_cpu(i) {
15559722
RK
1026 /*
1027 * glibc reads /proc/cpuinfo to determine the number of
1028 * online processors, looking for lines beginning with
1029 * "processor". Give glibc what it expects.
1030 */
1031 seq_printf(m, "processor\t: %d\n", i);
1da177e4
LT
1032 seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
1033 per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
1034 (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);
1035 }
1036#else /* CONFIG_SMP */
1037 seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
1038 loops_per_jiffy / (500000/HZ),
1039 (loops_per_jiffy / (5000/HZ)) % 100);
1040#endif
1041
1042 /* dump out the processor features */
1043 seq_puts(m, "Features\t: ");
1044
1045 for (i = 0; hwcap_str[i]; i++)
1046 if (elf_hwcap & (1 << i))
1047 seq_printf(m, "%s ", hwcap_str[i]);
1048
0ba8b9b2 1049 seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
1da177e4
LT
1050 seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]);
1051
0ba8b9b2 1052 if ((read_cpuid_id() & 0x0008f000) == 0x00000000) {
1da177e4 1053 /* pre-ARM7 */
0ba8b9b2 1054 seq_printf(m, "CPU part\t: %07x\n", read_cpuid_id() >> 4);
1da177e4 1055 } else {
0ba8b9b2 1056 if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
1da177e4
LT
1057 /* ARM7 */
1058 seq_printf(m, "CPU variant\t: 0x%02x\n",
0ba8b9b2 1059 (read_cpuid_id() >> 16) & 127);
1da177e4
LT
1060 } else {
1061 /* post-ARM7 */
1062 seq_printf(m, "CPU variant\t: 0x%x\n",
0ba8b9b2 1063 (read_cpuid_id() >> 20) & 15);
1da177e4
LT
1064 }
1065 seq_printf(m, "CPU part\t: 0x%03x\n",
0ba8b9b2 1066 (read_cpuid_id() >> 4) & 0xfff);
1da177e4 1067 }
0ba8b9b2 1068 seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);
1da177e4 1069
1da177e4
LT
1070 seq_puts(m, "\n");
1071
1072 seq_printf(m, "Hardware\t: %s\n", machine_name);
1073 seq_printf(m, "Revision\t: %04x\n", system_rev);
1074 seq_printf(m, "Serial\t\t: %08x%08x\n",
1075 system_serial_high, system_serial_low);
1076
1077 return 0;
1078}
1079
1080static void *c_start(struct seq_file *m, loff_t *pos)
1081{
1082 return *pos < 1 ? (void *)1 : NULL;
1083}
1084
1085static void *c_next(struct seq_file *m, void *v, loff_t *pos)
1086{
1087 ++*pos;
1088 return NULL;
1089}
1090
1091static void c_stop(struct seq_file *m, void *v)
1092{
1093}
1094
2ffd6e18 1095const struct seq_operations cpuinfo_op = {
1da177e4
LT
1096 .start = c_start,
1097 .next = c_next,
1098 .stop = c_stop,
1099 .show = c_show
1100};