diff options
Diffstat (limited to 'arch/arm/kernel/setup.c')
| -rw-r--r-- | arch/arm/kernel/setup.c | 111 |
1 files changed, 109 insertions, 2 deletions
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 122d999bdc7..d5231ae7355 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
| @@ -19,12 +19,15 @@ | |||
| 19 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
| 20 | #include <linux/screen_info.h> | 20 | #include <linux/screen_info.h> |
| 21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 22 | #include <linux/kexec.h> | ||
| 23 | #include <linux/crash_dump.h> | ||
| 22 | #include <linux/root_dev.h> | 24 | #include <linux/root_dev.h> |
| 23 | #include <linux/cpu.h> | 25 | #include <linux/cpu.h> |
| 24 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
| 25 | #include <linux/smp.h> | 27 | #include <linux/smp.h> |
| 26 | #include <linux/fs.h> | 28 | #include <linux/fs.h> |
| 27 | #include <linux/proc_fs.h> | 29 | #include <linux/proc_fs.h> |
| 30 | #include <linux/memblock.h> | ||
| 28 | 31 | ||
| 29 | #include <asm/unified.h> | 32 | #include <asm/unified.h> |
| 30 | #include <asm/cpu.h> | 33 | #include <asm/cpu.h> |
| @@ -44,7 +47,9 @@ | |||
| 44 | #include <asm/traps.h> | 47 | #include <asm/traps.h> |
| 45 | #include <asm/unwind.h> | 48 | #include <asm/unwind.h> |
| 46 | 49 | ||
| 50 | #if defined(CONFIG_DEPRECATED_PARAM_STRUCT) | ||
| 47 | #include "compat.h" | 51 | #include "compat.h" |
| 52 | #endif | ||
| 48 | #include "atags.h" | 53 | #include "atags.h" |
| 49 | #include "tcm.h" | 54 | #include "tcm.h" |
| 50 | 55 | ||
| @@ -269,6 +274,21 @@ static void __init cacheid_init(void) | |||
| 269 | extern struct proc_info_list *lookup_processor_type(unsigned int); | 274 | extern struct proc_info_list *lookup_processor_type(unsigned int); |
| 270 | extern struct machine_desc *lookup_machine_type(unsigned int); | 275 | extern struct machine_desc *lookup_machine_type(unsigned int); |
| 271 | 276 | ||
| 277 | static void __init feat_v6_fixup(void) | ||
| 278 | { | ||
| 279 | int id = read_cpuid_id(); | ||
| 280 | |||
| 281 | if ((id & 0xff0f0000) != 0x41070000) | ||
| 282 | return; | ||
| 283 | |||
| 284 | /* | ||
| 285 | * HWCAP_TLS is available only on 1136 r1p0 and later, | ||
| 286 | * see also kuser_get_tls_init. | ||
| 287 | */ | ||
| 288 | if ((((id >> 4) & 0xfff) == 0xb36) && (((id >> 20) & 3) == 0)) | ||
| 289 | elf_hwcap &= ~HWCAP_TLS; | ||
| 290 | } | ||
| 291 | |||
| 272 | static void __init setup_processor(void) | 292 | static void __init setup_processor(void) |
| 273 | { | 293 | { |
| 274 | struct proc_info_list *list; | 294 | struct proc_info_list *list; |
| @@ -311,6 +331,8 @@ static void __init setup_processor(void) | |||
| 311 | elf_hwcap &= ~HWCAP_THUMB; | 331 | elf_hwcap &= ~HWCAP_THUMB; |
| 312 | #endif | 332 | #endif |
| 313 | 333 | ||
| 334 | feat_v6_fixup(); | ||
| 335 | |||
| 314 | cacheid_init(); | 336 | cacheid_init(); |
| 315 | cpu_proc_init(); | 337 | cpu_proc_init(); |
| 316 | } | 338 | } |
| @@ -402,13 +424,12 @@ static int __init arm_add_memory(unsigned long start, unsigned long size) | |||
| 402 | size -= start & ~PAGE_MASK; | 424 | size -= start & ~PAGE_MASK; |
| 403 | bank->start = PAGE_ALIGN(start); | 425 | bank->start = PAGE_ALIGN(start); |
| 404 | bank->size = size & PAGE_MASK; | 426 | bank->size = size & PAGE_MASK; |
| 405 | bank->node = PHYS_TO_NID(start); | ||
| 406 | 427 | ||
| 407 | /* | 428 | /* |
| 408 | * Check whether this memory region has non-zero size or | 429 | * Check whether this memory region has non-zero size or |
| 409 | * invalid node number. | 430 | * invalid node number. |
| 410 | */ | 431 | */ |
| 411 | if (bank->size == 0 || bank->node >= MAX_NUMNODES) | 432 | if (bank->size == 0) |
| 412 | return -EINVAL; | 433 | return -EINVAL; |
| 413 | 434 | ||
| 414 | meminfo.nr_banks++; | 435 | meminfo.nr_banks++; |
| @@ -663,6 +684,86 @@ static int __init customize_machine(void) | |||
| 663 | } | 684 | } |
| 664 | arch_initcall(customize_machine); | 685 | arch_initcall(customize_machine); |
| 665 | 686 | ||
| 687 | #ifdef CONFIG_KEXEC | ||
| 688 | static inline unsigned long long get_total_mem(void) | ||
| 689 | { | ||
| 690 | unsigned long total; | ||
| 691 | |||
| 692 | total = max_low_pfn - min_low_pfn; | ||
| 693 | return total << PAGE_SHIFT; | ||
| 694 | } | ||
| 695 | |||
| 696 | /** | ||
| 697 | * reserve_crashkernel() - reserves memory are for crash kernel | ||
| 698 | * | ||
| 699 | * This function reserves memory area given in "crashkernel=" kernel command | ||
| 700 | * line parameter. The memory reserved is used by a dump capture kernel when | ||
| 701 | * primary kernel is crashing. | ||
| 702 | */ | ||
| 703 | static void __init reserve_crashkernel(void) | ||
| 704 | { | ||
| 705 | unsigned long long crash_size, crash_base; | ||
| 706 | unsigned long long total_mem; | ||
| 707 | int ret; | ||
| 708 | |||
| 709 | total_mem = get_total_mem(); | ||
| 710 | ret = parse_crashkernel(boot_command_line, total_mem, | ||
| 711 | &crash_size, &crash_base); | ||
| 712 | if (ret) | ||
| 713 | return; | ||
| 714 | |||
| 715 | ret = reserve_bootmem(crash_base, crash_size, BOOTMEM_EXCLUSIVE); | ||
| 716 | if (ret < 0) { | ||
| 717 | printk(KERN_WARNING "crashkernel reservation failed - " | ||
| 718 | "memory is in use (0x%lx)\n", (unsigned long)crash_base); | ||
| 719 | return; | ||
| 720 | } | ||
| 721 | |||
| 722 | printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " | ||
| 723 | "for crashkernel (System RAM: %ldMB)\n", | ||
| 724 | (unsigned long)(crash_size >> 20), | ||
| 725 | (unsigned long)(crash_base >> 20), | ||
| 726 | (unsigned long)(total_mem >> 20)); | ||
| 727 | |||
| 728 | crashk_res.start = crash_base; | ||
| 729 | crashk_res.end = crash_base + crash_size - 1; | ||
| 730 | insert_resource(&iomem_resource, &crashk_res); | ||
| 731 | } | ||
| 732 | #else | ||
| 733 | static inline void reserve_crashkernel(void) {} | ||
| 734 | #endif /* CONFIG_KEXEC */ | ||
| 735 | |||
| 736 | /* | ||
| 737 | * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by | ||
| 738 | * is_kdump_kernel() to determine if we are booting after a panic. Hence | ||
| 739 | * ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE. | ||
| 740 | */ | ||
| 741 | |||
| 742 | #ifdef CONFIG_CRASH_DUMP | ||
| 743 | /* | ||
| 744 | * elfcorehdr= specifies the location of elf core header stored by the crashed | ||
| 745 | * kernel. This option will be passed by kexec loader to the capture kernel. | ||
| 746 | */ | ||
| 747 | static int __init setup_elfcorehdr(char *arg) | ||
| 748 | { | ||
| 749 | char *end; | ||
| 750 | |||
| 751 | if (!arg) | ||
| 752 | return -EINVAL; | ||
| 753 | |||
| 754 | elfcorehdr_addr = memparse(arg, &end); | ||
| 755 | return end > arg ? 0 : -EINVAL; | ||
| 756 | } | ||
| 757 | early_param("elfcorehdr", setup_elfcorehdr); | ||
| 758 | #endif /* CONFIG_CRASH_DUMP */ | ||
| 759 | |||
| 760 | static void __init squash_mem_tags(struct tag *tag) | ||
| 761 | { | ||
| 762 | for (; tag->hdr.size; tag = tag_next(tag)) | ||
| 763 | if (tag->hdr.tag == ATAG_MEM) | ||
| 764 | tag->hdr.tag = ATAG_NONE; | ||
| 765 | } | ||
| 766 | |||
| 666 | void __init setup_arch(char **cmdline_p) | 767 | void __init setup_arch(char **cmdline_p) |
| 667 | { | 768 | { |
| 668 | struct tag *tags = (struct tag *)&init_tags; | 769 | struct tag *tags = (struct tag *)&init_tags; |
| @@ -683,12 +784,14 @@ void __init setup_arch(char **cmdline_p) | |||
| 683 | else if (mdesc->boot_params) | 784 | else if (mdesc->boot_params) |
| 684 | tags = phys_to_virt(mdesc->boot_params); | 785 | tags = phys_to_virt(mdesc->boot_params); |
| 685 | 786 | ||
| 787 | #if defined(CONFIG_DEPRECATED_PARAM_STRUCT) | ||
| 686 | /* | 788 | /* |
| 687 | * If we have the old style parameters, convert them to | 789 | * If we have the old style parameters, convert them to |
| 688 | * a tag list. | 790 | * a tag list. |
| 689 | */ | 791 | */ |
| 690 | if (tags->hdr.tag != ATAG_CORE) | 792 | if (tags->hdr.tag != ATAG_CORE) |
| 691 | convert_to_tag_list(tags); | 793 | convert_to_tag_list(tags); |
| 794 | #endif | ||
| 692 | if (tags->hdr.tag != ATAG_CORE) | 795 | if (tags->hdr.tag != ATAG_CORE) |
| 693 | tags = (struct tag *)&init_tags; | 796 | tags = (struct tag *)&init_tags; |
| 694 | 797 | ||
| @@ -716,12 +819,15 @@ void __init setup_arch(char **cmdline_p) | |||
| 716 | 819 | ||
| 717 | parse_early_param(); | 820 | parse_early_param(); |
| 718 | 821 | ||
| 822 | arm_memblock_init(&meminfo, mdesc); | ||
| 823 | |||
| 719 | paging_init(mdesc); | 824 | paging_init(mdesc); |
| 720 | request_standard_resources(&meminfo, mdesc); | 825 | request_standard_resources(&meminfo, mdesc); |
| 721 | 826 | ||
| 722 | #ifdef CONFIG_SMP | 827 | #ifdef CONFIG_SMP |
| 723 | smp_init_cpus(); | 828 | smp_init_cpus(); |
| 724 | #endif | 829 | #endif |
| 830 | reserve_crashkernel(); | ||
| 725 | 831 | ||
| 726 | cpu_init(); | 832 | cpu_init(); |
| 727 | tcm_init(); | 833 | tcm_init(); |
| @@ -729,6 +835,7 @@ void __init setup_arch(char **cmdline_p) | |||
| 729 | /* | 835 | /* |
| 730 | * Set up various architecture-specific pointers | 836 | * Set up various architecture-specific pointers |
| 731 | */ | 837 | */ |
| 838 | arch_nr_irqs = mdesc->nr_irqs; | ||
| 732 | init_arch_irq = mdesc->init_irq; | 839 | init_arch_irq = mdesc->init_irq; |
| 733 | system_timer = mdesc->timer; | 840 | system_timer = mdesc->timer; |
| 734 | init_machine = mdesc->init_machine; | 841 | init_machine = mdesc->init_machine; |
