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