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