ARM: 5880/1: arm: use generic infrastructure for early params
[safe/jmp/linux-2.6] / 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 #endif
107
108 struct stack {
109         u32 irq[3];
110         u32 abt[3];
111         u32 und[3];
112 } ____cacheline_aligned;
113
114 static struct stack stacks[NR_CPUS];
115
116 char elf_platform[ELF_PLATFORM_SIZE];
117 EXPORT_SYMBOL(elf_platform);
118
119 static const char *cpu_name;
120 static const char *machine_name;
121 static char __initdata command_line[COMMAND_LINE_SIZE];
122
123 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
124 static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
125 #define ENDIANNESS ((char)endian_test.l)
126
127 DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data);
128
129 /*
130  * Standard memory resources
131  */
132 static struct resource mem_res[] = {
133         {
134                 .name = "Video RAM",
135                 .start = 0,
136                 .end = 0,
137                 .flags = IORESOURCE_MEM
138         },
139         {
140                 .name = "Kernel text",
141                 .start = 0,
142                 .end = 0,
143                 .flags = IORESOURCE_MEM
144         },
145         {
146                 .name = "Kernel data",
147                 .start = 0,
148                 .end = 0,
149                 .flags = IORESOURCE_MEM
150         }
151 };
152
153 #define video_ram   mem_res[0]
154 #define kernel_code mem_res[1]
155 #define kernel_data mem_res[2]
156
157 static struct resource io_res[] = {
158         {
159                 .name = "reserved",
160                 .start = 0x3bc,
161                 .end = 0x3be,
162                 .flags = IORESOURCE_IO | IORESOURCE_BUSY
163         },
164         {
165                 .name = "reserved",
166                 .start = 0x378,
167                 .end = 0x37f,
168                 .flags = IORESOURCE_IO | IORESOURCE_BUSY
169         },
170         {
171                 .name = "reserved",
172                 .start = 0x278,
173                 .end = 0x27f,
174                 .flags = IORESOURCE_IO | IORESOURCE_BUSY
175         }
176 };
177
178 #define lp0 io_res[0]
179 #define lp1 io_res[1]
180 #define lp2 io_res[2]
181
182 static const char *proc_arch[] = {
183         "undefined/unknown",
184         "3",
185         "4",
186         "4T",
187         "5",
188         "5T",
189         "5TE",
190         "5TEJ",
191         "6TEJ",
192         "7",
193         "?(11)",
194         "?(12)",
195         "?(13)",
196         "?(14)",
197         "?(15)",
198         "?(16)",
199         "?(17)",
200 };
201
202 int cpu_architecture(void)
203 {
204         int cpu_arch;
205
206         if ((read_cpuid_id() & 0x0008f000) == 0) {
207                 cpu_arch = CPU_ARCH_UNKNOWN;
208         } else if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
209                 cpu_arch = (read_cpuid_id() & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
210         } else if ((read_cpuid_id() & 0x00080000) == 0x00000000) {
211                 cpu_arch = (read_cpuid_id() >> 16) & 7;
212                 if (cpu_arch)
213                         cpu_arch += CPU_ARCH_ARMv3;
214         } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
215                 unsigned int mmfr0;
216
217                 /* Revised CPUID format. Read the Memory Model Feature
218                  * Register 0 and check for VMSAv7 or PMSAv7 */
219                 asm("mrc        p15, 0, %0, c0, c1, 4"
220                     : "=r" (mmfr0));
221                 if ((mmfr0 & 0x0000000f) == 0x00000003 ||
222                     (mmfr0 & 0x000000f0) == 0x00000030)
223                         cpu_arch = CPU_ARCH_ARMv7;
224                 else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
225                          (mmfr0 & 0x000000f0) == 0x00000020)
226                         cpu_arch = CPU_ARCH_ARMv6;
227                 else
228                         cpu_arch = CPU_ARCH_UNKNOWN;
229         } else
230                 cpu_arch = CPU_ARCH_UNKNOWN;
231
232         return cpu_arch;
233 }
234
235 static void __init cacheid_init(void)
236 {
237         unsigned int cachetype = read_cpuid_cachetype();
238         unsigned int arch = cpu_architecture();
239
240         if (arch >= CPU_ARCH_ARMv6) {
241                 if ((cachetype & (7 << 29)) == 4 << 29) {
242                         /* ARMv7 register format */
243                         cacheid = CACHEID_VIPT_NONALIASING;
244                         if ((cachetype & (3 << 14)) == 1 << 14)
245                                 cacheid |= CACHEID_ASID_TAGGED;
246                 } else if (cachetype & (1 << 23))
247                         cacheid = CACHEID_VIPT_ALIASING;
248                 else
249                         cacheid = CACHEID_VIPT_NONALIASING;
250         } else {
251                 cacheid = CACHEID_VIVT;
252         }
253
254         printk("CPU: %s data cache, %s instruction cache\n",
255                 cache_is_vivt() ? "VIVT" :
256                 cache_is_vipt_aliasing() ? "VIPT aliasing" :
257                 cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown",
258                 cache_is_vivt() ? "VIVT" :
259                 icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
260                 cache_is_vipt_aliasing() ? "VIPT aliasing" :
261                 cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
262 }
263
264 /*
265  * These functions re-use the assembly code in head.S, which
266  * already provide the required functionality.
267  */
268 extern struct proc_info_list *lookup_processor_type(unsigned int);
269 extern struct machine_desc *lookup_machine_type(unsigned int);
270
271 static void __init setup_processor(void)
272 {
273         struct proc_info_list *list;
274
275         /*
276          * locate processor in the list of supported processor
277          * types.  The linker builds this table for us from the
278          * entries in arch/arm/mm/proc-*.S
279          */
280         list = lookup_processor_type(read_cpuid_id());
281         if (!list) {
282                 printk("CPU configuration botched (ID %08x), unable "
283                        "to continue.\n", read_cpuid_id());
284                 while (1);
285         }
286
287         cpu_name = list->cpu_name;
288
289 #ifdef MULTI_CPU
290         processor = *list->proc;
291 #endif
292 #ifdef MULTI_TLB
293         cpu_tlb = *list->tlb;
294 #endif
295 #ifdef MULTI_USER
296         cpu_user = *list->user;
297 #endif
298 #ifdef MULTI_CACHE
299         cpu_cache = *list->cache;
300 #endif
301
302         printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n",
303                cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
304                proc_arch[cpu_architecture()], cr_alignment);
305
306         sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS);
307         sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
308         elf_hwcap = list->elf_hwcap;
309 #ifndef CONFIG_ARM_THUMB
310         elf_hwcap &= ~HWCAP_THUMB;
311 #endif
312
313         cacheid_init();
314         cpu_proc_init();
315 }
316
317 /*
318  * cpu_init - initialise one CPU.
319  *
320  * cpu_init sets up the per-CPU stacks.
321  */
322 void cpu_init(void)
323 {
324         unsigned int cpu = smp_processor_id();
325         struct stack *stk = &stacks[cpu];
326
327         if (cpu >= NR_CPUS) {
328                 printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu);
329                 BUG();
330         }
331
332         /*
333          * Define the placement constraint for the inline asm directive below.
334          * In Thumb-2, msr with an immediate value is not allowed.
335          */
336 #ifdef CONFIG_THUMB2_KERNEL
337 #define PLC     "r"
338 #else
339 #define PLC     "I"
340 #endif
341
342         /*
343          * setup stacks for re-entrant exception handlers
344          */
345         __asm__ (
346         "msr    cpsr_c, %1\n\t"
347         "add    r14, %0, %2\n\t"
348         "mov    sp, r14\n\t"
349         "msr    cpsr_c, %3\n\t"
350         "add    r14, %0, %4\n\t"
351         "mov    sp, r14\n\t"
352         "msr    cpsr_c, %5\n\t"
353         "add    r14, %0, %6\n\t"
354         "mov    sp, r14\n\t"
355         "msr    cpsr_c, %7"
356             :
357             : "r" (stk),
358               PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
359               "I" (offsetof(struct stack, irq[0])),
360               PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
361               "I" (offsetof(struct stack, abt[0])),
362               PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE),
363               "I" (offsetof(struct stack, und[0])),
364               PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
365             : "r14");
366 }
367
368 static struct machine_desc * __init setup_machine(unsigned int nr)
369 {
370         struct machine_desc *list;
371
372         /*
373          * locate machine in the list of supported machines.
374          */
375         list = lookup_machine_type(nr);
376         if (!list) {
377                 printk("Machine configuration botched (nr %d), unable "
378                        "to continue.\n", nr);
379                 while (1);
380         }
381
382         printk("Machine: %s\n", list->name);
383
384         return list;
385 }
386
387 static int __init arm_add_memory(unsigned long start, unsigned long size)
388 {
389         struct membank *bank = &meminfo.bank[meminfo.nr_banks];
390
391         if (meminfo.nr_banks >= NR_BANKS) {
392                 printk(KERN_CRIT "NR_BANKS too low, "
393                         "ignoring memory at %#lx\n", start);
394                 return -EINVAL;
395         }
396
397         /*
398          * Ensure that start/size are aligned to a page boundary.
399          * Size is appropriately rounded down, start is rounded up.
400          */
401         size -= start & ~PAGE_MASK;
402         bank->start = PAGE_ALIGN(start);
403         bank->size  = size & PAGE_MASK;
404         bank->node  = PHYS_TO_NID(start);
405
406         /*
407          * Check whether this memory region has non-zero size or
408          * invalid node number.
409          */
410         if (bank->size == 0 || bank->node >= MAX_NUMNODES)
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 static int __init parse_tag_cmdline(const struct tag *tag)
596 {
597         strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
598         return 0;
599 }
600
601 __tagtable(ATAG_CMDLINE, parse_tag_cmdline);
602
603 /*
604  * Scan the tag table for this tag, and call its parse function.
605  * The tag table is built by the linker from all the __tagtable
606  * declarations.
607  */
608 static int __init parse_tag(const struct tag *tag)
609 {
610         extern struct tagtable __tagtable_begin, __tagtable_end;
611         struct tagtable *t;
612
613         for (t = &__tagtable_begin; t < &__tagtable_end; t++)
614                 if (tag->hdr.tag == t->tag) {
615                         t->parse(tag);
616                         break;
617                 }
618
619         return t < &__tagtable_end;
620 }
621
622 /*
623  * Parse all tags in the list, checking both the global and architecture
624  * specific tag tables.
625  */
626 static void __init parse_tags(const struct tag *t)
627 {
628         for (; t->hdr.size; t = tag_next(t))
629                 if (!parse_tag(t))
630                         printk(KERN_WARNING
631                                 "Ignoring unrecognised tag 0x%08x\n",
632                                 t->hdr.tag);
633 }
634
635 /*
636  * This holds our defaults.
637  */
638 static struct init_tags {
639         struct tag_header hdr1;
640         struct tag_core   core;
641         struct tag_header hdr2;
642         struct tag_mem32  mem;
643         struct tag_header hdr3;
644 } init_tags __initdata = {
645         { tag_size(tag_core), ATAG_CORE },
646         { 1, PAGE_SIZE, 0xff },
647         { tag_size(tag_mem32), ATAG_MEM },
648         { MEM_SIZE, PHYS_OFFSET },
649         { 0, ATAG_NONE }
650 };
651
652 static void (*init_machine)(void) __initdata;
653
654 static int __init customize_machine(void)
655 {
656         /* customizes platform devices, or adds new ones */
657         if (init_machine)
658                 init_machine();
659         return 0;
660 }
661 arch_initcall(customize_machine);
662
663 void __init setup_arch(char **cmdline_p)
664 {
665         struct tag *tags = (struct tag *)&init_tags;
666         struct machine_desc *mdesc;
667         char *from = default_command_line;
668
669         unwind_init();
670
671         setup_processor();
672         mdesc = setup_machine(machine_arch_type);
673         machine_name = mdesc->name;
674
675         if (mdesc->soft_reboot)
676                 reboot_setup("s");
677
678         if (__atags_pointer)
679                 tags = phys_to_virt(__atags_pointer);
680         else if (mdesc->boot_params)
681                 tags = phys_to_virt(mdesc->boot_params);
682
683         /*
684          * If we have the old style parameters, convert them to
685          * a tag list.
686          */
687         if (tags->hdr.tag != ATAG_CORE)
688                 convert_to_tag_list(tags);
689         if (tags->hdr.tag != ATAG_CORE)
690                 tags = (struct tag *)&init_tags;
691
692         if (mdesc->fixup)
693                 mdesc->fixup(mdesc, tags, &from, &meminfo);
694
695         if (tags->hdr.tag == ATAG_CORE) {
696                 if (meminfo.nr_banks != 0)
697                         squash_mem_tags(tags);
698                 save_atags(tags);
699                 parse_tags(tags);
700         }
701
702         init_mm.start_code = (unsigned long) _text;
703         init_mm.end_code   = (unsigned long) _etext;
704         init_mm.end_data   = (unsigned long) _edata;
705         init_mm.brk        = (unsigned long) _end;
706
707         /* parse_early_param needs a boot_command_line */
708         strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
709
710         /* populate command_line too for later use, preserving boot_command_line */
711         strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
712         *cmdline_p = command_line;
713
714         parse_early_param();
715
716         paging_init(mdesc);
717         request_standard_resources(&meminfo, mdesc);
718
719 #ifdef CONFIG_SMP
720         smp_init_cpus();
721 #endif
722
723         cpu_init();
724         tcm_init();
725
726         /*
727          * Set up various architecture-specific pointers
728          */
729         init_arch_irq = mdesc->init_irq;
730         system_timer = mdesc->timer;
731         init_machine = mdesc->init_machine;
732
733 #ifdef CONFIG_VT
734 #if defined(CONFIG_VGA_CONSOLE)
735         conswitchp = &vga_con;
736 #elif defined(CONFIG_DUMMY_CONSOLE)
737         conswitchp = &dummy_con;
738 #endif
739 #endif
740         early_trap_init();
741 }
742
743
744 static int __init topology_init(void)
745 {
746         int cpu;
747
748         for_each_possible_cpu(cpu) {
749                 struct cpuinfo_arm *cpuinfo = &per_cpu(cpu_data, cpu);
750                 cpuinfo->cpu.hotpluggable = 1;
751                 register_cpu(&cpuinfo->cpu, cpu);
752         }
753
754         return 0;
755 }
756 subsys_initcall(topology_init);
757
758 #ifdef CONFIG_HAVE_PROC_CPU
759 static int __init proc_cpu_init(void)
760 {
761         struct proc_dir_entry *res;
762
763         res = proc_mkdir("cpu", NULL);
764         if (!res)
765                 return -ENOMEM;
766         return 0;
767 }
768 fs_initcall(proc_cpu_init);
769 #endif
770
771 static const char *hwcap_str[] = {
772         "swp",
773         "half",
774         "thumb",
775         "26bit",
776         "fastmult",
777         "fpa",
778         "vfp",
779         "edsp",
780         "java",
781         "iwmmxt",
782         "crunch",
783         "thumbee",
784         "neon",
785         "vfpv3",
786         "vfpv3d16",
787         NULL
788 };
789
790 static int c_show(struct seq_file *m, void *v)
791 {
792         int i;
793
794         seq_printf(m, "Processor\t: %s rev %d (%s)\n",
795                    cpu_name, read_cpuid_id() & 15, elf_platform);
796
797 #if defined(CONFIG_SMP)
798         for_each_online_cpu(i) {
799                 /*
800                  * glibc reads /proc/cpuinfo to determine the number of
801                  * online processors, looking for lines beginning with
802                  * "processor".  Give glibc what it expects.
803                  */
804                 seq_printf(m, "processor\t: %d\n", i);
805                 seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
806                            per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
807                            (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);
808         }
809 #else /* CONFIG_SMP */
810         seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
811                    loops_per_jiffy / (500000/HZ),
812                    (loops_per_jiffy / (5000/HZ)) % 100);
813 #endif
814
815         /* dump out the processor features */
816         seq_puts(m, "Features\t: ");
817
818         for (i = 0; hwcap_str[i]; i++)
819                 if (elf_hwcap & (1 << i))
820                         seq_printf(m, "%s ", hwcap_str[i]);
821
822         seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
823         seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]);
824
825         if ((read_cpuid_id() & 0x0008f000) == 0x00000000) {
826                 /* pre-ARM7 */
827                 seq_printf(m, "CPU part\t: %07x\n", read_cpuid_id() >> 4);
828         } else {
829                 if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
830                         /* ARM7 */
831                         seq_printf(m, "CPU variant\t: 0x%02x\n",
832                                    (read_cpuid_id() >> 16) & 127);
833                 } else {
834                         /* post-ARM7 */
835                         seq_printf(m, "CPU variant\t: 0x%x\n",
836                                    (read_cpuid_id() >> 20) & 15);
837                 }
838                 seq_printf(m, "CPU part\t: 0x%03x\n",
839                            (read_cpuid_id() >> 4) & 0xfff);
840         }
841         seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);
842
843         seq_puts(m, "\n");
844
845         seq_printf(m, "Hardware\t: %s\n", machine_name);
846         seq_printf(m, "Revision\t: %04x\n", system_rev);
847         seq_printf(m, "Serial\t\t: %08x%08x\n",
848                    system_serial_high, system_serial_low);
849
850         return 0;
851 }
852
853 static void *c_start(struct seq_file *m, loff_t *pos)
854 {
855         return *pos < 1 ? (void *)1 : NULL;
856 }
857
858 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
859 {
860         ++*pos;
861         return NULL;
862 }
863
864 static void c_stop(struct seq_file *m, void *v)
865 {
866 }
867
868 const struct seq_operations cpuinfo_op = {
869         .start  = c_start,
870         .next   = c_next,
871         .stop   = c_stop,
872         .show   = c_show
873 };