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