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