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