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