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