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