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