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 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> 34 35 #include <asm/mach/arch.h> 36 #include <asm/mach/irq.h> 37 #include <asm/mach/time.h> 38 39 #include "compat.h" 40 41 #ifndef MEM_SIZE 42 #define MEM_SIZE (16*1024*1024) 43 #endif 44 45 #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE) 46 char fpe_type[8]; 47 48 static 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 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; 61 62 unsigned int processor_id; 63 unsigned int __machine_arch_type; 64 EXPORT_SYMBOL(__machine_arch_type); 65 66 unsigned int __atags_pointer __initdata; 67 68 unsigned int system_rev; 69 EXPORT_SYMBOL(system_rev); 70 71 unsigned int system_serial_low; 72 EXPORT_SYMBOL(system_serial_low); 73 74 unsigned int system_serial_high; 75 EXPORT_SYMBOL(system_serial_high); 76 77 unsigned int elf_hwcap; 78 EXPORT_SYMBOL(elf_hwcap); 79 80 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 96 97 struct stack { 98 u32 irq[3]; 99 u32 abt[3]; 100 u32 und[3]; 101 } ____cacheline_aligned; 102 103 static struct stack stacks[NR_CPUS]; 104 105 char elf_platform[ELF_PLATFORM_SIZE]; 106 EXPORT_SYMBOL(elf_platform); 107 108 unsigned long phys_initrd_start __initdata = 0; 109 unsigned long phys_initrd_size __initdata = 0; 110 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]; 115 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) 119 120 DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data); 121 122 /* 123 * Standard memory resources 124 */ 125 static struct resource mem_res[] = { 126 { 127 .name = "Video RAM", 128 .start = 0, 129 .end = 0, 130 .flags = IORESOURCE_MEM 131 }, 132 { 133 .name = "Kernel text", 134 .start = 0, 135 .end = 0, 136 .flags = IORESOURCE_MEM 137 }, 138 { 139 .name = "Kernel data", 140 .start = 0, 141 .end = 0, 142 .flags = IORESOURCE_MEM 143 } 144 }; 145 146 #define video_ram mem_res[0] 147 #define kernel_code mem_res[1] 148 #define kernel_data mem_res[2] 149 150 static struct resource io_res[] = { 151 { 152 .name = "reserved", 153 .start = 0x3bc, 154 .end = 0x3be, 155 .flags = IORESOURCE_IO | IORESOURCE_BUSY 156 }, 157 { 158 .name = "reserved", 159 .start = 0x378, 160 .end = 0x37f, 161 .flags = IORESOURCE_IO | IORESOURCE_BUSY 162 }, 163 { 164 .name = "reserved", 165 .start = 0x278, 166 .end = 0x27f, 167 .flags = IORESOURCE_IO | IORESOURCE_BUSY 168 } 169 }; 170 171 #define lp0 io_res[0] 172 #define lp1 io_res[1] 173 #define lp2 io_res[2] 174 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", 192 }; 193 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", 211 }; 212 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", 230 }; 231 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)", 250 }; 251 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) 256 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) 261 262 static inline void dump_cache(const char *prefix, int cpu, unsigned int cache) 263 { 264 unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0); 265 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))); 273 } 274 275 static void __init dump_cpu_info(int cpu) 276 { 277 unsigned int info = read_cpuid(CPUID_CACHETYPE); 278 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)); 287 } 288 } 289 290 if (arch_is_coherent()) 291 printk("Cache coherency enabled\n"); 292 } 293 294 int cpu_architecture(void) 295 { 296 int cpu_arch; 297 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; 309 } 310 311 return cpu_arch; 312 } 313 314 /* 315 * These functions re-use the assembly code in head.S, which 316 * already provide the required functionality. 317 */ 318 extern struct proc_info_list *lookup_processor_type(unsigned int); 319 extern struct machine_desc *lookup_machine_type(unsigned int); 320 321 static void __init setup_processor(void) 322 { 323 struct proc_info_list *list; 324 325 /* 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 329 */ 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); 335 } 336 337 cpu_name = list->cpu_name; 338 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 351 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); 355 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 362 363 cpu_proc_init(); 364 } 365 366 /* 367 * cpu_init - initialise one CPU. 368 * 369 * cpu_init dumps the cache information, initialises SMP specific 370 * information, and sets up the per-CPU stacks. 371 */ 372 void cpu_init(void) 373 { 374 unsigned int cpu = smp_processor_id(); 375 struct stack *stk = &stacks[cpu]; 376 377 if (cpu >= NR_CPUS) { 378 printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu); 379 BUG(); 380 } 381 382 if (system_state == SYSTEM_BOOTING) 383 dump_cpu_info(cpu); 384 385 /* 386 * setup stacks for re-entrant exception handlers 387 */ 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" 396 : 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"); 406 } 407 408 static struct machine_desc * __init setup_machine(unsigned int nr) 409 { 410 struct machine_desc *list; 411 412 /* 413 * locate machine in the list of supported machines. 414 */ 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); 420 } 421 422 printk("Machine: %s\n", list->name); 423 424 return list; 425 } 426 427 static void __init early_initrd(char **p) 428 { 429 unsigned long start, size; 430 431 start = memparse(*p, p); 432 if (**p == ',') { 433 size = memparse((*p) + 1, p); 434 435 phys_initrd_start = start; 436 phys_initrd_size = size; 437 } 438 } 439 __early_param("initrd=", early_initrd); 440 441 static void __init arm_add_memory(unsigned long start, unsigned long size) 442 { 443 struct membank *bank; 444 445 /* 446 * Ensure that start/size are aligned to a page boundary. 447 * Size is appropriately rounded down, start is rounded up. 448 */ 449 size -= start & ~PAGE_MASK; 450 451 bank = &meminfo.bank[meminfo.nr_banks++]; 452 453 bank->start = PAGE_ALIGN(start); 454 bank->size = size & PAGE_MASK; 455 bank->node = PHYS_TO_NID(start); 456 } 457 458 /* 459 * Pick out the memory size. We look for mem=size@start, 460 * where start and size are "size[KkMm]" 461 */ 462 static void __init early_mem(char **p) 463 { 464 static int usermem __initdata = 0; 465 unsigned long size, start; 466 467 /* 468 * If the user specifies memory size, we 469 * blow away any automatically generated 470 * size. 471 */ 472 if (usermem == 0) { 473 usermem = 1; 474 meminfo.nr_banks = 0; 475 } 476 477 start = PHYS_OFFSET; 478 size = memparse(*p, p); 479 if (**p == '@') 480 start = memparse(*p + 1, p); 481 482 arm_add_memory(start, size); 483 } 484 __early_param("mem=", early_mem); 485 486 /* 487 * Initial parsing of the command line. 488 */ 489 static void __init parse_cmdline(char **cmdline_p, char *from) 490 { 491 char c = ' ', *to = command_line; 492 int len = 0; 493 494 for (;;) { 495 if (c == ' ') { 496 extern struct early_params __early_begin, __early_end; 497 struct early_params *p; 498 499 for (p = &__early_begin; p < &__early_end; p++) { 500 int len = strlen(p->arg); 501 502 if (memcmp(from, p->arg, len) == 0) { 503 if (to != command_line) 504 to -= 1; 505 from += len; 506 p->fn(&from); 507 508 while (*from != ' ' && *from != '\0') 509 from++; 510 break; 511 } 512 } 513 } 514 c = *from++; 515 if (!c) 516 break; 517 if (COMMAND_LINE_SIZE <= ++len) 518 break; 519 *to++ = c; 520 } 521 *to = '\0'; 522 *cmdline_p = command_line; 523 } 524 525 static void __init 526 setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz) 527 { 528 #ifdef CONFIG_BLK_DEV_RAM 529 extern int rd_size, rd_image_start, rd_prompt, rd_doload; 530 531 rd_image_start = image_start; 532 rd_prompt = prompt; 533 rd_doload = doload; 534 535 if (rd_sz) 536 rd_size = rd_sz; 537 #endif 538 } 539 540 static void __init 541 request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc) 542 { 543 struct resource *res; 544 int i; 545 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); 550 551 for (i = 0; i < mi->nr_banks; i++) { 552 unsigned long virt_start, virt_end; 553 554 if (mi->bank[i].size == 0) 555 continue; 556 557 virt_start = __phys_to_virt(mi->bank[i].start); 558 virt_end = virt_start + mi->bank[i].size - 1; 559 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; 565 566 request_resource(&iomem_resource, res); 567 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); 574 } 575 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); 580 } 581 582 /* 583 * Some machines don't have the possibility of ever 584 * possessing lp0, lp1 or lp2 585 */ 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); 592 } 593 594 /* 595 * Tag parsing. 596 * 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). 603 */ 604 static int __init parse_tag_core(const struct tag *tag) 605 { 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); 610 } 611 return 0; 612 } 613 614 __tagtable(ATAG_CORE, parse_tag_core); 615 616 static int __init parse_tag_mem32(const struct tag *tag) 617 { 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; 623 } 624 arm_add_memory(tag->u.mem.start, tag->u.mem.size); 625 return 0; 626 } 627 628 __tagtable(ATAG_MEM, parse_tag_mem32); 629 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 638 }; 639 640 static int __init parse_tag_videotext(const struct tag *tag) 641 { 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; 652 } 653 654 __tagtable(ATAG_VIDEOTEXT, parse_tag_videotext); 655 #endif 656 657 static int __init parse_tag_ramdisk(const struct tag *tag) 658 { 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; 663 } 664 665 __tagtable(ATAG_RAMDISK, parse_tag_ramdisk); 666 667 static int __init parse_tag_initrd(const struct tag *tag) 668 { 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; 674 } 675 676 __tagtable(ATAG_INITRD, parse_tag_initrd); 677 678 static int __init parse_tag_initrd2(const struct tag *tag) 679 { 680 phys_initrd_start = tag->u.initrd.start; 681 phys_initrd_size = tag->u.initrd.size; 682 return 0; 683 } 684 685 __tagtable(ATAG_INITRD2, parse_tag_initrd2); 686 687 static int __init parse_tag_serialnr(const struct tag *tag) 688 { 689 system_serial_low = tag->u.serialnr.low; 690 system_serial_high = tag->u.serialnr.high; 691 return 0; 692 } 693 694 __tagtable(ATAG_SERIAL, parse_tag_serialnr); 695 696 static int __init parse_tag_revision(const struct tag *tag) 697 { 698 system_rev = tag->u.revision.rev; 699 return 0; 700 } 701 702 __tagtable(ATAG_REVISION, parse_tag_revision); 703 704 static int __init parse_tag_cmdline(const struct tag *tag) 705 { 706 strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE); 707 return 0; 708 } 709 710 __tagtable(ATAG_CMDLINE, parse_tag_cmdline); 711 712 /* 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. 716 */ 717 static int __init parse_tag(const struct tag *tag) 718 { 719 extern struct tagtable __tagtable_begin, __tagtable_end; 720 struct tagtable *t; 721 722 for (t = &__tagtable_begin; t < &__tagtable_end; t++) 723 if (tag->hdr.tag == t->tag) { 724 t->parse(tag); 725 break; 726 } 727 728 return t < &__tagtable_end; 729 } 730 731 /* 732 * Parse all tags in the list, checking both the global and architecture 733 * specific tag tables. 734 */ 735 static void __init parse_tags(const struct tag *t) 736 { 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); 742 } 743 744 /* 745 * This holds our defaults. 746 */ 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 } 759 }; 760 761 static void (*init_machine)(void) __initdata; 762 763 static int __init customize_machine(void) 764 { 765 /* customizes platform devices, or adds new ones */ 766 if (init_machine) 767 init_machine(); 768 return 0; 769 } 770 arch_initcall(customize_machine); 771 772 void __init setup_arch(char **cmdline_p) 773 { 774 struct tag *tags = (struct tag *)&init_tags; 775 struct machine_desc *mdesc; 776 char *from = default_command_line; 777 778 setup_processor(); 779 mdesc = setup_machine(machine_arch_type); 780 machine_name = mdesc->name; 781 782 if (mdesc->soft_reboot) 783 reboot_setup("s"); 784 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); 789 790 /* 791 * If we have the old style parameters, convert them to 792 * a tag list. 793 */ 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; 798 799 if (mdesc->fixup) 800 mdesc->fixup(mdesc, tags, &from, &meminfo); 801 802 if (tags->hdr.tag == ATAG_CORE) { 803 if (meminfo.nr_banks != 0) 804 squash_mem_tags(tags); 805 parse_tags(tags); 806 } 807 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; 812 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); 818 819 #ifdef CONFIG_SMP 820 smp_init_cpus(); 821 #endif 822 823 cpu_init(); 824 825 /* 826 * Set up various architecture-specific pointers 827 */ 828 init_arch_irq = mdesc->init_irq; 829 system_timer = mdesc->timer; 830 init_machine = mdesc->init_machine; 831 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 839 } 840 841 842 static int __init topology_init(void) 843 { 844 int cpu; 845 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); 850 } 851 852 return 0; 853 } 854 855 subsys_initcall(topology_init); 856 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 870 }; 871 872 static void 873 c_show_cache(struct seq_file *m, const char *type, unsigned int cache) 874 { 875 unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0); 876 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))); 886 } 887 888 static int c_show(struct seq_file *m, void *v) 889 { 890 int i; 891 892 seq_printf(m, "Processor\t: %s rev %d (%s)\n", 893 cpu_name, (int)processor_id & 15, elf_platform); 894 895 #if defined(CONFIG_SMP) 896 for_each_online_cpu(i) { 897 /* 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. 901 */ 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); 906 } 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 912 913 /* dump out the processor features */ 914 seq_puts(m, "Features\t: "); 915 916 for (i = 0; hwcap_str[i]; i++) 917 if (elf_hwcap & (1 << i)) 918 seq_printf(m, "%s ", hwcap_str[i]); 919 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()]); 922 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); 935 } 936 seq_printf(m, "CPU part\t: 0x%03x\n", 937 (processor_id >> 4) & 0xfff); 938 } 939 seq_printf(m, "CPU revision\t: %d\n", processor_id & 15); 940 941 { 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"); 952 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)); 958 } 959 } 960 } 961 962 seq_puts(m, "\n"); 963 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); 968 969 return 0; 970 } 971 972 static void *c_start(struct seq_file *m, loff_t *pos) 973 { 974 return *pos < 1 ? (void *)1 : NULL; 975 } 976 977 static void *c_next(struct seq_file *m, void *v, loff_t *pos) 978 { 979 ++*pos; 980 return NULL; 981 } 982 983 static void c_stop(struct seq_file *m, void *v) 984 { 985 } 986 987 struct seq_operations cpuinfo_op = { 988 .start = c_start, 989 .next = c_next, 990 .stop = c_stop, 991 .show = c_show 992 }; 993