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