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