dm table: add more context to terse warning messages
[linux-2.6/mini2440.git] / arch / arm / kernel / setup.c
blobbc5e4128f9f318a50bd4abc2e2b426c8db11eecb
1 /*
2 * linux/arch/arm/kernel/setup.c
4 * Copyright (C) 1995-2001 Russell King
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>
28 #include <asm/cpu.h>
29 #include <asm/cputype.h>
30 #include <asm/elf.h>
31 #include <asm/procinfo.h>
32 #include <asm/sections.h>
33 #include <asm/setup.h>
34 #include <asm/mach-types.h>
35 #include <asm/cacheflush.h>
36 #include <asm/cachetype.h>
37 #include <asm/tlbflush.h>
39 #include <asm/mach/arch.h>
40 #include <asm/mach/irq.h>
41 #include <asm/mach/time.h>
42 #include <asm/traps.h>
43 #include <asm/unwind.h>
45 #include "compat.h"
46 #include "atags.h"
48 #ifndef MEM_SIZE
49 #define MEM_SIZE (16*1024*1024)
50 #endif
52 #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
53 char fpe_type[8];
55 static int __init fpe_setup(char *line)
57 memcpy(fpe_type, line, 8);
58 return 1;
61 __setup("fpe=", fpe_setup);
62 #endif
64 extern void paging_init(struct machine_desc *desc);
65 extern void reboot_setup(char *str);
67 unsigned int processor_id;
68 EXPORT_SYMBOL(processor_id);
69 unsigned int __machine_arch_type;
70 EXPORT_SYMBOL(__machine_arch_type);
71 unsigned int cacheid;
72 EXPORT_SYMBOL(cacheid);
74 unsigned int __atags_pointer __initdata;
76 unsigned int system_rev;
77 EXPORT_SYMBOL(system_rev);
79 unsigned int system_serial_low;
80 EXPORT_SYMBOL(system_serial_low);
82 unsigned int system_serial_high;
83 EXPORT_SYMBOL(system_serial_high);
85 unsigned int elf_hwcap;
86 EXPORT_SYMBOL(elf_hwcap);
89 #ifdef MULTI_CPU
90 struct processor processor;
91 #endif
92 #ifdef MULTI_TLB
93 struct cpu_tlb_fns cpu_tlb;
94 #endif
95 #ifdef MULTI_USER
96 struct cpu_user_fns cpu_user;
97 #endif
98 #ifdef MULTI_CACHE
99 struct cpu_cache_fns cpu_cache;
100 #endif
101 #ifdef CONFIG_OUTER_CACHE
102 struct outer_cache_fns outer_cache;
103 #endif
105 struct stack {
106 u32 irq[3];
107 u32 abt[3];
108 u32 und[3];
109 } ____cacheline_aligned;
111 static struct stack stacks[NR_CPUS];
113 char elf_platform[ELF_PLATFORM_SIZE];
114 EXPORT_SYMBOL(elf_platform);
116 static const char *cpu_name;
117 static const char *machine_name;
118 static char __initdata command_line[COMMAND_LINE_SIZE];
120 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
121 static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
122 #define ENDIANNESS ((char)endian_test.l)
124 DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data);
127 * Standard memory resources
129 static struct resource mem_res[] = {
131 .name = "Video RAM",
132 .start = 0,
133 .end = 0,
134 .flags = IORESOURCE_MEM
137 .name = "Kernel text",
138 .start = 0,
139 .end = 0,
140 .flags = IORESOURCE_MEM
143 .name = "Kernel data",
144 .start = 0,
145 .end = 0,
146 .flags = IORESOURCE_MEM
150 #define video_ram mem_res[0]
151 #define kernel_code mem_res[1]
152 #define kernel_data mem_res[2]
154 static struct resource io_res[] = {
156 .name = "reserved",
157 .start = 0x3bc,
158 .end = 0x3be,
159 .flags = IORESOURCE_IO | IORESOURCE_BUSY
162 .name = "reserved",
163 .start = 0x378,
164 .end = 0x37f,
165 .flags = IORESOURCE_IO | IORESOURCE_BUSY
168 .name = "reserved",
169 .start = 0x278,
170 .end = 0x27f,
171 .flags = IORESOURCE_IO | IORESOURCE_BUSY
175 #define lp0 io_res[0]
176 #define lp1 io_res[1]
177 #define lp2 io_res[2]
179 static const char *proc_arch[] = {
180 "undefined/unknown",
181 "3",
182 "4",
183 "4T",
184 "5",
185 "5T",
186 "5TE",
187 "5TEJ",
188 "6TEJ",
189 "7",
190 "?(11)",
191 "?(12)",
192 "?(13)",
193 "?(14)",
194 "?(15)",
195 "?(16)",
196 "?(17)",
199 int cpu_architecture(void)
201 int cpu_arch;
203 if ((read_cpuid_id() & 0x0008f000) == 0) {
204 cpu_arch = CPU_ARCH_UNKNOWN;
205 } else if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
206 cpu_arch = (read_cpuid_id() & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
207 } else if ((read_cpuid_id() & 0x00080000) == 0x00000000) {
208 cpu_arch = (read_cpuid_id() >> 16) & 7;
209 if (cpu_arch)
210 cpu_arch += CPU_ARCH_ARMv3;
211 } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
212 unsigned int mmfr0;
214 /* Revised CPUID format. Read the Memory Model Feature
215 * Register 0 and check for VMSAv7 or PMSAv7 */
216 asm("mrc p15, 0, %0, c0, c1, 4"
217 : "=r" (mmfr0));
218 if ((mmfr0 & 0x0000000f) == 0x00000003 ||
219 (mmfr0 & 0x000000f0) == 0x00000030)
220 cpu_arch = CPU_ARCH_ARMv7;
221 else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
222 (mmfr0 & 0x000000f0) == 0x00000020)
223 cpu_arch = CPU_ARCH_ARMv6;
224 else
225 cpu_arch = CPU_ARCH_UNKNOWN;
226 } else
227 cpu_arch = CPU_ARCH_UNKNOWN;
229 return cpu_arch;
232 static void __init cacheid_init(void)
234 unsigned int cachetype = read_cpuid_cachetype();
235 unsigned int arch = cpu_architecture();
237 if (arch >= CPU_ARCH_ARMv6) {
238 if ((cachetype & (7 << 29)) == 4 << 29) {
239 /* ARMv7 register format */
240 cacheid = CACHEID_VIPT_NONALIASING;
241 if ((cachetype & (3 << 14)) == 1 << 14)
242 cacheid |= CACHEID_ASID_TAGGED;
243 } else if (cachetype & (1 << 23))
244 cacheid = CACHEID_VIPT_ALIASING;
245 else
246 cacheid = CACHEID_VIPT_NONALIASING;
247 } else {
248 cacheid = CACHEID_VIVT;
251 printk("CPU: %s data cache, %s instruction cache\n",
252 cache_is_vivt() ? "VIVT" :
253 cache_is_vipt_aliasing() ? "VIPT aliasing" :
254 cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown",
255 cache_is_vivt() ? "VIVT" :
256 icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
257 cache_is_vipt_aliasing() ? "VIPT aliasing" :
258 cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
262 * These functions re-use the assembly code in head.S, which
263 * already provide the required functionality.
265 extern struct proc_info_list *lookup_processor_type(unsigned int);
266 extern struct machine_desc *lookup_machine_type(unsigned int);
268 static void __init setup_processor(void)
270 struct proc_info_list *list;
273 * locate processor in the list of supported processor
274 * types. The linker builds this table for us from the
275 * entries in arch/arm/mm/proc-*.S
277 list = lookup_processor_type(read_cpuid_id());
278 if (!list) {
279 printk("CPU configuration botched (ID %08x), unable "
280 "to continue.\n", read_cpuid_id());
281 while (1);
284 cpu_name = list->cpu_name;
286 #ifdef MULTI_CPU
287 processor = *list->proc;
288 #endif
289 #ifdef MULTI_TLB
290 cpu_tlb = *list->tlb;
291 #endif
292 #ifdef MULTI_USER
293 cpu_user = *list->user;
294 #endif
295 #ifdef MULTI_CACHE
296 cpu_cache = *list->cache;
297 #endif
299 printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n",
300 cpu_name, read_cpuid_id(), read_cpuid_id() & 15,
301 proc_arch[cpu_architecture()], cr_alignment);
303 sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS);
304 sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
305 elf_hwcap = list->elf_hwcap;
306 #ifndef CONFIG_ARM_THUMB
307 elf_hwcap &= ~HWCAP_THUMB;
308 #endif
310 cacheid_init();
311 cpu_proc_init();
315 * cpu_init - initialise one CPU.
317 * cpu_init sets up the per-CPU stacks.
319 void cpu_init(void)
321 unsigned int cpu = smp_processor_id();
322 struct stack *stk = &stacks[cpu];
324 if (cpu >= NR_CPUS) {
325 printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu);
326 BUG();
330 * setup stacks for re-entrant exception handlers
332 __asm__ (
333 "msr cpsr_c, %1\n\t"
334 "add sp, %0, %2\n\t"
335 "msr cpsr_c, %3\n\t"
336 "add sp, %0, %4\n\t"
337 "msr cpsr_c, %5\n\t"
338 "add sp, %0, %6\n\t"
339 "msr cpsr_c, %7"
341 : "r" (stk),
342 "I" (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
343 "I" (offsetof(struct stack, irq[0])),
344 "I" (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
345 "I" (offsetof(struct stack, abt[0])),
346 "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),
347 "I" (offsetof(struct stack, und[0])),
348 "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
349 : "r14");
352 static struct machine_desc * __init setup_machine(unsigned int nr)
354 struct machine_desc *list;
357 * locate machine in the list of supported machines.
359 list = lookup_machine_type(nr);
360 if (!list) {
361 printk("Machine configuration botched (nr %d), unable "
362 "to continue.\n", nr);
363 while (1);
366 printk("Machine: %s\n", list->name);
368 return list;
371 static int __init arm_add_memory(unsigned long start, unsigned long size)
373 struct membank *bank = &meminfo.bank[meminfo.nr_banks];
375 if (meminfo.nr_banks >= NR_BANKS) {
376 printk(KERN_CRIT "NR_BANKS too low, "
377 "ignoring memory at %#lx\n", start);
378 return -EINVAL;
382 * Ensure that start/size are aligned to a page boundary.
383 * Size is appropriately rounded down, start is rounded up.
385 size -= start & ~PAGE_MASK;
386 bank->start = PAGE_ALIGN(start);
387 bank->size = size & PAGE_MASK;
388 bank->node = PHYS_TO_NID(start);
391 * Check whether this memory region has non-zero size or
392 * invalid node number.
394 if (bank->size == 0 || bank->node >= MAX_NUMNODES)
395 return -EINVAL;
397 meminfo.nr_banks++;
398 return 0;
402 * Pick out the memory size. We look for mem=size@start,
403 * where start and size are "size[KkMm]"
405 static void __init early_mem(char **p)
407 static int usermem __initdata = 0;
408 unsigned long size, start;
411 * If the user specifies memory size, we
412 * blow away any automatically generated
413 * size.
415 if (usermem == 0) {
416 usermem = 1;
417 meminfo.nr_banks = 0;
420 start = PHYS_OFFSET;
421 size = memparse(*p, p);
422 if (**p == '@')
423 start = memparse(*p + 1, p);
425 arm_add_memory(start, size);
427 __early_param("mem=", early_mem);
430 * Initial parsing of the command line.
432 static void __init parse_cmdline(char **cmdline_p, char *from)
434 char c = ' ', *to = command_line;
435 int len = 0;
437 for (;;) {
438 if (c == ' ') {
439 extern struct early_params __early_begin, __early_end;
440 struct early_params *p;
442 for (p = &__early_begin; p < &__early_end; p++) {
443 int arglen = strlen(p->arg);
445 if (memcmp(from, p->arg, arglen) == 0) {
446 if (to != command_line)
447 to -= 1;
448 from += arglen;
449 p->fn(&from);
451 while (*from != ' ' && *from != '\0')
452 from++;
453 break;
457 c = *from++;
458 if (!c)
459 break;
460 if (COMMAND_LINE_SIZE <= ++len)
461 break;
462 *to++ = c;
464 *to = '\0';
465 *cmdline_p = command_line;
468 static void __init
469 setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
471 #ifdef CONFIG_BLK_DEV_RAM
472 extern int rd_size, rd_image_start, rd_prompt, rd_doload;
474 rd_image_start = image_start;
475 rd_prompt = prompt;
476 rd_doload = doload;
478 if (rd_sz)
479 rd_size = rd_sz;
480 #endif
483 static void __init
484 request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
486 struct resource *res;
487 int i;
489 kernel_code.start = virt_to_phys(_text);
490 kernel_code.end = virt_to_phys(_etext - 1);
491 kernel_data.start = virt_to_phys(_data);
492 kernel_data.end = virt_to_phys(_end - 1);
494 for (i = 0; i < mi->nr_banks; i++) {
495 if (mi->bank[i].size == 0)
496 continue;
498 res = alloc_bootmem_low(sizeof(*res));
499 res->name = "System RAM";
500 res->start = mi->bank[i].start;
501 res->end = mi->bank[i].start + mi->bank[i].size - 1;
502 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
504 request_resource(&iomem_resource, res);
506 if (kernel_code.start >= res->start &&
507 kernel_code.end <= res->end)
508 request_resource(res, &kernel_code);
509 if (kernel_data.start >= res->start &&
510 kernel_data.end <= res->end)
511 request_resource(res, &kernel_data);
514 if (mdesc->video_start) {
515 video_ram.start = mdesc->video_start;
516 video_ram.end = mdesc->video_end;
517 request_resource(&iomem_resource, &video_ram);
521 * Some machines don't have the possibility of ever
522 * possessing lp0, lp1 or lp2
524 if (mdesc->reserve_lp0)
525 request_resource(&ioport_resource, &lp0);
526 if (mdesc->reserve_lp1)
527 request_resource(&ioport_resource, &lp1);
528 if (mdesc->reserve_lp2)
529 request_resource(&ioport_resource, &lp2);
533 * Tag parsing.
535 * This is the new way of passing data to the kernel at boot time. Rather
536 * than passing a fixed inflexible structure to the kernel, we pass a list
537 * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE
538 * tag for the list to be recognised (to distinguish the tagged list from
539 * a param_struct). The list is terminated with a zero-length tag (this tag
540 * is not parsed in any way).
542 static int __init parse_tag_core(const struct tag *tag)
544 if (tag->hdr.size > 2) {
545 if ((tag->u.core.flags & 1) == 0)
546 root_mountflags &= ~MS_RDONLY;
547 ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
549 return 0;
552 __tagtable(ATAG_CORE, parse_tag_core);
554 static int __init parse_tag_mem32(const struct tag *tag)
556 return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
559 __tagtable(ATAG_MEM, parse_tag_mem32);
561 #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
562 struct screen_info screen_info = {
563 .orig_video_lines = 30,
564 .orig_video_cols = 80,
565 .orig_video_mode = 0,
566 .orig_video_ega_bx = 0,
567 .orig_video_isVGA = 1,
568 .orig_video_points = 8
571 static int __init parse_tag_videotext(const struct tag *tag)
573 screen_info.orig_x = tag->u.videotext.x;
574 screen_info.orig_y = tag->u.videotext.y;
575 screen_info.orig_video_page = tag->u.videotext.video_page;
576 screen_info.orig_video_mode = tag->u.videotext.video_mode;
577 screen_info.orig_video_cols = tag->u.videotext.video_cols;
578 screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
579 screen_info.orig_video_lines = tag->u.videotext.video_lines;
580 screen_info.orig_video_isVGA = tag->u.videotext.video_isvga;
581 screen_info.orig_video_points = tag->u.videotext.video_points;
582 return 0;
585 __tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
586 #endif
588 static int __init parse_tag_ramdisk(const struct tag *tag)
590 setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
591 (tag->u.ramdisk.flags & 2) == 0,
592 tag->u.ramdisk.start, tag->u.ramdisk.size);
593 return 0;
596 __tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
598 static int __init parse_tag_serialnr(const struct tag *tag)
600 system_serial_low = tag->u.serialnr.low;
601 system_serial_high = tag->u.serialnr.high;
602 return 0;
605 __tagtable(ATAG_SERIAL, parse_tag_serialnr);
607 static int __init parse_tag_revision(const struct tag *tag)
609 system_rev = tag->u.revision.rev;
610 return 0;
613 __tagtable(ATAG_REVISION, parse_tag_revision);
615 static int __init parse_tag_cmdline(const struct tag *tag)
617 strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
618 return 0;
621 __tagtable(ATAG_CMDLINE, parse_tag_cmdline);
624 * Scan the tag table for this tag, and call its parse function.
625 * The tag table is built by the linker from all the __tagtable
626 * declarations.
628 static int __init parse_tag(const struct tag *tag)
630 extern struct tagtable __tagtable_begin, __tagtable_end;
631 struct tagtable *t;
633 for (t = &__tagtable_begin; t < &__tagtable_end; t++)
634 if (tag->hdr.tag == t->tag) {
635 t->parse(tag);
636 break;
639 return t < &__tagtable_end;
643 * Parse all tags in the list, checking both the global and architecture
644 * specific tag tables.
646 static void __init parse_tags(const struct tag *t)
648 for (; t->hdr.size; t = tag_next(t))
649 if (!parse_tag(t))
650 printk(KERN_WARNING
651 "Ignoring unrecognised tag 0x%08x\n",
652 t->hdr.tag);
656 * This holds our defaults.
658 static struct init_tags {
659 struct tag_header hdr1;
660 struct tag_core core;
661 struct tag_header hdr2;
662 struct tag_mem32 mem;
663 struct tag_header hdr3;
664 } init_tags __initdata = {
665 { tag_size(tag_core), ATAG_CORE },
666 { 1, PAGE_SIZE, 0xff },
667 { tag_size(tag_mem32), ATAG_MEM },
668 { MEM_SIZE, PHYS_OFFSET },
669 { 0, ATAG_NONE }
672 static void (*init_machine)(void) __initdata;
674 static int __init customize_machine(void)
676 /* customizes platform devices, or adds new ones */
677 if (init_machine)
678 init_machine();
679 return 0;
681 arch_initcall(customize_machine);
683 void __init setup_arch(char **cmdline_p)
685 struct tag *tags = (struct tag *)&init_tags;
686 struct machine_desc *mdesc;
687 char *from = default_command_line;
689 unwind_init();
691 setup_processor();
692 mdesc = setup_machine(machine_arch_type);
693 machine_name = mdesc->name;
695 if (mdesc->soft_reboot)
696 reboot_setup("s");
698 if (__atags_pointer)
699 tags = phys_to_virt(__atags_pointer);
700 else if (mdesc->boot_params)
701 tags = phys_to_virt(mdesc->boot_params);
704 * If we have the old style parameters, convert them to
705 * a tag list.
707 if (tags->hdr.tag != ATAG_CORE)
708 convert_to_tag_list(tags);
709 if (tags->hdr.tag != ATAG_CORE)
710 tags = (struct tag *)&init_tags;
712 if (mdesc->fixup)
713 mdesc->fixup(mdesc, tags, &from, &meminfo);
715 if (tags->hdr.tag == ATAG_CORE) {
716 if (meminfo.nr_banks != 0)
717 squash_mem_tags(tags);
718 save_atags(tags);
719 parse_tags(tags);
722 init_mm.start_code = (unsigned long) _text;
723 init_mm.end_code = (unsigned long) _etext;
724 init_mm.end_data = (unsigned long) _edata;
725 init_mm.brk = (unsigned long) _end;
727 memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
728 boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
729 parse_cmdline(cmdline_p, from);
730 paging_init(mdesc);
731 request_standard_resources(&meminfo, mdesc);
733 #ifdef CONFIG_SMP
734 smp_init_cpus();
735 #endif
737 cpu_init();
740 * Set up various architecture-specific pointers
742 init_arch_irq = mdesc->init_irq;
743 system_timer = mdesc->timer;
744 init_machine = mdesc->init_machine;
746 #ifdef CONFIG_VT
747 #if defined(CONFIG_VGA_CONSOLE)
748 conswitchp = &vga_con;
749 #elif defined(CONFIG_DUMMY_CONSOLE)
750 conswitchp = &dummy_con;
751 #endif
752 #endif
753 early_trap_init();
757 static int __init topology_init(void)
759 int cpu;
761 for_each_possible_cpu(cpu) {
762 struct cpuinfo_arm *cpuinfo = &per_cpu(cpu_data, cpu);
763 cpuinfo->cpu.hotpluggable = 1;
764 register_cpu(&cpuinfo->cpu, cpu);
767 return 0;
770 subsys_initcall(topology_init);
772 static const char *hwcap_str[] = {
773 "swp",
774 "half",
775 "thumb",
776 "26bit",
777 "fastmult",
778 "fpa",
779 "vfp",
780 "edsp",
781 "java",
782 "iwmmxt",
783 "crunch",
784 "thumbee",
785 "neon",
786 "vfpv3",
787 "vfpv3d16",
788 NULL
791 static int c_show(struct seq_file *m, void *v)
793 int i;
795 seq_printf(m, "Processor\t: %s rev %d (%s)\n",
796 cpu_name, read_cpuid_id() & 15, elf_platform);
798 #if defined(CONFIG_SMP)
799 for_each_online_cpu(i) {
801 * glibc reads /proc/cpuinfo to determine the number of
802 * online processors, looking for lines beginning with
803 * "processor". Give glibc what it expects.
805 seq_printf(m, "processor\t: %d\n", i);
806 seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
807 per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
808 (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);
810 #else /* CONFIG_SMP */
811 seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
812 loops_per_jiffy / (500000/HZ),
813 (loops_per_jiffy / (5000/HZ)) % 100);
814 #endif
816 /* dump out the processor features */
817 seq_puts(m, "Features\t: ");
819 for (i = 0; hwcap_str[i]; i++)
820 if (elf_hwcap & (1 << i))
821 seq_printf(m, "%s ", hwcap_str[i]);
823 seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24);
824 seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]);
826 if ((read_cpuid_id() & 0x0008f000) == 0x00000000) {
827 /* pre-ARM7 */
828 seq_printf(m, "CPU part\t: %07x\n", read_cpuid_id() >> 4);
829 } else {
830 if ((read_cpuid_id() & 0x0008f000) == 0x00007000) {
831 /* ARM7 */
832 seq_printf(m, "CPU variant\t: 0x%02x\n",
833 (read_cpuid_id() >> 16) & 127);
834 } else {
835 /* post-ARM7 */
836 seq_printf(m, "CPU variant\t: 0x%x\n",
837 (read_cpuid_id() >> 20) & 15);
839 seq_printf(m, "CPU part\t: 0x%03x\n",
840 (read_cpuid_id() >> 4) & 0xfff);
842 seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15);
844 seq_puts(m, "\n");
846 seq_printf(m, "Hardware\t: %s\n", machine_name);
847 seq_printf(m, "Revision\t: %04x\n", system_rev);
848 seq_printf(m, "Serial\t\t: %08x%08x\n",
849 system_serial_high, system_serial_low);
851 return 0;
854 static void *c_start(struct seq_file *m, loff_t *pos)
856 return *pos < 1 ? (void *)1 : NULL;
859 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
861 ++*pos;
862 return NULL;
865 static void c_stop(struct seq_file *m, void *v)
869 const struct seq_operations cpuinfo_op = {
870 .start = c_start,
871 .next = c_next,
872 .stop = c_stop,
873 .show = c_show