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