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