[ARM] 4423/1: add ATAGS support
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / arch / arm / kernel / setup.c
blob5be2e987b8435b047bf168128364e3736eda30f4
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>
27 #include <asm/cpu.h>
28 #include <asm/elf.h>
29 #include <asm/procinfo.h>
30 #include <asm/setup.h>
31 #include <asm/mach-types.h>
32 #include <asm/cacheflush.h>
33 #include <asm/tlbflush.h>
35 #include <asm/mach/arch.h>
36 #include <asm/mach/irq.h>
37 #include <asm/mach/time.h>
39 #include "compat.h"
41 #ifndef MEM_SIZE
42 #define MEM_SIZE (16*1024*1024)
43 #endif
45 #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
46 char fpe_type[8];
48 static int __init fpe_setup(char *line)
50 memcpy(fpe_type, line, 8);
51 return 1;
54 __setup("fpe=", fpe_setup);
55 #endif
57 extern void paging_init(struct meminfo *, struct machine_desc *desc);
58 extern void reboot_setup(char *str);
59 extern int root_mountflags;
60 extern void _stext, _text, _etext, __data_start, _edata, _end;
62 unsigned int processor_id;
63 unsigned int __machine_arch_type;
64 EXPORT_SYMBOL(__machine_arch_type);
66 unsigned int __atags_pointer __initdata;
68 unsigned int system_rev;
69 EXPORT_SYMBOL(system_rev);
71 unsigned int system_serial_low;
72 EXPORT_SYMBOL(system_serial_low);
74 unsigned int system_serial_high;
75 EXPORT_SYMBOL(system_serial_high);
77 unsigned int elf_hwcap;
78 EXPORT_SYMBOL(elf_hwcap);
81 #ifdef MULTI_CPU
82 struct processor processor;
83 #endif
84 #ifdef MULTI_TLB
85 struct cpu_tlb_fns cpu_tlb;
86 #endif
87 #ifdef MULTI_USER
88 struct cpu_user_fns cpu_user;
89 #endif
90 #ifdef MULTI_CACHE
91 struct cpu_cache_fns cpu_cache;
92 #endif
93 #ifdef CONFIG_OUTER_CACHE
94 struct outer_cache_fns outer_cache;
95 #endif
97 struct stack {
98 u32 irq[3];
99 u32 abt[3];
100 u32 und[3];
101 } ____cacheline_aligned;
103 static struct stack stacks[NR_CPUS];
105 char elf_platform[ELF_PLATFORM_SIZE];
106 EXPORT_SYMBOL(elf_platform);
108 unsigned long phys_initrd_start __initdata = 0;
109 unsigned long phys_initrd_size __initdata = 0;
111 static struct meminfo meminfo __initdata = { 0, };
112 static const char *cpu_name;
113 static const char *machine_name;
114 static char __initdata command_line[COMMAND_LINE_SIZE];
116 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
117 static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
118 #define ENDIANNESS ((char)endian_test.l)
120 DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data);
123 * Standard memory resources
125 static struct resource mem_res[] = {
127 .name = "Video RAM",
128 .start = 0,
129 .end = 0,
130 .flags = IORESOURCE_MEM
133 .name = "Kernel text",
134 .start = 0,
135 .end = 0,
136 .flags = IORESOURCE_MEM
139 .name = "Kernel data",
140 .start = 0,
141 .end = 0,
142 .flags = IORESOURCE_MEM
146 #define video_ram mem_res[0]
147 #define kernel_code mem_res[1]
148 #define kernel_data mem_res[2]
150 static struct resource io_res[] = {
152 .name = "reserved",
153 .start = 0x3bc,
154 .end = 0x3be,
155 .flags = IORESOURCE_IO | IORESOURCE_BUSY
158 .name = "reserved",
159 .start = 0x378,
160 .end = 0x37f,
161 .flags = IORESOURCE_IO | IORESOURCE_BUSY
164 .name = "reserved",
165 .start = 0x278,
166 .end = 0x27f,
167 .flags = IORESOURCE_IO | IORESOURCE_BUSY
171 #define lp0 io_res[0]
172 #define lp1 io_res[1]
173 #define lp2 io_res[2]
175 static const char *cache_types[16] = {
176 "write-through",
177 "write-back",
178 "write-back",
179 "undefined 3",
180 "undefined 4",
181 "undefined 5",
182 "write-back",
183 "write-back",
184 "undefined 8",
185 "undefined 9",
186 "undefined 10",
187 "undefined 11",
188 "undefined 12",
189 "undefined 13",
190 "write-back",
191 "undefined 15",
194 static const char *cache_clean[16] = {
195 "not required",
196 "read-block",
197 "cp15 c7 ops",
198 "undefined 3",
199 "undefined 4",
200 "undefined 5",
201 "cp15 c7 ops",
202 "cp15 c7 ops",
203 "undefined 8",
204 "undefined 9",
205 "undefined 10",
206 "undefined 11",
207 "undefined 12",
208 "undefined 13",
209 "cp15 c7 ops",
210 "undefined 15",
213 static const char *cache_lockdown[16] = {
214 "not supported",
215 "not supported",
216 "not supported",
217 "undefined 3",
218 "undefined 4",
219 "undefined 5",
220 "format A",
221 "format B",
222 "undefined 8",
223 "undefined 9",
224 "undefined 10",
225 "undefined 11",
226 "undefined 12",
227 "undefined 13",
228 "format C",
229 "undefined 15",
232 static const char *proc_arch[] = {
233 "undefined/unknown",
234 "3",
235 "4",
236 "4T",
237 "5",
238 "5T",
239 "5TE",
240 "5TEJ",
241 "6TEJ",
242 "7",
243 "?(11)",
244 "?(12)",
245 "?(13)",
246 "?(14)",
247 "?(15)",
248 "?(16)",
249 "?(17)",
252 #define CACHE_TYPE(x) (((x) >> 25) & 15)
253 #define CACHE_S(x) ((x) & (1 << 24))
254 #define CACHE_DSIZE(x) (((x) >> 12) & 4095) /* only if S=1 */
255 #define CACHE_ISIZE(x) ((x) & 4095)
257 #define CACHE_SIZE(y) (((y) >> 6) & 7)
258 #define CACHE_ASSOC(y) (((y) >> 3) & 7)
259 #define CACHE_M(y) ((y) & (1 << 2))
260 #define CACHE_LINE(y) ((y) & 3)
262 static inline void dump_cache(const char *prefix, int cpu, unsigned int cache)
264 unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0);
266 printk("CPU%u: %s: %d bytes, associativity %d, %d byte lines, %d sets\n",
267 cpu, prefix,
268 mult << (8 + CACHE_SIZE(cache)),
269 (mult << CACHE_ASSOC(cache)) >> 1,
270 8 << CACHE_LINE(cache),
271 1 << (6 + CACHE_SIZE(cache) - CACHE_ASSOC(cache) -
272 CACHE_LINE(cache)));
275 static void __init dump_cpu_info(int cpu)
277 unsigned int info = read_cpuid(CPUID_CACHETYPE);
279 if (info != processor_id) {
280 printk("CPU%u: D %s %s cache\n", cpu, cache_is_vivt() ? "VIVT" : "VIPT",
281 cache_types[CACHE_TYPE(info)]);
282 if (CACHE_S(info)) {
283 dump_cache("I cache", cpu, CACHE_ISIZE(info));
284 dump_cache("D cache", cpu, CACHE_DSIZE(info));
285 } else {
286 dump_cache("cache", cpu, CACHE_ISIZE(info));
290 if (arch_is_coherent())
291 printk("Cache coherency enabled\n");
294 int cpu_architecture(void)
296 int cpu_arch;
298 if ((processor_id & 0x0008f000) == 0) {
299 cpu_arch = CPU_ARCH_UNKNOWN;
300 } else if ((processor_id & 0x0008f000) == 0x00007000) {
301 cpu_arch = (processor_id & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3;
302 } else if ((processor_id & 0x00080000) == 0x00000000) {
303 cpu_arch = (processor_id >> 16) & 7;
304 if (cpu_arch)
305 cpu_arch += CPU_ARCH_ARMv3;
306 } else {
307 /* the revised CPUID */
308 cpu_arch = ((processor_id >> 12) & 0xf) - 0xb + CPU_ARCH_ARMv6;
311 return cpu_arch;
315 * These functions re-use the assembly code in head.S, which
316 * already provide the required functionality.
318 extern struct proc_info_list *lookup_processor_type(unsigned int);
319 extern struct machine_desc *lookup_machine_type(unsigned int);
321 static void __init setup_processor(void)
323 struct proc_info_list *list;
326 * locate processor in the list of supported processor
327 * types. The linker builds this table for us from the
328 * entries in arch/arm/mm/proc-*.S
330 list = lookup_processor_type(processor_id);
331 if (!list) {
332 printk("CPU configuration botched (ID %08x), unable "
333 "to continue.\n", processor_id);
334 while (1);
337 cpu_name = list->cpu_name;
339 #ifdef MULTI_CPU
340 processor = *list->proc;
341 #endif
342 #ifdef MULTI_TLB
343 cpu_tlb = *list->tlb;
344 #endif
345 #ifdef MULTI_USER
346 cpu_user = *list->user;
347 #endif
348 #ifdef MULTI_CACHE
349 cpu_cache = *list->cache;
350 #endif
352 printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n",
353 cpu_name, processor_id, (int)processor_id & 15,
354 proc_arch[cpu_architecture()], cr_alignment);
356 sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS);
357 sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS);
358 elf_hwcap = list->elf_hwcap;
359 #ifndef CONFIG_ARM_THUMB
360 elf_hwcap &= ~HWCAP_THUMB;
361 #endif
363 cpu_proc_init();
367 * cpu_init - initialise one CPU.
369 * cpu_init dumps the cache information, initialises SMP specific
370 * information, and sets up the per-CPU stacks.
372 void cpu_init(void)
374 unsigned int cpu = smp_processor_id();
375 struct stack *stk = &stacks[cpu];
377 if (cpu >= NR_CPUS) {
378 printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu);
379 BUG();
382 if (system_state == SYSTEM_BOOTING)
383 dump_cpu_info(cpu);
386 * setup stacks for re-entrant exception handlers
388 __asm__ (
389 "msr cpsr_c, %1\n\t"
390 "add sp, %0, %2\n\t"
391 "msr cpsr_c, %3\n\t"
392 "add sp, %0, %4\n\t"
393 "msr cpsr_c, %5\n\t"
394 "add sp, %0, %6\n\t"
395 "msr cpsr_c, %7"
397 : "r" (stk),
398 "I" (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
399 "I" (offsetof(struct stack, irq[0])),
400 "I" (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
401 "I" (offsetof(struct stack, abt[0])),
402 "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),
403 "I" (offsetof(struct stack, und[0])),
404 "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
405 : "r14");
408 static struct machine_desc * __init setup_machine(unsigned int nr)
410 struct machine_desc *list;
413 * locate machine in the list of supported machines.
415 list = lookup_machine_type(nr);
416 if (!list) {
417 printk("Machine configuration botched (nr %d), unable "
418 "to continue.\n", nr);
419 while (1);
422 printk("Machine: %s\n", list->name);
424 return list;
427 static void __init early_initrd(char **p)
429 unsigned long start, size;
431 start = memparse(*p, p);
432 if (**p == ',') {
433 size = memparse((*p) + 1, p);
435 phys_initrd_start = start;
436 phys_initrd_size = size;
439 __early_param("initrd=", early_initrd);
441 static void __init arm_add_memory(unsigned long start, unsigned long size)
443 struct membank *bank;
446 * Ensure that start/size are aligned to a page boundary.
447 * Size is appropriately rounded down, start is rounded up.
449 size -= start & ~PAGE_MASK;
451 bank = &meminfo.bank[meminfo.nr_banks++];
453 bank->start = PAGE_ALIGN(start);
454 bank->size = size & PAGE_MASK;
455 bank->node = PHYS_TO_NID(start);
459 * Pick out the memory size. We look for mem=size@start,
460 * where start and size are "size[KkMm]"
462 static void __init early_mem(char **p)
464 static int usermem __initdata = 0;
465 unsigned long size, start;
468 * If the user specifies memory size, we
469 * blow away any automatically generated
470 * size.
472 if (usermem == 0) {
473 usermem = 1;
474 meminfo.nr_banks = 0;
477 start = PHYS_OFFSET;
478 size = memparse(*p, p);
479 if (**p == '@')
480 start = memparse(*p + 1, p);
482 arm_add_memory(start, size);
484 __early_param("mem=", early_mem);
487 * Initial parsing of the command line.
489 static void __init parse_cmdline(char **cmdline_p, char *from)
491 char c = ' ', *to = command_line;
492 int len = 0;
494 for (;;) {
495 if (c == ' ') {
496 extern struct early_params __early_begin, __early_end;
497 struct early_params *p;
499 for (p = &__early_begin; p < &__early_end; p++) {
500 int len = strlen(p->arg);
502 if (memcmp(from, p->arg, len) == 0) {
503 if (to != command_line)
504 to -= 1;
505 from += len;
506 p->fn(&from);
508 while (*from != ' ' && *from != '\0')
509 from++;
510 break;
514 c = *from++;
515 if (!c)
516 break;
517 if (COMMAND_LINE_SIZE <= ++len)
518 break;
519 *to++ = c;
521 *to = '\0';
522 *cmdline_p = command_line;
525 static void __init
526 setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
528 #ifdef CONFIG_BLK_DEV_RAM
529 extern int rd_size, rd_image_start, rd_prompt, rd_doload;
531 rd_image_start = image_start;
532 rd_prompt = prompt;
533 rd_doload = doload;
535 if (rd_sz)
536 rd_size = rd_sz;
537 #endif
540 static void __init
541 request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
543 struct resource *res;
544 int i;
546 kernel_code.start = virt_to_phys(&_text);
547 kernel_code.end = virt_to_phys(&_etext - 1);
548 kernel_data.start = virt_to_phys(&__data_start);
549 kernel_data.end = virt_to_phys(&_end - 1);
551 for (i = 0; i < mi->nr_banks; i++) {
552 unsigned long virt_start, virt_end;
554 if (mi->bank[i].size == 0)
555 continue;
557 virt_start = __phys_to_virt(mi->bank[i].start);
558 virt_end = virt_start + mi->bank[i].size - 1;
560 res = alloc_bootmem_low(sizeof(*res));
561 res->name = "System RAM";
562 res->start = __virt_to_phys(virt_start);
563 res->end = __virt_to_phys(virt_end);
564 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
566 request_resource(&iomem_resource, res);
568 if (kernel_code.start >= res->start &&
569 kernel_code.end <= res->end)
570 request_resource(res, &kernel_code);
571 if (kernel_data.start >= res->start &&
572 kernel_data.end <= res->end)
573 request_resource(res, &kernel_data);
576 if (mdesc->video_start) {
577 video_ram.start = mdesc->video_start;
578 video_ram.end = mdesc->video_end;
579 request_resource(&iomem_resource, &video_ram);
583 * Some machines don't have the possibility of ever
584 * possessing lp0, lp1 or lp2
586 if (mdesc->reserve_lp0)
587 request_resource(&ioport_resource, &lp0);
588 if (mdesc->reserve_lp1)
589 request_resource(&ioport_resource, &lp1);
590 if (mdesc->reserve_lp2)
591 request_resource(&ioport_resource, &lp2);
595 * Tag parsing.
597 * This is the new way of passing data to the kernel at boot time. Rather
598 * than passing a fixed inflexible structure to the kernel, we pass a list
599 * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE
600 * tag for the list to be recognised (to distinguish the tagged list from
601 * a param_struct). The list is terminated with a zero-length tag (this tag
602 * is not parsed in any way).
604 static int __init parse_tag_core(const struct tag *tag)
606 if (tag->hdr.size > 2) {
607 if ((tag->u.core.flags & 1) == 0)
608 root_mountflags &= ~MS_RDONLY;
609 ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
611 return 0;
614 __tagtable(ATAG_CORE, parse_tag_core);
616 static int __init parse_tag_mem32(const struct tag *tag)
618 if (meminfo.nr_banks >= NR_BANKS) {
619 printk(KERN_WARNING
620 "Ignoring memory bank 0x%08x size %dKB\n",
621 tag->u.mem.start, tag->u.mem.size / 1024);
622 return -EINVAL;
624 arm_add_memory(tag->u.mem.start, tag->u.mem.size);
625 return 0;
628 __tagtable(ATAG_MEM, parse_tag_mem32);
630 #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
631 struct screen_info screen_info = {
632 .orig_video_lines = 30,
633 .orig_video_cols = 80,
634 .orig_video_mode = 0,
635 .orig_video_ega_bx = 0,
636 .orig_video_isVGA = 1,
637 .orig_video_points = 8
640 static int __init parse_tag_videotext(const struct tag *tag)
642 screen_info.orig_x = tag->u.videotext.x;
643 screen_info.orig_y = tag->u.videotext.y;
644 screen_info.orig_video_page = tag->u.videotext.video_page;
645 screen_info.orig_video_mode = tag->u.videotext.video_mode;
646 screen_info.orig_video_cols = tag->u.videotext.video_cols;
647 screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
648 screen_info.orig_video_lines = tag->u.videotext.video_lines;
649 screen_info.orig_video_isVGA = tag->u.videotext.video_isvga;
650 screen_info.orig_video_points = tag->u.videotext.video_points;
651 return 0;
654 __tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
655 #endif
657 static int __init parse_tag_ramdisk(const struct tag *tag)
659 setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
660 (tag->u.ramdisk.flags & 2) == 0,
661 tag->u.ramdisk.start, tag->u.ramdisk.size);
662 return 0;
665 __tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
667 static int __init parse_tag_initrd(const struct tag *tag)
669 printk(KERN_WARNING "ATAG_INITRD is deprecated; "
670 "please update your bootloader.\n");
671 phys_initrd_start = __virt_to_phys(tag->u.initrd.start);
672 phys_initrd_size = tag->u.initrd.size;
673 return 0;
676 __tagtable(ATAG_INITRD, parse_tag_initrd);
678 static int __init parse_tag_initrd2(const struct tag *tag)
680 phys_initrd_start = tag->u.initrd.start;
681 phys_initrd_size = tag->u.initrd.size;
682 return 0;
685 __tagtable(ATAG_INITRD2, parse_tag_initrd2);
687 static int __init parse_tag_serialnr(const struct tag *tag)
689 system_serial_low = tag->u.serialnr.low;
690 system_serial_high = tag->u.serialnr.high;
691 return 0;
694 __tagtable(ATAG_SERIAL, parse_tag_serialnr);
696 static int __init parse_tag_revision(const struct tag *tag)
698 system_rev = tag->u.revision.rev;
699 return 0;
702 __tagtable(ATAG_REVISION, parse_tag_revision);
704 static int __init parse_tag_cmdline(const struct tag *tag)
706 strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
707 return 0;
710 __tagtable(ATAG_CMDLINE, parse_tag_cmdline);
713 * Scan the tag table for this tag, and call its parse function.
714 * The tag table is built by the linker from all the __tagtable
715 * declarations.
717 static int __init parse_tag(const struct tag *tag)
719 extern struct tagtable __tagtable_begin, __tagtable_end;
720 struct tagtable *t;
722 for (t = &__tagtable_begin; t < &__tagtable_end; t++)
723 if (tag->hdr.tag == t->tag) {
724 t->parse(tag);
725 break;
728 return t < &__tagtable_end;
732 * Parse all tags in the list, checking both the global and architecture
733 * specific tag tables.
735 static void __init parse_tags(const struct tag *t)
737 for (; t->hdr.size; t = tag_next(t))
738 if (!parse_tag(t))
739 printk(KERN_WARNING
740 "Ignoring unrecognised tag 0x%08x\n",
741 t->hdr.tag);
745 * This holds our defaults.
747 static struct init_tags {
748 struct tag_header hdr1;
749 struct tag_core core;
750 struct tag_header hdr2;
751 struct tag_mem32 mem;
752 struct tag_header hdr3;
753 } init_tags __initdata = {
754 { tag_size(tag_core), ATAG_CORE },
755 { 1, PAGE_SIZE, 0xff },
756 { tag_size(tag_mem32), ATAG_MEM },
757 { MEM_SIZE, PHYS_OFFSET },
758 { 0, ATAG_NONE }
761 static void (*init_machine)(void) __initdata;
763 static int __init customize_machine(void)
765 /* customizes platform devices, or adds new ones */
766 if (init_machine)
767 init_machine();
768 return 0;
770 arch_initcall(customize_machine);
772 void __init setup_arch(char **cmdline_p)
774 struct tag *tags = (struct tag *)&init_tags;
775 struct machine_desc *mdesc;
776 char *from = default_command_line;
778 setup_processor();
779 mdesc = setup_machine(machine_arch_type);
780 machine_name = mdesc->name;
782 if (mdesc->soft_reboot)
783 reboot_setup("s");
785 if (__atags_pointer)
786 tags = phys_to_virt(__atags_pointer);
787 else if (mdesc->boot_params)
788 tags = phys_to_virt(mdesc->boot_params);
791 * If we have the old style parameters, convert them to
792 * a tag list.
794 if (tags->hdr.tag != ATAG_CORE)
795 convert_to_tag_list(tags);
796 if (tags->hdr.tag != ATAG_CORE)
797 tags = (struct tag *)&init_tags;
799 if (mdesc->fixup)
800 mdesc->fixup(mdesc, tags, &from, &meminfo);
802 if (tags->hdr.tag == ATAG_CORE) {
803 if (meminfo.nr_banks != 0)
804 squash_mem_tags(tags);
805 parse_tags(tags);
808 init_mm.start_code = (unsigned long) &_text;
809 init_mm.end_code = (unsigned long) &_etext;
810 init_mm.end_data = (unsigned long) &_edata;
811 init_mm.brk = (unsigned long) &_end;
813 memcpy(boot_command_line, from, COMMAND_LINE_SIZE);
814 boot_command_line[COMMAND_LINE_SIZE-1] = '\0';
815 parse_cmdline(cmdline_p, from);
816 paging_init(&meminfo, mdesc);
817 request_standard_resources(&meminfo, mdesc);
819 #ifdef CONFIG_SMP
820 smp_init_cpus();
821 #endif
823 cpu_init();
826 * Set up various architecture-specific pointers
828 init_arch_irq = mdesc->init_irq;
829 system_timer = mdesc->timer;
830 init_machine = mdesc->init_machine;
832 #ifdef CONFIG_VT
833 #if defined(CONFIG_VGA_CONSOLE)
834 conswitchp = &vga_con;
835 #elif defined(CONFIG_DUMMY_CONSOLE)
836 conswitchp = &dummy_con;
837 #endif
838 #endif
842 static int __init topology_init(void)
844 int cpu;
846 for_each_possible_cpu(cpu) {
847 struct cpuinfo_arm *cpuinfo = &per_cpu(cpu_data, cpu);
848 cpuinfo->cpu.hotpluggable = 1;
849 register_cpu(&cpuinfo->cpu, cpu);
852 return 0;
855 subsys_initcall(topology_init);
857 static const char *hwcap_str[] = {
858 "swp",
859 "half",
860 "thumb",
861 "26bit",
862 "fastmult",
863 "fpa",
864 "vfp",
865 "edsp",
866 "java",
867 "iwmmxt",
868 "crunch",
869 NULL
872 static void
873 c_show_cache(struct seq_file *m, const char *type, unsigned int cache)
875 unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0);
877 seq_printf(m, "%s size\t\t: %d\n"
878 "%s assoc\t\t: %d\n"
879 "%s line length\t: %d\n"
880 "%s sets\t\t: %d\n",
881 type, mult << (8 + CACHE_SIZE(cache)),
882 type, (mult << CACHE_ASSOC(cache)) >> 1,
883 type, 8 << CACHE_LINE(cache),
884 type, 1 << (6 + CACHE_SIZE(cache) - CACHE_ASSOC(cache) -
885 CACHE_LINE(cache)));
888 static int c_show(struct seq_file *m, void *v)
890 int i;
892 seq_printf(m, "Processor\t: %s rev %d (%s)\n",
893 cpu_name, (int)processor_id & 15, elf_platform);
895 #if defined(CONFIG_SMP)
896 for_each_online_cpu(i) {
898 * glibc reads /proc/cpuinfo to determine the number of
899 * online processors, looking for lines beginning with
900 * "processor". Give glibc what it expects.
902 seq_printf(m, "processor\t: %d\n", i);
903 seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n",
904 per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),
905 (per_cpu(cpu_data, i).loops_per_jiffy / (5000UL/HZ)) % 100);
907 #else /* CONFIG_SMP */
908 seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
909 loops_per_jiffy / (500000/HZ),
910 (loops_per_jiffy / (5000/HZ)) % 100);
911 #endif
913 /* dump out the processor features */
914 seq_puts(m, "Features\t: ");
916 for (i = 0; hwcap_str[i]; i++)
917 if (elf_hwcap & (1 << i))
918 seq_printf(m, "%s ", hwcap_str[i]);
920 seq_printf(m, "\nCPU implementer\t: 0x%02x\n", processor_id >> 24);
921 seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]);
923 if ((processor_id & 0x0008f000) == 0x00000000) {
924 /* pre-ARM7 */
925 seq_printf(m, "CPU part\t: %07x\n", processor_id >> 4);
926 } else {
927 if ((processor_id & 0x0008f000) == 0x00007000) {
928 /* ARM7 */
929 seq_printf(m, "CPU variant\t: 0x%02x\n",
930 (processor_id >> 16) & 127);
931 } else {
932 /* post-ARM7 */
933 seq_printf(m, "CPU variant\t: 0x%x\n",
934 (processor_id >> 20) & 15);
936 seq_printf(m, "CPU part\t: 0x%03x\n",
937 (processor_id >> 4) & 0xfff);
939 seq_printf(m, "CPU revision\t: %d\n", processor_id & 15);
942 unsigned int cache_info = read_cpuid(CPUID_CACHETYPE);
943 if (cache_info != processor_id) {
944 seq_printf(m, "Cache type\t: %s\n"
945 "Cache clean\t: %s\n"
946 "Cache lockdown\t: %s\n"
947 "Cache format\t: %s\n",
948 cache_types[CACHE_TYPE(cache_info)],
949 cache_clean[CACHE_TYPE(cache_info)],
950 cache_lockdown[CACHE_TYPE(cache_info)],
951 CACHE_S(cache_info) ? "Harvard" : "Unified");
953 if (CACHE_S(cache_info)) {
954 c_show_cache(m, "I", CACHE_ISIZE(cache_info));
955 c_show_cache(m, "D", CACHE_DSIZE(cache_info));
956 } else {
957 c_show_cache(m, "Cache", CACHE_ISIZE(cache_info));
962 seq_puts(m, "\n");
964 seq_printf(m, "Hardware\t: %s\n", machine_name);
965 seq_printf(m, "Revision\t: %04x\n", system_rev);
966 seq_printf(m, "Serial\t\t: %08x%08x\n",
967 system_serial_high, system_serial_low);
969 return 0;
972 static void *c_start(struct seq_file *m, loff_t *pos)
974 return *pos < 1 ? (void *)1 : NULL;
977 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
979 ++*pos;
980 return NULL;
983 static void c_stop(struct seq_file *m, void *v)
987 struct seq_operations cpuinfo_op = {
988 .start = c_start,
989 .next = c_next,
990 .stop = c_stop,
991 .show = c_show